Use "named parameters" to specify sound source properties + some small tweaks.
This commit is contained in:
parent
7f9d7a2542
commit
45a126be5a
3 changed files with 120 additions and 63 deletions
|
@ -1435,18 +1435,28 @@ void event_handler::handle_event_command(const queued_event& event_info,
|
|||
if(!sounds.empty() && !delay.empty() && !chance.empty()) {
|
||||
const std::vector<std::string>& vx = utils::split(x);
|
||||
const std::vector<std::string>& vy = utils::split(y);
|
||||
const int loops = lexical_cast_default<int>(loop, 0);
|
||||
|
||||
if(play_fogged.empty())
|
||||
soundsources->add(id, sounds, lexical_cast<int>(delay), lexical_cast<int>(chance), loops);
|
||||
else
|
||||
soundsources->add(id, sounds, lexical_cast<int>(delay),
|
||||
lexical_cast<int>(chance), loops, utils::string_bool(play_fogged));
|
||||
if(vx.size() != vy.size()) {
|
||||
lg::wml_error << "invalid number of sound source location coordinates";
|
||||
return;
|
||||
}
|
||||
|
||||
soundsource::sourcespec spec(id, sounds, lexical_cast_default<int>(delay, 1000), lexical_cast_default<int>(chance, 100));
|
||||
|
||||
spec.loop(lexical_cast_default<int>(loop, 0));
|
||||
|
||||
if(play_fogged.empty()) {
|
||||
spec.check_fog(true);
|
||||
} else {
|
||||
spec.check_fog(utils::string_bool(play_fogged));
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < minimum(vx.size(), vy.size()); ++i) {
|
||||
gamemap::location loc(lexical_cast<int>(vx[i]), lexical_cast<int>(vy[i]));
|
||||
soundsources->add_location(id, loc);
|
||||
spec.location(loc);
|
||||
}
|
||||
|
||||
soundsources->add(spec);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,7 @@ static int calculate_volume(int x, int y, const display &disp)
|
|||
|
||||
namespace soundsource {
|
||||
|
||||
unsigned int manager::positional_source::last_id = 0;
|
||||
unsigned int positional_source::last_id = 0;
|
||||
|
||||
manager::manager(const display &disp) : _disp(disp)
|
||||
{
|
||||
|
@ -58,16 +58,16 @@ void manager::handle_generic_event(const std::string &event_name)
|
|||
update_positions();
|
||||
}
|
||||
|
||||
void manager::add(const std::string &id, const std::string &files, int min_delay, int chance, int loop, bool play_fogged)
|
||||
void manager::add(const sourcespec &spec)
|
||||
{
|
||||
positional_source_iterator it;
|
||||
|
||||
if((it = _sources.find(id)) == _sources.end()) {
|
||||
_sources[id] = new positional_source(files, min_delay, chance, loop, play_fogged);
|
||||
if((it = _sources.find(spec.id)) == _sources.end()) {
|
||||
_sources[spec.id] = new positional_source(spec);
|
||||
}
|
||||
else {
|
||||
delete (*it).second;
|
||||
(*it).second = new positional_source(files, min_delay, chance, loop, play_fogged);
|
||||
(*it).second = new positional_source(spec);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,14 +110,14 @@ void manager::add_location(const std::string &id, const gamemap::location &loc)
|
|||
}
|
||||
|
||||
|
||||
manager::positional_source::positional_source(const std::string &files, int min_delay, int chance, int loop, bool play_fogged)
|
||||
: _last_played(0), _min_delay(min_delay), _chance(chance), _loop(loop),
|
||||
_id(last_id++), _play_fogged(play_fogged), _visible(false),
|
||||
_files(files)
|
||||
positional_source::positional_source(const sourcespec &spec)
|
||||
: _last_played(0), _min_delay(spec.min_delay), _chance(spec.chance), _loops(spec.loops),
|
||||
_id(last_id++), _check_fogged(spec.check_fogged), _visible(false), _files(spec.files),
|
||||
_locations(spec.locations)
|
||||
{
|
||||
}
|
||||
|
||||
void manager::positional_source::update(unsigned int time, const display &disp)
|
||||
void positional_source::update(unsigned int time, const display &disp)
|
||||
{
|
||||
if(time - _last_played < _min_delay || !_visible)
|
||||
return;
|
||||
|
@ -130,14 +130,14 @@ void manager::positional_source::update(unsigned int time, const display &disp)
|
|||
// If no locations have been specified, treat the source as if
|
||||
// it was present everywhere on the map
|
||||
if(_locations.size() == 0) {
|
||||
sound::play_sound_positioned(_files, last_id, _loop, 0); // max volume
|
||||
sound::play_sound_positioned(_files, last_id, _loops, 0); // max volume
|
||||
return;
|
||||
}
|
||||
|
||||
// SDL_Rect area = disp.map_outside_area();
|
||||
|
||||
int distance_volume = 256;
|
||||
for(std::list<gamemap::location>::iterator i = _locations.begin(); i != _locations.end(); ++i) {
|
||||
for(std::vector<gamemap::location>::iterator i = _locations.begin(); i != _locations.end(); ++i) {
|
||||
int locx = disp.get_location_x(*i);
|
||||
int locy = disp.get_location_y(*i);
|
||||
/*
|
||||
|
@ -153,24 +153,24 @@ void manager::positional_source::update(unsigned int time, const display &disp)
|
|||
}
|
||||
|
||||
if(!sound::is_sound_playing(last_id)) {
|
||||
sound::play_sound_positioned(_files, last_id, _loop, distance_volume);
|
||||
sound::play_sound_positioned(_files, last_id, _loops, distance_volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void manager::positional_source::update_positions(unsigned int time, const display &disp)
|
||||
void positional_source::update_positions(unsigned int time, const display &disp)
|
||||
{
|
||||
const bool was_visible = _visible;
|
||||
SDL_Rect area = disp.map_outside_area();
|
||||
|
||||
_visible = false;
|
||||
|
||||
for(std::list<gamemap::location>::iterator i = _locations.begin(); i != _locations.end(); ++i) {
|
||||
for(std::vector<gamemap::location>::iterator i = _locations.begin(); i != _locations.end(); ++i) {
|
||||
int locx = disp.get_location_x(*i);
|
||||
int locy = disp.get_location_y(*i);
|
||||
|
||||
if(disp.outside_area(area, locx, locy) || disp.shrouded(*i)
|
||||
|| (!_play_fogged && disp.fogged(*i)))
|
||||
|| (_check_fogged && disp.fogged(*i)))
|
||||
continue;
|
||||
else {
|
||||
_visible = true;
|
||||
|
@ -190,7 +190,7 @@ void manager::positional_source::update_positions(unsigned int time, const displ
|
|||
sound::stop_sound(last_id);
|
||||
}
|
||||
|
||||
void manager::positional_source::add_location(const gamemap::location &loc)
|
||||
void positional_source::add_location(const gamemap::location &loc)
|
||||
{
|
||||
_locations.push_back(loc);
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#ifndef SOUNDSOURCE_HPP_INCLUDED
|
||||
#define SOUNDSOURCE_HPP_INCLUDED
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -26,43 +25,48 @@ class display;
|
|||
|
||||
namespace soundsource {
|
||||
|
||||
class sourcespec;
|
||||
class manager;
|
||||
|
||||
/*
|
||||
* Sound source is an object on a map (a location) which has one or more
|
||||
* sounds effects associated with it, which are played randomly and with
|
||||
* appropriate delays, when sound emiting object is visible on screen.
|
||||
*/
|
||||
class positional_source {
|
||||
friend class manager;
|
||||
|
||||
unsigned int _last_played;
|
||||
unsigned int _min_delay;
|
||||
unsigned int _chance;
|
||||
unsigned int _loops;
|
||||
unsigned int _id;
|
||||
bool _check_fogged;
|
||||
bool _visible;
|
||||
std::string _files;
|
||||
std::vector<gamemap::location> _locations;
|
||||
|
||||
// Last assigned id; this can, of course, overflow, but I'd
|
||||
// never expect to see 4 billions sound sources being created...
|
||||
static unsigned int last_id;
|
||||
|
||||
// min_delay is a minimum time in seconds, which must pass before
|
||||
// this sound source can be played again if it remains visible
|
||||
//
|
||||
// chance is a chance ;-) (in %) that the sound source will emit
|
||||
// sound every second after the delay has passed or once the source
|
||||
// becomes visible
|
||||
positional_source(const sourcespec &spec);
|
||||
|
||||
void update(unsigned int time, const display &disp);
|
||||
void update_positions(unsigned int time, const display &disp);
|
||||
|
||||
void add_location(const gamemap::location &loc);
|
||||
void remove_location(const gamemap::location &loc);
|
||||
void replace_location(const gamemap::location &oldloc, const gamemap::location &newloc);
|
||||
};
|
||||
|
||||
class manager : public events::observer {
|
||||
/*
|
||||
* Sound source is an object on a map (a location) which has one or more
|
||||
* sounds effects associated with it, which are played randomly and with
|
||||
* appropriate delays, when sound emiting object is visible on screen.
|
||||
*/
|
||||
class positional_source {
|
||||
unsigned int _last_played;
|
||||
unsigned int _min_delay;
|
||||
unsigned int _chance;
|
||||
unsigned int _loop;
|
||||
unsigned int _id;
|
||||
bool _play_fogged;
|
||||
bool _visible;
|
||||
std::string _files;
|
||||
std::list<gamemap::location> _locations;
|
||||
|
||||
// Last assigned id; this can, of course, overflow, but I'd
|
||||
// never expect to see 4 billions sound sources being created...
|
||||
static unsigned int last_id;
|
||||
|
||||
public:
|
||||
// min_delay is a minimum time in seconds, which must pass before
|
||||
// this sound source can be played again if it remains visible
|
||||
//
|
||||
// chance is a chance ;-) (in %) that the sound source will emit
|
||||
// sound every second after the delay has passed or once the source
|
||||
// becomes visible
|
||||
positional_source(const std::string &files, int min_delay, int chance, int loop, bool play_fogged = false);
|
||||
|
||||
void update(unsigned int time, const display &disp);
|
||||
void update_positions(unsigned int time, const display &disp);
|
||||
|
||||
void add_location(const gamemap::location &loc);
|
||||
void remove_location(const gamemap::location &loc);
|
||||
void replace_location(const gamemap::location &oldloc, const gamemap::location &newloc);
|
||||
};
|
||||
|
||||
typedef std::map<std::string, positional_source *> positional_source_map;
|
||||
typedef positional_source_map::iterator positional_source_iterator;
|
||||
|
@ -81,13 +85,56 @@ public:
|
|||
void handle_generic_event(const std::string &event_name);
|
||||
|
||||
// add or replace a soundsource
|
||||
void add(const std::string &id, const std::string &files, int min_delay, int chance, int loop, bool play_fogged = false);
|
||||
void add(const sourcespec &source);
|
||||
void remove(const std::string &id);
|
||||
void update();
|
||||
|
||||
void add_location(const std::string &id, const gamemap::location &loc);
|
||||
};
|
||||
|
||||
} // namespace soundsource
|
||||
/*
|
||||
* A class encapsulating parameters, so that they're easier to pass around/extend/read.
|
||||
*/
|
||||
class sourcespec {
|
||||
const std::string &id;
|
||||
const std::string &files;
|
||||
|
||||
int min_delay;
|
||||
int chance;
|
||||
|
||||
int loops;
|
||||
int check_fogged;
|
||||
|
||||
std::vector<gamemap::location> locations;
|
||||
|
||||
public:
|
||||
sourcespec(const std::string &id_, const std::string &files_, int min_delay_, int chance_)
|
||||
: id(id), files(files_), min_delay(min_delay_), chance(chance_)
|
||||
{
|
||||
loops = 0;
|
||||
check_fogged = false;
|
||||
|
||||
}
|
||||
|
||||
sourcespec& loop(int loops_) {
|
||||
loops = loops_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
sourcespec& check_fog(bool fogged) {
|
||||
check_fogged = fogged;
|
||||
return *this;
|
||||
}
|
||||
|
||||
sourcespec& location(const gamemap::location &loc) {
|
||||
locations.push_back(loc);
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend class manager;
|
||||
friend class positional_source;
|
||||
};
|
||||
|
||||
} // namespace soundsourcespec
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue