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