--- deliantra/server/common/map.C 2009/11/06 13:03:34 1.168 +++ deliantra/server/common/map.C 2009/12/18 21:25:27 1.179 @@ -152,8 +152,7 @@ if (tmp->flag [FLAG_ALIVE] && tmp->head_ () != ob && tmp != ob - && tmp->type != DOOR - && !tmp->flag [FLAG_WIZPASS]) + && tmp->type != DOOR) return 1; } } @@ -219,33 +218,6 @@ return 0; } -/* When the map is loaded, load_object does not actually insert objects - * into inventory, but just links them. What this does is go through - * and insert them properly. - * The object 'container' is the object that contains the inventory. - * This is needed so that we can update the containers weight. - */ -static void -fix_container (object *container) -{ - object *tmp = container->inv, *next; - - container->inv = 0; - while (tmp) - { - next = tmp->below; - if (tmp->inv) - fix_container (tmp); - - insert_ob_in_ob (tmp, container); - tmp = next; - } - - // go through and calculate what all the containers are carrying. - //TODO: remove - container->update_weight (); -} - //-GPL void @@ -272,6 +244,19 @@ INVOKE_OBJECT (RESET, tmp); } +void +maptile::post_load () +{ +#if 0 + if (!spaces) + return; + + for (mapspace *ms = spaces + size (); ms-- > spaces; ) + for (object *tmp = ms->bot; tmp; tmp = tmp->above) + ; // nop +#endif +} + //+GPL /* link_multipart_objects go through all the objects on the map looking @@ -450,7 +435,7 @@ width = 16; height = 16; timeout = 300; - max_nrof = 1000; // 1000 items of anything + max_items = MAX_ITEM_PER_ACTION; max_volume = 2000000; // 2m³ } @@ -646,12 +631,6 @@ case KW_shopmax: thawer.get (shopmax); break; case KW_shoprace: thawer.get (shoprace); break; case KW_outdoor: thawer.get (outdoor); break; - case KW_temp: thawer.get (temp); break; - case KW_pressure: thawer.get (pressure); break; - case KW_humid: thawer.get (humid); break; - case KW_windspeed: thawer.get (windspeed); break; - case KW_winddir: thawer.get (winddir); break; - case KW_sky: thawer.get (sky); break; case KW_per_player: thawer.get (per_player); break; case KW_per_party: thawer.get (per_party); break; @@ -730,10 +709,10 @@ bool maptile::_save_header (object_freezer &freezer) { -#define MAP_OUT(k) freezer.put (KW_ ## k, k) -#define MAP_OUT2(k,v) freezer.put (KW_ ## k, v) +#define MAP_OUT(k) freezer.put (KW(k), k) +#define MAP_OUT2(k,v) freezer.put (KW(k), v) - MAP_OUT2 (arch, "map"); + MAP_OUT2 (arch, CS(map)); if (name) MAP_OUT (name); MAP_OUT (swap_time); @@ -751,22 +730,15 @@ MAP_OUT (shopmax); if (shoprace) MAP_OUT (shoprace); - MAP_OUT (darkness); MAP_OUT (width); MAP_OUT (height); MAP_OUT (enter_x); MAP_OUT (enter_y); - - if (msg) freezer.put (KW_msg , KW_endmsg , msg); - if (maplore) freezer.put (KW_maplore, KW_endmaplore, maplore); - + MAP_OUT (darkness); MAP_OUT (outdoor); - MAP_OUT (temp); - MAP_OUT (pressure); - MAP_OUT (humid); - MAP_OUT (windspeed); - MAP_OUT (winddir); - MAP_OUT (sky); + + if (msg) freezer.put (KW(msg) , KW(endmsg) , msg); + if (maplore) freezer.put (KW(maplore), KW(endmaplore), maplore); MAP_OUT (per_player); MAP_OUT (per_party); @@ -777,7 +749,7 @@ if (tile_path [3]) MAP_OUT2 (tile_path_4, tile_path [3]); freezer.put (this); - freezer.put (KW_end); + freezer.put (KW(end)); return true; } @@ -872,6 +844,7 @@ } /* decay and destroy perishable items in a map */ +// TODO: should be done regularly, not on map load? void maptile::do_decay_objects () { @@ -928,7 +901,8 @@ || (mat & M_GLASS && rndm (1, 2) == 1) || ((mat & M_STONE || mat & M_ADAMANT) && rndm (1, 10) == 1) || ((mat & M_SOFT_METAL || mat & M_BONE) && rndm (1, 3) == 1) - || (mat & M_ICE && temp > 32)) + //|| (mat & M_ICE && temp > 32) + ) destroy = 1; } @@ -1029,9 +1003,13 @@ 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; + uint8_t middle_visibility = 0; //object *middle = 0; //object *top = 0; @@ -1041,6 +1019,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,11 +1034,11 @@ * * 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 (expect_false (tmp->type == PLAYER || tmp->flag [FLAG_MONSTER])) top = tmp; - else if (QUERY_FLAG (tmp, FLAG_IS_FLOOR)) + else 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. @@ -1066,26 +1046,31 @@ middle = 0; top = 0; floor = tmp; + volume = 0; + items = 0; } - /* Flag anywhere have high priority */ - else if (QUERY_FLAG (tmp, FLAG_SEE_ANYWHERE)) + else { - middle = tmp; - anywhere = 1; - } - - /* 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 (expect_true (!tmp->flag [FLAG_NO_PICK])) + { + ++items; + volume += tmp->volume (); + } - if (tmp == tmp->above) - { - LOG (llevError, "Error in structure of map\n"); - exit (-1); + /* 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 + */ + if (expect_false (::faces [tmp->face].visibility >= middle_visibility)) + { + middle_visibility = ::faces [tmp->face].visibility; + middle = tmp; + } + } } move_slow |= tmp->move_slow; @@ -1094,20 +1079,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 +1178,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 +1572,7 @@ } // instead of crashing in the unlikely(?) case, try to return *something* - return archetype::find ("bug"); + return archetype::find (shstr_bug); } //-GPL