--- deliantra/server/common/map.C 2007/02/16 22:16:16 1.89 +++ deliantra/server/common/map.C 2007/03/15 13:19:37 1.95 @@ -406,7 +406,7 @@ switch (f.kw) { case KW_arch: - if (object *op = object::read (f)) + if (object *op = object::read (f, this)) { if (op->inv) sum_weight (op); @@ -1077,17 +1077,15 @@ { object *tmp, *last = 0; uint8 flags = P_UPTODATE, light = 0, anywhere = 0; - facetile *top, *floor, *middle; - object *top_obj, *floor_obj, *middle_obj; MoveType move_block = 0, move_slow = 0, move_on = 0, move_off = 0, move_allow = 0; - middle = blank_face; - top = blank_face; - floor = blank_face; - - middle_obj = 0; - top_obj = 0; - floor_obj = 0; + //object *middle = 0; + //object *top = 0; + //object *floor = 0; + // this seems to generate better code than using locals, above + object *&top = faces_obj[0] = 0; + object *&middle = faces_obj[1] = 0; + object *&floor = faces_obj[2] = 0; for (tmp = bot; tmp; last = tmp, tmp = tmp->above) { @@ -1110,37 +1108,28 @@ if (!tmp->invisible) { if ((tmp->type == PLAYER || QUERY_FLAG (tmp, FLAG_MONSTER))) - { - top = tmp->face; - top_obj = tmp; - } + 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 = blank_face; - top = blank_face; - floor = tmp->face; - floor_obj = tmp; + middle = 0; + top = 0; + floor = tmp; } /* Flag anywhere have high priority */ else if (QUERY_FLAG (tmp, FLAG_SEE_ANYWHERE)) { - middle = tmp->face; - - middle_obj = tmp; + 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 == blank_face || (tmp->face->visibility > middle->visibility && !anywhere)) - { - middle = tmp->face; - middle_obj = tmp; - } + else if (!middle || (::faces [tmp->face].visibility > ::faces [middle->face].visibility && !anywhere)) + middle = tmp; } if (tmp == tmp->above) @@ -1185,7 +1174,7 @@ * may be possible for the faces to match but be different objects. */ if (top == middle) - middle = blank_face; + middle = 0; /* There are three posibilities at this point: * 1) top face is set, need middle to be set. @@ -1200,19 +1189,18 @@ break; /* If two top faces are already set, quit processing */ - if ((top != blank_face) && (middle != blank_face)) + if (top && middle) break; /* Only show visible faces */ if (!tmp->invisible) { /* Fill in top if needed */ - if (top == blank_face) + if (!top) { - top = tmp->face; - top_obj = tmp; + top = tmp; if (top == middle) - middle = blank_face; + middle = 0; } else { @@ -1223,10 +1211,9 @@ * more to fill in. We don't check visiblity here, since * */ - if (tmp->face != top) + if (tmp != top) { - middle = tmp->face; - middle_obj = tmp; + middle = tmp; break; } } @@ -1234,14 +1221,16 @@ } if (middle == floor) - middle = blank_face; + middle = 0; if (top == middle) - middle = blank_face; + middle = 0; - faces [0] = top; faces_obj [0] = top != blank_face ? top_obj : 0; - faces [1] = middle; faces_obj [1] = middle != blank_face ? middle_obj : 0; - faces [2] = floor; faces_obj [2] = floor != blank_face ? floor_obj : 0; +#if 0 + faces_obj [0] = top; + faces_obj [1] = middle; + faces_obj [2] = floor; +#endif } uint64 @@ -1671,4 +1660,29 @@ return ::region::default_region (); } +/* picks a random object from a style map. + * Redone by MSW so it should be faster and not use static + * variables to generate tables. + */ +object * +maptile::pick_random_object () const +{ + /* while returning a null object will result in a crash, that + * is actually preferable to an infinite loop. That is because + * most servers will automatically restart in case of crash. + * Change the logic on getting the random space - shouldn't make + * any difference, but this seems clearer to me. + */ + for (int i = 1000; --i;) + { + object *pick = at (rndm (width), rndm (height)).bot; + + // do not prefer big monsters just because they are big. + if (pick && pick->head_ () == pick) + return pick->head_ (); + } + + // instead of crashing in the unlikely(?) case, try to return *something* + return get_archetype ("blocked"); +}