summaryrefslogtreecommitdiff
path: root/Data/BuiltIn/Libraries/lua-addons/addons/MountMuzzle
diff options
context:
space:
mode:
Diffstat (limited to 'Data/BuiltIn/Libraries/lua-addons/addons/MountMuzzle')
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/MountMuzzle/LICENSE25
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/MountMuzzle/README.md238
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/MountMuzzle/constants.lua111
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/MountMuzzle/helpers.lua80
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/MountMuzzle/mountmuzzle.lua261
5 files changed, 715 insertions, 0 deletions
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/MountMuzzle/LICENSE b/Data/BuiltIn/Libraries/lua-addons/addons/MountMuzzle/LICENSE
new file mode 100644
index 0000000..1b2e964
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/MountMuzzle/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 Mount Muzzle 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/MountMuzzle/README.md b/Data/BuiltIn/Libraries/lua-addons/addons/MountMuzzle/README.md
new file mode 100644
index 0000000..6345213
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/MountMuzzle/README.md
@@ -0,0 +1,238 @@
+**Author:** [Sjshovan (Apogee)](https://github.com/Ap0gee)
+**Version:** v0.9.5
+
+
+# Mount Muzzle
+
+> A Windower 4 addon that allows the user to change or remove the default mount 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 `MountMuzzle` addon.
+3. Click the download button.
+4. Ensure the addon is switched on.
+
+**Manual:**
+1. Navigate to <https://github.com/Ap0gee/MountMuzzle>.
+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.5`). The folder should be named `MountMuzzle`.
+
+___
+### Aliases
+The following aliases are available to Mount Muzzle commands:
+
+**mountmuzzle:** muzzle | mm
+**list:** l
+**set:** s
+**get:** g
+**default:** d
+**unload:** u
+**reload:** r
+**about:** a
+**silent:** s
+**mount:** m
+**chocobo:** c
+**zone:** z
+**help:** h
+
+ ___
+### Usage
+
+Manually load the addon by using one of the following commands:
+
+ //lua load mountmuzzle
+ //lua l mountmuzzle
+
+___
+### Commands
+
+**help**
+
+Displays available Mount Muzzle commands. Below are the equivalent ways of calling the command:
+
+ //mountmuzzle help
+ //muzzle help
+ //mm help
+ //mountmuzzle h
+ //muzzle h
+ //mm h
+
+**list**
+
+Displays the available muzzle types. Below are the equivalent ways of calling the command:
+
+ //mountmuzzle list
+ //muzzle list
+ //mm list
+ //mm l
+
+**set _\<muzzle>_**
+
+Sets the current muzzle to the given muzzle type. This command takes a single argument represented by `<muzzle>`. Below are the equivalent ways of calling the command:
+
+ //mountmuzzle set <muzzle>
+ //muzzle set <muzzle>
+ //mm set <muzzle>
+ //mm s <muzzle>
+
+Here are some usage examples for the **set _\<muzzle>_** command: `mm set silent` and `muzzle set zone` etc...
+
+**get**
+
+Displays the current muzzle that is set. Below are the equivalent ways of calling the command:
+
+ //mountmuzzle get
+ //muzzle get
+ //mm get
+ //mm g
+
+**default**
+
+Sets the current muzzle to the default muzzle type: `Silent`. Below are the equivalent ways of calling the command:
+
+ //mountmuzzle default
+ //muzzle default
+ //mm default
+ //mm d
+
+**unload**
+
+Unloads the Mount Muzzle addon. Below are the equivalent ways of calling the command:
+
+ //mountmuzzle unload
+ //muzzle unload
+ //mm unload
+ //mm u
+
+**reload**
+
+Reloads the Mount Muzzle addon. Below are the equivalent ways of calling the command:
+
+ //mountmuzzle reload
+ //muzzle reload
+ //mm reload
+ //mm r
+
+**about**
+
+Displays information about the Mount Muzzle addon. Below are the equivalent ways of calling the command:
+
+ //mountmuzzle about
+ //muzzle about
+ //mm about
+ //mm a
+
+___
+### Support
+**Having Issues with this addon?**
+* Please let me know [here](https://github.com/Ap0gee/MountMuzzle/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 show your love and help me make more awesome stuff?**
+* You can do so here: <https://www.paypal.me/Sjshovan>
+
+___
+### Change Log
+
+**v0.9.5** - 1/05/2019
+- **Fix:** Client sometimes crashes/locks when exiting game.
+- **Update:** Silent muzzle song id changed to help prevent future game updates from overriding.
+- **Update:** README Known Issues updated.
+- **Update:** README TODOS updated.
+
+**v0.9.4** - 9/06/2018
+- **Fix:** Music wouldn't change if addon loaded while on mount.
+- **Fix:** Music wouldn't change if addon unloaded while on mount.
+- **Fix:** Muzzle type 'Silent' was playing incorrect track.
+- **Update:** Licences now display correct addon name.
+- **Update:** Muzzle type 'Normal' changed to 'Mount'.
+- **Update:** Muzzle type 'Choco' changed to 'Chocobo'.
+- **Update:** mountmuzzle.lua refactored and condensed.
+- **Update:** README Commands updated.
+- **Update:** README Installation updated.
+- **Update:** README Table of Contents updated.
+- **Update:** README Known Issues updated.
+- **Update:** README TODOS updated.
+- **Add:** New commands added (about, unload).
+- **Add:** Shorthand aliases added to all commands.
+- **Add:** Aliases added to README.
+
+**v0.9.3** - 5/31/2018
+- **Remove:** Removed /data/settings.xml file.
+- **Update:** Licences now display correct author name.
+- **Update:** helpers.lua now requires only colors from constants.lua.
+- **Update:** constants.lua now returns table of globals for modular support.
+- **Update:** mountmuzzle.lua refactored in attempt to meet merge criteria.
+- **Update:** README refactored in attempt to meet merge criteria.
+
+**v0.9.2** - 5/24/2018
+- **Fix:** Zone music gets silenced if player enters reive on mount with zone muzzle selected.
+- **Fix:** Player reaches error if no arguments are given upon invoking the addon.
+- **Update:** Convert tab characters to spaces, simplify code.
+- **Update:** README Usage Instructions updated.
+- **Update:** README Known Issues updated.
+- **Add:** Table of Contents added to README.
+- **Add:** Prerequisites added to README.
+- **Add:** Installation added to README.
+- **Add:** Support added to README.
+- **Add:** License added to README.
+
+**v0.9.1** - 5/22/2018
+- **Fix:** Chosen music does not start upon login if mounted.
+- **Fix:** Chosen music does not persist upon changing zones.
+- **Add:** Known Issues added to README.
+- **Add:** TODOS added to README.
+
+**v0.9.0** - 5/21/2018
+- Initial release
+
+___
+### Known Issues
+
+- **Issue:** If Mount Muzzle is selected to automatically load and the player is mounted upon login, there is a significant delay before the chosen music will begin to play.
+- **Issue:** Upon changing zones the default music can be heard for a moment before the chosen music begins to play.
+- **Issue:** Unable to correctly set mount music to original if Mount Muzzle is unloaded while mounted.
+- **Issue:** Unable to alter mount music upon addon unload through the Windower `exit` command, which causes client to crash. No known viable alternatives.
+___
+### TODOs
+
+- **TODO:** Investigate alternative methods for music change as packet injection/swap allows the player to hear the default music upon zone change and login, regardless of chosen music.
+- **TODO:** Investigate methods for determining which mount type the player is on when loading/unloading Mount Muzzle.
+- **TODO:** Investigate ways to prevent packet injection client crash/lock within unload event if triggered through Windower `exit` command.
+___
+
+### 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/MountMuzzle/constants.lua b/Data/BuiltIn/Libraries/lua-addons/addons/MountMuzzle/constants.lua
new file mode 100644
index 0000000..dfd66a7
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/MountMuzzle/constants.lua
@@ -0,0 +1,111 @@
+--[[
+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 Mount Muzzle 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 = {
+ mount = 0x1A,
+ unmount = 0x12
+ },
+ }
+ },
+}
+
+player = {
+ statuses = {
+ mounted = 85
+ },
+ buffs = {
+ reiveMark = 511,
+ mounted = 252
+ }
+}
+
+music = {
+ songs = {
+ silent = 9999,
+ mount = 84,
+ chocobo = 212,
+ zone = 0,
+ },
+ types = {
+ mount = 4,
+ idle_day = 0,
+ idle_night = 1
+ }
+}
+
+colors = {
+ primary = 200,
+ secondary = 207,
+ info = 0,
+ warn = 140,
+ danger = 167,
+ success = 158
+}
+
+muzzles = {
+ silent = {
+ name = 'silent',
+ song = music.songs.silent,
+ description = 'No Music (Default)'
+ },
+ mount = {
+ name = 'mount',
+ song = music.songs.mount,
+ description = 'Mount Music'
+ },
+ chocobo = {
+ name = 'chocobo',
+ song = music.songs.chocobo,
+ description = 'Chocobo Music'
+ },
+ zone = {
+ name = 'zone',
+ song = music.songs.zone,
+ description = 'Current Zone Music'
+ }
+}
+
+return {
+ packets = packets,
+ player = player,
+ music = music,
+ colors = colors,
+ muzzles = muzzles
+} \ No newline at end of file
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/MountMuzzle/helpers.lua b/Data/BuiltIn/Libraries/lua-addons/addons/MountMuzzle/helpers.lua
new file mode 100644
index 0000000..000a65e
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/MountMuzzle/helpers.lua
@@ -0,0 +1,80 @@
+--[[
+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 Mount Muzzle 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 short_name = "mm":color(colors.primary)
+ local command = command:color(colors.secondary)
+ local sep = "=>":color(colors.primary)
+ local description = description:color(colors.info)
+
+ return "%s %s %s %s":format(short_name, command, sep, description)
+end
+
+function buildHelpTypeEntry(name, description)
+ local name = name:color(colors.secondary)
+ local sep = "=>":color(colors.primary)
+ local description = description:color(colors.info)
+
+ return "%s %s %s":format(name, sep, description)
+end
+
+function buildHelpTitle(context)
+ local context = context:color(colors.danger)
+
+ return "%s Help: %s":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_color = colors.success
+ local response_type = 'Success'
+
+ if not success then
+ response_type = 'Error'
+ response_color = colors.danger
+ end
+
+ return "%s: %s":format(response_type:color(response_color), message)
+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
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/MountMuzzle/mountmuzzle.lua b/Data/BuiltIn/Libraries/lua-addons/addons/MountMuzzle/mountmuzzle.lua
new file mode 100644
index 0000000..95ab080
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/MountMuzzle/mountmuzzle.lua
@@ -0,0 +1,261 @@
+--[[
+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 Mount Muzzle 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 = 'Mount Muzzle'
+_addon.description = 'Change or remove the default mount music.'
+_addon.author = 'Sjshovan (Apogee) sjshovan@gmail.com'
+_addon.version = '0.9.5'
+_addon.commands = {'mountmuzzle', 'muzzle', 'mm'}
+
+local _logger = require('logger')
+local _config = require('config')
+local _packets = require('packets')
+
+require('constants')
+require('helpers')
+
+local needs_inject = false
+
+local defaults = {
+ muzzle = muzzles.silent.name
+}
+
+local settings = _config.load(defaults)
+
+local help = {
+ commands = {
+ buildHelpSeperator('=', 26),
+ buildHelpTitle('Commands'),
+ buildHelpSeperator('=', 26),
+ buildHelpCommandEntry('list', 'Display the available muzzle types.'),
+ buildHelpCommandEntry('set <muzzle>', 'Set the current muzzle to the given muzzle type.'),
+ buildHelpCommandEntry('get', 'Display the current muzzle.'),
+ buildHelpCommandEntry('default', 'Set the current muzzle to the default (Silent).'),
+ buildHelpCommandEntry('unload', 'Unload Mount Muzzle.'),
+ buildHelpCommandEntry('reload', 'Reload Mount Muzzle.'),
+ buildHelpCommandEntry('about', 'Display information about Mount Muzzle.'),
+ buildHelpCommandEntry('help', 'Display Mount Muzzle commands.'),
+ buildHelpSeperator('=', 26),
+ },
+ types = {
+ buildHelpSeperator('=', 23),
+ buildHelpTitle('Types'),
+ buildHelpSeperator('=', 23),
+ buildHelpTypeEntry(muzzles.silent.name:ucfirst(), muzzles.silent.description),
+ buildHelpTypeEntry(muzzles.mount.name:ucfirst(), muzzles.mount.description),
+ buildHelpTypeEntry(muzzles.chocobo.name:ucfirst(), muzzles.chocobo.description),
+ buildHelpTypeEntry(muzzles.zone.name:ucfirst(), muzzles.zone.description),
+ buildHelpSeperator('=', 23),
+ },
+ 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 = {
+ muzzles = {
+ s = muzzles.silent.name,
+ m = muzzles.mount.name,
+ c = muzzles.chocobo.name,
+ z = muzzles.zone.name
+ }
+ }
+}
+
+function display_help(table_help)
+ for index, command in pairs(table_help) do
+ displayResponse(command)
+ end
+end
+
+function getMuzzle()
+ return settings.muzzle
+end
+
+function getPlayerBuffs()
+ return T(windower.ffxi.get_player().buffs)
+end
+
+function resolveCurrentMuzzle()
+ local current_muzzle = getMuzzle()
+
+ if not muzzleValid(current_muzzle) then
+ current_muzzle = muzzles.silent.name
+ setMuzzle(current_muzzle)
+ displayResponse(
+ 'Note: Muzzle found in settings was not valid and is now set to the default (%s).':format('Silent':color(colors.secondary)),
+ colors.warn
+ )
+ end
+
+ return muzzles[current_muzzle]
+end
+
+function setMuzzle(muzzle)
+ settings.muzzle = muzzle
+ settings:save()
+end
+
+function playerInReive()
+ return getPlayerBuffs():contains(player.buffs.reiveMark)
+end
+
+function playerIsMounted()
+ local _player = windower.ffxi.get_player()
+
+ if _player then
+ return _player.status == player.statuses.mounted or getPlayerBuffs():contains(player.buffs.mounted)
+ end
+
+ return false
+end
+
+function muzzleValid(muzzle)
+ return muzzles[muzzle] ~= nil
+end
+
+function injectMuzzleMusic()
+ injectMusic(music.types.mount, resolveCurrentMuzzle().song)
+end
+
+function injectMusic(bgmType, songID)
+ _packets.inject(_packets.new('incoming', packets.inbound.music_change.id, {
+ ['BGM Type'] = bgmType,
+ ['Song ID'] = songID,
+ }))
+end
+
+function requestInject()
+ needs_inject = true
+end
+
+function handleInjectionNeeds()
+ if needs_inject and playerIsMounted() then
+ injectMuzzleMusic()
+ needs_inject = false;
+ end
+end
+
+function tryInject()
+ requestInject()
+ handleInjectionNeeds()
+end
+
+windower.register_event('login', 'load', 'zone change', function()
+ tryInject()
+end)
+
+windower.register_event('addon command', function(command, ...)
+ if command then
+ command = command:lower()
+ else
+ return display_help(help.commands)
+ end
+
+ local command_args = {...}
+ local respond = false
+ local response_message = ''
+ local success = true
+
+ if command == 'list' or command == 'l' then
+ display_help(help.types)
+
+ elseif command == 'set' or command == 's' then
+ respond = true
+
+ local muzzle = tostring(command_args[1]):lower()
+ local from_alias = help.aliases.muzzles[muzzle]
+
+ if (from_alias ~= nil) then
+ muzzle = from_alias
+ end
+
+ if not muzzleValid(muzzle) then
+ success = false
+ response_message = 'Muzzle type not recognized.'
+ else
+ requestInject()
+ setMuzzle(muzzle)
+ response_message = 'Updated current muzzle to %s.':format(muzzle:ucfirst():color(colors.secondary))
+ end
+
+ elseif command == 'get' or command == 'g' then
+ respond = true
+ response_message = 'Current muzzle is %s.':format(getMuzzle():ucfirst():color(colors.secondary))
+
+ elseif command == 'default' or command == 'd' then
+ respond = true
+ requestInject()
+
+ setMuzzle(muzzles.silent.name)
+ response_message = 'Updated current muzzle to the default (%s).':format('Silent':color(colors.secondary))
+
+ elseif command == 'reload' or command == 'r' then
+ windower.send_command('lua r mountmuzzle')
+
+ elseif command == 'unload' or command == 'u' then
+ respond = true
+ response_message = 'Thank you for using Mount Muzzle. Goodbye.'
+ injectMusic(music.types.mount, muzzles.zone.song)
+ windower.send_command('lua unload mountmuzzle')
+
+ elseif command == 'about' or command == 'a' then
+ display_help(help.about)
+
+ elseif command == 'help' or command == 'h' then
+ display_help(help.commands)
+ else
+ display_help(help.commands)
+ end
+
+ if respond then
+ displayResponse(
+ buildCommandResponse(response_message, success)
+ )
+ end
+
+ handleInjectionNeeds()
+end)
+
+windower.register_event('incoming chunk', function(id, data)
+ if id == packets.inbound.music_change.id then
+ local packet = _packets.parse('incoming', data)
+
+ if packet['BGM Type'] == music.types.mount then
+ packet['Song ID'] = resolveCurrentMuzzle().song
+ return _packets.build(packet)
+ end
+
+ tryInject()
+ end
+end) \ No newline at end of file