Beispiel #1
0
        public string GetSettingsString(bool comments)
        {
            sb.Clear();

            if (comments)
            {
                sb.Append("ConfigVersion=").Append(CFG_VERSION).AppendLine(comments ? " // Do not edit. This is used by the mod to reset settings when their defaults change without changing them if they're custom." : "");
                sb.AppendLine("// Paint Gun mod config; this file gets automatically overwritten after being loaded so don't leave custom comments.");
                sb.AppendLine("// You can reload this while the game is running by typing in chat: /pg reload");
                sb.AppendLine("// Lines starting with // are comments. All values are case insensitive unless otherwise specified.");
                sb.AppendLine();
            }

            sb.Append("ExtraSounds=").Append(extraSounds).AppendLine(comments ? " // toggle all HUD-sounds for this mod's actions, like cycling colors/skins, alerts when can't do something, etc. Default: true" : "");
            sb.Append("SprayParticles=").Append(sprayParticles).AppendLine(comments ? " // toggles the spray particles. Default: true" : "");
            sb.Append("SpraySoundVolume=").Append(spraySoundVolume).AppendLine(comments ? " // paint gun spraying sound volume. Default: 0.8" : "");
            sb.Append("SelectColorZigZag=").Append(selectColorZigZag).AppendLine(comments ? " // type of scrolling through colors in the palette, false is each row at a time, true is in zig-zag. Default: false" : "");
            sb.Append("HidePaletteWithHUD=").Append(hidePaletteWithHUD).AppendLine(comments ? " // wether to hide the color palette and aim info along with the HUD. Set to false to always show regardless of the HUD being visible or not. Default: true" : "");

            sb.Append("PaletteScreenPos=").Append(Math.Round(paletteScreenPos.X, 5)).Append(", ").Append(Math.Round(paletteScreenPos.Y, 5)).AppendLine(comments ? $" // color palette screen position in X and Y coordinates where 0,0 is the screen center. Positive values are right and up and negative ones are opposite of that. Default: {paletteScreenPos.X.ToString("0.#####")}, {paletteScreenPos.Y.ToString("0.#####")}" : "");
            sb.Append("PaletteScale=").Append(Math.Round(paletteScale, 5)).AppendLine(comments ? $" // color palette overall scale. Default: {paletteScaleDefault.ToString("0.#####")}" : "");
            sb.Append("PaletteBackgroundOpacity=").Append(paletteBackgroundOpacity < 0 ? "HUD" : Math.Round(paletteBackgroundOpacity, 5).ToString()).AppendLine(comments ? " // palette's background opacity percent scalar (0 to 1 value) or set to HUD to use the game's HUD opacity. Default: HUD" : "");

            sb.Append("AimInfoScreenPos=").Append(Math.Round(aimInfoScreenPos.X, 5)).Append(", ").Append(Math.Round(aimInfoScreenPos.Y, 5)).AppendLine(comments ? $" // aim info's screen position in X and Y coordinates where 0,0 is the screen center. Positive values are right and up and negative ones are opposite of that. Default: {aimInfoScreenPos.X.ToString("0.#####")}, {aimInfoScreenPos.Y.ToString("0.#####")}" : "");
            // TODO: make it work with scale?
            //str.Append("AimInfoScale=").Append(Math.Round(aimInfoScale, 5)).AppendLine(comments ? $" // aiming info box overall scale. Default: {aimInfoScaleDefault:0.#####}" : "");
            sb.Append("AimInfoBackgroundOpacity=").Append(aimInfoBackgroundOpacity < 0 ? "HUD" : Math.Round(aimInfoBackgroundOpacity, 5).ToString()).AppendLine(comments ? " // aim info's background opacity percent scalar (0 to 1 value) or set to HUD to use the game's HUD opacity. Default: HUD" : "");

            sb.Append("RequireCtrlForColorCycle=").Append(requireCtrlForColorCycle).AppendLine(comments ? " // Whether color cycling requires ctrl+scroll (true) or just scroll (false). Skin cycling (shift+scroll) is unaffected. Default: false" : "");

            if (comments)
            {
                sb.AppendLine();
                sb.AppendLine("// This allows you to hide certain skin IDs from the HUD palette, separated by comma and case-sensitive!");
                sb.Append("// All detected skins, sorted by DLC: ");

                int widestName = 0;

                // using dlcId so they get sorted by order DLCs were introduced
                SortedDictionary <uint, List <SkinInfo> > skinsByDLC = new SortedDictionary <uint, List <SkinInfo> >();

                foreach (SkinInfo skin in Main.Palette.Skins.Values)
                {
                    if (skin.SubtypeId == MyStringHash.NullOrEmpty)
                    {
                        continue;
                    }

                    uint         dlcId = 0;
                    MyDLCs.MyDLC dlc;
                    if (skin.Definition?.DLCs != null && skin.Definition.DLCs.Length > 0 && MyDLCs.TryGetDLC(skin.Definition.DLCs[0], out dlc))
                    {
                        dlcId      = dlc.AppId;
                        widestName = Math.Max(widestName, dlc.Name.Length);
                    }

                    // get or add list
                    List <SkinInfo> skins;
                    if (!skinsByDLC.TryGetValue(dlcId, out skins))
                    {
                        skinsByDLC[dlcId] = skins = new List <SkinInfo>();
                    }

                    skins.Add(skin);
                }

                foreach (KeyValuePair <uint, List <SkinInfo> > kv in skinsByDLC)
                {
                    uint         dlcId   = kv.Key;
                    string       dlcName = "(No DLC)";
                    MyDLCs.MyDLC dlc;
                    if (dlcId > 0 && MyDLCs.TryGetDLC(dlcId, out dlc))
                    {
                        dlcName = dlc.Name;
                    }

                    sb.AppendLine().Append("//  ").Append(' ', widestName - dlcName.Length).Append(dlcName).Append(":  ");

                    foreach (SkinInfo skin in kv.Value)
                    {
                        sb.Append(skin.SubtypeId.String).Append(", ");
                    }

                    sb.Length -= 2; // remove last comma
                }

                sb.AppendLine();
            }

            sb.Append("HideSkinsFromPalette=").Append(string.Join(", ", hideSkinsFromPalette)).AppendLine();

            if (comments)
            {
                sb.AppendLine();
                sb.AppendLine("// Key/mouse/gamepad combination to trigger '/pg pick' command.");
                sb.AppendLine("// Separate multiple keys/buttons/controls with spaces. For gamepad add " + InputHandler.GAMEPAD_PREFIX + " prefix, for mouse add " + InputHandler.MOUSE_PREFIX + " prefix and for game controls add " + InputHandler.CONTROL_PREFIX + " prefix.");
                sb.AppendLine("// All keys, mouse buttons, gamepad buttons/axes and control names are at the bottom of this file.");
            }
            sb.Append("PickColorMode-input1=").Append(colorPickMode1?.GetStringCombination() ?? "").AppendLine(comments ? " // Default: " + (default_colorPickMode1?.GetStringCombination() ?? "") : "");
            sb.Append("PickColorMode-input2=").Append(colorPickMode2?.GetStringCombination() ?? "").AppendLine(comments ? " // Default: " + (default_colorPickMode2?.GetStringCombination() ?? "") : "");

            if (comments)
            {
                sb.AppendLine();
                sb.AppendLine("// Key/mouse/gamepad combination to instantly get the aimed block/player's color into the selected slot.");
                sb.AppendLine("// Same input rules as above.");
            }
            sb.Append("InstantPickColor-input1=").Append(instantColorPick1?.GetStringCombination() ?? "").AppendLine(comments ? " // Default: " + (default_instantColorPick1?.GetStringCombination() ?? "") : "");
            sb.Append("InstantPickColor-input2=").Append(instantColorPick2?.GetStringCombination() ?? "").AppendLine(comments ? " // Default: " + (default_instantColorPick2?.GetStringCombination() ?? "") : "");

            if (comments)
            {
                sb.AppendLine();
                sb.AppendLine("// Key/mouse/gamepad combination to toggle the replace color mode, which only works in creative.");
                sb.AppendLine("// Same input rules as above.");
            }
            sb.Append("ReplaceColorMode-input1=").Append(replaceColorMode1?.GetStringCombination() ?? "").AppendLine(comments ? " // Default: " + (default_replaceColorMode1?.GetStringCombination() ?? "") : "");
            sb.Append("ReplaceColorMode-input2=").Append(replaceColorMode2?.GetStringCombination() ?? "").AppendLine(comments ? " // Default: " + (default_replaceColorMode2?.GetStringCombination() ?? "") : "");

            if (comments)
            {
                sb.AppendLine();
                sb.AppendLine("// List of inputs, generated from game data.");

                const int NEWLINE_EVERY_CHARACTERS = 130;

                int characters = 0;
                sb.Append("// Key names: ").AppendLine().Append("//     ");
                foreach (KeyValuePair <string, object> kv in InputHandler.inputs)
                {
                    if (kv.Key.StartsWith(InputHandler.MOUSE_PREFIX, StringComparison.Ordinal) ||
                        kv.Key.StartsWith(InputHandler.GAMEPAD_PREFIX, StringComparison.Ordinal) ||
                        kv.Key.StartsWith(InputHandler.CONTROL_PREFIX, StringComparison.Ordinal))
                    {
                        continue;
                    }

                    int prevLen = sb.Length;

                    sb.Append(kv.Key).Append(", ");

                    characters += (sb.Length - prevLen);
                    if (characters >= NEWLINE_EVERY_CHARACTERS)
                    {
                        sb.AppendLine().Append("//     ");
                        characters = 0;
                    }
                }
                sb.AppendLine();

                characters = 0;
                sb.Append("// Mouse button names: ").AppendLine().Append("//     ");
                foreach (KeyValuePair <string, object> kv in InputHandler.inputs)
                {
                    if (kv.Key.StartsWith(InputHandler.MOUSE_PREFIX, StringComparison.Ordinal))
                    {
                        int prevLen = sb.Length;

                        sb.Append(kv.Key).Append(", ");

                        characters += (sb.Length - prevLen);
                        if (characters >= NEWLINE_EVERY_CHARACTERS)
                        {
                            sb.AppendLine().Append("//     ");
                            characters = 0;
                        }
                    }
                }
                sb.AppendLine();

                characters = 0;
                sb.Append("// Gamepad button/axes names: ").AppendLine().Append("//     ");
                foreach (KeyValuePair <string, object> kv in InputHandler.inputs)
                {
                    if (kv.Key.StartsWith(InputHandler.GAMEPAD_PREFIX, StringComparison.Ordinal))
                    {
                        int prevLen = sb.Length;

                        sb.Append(kv.Key).Append(", ");

                        characters += (sb.Length - prevLen);
                        if (characters >= NEWLINE_EVERY_CHARACTERS)
                        {
                            sb.AppendLine().Append("//     ");
                            characters = 0;
                        }
                    }
                }
                sb.AppendLine();

                characters = 0;
                sb.Append("// Control names: ").AppendLine().Append("//     ");
                foreach (KeyValuePair <string, object> kv in InputHandler.inputs)
                {
                    if (kv.Key.StartsWith(InputHandler.CONTROL_PREFIX, StringComparison.Ordinal))
                    {
                        int prevLen = sb.Length;

                        sb.Append(kv.Key).Append(", ");

                        characters += (sb.Length - prevLen);
                        if (characters >= NEWLINE_EVERY_CHARACTERS)
                        {
                            sb.AppendLine().Append("//     ");
                            characters = 0;
                        }
                    }
                }
                sb.AppendLine();
            }

            return(sb.ToString());
        }
Beispiel #2
0
        void InitBlockSkins()
        {
            if (Constants.SKIN_INIT_LOGGING)
            {
                Log.Info("Finding block skins...");
            }

            HashSet <string> definedIcons = new HashSet <string>();

            foreach (MyTransparentMaterialDefinition def in MyDefinitionManager.Static.GetTransparentMaterialDefinitions())
            {
                if (def.Id.SubtypeName.StartsWith(SKIN_ICON_PREFIX))
                {
                    definedIcons.Add(def.Id.SubtypeName);
                }
            }

            int foundSkins = 0;

            foreach (MyAssetModifierDefinition assetDef in MyDefinitionManager.Static.GetAssetModifierDefinitions())
            {
                if (IsSkinAsset(assetDef))
                {
                    foundSkins++;
                }
            }

            int capacity = foundSkins + 1; // include "No Skin" too.

            Skins       = new SortedDictionary <MyStringHash, SkinInfo>(new SkinSorter());
            SkinsForHUD = new List <SkinInfo>(capacity);

            StringBuilder sb = new StringBuilder(256);

            foreach (MyAssetModifierDefinition assetDef in MyDefinitionManager.Static.GetAssetModifierDefinitions())
            {
                if (assetDef.Id.SubtypeId.String == "RustNonColorable_Armor")
                {
                    continue; // HACK: DLC-less skin that has no steam item, not sure what to do about this so I'm just gonna make it not exist for now
                }
                if (IsSkinAsset(assetDef))
                {
                    bool isCustomSkin = (!assetDef.Context.IsBaseGame && (assetDef.DLCs == null || assetDef.DLCs.Length == 0));

                    #region Generate user friendly name
                    string name = assetDef.Id.SubtypeName;
                    sb.Clear();
                    sb.Append(name);

                    if (name.EndsWith(ARMOR_SUFFIX))
                    {
                        sb.Length -= ARMOR_SUFFIX.Length;
                    }

                    string nameId = sb.ToString();

                    // Add spaces before upper case letters except first.
                    // Or replace _ with space.
                    for (int i = 1; i < sb.Length; ++i)
                    {
                        char c = sb[i];

                        if (c == '_')
                        {
                            sb[i] = ' ';
                        }

                        if (char.IsUpper(c) && sb[i - 1] != ' ')
                        {
                            sb.Insert(i, ' ');
                        }
                    }

                    name = sb.ToString();
                    #endregion

                    string icon = SKIN_ICON_PREFIX + nameId;

                    if (!definedIcons.Contains(icon))
                    {
                        if (isCustomSkin || Utils.IsLocalMod())
                        {
                            Log.Error($"'{icon}' not found in transparent materials definitions.", Log.PRINT_MESSAGE);
                        }

                        icon = SKIN_ICON_UNKNOWN;
                    }

                    if (isCustomSkin)
                    {
                        FixModTexturePaths(assetDef);
                    }

                    SkinInfo skinInfo = new SkinInfo(assetDef, name, icon);
                    Skins[skinInfo.SubtypeId] = skinInfo;

                    // HACK: this skin isn't colorable, so might as well make it ignore color palette like gold and silver
                    if (assetDef.Id.SubtypeId.String == "RustNonColorable_Armor")
                    {
                        assetDef.DefaultColor = Color.Gray;
                    }
                }
            }

            SkinInfo noSkin = new SkinInfo(null, "No Skin", SKIN_ICON_PREFIX + "NoSkin");
            Skins[noSkin.SubtypeId] = noSkin;

            CleanUpFixMods();

            bool neonSkinExists = false;

            const int SubtypeWidth = -26;
            const int NameWidth    = -26;
            const int DLCsWidth    = -20;

            Log.Info($"{"Skin SubtypeId",SubtypeWidth} {"Name",NameWidth} {"DLCs",DLCsWidth} Mod");

            foreach (SkinInfo skin in Skins.Values)
            {
                if (skin.SubtypeId.String == "Neon_Colorable_Surface")
                {
                    neonSkinExists = true;
                }

                if (Constants.SKIN_INIT_LOGGING)
                {
                    string dlcList = "";
                    if (skin.Definition?.DLCs != null && skin.Definition.DLCs.Length > 0)
                    {
                        dlcList = String.Join(",", skin.Definition.DLCs);
                    }

                    string modName = skin.Definition?.Context?.ModName ?? "";

                    Log.Info($"{$"'{skin.SubtypeId.String}'",SubtypeWidth} {skin.Name,NameWidth} {dlcList,DLCsWidth} {modName}");

#if false
                    sb.Clear();
                    sb.Append("Defined skin id='").Append(skin.SubtypeId.String).Append("'; Name='").Append(skin.Name).Append("'");

                    if (skin.Icon.String == SKIN_ICON_UNKNOWN)
                    {
                        sb.Append("; No Icon!");
                    }

                    if (skin.Definition?.DLCs != null && skin.Definition.DLCs.Length > 0)
                    {
                        sb.Append("; DLC=");

                        int preLen = sb.Length;

                        foreach (string dlcId in skin.Definition.DLCs)
                        {
                            MyDLCs.MyDLC dlc;
                            if (!MyDLCs.TryGetDLC(dlcId, out dlc))
                            {
                                Log.Error($"Skin '{skin.SubtypeId.String}' uses unknown DLC={dlcId}");
                                continue;
                            }

                            sb.Append(dlc.Name).Append(", ");
                        }

                        if (sb.Length > preLen)
                        {
                            sb.Length -= 2; // remove last comma
                        }
                    }

                    if (skin.Definition?.Context != null && !skin.Definition.Context.IsBaseGame)
                    {
                        sb.Append("; Mod='").Append(skin.Definition.Context.ModName).Append("'");
                    }

                    Log.Info(sb.ToString());
#endif
                }
            }

            if (!neonSkinExists)
            {
                Log.Error("WARNING: Expected to find 'Neon_Colorable_Surface' but did not!\nCheck the skins list in the mod's log to ensure all of them are there.");
            }
        }