Crossfire Server, Trunk  1.75.0
sounds.cpp
Go to the documentation of this file.
1 /*
2  * Crossfire -- cooperative multi-player graphical RPG and adventure game
3  *
4  * Copyright (c) 1999-2014 Mark Wedel and the Crossfire Development Team
5  * Copyright (c) 1992 Frank Tore Johansen
6  *
7  * Crossfire is free software and comes with ABSOLUTELY NO WARRANTY. You are
8  * welcome to redistribute it under certain conditions. For details, please
9  * see COPYING and LICENSE.
10  *
11  * The authors can be reached via e-mail at <crossfire@metalforge.org>.
12  */
13 
21 #include "global.h"
22 
23 #include <assert.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include "sounds.h"
28 #include "sproto.h"
29 
35 #define MAX_SOUND_DISTANCE 10
36 
51 void play_sound_player_only(player *pl, int8_t sound_type, object *emitter, int dir, const char *action) {
52  SockList sl;
53  int volume = 50;
54  sstring name;
55  object *source;
56 
57  if (pl->socket->sound&SND_MUTE || !(pl->socket->sound&SND_EFFECTS))
58  return;
60  return;
61  if (!emitter->map && !(emitter->env && emitter->env->map))
62  return;
63 
64  source = emitter->map ? emitter : emitter->env;
65 
66  // Approximate the distance to the emitter from the source
67  int dx = FABS(source->x-pl->ob->x),
68  dy = FABS(source->y-pl->ob->y);
69  int distance = (MIN(dx, dy) * 3 + FABS(dx-dy) * 2) / 2;
70  // Make the sound dissipation more gradual.
71  distance >>= 1;
72  // Downscale the volume by distance
73  volume = distance ? volume / distance : volume;
74 
75  pl->socket->sounds_this_tick++;
76 
77  name = emitter->name;
78  if (emitter->type == PLAYER) {
79  name = emitter->race;
80  } else if (emitter->type == EXIT) {
81  name = emitter->arch->clone.name; /* The name may be custom, so use generic exit name */
82  }
83  if (name == NULL) {
84  return;
85  }
86 
87  SockList_Init(&sl);
88  SockList_AddString(&sl, "sound2 ");
89  SockList_AddChar(&sl, (int8_t)(source->x-pl->ob->x));
90  SockList_AddChar(&sl, (int8_t)(source->y-pl->ob->y));
91  SockList_AddChar(&sl, dir);
92  SockList_AddChar(&sl, volume);
93  SockList_AddChar(&sl, sound_type);
94  SockList_AddLen8Data(&sl, action, strlen(action));
95  SockList_AddLen8Data(&sl, name, strlen(name));
96  Send_With_Handling(pl->socket, &sl);
97  SockList_Term(&sl);
98 }
99 
100 #define POW2(x) ((x)*(x))
101 
113 void play_sound_map(int8_t sound_type, object *emitter, int dir, const char *action) {
114  player *pl;
115  object *source;
116 
117  if (!emitter->map && !(emitter->env && emitter->env->map))
118  return;
119 
120  source = emitter->map ? emitter : emitter->env;
121 
122  // If sound_chance is defined, then we skip if the chance fails to generate a sound.
123  if (emitter->sound_chance) {
124  // Override -- sound chance > 200 acts as 0.
125  if (emitter->sound_chance > 200)
126  return;
127  if (RANDOM() % 100 < emitter->sound_chance)
128  return;
129  }
130 
131  for (pl = first_player; pl; pl = pl->next) {
132  if (pl->ob->map == emitter->map) {
133  int distance = ihypot(pl->ob->x-source->x, pl->ob->y-source->y);
134 
135  if (distance <= MAX_SOUND_DISTANCE) {
136  play_sound_player_only(pl, sound_type, emitter, dir, action);
137  }
138  }
139  }
140 }
141 
150 void send_background_music(player *pl, const char *music) {
151  SockList sl;
152 
153  if (pl->socket->sound&SND_MUTE || !(pl->socket->sound&SND_MUSIC))
154  return;
155 
156  SockList_Init(&sl);
157  SockList_AddString(&sl, "music ");
158  SockList_AddString(&sl, music == NULL ? "NONE" : music);
159  Send_With_Handling(pl->socket, &sl);
160  SockList_Term(&sl);
161 }
162 
163 static char const* pick_bg_music(mapstruct *map) {
164  if (map->background_music != NULL) {
165  return map->background_music;
166  }
167  return get_name_of_region_for_map(map);
168 }
169 
171  assert(player->contr);
172  assert(player->type == PLAYER);
174 }
175 
PLAYER
@ PLAYER
Definition: object.h:112
get_name_of_region_for_map
const char * get_name_of_region_for_map(const mapstruct *m)
Gets the name of a region for a map.
Definition: region.cpp:89
player::next
player * next
Pointer to next player, NULL if this is last.
Definition: player.h:106
global.h
first_player
player * first_player
First player.
Definition: init.cpp:106
player_update_bg_music
void player_update_bg_music(object *player)
Definition: sounds.cpp:170
FABS
#define FABS(x)
Decstations have trouble with fabs()...
Definition: define.h:22
player
One player.
Definition: player.h:105
socket_struct::sound
uint32_t sound
Client sound mode.
Definition: newserver.h:111
object::arch
struct archetype * arch
Pointer to archetype.
Definition: object.h:424
SockList_AddString
void SockList_AddString(SockList *sl, const char *data)
Adds a string without length.
Definition: lowlevel.cpp:157
object::x
int16_t x
Definition: object.h:335
player::ob
object * ob
The object representing the player.
Definition: player.h:177
object::map
struct mapstruct * map
Pointer to the map in which this object is present.
Definition: object.h:305
MIN
#define MIN(x, y)
Definition: compat.h:21
MAX_SOUND_DISTANCE
#define MAX_SOUND_DISTANCE
Maximum distance a player may hear a sound from.
Definition: sounds.cpp:35
play_sound_map
void play_sound_map(int8_t sound_type, object *emitter, int dir, const char *action)
Plays a sound on a map.
Definition: sounds.cpp:113
ihypot
int ihypot(int a, int b)
Rough estimate of hypot(a, b).
Definition: utils.cpp:570
SND_EFFECTS
#define SND_EFFECTS
Those flags are for the 'socket.sound' field.
Definition: sounds.h:12
name
Plugin animator file specs[Config] name
Definition: animfiles.txt:4
object::y
int16_t y
Position in the map for this object.
Definition: object.h:335
archetype::clone
object clone
An object from which to do object_copy()
Definition: object.h:487
SockList_AddChar
void SockList_AddChar(SockList *sl, unsigned char c)
Adds an 8 bit value.
Definition: lowlevel.cpp:106
object::type
uint8_t type
PLAYER, BULLET, etc.
Definition: object.h:348
MAX_SOUNDS_TICK
#define MAX_SOUNDS_TICK
Maximum number of sounds a player can receive for each tick.
Definition: sounds.h:16
send_background_music
void send_background_music(player *pl, const char *music)
Sends background music to client.
Definition: sounds.cpp:150
sproto.h
SND_MUTE
#define SND_MUTE
Don't sent anything for now.
Definition: sounds.h:14
object::sound_chance
uint8_t sound_chance
Probability, 1 to 100, of the object emitting a sound.
Definition: object.h:403
object::race
sstring race
Human, goblin, dragon, etc.
Definition: object.h:326
SockList_Init
void SockList_Init(SockList *sl)
Initializes the SockList instance.
Definition: lowlevel.cpp:55
RANDOM
#define RANDOM()
Definition: define.h:638
SockList_Term
void SockList_Term(SockList *sl)
Frees all resources allocated by a SockList instance.
Definition: lowlevel.cpp:65
EXIT
@ EXIT
Definition: object.h:186
socket_struct::sounds_this_tick
int8_t sounds_this_tick
Number of sounds sent this tick.
Definition: newserver.h:121
sounds.h
object::name
sstring name
The name of the object, obviously...
Definition: object.h:319
mapstruct::background_music
char * background_music
Background music to use for this map.
Definition: map.h:357
mapstruct
This is a game-map.
Definition: map.h:315
object::env
object * env
Pointer to the object which is the environment.
Definition: object.h:301
SND_MUSIC
#define SND_MUSIC
Client wants background music info.
Definition: sounds.h:13
sstring
const typedef char * sstring
Definition: sstring.h:2
SockList_AddLen8Data
void SockList_AddLen8Data(SockList *sl, const void *data, size_t len)
Adds a data block prepended with an 8 bit length field.
Definition: lowlevel.cpp:179
play_sound_player_only
void play_sound_player_only(player *pl, int8_t sound_type, object *emitter, int dir, const char *action)
Plays a sound for specified player only.
Definition: sounds.cpp:51
pick_bg_music
static char const * pick_bg_music(mapstruct *map)
Definition: sounds.cpp:163
player::socket
socket_struct * socket
Socket information for this player.
Definition: player.h:107
Send_With_Handling
void Send_With_Handling(socket_struct *ns, SockList *sl)
Calls Write_To_Socket to send data to the client.
Definition: lowlevel.cpp:447
SockList
Contains the base information we use to make up a packet we want to send.
Definition: newclient.h:684