[SOLVED] Parsing required subsystems logic

Here’s an example of what a vaygr research item might look like:

{
	Name =					"ShipyardBUILDSPEEDUpgrade1",
	RequiredResearch =		"",
	RequiredSubSystems =	"Research | CapShipProduction & Hyperspace",
	RequireTag = 			"VaygrBuilder",  
	Cost = 					1000,
	Time = 					95,
	DisplayedName =			"$7825",
	DisplayPriority =		65,
	Description =			"$7826",
	UpgradeType =			Modifier,
	TargetType =			Ship,
	TargetName =			"Vgr_ShipYard",
	UpgradeName =			"BUILDSPEED",
	UpgradeValue =			1.3,
	Icon =					Icon_Build,
	ShortDisplayedName =	"$7240",
}

A gamerule in my mod disables certain modules, but not others. How do I parse out using a script the requirement for a module in the RequiredSubSystems field? I need to be able to do this no matter what other modules are listed in that field, no matter the order, and no matter what logical operators (& and |) are used. Has anyone attempted this in the past? I suspect it may be enough to strip the module name and the immediately-preceding operator since they are meant to be read from left to right. Is this correct? Thanks.

PS. Does the game ever use parentheses to group items together?

I discovered the standard string library is not available here, so I may be screwed.

The only thing I can think of is to add new fields to the table:

{
	Name =					"ShipyardBUILDSPEEDUpgrade1",
	RequiredResearch =		"",
	RequiredSubSystems =	"Research | CapShipProduction & Hyperspace",
	RequireTag = 			"VaygrBuilder",
	ReqSubNoRch =			"CapShipProduction & Hyperspace",
	ReqSubNoHyp =			"Research | CapShipProduction",
	ReqSubNoRchNoHyp =		"CapShipProduction",
	Cost = 					1000,
	Time = 					95,
	DisplayedName =			"$7825",
	DisplayPriority =		65,
	Description =			"$7826",
	UpgradeType =			Modifier,
	TargetType =			Ship,
	TargetName =			"Vgr_ShipYard",
	UpgradeName =			"BUILDSPEED",
	UpgradeValue =			1.3,
	Icon =					Icon_Build,
	ShortDisplayedName =	"$7240",
}

Except, I have four parameters that work like this, for a total of 16 possible combinations of states, each needing its own field. If I add another parameter then I will need 32 fields.

:frowning:

Another solution is to write external tools (written in Python for instance) that spit out all the build/research tables.

I think all I need to do is remove the relevant keyword as well as the logical operator to the left of it using some string operation, except when the keyword is on the far left of the string in which case I need to remove the operator directly to the right of it. I have not confirmed yet whether parentheses are ever used to group logical statements together.

A single required item may also be listed, in which case no operator at all would be used.

Am I approaching the problem correctly or did I overlook something?

I don’t understand the specifics of what you are trying to do, but something you can try is using lua to determine your string by hopefully making a global somewhere which is in the .subs scope (unsure of the possibility of this, more of an idea) and just add it to the table, for a crude example:

local resSubSysStr = "Research | CapShipProduction & Hyperspace"

if gamemode == "noHyperspace" then
   resSubSysStr = "Research | CapShipProduction"
elseif gamemode == "noResearch" then
   resSubSysStr = "CapShipProduction & Hyperspace"
elseif gamemode == "noResearchNoHyperspace" then
  resSubSysStr = "CapShipProduction"
end

{
	Name =					"ShipyardBUILDSPEEDUpgrade1",
	RequiredResearch =		"",
	RequiredSubSystems =	resSubSysStr,
	RequireTag = 			"VaygrBuilder",  
	Cost = 					1000,
	Time = 					95,
	DisplayedName =			"$7825",
	DisplayPriority =		65,
	Description =			"$7826",
	UpgradeType =			Modifier,
	TargetType =			Ship,
	TargetName =			"Vgr_ShipYard",
	UpgradeName =			"BUILDSPEED",
	UpgradeValue =			1.3,
	Icon =					Icon_Build,
	ShortDisplayedName =	"$7240",
}

I would have to repeat this many times since each build and research has different requirements.

True to a degree, but if you get crafty you can do it like this. I used my brain for a millisecond and realised this is being done for research items, which means this theory is very possible and the following code would be in def_reserach.lua after doscanpath("…") of your race/s (bar the example research item at the beginning).

--  example research item
{
	Name =					"ShipyardBUILDSPEEDUpgrade1",
	RequiredResearch =		"",
	RequiredSubSystems =	"",
    ReqSubName = "NAME OF SUB REQUIRED, LIKE CapShipProduction", -- I added this
	RequireTag = 			"VaygrBuilder",  
	Cost = 					1000,
	Time = 					95,
	DisplayedName =			"$7825",
	DisplayPriority =		65,
	Description =			"$7826",
	UpgradeType =			Modifier,
	TargetType =			Ship,
	TargetName =			"Vgr_ShipYard",
	UpgradeName =			"BUILDSPEED",
	UpgradeValue =			1.3,
	Icon =					Icon_Build,
	ShortDisplayedName =	"$7240",
}

--  def_research.lua
local gamemodeType = GetGameSettingAsString("????") -- (something like this maybe)

for i,e in research do
  local reqSubSys = "Research | Hyperspace & "..e.ReqSubName
  
  if gamemodeType == "noHyperspace" then
     reqSubSys = "Research | "..e.ReqSubName
  elseif gamemodeType == "noResearch" then
     reqSubSys = "Hyperspace & "..e.ReqSubName
  elseif gamemodeType == "noResearchNoHyperspace" then
    reqSubSys = e.ReqSubName
  end

 e.RequiredSubSystems = reqSubSys
end

I ended up writing Python scripts to process spreadsheet data and output Lua tables.

2 Likes

I’m pretty sure parenthesis work. I don’t know if you can make it all complicated with multiple layers but this seems to work for example:

RequiredResearch = “(Fed_TMP_CorvetteTech | Fed_TMP_CorvetteTech_F) & !BuildOff”,

1 Like

I keep wondering if there’s a Python library that already parses stuff similar to that.