Kors Posted November 20, 2017 Share Posted November 20, 2017 How to make that only A, b, c, d, e and remove ,other, sry bad english. Link to comment
Kors Posted November 20, 2017 Author Share Posted November 20, 2017 (edited) meta.xml <meta> <info description="judo" author="judo" type="script" version="0.3.0" /> <!-- If radio3d_playlist resource exists, then it's included. Actually only clientside? --> <include resource="radio3d_playlist" /> <script src="server_player.lua" type="server" /> <script src="radio3d_client.lua" type="client" /> <file src="music/placeholder.mp3" /> <export function="changeSetting" type="server"/> <settings> <setting name="*sound3d_min_distance" value="8" friendlyname="Minimum Distance" group="Sound Distance" accept="0-1000" desc="Distance when sound will start get more quiet when moving away from sound source." /> <setting name="*sound3d_max_distance" value="15" friendlyname="Maximum Distance" group="Sound Distance" accept="0-1000" desc="Maximum distance, can cut down the area the sound is heared too." /> <setting name="*sound3d_outside_volume_vehicle" value="50" friendlyname="Volume of other Vehicles" group="Sound Volumes" accept="0-100" desc="How loud do you want to hear other vehicles while in your car? Percent." /> <setting name="*sound3d_outside_volume_foot" value="70" friendlyname="Volume on foot" group="Sound Volumes" accept="0-100" desc="How loud do you want to hear other vehicles while being on foot? Percent." /> <setting name="*sound3d_own_vehicle_volume" value="100" friendlyname="Own vehicle volume" group="Sound Volumes" accept="0-100" desc="How loud do you want to hear own vehicle while being in it? Percent." /> <setting name="*sound3d_radio_off_on_vehicle_exit" value="false" friendlyname="Radio off on vehicle Exit" group="Preferences" accept="false,true" desc="Turn off radio when exiting vehicle?" /> <setting name="*sound3d_radio_off_on_blow_up" value="true" friendlyname="Radio off on vehicle blow" group="Preferences" accept="false,true" desc="Turn off radio when vehicle blows up?" /> <setting name="*playlist_title" value="Choose Song" friendlyname="Playlist Title" group="Text" accept="*" examples="Choose Song, Playlist, etc" desc="The title appearing in top of the playlist" /> <setting name="*close_playlist_desc" value="Press 0 to close the playlist" friendlyname="Close Playlist" group="Text" accept="*" examples="Press 0 to close the playlist, 0 to close" desc="The description appearing in bottom of the playlist" /> <setting name="*no_music" value="No music" friendlyname="No Music entry" group="Text" accept="*" examples="no music, disable" desc="Playlist entry to disable music" /> <setting name="*placeholder" value="Placeholder" friendlyname="Placeholder" group="Text" accept="*" examples="Placeholder, Default, Beat Loop" desc="Name of Placeholder playlist entry" /> <setting name="*loop" value="true" friendlyname="Loop a song" group="Preferences" accept="false,true" desc="Loop an entry infinitely or not (might be better to set false sometimes). The song element would still stay, and playlist entry would be highlighted, so isn't working exactly as should." /> <setting name="*close_on_selection" value="true" friendlyname="Close playlist when selected" group="Preferences" accept="false,true" desc="Close the playlist when a song is selected. (some letters might be turned back to mta controls too early (i.e exit vehicle F)" /> <setting name="*playlist_close_delay" value="500" friendlyname="Playlist Close delay" group="Preferences" accept="0-1000" desc="Used if 'Close playlist when selected' is set to true. The delay on closing the playlist when selecting song (not pressing 0 again). In milliseconds (1 sec = 1000 ms)" /> </settings> </meta> local localPlayer = getLocalPlayer() function constructNumbersFromLetters() playlistNumbers = {} for number, letter in ipairs (playlistLetters) do playlistNumbers[letter] = number end end function getLocalPlaylist() local theSongs = {} local xml = xmlLoadFile(":radio3d_playlist/playlist.xml") if xml then local i = 0 while (xmlFindChild(xml, "song", i)) do local filename = xmlNodeGetAttribute(xmlFindChild(xml, "song", i), "filename") table.insert(theSongs, ":radio3d_playlist/music/"..filename) i = i + 1; end xmlUnloadFile(xml) end return theSongs end function createPlaylist() playlist = {} -- 1. Fill the playlist with placeholders for number, letter in ipairs (playlistLetters) do local filePath = "music/placeholder.mp3" -- local songTitle = "Placeholder" local songTitle = settings.placeholder -- local songTitle = string.sub(filePath, 7, -5) local song = {filePath, songTitle} table.insert(playlist, song) end -- 2. Change the beginning of playlist to local playlist local localPlaylist = getLocalPlaylist() for key, filePath in pairs(localPlaylist) do local songTitle = string.sub(filePath, 25, -5) local song = {filePath, songTitle} playlist[key] = song end end function guiCreateSizedLabel(theText, parent) theLabel = guiCreateLabel(0, 0, 0, 0, theText, false, parent) guiSetLabelSize(theLabel) return theLabel end function initMusicSelectorMenu() labelSongs = {} local screenX, screenY = guiGetScreenSize() local musicSelectorMenuTitle = settings.playListTitle musicSelectorMenuX = screenX - musicSelectorMenuWidth - 20 musicSelectorMenuY = 140 musicSelectorMenu = guiCreateWindow(musicSelectorMenuX, musicSelectorMenuY, musicSelectorMenuWidth, 0, musicSelectorMenuTitle, false) guiWindowSetMovable(musicSelectorMenu, false) guiWindowSetSizable(musicSelectorMenu, false) disableLabel = guiCreateSizedLabel("x. "..settings.noMusic, musicSelectorMenu) closeLabel = guiCreateSizedLabel(settings.closePlaylistDesc) end function guiSetLabelSize(theLabel) local labelHeight = guiLabelGetFontHeight(theLabel) local labelWidth = guiLabelGetTextExtent(theLabel) guiSetSize(theLabel, labelWidth, labelHeight, false) end function populateMusicSelectorMenu() local y = 20 local x_offset = 10 for number, song in ipairs (playlist) do local songTitle = song[2] local labelLetter = playlistLetters[number] local label = guiCreateLabel(x_offset, y, 0, 0, labelLetter..". "..songTitle, false, musicSelectorMenu) local labelHeight = guiLabelGetFontHeight(label) guiSetLabelSize(label) y = y + labelHeight guiLabelSetColor(label, 255, 255, 255) labelSongs[number] = label end guiSetPosition(disableLabel, x_offset, y, false) local windowHeight = 40+y guiSetSize(musicSelectorMenu, musicSelectorMenuWidth, windowHeight, false) guiSetPosition(closeLabel, musicSelectorMenuX+x_offset, musicSelectorMenuY+windowHeight, false) end function drawMusicSelectorMenu() initMusicSelectorMenu() populateMusicSelectorMenu() guiSetVisible(musicSelectorMenu, false) guiSetVisible(closeLabel, false) bindKey("0", "down", musicSelector) end function resetLabels() for number, label in ipairs (labelSongs) do guiSetVisible(label, false) label = nil end labelSongs = {} end function updateMusicSelectorMenu() resetLabels() populateMusicSelectorMenu() end function updatePlaylist() createPlaylist() updateMusicSelectorMenu() end function bindAPlaylistKey(letter) bindKey(letter, "down", switchSong) end function unbindAPlaylistKey(letter) unbindKey(letter, "down", switchSong) end function bindPlaylistKeys() toggleAllControls(false) for number, letter in ipairs (playlistLetters) do bindAPlaylistKey(letter) end bindKey("x", "down", stopSong) end function unbindPlaylistKeys() toggleAllControls(true) for number, letter in ipairs (playlistLetters) do unbindAPlaylistKey(letter) end unbindKey("x", "down", stopSong) end function showMusicSelectorMenu() lastVehicle = getPedOccupiedVehicle(getLocalPlayer()) local selectedSongID = getElementData(lastVehicle, "song_id") if selectedSongID ~= false then guiLabelSetColor(labelSongs[selectedSongID], 255, 255, 0) activeSongCache = selectedSongID end guiSetVisible(musicSelectorMenu, true) guiSetVisible(closeLabel, true) bindPlaylistKeys() end function hideMusicSelectorMenu() guiSetVisible(musicSelectorMenu, false) guiSetVisible(closeLabel, false) if activeSongCache then guiLabelSetColor(labelSongs[activeSongCache], 255, 255, 255) end unbindPlaylistKeys() end function getIDFromLetter(letter) return playlistNumbers[letter] end -- set current song to selected one (and switch the coloured label if needed) function switchSong(newLetter, keyState) local newSongID = getIDFromLetter(newLetter) if playlist[newSongID] ~= nil then selectorStopSong() guiLabelSetColor(labelSongs[newSongID], 255, 255, 0) activeSongCache = newSongID PlayerStartSong(newSongID) if settings.closeOnSelection then -- if hideMusicSelectorMenu() is called too early some letters might be turned to mta controls too early (i.e exit vehicle F) setTimer(hideMusicSelectorMenu, settings.playlistCloseDelay, 1) end end end function selectorStopSong() if lastVehicle ~= nil then local selectedSongID = getElementData(lastVehicle, "song_id") if selectedSongID ~= false then guiLabelSetColor(labelSongs[selectedSongID], 255, 255, 255) PlayerStopSong(lastVehicle) end end end function stopSong(letter, keyState) selectorStopSong() hideMusicSelectorMenu() end -- does player drive the vehicle (s)he is in at the time function isPlayerVehicleDriver() local playerVehicle = getPedOccupiedVehicle(localPlayer) local playerVehicleDriver = getVehicleOccupant(playerVehicle) return (localPlayer == playerVehicleDriver) end -- toggle dialog with 0 function musicSelector() if isPedInVehicle(localPlayer) and isPlayerVehicleDriver() then if guiGetVisible(musicSelectorMenu) then hideMusicSelectorMenu() else showMusicSelectorMenu() end end end function saveVehicle(thePlayer, theSeat) lastVehicle = getPedOccupiedVehicle(localPlayer) end function selectorStopSongAndHideMusicSelectorMenu(thePlayer, theSeat) if (thePlayer == localPlayer) and (theSeat == 0) then if settings.soundRadioOffOnVehicleExit then selectorStopSong() -- turn off radio, when exiting vehicle end hideMusicSelectorMenu() end end function updateLastVehicle() lastVehicle = getPedOccupiedVehicle(localPlayer) end function table.size(tab) local length = 0 for _ in pairs(tab) do length = length + 1 end return length end function PlayerStopSong() setElementData(lastVehicle, "song_id", false) setElementData(lastVehicle, "song_start_time", false) end function PlayerStartSong(songID) local playerVehicle = getPedOccupiedVehicle(getLocalPlayer()) if playerVehicle then -- It syncs with server automatically setElementData(playerVehicle, "song_id", songID) setElementData(playerVehicle, "song_start_time", getTickCount()) end end function initiate3DSound(songId, x, y, z, songStartTime, ownVehicle) -- loop = true local loop = settings.loop songId = tonumber(songId) local song = playlist[songId] if song == nil then outputDebugString("initiate3DSound: song is nil") return false else if song[1] == nil then outputDebugString("initiate3DSound: song[1] is nil") return false end end -- Seems there some timing problems? -- Should add a little timer here? -- Usually only first time local filepath = song[1] local volume = settings.soundOutsideVolumeOnFoot if isPedInVehicle(localPlayer) then volume = settings.soundOutsideVolumeInVehicle else -- on foot volume = settings.soundOutsideVolumeOnFoot end -- full volume for own vehicle (no need to be a driver) if (ownVehicle ~= nil) and (ownVehicle ~= false) then volume = settings.soundOwnVehicleVolume end outputDebugString("Starting playSound3D") local sound3d = playSound3D(filepath, x, y, z, loop) setSoundVolume(sound3d, volume) setSoundMinDistance(sound3d, settings.soundMinDistance) setSoundMaxDistance(sound3d, settings.soundMaxDistance) -- if sound initiated has been started before creation for this player if (songStartTime ~= nil) and (songStartTime > 0) then local currentTickCount = getTickCount() local seekPosition = getTickCount() - songStartTime local soundLength = getSoundLength(sound3d) if (soundLength ~= false) and (soundLength > 0) then timesLooped = seekPosition/soundLength if timesLooped >= 1 then seekPosition = seekPosition%soundLength end end setSoundPosition(sound3d, seekPosition) end return sound3d end -- if client is in that vehicle function inVehicle(theVehicle) if theVehicle ~= nil then myVehicle = getPedOccupiedVehicle(getLocalPlayer()) if myVehicle == theVehicle then return true end end return false end -- toElement is a vehicle for example function attach3DSound(toElement, songId, songStartTime) local x, y, z = getElementPosition(toElement) if songStartTime == nil then songStartTime = 0 end -- set vehicle you're in louder than others (really others are trimmed down) local soundElement = initiate3DSound(songId, x, y, z, songStartTime, inVehicle(toElement)) sound3DElements[toElement] = soundElement end -- source is an element, a vehicle for example function detach3DSound(fromElement) if (sound3DElements[fromElement] ~= nil) then local soundElement = sound3DElements[fromElement] stopSound(soundElement) sound3DElements[fromElement] = nil end end function updateSong(dataName, oldValue) if getElementType(source) == "vehicle" and dataName == "song_id" then -- oldValue will probably always show as false, because we stopped the music before starting new one -- this means we need to make new 3dsound object if (oldValue ~= nil) and (oldValue ~= false) then if (getElementData(source, dataName)) then attach3DSound(source, getElementData(source, dataName)) -- if this msg is get sth is wrong, because replacing song should stop old one -- outputDebugString("CLIENT: set song from "..oldValue.." to "..getElementData(source, dataName).." for "..getVehicleName(source)) else detach3DSound(source) -- outputDebugString("CLIENT: turned off song for "..getVehicleName(source)) end else attach3DSound(source, getElementData(source, dataName)) -- outputDebugString("CLIENT: set song from nothing to "..getElementData(source, dataName).." for "..getVehicleName(source)) end end end function removeSongFromElement() if getElementType(source) == "vehicle" then -- detach3DSound checks itself if there is such element afterall detach3DSound(source) end end function rePositionSound() -- this needs to be with VERY good performance if sound3DElements ~= nil then for element, sound in pairs(sound3DElements) do local x, y, z = getElementPosition(element) setElementPosition(sound, x, y, z) end end end function showSound3DElementsSize(commandName) outputChatBox(table.size(sound3DElements)) end -- when a client joins server, start music elements function initiate3DSoundsOnConnect() local vehicles = getElementsByType("vehicle") -- on client render might be needed for theKey, theVehicle in ipairs(vehicles) do local songId = getElementData(theVehicle, "song_id") -- if song is attached to element (song_id is set, not false) if songId then local songStartTime = getElementData(theVehicle, "song_start_time") attach3DSound(theVehicle, songId, songStartTime) end end end function cancelRadioEvent(stationID) cancelEvent() end function disableRadio() setRadioChannel(13) end -- this helps only when song_id was changed (including turn off and on (not on first connect) addEventHandler("onClientElementDataChange", getRootElement(), updateSong) addEventHandler("onClientElementDestroy", getRootElement(), removeSongFromElement) addEventHandler("onClientPreRender", getRootElement(), function() rePositionSound() end ) addEventHandler("onClientPlayerVehicleEnter", getRootElement(), function() updateLastVehicle() -- when entering vehicle set all volumes to inVehicle -- except maybe a song is playing in here already, then put this to maximum if table.size(sound3DElements) > 0 then for element, sound in pairs(sound3DElements) do if inVehicle(element) then -- outputDebugString("my car playing ".. settings.soundOwnVehicleVolume) setSoundVolume(sound, settings.soundOwnVehicleVolume) else -- outputDebugString("not my car playing "..settings.soundOutsideVolumeInVehicle) setSoundVolume(sound, settings.soundOutsideVolumeInVehicle) end end end -- try to set radio to none (that's all, let them change it if wanted) disableRadio() end ) addEventHandler("onClientVehicleStartExit", getRootElement(), saveVehicle) addEventHandler("onClientVehicleExit", getRootElement(), function(thePlayer, theSeat) -- when exiting vehicle set all volumes to onFoot if table.size(sound3DElements) > 0 then for element, sound in pairs(sound3DElements) do setSoundVolume(sound, settings.soundOutsideVolumeOnFoot) -- outputDebugString("On foot, all to "..settings.soundOutsideVolumeOnFoot) end end selectorStopSongAndHideMusicSelectorMenu(thePlayer, theSeat) end ) -- addEventHandler("onClientPlayerRadioSwitch", getRootElement(), cancelRadioEvent) addCommandHandler("songs", showSound3DElementsSize) addCommandHandler("updateplaylist", updatePlaylist) addEvent("onSendRadio3dSettings", true) -- Wait for server to return settings addEventHandler("onSendRadio3dSettings", localPlayer, function(newSettings) if newSettings == nil then triggerServerEvent("onRadio3dClientScriptLoaded", localPlayer) else settings = newSettings -- outputChatBox("settings: "..tostring(settings)) -- local table of sound elements sound3DElements = {} playlistLetters = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"} constructNumbersFromLetters() createPlaylist() musicSelectorMenuWidth = 240 drawMusicSelectorMenu() initiate3DSoundsOnConnect() -- outputChatBox("done") end end ) addEventHandler("onClientResourceStart", getResourceRootElement(getThisResource()), function() triggerServerEvent("onRadio3dClientScriptLoaded", localPlayer) end ) addEvent("onGamemodeMapStop", true) addEventHandler("onGamemodeMapStop", getRootElement(), function() -- outputChatBox("kliendil ka nyyd olemas") --local vehicles = getElementsByType("vehicle") -- Remove all songs from elements --[[ for theKey, theVehicle in ipairs(vehicles) do setElementData(theVehicle, "song_id", false) setElementData(theVehicle, "song_start_time", false) end ]] end ) -- For exported function function changeRadio3dSetting(settingName, newValue) if settingName == nil then return false end if type(settingName) ~= "string" then return false end if newValue == nil then return false end if settings == nil then settings = {} end settings[settingName] = newValue end addEvent("onChangeRadio3dSetting", true) addEventHandler("onChangeRadio3dSetting", localPlayer, changeRadio3dSetting) server_player.lua local root = getRootElement() -- get string or default function getString(var,default) local result = get(var) if not result then return default end return tostring(result) end -- get number or default function getNumber(var,default) local result = get(var) if not result then return default end return tonumber(result) end -- get true or false or default function getBool(var,default) local result = get(var) if not result then return default end return result == 'true' end local settings = { soundMinDistance = getNumber('radio3d.sound3d_min_distance', 8), soundMaxDistance = getNumber('radio3d.sound3d_max_distance', 15), soundOutsideVolumeInVehicle = getNumber('radio3d.sound3d_outside_volume_vehicle', 50) / 100, soundOutsideVolumeOnFoot = getNumber('radio3d.sound3d_outside_volume_foot', 70) / 100, soundOwnVehicleVolume = getNumber('radio3d.sound3d_own_vehicle_volume', 100) / 100, soundRadioOffOnVehicleExit = getBool('radio3d.sound3d_radio_off_on_vehicle_exit', false), soundRadioOffOnBlowUp = getBool('radio3d.sound3d_radio_off_on_blow_up', true), playListTitle = getString('radio3d.playlist_title', "Плеер"), closePlaylistDesc = getString('radio3d.close_playlist_desc', "Нажмите 0 для закрытие плеера"), noMusic = getString('radio3d.no_music', "No music"), placeholder = getString('radio3d.placeholder', "Placeholder"), loop = getBool('radio3d.loop', true), closeOnSelection = getBool('radio3d.close_on_selection', true), playlistCloseDelay = getNumber('radio3d.playlist_close_delay', 500) } addEvent("onRadio3dClientScriptLoaded", true) addEventHandler("onRadio3dClientScriptLoaded", getRootElement(), function() -- outputChatBox("settings: "..tostring(settings)) triggerClientEvent(source, "onSendRadio3dSettings", getRootElement(), settings) end ) -- function removeSongOnExplode(theVehicle) -- setElementData(theVehicle, "tempdata.originalnick", sPlayerNickname) -- end -- addEventHandler("onVehicleExplode", getRootElement(), removeSongOnExplode) function removeAllSounds() local vehicles = getElementsByType("vehicle") for theKey, theVehicle in ipairs(vehicles) do -- sometimes real elements are already deleted (i.e onGamemodeMapStop), so extra check if isElement(theVehicle) then local songId = getElementData(theVehicle, "song_id") -- if song is attached to element (song_id is set, not false (or nil)) if songId then setElementData(theVehicle, "song_id", false) setElementData(theVehicle, "song_start_time", false) end end end end function onCurrentResourceStop(theResource) removeAllSounds() end function removeSongOnGamemodeMapStop(gamemode) -- outputChatBox("gamemode stopped") triggerClientEvent("onGamemodeMapStop", getRootElement()) removeAllSounds() end -- function removeSongOnGamemodeMapStart(gamemode) -- outputChatBox("gamemode started") -- end function removeSongFromElement(theElement) local songId = getElementData(theElement, "song_id") if songId then setElementData(theElement, "song_id", false) setElementData(theElement, "song_start_time", false) end end function removeSongOnExplode() removeSongFromElement(source) end if settings.soundRadioOffOnBlowUp then addEventHandler("onVehicleExplode", getRootElement(), removeSongOnExplode) end addEventHandler("onResourceStop", getResourceRootElement(), onCurrentResourceStop) addEventHandler("onGamemodeMapStop", getRootElement(), removeSongOnGamemodeMapStop) -- addEventHandler("onGamemodeMapStart", getRootElement(), removeSongOnGamemodeMapStart) -- Export function changeSetting(triggerFor, settingName, newValue) triggerClientEvent(triggerFor, "onChangeRadio3dSetting", root, settingName, newValue) end radio3d_client.lua Edited November 20, 2017 by Marvik Add spoilers Link to comment
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now