public RichEvent(string?simpleLabel, IEnumerable <IFlowNode>?advancedLabel = null, SpriteInfo?sprite = null, Item?item = null) { SimpleLabel = simpleLabel; AdvancedLabel = advancedLabel; Sprite = sprite; Item = item; }
public SpriteNode( SpriteInfo?sprite, float scale, Alignment?align = null, Func <IFlowNodeSlice, int, int, bool>?onClick = null, Func <IFlowNodeSlice, int, int, bool>?onHover = null, Func <IFlowNodeSlice, int, int, bool>?onRightClick = null, bool noComponent = false, float size = 16, int frame = -1, object?extra = null, string?id = null ) { Sprite = sprite; Scale = scale; Size = size; Alignment = align ?? Alignment.None; OnClick = onClick; OnHover = onHover; OnRightClick = onRightClick; NoComponent = noComponent; Frame = frame; Extra = extra; UniqueId = id; }
public SpriteNode(SpriteInfo?sprite, float scale = 4f, string?label = null, int quantity = 0, Alignment alignment = Alignment.None) { Sprite = sprite; Scale = scale; Label = label; Quantity = quantity; Alignment = alignment; }
/********* ** Private methods *********/ /// <summary>Get the internal drop list entries.</summary> /// <param name="drops">The possible drops.</param> /// <param name="gameHelper">Provides utility methods for interacting with the game code.</param> private IEnumerable <Tuple <ItemDropData, SObject, SpriteInfo?> > GetEntries(IEnumerable <ItemDropData> drops, GameHelper gameHelper) { foreach (ItemDropData drop in drops) { SObject item = this.GameHelper.GetObjectBySpriteIndex(drop.ItemID); SpriteInfo?sprite = gameHelper.GetSprite(item); yield return(Tuple.Create(drop, item, sprite)); } }
/********* ** Private methods *********/ /// <summary>Get a fish pond's possible drops by population.</summary> /// <param name="currentPopulation">The current population for showing unlocked drops.</param> /// <param name="data">The fish pond data.</param> /// <param name="gameHelper">Provides utility methods for interacting with the game code.</param> /// <remarks>Derived from <see cref="FishPond.dayUpdate"/> and <see cref="FishPond.GetFishProduce"/>.</remarks> private IEnumerable <FishPondDrop> GetEntries(int currentPopulation, FishPondData data, GameHelper gameHelper) { foreach (FishPondDropData drop in gameHelper.GetFishPondDrops(data)) { bool isUnlocked = currentPopulation >= drop.MinPopulation; SObject item = this.GameHelper.GetObjectBySpriteIndex(drop.ItemID); SpriteInfo?sprite = gameHelper.GetSprite(item); yield return(new FishPondDrop(drop, item, sprite, isUnlocked)); } }
/********* ** Public methods *********/ /// <summary>Construct an instance.</summary> /// <param name="gameHelper">Provides utility methods for interacting with the game code.</param> /// <param name="label">A short field label.</param> /// <param name="item">The item for which to display an icon.</param> /// <param name="codex">Provides subject entries to create a link, if applicable.</param> /// <param name="text">The text to display (if not the item name).</param> public ItemIconField(GameHelper gameHelper, string label, Item?item, ISubjectRegistry?codex, string?text = null) : base(label, hasValue: item != null) { this.Sprite = gameHelper.GetSprite(item); if (item != null) { this.LinkSubject = codex?.GetByEntity(item, null); text = !string.IsNullOrWhiteSpace(text) ? text : item.DisplayName; Color?color = this.LinkSubject != null ? Color.Blue : null; this.Value = new IFormattedText[] { new FormattedText(text, color) }; } }
public void AddCrop( string id, Item item, string name, SpriteInfo?sprite, bool isTrellisCrop, bool isGiantCrop, SpriteInfo?giantSprite, Item[]?seeds, bool isPaddyCrop, IEnumerable <int> phases, IEnumerable <SpriteInfo?>?phaseSprites, int regrow, WorldDate start, WorldDate end ) { Crops[id] = new CropInfo( Id: id, Item: item, Name: name, Sprite: sprite, IsTrellisCrop: isTrellisCrop, IsGiantCrop: isGiantCrop, GiantSprite: giantSprite, Seeds: seeds, Phases: phases.ToArray(), PhaseSprites: phaseSprites?.ToArray(), Regrow: regrow, IsPaddyCrop: isPaddyCrop, StartDate: start, EndDate: end ); }
/// <summary>Create a recipe item model.</summary> /// <param name="name">The display name for the item.</param> /// <param name="item">The instance of the item.</param> /// <param name="sprite">The item sprite, or <c>null</c> to generate it automatically.</param> /// <param name="minCount">The minimum number of items needed or created.</param> /// <param name="maxCount">The maximum number of items needed or created.</param> /// <param name="chance">The chance of creating an output item.</param> /// <param name="isOutput">Whether the item is output or input.</param> private RecipeItemEntry CreateItemEntry(string name, Item?item = null, SpriteInfo?sprite = null, int minCount = 1, int maxCount = 1, decimal chance = 100, bool isOutput = false) { // get display text string text; { // name + count if (minCount != maxCount) { text = I18n.Item_RecipesForMachine_MultipleItems(name: name, count: I18n.Generic_Range(min: minCount, max: maxCount)); } else if (minCount > 1) { text = I18n.Item_RecipesForMachine_MultipleItems(name: name, count: minCount); } else { text = name; } // chance if (chance is > 0 and < 100) { text += $" ({I18n.Generic_Percent(chance)})"; } // output suffix if (isOutput) { text += ":"; } } return(new RecipeItemEntry( Sprite: sprite ?? this.GameHelper.GetSprite(item), DisplayText: text )); }
/// <summary>Draw a sprite to the screen scaled and centered to fit the given dimensions.</summary> /// <param name="spriteBatch">The sprite batch being drawn.</param> /// <param name="sprite">The sprite to draw.</param> /// <param name="x">The X-position at which to draw the sprite.</param> /// <param name="y">The X-position at which to draw the sprite.</param> /// <param name="size">The size to draw.</param> /// <param name="color">The color to tint the sprite.</param> public static void DrawSpriteWithin(this SpriteBatch spriteBatch, SpriteInfo?sprite, float x, float y, Vector2 size, Color?color = null) { sprite?.Draw(spriteBatch, (int)x, (int)y, size, color); }
public SimpleBuilder Sprite(SpriteInfo?sprite, float scale = 4f, string?label = null, int quantity = 0, Alignment align = Alignment.None) { AssertState(); Nodes.Add(new SpriteNode(sprite, scale, label, quantity, align)); return(this); }
/// <summary>Draw text with an icon.</summary> /// <param name="batch">The sprite batch.</param> /// <param name="font">The sprite font.</param> /// <param name="position">The position at which to draw the text.</param> /// <param name="absoluteWrapWidth">The width at which to wrap the text.</param> /// <param name="text">The block of text to write.</param> /// <param name="textColor">The text color.</param> /// <param name="icon">The sprite to draw.</param> /// <param name="iconSize">The size to draw.</param> /// <param name="iconColor">The color to tint the sprite.</param> /// <param name="probe">Whether to calculate the positions without actually drawing anything to the screen.</param> /// <returns>Returns the drawn size.</returns> private Vector2 DrawIconText(SpriteBatch batch, SpriteFont font, Vector2 position, float absoluteWrapWidth, string text, Color textColor, SpriteInfo?icon = null, Vector2?iconSize = null, Color?iconColor = null, bool probe = false) { // draw icon int textOffset = 0; if (icon != null && iconSize.HasValue) { if (!probe) { batch.DrawSpriteWithin(icon, position.X, position.Y, iconSize.Value, iconColor); } textOffset = this.IconMargin; } else { iconSize = Vector2.Zero; } // draw text Vector2 textSize = probe ? font.MeasureString(text) : batch.DrawTextBlock(font, text, position + new Vector2(iconSize.Value.X + textOffset, 0), absoluteWrapWidth - position.X, textColor); // get drawn size return(new Vector2( x: iconSize.Value.X + textSize.X, y: Math.Max(iconSize.Value.Y, textSize.Y) )); }
/********* ** Public methods *********/ /// <summary>Construct an instance.</summary> /// <param name="gameHelper">Provides utility methods for interacting with the game code.</param> /// <param name="value">The underlying in-game entity.</param> /// <param name="tilePosition">The object's tile position in the current location (if applicable).</param> /// <param name="reflection">Simplifies access to private game code.</param> /// <param name="getSubject">Get the subject info about the target.</param> public ObjectTarget(GameHelper gameHelper, SObject value, Vector2 tilePosition, IReflectionHelper reflection, Func <ISubject> getSubject) : base(gameHelper, SubjectType.Object, value, tilePosition, getSubject) { this.Reflection = reflection; this.CustomSprite = gameHelper.GetSprite(value, onlyCustom: true); // only get sprite if it's custom; else we'll use contextual logic (e.g. for fence direction) }
private CropInfo?GetCropInfo(int id, string data) { // TODO: Create Crop instances so we can // lean more on vanilla logic. string[] bits = data.Split('/'); if (bits.Length < 5) { return(null); } int sprite = Convert.ToInt32(bits[2]); int harvest = Convert.ToInt32(bits[3]); int regrow = Convert.ToInt32(bits[4]); bool isTrellisCrop = bits.Length > 7 && bits[7].Equals("true"); if (!Game1.objectInformation.ContainsKey(harvest)) { return(null); } string[] seasons = bits[1].Split(' ', StringSplitOptions.RemoveEmptyEntries); WorldDate?startDate = null; WorldDate?endDate = null; // TODO: Handle weird crops with a gap. foreach (string season in seasons) { WorldDate start; WorldDate end; try { start = new(1, season, 1); end = new(1, season, ModEntry.DaysPerMonth); } catch (Exception) { ModEntry.Instance.Log($"Invalid season for crop {id} (harvest:{harvest}): {season}", LogLevel.Warn); return(null); } if (startDate == null || startDate > start) { startDate = start; } if (endDate == null || endDate < end) { endDate = end; } } // Skip crops that don't have any valid seasons. // Who knows what else isn't valid? if (startDate == null || endDate == null) { return(null); } // Skip crops that are always active. if (startDate.SeasonIndex == 0 && startDate.DayOfMonth == 1 && endDate.SeasonIndex == (WorldDate.MonthsPerYear - 1) && endDate.DayOfMonth == ModEntry.DaysPerMonth) { return(null); } // If the sprite is 23, it's a seasonal multi-seed // so we want to show that rather than the seed. Item item = new SObject(sprite == 23 ? id : harvest, 1).getOne(); // Phases int[] phases = bits[0].Split(' ').Select(val => Convert.ToInt32(val)).ToArray(); // Stupid hard coded bullshit. bool paddyCrop = harvest == 271 || harvest == 830; // Phase Sprites // We need an extra sprite for the finished crop, // as well as one for regrow if that's enabled. SpriteInfo[] sprites = new SpriteInfo[phases.Length + 1 + (regrow > 0 ? 1 : 0)]; // Are we dealing with colors? Color?color = null; string[]? colorbits = regrow <= 0 && bits.Length > 8 ? bits[8].Split(' ') : null; if (colorbits != null && colorbits.Length >= 4 && colorbits[0].Equals("true")) { // Technically there could be many colors, but we just use // the first one. color = new( Convert.ToByte(colorbits[1]), Convert.ToByte(colorbits[2]), Convert.ToByte(colorbits[3]) ); } for (int i = 0; i < sprites.Length; i++) { bool final = i == (sprites.Length - (regrow > 0 ? 2 : 1)); sprites[i] = new( Game1.cropSpriteSheet, new Rectangle( Math.Min(240, (i + 1) * 16 + (sprite % 2 != 0 ? 128 : 0)), sprite / 2 * 16 * 2, 16, 32 ), overlaySource : final && color.HasValue ? new Rectangle( Math.Min(240, (i + 2) * 16 + (sprite % 2 != 0 ? 128 : 0)), sprite / 2 * 16 * 2, 16, 32 ) : null, overlayColor : final ? color : null ); } bool isGiantCrop = false; SpriteInfo?giantSprite = null; // Vanilla Giant Crops if (harvest == 190 || harvest == 254 || harvest == 276) { isGiantCrop = true; int which; if (harvest == 190) { which = 0; } else if (harvest == 254) { which = 1; } else { which = 2; } giantSprite = new( Game1.cropSpriteSheet, new Rectangle(112 + which * 48, 512, 48, 64) ); } // JsonAssets Giant Crops if (!isGiantCrop && Mod.intJA != null && Mod.intJA.IsLoaded) { Texture2D?tex = Mod.intJA.GetGiantCropTexture(harvest); if (tex != null) { isGiantCrop = true; giantSprite = new(tex, tex.Bounds); } } // MoreGiantCrops Giant Crops if (!isGiantCrop && Mod.intMGC != null && Mod.intMGC.IsGiantCrop(harvest)) { isGiantCrop = true; Texture2D?tex = Mod.intMGC.GetGiantCropTexture(harvest); if (tex != null) { giantSprite = new(tex, tex.Bounds); } } return(new( Id: Convert.ToString(id), Item : item, Name : item.DisplayName, Sprite : SpriteHelper.GetSprite(item), IsTrellisCrop : isTrellisCrop, IsGiantCrop : isGiantCrop, GiantSprite : giantSprite, Seeds : new Item[] { new SObject(id, 1) }, Phases : phases, PhaseSprites : sprites, Regrow : regrow, IsPaddyCrop : paddyCrop, StartDate : startDate, EndDate : endDate )); }