diff options
Diffstat (limited to 'Data/BuiltIn/Libraries/lua-addons/addons/BattleStations')
5 files changed, 1350 insertions, 0 deletions
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/BattleStations/LICENSE b/Data/BuiltIn/Libraries/lua-addons/addons/BattleStations/LICENSE new file mode 100644 index 0000000..d719b9e --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/BattleStations/LICENSE @@ -0,0 +1,25 @@ +Copyright © 2018, Sjshovan (Apogee) +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Battle Stations nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL Sjshovan (Apogee) BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\ No newline at end of file diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/BattleStations/README.md b/Data/BuiltIn/Libraries/lua-addons/addons/BattleStations/README.md new file mode 100644 index 0000000..83fd082 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/BattleStations/README.md @@ -0,0 +1,225 @@ +**Author:** [Sjshovan (Apogee)](https://github.com/Ap0gee) +**Version:** v0.9.1 + + +# Battle Stations + +> A Windower 4 addon that allows the user to change or remove the default battle music in Final Fantasy 11 Online. + + +### Table of Contents + +- [Prerequisites](#prerequisites) +- [Installation](#installation) +- [Aliases](#aliases) +- [Usage](#usage) +- [Commands](#commands) +- [Support](#support) +- [Change Log](#change-log) +- [Known Issues](#known-issues) +- [TODOs](#todos) +- [License](#license) + +___ +### Prerequisites +1. [Final Fantasy 11 Online](http://www.playonline.com/ff11us/index.shtml) +2. [Windower 4](http://windower.net/) + +___ +### Installation + +**Windower:** +1. Navigate to the `Addons` section at the top of Windower. +2. Locate the `BattleStations` addon. +3. Click the download button. +4. Ensure the addon is switched on. + +**Manual:** +1. Navigate to <https://github.com/Ap0gee/BattleStations>. +2. Click on `Releases`. +3. Click on the `Source code (zip)` link within the latest release to download. +4. Extract the zipped folder to `Windower4/addons/`. +5. Rename the folder to remove the version tag (`-v0.9.0`). The folder should be named `BattleStations`. + +___ +### Aliases +The following aliases are available to Battle Stations commands: + +**battlestations:** stations | bs +**list:** l +**set:** s +**get:** g +**default:** d +**normal:** n +**reload:** r +**about:** a +**help:** h +**stations:** station | s +**radios:** receivers | receiver | radio | r +**all:** all | a | * + +___ +### Usage + +Manually load the addon by using one of the following commands: + + //lua load battlestations + //lua l battlestations + +___ +### Commands + +**help** + +Displays the available Battle Stations commands. Below are the equivalent ways of calling the command: + + //battlestations help + //stations help + //bs help + + //battlestations h + //stations h + //bs h + +**list _[radios|stations] [category#]_** + +Displays the available radios and or stations. Below are some useage examples of this command: + + //bs list + //bs l + + //bs list radios + //bs l radios + //bs l r + + //bs list stations + //bs l stations + //bs l s + + //bs l s 100 + +* _**[radios|stations]:**_ Optional parameter used to filter the list display to show only available radios or stations. If neither filter type is present, all available stations and radios will be listed. +* _**[category#]:**_ Optional parameter used to filter the list of stations by the given category number. The available category numbers are 100-107. + +**set _\<station> [radio]_** + +Sets the radio(s) to the given station. Below are some useage examples of this command: + + //bs set 100.1 + //bs s 100.1 + + //bs s 100.1 solo + //bs s 100.1 party + +* _**\<station>:**_ Required parameter. +* _**[radio]:**_ Optional parameter used to specify which radio to set the given station to. If no radio type is present both radios will be set to the given station. + +**get _[radio]_** + +Displays the currently set station on the given radio(s). Below are some useage examples of this command: + + //bs get + //bs g + + //bs g solo + //bs g party + +* _**[radio]:**_ Optional parameter used to specify the radio for which you would like to display the currently set station. If no radio type is present, the currently set station for both radios will be displayed. + +**default _[radio]_** + +Sets the given radio(s) to the default station (Current Zone Music). Below are some useage examples of this command: + + //bs default + //bs d + + //bs d solo + //bs d party + +* _**[radio]:**_ Optional parameter used to specify which radio to set the default station to. If no radio type is present, both radios will be set to the default station. + + +**normal _[radio]_** + +Sets the given radio(s) to the original game music. Below are some useage examples of this command: + + //bs normal + //bs n + + //bs n solo + //bs n party + +* _**[radio]:**_ Optional parameter used to specify which radio to set the normal station to. If no radio type is present, both radios will be set to the normal station. + +**reload** + +Reloads the Battle Stations addon. Below are the equivalent ways of calling the command: + + //battlestations reload + //stations reload + //bs reload + + //battlestations r + //stations r + //bs r + +**about** + +Displays information about the Battle Stations addon. Below are the equivalent ways of calling the command: + + /battlestations about + //stations about + //bs about + + //battlestations a + //stations a + //bs a + +___ +### Support +**Having Issues with this addon?** +* Please let me know [here](https://github.com/Ap0gee/BattleStations/issues/new). + +**Have something to say?** +* Send me some feedback here: <sjshovan@gmail.com> + +**Want to stay in the loop with my work?** +* You can follow me at: <https://twitter.com/Sjshovan> + +**Want to toss a coin to your modder?** +* You can do so here: <https://www.paypal.me/Sjshovan> + +___ +### Change Log + +**v0.9.1** - 12/29/2019 +- **Fix:** Resolved mismatched setting type error within the `bs normal` command. +- **Add:** New command added (about). +- **Update:** Silent song id changed to help prevent future game updates from overriding. +- **Update:** README Commands updated. +- **Update:** README Aliases updated. +- **Update:** README Known Issues updated. +- **Update:** README TODOS updated. + +**v0.9.0** - 6/19/2018 +- Initial release + +___ +### Known Issues + +- **Issue:** During campaign battles in the past, the music switches from the campaign music to the normal zone music while stations are set to `107.3`. + +___ +### TODOS + +- **TODO:** Consider providing aliases to stations to make references easier. +- **TODO:** Consider adding categories as a list type. +- **TODO:** Investigate methods for resolving the campaign battle music issue. +___ + +### License + +Copyright © 2018, [Sjshovan (Apogee)](https://github.com/Ap0gee). +Released under the [BSD License](LICENSE). + +***
\ No newline at end of file diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/BattleStations/battlestations.lua b/Data/BuiltIn/Libraries/lua-addons/addons/BattleStations/battlestations.lua new file mode 100644 index 0000000..5c2922a --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/BattleStations/battlestations.lua @@ -0,0 +1,597 @@ +--[[ +Copyright © 2018, Sjshovan (Apogee) +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Battle Stations nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL Sjshovan (Apogee) BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +]] + +_addon.name = 'Battle Stations' +_addon.description = 'Change or remove the default battle music.' +_addon.author = 'Sjshovan (Apogee) sjshovan@gmail.com' +_addon.version = '0.9.1' +_addon.commands = {'battlestations', 'stations', 'bs'} + +local _logger = require('logger') +local _config = require('config') +local _packets = require('packets') + +require('functions') +require('constants') +require('helpers') + +local defaults = { + stations = { + solo = 107.3, + party = 107.3 + } +} + +local settings = _config.load(defaults) + +local help = { + commands = { + buildHelpSeperator('=', 28), + buildHelpTitle('Commands'), + buildHelpSeperator('=', 28), + buildHelpCommandEntry('list [radios|stations] [category#]', 'Display the available radios and or stations.'), + buildHelpCommandEntry('set <station> [radio]', 'Set radio(s) to the given station.'), + buildHelpCommandEntry('get [radio]', 'Display currently set station on the given radio(s).'), + buildHelpCommandEntry('default [radio]', 'Set radio(s) to the default station (Current Zone Music).'), + buildHelpCommandEntry('normal [radio]', 'Set radio(s) to the original game music.'), + buildHelpCommandEntry('reload', 'Reload Battle Stations.'), + buildHelpCommandEntry('about', 'Display information about Battle Stations.'), + buildHelpCommandEntry('help', 'Display Battle Stations commands.'), + buildHelpSeperator('=', 28), + }, + + radios = { + buildHelpSeperator('=', 25), + buildHelpTitle('Radios'), + buildHelpSeperator('=', 25), + buildHelpRadioEntry(stations.receivers.solo:ucfirst(), 'Plays Solo Battle Music'), + buildHelpRadioEntry(stations.receivers.party:ucfirst(), 'Plays Party Battle Music'), + buildHelpSeperator('=', 25), + }, + + about = { + buildHelpSeperator('=', 23), + buildHelpTitle('About'), + buildHelpSeperator('=', 23), + buildHelpTypeEntry('Name', _addon.name), + buildHelpTypeEntry('Description', _addon.description), + buildHelpTypeEntry('Author', _addon.author), + buildHelpTypeEntry('Version', _addon.version), + buildHelpSeperator('=', 23), + }, + + aliases = { + list = { + stations = T{ + 's', + 'station', + 'stations', + }, + radios = T{ + 'r', + 'radio', + 'radios', + 'receiver', + 'receivers' + }, + categories = T{ + 'c', + 'cat', + 'category', + 'categories' + }, + all = T{ + '*', + 'a', + 'all', + } + } + } +} + +function displayHelp(table_help) + for index, command in pairs(table_help) do + displayResponse(command) + end +end + +function displayStations(range) + displayResponse(buildHelpSeperator('=', 27)) + displayResponse(buildHelpTitle('Stations')) + displayResponse(buildHelpSeperator('=', 27)) + + if range ~= nil then + if categoryValid(range) then + displayRangeFrequencies(range) + end + else + for i=100, 107, 1 do + range = tostring(i) + displayRangeFrequencies(range) + end + end + displayResponse(buildHelpSeperator('=', 26)) +end + +function displayRangeFrequencies(range, name) + local categories = stations.categories + + if categoryValid(range) then + local name = categories[range] + displayResponse(buildHelpStationCategoryEntry(range, name)) + displayFrequencies(range) + end +end + +function displayFrequencies(range) + for i=1, 9, 1 do + local frequency = range .. '.%s':format(tostring(i)) + if frequencyValid(frequency) then + local frequencyObj = getFrequencyObjByValue(frequency) + local response = buildHelpStationEntry(frequency, frequencyObj.callSign) + displayResponse(response) + end + end +end + +function displayCategories() + displayResponse(buildHelpSeperator('=', 27)) + displayResponse(buildHelpTitle('Categories')) + displayResponse(buildHelpSeperator('=', 27)) + for i=100, 107, 1 do + local range = tostring(i) + if categoryValid(range) then + local name = stations.categories[range] + displayResponse(buildHelpStationCategoryEntry(range, name)) + end + end + displayResponse(buildHelpSeperator('=', 27)) +end + +function getStations() + return settings.stations +end + +function setStation(radio, frequency) + if radio == stations.receivers.solo then + settings.stations.solo = frequency + elseif radio == stations.receivers.party then + settings.stations.party = frequency + else + settings.stations.solo = frequency + settings.stations.party = frequency + end + + settings:save() +end + +function resolveCurrentStations() + local current_stations = getStations() + local radio = 'solo' + local frequency = tostring(defaults.stations.solo) + local message_template = '%s station found in settings was not valid and was set to the default %s (%s).' + + if not frequencyValid(current_stations.solo) then + current_stations.solo = frequency + setStation(radio, frequency) + + displayResponse( + buildWarningMessage( + message_template:format( + radio:ucfirst():color(colors.secondary), + frequency:color(colors.primary), + getFrequencyObjByValue(frequency).callSign + ) + ) + ) + end + + if not frequencyValid(current_stations.party) then + radio = 'party' + frequency = tostring(defaults.stations.party) + current_stations.party = party_default + + setStation(radio, frequency) + + displayResponse( + buildWarningMessage( + message_template:format( + radio:ucfirst():color(colors.secondary), + frequency:color(colors.primary), + getFrequencyObjByValue(frequency).callSign + ) + ) + ) + end + + return current_stations +end + +function injectBattleMusic() + local current_stations = resolveCurrentStations() + local song = getFrequencyObjByValue(current_stations.solo).song + local music_type = music.types.battle_solo + + if playerInParty() then + music_type = music.types.battle_party + song = getFrequencyObjByValue(current_stations.party).song + end + + song = getConditionalSongTranslation(song) + + _packets.inject(_packets.new('incoming', packets.inbound.music_change.id, { + ['BGM Type'] = music_type, + ['Song ID'] = song + })) +end + +function getFrequencyObjByValue(frequency) + return stations.frequencies[tostring(frequency)] +end + +function getCurrentTime(formatted) + local timestamp = tostring(windower.ffxi.get_info().time) + local hours = (timestamp / 60):floor() + local minutes = timestamp % 60 + if formatted then + return "%s:%s":format(hours, minutes) + end + return timestamp +end + +function getZoneBGMTable() + local data = windower.packets.last_incoming(packets.inbound.zone_update.id) + local packet = _packets.parse('incoming', data) + return { + day = packet['Day Music'], + night = packet['Night Music'], + solo = packet['Solo Combat Music'], + party = packet['Party Combat Music'] + } +end + +function getConditionalSongTranslation(song) + local zone_bgm_table = getZoneBGMTable() + if song == music.songs.others.zone then + if timeIsDaytime() then + song = zone_bgm_table.day + else + song = zone_bgm_table.night + end + + if playerInReive() then + song = music.songs.seekers_of_adoulin.breaking_ground + end + + elseif song == music.songs.others.normal then + if playerInParty() then + song = zone_bgm_table.party + else + song = zone_bgm_table.solo + end + end + return song +end + +function getPlayerBuffs() + return T(windower.ffxi.get_player().buffs) +end + +function timeIsDaytime() + local current_time = tonumber(getCurrentTime()) + return current_time >= 6*60 and current_time <= 18*60 +end + +function playerIsFighting() + return windower.ffxi.get_player().status == player.statuses.fighting +end + +function playerInParty() + return windower.ffxi.get_party().alliance_count > 1 +end + +function playerInReive() + return getPlayerBuffs():contains(player.buffs.reiveMark) +end + +function frequencyValid(frequency) + return stations.frequencies[tostring(frequency)] ~= nil +end + +function radioValid(radio) + return stations.receivers[radio] ~= nil or radio == '*' +end + +function categoryValid(category) + return stations.categories[category] ~= nil +end + +function listTypeValid(list_type) + return help.lists[list_type] ~= nil +end + +function handleInjectionNeeds() + if needs_inject then + injectBattleMusic() + needs_inject = false; + end +end + +windower.register_event('load', function () + injectBattleMusic() +end) + +windower.register_event('unload', function() + local music_type = music.types.battle_solo + local zone_bgm_table = getZoneBGMTable() + local song = zone_bgm_table.solo + + if playerInParty() then + music_type = music.types.battle_party + song = zone_bgm_table.solo + end + + _packets.inject(_packets.new('incoming', packets.inbound.music_change.id, { + ['BGM Type'] = music_type, + ['Song ID'] = song, + })) +end) + +windower.register_event('action', function(act) + if act.actor_id == windower.ffxi.get_player().id then + if act.category == 4 and act.recast == 225 and act.targets[1].actions[1].animation == 939 then + if not playerInParty() then + functions.loop(injectBattleMusic, 1, 5) + end + end + end +end) + +windower.register_event('outgoing chunk', function(id, data) + if id == packets.outbound.action.id then + local packet = _packets.parse('outgoing', data) + if packet.Category == packets.outbound.action.categories.engage then + injectBattleMusic() + end + end +end) + +windower.register_event('addon command', function(command, ...) + if command then + command = command:lower() + else + displayHelp(help.commands) + return + end + + local command_args = {...} + + local respond = false + local response_message = '' + local success = true + + if command == 'list' or command == 'l' then + local list_type = (command_args[1] or '*'):lower() + local category = command_args[2] + + if help.aliases.list.stations:contains(list_type) then + if category then + if categoryValid(category) then + displayStations(category) + + else + respond = true + success = false + response_message = 'Category not recognized.' + end + else + displayStations() + end + + elseif help.aliases.list.radios:contains(list_type) then + displayHelp(help.radios) + + elseif help.aliases.list.categories:contains(list_type) then + displayCategories() + + elseif help.aliases.list.all:contains(list_type) then + displayHelp(help.radios) + displayStations() + + else + respond = true + success = false + response_message = 'List type not recognized.' + end + + elseif command == 'set' or command == 's' then + respond = true + + local frequency = command_args[1]:lower() + + local radio = (command_args[2] or '*'):lower() + + if not frequencyValid(frequency) then + success = false + response_message = 'Frequency not recognized.' + + elseif not radioValid(radio) then + success = false + response_message = 'Radio not recognized.' + else + needs_inject = true + + local context = 'radio' + + setStation(radio, tonumber(frequency)) + + if radio == '*' then + context = 'radios' + radio = 'Solo and Party' + end + + response_message = buildSetResponseMessage( + radio:ucfirst(), + context, + frequency, + getFrequencyObjByValue(frequency).callSign + )..'.' + end + + elseif command == 'get' or command == 'g' then + respond = true + + local current_stations = resolveCurrentStations() + local radio = (command_args[1] or '*'):lower() + local frequency = current_stations[radio] + local frequency2 = current_stations.party + local individual = false + + if not radioValid(radio) then + success = false + response_message = 'Radio not recognized.' + else + local context = 'radio is' + + if radio == '*' then + frequency = current_stations.solo + + if current_stations.party ~= current_stations.solo then + individual = true + else + context = 'radios are' + radio = 'Solo and Party' + end + end + + if not individual then + response_message = buildGetResponseMessage( + radio:ucfirst(), + context, + frequency, + getFrequencyObjByValue(frequency).callSign + )..'.' + + else + local solo_message = buildGetResponseMessage( + stations.receivers.solo:ucfirst(), + context, + frequency, + getFrequencyObjByValue(frequency).callSign + ) + + local party_message = buildGetResponseMessage( + stations.receivers.party:ucfirst(), + context, + frequency2, + getFrequencyObjByValue(frequency2).callSign + ) + + response_message = solo_message..' and '..party_message..'.' + end + end + + elseif command == 'default' or command == 'd' then + respond = true + + local radio = (command_args[1] or '*'):lower() + + if not radioValid(radio) then + success = false + response_message = 'Radio not recognized.' + else + needs_inject = true + + local frequency = defaults.stations.solo + local context = 'radio' + + setStation(radio, tonumber(frequency)) + + if radio == '*' then + context = 'radios' + radio = 'Solo and Party' + end + + response_message = buildSetResponseMessage( + radio:ucfirst(), + context, + frequency, + getFrequencyObjByValue(frequency).callSign + )..'.' + end + + elseif command == 'normal' or command == 'n' then + respond = true + + local radio = (command_args[1] or '*'):lower() + + if not radioValid(radio) then + success = false + response_message = 'Radio not recognized.' + else + needs_inject = true + + local frequency = '107.2' + local context = 'radio' + + setStation(radio, tonumber(frequency)) + + if radio == '*' then + context = 'radios' + radio = 'Solo and Party' + end + + response_message = buildSetResponseMessage( + radio:ucfirst(), + context, + frequency, + getFrequencyObjByValue(frequency).callSign + )..'.' + end + + elseif command == 'reload' or command == 'r' then + windower.send_command('lua r battlestations') + + elseif command == 'about' or command == 'a' then + displayHelp(help.about) + + elseif command == 'help' or command == 'h' then + displayHelp(help.commands) + + else + displayHelp(help.commands) + end + + if respond then + displayResponse( + buildCommandResponse(response_message, success) + ) + end + + handleInjectionNeeds() +end)
\ No newline at end of file diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/BattleStations/constants.lua b/Data/BuiltIn/Libraries/lua-addons/addons/BattleStations/constants.lua new file mode 100644 index 0000000..950ecc1 --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/BattleStations/constants.lua @@ -0,0 +1,382 @@ +--[[ +Copyright © 2018, Sjshovan (Apogee) +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Battle Stations nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL Sjshovan (Apogee) BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +]] + +packets = { + inbound = { + music_change = { + id = 0x05F + }, + zone_update = { + id = 0x00A + } + }, + outbound = { + action = { + id = 0x1A, + categories = { + engage = 2, + disengage = 4 + + }, + } + }, +} + +player = { + statuses = { + idle = 0x00, + fighting = 0x01, + }, + buffs = { + reiveMark = 511 + } +} + +colors = { + primary = 200, + secondary = 207, + info = 0, + warn = 140, + danger = 167, + success = 158 +} + +music = { + songs = { + final_fantasy_xi = { + battle_theme = 101, + battle_theme_2 = 103, + battle_in_the_dungeon = 115, + battle_in_the_dungeon_2 = 102, + tough_battle = 125, + awakening = 119 + }, + rise_of_the_zilart = { + battle_theme_3 = 191, + battle_in_the_dungeon_3 = 192, + tough_battle_2 = 193, + fighters_of_the_crystal = 196, + ealdnarche = 198, + belief = 195 + }, + chains_of_promathia = { + onslaught = 219, + depths_of_the_soul = 218, + turmoil = 220, + ruler_of_the_skies = 232, + dusk_and_dawn = 224, + a_realm_of_emptiness = 137 + }, + treasures_of_aht_urhgan = { + mercenaries_delight = 138, + delve = 139, + rapid_onslaught_assault = 144, + fated_strife_besieged = 142, + hellriders = 143, + black_coffin = 172, + iron_colossus = 186, + ragnarok = 187 + }, + wings_of_the_goddess = { + clash_of_standards = 215, + on_this_blade = 216, + roar_of_the_battle_drums = 247, + run_maggot_run = 249, + under_a_clouded_moon = 250, + kindred_cry = 217, + provenance_watcher = 55, + goddess_divine = 46 + }, + seekers_of_adoulin = { + steel_sings_blades_dance = 57, + breaking_ground = 64, + buccaneers = 170, + keepers_of_the_wild = 62 + }, + add_ons = { + echoes_of_creation = 47, + luck_of_the_mog = 49, + a_feast_for_ladies = 50, + melodies_errant = 52, + shinryu = 53, + wail_of_the_void = 82 + }, + others = { + silent = 9999, + normal = 09, + zone = 00 + }, + }, + types = { + battle_solo = 2, + battle_party = 3, + idle_day = 0, + idle_night = 1 + } +} + +stations = { + receivers = T{ + solo = 'solo', + party = 'party' + }, + + categories = T{ + ['100'] = 'Final Fantasy XI', + ['101'] = 'Rise of the Zilart', + ['102'] = 'Chains of Promathia', + ['103'] = 'Treasures of Aht Urhgan', + ['104'] = 'Wings of the Goddess', + ['105'] = 'Seekers of Adoulin', + ['106'] = 'Add-Ons', + ['107'] = 'Others' + }, + + frequencies = T{ + + --(100) Final Fantasy XI -- + + ['100.1'] = { + callSign = 'Battle Theme', + song = music.songs.final_fantasy_xi.battle_theme + }, + ['100.2'] = { + callSign = 'Battle Theme 2', + song = music.songs.final_fantasy_xi.battle_theme_2 + }, + ['100.3'] = { + callSign = 'Battle in the Dungeon', + song = music.songs.final_fantasy_xi.battle_in_the_dungeon + }, + ['100.4'] = { + callSign = 'Battle in the Dungeon 2', + song = music.songs.final_fantasy_xi.battle_in_the_dungeon_2 + }, + ['100.5'] = { + callSign = 'Tough Battle', + song = music.songs.final_fantasy_xi.tough_battle + }, + ['100.6'] = { + callSign = 'Awakening', + song = music.songs.final_fantasy_xi.awakening + }, + + --(101) Rise of the Zilart -- + + ['101.1'] = { + callSign = 'Battle Theme 3', + song = music.songs.rise_of_the_zilart.battle_theme_3 + }, + ['101.2'] = { + callSign = 'Battle in the Dungeon 3', + song = music.songs.rise_of_the_zilart.battle_in_the_dungeon_3 + }, + ['101.3'] = { + callSign = 'Tough Battle 2', + song = music.songs.rise_of_the_zilart.tough_battle_2 + }, + ['101.4'] = { + callSign = 'Fighters of the Crystal', + song = music.songs.rise_of_the_zilart.fighters_of_the_crystal + }, + ['101.5'] = { + callSign = "Eald'narche", + song = music.songs.rise_of_the_zilart.ealdnarche + }, + ['101.6'] = { + callSign = 'Belief', + song = music.songs.rise_of_the_zilart.belief + }, + + --(102) Chains of Promathia -- + + ['102.1'] = { + callSign = 'Onslaught', + song = music.songs.chains_of_promathia.onslaught + }, + ['102.2'] = { + callSign = 'Depths of the Soul', + song = music.songs.chains_of_promathia.depths_of_the_soul + }, + ['102.3'] = { + callSign = 'Turmoil', + song = music.songs.chains_of_promathia.turmoil + }, + ['102.4'] = { + callSign = 'Ruler of the Skies', + song = music.songs.chains_of_promathia.ruler_of_the_skies + }, + ['102.5'] = { + callSign = 'Dusk and Dawn', + song = music.songs.chains_of_promathia.dusk_and_dawn + }, + ['102.6'] = { + callSign = 'A Realm of Emptiness', + song = music.songs.chains_of_promathia.a_realm_of_emptiness + }, + + --(103) Treasures of Aht Urhgan -- + + ['103.1'] = { + callSign = "Mercenaries' Delight", + song = music.songs.treasures_of_aht_urhgan.mercenaries_delight + }, + ['103.2'] = { + callSign = 'Delve', + song = music.songs.treasures_of_aht_urhgan.delve + }, + ['103.3'] = { + callSign = 'Rapid Onslaught -Assult-', + song = music.songs.treasures_of_aht_urhgan.rapid_onslaught_assault + }, + ['103.4'] = { + callSign = 'Fated Strife -Besieged-', + song = music.songs.treasures_of_aht_urhgan.fated_strife_besieged + }, + ['103.5'] = { + callSign = 'Hellriders', + song = music.songs.treasures_of_aht_urhgan.hellriders + }, + ['103.6'] = { + callSign = 'Black Coffin', + song = music.songs.treasures_of_aht_urhgan.black_coffin + }, + ['103.7'] = { + callSign = 'Iron Colossus', + song = music.songs.treasures_of_aht_urhgan.iron_colossus + }, + ['103.8'] = { + callSign = 'Ragnarok', + song = music.songs.treasures_of_aht_urhgan.ragnarok + }, + + --(104) Wings of the Goddess -- + + ['104.1'] = { + callSign = 'Clash of Standards', + song = music.songs.wings_of_the_goddess.clash_of_standards + }, + ['104.2'] = { + callSign = 'On this Blade', + song = music.songs.wings_of_the_goddess.on_this_blade + }, + ['104.3'] = { + callSign = 'Roar of the Battle Drums', + song = music.songs.wings_of_the_goddess.roar_of_the_battle_drums + }, + ['104.4'] = { + callSign = 'Run Maggot, Run!', + song = music.songs.wings_of_the_goddess.run_maggot_run + }, + ['104.5'] = { + callSign = 'Under a Clouded Moon', + song = music.songs.wings_of_the_goddess.under_a_clouded_moon + }, + ['104.6'] = { + callSign = 'Kindred Cry', + song = music.songs.wings_of_the_goddess.kindred_cry + }, + ['104.7'] = { + callSign = 'Provenance Watcher', + song = music.songs.wings_of_the_goddess.provenance_watcher + }, + ['104.8'] = { + callSign = 'Goddess Divine', + song = music.songs.wings_of_the_goddess.goddess_divine + }, + + --(105) Seekers of Adoulin -- + + ['105.1'] = { + callSign = 'Steel Sings, Blades Dance', + song = music.songs.seekers_of_adoulin.steel_sings_blades_dance + }, + ['105.2'] = { + callSign = 'Braking Ground', + song = music.songs.seekers_of_adoulin.breaking_ground + }, + ['105.3'] = { + callSign = 'Buccaneers', + song = music.songs.seekers_of_adoulin.buccaneers + }, + ['105.4'] = { + callSign = 'Keepers of the Wild', + song = music.songs.seekers_of_adoulin.keepers_of_the_wild + }, + + --(106) Add-Ons -- + + ['106.1'] = { + callSign = 'Echoes of Creation', + song = music.songs.add_ons.echoes_of_creation + }, + ['106.2'] = { + callSign = 'Luck of the Mog', + song = music.songs.add_ons.luck_of_the_mog + }, + ['106.3'] = { + callSign = 'A Feast for Ladies', + song = music.songs.add_ons.a_feast_for_ladies + }, + ['106.4'] = { + callSign = 'Melodies Errant', + song = music.songs.add_ons.melodies_errant + }, + ['106.5'] = { + callSign = 'Shinryu', + song = music.songs.add_ons.shinryu + }, + ['106.6'] = { + callSign = 'Wail of the Void', + song = music.songs.add_ons.wail_of_the_void + }, + + --(107) Others -- + + ['107.1'] = { + callSign = 'No Music', + song = music.songs.others.silent + }, + ['107.2'] = { + callSign = 'Original Music', + song = music.songs.others.normal + }, + ['107.3'] = { + callSign = 'Current Zone Music (Default)', + song = music.songs.others.zone + } + } +} + +return { + packets = packets, + player = player, + colors = colors, + music = music, + stations = stations +}
\ No newline at end of file diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/BattleStations/helpers.lua b/Data/BuiltIn/Libraries/lua-addons/addons/BattleStations/helpers.lua new file mode 100644 index 0000000..17b2acf --- /dev/null +++ b/Data/BuiltIn/Libraries/lua-addons/addons/BattleStations/helpers.lua @@ -0,0 +1,121 @@ +--[[ +Copyright © 2018, Sjshovan (Apogee) +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of Battle Stations nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL Sjshovan (Apogee) BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +]] + +local colors = require("constants").colors + +function buildHelpCommandEntry(command, description) + local entry_template = "%s %s %s %s" + local short_name = "bs":color(colors.primary) + local command = command:color(colors.secondary) + local sep = "=>":color(colors.primary) + local description = description:color(colors.info) + return entry_template:format(short_name, command, sep, description) +end + +function buildHelpTypeEntry(name, description) + local entry_template = "%s %s %s" + local name = name:color(colors.secondary) + local sep = "=>":color(colors.primary) + local description = description:color(colors.info) + return entry_template:format(name, sep, description) +end + +function buildHelpRadioEntry(name, description) + local entry_template = "%s %s %s" + local name = name:color(colors.secondary) + local sep = "=>":color(colors.primary) + local description = description:color(colors.info) + return entry_template:format(name, sep, description) +end + +function buildHelpStationEntry(frequency, callSign) + local entry_template = " %s %s %s" + local frequency = frequency:color(colors.secondary) + local sep = "=>":color(colors.primary) + local callSign = callSign:color(colors.info) + return entry_template:format(frequency, sep, callSign) +end + +function buildHelpStationCategoryEntry(range, name) + local entry_template = "(%s) %s" + local range = range:color(colors.primary) + local name = name:color(colors.danger) + return entry_template:format(range, name) +end + +function buildHelpTitle(context) + local title_template = "%s Help: %s" + local context = context:color(colors.danger) + return title_template:color(colors.primary):format(_addon.name, context) +end + +function buildHelpSeperator(character, count) + local sep = '' + for i = 1, count do + sep = sep .. character + end + return sep:color(colors.warn) +end + +function buildCommandResponse(message, success) + local response_template = '%s: %s' + local response_color = colors.success + local response_type = 'Success' + + if not success then + response_type = 'Error' + response_color = colors.danger + end + return response_template:format(response_type:color(response_color), message) +end + +function buildWarningMessage(message) + local message_template = '%s: %s' + local response_type = 'Note' + return message_template:format(response_type:color(colors.warn), message) +end + +function buildGetResponseMessage(radio, context, frequency, callSign) + local message_template = '%s %s currently set to %s (%s)' + radio = radio:color(colors.secondary) + frequency = tostring(frequency):color(colors.primary) + return message_template:format(radio, context, frequency, callSign) +end + +function buildSetResponseMessage(radio, context, frequency, callSign) + local message_template = '%s %s updated to station %s (%s)' + radio = radio:color(colors.secondary) + frequency = tostring(frequency):color(colors.primary) + return message_template:format(radio, context, frequency, callSign) +end + +function displayResponse(response, color) + color = color or colors.info + windower.add_to_chat(color, response) + windower.console.write(response:strip_colors()) +end
\ No newline at end of file |