1 /*
2    Copyright (C) 2006 - 2018 by Karol Nowak <grzywacz@sul.uni.lodz.pl>
3    Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY.
11 
12    See the COPYING file for more details.
13 */
14 
15 #pragma once
16 
17 #include <map>
18 
19 #include "generic_event.hpp"
20 #include "map/location.hpp"
21 
22 class config;
23 class display;
24 
25 namespace soundsource {
26 
27 class sourcespec;
28 class manager;
29 
30 /*
31  * Sound source is an object on a map (a location) which has one or more
32  * sounds effects associated with it, which are played randomly and with
33  * appropriate delays, when sound emitting object is visible on screen.
34  */
35 class positional_source {
36 	unsigned int last_played_;
37 	int min_delay_;
38 	int chance_;
39 	int loops_;
40 	const unsigned int id_;
41 	int range_;
42 	int faderange_;
43 	bool check_fogged_;
44 	bool check_shrouded_;
45 	std::string files_;
46 	std::vector<map_location> locations_;
47 
48 	// Last assigned id; this can, of course, overflow, but I'd
49 	// never expect to see 4 billions sound sources being created...
50 	static unsigned int last_id;
51 
52 public:
53 	// min_delay is a minimum time in seconds, which must pass before
54 	// this sound source can be played again if it remains visible
55 	//
56 	// chance is a chance ;-) (in %) that the sound source will emit
57 	// sound every second after the delay has passed or once the source
58 	// becomes visible
59 	positional_source(const sourcespec &spec);
60 	~positional_source();
61 
62 	bool is_global() const;
63 
64 	void update(unsigned int time, const display &disp);
65 	void update_positions(unsigned int time, const display &disp);
66 
67 	int calculate_volume(const map_location &loc, const display &disp);
68 
69 	/**
70 	 * Serializes attributes as WML config.
71 	 * @param cfg A reference to a [sound_source] tag object.
72 	 */
73 	void write_config(config& cfg) const;
74 };
75 
76 class manager : public events::observer
77 {
78 
79 	typedef std::map<std::string, std::unique_ptr<positional_source>> positional_source_map;
80 	typedef positional_source_map::iterator            positional_source_iterator;
81 	typedef positional_source_map::const_iterator      positional_source_const_iterator;
82 
83 	positional_source_map sources_;
84 	const display &disp_;
85 
86 public:
87 	manager(const display &disp);
88 	~manager();
89 
90 	// event interface
91 	void handle_generic_event(const std::string &event_name);
92 
93 	// add or replace a soundsource
94 	void add(const sourcespec &source);
95 	void remove(const std::string &id);
96 	config get(const std::string &id);
97 	void update();
98 
99 	// checks which sound sources are visible
100 	void update_positions();
101 
102 	/**
103 	 * Serializes information into cfg as new children of key
104 	 * "sound_source", appended to existing content.
105 	 */
106 	void write_sourcespecs(config& cfg) const;
107 };
108 
109 /**
110  * Sound source info class.
111  * Encapsulates sound source parameters, so that they're easier to pass
112  * around/extend/read.
113  */
114 class sourcespec
115 {
116 	const std::string id_;
117 	const std::string files_;
118 
119 	int min_delay_;
120 	int chance_;
121 
122 	int loops_;
123 	int range_;
124 	int faderange_;
125 	bool check_fogged_;
126 	bool check_shrouded_;
127 
128 	std::vector<map_location> locations_;
129 
130 public:
131 	/** Parameter-list constructor. */
sourcespec(const std::string & id,const std::string & files,int min_delay,int chance)132 	sourcespec(const std::string& id, const std::string& files, int min_delay, int chance) :
133 		id_(id),
134 		files_(files),
135 		min_delay_(min_delay),
136 		chance_(chance),
137 		loops_(0),
138 		range_(3),
139 		faderange_(14),
140 		check_fogged_(false),
141 		check_shrouded_(false),
142 		locations_()
143 	{}
144 
145 	/** WML constructor. */
146 	sourcespec(const config& cfg);
147 
148 	/**
149 	 * Serializes information into cfg as a new (appended)
150 	 * child of key "sound_source".
151 	 */
152 	void write(config& cfg) const;
153 
loops() const154 	int loops() const { return loops_; }
155 
set_loops(int value)156 	void set_loops(int value) {
157 		loops_ = value;
158 	}
159 
check_fogged() const160 	bool check_fogged() const { return check_fogged_; }
check_shrouded() const161 	bool check_shrouded() const { return check_shrouded_; }
162 
set_check_fogged(bool value)163 	void set_check_fogged(bool value) {
164 		check_fogged_ = value;
165 	}
166 
set_check_shrouded(bool value)167 	void set_check_shrouded(bool value) {
168 		check_shrouded_ = value;
169 	}
170 
get_locations() const171 	const std::vector<map_location>& get_locations() const {
172 		return locations_;
173 	}
174 
full_range() const175 	int full_range() const { return range_; }
176 
set_full_range(int value)177 	void set_full_range(int value) {
178 		range_ = value;
179 	}
180 
fade_range() const181 	int fade_range() const { return faderange_; }
182 
set_fade_range(int value)183 	void set_fade_range(int value) {
184 		faderange_ = value;
185 	}
186 
minimum_delay() const187 	int minimum_delay() const { return min_delay_; }
188 
set_minimum_delay(int value)189 	void set_minimum_delay(int value) {
190 		min_delay_ = value;
191 	}
192 
chance() const193 	int chance() const { return chance_; }
194 
set_chance(int value)195 	void set_chance(int value) {
196 		chance_ = value;
197 	}
198 
id() const199 	const std::string& id() const { return id_; }
200 
files() const201 	const std::string& files() const { return files_; }
202 };
203 
204 } // namespace soundsource
205