ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/object.C
Revision: 1.316
Committed: Sun Mar 28 02:53:46 2010 UTC (14 years, 2 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.315: +4 -1 lines
Log Message:
hrmpf

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