initial commit
This commit is contained in:
parent
2fc3aaf79b
commit
c30f84e616
9 changed files with 628 additions and 0 deletions
88
.gitignore
vendored
Normal file
88
.gitignore
vendored
Normal file
|
@ -0,0 +1,88 @@
|
|||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/lua,visualstudiocode,windows
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=lua,visualstudiocode,windows
|
||||
|
||||
### Lua ###
|
||||
# Compiled Lua sources
|
||||
luac.out
|
||||
|
||||
# luarocks build files
|
||||
*.src.rock
|
||||
*.zip
|
||||
*.tar.gz
|
||||
|
||||
# Object files
|
||||
*.o
|
||||
*.os
|
||||
*.ko
|
||||
*.obj
|
||||
*.elf
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
|
||||
# Libraries
|
||||
*.lib
|
||||
*.a
|
||||
*.la
|
||||
*.lo
|
||||
*.def
|
||||
*.exp
|
||||
|
||||
# Shared objects (inc. Windows DLLs)
|
||||
*.dll
|
||||
*.so
|
||||
*.so.*
|
||||
*.dylib
|
||||
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
*.i*86
|
||||
*.x86_64
|
||||
*.hex
|
||||
|
||||
|
||||
### VisualStudioCode ###
|
||||
.vscode/*
|
||||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
!.vscode/launch.json
|
||||
!.vscode/extensions.json
|
||||
*.code-workspace
|
||||
|
||||
### VisualStudioCode Patch ###
|
||||
# Ignore all local history of files
|
||||
.history
|
||||
|
||||
### Windows ###
|
||||
# Windows thumbnail cache files
|
||||
Thumbs.db
|
||||
Thumbs.db:encryptable
|
||||
ehthumbs.db
|
||||
ehthumbs_vista.db
|
||||
|
||||
# Dump file
|
||||
*.stackdump
|
||||
|
||||
# Folder config file
|
||||
[Dd]esktop.ini
|
||||
|
||||
# Recycle Bin used on file shares
|
||||
$RECYCLE.BIN/
|
||||
|
||||
# Windows Installer files
|
||||
*.cab
|
||||
*.msi
|
||||
*.msix
|
||||
*.msm
|
||||
*.msp
|
||||
|
||||
# Windows shortcuts
|
||||
*.lnk
|
||||
|
||||
[Bb]uild
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/lua,visualstudiocode,windows
|
68
MWSE/mods/celediel/MoreAttentiveGuards/combat.lua
Normal file
68
MWSE/mods/celediel/MoreAttentiveGuards/combat.lua
Normal file
|
@ -0,0 +1,68 @@
|
|||
local common = require("celediel.MoreAttentiveGuards.common")
|
||||
local config = require("celediel.MoreAttentiveGuards.config").getConfig()
|
||||
|
||||
local this = {}
|
||||
|
||||
-- {{{ helper functions
|
||||
|
||||
local function log(...) if config.debug then common.log(...) end end
|
||||
|
||||
local function alertGuards(aggressor, cell)
|
||||
-- a wanted player gets no help
|
||||
if tes3.mobilePlayer.bounty > 0 then
|
||||
log("Player is wanted, ignoring combat.")
|
||||
return
|
||||
end
|
||||
|
||||
log("Checking for guards in cell %s to bring justice to %s", cell.name or cell.id, aggressor.object.name)
|
||||
local playerPos = tes3.mobilePlayer.position
|
||||
|
||||
for npc in cell:iterateReferences(tes3.objectType.npc) do
|
||||
local distance = playerPos:distance(npc.position)
|
||||
if npc.object.isGuard and distance <= config.combatDistance then
|
||||
log("Alerting %s, %s units away, to the combat!", npc.object.name, distance)
|
||||
|
||||
if config.combatDialogue then
|
||||
local response = common.guardDialogue(npc, table.choice(common.dialogues[config.language].join_combat),
|
||||
aggressor)
|
||||
log(response)
|
||||
end
|
||||
|
||||
npc.mobile:startCombat(aggressor)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- }}}
|
||||
|
||||
-- {{{ returned event functions
|
||||
|
||||
this.onCombatStart = function(e)
|
||||
if not config.combatEnable then return end
|
||||
|
||||
-- if player initiates combat or combat is not against player, do nothing
|
||||
if e.actor == tes3.mobilePlayer or e.target ~= tes3.mobilePlayer then return end
|
||||
|
||||
-- inCombat is true after player has taken combat actions
|
||||
-- or after combat has gone on awhile, but hopefully the guards will already be attacking by then
|
||||
-- should be fine in cities, but will prevent players from provoking NPCs
|
||||
-- in the wilderness and leading them into town
|
||||
if tes3.mobilePlayer.inCombat then
|
||||
log("Player is in combat, not sure who started it, so not helping.")
|
||||
return
|
||||
end
|
||||
|
||||
local cell = tes3.getPlayerCell()
|
||||
|
||||
if cell.isInterior and not cell.behavesAsExterior then
|
||||
alertGuards(e.actor, cell)
|
||||
else
|
||||
for _, extCell in pairs(tes3.getActiveCells()) do alertGuards(e.actor, extCell) end
|
||||
end
|
||||
end
|
||||
|
||||
-- }}}
|
||||
|
||||
return this
|
||||
|
||||
-- vim:fdm=marker
|
58
MWSE/mods/celediel/MoreAttentiveGuards/common.lua
Normal file
58
MWSE/mods/celediel/MoreAttentiveGuards/common.lua
Normal file
|
@ -0,0 +1,58 @@
|
|||
local this = {}
|
||||
|
||||
-- {{{ mod info and such
|
||||
|
||||
this.modName = "More Attentive Guards" -- or something
|
||||
this.author = "Celediel"
|
||||
this.version = "0.0.1"
|
||||
this.modInfo = [[Guards with some actual spacial awareness!
|
||||
Guards 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.dialogues = require("celediel.MoreAttentiveGuards.dialogues")
|
||||
this.configString = string.gsub(this.modName, "%s+", "")
|
||||
|
||||
-- }}}
|
||||
|
||||
-- {{{ NPC stuff or whatever
|
||||
|
||||
this.basicIdles = {60, 20, 20, 20, 0, 0, 0, 0}
|
||||
|
||||
-- }}}
|
||||
|
||||
-- {{{ functions
|
||||
|
||||
this.log = function(...) mwse.log("[%s] %s", this.modName, string.format(...)) end
|
||||
|
||||
-- https://en.uesp.net/wiki/Tes3Mod:AIWander told me some things about idles
|
||||
this.generateIdles = function()
|
||||
local idles = {}
|
||||
-- idles[1] = 0 -- ? idle 1 is not used?
|
||||
for i = 1, 4 do idles[i] = math.random(0, 60) end
|
||||
idles[5] = 0 -- ? Idle6: Rubbing hands together and showing wares
|
||||
for i = 6, 8 do idles[i] = math.random(0, 60) end
|
||||
return idles
|
||||
end
|
||||
|
||||
this.guardDialogue = function(npc, str, target)
|
||||
-- target of the dialogue, either an NPC/Creature, or the player's class or race
|
||||
-- this is what %s is replaced with in the dialogue string; npc/creature for combat, player for sneak
|
||||
local targetOrPlayer
|
||||
if target == tes3.mobilePlayer then
|
||||
targetOrPlayer = math.random() >= 0.5 and target.object.class.name or target.object.race.name
|
||||
else
|
||||
targetOrPlayer = target.object.name
|
||||
end
|
||||
|
||||
local name = npc.object.name
|
||||
local message = string.format(str, targetOrPlayer)
|
||||
local output = string.format("%s: %s", name, message)
|
||||
|
||||
tes3.messageBox(output)
|
||||
return output
|
||||
end
|
||||
|
||||
-- }}}
|
||||
|
||||
return this
|
||||
|
||||
-- vim:fdm=marker
|
26
MWSE/mods/celediel/MoreAttentiveGuards/config.lua
Normal file
26
MWSE/mods/celediel/MoreAttentiveGuards/config.lua
Normal file
|
@ -0,0 +1,26 @@
|
|||
local common = require("celediel.MoreAttentiveGuards.common")
|
||||
local this = {}
|
||||
|
||||
local currentConfig
|
||||
|
||||
this.default = {
|
||||
-- common
|
||||
language = "english",
|
||||
debug = false,
|
||||
-- sneak
|
||||
sneakEnable = true,
|
||||
sneakDialogue = true,
|
||||
sneakDialogueTimer = 5,
|
||||
sneakDialogueChance = 67,
|
||||
-- combat
|
||||
combatEnable = true,
|
||||
combatDistance = 850,
|
||||
combatDialogue = true
|
||||
}
|
||||
|
||||
function this.getConfig()
|
||||
currentConfig = currentConfig or mwse.loadConfig(common.configString, this.default)
|
||||
return currentConfig
|
||||
end
|
||||
|
||||
return this
|
35
MWSE/mods/celediel/MoreAttentiveGuards/dialogues.lua
Normal file
35
MWSE/mods/celediel/MoreAttentiveGuards/dialogues.lua
Normal file
|
@ -0,0 +1,35 @@
|
|||
return {
|
||||
["english"] = {
|
||||
-- guards might say this every so often to players who are sneaking
|
||||
-- %s is replaced with race or class
|
||||
["sneaking"] = {
|
||||
"Why are you sneaking around like a s'wit?",
|
||||
"What are you up to, %s...?",
|
||||
"What are you up to...?",
|
||||
"I'm watching you, %s...",
|
||||
"I'm watching you...",
|
||||
"I've got my eye on you, %s...",
|
||||
"I've got my eye on you..."
|
||||
},
|
||||
-- guards say this when players stop sneaking while being followed
|
||||
-- %s is replaced with race or class
|
||||
["stop_sneaking"] = {
|
||||
"That's what I thought.",
|
||||
"That's better, %s.",
|
||||
},
|
||||
-- guards say this when they're satisfied that the player is not doing anything illegal
|
||||
-- %s is replaced with race or class
|
||||
["stop_following"] = {
|
||||
"I don't have time for this...",
|
||||
"Sneaking around for no reason, are we...?",
|
||||
"Sneaking around for no reason, are we...? Alright then, %s.",
|
||||
},
|
||||
-- guards say this when coming to player's rescue when they're attacked unprovoked
|
||||
-- %s is replaced with the name of the npc or creature attacking the player
|
||||
["join_combat"] = {
|
||||
"Not today %s!",
|
||||
"You n'wah!",
|
||||
"Stop right there, criminal scum!"
|
||||
}
|
||||
}
|
||||
}
|
15
MWSE/mods/celediel/MoreAttentiveGuards/main.lua
Normal file
15
MWSE/mods/celediel/MoreAttentiveGuards/main.lua
Normal file
|
@ -0,0 +1,15 @@
|
|||
local sneak = require("celediel.MoreAttentiveGuards.sneak")
|
||||
local combat = require("celediel.MoreAttentiveGuards.combat")
|
||||
local common = require("celediel.MoreAttentiveGuards.common")
|
||||
|
||||
local eventPattern = "on(%u)"
|
||||
|
||||
local function onInitialized()
|
||||
-- in order for this to work, all functions in returned table must be named onEventName
|
||||
for name, func in pairs(sneak) do event.register(name:gsub(eventPattern, string.lower), func) end
|
||||
for name, func in pairs(combat) do event.register(name:gsub(eventPattern, string.lower), func) end
|
||||
common.log("%s initialized", common.modName)
|
||||
end
|
||||
|
||||
event.register("initialized", onInitialized)
|
||||
event.register("modConfigReady", function() mwse.mcm.register(require("celediel.MoreAttentiveGuards.mcm")) end)
|
109
MWSE/mods/celediel/MoreAttentiveGuards/mcm.lua
Normal file
109
MWSE/mods/celediel/MoreAttentiveGuards/mcm.lua
Normal file
|
@ -0,0 +1,109 @@
|
|||
local config = require("celediel.MoreAttentiveGuards.config").getConfig()
|
||||
local common = require("celediel.MoreAttentiveGuards.common")
|
||||
|
||||
local function createTableVar(id) return mwse.mcm.createTableVariable({id = id, table = config}) end
|
||||
|
||||
local function createLanguageOptions()
|
||||
local options = {}
|
||||
-- I guess I don't know how ipairs works
|
||||
local i = 1
|
||||
for name, _ in pairs(common.dialogues) do
|
||||
options[i] = {label = name:gsub("^%l", string.upper), value = name}
|
||||
i = i + 1 -- wtf lua
|
||||
end
|
||||
return options
|
||||
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\n\n", common.modName, common.version, common.author, common.modInfo)
|
||||
})
|
||||
|
||||
local mainCategory = page:createCategory(common.modName)
|
||||
|
||||
-- {{{ general settings
|
||||
|
||||
local generalCategory = mainCategory:createCategory("Common settings")
|
||||
|
||||
generalCategory:createDropdown({label = "Language", options = createLanguageOptions(), variable = createTableVar("language")})
|
||||
|
||||
generalCategory:createYesNoButton({
|
||||
label = "Debug mode",
|
||||
description = "Print debug messages to the log.",
|
||||
variable = createTableVar("debug")
|
||||
})
|
||||
|
||||
-- }}}
|
||||
|
||||
-- {{{ sneak settings
|
||||
|
||||
local sneakCategory = mainCategory:createCategory("Sneak Settings")
|
||||
|
||||
sneakCategory:createYesNoButton({
|
||||
label = "Enable sneak module",
|
||||
description = "Guards who catch you sneaking will follow you for a bit of time.",
|
||||
variable = createTableVar("sneakEnable")
|
||||
})
|
||||
|
||||
sneakCategory:createYesNoButton({
|
||||
label = "Sneak dialogue",
|
||||
description = "Guards sometimes say things to you when you sneak.",
|
||||
variable = createTableVar("sneakDialogue")
|
||||
})
|
||||
|
||||
sneakCategory:createSlider({
|
||||
label = "Sneak dialogue chance",
|
||||
description = "Percent chance a guard will say something each time the dialogue timer fires.",
|
||||
min = 0,
|
||||
max = 100,
|
||||
step = 1,
|
||||
jump = 5,
|
||||
variable = createTableVar("sneakDialogueChance")
|
||||
})
|
||||
|
||||
sneakCategory:createSlider({
|
||||
label = "Sneak dialogue timer",
|
||||
description = "Roll for dialogue every x seconds while following.",
|
||||
min = 0,
|
||||
max = 60,
|
||||
step = 1,
|
||||
jump = 5,
|
||||
variable = createTableVar("sneakDialogueTimer")
|
||||
})
|
||||
|
||||
-- }}}
|
||||
|
||||
-- {{{ combat settings
|
||||
|
||||
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.",
|
||||
variable = createTableVar("combatEnable")
|
||||
})
|
||||
|
||||
combatCategory:createSlider({
|
||||
label = "Guard alert range",
|
||||
description = "How far away guards are alerted to combat against the player",
|
||||
min = 1,
|
||||
max = 20000,
|
||||
step = 10,
|
||||
jump = 50,
|
||||
variable = createTableVar("combatDistance")
|
||||
})
|
||||
|
||||
combatCategory:createYesNoButton({
|
||||
label = "Enable combat dialogue",
|
||||
description = "Guards have things to say when they come to the rescue of a player who is attacked unprovoked.",
|
||||
variable = createTableVar("combatDialogue")
|
||||
})
|
||||
|
||||
-- }}}
|
||||
|
||||
return template
|
||||
|
||||
-- vim:fdm=marker
|
164
MWSE/mods/celediel/MoreAttentiveGuards/sneak.lua
Normal file
164
MWSE/mods/celediel/MoreAttentiveGuards/sneak.lua
Normal file
|
@ -0,0 +1,164 @@
|
|||
local common = require("celediel.MoreAttentiveGuards.common")
|
||||
local config = require("celediel.MoreAttentiveGuards.config").getConfig()
|
||||
local this = {}
|
||||
|
||||
-- {{{ variables and such
|
||||
-- only one guard following at a time makes sense
|
||||
-- other guards are like "oh they've got this, I don't need to help"
|
||||
local follower
|
||||
local followTimer
|
||||
local dialogueTimer
|
||||
local isFollowing = false
|
||||
local ogPosition
|
||||
-- }}}
|
||||
|
||||
-- {{{ helper functions
|
||||
|
||||
local function log(...) if config.debug then common.log(...) end end
|
||||
|
||||
local function calculateFollowTime()
|
||||
-- Modified formula from RubberMan's "Inquisitive Guards"
|
||||
-- https://www.nexusmods.com/morrowind/mods/46538
|
||||
local sneak = tes3.mobilePlayer.sneak.value and tes3.mobilePlayer.sneak.value or tes3.mobilePlayer.sneak.base
|
||||
local max = tes3.hasCodePatchFeature(110) and (sneak <= 100 and 101 or 0) or 101
|
||||
local value = (max - sneak) / 3
|
||||
-- round to nearest integer
|
||||
return math.fmod(value, 1) >= 0.5 and math.ceil(value) or math.floor(value)
|
||||
end
|
||||
|
||||
-- }}}
|
||||
|
||||
-- {{{ timer functions
|
||||
|
||||
local function startDialogue()
|
||||
if not follower then return end
|
||||
|
||||
local dialogue = table.choice(common.dialogues[config.language].sneaking)
|
||||
local roll = math.random(0, 100)
|
||||
|
||||
log("Dialogue roll = %s > %s", config.sneakDialogueChance, roll)
|
||||
if config.sneakDialogueChance > roll then
|
||||
local response = common.guardDialogue(follower, dialogue, tes3.mobilePlayer)
|
||||
log(response)
|
||||
end
|
||||
end
|
||||
|
||||
-- * NPC travels back to where they were before following player, then wanders
|
||||
-- * tries to guess how long it'll take NPC to get back to their original position
|
||||
local function stopFollowing(onTimer)
|
||||
if not follower or not isFollowing then return end
|
||||
isFollowing = false
|
||||
|
||||
local function startWander()
|
||||
log("%s has probably reached their original destination, resuming wander...", follower.object.name)
|
||||
tes3.setAIWander({reference = follower, range = 2000, reset = false, idles = common.generateIdles()})
|
||||
|
||||
follower = nil
|
||||
end
|
||||
|
||||
local function startTravel()
|
||||
-- I couldn't think of a better way to "know" when they've reach their destination
|
||||
-- so I set a timer based on the distance from the original position. It's okay-ish.
|
||||
local distance = ogPosition:distance(follower.position)
|
||||
local duration = math.ceil(distance / 95)
|
||||
|
||||
-- duration of 0 is bad for timers, so
|
||||
duration = duration > 0 and duration or 1
|
||||
|
||||
log("%s has decided that %s isn't doing anything suspicious, heading back to %s... " ..
|
||||
"(which is %s distance units away... it'll probably take %s seconds to get there)",
|
||||
follower.object.name, tes3.player.object.name, ogPosition, distance, duration)
|
||||
|
||||
-- send a dialogue to let player know guard doesn't care any more
|
||||
if onTimer then
|
||||
local response = common.guardDialogue(follower,
|
||||
table.choice(common.dialogues[config.language].stop_following),
|
||||
tes3.mobilePlayer)
|
||||
log(response)
|
||||
end
|
||||
|
||||
if dialogueTimer and dialogueTimer.state == timer.active then dialogueTimer:cancel() end
|
||||
|
||||
tes3.setAITravel({reference = follower, destination = ogPosition})
|
||||
ogPosition = nil
|
||||
|
||||
timer.start({duration = duration, iterations = 1, callback = startWander})
|
||||
end
|
||||
|
||||
timer.delayOneFrame(startTravel)
|
||||
end
|
||||
|
||||
local function startFollowing()
|
||||
if not follower or isFollowing then return end
|
||||
|
||||
local function startFollow()
|
||||
local followTime = calculateFollowTime()
|
||||
log("%s starting to follow %s for %s time units", follower.object.name, tes3.player.object.name, followTime)
|
||||
|
||||
tes3.setAIFollow({reference = follower, target = tes3.mobilePlayer})
|
||||
|
||||
followTimer = timer.start({duration = followTime, callback = stopFollowing})
|
||||
|
||||
if config.sneakDialogue then
|
||||
startDialogue()
|
||||
dialogueTimer = timer.start({
|
||||
duration = config.sneakDialogueTimer,
|
||||
iterations = -1,
|
||||
callback = startDialogue
|
||||
})
|
||||
end
|
||||
|
||||
isFollowing = true
|
||||
end
|
||||
|
||||
ogPosition = follower.position:copy()
|
||||
|
||||
timer.delayOneFrame(startFollow)
|
||||
end
|
||||
|
||||
local function abortFollow()
|
||||
local response = common.guardDialogue(follower, table.choice(common.dialogues[config.language].stop_sneaking),
|
||||
tes3.mobilePlayer)
|
||||
log(response)
|
||||
stopFollowing(false)
|
||||
end
|
||||
|
||||
-- }}}
|
||||
|
||||
-- {{{ returned event functions
|
||||
|
||||
this.onDetectSneak = function(e)
|
||||
if not config.sneakEnable then return end
|
||||
if e.target ~= tes3.mobilePlayer or not tes3.mobilePlayer.isSneaking or not e.detector.object.isGuard then return end
|
||||
|
||||
if not isFollowing then
|
||||
log("%s is checking for %s %ssuccessfully", e.detector.object and e.detector.object.name or "no one",
|
||||
e.target.object and e.target.object.name or "no one", e.isDetected and "" or "un")
|
||||
end
|
||||
|
||||
if e.isDetected and not follower and not isFollowing then
|
||||
follower = e.detector
|
||||
-- follow for a time
|
||||
startFollowing()
|
||||
-- else -- uncomment this for extreme debug messages
|
||||
-- log("Not following because detection = %s or follower = %s or isFollowing = %s", e.isDetected, follower,
|
||||
-- isFollowing)
|
||||
end
|
||||
end
|
||||
|
||||
this.onCalcMoveSpeed = function(e)
|
||||
if e.mobile ~= tes3.mobilePlayer or tes3.mobilePlayer.isSneaking then return end
|
||||
|
||||
if follower and followTimer and followTimer.state == timer.active then
|
||||
log("Player not sneaking, aborting follow")
|
||||
|
||||
followTimer:cancel()
|
||||
abortFollow()
|
||||
end
|
||||
end
|
||||
|
||||
-- }}}
|
||||
|
||||
return this
|
||||
|
||||
-- vim: fdm=marker
|
65
README.md
Normal file
65
README.md
Normal file
|
@ -0,0 +1,65 @@
|
|||
# More Attentive Guards for Morrowind #
|
||||
|
||||
## About ##
|
||||
|
||||
An MWSE-Lua mod that replicates the features of
|
||||
[Inquisitive Guards](https://www.nexusmods.com/morrowind/mods/46538) by RubberMan
|
||||
and
|
||||
[Protective Guards](http://download.fliggerty.com/download-110-20) by Fliggerty
|
||||
|
||||
* Guards that catch the player sneaking about in town will follow them for a length of time dependent on their sneak skill.
|
||||
* Guards will come to the aid of an unwanted player who is attacked unprovoked
|
||||
* MCM Menu for configuration of many options
|
||||
|
||||
### Dialogue ###
|
||||
|
||||
* Guards will say things:
|
||||
* While the player is sneaking, on a chance based timer
|
||||
* When the player stops sneaking while being followed
|
||||
* When the guard gets bored of following the player
|
||||
* When coming to the aid of an unwanted player who is attacked unprovoked
|
||||
|
||||
Open dialogues.lua to edit the dialogues. I'm no writer so they're probably bad, but the framework is there for the dialogues to be easily edited or translated.
|
||||
|
||||
To add a new language add something like this to dialogues.lua:
|
||||
|
||||
```
|
||||
["your language"] = {
|
||||
-- guards might say this every so often to players who are sneaking
|
||||
-- %s is replaced with race or class
|
||||
["sneaking"] = {
|
||||
"dialogue goes here",
|
||||
},
|
||||
-- guards say this when players stop sneaking while being followed
|
||||
-- %s is replaced with race or class
|
||||
["stop_sneaking"] = {
|
||||
"dialogue goes here",
|
||||
},
|
||||
-- guards say this when they're satisfied that the player is not doing anything illegal
|
||||
-- %s is replaced with race or class
|
||||
["stop_following"] = {
|
||||
"dialogue goes here",
|
||||
},
|
||||
-- guards say this when coming to player's rescue when they're attacked unprovoked
|
||||
-- %s is replaced with the name of the npc or creature attacking the player
|
||||
["join_combat"] = {
|
||||
"dialogue goes here",
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The MCM dropdown will automatically be populated with the configured language, and once selected, those dialogues will be used.
|
||||
|
||||
|
||||
## Requirements ##
|
||||
MWSE 2.1 nightly @ [github](https://github.com/MWSE/MWSE)
|
||||
|
||||
## Credits ##
|
||||
|
||||
* MWSE Team for MWSE with Lua support
|
||||
* Lua is way different than MWScript, but I did glance at the scripts from
|
||||
both Inquisitive Guards and Protective Guards for inspiration
|
||||
|
||||
## License ##
|
||||
|
||||
MIT License. See LICENSE file.
|
Loading…
Add table
Reference in a new issue