--- deliantra/server/socket/request.C 2007/03/11 02:12:45 1.69 +++ deliantra/server/socket/request.C 2007/03/11 21:26:05 1.70 @@ -1168,74 +1168,19 @@ /** Clears a map cell */ static void -map_clearcell (struct MapCell *cell, int face0, int face1, int face2, int count) +map_clearcell (struct MapCell *cell, int count) { - cell->faces[0] = face0; - cell->faces[1] = face1; - cell->faces[2] = face2; + cell->faces[0] = 0; + cell->faces[1] = 0; + cell->faces[2] = 0; cell->count = count; cell->stat_hp = 0; cell->flags = 0; cell->player = 0; } -#define MAX_HEAD_POS MAX(MAX_CLIENT_X, MAX_CLIENT_Y) #define MAX_LAYERS 3 -/* Using a global really isn't a good approach, but saves the over head of - * allocating and deallocating such a block of data each time run through, - * and saves the space of allocating this in the socket object when we only - * need it for this cycle. If the server is ever threaded, this needs to be - * re-examined. - */ -static object *heads[MAX_HEAD_POS * MAX_HEAD_POS * MAX_LAYERS]; - -/** - * Returns true if any of the heads for this - * space is set. Returns false if all are blank - this is used - * for empty space checking. - */ -static inline int -have_head (int ax, int ay) -{ - if (heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS] || - heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + 1] || heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + 2]) - return 1; - - return 0; -} - -/** - * check_head is a bit simplistic version of update_space below. - * basically, it only checks the that the head on space ax,ay at layer - * needs to get sent - if so, it adds the data, sending the head - * if needed, and returning 1. If this no data needs to get - * sent, it returns zero. - */ -static int -check_head (packet &sl, client &ns, int ax, int ay, int layer) -{ - short face_num; - - if (heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer]) - face_num = heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer]->face; - else - face_num = 0; - - if (face_num != ns.lastmap.cells[ax][ay].faces[layer]) - { - sl << uint16 (face_num); - if (face_num && !(ns.faces_sent[face_num] & NS_FACESENT_FACE)) - esrv_send_face (&ns, face_num, 0); - - heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer] = NULL; - ns.lastmap.cells[ax][ay].faces[layer] = face_num; - return 1; - } - - return 0; /* No change */ -} - /** * Removes the need to replicate the same code for each layer. * this returns true if this space is now in fact different than @@ -1258,49 +1203,10 @@ static int update_space (packet &sl, client &ns, maptile *mp, int mx, int my, int sx, int sy, int layer) { - object *ob, *head; uint16 face_num; int bx, by, i; - /* If there is a multipart object stored away, treat that as more important. - * If not, then do the normal processing. - */ - head = heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer]; - - /* Check to see if this head is part of the set of objects - * we would normally send for this space. If so, then - * don't use the head value. We need to do the check - * here and not when setting up the heads[] value for two reasons - - * 1) the heads[] values will get used even if the space is not visible. - * 2) its possible the head is not on the same map as a part, and I'd - * rather not need to do the map translation overhead. - * 3) We need to do some extra checking to make sure that we will - * otherwise send the image as this layer, eg, either it matches - * the head value, or is not multipart. - */ - if (head && !head->more) - { - for (i = 0; i < MAP_LAYERS; i++) - { - ob = GET_MAP_FACE_OBJ (mp, mx, my, i); - if (!ob) - continue; - - if (ob->head) - ob = ob->head; - - if (ob == head) - { - heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer] = NULL; - head = NULL; - break; - } - } - } - - ob = head; - if (!ob) - ob = GET_MAP_FACE_OBJ (mp, mx, my, layer); + object *ob = GET_MAP_FACE_OBJ (mp, mx, my, layer); /* If there is no object for this space, or if the face for the object * is the blank face, set the face number to zero. @@ -1310,137 +1216,11 @@ */ if (!ob || ob->face == blank_face) face_num = 0; - else if (head) - { - /* if this is a head that had previously been stored */ - face_num = ob->face; - } else - { - /* if the faces for the different parts of a multipart object - * are the same, we only want to send the bottom right most - * portion of the object. That info is in the tail_.. values - * of the head. Note that for the head itself, ob->head will - * be null, so we only do this block if we are working on - * a tail piece. - */ - - /* tail_x and tail_y will only be set in the head object. If - * this is the head object and these are set, we proceed - * with logic to only send bottom right. Similarly, if - * this is one of the more parts but the head has those values - * set, we want to do the processing. There can be cases where - * the head is not visible but one of its parts is, so we just - * can always expect that ob->arch->tail_x will be true for all - * object we may want to display. - */ - if ((ob->arch->tail_x || ob->arch->tail_y) || (ob->head && (ob->head->arch->tail_x || ob->head->arch->tail_y))) - { - - if (ob->head) - head = ob->head; - else - head = ob; - - /* Basically figure out where the offset is from where we are right - * now. the ob->arch->clone.{x,y} values hold the offset that this current - * piece is from the head, and the tail is where the tail is from the - * head. Note that bx and by will equal sx and sy if we are already working - * on the bottom right corner. If ob is the head, the clone values - * will be zero, so the right thing will still happen. - */ - bx = sx + head->arch->tail_x - ob->arch->clone.x; - by = sy + head->arch->tail_y - ob->arch->clone.y; - - /* I don't think this can ever happen, but better to check for it just - * in case. - */ - if (bx < sx || by < sy) - { - LOG (llevError, "update_space: bx (%d) or by (%d) is less than sx (%d) or sy (%d)\n", bx, by, sx, sy); - face_num = 0; - } - /* single part object, multipart object with non merged faces, - * of multipart object already at lower right. - */ - else if (bx == sx && by == sy) - { - face_num = ob->face; - - /* if this face matches one stored away, clear that one away. - * this code relies on the fact that the map1 commands - * goes from 2 down to 0. - */ - for (i = 0; i < MAP_LAYERS; i++) - if (heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + i] && - heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + i]->face == face_num) - heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + i] = NULL; - } - else - { - /* If this head is stored away, clear it - otherwise, - * there can be cases where a object is on multiple layers - - * we only want to send it once. - */ - face_num = head->face; - for (i = 0; i < MAP_LAYERS; i++) - if (heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] && - heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i]->face == face_num) - heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] = NULL; - - /* First, try to put the new head on the same layer. If that is used up, - * then find another layer. - */ - if (heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + layer] == NULL) - { - heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + layer] = head; - } - else - for (i = 0; i < MAX_LAYERS; i++) - { - if (heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] == NULL || - heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] == head) - { - heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] = head; - } - } - face_num = 0; /* Don't send this object - we'll send the head later */ - } - } - else - { - /* In this case, we are already at the lower right or single part object, - * so nothing special - */ - face_num = ob->face; - - /* clear out any head entries that have the same face as this one */ - for (bx = 0; bx < layer; bx++) - if (heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + bx] && - heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + bx]->face == face_num) - heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + bx] = NULL; - } - } /* else not already head object or blank face */ - - /* This is a real hack. Basically, if we have nothing to send for this layer, - * but there is a head on the next layer, send that instead. - * Without this, what happens is you can get the case where the player stands - * on the same space as the head. However, if you have overlapping big objects - * of the same type, what happens then is it doesn't think it needs to send - * This tends to make stacking also work/look better. - */ - if (!face_num && layer > 0 && heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer - 1]) - { - face_num = heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer - 1]->face; - heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer - 1] = NULL; - } - - /* Another hack - because of heads and whatnot, this face may match one - * we already sent for a lower layer. In that case, don't send - * this one. - */ - if (face_num && layer + 1 < MAP_LAYERS && ns.lastmap.cells[sx][sy].faces[layer + 1] == face_num) - face_num = 0; + /* In this case, we are already at the lower right or single part object, + * so nothing special + */ + face_num = ob->face; /* We've gotten what face we want to use for the object. Now see if * if it has changed since we last sent it to the client. @@ -1631,9 +1411,6 @@ estartlen = 0; } - /* Init data to zero */ - memset (heads, 0, sizeof (object *) * MAX_HEAD_POS * MAX_HEAD_POS * MAX_LAYERS); - /* x,y are the real map locations. ax, ay are viewport relative * locations. */ @@ -1672,10 +1449,6 @@ sl << uint16 (mask); - if (check_head (sl, socket, ax, ay, 2)) mask |= 0x4; - if (check_head (sl, socket, ax, ay, 1)) mask |= 0x2; - if (check_head (sl, socket, ax, ay, 0)) mask |= 0x1; - /* If all we are doing is sending 0 (blank) faces, we don't * actually need to send that - just the coordinates * with no faces tells the client to blank out the @@ -1722,7 +1495,7 @@ if (lastcell.count != -1) { sl << uint16 (mask); - map_clearcell (&lastcell, 0, 0, 0, -1); + map_clearcell (&lastcell, -1); } } else if (d > 3) @@ -1744,25 +1517,12 @@ count = -1; - if (socket.mapmode == Map1aCmd && have_head (ax, ay)) - { - /* Now check to see if any heads need to be sent */ - - if (check_head (sl, socket, ax, ay, 2)) mask |= 0x4; - if (check_head (sl, socket, ax, ay, 1)) mask |= 0x2; - if (check_head (sl, socket, ax, ay, 0)) mask |= 0x1; - - lastcell.count = count; - } - else - { - /* properly clear a previously sent big face */ - if (lastcell.faces[0] != 0 || lastcell.faces[1] != 0 || lastcell.faces[2] != 0 - || lastcell.stat_hp || lastcell.flags || lastcell.player) - need_send = 1; + /* properly clear a previously sent big face */ + if (lastcell.faces[0] != 0 || lastcell.faces[1] != 0 || lastcell.faces[2] != 0 + || lastcell.stat_hp || lastcell.flags || lastcell.player) + need_send = 1; - map_clearcell (&lastcell, 0, 0, 0, count); - } + map_clearcell (&lastcell, count); if ((mask & 0xf) || need_send) sl[oldlen + 1] = mask & 0xff;