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