Пример #1
0
        public void Setup(ModuleB9PartSwitch parent, bool displayWarnings = true)
        {
            if (parent == null)
            {
                throw new ArgumentNullException("parent cannot be null");
            }
            if (parent.part == null)
            {
                throw new ArgumentNullException("parent.part cannot be null");
            }

            this.parent = parent;

            aspectLocks.Clear();

            Part part       = parent.part;
            Part partPrefab = part.GetPrefab() ?? part;

            partModifiers.Clear();

            IEnumerable <object> aspectLocksOnOtherModules = parent.PartAspectLocksOnOtherModules;

            string errorString = null;

            void OnInitializationError(string message)
            {
                LogError(message);

                if (displayWarnings)
                {
                    if (errorString == null)
                    {
                        errorString = $"Initialization errors on {parent} subtype '{Name}'";
                    }

                    errorString += "\n  " + message;
                }
            }

            void MaybeAddModifier(IPartModifier modifier)
            {
                if (modifier == null)
                {
                    return;
                }

                if (modifier is IPartAspectLock partAspectLockHolder)
                {
                    object partAspectLock = partAspectLockHolder;
                    if (aspectLocksOnOtherModules.Contains(partAspectLock))
                    {
                        OnInitializationError($"More than one module can't manage {modifier.Description}");
                        return;
                    }
                    else
                    {
                        aspectLocks.Add(partAspectLock);
                    }
                }

                partModifiers.Add(modifier);
            }

            if (maxTemp > 0)
            {
                MaybeAddModifier(new PartMaxTempModifier(part, partPrefab.maxTemp, maxTemp));
            }

            if (skinMaxTemp > 0)
            {
                MaybeAddModifier(new PartSkinMaxTempModifier(part, partPrefab.skinMaxTemp, skinMaxTemp));
            }

            if (crashTolerance > 0)
            {
                MaybeAddModifier(new PartCrashToleranceModifier(part, partPrefab.crashTolerance, crashTolerance));
            }

            if (attachNode.IsNotNull())
            {
                if (part.attachRules.srfAttach)
                {
                    if (part.srfAttachNode.IsNotNull())
                    {
                        MaybeAddModifier(new PartAttachNodeModifier(part.srfAttachNode, partPrefab.srfAttachNode, attachNode, parent));
                    }
                    else
                    {
                        OnInitializationError("attachNode specified but part does not have a surface attach node");
                    }
                }
                else
                {
                    OnInitializationError("attachNode specified but part does not allow surface attach");
                }
            }

            if (CoMOffset.IsFinite())
            {
                MaybeAddModifier(new PartCoMOffsetModifier(part, partPrefab.CoMOffset, CoMOffset));
            }

            if (CoPOffset.IsFinite())
            {
                MaybeAddModifier(new PartCoPOffsetModifier(part, partPrefab.CoPOffset, CoPOffset));
            }

            if (CoLOffset.IsFinite())
            {
                MaybeAddModifier(new PartCoLOffsetModifier(part, partPrefab.CoLOffset, CoLOffset));
            }

            if (CenterOfBuoyancy.IsFinite())
            {
                MaybeAddModifier(new PartCenterOfBuoyancyModifier(part, partPrefab.CenterOfBuoyancy, CenterOfBuoyancy));
            }

            if (CenterOfDisplacement.IsFinite())
            {
                MaybeAddModifier(new PartCenterOfDisplacementModifier(part, partPrefab.CenterOfDisplacement, CenterOfDisplacement));
            }

            if (stackSymmetry >= 0)
            {
                MaybeAddModifier(new PartStackSymmetryModifier(part, partPrefab.stackSymmetry, stackSymmetry));
            }

            foreach (AttachNodeModifierInfo info in attachNodeModifierInfos)
            {
                foreach (IPartModifier partModifier in info.CreatePartModifiers(part, parent, OnInitializationError))
                {
                    MaybeAddModifier(partModifier);
                }
            }

            foreach (TextureSwitchInfo info in textureSwitches)
            {
                foreach (TextureReplacement replacement in info.CreateTextureReplacements(part, OnInitializationError))
                {
                    MaybeAddModifier(replacement);
                }
            }

            foreach (MaterialModifierInfo materialModifierInfo in materialModifierInfos)
            {
                foreach (IPartModifier partModifier in materialModifierInfo.CreateModifiers(part.GetModelRoot(), OnInitializationError))
                {
                    MaybeAddModifier(partModifier);
                }
            }

            nodes.Clear();
            foreach (IStringMatcher nodeName in nodeNames)
            {
                bool foundNode = false;

                foreach (AttachNode node in part.attachNodes)
                {
                    if (!nodeName.Match(node.id))
                    {
                        continue;
                    }

                    foundNode = true;

                    if (node.nodeType != AttachNode.NodeType.Stack)
                    {
                        OnInitializationError($"Node {node.id} is not a stack node, and thus cannot be managed by ModuleB9PartSwitch");
                        continue;
                    }

                    nodes.Add(node);
                    partModifiers.Add(new AttachNodeToggler(node));
                }

                if (!foundNode)
                {
                    OnInitializationError($"No attach nodes matching '{nodeName}' found");
                }
            }

            if (HasTank)
            {
                foreach (TankResource resource in tankType)
                {
                    float            filledProportion = (resource.percentFilled ?? percentFilled ?? tankType.percentFilled ?? 100f) * 0.01f;
                    bool?            tweakable        = resourcesTweakable ?? tankType.resourcesTweakable;
                    ResourceModifier resourceModifier = new ResourceModifier(resource, () => parent.GetTotalVolume(this), part, filledProportion, tweakable);
                    MaybeAddModifier(resourceModifier);
                }
            }

            transforms.Clear();
            foreach (var transformName in transformNames)
            {
                bool foundTransform = false;

                foreach (Transform transform in part.GetModelRoot().TraverseHierarchy().Where(t => transformName.Match(t.name)))
                {
                    foundTransform = true;
                    partModifiers.Add(new TransformToggler(transform, part));
                    transforms.Add(transform);
                }

                if (!foundTransform)
                {
                    OnInitializationError($"No transforms matching '{transformName}' found");
                }
            }

            foreach (TransformModifierInfo transformModifierInfo in transformModifierInfos)
            {
                foreach (IPartModifier partModifier in transformModifierInfo.CreatePartModifiers(part, OnInitializationError))
                {
                    MaybeAddModifier(partModifier);
                }
            }

            // Icon setup doesn't set partInfo correctly, so it exists but as a copy without partConfig
            if ((part.partInfo?.partConfig).IsNotNull())
            {
                foreach (ModuleModifierInfo moduleModifierInfo in moduleModifierInfos)
                {
                    try
                    {
                        foreach (IPartModifier partModifier in moduleModifierInfo.CreatePartModifiers(part, parent, parent.CreateModuleDataChangedEventDetails()))
                        {
                            MaybeAddModifier(partModifier);
                        }
                    }
                    catch (Exception ex)
                    {
                        OnInitializationError(ex.Message);
                        Debug.LogException(ex);
                    }
                }
            }

            if (!parent.subtypes.Any(subtype => subtype.Name == mirrorSymmetrySubtype))
            {
                OnInitializationError($"Cannot find subtype '{mirrorSymmetrySubtype}' for mirror symmetry subtype");
                mirrorSymmetrySubtype = Name;
            }

            if (errorString.IsNotNull())
            {
                SeriousWarningHandler.DisplaySeriousWarning(errorString);
            }
        }
Пример #2
0
        public void Setup(ModuleB9PartSwitch parent, bool displayWarnings = true)
        {
            if (parent == null)
            {
                throw new ArgumentNullException("parent cannot be null");
            }
            if (parent.part == null)
            {
                throw new ArgumentNullException("parent.part cannot be null");
            }

            this.parent = parent;

            aspectLocks.Clear();

            Part part       = parent.part;
            Part partPrefab = part.GetPrefab() ?? part;

            partModifiers.Clear();

            IEnumerable <object> aspectLocksOnOtherModules = parent.PartAspectLocksOnOtherModules;

            string errorString = null;

            void OnInitializationError(string message)
            {
                LogError(message);

                if (displayWarnings)
                {
                    if (errorString == null)
                    {
                        errorString = $"Initialization errors on {parent} subtype '{Name}'";
                    }

                    errorString += "\n  " + message;
                }
            }

            void MaybeAddModifier(IPartModifier modifier)
            {
                if (modifier == null)
                {
                    return;
                }
                if (aspectLocksOnOtherModules.Contains(modifier.PartAspectLock))
                {
                    OnInitializationError($"More than one module can't manage {modifier.Description}");
                }
                else
                {
                    partModifiers.Add(modifier);
                    aspectLocks.Add(modifier.PartAspectLock);
                }
            }

            if (maxTemp > 0)
            {
                MaybeAddModifier(new PartMaxTempModifier(part, partPrefab.maxTemp, maxTemp));
            }

            if (skinMaxTemp > 0)
            {
                MaybeAddModifier(new PartSkinMaxTempModifier(part, partPrefab.skinMaxTemp, skinMaxTemp));
            }

            if (crashTolerance > 0)
            {
                MaybeAddModifier(new PartCrashToleranceModifier(part, partPrefab.crashTolerance, crashTolerance));
            }

            if (attachNode.IsNotNull())
            {
                if (part.attachRules.allowSrfAttach)
                {
                    if (part.srfAttachNode.IsNotNull())
                    {
                        MaybeAddModifier(new PartAttachNodeModifier(part.srfAttachNode, partPrefab.srfAttachNode, attachNode, parent));
                    }
                    else
                    {
                        OnInitializationError("attachNode specified but part does not have a surface attach node");
                    }
                }
                else
                {
                    OnInitializationError("attachNode specified but part does not allow surface attach");
                }
            }

            if (CoMOffset.IsFinite())
            {
                MaybeAddModifier(new PartCoMOffsetModifier(part, partPrefab.CoMOffset, CoMOffset));
            }

            if (CoPOffset.IsFinite())
            {
                MaybeAddModifier(new PartCoPOffsetModifier(part, partPrefab.CoPOffset, CoPOffset));
            }

            if (CoLOffset.IsFinite())
            {
                MaybeAddModifier(new PartCoLOffsetModifier(part, partPrefab.CoLOffset, CoLOffset));
            }

            if (CenterOfBuoyancy.IsFinite())
            {
                MaybeAddModifier(new PartCenterOfBuoyancyModifier(part, partPrefab.CenterOfBuoyancy, CenterOfBuoyancy));
            }

            if (CenterOfDisplacement.IsFinite())
            {
                MaybeAddModifier(new PartCenterOfDisplacementModifier(part, partPrefab.CenterOfDisplacement, CenterOfDisplacement));
            }

            if (stackSymmetry >= 0)
            {
                MaybeAddModifier(new PartStackSymmetryModifier(part, partPrefab.stackSymmetry, stackSymmetry));
            }

            foreach (AttachNodeModifierInfo info in attachNodeModifierInfos)
            {
                MaybeAddModifier(info.CreateAttachNodeModifier(part, parent, OnInitializationError));
            }

            foreach (TextureSwitchInfo info in textureSwitches)
            {
                foreach (TextureReplacement replacement in info.CreateTextureReplacements(part, OnInitializationError))
                {
                    MaybeAddModifier(replacement);
                }
            }

            nodes.Clear();
            foreach (string nodeName in nodeNames)
            {
                string pattern     = '^' + Regex.Escape(nodeName).Replace(@"\*", ".*").Replace(@"\?", ".") + '$';
                Regex  nodeIdRegex = new Regex(pattern);

                bool foundNode = false;

                foreach (AttachNode node in part.attachNodes)
                {
                    if (!nodeIdRegex.IsMatch(node.id))
                    {
                        continue;
                    }

                    foundNode = true;

                    if (node.nodeType != AttachNode.NodeType.Stack)
                    {
                        OnInitializationError($"Node {node.id} is not a stack node, and thus cannot be managed by ModuleB9PartSwitch");
                        continue;
                    }

                    nodes.Add(node);
                    partModifiers.Add(new AttachNodeToggler(node));
                }

                if (!foundNode)
                {
                    OnInitializationError($"No attach nodes matching '{nodeName}' found");
                }
            }

            if (HasTank)
            {
                volumeProvider = new SubtypeVolumeProvider(parent, volumeMultiplier, volumeAdded);
                foreach (TankResource resource in tankType)
                {
                    float            filledProportion = (resource.percentFilled ?? percentFilled ?? tankType.percentFilled ?? 100f) * 0.01f;
                    bool?            tweakable        = resourcesTweakable ?? tankType.resourcesTweakable;
                    ResourceModifier resourceModifier = new ResourceModifier(resource, volumeProvider, part, filledProportion, tweakable);
                    MaybeAddModifier(resourceModifier);
                }
            }

            transforms.Clear();
            foreach (var transformName in transformNames)
            {
                bool foundTransform = false;

                foreach (Transform transform in part.GetModelTransforms(transformName))
                {
                    foundTransform = true;
                    partModifiers.Add(new TransformToggler(transform, part));
                    transforms.Add(transform);
                }

                if (!foundTransform)
                {
                    OnInitializationError($"No transforms named '{transformName}' found");
                }
            }

            foreach (TransformModifierInfo transformModifierInfo in transformModifierInfos)
            {
                foreach (IPartModifier partModifier in transformModifierInfo.CreatePartModifiers(part, OnInitializationError))
                {
                    MaybeAddModifier(partModifier);
                }
            }

            if (!parent.subtypes.Any(subtype => subtype.Name == mirrorSymmetrySubtype))
            {
                OnInitializationError($"Cannot find subtype '{mirrorSymmetrySubtype}' for mirror symmetry subtype");
                mirrorSymmetrySubtype = Name;
            }

            if (errorString.IsNotNull())
            {
                SeriousWarningHandler.DisplaySeriousWarning(errorString);
            }
        }