We were using this script in BtA and it was crashing missions due to attempting to target destroyed turrets. Admiral MS fixed it up for us. This doesn't remove destroyed turrets from the hotkey list, but it does prevent them from being targetted and thus crashing the game.
#Conditional Hooks
$Application: FS2_Open
$On Gameplay Start:
[
turretHotkeys = {}
turretHotkeys.key = "F9"
turretHotkeys.enabled = false
-- Subsystem indicator settings
turretHotkeys.indicator = {}
turretHotkeys.indicator.color = {
r = 255,
g = 255,
b = 255,
a = 200
}
turretHotkeys.subsystems = {}
turretHotkeys.lastIndex = {1, 0}
function turretHotkeys:keyPressed(key)
if (self:isEnabled() and key == self.key) then
local tblIndex, subsysIndex = self:getNextIndex()
if (tblIndex ~= false) then
-- This is ugly code, don't look at it or it won't work
local subsys = self.subsystems[tblIndex].ship[self.subsystems[tblIndex][subsysIndex]]
if (subsys:isValid()) then
hv.Player.Target = self.subsystems[tblIndex].ship
hv.Player.TargetSubsystem = subsys
end
self.lastIndex = { tblIndex, subsysIndex }
end
end
end
function turretHotkeys:checkIndexes(tblIndex, subsysIndex)
if (tblIndex > 0 and tblIndex <= #self.subsystems) then
if (subsysIndex > 0 and subsysIndex <= #self.subsystems[tblIndex]) then
return tblIndex, subsysIndex
else
return tblIndex, math.max(1, math.min(subsysIndex, #self.subsystems[tblIndex]))
end
else
-- If we're here it means that we've got an invalid index...
return math.max(1, math.min(tblIndex, #self.subsystems)), math.max(1, math.min(1, #self.subsystems[tblIndex]))
end
end
function turretHotkeys:getNextIndex()
local tblIndex = self.lastIndex[1]
local tbl = self.subsystems[tblIndex]
if (tbl == nil) then
if (tblIndex == 1) then
return false
else
return self:checkIndexes(1, 1)
end
end
local subsystemIndex = self.lastIndex[2] + 1
if (subsystemIndex > #tbl) then
subsystemIndex = 1
tblIndex = tblIndex + 1
tbl = self.subsystems[tblIndex]
end
if (tblIndex > #self.subsystems) then
tblIndex = 1
if (tblIndex > #self.subsystems) then
return self:checkIndexes(tblIndex, 1)
end
end
return self:checkIndexes(tblIndex, subsystemIndex)
end
function turretHotkeys:onFrame()
if (self:isEnabled()) then
self:checkShips()
if (not hu.HUDDrawn) then
self:drawSubsystems()
end
end
end
function turretHotkeys:checkShips()
local index = 1
local done = false
while (not done) do
for i = index, #self.subsystems do
if (not self.subsystems[index].ship:isValid() ) then
table.remove(self.subsystems, index)
index = i
end
end
done = true
end
end
function turretHotkeys:drawSubsystems()
local target = hv.Player.Target
local subsysName = hv.Player.TargetSubsystem:getModelName()
for i = 1, #self.subsystems do
local tbl = self.subsystems[i]
for j = 1, #tbl do
local current = tbl.ship[tbl[j]]
if current.HitpointsLeft > 0 and (tbl.ship ~= target or current:getModelName() ~= subsysName) then
self:drawSubsystem(current)
end
end
end
end
function turretHotkeys:drawSubsystem(subsys)
local indicator = self.indicator
gr.setColor(indicator.color.r, indicator.color.g, indicator.color.b, indicator.color.a)
gr.drawSubsystemTargetingBrackets(subsys)
end
function turretHotkeys:addShip(ship)
table.insert(self.subsystems, {
name = ship.Name,
ship = ship
})
end
function turretHotkeys:isValidIndex(index)
return self.subsystems[index] ~= nil and self.subsystems[index].ship:isValid()
end
function turretHotkeys:addSubsystem(index, name)
local tbl = self.subsystems[index]
if (not tbl.ship[name]:isValid()) then
ba.warning(string.format("Unknown subsystem %q on ship %q of class %q.", name, tbl.ship.name, tbl.ship.class))
return false
end
table.insert(tbl, name)
return true
end
function turretHotkeys:removeSubsystem(index, name)
local tbl = self.subsystems[index]
local newIndex = 1
local done = false
while (not done) do
for i = newIndex, #turretHotkeys.subsystemNames do
if (turretHotkeys.subsystemNames[i] == name) then
table.remove(turretHotkeys.subsystemNames, i)
newIndex = i
break
end
end
done = true
end
end
function turretHotkeys:isEnabled()
return self.enabled and hv.Player:getBreedName() == "Ship"
end
function thkEnable(bool)
if (bool == nil) then
bool = true
end
if (type(bool) ~= "boolean") then
ba.warning("Invalid argument type for thkKey. Need a boolean or no argument, got " .. type(bool) .. ".")
return
end
turretHotkeys.enabled = bool
end
function thkKey(key)
if (type(key) ~= "string") then
ba.warning("Invalid argument type for thkKey. Need a string, got " .. type(key) .. ".")
return
end
turretHotkeys.key = key
end
function thkShip(...)
local names = { ... }
for i = 1, #names do
if (type(names[i]) ~= "string") then
ba.warning("Invalid argument type for thkShip. Need a string, got " .. type(names[i]) .. ".")
return
end
local ship = mn.Ships[names[i]]
if (not ship:isValid()) then
ba.warning("No ship with name \"" .. names[i] .. "\" could be found in the current mission.")
return
end
turretHotkeys:addShip(ship)
end
end
function thkAdd(index, name)
if (type(index) ~= "number") then
ba.warning("Invalid first argument type for thkAdd. Need a string, got " .. type(index) .. ".")
return
end
if (type(name) ~= "string") then
ba.warning("Invalid second argument type for thkAdd. Need a string, got " .. type(name) .. ".")
return
end
if (not turretHotkeys:isValidIndex(index)) then
ba.warning("Invalid ship index \"" .. tostring(index) .. "\"!")
return
end
turretHotkeys:addSubsystem(index, name)
end
function thkRemove(index, name)
if (type(index) ~= "number") then
ba.warning("Invalid first argument type for thkRemove. Need a string, got " .. type(index) .. ".")
return
end
if (type(name) ~= "string") then
ba.warning("Invalid second argument type for thkRemove. Need a string, got " .. type(name) .. ".")
return
end
if (not turretHotkeys:isValidIndex(index)) then
ba.warning("Invalid ship index \"" .. tostring(index) .. "\"!")
return
end
turretHotkeys:removeSubsystem(index, name)
end
function thkClear()
turretHotkeys.subsystems = {}
end
]
$State: GS_STATE_GAME_PLAY
$On Key Pressed:
[
turretHotkeys:keyPressed(hv.Key)
]
$State: GS_STATE_GAME_PLAY
$On Frame:
[
turretHotkeys:onFrame()
]
#End