ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/object.C
Revision: 1.292
Committed: Mon Oct 19 21:48:49 2009 UTC (14 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.291: +5 -5 lines
Log Message:
*** empty log message ***

File Contents

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