--- deliantra/server/socket/request.C 2010/04/21 05:48:22 1.175 +++ deliantra/server/socket/request.C 2011/05/07 20:03:28 1.183 @@ -1,7 +1,7 @@ /* * This file is part of Deliantra, the Roguelike Realtime MMORPG. * - * Copyright (©) 2005,2006,2007,2008,2009,2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team + * Copyright (©) 2005,2006,2007,2008,2009,2010,2011 Marc Alexander Lehmann / Robin Redeker / the Deliantra team * Copyright (©) 2001 Mark Wedel * Copyright (©) 1992 Frank Tore Johansen * @@ -148,10 +148,7 @@ memset (&pl->ns->lastmap, 0, sizeof (pl->ns->lastmap)); pl->ns->force_newmap = false; - - if (pl->ns->newmapcmd == 1) - pl->ns->send_packet ("newmap"); - + pl->ns->send_packet ("newmap"); pl->ns->floorbox_reset (); } @@ -163,14 +160,18 @@ if (socket.mapinfocmd) { - if (ob->map && ob->map->path[0]) + if (ob->map && ob->map->path) { int flags = 0; - if (ob->map->tile_path[0]) flags |= 1; - if (ob->map->tile_path[1]) flags |= 2; - if (ob->map->tile_path[2]) flags |= 4; - if (ob->map->tile_path[3]) flags |= 8; + // due to historical glitches, the bit ordering and map index ordering differs + if (ob->map->tile_path[TILE_NORTH]) flags |= 0x01; + if (ob->map->tile_path[TILE_EAST ]) flags |= 0x02; + if (ob->map->tile_path[TILE_SOUTH]) flags |= 0x04; + if (ob->map->tile_path[TILE_WEST ]) flags |= 0x08; + // these two are debatable + if (ob->map->tile_path[TILE_UP ]) flags |= 0x10; + if (ob->map->tile_path[TILE_DOWN ]) flags |= 0x20; socket.send_packet_printf ("mapinfo - spatial %d %d %d %d %d %s", flags, socket.mapx / 2 - ob->x, socket.mapy / 2 - ob->y, @@ -248,10 +249,7 @@ sl.printf ("%d:%s\n", CS_STAT_SKILLINFO + i, &skillvec [i]->name); if (sl.length () > MAXSOCKBUF) - { - LOG (llevError, "Buffer overflow in send_skill_info!\n"); - fatal (0); - } + cleanup ("buffer overflow in send_skill_info!"); ns->send_packet (sl); } @@ -271,10 +269,7 @@ sl.printf ("%d:%s\n", 1 << i, spellpathnames[i]); if (sl.length () > MAXSOCKBUF) - { - LOG (llevError, "Buffer overflow in send_spell_paths!\n"); - fatal (0); - } + cleanup ("buffer overflow in send_spell_paths!"); ns->send_packet (sl); } @@ -352,8 +347,14 @@ { int dir = *buf++ - '1'; - if (dir >= 0 && dir <= 3) + // due to historical glitches, the mapinfo index and tile index differs + static unsigned char dirmap [] = { TILE_NORTH, TILE_EAST, TILE_SOUTH, TILE_WEST, TILE_UP, TILE_DOWN }; + + // maybe we should only allow the four flat directions + if (dir >= 0 && dir < array_length (dirmap)) { + dir = dirmap [dir]; + if (!map->tile_path [dir]) map = 0; else if (map->tile_available (dir, false)) @@ -386,10 +387,14 @@ { int flags = 0; - if (map->tile_path[0]) flags |= 1; - if (map->tile_path[1]) flags |= 2; - if (map->tile_path[2]) flags |= 4; - if (map->tile_path[3]) flags |= 8; + // due to historical glitches, the bit ordering and map index ordering differs + if (map->tile_path[TILE_NORTH]) flags |= 0x01; + if (map->tile_path[TILE_EAST ]) flags |= 0x02; + if (map->tile_path[TILE_SOUTH]) flags |= 0x04; + if (map->tile_path[TILE_WEST ]) flags |= 0x08; + // these two are debatable + if (map->tile_path[TILE_UP ]) flags |= 0x10; + if (map->tile_path[TILE_DOWN ]) flags |= 0x20; send_packet_printf ("mapinfo %s spatial %d %d %d %d %d %s", token, flags, mapx, mapy, map->width, map->height, &map->path); } @@ -886,19 +891,32 @@ //-GPL -// prefetch maps in an area of PREFETCH x PREFETCH around the player -#define PREFETCH 40 - -// prefetch a generous area around the player +// prefetch some flat area around the player static void -prefetch_surrounding_maps (object *op) +prefetch_surrounding_area (object *op, maptile *map, int range) { - for (maprect *rect = op->map->split_to_tiles (mapwalk_buf, - op->x - PREFETCH , op->y - PREFETCH , - op->x + PREFETCH + 1, op->y + PREFETCH + 1); + for (maprect *rect = map->split_to_tiles (mapwalk_buf, + op->x - range , op->y - range , + op->x + range + 1, op->y + range + 1); rect->m; ++rect) - rect->m->touch (); + { + rect->m->touch (); + rect->m->activate (); + } +} + +// prefetch a generous area around the player, also up and down +void +object::prefetch_surrounding_maps () +{ + prefetch_surrounding_area (this, map, 40); + + if (maptile *m = map->tile_available (TILE_DOWN)) + prefetch_surrounding_area (this, m, 20); + + if (maptile *m = map->tile_available (TILE_UP)) + prefetch_surrounding_area (this, m, 20); } //+GPL @@ -917,13 +935,13 @@ * can get swapped out. If so, don't try to send them a map. All will * be OK once they really log in. */ - if (!ob->map || ob->map->in_memory != MAP_ACTIVE) + if (!ob->map || ob->map->state != MAP_ACTIVE) return; int startlen, oldlen; check_map_change (pl); - prefetch_surrounding_maps (pl->ob); + pl->ob->prefetch_surrounding_maps (); /* do LOS after calls to update_position */ /* unfortunately, we need to udpate los when observing, currently */ @@ -958,7 +976,7 @@ client &socket = *pl->ns; - packet sl (socket.mapmode == Map1Cmd ? "map1" : "map1a"); + packet sl ("map1a"); startlen = sl.length (); @@ -1351,10 +1369,7 @@ append_spell (pl, sl, spell); if (sl.length () > MAXSOCKBUF) - { - LOG (llevError, "Buffer overflow in esrv_add_spells!\n"); - fatal (0); - } + cleanup ("buffer overflow in esrv_add_spells!"); /* finally, we can send the packet */ pl->ns->flush_fx ();