--- deliantra/server/socket/sounds.C 2006/09/16 22:24:13 1.5
+++ deliantra/server/socket/sounds.C 2008/05/06 16:55:26 1.26
@@ -1,3 +1,26 @@
+/*
+ * This file is part of Deliantra, the Roguelike Realtime MMORPG.
+ *
+ * Copyright (©) 2005,2006,2007,2008 Marc Alexander Lehmann / Robin Redeker / the Deliantra team
+ * Copyright (©) 2002,2007 Mark Wedel & Crossfire Development Team
+ * Copyright (©) 1992,2007 Frank Tore Johansen
+ *
+ * Deliantra 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.
+ *
+ * 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
+ */
+
/* Send bug reports to Raphael Quinet (quinet@montefiore.ulg.ac.be) */
/**
@@ -11,68 +34,105 @@
#include
#include
-/**
- * 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
+#include
+
+// the hashtable
+typedef std::tr1::unordered_map
+ <
+ const char *,
+ faceidx,
+ str_hash,
+ str_equal,
+ slice_allocator< std::pair >
+ > HT;
+
+static HT ht;
+
+faceidx
+sound_find (const char *str)
+{
+ auto (i, ht.find (str));
+
+ if (i != ht.end ())
+ return i->second;
+
+ if (strncmp (str, "sound/", sizeof ("sound/") - 1))
+ str = format ("sound/%s", str);
+
+ return face_find (str);
+}
-/**
- * Plays a sound for specified player only
- */
void
-play_sound_player_only (player *pl, short soundnum, sint8 x, sint8 y)
+sound_set (const char *str, faceidx face)
{
- char soundtype;
- SockList sl;
+ auto (i, ht.find (str));
- if (!pl->socket.sound)
- return;
- /* Do some quick conversion to the sound type we want. */
- if (soundnum >= SOUND_CAST_SPELL_0)
- {
- soundtype = SOUND_SPELL;
- soundnum -= SOUND_CAST_SPELL_0;
- }
+ if (i != ht.end ())
+ i->second = face;
else
- soundtype = SOUND_NORMAL;
-
- sl.buf = (unsigned char *) malloc (MAXSOCKBUF);
- strcpy ((char *) sl.buf, "sound ");
- sl.len = strlen ((char *) sl.buf);
- SockList_AddChar (&sl, x);
- SockList_AddChar (&sl, y);
- SockList_AddShort (&sl, soundnum);
- SockList_AddChar (&sl, soundtype);
- Send_With_Handling (&pl->socket, &sl);
- free (sl.buf);
+ ht.insert (std::make_pair (strdup (str), face));
}
-#define POW2(x) ((x) * (x))
+//TODO: remove
+// for gcfclient-compatibility, to vanish at some point
+faceidx old_sound_index [SOUND_CAST_SPELL_0];
-/** Plays some sound on map at x,y. */
+/*
+ * Plays a sound for specified player only
+ */
void
-play_sound_map (maptile *map, int x, int y, short sound_num)
+client::play_sound (faceidx sound, int dx, int dy)
{
- player *pl;
+ if (!sound)
+ return;
+
+ uint8 vol = 255 - idistance (dx, dy) * 255 / MAX_SOUND_DISTANCE;
- if (sound_num >= NROF_SOUNDS)
+ // cut off volume here
+ if (vol <= 0)
+ return;
+
+ if (fx_want [FT_SOUND])
{
- LOG (llevError, "Tried to play an invalid sound num: %d\n", sound_num);
- return;
- }
+ // cfplus
+ send_face (sound);
+ flush_fx ();
+
+ packet sl ("sc");
- for (pl = first_player; pl; pl = pl->next)
+ uint8 *len = sl.cur;
+
+ sl << uint8 (0) // group length
+ << uint8 (0) // type == one-time effect
+ << ber32 (sound)
+ << sint8 (dx)
+ << sint8 (dy)
+ << uint8 (vol); // 0 == silent, 255 max
+
+ *len = sl.cur - len; // patch in group length
+
+ send_packet (sl);
+ }
+ else if (this->sound)
{
- if (pl->ob->map == map)
- {
- int distance = isqrt (POW2 (pl->ob->x - x) + POW2 (pl->ob->y - y));
-
- if (distance <= MAX_SOUND_DISTANCE)
- {
- play_sound_player_only (pl, sound_num, (sint8) (x - pl->ob->x), (sint8) (y - pl->ob->y));
- }
- }
+ //TODO: remove, or make bearable
+ // gcfclient compatibility
+
+ int gcfclient_sound;
+ for (gcfclient_sound = SOUND_CAST_SPELL_0; gcfclient_sound--; )
+ if (old_sound_index [gcfclient_sound] == sound)
+ {
+ packet sl ("sound");
+
+ sl << uint8 (dx)
+ << uint8 (dy)
+ << uint16 (gcfclient_sound)
+ << uint8 (SOUND_NORMAL);
+
+ send_packet (sl);
+
+ break;
+ }
}
}
+