From 09e1bb450d8ba4ca0fad4c8d53fea723a0dfcabf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lilian=20J=C3=B3nsd=C3=B3ttir?= Date: Wed, 8 Sep 2021 11:33:07 -0700 Subject: [PATCH] faction members can help out too --- .../celediel/MoreAttentiveGuards/combat.lua | 70 +++++++++++++++---- .../celediel/MoreAttentiveGuards/common.lua | 5 +- .../celediel/MoreAttentiveGuards/config.lua | 5 +- .../mods/celediel/MoreAttentiveGuards/mcm.lua | 42 +++++++++-- 4 files changed, 102 insertions(+), 20 deletions(-) diff --git a/MWSE/mods/celediel/MoreAttentiveGuards/combat.lua b/MWSE/mods/celediel/MoreAttentiveGuards/combat.lua index 9efe801..b0bbf30 100644 --- a/MWSE/mods/celediel/MoreAttentiveGuards/combat.lua +++ b/MWSE/mods/celediel/MoreAttentiveGuards/combat.lua @@ -69,19 +69,28 @@ local function combatChecks(attacker, target) return true end -local function guardChecks(guard) - local name = guard.object.name - local distance = tes3.mobilePlayer.position:distance(guard.position) +local function genericNPCChecks(npc) + local name = npc.object.name + local distance = tes3.mobilePlayer.position:distance(npc.position) + -- log("Checking out %s (%s) %s away from player in cell %s", name, npc.object.id, distance, npc.cell) - if not guard.object.isGuard then return false end - - if guard.disabled then - log("Disabled guard %s, not alerting", name) + if npc.disabled then + log("Disabled helper %s, not alerting", name) return false end - if not guard.mobile or guard.mobile.isDead then - log("Dead guard %s, not alerting", name) + if not npc.mobile then + log("%s doesn't have mobile, can't alert", name) + return false + end + + if npc.mobile.isDead then + log("Dead helper %s, not alerting", name) + return false + end + + if npc.mobile.inCombat then + log("%s already in combat, not alerting", name) return false end @@ -94,10 +103,45 @@ local function guardChecks(guard) return true end -local function alertGuards(aggressor, cell) +local function guardChecks(npc) + if not npc.object.isGuard then return false end + + if not genericNPCChecks(npc) then return false end + + -- doin' swell + return true +end + +local function factionHelperChecks(npc) + if not config.factionMembersHelp then return false end + + if not genericNPCChecks(npc) then return false end + + -- now that that's out of the way + local name = npc.object.name + local npcFaction = npc.object.faction + + if not npcFaction then return false end + if not npcFaction.playerJoined then return false end + + if config.ignoredFactions[npcFaction.id] then + log("Ignored faction %s, not alerting %s", npcFaction, name) + return false + end + + if npcFaction.playerRank < config.factionMembersHelpRank then + log("Player not high enough rank in faction %s, %s care enough to help", npcFaction, name) + return false + end + + -- hell yeah + return true +end + +local function alertHelpers(aggressor, cell) log("Checking for guards in cell %s to bring justice to %s", cell.name or cell.id, aggressor.object.name) for npc in cell:iterateReferences(tes3.objectType.npc) do - if guardChecks(npc) then + if guardChecks(npc) or factionHelperChecks(npc) then log("Alerting %s to the combat!", npc.object.name) if config.combatDialogue == common.dialogueMode.text then @@ -121,7 +165,7 @@ end this.onCombatStarted = function(e) if not combatChecks(e.actor, e.target) then return end - for _, cell in pairs(tes3.getActiveCells()) do alertGuards(e.actor, cell) end + for _, cell in pairs(tes3.getActiveCells()) do alertHelpers(e.actor, cell) end end -- this will stop guards from attacking ignored actors ever @@ -133,7 +177,7 @@ this.onCombatStart = function(e) (e.actor.baseObject and e.actor.baseObject or e.actor.object) if (config.ignored[string.lower(target.id)] or config.ignored[string.lower(target.sourceMod)]) and attacker.isGuard then - log("Combat started against %s by a guard, %s... stopping...", e.target.object.name, e.actor.object.name) + log("Combat started against ignored %s by helper %s... stopping...", e.target.object.name, e.actor.object.name) return false end end diff --git a/MWSE/mods/celediel/MoreAttentiveGuards/common.lua b/MWSE/mods/celediel/MoreAttentiveGuards/common.lua index cb6ee4f..fb8e95d 100644 --- a/MWSE/mods/celediel/MoreAttentiveGuards/common.lua +++ b/MWSE/mods/celediel/MoreAttentiveGuards/common.lua @@ -5,8 +5,9 @@ local this = {} this.modName = "More Attentive Guards" -- or something this.author = "Celediel" this.version = "1.1.6" -this.modInfo = "Guards with some actual spatial awareness!\n\nGuards who catch you sneaking will follow you for a bit of" .. - "time, and will also come to the player's rescue if attacked unprovoked." +this.modInfo = "Guards with some actual spatial awareness!\n\nGuards who catch you sneaking will follow you for a bit of " .. + "time, and will also come to the player's rescue if attacked unprovoked.\n\nNearby faction members can " .. + "also be configured to help in combat." this.dialogues = { text = require("celediel.MoreAttentiveGuards.dialogue.text"), voice = require("celediel.MoreAttentiveGuards.dialogue.voice") diff --git a/MWSE/mods/celediel/MoreAttentiveGuards/config.lua b/MWSE/mods/celediel/MoreAttentiveGuards/config.lua index ddcdd7c..3c60a77 100644 --- a/MWSE/mods/celediel/MoreAttentiveGuards/config.lua +++ b/MWSE/mods/celediel/MoreAttentiveGuards/config.lua @@ -14,12 +14,15 @@ this.default = { sneakDialogueChance = 67, -- combat combatEnable = true, + factionMembersHelp = true, + factionMembersHelpRank = 1, combatDistance = 850, combatDialogue = common.dialogueMode.voice, ignored = { ["mer_tgw_guar"] = true, ["mer_tgw_guar_w"] = true - } + }, + ignoredFactions = {} } function this.getConfig() diff --git a/MWSE/mods/celediel/MoreAttentiveGuards/mcm.lua b/MWSE/mods/celediel/MoreAttentiveGuards/mcm.lua index d6e39b1..aaf902f 100644 --- a/MWSE/mods/celediel/MoreAttentiveGuards/mcm.lua +++ b/MWSE/mods/celediel/MoreAttentiveGuards/mcm.lua @@ -97,13 +97,29 @@ local combatCategory = mainCategory:createCategory("Combat Settings") combatCategory:createYesNoButton({ label = "Enable combat module", - description = "Guards will come to the rescue of a player who is attacked unprovoked.", + description = "Guards (and optionally faction members) will come to the rescue of a player who is attacked unprovoked.", variable = createTableVar("combatEnable") }) +combatCategory:createYesNoButton({ + label = "Faction members help too", + description = "NPCs who are in the same faction as the player will also assist in combat.", + variable = createTableVar("factionMembersHelp") +}) + combatCategory:createSlider({ - label = "Guard alert range", - description = "How far away guards are alerted to combat against the player", + label = "Faction rank required for help", + description = "If the player is less than the configured rank, faction members will not help out.", + min = 0, + max = 10, + step = 1, + jump = 5, + variable = createTableVar("factionMembersHelpRank") +}) + +combatCategory:createSlider({ + label = "Combat alert range", + description = "How far away helpers are alerted to combat against the player", min = 1, max = 20000, step = 10, @@ -113,7 +129,7 @@ combatCategory:createSlider({ combatCategory:createDropdown({ label = "Combat dialogue", - description = "Guards have things to say when they come to the rescue of a player who is attacked unprovoked.", + description = "Helpers have things to say when they come to the rescue of a player who is attacked unprovoked.", variable = createTableVar("combatDialogue"), options = { { label = "Text", value = common.dialogueMode.text }, @@ -136,6 +152,24 @@ template:createExclusionsPage({ variable = createTableVar("ignored") }) +template:createExclusionsPage({ + label = "Ignored factions", + description = "Members of these factions will not help the player in combat", + showAllBlocked = false, + filters = { + { label = "Factions", callback = function() + local factions = {} + + for _, faction in pairs(tes3.dataHandler.nonDynamicData.factions) do + table.insert(factions, faction.id) + end + + return factions + end } + }, + variable = createTableVar("ignoredFactions") +}) + return template -- vim:fdm=marker