--- deliantra/server/common/map.C 2009/11/06 13:03:34 1.168 +++ deliantra/server/common/map.C 2009/11/08 20:55:39 1.172 @@ -451,6 +451,7 @@ height = 16; timeout = 300; max_nrof = 1000; // 1000 items of anything + max_items = MAX_ITEM_PER_ACTION; max_volume = 2000000; // 2m³ } @@ -1029,9 +1030,12 @@ mapspace::update_ () { object *last = 0; - uint8 flags = P_UPTODATE, anywhere = 0; + uint8 flags = P_UPTODATE; sint8 light = 0; MoveType move_block = 0, move_slow = 0, move_on = 0, move_off = 0, move_allow = 0; + uint64_t volume = 0; + uint32_t items = 0; + object *anywhere = 0; //object *middle = 0; //object *top = 0; @@ -1041,6 +1045,8 @@ object *&middle = faces_obj[1] = 0; object *&floor = faces_obj[2] = 0; + object::flags_t allflags; // all flags of all objects or'ed together + for (object *tmp = bot; tmp; last = tmp, tmp = tmp->above) { // Lights are additive, up to MAX_LIGHT_RADIUS, see los.C) @@ -1054,38 +1060,42 @@ * * Always put the player down for drawing. */ - if (!tmp->invisible) + if (expect_true (!tmp->invisible)) { - if ((tmp->type == PLAYER || QUERY_FLAG (tmp, FLAG_MONSTER))) + if (tmp->type == PLAYER || tmp->flag [FLAG_MONSTER]) top = tmp; - else if (QUERY_FLAG (tmp, FLAG_IS_FLOOR)) - { - /* If we got a floor, that means middle and top were below it, - * so should not be visible, so we clear them. - */ - middle = 0; - top = 0; - floor = tmp; - } - /* Flag anywhere have high priority */ - else if (QUERY_FLAG (tmp, FLAG_SEE_ANYWHERE)) + else { - middle = tmp; - anywhere = 1; + if (expect_false (tmp->flag [FLAG_IS_FLOOR])) + { + /* If we got a floor, that means middle and top were below it, + * so should not be visible, so we clear them. + */ + middle = 0; + top = 0; + floor = tmp; + volume = 0; + items = 0; + } + else + { + if (expect_true (!tmp->flag [FLAG_NO_PICK])) + { + ++items; + volume += tmp->volume (); + } + + /* Flag anywhere have high priority */ + if (expect_false (tmp->flag [FLAG_SEE_ANYWHERE])) + anywhere = tmp; + /* Find the highest visible face around. If equal + * visibilities, we still want the one nearer to the + * top + */ + else if (!middle || (::faces [tmp->face].visibility > ::faces [middle->face].visibility)) + middle = tmp; + } } - - /* Find the highest visible face around. If equal - * visibilities, we still want the one nearer to the - * top - */ - else if (!middle || (::faces [tmp->face].visibility > ::faces [middle->face].visibility && !anywhere)) - middle = tmp; - } - - if (tmp == tmp->above) - { - LOG (llevError, "Error in structure of map\n"); - exit (-1); } move_slow |= tmp->move_slow; @@ -1094,20 +1104,30 @@ move_off |= tmp->move_off; move_allow |= tmp->move_allow; - if (QUERY_FLAG (tmp, FLAG_BLOCKSVIEW)) flags |= P_BLOCKSVIEW; - if (QUERY_FLAG (tmp, FLAG_NO_MAGIC)) flags |= P_NO_MAGIC; - if (tmp->type == PLAYER) flags |= P_PLAYER; - if (tmp->type == SAFE_GROUND) flags |= P_SAFE; - if (QUERY_FLAG (tmp, FLAG_ALIVE)) flags |= P_IS_ALIVE; - if (QUERY_FLAG (tmp, FLAG_DAMNED)) flags |= P_NO_CLERIC; + allflags |= tmp->flag; + + if (tmp->type == PLAYER) flags |= P_PLAYER; + if (tmp->type == SAFE_GROUND) flags |= P_SAFE; } + // FLAG_SEE_ANYWHERE takes precedence + if (anywhere) + middle = anywhere; + + // ORing all flags together and checking them here is much faster + if (allflags [FLAG_BLOCKSVIEW]) flags |= P_BLOCKSVIEW; + if (allflags [FLAG_NO_MAGIC] ) flags |= P_NO_MAGIC; + if (allflags [FLAG_ALIVE] ) flags |= P_IS_ALIVE; + if (allflags [FLAG_DAMNED] ) flags |= P_NO_CLERIC; + this->light = min (light, MAX_LIGHT_RADIUS); this->flags_ = flags; this->move_block = move_block & ~move_allow; this->move_on = move_on; this->move_off = move_off; this->move_slow = move_slow; + this->volume_ = (volume + 1023) / 1024; + this->items_ = upos_min (items, 65535); // assume nrof <= 2**31 /* At this point, we have a floor face (if there is a floor), * and the floor is set - we are not going to touch it at @@ -1183,17 +1203,6 @@ #endif } -uint64 -mapspace::volume () const -{ - uint64 vol = 0; - - for (object *op = top; op && !op->flag [FLAG_NO_PICK]; op = op->below) - vol += op->volume (); - - return vol; -} - maptile * maptile::tile_available (int dir, bool load) { @@ -1588,7 +1597,7 @@ } // instead of crashing in the unlikely(?) case, try to return *something* - return archetype::find ("bug"); + return archetype::find (shstr_bug); } //-GPL