Author Topic: Highlight or hotkey individual turret  (Read 17251 times)

0 Members and 1 Guest are viewing this topic.

Offline General Battuta

  • Poe's Law In Action
  • 214
  • i wonder when my postcount will exceed my iq
Re: Highlight or hotkey individual turret
Hey, should I do

script-eval thkShip (Deianira)
script-eval thkShip (Iolanthe)

or script-eval thkShip (Deianira, Iolanthe)

 

Offline General Battuta

  • Poe's Law In Action
  • 214
  • i wonder when my postcount will exceed my iq
Re: Highlight or hotkey individual turret
The latter seems to work!

 

Offline m!m

  • 211
Re: Highlight or hotkey individual turret
Both version do the exact same thing to make it possible to add more ships than the character limit in SEXPs allows.

 

Offline m!m

  • 211
Re: Highlight or hotkey individual turret
Minor update to use the newly added drawSubsystemTargetingBrackets to indicate a hotkey-accessible subsystem. This needs a recent trunk build to work.
Code: [Select]
#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 = fale

    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 (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


 

Offline mjn.mixael

  • Cutscene Master
  • 212
  • Chopped liver
    • Steam
    • Twitter
Re: Highlight or hotkey individual turret
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.

Code: [Select]
#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
Cutscene Upgrade Project - Mainhall Remakes - Between the Ashes
Youtube Channel - P3D Model Box
Between the Ashes is looking for committed testers, PM me for details.
Freespace Upgrade Project See what's happening.

 

Offline Black Wolf

  • Twisted Infinities
  • 212
  • Hey! You! Get off-a my cloud!
    • Visit the TI homepage!
Re: Highlight or hotkey individual turret
Alright then, here you go:
Code: [Select]
#Conditional Hooks

$Application: FS2_Open
$On Gameplay Start:
[
turretHotkeys = {}
turretHotkeys.key = "F9"
turretHotkeys.enabled = false

-- Subsystem indicator settings
turretHotkeys.indicator = {}
turretHotkeys.indicator.width = 20
turretHotkeys.indicator.height = 20
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()

        -- self:drawSubsystems()
    end
end

function turretHotkeys:checkShips()
    local index = 1
    local done = fale

    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 (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

There are a few modifications to the way the script works now.
First you have to call thkEnable() when you want to enable the script. You can disable it again with thkEnable(false).
To specify the ships you can call thkShip(<...>) with the ship names you want to have subsystems on. Every function call adds the specified ships to the list of ships.
To specify a subsystem you still use thkAdd but you will have to specify which ship to use as the fist argument which should be the number of the ship. That means if you cann thkShip('Ship A', 'Ship B', 'Ship C'), thkAdd(2, 'turret-42') will mark that subsystem on Ship B as being able to be selected using the hotkey.

:bump:

Hey, can someone who's made use of this sexp give me the exact syntax and mission setup I need to use to make it put brackets around a specific turret?

I have 4 chained script-evals associated with the proper event sequence, with this written in them:

thkEnable()
thkShip('PVI Aswan')
thkAdd(1, 'Turret13') (I've also tried just plain thkAdd('Turret13') with no success)
thkEnable(false)

Ship names are right, subsystem name is right, and I copied mjn's latest version of the script directly into turretHotkey-sct.tbm. Really not sure what's wrong, so I'm hoping it's a syntax issue that I've missed somewhere. Any suggestions?
TWISTED INFINITIES · SECTORGAME· FRONTLINES
Rarely Updated P3D.
Burn the heretic who killed F2S! Burn him, burn him!!- GalEmp

 

Offline m!m

  • 211
Re: Highlight or hotkey individual turret
thkEnable(false) disables all rendering of the brackets so if you execute that directly after thkAdd you will not see the brackets as they aren't rendered at all. So you could try removing thkEnable(false) and see if that changes it.

 

Offline Black Wolf

  • Twisted Infinities
  • 212
  • Hey! You! Get off-a my cloud!
    • Visit the TI homepage!
Re: Highlight or hotkey individual turret
thkEnable(false) disables all rendering of the brackets so if you execute that directly after thkAdd you will not see the brackets as they aren't rendered at all. So you could try removing thkEnable(false) and see if that changes it.

That only fires once the turret has been destroyed, due to the conditions of the chain, but I'll try it.
TWISTED INFINITIES · SECTORGAME· FRONTLINES
Rarely Updated P3D.
Burn the heretic who killed F2S! Burn him, burn him!!- GalEmp

 

Offline m!m

  • 211
Re: Highlight or hotkey individual turret
If it doesn't fire immediately then it should work but that was my best guess, maybe mjn.mixael can help you with this...

 

Offline mjn.mixael

  • Cutscene Master
  • 212
  • Chopped liver
    • Steam
    • Twitter
Re: Highlight or hotkey individual turret
Here's how we did it.

Cutscene Upgrade Project - Mainhall Remakes - Between the Ashes
Youtube Channel - P3D Model Box
Between the Ashes is looking for committed testers, PM me for details.
Freespace Upgrade Project See what's happening.

 

Offline Black Wolf

  • Twisted Infinities
  • 212
  • Hey! You! Get off-a my cloud!
    • Visit the TI homepage!
Re: Highlight or hotkey individual turret
http://imagebin.org/289952

As far as I can tell, mine is identical, so I'm not sure what's going on. It does assign the F9 hotkey to the appropriate Turret, which is something, but I understood it would draw brackets around it as well, even when the hotkey isn't pressed, to aid identification?
« Last Edit: January 30, 2014, 09:22:44 am by Black Wolf »
TWISTED INFINITIES · SECTORGAME· FRONTLINES
Rarely Updated P3D.
Burn the heretic who killed F2S! Burn him, burn him!!- GalEmp

 

Offline mjn.mixael

  • Cutscene Master
  • 212
  • Chopped liver
    • Steam
    • Twitter
Re: Highlight or hotkey individual turret
Oh, I don't think it does the latter. I use this script for that on ships, though I don't think it will work on subsystems.
Cutscene Upgrade Project - Mainhall Remakes - Between the Ashes
Youtube Channel - P3D Model Box
Between the Ashes is looking for committed testers, PM me for details.
Freespace Upgrade Project See what's happening.

 

Offline mjn.mixael

  • Cutscene Master
  • 212
  • Chopped liver
    • Steam
    • Twitter
Re: Highlight or hotkey individual turret
:necro:

So BtA is using this version of the script and I just noticed that I now crashes FSO.

Code: [Select]
#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

I'll post a test mission soon.. but halp!

Scratch that.. It's apparently somehow mission specific. BLAH.
« Last Edit: September 26, 2014, 05:54:07 pm by mjn.mixael »
Cutscene Upgrade Project - Mainhall Remakes - Between the Ashes
Youtube Channel - P3D Model Box
Between the Ashes is looking for committed testers, PM me for details.
Freespace Upgrade Project See what's happening.

 

Offline mjn.mixael

  • Cutscene Master
  • 212
  • Chopped liver
    • Steam
    • Twitter
Re: Highlight or hotkey individual turret
Figured it out and posting it here so that it's documented and might be fixed. The crash is somehow caused by additional turret data added by FRED.

I was trying to hotkey missile launchers which would be listed like so.

Code: [Select]
+Subsystem: turret01
+Subsystem: turret02
+Subsystem: turret03

But if FRED decides for some reason (haven't figured out why yet) to add Ammo amount.. bam crash.
Code: [Select]
+Subsystem: turret01
+Sbank Ammo: ( 0 )
+Subsystem: turret02
+Sbank Ammo: ( 0 )
+Subsystem: turret03
+Sbank Ammo: ( 0 )

Note that the latter is perfectly acceptable for FRED and FSO, but it definitely caused the crash somehow.
Cutscene Upgrade Project - Mainhall Remakes - Between the Ashes
Youtube Channel - P3D Model Box
Between the Ashes is looking for committed testers, PM me for details.
Freespace Upgrade Project See what's happening.

 

Offline AdmiralRalwood

  • 211
  • The Cthulhu programmer himself!
    • Skype
    • Steam
    • Twitter
Re: Highlight or hotkey individual turret
I was unable to reproduce the crash, but I did find that there was a logic error preventing the brackets from being drawn and thkRemove() wouldn't work.

Code: [Select]
#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 (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, #tbl do
            if (tbl[i] == name) then
                table.remove(tbl, 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
Ph'nglui mglw'nafh Codethulhu GitHub wgah'nagl fhtagn.

schrödinbug (noun) - a bug that manifests itself in running software after a programmer notices that the code should never have worked in the first place.

When you gaze long into BMPMAN, BMPMAN also gazes into you.

"I am one of the best FREDders on Earth" -General Battuta

<Aesaar> literary criticism is vladimir putin

<MageKing17> "There's probably a reason the code is the way it is" is a very dangerous line of thought. :P
<MageKing17> Because the "reason" often turns out to be "nobody noticed it was wrong".
(the very next day)
<MageKing17> this ****ing code did it to me again
<MageKing17> "That doesn't really make sense to me, but I'll assume it was being done for a reason."
<MageKing17> **** ME
<MageKing17> THE REASON IS PEOPLE ARE STUPID
<MageKing17> ESPECIALLY ME

<MageKing17> God damn, I do not understand how this is breaking.
<MageKing17> Everything points to "this should work fine", and yet it's clearly not working.
<MjnMixael> 2 hours later... "God damn, how did this ever work at all?!"
(...)
<MageKing17> so
<MageKing17> more than two hours
<MageKing17> but once again we have reached the inevitable conclusion
<MageKing17> How did this code ever work in the first place!?

<@The_E> Welcome to OpenGL, where standards compliance is optional, and error reporting inconsistent

<MageKing17> It was all working perfectly until I actually tried it on an actual mission.

<IronWorks> I am useful for FSO stuff again. This is a red-letter day!
* z64555 erases "Thursday" and rewrites it in red ink

<MageKing17> TIL the entire homing code is held up by shoestrings and duct tape, basically.

  

Offline Rheyah

  • 28
  • Will release something one day. Promise.
Re: Highlight or hotkey individual turret
I needed the brackets thing fixing.  Thanks, Admiral!

 

Offline Lepanto

  • 210
  • Believes in Truth
    • Skype
Re: Highlight or hotkey individual turret
Found a weird bug (oh, joy, I know.) Using AdmiralRalwood's version of the script.

When I add a ship(s) and their turrets to the list, then have any of those ships depart, then have new ships jump in and add THEIR turrets, it throws an error or CTDs. Even if I use thkClear to clear the script before tagging the new ships and turrets.

When playing one of these missions in debug mode, it gave me a couple lua errors when one of the thkAdded ships jumped out. Then, when the other thkAdded ships jumped in, I tried to F9-target their turrets and got a CTD. When I F9-target the new ships just after they jump in, anyway; one time, I waited a little while after they jumped in, and F9 worked just fine despite having thrown the same lua errors earlier.

What's up? How do I prevent ships jumping out from screwing the script up?

Lua errors when the thkAdded ship jumped out:
Code: [Select]
Assert: model_instance_num < (int)Polygon_model_instances.size()
File: modelread.cpp
Line: 2990

fs2_open_3_7_2_RC5-DEBUG.exe! @ILT+83290(__RTC_CheckEsp)
fs2_open_3_7_2_RC5-DEBUG.exe! WinAssert + 194 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! model_get_instance + 106 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! find_submodel_instance_point + 144 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! find_submodel_instance_world_point + 47 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! get_subsystem_pos + 162 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! get_subsystem_world_pos + 47 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! draw_subsys_brackets + 205 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! l_Graphics_drawSubsystemTargetingBrackets_f + 238 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! luaD_precall + 785 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! luaV_execute + 5766 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! luaD_call + 161 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! f_call + 58 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! luaD_rawrunprotected + 86 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! luaD_pcall + 100 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! lua_pcall + 134 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! script_state::RunBytecodeSub + 317 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! script_state::RunBytecode + 66 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! ConditionedHook::Run + 169 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! script_state::RunCondition + 167 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! gr_flip + 80 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! gr_opengl_cleanup + 90 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! gr_close + 84 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! doexit + 266 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! exit + 18 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! LuaError + 928 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! script_state::EvalString + 665 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! sexp_script_eval + 643 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! eval_sexp + 11523 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! eval_when_do_one_exp + 417 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! eval_when + 792 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! eval_sexp + 3659 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! mission_process_event + 547 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! mission_eval_goals + 517 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! game_simulation_frame + 1153 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! game_frame + 497 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! game_do_frame + 239 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! game_do_state + 379 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! gameseq_process_events + 237 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! game_main + 782 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! WinMain + 330 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! __tmainCRTStartup + 358 bytes
fs2_open_3_7_2_RC5-DEBUG.exe! WinMainCRTStartup + 15 bytes
KERNEL32.DLL! BaseThreadInitThunk + 36 bytes
ntdll.dll! RtlInitializeExceptionChain + 143 bytes
ntdll.dll! RtlInitializeExceptionChain + 90 bytes

Code: [Select]
---------------------------
Error!
---------------------------
LUA ERROR: [string "turretHotkey-sct.tbm - On Gameplay Start"]:97: attempt to index field '?' (a nil value)



------------------------------------------------------------------
ADE Debug:

------------------------------------------------------------------
Name: checkShips

Name of: method

Function type: Lua

Defined on: 91

Upvalues: 0



Source: turretHotkey-sct.tbm - On Gameplay Start

Short source: [string "turretHotkey-sct.tbm - On Gameplay Start"]

Current line: 98

- Function line: 8

------------------------------------------------------------------




------------------------------------------------------------------


stack traceback:
[C]: ?
[string "turretHotkey-sct.tbm - On Gameplay Start"]:97: in function 'checkShips'
[string "turretHotkey-sct.tbm - On Gameplay Start"]:83: in function 'onFrame'
[string "turretHotkey-sct.tbm - On Frame"]:1: in main chunk

------------------------------------------------------------------


------------------------------------------------------------------


[ This info is in the clipboard so you can paste it somewhere now ]





Use Yes to break into Debugger, No to continue.

and Cancel to Quit
---------------------------
Yes   No   Cancel   
---------------------------

Debug log for the CTD in attachment.

Also, whenever I replay a mission with the turret script in it, it throws the following error.
Code: [Select]
LUA ERROR: [string "?"]:1: '=' expected near '<eof>'

------------------------------------------------------------------
ADE Debug:
------------------------------------------------------------------
Name: (null)
Name of: (null)
Function type: (null)
Defined on: 0
Upvalues: 0

Source: (null)
Short source:
Current line: 0
- Function line: 0
------------------------------------------------------------------


------------------------------------------------------------------

stack traceback:
------------------------------------------------------------------

------------------------------------------------------------------

[attachment deleted by nobody]
"We have now reached the point where every goon with a grievance, every bitter bigot, merely has to place the prefix, 'I know this is not politically correct, but...' in front of the usual string of insults in order to be not just safe from criticism, but actually a card, a lad, even a hero. Conversely, to talk about poverty and inequality, to draw attention to the reality that discrimination and injustice are still facts of life, is to commit the sin of political correctness. Anti-PC has become the latest cover for creeps. It is a godsend for every curmudgeon and crank, from fascists to the merely smug."
Finian O'Toole, The Irish Times, 5 May 1994

Blue Planet: The Battle Captains: Missions starring the Admirals of BP: WiH
Frontlines 2334+2335: T-V War campaign
GVB Ammit: Vasudan strike bomber
Player-Controlled Capship Modding Tutorial

 

Offline AdmiralRalwood

  • 211
  • The Cthulhu programmer himself!
    • Skype
    • Steam
    • Twitter
Re: Highlight or hotkey individual turret
Found a weird bug (oh, joy, I know.) Using AdmiralRalwood's version of the script.

When I add a ship(s) and their turrets to the list, then have any of those ships depart, then have new ships jump in and add THEIR turrets, it throws an error or CTDs. Even if I use thkClear to clear the script before tagging the new ships and turrets.

When playing one of these missions in debug mode, it gave me a couple lua errors when one of the thkAdded ships jumped out. Then, when the other thkAdded ships jumped in, I tried to F9-target their turrets and got a CTD. When I F9-target the new ships just after they jump in, anyway; one time, I waited a little while after they jumped in, and F9 worked just fine despite having thrown the same lua errors earlier.

What's up? How do I prevent ships jumping out from screwing the script up?
You should remove a ship before it jumps out. As for other problems, I'm going to need to see the exact SEXPs you're using.

...Actually, I just saw a couple logic errors with bits of the script I didn't modify last time (including in the function that's supposed to make sure the ships are still valid), so maybe give it a shot with this version:

Code: [Select]
#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 (hu.HUDDrawn) then
            self:drawSubsystems()
        end
    end
end

function turretHotkeys:checkShips()
    local index = 1
    local done = false

    while (not done) do
        done = true
        for i = index, #self.subsystems do
            if (i ~= #self.subsystems) do
                done = false
            end
            if (not self.subsystems[i].ship:isValid() ) then
                table.remove(self.subsystems, i)
                index = i
                break
            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]
        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) do
                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
Ph'nglui mglw'nafh Codethulhu GitHub wgah'nagl fhtagn.

schrödinbug (noun) - a bug that manifests itself in running software after a programmer notices that the code should never have worked in the first place.

When you gaze long into BMPMAN, BMPMAN also gazes into you.

"I am one of the best FREDders on Earth" -General Battuta

<Aesaar> literary criticism is vladimir putin

<MageKing17> "There's probably a reason the code is the way it is" is a very dangerous line of thought. :P
<MageKing17> Because the "reason" often turns out to be "nobody noticed it was wrong".
(the very next day)
<MageKing17> this ****ing code did it to me again
<MageKing17> "That doesn't really make sense to me, but I'll assume it was being done for a reason."
<MageKing17> **** ME
<MageKing17> THE REASON IS PEOPLE ARE STUPID
<MageKing17> ESPECIALLY ME

<MageKing17> God damn, I do not understand how this is breaking.
<MageKing17> Everything points to "this should work fine", and yet it's clearly not working.
<MjnMixael> 2 hours later... "God damn, how did this ever work at all?!"
(...)
<MageKing17> so
<MageKing17> more than two hours
<MageKing17> but once again we have reached the inevitable conclusion
<MageKing17> How did this code ever work in the first place!?

<@The_E> Welcome to OpenGL, where standards compliance is optional, and error reporting inconsistent

<MageKing17> It was all working perfectly until I actually tried it on an actual mission.

<IronWorks> I am useful for FSO stuff again. This is a red-letter day!
* z64555 erases "Thursday" and rewrites it in red ink

<MageKing17> TIL the entire homing code is held up by shoestrings and duct tape, basically.

 

Offline Lepanto

  • 210
  • Believes in Truth
    • Skype
Re: Highlight or hotkey individual turret
Thanks a lot; this is rather important for Inferno.

But still ran into this error when starting FSO with the new version:
Code: [Select]
LUA ERROR: [string "turretHotkey-sct.tbm - On Gameplay Start"]:98: 'then' expected near 'do'

------------------------------------------------------------------
ADE Debug:
------------------------------------------------------------------
Name: (null)
Name of: (null)
Function type: (null)
Defined on: 0
Upvalues: 0

Source: (null)
Short source:
Current line: 0
- Function line: 0
------------------------------------------------------------------


------------------------------------------------------------------

stack traceback:
------------------------------------------------------------------

------------------------------------------------------------------
"We have now reached the point where every goon with a grievance, every bitter bigot, merely has to place the prefix, 'I know this is not politically correct, but...' in front of the usual string of insults in order to be not just safe from criticism, but actually a card, a lad, even a hero. Conversely, to talk about poverty and inequality, to draw attention to the reality that discrimination and injustice are still facts of life, is to commit the sin of political correctness. Anti-PC has become the latest cover for creeps. It is a godsend for every curmudgeon and crank, from fascists to the merely smug."
Finian O'Toole, The Irish Times, 5 May 1994

Blue Planet: The Battle Captains: Missions starring the Admirals of BP: WiH
Frontlines 2334+2335: T-V War campaign
GVB Ammit: Vasudan strike bomber
Player-Controlled Capship Modding Tutorial

 

Offline AdmiralRalwood

  • 211
  • The Cthulhu programmer himself!
    • Skype
    • Steam
    • Twitter
Re: Highlight or hotkey individual turret
Thanks a lot; this is rather important for Inferno.

But still ran into this error when starting FSO with the new version:
Code: [Select]
LUA ERROR: [string "turretHotkey-sct.tbm - On Gameplay Start"]:98: 'then' expected near 'do'
Whoops; accidentally used "do" instead of "then" for an if statement (I'm not a Lua coder, but I play one on HLP...).

Code: [Select]
#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 (hu.HUDDrawn) then
            self:drawSubsystems()
        end
    end
end

function turretHotkeys:checkShips()
    local index = 1
    local done = false

    while (not done) do
        done = true
        for i = index, #self.subsystems do
            if (i ~= #self.subsystems) then
                done = false
            end
            if (not self.subsystems[i].ship:isValid() ) then
                table.remove(self.subsystems, i)
                index = i
                break
            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]
        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) do
                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
Ph'nglui mglw'nafh Codethulhu GitHub wgah'nagl fhtagn.

schrödinbug (noun) - a bug that manifests itself in running software after a programmer notices that the code should never have worked in the first place.

When you gaze long into BMPMAN, BMPMAN also gazes into you.

"I am one of the best FREDders on Earth" -General Battuta

<Aesaar> literary criticism is vladimir putin

<MageKing17> "There's probably a reason the code is the way it is" is a very dangerous line of thought. :P
<MageKing17> Because the "reason" often turns out to be "nobody noticed it was wrong".
(the very next day)
<MageKing17> this ****ing code did it to me again
<MageKing17> "That doesn't really make sense to me, but I'll assume it was being done for a reason."
<MageKing17> **** ME
<MageKing17> THE REASON IS PEOPLE ARE STUPID
<MageKing17> ESPECIALLY ME

<MageKing17> God damn, I do not understand how this is breaking.
<MageKing17> Everything points to "this should work fine", and yet it's clearly not working.
<MjnMixael> 2 hours later... "God damn, how did this ever work at all?!"
(...)
<MageKing17> so
<MageKing17> more than two hours
<MageKing17> but once again we have reached the inevitable conclusion
<MageKing17> How did this code ever work in the first place!?

<@The_E> Welcome to OpenGL, where standards compliance is optional, and error reporting inconsistent

<MageKing17> It was all working perfectly until I actually tried it on an actual mission.

<IronWorks> I am useful for FSO stuff again. This is a red-letter day!
* z64555 erases "Thursday" and rewrites it in red ink

<MageKing17> TIL the entire homing code is held up by shoestrings and duct tape, basically.