mirror of
				https://github.com/OpenMW/openmw.git
				synced 2025-10-31 10:26:41 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			160 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			Lua
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			160 lines
		
	
	
	
		
			4.9 KiB
		
	
	
	
		
			Lua
		
	
	
		
			Executable file
		
	
	
	
	
| local ambient = require('openmw.ambient')
 | |
| local core = require('openmw.core')
 | |
| local self = require('openmw.self')
 | |
| local storage = require('openmw.storage')
 | |
| local types = require('openmw.types')
 | |
| 
 | |
| local musicSettings = storage.playerSection('SettingsOMWMusic')
 | |
| 
 | |
| local helpers = require('scripts.omw.music.helpers')
 | |
| 
 | |
| local registeredPlaylists = {}
 | |
| local playlistsTracksOrder = helpers.getStoredTracksOrder()
 | |
| local fightingActors = {}
 | |
| local registrationOrder = 0
 | |
| 
 | |
| local currentPlaylist = nil
 | |
| local skippedOneFrame = false
 | |
| 
 | |
| local battlePriority = 10
 | |
| local explorePriority = 100
 | |
| 
 | |
| local function registerPlaylist(playlist)
 | |
|     helpers.initMissingPlaylistFields(playlist)
 | |
| 
 | |
|     local existingOrder = playlistsTracksOrder[playlist.id]
 | |
|     if not existingOrder or next(existingOrder) == nil or math.max(unpack(existingOrder)) > #playlist.tracks then
 | |
|         local newPlaylistOrder = helpers.initTracksOrder(playlist.tracks, playlist.randomize)
 | |
|         playlistsTracksOrder[playlist.id] = newPlaylistOrder
 | |
|         helpers.setStoredTracksOrder(playlist.id, newPlaylistOrder)
 | |
|     else
 | |
|         playlistsTracksOrder[playlist.id] = existingOrder
 | |
|     end
 | |
| 
 | |
|     if registeredPlaylists[playlist.id] == nil then
 | |
|         playlist.registrationOrder = registrationOrder
 | |
|         registrationOrder = registrationOrder + 1
 | |
|     end
 | |
| 
 | |
|     registeredPlaylists[playlist.id] = playlist
 | |
| end
 | |
| 
 | |
| local function setPlaylistActive(id, state)
 | |
|     if id == nil then
 | |
|         error("Playlist ID is nil")
 | |
|     end
 | |
| 
 | |
|     local playlist = registeredPlaylists[id]
 | |
|     if playlist then
 | |
|         playlist.active = state
 | |
|     else
 | |
|         error(string.format("Playlist '%s' is not registered.", id))
 | |
|     end
 | |
| end
 | |
| 
 | |
| local function onCombatTargetsChanged(eventData)
 | |
|     if eventData.actor == nil then return end
 | |
| 
 | |
|     if next(eventData.targets) ~= nil then
 | |
|         fightingActors[eventData.actor.id] = true
 | |
|     else
 | |
|         fightingActors[eventData.actor.id] = nil
 | |
|     end
 | |
| end
 | |
| 
 | |
| local function playerDied()
 | |
|     ambient.streamMusic("music/special/mw_death.mp3")
 | |
| end
 | |
| 
 | |
| local function switchPlaylist(newPlaylist)
 | |
|     local newPlaylistOrder = playlistsTracksOrder[newPlaylist.id]
 | |
|     local nextTrackIndex = table.remove(newPlaylistOrder)
 | |
| 
 | |
|     if nextTrackIndex == nil then
 | |
|         error("Can not fetch track: nextTrackIndex is nil")
 | |
|     end
 | |
| 
 | |
|     -- If there are no tracks left, fill playlist again.
 | |
|     if next(newPlaylistOrder) == nil then
 | |
|         newPlaylistOrder = helpers.initTracksOrder(newPlaylist.tracks, newPlaylist.randomize)
 | |
| 
 | |
|         if not newPlaylist.cycleTracks then
 | |
|             newPlaylist.deactivateAfterEnd = true
 | |
|         end
 | |
| 
 | |
|         -- If next track for randomized playist will be the same as one we want to play, swap it with random track.
 | |
|         if newPlaylist.randomize and #newPlaylistOrder > 1 and newPlaylistOrder[1] == nextTrackIndex then
 | |
|             local index = math.random(2, #newPlaylistOrder)
 | |
|             newPlaylistOrder[1], newPlaylistOrder[index] = newPlaylistOrder[index], newPlaylistOrder[1]
 | |
|         end
 | |
| 
 | |
|         playlistsTracksOrder[newPlaylist.id] = newPlaylistOrder
 | |
|     end
 | |
| 
 | |
|     helpers.setStoredTracksOrder(newPlaylist.id, newPlaylistOrder)
 | |
| 
 | |
|     local trackPath = newPlaylist.tracks[nextTrackIndex]
 | |
|     if trackPath == nil then
 | |
|         error(string.format("Can not fetch track with index %s from playlist '%s'.", nextTrackIndex, newPlaylist.id))
 | |
|     else
 | |
|         ambient.streamMusic(trackPath, newPlaylist.fadeOut)
 | |
|         if newPlaylist.playOneTrack then
 | |
|             newPlaylist.deactivateAfterEnd = true
 | |
|         end
 | |
|     end
 | |
| 
 | |
|     currentPlaylist = newPlaylist
 | |
| end
 | |
| 
 | |
| local function onFrame(dt)
 | |
|     -- Skip a first frame to allow other scripts to update playlists state.
 | |
|     if not skippedOneFrame then
 | |
|         skippedOneFrame = true
 | |
|         return
 | |
|     end
 | |
| 
 | |
|     if not core.sound.isEnabled() then return end
 | |
| 	
 | |
| 	-- Do not allow to switch playlists when player is dead
 | |
| 	local musicPlaying = ambient.isMusicPlaying()
 | |
| 	if types.Actor.isDead(self) and musicPlaying then return end
 | |
| 
 | |
|     local combatMusicEnabled = musicSettings:get("CombatMusicEnabled") and helpers.isInCombat(fightingActors)
 | |
|     setPlaylistActive("battle", combatMusicEnabled)
 | |
| 
 | |
|     local newPlaylist = helpers.getActivePlaylistByPriority(registeredPlaylists)
 | |
| 
 | |
|     if not newPlaylist then
 | |
|         ambient.stopMusic()
 | |
| 
 | |
|         if currentPlaylist ~= nil then
 | |
|             currentPlaylist.deactivateAfterEnd = nil
 | |
|         end
 | |
| 
 | |
|         currentPlaylist = nil
 | |
|         return
 | |
|     end
 | |
| 
 | |
|     if newPlaylist == currentPlaylist and musicPlaying then return end
 | |
| 
 | |
|     if newPlaylist and newPlaylist.deactivateAfterEnd then
 | |
|         newPlaylist.deactivateAfterEnd = nil
 | |
|         newPlaylist.active = false
 | |
|         return
 | |
|     end
 | |
| 
 | |
|     switchPlaylist(newPlaylist)
 | |
| end
 | |
| 
 | |
| registerPlaylist({ id = "battle", priority = battlePriority, randomize = true })
 | |
| registerPlaylist({ id = "explore", priority = explorePriority, randomize = true, active = true })
 | |
| 
 | |
| return {
 | |
|     engineHandlers = {
 | |
|         onFrame = onFrame
 | |
|     },
 | |
|     eventHandlers = {
 | |
|         Died = playerDied,
 | |
|         OMWMusicCombatTargetsChanged = onCombatTargetsChanged
 | |
|     }
 | |
| }
 |