ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/object.C
Revision: 1.214
Committed: Tue Apr 22 07:01:46 2008 UTC (16 years, 1 month ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.213: +57 -50 lines
Log Message:
see Changes

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