ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/common/object.C
Revision: 1.233
Committed: Tue May 6 18:47:32 2008 UTC (16 years ago) by root
Content type: text/plain
Branch: MAIN
Changes since 1.232: +5 -2 lines
Log Message:
*** empty log message ***

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