Skip to content

Commit

Permalink
Fix in interact menu api for missionid cdata objects causing an error…
Browse files Browse the repository at this point in the history
… in AddUITriggeredEvent.
  • Loading branch information
bvbohnen committed Oct 31, 2021
1 parent eb145df commit 313d2de
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 66 deletions.
4 changes: 2 additions & 2 deletions Support/steam_versions.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"sn_interact_collection": "1.1",
"sn_extra_game_options": "1.12",
"sn_better_target_monitor": "2.0",
"sn_mod_support_apis": "1.87",
"sn_mod_support_apis": "1.88",
"sn_remove_dock_glow": "1.2",
"sn_quiet_target_range_clicks": "1.1",
"sn_remove_blinking_lights": "1.4",
Expand All @@ -14,5 +14,5 @@
"sn_start_with_seta": "1.1",
"sn_debug_info": "1.1",
"sn_reduce_fog": "1.0",
"sn_asteroid_fade": "1.3"
"sn_asteroid_fade": "1.4"
}
12 changes: 12 additions & 0 deletions extensions/sn_asteroid_fade/Customizer_Script.py
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,10 @@ def Patch_Shader_Files(shader_names, testmode = False):
haziness just make it look bad (and cannot be hidden since
asteroids wouldnt go fully transparent).
Giving up on this path for now to go back to dithering.
Note: 4.10b7 adds an alpha term to asteroid.f, with the return
switching from GENERAL_OUTPUT(...) to GENERAL_OUTPUTA(alpha, ...).
In testing, this doesn't appear to be helpful.
'''
# Calculate the custom fade.
# See notes above (on 3.3 version) for explanation.
Expand Down Expand Up @@ -954,6 +958,14 @@ def Patch_Shader_Files(shader_names, testmode = False):
ref_line = '}'
new_text = (new_code + ref_line).join(new_text.rsplit(ref_line, 1))

# Test out modifying the GENERAL_OUTPUTA line, added in 4.1.
# Result: no effect when ast_fade locked to 0.5, asteroids were
# still fully visible (or fading in with ego janky logic).
#new_text = new_text.replace(
# 'GENERAL_OUTPUTA(ColorBaseDiffuse.a * F_alphascale',
# 'GENERAL_OUTPUTA(ColorBaseDiffuse.a * F_alphascale * ast_fade'
# )

# In test mode, shortcut the ast_fade to the asteroid color.
# Close asteroids will be white, far away black (ideally).
# This overwrites the normal asteroid output result.
Expand Down
4 changes: 3 additions & 1 deletion extensions/sn_asteroid_fade/change_log.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,6 @@ Change Log
- Fade in range limited to 15 km start to end.
* 1.3
- Update for X4 4.0 render distance changes.
- Reduced asteroid targeting range to 25km to prevent occasional pop-in due to zone culling.
- Reduced asteroid targeting range to 25km to prevent occasional pop-in due to zone culling.
* 1.4
- Update for X4 4.1.
2 changes: 1 addition & 1 deletion extensions/sn_asteroid_fade/content.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
description=" "
save="false"
sync="false"
version="103">
version="104">

<text description=" " language="7"/>
<text description=" " language="33"/>
Expand Down
4 changes: 3 additions & 1 deletion extensions/sn_mod_support_apis/change_log.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,4 +58,6 @@ Change Log for overall api package.
* 1.86
- Hotkey pipe server bugfix.
* 1.87
- Update/fix to interact api for x4 4.10 beta 5.
- Update/fix to interact api for x4 4.10 beta 5.
* 1.88
- Fix in interact api for missionid cdata values failing to convert to md, which will now be passed as strings.
2 changes: 1 addition & 1 deletion extensions/sn_mod_support_apis/content.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
name="Mod Support APIs"
description=" "
author="SirNukes"
version="187"
version="188"
date="2019-07-23"
save="false"
sync="false">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -269,14 +269,13 @@ The possible params are as follows. Not all of these will exist for every target
- This occurs in the map view, looking at a shipyard, right clicking on a ship under construction, in which case the $object is the shipyard and $construction is the ship.
- May be unspecified.
* $mission
- ID of an active mission.
- ID of an active mission, as a cdata string representation.
- May be unspecified.
* $missionoffer
- ID of a mission offer.
- ID of a mission offer, as a cdata string representation.
- May be unspecified.
* $componentMissions
- Potentially a list of mission ids (untested).
- Not verified in game as ever being populated, though the table will exist when opening a menu for a station from the map.
- Potentially a list of mission ids (untested), as cdata strings.
- May be unspecified.
* $offsetcomponent
- Reference object for a position targeted, often a sector.
Expand Down
66 changes: 55 additions & 11 deletions extensions/sn_mod_support_apis/lua/interact_menu/Interface.lua
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,8 @@ function L.Init_Patch_Menu()
-- Wrap onUpdate, so it can be suppressed. Note that Helper will link
-- to this when the menu showMenuCallback kicks off, which is fine
-- with this style of wrapping. (Temporary wraps wouldn't work so well.)
-- Note: onUpdate wants to check if the mouse is over the menu,
-- but the menu box isn't known while delayed (not until draw() finishes).
-- Note: onUpdate will get called 1-2 times before the frame delay
-- completes, due to event order alignment (and that onUpdate fires
-- on the same frame the menu display() was called, needlessly).
Expand All @@ -357,15 +359,13 @@ function L.Init_Patch_Menu()
end
end

-- Delay the update function, since it wants to check if the mouse is over
-- the menu, but the menu box isn't known yet (not until draw() finishes).
local ego_onUpdate = menu.onUpdate
menu.onUpdate = function(...)
if not L.delaying_menu then
ego_onUpdate(...)
end
end

-- Removed; temp printout used during some debugging.
--local ego_insertInteractionContent = menu.insertInteractionContent
--menu.insertInteractionContent = function(name, entry, ...)
-- DebugError("insertInteractionContent("..name..", "..tostring(entry.text)..")")
-- ego_insertInteractionContent(name, entry, ...)
--end

-- Patch prepareActions to slot in the custom function afterward.
local ego_prepareActions = menu.prepareActions
menu.prepareActions = function (...)
Expand Down Expand Up @@ -430,6 +430,9 @@ function L.Delayed_Draw()
L.delaying_menu = false

-- Run the suppressed functions.
-- Note: if a C function fails, prepareActions will silently die and
-- not return, so draw() will not be called, and the onUpdate function
-- will throw errors due to missing mouse position data.
menu.prepareActions()
menu.draw()
end
Expand Down Expand Up @@ -473,8 +476,9 @@ function L.Signal_MD_Get_Actions()
-- Int 1-24 (or nil) greek letter index.
subordinategroup = menu.subordinategroup,

-- Just pass mission ids through as-is; attempts to convert them
-- to something like parent cues didn't work out below.
-- Note: mission ids are cdata objects (ULL), which the AddUITriggeredEvent
-- function will error on ("Cannot convert table value '(null)' to ScriptValue").
-- Handle conversions further below.
mission = menu.mission,
missionoffer = menu.missionoffer,
componentMissions = menu.componentMissions,
Expand Down Expand Up @@ -507,13 +511,53 @@ function L.Signal_MD_Get_Actions()
-- unified term here.
ret_table.texts.targetBaseOrShortName = menu.texts.targetBaseName or menu.texts.targetShortName

-- Convert cdata to something that AddUITriggeredEvent can handle.
-- For now, just use strings.
-- TODO: maybe cast to numbers, but lua doubles can lose precision
-- from 64-bit ints.
-- This will just check the top layer and one level of table nesting,
-- which should catch all missionid entries.
for field, value in pairs(ret_table) do
-- Nested table handling
if type(value) == "table" then
-- For safety, always make sure this ret_table value is a
-- different table from the one from the menu (to avoid
-- messing up menu data) if cdata is being replaced.
local convert = false
for subfield, subvalue in pairs(value) do
if type(subvalue) == "cdata" then
convert = true
break
end
end
if convert then
-- Copy elements to the new table, converting on the
-- cdata ones (probably all, but be safe).
local new_table = {}
ret_table[field] = new_table
for subfield, subvalue in pairs(value) do
if type(subvalue) == "cdata" then
new_table[subfield] = tostring(subvalue)
else
new_table[subfield] = subvalue
end
end
end
else
if type(value) == "cdata" then
ret_table[field] = tostring(value)
end
end
end

--Lib.Print_Table(ret_table, "interact_menu_params")
--if ret_table.componentMissions ~= nil then
-- Lib.Print_Table(ret_table.componentMissions, "componentMissions")
--end
--Lib.Print_Table(ret_table.texts, "texts")

-- Package up menu into into a table, and signal to md.
-- Note: will give a (null) conversion error on cdata objects in ret_table.
AddUITriggeredEvent("Interact_Menu_API", "onDisplay", ret_table)

-- Clear any prior recorded temp actions.
Expand Down
93 changes: 48 additions & 45 deletions extensions/sn_mod_support_apis/md/Interact_Menu_API.xml
Original file line number Diff line number Diff line change
Expand Up @@ -585,56 +585,61 @@
<actions>
<!--The table will largely be used as-is.-->
<set_value name="$menu_params" exact="event.param3"/>
<!--Error check for bad table (may be null due to conversion error).
In such cases, expect a AddUITriggeredEvent releated error in
the debug log, so don't print an error message here.-->
<do_if value="typeof $menu_params == datatype.table">

<!--Convert select lua object ids to their md components.-->
<do_for_each name="$field" in="['$object', '$offsetcomponent', '$construction']">
<do_if value="$menu_params.{$field}?">
<!--Convert 0 to null explicitly. (Component lookup will also
return null, but with a log error)-->
<do_if value="$menu_params.{$field} == 0">
<set_value name="$menu_params.{$field}" exact="null"/>
<!--Convert select lua object ids to their md components.-->
<do_for_each name="$field" in="['$object', '$offsetcomponent', '$construction']">
<do_if value="$menu_params.{$field}?">
<!--Convert 0 to null explicitly. (Component lookup will also
return null, but with a log error)-->
<do_if value="$menu_params.{$field} == 0">
<set_value name="$menu_params.{$field}" exact="null"/>
</do_if>
<do_else>
<set_value name="$menu_params.{$field}" exact="component.{$menu_params.{$field}}"/>
</do_else>
</do_if>
<do_else>
<set_value name="$menu_params.{$field}" exact="component.{$menu_params.{$field}}"/>
</do_else>
</do_if>
</do_for_each>
</do_for_each>

<!--Loop over lists, if present.-->
<do_for_each name="$field" in="['$selectedplayerships', '$selectedplayerdeployables', '$selectedotherobjects']">
<do_if value="$menu_params.{$field}?">
<do_for_each name="$ship_id" in="$menu_params.{$field}">
<set_value name="$menu_params.{$field}.{loop.index}" exact="component.{$ship_id}"/>
</do_for_each>
<!--Loop over lists, if present.-->
<do_for_each name="$field" in="['$selectedplayerships', '$selectedplayerdeployables', '$selectedotherobjects']">
<do_if value="$menu_params.{$field}?">
<do_for_each name="$ship_id" in="$menu_params.{$field}">
<set_value name="$menu_params.{$field}.{loop.index}" exact="component.{$ship_id}"/>
</do_for_each>
</do_if>
</do_for_each>

<!--Convert an offset position to an md Position.-->
<do_if value="$menu_params.$offset?">
<set_value name="$menu_params.$offset" exact="position.[
$menu_params.$offset.$x,
$menu_params.$offset.$y,
$menu_params.$offset.$z,
]"/>
</do_if>
</do_for_each>

<!--Convert an offset position to an md Position.-->
<do_if value="$menu_params.$offset?">
<set_value name="$menu_params.$offset" exact="position.[
$menu_params.$offset.$x,
$menu_params.$offset.$y,
$menu_params.$offset.$z,
]"/>
</do_if>
<!--Convert 0/1 to bool true/false.-->
<do_for_each name="$field" in="['$isshipconsole', '$isdockedship', '$showPlayerInteractions', '$hasPlayerShipPilot']">
<set_value name="$menu_params.{$field}" exact="if $menu_params.{$field} == 1 then true else false"/>
</do_for_each>

<!--Convert 0/1 to bool true/false.-->
<do_for_each name="$field" in="['$isshipconsole', '$isdockedship', '$showPlayerInteractions', '$hasPlayerShipPilot']">
<set_value name="$menu_params.{$field}" exact="if $menu_params.{$field} == 1 then true else false"/>
</do_for_each>
<!--TODO: what other conversions are needed?-->

<!--TODO: what other conversions are needed?-->
<!--Store this data to repeat later for a possible callback cue, so
the lua doesn't have to send it twice.-->
<set_value name="Globals.$menu_params" exact="$menu_params"/>

<!--Store this data to repeat later for a possible callback cue, so
the lua doesn't have to send it twice.-->
<set_value name="Globals.$menu_params" exact="$menu_params"/>
<do_if value="Globals.$DebugChance">
<signal_cue_instantly cue="Debug_Print_Params"/>
</do_if>

<do_if value="Globals.$DebugChance">
<signal_cue_instantly cue="Debug_Print_Params"/>
<!--Signal this locally to a dummy cue, that users can listen to.-->
<signal_cue_instantly cue="Get_Actions" param="$menu_params"/>
</do_if>

<!--Signal this locally to a dummy cue, that users can listen to.-->
<signal_cue_instantly cue="Get_Actions" param="$menu_params"/>
</actions>
</cue>

Expand Down Expand Up @@ -790,15 +795,13 @@
shipyard and $construction is the ship.
- May be unspecified.
* $mission
- ID of an active mission.
- ID of an active mission, as a cdata string representation.
- May be unspecified.
* $missionoffer
- ID of a mission offer.
- ID of a mission offer, as a cdata string representation.
- May be unspecified.
* $componentMissions
- Potentially a list of mission ids (untested).
- Not verified in game as ever being populated, though the table will
exist when opening a menu for a station from the map.
- Potentially a list of mission ids (untested), as cdata strings.
- May be unspecified.
* $offsetcomponent
- Reference object for a position targeted, often a sector.
Expand Down

0 comments on commit 313d2de

Please sign in to comment.