--- deliantra/server/common/map.C 2007/06/07 19:12:22 1.109 +++ deliantra/server/common/map.C 2007/07/26 00:27:07 1.114 @@ -1,23 +1,22 @@ /* - * This file is part of Crossfire TRT, the Multiplayer Online Role Playing Game. + * This file is part of Crossfire TRT, the Roguelike Realtime MORPG. * * Copyright (©) 2005,2006,2007 Marc Alexander Lehmann / Robin Redeker / the Crossfire TRT team * Copyright (©) 2001-2003,2007 Mark Wedel & Crossfire Development Team * Copyright (©) 1992,2007 Frank Tore Johansen * - * Crossfire TRT is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the Free - * Software Foundation; either version 2 of the License, or (at your option) - * any later version. + * Crossfire TRT is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * for more details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License along - * with Crossfire TRT; if not, write to the Free Software Foundation, Inc. 51 - * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . * * The authors can be reached via e-mail to */ @@ -31,72 +30,6 @@ #include "path.h" -/* - * This makes a path absolute outside the world of Crossfire. - * In other words, it prepends LIBDIR/MAPDIR/ to the given path - * and returns the pointer to a static array containing the result. - * it really should be called create_mapname - */ -const char * -create_pathname (const char *name) -{ - static char buf[8192]; - snprintf (buf, sizeof (buf), "%s/%s/%s", settings.datadir, settings.mapdir, name); - return buf; -} - -/* - * This function checks if a file with the given path exists. - * -1 is returned if it fails, otherwise the mode of the file - * is returned. - * It tries out all the compression suffixes listed in the uncomp[] array. - * - * If prepend_dir is set, then we call create_pathname (which prepends - * libdir & mapdir). Otherwise, we assume the name given is fully - * complete. - * Only the editor actually cares about the writablity of this - - * the rest of the code only cares that the file is readable. - * when the editor goes away, the call to stat should probably be - * replaced by an access instead (similar to the windows one, but - * that seems to be missing the prepend_dir processing - */ -int -check_path (const char *name, int prepend_dir) -{ - char buf[MAX_BUF]; - - char *endbuf; - struct stat statbuf; - int mode = 0; - - if (prepend_dir) - assign (buf, create_pathname (name)); - else - assign (buf, name); - - /* old method (strchr(buf, '\0')) seemd very odd to me - - * this method should be equivalant and is clearer. - * Can not use strcat because we need to cycle through - * all the names. - */ - endbuf = buf + strlen (buf); - - if (stat (buf, &statbuf)) - return -1; - if (!S_ISREG (statbuf.st_mode)) - return (-1); - - if (((statbuf.st_mode & S_IRGRP) && getegid () == statbuf.st_gid) || - ((statbuf.st_mode & S_IRUSR) && geteuid () == statbuf.st_uid) || (statbuf.st_mode & S_IROTH)) - mode |= 4; - - if ((statbuf.st_mode & S_IWGRP && getegid () == statbuf.st_gid) || - (statbuf.st_mode & S_IWUSR && geteuid () == statbuf.st_uid) || (statbuf.st_mode & S_IWOTH)) - mode |= 2; - - return (mode); -} - /* This rolls up wall, blocks_magic, blocks_view, etc, all into * one function that just returns a P_.. value (see map.h) * it will also do map translation for tiled maps, returning @@ -358,16 +291,28 @@ return; for (mapspace *ms = spaces + size (); ms-- > spaces; ) - for (object *op = ms->bot; op; op = op->above) - { - /* already multipart - don't do anything more */ - if (op->head_ () == op && !op->more && op->arch->more) - { - op->remove (); - op->expand_tail (); - insert (op, op->x, op->y, 0, INS_NO_MERGE | INS_ABOVE_FLOOR_ONLY | INS_NO_WALK_ON); - } - } + { + object *op = ms->bot; + while (op) + { + /* already multipart - don't do anything more */ + if (op->head_ () == op && !op->more && op->arch->more) + { + op->remove (); + op->expand_tail (); + + // FIXME: INS_ON_TOP is just a workaround for the pentagram vs. + // multi-tile monster bug, where INS_ABOVE_FLOOR_ONLY put the monsters + // below the pentagrams... hopefully INS_ON_TOP doesn't break anything + insert (op, op->x, op->y, 0, INS_NO_MERGE | INS_ON_TOP | INS_NO_WALK_ON); + + op = ms->bot; // we are mutating the mapspace too much with INS_ON_TOP + // so we have to reset the iteration through the mapspace + } + else + op = op->above; + } + } } /* @@ -737,6 +682,10 @@ case KW_tile_path_3: thawer.get (tile_path [2]); break; case KW_tile_path_4: thawer.get (tile_path [3]); break; + case KW_ERROR: + set_key (thawer.kw_str, thawer.value); + break; + case KW_end: return true; @@ -867,8 +816,8 @@ void maptile::clear () { - sfree (regions, size ()), regions = 0; - free (regionmap), regionmap = 0; + sfree (regions, size ()); regions = 0; + delete [] regionmap; regionmap = 0; if (spaces) { @@ -1723,3 +1672,30 @@ return get_archetype ("blocked"); } +/** + * Maximum distance a player may hear a sound from. + * This is only used for new client/server sound. If the sound source + * on the map is farther away than this, we don't sent it to the client. + */ +#define MAX_SOUND_DISTANCE 10 + +void +maptile::play_sound (faceidx sound, int x, int y) const +{ + if (!sound) + return; + + for_all_players (pl) + if (pl->ob->map == this) + if (client *ns = pl->ns) + { + int dx = x - pl->ob->x; + int dy = y - pl->ob->y; + + int distance = idistance (dx, dy); + + if (distance <= MAX_SOUND_DISTANCE) + ns->play_sound (sound, dx, dy); + } +} +