ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/deliantra/server/socket/request.C
(Generate patch)

Comparing deliantra/server/socket/request.C (file contents):
Revision 1.143 by root, Tue Dec 23 06:58:24 2008 UTC vs.
Revision 1.144 by root, Fri Dec 26 10:36:42 2008 UTC

1108 << uint8 (eentrysize); 1108 << uint8 (eentrysize);
1109 1109
1110 estartlen = esl.length (); 1110 estartlen = esl.length ();
1111 } 1111 }
1112 1112
1113 /* We could do this logic as conditionals in the if statement,
1114 * but that started to get a bit messy to look at.
1115 */
1116 int hx = socket.mapx / 2; 1113 int hx = socket.mapx / 2;
1117 int hy = socket.mapy / 2; 1114 int hy = socket.mapy / 2;
1118 1115
1119 for (int dx = -hx; dx <= hx; dx++) 1116 ordered_mapwalk_begin (ob, -hx, -hy, hx, hy)
1120 {
1121 sint16 nx, ny;
1122 maptile *m = 0;
1123
1124 for (int dy = -hy; dy <= hy; dy++)
1125 {
1126 // check to see if we can simply go one down quickly
1127 if (m && ++ny >= m->height)
1128 m = 0;
1129
1130 // no, so do it the slow way
1131 if (!m)
1132 {
1133 nx = ob->x + dx; ny = ob->y + dy; m = ob->map;
1134
1135 if (xy_normalise (m, nx, ny))
1136 m->touch ();
1137 else
1138 m = 0;
1139 }
1140
1141 int ax = dx + hx; 1117 int ax = dx + hx;
1142 int ay = dy + hy; 1118 int ay = dy + hy;
1143 1119
1144 int emask, mask; 1120 int emask, mask;
1145 emask = mask = (ax & 0x3f) << 10 | (ay & 0x3f) << 4; 1121 emask = mask = (ax << 10) | (ay << 4);
1146 1122
1147 MapCell &lastcell = socket.lastmap.cells[ax][ay]; 1123 MapCell &lastcell = socket.lastmap.cells[ax][ay];
1148 1124
1149 /* If the coordinates are not valid, or it is too dark to see, 1125 /* If the coordinates are not valid, or it is too dark to see,
1150 * we tell the client as such 1126 * we tell the client as such
1151 */ 1127 */
1152 if (!m) 1128 if (!m)
1153 { 1129 {
1154 /* space is out of map. Update space and clear values 1130 /* space is out of map. Update space and clear values
1155 * if this hasn't already been done. If the space is out 1131 * if this hasn't already been done. If the space is out
1156 * of the map, it shouldn't have a head. 1132 * of the map, it shouldn't have a head.
1157 */ 1133 */
1158 if (lastcell.count != -1) 1134 if (lastcell.count != -1)
1135 {
1136 sl << uint16 (mask);
1137 map_clearcell (&lastcell, -1);
1138 }
1139
1140 continue;
1141 }
1142
1143 int d = pl->blocked_los_uc (dx, dy);
1144
1145 if (d > 3)
1146 {
1147 /* This block deals with spaces that are not visible for whatever
1148 * reason. Still may need to send the head for this space.
1149 */
1150 if (lastcell.count != -1
1151 || lastcell.faces[0]
1152 || lastcell.faces[1]
1153 || lastcell.faces[2]
1154 || lastcell.stat_hp
1155 || lastcell.flags
1156 || lastcell.player)
1157 sl << uint16 (mask);
1158
1159 /* properly clear a previously sent big face */
1160 map_clearcell (&lastcell, -1);
1161 }
1162 else
1163 {
1164 /* In this block, the space is visible.
1165 */
1166
1167 /* Rather than try to figure out what everything that we might
1168 * need to send is, then form the packet after that,
1169 * we presume that we will in fact form a packet, and update
1170 * the bits by what we do actually send. If we send nothing,
1171 * we just back out sl.length () to the old value, and no harm
1172 * is done.
1173 * I think this is simpler than doing a bunch of checks to see
1174 * what if anything we need to send, setting the bits, then
1175 * doing those checks again to add the real data.
1176 */
1177 oldlen = sl.length ();
1178 eoldlen = esl.length ();
1179
1180 sl << uint16 (mask);
1181
1182 unsigned char dummy;
1183 unsigned char *last_ext = &dummy;
1184
1185 /* Darkness changed */
1186 if (lastcell.count != d && socket.darkness)
1187 {
1188 mask |= 0x8;
1189
1190 if (socket.extmap)
1191 {
1192 *last_ext |= 0x80;
1193 last_ext = &sl[sl.length ()];
1194 sl << uint8 (d);
1195 }
1196 else
1197 sl << uint8 (255 - 64 * d);
1198 }
1199
1200 lastcell.count = d;
1201
1202 mapspace &ms = m->at (nx, ny);
1203 ms.update ();
1204
1205 if (expect_true (socket.extmap))
1206 {
1207 uint8 stat_hp = 0;
1208 uint8 stat_width = 0;
1209 uint8 flags = 0;
1210 tag_t player = 0;
1211
1212 // send hp information, if applicable
1213 if (object *op = ms.faces_obj [0])
1214 if (op->is_head () && !op->invisible)
1159 { 1215 {
1160 sl << uint16 (mask); 1216 if (op->stats.maxhp > op->stats.hp
1161 map_clearcell (&lastcell, -1); 1217 && op->stats.maxhp > 0
1218 && (op->type == PLAYER
1219 || op->type == DOOR // does not work, have maxhp 0
1220 || QUERY_FLAG (op, FLAG_MONSTER)
1221 || QUERY_FLAG (op, FLAG_ALIVE)
1222 || QUERY_FLAG (op, FLAG_GENERATOR)))
1223 {
1224 stat_hp = 255 - (op->stats.hp * 255 + 254) / op->stats.maxhp;
1225 stat_width = op->arch->max_x - op->arch->x; //TODO: should be upper-left edge
1226 }
1227
1228 if (expect_false (op->has_dialogue ()))
1229 flags |= 1;
1230
1231 if (expect_false (op->type == PLAYER))
1232 player = op == ob ? pl->ob->count
1233 : op == pl->ob ? ob->count
1234 : op->count;
1162 } 1235 }
1163 1236
1164 continue; 1237 if (expect_false (lastcell.stat_hp != stat_hp))
1165 }
1166
1167 int d = pl->blocked_los_uc (dx, dy);
1168
1169 if (d > 3)
1170 {
1171 int need_send = 0, count;
1172
1173 /* This block deals with spaces that are not visible for whatever
1174 * reason. Still may need to send the head for this space.
1175 */
1176
1177 oldlen = sl.length ();
1178
1179 sl << uint16 (mask);
1180
1181 if (lastcell.count != -1)
1182 need_send = 1;
1183
1184 count = -1;
1185
1186 if (lastcell.faces[0] || lastcell.faces[1] || lastcell.faces[2]
1187 || lastcell.stat_hp || lastcell.flags || lastcell.player)
1188 need_send = 1;
1189
1190 /* properly clear a previously sent big face */
1191 map_clearcell (&lastcell, count);
1192
1193 if ((mask & 0xf) || need_send)
1194 sl[oldlen + 1] = mask & 0xff;
1195 else
1196 sl.reset (oldlen);
1197 }
1198 else
1199 {
1200 /* In this block, the space is visible.
1201 */
1202
1203 /* Rather than try to figure out what everything that we might
1204 * need to send is, then form the packet after that,
1205 * we presume that we will in fact form a packet, and update
1206 * the bits by what we do actually send. If we send nothing,
1207 * we just back out sl.length () to the old value, and no harm
1208 * is done.
1209 * I think this is simpler than doing a bunch of checks to see
1210 * what if anything we need to send, setting the bits, then
1211 * doing those checks again to add the real data.
1212 */
1213 oldlen = sl.length ();
1214 eoldlen = esl.length ();
1215
1216 sl << uint16 (mask);
1217
1218 unsigned char dummy;
1219 unsigned char *last_ext = &dummy;
1220
1221 /* Darkness changed */
1222 if (lastcell.count != d && socket.darkness)
1223 { 1238 {
1239 lastcell.stat_hp = stat_hp;
1240
1224 mask |= 0x8; 1241 mask |= 0x8;
1242 *last_ext |= 0x80;
1243 last_ext = &sl[sl.length ()];
1225 1244
1226 if (socket.extmap) 1245 sl << uint8 (5) << uint8 (stat_hp);
1246
1247 if (stat_width > 1)
1227 { 1248 {
1228 *last_ext |= 0x80; 1249 *last_ext |= 0x80;
1229 last_ext = &sl[sl.length ()]; 1250 last_ext = &sl[sl.length ()];
1230 sl << uint8 (d);
1231 }
1232 else
1233 sl << uint8 (255 - 64 * d);
1234 }
1235 1251
1236 lastcell.count = d;
1237
1238 mapspace &ms = m->at (nx, ny);
1239 ms.update ();
1240
1241 if (socket.extmap)
1242 {
1243 uint8 stat_hp = 0;
1244 uint8 stat_width = 0;
1245 uint8 flags = 0;
1246 tag_t player = 0;
1247
1248 // send hp information, if applicable
1249 if (object *op = ms.faces_obj [0])
1250 if (op->is_head () && !op->invisible)
1251 {
1252 if (op->stats.maxhp > op->stats.hp
1253 && op->stats.maxhp > 0
1254 && (op->type == PLAYER
1255 || op->type == DOOR // does not work, have maxhp 0
1256 || QUERY_FLAG (op, FLAG_MONSTER)
1257 || QUERY_FLAG (op, FLAG_ALIVE)
1258 || QUERY_FLAG (op, FLAG_GENERATOR)))
1259 {
1260 stat_hp = 255 - (op->stats.hp * 255 + 254) / op->stats.maxhp;
1261 stat_width = op->arch->max_x - op->arch->x; //TODO: should be upper-left edge
1262 }
1263
1264 if (op->has_dialogue ())
1265 flags |= 1;
1266
1267 if (op->type == PLAYER)
1268 player = op == ob ? pl->ob->count
1269 : op == pl->ob ? ob->count
1270 : op->count;
1271 }
1272
1273 if (lastcell.stat_hp != stat_hp)
1274 {
1275 lastcell.stat_hp = stat_hp;
1276
1277 mask |= 0x8;
1278 *last_ext |= 0x80;
1279 last_ext = &sl[sl.length ()];
1280
1281 sl << uint8 (5) << uint8 (stat_hp);
1282
1283 if (stat_width > 1)
1284 {
1285 *last_ext |= 0x80;
1286 last_ext = &sl[sl.length ()];
1287
1288 sl << uint8 (6) << uint8 (stat_width); 1252 sl << uint8 (6) << uint8 (stat_width);
1289 }
1290 } 1253 }
1291
1292 if (lastcell.player != player)
1293 {
1294 lastcell.player = player;
1295
1296 mask |= 0x8;
1297 *last_ext |= 0x80;
1298 last_ext = &sl[sl.length ()];
1299
1300 sl << uint8 (0x47) << uint8 (4) << (uint32)player;
1301 }
1302
1303 if (lastcell.flags != flags)
1304 {
1305 lastcell.flags = flags;
1306
1307 mask |= 0x8;
1308 *last_ext |= 0x80;
1309 last_ext = &sl[sl.length ()];
1310
1311 sl << uint8 (8) << uint8 (flags);
1312 }
1313 } 1254 }
1314 1255
1315 /* Floor face */ 1256 if (expect_false (lastcell.player != player))
1316 if (update_space (sl, socket, ms, lastcell, 2)) 1257 {
1258 lastcell.player = player;
1259
1317 mask |= 0x4; 1260 mask |= 0x8;
1261 *last_ext |= 0x80;
1262 last_ext = &sl[sl.length ()];
1318 1263
1319 /* Middle face */ 1264 sl << uint8 (0x47) << uint8 (4) << (uint32)player;
1320 if (update_space (sl, socket, ms, lastcell, 1)) 1265 }
1266
1267 if (expect_false (lastcell.flags != flags))
1268 {
1269 lastcell.flags = flags;
1270
1321 mask |= 0x2; 1271 mask |= 0x8;
1272 *last_ext |= 0x80;
1273 last_ext = &sl[sl.length ()];
1322 1274
1323 if (ob->invisible 1275 sl << uint8 (8) << uint8 (flags);
1276 }
1277 }
1278
1279 /* Floor face */
1280 if (update_space (sl, socket, ms, lastcell, 2))
1281 mask |= 0x4;
1282
1283 /* Middle face */
1284 if (update_space (sl, socket, ms, lastcell, 1))
1285 mask |= 0x2;
1286
1287 if (expect_false (ob->invisible)
1324 && ob->invisible & (ob->invisible < 50 ? 1 : 7) 1288 && ob->invisible & (ob->invisible < 50 ? 1 : 7)
1325 && ms.player () == ob) 1289 && ms.player () == ob)
1326 { 1290 {
1327 // force player to be visible to himself if invisible 1291 // force player to be visible to himself if invisible
1328 if (lastcell.faces[0] != ob->face) 1292 if (lastcell.faces[0] != ob->face)
1329 { 1293 {
1330 lastcell.faces[0] = ob->face; 1294 lastcell.faces[0] = ob->face;
1331 1295
1332 mask |= 0x1;
1333 sl << uint16 (ob->face);
1334
1335 socket.send_faces (ob);
1336 }
1337 }
1338 /* Top face */
1339 else if (update_space (sl, socket, ms, lastcell, 0))
1340 mask |= 0x1; 1296 mask |= 0x1;
1297 sl << uint16 (ob->face);
1341 1298
1299 socket.send_faces (ob);
1300 }
1301 }
1302 /* Top face */
1303 else if (update_space (sl, socket, ms, lastcell, 0))
1304 mask |= 0x1;
1305
1342 /* Check to see if we are in fact sending anything for this 1306 /* Check to see if we are in fact sending anything for this
1343 * space by checking the mask. If so, update the mask. 1307 * space by checking the mask. If so, update the mask.
1344 * if not, reset the len to that from before adding the mask 1308 * if not, reset the len to that from before adding the mask
1345 * value, so we don't send those bits. 1309 * value, so we don't send those bits.
1346 */ 1310 */
1347 if (mask & 0xf) 1311 if (mask & 0xf)
1348 sl[oldlen + 1] = mask & 0xff; 1312 sl[oldlen + 1] = mask & 0xff;
1349 else 1313 else
1350 sl.reset (oldlen); 1314 sl.reset (oldlen);
1351 1315
1352 if (socket.ext_mapinfos) 1316 if (socket.ext_mapinfos)
1353 esl << uint16 (emask); 1317 esl << uint16 (emask);
1354 1318
1355 if (socket.EMI_smooth) 1319 if (socket.EMI_smooth)
1320 {
1321 for (int layer = 2+1; layer--; )
1356 { 1322 {
1357 for (int layer = 2+1; layer--; )
1358 {
1359 object *ob = ms.faces_obj [layer]; 1323 object *ob = ms.faces_obj [layer];
1360 1324
1361 // If there is no object for this space, or if the face for the object 1325 // If there is no object for this space, or if the face for the object
1362 // is the blank face, set the smoothlevel to zero. 1326 // is the blank face, set the smoothlevel to zero.
1363 int smoothlevel = ob && ob->face != blank_face ? ob->smoothlevel : 0; 1327 int smoothlevel = ob && ob->face != blank_face ? ob->smoothlevel : 0;
1364 1328
1365 // We've gotten what face we want to use for the object. Now see if 1329 // We've gotten what face we want to use for the object. Now see if
1366 // if it has changed since we last sent it to the client. 1330 // if it has changed since we last sent it to the client.
1367 if (lastcell.smooth[layer] != smoothlevel) 1331 if (lastcell.smooth[layer] != smoothlevel)
1368 { 1332 {
1369 lastcell.smooth[layer] = smoothlevel; 1333 lastcell.smooth[layer] = smoothlevel;
1370 esl << uint8 (smoothlevel); 1334 esl << uint8 (smoothlevel);
1371 emask |= 1 << layer; 1335 emask |= 1 << layer;
1372 }
1373 } 1336 }
1337 }
1374 1338
1375 if (emask & 0xf) 1339 if (emask & 0xf)
1376 esl[eoldlen + 1] = emask & 0xff; 1340 esl[eoldlen + 1] = emask & 0xff;
1377 else 1341 else
1378 esl.reset (eoldlen); 1342 esl.reset (eoldlen);
1379 } 1343 }
1380 } /* else this is a viewable space */ 1344 } /* else this is a viewable space */
1381 } /* for x loop */ 1345 ordered_mapwalk_end
1382 } /* for y loop */
1383 1346
1384 socket.flush_fx (); 1347 socket.flush_fx ();
1385 1348
1386 /* Verify that we in fact do need to send this */ 1349 /* Verify that we in fact do need to send this */
1387 if (socket.ext_mapinfos) 1350 if (socket.ext_mapinfos)

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines