[API/GUIDE] How to mod the UI (_G Workaround and Right Click API) v0.32 (02/27/19))

The place to discuss scripting and game modifications for X4: Foundations.

Moderators: Scripting / Modding Moderators, Moderators for English X Forum

User avatar
Malakie
Posts: 1059
Joined: Tue, 13. Apr 04, 23:08
x4

Re: [API/GUIDE] How to mod the UI (_G Workaround and Right Click API) v0.31

Post by Malakie » Fri, 22. Feb 19, 23:38

This no longer works in the current build of the game....

Activating it BREAKS the game... Trying to right click on ANY owned item in the list, no menu at all now appears. I downloaded the most current version I could find.. Now at least the right menu shows up for objects you own.. However the entire Ship design menu and stations design menu no longer does.. When you try to repair or update a ship or try to build a new one, the menu of items is completely gone.

Removing this mod, all is well again but of course that breaks any other mod using it.

Any idea on when a fix will be coming?
Take it light.....

Malakie

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

dwbennett
Posts: 56
Joined: Fri, 14. Dec 18, 02:15
x4

Re: [API/GUIDE] How to mod the UI (_G Workaround and Right Click API) v0.31

Post by dwbennett » Tue, 26. Feb 19, 17:03

With Ver. 2.0 of the game, the RghtClickAPI part of UI_API_v0.35 causes major problems. After selecting a ship in map view and then right clicking on it (no holding the right button), the map view rotates and tilts as when the right mouse button is clicked and held on the map. After right clicking on the map again the right click and hold will finally release with the map in whatever final view the map gyrations generates. Left clicking on a ship in the map without selecting it first causes the same problem. Turning off the Community Right Click API mod in the Extension menu or removing the RightClickAPI folder from the Extension folder will both solve the problem as far as I can tell.

Take care,
dwbennett

morbideth
Posts: 391
Joined: Sun, 9. Nov 08, 03:07
x3tc

Re: [API/GUIDE] How to mod the UI (_G Workaround and Right Click API) v0.32 (02/27/19))

Post by morbideth » Wed, 27. Feb 19, 14:29

v0.32
  • Updated the right click api to work with 2.0.
  • Added 'showTypes' features to debugging tools, intended for use with the right-click menu. add capi.showTypes = true to your init() function to print the action types when you right-click on something. Use this to determine which action type you want to use to trigger your right-click menu.
  • Added right-click stuff to templet

Berserk Knight
Posts: 398
Joined: Tue, 17. Dec 13, 01:34
x4

Re: [API/GUIDE] How to mod the UI (_G Workaround and Right Click API) v0.32 (02/27/19))

Post by Berserk Knight » Fri, 8. Mar 19, 12:21

I have a feature request for the Rightclick API.
Or more correctly, "I have some code changes (that I've already made and tested on my end) that may be beneficial, and was wondering if you'd incorporate them."

We can make custom sections and put new orders under them, but they don't get mouseover tooltips, target names on the right side, etc. that orders under certain regular sections get (that we might want in ours as well).
What I did was replace the simple comparison checks with functions that do the same check plus an additional check against a list of registered custom section IDs.

The following is the entire modified right_click_api.lua file, patched for 2.20 beta2 (mostly just "Attackinrange" order addition and some changes to a few parameters when making buttons and such) along with the changes mentioned above.
(The additional lists and API functions start at line 864. You might want to move it near the other declarations if you decide to incorporate this.)

Code: Select all

-- ffi setup
local ffi = require("ffi")
local C = ffi.C
ffi.cdef[[
	typedef uint64_t BuildTaskID;
	typedef uint64_t UniverseID;
	typedef struct {
		const char* macro;
		const char* ware;
		uint32_t amount;
		uint32_t capacity;
	} AmmoData;
	typedef struct {
		int x;
		int y;
	} Coord2D;
	typedef struct {
		float x;
		float y;
		float z;
	} Coord3D;
	typedef struct {
		size_t queueidx;
		const char* state;
		const char* statename;
		const char* orderdef;
		size_t actualparams;
		bool enabled;
		bool isinfinite;
		bool issyncpointreached;
		bool istemporder;
	} Order;
	typedef struct {
		const char* id;
		const char* name;
		const char* desc;
		uint32_t amount;
		uint32_t numtiers;
		bool canhire;
	} PeopleInfo;
	typedef struct {
		uint32_t id;
		const char* text;
		const char* type;
		bool ispossible;
		bool istobedisplayed;
	} UIAction;
	typedef struct {
		UniverseID component;
		const char* connection;
	} UIComponentSlot;
	typedef struct {
		const char* shape;
		const char* name;
		uint32_t requiredSkill;
		float radius;
		bool rollMembers;
		bool rollFormation;
		size_t maxShipsPerLine;
	} UIFormationInfo;
	typedef struct {
		const float x;
		const float y;
		const float z;
		const float yaw;
		const float pitch;
		const float roll;
	} UIPosRot;
	typedef struct {
		const char* wareid;
		int32_t amount;
	} YieldInfo;
	bool CanAcceptSubordinate(UniverseID commanderid, UniverseID potentialsubordinateid);
	bool CancelConstruction(UniverseID containerid, BuildTaskID id);
	bool CanCancelConstruction(UniverseID containerid, BuildTaskID id);
	const char* CanTeleportPlayerTo(UniverseID controllableid, bool allowcontrolling, bool force);
	uint32_t GetAllLaserTowers(AmmoData* result, uint32_t resultlen, UniverseID defensibleid);
	uint32_t GetAllMines(AmmoData* result, uint32_t resultlen, UniverseID defensibleid);
	uint32_t GetAllNavBeacons(AmmoData* result, uint32_t resultlen, UniverseID defensibleid);
	uint32_t GetAllResourceProbes(AmmoData* result, uint32_t resultlen, UniverseID defensibleid);
	uint32_t GetAllSatellites(AmmoData* result, uint32_t resultlen, UniverseID defensibleid);
	uint32_t GetCompSlotPlayerActions(UIAction* result, uint32_t resultlen, UIComponentSlot compslot);
	Coord2D GetCompSlotScreenPos(UIComponentSlot compslot);
	UniverseID GetContextByClass(UniverseID componentid, const char* classname, bool includeself);
	uint32_t GetFormationShapes(UIFormationInfo* result, uint32_t resultlen);
	uint32_t GetMineablesAtSectorPos(YieldInfo* result, uint32_t resultlen, UniverseID sectorid, Coord3D position);
	uint32_t GetMissionThreadSubMissions(MissionID* result, uint32_t resultlen, MissionID missionid);
	uint32_t GetNumAllLaserTowers(UniverseID defensibleid);
	uint32_t GetNumAllMines(UniverseID defensibleid);
	uint32_t GetNumAllRoles(void);
	uint32_t GetNumAllNavBeacons(UniverseID defensibleid);
	uint32_t GetNumAllResourceProbes(UniverseID defensibleid);
	uint32_t GetNumAllSatellites(UniverseID defensibleid);
	uint32_t GetNumCompSlotPlayerActions(UIComponentSlot compslot);
	uint32_t GetNumFormationShapes(void);
	uint32_t GetNumMineablesAtSectorPos(UniverseID sectorid, Coord3D position);
	uint32_t GetNumMissionThreadSubMissions(MissionID missionid);
	uint32_t GetNumVenturePlatformDocks(UniverseID ventureplatformid);
	uint32_t GetNumVenturePlatforms(UniverseID defensibleid);
	uint32_t GetNumWares(const char* tags, bool research, const char* licenceownerid, const char* exclusiontags);
	UniverseID GetPlayerContainerID(void);
	UniverseID GetPlayerID(void);
	UniverseID GetPlayerOccupiedShipID(void);
	uint32_t GetPeople(PeopleInfo* result, uint32_t resultlen, UniverseID controllableid);
	float GetTextWidth(const char*const text, const char*const fontname, const float fontsize);
	uint32_t GetVenturePlatformDocks(UniverseID* result, uint32_t resultlen, UniverseID ventureplatformid);
	uint32_t GetVenturePlatforms(UniverseID* result, uint32_t resultlen, UniverseID defensibleid);
	uint32_t GetWares(const char** result, uint32_t resultlen, const char* tags, bool research, const char* licenceownerid, const char* exclusiontags);
	bool HasVenturerDock(UniverseID containerid, UniverseID shipid, UniverseID ventureplatformid);
	bool IsBuilderBusy(UniverseID shipid);
	bool IsDefensibleBeingBoardedBy(UniverseID defensibleid, const char* factionid);
	bool IsMouseEmulationActive(void);
	bool IsObjectKnown(const UniverseID componentid);
	bool IsPlayerCameraTargetViewPossible(UniverseID targetid, bool force);
	void LaunchLaserTower(UniverseID defensibleid, const char* lasertowermacroname);
	void LaunchMine(UniverseID defensibleid, const char* minemacroname);
	void LaunchNavBeacon(UniverseID defensibleid, const char* navbeaconmacroname);
	void LaunchResourceProbe(UniverseID defensibleid, const char* resourceprobemacroname);
	void LaunchSatellite(UniverseID defensibleid, const char* satellitemacroname);
	void MakePlayerOwnerOf(UniverseID objectid);
	void MovePlayerToSectorPos(UniverseID sectorid, UIPosRot position);
	void NotifyInteractMenuHidden(const uint32_t id, const bool allclosed);
	void NotifyInteractMenuShown(const uint32_t id);
	bool PerformCompSlotPlayerAction(UIComponentSlot compslot, uint32_t actionid);
	bool RemoveOrder(UniverseID controllableid, size_t idx, bool playercancelled, bool checkonly);
	bool RequestDockAt(UniverseID containerid, bool checkonly);
	UIFormationInfo SetFormationShape(UniverseID objectid, const char* formationshape);
	void SetGuidance(UniverseID componentid, UIPosRot offset);
	bool TeleportPlayerTo(UniverseID controllableid, bool allowcontrolling, bool instant, bool force);
]]

local orig = {}
capi = {}



local accountmanagementActions = {}
local assignActions = {}
local attackActions = {}
local attackinrangeActions = {}
local attackmultipleActions = {}
local attackplayertargetActions = {}
local boardActions = {}
local buildActions = {}
local buildshipsActions = {}
local changeformationActions = {}
local configurestationActions = {}
local collectActions = {}
local collectspaceActions = {}
local deployhereActions = {}
local deployatActions = {}
local dockatActions = {}
local dockatplayerActions = {}
local dockrequestActions = {}
local exploreActions = {}
local exploreupdateActions = {}
local flytoActions = {}
local followActions = {}
local guidanceActions = {}
local hireActions = {}
local logicalstationoverviewActions = {}
local manageassignmentsActions = {}
local miningActions = {}
local orderoverviewActions = {}
local paintmodActions = {}
local player_docktotradeActions = {}
local proceedwithordersActions = {}
local protectstationActions = {}
local recallsubsActions = {}
local removeallordersActions = {}
local sellshipsActions = {}
local stopandholdfireActions = {}
local targetviewActions = {}
local teleportActions = {}
local upgradeActions = {}
local upgradeshipsActions = {}
local venturedockatActions = {}
local wareexchangeActions = {}
local withdrawandholdActions = {}
local withdrawfromcombatActions = {}
local cheat_satelliteActions = {}
local cheat_navbeaconActions = {}
local cheat_resourceprobeActions = {}
local cheat_takeownershipActions = {}
local cheat_warpActions = {}

function capi.InsertLuaAction(actiontype, istobedisplayed)
	-- process your own action
	if actiontype == "accountmanagement" then
		capi.OnAccountmanagement()
	elseif actiontype == "assign" then
		capi.OnAssign()
	elseif actiontype == "attack" then
		capi.OnAttack()
	elseif actiontype == "attackinrange" then
		capi.OnAttackinrange()
	elseif actiontype == "attackmultiple" then
		capi.OnAttackmultiple()
	elseif actiontype == "attackplayertarget" then
		capi.OnAttackplayertarget()
	elseif actiontype == "board" then
		capi.OnBoard()
	elseif actiontype == "build" then
		capi.OnBuild()
	elseif actiontype == "buildships" then
		capi.OnBuildships()
	elseif actiontype == "changeformation" then
		capi.OnChangeformation()
	elseif actiontype == "configurestation" then
		capi.OnConfigurestation()
	elseif actiontype == "collect" then
		capi.OnCollect()
	elseif actiontype == "collectspace" then
		capi.OnCollectspace()
	elseif actiontype == "deployhere" then
		capi.OnDeployhere()
	elseif actiontype == "deployat" then
		capi.OnDeployat()
	elseif actiontype == "dockat" then
		capi.OnDockat()
	elseif actiontype == "dockatplayer" then
		capi.OnDockatplayer()
	elseif actiontype == "dockrequest" then
		capi.OnDockrequest()
	elseif actiontype == "explore" then
		capi.OnExplore()
	elseif actiontype == "exploreupdate" then
		capi.OnExploreupdate()
	elseif actiontype == "flyto" then
		capi.OnFlyto()
	elseif actiontype == "follow" then
		capi.OnFollow()
	elseif actiontype == "guidance" then
		capi.OnGuidance()
	elseif actiontype == "hire" then
		capi.OnHire()
	elseif actiontype == "logicalstationoverview" then
		capi.OnLogicalstationoverview()
	elseif actiontype == "manageassignments" then
		capi.OnManageassignments()
	elseif actiontype == "mining" then
		capi.OnMining()
	elseif actiontype == "orderoverview" then
		capi.OnOrderoverview()
	elseif actiontype == "paintmod" then
		capi.OnPaintmod()
	elseif actiontype == "player_docktotrade" then
		capi.OnPlayer_docktotrade()
	elseif actiontype == "proceedwithorders" then
		capi.OnProceedwithorders()
	elseif actiontype == "protectstation" then
		capi.OnProtectstation()
	elseif actiontype == "recallsubs" then
		capi.OnRecallsubs()
	elseif actiontype == "removeallorders" then
		capi.OnRemoveallorders()
	elseif actiontype == "sellships" then
		capi.OnSellships()
	elseif actiontype == "stopandholdfire" then
		capi.OnStopandholdfire()
	elseif actiontype == "targetview" then
		capi.OnTargetview()
	elseif actiontype == "teleport" then
		capi.OnTeleport()
	elseif actiontype == "upgrade" then
		capi.OnUpgrade()
	elseif actiontype == "upgradeships" then
		capi.OnUpgradeships()
	elseif actiontype == "venturedockat" then
		capi.OnVenturedockat()
	elseif actiontype == "wareexchange" then
		capi.OnWareexchange()
	elseif actiontype == "withdrawandhold" then
		capi.OnWithdrawandhold()
	elseif actiontype == "withdrawfromcombat" then
		capi.OnWithdrawfromcombat()
	elseif actiontype == "cheat_satellite" then--I don't know if modders can get access to these, so Im adding them anyway.
		capi.OnCheat_satellite()
	elseif actiontype == "cheat_navbeacon" then
		capi.OnCheat_navbeacon()
	elseif actiontype == "cheat_resourceprobe" then
		capi.OnCheat_resourceprobe()
	elseif actiontype == "cheat_takeownership" then
		capi.OnCheat_takeownership()
	elseif actiontype == "cheat_warp" then
		capi.OnCheat_warp()
	end
		--then call original function first
	orig.insertLuaAction(actiontype, istobedisplayed)
end
function capi.RegisterAccountmanagementAction(actionFunction)
	table.insert(accountmanagementActions, actionFunction)
end
function capi.OnAccountmanagement()
	for _, func in ipairs(accountmanagementActions) do
		func(orig.menu)
	end
end
function capi.RegisterAssignAction(actionFunction)
	table.insert(assignActions, actionFunction)
end
function capi.OnAssign()
	for _, func in ipairs(assignActions) do
		func(orig.menu)
	end
end
function capi.RegisterAttackAction(actionFunction)
	table.insert(attackActions, actionFunction)
end
function capi.OnAttack()
	for _, func in ipairs(attackActions) do
		func(orig.menu)
	end
end
function capi.RegisterAttackinrangeAction(actionFunction)
	table.insert(attackinrangeActions, actionFunction)
end
function capi.OnAttackinrange()
	for _, func in ipairs(attackinrangeActions) do
		func(orig.menu)
	end
end
function capi.RegisterAttackmultipleAction(actionFunction)
	table.insert(attackmultipleActions, actionFunction)
end
function capi.OnAttackmultiple()
	for _, func in ipairs(attackmultipleActions) do
		func(orig.menu)
	end
end
function capi.RegisterAttackplayertargetAction(actionFunction)
	table.insert(attackplayertargetActions, actionFunction)
end
function capi.OnAttackplayertarget()
	for _, func in ipairs(attackplayertargetActions) do
		func(orig.menu)
	end
end
function capi.RegisterBoardAction(actionFunction)
	table.insert(boardActions, actionFunction)
end
function capi.OnBoard()
	for _, func in ipairs(boardActions) do
		func(orig.menu)
	end
end
function capi.RegisterBuildAction(actionFunction)
	table.insert(buildActions, actionFunction)
end
function capi.OnBuild()
	for _, func in ipairs(buildActions) do
		func(orig.menu)
	end
end
function capi.RegisterBuildshipsAction(actionFunction)
	table.insert(buildshipsActions, actionFunction)
end
function capi.OnBuildships()
	for _, func in ipairs(buildshipsActions) do
		func(orig.menu)
	end
end
function capi.RegisterChangeformationAction(actionFunction)
	table.insert(changeformationActions, actionFunction)
end
function capi.OnChangeformation()
	for _, func in ipairs(changeformationActions) do
		func(orig.menu)
	end
end
function capi.RegisterConfigurestationAction(actionFunction)
	table.insert(configurestationActions, actionFunction)
end
function capi.OnConfigurestation()
	for _, func in ipairs(configurestationActions) do
		func(orig.menu)
	end
end
function capi.RegisterCollectAction(actionFunction)
	table.insert(collectActions, actionFunction)
end
function capi.OnCollect()
	for _, func in ipairs(collectActions) do
		func(orig.menu)
	end
end
function capi.RegisterCollectspaceAction(actionFunction)
	table.insert(collectspaceActions, actionFunction)
end
function capi.OnCollectspace()
	for _, func in ipairs(collectspaceActions) do
		func(orig.menu)
	end
end
function capi.RegisterDeployhereAction(actionFunction)
	table.insert(deployhereActions, actionFunction)
end
function capi.OnDeployhere()
	for _, func in ipairs(deployhereActions) do
		func(orig.menu)
	end
end
function capi.RegisterDeployatAction(actionFunction)
	table.insert(deployatActions, actionFunction)
end
function capi.OnDeployat()
	for _, func in ipairs(deployatActions) do
		func(orig.menu)
	end
end
function capi.RegisterDockatAction(actionFunction)
	table.insert(dockatActions, actionFunction)
end
function capi.OnDockat()
	for _, func in ipairs(dockatActions) do
		func(orig.menu)
	end
end
function capi.RegisterDockatplayerAction(actionFunction)
	table.insert(dockatplayerActions, actionFunction)
end
function capi.OnDockatplayer()
	for _, func in ipairs(dockatplayerActions) do
		func(orig.menu)
	end
end
function capi.RegisterDockrequestAction(actionFunction)
	table.insert(dockrequestActions, actionFunction)
end
function capi.OnDockrequest()
	for _, func in ipairs(dockrequestActions) do
		func(orig.menu)
	end
end
function capi.RegisterExploreAction(actionFunction)
	table.insert(exploreActions, actionFunction)
end
function capi.OnExplore()
	for _, func in ipairs(exploreActions) do
		func(orig.menu)
	end
end
function capi.RegisterExploreupdateAction(actionFunction)
	table.insert(exploreupdateActions, actionFunction)
end
function capi.OnExploreupdate()
	for _, func in ipairs(exploreupdateActions) do
		func(orig.menu)
	end
end
function capi.RegisterFlytoAction(actionFunction)
	table.insert(flytoActions, actionFunction)
end
function capi.OnFlyto()
	for _, func in ipairs(flytoActions) do
		func(orig.menu)
	end
end
function capi.RegisterFollowAction(actionFunction)
	table.insert(followActions, actionFunction)
end
function capi.OnFollow()
	for _, func in ipairs(followActions) do
		func(orig.menu)
	end
end
function capi.RegisterGuidanceAction(actionFunction)
	table.insert(guidanceActions, actionFunction)
end

function capi.OnGuidance()
	for _, func in ipairs(guidanceActions) do
		func(orig.menu)
	end
end
function capi.RegisterHireAction(actionFunction)
	table.insert(hireActions, actionFunction)
end
function capi.OnHire()
	for _, func in ipairs(hireActions) do
		func(orig.menu)
	end
end
function capi.RegisterLogicalstationoverviewAction(actionFunction)
	table.insert(logicalstationoverviewActions, actionFunction)
end
function capi.OnLogicalstationoverview()
	for _, func in ipairs(logicalstationoverviewActions) do
		func(orig.menu)
	end
end
function capi.RegisterManageassignmentsAction(actionFunction)
	table.insert(manageassignmentsActions, actionFunction)
end
function capi.OnManageassignments()
	for _, func in ipairs(manageassignmentsActions) do
		func(orig.menu)
	end
end
function capi.RegisterMiningAction(actionFunction)
	table.insert(miningActions, actionFunction)
end
function capi.OnMining()
	for _, func in ipairs(miningActions) do
		func(orig.menu)
	end
end
function capi.RegisterOrderoverviewAction(actionFunction)
	table.insert(orderoverviewActions, actionFunction)
end
function capi.OnOrderoverview()
	for _, func in ipairs(orderoverviewActions) do
		func(orig.menu)
	end
end
function capi.RegisterPaintmodAction(actionFunction)
	table.insert(paintmodActions, actionFunction)
end
function capi.OnPaintmod()
	for _, func in ipairs(paintmodActions) do
		func(orig.menu)
	end
end
function capi.RegisterPlayer_docktotradeAction(actionFunction)
	table.insert(player_docktotradeActions, actionFunction)
end
function capi.OnPlayer_docktotrade()
	for _, func in ipairs(player_docktotradeActions) do
		func(orig.menu)
	end
end
function capi.RegisterProceedwithordersAction(actionFunction)
	table.insert(proceedwithordersActions, actionFunction)
end
function capi.OnProceedwithorders()
	for _, func in ipairs(proceedwithordersActions) do
		func(orig.menu)
	end
end
function capi.RegisterProtectstationAction(actionFunction)
	table.insert(protectstationActions, actionFunction)
end
function capi.OnProtectstation()
	for _, func in ipairs(protectstationActions) do
		func(orig.menu)
	end
end
function capi.RegisterRecallsubsAction(actionFunction)
	table.insert(recallsubsActions, actionFunction)
end
function capi.OnRecallsubs()
	for _, func in ipairs(recallsubsActions) do
		func(orig.menu)
	end
end
function capi.RegisterRemoveallordersAction(actionFunction)
	table.insert(removeallordersActions, actionFunction)
end
function capi.OnRemoveallorders()
	for _, func in ipairs(removeallordersActions) do
		func(orig.menu)
	end
end
function capi.RegisterSellshipsAction(actionFunction)
	table.insert(sellshipsActions, actionFunction)
end
function capi.OnSellships()
	for _, func in ipairs(sellshipsActions) do
		func(orig.menu)
	end
end
function capi.RegisterStopandholdfireAction(actionFunction)
	table.insert(stopandholdfireActions, actionFunction)
end
function capi.OnStopandholdfire()
	for _, func in ipairs(stopandholdfireActions) do
		func(orig.menu)
	end
end
function capi.RegisterTargetviewAction(actionFunction)
	table.insert(targetviewActions, actionFunction)
end
function capi.OnTargetview()
	for _, func in ipairs(targetviewActions) do
		func(orig.menu)
	end
end
function capi.RegisterTeleportAction(actionFunction)
	table.insert(teleportActions, actionFunction)
end
function capi.OnTeleport()
	for _, func in ipairs(teleportActions) do
		func(orig.menu)
	end
end
function capi.RegisterUpgradeAction(actionFunction)
	table.insert(upgradeActions, actionFunction)
end
function capi.OnUpgrade()
	for _, func in ipairs(upgradeActions) do
		func(orig.menu)
	end
end
function capi.RegisterUpgradeshipsAction(actionFunction)
	table.insert(upgradeshipsActions, actionFunction)
end
function capi.OnUpgradeships()
	for _, func in ipairs(upgradeshipsActions) do
		func(orig.menu)
	end
end
function capi.RegisterVenturedockatAction(actionFunction)
	table.insert(venturedockatActions, actionFunction)
end
function capi.OnVenturedockat()
	for _, func in ipairs(venturedockatActions) do
		func(orig.menu)
	end
end
function capi.RegisterWareexchangeAction(actionFunction)
	table.insert(wareexchangeActions, actionFunction)
end
function capi.OnWareexchange()
	for _, func in ipairs(wareexchangeActions) do
		func(orig.menu)
	end
end
function capi.RegisterWithdrawandholdAction(actionFunction)
	table.insert(withdrawandholdActions, actionFunction)
end
function capi.OnWithdrawandhold()
	for _, func in ipairs(withdrawandholdActions) do
		func(orig.menu)
	end
end
function capi.RegisterWithdrawfromcombatAction(actionFunction)
	table.insert(withdrawfromcombatActions, actionFunction)
end
function capi.OnWithdrawfromcombat()
	for _, func in ipairs(withdrawfromcombatActions) do
		func(orig.menu)
	end
end
function capi.RegisterCheat_satelliteAction(actionFunction)
	table.insert(cheat_satelliteActions, actionFunction)
end
function capi.OnCheat_satellite()
	for _, func in ipairs(cheat_satelliteActions) do
		func(orig.menu)
	end
end
function capi.RegisterCheat_navbeaconAction(actionFunction)
	table.insert(cheat_navbeaconActions, actionFunction)
end
function capi.OnCheat_navbeacon()
	for _, func in ipairs(cheat_navbeaconActions) do
		func(orig.menu)
	end
end
function capi.RegisterCheat_resourceprobeAction(actionFunction)
	table.insert(cheat_resourceprobeActions, actionFunction)
end
function capi.OnCheat_resourceprobe()
	for _, func in ipairs(cheat_resourceprobeActions) do
		func(orig.menu)
	end
end
function capi.RegisterCheat_takeownershipAction(actionFunction)
	table.insert(cheat_takeownershipActions, actionFunction)
end
function capi.OnCheat_takeownership()
	for _, func in ipairs(cheat_takeownershipActions) do
		func(orig.menu)
	end
end
function capi.RegisterCheat_warpAction(actionFunction)
	table.insert(cheat_warpActions, actionFunction)
end
function capi.OnCheat_warp()
	for _, func in ipairs(cheat_warpActions) do
		func(orig.menu)
	end
end

function capi.processSelectedPlayerShips()
	local convertedComponent = ConvertStringTo64Bit(tostring(orig.menu.componentSlot.component))
	local isplayerownedtarget = false
	if convertedComponent ~= 0 then
		isplayerownedtarget = GetComponentData(convertedComponent, "isplayerowned")
	end
	local playercontainer = C.GetPlayerContainerID()
	local convertedPlayerContainer
	if playercontainer ~= 0 then
		convertedPlayerContainer = ConvertStringTo64Bit(tostring(playercontainer))
	end

	orig.menu.possibleorders = capi.possibleorders

	orig.menu.numdockingpossible = 0
	orig.menu.numassignableships = 0
	orig.menu.numassignableminingships = 0
	orig.menu.numremovableorders = 0
	orig.menu.numremovabledefaultorders = 0
	orig.menu.numwaitingforsignal = 0
	orig.menu.numdockingatplayerpossible = 0

	for i = #orig.menu.selectedplayerships, 1, -1 do
		local ship = orig.menu.selectedplayerships[i]
		if ship == orig.menu.componentSlot.component then
			table.remove(orig.menu.selectedplayerships, i)
		else
			-- Check orders
			for orderid, value in pairs(capi.possibleorders) do
				if not value then
					if C.IsOrderSelectableFor(orderid, ship) then
						capi.possibleorders[orderid] = true
					end
				end
			end
			
			-- Check assignments
			if isplayerownedtarget and C.IsComponentClass(orig.menu.componentSlot.component, "controllable") then
				local commander = ConvertIDTo64Bit(GetCommander(ship))
				if commander ~= convertedComponent and C.CanAcceptSubordinate(orig.menu.componentSlot.component, ship) then
					orig.menu.numassignableships = orig.menu.numassignableships + 1
					if GetComponentData(ship, "primarypurpose") == "mine" then
						orig.menu.numassignableminingships = orig.menu.numassignableminingships + 1
					end
				end
			end

			-- Check docking
			if C.IsComponentClass(orig.menu.componentSlot.component, "container") then
				if (convertedComponent ~= 0) and IsDockingPossible(ship, convertedComponent) then
					orig.menu.numdockingpossible = orig.menu.numdockingpossible + 1
				end
			end
			if (playercontainer ~= 0) and IsDockingPossible(ship, convertedPlayerContainer) then
				orig.menu.numdockingatplayerpossible = orig.menu.numdockingatplayerpossible + 1
			end

			-- check order removal
			local numorders = C.GetNumOrders(ship)
			local currentorders = ffi.new("Order[?]", numorders)
			numorders = C.GetOrders(currentorders, numorders, ship)
			for i = numorders, 1, -1 do
				local isdocked, isdocking = GetComponentData(ship, "isdocked", "isdocking")
				if (i == 1) and ((ffi.string(currentorders[0].orderdef) == "DockAndWait") and (isdocked or isdocking)) then
					-- do nothing - removing the dock order would create an undock order ... rather have the ship stay put [Nick]
				else
					if C.RemoveOrder(ship, i, false, true) then
						orig.menu.numremovableorders = orig.menu.numremovableorders + 1
						break
					end
					local currentdefaultorder = ffi.new("Order")
					if C.GetDefaultOrder(currentdefaultorder, ship) then
						if (ffi.string(currentdefaultorder.orderdef) ~= "Wait") and (ffi.string(currentdefaultorder.orderdef) ~= "DockAndWait") then
							orig.menu.numremovabledefaultorders = orig.menu.numremovabledefaultorders + 1
							break
						end
					end
					local commander = ConvertIDTo64Bit(GetCommander(convertedComponent))
					if commander and (commander ~= 0) and (commander ~= ConvertStringTo64Bit(tostring(C.GetPlayerOccupiedShipID()))) then
						orig.menu.numremovabledefaultorders = orig.menu.numremovabledefaultorders + 1
						break
					end
				end
			end

			-- check for waiting for signal
			local numorders = C.GetNumOrders(ship)
			if numorders > 0 then
				local orderparams = GetOrderParams(ship, 1)
				local iswaitingforsignal = false
				for i, param in ipairs(orderparams) do
					if param.name == "releasesignal" and type(param.value) == "table" and param.value[1] == "playerownedship_proceed" then
						orig.menu.numwaitingforsignal = orig.menu.numwaitingforsignal + 1
						break
					end
				end
			end
		end
	end
	local occupiedPlayerShip = ConvertStringTo64Bit(tostring(C.GetPlayerOccupiedShipID()))
	if (#orig.menu.selectedplayerships == 1) and (orig.menu.selectedplayerships[1] == occupiedPlayerShip) then
		orig.menu.showPlayerInteractions = true
	else
		for i, ship in ipairs(orig.menu.selectedplayerships) do
			if ship == occupiedPlayerShip then
				orig.menu.removedOccupiedPlayerShip = occupiedPlayerShip
				table.remove(orig.menu.selectedplayerships, i)
				break
			end
		end
	end

	if isplayerownedtarget and C.IsComponentClass(orig.menu.componentSlot.component, "ship") then
		if (playercontainer ~= 0) and (convertedComponent ~= 0) and IsDockingPossible(convertedComponent, convertedPlayerContainer) then
			orig.menu.numdockingatplayerpossible = orig.menu.numdockingatplayerpossible + 1
		end
	end

	for i = #orig.menu.selectednpcships, 1, -1 do
		local ship = orig.menu.selectednpcships[i]
		if ship == orig.menu.componentSlot.component then
			table.remove(orig.menu.selectednpcships, i)
			break
		end
	end
end

function capi.addOrder(order)
	capi.possibleorders[order] = false 
end

capi.config = {
	layer = 3,
	width = 250,
	rowHeight = 16,
	entryFontSize = Helper.standardFontSize,
	entryX = 3,
	mouseOutRange = 100,
	border = 5,

	sections = {
		{ id = "main",					text = "",						isorder = false },
		{ id = "interaction",			text = ReadText(1001, 7865),	isorder = false },
		{ id = "hiringbuilderoption",	text = "",						isorder = false,	subsections = {
			{ id = "hiringbuilder",	text = ReadText(1001, 7873) },
		}},
		{ id = "trade",					text = ReadText(1001, 7104),	isorder = false },
		{ id = "playersquad_orders",	text = ReadText(1001, 1002),	isorder = false },	-- Broadcast
		{ id = "main_orders",			text = ReadText(1001, 7802),	isorder = false },
		{ id = "formationshapeoption",	text = "",						isorder = false,	subsections = {
			{ id = "formationshape",	text = ReadText(1001, 7862) },
		}},
		{ id = "main_assignments",		text = ReadText(1001, 7803),	isorder = false },
		{ id = "order",					text = "",						isorder = nil },
		{ id = "guidance",				text = "",						isorder = nil,		isplayerinteraction = true },
		{ id = "player_interaction",	text = ReadText(1001, 7843),	isorder = false,	isplayerinteraction = true },
		{ id = "consumables",			text = ReadText(1001, 7846),	isorder = false,	subsections = {
			{ id = "consumables_civilian",	text = ReadText(1001, 7847) },
			{ id = "consumables_military",	text = ReadText(1001, 7848) },
		}},
		{ id = "cheats",				text = "Cheats",				isorder = false }, -- (cheat only)
		{ id = "selected",				text = "",						isorder = true,		isplayerinteraction = true },
		{ id = "selected_orders_all",	text = ReadText(1001, 7804),	isorder = true },
		{ id = "selected_orders",		text = ReadText(1001, 7804),	isorder = true },
		{ id = "mining_orders",			text = "",						isorder = true,		subsections = {
			{ id = "mining",			text = ReadText(1041, 351) },
		}},
		{ id = "venturedockoption",		text = "",						isorder = true,		subsections = {
			{ id = "venturedock",	text = ReadText(1001, 7844) },
		}},
		{ id = "trade_orders",			text = ReadText(1001, 7861),	isorder = true },
		{ id = "selected_assignments",	text = ReadText(1001, 7805),	isorder = true },
		{ id = "selected_consumables",	text = ReadText(1001, 7849),	isorder = true,		subsections = {
			{ id = "selected_consumables_civilian",	text = ReadText(1001, 7847) },
			{ id = "selected_consumables_military",	text = ReadText(1001, 7848) },
		}},
	},
}

local sectionMainAssignments = {}
local sectionPlayerInteraction = {}
local sectionSelectedOrdersAll = {}
local sectionSelectedOrders = {}
local sectionTradeOrders = {}
local sectionSelectedAssignments = {}
local sectionTrade = {}

function capi.AddSectionMainAssignments(id)
	sectionMainAssignments[id] = true
end
function capi.AddSectionPlayerInteraction(id)
	sectionPlayerInteraction[id] = true
end
function capi.AddSectionSelectedOrdersAll(id)
	sectionSelectedOrdersAll[id] = true
end
function capi.AddSectionSelectedOrders(id)
	sectionSelectedOrders[id] = true
end
function capi.AddSectionTradeOrders(id)
	sectionTradeOrders[id] = true
end
function capi.AddSectionSelectedAssignments(id)
	sectionSelectedAssignments[id] = true
end
function capi.AddSectionTrade(id)
	sectionTrade[id] = true
end

function capi.IsSectionMainAssignments(id)
	if (id == "main_assignments") or sectionMainAssignments[id] then
		return true
	end
	return false
end
function capi.IsSectionPlayerInteraction(id)
	if (id == "player_interaction") or sectionPlayerInteraction[id] then
		return true
	end
	return false
end
function capi.IsSectionSelectedOrdersAll(id)
	if (id == "selected_orders_all") or sectionSelectedOrdersAll[id] then
		return true
	end
	return false
end
function capi.IsSectionSelectedOrders(id)
	if (id == "selected_orders") or sectionSelectedOrders[id] then
		return true
	end
	return false
end
function capi.IsSectionTradeOrders(id)
	if (id == "trade_orders") or sectionTradeOrders[id] then
		return true
	end
	return false
end
function capi.IsSectionSelectedAssignments(id)
	if (id == "selected_assignments") or sectionSelectedAssignments[id] then
		return true
	end
	return false
end
function capi.IsSectionTrade(id)
	if (id == "trade") or sectionTrade[id] then
		return true
	end
	return false
end

function capi.addSectionTitle(ftable, section, first)
	local height = 0
	if section.text ~= "" then
		if not first then
			local row = ftable:addRow(false, { bgColor = Helper.color.transparent })
			row[1]:setColSpan(2):createText("", { minRowHeight = capi.config.rowHeight / 2, fontsize = 1 })
			height = height + row:getHeight() + Helper.borderSize
		end
		local row = ftable:addRow(false, { bgColor = Helper.color.transparent })
		if capi.IsSectionMainAssignments(section.id) then
			row[1]:createText(string.format(section.text, orig.menu.texts.commanderShortName), { font = Helper.standardFontBold, mouseOverText = orig.menu.texts.commanderName, titleColor = Helper.defaultSimpleBackgroundColor })
			row[2]:createText("[" .. GetComponentData(ConvertStringTo64Bit(tostring(orig.menu.componentSlot.component)), "assignmentname") .. "]", { font = Helper.standardFontBold, halign = "right", height = Helper.subHeaderHeight, titleColor = Helper.defaultSimpleBackgroundColor })
		elseif capi.IsSectionPlayerInteraction(section.id) then
			if not first then
				row[1]:createText(section.text, { font = Helper.standardFontBold, mouseOverText = section.text .. " " .. orig.menu.texts.targetName, titleColor = Helper.defaultSimpleBackgroundColor })
				row[2]:createText(orig.menu.texts.targetBaseName or orig.menu.texts.targetShortName, { font = Helper.standardFontBold, halign = "right", color = orig.menu.colors.target, mouseOverText = section.text .. " " .. orig.menu.texts.targetName, height = Helper.subHeaderHeight, titleColor = Helper.defaultSimpleBackgroundColor })
			end
		elseif capi.IsSectionSelectedOrdersAll(section.id) then
			row[1]:createText(section.text, { font = Helper.standardFontBold, mouseOverText = orig.menu.texts.selectedFullNamesAll, titleColor = Helper.defaultSimpleBackgroundColor })
			row[2]:createText(orig.menu.texts.selectedNameAll, { font = Helper.standardFontBold, halign = "right", color = orig.menu.colors.selected, mouseOverText = orig.menu.texts.selectedFullNamesAll, height = Helper.subHeaderHeight, titleColor = Helper.defaultSimpleBackgroundColor })
		elseif capi.IsSectionSelectedOrders(section.id) or capi.IsSectionTradeOrders(section.id) or capi.IsSectionSelectedAssignments(section.id) then
			row[1]:createText(section.text, { font = Helper.standardFontBold, mouseOverText = orig.menu.texts.selectedFullNames, titleColor = Helper.defaultSimpleBackgroundColor })
			row[2]:createText(orig.menu.texts.selectedName, { font = Helper.standardFontBold, halign = "right", color = orig.menu.colors.selected, mouseOverText = orig.menu.texts.selectedFullNames, height = Helper.subHeaderHeight, titleColor = Helper.defaultSimpleBackgroundColor })
		else
			row[1]:setColSpan(2):createText(section.text, { font = Helper.standardFontBold, height = Helper.subHeaderHeight, titleColor = Helper.defaultSimpleBackgroundColor })
		end
		height = height + row:getHeight() + Helper.borderSize
	end
	return height
end

function capi.createContentTable(frame, position)
	local x = 0
	if position == "right" then
		x = orig.menu.width + Helper.borderSize
	end

	local ftable = frame:addTable(2, { tabOrder = orig.menu.subsection and 2 or 1, x = x, width = orig.menu.width, backgroundID = "solid", backgroundColor = Helper.color.semitransparent, highlightMode = "off" })
	ftable:setDefaultCellProperties("text",   { minRowHeight = capi.config.rowHeight, fontsize = capi.config.entryFontSize, x = capi.config.entryX })
	ftable:setDefaultCellProperties("button", { height = capi.config.rowHeight })
	ftable:setDefaultComplexCellProperties("button", "text", { fontsize = capi.config.entryFontSize, x = capi.config.entryX })
	ftable:setDefaultComplexCellProperties("button", "text2", { fontsize = capi.config.entryFontSize, x = capi.config.entryX })
	ftable:setColWidthPercent(2, 40)
	ftable:setDefaultBackgroundColSpan(1, 2)

	local height = 0

	-- title
	local row = ftable:addRow(false, { bgColor = Helper.color.transparent })
	local text = orig.menu.texts.targetShortName
	if orig.menu.construction then
		text = orig.menu.texts.constructionName
	end
	text = TruncateText(text, Helper.standardFontBold, Helper.scaleFont(Helper.standardFontBold, Helper.headerRow1FontSize), orig.menu.width - Helper.standardButtonWidth - 2 * capi.config.entryX)
	row[1]:setColSpan(2):createText(text, Helper.headerRowCenteredProperties)
	row[1].properties.color = orig.menu.colors.target
	height = height + row:getHeight() + Helper.borderSize

	-- entries
	local convertedComponent = ConvertStringTo64Bit(tostring(orig.menu.componentSlot.component))
	local isonlinetarget, isplayerownedtarget
	if convertedComponent ~= 0 then
		isonlinetarget, isplayerownedtarget = GetComponentData(convertedComponent, "isonlineobject", "isplayerowned")
	end
	if (#orig.menu.selectedplayerships == 0) and (#orig.menu.selectednpcships > 0) then
		-- only npc ships are selected, show the player that they cannot do anything with an npc ship
		local row = ftable:addRow(false, { bgColor = Helper.color.transparent })
		row[1]:createText(ReadText(1001, 7804), { mouseOverText = orig.menu.texts.npcFullNames, titleColor = Helper.defaultSimpleBackgroundColor })
		row[2]:createText(orig.menu.texts.npcName, { halign = "right", color = orig.menu.colors.selected, mouseOverText = orig.menu.texts.npcFullNames, titleColor = Helper.defaultSimpleBackgroundColor })
		local row = ftable:addRow(true, { bgColor = Helper.color.transparent })
		local button = row[1]:setColSpan(2):createButton({ active = false, bgColor = Helper.color.darkgrey }):setText(ReadText(1001, 7852), { color = Helper.color.red })
	elseif isonlinetarget and isplayerownedtarget then
		local row = ftable:addRow(true, { fixed = true, bgColor = Helper.color.transparent })
		local button = row[1]:setColSpan(2):createButton({ active = false, bgColor = Helper.color.darkgrey }):setText(ReadText(1001, 7868), { color = Helper.color.red })
	else
		local first = true
		for _, section in ipairs(capi.config.sections) do
			local pass = false
			if orig.menu.showPlayerInteractions then
				if section.isplayerinteraction or (orig.menu.shown and (not section.isorder)) then
					pass = true
				end
			elseif (section.isorder == nil) or (section.isorder == (#orig.menu.selectedplayerships > 0)) then
				pass = true
			end

			if pass then
				if section.subsections then
					local hastitle = false
					for _, subsection in ipairs(section.subsections) do
						if (#orig.menu.actions[subsection.id] > 0) or orig.menu.forceSubSection[subsection.id] then
							if not hastitle then
								height = height + capi.addSectionTitle(ftable, section, first)
								first = false
								hastitle = true
							end
							local data = { id = subsection.id, y = height }
							local row = ftable:addRow(data, { bgColor = Helper.color.transparent })
							local iconHeight = Helper.scaleY(capi.config.rowHeight)
							local button = row[1]:setColSpan(2):createButton({
								bgColor = #orig.menu.actions[subsection.id] > 0 and Helper.color.transparent or Helper.color.darkgrey,
								highlightColor = #orig.menu.actions[subsection.id] > 0 and Helper.defaultButtonHighlightColor or Helper.defaultUnselectableButtonHighlightColor,
								mouseOverText = (#orig.menu.actions[subsection.id] > 0) and "" or orig.menu.forceSubSection[subsection.id]
							}):setText(subsection.text, { color = Helper.color.white }):setIcon("table_arrow_inv_right", { scaling = false, width = iconHeight, height = iconHeight, x = orig.menu.width - iconHeight })
							row[1].handlers.onClick = function () return orig.menu.handleSubSectionOption(data) end
							height = height + row:getHeight() + Helper.borderSize
						end
					end
				elseif #orig.menu.actions[section.id] > 0 then
					height = height + capi.addSectionTitle(ftable, section, first)
					first = false
					local availabletextwidth
					if capi.IsSectionSelectedOrders(section.id) or capi.IsSectionTradeOrders(section.id) or capi.IsSectionSelectedAssignments(section.id) or capi.IsSectionPlayerInteraction(section.id) or capi.IsSectionTrade(section.id) then
						local maxtextwidth = 0
						for _, entry in ipairs(orig.menu.actions[section.id]) do
							if not entry.hidetarget then
								maxtextwidth = math.max(maxtextwidth, C.GetTextWidth(entry.text .. " ", Helper.standardFont, Helper.scaleFont(Helper.standardFont, capi.config.entryFontSize, true)))
							end
						end
						availabletextwidth = orig.menu.width - maxtextwidth - 2 * Helper.scaleX(capi.config.entryX) - Helper.borderSize
					end

					for _, entry in ipairs(orig.menu.actions[section.id]) do
						if entry.active == nil then
							entry.active = true
						end
						local row = ftable:addRow(true, { bgColor = Helper.color.transparent })
						local button = row[1]:setColSpan(2):createButton({
							bgColor = entry.active and Helper.color.transparent or Helper.color.darkgrey,
							highlightColor = entry.active and Helper.defaultButtonHighlightColor or Helper.defaultUnselectableButtonHighlightColor,
							mouseOverText = entry.mouseOverText
						}):setText(entry.text, { color = entry.active and Helper.color.white or Helper.color.lightgrey })
						button.properties.uiTriggerID = entry.type
						if capi.IsSectionSelectedOrders(section.id) or capi.IsSectionTradeOrders(section.id) or capi.IsSectionSelectedAssignments(section.id) or capi.IsSectionPlayerInteraction(section.id) or capi.IsSectionTrade(section.id) then
							if not entry.hidetarget then
								local text2 = ""
								if entry.text2 then
									text2 = entry.text2
								else
									if (capi.IsSectionTradeOrders(section.id) or capi.IsSectionTrade(section.id)) and entry.buildstorage then
										text2 = orig.menu.texts.buildstorageName
									else
										text2 = orig.menu.texts.targetBaseName or orig.menu.texts.targetShortName
									end
								end
								text2 = TruncateText(text2, button.properties.text.font, Helper.scaleFont(button.properties.text.font, button.properties.text.fontsize, button.properties.scaling), availabletextwidth)
								button:setText2(text2, { halign = "right", color = orig.menu.colors.target })
								if entry.mouseOverText == nil then
									button.properties.mouseOverText = entry.text .. " " .. orig.menu.texts.targetName
								end
							end
						end
						if entry.active then
							row[1].handlers.onClick = entry.script
						end
						height = height + row:getHeight() + Helper.borderSize
					end
				end
			end
		end
		if first then
			local row = ftable:addRow(true, { bgColor = Helper.color.transparent })
			local button = row[1]:setColSpan(2):createButton({ active = false, bgColor = Helper.color.darkgrey }):setText("---", { halign = "center", color = Helper.color.red })
		end
	end

	ftable:setSelectedRow(orig.menu.selectedRows.contentTable)
	orig.menu.selectedRows.contentTable = nil

	return ftable
end

function capi.prepareSections()
	orig.menu.actions = {}
	for _, section in ipairs(capi.config.sections) do
		if section.subsections then
			for _, subsection in ipairs(section.subsections) do
				orig.menu.actions[subsection.id] = {}
			end
		else
			orig.menu.actions[section.id] = {}
		end
	end
end


local function init()
   for _, menu in ipairs(Menus) do
       if menu.name == "InteractMenu" then
             orig.menu = menu -- save entire menu, for other helper function access
       	     orig.insertLuaAction = menu.insertLuaAction -- save original function
       	     menu.insertLuaAction = capi.InsertLuaAction -- replace called function with you own
			 orig.menu.processSelectedPlayerShips = menu.processSelectedPlayerShips
			 menu.processSelectedPlayerShips = capi.processSelectedPlayerShips
			 orig.menu.addSectionTitle = menu.addSectionTitle
			 menu.addSectionTitle = capi.addSectionTitle
			 orig.menu.createContentTable = menu.createContentTable
			 menu.createContentTable = capi.createContentTable
			 orig.menu.prepareSections = menu.prepareSections
			 menu.prepareSections = capi.prepareSections
          break
      end
   end
   
   orig.menu.possibleorders = {
		["Attack"] = false,
		["AttackInRange"] = false,
		["Board"] = false,
		["Collect"] = false,
		["CollectDropsInRadius"] = false,
		["DeployObjectAtPosition"] = false,
		["DockAndWait"] = false,
		["Explore"] = false,
		["ExploreUpdate"] = false,
		["Flee"] = false,
		["Follow"] = false,
		["MiningPlayer"] = false,
		["MoveWait"] = false,
		["Player_DockToTrade"] = false,
		["ProtectStation"] = false,
		["Repair"] = false,
	}
	
	
	capi.possibleorders = orig.menu.possibleorders
	capi.forceSubSection = orig.menu.forceSubSection
	--orig.menu.possibleorders = capi.possibleorders
	
	
end

init()

User avatar
Shuulo
Posts: 1629
Joined: Mon, 14. Apr 08, 17:03
x4

Re: [API/GUIDE] How to mod the UI (_G Workaround and Right Click API) v0.32 (02/27/19))

Post by Shuulo » Fri, 8. Mar 19, 18:40

Whenever G workaround is in my extensions folder launching game crashes my PC. Anyone encountered that?

Misunderstood Wookie
Posts: 377
Joined: Mon, 15. Mar 04, 08:07
x4

Re: [API/GUIDE] How to mod the UI (_G Workaround and Right Click API) v0.32 (02/27/19))

Post by Misunderstood Wookie » Mon, 8. Apr 19, 06:41

Any able to help me fix https://www.nexusmods.com/x4foundations/mods/249 to work with 0.32
it was working now it somehow is not working.
*modified*
*X3 LiteCube User*
MOD GemFX Real Space Shaders
MOD Variety and Rebalance Overhaul Icon Pack
I lost my Hans and should not be flying Solo.
Image

taintedxodus
Posts: 28
Joined: Fri, 2. Mar 07, 00:58
x4

Re: [API/GUIDE] How to mod the UI (_G Workaround and Right Click API) v0.32 (02/27/19))

Post by taintedxodus » Sat, 13. Apr 19, 23:25

ledhead900 wrote:
Mon, 8. Apr 19, 06:41
Any able to help me fix https://www.nexusmods.com/x4foundations/mods/249 to work with 0.32
it was working now it somehow is not working.
It is working for me so ill show what should be for it to work.
EHM3_factionObj_and_Sect_Colours.xml is the only file that changed, it should look like this.

Code: Select all

<?xml version="1.0" encoding="utf-8" ?>
<mdscript name="EnhancedHolomap3-startup" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="md.xsd">
  <cues>
    <cue name="Register_factionspecific_objectcolours" version="1">
      <conditions>
        <event_cue_completed cue="md.G_Work_Around.Init" />
      </conditions>
      <actions>
		<raise_lua_event name="'RegisterAddon'" param="'extensions.EHM3_factionObj_and_Sect_Colours.EHM3_factionObj_and_Sect_Colours'"/>
      </actions>
    </cue>
    <cue name="Feedback_Wanted">
      <conditions>
        <event_cue_completed cue="Register_factionspecific_objectcolours"/>
      </conditions>
      <actions>
        <debug_text text="'Register_factionspecific_objectcolours Cue Loaded'" filter="error"/>
        <reset_cue cue="Register_factionspecific_objectcolours"/>
        <reset_cue cue="Feedback_Wanted"/>
      </actions>
    </cue>
  </cues>
</mdscript>

Misunderstood Wookie
Posts: 377
Joined: Mon, 15. Mar 04, 08:07
x4

Re: [API/GUIDE] How to mod the UI (_G Workaround and Right Click API) v0.32 (02/27/19))

Post by Misunderstood Wookie » Sun, 14. Apr 19, 15:46

Yea that works, seems the Nexus version is outdated had to build the cat file with what you posted.
*modified*
*X3 LiteCube User*
MOD GemFX Real Space Shaders
MOD Variety and Rebalance Overhaul Icon Pack
I lost my Hans and should not be flying Solo.
Image

User avatar
020779
Posts: 7
Joined: Sat, 28. May 11, 06:57
x4

Re: [API/GUIDE] How to mod the UI (_G Workaround and Right Click API) v0.32 (02/27/19))

Post by 020779 » Sun, 14. Apr 19, 22:24

Seems something broken on 2.50 beta1

Right-click menu don't open on player owned plots, with\from player ship selected.

Berserk Knight
Posts: 398
Joined: Tue, 17. Dec 13, 01:34
x4

Re: [API/GUIDE] How to mod the UI (_G Workaround and Right Click API) v0.32 (02/27/19))

Post by Berserk Knight » Sun, 14. Apr 19, 23:39

020779 wrote:
Sun, 14. Apr 19, 22:24
Seems something broken on 2.50 beta1

Right-click menu don't open on player owned plots, with\from player ship selected.
Please use the beta to actually test the patch itself so EgoSoft can fix THEIR stuff first.
(I don't post updates of my mods for beta patches specifically for this reason, despite tracking every change and constantly keeping the code up to date.)

morbideth wrote:
Wed, 2. Jan 19, 07:33
  • You may NOT: Host these files elsewhere without either my permission or if I have been inactive on these forums for over a month.
With this clause, I can probably post an updated version somewhere, since it's been about a month and a half. (But I refuse to do so while the patch is still in beta.)

I hope morbideth is okay. The last post (on a different thread) indicated they weren't feeling well.

taintedxodus
Posts: 28
Joined: Fri, 2. Mar 07, 00:58
x4

Re: [API/GUIDE] How to mod the UI (_G Workaround and Right Click API) v0.32 (02/27/19))

Post by taintedxodus » Mon, 15. Apr 19, 00:28

You likely can put it in this thread as DeadMorOz did, or just the updated code...

Endeavour79
Posts: 287
Joined: Fri, 29. Nov 13, 23:14
x4

Re: [API/GUIDE] How to mod the UI (_G Workaround and Right Click API) v0.32 (02/27/19))

Post by Endeavour79 » Sat, 27. Apr 19, 05:13

Would need an update for this mods.
Breaks gameplay UI in 2.50 beta versions.

Misunderstood Wookie
Posts: 377
Joined: Mon, 15. Mar 04, 08:07
x4

Re: [API/GUIDE] How to mod the UI (_G Workaround and Right Click API) v0.32 (02/27/19))

Post by Misunderstood Wookie » Sat, 27. Apr 19, 17:26

Best to just presume every update is going to break this, as it usually does.
there really are not that many mods I use which rely on this, the main reason I used this was to get the map colours for icons and faction names to match the sector colours for the their respective races
*modified*
*X3 LiteCube User*
MOD GemFX Real Space Shaders
MOD Variety and Rebalance Overhaul Icon Pack
I lost my Hans and should not be flying Solo.
Image

Berserk Knight
Posts: 398
Joined: Tue, 17. Dec 13, 01:34
x4

Re: [API/GUIDE] How to mod the UI (_G Workaround and Right Click API) v0.32 (02/27/19))

Post by Berserk Knight » Thu, 30. May 19, 05:06

I made a v0.33 for patch 2.50, uploaded at Nexus.

anonymouz
Posts: 4
Joined: Wed, 29. May 19, 14:41

Re: [API/GUIDE] How to mod the UI (_G Workaround and Right Click API) v0.32 (02/27/19))

Post by anonymouz » Mon, 3. Jun 19, 12:31

Where is the so called "Cheat Menu" on the Map, described in the first Post?
I have all 3 Tools added, activated and they running fine on x4f 2.21 - but i cant find the Cheat Menu for testing some things

Berserk Knight
Posts: 398
Joined: Tue, 17. Dec 13, 01:34
x4

Re: [API/GUIDE] How to mod the UI (_G Workaround and Right Click API) v0.32 (02/27/19))

Post by Berserk Knight » Thu, 17. Oct 19, 15:22

Uploaded an updated Right Click API v0.34 for patch 2.60, at Nexus.
Only minor changes made by EgoSoft this time. (Exclusion of drones when giving orders.)

XTC0R
Posts: 401
Joined: Sat, 1. Dec 18, 19:58
x4

Re: [API/GUIDE] How to mod the UI (_G Workaround and Right Click API) v0.32 (02/27/19))

Post by XTC0R » Thu, 21. Nov 19, 18:07

Berserk Knight wrote:
Thu, 17. Oct 19, 15:22
Uploaded an updated Right Click API v0.34 for patch 2.60, at Nexus.
Only minor changes made by EgoSoft this time. (Exclusion of drones when giving orders.)
Since Beta 3.0 the Right Click API mod prevents the right click on ship context menu to show up. I had to remove the mod to get the contetx menu back.

ErdeFB
Posts: 22
Joined: Sun, 20. Oct 13, 21:49
x4

Re: [API/GUIDE] How to mod the UI (_G Workaround and Right Click API) v0.32 (02/27/19))

Post by ErdeFB » Sun, 24. Nov 19, 23:07

Can confirm non-functional. Hopefully this gets updated or even better, Egosoft makes it redundant with a patch. Here's hoping. :D

sdfg
Posts: 23
Joined: Mon, 14. Oct 13, 22:40

Re: [API/GUIDE] How to mod the UI (_G Workaround and Right Click API) v0.32 (02/27/19))

Post by sdfg » Tue, 11. Feb 20, 16:41

Does anyone know any workaround for 3.0?

Berserk Knight
Posts: 398
Joined: Tue, 17. Dec 13, 01:34
x4

Re: [API/GUIDE] How to mod the UI (_G Workaround and Right Click API) v0.32 (02/27/19))

Post by Berserk Knight » Tue, 31. Mar 20, 18:12

Uploaded an updated Right Click API v0.35 for patch 3.00, at Nexus.

Post Reply

Return to “X4: Foundations - Scripts and Modding”