initial commit
This commit is contained in:
commit
b576864f31
92
.gitignore
vendored
Normal file
92
.gitignore
vendored
Normal 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
|
11
MWSE/mods/celediel/NoMoreFriendlyFire/common.lua
Normal file
11
MWSE/mods/celediel/NoMoreFriendlyFire/common.lua
Normal 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
|
12
MWSE/mods/celediel/NoMoreFriendlyFire/config.lua
Normal file
12
MWSE/mods/celediel/NoMoreFriendlyFire/config.lua
Normal 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
|
108
MWSE/mods/celediel/NoMoreFriendlyFire/main.lua
Normal file
108
MWSE/mods/celediel/NoMoreFriendlyFire/main.lua
Normal 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)
|
24
MWSE/mods/celediel/NoMoreFriendlyFire/mcm.lua
Normal file
24
MWSE/mods/celediel/NoMoreFriendlyFire/mcm.lua
Normal 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
|
Loading…
Reference in a new issue