Skip to content

Commit 8a48655

Browse files
Merge pull request #1527 from eugenikus8/city-sounds
Sounds: enable ambient sounds
2 parents 51f87b8 + e6ddcd3 commit 8a48655

File tree

4 files changed

+148
-42
lines changed

4 files changed

+148
-42
lines changed

src/building/properties.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -748,6 +748,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = {
748748
.fire_proof = 1,
749749
.image_group = 61,
750750
.image_offset = 2,
751+
.sound_id = SOUND_CITY_AQUEDUCT, //if has_water_access
751752
.event_data.attr = "large_statue",
752753
.building_model_data = {.cost = 150, .desirability_value = 14, .desirability_step = 2,
753754
.desirability_step_size = -2, .desirability_range = 5, .laborers = 0}
@@ -1138,7 +1139,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = {
11381139
.size = 1,
11391140
.fire_proof = 1,
11401141
.image_group = 23,
1141-
// .sound_id = SOUND_CITY_WELL, // Disabled in original
1142+
.sound_id = SOUND_CITY_WELL,
11421143
.event_data.attr = "well",
11431144
.building_model_data = {.cost = 5, .desirability_value = -1, .desirability_step = 1,
11441145
.desirability_step_size = 2, .desirability_range = 1, .laborers = 0}
@@ -1414,6 +1415,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = {
14141415
.venus_gt_bonus = 1,
14151416
.size = 2,
14161417
.fire_proof = 1,
1418+
.sound_id = SOUND_CITY_AQUEDUCT, //if has_water_access
14171419
.custom_asset.group = "Aesthetics",
14181420
.custom_asset.id = "s pond south off",
14191421
.event_data.attr = "small_pond",
@@ -1424,6 +1426,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = {
14241426
.venus_gt_bonus = 1,
14251427
.size = 3,
14261428
.fire_proof = 1,
1429+
.sound_id = SOUND_CITY_AQUEDUCT, //if has_water_access
14271430
.custom_asset.group = "Aesthetics",
14281431
.custom_asset.id = "l pond south off",
14291432
.event_data.attr = "large_pond",
@@ -1742,7 +1745,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = {
17421745
},
17431746
[BUILDING_ARENA] = {
17441747
.size = 3,
1745-
.sound_id = SOUND_CITY_COLOSSEUM,
1748+
.sound_id = SOUND_CITY_ARENA,
17461749
.custom_asset.group = "Health_Culture",
17471750
.custom_asset.id = "Arena OFF",
17481751
.event_data.attr = "arena",
@@ -2159,6 +2162,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = {
21592162
},
21602163
[BUILDING_NATIVE_HUT_ALT] = {
21612164
.size = 1,
2165+
.sound_id = SOUND_CITY_NATIVE_HUT,
21622166
.fire_proof = 1,
21632167
.custom_asset.group = "Terrain_Maps",
21642168
.custom_asset.id = "Native_Hut_Central_01",
@@ -2168,6 +2172,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = {
21682172
},
21692173
[BUILDING_NATIVE_DECORATION] = {
21702174
.size = 1,
2175+
.sound_id = SOUND_CITY_NATIVE_DECORATION,
21712176
.fire_proof = 1,
21722177
.custom_asset.group = "Terrain_Maps",
21732178
.custom_asset.id = "Native_Decoration_Central_01",
@@ -2177,6 +2182,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = {
21772182
},
21782183
[BUILDING_NATIVE_MONUMENT] = {
21792184
.size = 4,
2185+
.sound_id = SOUND_CITY_NATIVE_DECORATION,
21802186
.fire_proof = 1,
21812187
.custom_asset.group = "Terrain_Maps",
21822188
.custom_asset.id = "Native_Monument_Central_01",
@@ -2186,6 +2192,7 @@ static building_properties properties[BUILDING_TYPE_MAX] = {
21862192
},
21872193
[BUILDING_NATIVE_WATCHTOWER] = {
21882194
.size = 1,
2195+
.sound_id = SOUND_CITY_WATCHTOWER,
21892196
.fire_proof = 1,
21902197
.custom_asset.group = "Terrain_Maps",
21912198
.custom_asset.id = "Native_Watchtower_Central_01",

src/sound/city.c

Lines changed: 133 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
#include "city.h"
22

3+
#include "graphics/window.h"
4+
35
#include "building/properties.h"
46
#include "city/figures.h"
7+
#include "city/population.h"
58
#include "core/file.h"
69
#include "core/random.h"
710
#include "core/time.h"
@@ -13,6 +16,7 @@
1316
#define SOUND_VIEWS_THRESHOLD 200
1417
#define SOUND_DELAY_MILLIS 30000
1518
#define SOUND_PLAY_INTERVAL_MILLIS 2000
19+
#define AMBIENT_PLAY_INTERVAL_MILLIS 5000
1620

1721
typedef enum {
1822
SOUND_AMBIENT_NONE = 0,
@@ -22,6 +26,7 @@ typedef enum {
2226
SOUND_AMBIENT_EMPTY_LAND3, // SOUND_AMBIENT_RIVER,
2327
SOUND_AMBIENT_EMPTY_TERRAIN01,
2428
SOUND_AMBIENT_EMPTY_TERRAIN02,
29+
SOUND_AMBIENT_EMPTY_LAND,
2530
SOUND_AMBIENT_MAX
2631
} sound_ambient_type;
2732

@@ -43,6 +48,7 @@ static struct {
4348
background_sound city_sounds[SOUND_CITY_MAX];
4449
background_sound ambient_sounds[SOUND_AMBIENT_MAX];
4550
time_millis last_update_time;
51+
time_millis ambient_last_played_time;
4652
} data = {
4753
.city_sounds = {
4854
[SOUND_CITY_HOUSE_SLUM] = { .filenames.total = 8, .filenames.list = (sound_filenames[]) { "wavs/house_slum1.wav", "wavs/house_slum2.wav", "wavs/house_slum3.wav", "wavs/house_slum4.wav", "wavs/house_poor1.wav", "wavs/house_poor2.wav", "wavs/house_poor3.wav", "wavs/house_poor4.wav" } },
@@ -61,7 +67,7 @@ static struct {
6167
[SOUND_CITY_GARDEN] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/gardens1.wav" } },
6268
[SOUND_CITY_CLINIC] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/clinic.wav" } },
6369
[SOUND_CITY_HOSPITAL] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/hospital.wav" } },
64-
[SOUND_CITY_BATHHOUSE] = { .filenames.total = 2, .filenames.list = (sound_filenames[]) { "wavs/baths.wav", "wavs/aquaduct.wav" } },
70+
[SOUND_CITY_BATHHOUSE] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/baths.wav" } },
6571
[SOUND_CITY_BARBER] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/barber.wav" } },
6672
[SOUND_CITY_SCHOOL] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/school.wav" } },
6773
[SOUND_CITY_ACADEMY] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/academy.wav" } },
@@ -92,7 +98,7 @@ static struct {
9298
[SOUND_CITY_FORUM] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/forum.wav" } },
9399
[SOUND_CITY_RESERVOIR] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/resevoir.wav" } },
94100
[SOUND_CITY_FOUNTAIN] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/fountain.wav" } },
95-
[SOUND_CITY_WELL] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/well1.wav" } },
101+
[SOUND_CITY_WELL] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/well.wav" } },
96102
[SOUND_CITY_MILITARY_ACADEMY] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/mil_acad.wav" } },
97103
[SOUND_CITY_BARRACKS] = { .filenames.total = 2, .filenames.list = (sound_filenames[]) { "wavs/barracks.wav", "wavs/marching.wav" } },
98104
[SOUND_CITY_ORACLE] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/oracle.wav" } },
@@ -119,14 +125,18 @@ static struct {
119125
[SOUND_CITY_DEPOT] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { ASSETS_DIRECTORY "/Sounds/Ox.ogg" } },
120126
[SOUND_CITY_CONCRETE_MAKER] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { ASSETS_DIRECTORY "/Sounds/ConcreteMaker.ogg" } },
121127
[SOUND_CITY_CONSTRUCTION_SITE] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { ASSETS_DIRECTORY "/Sounds/Engineer.ogg" } },
122-
[SOUND_CITY_NATIVE_HUT] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { ASSETS_DIRECTORY "/Sounds/NativeHut.ogg" } }
128+
[SOUND_CITY_NATIVE_HUT] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { ASSETS_DIRECTORY "/Sounds/NativeHut.ogg" } },
129+
[SOUND_CITY_AQUEDUCT] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/aquaduct.wav" } },
130+
[SOUND_CITY_ARENA] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/colloseum.wav" } }, //Dummy. If a separate sound appears, place it in the ASSETS_DIRECTORY
131+
[SOUND_CITY_NATIVE_DECORATION] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/park.wav" } },
123132
},
124133
.ambient_sounds = {
125-
[SOUND_AMBIENT_EMPTY_LAND1] = {.filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/empty_land1.wav" } },
126-
[SOUND_AMBIENT_EMPTY_LAND2] = {.filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/empty_land2.wav" } },
127-
[SOUND_AMBIENT_EMPTY_LAND3] = {.filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/empty_land3.wav" } },
128-
[SOUND_AMBIENT_EMPTY_TERRAIN01] = {.filenames.total = 1, .filenames.list = (sound_filenames[]) { ASSETS_DIRECTORY "/Sounds/Terrain01.ogg" } },
129-
[SOUND_AMBIENT_EMPTY_TERRAIN02] = {.filenames.total = 1, .filenames.list = (sound_filenames[]) { ASSETS_DIRECTORY "/Sounds/Terrain02.ogg" } }
134+
[SOUND_AMBIENT_EMPTY_LAND1] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/empty_land1.wav" } },
135+
[SOUND_AMBIENT_EMPTY_LAND2] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/empty_land2.wav" } },
136+
[SOUND_AMBIENT_EMPTY_LAND3] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/empty_land3.wav" } },
137+
[SOUND_AMBIENT_EMPTY_TERRAIN01] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { ASSETS_DIRECTORY "/Sounds/Terrain01.ogg" } },
138+
[SOUND_AMBIENT_EMPTY_TERRAIN02] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { ASSETS_DIRECTORY "/Sounds/Terrain02.ogg" } },
139+
[SOUND_AMBIENT_EMPTY_LAND] = { .filenames.total = 1, .filenames.list = (sound_filenames[]) { "wavs/empty_land.wav" } },
130140
}
131141
};
132142

@@ -156,19 +166,59 @@ void sound_city_set_volume(int percentage)
156166
sound_device_set_volume_for_type(SOUND_TYPE_CITY, percentage);
157167
}
158168

159-
void sound_city_mark_building_view(building_type type, int num_workers, int direction)
169+
void sound_city_mark_building_view(building_type type, int num_workers, int direction, int has_water_access)
160170
{
161171
sound_city_type sound = building_properties_for_type(type)->sound_id;
162172

163173
if (sound == SOUND_CITY_NONE) {
164174
return;
165175
}
166-
if (type == BUILDING_THEATER || type == BUILDING_AMPHITHEATER ||
167-
type == BUILDING_GLADIATOR_SCHOOL || type == BUILDING_HIPPODROME) {
168-
// entertainment is shut off when caesar invades
169-
if (num_workers <= 0 || city_figures_imperial_soldiers() > 0) {
170-
return;
171-
}
176+
const model_building *model = model_get_building(type);
177+
int enemies_present = city_figures_enemies() > 0 || city_figures_imperial_soldiers() > 0;
178+
179+
// Buildings for which sound is disabled during enemy attacks
180+
int mute_on_enemies = 0;
181+
int always_play = 0;
182+
switch (type) {
183+
case BUILDING_BATHHOUSE:
184+
case BUILDING_SCHOOL:
185+
case BUILDING_THEATER:
186+
case BUILDING_AMPHITHEATER:
187+
case BUILDING_ARENA:
188+
case BUILDING_COLOSSEUM:
189+
case BUILDING_HIPPODROME:
190+
case BUILDING_ACTOR_COLONY:
191+
case BUILDING_GLADIATOR_SCHOOL:
192+
case BUILDING_CHARIOT_MAKER:
193+
case BUILDING_GOVERNORS_HOUSE:
194+
case BUILDING_GOVERNORS_VILLA:
195+
case BUILDING_GOVERNORS_PALACE:
196+
mute_on_enemies = 1;
197+
break;
198+
// Buildings that always produce sound
199+
case BUILDING_NATIVE_HUT:
200+
case BUILDING_NATIVE_MEETING:
201+
case BUILDING_NATIVE_CROPS:
202+
case BUILDING_NATIVE_WATCHTOWER:
203+
case BUILDING_NATIVE_MONUMENT:
204+
case BUILDING_NATIVE_DECORATION:
205+
always_play = 1;
206+
break;
207+
default:
208+
break;
209+
}
210+
// Mute building sounds when there is no access to water
211+
if ((type == BUILDING_BATHHOUSE || type == BUILDING_CONCRETE_MAKER || type == BUILDING_FOUNTAIN ||
212+
type == BUILDING_LARGE_STATUE || type == BUILDING_SMALL_POND || type == BUILDING_LARGE_POND) &&
213+
!has_water_access) {
214+
return;
215+
}
216+
217+
// Shut off when:
218+
if (!always_play && ((model->laborers > 0 && num_workers <= 0)
219+
|| city_population() <= 0
220+
|| (enemies_present && mute_on_enemies))) {
221+
return;
172222
}
173223

174224
data.city_sounds[sound].available = 1;
@@ -247,41 +297,35 @@ static void play_sound(background_sound *sound, int direction)
247297
setting_sound(SOUND_TYPE_CITY)->volume, left_pan, right_pan, 0);
248298
}
249299

250-
void sound_city_play(void)
300+
static void sound_city_play_city(void)
251301
{
252302
time_millis now = time_get_millis();
303+
304+
if (now - data.last_update_time < SOUND_PLAY_INTERVAL_MILLIS) {
305+
// Only play 1 sound every 2 seconds
306+
return;
307+
}
308+
253309
time_millis max_delay = 0;
254310
background_sound *sound_to_play = 0;
255311
for (sound_city_type sound = SOUND_CITY_FIRST; sound < SOUND_CITY_MAX; sound++) {
256312
background_sound *current_sound = &data.city_sounds[sound];
257-
if (current_sound->available) {
258-
current_sound->available = 0;
259-
if (current_sound->total_views >= SOUND_VIEWS_THRESHOLD) {
260-
if (now - current_sound->last_played_time >= SOUND_DELAY_MILLIS) {
261-
if (now - current_sound->last_played_time > max_delay) {
262-
max_delay = now - current_sound->last_played_time;
263-
sound_to_play = current_sound;
264-
}
265-
}
266-
}
267-
} else {
268-
current_sound->total_views = 0;
269-
for (int d = 0; d < 5; d++) {
270-
current_sound->direction_views[d] = 0;
313+
if (!current_sound->available) {
314+
continue;
315+
}
316+
current_sound->available = 0;
317+
if (current_sound->total_views >= SOUND_VIEWS_THRESHOLD &&
318+
now - current_sound->last_played_time >= SOUND_DELAY_MILLIS) {
319+
if (now - current_sound->last_played_time > max_delay) {
320+
max_delay = now - current_sound->last_played_time;
321+
sound_to_play = current_sound;
271322
}
272323
}
273324
}
274325

275-
if (now - data.last_update_time < SOUND_PLAY_INTERVAL_MILLIS) {
276-
// Only play 1 sound every 2 seconds
277-
return;
278-
}
279-
280326
if (!sound_to_play) {
281-
// progress_ambient();
282327
return;
283328
}
284-
285329
// always only one channel available... use it
286330
int direction;
287331
if (sound_to_play->direction_views[SOUND_DIRECTION_CENTER] > 10) {
@@ -295,10 +339,62 @@ void sound_city_play(void)
295339
}
296340

297341
play_sound(sound_to_play, direction);
342+
sound_to_play->last_played_time = now;
343+
sound_to_play->total_views = 0;
344+
for (int d = 0; d < 5; d++) {
345+
sound_to_play->direction_views[d] = 0;
346+
}
298347
data.last_update_time = now;
348+
}
349+
350+
static void sound_city_play_ambient(void)
351+
{
352+
if (!window_is(WINDOW_CITY)) {
353+
return;
354+
}
355+
356+
time_millis now = time_get_millis();
357+
358+
// Skip if ambient interval not reached or too soon after a city sound
359+
if (now - data.ambient_last_played_time < AMBIENT_PLAY_INTERVAL_MILLIS * 2) {
360+
return;
361+
}
362+
if (now - data.last_update_time < SOUND_PLAY_INTERVAL_MILLIS) {
363+
return;
364+
}
365+
366+
sound_city_progress_ambient();
367+
time_millis max_delay = 0;
368+
background_sound *sound_to_play = 0;
369+
for (sound_ambient_type sound = SOUND_AMBIENT_FIRST; sound < SOUND_AMBIENT_MAX; sound++) {
370+
background_sound *current_sound = &data.ambient_sounds[sound];
371+
if (!current_sound->available) {
372+
continue;
373+
}
374+
375+
if (now - current_sound->last_played_time >= AMBIENT_PLAY_INTERVAL_MILLIS) {
376+
if (now - current_sound->last_played_time > max_delay) {
377+
max_delay = now - current_sound->last_played_time;
378+
sound_to_play = current_sound;
379+
}
380+
}
381+
}
382+
383+
if (!sound_to_play) {
384+
return;
385+
}
386+
387+
play_sound(sound_to_play, SOUND_DIRECTION_CENTER);
299388
sound_to_play->last_played_time = now;
300389
sound_to_play->total_views = 0;
301390
for (int d = 0; d < 5; d++) {
302391
sound_to_play->direction_views[d] = 0;
303392
}
393+
data.ambient_last_played_time = now;
394+
}
395+
396+
void sound_city_play(void)
397+
{
398+
sound_city_play_city();
399+
sound_city_play_ambient();
304400
}

src/sound/city.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,17 @@ typedef enum {
8888
SOUND_CITY_CONCRETE_MAKER,
8989
SOUND_CITY_CONSTRUCTION_SITE,
9090
SOUND_CITY_NATIVE_HUT,
91+
SOUND_CITY_AQUEDUCT,
92+
SOUND_CITY_ARENA,
93+
SOUND_CITY_NATIVE_DECORATION,
9194
SOUND_CITY_MAX
9295
} sound_city_type;
9396

9497
void sound_city_init(void);
9598

9699
void sound_city_set_volume(int percentage);
97100

98-
void sound_city_mark_building_view(building_type type, int num_workers, int direction);
101+
void sound_city_mark_building_view(building_type type, int num_workers, int direction, int has_water_access);
99102

100103
void sound_city_mark_construction_site_view(int direction);
101104

src/widget/city_without_overlay.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,12 +244,12 @@ static void draw_footprint(int x, int y, int grid_offset)
244244
if (building_monument_is_unfinished_monument(b)) {
245245
sound_city_mark_construction_site_view(direction);
246246
} else {
247-
sound_city_mark_building_view(b->type, b->num_workers, direction);
247+
sound_city_mark_building_view(b->type, b->num_workers, direction, b->has_water_access);
248248
}
249249
}
250250
}
251251
if (map_terrain_is(grid_offset, TERRAIN_GARDEN)) {
252-
sound_city_mark_building_view(BUILDING_GARDENS, 0, SOUND_DIRECTION_CENTER);
252+
sound_city_mark_building_view(BUILDING_GARDENS, 0, SOUND_DIRECTION_CENTER, 0);
253253
}
254254

255255
// Apply hover effect to non-building tiles if cursor is on them, config enabled, and not scrolling

0 commit comments

Comments
 (0)