ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/object.C
Revision: 1.294
Committed: Thu Nov 5 15:43:21 2009 UTC (14 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.293: +5 -3 lines
Log Message:
mark gpl sections, common/

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