private void updateNodePositions(bool userInput) { float h = currentHeight * 0.5f; SSTUAttachNodeUtils.updateAttachNodePosition(part, part.FindAttachNode("top"), new Vector3(0, h, 0), Vector3.up, userInput); SSTUAttachNodeUtils.updateAttachNodePosition(part, part.FindAttachNode("bottom"), new Vector3(0, -h, 0), Vector3.down, userInput); }
private void updateAttachNodes(bool userInput) { topModule.model.updateAttachNodes(part, topNodeNames, userInput, ModelOrientation.TOP); bottomModule.model.updateAttachNodes(part, bottomNodeNames, userInput, ModelOrientation.BOTTOM); Vector3 pos = new Vector3(0, getTopFairingBottomY(), 0); SSTUSelectableNodes.updateNodePosition(part, noseInterstageNode, pos); AttachNode noseInterstage = part.FindAttachNode(noseInterstageNode); if (noseInterstage != null) { SSTUAttachNodeUtils.updateAttachNodePosition(part, noseInterstage, pos, Vector3.up, userInput); } float bottomFairingTopY = getBottomFairingTopY(); pos = new Vector3(0, bottomFairingTopY, 0); SSTUSelectableNodes.updateNodePosition(part, mountInterstageNode, pos); AttachNode mountInterstage = part.FindAttachNode(mountInterstageNode); if (mountInterstage != null) { SSTUAttachNodeUtils.updateAttachNodePosition(part, mountInterstage, pos, Vector3.down, userInput); } }
private void updateNodePositions(bool userInput) { float scale = getCurrentScale(); float topY = currentHeight; float innerY = internalNodePosition * scale; float bottomY = bottomNodePosition * scale; Vector3 bottomNodePOs = new Vector3(0, bottomY, 0); Vector3 innerNodePos = new Vector3(0, innerY, 0); Vector3 topNodePos = new Vector3(0, topY, 0); AttachNode node = part.FindAttachNode(bottomNodeName); if (node != null) { SSTUAttachNodeUtils.updateAttachNodePosition(part, node, bottomNodePOs, node.orientation, userInput); } node = part.FindAttachNode(internalNodeName); if (node != null) { SSTUAttachNodeUtils.updateAttachNodePosition(part, node, innerNodePos, node.orientation, userInput); } node = part.FindAttachNode(topNodeName); if (node != null) { SSTUAttachNodeUtils.updateAttachNodePosition(part, node, topNodePos, node.orientation, userInput); } }
protected virtual void updateAttachNodes(bool userInput) { currentNoseModule.updateAttachNodes(part, topNodeNames, userInput, ModelOrientation.TOP); currentMountModule.updateAttachNodes(part, bottomNodeNames, userInput, ModelOrientation.BOTTOM); AttachNode surface = part.srfAttachNode; if (surface != null) { Vector3 pos = currentMainTankModule.modelDefinition.surfaceNode.position * currentMainTankModule.currentDiameterScale; Vector3 rot = currentMainTankModule.modelDefinition.surfaceNode.orientation; SSTUAttachNodeUtils.updateAttachNodePosition(part, surface, pos, rot, userInput); } if (!String.IsNullOrEmpty(interstageNodeName)) { float y = currentMountModule.currentVerticalPosition + (currentMountModule.modelDefinition.fairingTopOffset * currentMountModule.currentHeightScale); Vector3 pos = new Vector3(0, y, 0); SSTUSelectableNodes.updateNodePosition(part, interstageNodeName, pos); AttachNode interstage = part.findAttachNode(interstageNodeName); if (interstage != null) { Vector3 orientation = new Vector3(0, -1, 0); SSTUAttachNodeUtils.updateAttachNodePosition(part, interstage, pos, orientation, userInput); } } }
public void updateAttachNodes(Part part, String[] nodeNames, bool userInput, ModelOrientation orientation) { if (nodeNames.Length == 1 && nodeNames[0] == "NONE") { return; } Vector3 basePos = new Vector3(0, currentVerticalPosition, 0); AttachNode node = null; AttachNodeBaseData data; int nodeCount = modelDefinition.attachNodeData.Length; int len = nodeNames.Length; Vector3 pos = Vector3.zero; Vector3 orient = Vector3.up; int size = 2; bool invert = (orientation == ModelOrientation.BOTTOM && modelDefinition.invertForBottom) || (orientation == ModelOrientation.TOP && modelDefinition.invertForTop); for (int i = 0; i < len; i++) { node = part.findAttachNode(nodeNames[i]); if (i < nodeCount) { data = modelDefinition.attachNodeData[i]; size = data.size; pos = data.position * currentHeightScale; if (invert) { pos.y = -pos.y; pos.x = -pos.x; } pos.y += currentVerticalPosition; orient = data.orientation; if (invert) { orient = -orient; } if (node == null)//create it { SSTUAttachNodeUtils.createAttachNode(part, nodeNames[i], pos, orient, size); } else//update its position { SSTUAttachNodeUtils.updateAttachNodePosition(part, node, pos, orient, userInput); } } else//extra node, destroy { if (HighLogic.LoadedSceneIsEditor || HighLogic.LoadedSceneIsFlight) { SSTUAttachNodeUtils.destroyAttachNode(part, node); } } } }
private void updateNodePositions(bool userInput) { AttachNode topNode = part.FindAttachNode("top"); AttachNode bottomNode = part.FindAttachNode("bottom"); float scale = currentDiameter / modelDiameter; float topY = topNodePosition * scale; float bottomY = bottomNodePosition * scale; Vector3 pos = new Vector3(0, topY, 0); SSTUAttachNodeUtils.updateAttachNodePosition(part, topNode, pos, topNode.orientation, userInput); pos = new Vector3(0, bottomY, 0); SSTUAttachNodeUtils.updateAttachNodePosition(part, bottomNode, pos, bottomNode.orientation, userInput); }
private void updateAttachNodes(bool userInput) { int len = modelGroups.Length; List <string> enabledNodeNames = new List <string>(); AttachNode attachNode; ModelSwitchGroup group; ModelSwitchData model; for (int i = 0; i < len; i++) { group = modelGroups[i]; model = group.enabledModel; if (!controlledNodes.Contains(group.parentNode)) { continue; } //not a node that we should touch... if (model == null || model.suppressNode) { continue; } enabledNodeNames.Add(group.parentNode); Vector3 pos = group.getModelRootTransform().position; pos = part.transform.InverseTransformPoint(pos); Vector3 rotation = group.getModelRootTransform().up; attachNode = part.findAttachNode(group.parentNode); if (attachNode == null) { attachNode = SSTUAttachNodeUtils.createAttachNode(part, group.parentNode, pos, rotation, 2); } else { SSTUAttachNodeUtils.updateAttachNodePosition(part, attachNode, pos, rotation, userInput); } } List <AttachNode> attachNodes = new List <AttachNode>(); attachNodes.AddRange(part.attachNodes); len = attachNodes.Count; for (int i = 0; i < len; i++) { attachNode = attachNodes[i]; if (!controlledNodes.Contains(attachNode.id)) { continue; } //not a node that we should touch... if (attachNode.attachedPart == null && !enabledNodeNames.Contains(attachNode.id)) { SSTUAttachNodeUtils.destroyAttachNode(part, attachNode); } } }
public void toggleNode() { AttachNode node = part.findAttachNode(nodeName); if (node == null) { currentlyEnabled = true; SSTUAttachNodeUtils.createAttachNode(part, nodeName, nodeDefaultPosition, nodeDefaultOrientation, 2); } else if (node.attachedPart == null) { currentlyEnabled = false; SSTUAttachNodeUtils.destroyAttachNode(part, node); } }
public void updateAttachNodePositions(bool userInput) { float h = height * 0.5f; AttachNode topNode = part.FindAttachNode("top"); if (topNode != null) { SSTUAttachNodeUtils.updateAttachNodePosition(part, topNode, new Vector3(topNode.position.x, h, topNode.position.z), topNode.orientation, userInput); } AttachNode bottomNode = part.FindAttachNode("bottom"); if (bottomNode != null) { SSTUAttachNodeUtils.updateAttachNodePosition(part, bottomNode, new Vector3(bottomNode.position.x, -h, bottomNode.position.z), bottomNode.orientation, userInput); } }
private void updateAttachNodes(bool userInput) { float standoffBottomZ = standoffModule.moduleBottom; Vector3 pos = new Vector3(-standoffBottomZ, 0, 0); AttachNode srfNode = part.srfAttachNode; if (srfNode != null) { SSTUAttachNodeUtils.updateAttachNodePosition(part, srfNode, pos, Vector3.right, userInput, 0); } AttachNode bottomNode = part.FindAttachNode("bottom"); if (bottomNode != null) { SSTUAttachNodeUtils.updateAttachNodePosition(part, bottomNode, pos, bottomNode.orientation, userInput, 0); } }
private void setTankDiameterFromEditor(float newDiameter, bool updateSymmetry) { float oldDiameter = prevTankDiameter; currentTankDiameter = newDiameter; restoreEditorFields(); updateEditorStats(true); SSTUAttachNodeUtils.updateSurfaceAttachedChildren(part, oldDiameter, newDiameter); if (updateSymmetry) { foreach (Part p in part.symmetryCounterparts) { p.GetComponent <SSTUModularFuelTank>().setTankDiameterFromEditor(newDiameter, false); } } SSTUStockInterop.fireEditorUpdate(); SSTUModInterop.onPartGeometryUpdate(part, true); }
private void updateAttachNodes(bool userInput) { AttachNode srf = part.srfAttachNode; if (srf != null) { float standoffHeight = standoffModule.model.currentHeight + currentScale * structureOffset; Vector3 pos = new Vector3(standoffHeight, 0, 0); SSTUAttachNodeUtils.updateAttachNodePosition(part, srf, pos, srf.orientation, userInput); } AttachNode btm = part.FindAttachNode("bottom"); if (btm != null) { float standoffHeight = standoffModule.model.currentHeight + currentScale * structureOffset; Vector3 pos = new Vector3(standoffHeight, 0, 0); SSTUAttachNodeUtils.updateAttachNodePosition(part, btm, pos, btm.orientation, userInput); } }
/// <summary> /// Update the attach node positions based on the current tank parameters. /// </summary> private void updateNodePositions(bool userInput) { AttachNode topNode = part.FindAttachNode("top"); if (topNode != null) { SSTUAttachNodeUtils.updateAttachNodePosition(part, topNode, new Vector3(0, partTopY, 0), topNode.orientation, userInput); } AttachNode bottomNode = part.FindAttachNode("bottom"); if (bottomNode != null) { SSTUAttachNodeUtils.updateAttachNodePosition(part, bottomNode, new Vector3(0, partBottomY, 0), bottomNode.orientation, userInput); } Vector3 pos = new Vector3(0, topFairingBottomY, 0); SSTUSelectableNodes.updateNodePosition(part, noseInterstageNode, pos); AttachNode noseInterstage = part.FindAttachNode(noseInterstageNode); if (noseInterstage != null) { SSTUAttachNodeUtils.updateAttachNodePosition(part, noseInterstage, pos, Vector3.up, userInput); } pos = new Vector3(0, bottomFairingTopY, 0); SSTUSelectableNodes.updateNodePosition(part, mountInterstageNode, pos); AttachNode mountInterstage = part.FindAttachNode(mountInterstageNode); if (mountInterstage != null) { SSTUAttachNodeUtils.updateAttachNodePosition(part, mountInterstage, pos, Vector3.down, userInput); } if (userInput) { //TODO -- cache prev tank diameter somewhere, use that for child offset functionality //SSTUAttachNodeUtils.updateSurfaceAttachedChildren(part, null, currentTankDiameter); } }
//[KSPEvent(guiName = "Invert Node", guiActiveEditor = false)] //public void invertNodeEvent() //{ // //TODO //} public override void OnStart(PartModule.StartState state) { base.OnStart(state); Events["toggleNodeEvent"].guiName = "Toggle " + nodeName + " node"; if (HighLogic.LoadedSceneIsEditor || HighLogic.LoadedSceneIsFlight) { if (!initialized) { currentlyEnabled = startsEnabled; initialized = true; AttachNode node = part.findAttachNode(nodeName); if (currentlyEnabled && node == null) { SSTUAttachNodeUtils.createAttachNode(part, nodeName, nodeDefaultPosition, nodeDefaultOrientation, 2); } else if (!currentlyEnabled && node != null && node.attachedPart == null) { SSTUAttachNodeUtils.destroyAttachNode(part, node); } else if (!currentlyEnabled && node != null && node.attachedPart != null)//error, should never occur if things were handled properly { currentlyEnabled = true; } } else { AttachNode node = part.findAttachNode(nodeName); if (currentlyEnabled && node == null) { currentlyEnabled = true; SSTUAttachNodeUtils.createAttachNode(part, nodeName, nodeDefaultPosition, nodeDefaultOrientation, 2); } else if (!currentlyEnabled && node != null && node.attachedPart == null) { currentlyEnabled = false; SSTUAttachNodeUtils.destroyAttachNode(part, node); } } } }
private void updateAttachNodes(bool userInput) { if (!standAlonePart) { return; } float height = model.model.currentHeight; AttachNode topNode = part.FindAttachNode("top"); if (topNode != null) { Vector3 topNodePos = new Vector3(0, height * 0.5f, 0); SSTUAttachNodeUtils.updateAttachNodePosition(part, topNode, topNodePos, topNode.orientation, userInput); } AttachNode bottomNode = part.FindAttachNode("bottom"); if (bottomNode != null) { Vector3 botNodePos = new Vector3(0, -height * 0.5f, 0); SSTUAttachNodeUtils.updateAttachNodePosition(part, bottomNode, botNodePos, bottomNode.orientation, userInput); } }
/// <summary> /// Updates the attach nodes on the part for the input list of attach nodes and the current specified nodes for this model. /// Any 'extra' attach nodes from the part will be disabled. /// </summary> /// <param name="part"></param> /// <param name="nodeNames"></param> /// <param name="userInput"></param> /// <param name="orientation"></param> public void updateAttachNodes(Part part, String[] nodeNames, bool userInput, ModelOrientation orientation) { if (nodeNames == null || nodeNames.Length < 1) { return; } if (nodeNames.Length == 1 && (nodeNames[0] == "NONE" || nodeNames[0] == "none")) { return; } float currentVerticalPosition = this.currentVerticalPosition; float offset = getVerticalOffset(); if (orientation == ModelOrientation.BOTTOM) { offset = -offset; } currentVerticalPosition -= offset; AttachNode node = null; AttachNodeBaseData data; int nodeCount = modelDefinition.attachNodeData.Length; int len = nodeNames.Length; Vector3 pos = Vector3.zero; Vector3 orient = Vector3.up; int size = 4; bool invert = modelDefinition.shouldInvert(orientation); for (int i = 0; i < len; i++) { node = part.FindAttachNode(nodeNames[i]); if (i < nodeCount) { data = modelDefinition.attachNodeData[i]; size = Mathf.RoundToInt(data.size * currentDiameterScale); pos = data.position * currentHeightScale; if (invert) { pos.y = -pos.y; pos.x = -pos.x; } pos.y += currentVerticalPosition; orient = data.orientation; if (invert) { orient = -orient; orient.z = -orient.z; } if (node == null)//create it { SSTUAttachNodeUtils.createAttachNode(part, nodeNames[i], pos, orient, size); } else//update its position { SSTUAttachNodeUtils.updateAttachNodePosition(part, node, pos, orient, userInput); } } else//extra node, destroy { if (HighLogic.LoadedSceneIsEditor || HighLogic.LoadedSceneIsFlight) { SSTUAttachNodeUtils.destroyAttachNode(part, node); } } } }
public override void OnStart(StartState state) { base.OnStart(state); initialize(); string[] groupNames = TankSet.getSetNames(tankSets); this.updateUIChooseOptionControl(nameof(currentTankSet), groupNames, groupNames, true, currentTankSet); string[] names = currentTankSetModule.getModelNames(); string[] descs = currentTankSetModule.getTankDescriptions(); this.updateUIChooseOptionControl(nameof(currentTankType), names, descs, true, currentTankType); if (maxTankDiameter == minTankDiameter) { Fields[nameof(currentTankDiameter)].guiActiveEditor = false; } else { this.updateUIFloatEditControl(nameof(currentTankDiameter), minTankDiameter, maxTankDiameter, tankDiameterIncrement * 2, tankDiameterIncrement, tankDiameterIncrement * 0.05f, true, currentTankDiameter); } updateAvailableVariants(false); updateUIScaleControls(); Fields[nameof(currentTankDiameter)].uiControlEditor.onFieldChanged = delegate(BaseField a, object b) { this.actionWithSymmetry(m => { m.updateEditorStats(true); SSTUAttachNodeUtils.updateSurfaceAttachedChildren(m.part, m.prevTankDiameter, m.currentTankDiameter); SSTUModInterop.onPartGeometryUpdate(m.part, true); }); SSTUStockInterop.fireEditorUpdate(); }; Fields[nameof(currentTankVerticalScale)].uiControlEditor.onFieldChanged = delegate(BaseField a, object b) { this.actionWithSymmetry(m => { m.updateEditorStats(true); SSTUModInterop.onPartGeometryUpdate(m.part, true); }); SSTUStockInterop.fireEditorUpdate(); }; Fields[nameof(currentTankSet)].uiControlEditor.onFieldChanged = delegate(BaseField a, object b) { this.actionWithSymmetry(m => { TankSet newSet = Array.Find(m.tankSets, s => s.name == m.currentTankSet); m.currentTankSetModule = newSet; string variant = m.lastSelectedVariant; m.currentTankType = newSet.getDefaultModel(m.lastSelectedVariant); m.tankModule.updateSelections(); m.tankModule.modelSelected(m.currentTankType); m.Fields[nameof(m.currentTankType)].guiActiveEditor = newSet.Length > 1; //re-seat this if it was changed in the 'setMainTankModuleFromEditor' method //will allow for user-initiated main-tank changes to still change the 'last variant' but will //persist the variant if the newly selected set did not contain the selected variant //so that it will persist to the next set selection, OR be reseated on the next user-tank selection within the current set if (!m.currentTankSetModule.hasVariant(variant)) { m.lastSelectedVariant = variant; } if (m.variantData != null) { m.updateAvailableVariants(true); } m.updateEditorStats(true); m.updateUIScaleControls(); SSTUModInterop.onPartGeometryUpdate(m.part, true); }); SSTUStockInterop.fireEditorUpdate(); }; Fields[nameof(currentNoseType)].uiControlEditor.onFieldChanged = delegate(BaseField a, object b) { noseModule.modelSelected(a, b); this.actionWithSymmetry(m => { m.updateEditorStats(true); m.updateAnimationControl(m.noseAnimationID, m.noseModule.model, 1); SSTUModInterop.onPartGeometryUpdate(m.part, true); }); SSTUStockInterop.fireEditorUpdate(); }; Fields[nameof(currentTankType)].uiControlEditor.onFieldChanged = delegate(BaseField a, object b) { tankModule.modelSelected(a, b); this.actionWithSymmetry(m => { if (variantData != null) { m.updateAvailableVariants(true); } m.updateEditorStats(true); m.lastSelectedVariant = tankModule.model.variantName; m.updateAnimationControl(m.bodyAnimationID, m.tankModule.model, 3); m.updateUIScaleControls(); SSTUModInterop.onPartGeometryUpdate(m.part, true); }); SSTUStockInterop.fireEditorUpdate(); }; Fields[nameof(currentMountType)].uiControlEditor.onFieldChanged = delegate(BaseField a, object b) { mountModule.modelSelected(a, b); this.actionWithSymmetry(m => { m.updateEditorStats(true); m.updateAnimationControl(m.mountAnimationID, m.mountModule.model, 5); SSTUModInterop.onPartGeometryUpdate(m.part, true); }); SSTUStockInterop.fireEditorUpdate(); }; Fields[nameof(currentNoseTexture)].uiControlEditor.onFieldChanged = noseModule.textureSetSelected; Fields[nameof(currentTankTexture)].uiControlEditor.onFieldChanged = tankModule.textureSetSelected; Fields[nameof(currentMountTexture)].uiControlEditor.onFieldChanged = mountModule.textureSetSelected; Fields[nameof(currentTankSet)].guiActiveEditor = tankSets.Length > 1; Fields[nameof(currentTankType)].guiActiveEditor = currentTankSetModule.Length > 1; Fields[nameof(currentNoseType)].guiActiveEditor = noseModule.models.Count > 1; Fields[nameof(currentMountType)].guiActiveEditor = mountModule.models.Count > 1; SSTUStockInterop.fireEditorUpdate(); SSTUModInterop.onPartGeometryUpdate(part, true); if (HighLogic.LoadedSceneIsEditor) { GameEvents.onEditorShipModified.Add(new EventData <ShipConstruct> .OnEvent(onEditorVesselModified)); } }
private void updateAttachNodes(bool userInput) { int len = modelGroups.Length; List <string> enabledNodeNames = new List <string>(); AttachNode attachNode; ModelSwitchGroup group; ModelSwitchData model; for (int i = 0; i < len; i++) { //updated node handling routing group = modelGroups[i]; if (!group.groupEnabled)//group disabled { continue; } model = group.enabledModel; if (model == null)//ERROR - no model on enabled group { continue; } //if (model.nodes == null) { continue; }//ERROR - nodes should not be null; let it crash int len2 = model.nodes.Length; if (len2 > 0) { for (int k = 0; k < len2; k++) { if (!controlledNodes.Contains(model.nodes[k].name)) { continue; } //not a node under this modules control if (group.isChildAtNodeEnabled(model.nodes[k].name)) { continue; } //child enabled, let it handle the node setup if (!model.nodes[k].createAttachNode) { continue; } //node is disabled if (enabledNodeNames.Contains(model.nodes[k].name)) { continue; } //node already enabled from other model -- user config/setup ERROR // if it passed all those checks it is a valid model node for attach-node creation; setup the position and rotation relative to this groups base transform Vector3 pos = model.nodes[k].position; Quaternion nr = Quaternion.Euler(model.nodes[k].rotation); Vector3 rot = Vector3.zero; //position will be a local position transformed by group base transform into world space, and then by part transform into local space //rotation will be the base-transforms rotation quaternion multiplied (or inverse) by the local-rotation quaternion from euler-angle of the rotation for the node //and then how to get it as a vector-axis? mult the 'fwd' vector by the quat? attachNode = part.FindAttachNode(model.nodes[k].name); if (attachNode == null) { attachNode = SSTUAttachNodeUtils.createAttachNode(part, group.parentNode, pos, rot, 2); } else { SSTUAttachNodeUtils.updateAttachNodePosition(part, attachNode, pos, rot, userInput); } } //check each node for 'enabled' flag //if enabled check for children //if child is present, let child handle the node //else enable it } else//no model nodes, so no chance for children groups; only nodes defined in the MODEL and flagged for enabled will be enabled; no nodes == no nodes! { //NOOP } // original code block // does not use the 'enableAttachNode' data from the node specifications in the MODELs //group = modelGroups[i]; //model = group.enabledModel; //if (!controlledNodes.Contains(group.parentNode)) { continue; }//not a node that we should touch... //if (model == null || model.suppressNode) { continue; } //enabledNodeNames.Add(group.parentNode); //Vector3 pos = group.getModelRootTransform().position; //pos = part.transform.InverseTransformPoint(pos); //Vector3 rotation = group.getModelRootTransform().up; //attachNode = part.findAttachNode(group.parentNode); //if (attachNode == null) //{ // attachNode = SSTUAttachNodeUtils.createAttachNode(part, group.parentNode, pos, rotation, 2); //} //else //{ // SSTUAttachNodeUtils.updateAttachNodePosition(part, attachNode, pos, rotation, userInput); //} } List <AttachNode> attachNodes = new List <AttachNode>(); attachNodes.AddRange(part.attachNodes); len = attachNodes.Count; for (int i = 0; i < len; i++) { attachNode = attachNodes[i]; if (!controlledNodes.Contains(attachNode.id)) { continue; } //not a node that we should touch... if (attachNode.attachedPart == null && !enabledNodeNames.Contains(attachNode.id)) { SSTUAttachNodeUtils.destroyAttachNode(part, attachNode); } } }