1 | /* |
1 | /* |
2 | * static char *rcsid_init_c = |
2 | * static char *rcsid_init_c = |
3 | * "$Id: request.C,v 1.2 2006/08/17 20:23:32 root Exp $"; |
3 | * "$Id: request.C,v 1.9 2006/08/24 17:29:30 root Exp $"; |
4 | */ |
4 | */ |
5 | |
5 | |
6 | /* |
6 | /* |
7 | CrossFire, A Multiplayer game for X-windows |
7 | CrossFire, A Multiplayer game for X-windows |
8 | |
8 | |
… | |
… | |
163 | * empty). |
163 | * empty). |
164 | */ |
164 | */ |
165 | ns->sent_scroll = 1; |
165 | ns->sent_scroll = 1; |
166 | } |
166 | } |
167 | |
167 | |
|
|
168 | static void |
|
|
169 | clear_map (player *pl) |
|
|
170 | { |
|
|
171 | NewSocket &socket = pl->socket; |
|
|
172 | |
|
|
173 | memset (&socket.lastmap, 0, sizeof (socket.lastmap)); |
|
|
174 | |
|
|
175 | if (socket.newmapcmd == 1) |
|
|
176 | Write_String_To_Socket (&socket, "newmap", 6); |
|
|
177 | |
|
|
178 | socket.update_look = 1; |
|
|
179 | socket.look_position = 0; |
|
|
180 | } |
|
|
181 | |
168 | /** check for map change and send new map data */ |
182 | /** check for map change and send new map data */ |
169 | static void |
183 | static void |
170 | check_map_change (player *pl) |
184 | check_map_change (player *pl) |
171 | { |
185 | { |
172 | NewSocket &socket = pl->socket; |
186 | NewSocket &socket = pl->socket; |
… | |
… | |
174 | char buf[MAX_BUF]; /* eauugggh */ |
188 | char buf[MAX_BUF]; /* eauugggh */ |
175 | |
189 | |
176 | if (socket.current_map != ob->map) |
190 | if (socket.current_map != ob->map) |
177 | { |
191 | { |
178 | socket.current_map = ob->map; |
192 | socket.current_map = ob->map; |
179 | memset (&socket.lastmap, 0, sizeof(socket.lastmap)); |
|
|
180 | |
193 | |
181 | if (socket.newmapcmd == 1) |
194 | clear_map (pl); |
182 | Write_String_To_Socket (&socket, "newmap", 6); |
|
|
183 | |
|
|
184 | socket.update_look = 1; |
|
|
185 | socket.look_position =0; |
|
|
186 | |
195 | |
187 | if (socket.mapinfocmd) |
196 | if (socket.mapinfocmd) |
188 | { |
197 | { |
189 | if (ob->map && ob->map->path [0]) |
198 | if (ob->map && ob->map->path [0]) |
190 | { |
199 | { |
… | |
… | |
205 | Write_String_To_Socket (&socket, buf, strlen (buf)); |
214 | Write_String_To_Socket (&socket, buf, strlen (buf)); |
206 | } |
215 | } |
207 | } |
216 | } |
208 | else if (socket.current_x != ob->x || socket.current_y != ob->y) |
217 | else if (socket.current_x != ob->x || socket.current_y != ob->y) |
209 | { |
218 | { |
|
|
219 | int dx = ob->x - socket.current_x; |
|
|
220 | int dy = ob->y - socket.current_y; |
|
|
221 | |
|
|
222 | if (socket.buggy_mapscroll && (abs (dx) > 8 || abs (dy) > 8)) |
|
|
223 | clear_map (pl); // current (<= 1.9.1) clients have unchecked buffer overflows |
|
|
224 | else |
|
|
225 | { |
210 | socket_map_scroll (&socket, ob->x - socket.current_x, ob->y - socket.current_y); |
226 | socket_map_scroll (&socket, ob->x - socket.current_x, ob->y - socket.current_y); |
211 | socket.update_look = 1; |
227 | socket.update_look = 1; |
212 | socket.look_position = 0; |
228 | socket.look_position = 0; |
|
|
229 | } |
213 | } |
230 | } |
214 | |
231 | |
215 | socket.current_x = ob->x; |
232 | socket.current_x = ob->x; |
216 | socket.current_y = ob->y; |
233 | socket.current_y = ob->y; |
217 | } |
234 | } |
… | |
… | |
368 | ns->mapinfocmd = atoi(param); |
385 | ns->mapinfocmd = atoi(param); |
369 | safe_strcat(cmdback, "1", &slen, HUGE_BUF); |
386 | safe_strcat(cmdback, "1", &slen, HUGE_BUF); |
370 | } else if (!strcmp(cmd,"extcmd")) { |
387 | } else if (!strcmp(cmd,"extcmd")) { |
371 | ns->extcmd = atoi(param); |
388 | ns->extcmd = atoi(param); |
372 | safe_strcat(cmdback, "1", &slen, HUGE_BUF); |
389 | safe_strcat(cmdback, "1", &slen, HUGE_BUF); |
|
|
390 | } else if (!strcmp(cmd,"extmap")) { |
|
|
391 | ns->extmap = atoi(param); |
|
|
392 | safe_strcat(cmdback, "1", &slen, HUGE_BUF); |
373 | } else if (!strcmp(cmd,"facecache")) { |
393 | } else if (!strcmp(cmd,"facecache")) { |
374 | ns->facecache = atoi(param); |
394 | ns->facecache = atoi(param); |
375 | safe_strcat(cmdback, param, &slen, HUGE_BUF); |
395 | safe_strcat(cmdback, param, &slen, HUGE_BUF); |
376 | } else if (!strcmp(cmd,"faceset")) { |
396 | } else if (!strcmp(cmd,"faceset")) { |
377 | char tmpbuf[20]; |
397 | char tmpbuf[20]; |
… | |
… | |
820 | } |
840 | } |
821 | cp = strchr(cp+1, ' '); |
841 | cp = strchr(cp+1, ' '); |
822 | if (cp) { |
842 | if (cp) { |
823 | LOG(llevDebug,"CS: connection from client of type <%s>, ip %s\n", cp, ns->host); |
843 | LOG(llevDebug,"CS: connection from client of type <%s>, ip %s\n", cp, ns->host); |
824 | |
844 | |
|
|
845 | snprintf (ns->client, sizeof (ns->client), "%s", cp + 1); |
|
|
846 | |
825 | /* This is first implementation - i skip all beta DX clients with it |
847 | /* This is first implementation - i skip all beta DX clients with it |
826 | * Add later stuff here for other clients |
848 | * Add later stuff here for other clients |
827 | */ |
849 | */ |
828 | |
850 | |
829 | /* these are old dxclients */ |
851 | /* these are old dxclients */ |
… | |
… | |
1265 | |
1287 | |
1266 | |
1288 | |
1267 | /** Clears a map cell */ |
1289 | /** Clears a map cell */ |
1268 | static void map_clearcell(struct MapCell *cell, int face0, int face1, int face2, int count) |
1290 | static void map_clearcell(struct MapCell *cell, int face0, int face1, int face2, int count) |
1269 | { |
1291 | { |
1270 | cell->count=count; |
|
|
1271 | cell->faces[0] = face0; |
1292 | cell->faces[0] = face0; |
1272 | cell->faces[1] = face1; |
1293 | cell->faces[1] = face1; |
1273 | cell->faces[2] = face2; |
1294 | cell->faces[2] = face2; |
|
|
1295 | cell->count = count; |
|
|
1296 | cell->stat_hp = 0; |
|
|
1297 | cell->player = 0; |
1274 | } |
1298 | } |
1275 | |
1299 | |
1276 | #define MAX_HEAD_POS MAX(MAX_CLIENT_X, MAX_CLIENT_Y) |
1300 | #define MAX_HEAD_POS MAX(MAX_CLIENT_X, MAX_CLIENT_Y) |
1277 | #define MAX_LAYERS 3 |
1301 | #define MAX_LAYERS 3 |
1278 | |
1302 | |
… | |
… | |
1303 | * basically, it only checks the that the head on space ax,ay at layer |
1327 | * basically, it only checks the that the head on space ax,ay at layer |
1304 | * needs to get sent - if so, it adds the data, sending the head |
1328 | * needs to get sent - if so, it adds the data, sending the head |
1305 | * if needed, and returning 1. If this no data needs to get |
1329 | * if needed, and returning 1. If this no data needs to get |
1306 | * sent, it returns zero. |
1330 | * sent, it returns zero. |
1307 | */ |
1331 | */ |
1308 | static inline int check_head(SockList *sl, NewSocket *ns, int ax, int ay, int layer) |
1332 | static int check_head (SockList &sl, NewSocket &ns, int ax, int ay, int layer) |
1309 | { |
1333 | { |
1310 | short face_num; |
1334 | short face_num; |
1311 | |
1335 | |
1312 | if (heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer]) |
1336 | if (heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer]) |
1313 | face_num = heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer]->face->number; |
1337 | face_num = heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer]->face->number; |
1314 | else |
1338 | else |
1315 | face_num = 0; |
1339 | face_num = 0; |
1316 | |
1340 | |
1317 | if (face_num != ns->lastmap.cells[ax][ay].faces[layer]) { |
1341 | if (face_num != ns.lastmap.cells[ax][ay].faces[layer]) { |
1318 | SockList_AddShort(sl, face_num); |
1342 | SockList_AddShort (&sl, face_num); |
1319 | if (face_num && !(ns->faces_sent[face_num] & NS_FACESENT_FACE)) |
1343 | if (face_num && !(ns.faces_sent[face_num] & NS_FACESENT_FACE)) |
1320 | esrv_send_face(ns, face_num, 0); |
1344 | esrv_send_face (&ns, face_num, 0); |
1321 | heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer] = NULL; |
1345 | heads[(ay * MAX_HEAD_POS + ax) * MAX_LAYERS + layer] = NULL; |
1322 | ns->lastmap.cells[ax][ay].faces[layer] = face_num; |
1346 | ns.lastmap.cells[ax][ay].faces[layer] = face_num; |
1323 | return 1; |
1347 | return 1; |
1324 | } |
1348 | } |
1325 | |
1349 | |
1326 | return 0; /* No change */ |
1350 | return 0; /* No change */ |
1327 | } |
1351 | } |
… | |
… | |
1344 | * the map command, where the faces stack up. Sinces that is no longer |
1368 | * the map command, where the faces stack up. Sinces that is no longer |
1345 | * the case, it seems to make more sense to have these layer values |
1369 | * the case, it seems to make more sense to have these layer values |
1346 | * actually match. |
1370 | * actually match. |
1347 | */ |
1371 | */ |
1348 | |
1372 | |
1349 | static inline int update_space(SockList *sl, NewSocket *ns, mapstruct *mp, int mx, int my, int sx, int sy, int layer) |
1373 | static int update_space(SockList *sl, NewSocket *ns, mapstruct *mp, int mx, int my, int sx, int sy, int layer) |
1350 | { |
1374 | { |
1351 | object *ob, *head; |
1375 | object *ob, *head; |
1352 | uint16 face_num; |
1376 | uint16 face_num; |
1353 | int bx, by,i; |
1377 | int bx, by,i; |
1354 | |
1378 | |
… | |
… | |
1623 | uint16 mask,emask; |
1647 | uint16 mask,emask; |
1624 | uint8 eentrysize; |
1648 | uint8 eentrysize; |
1625 | uint16 ewhatstart,ewhatflag; |
1649 | uint16 ewhatstart,ewhatflag; |
1626 | uint8 extendedinfos; |
1650 | uint8 extendedinfos; |
1627 | mapstruct *m; |
1651 | mapstruct *m; |
|
|
1652 | NewSocket &socket = pl->contr->socket; |
1628 | |
1653 | |
1629 | check_map_change (pl->contr); |
1654 | check_map_change (pl->contr); |
1630 | |
1655 | |
1631 | sl.buf=(unsigned char*)malloc(MAXSOCKBUF); |
1656 | sl.buf=(unsigned char*)malloc(MAXSOCKBUF); |
1632 | if (pl->contr->socket.mapmode == Map1Cmd) |
1657 | if (socket.mapmode == Map1Cmd) |
1633 | strcpy((char*)sl.buf,"map1 "); |
1658 | strcpy((char*)sl.buf,"map1 "); |
1634 | else |
1659 | else |
1635 | strcpy((char*)sl.buf,"map1a "); |
1660 | strcpy((char*)sl.buf,"map1a "); |
1636 | sl.len=strlen((char*)sl.buf); |
1661 | sl.len=strlen((char*)sl.buf); |
1637 | startlen = sl.len; |
1662 | startlen = sl.len; |
1638 | /*Extendedmapinfo structure initialisation*/ |
1663 | /*Extendedmapinfo structure initialisation*/ |
1639 | if (pl->contr->socket.ext_mapinfos){ |
1664 | if (socket.ext_mapinfos){ |
1640 | esl.buf=(unsigned char*)malloc(MAXSOCKBUF); |
1665 | esl.buf=(unsigned char*)malloc(MAXSOCKBUF); |
1641 | strcpy((char*)esl.buf,"mapextended "); |
1666 | strcpy((char*)esl.buf,"mapextended "); |
1642 | esl.len=strlen((char*)esl.buf); |
1667 | esl.len=strlen((char*)esl.buf); |
1643 | extendedinfos=EMI_NOREDRAW; |
1668 | extendedinfos=EMI_NOREDRAW; |
1644 | if (pl->contr->socket.EMI_smooth) |
1669 | if (socket.EMI_smooth) |
1645 | extendedinfos|=EMI_SMOOTH; |
1670 | extendedinfos|=EMI_SMOOTH; |
1646 | ewhatstart=esl.len; |
1671 | ewhatstart=esl.len; |
1647 | ewhatflag=extendedinfos; /*The EMI_NOREDRAW bit |
1672 | ewhatflag=extendedinfos; /*The EMI_NOREDRAW bit |
1648 | could need to be taken away*/ |
1673 | could need to be taken away*/ |
1649 | SockList_AddChar(&esl, extendedinfos); |
1674 | SockList_AddChar(&esl, extendedinfos); |
1650 | eentrysize=getExtendedMapInfoSize(&(pl->contr->socket)); |
1675 | eentrysize=getExtendedMapInfoSize(&socket); |
1651 | SockList_AddChar(&esl, eentrysize); |
1676 | SockList_AddChar(&esl, eentrysize); |
1652 | estartlen = esl.len; |
1677 | estartlen = esl.len; |
1653 | } else { |
1678 | } else { |
1654 | /* suppress compiler warnings */ |
1679 | /* suppress compiler warnings */ |
1655 | ewhatstart = 0; |
1680 | ewhatstart = 0; |
… | |
… | |
1665 | ay=0; |
1690 | ay=0; |
1666 | |
1691 | |
1667 | /* We could do this logic as conditionals in the if statement, |
1692 | /* We could do this logic as conditionals in the if statement, |
1668 | * but that started to get a bit messy to look at. |
1693 | * but that started to get a bit messy to look at. |
1669 | */ |
1694 | */ |
1670 | max_x = pl->x+(pl->contr->socket.mapx+1)/2; |
1695 | max_x = pl->x+(socket.mapx+1)/2; |
1671 | max_y = pl->y+(pl->contr->socket.mapy+1)/2; |
1696 | max_y = pl->y+(socket.mapy+1)/2; |
1672 | if (pl->contr->socket.mapmode == Map1aCmd) { |
1697 | if (socket.mapmode == Map1aCmd) { |
1673 | max_x += MAX_HEAD_OFFSET; |
1698 | max_x += MAX_HEAD_OFFSET; |
1674 | max_y += MAX_HEAD_OFFSET; |
1699 | max_y += MAX_HEAD_OFFSET; |
1675 | } |
1700 | } |
1676 | |
1701 | |
1677 | for(y=pl->y-pl->contr->socket.mapy/2; y<max_y; y++,ay++) { |
1702 | for(y=pl->y-socket.mapy/2; y<max_y; y++,ay++) { |
1678 | ax=0; |
1703 | ax=0; |
1679 | for(x=pl->x-pl->contr->socket.mapx/2;x<max_x;x++,ax++) { |
1704 | for(x=pl->x-socket.mapx/2;x<max_x;x++,ax++) { |
1680 | |
1705 | |
1681 | emask = mask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4; |
1706 | emask = mask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4; |
1682 | |
1707 | |
1683 | /* If this space is out of the normal viewable area, we only check |
1708 | /* If this space is out of the normal viewable area, we only check |
1684 | * the heads value ax or ay will only be greater than what |
1709 | * the heads value ax or ay will only be greater than what |
1685 | * the client wants if using the map1a command - this is because |
1710 | * the client wants if using the map1a command - this is because |
1686 | * if the map1a command is not used, max_x and max_y will be |
1711 | * if the map1a command is not used, max_x and max_y will be |
1687 | * set to lower values. |
1712 | * set to lower values. |
1688 | */ |
1713 | */ |
1689 | if (ax >= pl->contr->socket.mapx || ay >= pl->contr->socket.mapy) { |
1714 | if (ax >= socket.mapx || ay >= socket.mapy) { |
1690 | int i, got_one; |
1715 | int i, got_one; |
1691 | |
1716 | |
1692 | oldlen = sl.len; |
1717 | oldlen = sl.len; |
1693 | |
1718 | |
1694 | |
|
|
1695 | SockList_AddShort(&sl, mask); |
1719 | SockList_AddShort(&sl, mask); |
1696 | |
1720 | |
1697 | if (check_head(&sl, &pl->contr->socket, ax, ay, 2)) |
1721 | if (check_head (sl, socket, ax, ay, 2)) |
1698 | mask |= 0x4; |
1722 | mask |= 0x4; |
1699 | if (check_head(&sl, &pl->contr->socket, ax, ay, 1)) |
1723 | if (check_head (sl, socket, ax, ay, 1)) |
1700 | mask |= 0x2; |
1724 | mask |= 0x2; |
1701 | if (check_head(&sl, &pl->contr->socket, ax, ay, 0)) |
1725 | if (check_head (sl, socket, ax, ay, 0)) |
1702 | mask |= 0x1; |
1726 | mask |= 0x1; |
1703 | |
1727 | |
1704 | /* If all we are doing is sending 0 (blank) faces, we don't |
1728 | /* If all we are doing is sending 0 (blank) faces, we don't |
1705 | * actually need to send that - just the coordinates |
1729 | * actually need to send that - just the coordinates |
1706 | * with no faces tells the client to blank out the |
1730 | * with no faces tells the client to blank out the |
… | |
… | |
1712 | } |
1736 | } |
1713 | |
1737 | |
1714 | if (got_one && (mask & 0xf)) { |
1738 | if (got_one && (mask & 0xf)) { |
1715 | sl.buf[oldlen+1] = mask & 0xff; |
1739 | sl.buf[oldlen+1] = mask & 0xff; |
1716 | } else { /*either all faces blank, either no face at all*/ |
1740 | } else { /*either all faces blank, either no face at all*/ |
1717 | if (mask & 0xf) /*at least 1 face, we know it's blank, only send coordinates*/ |
1741 | if (mask & 0xf) /*at least 1 face, we know it's blank, only send coordinates*/ |
1718 | sl.len = oldlen + 2; |
1742 | sl.len = oldlen + 2; |
1719 | else |
1743 | else |
1720 | sl.len = oldlen; |
1744 | sl.len = oldlen; |
1721 | } |
1745 | } |
1722 | /*What concerns extendinfos, nothing to be done for now |
1746 | /*What concerns extendinfos, nothing to be done for now |
1723 | * (perhaps effects layer later) |
1747 | * (perhaps effects layer later) |
1724 | */ |
1748 | */ |
1725 | continue; /* don't do processing below */ |
1749 | continue; /* don't do processing below */ |
1726 | } |
1750 | } |
|
|
1751 | |
|
|
1752 | MapCell &lastcell = socket.lastmap.cells[ax][ay]; |
1727 | |
1753 | |
1728 | d = pl->contr->blocked_los[ax][ay]; |
1754 | d = pl->contr->blocked_los[ax][ay]; |
1729 | |
1755 | |
1730 | /* If the coordinates are not valid, or it is too dark to see, |
1756 | /* If the coordinates are not valid, or it is too dark to see, |
1731 | * we tell the client as such |
1757 | * we tell the client as such |
… | |
… | |
1736 | if (!m) { |
1762 | if (!m) { |
1737 | /* space is out of map. Update space and clear values |
1763 | /* space is out of map. Update space and clear values |
1738 | * if this hasn't already been done. If the space is out |
1764 | * if this hasn't already been done. If the space is out |
1739 | * of the map, it shouldn't have a head |
1765 | * of the map, it shouldn't have a head |
1740 | */ |
1766 | */ |
1741 | if (pl->contr->socket.lastmap.cells[ax][ay].count != -1) { |
1767 | if (lastcell.count != -1) { |
1742 | SockList_AddShort(&sl, mask); |
1768 | SockList_AddShort(&sl, mask); |
1743 | map_clearcell(&pl->contr->socket.lastmap.cells[ax][ay],0,0,0,-1); |
1769 | map_clearcell(&lastcell,0,0,0,-1); |
1744 | } |
1770 | } |
1745 | } else if (d>3) { |
1771 | } else if (d>3) { |
1746 | int need_send=0, count; |
1772 | int need_send=0, count; |
1747 | /* This block deals with spaces that are not visible for whatever |
1773 | /* This block deals with spaces that are not visible for whatever |
1748 | * reason. Still may need to send the head for this space. |
1774 | * reason. Still may need to send the head for this space. |
1749 | */ |
1775 | */ |
1750 | |
1776 | |
1751 | oldlen = sl.len; |
1777 | oldlen = sl.len; |
1752 | #if 0 |
1778 | |
1753 | /* First thing we do is blank out this space (clear it) |
|
|
1754 | * if not already done. If the client is using darkness, and |
|
|
1755 | * this space is at the edge, we also include the darkness. |
|
|
1756 | */ |
|
|
1757 | if (d==4) { |
|
|
1758 | if (pl->contr->socket.darkness && pl->contr->socket.lastmap.cells[ax][ay].count != d) { |
|
|
1759 | mask |= 8; |
|
|
1760 | SockList_AddShort(&sl, mask); |
|
|
1761 | SockList_AddChar(&sl, 0); |
|
|
1762 | } |
|
|
1763 | count = d; |
|
|
1764 | } else |
|
|
1765 | #endif |
|
|
1766 | { |
|
|
1767 | SockList_AddShort(&sl, mask); |
1779 | SockList_AddShort(&sl, mask); |
1768 | if (pl->contr->socket.lastmap.cells[ax][ay].count != -1) need_send=1; |
1780 | if (lastcell.count != -1) need_send=1; |
1769 | count = -1; |
1781 | count = -1; |
1770 | } |
|
|
1771 | |
1782 | |
1772 | if (pl->contr->socket.mapmode == Map1aCmd && have_head(ax, ay)) { |
1783 | if (socket.mapmode == Map1aCmd && have_head(ax, ay)) { |
1773 | /* Now check to see if any heads need to be sent */ |
1784 | /* Now check to see if any heads need to be sent */ |
1774 | |
1785 | |
1775 | if (check_head(&sl, &pl->contr->socket, ax, ay, 2)) |
1786 | if (check_head (sl, socket, ax, ay, 2)) |
1776 | mask |= 0x4; |
1787 | mask |= 0x4; |
1777 | if (check_head(&sl, &pl->contr->socket, ax, ay, 1)) |
1788 | if (check_head (sl, socket, ax, ay, 1)) |
1778 | mask |= 0x2; |
1789 | mask |= 0x2; |
1779 | if (check_head(&sl, &pl->contr->socket, ax, ay, 0)) |
1790 | if (check_head (sl, socket, ax, ay, 0)) |
1780 | mask |= 0x1; |
1791 | mask |= 0x1; |
1781 | pl->contr->socket.lastmap.cells[ax][ay].count = count; |
1792 | |
|
|
1793 | lastcell.count = count; |
1782 | |
1794 | |
1783 | } else { |
1795 | } else { |
1784 | struct MapCell *cell = &pl->contr->socket.lastmap.cells[ax][ay]; |
1796 | struct MapCell *cell = &lastcell; |
1785 | /* properly clear a previously sent big face */ |
1797 | /* properly clear a previously sent big face */ |
1786 | if(cell->faces[0] != 0 |
1798 | if(cell->faces[0] != 0 |
1787 | || cell->faces[1] != 0 |
1799 | || cell->faces[1] != 0 |
1788 | || cell->faces[2] != 0) |
1800 | || cell->faces[2] != 0) |
1789 | need_send = 1; |
1801 | need_send = 1; |
1790 | map_clearcell(&pl->contr->socket.lastmap.cells[ax][ay], 0, 0, 0, count); |
1802 | map_clearcell(&lastcell, 0, 0, 0, count); |
1791 | } |
1803 | } |
1792 | |
1804 | |
1793 | if ((mask & 0xf) || need_send) { |
1805 | if ((mask & 0xf) || need_send) { |
1794 | sl.buf[oldlen+1] = mask & 0xff; |
1806 | sl.buf[oldlen+1] = mask & 0xff; |
1795 | } else { |
1807 | } else { |
… | |
… | |
1814 | mask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4; |
1826 | mask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4; |
1815 | eoldlen = esl.len; |
1827 | eoldlen = esl.len; |
1816 | emask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4; |
1828 | emask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4; |
1817 | SockList_AddShort(&sl, mask); |
1829 | SockList_AddShort(&sl, mask); |
1818 | |
1830 | |
1819 | if (pl->contr->socket.ext_mapinfos) |
1831 | if (socket.ext_mapinfos) |
1820 | SockList_AddShort(&esl, emask); |
1832 | SockList_AddShort(&esl, emask); |
1821 | |
1833 | |
|
|
1834 | unsigned char dummy; |
|
|
1835 | unsigned char *last_ext = &dummy; |
|
|
1836 | |
1822 | /* Darkness changed */ |
1837 | /* Darkness changed */ |
1823 | if (pl->contr->socket.lastmap.cells[ax][ay].count != d && pl->contr->socket.darkness) { |
1838 | if (lastcell.count != d && socket.darkness) { |
1824 | pl->contr->socket.lastmap.cells[ax][ay].count = d; |
1839 | mask |= 0x8; |
1825 | mask |= 0x8; /* darkness bit */ |
|
|
1826 | |
1840 | |
1827 | /* Protocol defines 255 full bright, 0 full dark. |
1841 | if (socket.extmap) |
1828 | * We currently don't have that many darkness ranges, |
1842 | { |
1829 | * so we current what limited values we do have. |
1843 | *last_ext |= 0x80; last_ext = sl.buf + sl.len; SockList_AddChar (&sl, d); |
1830 | */ |
1844 | } |
1831 | if (d==0) SockList_AddChar(&sl, 255); |
1845 | else |
1832 | else if (d==1) SockList_AddChar(&sl, 191); |
1846 | SockList_AddChar (&sl, 255 - 64 * d); |
1833 | else if (d==2) SockList_AddChar(&sl, 127); |
|
|
1834 | else if (d==3) SockList_AddChar(&sl, 63); |
|
|
1835 | } |
1847 | } |
1836 | else { |
1848 | |
1837 | /* need to reset from -1 so that if it does become blocked again, |
1849 | lastcell.count = d; |
1838 | * the code that deals with that can detect that it needs to tell |
1850 | |
1839 | * the client that this space is now blocked. |
1851 | if (socket.extmap) |
1840 | */ |
1852 | { |
1841 | pl->contr->socket.lastmap.cells[ax][ay].count = d; |
1853 | uint8 stat_hp = 0; |
1842 | } |
1854 | uint8 stat_width = 0; |
|
|
1855 | tag_t player = 0; |
|
|
1856 | |
|
|
1857 | // send hp information, if applicable |
|
|
1858 | if (object *op = GET_MAP_FACE_OBJ (m, nx, ny, 0)) |
|
|
1859 | { |
|
|
1860 | if (op->head || op->invisible) |
|
|
1861 | ; // do not show |
|
|
1862 | else if (op->type == PLAYER |
|
|
1863 | || QUERY_FLAG (op, FLAG_MONSTER) |
|
|
1864 | || QUERY_FLAG (op, FLAG_ALIVE) |
|
|
1865 | || QUERY_FLAG (op, FLAG_GENERATOR)) |
|
|
1866 | { |
|
|
1867 | if (op->stats.maxhp > 0 |
|
|
1868 | && (unsigned)op->stats.maxhp > (unsigned)op->stats.hp) |
|
|
1869 | { |
|
|
1870 | stat_hp = 255 - (op->stats.hp * 255 + 254) / op->stats.maxhp; |
|
|
1871 | stat_width = op->arch->tail_x; |
|
|
1872 | } |
|
|
1873 | } |
|
|
1874 | |
|
|
1875 | if (op->type == PLAYER && op != pl) |
|
|
1876 | player = op->count; |
|
|
1877 | } |
|
|
1878 | |
|
|
1879 | if (lastcell.stat_hp != stat_hp && 0) |
|
|
1880 | { |
|
|
1881 | lastcell.stat_hp = stat_hp; |
|
|
1882 | |
|
|
1883 | mask |= 0x8; |
|
|
1884 | *last_ext |= 0x80; last_ext = sl.buf + sl.len; SockList_AddChar (&sl, 5); |
|
|
1885 | SockList_AddChar (&sl, stat_hp); |
|
|
1886 | |
|
|
1887 | if (stat_width > 1) |
|
|
1888 | { |
|
|
1889 | *last_ext |= 0x80; last_ext = sl.buf + sl.len; SockList_AddChar (&sl, 6); |
|
|
1890 | SockList_AddChar (&sl, stat_width); |
|
|
1891 | } |
|
|
1892 | } |
|
|
1893 | |
|
|
1894 | if (lastcell.player != player && 0) |
|
|
1895 | { |
|
|
1896 | lastcell.player = player; |
|
|
1897 | mask |= 0x8; |
|
|
1898 | *last_ext |= 0x80; last_ext = sl.buf + sl.len; SockList_AddChar (&sl, 0x47); |
|
|
1899 | SockList_AddChar (&sl, 4); |
|
|
1900 | SockList_AddInt (&sl, player); |
|
|
1901 | } |
|
|
1902 | } |
1843 | |
1903 | |
1844 | /* Floor face */ |
1904 | /* Floor face */ |
1845 | if (update_space(&sl, &pl->contr->socket, m, nx, ny, ax, ay, 2)) |
1905 | if (update_space(&sl, &socket, m, nx, ny, ax, ay, 2)) |
1846 | mask |= 0x4; |
1906 | mask |= 0x4; |
1847 | |
1907 | |
1848 | if (pl->contr->socket.EMI_smooth) |
1908 | if (socket.EMI_smooth) |
1849 | if (update_smooth(&esl, &pl->contr->socket, m, nx, ny, ax, ay, 2)){ |
1909 | if (update_smooth(&esl, &socket, m, nx, ny, ax, ay, 2)) |
1850 | emask |= 0x4; |
1910 | emask |= 0x4; |
1851 | } |
|
|
1852 | |
1911 | |
1853 | /* Middle face */ |
1912 | /* Middle face */ |
1854 | if (update_space(&sl, &pl->contr->socket, m, nx, ny, ax, ay, 1)) |
1913 | if (update_space(&sl, &socket, m, nx, ny, ax, ay, 1)) |
1855 | mask |= 0x2; |
1914 | mask |= 0x2; |
1856 | |
1915 | |
1857 | if (pl->contr->socket.EMI_smooth) |
1916 | if (socket.EMI_smooth) |
1858 | if (update_smooth(&esl, &pl->contr->socket, m, nx, ny, ax, ay, 1)){ |
1917 | if (update_smooth(&esl, &socket, m, nx, ny, ax, ay, 1)) |
1859 | emask |= 0x2; |
1918 | emask |= 0x2; |
1860 | } |
|
|
1861 | |
|
|
1862 | |
1919 | |
1863 | if(nx == pl->x && ny == pl->y && pl->invisible & (pl->invisible < 50 ? 4 : 1)) { |
1920 | if(nx == pl->x && ny == pl->y && pl->invisible & (pl->invisible < 50 ? 4 : 1)) { |
1864 | if (pl->contr->socket.lastmap.cells[ax][ay].faces[0] != pl->face->number) { |
1921 | if (lastcell.faces[0] != pl->face->number) { |
1865 | pl->contr->socket.lastmap.cells[ax][ay].faces[0] = pl->face->number; |
1922 | lastcell.faces[0] = pl->face->number; |
1866 | mask |= 0x1; |
1923 | mask |= 0x1; |
1867 | if (!(pl->contr->socket.faces_sent[pl->face->number] &NS_FACESENT_FACE)) |
1924 | if (!(socket.faces_sent[pl->face->number] &NS_FACESENT_FACE)) |
1868 | esrv_send_face(&pl->contr->socket, pl->face->number, 0); |
1925 | esrv_send_face(&socket, pl->face->number, 0); |
1869 | SockList_AddShort(&sl, pl->face->number); |
1926 | SockList_AddShort(&sl, pl->face->number); |
1870 | } |
1927 | } |
1871 | } |
1928 | } |
1872 | /* Top face */ |
1929 | /* Top face */ |
1873 | else { |
1930 | else { |
1874 | if (update_space(&sl, &pl->contr->socket, m, nx, ny, ax, ay, 0)) |
1931 | if (update_space(&sl, &socket, m, nx, ny, ax, ay, 0)) |
1875 | mask |= 0x1; |
1932 | mask |= 0x1; |
1876 | if (pl->contr->socket.EMI_smooth) |
1933 | if (socket.EMI_smooth) |
1877 | if (update_smooth(&esl, &pl->contr->socket, m, nx, ny, ax, ay, 0)){ |
1934 | if (update_smooth(&esl, &socket, m, nx, ny, ax, ay, 0)){ |
1878 | emask |= 0x1; |
1935 | emask |= 0x1; |
1879 | } |
1936 | } |
1880 | } |
1937 | } |
1881 | /* Check to see if we are in fact sending anything for this |
1938 | /* Check to see if we are in fact sending anything for this |
1882 | * space by checking the mask. If so, update the mask. |
1939 | * space by checking the mask. If so, update the mask. |
… | |
… | |
1896 | } /* else this is a viewable space */ |
1953 | } /* else this is a viewable space */ |
1897 | } /* for x loop */ |
1954 | } /* for x loop */ |
1898 | } /* for y loop */ |
1955 | } /* for y loop */ |
1899 | |
1956 | |
1900 | /* Verify that we in fact do need to send this */ |
1957 | /* Verify that we in fact do need to send this */ |
1901 | if (pl->contr->socket.ext_mapinfos){ |
1958 | if (socket.ext_mapinfos){ |
1902 | if (!(sl.len>startlen || pl->contr->socket.sent_scroll)){ |
1959 | if (!(sl.len>startlen || socket.sent_scroll)){ |
1903 | /* No map data will follow, so don't say the client |
1960 | /* No map data will follow, so don't say the client |
1904 | * it doesn't need draw! |
1961 | * it doesn't need draw! |
1905 | */ |
1962 | */ |
1906 | ewhatflag&=(~EMI_NOREDRAW); |
1963 | ewhatflag&=(~EMI_NOREDRAW); |
1907 | esl.buf[ewhatstart+1] = ewhatflag & 0xff; |
1964 | esl.buf[ewhatstart+1] = ewhatflag & 0xff; |
1908 | } |
1965 | } |
1909 | if (esl.len>estartlen) { |
1966 | if (esl.len>estartlen) { |
1910 | Send_With_Handling(&pl->contr->socket, &esl); |
1967 | Send_With_Handling(&socket, &esl); |
1911 | } |
1968 | } |
1912 | free(esl.buf); |
1969 | free(esl.buf); |
1913 | } |
1970 | } |
1914 | if (sl.len>startlen || pl->contr->socket.sent_scroll) { |
1971 | if (sl.len>startlen || socket.sent_scroll) { |
1915 | Send_With_Handling(&pl->contr->socket, &sl); |
1972 | Send_With_Handling(&socket, &sl); |
1916 | pl->contr->socket.sent_scroll = 0; |
1973 | socket.sent_scroll = 0; |
1917 | } |
1974 | } |
1918 | free(sl.buf); |
1975 | free(sl.buf); |
1919 | } |
1976 | } |
1920 | |
1977 | |
1921 | /** |
1978 | /** |