public static string GetString(this ModDataDictionary d, string key, string defaultValue = null) { string result = defaultValue; d.TryGetValue(key, out result); return(result); }
//---------------------------------------------------------------------- // 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(); }
/// <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 });
/// <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); }
/// <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); }
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); }
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); }
/// <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); }
/// <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); }
/// <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); } }
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); }
/// <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); } }
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; * } * } * * } * } */ }
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); }
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); }
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; }