ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/object.C
Revision: 1.301
Committed: Mon Nov 9 18:47:56 2009 UTC (14 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.300: +2 -3 lines
Log Message:
remove max_nrof from maps, make spell updates delayed

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