aboutsummaryrefslogtreecommitdiff
path: root/src/sound.h
blob: c21401e8ba946751525b72b873c38ebc7329b670 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
Minetest
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#ifndef SOUND_HEADER
#define SOUND_HEADER

#include "irrlichttypes_bloated.h"
#include <string>
#include <set>

class OnDemandSoundFetcher
{
public:
	virtual void fetchSounds(const std::string &name,
			std::set<std::string> &dst_paths,
			std::set<std::string> &dst_datas) = 0;
};

struct SimpleSoundSpec
{
	std::string name;
	float gain;
	SimpleSoundSpec(std::string name="", float gain=1.0):
		name(name),
		gain(gain)
	{}
	bool exists() {return name != "";}
	// Serialization intentionally left out
};

class ISoundManager
{
public:
	virtual ~ISoundManager(){}
	
	// Multiple sounds can be loaded per name; when played, the sound
	// should be chosen randomly from alternatives
	// Return value determines success/failure
	virtual bool loadSoundFile(const std::string &name,
			const std::string &filepath) = 0;
	virtual bool loadSoundData(const std::string &name,
			const std::string &filedata) = 0;

	virtual void updateListener(v3f pos, v3f vel, v3f at, v3f up) = 0;
	virtual void setListenerGain(float gain) = 0;

	// playSound functions return -1 on failure, otherwise a handle to the
	// sound. If name=="", call should be ignored without error.
	virtual int playSound(const std::string &name, bool loop,
			float volume) = 0;
	virtual int playSoundAt(const std::string &name, bool loop,
			float volume, v3f pos) = 0;
	virtual void stopSound(int sound) = 0;
	virtual bool soundExists(int sound) = 0;
	virtual void updateSoundPosition(int sound, v3f pos) = 0;

	int playSound(const SimpleSoundSpec &spec, bool loop)
		{ return playSound(spec.name, loop, spec.gain); }
	int playSoundAt(const SimpleSoundSpec &spec, bool loop, v3f pos)
		{ return playSoundAt(spec.name, loop, spec.gain, pos); }
};

class DummySoundManager: public ISoundManager
{
public:
	virtual bool loadSoundFile(const std::string &name,
			const std::string &filepath) {return true;}
	virtual bool loadSoundData(const std::string &name,
			const std::string &filedata) {return true;}
	void updateListener(v3f pos, v3f vel, v3f at, v3f up) {}
	void setListenerGain(float gain) {}
	int playSound(const std::string &name, bool loop,
			float volume) {return 0;}
	int playSoundAt(const std::string &name, bool loop,
			float volume, v3f pos) {return 0;}
	void stopSound(int sound) {}
	bool soundExists(int sound) {return false;}
	void updateSoundPosition(int sound, v3f pos) {}
};

// Global DummySoundManager singleton
extern DummySoundManager dummySoundManager;

#endif

lass="hl com">Copyright (C) 2016-2019 paramat Based on Valleys Mapgen by Gael de Sailly (https://forum.minetest.net/viewtopic.php?f=9&t=11430) and mapgen_v7, mapgen_flat by kwolekr and paramat. Licensing changed by permission of Gael de Sailly. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "mapgen.h" #include "voxel.h" #include "noise.h" #include "mapblock.h" #include "mapnode.h" #include "map.h" #include "nodedef.h" #include "voxelalgorithms.h" //#include "profiler.h" // For TimeTaker #include "settings.h" // For g_settings #include "emerge.h" #include "dungeongen.h" #include "mg_biome.h" #include "mg_ore.h" #include "mg_decoration.h" #include "mapgen_valleys.h" #include "cavegen.h" #include <cmath> FlagDesc flagdesc_mapgen_valleys[] = { {"altitude_chill", MGVALLEYS_ALT_CHILL}, {"humid_rivers", MGVALLEYS_HUMID_RIVERS}, {"vary_river_depth", MGVALLEYS_VARY_RIVER_DEPTH}, {"altitude_dry", MGVALLEYS_ALT_DRY}, {NULL, 0} }; MapgenValleys::MapgenValleys(MapgenValleysParams *params, EmergeParams *emerge) : MapgenBasic(MAPGEN_VALLEYS, params, emerge) { FATAL_ERROR_IF(biomegen->getType() != BIOMEGEN_ORIGINAL, "MapgenValleys has a hard dependency on BiomeGenOriginal"); m_bgen = (BiomeGenOriginal *)biomegen; spflags = params->spflags; altitude_chill = params->altitude_chill; river_depth_bed = params->river_depth + 1.0f; river_size_factor = params->river_size / 100.0f; cave_width = params->cave_width; large_cave_depth = params->large_cave_depth; small_cave_num_min = params->small_cave_num_min; small_cave_num_max = params->small_cave_num_max; large_cave_num_min = params->large_cave_num_min; large_cave_num_max = params->large_cave_num_max; large_cave_flooded = params->large_cave_flooded; cavern_limit = params->cavern_limit; cavern_taper = params->cavern_taper; cavern_threshold = params->cavern_threshold; dungeon_ymin = params->dungeon_ymin; dungeon_ymax = params->dungeon_ymax; //// 2D Terrain noise noise_filler_depth = new Noise(&params->np_filler_depth, seed, csize.X, csize.Z); noise_inter_valley_slope = new Noise(&params->np_inter_valley_slope, seed, csize.X, csize.Z); noise_rivers = new Noise(&params->np_rivers, seed, csize.X, csize.Z); noise_terrain_height = new Noise(&params->np_terrain_height, seed, csize.X, csize.Z); noise_valley_depth = new Noise(&params->np_valley_depth, seed, csize.X, csize.Z); noise_valley_profile = new Noise(&params->np_valley_profile, seed, csize.X, csize.Z); //// 3D Terrain noise // 1-up 1-down overgeneration noise_inter_valley_fill = new Noise(&params->np_inter_valley_fill, seed, csize.X, csize.Y + 2, csize.Z); // 1-down overgeneraion MapgenBasic::np_cave1 = params->np_cave1; MapgenBasic::np_cave2 = params->np_cave2; MapgenBasic::np_cavern = params->np_cavern; MapgenBasic::np_dungeons = params->np_dungeons; } MapgenValleys::~MapgenValleys() { delete noise_filler_depth; delete noise_inter_valley_fill; delete noise_inter_valley_slope; delete noise_rivers; delete noise_terrain_height; delete noise_valley_depth; delete noise_valley_profile; } MapgenValleysParams::MapgenValleysParams(): np_filler_depth (0.0, 1.2, v3f(256, 256, 256), 1605, 3, 0.5, 2.0), np_inter_valley_fill (0.0, 1.0, v3f(256, 512, 256), 1993, 6, 0.8, 2.0), np_inter_valley_slope (0.5, 0.5, v3f(128, 128, 128), 746, 1, 1.0, 2.0), np_rivers (0.0, 1.0, v3f(256, 256, 256), -6050, 5, 0.6, 2.0), np_terrain_height (-10.0, 50.0, v3f(1024, 1024, 1024), 5202, 6, 0.4, 2.0), np_valley_depth (5.0, 4.0, v3f(512, 512, 512), -1914, 1, 1.0, 2.0), np_valley_profile (0.6, 0.50, v3f(512, 512, 512), 777, 1, 1.0, 2.0), np_cave1 (0.0, 12.0, v3f(61, 61, 61), 52534, 3, 0.5, 2.0), np_cave2 (0.0, 12.0, v3f(67, 67, 67), 10325, 3, 0.5, 2.0), np_cavern (0.0, 1.0, v3f(768, 256, 768), 59033, 6, 0.63, 2.0), np_dungeons (0.9, 0.5, v3f(500, 500, 500), 0, 2, 0.8, 2.0) { } void MapgenValleysParams::readParams(const Settings *settings) { settings->getFlagStrNoEx("mgvalleys_spflags", spflags, flagdesc_mapgen_valleys); settings->getU16NoEx("mgvalleys_altitude_chill", altitude_chill); settings->getS16NoEx("mgvalleys_large_cave_depth", large_cave_depth); settings->getU16NoEx("mgvalleys_small_cave_num_min", small_cave_num_min); settings->getU16NoEx("mgvalleys_small_cave_num_max", small_cave_num_max); settings->getU16NoEx("mgvalleys_large_cave_num_min", large_cave_num_min); settings->getU16NoEx("mgvalleys_large_cave_num_max", large_cave_num_max); settings->getFloatNoEx("mgvalleys_large_cave_flooded", large_cave_flooded); settings->getU16NoEx("mgvalleys_river_depth", river_depth); settings->getU16NoEx("mgvalleys_river_size", river_size); settings->getFloatNoEx("mgvalleys_cave_width", cave_width); settings->getS16NoEx("mgvalleys_cavern_limit", cavern_limit); settings->getS16NoEx("mgvalleys_cavern_taper", cavern_taper); settings->getFloatNoEx("mgvalleys_cavern_threshold", cavern_threshold); settings->getS16NoEx("mgvalleys_dungeon_ymin", dungeon_ymin); settings->getS16NoEx("mgvalleys_dungeon_ymax", dungeon_ymax); settings->getNoiseParams("mgvalleys_np_filler_depth", np_filler_depth); settings->getNoiseParams("mgvalleys_np_inter_valley_fill", np_inter_valley_fill); settings->getNoiseParams("mgvalleys_np_inter_valley_slope", np_inter_valley_slope); settings->getNoiseParams("mgvalleys_np_rivers", np_rivers); settings->getNoiseParams("mgvalleys_np_terrain_height", np_terrain_height); settings->getNoiseParams("mgvalleys_np_valley_depth", np_valley_depth); settings->getNoiseParams("mgvalleys_np_valley_profile", np_valley_profile); settings->getNoiseParams("mgvalleys_np_cave1", np_cave1); settings->getNoiseParams("mgvalleys_np_cave2", np_cave2); settings->getNoiseParams("mgvalleys_np_cavern", np_cavern); settings->getNoiseParams("mgvalleys_np_dungeons", np_dungeons); } void MapgenValleysParams::writeParams(Settings *settings) const { settings->setFlagStr("mgvalleys_spflags", spflags, flagdesc_mapgen_valleys); settings->setU16("mgvalleys_altitude_chill", altitude_chill); settings->setS16("mgvalleys_large_cave_depth", large_cave_depth); settings->setU16("mgvalleys_small_cave_num_min", small_cave_num_min); settings->setU16("mgvalleys_small_cave_num_max", small_cave_num_max); settings->setU16("mgvalleys_large_cave_num_min", large_cave_num_min); settings->setU16("mgvalleys_large_cave_num_max", large_cave_num_max); settings->setFloat("mgvalleys_large_cave_flooded", large_cave_flooded); settings->setU16("mgvalleys_river_depth", river_depth); settings->setU16("mgvalleys_river_size", river_size); settings->setFloat("mgvalleys_cave_width", cave_width); settings->setS16("mgvalleys_cavern_limit", cavern_limit); settings->setS16("mgvalleys_cavern_taper", cavern_taper); settings->setFloat("mgvalleys_cavern_threshold", cavern_threshold); settings->setS16("mgvalleys_dungeon_ymin", dungeon_ymin); settings->setS16("mgvalleys_dungeon_ymax", dungeon_ymax); settings->setNoiseParams("mgvalleys_np_filler_depth", np_filler_depth); settings->setNoiseParams("mgvalleys_np_inter_valley_fill", np_inter_valley_fill); settings->setNoiseParams("mgvalleys_np_inter_valley_slope", np_inter_valley_slope); settings->setNoiseParams("mgvalleys_np_rivers", np_rivers); settings->setNoiseParams("mgvalleys_np_terrain_height", np_terrain_height); settings->setNoiseParams("mgvalleys_np_valley_depth", np_valley_depth); settings->setNoiseParams("mgvalleys_np_valley_profile", np_valley_profile); settings->setNoiseParams("mgvalleys_np_cave1", np_cave1); settings->setNoiseParams("mgvalleys_np_cave2", np_cave2); settings->setNoiseParams("mgvalleys_np_cavern", np_cavern); settings->setNoiseParams("mgvalleys_np_dungeons", np_dungeons); } void MapgenValleysParams::setDefaultSettings(Settings *settings) { settings->setDefault("mgvalleys_spflags", flagdesc_mapgen_valleys, MGVALLEYS_ALT_CHILL | MGVALLEYS_HUMID_RIVERS | MGVALLEYS_VARY_RIVER_DEPTH | MGVALLEYS_ALT_DRY); } ///////////////////////////////////////////////////////////////// void MapgenValleys::makeChunk(BlockMakeData *data) { // Pre-conditions assert(data->vmanip); assert(data->nodedef); //TimeTaker t("makeChunk"); this->generating = true; this->vm = data->vmanip; this->ndef = data->nodedef; v3s16 blockpos_min = data->blockpos_min; v3s16 blockpos_max = data->blockpos_max; node_min = blockpos_min * MAP_BLOCKSIZE; node_max = (blockpos_max + v3s16(1, 1, 1)) * MAP_BLOCKSIZE - v3s16(1, 1, 1); full_node_min = (blockpos_min - 1) * MAP_BLOCKSIZE; full_node_max = (blockpos_max + 2) * MAP_BLOCKSIZE - v3s16(1, 1, 1); blockseed = getBlockSeed2(full_node_min, seed); // Generate biome noises. Note this must be executed strictly before // generateTerrain, because generateTerrain depends on intermediate // biome-related noises. m_bgen->calcBiomeNoise(node_min); // Generate terrain s16 stone_surface_max_y = generateTerrain(); // Create heightmap updateHeightmap(node_min, node_max); // Place biome-specific nodes and build biomemap if (flags & MG_BIOMES) { generateBiomes(); } // Generate tunnels, caverns and large randomwalk caves if (flags & MG_CAVES) { // Generate tunnels first as caverns confuse them generateCavesNoiseIntersection(stone_surface_max_y); // Generate caverns bool near_cavern = generateCavernsNoise(stone_surface_max_y); // Generate large randomwalk caves if (near_cavern) // Disable large randomwalk caves in this mapchunk by setting // 'large cave depth' to world base. Avoids excessive liquid in // large caverns and floating blobs of overgenerated liquid. generateCavesRandomWalk(stone_surface_max_y, -MAX_MAP_GENERATION_LIMIT); else generateCavesRandomWalk(stone_surface_max_y, large_cave_depth); } // Generate the registered ores if (flags & MG_ORES) m_emerge->oremgr->placeAllOres(this, blockseed, node_min, node_max); // Dungeon creation if (flags & MG_DUNGEONS) generateDungeons(stone_surface_max_y); // Generate the registered decorations if (flags & MG_DECORATIONS) m_emerge->decomgr->placeAllDecos(this, blockseed, node_min, node_max); // Sprinkle some dust on top after everything else was generated if (flags & MG_BIOMES) dustTopNodes(); updateLiquid(&data->transforming_liquid, full_node_min, full_node_max); if (flags & MG_LIGHT) calcLighting(node_min - v3s16(0, 1, 0), node_max + v3s16(0, 1, 0), full_node_min, full_node_max); this->generating = false; //printf("makeChunk: %lums\n", t.stop()); } int MapgenValleys::getSpawnLevelAtPoint(v2s16 p) { // Check if in a river channel float n_rivers = NoisePerlin2D(&noise_rivers->np, p.X, p.Y, seed); if (std::fabs(n_rivers) <= river_size_factor) // Unsuitable spawn point return MAX_MAP_GENERATION_LIMIT;