ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/object.C
Revision: 1.307
Committed: Sun Nov 29 10:55:18 2009 UTC (14 years, 5 months ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.306: +1 -1 lines
Log Message:
indent (remove useless use of void)

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