ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/object.C
Revision: 1.282
Committed: Tue Feb 17 03:53:31 2009 UTC (15 years, 3 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.281: +5 -2 lines
Log Message:
indent

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