ialdabaoth Posted March 13, 2014 Share Posted March 13, 2014 Have you checked output_log.txt for errors when your cfg is applied? Or to see if something else is adding new engine modules in?... I had two different versions of Module Manager installed.I'll just go sit over here now. Quote Link to comment Share on other sites More sharing options...
IronGremlin Posted March 13, 2014 Share Posted March 13, 2014 Hey guys, the link in the OP doesn't seem to be functional, does anyone know where I could get a copy of MM 1.5.6 ? Quote Link to comment Share on other sites More sharing options...
bagelbyheart Posted March 13, 2014 Share Posted March 13, 2014 I'm seeing the same thing =\ Quote Link to comment Share on other sites More sharing options...
Starwaster Posted March 13, 2014 Share Posted March 13, 2014 Hey guys, the link in the OP doesn't seem to be functional, does anyone know where I could get a copy of MM 1.5.6 ?Not functional or you get a security warning? Quote Link to comment Share on other sites More sharing options...
bagelbyheart Posted March 13, 2014 Share Posted March 13, 2014 Security warning followed by not functional. Chrome reported "Failed - No File" Quote Link to comment Share on other sites More sharing options...
IronGremlin Posted March 13, 2014 Share Posted March 13, 2014 Both, actually Quote Link to comment Share on other sites More sharing options...
NathanKell Posted March 13, 2014 Share Posted March 13, 2014 Sarbian said elsewhere his site is down and he's scrambling to fix. For now you can get MM 1.5.6 from, say, the Real Fuels mod in my sig, or from the latest FAR. Quote Link to comment Share on other sites More sharing options...
bagelbyheart Posted March 13, 2014 Share Posted March 13, 2014 You are a saint sir! Quote Link to comment Share on other sites More sharing options...
Tallinu Posted March 17, 2014 Share Posted March 17, 2014 I'm trying to update a KAS config[...]and this is my MM config:@PART[KAS_ContainerBay1]:Final{ !scale !mesh @rescaleFactor = 1 @node_stack_top = 0.0, -0.35, 0.0, 0.0, 1.0, 0.0, 0 @node_stack_bottom = 0.0, -0.4, 0.0, 0.0, 1.0, 0.0, 0 @node_attach = 0.0, -0.4, 0.0, 0.0, -1.0, 0.0 MODEL { model = KAS/Parts/containerBay1/containerBay1 scale = 0.5,0.5,0.5 } MODULE { name = KASModuleGrab evaPartPos = (0.0, 0.10, -0.15) evaPartDir = (0,0,-1) customGroundPos = true dropPartPos = (0.0, 0.0, -0.55) dropPartRot = (-10.0, 0.0, 0.0) attachOnPart = True attachOnEva = False attachOnStatic = False attachSendMsgOnly = False }}It looks like you're trying to do what I just tried to do with the container storage rack, but I found that no matter what attach node I tried, it always sank halfway into whatever I tried to attach it to (part or terrain). Have you had any luck getting it to work? Quote Link to comment Share on other sites More sharing options...
CaptRobau Posted March 17, 2014 Share Posted March 17, 2014 I'm trying to change some things to the ion engine. Yet for some reason not everything is working correctly:@PART[ionEngine]{ @category = Propulsion @MODULE[ModuleEngines] { @maxThrust = 1.25 @PROPELLANT[ElectricCharge] { @ratio = 0.8 DrawGauge = true } }}The category change works, but the engine stuff doesn't. What am I doing wrong? Quote Link to comment Share on other sites More sharing options...
NathanKell Posted March 17, 2014 Share Posted March 17, 2014 Check ksp.log, it will tell you. Maybe you're running Hot Rockets and so the engine module name was already changed? Quote Link to comment Share on other sites More sharing options...
CaptRobau Posted March 17, 2014 Share Posted March 17, 2014 Ah yes, I'm running HotRockets. Makes sense now. Quote Link to comment Share on other sites More sharing options...
KerbMav Posted March 17, 2014 Share Posted March 17, 2014 From where did I get a 1.5.7 version of this mod??OK, I know I got it from a different mod, but now I am confused that you are still at 1.5.6 here ...Edith tells me, it was DRE. Quote Link to comment Share on other sites More sharing options...
heralo Posted March 17, 2014 Share Posted March 17, 2014 It looks like you're trying to do what I just tried to do with the container storage rack, but I found that no matter what attach node I tried, it always sank halfway into whatever I tried to attach it to (part or terrain). Have you had any luck getting it to work?Yes, I think so. I've played with it in place the last few days and haven't noticed any issues. I can PM you the cfg when I get home from work if you want. Quote Link to comment Share on other sites More sharing options...
KerbMav Posted March 17, 2014 Share Posted March 17, 2014 If I am already using :Final to add some TechRequired entries, how can I make sure that everything I missed gets edited by this here:@PART[*]:HAS[~TechRequired[]]:Final{ TechRequired=advScienceTech}? Quote Link to comment Share on other sites More sharing options...
Starwaster Posted March 18, 2014 Share Posted March 18, 2014 If I am already using :Final to add some TechRequired entries, how can I make sure that everything I missed gets edited by this here:@PART[*]:HAS[~TechRequired[]]:Final{ TechRequired=advScienceTech}?This is what I use.@PART[*]:HAS[#module[Part],~TechRequired[]]:Final{ TechRequired = advRocketry entryCost = 1000}Really the same as what you have except that it only adds it to Parts. (probably some unnecessary weeding; 'Winglets' would get weeded out...)entryCost is superfluous... NOW. In the future it'll probably have a use. Quote Link to comment Share on other sites More sharing options...
Crater Posted March 18, 2014 Share Posted March 18, 2014 If I am already using :Final to add some TechRequired entries, how can I make sure that everything I missed gets edited by this here:@PART[*]:HAS[~TechRequired[]]:Final{ TechRequired=advScienceTech}?Make sure that the config file with that in is alphabetically last, so stick it in a folder called "GameData/ZZZZ_Final_Mods".All of the configs are parsed in find-them order, then all the :Final ones, in the same order. Quote Link to comment Share on other sites More sharing options...
Climberfx Posted March 18, 2014 Share Posted March 18, 2014 I love this mod. Thank you for your work done. Quote Link to comment Share on other sites More sharing options...
ialdabaoth Posted March 20, 2014 Share Posted March 20, 2014 Sarbian: Node[Name, Tag] is useless, because almost no one uses 'tag', and if you don't have a tag, you CAN'T pick anything but the first node.Originally, it was supposed to work identically to value keys - i.e., Node[Name, index]So you should be able to say MODULE[ModuleEnginesFX, 1] {}Here's a partial rewrite that fixes it: public static ConfigNode FindConfigNodeIn(ConfigNode src, string nodeType, string nodeName = null, int index) {#if DEBUG if (nodeTag == null) print ("Searching node for " + nodeType + "[" + nodeName + "]"); else print ("Searching node for " + nodeType + "[" + nodeName + "," + nodeTag + "]");#endif int found = 0; foreach (ConfigNode n in src.GetNodes(nodeType)) { if (nodeName == null && nodeTag == null) return n; if (n.HasValue("name") && WildcardMatch(n.GetValue("name"), nodeName)) { if (found == index) {#if DEBUG print ("found node " + found.ToString() + "!");#endif return n; } else { found++; } } } return null; } public static ConfigNode ModifyNode(ConfigNode original, ConfigNode mod) { if (!IsSane(original) || !IsSane(mod)) { print("[ModuleManager] A node has an empty name. Skipping it. Original: " + original.name); return original; } ConfigNode newNode = original.CreateCopy(); foreach (ConfigNode.Value val in mod.values) { if (val.name[0] != '@' && val.name[0] != '!' && val.name[0] != '%') newNode.AddValue(val.name, val.value); else { // Parsing: Format is @key = value or @key,index = value string valName = val.name.Substring(1); int index = 0; if (valName.Contains(",")) { int.TryParse(valName.Split(',')[1], out index); valName = valName.Split(',')[0]; } // index is useless right now, but some day it might not be. if (val.name[0] == '@') newNode.SetValue(valName, val.value, index); else if (val.name[0] == '!') newNode.RemoveValues(valName); else if (val.name[0] == '%') { newNode.RemoveValues(valName); newNode.AddValue(valName, val.value); } } } foreach (ConfigNode subMod in mod.nodes) { subMod.name = RemoveWS(subMod.name); if (subMod.name[0] != '@' && subMod.name[0] != '!' && subMod.name[0] != '%' && subMod.name[0] != '$') newNode.AddNode(subMod); else { ConfigNode subNode; //if (subMod.name[0] == '@' && subMod.name[0] != '%') // subNode = null; if (subMod.name.Contains("[")) { // format @NODETYPE[Name] {...} or @NODETYPE[Name, index] {...} or ! instead of @ string nodeType = subMod.name.Substring(1).Split('[')[0]; string nodeName = subMod.name.Split('[')[1].Replace("]", ""); int index = 0; if (nodeName.Contains(",")) { // format @NODETYPE[Name, index] {...} or ! instead of @ int.TryParse(nodeType.Split(',')[1], out index); nodeName = nodeName.Split(',')[0]; } subNode = FindConfigNodeIn(newNode, nodeType, nodeName, index); } else { // format @NODETYPE {...} or ! instead of @ string nodeType = subMod.name.Substring(1); // format @NODETYPE,N {...} or ! instead of @ // The problem with ! is that the index is messed up // So the patch need to take that into account // and lower the index for the next search int index = 0; if (nodeType.Contains(",")) { int.TryParse(nodeType.Split(',')[1], out index); nodeType = nodeType.Split(',')[0]; } ConfigNode[] subNodes = newNode.GetNodes(nodeType); if (subNodes.Length > index) subNode = subNodes[index]; else subNode = null; } if (subMod.name[0] == '@') { // find the original subnode to modify, modify it and add the modified. if (subNode != null) { ConfigNode newSubNode = ModifyNode(subNode, subMod); newNode.nodes.Add(newSubNode); } else print("[ModuleManager] Could not find node to modify: " + subMod.name); } if (subMod.name[0] == '%') { // if the original node exist add it if (subNode != null) { ConfigNode newSubNode = ModifyNode(subNode, subMod); newNode.nodes.Add(newSubNode); } else { // if not add the mod node without the % in its name // This part is messy. ialdabaoth is right, i need to rewrite. string type; string name; if (subMod.name.Contains("[")) { type = subMod.name.Substring(1).Split('[')[0]; name = subMod.name.Split('[')[1].Replace("]", ""); } else { type = subMod.name.Substring(1); name = null; } ConfigNode copy = new ConfigNode(type); if (name != null) copy.AddValue("name", name); ConfigNode newSubNode = ModifyNode(copy, subMod); newNode.nodes.Add(newSubNode); } } if (subMod.name[0] == '$') { // find the original subnode to copy, add the original, add the the modified copy. if (subNode != null) { newNode.nodes.Add(subNode); ConfigNode newSubNode = ModifyNode(subNode, subMod); newNode.nodes.Add(newSubNode); } else print("[ModuleManager] Could not find node to copy: " + subMod.name); } if (subNode != null) newNode.nodes.Remove(subNode); } } return newNode; } Quote Link to comment Share on other sites More sharing options...
ialdabaoth Posted March 20, 2014 Share Posted March 20, 2014 ALSO: I can't test it right now, but the following should allow you to apply patches to ALL subnodes that wildcard-match, rather than merely the first: public static ConfigNode ModifyNode(ConfigNode original, ConfigNode mod) { if (!IsSane(original) || !IsSane(mod)) { print("[ModuleManager] A node has an empty name. Skipping it. Original: " + original.name); return original; } ConfigNode newNode = original.CreateCopy(); foreach (ConfigNode.Value val in mod.values) { if (val.name[0] != '@' && val.name[0] != '!' && val.name[0] != '%') newNode.AddValue(val.name, val.value); else { // Parsing: Format is @key = value or @key,index = value string valName = val.name.Substring(1); int index = 0; if (valName.Contains(",")) { int.TryParse(valName.Split(',')[1], out index); valName = valName.Split(',')[0]; } // index is useless right now, but some day it might not be. if (val.name[0] == '@') newNode.SetValue(valName, val.value, index); else if (val.name[0] == '!') newNode.RemoveValues(valName); else if (val.name[0] == '%') { newNode.RemoveValues(valName); newNode.AddValue(valName, val.value); } } } foreach (ConfigNode subMod in mod.nodes) { subMod.name = RemoveWS(subMod.name); if (subMod.name[0] != '@' && subMod.name[0] != '!' && subMod.name[0] != '%' && subMod.name[0] != '$') newNode.AddNode(subMod); else { ConfigNode subNode; //if (subMod.name[0] == '@' && subMod.name[0] != '%') // subNode = null; string nodeType; string nodeName; string indexes = ""; int index; if (subMod.name.Contains("[")) { nodeType = subMod.name.Substring(1).Split('[')[0]; nodeName = subMod.name.Split('[')[1].Replace("]", ""); indexes = ""; index = 0; // format @NODETYPE[Name] {...} or @NODETYPE[Name], index {...} or ! instead of @ if (nodeName.Contains(",")) { // format @NODETYPE[Name], index {...} or ! instead of @ nodeName = nodeName.Split(',')[0]; indexes = nodeType.Split(',')[1]; } } else { // format @NODETYPE {...} or ! instead of @ nodeType = subMod.name.Substring(1); nodeName = null; indexes = ""; index = 0; // format @NODETYPE,N {...} or ! instead of @ // The problem with ! is that the index is messed up // So the patch need to take that into account // and lower the index for the next search if (nodeType.Contains(",")) { nodeType = nodeType.Split(',')[0]; indexes = nodeType.Split(','); } ConfigNode[] subNodes = newNode.GetNodes(nodeType); if (subNodes.Length > index) subNode = subNodes[index]; else subNode = null; } // an index of '*' means apply to ALL subnodes that match if (indexes == "*" || indexes == "") index = 0; else int.TryParse(indexes, out index); bool moreToDo = true; do { subNode = FindConfigNodeIn(newNode, nodeType, nodeName, index); if (subNode != null) { if (subMod.name[0] == '@') { // find the original subnode to modify, modify it and add the modified. if (subNode != null) { ConfigNode newSubNode = ModifyNode(subNode, subMod); newNode.nodes.Add(newSubNode); } else print("[ModuleManager] Could not find node to modify: " + subMod.name); } if (subMod.name[0] == '%') { // if the original node exist add it if (subNode != null) { ConfigNode newSubNode = ModifyNode(subNode, subMod); newNode.nodes.Add(newSubNode); } else { // if not add the mod node without the % in its name // This part is messy. ialdabaoth is right, i need to rewrite. string type; string name; if (subMod.name.Contains("[")) { type = subMod.name.Substring(1).Split('[')[0]; name = subMod.name.Split('[')[1].Replace("]", ""); } else { type = subMod.name.Substring(1); name = null; } ConfigNode copy = new ConfigNode(type); if (name != null) copy.AddValue("name", name); ConfigNode newSubNode = ModifyNode(copy, subMod); newNode.nodes.Add(newSubNode); } } if (subMod.name[0] == '$') { // find the original subnode to copy, add the original, add the the modified copy. if (subNode != null) { newNode.nodes.Add(subNode); ConfigNode newSubNode = ModifyNode(subNode, subMod); newNode.nodes.Add(newSubNode); } else print("[ModuleManager] Could not find node to copy: " + subMod.name); } // an index of '*' means apply to ALL subnodes that match if (indexes == "*") index++; else moreToDo = false; } else { moreToDo = false; } } while (moreToDo); if (subNode != null) newNode.nodes.Remove(subNode); } } return newNode; } Quote Link to comment Share on other sites More sharing options...
ialdabaoth Posted March 21, 2014 Share Posted March 21, 2014 UPDATE! I just talked to sarbian; in his absence, I will be creating and releasing Module Manager 2.0.0I will do EVERYTHING I CAN not to break backwards compatibility, but no guarantees - there's a few cases where the current system does not provide an unambiguous configNode application sequence.Here is a preview of 2.0.0 syntax:1. Mod DefinitionsMOD { name = MyMod // this is the name of your mod version = 23 // this is the version of your mod. It must be a single number, that increases whenever you release a new version. plugin = MyMod\mymod.dll url = http://www.mymod.com/download NEEDS { // a 'NEEDS' block defines a dependency name = NeededMod // i.e., ModManager should throw an error if the correct version of NeededMod isn't installed. min_version = 15 // If NeededMod is installed, but the installed Version is 14 or lower, ModManager should throw an error. // if min_version is blank, defaults to -1 max_version = 9999 // If NeededMod is installed, but the installed Version is 10000 or higher, ModManager should throw an error. // if max_version is blank, defaults to a ridiculously large number (2 billion or so) error_message = MyMod version 23 requires NeededMod version 15 or higher. (Last tested version was 17). Please check $KSPFORUM:threads/75562-MyMod-Thread for details. } CONFLICTS { // a 'CONFLICTS' block is the opposite of a 'NEEDS' block. name = BadMod // i.e., ModManager should throw an error if a conflicting version of BadMod is installed. min_version = 11 // If BadMod is installed, but the installed Version is 10 or lower, ModManager should NOT throw an error. // if min_version is blank, defaults to -1 max_version = 13 // If BadMod is installed, but the installed Version is 14 or higher, ModManager should NOT throw an error. // if max_version is blank, defaults to a ridiculously large number (2 billion or so) }}If you do not include a Mod Definition with your mod, ModuleManager 2.0.0 WILL STILL WORK, but you (and other modders!) will not have access to any of the new fancy sequencing rules, or dependency checking. You'll only have access to the first-pass run and the :FINAL run.If you DO include a Mod Definition, ModuleManager 2.0.0 will do two awesome things for you:2. Dependency and Conflict CheckingModuleManager 2.0 will check dependencies, by which I mean it will look for any other MOD nodes that match your NEEDS {} and CONFLICTS {} nodes, and throw up a warning to the user that they need to resolve any dependencies or conflicts indicated.3. Per-Mod Patch SequencingModuleManager 2.0 will create three new passes for each MOD node it finds, that happen after the first-pass but before :FINAL. These passes look like this::BEFORE[MyMod]The :BEFORE[MyMod] pass happens first, and happens once for each mod. You can specify it one of two ways:@PART[some_part]:BEFORE[MyMod] // this config patch will ONLY be applied if any version of the MyMod mod is installed.{ // do stuff}if you require a specific version, you can do:@PART[some_part]:BEFORE[MyMod,23] // this config patch will ONLY be applied if version 23 or greater of the MyMod mod is installed.{ // do stuff}And if you need versions of MULTIPLE mods, you can do:@PART[some_part]:BEFORE[MyMod,23]:NEEDS[ModuleManager,200] // this config patch will ONLY be applied if version 23 or greater of the MyMod mod is installed, AND version 200 or greater of ModuleManager is installed.{ // do stuff}@PART[some_part]:BEFORE[MyMod,23]:NEEDS[!Firespitter] // this config patch will ONLY be applied if version 23 or greater of the MyMod mod is installed, AND no version of Firespitter is installed.{ // do stuff}:FOR[MyMod]The :FOR[MyMod] pass happens next, and happens once for each mod. It uses the same syntax:@PART[some_part]:FOR[MyMod] // this config patch will ONLY be applied any version of the MyMod mod is installed.{ // do stuff}@PART[some_part]:FOR[MyMod,23] // this config patch will ONLY be applied if version 23 or greater of the MyMod mod is installed.{ // do stuff}@PART[some_part]:FOR[MyMod,23]:NEEDS[ModuleManager,200]:NEEDS[!RealFuels,50] // this config patch will ONLY be applied if version 23 or greater of the MyMod mod is installed, AND version 200 or greater of ModuleManager is installed, AND version 50 or greater of RealFuels ISN'T installed.{ // do stuff}:AFTER[MyMod]The :AFTER[MyMod] pass happens next, and happens once for each mod. It uses the same syntax as above:@PART[some_part]:AFTER[MyMod] // this config patch will ONLY be applied if any version of the MyMod mod is installed{ // do stuff}@PART[some_part]:AFTER[MyMod,23]:NEEDS[!ModuleManager] // this config patch will ONLY be applied if version 23 or greater of the MyMod mod is installed, AND no version of ModuleManager is installed. Good luck with that.{ // do stuff}I'll continue to post here with progress. Quote Link to comment Share on other sites More sharing options...
GavinZac Posted March 21, 2014 Share Posted March 21, 2014 Looks like a very exciting expansion! Looking forward to learning some new skills. Quote Link to comment Share on other sites More sharing options...
sarbian Posted March 21, 2014 Author Share Posted March 21, 2014 Looks greats and it would solve a lot of the common problem when a lot of mods uses MMI have added the dev branch to my new Jenkins server. Anything pushed to dev will be compiled and made available here : http://ksp.sarbian.com/jenkins/job/ModuleManager%20Dev/ Quote Link to comment Share on other sites More sharing options...
Arrowmaster Posted March 22, 2014 Share Posted March 22, 2014 While I like the additions of more passes to better handle multiple mods making changes to the same parts, I don't like the syntax and BEFORE, FOR, and AFTER names. I think its just trying to bandaid a broken method of only 2 passes by adding 3 more.What about a way to link to link each file with @NODE definitions in it to a MOD and and define interactions such as this cfg file must be loaded before/after any files linked to OTHERMOD if its installed. I feel like without a way to define interactions between mods the problem will resurface again as more complex configs are used. To keep things simpler make everything in the same file that uses the new format load at the same time. Does this make any sense how im trying to explain it?I have a question about the version selection logic in this.@PART[some_part]:FOR[MyMod,23]:NEEDS[ModuleManager,200]:NEEDS[!RealFuels,50] // this config patch will ONLY be applied if version 23 or greater of the MyMod mod is installed, AND version 200 or greater of ModuleManager is installed, AND version 50 or greater of RealFuels ISN'T installed.{ // do stuff}Is there a way to say only load this if a version of MOD before X is installed or would that require something like this for only working on version 49 or lesser of RealFuels? Like this?@PART[some_part]:FOR[MyMod,23]:NEEDS[RealFuels]:NEEDS[!RealFuels,50]{ // do stuff}Why not just support comparison options with it defaulting to >= so something like this could be done? Make it support >= (default if none entered), >, =, <, and <=.@PART[some_part]:FOR[MyMod,23]:NEEDS[RealFuels,<50]{ // do stuff}Have you added in the abiltiy to use :HAS on subnodes? So we can select from multiple nodes without having to use the tags that nobody does or without knowing exactly which number references it. For example like this.@PART[*]{ @MODULE[foo]:HAS[#bar=baz] { // do stuff }}And I think some people wanted the ability to use other operators in #bar=baz to so stuff like #mass<0.05. Quote Link to comment Share on other sites More sharing options...
BudgetHedgehog Posted March 23, 2014 Share Posted March 23, 2014 (edited) Looking forward to 2.0.0!Quick question though: I want to move all RCS tanks to the Control tab, so I use the following@PART[*]:HAS[@RESOURCE[MonoPropellant]]:Final{ @category = Control}However, this moves all the command pods there as well. What syntax should I put that includes things with resource MonoPropellant but excludes ModuleCommand?EDIT: Am I right in thinking it would be @PART[*]:HAS[@RESOURCE[MonoPropellant]]:HAS[!MODULE[ModuleCommand]:Final{ @category = Control}? Edited March 23, 2014 by ObsessedWithKSP Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.