Author Topic: attempting some UI modding  (Read 289 times)

adeilt

  • Newbie
  • *
  • Status:
    Offline
    Posts:
    10
    • View Profile
on: July 22, 2019, 04:01:34 PM
I've got a couple of ideas for workshop mods, but I'm having trouble finding any traction on them.  I'm new to Lua although I've had a reasonable amount of experience with Python and Javascript.

First, I want to modify the mining system arrows so that they're more visually distinguishable from other arrows.  However, every time I try to override the onPreRenderHud function it breaks the Mining System upgrade modules entirely (i.e. they don't function and their tooltips are empty).

I copied the entire method, added a couple of `local`s to make adjustments easier, and changed exactly one line in the function:

Code: [Select]
local arrowLength = 10  // default is 30
local arrowWidth = 30   // default is 10

local oldOnPreRenderHud = onPreRenderHud

function onPreRenderHud()
  -- omitted lines were copied verbatim from the original

  -- this next line is the only change I made
        renderer:renderEntityArrow(tuple.asteroid, arrowLength, arrowWidth, 250, tuple.material.color);

  -- omitted lines were copied verbatim from the original
end

Can anyone tell me what I'm doing wrong?  Is there a cleaner way to override or wrap the function so that I don't have to copy most of it verbatim?  I saw docssy's mod that made similar edits to the miningsystem.lua script, but his method required replacement of the entire file. https://www.avorion.net/forum/index.php/topic,5605.msg30327.html

My other idea is to move the pickup notifications elsewhere on screen.  When I'm in build mode, the stats of the ship I'm currently building are frequently covered up by pickups made by other ships in our alliance fleet.  Turrets are particularly irritating to edit because when I add a turret to a ship, the "removed that turret from your inventory" message covers up the section of the stats relating to turret slots.

That one has given me more trouble; I suspect that the location of those notifications is not modifiable via Lua scripts.  Am I wrong?  If so, can anyone point me to where such a thing might be accomplished?

adeilt



adeilt

  • Newbie
  • *
  • Status:
    Offline
    Posts:
    10
    • View Profile
on: July 23, 2019, 04:33:45 AM
I've done some more poking at this, and it looks like I might be overriding the entire miningsystem.lua file (which is not what I want to do).  Perhaps I need to hook into the loot drop somewhere and modify the object after it's instantiated?



adeilt

  • Newbie
  • *
  • Status:
    Offline
    Posts:
    10
    • View Profile
on: July 23, 2019, 04:53:33 AM
I've found:

https://avorion.gamepedia.com/Writing_your_own_Mod#Modifying_Modules_and_Libraries

Looks like I'll probably be more successful after I read that.



adeilt

  • Newbie
  • *
  • Status:
    Offline
    Posts:
    10
    • View Profile
on: July 23, 2019, 05:13:26 AM
Yup.  Definitely doing it all wrong.  :)

I think I've got it now.



adeilt

  • Newbie
  • *
  • Status:
    Offline
    Posts:
    10
    • View Profile
on: July 23, 2019, 07:07:18 AM
So this is the current attempt (still as a miningsystem.lua mod):

Code: [Select]
local vanilla_UIRenderer = UIRenderer
function UIRenderer()
    local renderer = vanilla_UIRenderer()
    renderer.original_RenderEntityArrow = renderer.renderEntityArrow
    renderer.renderEntityArrow = function(self, asteroid, width, length, visibility_threshold, color)
        width = 5  -- default is 10
        length = 60  -- default is 30
        renderer.original_RenderEntityArrow(self, asteroid, width, length, visibility_threshold, color)
    end
end

Still doesn't work, and I'm out of time for tonight.  I'll try again tomorrow.



adeilt

  • Newbie
  • *
  • Status:
    Offline
    Posts:
    10
    • View Profile
on: July 24, 2019, 06:31:27 AM
Code: [Select]
if type(UIRenderer) == 'table' then
    print("BEFORE")
    print(type(UIRenderer.new))
    printTable(UIRenderer)
    local vanilla_UIRenderer = UIRenderer

    UIRenderer.new = function()
        local renderer = vanilla_UIRenderer()
        vanilla_RenderEntityArrow = renderer.renderEntityArrow
        renderer.renderEntityArrow = function(self, asteroid, width, length, visibility_threshold, color)
            width = 5  -- default is 10
            length = 60  -- default is 30
            vanilla_RenderEntityArrow(self, asteroid, width, length, visibility_threshold, color)
        end
        print("ARROW")
        print(type(renderer.renderEntityArrow))
        printTable(renderer)
       
        return renderer
    end
    print("AFTER")
    print(type(UIRenderer.new))
    printTable(UIRenderer)

end

That still doesn't work.  BEFORE and AFTER get printed and I'm definitely modifying the "new" method, but ARROW never gets printed.  A friend suggested that I read about metatables, and that looks promising... for tomorrow.



adeilt

  • Newbie
  • *
  • Status:
    Offline
    Posts:
    10
    • View Profile
on: July 25, 2019, 03:34:28 AM
I think I've hit a dead end with trying to override the constructor for the thing that UIRenderer() returns:

Code: [Select]
if type(UIRenderer) == 'table' then
    local UIRenderer_metatable = getmetatable(UIRenderer)
    local UIRenderer_metatable_call = UIRenderer_metatable.__call

    UIRenderer_metatable.__call = function()
        local renderer = UIRenderer_metatable_call()
        local vanilla_RenderEntityArrow = renderer.renderEntityArrow
       
        renderer.renderEntityArrow = function(self, asteroid, width, length, visibility_threshold, color)
            width = 5  -- default is 10
            length = 60  -- default is 30
            return vanilla_RenderEntityArrow(self, asteroid, width, length, visibility_threshold, color)
        end
        return renderer
    end
else
    print("Why isn't UIRenderer always a table?")
end

This works in that the constructor gets overridden, but it doesn't work in that I can't assign to renderer.renderEntityArrow because these are true:

Code: [Select]
type(UIRenderer()) ~= 'table'
type(UIRenderer()) == 'userdata'
UIRenderer().__avoriontype == 'UIRenderer'

I'm going to have another go at overriding onPreRenderHud.



adeilt

  • Newbie
  • *
  • Status:
    Offline
    Posts:
    10
    • View Profile
on: July 25, 2019, 03:52:28 AM
I tried overriding onPreRenderHud directly like I did in my original post and that worked fine for no reason I can determine. ???



adeilt

  • Newbie
  • *
  • Status:
    Offline
    Posts:
    10
    • View Profile
on: July 25, 2019, 05:17:46 AM
Well, I posted it as-is, but I'm still hoping to figure out how to make it compatible with other overriders of onPreRenderHud.  Anyone got any clues for me?

https://steamcommunity.com/sharedfiles/filedetails/?id=1814439132



brunobf

  • Newbie
  • *
  • Status:
    Offline
    Posts:
    11
    • View Profile
on: July 25, 2019, 06:20:41 AM
One way to do it is like  this:
Code: [Select]
if onClient() then
    local metaTable = getmetatable(UIRenderer)
    local old_renderEntityArrow = metaTable["renderEntityArrow"]

    metaTable["renderEntityArrow"] = function(self, entity, width, length, visibilityThreshold, ...)
        -- The original miningsystem uses these parameters:
        -- renderer:renderEntityArrow(tuple.asteroid, 30, 10, 250, tuple.material.color);
        if width == 30 and length == 10 and visibilityThreshold == 250 then
            old_renderEntityArrow(self, entity, 5, 5, visibilityThreshold, ...)
            old_renderEntityArrow(self, entity, 5, 10, visibilityThreshold, ...)
        else
            old_renderEntityArrow(self, entity, width, length, visibilityThreshold, ...)
        end
    end
end

Because I don't know if there will ever be other calls to renderEntityArrow from that lua VM, I only did the override for that very specific set of params, based on the original code. If the devs ever change that, this will break.

You could instead override all calls, which right now would also work, except that if a new call is added it would also break. Pick your poison :)

« Last Edit: July 25, 2019, 07:20:32 AM by brunobf »



adeilt

  • Newbie
  • *
  • Status:
    Offline
    Posts:
    10
    • View Profile
on: July 25, 2019, 02:15:48 PM
Ah, thanks!  Many things become clear.

I can stop checking to see if UIRenderer() returns a table because it does iff onClient().

Upon reflection, I think that this also gives me the way to get at all the other arrows (although not by modding miningsystem.lua).  I'll have to mull this over a bit.