ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/object.C
Revision: 1.304
Committed: Tue Nov 10 16:29:20 2009 UTC (14 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.303: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# User Rev Content
1 elmex 1.1 /*
2 root 1.199 * This file is part of Deliantra, the Roguelike Realtime MMORPG.
3 pippijn 1.116 *
4 root 1.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.208 /* NO_FIX_PLAYER is set when a great many changes are being
1132     * made to players inventory. If set, avoiding the call
1133     * to save cpu time.
1134     */
1135 root 1.265 if (pl)
1136 root 1.267 if (pl->is_player () && (glow_radius || !QUERY_FLAG (pl, FLAG_NO_FIX_PLAYER)))
1137 root 1.265 {
1138     pl->update_stats ();
1139    
1140 root 1.270 if (glow_radius && pl->is_on_map ())
1141 root 1.265 update_all_los (pl->map, pl->x, pl->y);
1142     }
1143 root 1.59 }
1144     else if (map)
1145     {
1146 root 1.220 map->dirty = true;
1147     mapspace &ms = this->ms ();
1148    
1149     if (object *pl = ms.player ())
1150 root 1.96 {
1151 root 1.270 if (is_player ())
1152 root 1.220 {
1153 root 1.273 if (!flag [FLAG_WIZPASS])
1154     ms.smell = ++mapspace::smellcount; // remember the smell of the player
1155 root 1.270
1156 root 1.220 // leaving a spot always closes any open container on the ground
1157     if (container && !container->env)
1158     // this causes spurious floorbox updates, but it ensures
1159     // that the CLOSE event is being sent.
1160     close_container ();
1161    
1162     --map->players;
1163     map->touch ();
1164     }
1165 root 1.292 else if (pl->container_ () == this)
1166 root 1.220 {
1167     // removing a container should close it
1168     close_container ();
1169     }
1170 root 1.130
1171 root 1.220 esrv_del_item (pl->contr, count);
1172 root 1.96 }
1173    
1174 root 1.29 /* link the object above us */
1175 root 1.236 // re-link, make sure compiler can easily use cmove
1176     *(above ? &above->below : &ms.top) = below;
1177     *(below ? &below->above : &ms.bot) = above;
1178 root 1.26
1179 root 1.59 above = 0;
1180     below = 0;
1181 root 1.26
1182 root 1.265 ms.invalidate ();
1183 root 1.253
1184 root 1.59 if (map->in_memory == MAP_SAVING)
1185 root 1.29 return;
1186 elmex 1.1
1187 root 1.82 int check_walk_off = !flag [FLAG_NO_APPLY];
1188 elmex 1.1
1189 root 1.175 if (object *pl = ms.player ())
1190     {
1191 root 1.292 if (pl->container_ () == this)
1192 root 1.175 /* If a container that the player is currently using somehow gets
1193     * removed (most likely destroyed), update the player view
1194     * appropriately.
1195     */
1196     pl->close_container ();
1197    
1198 root 1.218 //TODO: the floorbox prev/next might need updating
1199 root 1.226 //esrv_del_item (pl->contr, count);
1200     //TODO: update floorbox to preserve ordering
1201     if (pl->contr->ns)
1202     pl->contr->ns->floorbox_update ();
1203 root 1.175 }
1204    
1205 root 1.293 if (check_walk_off)
1206     for (object *above, *tmp = ms.bot; tmp; tmp = above)
1207     {
1208     above = tmp->above;
1209    
1210     /* No point updating the players look faces if he is the object
1211     * being removed.
1212     */
1213 root 1.29
1214 root 1.293 /* See if object moving off should effect something */
1215     if ((move_type & tmp->move_off)
1216     && (move_type & ~tmp->move_off & ~tmp->move_block) == 0)
1217 elmex 1.72 move_apply (tmp, this, 0);
1218 root 1.293 }
1219 root 1.26
1220 root 1.270 if (affects_los ())
1221 root 1.59 update_all_los (map, x, y);
1222 elmex 1.1 }
1223     }
1224    
1225     /*
1226     * merge_ob(op,top):
1227     *
1228     * This function goes through all objects below and including top, and
1229     * merges op to the first matching object.
1230     * If top is NULL, it is calculated.
1231     * Returns pointer to object if it succeded in the merge, otherwise NULL
1232     */
1233 root 1.24 object *
1234     merge_ob (object *op, object *top)
1235     {
1236     if (!op->nrof)
1237 elmex 1.1 return 0;
1238 root 1.29
1239 root 1.194 if (!top)
1240 root 1.82 for (top = op; top && top->above; top = top->above)
1241     ;
1242 root 1.29
1243 root 1.82 for (; top; top = top->below)
1244 root 1.214 if (object::can_merge (op, top))
1245     {
1246     top->nrof += op->nrof;
1247    
1248     if (object *pl = top->visible_to ())
1249     esrv_update_item (UPD_NROF, pl, top);
1250    
1251     op->weight = 0; // cancel the addition above
1252     op->carrying = 0; // must be 0 already
1253 root 1.66
1254 root 1.259 op->destroy ();
1255 root 1.24
1256 root 1.214 return top;
1257     }
1258 root 1.29
1259 root 1.45 return 0;
1260 elmex 1.1 }
1261    
1262 root 1.138 void
1263     object::expand_tail ()
1264     {
1265     if (more)
1266     return;
1267    
1268     object *prev = this;
1269    
1270 root 1.160 for (archetype *at = (archetype *)arch->more; at; at = (archetype *)at->more)
1271 root 1.138 {
1272     object *op = arch_to_object (at);
1273    
1274     op->name = name;
1275     op->name_pl = name_pl;
1276     op->title = title;
1277    
1278     op->head = this;
1279     prev->more = op;
1280    
1281     prev = op;
1282     }
1283     }
1284    
1285 elmex 1.1 /*
1286 root 1.117 * same as insert_ob_in_map except it handles separate coordinates and does a clean
1287     * job preparing multi-part monsters.
1288 elmex 1.1 */
1289 root 1.24 object *
1290 root 1.49 insert_ob_in_map_at (object *op, maptile *m, object *originator, int flag, int x, int y)
1291 root 1.24 {
1292 root 1.244 op->remove ();
1293    
1294 root 1.93 for (object *tmp = op->head_ (); tmp; tmp = tmp->more)
1295 root 1.24 {
1296 root 1.159 tmp->x = x + tmp->arch->x;
1297     tmp->y = y + tmp->arch->y;
1298 elmex 1.1 }
1299 root 1.29
1300 root 1.24 return insert_ob_in_map (op, m, originator, flag);
1301 elmex 1.1 }
1302    
1303     /*
1304     * insert_ob_in_map (op, map, originator, flag):
1305     * This function inserts the object in the two-way linked list
1306     * which represents what is on a map.
1307     * The second argument specifies the map, and the x and y variables
1308     * in the object about to be inserted specifies the position.
1309     *
1310     * originator: Player, monster or other object that caused 'op' to be inserted
1311     * into 'map'. May be NULL.
1312     *
1313     * flag is a bitmask about special things to do (or not do) when this
1314     * function is called. see the object.h file for the INS_ values.
1315     * Passing 0 for flag gives proper default values, so flag really only needs
1316     * to be set if special handling is needed.
1317     *
1318     * Return value:
1319     * new object if 'op' was merged with other object
1320     * NULL if 'op' was destroyed
1321     * just 'op' otherwise
1322     */
1323 root 1.24 object *
1324 root 1.49 insert_ob_in_map (object *op, maptile *m, object *originator, int flag)
1325 elmex 1.1 {
1326 root 1.261 op->remove ();
1327 root 1.117
1328 root 1.258 if (m == &freed_map)//D TODO: remove soon
1329 root 1.245 {//D
1330 root 1.258 LOG (llevError | logBacktrace, "tries to insret object on freed objects map: %s", op->debug_desc ());//D
1331 root 1.245 }//D
1332    
1333 root 1.187 /* Ideally, the caller figures this out. However, it complicates a lot
1334     * of areas of callers (eg, anything that uses find_free_spot would now
1335     * need extra work
1336     */
1337 root 1.274 maptile *newmap = m;
1338     if (!xy_normalise (newmap, op->x, op->y))
1339 root 1.24 {
1340 root 1.259 op->head_ ()->destroy ();// remove head_ once all tail object destroyers found
1341 root 1.187 return 0;
1342 elmex 1.1 }
1343 root 1.25
1344 root 1.117 if (object *more = op->more)
1345 root 1.155 if (!insert_ob_in_map (more, m, originator, flag))
1346     return 0;
1347 root 1.25
1348 root 1.283 op->flag [FLAG_REMOVED] = false;
1349     op->env = 0;
1350     op->map = newmap;
1351 root 1.8
1352 root 1.117 mapspace &ms = op->ms ();
1353 root 1.24
1354     /* this has to be done after we translate the coordinates.
1355     */
1356     if (op->nrof && !(flag & INS_NO_MERGE))
1357 root 1.155 for (object *tmp = ms.bot; tmp; tmp = tmp->above)
1358 root 1.66 if (object::can_merge (op, tmp))
1359 root 1.25 {
1360 root 1.237 // TODO: we actually want to update tmp, not op,
1361 root 1.218 // but some caller surely breaks when we return tmp
1362     // from here :/
1363 root 1.25 op->nrof += tmp->nrof;
1364 root 1.259 tmp->destroy ();
1365 root 1.25 }
1366 root 1.24
1367     CLEAR_FLAG (op, FLAG_APPLIED); /* hack for fixing F_APPLIED in items of dead people */
1368     CLEAR_FLAG (op, FLAG_INV_LOCKED);
1369 root 1.25
1370 root 1.24 if (!QUERY_FLAG (op, FLAG_ALIVE))
1371     CLEAR_FLAG (op, FLAG_NO_STEAL);
1372    
1373     if (flag & INS_BELOW_ORIGINATOR)
1374     {
1375 root 1.241 if (originator->map != op->map || originator->x != op->x || originator->y != op->y)
1376 root 1.24 {
1377     LOG (llevError, "insert_ob_in_map called with INS_BELOW_ORIGINATOR when originator not on same space!\n");
1378     abort ();
1379     }
1380 root 1.25
1381 root 1.241 if (!originator->is_on_map ())
1382 root 1.282 {
1383     LOG (llevError, "insert_ob_in_map(%s) called with INS_BELOW_ORIGINATOR when originator '%s' not on map",
1384     op->debug_desc (), originator->debug_desc ());
1385     abort ();
1386     }
1387 root 1.241
1388 root 1.24 op->above = originator;
1389     op->below = originator->below;
1390 root 1.237 originator->below = op;
1391 root 1.25
1392 root 1.237 *(op->below ? &op->below->above : &ms.bot) = op;
1393 elmex 1.1 }
1394 root 1.24 else
1395     {
1396 root 1.237 object *floor = 0;
1397     object *top = ms.top;
1398 root 1.117
1399 root 1.24 /* If there are other objects, then */
1400 root 1.191 if (top)
1401 root 1.24 {
1402     /*
1403     * If there are multiple objects on this space, we do some trickier handling.
1404     * We've already dealt with merging if appropriate.
1405     * Generally, we want to put the new object on top. But if
1406     * flag contains INS_ABOVE_FLOOR_ONLY, once we find the last
1407     * floor, we want to insert above that and no further.
1408     * Also, if there are spell objects on this space, we stop processing
1409     * once we get to them. This reduces the need to traverse over all of
1410     * them when adding another one - this saves quite a bit of cpu time
1411     * when lots of spells are cast in one area. Currently, it is presumed
1412     * that flying non pickable objects are spell objects.
1413     */
1414 root 1.237 for (object *tmp = ms.bot; tmp; tmp = tmp->above)
1415 root 1.24 {
1416 root 1.237 if (QUERY_FLAG (tmp, FLAG_IS_FLOOR) || QUERY_FLAG (tmp, FLAG_OVERLAY_FLOOR))
1417     floor = tmp;
1418 root 1.26
1419 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))
1420 root 1.24 {
1421     /* We insert above top, so we want this object below this */
1422 root 1.237 top = tmp->below;
1423 root 1.24 break;
1424     }
1425 root 1.26
1426 root 1.237 top = tmp;
1427 root 1.24 }
1428 root 1.26
1429 root 1.24 /* We let update_position deal with figuring out what the space
1430     * looks like instead of lots of conditions here.
1431     * makes things faster, and effectively the same result.
1432     */
1433    
1434     /* Have object 'fall below' other objects that block view.
1435 root 1.135 * Unless those objects are exits.
1436 root 1.24 * If INS_ON_TOP is used, don't do this processing
1437     * Need to find the object that in fact blocks view, otherwise
1438     * stacking is a bit odd.
1439     */
1440 root 1.117 if (!(flag & INS_ON_TOP)
1441     && ms.flags () & P_BLOCKSVIEW
1442 root 1.135 && (op->face && !faces [op->face].visibility))
1443 root 1.24 {
1444 root 1.237 object *last;
1445    
1446 root 1.24 for (last = top; last != floor; last = last->below)
1447     if (QUERY_FLAG (last, FLAG_BLOCKSVIEW) && (last->type != EXIT))
1448     break;
1449 root 1.117
1450 root 1.24 /* Check to see if we found the object that blocks view,
1451     * and make sure we have a below pointer for it so that
1452     * we can get inserted below this one, which requires we
1453     * set top to the object below us.
1454     */
1455     if (last && last->below && last != floor)
1456     top = last->below;
1457 root 1.8 }
1458 root 1.24 } /* If objects on this space */
1459 root 1.25
1460 root 1.24 if (flag & INS_ABOVE_FLOOR_ONLY)
1461     top = floor;
1462    
1463 root 1.240 // insert object above top, or bottom-most if top = 0
1464 root 1.24 if (!top)
1465     {
1466 root 1.239 op->below = 0;
1467     op->above = ms.bot;
1468     ms.bot = op;
1469 root 1.25
1470 root 1.239 *(op->above ? &op->above->below : &ms.top) = op;
1471 root 1.24 }
1472     else
1473 root 1.240 {
1474 root 1.24 op->above = top->above;
1475 root 1.237 top->above = op;
1476 root 1.25
1477 root 1.24 op->below = top;
1478 root 1.237 *(op->above ? &op->above->below : &ms.top) = op;
1479 root 1.24 }
1480 root 1.240 }
1481 root 1.8
1482 root 1.270 if (op->is_player ())
1483 root 1.96 {
1484     op->contr->do_los = 1;
1485     ++op->map->players;
1486 root 1.100 op->map->touch ();
1487 root 1.96 }
1488 root 1.24
1489 root 1.98 op->map->dirty = true;
1490    
1491 root 1.191 if (object *pl = ms.player ())
1492 root 1.218 //TODO: the floorbox prev/next might need updating
1493 root 1.226 //esrv_send_item (pl, op);
1494     //TODO: update floorbox to preserve ordering
1495     if (pl->contr->ns)
1496     pl->contr->ns->floorbox_update ();
1497 root 1.24
1498     /* If this object glows, it may affect lighting conditions that are
1499     * visible to others on this map. But update_all_los is really
1500     * an inefficient way to do this, as it means los for all players
1501     * on the map will get recalculated. The players could very well
1502     * be far away from this change and not affected in any way -
1503     * this should get redone to only look for players within range,
1504 root 1.99 * or just updating the P_UPTODATE for spaces within this area
1505 root 1.24 * of effect may be sufficient.
1506     */
1507 root 1.270 if (op->affects_los ())
1508 root 1.265 {
1509     op->ms ().invalidate ();
1510     update_all_los (op->map, op->x, op->y);
1511     }
1512 root 1.24
1513     /* updates flags (blocked, alive, no magic, etc) for this map space */
1514     update_object (op, UP_OBJ_INSERT);
1515    
1516 root 1.82 INVOKE_OBJECT (INSERT, op);
1517    
1518 root 1.24 /* Don't know if moving this to the end will break anything. However,
1519 root 1.70 * we want to have floorbox_update called before calling this.
1520 root 1.24 *
1521     * check_move_on() must be after this because code called from
1522     * check_move_on() depends on correct map flags (so functions like
1523     * blocked() and wall() work properly), and these flags are updated by
1524     * update_object().
1525     */
1526    
1527     /* if this is not the head or flag has been passed, don't check walk on status */
1528 root 1.287 if (!(flag & INS_NO_WALK_ON) && op->is_head ())
1529 root 1.24 {
1530     if (check_move_on (op, originator))
1531 root 1.82 return 0;
1532 elmex 1.1
1533 root 1.24 /* If we are a multi part object, lets work our way through the check
1534     * walk on's.
1535     */
1536 root 1.155 for (object *tmp = op->more; tmp; tmp = tmp->more)
1537 root 1.24 if (check_move_on (tmp, originator))
1538 root 1.82 return 0;
1539 elmex 1.1 }
1540 root 1.25
1541 root 1.24 return op;
1542 elmex 1.1 }
1543    
1544     /* this function inserts an object in the map, but if it
1545 root 1.75 * finds an object of its own type, it'll remove that one first.
1546     * op is the object to insert it under: supplies x and the map.
1547 elmex 1.1 */
1548 root 1.24 void
1549 root 1.277 replace_insert_ob_in_map (shstr_tmp archname, object *op)
1550 root 1.24 {
1551     /* first search for itself and remove any old instances */
1552 elmex 1.1
1553 root 1.208 for (object *tmp = op->ms ().bot; tmp; tmp = tmp->above)
1554 root 1.277 if (tmp->arch->archname == archname) /* same archetype */
1555 root 1.259 tmp->destroy ();
1556 root 1.208
1557 root 1.277 object *tmp = arch_to_object (archetype::find (archname));
1558 elmex 1.1
1559 root 1.208 tmp->x = op->x;
1560     tmp->y = op->y;
1561 elmex 1.1
1562 root 1.208 insert_ob_in_map (tmp, op->map, op, 0);
1563 root 1.24 }
1564 elmex 1.1
1565 root 1.93 object *
1566     object::insert_at (object *where, object *originator, int flags)
1567     {
1568 root 1.205 if (where->env)
1569     return where->env->insert (this);
1570     else
1571     return where->map->insert (this, where->x, where->y, originator, flags);
1572 root 1.93 }
1573    
1574 root 1.301 // check whether we can put this into the map, respect max_volume, max_items
1575 root 1.299 bool
1576     object::can_drop_at (maptile *m, int x, int y, object *originator)
1577     {
1578     mapspace &ms = m->at (x, y);
1579    
1580     int items = ms.items ();
1581    
1582     if (!items // testing !items ensures we can drop at least one item
1583     || (items < m->max_items
1584 root 1.301 && ms.volume () < m->max_volume))
1585 root 1.299 return true;
1586    
1587     if (originator && originator->is_player ())
1588     originator->contr->failmsg (format (
1589     "No matter how hard you try, you just cannot put the %s here H<Try to remove some items from the floor first.>",
1590     query_name ()
1591     ));
1592    
1593     return false;
1594     }
1595    
1596 elmex 1.1 /*
1597 root 1.209 * decrease(object, number) decreases a specified number from
1598 root 1.208 * the amount of an object. If the amount reaches 0, the object
1599 elmex 1.1 * is subsequently removed and freed.
1600     *
1601     * Return value: 'op' if something is left, NULL if the amount reached 0
1602     */
1603 root 1.208 bool
1604 root 1.209 object::decrease (sint32 nr)
1605 elmex 1.1 {
1606 root 1.212 if (!nr)
1607     return true;
1608    
1609 root 1.208 nr = min (nr, nrof);
1610 elmex 1.1
1611 root 1.251 if (nrof > nr)
1612 elmex 1.1 {
1613 root 1.251 nrof -= nr;
1614 root 1.247 adjust_weight (env, -weight * max (1, nr)); // carrying == 0
1615 elmex 1.1
1616 root 1.212 if (object *pl = visible_to ())
1617     esrv_update_item (UPD_NROF, pl, this);
1618 root 1.29
1619 root 1.212 return true;
1620 elmex 1.1 }
1621 root 1.24 else
1622     {
1623 root 1.249 destroy ();
1624 root 1.212 return false;
1625 elmex 1.1 }
1626     }
1627    
1628 root 1.209 /*
1629 root 1.210 * split(ob,nr) splits up ob into two parts. The part which
1630 root 1.209 * is returned contains nr objects, and the remaining parts contains
1631 root 1.210 * the rest (or is removed and returned if that number is 0).
1632     * On failure, NULL is returned.
1633 root 1.209 */
1634 root 1.208 object *
1635 root 1.209 object::split (sint32 nr)
1636 root 1.208 {
1637 root 1.212 int have = number_of ();
1638    
1639     if (have < nr)
1640 root 1.209 return 0;
1641 root 1.212 else if (have == nr)
1642 root 1.209 {
1643     remove ();
1644     return this;
1645     }
1646     else
1647     {
1648     decrease (nr);
1649    
1650 root 1.230 object *op = deep_clone ();
1651 root 1.209 op->nrof = nr;
1652     return op;
1653     }
1654     }
1655    
1656 root 1.24 object *
1657     insert_ob_in_ob (object *op, object *where)
1658     {
1659 root 1.59 if (!where)
1660 root 1.24 {
1661 root 1.53 char *dump = dump_object (op);
1662     LOG (llevError, "Trying to put object in NULL.\n%s\n", dump);
1663     free (dump);
1664 root 1.24 return op;
1665     }
1666 root 1.29
1667 root 1.154 if (where->head_ () != where)
1668 root 1.24 {
1669 root 1.153 LOG (llevError | logBacktrace, "Warning: Tried to insert object into wrong part of multipart object.\n");
1670 root 1.24 where = where->head;
1671     }
1672 root 1.29
1673 root 1.59 return where->insert (op);
1674     }
1675    
1676     /*
1677     * env->insert (op)
1678     * This function inserts the object op in the linked list
1679     * inside the object environment.
1680     *
1681     * The function returns now pointer to inserted item, and return value can
1682     * be != op, if items are merged. -Tero
1683     */
1684     object *
1685     object::insert (object *op)
1686     {
1687 root 1.24 if (op->more)
1688     {
1689     LOG (llevError, "Tried to insert multipart object %s (%d)\n", &op->name, op->count);
1690     return op;
1691     }
1692 root 1.29
1693 root 1.208 op->remove ();
1694    
1695     op->flag [FLAG_OBJ_ORIGINAL] = 0;
1696 root 1.182
1697 root 1.24 if (op->nrof)
1698 root 1.208 for (object *tmp = inv; tmp; tmp = tmp->below)
1699     if (object::can_merge (tmp, op))
1700     {
1701     /* return the original object and remove inserted object
1702     (client needs the original object) */
1703     tmp->nrof += op->nrof;
1704 root 1.214
1705     if (object *pl = tmp->visible_to ())
1706     esrv_update_item (UPD_NROF, pl, tmp);
1707    
1708 root 1.210 adjust_weight (this, op->total_weight ());
1709    
1710 root 1.259 op->destroy ();
1711 root 1.208 op = tmp;
1712     goto inserted;
1713     }
1714    
1715     op->owner = 0; // it's his/hers now. period.
1716     op->map = 0;
1717     op->x = 0;
1718     op->y = 0;
1719    
1720     op->above = 0;
1721     op->below = inv;
1722     op->env = this;
1723    
1724     if (inv)
1725     inv->above = op;
1726 root 1.24
1727 root 1.208 inv = op;
1728 elmex 1.1
1729 root 1.208 op->flag [FLAG_REMOVED] = 0;
1730 elmex 1.1
1731 root 1.214 if (object *pl = op->visible_to ())
1732     esrv_send_item (pl, op);
1733    
1734 root 1.208 adjust_weight (this, op->total_weight ());
1735 elmex 1.1
1736 root 1.208 inserted:
1737 elmex 1.1 /* reset the light list and los of the players on the map */
1738 root 1.270 if (op->glow_radius && is_on_map ())
1739 root 1.265 {
1740     update_stats ();
1741     update_all_los (map, x, y);
1742     }
1743 root 1.270 else if (is_player () && !flag [FLAG_NO_FIX_PLAYER])
1744 root 1.265 // if this is a player's inventory, update stats
1745 root 1.214 update_stats ();
1746 root 1.59
1747 root 1.82 INVOKE_OBJECT (INSERT, this);
1748    
1749 elmex 1.1 return op;
1750     }
1751    
1752     /*
1753     * Checks if any objects has a move_type that matches objects
1754     * that effect this object on this space. Call apply() to process
1755     * these events.
1756     *
1757     * Any speed-modification due to SLOW_MOVE() of other present objects
1758     * will affect the speed_left of the object.
1759     *
1760     * originator: Player, monster or other object that caused 'op' to be inserted
1761     * into 'map'. May be NULL.
1762     *
1763     * Return value: 1 if 'op' was destroyed, 0 otherwise.
1764     *
1765     * 4-21-95 added code to check if appropriate skill was readied - this will
1766     * permit faster movement by the player through this terrain. -b.t.
1767     *
1768     * MSW 2001-07-08: Check all objects on space, not just those below
1769     * object being inserted. insert_ob_in_map may not put new objects
1770     * on top.
1771     */
1772 root 1.24 int
1773     check_move_on (object *op, object *originator)
1774 elmex 1.1 {
1775 root 1.287 if (QUERY_FLAG (op, FLAG_NO_APPLY))
1776     return 0;
1777    
1778 root 1.48 object *tmp;
1779 root 1.49 maptile *m = op->map;
1780 root 1.48 int x = op->x, y = op->y;
1781 root 1.26
1782 root 1.287 mapspace &ms = m->at (x, y);
1783 root 1.24
1784 root 1.287 ms.update ();
1785 root 1.24
1786 root 1.287 MoveType move_on = ms.move_on;
1787     MoveType move_slow = ms.move_slow;
1788     MoveType move_block = ms.move_block;
1789 root 1.24
1790     /* if nothing on this space will slow op down or be applied,
1791     * no need to do checking below. have to make sure move_type
1792     * is set, as lots of objects don't have it set - we treat that
1793     * as walking.
1794     */
1795     if (op->move_type && !(op->move_type & move_on) && !(op->move_type & move_slow))
1796     return 0;
1797 elmex 1.1
1798 root 1.24 /* This is basically inverse logic of that below - basically,
1799     * if the object can avoid the move on or slow move, they do so,
1800     * but can't do it if the alternate movement they are using is
1801     * blocked. Logic on this seems confusing, but does seem correct.
1802     */
1803     if ((op->move_type & ~move_on & ~move_block) != 0 && (op->move_type & ~move_slow & ~move_block) != 0)
1804     return 0;
1805    
1806     /* The objects have to be checked from top to bottom.
1807     * Hence, we first go to the top:
1808     */
1809 root 1.287 for (object *next, *tmp = ms.top; tmp; tmp = next)
1810 root 1.24 {
1811 root 1.287 next = tmp->below;
1812 root 1.26
1813 root 1.24 if (tmp == op)
1814     continue; /* Can't apply yourself */
1815 elmex 1.1
1816 root 1.24 /* Check to see if one of the movement types should be slowed down.
1817     * Second check makes sure that the movement types not being slowed
1818     * (~slow_move) is not blocked on this space - just because the
1819     * space doesn't slow down swimming (for example), if you can't actually
1820     * swim on that space, can't use it to avoid the penalty.
1821     */
1822     if (!QUERY_FLAG (op, FLAG_WIZPASS))
1823     {
1824     if ((!op->move_type && tmp->move_slow & MOVE_WALK) ||
1825     ((op->move_type & tmp->move_slow) && (op->move_type & ~tmp->move_slow & ~tmp->move_block) == 0))
1826     {
1827 root 1.287 float diff = tmp->move_slow_penalty * fabs (op->speed);
1828 elmex 1.1
1829 root 1.270 if (op->is_player ())
1830 root 1.287 if ((tmp->flag [FLAG_IS_HILLY ] && find_skill_by_number (op, SK_CLIMBING)) ||
1831     (tmp->flag [FLAG_IS_WOODED] && find_skill_by_number (op, SK_WOODSMAN)))
1832 root 1.26 diff /= 4.0;
1833    
1834 root 1.24 op->speed_left -= diff;
1835 root 1.8 }
1836     }
1837 elmex 1.1
1838 root 1.24 /* Basically same logic as above, except now for actual apply. */
1839     if ((!op->move_type && tmp->move_on & MOVE_WALK) ||
1840     ((op->move_type & tmp->move_on) && (op->move_type & ~tmp->move_on & ~tmp->move_block) == 0))
1841     {
1842 elmex 1.72 move_apply (tmp, op, originator);
1843 root 1.24
1844 root 1.48 if (op->destroyed ())
1845 root 1.24 return 1;
1846    
1847     /* what the person/creature stepped onto has moved the object
1848     * someplace new. Don't process any further - if we did,
1849     * have a feeling strange problems would result.
1850     */
1851     if (op->map != m || op->x != x || op->y != y)
1852     return 0;
1853 root 1.8 }
1854 elmex 1.1 }
1855 root 1.26
1856 root 1.24 return 0;
1857 elmex 1.1 }
1858    
1859     /*
1860     * present_arch(arch, map, x, y) searches for any objects with
1861     * a matching archetype at the given map and coordinates.
1862     * The first matching object is returned, or NULL if none.
1863     */
1864 root 1.24 object *
1865 root 1.49 present_arch (const archetype *at, maptile *m, int x, int y)
1866 root 1.24 {
1867 root 1.104 if (!m || out_of_map (m, x, y))
1868 root 1.24 {
1869     LOG (llevError, "Present_arch called outside map.\n");
1870     return NULL;
1871     }
1872 root 1.84
1873 root 1.104 for (object *tmp = m->at (x, y).bot; tmp; tmp = tmp->above)
1874 root 1.231 if (tmp->arch->archname == at->archname)
1875 elmex 1.1 return tmp;
1876 root 1.84
1877 elmex 1.1 return NULL;
1878     }
1879    
1880     /*
1881     * present(type, map, x, y) searches for any objects with
1882     * a matching type variable at the given map and coordinates.
1883     * The first matching object is returned, or NULL if none.
1884     */
1885 root 1.24 object *
1886 root 1.49 present (unsigned char type, maptile *m, int x, int y)
1887 root 1.24 {
1888     if (out_of_map (m, x, y))
1889     {
1890     LOG (llevError, "Present called outside map.\n");
1891     return NULL;
1892     }
1893 root 1.84
1894 root 1.104 for (object *tmp = m->at (x, y).bot; tmp; tmp = tmp->above)
1895 root 1.24 if (tmp->type == type)
1896 elmex 1.1 return tmp;
1897 root 1.84
1898 elmex 1.1 return NULL;
1899     }
1900    
1901     /*
1902     * present_in_ob(type, object) searches for any objects with
1903     * a matching type variable in the inventory of the given object.
1904     * The first matching object is returned, or NULL if none.
1905     */
1906 root 1.24 object *
1907     present_in_ob (unsigned char type, const object *op)
1908     {
1909 root 1.84 for (object *tmp = op->inv; tmp != NULL; tmp = tmp->below)
1910 root 1.24 if (tmp->type == type)
1911 elmex 1.1 return tmp;
1912 root 1.84
1913 elmex 1.1 return NULL;
1914     }
1915    
1916     /*
1917     * present_in_ob (type, str, object) searches for any objects with
1918     * a matching type & name variable in the inventory of the given object.
1919     * The first matching object is returned, or NULL if none.
1920     * This is mostly used by spell effect code, so that we only
1921     * have one spell effect at a time.
1922     * type can be used to narrow the search - if type is set,
1923     * the type must also match. -1 can be passed for the type,
1924     * in which case the type does not need to pass.
1925     * str is the string to match against. Note that we match against
1926     * the object name, not the archetype name. this is so that the
1927     * spell code can use one object type (force), but change it's name
1928     * to be unique.
1929     */
1930 root 1.24 object *
1931     present_in_ob_by_name (int type, const char *str, const object *op)
1932     {
1933 root 1.84 for (object *tmp = op->inv; tmp; tmp = tmp->below)
1934 root 1.82 if ((type == -1 || tmp->type == type) && (!strcmp (str, tmp->name)))
1935     return tmp;
1936 elmex 1.1
1937 root 1.82 return 0;
1938 elmex 1.1 }
1939    
1940     /*
1941     * present_arch_in_ob(archetype, object) searches for any objects with
1942     * a matching archetype in the inventory of the given object.
1943     * The first matching object is returned, or NULL if none.
1944     */
1945 root 1.24 object *
1946     present_arch_in_ob (const archetype *at, const object *op)
1947     {
1948 root 1.231 for (object *tmp = op->inv; tmp; tmp = tmp->below)
1949     if (tmp->arch->archname == at->archname)
1950 elmex 1.1 return tmp;
1951 root 1.82
1952 elmex 1.1 return NULL;
1953     }
1954    
1955     /*
1956     * activate recursively a flag on an object inventory
1957     */
1958 root 1.24 void
1959     flag_inv (object *op, int flag)
1960     {
1961 root 1.197 for (object *tmp = op->inv; tmp; tmp = tmp->below)
1962     {
1963     SET_FLAG (tmp, flag);
1964     flag_inv (tmp, flag);
1965     }
1966 root 1.82 }
1967    
1968     /*
1969     * deactivate recursively a flag on an object inventory
1970     */
1971 root 1.24 void
1972     unflag_inv (object *op, int flag)
1973     {
1974 root 1.197 for (object *tmp = op->inv; tmp; tmp = tmp->below)
1975     {
1976     CLEAR_FLAG (tmp, flag);
1977     unflag_inv (tmp, flag);
1978     }
1979 elmex 1.1 }
1980    
1981     /*
1982     * find_free_spot(object, map, x, y, start, stop) will search for
1983     * a spot at the given map and coordinates which will be able to contain
1984     * the given object. start and stop specifies how many squares
1985     * to search (see the freearr_x/y[] definition).
1986     * It returns a random choice among the alternatives found.
1987     * start and stop are where to start relative to the free_arr array (1,9
1988     * does all 4 immediate directions). This returns the index into the
1989     * array of the free spot, -1 if no spot available (dir 0 = x,y)
1990 root 1.196 * Note: This function does correctly handle tiled maps, but does not
1991 elmex 1.1 * inform the caller. However, insert_ob_in_map will update as
1992     * necessary, so the caller shouldn't need to do any special work.
1993     * Note - updated to take an object instead of archetype - this is necessary
1994     * because arch_blocked (now ob_blocked) needs to know the movement type
1995     * to know if the space in question will block the object. We can't use
1996     * the archetype because that isn't correct if the monster has been
1997     * customized, changed states, etc.
1998     */
1999 root 1.24 int
2000 root 1.49 find_free_spot (const object *ob, maptile *m, int x, int y, int start, int stop)
2001 root 1.24 {
2002 root 1.190 int altern[SIZEOFFREE];
2003 root 1.82 int index = 0, flag;
2004 root 1.24
2005 root 1.82 for (int i = start; i < stop; i++)
2006 root 1.24 {
2007 root 1.188 mapxy pos (m, x, y); pos.move (i);
2008    
2009     if (!pos.normalise ())
2010     continue;
2011    
2012     mapspace &ms = *pos;
2013 root 1.189
2014     if (ms.flags () & P_IS_ALIVE)
2015     continue;
2016 root 1.188
2017     /* However, often
2018     * ob doesn't have any move type (when used to place exits)
2019     * so the AND operation in OB_TYPE_MOVE_BLOCK doesn't work.
2020     */
2021 root 1.200 if (ob && ob->move_type == 0 && ms.move_block != MOVE_ALL)
2022 root 1.190 {
2023     altern [index++] = i;
2024     continue;
2025     }
2026 root 1.24
2027     /* Basically, if we find a wall on a space, we cut down the search size.
2028     * In this way, we won't return spaces that are on another side of a wall.
2029     * This mostly work, but it cuts down the search size in all directions -
2030     * if the space being examined only has a wall to the north and empty
2031     * spaces in all the other directions, this will reduce the search space
2032     * to only the spaces immediately surrounding the target area, and
2033     * won't look 2 spaces south of the target space.
2034     */
2035 root 1.188 if (ms.move_block == MOVE_ALL && maxfree[i] < stop)
2036     {
2037     stop = maxfree[i];
2038     continue;
2039     }
2040    
2041     /* Note it is intentional that we check ob - the movement type of the
2042     * head of the object should correspond for the entire object.
2043     */
2044     if (OB_TYPE_MOVE_BLOCK (ob, ms.move_block))
2045     continue;
2046    
2047 elmex 1.262 if (ob->blocked (pos.m, pos.x, pos.y))
2048 root 1.196 continue;
2049    
2050 root 1.188 altern [index++] = i;
2051 elmex 1.1 }
2052 root 1.74
2053 root 1.24 if (!index)
2054     return -1;
2055 root 1.74
2056 root 1.124 return altern [rndm (index)];
2057 elmex 1.1 }
2058    
2059     /*
2060 root 1.49 * find_first_free_spot(archetype, maptile, x, y) works like
2061 elmex 1.1 * find_free_spot(), but it will search max number of squares.
2062     * But it will return the first available spot, not a random choice.
2063     * Changed 0.93.2: Have it return -1 if there is no free spot available.
2064     */
2065 root 1.24 int
2066 root 1.49 find_first_free_spot (const object *ob, maptile *m, int x, int y)
2067 root 1.24 {
2068 root 1.82 for (int i = 0; i < SIZEOFFREE; i++)
2069 root 1.188 if (!ob->blocked (m, x + freearr_x[i], y + freearr_y[i]))
2070 root 1.82 return i;
2071 root 1.24
2072     return -1;
2073 elmex 1.1 }
2074    
2075     /*
2076     * The function permute(arr, begin, end) randomly reorders the array
2077     * arr[begin..end-1].
2078 root 1.82 * now uses a fisher-yates shuffle, old permute was broken
2079 elmex 1.1 */
2080 root 1.24 static void
2081     permute (int *arr, int begin, int end)
2082 elmex 1.1 {
2083 root 1.82 arr += begin;
2084     end -= begin;
2085    
2086     while (--end)
2087 root 1.124 swap (arr [end], arr [rndm (end + 1)]);
2088 elmex 1.1 }
2089    
2090     /* new function to make monster searching more efficient, and effective!
2091     * This basically returns a randomized array (in the passed pointer) of
2092     * the spaces to find monsters. In this way, it won't always look for
2093     * monsters to the north first. However, the size of the array passed
2094     * covers all the spaces, so within that size, all the spaces within
2095     * the 3x3 area will be searched, just not in a predictable order.
2096     */
2097 root 1.24 void
2098     get_search_arr (int *search_arr)
2099 elmex 1.1 {
2100 root 1.82 int i;
2101 elmex 1.1
2102 root 1.24 for (i = 0; i < SIZEOFFREE; i++)
2103 root 1.82 search_arr[i] = i;
2104 elmex 1.1
2105 root 1.24 permute (search_arr, 1, SIZEOFFREE1 + 1);
2106     permute (search_arr, SIZEOFFREE1 + 1, SIZEOFFREE2 + 1);
2107     permute (search_arr, SIZEOFFREE2 + 1, SIZEOFFREE);
2108 elmex 1.1 }
2109    
2110     /*
2111     * find_dir(map, x, y, exclude) will search some close squares in the
2112     * given map at the given coordinates for live objects.
2113     * It will not considered the object given as exclude among possible
2114     * live objects.
2115     * It returns the direction toward the first/closest live object if finds
2116     * any, otherwise 0.
2117     * Perhaps incorrectly, but I'm making the assumption that exclude
2118     * is actually want is going to try and move there. We need this info
2119     * because we have to know what movement the thing looking to move
2120     * there is capable of.
2121     */
2122 root 1.24 int
2123 root 1.49 find_dir (maptile *m, int x, int y, object *exclude)
2124 root 1.24 {
2125 root 1.275 int max = SIZEOFFREE, mflags;
2126     MoveType move_type;
2127 root 1.24
2128 root 1.155 if (exclude && exclude->head_ () != exclude)
2129 root 1.24 {
2130     exclude = exclude->head;
2131     move_type = exclude->move_type;
2132     }
2133     else
2134     {
2135     /* If we don't have anything, presume it can use all movement types. */
2136     move_type = MOVE_ALL;
2137     }
2138    
2139 root 1.275 for (int i = 1; i < max; i++)
2140 root 1.24 {
2141 root 1.275 mapxy pos (m, x, y);
2142     pos.move (i);
2143 root 1.75
2144 root 1.275 if (!pos.normalise ())
2145 root 1.75 max = maxfree[i];
2146 root 1.24 else
2147     {
2148 root 1.275 mapspace &ms = *pos;
2149 root 1.82
2150 root 1.275 if ((move_type & ms.move_block) == move_type)
2151     max = maxfree [i];
2152     else if (ms.flags () & P_IS_ALIVE)
2153 root 1.24 {
2154 root 1.275 for (object *tmp = ms.bot; tmp; tmp = tmp->above)
2155 root 1.270 if ((tmp->flag [FLAG_MONSTER] || tmp->is_player ())
2156 root 1.155 && (tmp != exclude || (tmp->head_ () != tmp && tmp->head_ () != exclude)))
2157 root 1.275 return freedir [i];
2158 root 1.8 }
2159     }
2160 elmex 1.1 }
2161 root 1.75
2162 root 1.24 return 0;
2163 elmex 1.1 }
2164    
2165     /*
2166     * distance(object 1, object 2) will return the square of the
2167     * distance between the two given objects.
2168     */
2169 root 1.24 int
2170     distance (const object *ob1, const object *ob2)
2171     {
2172 root 1.82 return (ob1->x - ob2->x) * (ob1->x - ob2->x) + (ob1->y - ob2->y) * (ob1->y - ob2->y);
2173 elmex 1.1 }
2174    
2175     /*
2176     * find_dir_2(delta-x,delta-y) will return a direction in which
2177     * an object which has subtracted the x and y coordinates of another
2178     * object, needs to travel toward it.
2179     */
2180 root 1.24 int
2181     find_dir_2 (int x, int y)
2182     {
2183 root 1.75 int q;
2184 elmex 1.1
2185 root 1.24 if (y)
2186     q = x * 100 / y;
2187 elmex 1.1 else if (x)
2188 root 1.24 q = -300 * x;
2189 elmex 1.1 else
2190     return 0;
2191    
2192 root 1.24 if (y > 0)
2193     {
2194     if (q < -242)
2195     return 3;
2196     if (q < -41)
2197     return 2;
2198     if (q < 41)
2199     return 1;
2200     if (q < 242)
2201     return 8;
2202     return 7;
2203     }
2204 elmex 1.1
2205     if (q < -242)
2206 root 1.24 return 7;
2207 elmex 1.1 if (q < -41)
2208 root 1.24 return 6;
2209 elmex 1.1 if (q < 41)
2210 root 1.24 return 5;
2211 elmex 1.1 if (q < 242)
2212 root 1.24 return 4;
2213 elmex 1.1
2214 root 1.24 return 3;
2215 elmex 1.1 }
2216    
2217     /*
2218     * dirdiff(dir1, dir2) returns how many 45-degrees differences there is
2219     * between two directions (which are expected to be absolute (see absdir())
2220     */
2221 root 1.24 int
2222     dirdiff (int dir1, int dir2)
2223     {
2224 root 1.82 int d;
2225 root 1.24
2226     d = abs (dir1 - dir2);
2227     if (d > 4)
2228 elmex 1.1 d = 8 - d;
2229 root 1.82
2230 elmex 1.1 return d;
2231     }
2232    
2233     /* peterm:
2234     * do LOS stuff for ball lightning. Go after the closest VISIBLE monster.
2235     * Basically, this is a table of directions, and what directions
2236     * one could go to go back to us. Eg, entry 15 below is 4, 14, 16.
2237     * This basically means that if direction is 15, then it could either go
2238     * direction 4, 14, or 16 to get back to where we are.
2239     * Moved from spell_util.c to object.c with the other related direction
2240     * functions.
2241     */
2242 root 1.295 static const int reduction_dir[SIZEOFFREE][3] = {
2243 root 1.24 {0, 0, 0}, /* 0 */
2244     {0, 0, 0}, /* 1 */
2245     {0, 0, 0}, /* 2 */
2246     {0, 0, 0}, /* 3 */
2247     {0, 0, 0}, /* 4 */
2248     {0, 0, 0}, /* 5 */
2249     {0, 0, 0}, /* 6 */
2250     {0, 0, 0}, /* 7 */
2251     {0, 0, 0}, /* 8 */
2252     {8, 1, 2}, /* 9 */
2253     {1, 2, -1}, /* 10 */
2254     {2, 10, 12}, /* 11 */
2255     {2, 3, -1}, /* 12 */
2256     {2, 3, 4}, /* 13 */
2257     {3, 4, -1}, /* 14 */
2258     {4, 14, 16}, /* 15 */
2259     {5, 4, -1}, /* 16 */
2260     {4, 5, 6}, /* 17 */
2261     {6, 5, -1}, /* 18 */
2262     {6, 20, 18}, /* 19 */
2263     {7, 6, -1}, /* 20 */
2264     {6, 7, 8}, /* 21 */
2265     {7, 8, -1}, /* 22 */
2266     {8, 22, 24}, /* 23 */
2267     {8, 1, -1}, /* 24 */
2268     {24, 9, 10}, /* 25 */
2269     {9, 10, -1}, /* 26 */
2270     {10, 11, -1}, /* 27 */
2271     {27, 11, 29}, /* 28 */
2272     {11, 12, -1}, /* 29 */
2273     {12, 13, -1}, /* 30 */
2274     {12, 13, 14}, /* 31 */
2275     {13, 14, -1}, /* 32 */
2276     {14, 15, -1}, /* 33 */
2277     {33, 15, 35}, /* 34 */
2278     {16, 15, -1}, /* 35 */
2279     {17, 16, -1}, /* 36 */
2280     {18, 17, 16}, /* 37 */
2281     {18, 17, -1}, /* 38 */
2282     {18, 19, -1}, /* 39 */
2283     {41, 19, 39}, /* 40 */
2284     {19, 20, -1}, /* 41 */
2285     {20, 21, -1}, /* 42 */
2286     {20, 21, 22}, /* 43 */
2287     {21, 22, -1}, /* 44 */
2288     {23, 22, -1}, /* 45 */
2289     {45, 47, 23}, /* 46 */
2290     {23, 24, -1}, /* 47 */
2291     {24, 9, -1}
2292     }; /* 48 */
2293 elmex 1.1
2294     /* Recursive routine to step back and see if we can
2295     * find a path to that monster that we found. If not,
2296     * we don't bother going toward it. Returns 1 if we
2297     * can see a direct way to get it
2298     * Modified to be map tile aware -.MSW
2299     */
2300 root 1.24 int
2301 root 1.49 can_see_monsterP (maptile *m, int x, int y, int dir)
2302 root 1.24 {
2303 root 1.29 sint16 dx, dy;
2304 root 1.75 int mflags;
2305 root 1.24
2306     if (dir < 0)
2307     return 0; /* exit condition: invalid direction */
2308    
2309     dx = x + freearr_x[dir];
2310     dy = y + freearr_y[dir];
2311    
2312     mflags = get_map_flags (m, &m, dx, dy, &dx, &dy);
2313    
2314     /* This functional arguably was incorrect before - it was
2315     * checking for P_WALL - that was basically seeing if
2316     * we could move to the monster - this is being more
2317     * literal on if we can see it. To know if we can actually
2318     * move to the monster, we'd need the monster passed in or
2319     * at least its move type.
2320     */
2321     if (mflags & (P_OUT_OF_MAP | P_BLOCKSVIEW))
2322     return 0;
2323    
2324     /* yes, can see. */
2325     if (dir < 9)
2326     return 1;
2327 root 1.75
2328     return can_see_monsterP (m, x, y, reduction_dir[dir][0])
2329     | can_see_monsterP (m, x, y, reduction_dir[dir][1])
2330     | can_see_monsterP (m, x, y, reduction_dir[dir][2]);
2331 root 1.24 }
2332    
2333 elmex 1.1 /*
2334     * can_pick(picker, item): finds out if an object is possible to be
2335     * picked up by the picker. Returnes 1 if it can be
2336     * picked up, otherwise 0.
2337     *
2338     * Cf 0.91.3 - don't let WIZ's pick up anything - will likely cause
2339     * core dumps if they do.
2340     *
2341     * Add a check so we can't pick up invisible objects (0.93.8)
2342     */
2343 root 1.24 int
2344     can_pick (const object *who, const object *item)
2345     {
2346     return /*QUERY_FLAG(who,FLAG_WIZ)|| */
2347     (item->weight > 0 && !QUERY_FLAG (item, FLAG_NO_PICK) &&
2348 root 1.270 !QUERY_FLAG (item, FLAG_ALIVE) && !item->invisible && (who->is_player () || item->weight < who->weight / 3));
2349 elmex 1.1 }
2350    
2351     /*
2352     * create clone from object to another
2353     */
2354 root 1.24 object *
2355 root 1.230 object::deep_clone ()
2356 root 1.24 {
2357 root 1.230 assert (("deep_clone called on non-head object", is_head ()));
2358 elmex 1.1
2359 root 1.230 object *dst = clone ();
2360 root 1.24
2361 root 1.230 object *prev = dst;
2362     for (object *part = this->more; part; part = part->more)
2363 root 1.24 {
2364 root 1.224 object *tmp = part->clone ();
2365 root 1.230 tmp->head = dst;
2366     prev->more = tmp;
2367 root 1.24 prev = tmp;
2368 elmex 1.1 }
2369 root 1.24
2370 root 1.230 for (object *item = inv; item; item = item->below)
2371     insert_ob_in_ob (item->deep_clone (), dst);
2372 elmex 1.1
2373 root 1.24 return dst;
2374 elmex 1.1 }
2375    
2376     /* This returns the first object in who's inventory that
2377     * has the same type and subtype match.
2378     * returns NULL if no match.
2379     */
2380 root 1.24 object *
2381     find_obj_by_type_subtype (const object *who, int type, int subtype)
2382 elmex 1.1 {
2383 root 1.82 for (object *tmp = who->inv; tmp; tmp = tmp->below)
2384 root 1.24 if (tmp->type == type && tmp->subtype == subtype)
2385     return tmp;
2386 elmex 1.1
2387 root 1.82 return 0;
2388 elmex 1.1 }
2389    
2390 root 1.276 shstr_tmp
2391     object::kv_get (shstr_tmp key) const
2392 root 1.24 {
2393 root 1.228 for (key_value *kv = key_values; kv; kv = kv->next)
2394     if (kv->key == key)
2395     return kv->value;
2396 root 1.24
2397 root 1.276 return shstr ();
2398 root 1.24 }
2399 elmex 1.1
2400 root 1.228 void
2401 root 1.276 object::kv_set (shstr_tmp key, shstr_tmp value)
2402 root 1.24 {
2403 root 1.228 for (key_value *kv = key_values; kv; kv = kv->next)
2404     if (kv->key == key)
2405     {
2406     kv->value = value;
2407     return;
2408     }
2409 root 1.24
2410 root 1.228 key_value *kv = new key_value;
2411 elmex 1.1
2412 root 1.228 kv->next = key_values;
2413     kv->key = key;
2414     kv->value = value;
2415 root 1.35
2416 root 1.228 key_values = kv;
2417 elmex 1.1 }
2418    
2419 root 1.228 void
2420 root 1.276 object::kv_del (shstr_tmp key)
2421 root 1.24 {
2422 root 1.228 for (key_value **kvp = &key_values; *kvp; kvp = &(*kvp)->next)
2423     if ((*kvp)->key == key)
2424     {
2425     key_value *kv = *kvp;
2426     *kvp = (*kvp)->next;
2427     delete kv;
2428     return;
2429     }
2430 elmex 1.1 }
2431 root 1.31
2432 root 1.34 object::depth_iterator::depth_iterator (object *container)
2433     : iterator_base (container)
2434     {
2435     while (item->inv)
2436     item = item->inv;
2437     }
2438    
2439 root 1.31 void
2440 root 1.34 object::depth_iterator::next ()
2441 root 1.31 {
2442 root 1.34 if (item->below)
2443     {
2444     item = item->below;
2445    
2446     while (item->inv)
2447     item = item->inv;
2448     }
2449 root 1.31 else
2450 root 1.34 item = item->env;
2451 root 1.31 }
2452 root 1.34
2453 elmex 1.97 const char *
2454     object::flag_desc (char *desc, int len) const
2455     {
2456     char *p = desc;
2457     bool first = true;
2458    
2459 root 1.101 *p = 0;
2460    
2461 elmex 1.97 for (int i = 0; i < NUM_FLAGS; i++)
2462     {
2463     if (len <= 10) // magic constant!
2464     {
2465     snprintf (p, len, ",...");
2466     break;
2467     }
2468    
2469 root 1.101 if (flag [i])
2470 elmex 1.97 {
2471     int cnt = snprintf (p, len, "%s%d", first ? "" : ",", i);
2472     len -= cnt;
2473     p += cnt;
2474     first = false;
2475     }
2476     }
2477    
2478     return desc;
2479     }
2480    
2481 root 1.101 // return a suitable string describing an object in enough detail to find it
2482 root 1.36 const char *
2483     object::debug_desc (char *info) const
2484     {
2485 elmex 1.97 char flagdesc[512];
2486     char info2[256 * 4];
2487 root 1.36 char *p = info;
2488    
2489 elmex 1.242 p += snprintf (p, 512, "{cnt:%d,uuid:%s,name:\"%s\"%s%s%s,flags:[%s],type:%d}",
2490 root 1.203 count,
2491     uuid.c_str (),
2492 root 1.36 &name,
2493 elmex 1.242 title ? ",title:\"" : "",
2494 elmex 1.97 title ? (const char *)title : "",
2495 elmex 1.242 title ? "\"" : "",
2496 elmex 1.97 flag_desc (flagdesc, 512), type);
2497 root 1.36
2498 root 1.217 if (!flag[FLAG_REMOVED] && env)
2499 root 1.36 p += snprintf (p, 256, "(in %s)", env->debug_desc (info2));
2500    
2501     if (map)
2502 root 1.96 p += snprintf (p, 256, "(on %s@%d+%d)", &map->path, x, y);
2503 root 1.36
2504     return info;
2505     }
2506    
2507     const char *
2508     object::debug_desc () const
2509     {
2510 root 1.143 static char info[3][256 * 4];
2511     static int info_idx;
2512 root 1.36
2513 root 1.143 return debug_desc (info [++info_idx % 3]);
2514 root 1.114 }
2515    
2516 root 1.125 struct region *
2517     object::region () const
2518     {
2519     return map ? map->region (x, y)
2520     : region::default_region ();
2521     }
2522    
2523 root 1.130 void
2524     object::open_container (object *new_container)
2525     {
2526     if (container == new_container)
2527     return;
2528    
2529 root 1.220 object *old_container = container;
2530    
2531     if (old_container)
2532 root 1.130 {
2533     if (INVOKE_OBJECT (CLOSE, old_container, ARG_OBJECT (this)))
2534     return;
2535    
2536     #if 0
2537     // remove the "Close old_container" object.
2538     if (object *closer = old_container->inv)
2539     if (closer->type == CLOSE_CON)
2540 root 1.259 closer->destroy ();
2541 root 1.130 #endif
2542    
2543 root 1.220 // make sure the container is available
2544     esrv_send_item (this, old_container);
2545    
2546 root 1.216 old_container->flag [FLAG_APPLIED] = false;
2547 root 1.130 container = 0;
2548    
2549 root 1.220 // client needs item update to make it work, client bug requires this to be separate
2550 root 1.130 esrv_update_item (UPD_FLAGS, this, old_container);
2551 root 1.220
2552 root 1.281 new_draw_info_format (NDI_UNIQUE, 0, this, "You close %s.", old_container->query_name ());
2553 root 1.177 play_sound (sound_find ("chest_close"));
2554 root 1.130 }
2555    
2556     if (new_container)
2557     {
2558     if (INVOKE_OBJECT (OPEN, new_container, ARG_OBJECT (this)))
2559     return;
2560    
2561     // TODO: this does not seem to serve any purpose anymore?
2562     #if 0
2563     // insert the "Close Container" object.
2564     if (archetype *closer = new_container->other_arch)
2565     {
2566     object *closer = arch_to_object (new_container->other_arch);
2567     closer->flag [FLAG_NO_MAP_SAVE] = 1;
2568     new_container->insert (closer);
2569     }
2570     #endif
2571    
2572 root 1.281 new_draw_info_format (NDI_UNIQUE, 0, this, "You open %s.", new_container->query_name ());
2573 root 1.132
2574 root 1.220 // make sure the container is available, client bug requires this to be separate
2575     esrv_send_item (this, new_container);
2576    
2577 root 1.216 new_container->flag [FLAG_APPLIED] = true;
2578 root 1.130 container = new_container;
2579    
2580 root 1.220 // client needs flag change
2581 root 1.130 esrv_update_item (UPD_FLAGS, this, new_container);
2582 root 1.131 esrv_send_inventory (this, new_container);
2583 root 1.177 play_sound (sound_find ("chest_open"));
2584 root 1.130 }
2585 root 1.220 // else if (!old_container->env && contr && contr->ns)
2586     // contr->ns->floorbox_reset ();
2587 root 1.130 }
2588    
2589 root 1.164 object *
2590 root 1.276 object::force_find (shstr_tmp name)
2591 root 1.164 {
2592     /* cycle through his inventory to look for the MARK we want to
2593     * place
2594     */
2595     for (object *tmp = inv; tmp; tmp = tmp->below)
2596     if (tmp->type == FORCE && tmp->slaying == name)
2597     return splay (tmp);
2598    
2599     return 0;
2600     }
2601    
2602 root 1.294 //-GPL
2603    
2604 sf-marcmagus 1.290 void
2605     object::force_set_timer (int duration)
2606     {
2607     this->duration = 1;
2608     this->speed_left = -1.f;
2609    
2610     this->set_speed (duration ? 1.f / duration : 0.f);
2611     }
2612    
2613 root 1.265 object *
2614 root 1.276 object::force_add (shstr_tmp name, int duration)
2615 root 1.164 {
2616     if (object *force = force_find (name))
2617 root 1.259 force->destroy ();
2618 root 1.164
2619     object *force = get_archetype (FORCE_NAME);
2620    
2621 sf-marcmagus 1.290 force->slaying = name;
2622     force->force_set_timer (duration);
2623 root 1.294 force->flag [FLAG_APPLIED] = true;
2624 root 1.164
2625 root 1.265 return insert (force);
2626 root 1.164 }
2627    
2628 root 1.178 void
2629 root 1.280 object::play_sound (faceidx sound) const
2630 root 1.178 {
2631     if (!sound)
2632     return;
2633    
2634 root 1.280 if (is_on_map ())
2635     map->play_sound (sound, x, y);
2636     else if (object *pl = in_player ())
2637     pl->contr->play_sound (sound);
2638     }
2639 root 1.178
2640 root 1.280 void
2641     object::say_msg (const char *msg) const
2642     {
2643     if (is_on_map ())
2644     map->say_msg (msg, x, y);
2645     else if (object *pl = in_player ())
2646     pl->contr->play_sound (sound);
2647 root 1.178 }
2648    
2649 root 1.265 void
2650     object::make_noise ()
2651     {
2652     // we do not model noise in the map, so instead put
2653     // a temporary light into the noise source
2654     // could use the map instead, but that's less reliable for our
2655     // goal, which is to make invisibility a bit harder to exploit
2656    
2657 root 1.266 // currently only works sensibly for players
2658     if (!is_player ())
2659     return;
2660    
2661 root 1.265 // find old force, or create new one
2662     object *force = force_find (shstr_noise_force);
2663    
2664     if (force)
2665 root 1.269 force->speed_left = -1.f; // patch old speed up
2666 root 1.265 else
2667 root 1.269 {
2668     force = archetype::get (shstr_noise_force);
2669    
2670     force->slaying = shstr_noise_force;
2671     force->stats.food = 1;
2672     force->speed_left = -1.f;
2673    
2674     force->set_speed (1.f / 4.f);
2675     force->flag [FLAG_IS_USED_UP] = true;
2676     force->flag [FLAG_APPLIED] = true;
2677    
2678     insert (force);
2679     }
2680 root 1.265 }
2681