Skip to content

Commit 602d876

Browse files
committed
shuffle mode, breaks on debug min
1 parent d0ef3ab commit 602d876

File tree

3 files changed

+118
-17
lines changed

3 files changed

+118
-17
lines changed

Data/Browncoats.rte/Music.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ AddDynamicSongSection = DynamicSongSection
152152
CopyOf = BCOSTTest Ambient Main 2
153153
AddSoundContainer = SoundContainer
154154
CopyOf = BCOSTTest Ambient Main 3
155+
SoundContainerSelectionCycleMode = shuffle
155156

156157
AddDynamicSongSection = DynamicSongSection
157158
PresetName = BCOSTTest Tense

Source/Entities/DynamicSong.cpp

Lines changed: 79 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ using namespace RTE;
55
ConcreteClassInfo(DynamicSongSection, Entity, 50);
66
ConcreteClassInfo(DynamicSong, Entity, 50);
77

8+
const std::unordered_map<std::string, DynamicSongSection::SoundContainerSelectionCycleMode> DynamicSongSection::c_SoundContainerSelectionCycleModeMap = {
9+
{"randomnorepeat", SoundContainerSelectionCycleMode::RANDOMNOREPEAT},
10+
{"shuffle", SoundContainerSelectionCycleMode::SHUFFLE}};
11+
812
DynamicSongSection::DynamicSongSection() {
913
Clear();
1014
}
@@ -21,8 +25,13 @@ DynamicSongSection::~DynamicSongSection() {
2125
void DynamicSongSection::Clear() {
2226
m_TransitionSoundContainers.clear();
2327
m_LastTransitionSoundContainerIndex = -1;
28+
m_TransitionShuffleIndices.clear();
29+
2430
m_SoundContainers.clear();
2531
m_LastSoundContainerIndex = -1;
32+
m_ShuffleIndices.clear();
33+
34+
m_SoundContainerSelectionCycleMode = RANDOMNOREPEAT;
2635
m_SectionType = "Default";
2736
}
2837

@@ -34,16 +43,16 @@ int DynamicSongSection::Create(const DynamicSongSection& reference) {
3443
soundContainer.Create(referenceSoundContainer);
3544
m_TransitionSoundContainers.push_back(soundContainer);
3645
}
37-
3846
m_LastTransitionSoundContainerIndex = reference.m_LastTransitionSoundContainerIndex;
39-
47+
4048
for (const SoundContainer& referenceSoundContainer: reference.m_SoundContainers) {
4149
SoundContainer soundContainer;
4250
soundContainer.Create(referenceSoundContainer);
4351
m_SoundContainers.push_back(soundContainer);
4452
}
45-
4653
m_LastSoundContainerIndex = reference.m_LastSoundContainerIndex;
54+
55+
m_SoundContainerSelectionCycleMode = reference.m_SoundContainerSelectionCycleMode;
4756
m_SectionType = reference.m_SectionType;
4857

4958
return 0;
@@ -62,11 +71,32 @@ int DynamicSongSection::ReadProperty(const std::string_view& propName, Reader& r
6271
reader >> soundContainerToAdd;
6372
m_SoundContainers.push_back(soundContainerToAdd);
6473
});
74+
MatchProperty("SoundContainerSelectionCycleMode", {
75+
std::string soundContainerSelectionCycleModeString = reader.ReadPropValue();
76+
if (c_SoundContainerSelectionCycleModeMap.find(soundContainerSelectionCycleModeString) != c_SoundContainerSelectionCycleModeMap.end()) {
77+
m_SoundContainerSelectionCycleMode = c_SoundContainerSelectionCycleModeMap.find(soundContainerSelectionCycleModeString)->second;
78+
} else {
79+
try {
80+
m_SoundContainerSelectionCycleMode = static_cast<SoundContainerSelectionCycleMode>(std::stoi(soundContainerSelectionCycleModeString));
81+
} catch (const std::exception&) {
82+
reader.ReportError("Tried to set non-existent SoundContainerSelectionCycleMode " + soundContainerSelectionCycleModeString);
83+
}
84+
}
85+
});
6586
MatchProperty("SectionType", { reader >> m_SectionType; });
6687

6788
EndPropertyList;
6889
}
6990

91+
void DynamicSongSection::SaveSoundContainerSelectionCycleMode(Writer& writer, SoundContainerSelectionCycleMode soundContainerSelectionCycleMode) {
92+
auto cycleModeMapEntry = std::find_if(c_SoundContainerSelectionCycleModeMap.begin(), c_SoundContainerSelectionCycleModeMap.end(), [&soundContainerSelectionCycleMode = soundContainerSelectionCycleMode](auto element) { return element.second == soundContainerSelectionCycleMode; });
93+
if (cycleModeMapEntry != c_SoundContainerSelectionCycleModeMap.end()) {
94+
writer << cycleModeMapEntry->first;
95+
} else {
96+
RTEAbort("Tried to write invalid SoundContainerSelectionCycleMode when saving DynamicSongSection.");
97+
}
98+
}
99+
70100
int DynamicSongSection::Save(Writer& writer) const {
71101
Entity::Save(writer);
72102

@@ -86,6 +116,8 @@ int DynamicSongSection::Save(Writer& writer) const {
86116
}
87117
writer.NewProperty("LastSoundContainerIndex");
88118
writer << m_LastSoundContainerIndex;
119+
writer.NewProperty("SoundContainerSelectionCycleMode");
120+
SaveSoundContainerSelectionCycleMode(writer, m_SoundContainerSelectionCycleMode);
89121
writer.NewProperty("SectionType");
90122
writer << m_SectionType;
91123

@@ -100,16 +132,31 @@ SoundContainer& DynamicSongSection::SelectTransitionSoundContainer() {
100132
return m_TransitionSoundContainers[0];
101133
}
102134

103-
std::vector<unsigned int> validIndices;
104-
for (unsigned int i = 0; i < m_TransitionSoundContainers.size(); i++) {
105-
if (i != m_LastTransitionSoundContainerIndex) {
106-
validIndices.push_back(i);
135+
if (m_TransitionShuffleIndices.empty()) {
136+
for(unsigned int i = 0; i <= m_TransitionSoundContainers.size() - 1; i++ ) {
137+
m_TransitionShuffleIndices.push_back(i);
107138
}
108139
}
109140

110-
unsigned int randomIndex = validIndices[RandomNum(0, static_cast<int>(validIndices.size()) - 1)];
111-
m_LastTransitionSoundContainerIndex = randomIndex;
112-
return m_TransitionSoundContainers[randomIndex];
141+
switch (m_SoundContainerSelectionCycleMode) {
142+
case RANDOMNOREPEAT: {
143+
std::vector<unsigned int> validIndices;
144+
for (unsigned int i = 0; i < m_TransitionSoundContainers.size(); i++) {
145+
if (i != m_LastTransitionSoundContainerIndex) {
146+
validIndices.push_back(i);
147+
}
148+
}
149+
150+
unsigned int randomIndex = validIndices[RandomNum(0, static_cast<int>(validIndices.size()) - 1)];
151+
m_LastTransitionSoundContainerIndex = randomIndex;
152+
return m_TransitionSoundContainers[randomIndex];
153+
}
154+
case SHUFFLE: {
155+
unsigned int selectedIndex = m_TransitionShuffleIndices[RandomNum(0, static_cast<int>(m_TransitionShuffleIndices.size()) - 1)];
156+
m_TransitionShuffleIndices.erase(m_TransitionShuffleIndices.begin() + selectedIndex);
157+
return m_TransitionSoundContainers[selectedIndex];
158+
}
159+
}
113160
}
114161

115162
SoundContainer& DynamicSongSection::SelectSoundContainer() {
@@ -119,16 +166,31 @@ SoundContainer& DynamicSongSection::SelectSoundContainer() {
119166
return m_SoundContainers[0];
120167
}
121168

122-
std::vector<unsigned int> validIndices;
123-
for (unsigned int i = 0; i < m_SoundContainers.size(); i++) {
124-
if (i != m_LastSoundContainerIndex) {
125-
validIndices.push_back(i);
169+
if (m_ShuffleIndices.empty()) {
170+
for(unsigned int i = 0; i <= m_SoundContainers.size() - 1; i++ ) {
171+
m_ShuffleIndices.push_back(i);
126172
}
127173
}
128174

129-
unsigned int randomIndex = validIndices[RandomNum(0, static_cast<int>(validIndices.size()) - 1)];
130-
m_LastSoundContainerIndex = randomIndex;
131-
return m_SoundContainers[randomIndex];
175+
switch (m_SoundContainerSelectionCycleMode) {
176+
case RANDOMNOREPEAT: {
177+
std::vector<unsigned int> validIndices;
178+
for (unsigned int i = 0; i < m_SoundContainers.size(); i++) {
179+
if (i != m_LastSoundContainerIndex) {
180+
validIndices.push_back(i);
181+
}
182+
}
183+
184+
unsigned int randomIndex = validIndices[RandomNum(0, static_cast<int>(validIndices.size()) - 1)];
185+
m_LastSoundContainerIndex = randomIndex;
186+
return m_SoundContainers[randomIndex];
187+
}
188+
case SHUFFLE: {
189+
unsigned int selectedIndex = m_ShuffleIndices[RandomNum(0, static_cast<int>(m_ShuffleIndices.size()) - 1)];
190+
m_ShuffleIndices.erase(m_ShuffleIndices.begin() + selectedIndex);
191+
return m_SoundContainers[selectedIndex];
192+
}
193+
}
132194
}
133195

134196
DynamicSong::DynamicSong() {

Source/Entities/DynamicSong.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ namespace RTE {
1212
SerializableOverrideMethods;
1313
ClassInfoGetters;
1414

15+
/// How the DynamicSongSection should select the next SoundContainer when SelectSoundContainer is called.
16+
enum SoundContainerSelectionCycleMode {
17+
RANDOMNOREPEAT = 0,
18+
SHUFFLE
19+
};
20+
1521
#pragma region Creation
1622
/// Constructor method used to instantiate a DynamicSongSection object in system memory. Create() should be called before using the object.
1723
DynamicSongSection();
@@ -56,6 +62,13 @@ namespace RTE {
5662
void AddSoundContainer(const SoundContainer& soundContainerToAdd) { m_SoundContainers.push_back(soundContainerToAdd); }
5763
#pragma endregion
5864

65+
#pragma region INI Handling
66+
/// Handles writing the given SoundContainerSelectionCycleMode out to the given Writer, using the static SoundContainerSelectionCycleMap.
67+
/// @param writer A Writer filled in with the property to write to.
68+
/// @param soundContainerSelectionCycleMode The SoundSelectionCycleMode to write.
69+
static void SaveSoundContainerSelectionCycleMode(Writer& writer, SoundContainerSelectionCycleMode soundContainerSelectionCycleMode);
70+
#pragma endregion
71+
5972
#pragma region Getters and Setters
6073
/// Gets the vector of TransitionSoundContainers for this DynamicSongSection.
6174
/// @return The vector of TransitionSoundContainers for this DynamicSongSection.
@@ -65,6 +78,26 @@ namespace RTE {
6578
/// @return The vector of SoundContainers for this DynamicSongSection.
6679
std::vector<SoundContainer>& GetSoundContainers() { return m_SoundContainers; }
6780

81+
/// Gets the SoundContainerSelectionCycleMode of this DynamicSongSection.
82+
/// @return The SoundContainerSelectionCycleMode of this DynamicSongSection.
83+
SoundContainerSelectionCycleMode GetSoundContainerSelectionCycleMode() const { return m_SoundContainerSelectionCycleMode; }
84+
85+
/// Sets the SoundContainerSelectionCycleMode of this DynamicSongSection. Resets any current state of selection.
86+
/// @param newSoundContainerSelectionCycleMode The new SoundContainerSelectionCycleMode for this DynamicSongSection.
87+
void SetSoundContainerSelectionCycleMode(SoundContainerSelectionCycleMode newSoundContainerSelectionCycleMode) {
88+
m_SoundContainerSelectionCycleMode = newSoundContainerSelectionCycleMode;
89+
m_LastTransitionSoundContainerIndex = -1;
90+
m_TransitionShuffleIndices.clear();
91+
for(unsigned int i = 0; i <= m_TransitionSoundContainers.size() - 1; i++ ) {
92+
m_TransitionShuffleIndices.push_back(i);
93+
}
94+
m_LastSoundContainerIndex = -1;
95+
m_ShuffleIndices.clear();
96+
for(unsigned int i = 0; i <= m_SoundContainers.size() - 1; i++ ) {
97+
m_ShuffleIndices.push_back(i);
98+
}
99+
}
100+
68101
/// Gets the SectionType of this DynamicSongSection.
69102
/// @return The SectionType of this DynamicSongSection.
70103
std::string& GetSectionType() { return m_SectionType; }
@@ -84,11 +117,16 @@ namespace RTE {
84117

85118
private:
86119
static Entity::ClassInfo m_sClass; //!< ClassInfo for this class.
120+
static const std::unordered_map<std::string, SoundContainerSelectionCycleMode> c_SoundContainerSelectionCycleModeMap; //!< A map of strings to SoundContainerSelectionCycleModes to support string parsing for the SoundContainerSelectionCycleMode enum. Populated in the implementing cpp file.
87121

88122
std::vector<SoundContainer> m_TransitionSoundContainers; //!< The SoundContainers that will play when first switching to this DynamicSongSection.
89123
unsigned int m_LastTransitionSoundContainerIndex; //!< The last index used to select a TransitionSoundContainer.
124+
std::vector<unsigned int> m_TransitionShuffleIndices; //!< Indices left to play if in Shuffle mode.
90125
std::vector<SoundContainer> m_SoundContainers; //!< The SoundContainers making up this DynamicSongSection.
91126
unsigned int m_LastSoundContainerIndex; //!< The last index used to select a SoundContainer.
127+
std::vector<unsigned int> m_ShuffleIndices; //!< Indices left to play if in Shuffle mode.
128+
129+
SoundContainerSelectionCycleMode m_SoundContainerSelectionCycleMode; //!< The selection cycle mode to use when selecting the next SoundContainer.
92130
std::string m_SectionType; //!< The name of the type of dynamic music this is.
93131

94132
/// Clears all the member variables of this DynamicSongSection, effectively resetting the members of this abstraction level only.

0 commit comments

Comments
 (0)