initial commit

This commit is contained in:
Lilian Jónsdóttir 2020-09-07 17:21:09 -07:00
commit b576864f31
5 changed files with 247 additions and 0 deletions

92
.gitignore vendored Normal file
View file

@ -0,0 +1,92 @@
# 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
*.7z
*.zip
meta.ini

View file

@ -0,0 +1,11 @@
local this = {}
-- mod info variables
this.modName = "No More Friendly Fire"
this.modConfig = this.modName:gsub("%s", "")
this.modInfo = "Stop friendly fire. Player companions can't damage the player, the player " ..
"can't damage companions, and companions can't damage each other. That's it."
this.author = "Celediel"
this.version = "1.2.1"
return this

View file

@ -0,0 +1,12 @@
local common = require("celediel.NoMoreFriendlyFire.common")
local currentConfig
local defaultConfig = {enable = true, debug = false}
local this = {}
this.getConfig = function()
currentConfig = currentConfig or mwse.loadConfig(common.modConfig, defaultConfig)
return currentConfig
end
return this

View file

@ -0,0 +1,108 @@
local common = require("celediel.NoMoreFriendlyFire.common")
local config = require("celediel.NoMoreFriendlyFire.config").getConfig()
local mag
pcall(function()
mag = require("celediel.MoreAttentiveGuards.interop")
end)
-- todo: make this not hardcoded somehow
local followMatches = {"follow", "together", "travel", "wait", "stay"}
local postDialogueTimer
local function log(...) if config.debug then mwse.log("[%s] %s", common.modName, string.format(...)) end end
-- keep track of followers
local followers = {}
local function buildFollowerList()
local friends = {}
local msg = ""
local magGuard = mag and mag.getGuardFollower() or nil
for friend in tes3.iterate(tes3.mobilePlayer.friendlyActors) do
if friend ~= magGuard then
friends[friend.object.id] = true
msg = msg .. friend.object.name .. " "
end
end
log("Friends: %s", msg)
return friends
end
-- Event functions
local eventFunctions = {}
eventFunctions.onDamage = function(e)
if not e.attackerReference then return end
if followers[e.attackerReference.object.id] and followers[e.reference.object.id] then
if config.enable then
log("%s hit %s for %s friendly damage, nullifying", e.attackerReference.object.name,
e.reference.object.name, e.damage)
e.damage = 0
return false -- I don't know if this makes a difference or not
else
log("%s hit %s for %s friendly damage", e.attackerReference.object.name, e.reference.object.name, e.damage)
end
-- uncomment this to see all damage done by everyone to everyone else
-- else
-- log("%s hit %s for %s damage", e.attackerReference.object.name, e.reference.object.name, e.damage)
end
end
eventFunctions.onCellChanged = function(e) followers = buildFollowerList() end
-- hopefully, when telling a follower to follow or wait, rebuild followers list
eventFunctions.onInfoResponse = function(e)
-- the dialogue option clicked on
local dialogue = tostring(e.dialogue):lower()
-- what that dialogue option triggers; this will catch AIFollow commands
local command = e.command:lower()
for _, item in pairs(followMatches) do
if command:match(item) or dialogue:match(item) then
log("Found %s in dialogue, rebuilding followers", item)
-- wait until game time restarts, and don't set multiple timers
if not postDialogueTimer or postDialogueTimer.state ~= timer.active then
postDialogueTimer = timer.start({
type = timer.simulate,
duration = 0.5,
iteration = 1,
callback = function()
followers = buildFollowerList()
end
})
end
end
end
end
-- rebuild followers list when player casts conjuration, in case its a summon spell
-- false positives are okay because we're not doing anything destructive
eventFunctions.onSpellCasted = function(e)
if e.caster == tes3.player and e.expGainSchool == tes3.magicSchool.conjuration then
log("Player cast conjuration spell %s, rebuilding followers list...", e.source.id)
-- wait for summon to be loaded
timer.start({
type = timer.simulate,
duration = 1,
iterations = 1,
callback = function() followers = buildFollowerList() end
})
end
end
-- Register events
local function onInitialized()
for name, func in pairs(eventFunctions) do
event.register(name:gsub("on(%u)", string.lower), func)
log("%s event registered", name)
end
mwse.log("[%s] Successfully initialized%s", common.modName, mag and " with More Attentive Guards interop" or "")
end
event.register("modConfigReady", function() mwse.mcm.register(require("celediel.NoMoreFriendlyFire.mcm")) end)
event.register("initialized", onInitialized)

View file

@ -0,0 +1,24 @@
local common = require("celediel.NoMoreFriendlyFire.common")
local config = require("celediel.NoMoreFriendlyFire.config").getConfig()
local template = mwse.mcm.createTemplate(common.modName)
template:saveOnClose(common.modConfig, config)
local page = template:createSideBarPage({
label = "Main options",
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 = "Stop friendly fire",
variable = mwse.mcm.createTableVariable({id = "enable", table = config})
})
category:createYesNoButton({
label = "Debug logging",
variable = mwse.mcm.createTableVariable({id = "debug", table = config})
})
return template