--- deliantra/server/common/object.C 2008/08/31 05:47:14 1.256 +++ deliantra/server/common/object.C 2008/12/23 01:51:27 1.267 @@ -772,14 +772,14 @@ */ || ((m.move_block | op->move_block) & ~op->move_allow) != m.move_block || 1) // the above is not strong enough a test to skip updating. los maybe? TODO (Schmorp) - m.flags_ = 0; + m.invalidate (); } /* if the object is being removed, we can't make intelligent * decisions, because remove_ob can't really pass the object * that is being removed. */ else if (action == UP_OBJ_CHANGE || action == UP_OBJ_REMOVE) - m.flags_ = 0; + m.invalidate (); else if (action == UP_OBJ_FACE) /* Nothing to do for that case */ ; else @@ -832,7 +832,8 @@ if (active) return; - if (has_active_speed () && flag [FLAG_FREED ]) LOG (llevError | logBacktrace, "BUG: tried to activate freed object %s\n", debug_desc ());//D + if (has_active_speed () && flag [FLAG_FREED]) LOG (llevError | logBacktrace, "BUG: tried to activate freed object %s\n", debug_desc ());//D + if (has_active_speed () && flag [FLAG_DEBUG]) LOG (llevError | logBacktrace, "BUG: tried to activate DEBUG object %s\n", debug_desc ());//D temp if (has_active_speed ()) actives.insert (this); @@ -910,7 +911,7 @@ || ms ().move_block == MOVE_ALL) { while (inv) - inv->destroy (true); + inv->destroy (); } else { /* Put objects in inventory onto this space */ @@ -924,7 +925,7 @@ || op->type == TRAP || op->flag [FLAG_IS_A_TEMPLATE] || op->flag [FLAG_DESTROY_ON_DEATH]) - op->destroy (true); + op->destroy (); else map->insert (op, x, y); } @@ -998,7 +999,7 @@ } void -object::destroy (bool destroy_inventory) +object::destroy () { if (destroyed ()) return; @@ -1006,11 +1007,11 @@ if (!is_head () && !head->destroyed ()) { LOG (llevError | logBacktrace, "tried to destroy the tail of an object"); - head->destroy (destroy_inventory); + head->destroy (); return; } - destroy_inv (!destroy_inventory); + destroy_inv (false); if (is_head ()) if (sound_destroy) @@ -1057,6 +1058,8 @@ adjust_weight (env, -total_weight ()); + object *pl = in_player (); + /* we set up values so that it could be inserted into * the map, but we don't actually do that - it is up * to the caller to decide what we want to do. @@ -1077,8 +1080,14 @@ * made to players inventory. If set, avoiding the call * to save cpu time. */ - if ((otmp = in_player ()) && otmp->contr && !QUERY_FLAG (otmp, FLAG_NO_FIX_PLAYER)) - otmp->update_stats (); + if (pl) + if (pl->is_player () && (glow_radius || !QUERY_FLAG (pl, FLAG_NO_FIX_PLAYER))) + { + pl->update_stats (); + + if (glow_radius && pl->is_on_map () && pl->map->darkness) + update_all_los (pl->map, pl->x, pl->y); + } } else if (map) { @@ -1115,7 +1124,7 @@ above = 0; below = 0; - ms.flags_ = 0; + ms.invalidate (); if (map->in_memory == MAP_SAVING) return; @@ -1158,7 +1167,7 @@ last = tmp; } - if (flag [FLAG_BLOCKSVIEW] || glow_radius) + if (map->darkness && affects_los ()) update_all_los (map, x, y); } } @@ -1192,7 +1201,7 @@ op->weight = 0; // cancel the addition above op->carrying = 0; // must be 0 already - op->destroy (1); + op->destroy (); return top; } @@ -1264,22 +1273,11 @@ object * insert_ob_in_map (object *op, maptile *m, object *originator, int flag) { - if (op->is_on_map ()) - { - LOG (llevError, "insert_ob_in_map called for object already on map"); - abort (); - } - - if (op->env) - { - LOG (llevError, "insert_ob_in_map called for object in an inventory (proceeding)"); - op->remove (); - } + op->remove (); - if (op->face && !face_info (op->face))//D TODO: remove soon + if (m == &freed_map)//D TODO: remove soon {//D - LOG (llevError | logBacktrace, "op->face out of bounds: %s", op->debug_desc ());//D - op->face = 1;//D + LOG (llevError | logBacktrace, "tries to insret object on freed objects map: %s", op->debug_desc ());//D }//D /* Ideally, the caller figures this out. However, it complicates a lot @@ -1288,7 +1286,7 @@ */ if (!xy_normalise (m, op->x, op->y)) { - op->head_ ()->destroy (1);// remove head_ once all tail object destroyers found + op->head_ ()->destroy ();// remove head_ once all tail object destroyers found return 0; } @@ -1311,7 +1309,7 @@ // but some caller surely breaks when we return tmp // from here :/ op->nrof += tmp->nrof; - tmp->destroy (1); + tmp->destroy (); } CLEAR_FLAG (op, FLAG_APPLIED); /* hack for fixing F_APPLIED in items of dead people */ @@ -1451,8 +1449,11 @@ * or just updating the P_UPTODATE for spaces within this area * of effect may be sufficient. */ - if (op->map->darkness && (op->glow_radius != 0)) - update_all_los (op->map, op->x, op->y); + if (op->affects_los () && op->map->darkness) + { + op->ms ().invalidate (); + update_all_los (op->map, op->x, op->y); + } /* updates flags (blocked, alive, no magic, etc) for this map space */ update_object (op, UP_OBJ_INSERT); @@ -1496,7 +1497,7 @@ for (object *tmp = op->ms ().bot; tmp; tmp = tmp->above) if (!strcmp (tmp->arch->archname, arch_string)) /* same archetype */ - tmp->destroy (1); + tmp->destroy (); object *tmp = arch_to_object (archetype::find (arch_string)); @@ -1629,7 +1630,7 @@ adjust_weight (this, op->total_weight ()); - op->destroy (1); + op->destroy (); op = tmp; goto inserted; } @@ -1657,11 +1658,13 @@ inserted: /* reset the light list and los of the players on the map */ - if (op->glow_radius && map && map->darkness) - update_all_los (map, x, y); - - // if this is a player's inventory, update stats - if (type == PLAYER && !flag [FLAG_NO_FIX_PLAYER]) + if (op->glow_radius && is_on_map () && map->darkness) + { + update_stats (); + update_all_los (map, x, y); + } + else if (type == PLAYER && !flag [FLAG_NO_FIX_PLAYER]) + // if this is a player's inventory, update stats update_stats (); INVOKE_OBJECT (INSERT, this); @@ -1973,7 +1976,7 @@ if (OB_TYPE_MOVE_BLOCK (ob, ms.move_block)) continue; - if (ob->blocked (m, pos.x, pos.y)) + if (ob->blocked (pos.m, pos.x, pos.y)) continue; altern [index++] = i; @@ -2550,7 +2553,7 @@ return 0; } -void +object * object::force_add (const shstr name, int duration) { if (object *force = force_find (name)) @@ -2566,7 +2569,7 @@ force->flag [FLAG_IS_USED_UP] = true; force->flag [FLAG_APPLIED] = true; - insert (force); + return insert (force); } void @@ -2587,3 +2590,24 @@ map->play_sound (sound, x, y); } +void +object::make_noise () +{ + // we do not model noise in the map, so instead put + // a temporary light into the noise source + // could use the map instead, but that's less reliable for our + // goal, which is to make invisibility a bit harder to exploit + + // currently only works sensibly for players + if (!is_player ()) + return; + + // find old force, or create new one + object *force = force_find (shstr_noise_force); + + if (force) + force->speed = 1.f / 4; // patch old speed up + else + force_add (shstr_noise_force, 4); +} +