commit e5d333e1cfd8508b2f8423043d273ad7cd8bc845 Author: Lilian Jónsdóttir Date: Sat Aug 7 22:59:41 2021 -0700 first commit diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e39b049 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021 Lilian Jónsdóttir + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/MWSE/mods/celediel/ASinkingFeeling/common.lua b/MWSE/mods/celediel/ASinkingFeeling/common.lua new file mode 100644 index 0000000..271450d --- /dev/null +++ b/MWSE/mods/celediel/ASinkingFeeling/common.lua @@ -0,0 +1,12 @@ +local this = {} + +this.modName = "A Sinking Feeling" +this.author = "Celediel" +this.modInfo = "No longer can you swim in heavy plate, now your armour, equipment or carried items drag you down while swimming.\n" .. + "Options exist for formulas based on equipped armour weight class, total equipment weight or encumbrance percentage." +this.version = "1.0.0" +this.configString = string.gsub(this.modName, "%s+", "") +this.modes = {equippedArmour = 0, allEquipment = 1, encumbrancePercentage = 2} +this.log = function(...) mwse.log("[%s] %s", "Armoured Sinking", string.format(...)) end + +return this \ No newline at end of file diff --git a/MWSE/mods/celediel/ASinkingFeeling/config.lua b/MWSE/mods/celediel/ASinkingFeeling/config.lua new file mode 100644 index 0000000..3688f8e --- /dev/null +++ b/MWSE/mods/celediel/ASinkingFeeling/config.lua @@ -0,0 +1,6 @@ +local common = require("celediel.ASinkingFeeling.common") + +local defaultConfig = {enabled = true, debug = false, downPullMultiplier = 100, mode = common.modes.equippedArmour} +local config = mwse.loadConfig(common.configString, defaultConfig) + +return config \ No newline at end of file diff --git a/MWSE/mods/celediel/ASinkingFeeling/main.lua b/MWSE/mods/celediel/ASinkingFeeling/main.lua new file mode 100644 index 0000000..5c4dc90 --- /dev/null +++ b/MWSE/mods/celediel/ASinkingFeeling/main.lua @@ -0,0 +1,88 @@ +local config = require("celediel.ASinkingFeeling.config") +local common = require("celediel.ASinkingFeeling.common") + +-- Helper Functions +local function getTotalArmourClass(actor) + local armourClass = 0 + + -- get armour level for each equipped piece of armour + -- light = 0, medium = 1, heavy = 2, plus one so light armour is affected + if actor and actor.equipment then + for stack in tes3.iterate(actor.equipment) do + local item = stack.object + if item.objectType == tes3.objectType.armor then + armourClass = armourClass + item.weightClass + 1 + end + end + end + + return armourClass +end + +local function getTotalEquipmentWeight(actor) + local weight = 0 + + if actor and actor.equipment then + for stack in tes3.iterate(actor.equipment) do + local item = stack.object + weight = weight + item.weight + end + end + + return weight +end + +-- Event functions +local function sinkInWater(e) + -- don't even calculate anything if disabled + if not config.enabled then return end + + -- shortcut refs + local mobile = e.mobile + local ref = e.reference + local actor = ref.object + + -- no creatures + if mobile.actorType == tes3.actorType.creature then return end + + local downPull = 0 + + -- calculate the down-pull with the configured formula + if config.mode == common.modes.equippedArmour then + local armourClass = getTotalArmourClass(actor) + downPull = (config.downPullMultiplier / 10) * armourClass + if config.debug then + common.log("Pulling %s down by %s using equipped armour mode (%s total armour class)", + ref.id, downPull, armourClass) + end + + elseif config.mode == common.modes.allEquipment then + local totalWeight = getTotalEquipmentWeight(actor) + -- doubling this keeps this formula somewhat uniform with armour class @ multiplier 100 + downPull = ((config.downPullMultiplier / 100) * totalWeight) * 2 + if config.debug then + common.log("Pulling %s down by %s using equipment weight mode (%s total equipment weight)", + ref.id, downPull, totalWeight) + end + + elseif config.mode == common.modes.encumbrancePercentage then + local encumbrance = mobile.encumbrance + -- tripling this keeps this formula somewhat uniform with armour class @ multiplier 100 + downPull = (config.downPullMultiplier * encumbrance.normalized) * 3 + if config.debug then + common.log("Pulling %s down by %s using encumbrance mode (%s/%s = %s encumbrance)", + ref.id, downPull, encumbrance.current, encumbrance.base, encumbrance.normalized) + end + end + + -- finally add down-pull from configured formula to tes3.mobilePlayer.velocity.z to simulate being pulled down + tes3.mobilePlayer.velocity.z = -downPull +end + +local function onInitialized() + event.register("calcSwimSpeed", sinkInWater) + common.log("Successfully initialized!") +end + +event.register("initialized", onInitialized) +event.register("modConfigReady", function() mwse.mcm.register(require("celediel.ASinkingFeeling.mcm")) end) \ No newline at end of file diff --git a/MWSE/mods/celediel/ASinkingFeeling/mcm.lua b/MWSE/mods/celediel/ASinkingFeeling/mcm.lua new file mode 100644 index 0000000..20e168e --- /dev/null +++ b/MWSE/mods/celediel/ASinkingFeeling/mcm.lua @@ -0,0 +1,54 @@ +local common = require("celediel.ASinkingFeeling.common") +local config = require("celediel.ASinkingFeeling.config") + +local function createTableVar(id) return mwse.mcm.createTableVariable {id = id, table = config} end + +local template = mwse.mcm.createTemplate(common.modName) +template:saveOnClose(common.configString, config) + +local page = template:createSideBarPage({ + label = "Sidebar Page???", + description = string.format("%s v%s by %s\n\n%s", common.modName, common.version, common.author, common.modInfo) +}) + +local category = page:createCategory(common.modName) + +category:createYesNoButton({ + label = "Enable the mod", + description = "Does what it says!", + variable = createTableVar("enabled") +}) + +category:createDropdown({ + label = "Down-pull formula", + description = "Formula used to calculate down-pull amount.\n\nOptions are: Equipped Armour, Equipment Weight, Encumbrance\n\n" .. + "Equipped Armour: Actors are pulled down by their combined armour class (Light = 1, Medium = 2, Heavy = 3), " .. + "multiplied by a tenth of the down-pull multiplier. Default of 100 makes it impossible to surface in all heavy armour for all but the most Athletic.\n\n" .. + "Equipment weight: Actors are pulled down by double the weight of all equipped gear multiplied by a hundredth of the down-pull multiplier.\n\n" .. + "Encumbrance: Actors are pulled down by their encumbrance percentage multiplied by triple the down-pull multiplier.\n\n" .. + "What is dead may never die.", + options = { + { label = "Equipped Armour", value = common.modes.equippedArmour }, + { label = "All Equipment", value = common.modes.allEquipment }, + { label = "Encumbrance", value = common.modes.encumbrancePercentage } + }, + variable = createTableVar("mode") +}) + +category:createSlider({ + label = "Down-pull multiplier", + description = "Multiplier used in the selected formula.\n\nDefault value of 100 acts similarly in all formulas.", + variable = createTableVar("downPullMultiplier"), + min = 0, + max = 300, + step = 1, + jump = 10 +}) + +category:createYesNoButton({ + label = "Debug logging", + description = "Spam mwse.log with useless nonsense.", + variable = createTableVar("debug") +}) + +return template diff --git a/README.md b/README.md new file mode 100644 index 0000000..e090356 --- /dev/null +++ b/README.md @@ -0,0 +1,42 @@ +# A Sinking Feeling # + +## About ## + +>He vaulted over the gunwale, landing on the deck below with his golden cloak billowing behind him. The white roses drew back, as men +>always did at the sight of Victarion Greyjoy armed and armored, his face hidden behind his kraken helm. They were clutching swords and +>spears and axes, but nine of every ten wore no armor, and the tenth had only a shirt of sewn scales. _These are no ironmen_, Victarion +>thought. _They still fear drowning._ +>- _George R.R. Martin - A Feast for Crows_ + +No longer can you swim in heavy plate; now your armour, equipment, or items drag you down while swimming. Options exist for formulas +based on equipped armour weight class, total equipment weight, or encumbrance percentage. + +Enable debug logging, and check MWSE for the exact values being used. + +[Video of the mod in action](https://gfycat.com/needysevereisabellineshrike). + +## Formulas ## + +**Equipped armour** (*Default option*): the armour class of each equipped item (+1 so Light armour is affected as well, +so Light = 1, Medium = 2, Heavy = 3) is added up for a value of 0 - 27 then multiplied by a tenth of the down-pull multiplier (See MCM). + +**Total Equipment Weight**: the weight of each equipped item is added up, doubled, then multiplied by a hundredth of the down-pull multiplier. + +**Encumbrance Percentage**: the actor's encumbrance percentage (carrying 120 of 300 = 40% or 0.4) is multiplied by triple the down-pull multiplier. + +The default down-pull multiplier value of 100 acts somewhat the same across all formulas. Encumbrance is a bit different, as while it's possible, +and quite easy, to have values of 0 for equipped armour and total equipment weight, the same cannot be said of encumbrance. It also can +vary greatly from character to character, while armour class and weight are static across the board. For a happy medium between the frustration +of realism and frustration-free video game-ness, I recommend the default values, and not wearing heavy armour whilst swimming, but the options +are there for those who desire them. + +## Requirements ## +MGE XE with MWSE @ [Nexus Mods](https://www.nexusmods.com/morrowind/mods/41102) \(Make sure you run MWSE-Update.exe\) + +## Credits ## + +* MWSE Team for MWSE with Lua support + +## License ## + +MIT License. See LICENSE file.