Beispiel #1
0
        public static string GetString(this ModDataDictionary d, string key, string defaultValue = null)
        {
            string result = defaultValue;

            d.TryGetValue(key, out result);
            return(result);
        }
Beispiel #2
0
        //----------------------------------------------------------------------
        // Storage/retrieval of bot data in a modData dictionary, and
        // inventory transfer from bot to bot (object to item, etc.).
        //----------------------------------------------------------------------

        /// <summary>
        /// Fill in the given ModDataDictionary with values from this bot,
        /// so they can be saved and restored later.
        /// </summary>
        void SetModData(ModDataDictionary d)
        {
            d[dataKey.isBot]  = "1";
            d[dataKey.name]   = name;
            d[dataKey.energy] = energy.ToString();
            d[dataKey.facing] = facingDirection.ToString();
        }
Beispiel #3
0
 /// <summary>Write a field to a mod data dictionary if it does not yet exist.</summary>
 /// <param name="data">The mod data dictionary to update.</param>
 /// <param name="key">The dictionary key to write.</param>
 /// <param name="value">The value to write, or <c>null</c> to remove it.</param>
 public static ModDataDictionary WriteFieldIfNotExists(this ModDataDictionary data, string key, string value)
 {
     if (!data.ContainsKey(key))
     {
         data[key] = value;
     }
     return(data);
 }
 /// <summary>Read a container preference from a mod data dictionary.</summary>
 /// <param name="data">The mod data dictionary to read.</param>
 /// <param name="key">The dictionary key to read.</param>
 private static AutomateContainerPreference ReadPreferenceField(this ModDataDictionary data, string key)
 {
     data.TryGetValue(key, out string rawValue);
     return(rawValue switch
     {
         nameof(AutomateContainerPreference.Allow) => AutomateContainerPreference.Allow,
         nameof(AutomateContainerPreference.Prefer) => AutomateContainerPreference.Prefer,
         nameof(AutomateContainerPreference.Disable) => AutomateContainerPreference.Disable,
         _ => AutomateContainerPreference.Allow
     });
Beispiel #5
0
        /// <summary>Increment a long integer field from the mod data dictionary.</summary>
        /// <param name="data">The mod data dictionary to update.</param>
        /// <param name="key">The dictionary key to write.</param>
        /// <param name="amount">Amount to increment by.</param>
        public static ModDataDictionary IncrementField(this ModDataDictionary data, string key, long amount)
        {
            if (data.TryGetValue(key, out var rawValue))
            {
                var num = long.Parse(rawValue);
                data[key] = Math.Max(num + amount, 0).ToString();
            }

            return(data);
        }
Beispiel #6
0
        /// <summary>Increment a double-precision field from the mod data dictionary.</summary>
        /// <param name="data">The mod data dictionary to update.</param>
        /// <param name="key">The dictionary key to write.</param>
        /// <param name="amount">Amount to increment by.</param>
        public static ModDataDictionary IncrementField(this ModDataDictionary data, string key, double amount)
        {
            if (data.TryGetValue(key, out var rawValue))
            {
                var num = double.Parse(rawValue);
                data[key] = (num + amount).ToString(CultureInfo.InvariantCulture);
            }

            return(data);
        }
Beispiel #7
0
        public static bool GetBool(this ModDataDictionary d, string key, bool defaultValue = false)
        {
            string strVal = null;

            if (d.TryGetValue(key, out strVal))
            {
                return(strVal == "1" || strVal == "T");
            }
            return(defaultValue);
        }
Beispiel #8
0
        public static int GetInt(this ModDataDictionary d, string key, int defaultValue = 0)
        {
            int    result = defaultValue;
            string strVal;

            if (d.TryGetValue(key, out strVal))
            {
                int.TryParse(strVal, out result);
            }
            return(result);
        }
 /// <summary>Write an integer value into the mod data, or remove it if it matches the <paramref name="default"/>.</summary>
 /// <param name="data">The mod data dictionary.</param>
 /// <param name="key">The data key within the <paramref name="data"/>.</param>
 /// <param name="value">The value to write.</param>
 /// <param name="default">The default value if the field is missing or invalid. If the value matches the default, it won't be written to the data to avoid unneeded serialization and network sync.</param>
 /// <param name="min">The minimum value to consider valid, or <c>null</c> to allow any value.</param>
 public static void SetInt(this ModDataDictionary data, string key, int value, int @default = 0, int?min = null)
 {
     if (value == @default || value <= min)
     {
         data.Remove(key);
     }
     else
     {
         data[key] = value.ToString(CultureInfo.InvariantCulture);
     }
 }
 /// <summary>Write a boolean value into the mod data, or remove it if it matches the <paramref name="default"/>.</summary>
 /// <param name="data">The mod data dictionary.</param>
 /// <param name="key">The data key within the <paramref name="data"/>.</param>
 /// <param name="value">The value to write.</param>
 /// <param name="default">The default value if the field is missing or invalid. If the value matches the default, it won't be written to the data to avoid unneeded serialization and network sync.</param>
 public static void SetBool(this ModDataDictionary data, string key, bool value, bool @default = false)
 {
     if (value == @default)
     {
         data.Remove(key);
     }
     else
     {
         data[key] = value.ToString(CultureInfo.InvariantCulture);
     }
 }
        /// <summary>Load contain data for the given item.</summary>
        /// <param name="data">The mod data to read.</param>
        /// <param name="discriminator">A key added to the mod data keys to distinguish different containers in the same mod data.</param>
        public ContainerData(ModDataDictionary data, string discriminator = null)
        {
            string prefix = ContainerData.GetKeyPrefix(discriminator);

            this.IsIgnored          = data.ReadField($"{prefix}/{nameof(ContainerData.IsIgnored)}", bool.Parse);
            this.Category           = data.ReadField($"{prefix}/{nameof(ContainerData.Category)}");
            this.Name               = data.ReadField($"{prefix}/{nameof(ContainerData.Name)}");
            this.Order              = data.ReadField($"{prefix}/{nameof(ContainerData.Order)}", int.Parse);
            this.AutomateStoreItems = data.ReadField(AutomateContainerHelper.StoreItemsKey, p => (AutomateContainerPreference)Enum.Parse(typeof(AutomateContainerPreference), p), defaultValue: AutomateContainerPreference.Allow);
            this.AutomateTakeItems  = data.ReadField(AutomateContainerHelper.TakeItemsKey, p => (AutomateContainerPreference)Enum.Parse(typeof(AutomateContainerPreference), p), defaultValue: AutomateContainerPreference.Allow);
        }
Beispiel #12
0
 /// <summary>Write a field to a mod data dictionary, or remove it if null.</summary>
 /// <param name="data">The mod data dictionary to update.</param>
 /// <param name="key">The dictionary key to write.</param>
 /// <param name="value">The value to write, or <c>null</c> to remove it.</param>
 public static ModDataDictionary WriteField(this ModDataDictionary data, string key, string value)
 {
     if (string.IsNullOrWhiteSpace(value))
     {
         data.Remove(key);
     }
     else
     {
         data[key] = value;
     }
     return(data);
 }
Beispiel #13
0
        /// <summary>Save the container data to the given mod data.</summary>
        /// <param name="data">The mod data.</param>
        /// <param name="discriminator">A key added to the mod data keys to distinguish different containers in the same mod data.</param>
        public void ToModData(ModDataDictionary data, string discriminator = null)
        {
            string prefix = ContainerData.GetKeyPrefix(discriminator);

            data
            .WriteField($"{prefix}/{nameof(ContainerData.IsIgnored)}", this.IsIgnored ? "true" : null)
            .WriteField($"{prefix}/{nameof(ContainerData.Category)}", this.Category)
            .WriteField($"{prefix}/{nameof(ContainerData.Name)}", !this.HasDefaultDisplayName() ? this.Name : null)
            .WriteField($"{prefix}/{nameof(ContainerData.Order)}", this.Order != 0 ? this.Order?.ToString(CultureInfo.InvariantCulture) : null)
            .WriteField(AutomateContainerHelper.StoreItemsKey, this.AutomateStoreItems != AutomateContainerPreference.Allow ? this.AutomateStoreItems.ToString() : null)
            .WriteField(AutomateContainerHelper.TakeItemsKey, this.AutomateTakeItems != AutomateContainerPreference.Allow ? this.AutomateTakeItems.ToString() : null);
        }
Beispiel #14
0
        /// <summary>Load contain data for the given item.</summary>
        /// <param name="data">The mod data to read.</param>
        /// <param name="defaultInternalName">The game's default name for the container, if any.</param>
        /// <param name="discriminator">A key added to the mod data keys to distinguish different containers in the same mod data.</param>
        public static ContainerData FromModData(ModDataDictionary data, string defaultInternalName, string discriminator = null)
        {
            string prefix = ContainerData.GetKeyPrefix(discriminator);

            return(new ContainerData(defaultInternalName)
            {
                IsIgnored = data.ReadField($"{prefix}/{nameof(ContainerData.IsIgnored)}", bool.Parse),
                Category = data.ReadField($"{prefix}/{nameof(ContainerData.Category)}"),
                Name = data.ReadField($"{prefix}/{nameof(ContainerData.Name)}"),
                Order = data.ReadField($"{prefix}/{nameof(ContainerData.Order)}", int.Parse),
                AutomateStoreItems = data.ReadField(AutomateContainerHelper.StoreItemsKey, p => (AutomateContainerPreference)Enum.Parse(typeof(AutomateContainerPreference), p), defaultValue: AutomateContainerPreference.Allow),
                AutomateTakeItems = data.ReadField(AutomateContainerHelper.TakeItemsKey, p => (AutomateContainerPreference)Enum.Parse(typeof(AutomateContainerPreference), p), defaultValue: AutomateContainerPreference.Allow)
            });
        }
        /// <summary>Write a value into the mod data with custom serialization, or remove it if it serializes to null or an empty string.</summary>
        /// <typeparam name="T">The value type.</typeparam>
        /// <param name="data">The mod data dictionary.</param>
        /// <param name="key">The field key.</param>
        /// <param name="value">The value to save.</param>
        /// <param name="serialize">Serialize the value to its string representation.</param>
        public static void SetCustom <T>(this ModDataDictionary data, string key, T value, Func <T, string> serialize = null)
        {
            string serialized = serialize != null
                ? serialize(value)
                : value?.ToString();

            if (string.IsNullOrWhiteSpace(serialized))
            {
                data.Remove(key);
            }
            else
            {
                data[key] = serialized;
            }
        }
        /****
        ** Custom
        ****/
        /// <summary>Read a value from the mod data with custom parsing if it exists and can be parsed, else get the default value.</summary>
        /// <typeparam name="T">The value type.</typeparam>
        /// <param name="data">The mod data dictionary.</param>
        /// <param name="key">The data key within the <paramref name="data"/>.</param>
        /// <param name="parse">Parse the raw value.</param>
        /// <param name="default">The default value if the field is missing or invalid.</param>
        /// <param name="suppressError">Whether to return the default value if <paramref name="parse"/> throws an exception; else rethrow it.</param>
        public static T GetCustom <T>(this ModDataDictionary data, string key, Func <string, T> parse, T @default = default, bool suppressError = true)
        {
            if (!data.TryGetValue(key, out string raw))
            {
                return(@default);
            }

            try
            {
                return(parse(raw));
            }
            catch when(suppressError)
            {
                return(@default);
            }
        }
Beispiel #17
0
        public Item GetWrappedGift(ModDataDictionary modData)
        {
            // Object-based solution for wrapped gifts:
            Item wrappedGift = new StardewValley.Object(parentSheetIndex: JsonAssets.GetObjectId(AssetPrefix + WrappedGiftName), initialStack: 1)
            {
                // Tackle category: Cannot be stacked higher than 1, which solves the issue of modData folding.
                // The unfortunate side-effect is that they can, however, be attached to rods. We'll sort this out in ButtonPressed.
                Category = -22
            };

            if (modData != null)
            {
                wrappedGift.modData = modData;
            }
            return(wrappedGift);
        }
Beispiel #18
0
 /// <summary>
 /// Apply the values in the given ModDataDictionary to this bot,
 /// configuring name, energy, etc.
 /// </summary>
 void ApplyModData(ModDataDictionary d, bool includingEnergy = true)
 {
     if (!d.GetBool(dataKey.isBot))
     {
         Debug.Log("ERROR: ApplyModData called with modData where isBot is not true!");
     }
     Name = d.GetString(dataKey.name, name);
     if (includingEnergy)
     {
         farmer.Stamina = d.GetInt(dataKey.energy, energy);
     }
     farmer.faceDirection(d.GetInt(dataKey.facing, facingDirection));
     if (string.IsNullOrEmpty(name))
     {
         Name = "Bot " + (uniqueFarmerID++);
     }
     //Debug.Log($"after ApplyModData, name=[{name}]");
 }
        internal static void DumpObject(string sName, ModDataDictionary oData)
        {
            if (oData == null)
            {
                LogTrace("ModDataDictionary " + sName, "is null");
            }
            else
            {
                LogTrace("ModDataDictionary " + sName, "");
                LogTrace("{", "");

                foreach (string key in oData.Keys)
                {
                    DumpObject("  " + key, oData[key]);
                }
                LogTrace("}", "");
            }
        }
        public static void SetFloat(this ModDataDictionary data, string key, float value, float @default = 0, float?min = null, float?max = null)
        {
            if (value < min)
            {
                value = min.Value;
            }
            if (value > max)
            {
                value = max.Value;
            }

            if (value == @default)
            {
                data.Remove(key);
            }
            else
            {
                data[key] = value.ToString(CultureInfo.InvariantCulture);
            }
        }
Beispiel #21
0
        public override void Load(ModDataDictionary data)
        {
            base.Load(data);

            /*
             * FOR 1.6
             * DataAccess DataAccess = DataAccess.GetDataAccess();
             * modData = data;
             * if (DataAccess.LocationNodes.ContainsKey(Game1.currentLocation))
             * {
             *      List<Node> nodes = DataAccess.LocationNodes[Game1.currentLocation];
             *      Node node = nodes.Find(n => n.Position.Equals(TileLocation));
             *      if (node != null && node is PipeNode)
             *      {
             *              PipeNode pipe = (PipeNode)node;
             *              if (modData["StoredItem"] != null)
             *              {
             *                      string name = modData["StoredItem"];
             *                      if (DataAccess.ModItems.Contains(name) && name != "Wrench")
             *                      {
             *                              CustomObjectItem obj = Factories.ItemFactory.CreateItem(name);
             *                              if (modData["StoredItemStack"] != null)
             *                              {
             *                                      obj.stack.Value = Int32.Parse(modData["StoredItemStack"]);
             *                              }
             *                              pipe.StoredItem = obj;
             *                                                                              }
             *                      else if (DataAccess.ModItems.Contains(name) && name == "Wrench")
             *                      {
             *                              CustomToolItem obj = Factories.ItemFactory.CreateTool(name);
             *                              pipe.StoredItem = obj;
             *                      }
             *              }
             *
             *      }
             * }
             */
        }
Beispiel #22
0
 public virtual void Load(ModDataDictionary data)
 {
     modData     = data;
     stack.Value = Int32.Parse(modData["Stack"]);
 }
 /****
 ** Float
 ****/
 /// <summary>Read a float value from the mod data if it exists and is valid, else get the default value.</summary>
 /// <param name="data">The mod data dictionary.</param>
 /// <param name="key">The data key within the <paramref name="data"/>.</param>
 /// <param name="default">The default value if the field is missing or invalid.</param>
 /// <param name="min">The minimum value to consider valid, or <c>null</c> to allow any value.</param>
 public static float GetFloat(this ModDataDictionary data, string key, float @default = 0, float?min = null)
 {
     return(data.TryGetValue(key, out string raw) && float.TryParse(raw, out float value) && value >= min
         ? value
         : @default);
 }
Beispiel #24
0
 public ModDataDictionaryWrapper(ModDataDictionary modDataDictionary) => GetBaseType = modDataDictionary;
 /*********
 ** Public methods
 *********/
 /****
 ** Bool
 ****/
 /// <summary>Read a boolean value from the mod data if it exists and is valid, else get the default value.</summary>
 /// <param name="data">The mod data dictionary.</param>
 /// <param name="key">The data key within the <paramref name="data"/>.</param>
 /// <param name="default">The default value if the field is missing or invalid.</param>
 public static bool GetBool(this ModDataDictionary data, string key, bool @default = false)
 {
     return(data.TryGetValue(key, out string raw) && bool.TryParse(raw, out bool value)
         ? value
         : @default);
 }
Beispiel #26
0
        public Item UnpackItem(ModDataDictionary modData, string recipientName)
        {
            string[] fields = new[] {
                "giftsender", "giftname", "giftid",
                "giftparentid", "gifttype", "giftstack",
                "giftquality", "giftpreserve", "gifthoney",
                "giftcolour", "giftdata"
            };
            if (fields.Any(field => !modData.ContainsKey(AssetPrefix + field)))
            {
                string msg = fields.Where(field => !modData.ContainsKey(field))
                             .Aggregate("This gift is missing data:", (str, field) => str + "\n" + field)
                             + "\nIf this gift was placed before updating, please revert to the previous version and collect the gift!"
                             + "\nOtherwise, leave a report on the mod page for Gift Wrapper with your log file (https://smapi.io/log).";
                Monitor.Log(msg, LogLevel.Warn);
                return(null);
            }

            // Parse the wrapped gift's serialised modData fields to use in rebuilding its gift item
            long   giftSender   = long.Parse(modData[AssetPrefix + fields[0]]);
            string giftName     = modData[AssetPrefix + fields[1]];
            int    giftId       = int.Parse(modData[AssetPrefix + fields[2]]);
            int    giftParentId = int.Parse(modData[AssetPrefix + fields[3]]);
            int    giftType     = int.Parse(modData[AssetPrefix + fields[4]]);
            int    giftStack    = int.Parse(modData[AssetPrefix + fields[5]]);
            int    giftQuality  = int.Parse(modData[AssetPrefix + fields[6]]);
            int    giftPreserve = int.Parse(modData[AssetPrefix + fields[7]]);
            int    giftHoney    = int.Parse(modData[AssetPrefix + fields[8]]);
            string giftColour   = modData[AssetPrefix + fields[9]];
            string giftData     = modData[AssetPrefix + fields[10]];
            Item   actualGift   = null;

            switch (giftType)
            {
            case (int)GiftType.BedFurniture:
                actualGift = new BedFurniture(which: giftId, tile: Vector2.Zero);
                break;

            case (int)GiftType.Furniture:
                actualGift = new Furniture(which: giftId, tile: Vector2.Zero);
                break;

            case (int)GiftType.BigCraftable:
                actualGift = new StardewValley.Object(tileLocation: Vector2.Zero, parentSheetIndex: giftId, isRecipe: false);
                break;

            case (int)GiftType.MeleeWeapon:
                actualGift = new MeleeWeapon(spriteIndex: giftId);
                break;

            case (int)GiftType.Hat:
                actualGift = new Hat(which: giftId);
                break;

            case (int)GiftType.Boots:
                actualGift = new Boots(which: giftId);                         // todo: test boots colour
                ((Boots)actualGift).appliedBootSheetIndex.Set(giftQuality);
                ((Boots)actualGift).indexInColorSheet.Set(int.Parse(giftColour));
                break;

            case (int)GiftType.Clothing:
                int[] colourSplit = giftColour.Split('/').ToList().ConvertAll(int.Parse).ToArray();
                Color colour      = new Color(r: colourSplit[0], g: colourSplit[1], b: colourSplit[2], a: colourSplit[3]);
                actualGift = new Clothing(item_index: giftId);
                ((Clothing)actualGift).clothesColor.Set(colour);
                break;

            case (int)GiftType.Ring:
                actualGift = new Ring(which: giftId);
                break;

            case (int)GiftType.Object:
                actualGift = new StardewValley.Object(parentSheetIndex: giftId, initialStack: giftStack)
                {
                    Quality = giftQuality
                };
                actualGift.Name = giftName;
                if (giftParentId != -1)
                {
                    ((StardewValley.Object)actualGift).preservedParentSheetIndex.Value = giftParentId;
                }
                if (giftPreserve != -1)
                {
                    ((StardewValley.Object)actualGift).preserve.Value = (StardewValley.Object.PreserveType)giftPreserve;
                }
                if (giftHoney != 0)
                {
                    ((StardewValley.Object)actualGift).honeyType.Value = (StardewValley.Object.HoneyType)giftHoney;
                }
                break;
            }

            if (actualGift == null)
            {
                return(null);
            }

            Dictionary <string, string> giftDataDeserialised = ((Newtonsoft.Json.Linq.JObject)JsonConvert.DeserializeObject(giftData)).ToObject <Dictionary <string, string> >();

            if (giftDataDeserialised != null)
            {
                // Apply serialised mod data back to the gifted item
                actualGift.modData.Set(giftDataDeserialised);
            }

            if (recipientName != null && Game1.player.UniqueMultiplayerID != giftSender)
            {
                // Show a message to all players to celebrate this wonderful event
                Multiplayer multiplayer = Helper.Reflection.GetField <Multiplayer>(typeof(Game1), "multiplayer").GetValue();
                multiplayer.globalChatInfoMessage(AssetPrefix + (giftStack > 1 ? "message.giftopened_quantity" : "message.giftopened"),
                                                  recipientName,                    // Recipient's name
                                                  Game1.getFarmer(giftSender).Name, // Sender's name
                                                  actualGift.DisplayName,           // Gift name
                                                  giftStack.ToString());            // Gift quantity
            }

            return(actualGift);
        }
 /*********
 ** Public fields
 *********/
 /// <summary>Read a field from the mod data dictionary.</summary>
 /// <typeparam name="T">The field type.</typeparam>
 /// <param name="data">The mod data dictionary to read.</param>
 /// <param name="key">The dictionary key to read.</param>
 /// <param name="parse">Convert the raw string value into the expected type.</param>
 /// <param name="defaultValue">The default value to return if the data field isn't set.</param>
 public static T ReadField <T>(this ModDataDictionary data, string key, Func <string, T> parse, T defaultValue = default)
 {
     return(data.TryGetValue(key, out string rawValue)
         ? parse(rawValue)
         : defaultValue);
 }
 /****
 ** Int
 ****/
 /// <summary>Read an integer value from the mod data if it exists and is valid, else get the default value.</summary>
 /// <param name="data">The mod data dictionary.</param>
 /// <param name="key">The data key within the <paramref name="data"/>.</param>
 /// <param name="default">The default value if the field is missing or invalid.</param>
 /// <param name="min">The minimum value to consider valid, or <c>null</c> to allow any value.</param>
 public static int GetInt(this ModDataDictionary data, string key, int @default = 0, int?min = null)
 {
     return(data.TryGetValue(key, out string raw) && int.TryParse(raw, out int value) && value >= min
         ? value
         : @default);
 }
 /// <summary>Read a field from the mod data dictionary.</summary>
 /// <param name="data">The mod data dictionary to read.</param>
 /// <param name="key">The dictionary key to read.</param>
 /// <param name="defaultValue">The default value to return if the data field isn't set.</param>
 public static string ReadField(this ModDataDictionary data, string key, string defaultValue = null)
 {
     return(data.TryGetValue(key, out string rawValue)
         ? rawValue
         : defaultValue);
 }
 public virtual void Load(ModDataDictionary data)
 {
     modData = data;
 }