7 const int CONTAMINATED_ZONE = 0;
8 const int UNDERGROUND = 1;
11class DynamicMusicLocationShape
27 vector min =
Vector(origin[0] - size, origin[1], origin[2] - size);
28 vector max =
Vector(origin[0] + size, origin[1], origin[2] + size);
34class DynamicMusicPlayerSettings
44 bool m_HasPriority =
false;
47 int m_Shape = DynamicMusicLocationShape.BOX;
57 locationBoundaries.Insert({min, max});
61class DynamicMusicPlayerTrackHistoryLookupType
75 bool m_Forced =
false;
76 bool m_FadeOut =
false;
81class DynamicMusicPlayer
83 #ifdef DMP_DEBUG_SETTINGS
106 protected int m_ActualTimeOfDay
119 private bool m_WaitingForPlayback;
120 private int m_RequestedPlaybackMode
124 private vector m_PlayerPosition;
126 private float m_FadeoutTimeElapsed;
127 private float m_FadeoutTimeRequested;
128 private bool m_FadeoutInProgress;
130 private bool m_Created;
137 m_ActualTimeOfDay = DynamicMusicPlayerTimeOfDay.ANY;
159 m_FadeoutTimeElapsed = 0.0;
160 m_FadeoutTimeRequested = 0.0;
169 void OnUpdate(
float timeslice)
185 if (m_FadeoutTimeElapsed >= m_FadeoutTimeRequested)
187 m_FadeoutTimeElapsed = 0.0;
188 m_FadeoutTimeRequested = 0.0;
189 m_FadeoutInProgress =
false;
203 RefreshTracksCache();
210 m_PlayerPosition =
g_Game.GetPlayer().GetPosition();
211 m_PlayerPosition[1] = 0.0;
219 if (PlayerInsideOfLocationFilter(m_LocationsDynamic))
221 else if (PlayerInsideOfLocationFilter(m_TracksLocationStaticPrioritizedCached))
232 if (PlayerInsideOfLocationFilter(m_TracksLocationStaticCached))
247 SetCategory(playbackData);
259 #ifdef DIAG_DEVELOPER
262 DisplayDebugStats(
true);
263 DisplayStaticLocations(
true);
279 if (!playbackData.m_FadeOut)
281 OnCategorySet(playbackData.m_Category, playbackData.m_Forced);
286 FadeoutTrack(GetPreviousTrackFadeoutSeconds(playbackData.m_Category));
289 void RegisterDynamicLocation(notnull
Entity caller,
int locationType,
float locationSize)
291 int id = caller.GetID();
292 if (!m_LocationsDynamic.Contains(
id))
296 location.m_Type = locationType;
297 location.m_Min = minMax[0];
298 location.m_Max = minMax[1];
299 m_LocationsDynamic.Insert(
id, location);
303 void UnregisterDynamicLocation(notnull
Entity caller)
305 m_LocationsDynamic.Remove(caller.GetID());
316 SetCategory(playbackData);
343 if (SetSelectedTrackFromCategory(category,
m_DynamicMusicPlayerRegistry.m_TracksCredits, DynamicMusicPlayerTrackHistoryLookupType.BUFFER))
389 m_RequestedPlaybackMode = value;
401 #ifdef ENABLE_LOGGING
402 DMPDebugPrint(
string.Format(
403 "OnCategorySet() - category: %1, forced: %2",
414 #ifdef ENABLE_LOGGING
416 DMPDebugPrint(
string.Format(
"Track END - %1",
m_CurrentTrack.m_SoundSet));
421 m_WaitingForPlayback =
false;
427 #ifdef ENABLE_LOGGING
429 DMPDebugPrint(
string.Format(
"Track STOP - %1",
m_CurrentTrack.m_SoundSet));
434 m_WaitingForPlayback =
false;
439 m_WaitingForPlayback =
true;
445 #ifdef ENABLE_LOGGING
446 DMPDebugPrint(
string.Format(
447 "WaitTime set to %1s, deferring playback of \"%2\"",
451 m_DebugWaitTime = waitTime;
459 #ifdef ENABLE_LOGGING
460 string messagePriority;
461 if (isPriorityLocation)
462 messagePriority =
"(with priority)";
463 DMPDebugPrint(
string.Format(
"Location matched %1", messagePriority));
467 playbackData.m_Category = category;
469 if (isPriorityLocation)
471 playbackData.m_Forced = isPriorityLocation;
475 if (m_WaitingForPlayback)
480 playbackData.m_FadeOut =
true;
481 SetCategory(playbackData);
485 SetCategory(playbackData);
488 SetCategory(playbackData);
491 SetCategory(playbackData);
502 playbackData.m_Category = category;
504 SetCategory(playbackData);
511 if (soundParams.IsValid())
514 SoundObject soundObject = soundBuilder.BuildSoundObject();
515 soundObject.SetKind(
WaveKind.WAVEMUSIC);
527 m_WaitingForPlayback =
false;
532 m_WaitingForPlayback =
false;
537 private void StopTrack()
543 private void ResetWaitingQueue()
545 if (m_WaitingForPlayback)
548 m_WaitingForPlayback =
false;
553 private void FadeoutTrack(
float fadeoutSeconds)
555 if (m_FadeoutInProgress)
562 #ifdef ENABLE_LOGGING
563 DMPDebugPrint(
string.Format(
"Stopping currently played track %1",
m_CurrentTrack.m_SoundSet));
564 DMPDebugPrint(
string.Format(
"-- Setting fadeout to %1", fadeoutSeconds));
566 m_FadeoutInProgress =
true;
567 m_FadeoutTimeRequested = fadeoutSeconds;
571 private void ProcessFadeOut()
575 float volume = 1 - (m_FadeoutTimeElapsed / m_FadeoutTimeRequested);
584 if (locations.Count() > 0)
588 switch (track.m_Shape)
590 case DynamicMusicLocationShape.BOX:
591 foreach (
int locationId,
array<vector> bounds : track.locationBoundaries)
593 if (
Math.IsPointInRectangle(bounds[0], bounds[1], m_PlayerPosition))
598 #ifdef ENABLE_LOGGING
599 DMPDebugPrint(
string.Format(
"Player inside location <%1, %2>", bounds[0], bounds[1]));
604 case DynamicMusicLocationShape.POLYGON:
605 if (
Math2D.IsPointInPolygonXZ(track.vertices, m_PlayerPosition))
610 #ifdef ENABLE_LOGGING
611 DMPDebugPrint(
string.Format(
"Player inside polygon location at <%1>", m_PlayerPosition));
624 if (locations.Count() > 0)
628 if (
Math.IsPointInRectangle(location.m_Min, location.m_Max, m_PlayerPosition))
630 #ifdef ENABLE_LOGGING
631 DMPDebugPrint(
string.Format(
"Player inside location <%1, %2>", location.m_Min, location.m_Max));
643 if (tracklist.Count() == 0)
649 if (filteredTrack.m_TimeOfDay == m_ActualTimeOfDay || filteredTrack.m_TimeOfDay == DynamicMusicPlayerTimeOfDay.ANY)
650 filteredTracks.Insert(filteredTrack);
656 trackIndex = SelectRandomTrackIndexFromCategoryPriorityFlagFirst(category, filteredTracks);
658 trackIndex = SelectRandomTrackIndexFromCategory(category, historyLookupType, filteredTracks);
662 m_LastPlayedTrackBufferPerCategory[category].Add(trackIndex);
681 if (!track.m_HasPriority)
684 priorityFlagIndices.Insert(i);
687 if (priorityFlagIndices.Count() > 0)
688 return priorityFlagIndices[priorityFlagIndices.GetRandomIndex()];
691 return tracks.GetRandomIndex();
699 int count = tracks.Count();
702 int index =
Math.RandomInt(0, count);
706 case DynamicMusicPlayerTrackHistoryLookupType.ANY:
709 case DynamicMusicPlayerTrackHistoryLookupType.BUFFER:
714 if (m_LastPlayedTrackBufferPerCategory[category].GetValues().Find(index) ==
INDEX_NOT_FOUND)
724 private void SetTimeOfDate()
728 m_ActualTimeOfDay =
g_Game.GetMission().GetWorldData().GetDaytime();
732 m_ActualTimeOfDay = DynamicMusicPlayerTimeOfDay.DAY;
737 return Math.RandomFloatInclusive(GetMinWaitTimePerCategory(category), GetMaxWaitTimePerCategory(category));
743 #ifdef DIAG_DEVELOPER
744 if (FeatureTimeAccel.GetFeatureTimeAccelEnabled(ETimeAccelCategories.DYNAMIC_MUSIC_PLAYER))
746 float timeAccel = FeatureTimeAccel.GetFeatureTimeAccelValue();
748 return waitTime / FeatureTimeAccel.GetFeatureTimeAccelValue();
757 #ifdef DIAG_DEVELOPER
758 if (FeatureTimeAccel.GetFeatureTimeAccelEnabled(ETimeAccelCategories.DYNAMIC_MUSIC_PLAYER))
760 float timeAccel = FeatureTimeAccel.GetFeatureTimeAccelValue();
762 return waitTime / FeatureTimeAccel.GetFeatureTimeAccelValue();
773 private void RefreshTracksCache()
777 m_TracksLocationStaticCached.Clear();
780 if (track.m_Shape == DynamicMusicLocationShape.BOX)
789 m_TracksLocationStaticCached.Insert(track);
792 m_TracksLocationStaticPrioritizedCached.Clear();
795 if (trackPrio.m_Shape == DynamicMusicLocationShape.BOX)
797 foreach (
array<vector> boundsPrio : trackPrio.locationBoundaries)
804 m_TracksLocationStaticPrioritizedCached.Insert(trackPrio);
809 #ifdef DIAG_DEVELOPER
812 private float m_DebugWaitTime = 0;
814 private void DisplayDebugStats(
bool enabled)
823 DbgUI.Text(
string.Format(
"Day/Night: %1", DynamicMusicPlayerTimeOfDay.ToString(m_ActualTimeOfDay)));
824 DbgUI.Text(
"Playback:");
825 DbgUI.Text(
string.Format(
" active: %1", isPlaybackActive.ToString()));
826 DbgUI.Text(
string.Format(
" waiting: %1", m_WaitingForPlayback.ToString()));
831 DbgUI.Text(
"Update timers:");
840 DbgUI.Text(
"Player:");
841 DbgUI.Text(
string.Format(
" position: %1", m_PlayerPosition.ToString()));
845 DbgUI.Text(
"Tracks counts:");
854 DbgUI.Text(
string.Format(
" Static[cache]: %1", m_TracksLocationStaticCached.Count()));
855 DbgUI.Text(
string.Format(
" Static(prio)[cache]: %1", m_TracksLocationStaticPrioritizedCached.Count()));
864 string isPlaying =
"waiting";
866 isPlaying =
"playing";
868 DbgUI.Text(
string.Format(
"State: %1", isPlaying));
869 if (m_WaitingForPlayback)
871 DbgUI.Text(
string.Format(
"Wait time: %1s (%2s)", (
int)m_DebugWaitTime, (
int)(
g_Game.GetCallQueue(
CALL_CATEGORY_SYSTEM).GetRemainingTime(PlayTrack) * 0.001)));
875 DbgUI.Text(
string.Format(
"Time of day: %1", DynamicMusicPlayerTimeOfDay.ToString(
m_CurrentTrack.m_TimeOfDay)));
882 if (
DbgUI.Button(
"Stop"))
885 if (
DbgUI.Button(
"Reset Waiting"))
891 DbgUI.Text(
"Set Category:\n");
892 if (
DbgUI.Button(
"Time"))
893 SetCategory(playbackData);
894 if (
DbgUI.Button(
"Location"))
897 SetCategory(playbackData);
899 if (
DbgUI.Button(
"Menu"))
902 SetCategory(playbackData);
904 if (
DbgUI.Button(
"Credits"))
907 SetCategory(playbackData);
910 DbgUI.Text(
"Reset Timers\n");
911 if (
DbgUI.Button(
"Timer ALL"))
918 if (
DbgUI.Button(
"Timer Daytime"))
920 if (
DbgUI.Button(
"Timer Location"))
922 if (
DbgUI.Button(
"Timer Location(prio)"))
929 private void DisplayStaticLocations(
bool enabled)
941 locationMin = bounds[0];
942 locationMax = bounds[1];
944 if (
vector.Distance(position,
Math.CenterOfRectangle(locationMin, locationMax)) > 2000)
947 Debug.CleanupDrawShapes(m_DebugShapesLocations);
949 locationMax[1] = locationMin[1] + 200.0;
950 locationMin[1] = locationMin[1] - 50.0;
954 Debug.CleanupDrawShapes(m_DebugShapesLocationsVertices);
955 DrawPolygonLocation(track);
960 foreach (
array<vector> boundsPrio : trackPrio.locationBoundaries)
962 locationMin = boundsPrio[0];
963 locationMax = boundsPrio[1];
965 if (
vector.Distance(position,
Math.CenterOfRectangle(locationMin, locationMax)) > 2000)
968 Debug.CleanupDrawShapes(m_DebugShapesLocations);
970 locationMax[1] = locationMin[1] + 200.0;
971 locationMin[1] = locationMin[1] - 50.0;
975 Debug.CleanupDrawShapes(m_DebugShapesLocationsVertices);
976 DrawPolygonLocation(trackPrio);
981 locationMin = locationDynamic.m_Min;
982 locationMax = locationDynamic.m_Max;
984 if (
vector.Distance(position,
Math.CenterOfRectangle(locationMin, locationMax)) > 2000)
987 Debug.CleanupDrawShapes(m_DebugShapesLocations);
989 locationMax[1] = locationMin[1] + 200.0;
990 locationMin[1] = locationMin[1] - 50.0;
996 Debug.CleanupDrawShapes(m_DebugShapesLocations);
997 Debug.CleanupDrawShapes(m_DebugShapesLocationsVertices);
1003 vector first, current, last;
1005 int count = track.vertices.Count();
1006 foreach (
int i,
vector vertexPos : track.vertices)
1008 vertexPos[1] = vertexPos[1] + 0.5;
1009 current = vertexPos;
1022 #ifdef ENABLE_LOGGING
1023 private void DMPDebugPrint(
string message)
1025 #ifdef DMP_DEBUG_PRINT
1033 private void CleanupDebugShapes(
array<Shape> shapesArr)
1035 Debug.CleanupDrawShapes(shapesArr);
1041 playbackData.m_Category = category;
1042 playbackData.m_Forced = forced;
1044 SetCategory(playbackData);
Base Param Class with no parameters. Used as general purpose parameter overloaded with Param1 to Para...
Result for an object found in CGame.IsBoxCollidingGeometryProxy.
const int TRACKS_BUFFER_HISTORY_SIZE
class DynamicMusicLocationDynamicData m_MinWaitTimeSeconds
EDynamicMusicPlayerCategory m_CategorySelected
const float TICK_PRIORITY_LOCATION_UPDATE_SECONDS
float m_TickLocationCacheUpdateElapsed
class DynamicMusicTrackData ANY
const float LOCATION_DISTANCE_MAX
float GetWaitTimeForCategory(EDynamicMusicPlayerCategory category)
void OnCategorySet(EDynamicMusicPlayerCategory category, bool forced)
const float TICK_FADEOUT_PROCESSOR_SECONDS
AbstractWave m_SoundPlaying
float m_PreviousTrackFadeoutSeconds
float m_TickTimeOfDateElapsed
ref DynamicMusicPlayerRegistry m_DynamicMusicPlayerRegistry
bool IsPriotitizedCategorySelected()
float m_TickFadeOutProcessingElapsed
void OnProfileOptionChanged(EDayZProfilesOptions option, int value)
void OnNextTrackSelected(DynamicMusicTrackData track, float waitTime)
void DetermineTrackByCategory(EDynamicMusicPlayerCategory category)
void OnLocationMatched(EDynamicMusicPlayerCategory category, bool isPriorityLocation)
const float TICK_LOCATION_CACHE_UPDATE_SECONDS
const float TICK_LOCATION_UPDATE_SECONDS
class DynamicMusicPlayerCategoryPlaybackData TICK_TIME_OF_DATE_UPDATE_SECONDS
DynamicMusicTrackData m_CurrentTrack
float m_TickPriorityLocationUpdateElapsed
ref array< ref DynamicMusicTrackData > m_TracksLocationMatchedPlayerInside
static prio + filtered by the distance between player and center of zone
void OnFadeoutFinished(EDynamicMusicPlayerCategory category)
float m_TickLocationUpdateElapsed
float m_MaxWaitTimeSeconds
EDynamicMusicPlayerCategory
const int INDEX_NOT_FOUND
const EventType MPSessionPlayerReadyEventTypeID
no params
proto native CGame GetGame()
enum WindingOrder Math2D()
proto native vector Vector(float x, float y, float z)
Vector constructor from components.
class AbstractSoundScene SoundObjectBuilder(SoundParams soundParams)
class SoundObject SoundParams(string name)
class PresenceNotifierNoiseEvents windowPosX
dbgUI settings