Happy, uh, 2nd of July?
I was working with Battuta to fix up the bugs with the turret hotkey script and figured I should post it here, too, so here you go:
#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 done = false
        local startindex = nil
        local startsubsys = nil
        while (not done) do
            local tblIndex, subsysIndex = self:getNextIndex()
            if (startindex == nil) then
                startindex = tblIndex
                startsubsys = subsysIndex
            else
                if (startindex == tblIndex and startsubsys == subsysIndex) then
                    done = true
                    break
                end
            end
            if (tblIndex ~= false) then
                -- This is ugly code, don't look at it or it won't work
                local tbl = self.subsystems[tblIndex]
                if (tbl ~= nil and tbl[subsysIndex] ~= nil) then
                    local subsys = tbl.ship[tbl[subsysIndex]]
                    if (subsys:isValid() and subsys.HitpointsLeft > 0) then
                        hv.Player.Target = self.subsystems[tblIndex].ship
                        hv.Player.TargetSubsystem = subsys
                        done = true
                    end
                    self.lastIndex = { tblIndex, subsysIndex }
                end
            else
                done = true
            end
        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 (hu.HUDDrawn) then
            self:drawSubsystems()
        end
    end
end
function turretHotkeys:checkShips()
    local i = 1
    while (i <= #self.subsystems) do
        if (self.subsystems[i].ship:isValid() and self.subsystems[i].ship.HitpointsLeft > 0 and self.subsystems[i].ship:getBreedName() == "Ship") then
            i = i + 1
        else
            table.remove(self.subsystems, i)
        end
    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
        done = true
        for i = newIndex, #tbl do
            if (i ~= #tbl) then
                done = false
            end
            if (tbl[i] == name) then
                table.remove(tbl, i)
                newIndex = i
                break
            end
        end
    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
No real new features, but plenty of bugfixes, and the hotkey will now skip over destroyed subsystems, plus destroyed/departed ships be automatically pruned.
EDIT: Updated again; pruned ships are now marked as inactive but left in the table, so indices won't rearrange themselves mid-mission without thkClear() getting called. In addition, thkAdd() and thkRemove() now accept a ship name for an index so you don't actually have to keep track of what order ships were added to the script (helpful if a ship is only added conditionally). Use script-eval-block to execute longer pieces of Lua from SEXPs.
#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 done = false
        local startindex = nil
        local startsubsys = nil
        while (not done) do
            local tblIndex, subsysIndex = self:getNextIndex()
            if (startindex == nil) then
                startindex = tblIndex
                startsubsys = subsysIndex
            else
                if (startindex == tblIndex and startsubsys == subsysIndex) then
                    done = true
                    break
                end
            end
            if (tblIndex ~= false) then
                -- This is ugly code, don't look at it or it won't work
                local tbl = self.subsystems[tblIndex]
                if (tbl ~= nil and tbl.active and tbl[subsysIndex] ~= nil) then
                    local subsys = tbl.ship[tbl[subsysIndex]]
                    if (subsys:isValid() and subsys.HitpointsLeft > 0) then
                        hv.Player.Target = self.subsystems[tblIndex].ship
                        hv.Player.TargetSubsystem = subsys
                        done = true
                    end
                end
                self.lastIndex = { tblIndex, subsysIndex }
            else
                done = true
            end
        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 (hu.HUDDrawn) then
            self:drawSubsystems()
        end
    end
end
function turretHotkeys:checkShips()
    for i = 1, #self.subsystems do
    	if (self.subsystems[i].active) then
	        if (not (self.subsystems[i].ship:isValid() and self.subsystems[i].ship.HitpointsLeft > 0 and self.subsystems[i].ship:getBreedName() == "Ship")) then
           		self.subsystems[i].active = false
    	    end
    	end
    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]
        if (tbl.active) then
	        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
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,
        active = true
    })
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
        done = true
        for i = newIndex, #tbl do
            if (i ~= #tbl) then
                done = false
            end
            if (tbl[i] == name) then
                table.remove(tbl, i)
                newIndex = i
                break
            end
        end
    end
end
function turretHotkeys:isEnabled()
    return self.enabled and hv.Player:getBreedName() == "Ship"
end
function turretHotkeys:findIndex(name)
	for i = 1, #self.subsystems do
		if (self.subsystems[i].name == name) then
			return i
		end
	end
	return nil
end
function thkEnable(bool)
    if (bool == nil) then
        bool = true
    end
    if (type(bool) ~= "boolean") then
        ba.warning("Invalid argument type for thkEnable. 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
    	if (type(index) == "string") then
    		local temp = turretHotkeys:findIndex(index)
    		if (index == nil) then
    			ba.warning("Ship name \"" .. index .. "\" not found in list of registered ship names.")
    			return
    		end
    		index = temp
    	else
	        ba.warning("Invalid first argument (index) type for thkAdd. Need a number or string, got " .. type(index) .. ".")
    	    return
    	end
    end
    if (type(name) ~= "string") then
        ba.warning("Invalid second argument (subsys name) 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
    	if (type(index) == "string") then
    		local temp = turretHotkeys:findIndex(index)
    		if (temp == nil) then
    			ba.warning("Ship name \"" .. index .. "\" not found in list of registered ship names.")
    			return
    		end
    		index = temp
    	else
	        ba.warning("Invalid first argument (index) type for thkRemove. Need a number or string, got " .. type(index) .. ".")
    	    return
    	end
    end
    if (type(name) ~= "string") then
        ba.warning("Invalid second argument (subsys name) 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
EDIT2: Couple more bugfixes in the previous version of the script.