version 1.70 | | version 1.71 |
---|
| | |
/* | | /* |
* static char *rcsid_init_c = | | * static char *rcsid_init_c = |
* "$Id: request.c,v 1.70 2005/08/17 08:17:31 akirschbaum Exp $"; | | * "$Id: request.c,v 1.71 2005/08/31 21:53:09 akirschbaum Exp $"; |
*/ | | */ |
| | |
/* | | /* |
| | |
| | |
void MapRedrawCmd(char *buff, int len, player *pl) | | void MapRedrawCmd(char *buff, int len, player *pl) |
{ | | { |
| | /* This function is currently disabled; just clearing the map state results in |
| | * display errors. It should clear the cache and send a newmap command. |
| | * Unfortunately this solution does not work because some client versions send |
| | * a mapredraw command after receiving a newmap command. |
| | */ |
| | #if 0 |
/* Okay, this is MAJOR UGLY. but the only way I know how to | | /* Okay, this is MAJOR UGLY. but the only way I know how to |
* clear the "cache" | | * clear the "cache" |
*/ | | */ |
memset(&pl->socket.lastmap, 0, sizeof(struct Map)); | | memset(&pl->socket.lastmap, 0, sizeof(struct Map)); |
draw_client_map(pl->ob); | | draw_client_map(pl->ob); |
| | #endif |
} | | } |
| | |
/** Newmap command */ | | /** Newmap command */ |
void MapNewmapCmd( player *pl) | | void MapNewmapCmd( player *pl) |
{ | | { |
if( pl->socket.newmapcmd == 1) | | if( pl->socket.newmapcmd == 1) { |
| | memset(&pl->socket.lastmap, 0, sizeof(pl->socket.lastmap)); |
Write_String_To_Socket( &pl->socket, "newmap", 6); | | Write_String_To_Socket( &pl->socket, "newmap", 6); |
} | | } |
| | } |
| | |
| | |
| | |
| | |
cell->faces[2] = face2; | | cell->faces[2] = face2; |
} | | } |
| | |
#define MAX_HEAD_POS 31 | | #define MAX_HEAD_POS MAX(MAX_CLIENT_X, MAX_CLIENT_Y) |
#define MAX_LAYERS 3 | | #define MAX_LAYERS 3 |
| | |
/* Using a global really isn't a good approach, but saves the over head of | | /* Using a global really isn't a good approach, but saves the over head of |
| | |
static object *heads[MAX_HEAD_POS * MAX_HEAD_POS * MAX_LAYERS]; | | static object *heads[MAX_HEAD_POS * MAX_HEAD_POS * MAX_LAYERS]; |
| | |
/** | | /** |
* Returns true of any of the heads for this | | * Returns true if any of the heads for this |
* space is set. Returns 0 if all are blank - this is used | | * space is set. Returns false if all are blank - this is used |
* for empty space checking. | | * for empty space checking. |
*/ | | */ |
static inline int have_head(int ax, int ay) { | | static inline int have_head(int ax, int ay) { |
| | |
ns->lastmap.cells[ax][ay].faces[layer] = face_num; | | ns->lastmap.cells[ax][ay].faces[layer] = face_num; |
return 1; | | return 1; |
} | | } |
/* We know, for now, that check_head is only called on blocked or otherwise | | |
* out of view spaces. So if there is no head object, clear | | |
* the last look for this layer - this sort of replaces the need to | | |
* call map_clearcell. | | |
*/ | | |
if (face_num ==0 && ns->lastmap.cells[ax][ay].faces[layer] != 0) | | |
ns->lastmap.cells[ax][ay].faces[layer] = 0; | | |
| | |
return 0; /* No change */ | | return 0; /* No change */ |
} | | } |
| | |
* otherwise send the image as this layer, eg, either it matches | | * otherwise send the image as this layer, eg, either it matches |
* the head value, or is not multipart. | | * the head value, or is not multipart. |
*/ | | */ |
if (head) { | | if (head && !head->more) { |
for (i=0; i<MAP_LAYERS; i++) { | | for (i=0; i<MAP_LAYERS; i++) { |
ob = GET_MAP_FACE_OBJ(mp, mx, my, i); | | ob = GET_MAP_FACE_OBJ(mp, mx, my, i); |
if (!ob) continue; | | if (!ob) continue; |
| | |
if (ob->head) ob=ob->head; | | if (ob->head) ob=ob->head; |
| | |
if (ob->face == head->face && | | if (ob == head) { |
(ob == head && !ob->more)) { | | |
heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer] = NULL; | | heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer] = NULL; |
head = NULL; | | head = NULL; |
break; | | break; |
| | |
if (bx < sx || by < sy) { | | if (bx < sx || by < sy) { |
LOG(llevError,"update_space: bx (%d) or by (%d) is less than sx (%d) or sy (%d)\n", | | LOG(llevError,"update_space: bx (%d) or by (%d) is less than sx (%d) or sy (%d)\n", |
bx, by, sx, sy); | | bx, by, sx, sy); |
| | face_num = 0; |
} | | } |
/* single part object, multipart object with non merged faces, | | /* single part object, multipart object with non merged faces, |
* of multipart object already at lower right. | | * of multipart object already at lower right. |
| | |
/* First, try to put the new head on the same layer. If that is used up, | | /* First, try to put the new head on the same layer. If that is used up, |
* then find another layer. | | * then find another layer. |
*/ | | */ |
if (heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + layer] == NULL || | | if (heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + layer] == NULL) { |
heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + layer] == head) { | | |
heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + layer] = head; | | heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + layer] = head; |
} else for (i=0; i<MAX_LAYERS; i++) { | | } else for (i=0; i<MAX_LAYERS; i++) { |
if (heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] == NULL || | | if (heads[(by * MAX_HEAD_POS + bx) * MAX_LAYERS + i] == NULL || |
| | |
* we already sent for a lower layer. In that case, don't send | | * we already sent for a lower layer. In that case, don't send |
* this one. | | * this one. |
*/ | | */ |
if (face_num && layer<MAP_LAYERS && ns->lastmap.cells[sx][sy].faces[layer+1] == face_num) { | | if (face_num && layer+1<MAP_LAYERS && ns->lastmap.cells[sx][sy].faces[layer+1] == face_num) { |
face_num = 0; | | face_num = 0; |
} | | } |
| | |
| | |
| | |
static inline int update_smooth(SockList *sl, NewSocket *ns, mapstruct *mp, int mx, int my, int sx, int sy, int layer) | | static inline int update_smooth(SockList *sl, NewSocket *ns, mapstruct *mp, int mx, int my, int sx, int sy, int layer) |
{ | | { |
object *ob, *head; | | object *ob; |
int smoothlevel; /* old face_num;*/ | | int smoothlevel; /* old face_num;*/ |
| | |
/* If there is a multipart object stored away, treat that as more important. | | |
* If not, then do the normal processing. | | |
*/ | | |
ob=NULL; | | |
head = heads[(sy * MAX_HEAD_POS + sx) * MAX_LAYERS + layer]; | | |
| | |
ob = GET_MAP_FACE_OBJ(mp, mx, my, layer); | | ob = GET_MAP_FACE_OBJ(mp, mx, my, layer); |
| | |
/* If there is no object for this space, or if the face for the object | | /* If there is no object for this space, or if the face for the object |
| | |
pl->contr->socket.lastmap.cells[ax][ay].count = count; | | pl->contr->socket.lastmap.cells[ax][ay].count = count; |
| | |
} else { | | } else { |
| | struct MapCell *cell = &pl->contr->socket.lastmap.cells[ax][ay]; |
| | /* properly clear a previously sent big face */ |
| | if(cell->faces[0] != 0 |
| | || cell->faces[1] != 0 |
| | || cell->faces[2] != 0) |
| | need_send = 1; |
map_clearcell(&pl->contr->socket.lastmap.cells[ax][ay], 0, 0, 0, count); | | map_clearcell(&pl->contr->socket.lastmap.cells[ax][ay], 0, 0, 0, count); |
} | | } |
| | |
| | |
return; | | return; |
} | | } |
| | |
if(pl->map == NULL || pl->map->in_memory != MAP_IN_MEMORY) { | | |
LOG(llevError,"draw_client_map called with no map/map out of memory\n"); | | |
return; | | |
} | | |
| | |
| | |
/* IF player is just joining the game, he isn't here yet, so the map | | /* IF player is just joining the game, he isn't here yet, so the map |
* can get swapped out. If so, don't try to send them a map. All will | | * can get swapped out. If so, don't try to send them a map. All will |
* be OK once they really log in. | | * be OK once they really log in. |
*/ | | */ |
if (pl->map==NULL || pl->map->in_memory!=MAP_IN_MEMORY) return; | | if (pl->map==NULL || pl->map->in_memory!=MAP_IN_MEMORY) return; |
| | |
memset(&newmap, 0, sizeof(struct Map)); | | memset(&newmap, 0, sizeof(struct Map)); |
| | |
for(j = (pl->y - pl->contr->socket.mapy/2) ; j < (pl->y + (pl->contr->socket.mapy+1)/2); j++) { | | for(j = (pl->y - pl->contr->socket.mapy/2) ; j < (pl->y + (pl->contr->socket.mapy+1)/2); j++) { |
| | |
*/ | | */ |
for(x=0; x<mx; x++) { | | for(x=0; x<mx; x++) { |
for(y=0; y<my; y++) { | | for(y=0; y<my; y++) { |
if ((x+dx) < 0 || (x+dx) >= ns->mapx || (y+dy) < 0 || (y + dy) >= ns->mapy) { | | if(x >= ns->mapx || y >= ns->mapy) { |
| | /* clear cells outside the viewable area */ |
| | memset(&newmap.cells[x][y], 0, sizeof(struct MapCell)); |
| | } |
| | else if ((x+dx) < 0 || (x+dx) >= ns->mapx || (y+dy) < 0 || (y + dy) >= ns->mapy) { |
| | /* clear newly visible tiles within the viewable area */ |
memset(&(newmap.cells[x][y]), 0, sizeof(struct MapCell)); | | memset(&(newmap.cells[x][y]), 0, sizeof(struct MapCell)); |
} | | } |
else { | | else { |
| | |
} | | } |
| | |
memcpy(&(ns->lastmap), &newmap,sizeof(struct Map)); | | memcpy(&(ns->lastmap), &newmap,sizeof(struct Map)); |
| | |
| | /* Make sure that the next "map1" command will be sent (even if it is |
| | * empty). |
| | */ |
ns->sent_scroll = 1; | | ns->sent_scroll = 1; |
} | | } |
| | |