ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/object.C
Revision: 1.293
Committed: Wed Oct 21 00:44:39 2009 UTC (14 years, 7 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_82
Changes since 1.292: +12 -20 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.213 if (flag [FLAG_REMOVED])
1047 root 1.29 return;
1048 root 1.24
1049 root 1.82 INVOKE_OBJECT (REMOVE, this);
1050 root 1.26
1051 root 1.213 flag [FLAG_REMOVED] = true;
1052    
1053 root 1.59 if (more)
1054     more->remove ();
1055 root 1.24
1056     /*
1057     * In this case, the object to be removed is in someones
1058     * inventory.
1059     */
1060 root 1.59 if (env)
1061 root 1.24 {
1062 root 1.221 flag [FLAG_REMOVED] = false; // hack around the issue of visible_to checking flag_removed
1063 root 1.220 if (object *pl = visible_to ())
1064     esrv_del_item (pl->contr, count);
1065 root 1.221 flag [FLAG_REMOVED] = true; // hack around the issue of visible_to checking flag_removed
1066 root 1.220
1067 root 1.208 adjust_weight (env, -total_weight ());
1068 root 1.24
1069 root 1.265 object *pl = in_player ();
1070    
1071 root 1.237 /* we set up values so that it could be inserted into
1072     * the map, but we don't actually do that - it is up
1073     * to the caller to decide what we want to do.
1074     */
1075     map = env->map;
1076     x = env->x;
1077     y = env->y;
1078    
1079 root 1.236 // make sure cmov optimisation is applicable
1080 root 1.208 *(above ? &above->below : &env->inv) = below;
1081 root 1.236 *(below ? &below->above : &above ) = above; // &above is just a dummy
1082 root 1.24
1083 root 1.236 above = 0;
1084     below = 0;
1085     env = 0;
1086 root 1.24
1087 root 1.208 /* NO_FIX_PLAYER is set when a great many changes are being
1088     * made to players inventory. If set, avoiding the call
1089     * to save cpu time.
1090     */
1091 root 1.265 if (pl)
1092 root 1.267 if (pl->is_player () && (glow_radius || !QUERY_FLAG (pl, FLAG_NO_FIX_PLAYER)))
1093 root 1.265 {
1094     pl->update_stats ();
1095    
1096 root 1.270 if (glow_radius && pl->is_on_map ())
1097 root 1.265 update_all_los (pl->map, pl->x, pl->y);
1098     }
1099 root 1.59 }
1100     else if (map)
1101     {
1102 root 1.220 map->dirty = true;
1103     mapspace &ms = this->ms ();
1104    
1105     if (object *pl = ms.player ())
1106 root 1.96 {
1107 root 1.270 if (is_player ())
1108 root 1.220 {
1109 root 1.273 if (!flag [FLAG_WIZPASS])
1110     ms.smell = ++mapspace::smellcount; // remember the smell of the player
1111 root 1.270
1112 root 1.220 // leaving a spot always closes any open container on the ground
1113     if (container && !container->env)
1114     // this causes spurious floorbox updates, but it ensures
1115     // that the CLOSE event is being sent.
1116     close_container ();
1117    
1118     --map->players;
1119     map->touch ();
1120     }
1121 root 1.292 else if (pl->container_ () == this)
1122 root 1.220 {
1123     // removing a container should close it
1124     close_container ();
1125     }
1126 root 1.130
1127 root 1.220 esrv_del_item (pl->contr, count);
1128 root 1.96 }
1129    
1130 root 1.29 /* link the object above us */
1131 root 1.236 // re-link, make sure compiler can easily use cmove
1132     *(above ? &above->below : &ms.top) = below;
1133     *(below ? &below->above : &ms.bot) = above;
1134 root 1.26
1135 root 1.59 above = 0;
1136     below = 0;
1137 root 1.26
1138 root 1.265 ms.invalidate ();
1139 root 1.253
1140 root 1.59 if (map->in_memory == MAP_SAVING)
1141 root 1.29 return;
1142 elmex 1.1
1143 root 1.82 int check_walk_off = !flag [FLAG_NO_APPLY];
1144 elmex 1.1
1145 root 1.175 if (object *pl = ms.player ())
1146     {
1147 root 1.292 if (pl->container_ () == this)
1148 root 1.175 /* If a container that the player is currently using somehow gets
1149     * removed (most likely destroyed), update the player view
1150     * appropriately.
1151     */
1152     pl->close_container ();
1153    
1154 root 1.218 //TODO: the floorbox prev/next might need updating
1155 root 1.226 //esrv_del_item (pl->contr, count);
1156     //TODO: update floorbox to preserve ordering
1157     if (pl->contr->ns)
1158     pl->contr->ns->floorbox_update ();
1159 root 1.175 }
1160    
1161 root 1.293 if (check_walk_off)
1162     for (object *above, *tmp = ms.bot; tmp; tmp = above)
1163     {
1164     above = tmp->above;
1165    
1166     /* No point updating the players look faces if he is the object
1167     * being removed.
1168     */
1169 root 1.29
1170 root 1.293 /* See if object moving off should effect something */
1171     if ((move_type & tmp->move_off)
1172     && (move_type & ~tmp->move_off & ~tmp->move_block) == 0)
1173 elmex 1.72 move_apply (tmp, this, 0);
1174 root 1.293 }
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.287 if (!(flag & INS_NO_WALK_ON) && op->is_head ())
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.287 if (QUERY_FLAG (op, FLAG_NO_APPLY))
1710     return 0;
1711    
1712 root 1.48 object *tmp;
1713 root 1.49 maptile *m = op->map;
1714 root 1.48 int x = op->x, y = op->y;
1715 root 1.26
1716 root 1.287 mapspace &ms = m->at (x, y);
1717 root 1.24
1718 root 1.287 ms.update ();
1719 root 1.24
1720 root 1.287 MoveType move_on = ms.move_on;
1721     MoveType move_slow = ms.move_slow;
1722     MoveType move_block = ms.move_block;
1723 root 1.24
1724     /* if nothing on this space will slow op down or be applied,
1725     * no need to do checking below. have to make sure move_type
1726     * is set, as lots of objects don't have it set - we treat that
1727     * as walking.
1728     */
1729     if (op->move_type && !(op->move_type & move_on) && !(op->move_type & move_slow))
1730     return 0;
1731 elmex 1.1
1732 root 1.24 /* This is basically inverse logic of that below - basically,
1733     * if the object can avoid the move on or slow move, they do so,
1734     * but can't do it if the alternate movement they are using is
1735     * blocked. Logic on this seems confusing, but does seem correct.
1736     */
1737     if ((op->move_type & ~move_on & ~move_block) != 0 && (op->move_type & ~move_slow & ~move_block) != 0)
1738     return 0;
1739    
1740     /* The objects have to be checked from top to bottom.
1741     * Hence, we first go to the top:
1742     */
1743 root 1.287 for (object *next, *tmp = ms.top; tmp; tmp = next)
1744 root 1.24 {
1745 root 1.287 next = tmp->below;
1746 root 1.26
1747 root 1.24 if (tmp == op)
1748     continue; /* Can't apply yourself */
1749 elmex 1.1
1750 root 1.24 /* Check to see if one of the movement types should be slowed down.
1751     * Second check makes sure that the movement types not being slowed
1752     * (~slow_move) is not blocked on this space - just because the
1753     * space doesn't slow down swimming (for example), if you can't actually
1754     * swim on that space, can't use it to avoid the penalty.
1755     */
1756     if (!QUERY_FLAG (op, FLAG_WIZPASS))
1757     {
1758     if ((!op->move_type && tmp->move_slow & MOVE_WALK) ||
1759     ((op->move_type & tmp->move_slow) && (op->move_type & ~tmp->move_slow & ~tmp->move_block) == 0))
1760     {
1761 root 1.287 float diff = tmp->move_slow_penalty * fabs (op->speed);
1762 elmex 1.1
1763 root 1.270 if (op->is_player ())
1764 root 1.287 if ((tmp->flag [FLAG_IS_HILLY ] && find_skill_by_number (op, SK_CLIMBING)) ||
1765     (tmp->flag [FLAG_IS_WOODED] && find_skill_by_number (op, SK_WOODSMAN)))
1766 root 1.26 diff /= 4.0;
1767    
1768 root 1.24 op->speed_left -= diff;
1769 root 1.8 }
1770     }
1771 elmex 1.1
1772 root 1.24 /* Basically same logic as above, except now for actual apply. */
1773     if ((!op->move_type && tmp->move_on & MOVE_WALK) ||
1774     ((op->move_type & tmp->move_on) && (op->move_type & ~tmp->move_on & ~tmp->move_block) == 0))
1775     {
1776 elmex 1.72 move_apply (tmp, op, originator);
1777 root 1.24
1778 root 1.48 if (op->destroyed ())
1779 root 1.24 return 1;
1780    
1781     /* what the person/creature stepped onto has moved the object
1782     * someplace new. Don't process any further - if we did,
1783     * have a feeling strange problems would result.
1784     */
1785     if (op->map != m || op->x != x || op->y != y)
1786     return 0;
1787 root 1.8 }
1788 elmex 1.1 }
1789 root 1.26
1790 root 1.24 return 0;
1791 elmex 1.1 }
1792    
1793     /*
1794     * present_arch(arch, map, x, y) searches for any objects with
1795     * a matching archetype at the given map and coordinates.
1796     * The first matching object is returned, or NULL if none.
1797     */
1798 root 1.24 object *
1799 root 1.49 present_arch (const archetype *at, maptile *m, int x, int y)
1800 root 1.24 {
1801 root 1.104 if (!m || out_of_map (m, x, y))
1802 root 1.24 {
1803     LOG (llevError, "Present_arch called outside map.\n");
1804     return NULL;
1805     }
1806 root 1.84
1807 root 1.104 for (object *tmp = m->at (x, y).bot; tmp; tmp = tmp->above)
1808 root 1.231 if (tmp->arch->archname == at->archname)
1809 elmex 1.1 return tmp;
1810 root 1.84
1811 elmex 1.1 return NULL;
1812     }
1813    
1814     /*
1815     * present(type, map, x, y) searches for any objects with
1816     * a matching type variable at the given map and coordinates.
1817     * The first matching object is returned, or NULL if none.
1818     */
1819 root 1.24 object *
1820 root 1.49 present (unsigned char type, maptile *m, int x, int y)
1821 root 1.24 {
1822     if (out_of_map (m, x, y))
1823     {
1824     LOG (llevError, "Present called outside map.\n");
1825     return NULL;
1826     }
1827 root 1.84
1828 root 1.104 for (object *tmp = m->at (x, y).bot; tmp; tmp = tmp->above)
1829 root 1.24 if (tmp->type == type)
1830 elmex 1.1 return tmp;
1831 root 1.84
1832 elmex 1.1 return NULL;
1833     }
1834    
1835     /*
1836     * present_in_ob(type, object) searches for any objects with
1837     * a matching type variable in the inventory of the given object.
1838     * The first matching object is returned, or NULL if none.
1839     */
1840 root 1.24 object *
1841     present_in_ob (unsigned char type, const object *op)
1842     {
1843 root 1.84 for (object *tmp = op->inv; tmp != NULL; tmp = tmp->below)
1844 root 1.24 if (tmp->type == type)
1845 elmex 1.1 return tmp;
1846 root 1.84
1847 elmex 1.1 return NULL;
1848     }
1849    
1850     /*
1851     * present_in_ob (type, str, object) searches for any objects with
1852     * a matching type & name variable in the inventory of the given object.
1853     * The first matching object is returned, or NULL if none.
1854     * This is mostly used by spell effect code, so that we only
1855     * have one spell effect at a time.
1856     * type can be used to narrow the search - if type is set,
1857     * the type must also match. -1 can be passed for the type,
1858     * in which case the type does not need to pass.
1859     * str is the string to match against. Note that we match against
1860     * the object name, not the archetype name. this is so that the
1861     * spell code can use one object type (force), but change it's name
1862     * to be unique.
1863     */
1864 root 1.24 object *
1865     present_in_ob_by_name (int type, const char *str, const object *op)
1866     {
1867 root 1.84 for (object *tmp = op->inv; tmp; tmp = tmp->below)
1868 root 1.82 if ((type == -1 || tmp->type == type) && (!strcmp (str, tmp->name)))
1869     return tmp;
1870 elmex 1.1
1871 root 1.82 return 0;
1872 elmex 1.1 }
1873    
1874     /*
1875     * present_arch_in_ob(archetype, object) searches for any objects with
1876     * a matching archetype in the inventory of the given object.
1877     * The first matching object is returned, or NULL if none.
1878     */
1879 root 1.24 object *
1880     present_arch_in_ob (const archetype *at, const object *op)
1881     {
1882 root 1.231 for (object *tmp = op->inv; tmp; tmp = tmp->below)
1883     if (tmp->arch->archname == at->archname)
1884 elmex 1.1 return tmp;
1885 root 1.82
1886 elmex 1.1 return NULL;
1887     }
1888    
1889     /*
1890     * activate recursively a flag on an object inventory
1891     */
1892 root 1.24 void
1893     flag_inv (object *op, int flag)
1894     {
1895 root 1.197 for (object *tmp = op->inv; tmp; tmp = tmp->below)
1896     {
1897     SET_FLAG (tmp, flag);
1898     flag_inv (tmp, flag);
1899     }
1900 root 1.82 }
1901    
1902     /*
1903     * deactivate recursively a flag on an object inventory
1904     */
1905 root 1.24 void
1906     unflag_inv (object *op, int flag)
1907     {
1908 root 1.197 for (object *tmp = op->inv; tmp; tmp = tmp->below)
1909     {
1910     CLEAR_FLAG (tmp, flag);
1911     unflag_inv (tmp, flag);
1912     }
1913 elmex 1.1 }
1914    
1915     /*
1916     * find_free_spot(object, map, x, y, start, stop) will search for
1917     * a spot at the given map and coordinates which will be able to contain
1918     * the given object. start and stop specifies how many squares
1919     * to search (see the freearr_x/y[] definition).
1920     * It returns a random choice among the alternatives found.
1921     * start and stop are where to start relative to the free_arr array (1,9
1922     * does all 4 immediate directions). This returns the index into the
1923     * array of the free spot, -1 if no spot available (dir 0 = x,y)
1924 root 1.196 * Note: This function does correctly handle tiled maps, but does not
1925 elmex 1.1 * inform the caller. However, insert_ob_in_map will update as
1926     * necessary, so the caller shouldn't need to do any special work.
1927     * Note - updated to take an object instead of archetype - this is necessary
1928     * because arch_blocked (now ob_blocked) needs to know the movement type
1929     * to know if the space in question will block the object. We can't use
1930     * the archetype because that isn't correct if the monster has been
1931     * customized, changed states, etc.
1932     */
1933 root 1.24 int
1934 root 1.49 find_free_spot (const object *ob, maptile *m, int x, int y, int start, int stop)
1935 root 1.24 {
1936 root 1.190 int altern[SIZEOFFREE];
1937 root 1.82 int index = 0, flag;
1938 root 1.24
1939 root 1.82 for (int i = start; i < stop; i++)
1940 root 1.24 {
1941 root 1.188 mapxy pos (m, x, y); pos.move (i);
1942    
1943     if (!pos.normalise ())
1944     continue;
1945    
1946     mapspace &ms = *pos;
1947 root 1.189
1948     if (ms.flags () & P_IS_ALIVE)
1949     continue;
1950 root 1.188
1951     /* However, often
1952     * ob doesn't have any move type (when used to place exits)
1953     * so the AND operation in OB_TYPE_MOVE_BLOCK doesn't work.
1954     */
1955 root 1.200 if (ob && ob->move_type == 0 && ms.move_block != MOVE_ALL)
1956 root 1.190 {
1957     altern [index++] = i;
1958     continue;
1959     }
1960 root 1.24
1961     /* Basically, if we find a wall on a space, we cut down the search size.
1962     * In this way, we won't return spaces that are on another side of a wall.
1963     * This mostly work, but it cuts down the search size in all directions -
1964     * if the space being examined only has a wall to the north and empty
1965     * spaces in all the other directions, this will reduce the search space
1966     * to only the spaces immediately surrounding the target area, and
1967     * won't look 2 spaces south of the target space.
1968     */
1969 root 1.188 if (ms.move_block == MOVE_ALL && maxfree[i] < stop)
1970     {
1971     stop = maxfree[i];
1972     continue;
1973     }
1974    
1975     /* Note it is intentional that we check ob - the movement type of the
1976     * head of the object should correspond for the entire object.
1977     */
1978     if (OB_TYPE_MOVE_BLOCK (ob, ms.move_block))
1979     continue;
1980    
1981 elmex 1.262 if (ob->blocked (pos.m, pos.x, pos.y))
1982 root 1.196 continue;
1983    
1984 root 1.188 altern [index++] = i;
1985 elmex 1.1 }
1986 root 1.74
1987 root 1.24 if (!index)
1988     return -1;
1989 root 1.74
1990 root 1.124 return altern [rndm (index)];
1991 elmex 1.1 }
1992    
1993     /*
1994 root 1.49 * find_first_free_spot(archetype, maptile, x, y) works like
1995 elmex 1.1 * find_free_spot(), but it will search max number of squares.
1996     * But it will return the first available spot, not a random choice.
1997     * Changed 0.93.2: Have it return -1 if there is no free spot available.
1998     */
1999 root 1.24 int
2000 root 1.49 find_first_free_spot (const object *ob, maptile *m, int x, int y)
2001 root 1.24 {
2002 root 1.82 for (int i = 0; i < SIZEOFFREE; i++)
2003 root 1.188 if (!ob->blocked (m, x + freearr_x[i], y + freearr_y[i]))
2004 root 1.82 return i;
2005 root 1.24
2006     return -1;
2007 elmex 1.1 }
2008    
2009     /*
2010     * The function permute(arr, begin, end) randomly reorders the array
2011     * arr[begin..end-1].
2012 root 1.82 * now uses a fisher-yates shuffle, old permute was broken
2013 elmex 1.1 */
2014 root 1.24 static void
2015     permute (int *arr, int begin, int end)
2016 elmex 1.1 {
2017 root 1.82 arr += begin;
2018     end -= begin;
2019    
2020     while (--end)
2021 root 1.124 swap (arr [end], arr [rndm (end + 1)]);
2022 elmex 1.1 }
2023    
2024     /* new function to make monster searching more efficient, and effective!
2025     * This basically returns a randomized array (in the passed pointer) of
2026     * the spaces to find monsters. In this way, it won't always look for
2027     * monsters to the north first. However, the size of the array passed
2028     * covers all the spaces, so within that size, all the spaces within
2029     * the 3x3 area will be searched, just not in a predictable order.
2030     */
2031 root 1.24 void
2032     get_search_arr (int *search_arr)
2033 elmex 1.1 {
2034 root 1.82 int i;
2035 elmex 1.1
2036 root 1.24 for (i = 0; i < SIZEOFFREE; i++)
2037 root 1.82 search_arr[i] = i;
2038 elmex 1.1
2039 root 1.24 permute (search_arr, 1, SIZEOFFREE1 + 1);
2040     permute (search_arr, SIZEOFFREE1 + 1, SIZEOFFREE2 + 1);
2041     permute (search_arr, SIZEOFFREE2 + 1, SIZEOFFREE);
2042 elmex 1.1 }
2043    
2044     /*
2045     * find_dir(map, x, y, exclude) will search some close squares in the
2046     * given map at the given coordinates for live objects.
2047     * It will not considered the object given as exclude among possible
2048     * live objects.
2049     * It returns the direction toward the first/closest live object if finds
2050     * any, otherwise 0.
2051     * Perhaps incorrectly, but I'm making the assumption that exclude
2052     * is actually want is going to try and move there. We need this info
2053     * because we have to know what movement the thing looking to move
2054     * there is capable of.
2055     */
2056 root 1.24 int
2057 root 1.49 find_dir (maptile *m, int x, int y, object *exclude)
2058 root 1.24 {
2059 root 1.275 int max = SIZEOFFREE, mflags;
2060     MoveType move_type;
2061 root 1.24
2062 root 1.155 if (exclude && exclude->head_ () != exclude)
2063 root 1.24 {
2064     exclude = exclude->head;
2065     move_type = exclude->move_type;
2066     }
2067     else
2068     {
2069     /* If we don't have anything, presume it can use all movement types. */
2070     move_type = MOVE_ALL;
2071     }
2072    
2073 root 1.275 for (int i = 1; i < max; i++)
2074 root 1.24 {
2075 root 1.275 mapxy pos (m, x, y);
2076     pos.move (i);
2077 root 1.75
2078 root 1.275 if (!pos.normalise ())
2079 root 1.75 max = maxfree[i];
2080 root 1.24 else
2081     {
2082 root 1.275 mapspace &ms = *pos;
2083 root 1.82
2084 root 1.275 if ((move_type & ms.move_block) == move_type)
2085     max = maxfree [i];
2086     else if (ms.flags () & P_IS_ALIVE)
2087 root 1.24 {
2088 root 1.275 for (object *tmp = ms.bot; tmp; tmp = tmp->above)
2089 root 1.270 if ((tmp->flag [FLAG_MONSTER] || tmp->is_player ())
2090 root 1.155 && (tmp != exclude || (tmp->head_ () != tmp && tmp->head_ () != exclude)))
2091 root 1.275 return freedir [i];
2092 root 1.8 }
2093     }
2094 elmex 1.1 }
2095 root 1.75
2096 root 1.24 return 0;
2097 elmex 1.1 }
2098    
2099     /*
2100     * distance(object 1, object 2) will return the square of the
2101     * distance between the two given objects.
2102     */
2103 root 1.24 int
2104     distance (const object *ob1, const object *ob2)
2105     {
2106 root 1.82 return (ob1->x - ob2->x) * (ob1->x - ob2->x) + (ob1->y - ob2->y) * (ob1->y - ob2->y);
2107 elmex 1.1 }
2108    
2109     /*
2110     * find_dir_2(delta-x,delta-y) will return a direction in which
2111     * an object which has subtracted the x and y coordinates of another
2112     * object, needs to travel toward it.
2113     */
2114 root 1.24 int
2115     find_dir_2 (int x, int y)
2116     {
2117 root 1.75 int q;
2118 elmex 1.1
2119 root 1.24 if (y)
2120     q = x * 100 / y;
2121 elmex 1.1 else if (x)
2122 root 1.24 q = -300 * x;
2123 elmex 1.1 else
2124     return 0;
2125    
2126 root 1.24 if (y > 0)
2127     {
2128     if (q < -242)
2129     return 3;
2130     if (q < -41)
2131     return 2;
2132     if (q < 41)
2133     return 1;
2134     if (q < 242)
2135     return 8;
2136     return 7;
2137     }
2138 elmex 1.1
2139     if (q < -242)
2140 root 1.24 return 7;
2141 elmex 1.1 if (q < -41)
2142 root 1.24 return 6;
2143 elmex 1.1 if (q < 41)
2144 root 1.24 return 5;
2145 elmex 1.1 if (q < 242)
2146 root 1.24 return 4;
2147 elmex 1.1
2148 root 1.24 return 3;
2149 elmex 1.1 }
2150    
2151     /*
2152     * dirdiff(dir1, dir2) returns how many 45-degrees differences there is
2153     * between two directions (which are expected to be absolute (see absdir())
2154     */
2155 root 1.24 int
2156     dirdiff (int dir1, int dir2)
2157     {
2158 root 1.82 int d;
2159 root 1.24
2160     d = abs (dir1 - dir2);
2161     if (d > 4)
2162 elmex 1.1 d = 8 - d;
2163 root 1.82
2164 elmex 1.1 return d;
2165     }
2166    
2167     /* peterm:
2168     * do LOS stuff for ball lightning. Go after the closest VISIBLE monster.
2169     * Basically, this is a table of directions, and what directions
2170     * one could go to go back to us. Eg, entry 15 below is 4, 14, 16.
2171     * This basically means that if direction is 15, then it could either go
2172     * direction 4, 14, or 16 to get back to where we are.
2173     * Moved from spell_util.c to object.c with the other related direction
2174     * functions.
2175     */
2176 root 1.278 const int reduction_dir[SIZEOFFREE][3] = {
2177 root 1.24 {0, 0, 0}, /* 0 */
2178     {0, 0, 0}, /* 1 */
2179     {0, 0, 0}, /* 2 */
2180     {0, 0, 0}, /* 3 */
2181     {0, 0, 0}, /* 4 */
2182     {0, 0, 0}, /* 5 */
2183     {0, 0, 0}, /* 6 */
2184     {0, 0, 0}, /* 7 */
2185     {0, 0, 0}, /* 8 */
2186     {8, 1, 2}, /* 9 */
2187     {1, 2, -1}, /* 10 */
2188     {2, 10, 12}, /* 11 */
2189     {2, 3, -1}, /* 12 */
2190     {2, 3, 4}, /* 13 */
2191     {3, 4, -1}, /* 14 */
2192     {4, 14, 16}, /* 15 */
2193     {5, 4, -1}, /* 16 */
2194     {4, 5, 6}, /* 17 */
2195     {6, 5, -1}, /* 18 */
2196     {6, 20, 18}, /* 19 */
2197     {7, 6, -1}, /* 20 */
2198     {6, 7, 8}, /* 21 */
2199     {7, 8, -1}, /* 22 */
2200     {8, 22, 24}, /* 23 */
2201     {8, 1, -1}, /* 24 */
2202     {24, 9, 10}, /* 25 */
2203     {9, 10, -1}, /* 26 */
2204     {10, 11, -1}, /* 27 */
2205     {27, 11, 29}, /* 28 */
2206     {11, 12, -1}, /* 29 */
2207     {12, 13, -1}, /* 30 */
2208     {12, 13, 14}, /* 31 */
2209     {13, 14, -1}, /* 32 */
2210     {14, 15, -1}, /* 33 */
2211     {33, 15, 35}, /* 34 */
2212     {16, 15, -1}, /* 35 */
2213     {17, 16, -1}, /* 36 */
2214     {18, 17, 16}, /* 37 */
2215     {18, 17, -1}, /* 38 */
2216     {18, 19, -1}, /* 39 */
2217     {41, 19, 39}, /* 40 */
2218     {19, 20, -1}, /* 41 */
2219     {20, 21, -1}, /* 42 */
2220     {20, 21, 22}, /* 43 */
2221     {21, 22, -1}, /* 44 */
2222     {23, 22, -1}, /* 45 */
2223     {45, 47, 23}, /* 46 */
2224     {23, 24, -1}, /* 47 */
2225     {24, 9, -1}
2226     }; /* 48 */
2227 elmex 1.1
2228     /* Recursive routine to step back and see if we can
2229     * find a path to that monster that we found. If not,
2230     * we don't bother going toward it. Returns 1 if we
2231     * can see a direct way to get it
2232     * Modified to be map tile aware -.MSW
2233     */
2234 root 1.24 int
2235 root 1.49 can_see_monsterP (maptile *m, int x, int y, int dir)
2236 root 1.24 {
2237 root 1.29 sint16 dx, dy;
2238 root 1.75 int mflags;
2239 root 1.24
2240     if (dir < 0)
2241     return 0; /* exit condition: invalid direction */
2242    
2243     dx = x + freearr_x[dir];
2244     dy = y + freearr_y[dir];
2245    
2246     mflags = get_map_flags (m, &m, dx, dy, &dx, &dy);
2247    
2248     /* This functional arguably was incorrect before - it was
2249     * checking for P_WALL - that was basically seeing if
2250     * we could move to the monster - this is being more
2251     * literal on if we can see it. To know if we can actually
2252     * move to the monster, we'd need the monster passed in or
2253     * at least its move type.
2254     */
2255     if (mflags & (P_OUT_OF_MAP | P_BLOCKSVIEW))
2256     return 0;
2257    
2258     /* yes, can see. */
2259     if (dir < 9)
2260     return 1;
2261 root 1.75
2262     return can_see_monsterP (m, x, y, reduction_dir[dir][0])
2263     | can_see_monsterP (m, x, y, reduction_dir[dir][1])
2264     | can_see_monsterP (m, x, y, reduction_dir[dir][2]);
2265 root 1.24 }
2266    
2267 elmex 1.1 /*
2268     * can_pick(picker, item): finds out if an object is possible to be
2269     * picked up by the picker. Returnes 1 if it can be
2270     * picked up, otherwise 0.
2271     *
2272     * Cf 0.91.3 - don't let WIZ's pick up anything - will likely cause
2273     * core dumps if they do.
2274     *
2275     * Add a check so we can't pick up invisible objects (0.93.8)
2276     */
2277 root 1.24 int
2278     can_pick (const object *who, const object *item)
2279     {
2280     return /*QUERY_FLAG(who,FLAG_WIZ)|| */
2281     (item->weight > 0 && !QUERY_FLAG (item, FLAG_NO_PICK) &&
2282 root 1.270 !QUERY_FLAG (item, FLAG_ALIVE) && !item->invisible && (who->is_player () || item->weight < who->weight / 3));
2283 elmex 1.1 }
2284    
2285     /*
2286     * create clone from object to another
2287     */
2288 root 1.24 object *
2289 root 1.230 object::deep_clone ()
2290 root 1.24 {
2291 root 1.230 assert (("deep_clone called on non-head object", is_head ()));
2292 elmex 1.1
2293 root 1.230 object *dst = clone ();
2294 root 1.24
2295 root 1.230 object *prev = dst;
2296     for (object *part = this->more; part; part = part->more)
2297 root 1.24 {
2298 root 1.224 object *tmp = part->clone ();
2299 root 1.230 tmp->head = dst;
2300     prev->more = tmp;
2301 root 1.24 prev = tmp;
2302 elmex 1.1 }
2303 root 1.24
2304 root 1.230 for (object *item = inv; item; item = item->below)
2305     insert_ob_in_ob (item->deep_clone (), dst);
2306 elmex 1.1
2307 root 1.24 return dst;
2308 elmex 1.1 }
2309    
2310     /* This returns the first object in who's inventory that
2311     * has the same type and subtype match.
2312     * returns NULL if no match.
2313     */
2314 root 1.24 object *
2315     find_obj_by_type_subtype (const object *who, int type, int subtype)
2316 elmex 1.1 {
2317 root 1.82 for (object *tmp = who->inv; tmp; tmp = tmp->below)
2318 root 1.24 if (tmp->type == type && tmp->subtype == subtype)
2319     return tmp;
2320 elmex 1.1
2321 root 1.82 return 0;
2322 elmex 1.1 }
2323    
2324 root 1.276 shstr_tmp
2325     object::kv_get (shstr_tmp key) const
2326 root 1.24 {
2327 root 1.228 for (key_value *kv = key_values; kv; kv = kv->next)
2328     if (kv->key == key)
2329     return kv->value;
2330 root 1.24
2331 root 1.276 return shstr ();
2332 root 1.24 }
2333 elmex 1.1
2334 root 1.228 void
2335 root 1.276 object::kv_set (shstr_tmp key, shstr_tmp value)
2336 root 1.24 {
2337 root 1.228 for (key_value *kv = key_values; kv; kv = kv->next)
2338     if (kv->key == key)
2339     {
2340     kv->value = value;
2341     return;
2342     }
2343 root 1.24
2344 root 1.228 key_value *kv = new key_value;
2345 elmex 1.1
2346 root 1.228 kv->next = key_values;
2347     kv->key = key;
2348     kv->value = value;
2349 root 1.35
2350 root 1.228 key_values = kv;
2351 elmex 1.1 }
2352    
2353 root 1.228 void
2354 root 1.276 object::kv_del (shstr_tmp key)
2355 root 1.24 {
2356 root 1.228 for (key_value **kvp = &key_values; *kvp; kvp = &(*kvp)->next)
2357     if ((*kvp)->key == key)
2358     {
2359     key_value *kv = *kvp;
2360     *kvp = (*kvp)->next;
2361     delete kv;
2362     return;
2363     }
2364 elmex 1.1 }
2365 root 1.31
2366 root 1.34 object::depth_iterator::depth_iterator (object *container)
2367     : iterator_base (container)
2368     {
2369     while (item->inv)
2370     item = item->inv;
2371     }
2372    
2373 root 1.31 void
2374 root 1.34 object::depth_iterator::next ()
2375 root 1.31 {
2376 root 1.34 if (item->below)
2377     {
2378     item = item->below;
2379    
2380     while (item->inv)
2381     item = item->inv;
2382     }
2383 root 1.31 else
2384 root 1.34 item = item->env;
2385 root 1.31 }
2386 root 1.34
2387 elmex 1.97 const char *
2388     object::flag_desc (char *desc, int len) const
2389     {
2390     char *p = desc;
2391     bool first = true;
2392    
2393 root 1.101 *p = 0;
2394    
2395 elmex 1.97 for (int i = 0; i < NUM_FLAGS; i++)
2396     {
2397     if (len <= 10) // magic constant!
2398     {
2399     snprintf (p, len, ",...");
2400     break;
2401     }
2402    
2403 root 1.101 if (flag [i])
2404 elmex 1.97 {
2405     int cnt = snprintf (p, len, "%s%d", first ? "" : ",", i);
2406     len -= cnt;
2407     p += cnt;
2408     first = false;
2409     }
2410     }
2411    
2412     return desc;
2413     }
2414    
2415 root 1.101 // return a suitable string describing an object in enough detail to find it
2416 root 1.36 const char *
2417     object::debug_desc (char *info) const
2418     {
2419 elmex 1.97 char flagdesc[512];
2420     char info2[256 * 4];
2421 root 1.36 char *p = info;
2422    
2423 elmex 1.242 p += snprintf (p, 512, "{cnt:%d,uuid:%s,name:\"%s\"%s%s%s,flags:[%s],type:%d}",
2424 root 1.203 count,
2425     uuid.c_str (),
2426 root 1.36 &name,
2427 elmex 1.242 title ? ",title:\"" : "",
2428 elmex 1.97 title ? (const char *)title : "",
2429 elmex 1.242 title ? "\"" : "",
2430 elmex 1.97 flag_desc (flagdesc, 512), type);
2431 root 1.36
2432 root 1.217 if (!flag[FLAG_REMOVED] && env)
2433 root 1.36 p += snprintf (p, 256, "(in %s)", env->debug_desc (info2));
2434    
2435     if (map)
2436 root 1.96 p += snprintf (p, 256, "(on %s@%d+%d)", &map->path, x, y);
2437 root 1.36
2438     return info;
2439     }
2440    
2441     const char *
2442     object::debug_desc () const
2443     {
2444 root 1.143 static char info[3][256 * 4];
2445     static int info_idx;
2446 root 1.36
2447 root 1.143 return debug_desc (info [++info_idx % 3]);
2448 root 1.114 }
2449    
2450 root 1.125 struct region *
2451     object::region () const
2452     {
2453     return map ? map->region (x, y)
2454     : region::default_region ();
2455     }
2456    
2457 root 1.129 const materialtype_t *
2458     object::dominant_material () const
2459     {
2460 root 1.165 if (materialtype_t *mt = name_to_material (materialname))
2461     return mt;
2462 root 1.129
2463 root 1.165 return name_to_material (shstr_unknown);
2464 root 1.129 }
2465    
2466 root 1.130 void
2467     object::open_container (object *new_container)
2468     {
2469     if (container == new_container)
2470     return;
2471    
2472 root 1.220 object *old_container = container;
2473    
2474     if (old_container)
2475 root 1.130 {
2476     if (INVOKE_OBJECT (CLOSE, old_container, ARG_OBJECT (this)))
2477     return;
2478    
2479     #if 0
2480     // remove the "Close old_container" object.
2481     if (object *closer = old_container->inv)
2482     if (closer->type == CLOSE_CON)
2483 root 1.259 closer->destroy ();
2484 root 1.130 #endif
2485    
2486 root 1.220 // make sure the container is available
2487     esrv_send_item (this, old_container);
2488    
2489 root 1.216 old_container->flag [FLAG_APPLIED] = false;
2490 root 1.130 container = 0;
2491    
2492 root 1.220 // client needs item update to make it work, client bug requires this to be separate
2493 root 1.130 esrv_update_item (UPD_FLAGS, this, old_container);
2494 root 1.220
2495 root 1.281 new_draw_info_format (NDI_UNIQUE, 0, this, "You close %s.", old_container->query_name ());
2496 root 1.177 play_sound (sound_find ("chest_close"));
2497 root 1.130 }
2498    
2499     if (new_container)
2500     {
2501     if (INVOKE_OBJECT (OPEN, new_container, ARG_OBJECT (this)))
2502     return;
2503    
2504     // TODO: this does not seem to serve any purpose anymore?
2505     #if 0
2506     // insert the "Close Container" object.
2507     if (archetype *closer = new_container->other_arch)
2508     {
2509     object *closer = arch_to_object (new_container->other_arch);
2510     closer->flag [FLAG_NO_MAP_SAVE] = 1;
2511     new_container->insert (closer);
2512     }
2513     #endif
2514    
2515 root 1.281 new_draw_info_format (NDI_UNIQUE, 0, this, "You open %s.", new_container->query_name ());
2516 root 1.132
2517 root 1.220 // make sure the container is available, client bug requires this to be separate
2518     esrv_send_item (this, new_container);
2519    
2520 root 1.216 new_container->flag [FLAG_APPLIED] = true;
2521 root 1.130 container = new_container;
2522    
2523 root 1.220 // client needs flag change
2524 root 1.130 esrv_update_item (UPD_FLAGS, this, new_container);
2525 root 1.131 esrv_send_inventory (this, new_container);
2526 root 1.177 play_sound (sound_find ("chest_open"));
2527 root 1.130 }
2528 root 1.220 // else if (!old_container->env && contr && contr->ns)
2529     // contr->ns->floorbox_reset ();
2530 root 1.130 }
2531    
2532 root 1.164 object *
2533 root 1.276 object::force_find (shstr_tmp name)
2534 root 1.164 {
2535     /* cycle through his inventory to look for the MARK we want to
2536     * place
2537     */
2538     for (object *tmp = inv; tmp; tmp = tmp->below)
2539     if (tmp->type == FORCE && tmp->slaying == name)
2540     return splay (tmp);
2541    
2542     return 0;
2543     }
2544    
2545 sf-marcmagus 1.290 void
2546     object::force_set_timer (int duration)
2547     {
2548     this->duration = 1;
2549     this->speed_left = -1.f;
2550    
2551     this->set_speed (duration ? 1.f / duration : 0.f);
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 sf-marcmagus 1.290 force->slaying = name;
2563    
2564     force->force_set_timer (duration);
2565 root 1.164
2566     force->flag [FLAG_APPLIED] = true;
2567    
2568 root 1.265 return insert (force);
2569 root 1.164 }
2570    
2571 root 1.178 void
2572 root 1.280 object::play_sound (faceidx sound) const
2573 root 1.178 {
2574     if (!sound)
2575     return;
2576    
2577 root 1.280 if (is_on_map ())
2578     map->play_sound (sound, x, y);
2579     else if (object *pl = in_player ())
2580     pl->contr->play_sound (sound);
2581     }
2582 root 1.178
2583 root 1.280 void
2584     object::say_msg (const char *msg) const
2585     {
2586     if (is_on_map ())
2587     map->say_msg (msg, x, y);
2588     else if (object *pl = in_player ())
2589     pl->contr->play_sound (sound);
2590 root 1.178 }
2591    
2592 root 1.265 void
2593     object::make_noise ()
2594     {
2595     // we do not model noise in the map, so instead put
2596     // a temporary light into the noise source
2597     // could use the map instead, but that's less reliable for our
2598     // goal, which is to make invisibility a bit harder to exploit
2599    
2600 root 1.266 // currently only works sensibly for players
2601     if (!is_player ())
2602     return;
2603    
2604 root 1.265 // find old force, or create new one
2605     object *force = force_find (shstr_noise_force);
2606    
2607     if (force)
2608 root 1.269 force->speed_left = -1.f; // patch old speed up
2609 root 1.265 else
2610 root 1.269 {
2611     force = archetype::get (shstr_noise_force);
2612    
2613     force->slaying = shstr_noise_force;
2614     force->stats.food = 1;
2615     force->speed_left = -1.f;
2616    
2617     force->set_speed (1.f / 4.f);
2618     force->flag [FLAG_IS_USED_UP] = true;
2619     force->flag [FLAG_APPLIED] = true;
2620    
2621     insert (force);
2622     }
2623 root 1.265 }
2624