ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/object.C
Revision: 1.311
Committed: Sat Jan 16 13:41:37 2010 UTC (14 years, 4 months ago) by root
Content type: text/plain
Branch: MAIN
CVS Tags: rel-2_93
Changes since 1.310: +1 -2 lines
Log Message:
more utf8 marking

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