1 | /* |
1 | /* |
2 | * static char *rcsid_init_c = |
2 | * static char *rcsid_init_c = |
3 | * "$Id: request.C,v 1.1 2006/08/13 17:16:06 elmex Exp $"; |
3 | * "$Id: request.C,v 1.2 2006/08/17 20:23:32 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 | |
… | |
… | |
104 | -1, /* Internal */ |
104 | -1, /* Internal */ |
105 | -1, /* life stealing */ |
105 | -1, /* life stealing */ |
106 | -1 /* Disease - not fully done yet */ |
106 | -1 /* Disease - not fully done yet */ |
107 | }; |
107 | }; |
108 | |
108 | |
|
|
109 | static void |
|
|
110 | socket_map_scroll (NewSocket *ns, int dx, int dy) |
|
|
111 | { |
|
|
112 | struct Map newmap; |
|
|
113 | int x,y, mx, my; |
|
|
114 | |
|
|
115 | { |
|
|
116 | char buf[MAXSOCKBUF]; |
|
|
117 | |
|
|
118 | sprintf(buf,"map_scroll %d %d", dx, dy); |
|
|
119 | Write_String_To_Socket(ns, buf, strlen (buf)); |
|
|
120 | } |
|
|
121 | |
|
|
122 | /* If we are using the Map1aCmd, we may in fact send |
|
|
123 | * head information that is outside the viewable map. |
|
|
124 | * So set the mx,my to the max value we want to |
|
|
125 | * look for. Removed code to do so - it caused extra |
|
|
126 | * complexities for the client, and probably doesn't make |
|
|
127 | * that much difference in bandwidth. |
|
|
128 | */ |
|
|
129 | mx = ns->mapx; |
|
|
130 | my = ns->mapy; |
|
|
131 | |
|
|
132 | if (ns->mapmode == Map1aCmd) { |
|
|
133 | mx += MAX_HEAD_OFFSET; |
|
|
134 | my += MAX_HEAD_OFFSET; |
|
|
135 | } |
|
|
136 | |
|
|
137 | /* the x and y here are coordinates for the new map, i.e. if we moved |
|
|
138 | * (dx,dy), newmap[x][y] = oldmap[x-dx][y-dy]. For this reason, |
|
|
139 | * if the destination x or y coordinate is outside the viewable |
|
|
140 | * area, we clear the values - otherwise, the old values |
|
|
141 | * are preserved, and the check_head thinks it needs to clear them. |
|
|
142 | */ |
|
|
143 | for(x=0; x<mx; x++) { |
|
|
144 | for(y=0; y<my; y++) { |
|
|
145 | if(x >= ns->mapx || y >= ns->mapy) { |
|
|
146 | /* clear cells outside the viewable area */ |
|
|
147 | memset(&newmap.cells[x][y], 0, sizeof(struct MapCell)); |
|
|
148 | } |
|
|
149 | else if ((x+dx) < 0 || (x+dx) >= ns->mapx || (y+dy) < 0 || (y + dy) >= ns->mapy) { |
|
|
150 | /* clear newly visible tiles within the viewable area */ |
|
|
151 | memset(&(newmap.cells[x][y]), 0, sizeof(struct MapCell)); |
|
|
152 | } |
|
|
153 | else { |
|
|
154 | memcpy(&(newmap.cells[x][y]), |
|
|
155 | &(ns->lastmap.cells[x+dx][y+dy]),sizeof(struct MapCell)); |
|
|
156 | } |
|
|
157 | } |
|
|
158 | } |
|
|
159 | |
|
|
160 | memcpy(&(ns->lastmap), &newmap,sizeof(struct Map)); |
|
|
161 | |
|
|
162 | /* Make sure that the next "map1" command will be sent (even if it is |
|
|
163 | * empty). |
|
|
164 | */ |
|
|
165 | ns->sent_scroll = 1; |
|
|
166 | } |
|
|
167 | |
109 | /** check for map change and send new map data */ |
168 | /** check for map change and send new map data */ |
110 | static void |
169 | static void |
111 | check_map_change (player *pl) |
170 | check_map_change (player *pl) |
112 | { |
171 | { |
|
|
172 | NewSocket &socket = pl->socket; |
|
|
173 | object *ob = pl->ob; |
113 | char buf[MAX_BUF]; /* eauugggh */ |
174 | char buf[MAX_BUF]; /* eauugggh */ |
114 | |
175 | |
115 | object *ob = pl->ob; |
|
|
116 | |
|
|
117 | if (!pl->socket.mapinfocmd) |
|
|
118 | return; |
|
|
119 | |
|
|
120 | if (pl->socket.current_map != ob->map) |
176 | if (socket.current_map != ob->map) |
121 | { |
177 | { |
122 | pl->socket.current_map = ob->map; |
178 | socket.current_map = ob->map; |
|
|
179 | memset (&socket.lastmap, 0, sizeof(socket.lastmap)); |
123 | |
180 | |
124 | if (ob->map && ob->map->path [0]) |
181 | if (socket.newmapcmd == 1) |
|
|
182 | Write_String_To_Socket (&socket, "newmap", 6); |
|
|
183 | |
|
|
184 | socket.update_look = 1; |
|
|
185 | socket.look_position =0; |
|
|
186 | |
|
|
187 | if (socket.mapinfocmd) |
125 | { |
188 | { |
|
|
189 | if (ob->map && ob->map->path [0]) |
|
|
190 | { |
126 | int flags = 0; |
191 | int flags = 0; |
127 | |
192 | |
128 | if (ob->map->tile_path [0]) flags |= 1; |
193 | if (ob->map->tile_path [0]) flags |= 1; |
129 | if (ob->map->tile_path [1]) flags |= 2; |
194 | if (ob->map->tile_path [1]) flags |= 2; |
130 | if (ob->map->tile_path [2]) flags |= 4; |
195 | if (ob->map->tile_path [2]) flags |= 4; |
131 | if (ob->map->tile_path [3]) flags |= 8; |
196 | if (ob->map->tile_path [3]) flags |= 8; |
132 | |
197 | |
133 | snprintf (buf, MAX_BUF, "mapinfo - spatial %d %d %d %d %d %s", |
198 | snprintf (buf, MAX_BUF, "mapinfo - spatial %d %d %d %d %d %s", |
134 | flags, pl->socket.mapx / 2 - ob->x, pl->socket.mapy / 2 - ob->y, |
199 | flags, socket.mapx / 2 - ob->x, socket.mapy / 2 - ob->y, |
135 | ob->map->width, ob->map->height, ob->map->path); |
200 | ob->map->width, ob->map->height, ob->map->path); |
136 | } |
201 | } |
137 | else |
202 | else |
138 | snprintf (buf, MAX_BUF, "mapinfo current"); |
203 | snprintf (buf, MAX_BUF, "mapinfo current"); |
139 | |
204 | |
140 | Write_String_To_Socket (&pl->socket, buf, strlen (buf)); |
205 | Write_String_To_Socket (&socket, buf, strlen (buf)); |
|
|
206 | } |
|
|
207 | } |
|
|
208 | else if (socket.current_x != ob->x || socket.current_y != ob->y) |
141 | } |
209 | { |
|
|
210 | socket_map_scroll (&socket, ob->x - socket.current_x, ob->y - socket.current_y); |
|
|
211 | socket.update_look = 1; |
|
|
212 | socket.look_position = 0; |
|
|
213 | } |
|
|
214 | |
|
|
215 | socket.current_x = ob->x; |
|
|
216 | socket.current_y = ob->y; |
142 | } |
217 | } |
143 | |
218 | |
144 | void ExtCmd (char *buf, int len, player *pl) |
219 | void ExtCmd (char *buf, int len, player *pl) |
145 | { |
220 | { |
146 | execute_global_event (EVENT_EXTCMD, pl, buf, len); |
221 | execute_global_event (EVENT_EXTCMD, pl, buf, len); |
… | |
… | |
788 | memset(&pl->socket.lastmap, 0, sizeof(struct Map)); |
863 | memset(&pl->socket.lastmap, 0, sizeof(struct Map)); |
789 | draw_client_map(pl->ob); |
864 | draw_client_map(pl->ob); |
790 | #endif |
865 | #endif |
791 | } |
866 | } |
792 | |
867 | |
793 | /** Newmap command */ |
|
|
794 | void MapNewmapCmd( player *pl) |
|
|
795 | { |
|
|
796 | if( pl->socket.newmapcmd == 1) { |
|
|
797 | memset(&pl->socket.lastmap, 0, sizeof(pl->socket.lastmap)); |
|
|
798 | Write_String_To_Socket( &pl->socket, "newmap", 6); |
|
|
799 | } |
|
|
800 | pl->socket.current_map = 0; |
|
|
801 | } |
|
|
802 | |
|
|
803 | |
|
|
804 | |
|
|
805 | /** |
868 | /** |
806 | * Moves an object (typically, container to inventory). |
869 | * Moves an object (typically, container to inventory). |
807 | * syntax is: move (to) (tag) (nrof) |
870 | * syntax is: move (to) (tag) (nrof) |
808 | */ |
871 | */ |
809 | void MoveCmd(char *buf, int len,player *pl) |
872 | void MoveCmd(char *buf, int len,player *pl) |
… | |
… | |
1560 | uint16 mask,emask; |
1623 | uint16 mask,emask; |
1561 | uint8 eentrysize; |
1624 | uint8 eentrysize; |
1562 | uint16 ewhatstart,ewhatflag; |
1625 | uint16 ewhatstart,ewhatflag; |
1563 | uint8 extendedinfos; |
1626 | uint8 extendedinfos; |
1564 | mapstruct *m; |
1627 | mapstruct *m; |
|
|
1628 | |
|
|
1629 | check_map_change (pl->contr); |
1565 | |
1630 | |
1566 | sl.buf=(unsigned char*)malloc(MAXSOCKBUF); |
1631 | sl.buf=(unsigned char*)malloc(MAXSOCKBUF); |
1567 | if (pl->contr->socket.mapmode == Map1Cmd) |
1632 | if (pl->contr->socket.mapmode == Map1Cmd) |
1568 | strcpy((char*)sl.buf,"map1 "); |
1633 | strcpy((char*)sl.buf,"map1 "); |
1569 | else |
1634 | else |
… | |
… | |
1849 | if (sl.len>startlen || pl->contr->socket.sent_scroll) { |
1914 | if (sl.len>startlen || pl->contr->socket.sent_scroll) { |
1850 | Send_With_Handling(&pl->contr->socket, &sl); |
1915 | Send_With_Handling(&pl->contr->socket, &sl); |
1851 | pl->contr->socket.sent_scroll = 0; |
1916 | pl->contr->socket.sent_scroll = 0; |
1852 | } |
1917 | } |
1853 | free(sl.buf); |
1918 | free(sl.buf); |
1854 | |
|
|
1855 | check_map_change (pl->contr); |
|
|
1856 | } |
1919 | } |
1857 | |
1920 | |
1858 | /** |
1921 | /** |
1859 | * Draws client map. |
1922 | * Draws client map. |
1860 | */ |
1923 | */ |
… | |
… | |
1977 | esrv_map_doneredraw(&pl->contr->socket, &newmap); |
2040 | esrv_map_doneredraw(&pl->contr->socket, &newmap); |
1978 | |
2041 | |
1979 | check_map_change (pl->contr); |
2042 | check_map_change (pl->contr); |
1980 | } |
2043 | } |
1981 | |
2044 | |
1982 | |
|
|
1983 | void esrv_map_scroll(NewSocket *ns,int dx,int dy) |
|
|
1984 | { |
|
|
1985 | struct Map newmap; |
|
|
1986 | int x,y, mx, my; |
|
|
1987 | char buf[MAXSOCKBUF]; |
|
|
1988 | |
|
|
1989 | sprintf(buf,"map_scroll %d %d", dx, dy); |
|
|
1990 | Write_String_To_Socket(ns, buf, strlen(buf)); |
|
|
1991 | |
|
|
1992 | /* If we are using the Map1aCmd, we may in fact send |
|
|
1993 | * head information that is outside the viewable map. |
|
|
1994 | * So set the mx,my to the max value we want to |
|
|
1995 | * look for. Removed code to do so - it caused extra |
|
|
1996 | * complexities for the client, and probably doesn't make |
|
|
1997 | * that much difference in bandwidth. |
|
|
1998 | */ |
|
|
1999 | mx = ns->mapx; |
|
|
2000 | my = ns->mapy; |
|
|
2001 | |
|
|
2002 | if (ns->mapmode == Map1aCmd) { |
|
|
2003 | mx += MAX_HEAD_OFFSET; |
|
|
2004 | my += MAX_HEAD_OFFSET; |
|
|
2005 | } |
|
|
2006 | |
|
|
2007 | /* the x and y here are coordinates for the new map, i.e. if we moved |
|
|
2008 | * (dx,dy), newmap[x][y] = oldmap[x-dx][y-dy]. For this reason, |
|
|
2009 | * if the destination x or y coordinate is outside the viewable |
|
|
2010 | * area, we clear the values - otherwise, the old values |
|
|
2011 | * are preserved, and the check_head thinks it needs to clear them. |
|
|
2012 | */ |
|
|
2013 | for(x=0; x<mx; x++) { |
|
|
2014 | for(y=0; y<my; y++) { |
|
|
2015 | if(x >= ns->mapx || y >= ns->mapy) { |
|
|
2016 | /* clear cells outside the viewable area */ |
|
|
2017 | memset(&newmap.cells[x][y], 0, sizeof(struct MapCell)); |
|
|
2018 | } |
|
|
2019 | else if ((x+dx) < 0 || (x+dx) >= ns->mapx || (y+dy) < 0 || (y + dy) >= ns->mapy) { |
|
|
2020 | /* clear newly visible tiles within the viewable area */ |
|
|
2021 | memset(&(newmap.cells[x][y]), 0, sizeof(struct MapCell)); |
|
|
2022 | } |
|
|
2023 | else { |
|
|
2024 | memcpy(&(newmap.cells[x][y]), |
|
|
2025 | &(ns->lastmap.cells[x+dx][y+dy]),sizeof(struct MapCell)); |
|
|
2026 | } |
|
|
2027 | } |
|
|
2028 | } |
|
|
2029 | |
|
|
2030 | memcpy(&(ns->lastmap), &newmap,sizeof(struct Map)); |
|
|
2031 | |
|
|
2032 | /* Make sure that the next "map1" command will be sent (even if it is |
|
|
2033 | * empty). |
|
|
2034 | */ |
|
|
2035 | ns->sent_scroll = 1; |
|
|
2036 | } |
|
|
2037 | |
2045 | |
2038 | /*****************************************************************************/ |
2046 | /*****************************************************************************/ |
2039 | /* GROS: The following one is used to allow a plugin to send a generic cmd to*/ |
2047 | /* GROS: The following one is used to allow a plugin to send a generic cmd to*/ |
2040 | /* a player. Of course, the client need to know the command to be able to */ |
2048 | /* a player. Of course, the client need to know the command to be able to */ |
2041 | /* manage it ! */ |
2049 | /* manage it ! */ |