ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/object.C
Revision: 1.300
Committed: Mon Nov 9 03:08:23 2009 UTC (14 years, 6 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.299: +66 -1 lines
Log Message:
whew

File Contents

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