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