ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/object.C
Revision: 1.286
Committed: Wed Sep 2 16:54:20 2009 UTC (14 years, 8 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_80
Changes since 1.285: +6 -4 lines
Log Message:
*** empty log message ***

File Contents

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