/// <inheritdoc /> public void AnimateFertilizer(StardewValley.Object obj, GameLocation loc, Vector2 tile) { if (obj.ParentSheetIndex == ModEntry.FishFoodID || obj.ParentSheetIndex == ModEntry.DeluxeFishFoodID || obj.ParentSheetIndex == ModEntry.DomesticatedFishFoodID) { Vector2 placementtile = (tile * 64f) + new Vector2(32f, 32f); if (obj.ParentSheetIndex == ModEntry.DomesticatedFishFoodID && Game1.currentLocation is BuildableGameLocation buildable) { foreach (Building b in buildable.buildings) { if (b is FishPond pond && b.occupiesTile(tile)) { placementtile = pond.GetCenterTile() * 64f; break; } } } Game1.playSound("throwDownITem"); float deltaY = -140f; float gravity = 0.0025f; float velocity = -0.08f - MathF.Sqrt(2 * 60f * gravity); float time = (MathF.Sqrt((velocity * velocity) - (gravity * deltaY * 2f)) / gravity) - (velocity / gravity); Multiplayer mp = MultiplayerHelpers.GetMultiplayer(); mp.broadcastSprites( Game1.currentLocation, new TemporaryAnimatedSprite( textureName: Game1.objectSpriteSheetName, sourceRect: Game1.getSourceRectForStandardTileSheet(Game1.objectSpriteSheet, obj.ParentSheetIndex, 16, 16), position: placementtile + new Vector2(0, deltaY), flipped: false, alphaFade: 0f, color: Color.White) { scale = Game1.pixelZoom, layerDepth = 1f, totalNumberOfLoops = 1, interval = time, acceleration = new Vector2(0f, gravity), motion = new Vector2(0f, velocity), timeBasedMotion = true, }); GameLocationUtils.DrawWaterSplash(Game1.currentLocation, placementtile, mp, (int)time); DelayedAction.playSoundAfterDelay("waterSlosh", (int)time, Game1.player.currentLocation); if (obj.ParentSheetIndex != ModEntry.DomesticatedFishFoodID) { DelayedAction.functionAfterDelay( () => Game1.currentLocation.waterColor.Value = ModEntry.Config.WaterOverlayColor, (int)time); } } }
private static void player_addItem(object sender, EventArgsCommand e) { if (e.Command.CalledArgs.Length > 0) { if (e.Command.CalledArgs[0].IsInt32()) { var count = 1; var quality = 0; if (e.Command.CalledArgs.Length > 1) { Console.WriteLine(e.Command.CalledArgs[1]); if (e.Command.CalledArgs[1].IsInt32()) { count = e.Command.CalledArgs[1].AsInt32(); } else { Log.AsyncR("[count] is invalid"); return; } if (e.Command.CalledArgs.Length > 2) { if (e.Command.CalledArgs[2].IsInt32()) { quality = e.Command.CalledArgs[2].AsInt32(); } else { Log.AsyncR("[quality] is invalid"); return; } } } var o = new Object(e.Command.CalledArgs[0].AsInt32(), count) {quality = quality}; Game1.player.addItemByMenuIfNecessary(o); } else { Log.AsyncR("<item> is invalid"); } } else { Log.LogObjectValueNotSpecified(); } }
public void importFarm(string[] p) { if (Game1.currentLocation is Farm) { Monitor.Log("You can't do this while you are on the farm", LogLevel.Warn); return; } if (p.Length == 0) { Monitor.Log("No plan id provided", LogLevel.Warn); return; } string id = p[0]; if (!Imports.ContainsKey(id)) { Monitor.Log("Could not find a plan with the id " + id + ". Checking online..", LogLevel.Warn); importFarmWeb(p); return; } Import import = Imports[id]; Monitor.Log("Clearing Farm", LogLevel.Trace); Farm farm = Game1.getFarm(); farm.objects.Clear(); farm.largeTerrainFeatures.Clear(); farm.terrainFeatures.Clear(); farm.buildings.Clear(); farm.animals.Clear(); farm.resourceClumps.Clear(); Monitor.Log("OK", LogLevel.Trace); Monitor.Log("Importing: " + id, LogLevel.Info); List <ImportTile> list = import.tiles; list.AddRange(import.buildings); foreach (ImportTile tile in list) { Vector2 pos = new Vector2(int.Parse(tile.x) / 16, int.Parse(tile.y) / 16); TerrainFeature tf = getTerrainFeature(tile.type, pos); if (tf != null) { if (tf is FruitTree ft) { ft.growthStage.Value = 5; ft.daysUntilMature.Value = 0; } if (farm.terrainFeatures.ContainsKey(pos)) { farm.terrainFeatures[pos] = tf; } else { farm.terrainFeatures.Add(pos, tf); } } SObject obj = getObject(tile.type, pos); if (obj != null) { if (farm.Objects.ContainsKey(pos)) { farm.Objects[pos] = obj; } else { farm.Objects.Add(pos, obj); } } Building building = getBuilding(tile.type, pos); if (building != null) { building.daysOfConstructionLeft.Value = 0; farm.buildings.Add(building); } if (tile.type == "large-log") { farm.addResourceClumpAndRemoveUnderlyingTerrain(602, 2, 2, pos); } if (tile.type == "large-stump") { farm.addResourceClumpAndRemoveUnderlyingTerrain(600, 2, 2, pos); } if (tile.type == "large-rock") { farm.addResourceClumpAndRemoveUnderlyingTerrain(752, 2, 2, pos); } if (!tile.type.StartsWith("large-") && building == null && obj == null && tf == null) { Monitor.Log("Could not place tile: " + tile.type + " (unknown type)", LogLevel.Warn); } } }
/// <summary>Get the data to display for this subject.</summary> /// <param name="metadata">Provides metadata that's not available from the game data directly.</param> public override IEnumerable <ICustomField> GetData(Metadata metadata) { // get data Item item = this.Target; Object obj = item as Object; bool isObject = obj != null; bool isCrop = this.FromCrop != null; bool isSeed = this.SeedForCrop != null; bool isDeadCrop = this.FromCrop?.dead == true; bool canSell = obj?.canBeShipped() == true || metadata.Shops.Any(shop => shop.BuysCategories.Contains(item.category)); // get overrides bool showInventoryFields = true; { ObjectData objData = metadata.GetObject(item, this.Context); if (objData != null) { this.Name = objData.NameKey != null?this.Translate(objData.NameKey) : this.Name; this.Description = objData.DescriptionKey != null?this.Translate(objData.DescriptionKey) : this.Description; this.Type = objData.TypeKey != null?this.Translate(objData.TypeKey) : this.Type; showInventoryFields = objData.ShowInventoryFields ?? true; } } // don't show data for dead crop if (isDeadCrop) { yield return(new GenericField(this.Translate(L10n.Crop.Summary), this.Translate(L10n.Crop.SummaryDead))); yield break; } // crop fields if (isCrop || isSeed) { // get crop Crop crop = this.FromCrop ?? this.SeedForCrop; // get harvest schedule int harvestablePhase = crop.phaseDays.Count - 1; bool canHarvestNow = (crop.currentPhase >= harvestablePhase) && (!crop.fullyGrown || crop.dayOfCurrentPhase <= 0); int daysToFirstHarvest = crop.phaseDays.Take(crop.phaseDays.Count - 1).Sum(); // ignore harvestable phase // add next-harvest field if (isCrop) { // calculate next harvest int daysToNextHarvest = 0; GameDate dayOfNextHarvest = null; if (!canHarvestNow) { // calculate days until next harvest int daysUntilLastPhase = daysToFirstHarvest - crop.dayOfCurrentPhase - crop.phaseDays.Take(crop.currentPhase).Sum(); { // growing: days until next harvest if (!crop.fullyGrown) { daysToNextHarvest = daysUntilLastPhase; } // regrowable crop harvested today else if (crop.dayOfCurrentPhase >= crop.regrowAfterHarvest) { daysToNextHarvest = crop.regrowAfterHarvest; } // regrowable crop else { daysToNextHarvest = crop.dayOfCurrentPhase; // dayOfCurrentPhase decreases to 0 when fully grown, where <=0 is harvestable } } dayOfNextHarvest = GameHelper.GetDate(metadata.Constants.DaysInSeason).GetDayOffset(daysToNextHarvest); } // generate field string summary; if (canHarvestNow) { summary = this.Translate(L10n.Crop.HarvestNow); } else if (Game1.currentLocation.Name != Constant.LocationNames.Greenhouse && !crop.seasonsToGrowIn.Contains(dayOfNextHarvest.Season)) { summary = this.Translate(L10n.Crop.HarvestTooLate, new { date = this.Stringify(dayOfNextHarvest) }); } else { summary = $"{this.Stringify(dayOfNextHarvest)} ({this.Text.GetPlural(daysToNextHarvest, L10n.Generic.Tomorrow, L10n.Generic.InXDays).Tokens(new { count = daysToNextHarvest })})"; } yield return(new GenericField(this.Translate(L10n.Crop.Harvest), summary)); } // crop summary { List <string> summary = new List <string>(); // harvest summary.Add(crop.regrowAfterHarvest == -1 ? this.Translate(L10n.Crop.SummaryHarvestOnce, new { daysToFirstHarvest = daysToFirstHarvest }) : this.Translate(L10n.Crop.SummaryHarvestMulti, new { daysToFirstHarvest = daysToFirstHarvest, daysToNextHarvests = crop.regrowAfterHarvest }) ); // seasons summary.Add(this.Translate(L10n.Crop.SummarySeasons, new { seasons = string.Join(", ", this.Text.GetSeasonNames(crop.seasonsToGrowIn)) })); // drops if (crop.minHarvest != crop.maxHarvest && crop.chanceForExtraCrops > 0) { summary.Add(this.Translate(L10n.Crop.SummaryDropsXToY, new { min = crop.minHarvest, max = crop.maxHarvest, percent = Math.Round(crop.chanceForExtraCrops * 100, 2) })); } else if (crop.minHarvest > 1) { summary.Add(this.Translate(L10n.Crop.SummaryDropsX, new { count = crop.minHarvest })); } // crop sale price Item drop = GameHelper.GetObjectBySpriteIndex(crop.indexOfHarvest); summary.Add(this.Translate(L10n.Crop.SummarySellsFor, new { price = GenericField.GetSaleValueString(this.GetSaleValue(drop, false, metadata), 1, this.Text) })); // generate field yield return(new GenericField(this.Translate(L10n.Crop.Summary), "-" + string.Join($"{Environment.NewLine}-", summary))); } } // crafting if (obj?.heldObject != null) { if (obj is Cask cask) { // get cask data Object agingObj = cask.heldObject; ItemQuality curQuality = (ItemQuality)agingObj.quality; string curQualityName = this.Translate(L10n.For(curQuality)); // calculate aging schedule float effectiveAge = metadata.Constants.CaskAgeSchedule.Values.Max() - cask.daysToMature; var schedule = ( from entry in metadata.Constants.CaskAgeSchedule let quality = entry.Key let baseDays = entry.Value where baseDays > effectiveAge orderby baseDays ascending let daysLeft = (int)Math.Ceiling((baseDays - effectiveAge) / cask.agingRate) select new { Quality = quality, DaysLeft = daysLeft, HarvestDate = GameHelper.GetDate(metadata.Constants.DaysInSeason).GetDayOffset(daysLeft) } ) .ToArray(); // display fields yield return(new ItemIconField(this.Translate(L10n.Item.Contents), obj.heldObject)); if (cask.minutesUntilReady <= 0 || !schedule.Any()) { yield return(new GenericField(this.Translate(L10n.Item.CaskSchedule), this.Translate(L10n.Item.CaskScheduleNow, new { quality = curQualityName }))); } else { string scheduleStr = string.Join(Environment.NewLine, ( from entry in schedule let tokens = new { quality = this.Translate(L10n.For(entry.Quality)), count = entry.DaysLeft, date = entry.HarvestDate } let str = this.Text.GetPlural(entry.DaysLeft, L10n.Item.CaskScheduleTomorrow, L10n.Item.CaskScheduleInXDays).Tokens(tokens) select $"-{str}" )); yield return(new GenericField(this.Translate(L10n.Item.CaskSchedule), this.Translate(L10n.Item.CaskSchedulePartial, new { quality = curQualityName }) + Environment.NewLine + scheduleStr)); } } else { string summary = obj.minutesUntilReady <= 0 ? this.Translate(L10n.Item.ContentsReady, new { name = obj.heldObject.DisplayName }) : this.Translate(L10n.Item.ContentsPartial, new { name = obj.heldObject.DisplayName, time = this.Stringify(TimeSpan.FromMinutes(obj.minutesUntilReady)) }); yield return(new ItemIconField(this.Translate(L10n.Item.Contents), obj.heldObject, summary)); } } // item if (showInventoryFields) { // needed for { List <string> neededFor = new List <string>(); // bundles if (isObject) { string[] bundles = (from bundle in this.GetUnfinishedBundles(obj) orderby bundle.Area, bundle.DisplayName select $"{this.GetTranslatedBundleArea(bundle)}: {bundle.DisplayName}").ToArray(); if (bundles.Any()) { neededFor.Add(this.Translate(L10n.Item.NeededForCommunityCenter, new { bundles = string.Join(", ", bundles) })); } } // polyculture achievement if (isObject && metadata.Constants.PolycultureCrops.Contains(obj.ParentSheetIndex)) { int needed = metadata.Constants.PolycultureCount - GameHelper.GetShipped(obj.ParentSheetIndex); if (needed > 0) { neededFor.Add(this.Translate(L10n.Item.NeededForPolyculture, new { count = needed })); } } // full shipment achievement if (isObject && GameHelper.GetFullShipmentAchievementItems().Any(p => p.Key == obj.ParentSheetIndex && !p.Value)) { neededFor.Add(this.Translate(L10n.Item.NeededForFullShipment)); } // a full collection achievement LibraryMuseum museum = Game1.locations.OfType <LibraryMuseum>().FirstOrDefault(); if (museum != null && museum.isItemSuitableForDonation(obj)) { neededFor.Add(this.Translate(L10n.Item.NeededForFullCollection)); } // yield if (neededFor.Any()) { yield return(new GenericField(this.Translate(L10n.Item.NeededFor), string.Join(", ", neededFor))); } } // sale data if (canSell && !isCrop) { // sale price string saleValueSummary = GenericField.GetSaleValueString(this.GetSaleValue(item, this.KnownQuality, metadata), item.Stack, this.Text); yield return(new GenericField(this.Translate(L10n.Item.SellsFor), saleValueSummary)); // sell to List <string> buyers = new List <string>(); if (obj?.canBeShipped() == true) { buyers.Add(this.Translate(L10n.Item.SellsToShippingBox)); } buyers.AddRange( from shop in metadata.Shops where shop.BuysCategories.Contains(item.category) let name = this.Translate(shop.DisplayKey).ToString() orderby name select name ); yield return(new GenericField(this.Translate(L10n.Item.SellsTo), string.Join(", ", buyers))); } // gift tastes var giftTastes = this.GetGiftTastes(item, metadata); yield return(new ItemGiftTastesField(this.Translate(L10n.Item.LovesThis), giftTastes, GiftTaste.Love)); yield return(new ItemGiftTastesField(this.Translate(L10n.Item.LikesThis), giftTastes, GiftTaste.Like)); } // fence if (item is Fence fence) { string healthLabel = this.Translate(L10n.Item.FenceHealth); // health if (Game1.getFarm().isBuildingConstructed(Constant.BuildingNames.GoldClock)) { yield return(new GenericField(healthLabel, this.Translate(L10n.Item.FenceHealthGoldClock))); } else { float maxHealth = fence.isGate ? fence.maxHealth * 2 : fence.maxHealth; float health = fence.health / maxHealth; double daysLeft = Math.Round(fence.health * metadata.Constants.FenceDecayRate / 60 / 24); double percent = Math.Round(health * 100); yield return(new PercentageBarField(healthLabel, (int)fence.health, (int)maxHealth, Color.Green, Color.Red, this.Translate(L10n.Item.FenceHealthSummary, new { percent = percent, count = daysLeft }))); } } // recipes if (item.GetSpriteType() == ItemSpriteType.Object) { RecipeModel[] recipes = GameHelper.GetRecipesForIngredient(this.DisplayItem).ToArray(); if (recipes.Any()) { yield return(new RecipesForIngredientField(this.Translate(L10n.Item.Recipes), item, recipes, this.Text)); } } // owned if (showInventoryFields && !isCrop && !(item is Tool)) { yield return(new GenericField(this.Translate(L10n.Item.Owned), this.Translate(L10n.Item.OwnedSummary, new { count = GameHelper.CountOwnedItems(item) }))); } // see also crop bool seeAlsoCrop = isSeed && item.parentSheetIndex != this.SeedForCrop.indexOfHarvest && // skip seeds which produce themselves (e.g. coffee beans) !(item.parentSheetIndex >= 495 && item.parentSheetIndex <= 497) && // skip random seasonal seeds item.parentSheetIndex != 770; // skip mixed seeds if (seeAlsoCrop) { Item drop = GameHelper.GetObjectBySpriteIndex(this.SeedForCrop.indexOfHarvest); yield return(new LinkField(this.Translate(L10n.Item.SeeAlso), drop.DisplayName, () => new ItemSubject(this.Text, drop, ObjectContext.Inventory, false, this.SeedForCrop))); } }
public InserterPipeNode(Vector2 position, GameLocation location, StardewValley.Object obj) : base(position, location, obj) { Priority = 1; ItemTimer = 500; }
public IEnumerable <SearchableItem> GetAll() { IEnumerable <SearchableItem> GetAllRaw() { // get tools for (int quality = Tool.stone; quality <= Tool.iridium; quality++) { yield return(this.TryCreate(ItemType.Tool, ToolFactory.axe, () => ToolFactory.getToolFromDescription(ToolFactory.axe, quality))); yield return(this.TryCreate(ItemType.Tool, ToolFactory.hoe, () => ToolFactory.getToolFromDescription(ToolFactory.hoe, quality))); yield return(this.TryCreate(ItemType.Tool, ToolFactory.pickAxe, () => ToolFactory.getToolFromDescription(ToolFactory.pickAxe, quality))); yield return(this.TryCreate(ItemType.Tool, ToolFactory.wateringCan, () => ToolFactory.getToolFromDescription(ToolFactory.wateringCan, quality))); if (quality != Tool.iridium) { yield return(this.TryCreate(ItemType.Tool, ToolFactory.fishingRod, () => ToolFactory.getToolFromDescription(ToolFactory.fishingRod, quality))); } } yield return(this.TryCreate(ItemType.Tool, this.CustomIDOffset, () => new MilkPail())); // these don't have any sort of ID, so we'll just assign some arbitrary ones yield return(this.TryCreate(ItemType.Tool, this.CustomIDOffset + 1, () => new Shears())); yield return(this.TryCreate(ItemType.Tool, this.CustomIDOffset + 2, () => new Pan())); yield return(this.TryCreate(ItemType.Tool, this.CustomIDOffset + 3, () => new Wand())); // wallpapers for (int id = 0; id < 112; id++) { yield return(this.TryCreate(ItemType.Wallpaper, id, () => new Wallpaper(id) { Category = SObject.furnitureCategory })); } // flooring for (int id = 0; id < 40; id++) { yield return(this.TryCreate(ItemType.Flooring, id, () => new Wallpaper(id, isFloor: true) { Category = SObject.furnitureCategory })); } // equipment foreach (int id in Game1.content.Load <Dictionary <int, string> >("Data\\Boots").Keys) { yield return(this.TryCreate(ItemType.Boots, id, () => new Boots(id))); } foreach (int id in Game1.content.Load <Dictionary <int, string> >("Data\\hats").Keys) { yield return(this.TryCreate(ItemType.Hat, id, () => new Hat(id))); } foreach (int id in Game1.objectInformation.Keys) { if (id >= Ring.ringLowerIndexRange && id <= Ring.ringUpperIndexRange) { yield return(this.TryCreate(ItemType.Ring, id, () => new Ring(id))); } } // weapons foreach (int id in Game1.content.Load <Dictionary <int, string> >("Data\\weapons").Keys) { Item weapon = (id >= 32 && id <= 34) ? (Item) new Slingshot(id) : new MeleeWeapon(id); yield return(this.TryCreate(ItemType.Weapon, id, () => weapon)); } // furniture foreach (int id in Game1.content.Load <Dictionary <int, string> >("Data\\Furniture").Keys) { if (id == 1466 || id == 1468) { yield return(this.TryCreate(ItemType.Furniture, id, () => new TV(id, Vector2.Zero))); } else { yield return(this.TryCreate(ItemType.Furniture, id, () => new Furniture(id, Vector2.Zero))); } } // craftables foreach (int id in Game1.bigCraftablesInformation.Keys) { yield return(this.TryCreate(ItemType.BigCraftable, id, () => new SObject(Vector2.Zero, id))); } // secret notes foreach (int id in Game1.content.Load <Dictionary <int, string> >("Data\\SecretNotes").Keys) { SObject note = new SObject(79, 1); note.name = $"{note.name} #{id}"; yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset + id, () => note)); } // objects foreach (int id in Game1.objectInformation.Keys) { if (id == 79) { continue; // secret note handled above } if (id >= Ring.ringLowerIndexRange && id <= Ring.ringUpperIndexRange) { continue; // handled separated } SObject item = new SObject(id, 1); yield return(this.TryCreate(ItemType.Object, id, () => item)); // fruit products if (item.Category == SObject.FruitsCategory) { // wine SObject wine = new SObject(348, 1) { Name = $"{item.Name} Wine", Price = item.Price * 3 }; wine.preserve.Value = SObject.PreserveType.Wine; wine.preservedParentSheetIndex.Value = item.ParentSheetIndex; yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 2 + id, () => wine)); // jelly SObject jelly = new SObject(344, 1) { Name = $"{item.Name} Jelly", Price = 50 + item.Price * 2 }; jelly.preserve.Value = SObject.PreserveType.Jelly; jelly.preservedParentSheetIndex.Value = item.ParentSheetIndex; yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 3 + id, () => jelly)); } // vegetable products else if (item.Category == SObject.VegetableCategory) { // juice SObject juice = new SObject(350, 1) { Name = $"{item.Name} Juice", Price = (int)(item.Price * 2.25d) }; juice.preserve.Value = SObject.PreserveType.Juice; juice.preservedParentSheetIndex.Value = item.ParentSheetIndex; yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 4 + id, () => juice)); // pickled SObject pickled = new SObject(342, 1) { Name = $"Pickled {item.Name}", Price = 50 + item.Price * 2 }; pickled.preserve.Value = SObject.PreserveType.Pickle; pickled.preservedParentSheetIndex.Value = item.ParentSheetIndex; yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 5 + id, () => pickled)); } // flower honey else if (item.Category == SObject.flowersCategory) { // get honey type SObject.HoneyType?type = null; switch (item.ParentSheetIndex) { case 376: type = SObject.HoneyType.Poppy; break; case 591: type = SObject.HoneyType.Tulip; break; case 593: type = SObject.HoneyType.SummerSpangle; break; case 595: type = SObject.HoneyType.FairyRose; break; case 597: type = SObject.HoneyType.BlueJazz; break; case 421: // sunflower standing in for all other flowers type = SObject.HoneyType.Wild; break; } // yield honey if (type != null) { SObject honey = new SObject(Vector2.Zero, 340, item.Name + " Honey", false, true, false, false) { Name = "Wild Honey" }; honey.honeyType.Value = type; if (type != SObject.HoneyType.Wild) { honey.Name = $"{item.Name} Honey"; honey.Price += item.Price * 2; } yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 5 + id, () => honey)); } } } } return(GetAllRaw().Where(p => p != null)); }
internal static bool HarvestPrefix(Crop __instance, Vector2 ___tilePosition, int xTile, int yTile, HoeDirt soil, JunimoHarvester junimoHarvester = null) { Object cropObj = new Object(__instance.indexOfHarvest, 1); string cropName = "Unknown"; if (cropObj != null) { cropName = cropObj.DisplayName; } if (soil is null) { _monitor.Log($"Crop ({cropName}) at {xTile}, {yTile} is missing HoeDirt, unable to process!", LogLevel.Trace); return(true); } if (soil.currentLocation is null) { _monitor.Log($"Crop ({cropName}) at {xTile}, {yTile} is missing currentLocation (bad GameLocation?), unable to process!", LogLevel.Trace); return(true); } if (!soil.currentLocation.objects.Values.Any(o => o.modData.ContainsKey(IslandGatherers.parrotPotFlag))) { return(true); } // If any farmer is in a location with a Harvest Statue and the farmer is not in bed, skip logic if (soil.currentLocation.farmers.Any(f => !f.isInBed)) { return(true); } // Get the nearby HarvestStatue, which will be placing the harvested crop into Chest statueObj = soil.currentLocation.objects.Values.First(o => o.modData.ContainsKey(IslandGatherers.parrotPotFlag)) as Chest; if ((bool)__instance.dead) { return(false); } bool success = false; if ((bool)__instance.forageCrop) { Object o = null; System.Random r2 = new System.Random((int)Game1.stats.DaysPlayed + (int)Game1.uniqueIDForThisGame / 2 + xTile * 1000 + yTile * 2000); switch ((int)__instance.whichForageCrop) { case 1: o = new Object(399, 1); break; case 2: soil.shake((float)System.Math.PI / 48f, (float)System.Math.PI / 40f, (float)(xTile * 64) < Game1.player.Position.X); return(false); } if (Game1.player.professions.Contains(16)) { o.Quality = 4; } else if (r2.NextDouble() < (double)((float)Game1.player.ForagingLevel / 30f)) { o.Quality = 2; } else if (r2.NextDouble() < (double)((float)Game1.player.ForagingLevel / 15f)) { o.Quality = 1; } Game1.stats.ItemsForaged += (uint)o.Stack; // Try to add the forage crop to the HarvestStatue's inventory if (statueObj.addItem(o) != null) { // Statue is full, flag it as being eaten statueObj.modData[IslandGatherers.ateCropsFlag] = true.ToString(); } return(false); } else if ((int)__instance.currentPhase >= __instance.phaseDays.Count - 1 && (!__instance.fullyGrown || (int)__instance.dayOfCurrentPhase <= 0)) { int numToHarvest = 1; int cropQuality = 0; int fertilizerQualityLevel = 0; if ((int)__instance.indexOfHarvest == 0) { return(false); } System.Random r = new System.Random(xTile * 7 + yTile * 11 + (int)Game1.stats.DaysPlayed + (int)Game1.uniqueIDForThisGame); switch ((int)soil.fertilizer) { case 368: fertilizerQualityLevel = 1; break; case 369: fertilizerQualityLevel = 2; break; case 919: fertilizerQualityLevel = 3; break; } double chanceForGoldQuality = 0.2 * ((double)Game1.player.FarmingLevel / 10.0) + 0.2 * (double)fertilizerQualityLevel * (((double)Game1.player.FarmingLevel + 2.0) / 12.0) + 0.01; double chanceForSilverQuality = System.Math.Min(0.75, chanceForGoldQuality * 2.0); if (fertilizerQualityLevel >= 3 && r.NextDouble() < chanceForGoldQuality / 2.0) { cropQuality = 4; } else if (r.NextDouble() < chanceForGoldQuality) { cropQuality = 2; } else if (r.NextDouble() < chanceForSilverQuality || fertilizerQualityLevel >= 3) { cropQuality = 1; } if ((int)__instance.minHarvest > 1 || (int)__instance.maxHarvest > 1) { int max_harvest_increase = 0; if (__instance.maxHarvestIncreasePerFarmingLevel.Value > 0) { max_harvest_increase = Game1.player.FarmingLevel / (int)__instance.maxHarvestIncreasePerFarmingLevel; } numToHarvest = r.Next(__instance.minHarvest, System.Math.Max((int)__instance.minHarvest + 1, (int)__instance.maxHarvest + 1 + max_harvest_increase)); } if ((double)__instance.chanceForExtraCrops > 0.0) { while (r.NextDouble() < System.Math.Min(0.9, __instance.chanceForExtraCrops)) { numToHarvest++; } } if ((int)__instance.indexOfHarvest == 771 || (int)__instance.indexOfHarvest == 889) { cropQuality = 0; } Object harvestedItem = (__instance.programColored ? new ColoredObject(__instance.indexOfHarvest, 1, __instance.tintColor) { Quality = cropQuality } : new Object(__instance.indexOfHarvest, 1, isRecipe: false, -1, cropQuality)); if ((int)__instance.harvestMethod == 1) { if (statueObj.addItem(harvestedItem.getOne()) != null) { // Statue is full, flag it as being eaten statueObj.modData[IslandGatherers.ateCropsFlag] = true.ToString(); } success = true; } else if (statueObj.addItem(harvestedItem.getOne()) is null) { Vector2 initialTile = new Vector2(xTile, yTile); if (r.NextDouble() < Game1.player.team.AverageLuckLevel() / 1500.0 + Game1.player.team.AverageDailyLuck() / 1200.0 + 9.9999997473787516E-05) { numToHarvest *= 2; } success = true; } else { // Statue is full, flag it as being eaten statueObj.modData[IslandGatherers.ateCropsFlag] = true.ToString(); } if (success) { if ((int)__instance.indexOfHarvest == 421) { __instance.indexOfHarvest.Value = 431; numToHarvest = r.Next(1, 4); } int price = System.Convert.ToInt32(Game1.objectInformation[__instance.indexOfHarvest].Split('/')[1]); harvestedItem = (__instance.programColored ? new ColoredObject(__instance.indexOfHarvest, 1, __instance.tintColor) : new Object(__instance.indexOfHarvest, 1)); float experience = (float)(16.0 * System.Math.Log(0.018 * (double)price + 1.0, System.Math.E)); for (int i = 0; i < numToHarvest - 1; i++) { if (statueObj.addItem(harvestedItem.getOne()) != null) { // Statue is full, flag it as being eaten statueObj.modData[IslandGatherers.ateCropsFlag] = true.ToString(); } } if ((int)__instance.indexOfHarvest == 262 && r.NextDouble() < 0.4) { Object hay_item = new Object(178, 1); if (statueObj.addItem(hay_item.getOne()) != null) { // Statue is full, flag it as being eaten statueObj.modData[IslandGatherers.ateCropsFlag] = true.ToString(); } } else if ((int)__instance.indexOfHarvest == 771) { if (r.NextDouble() < 0.1) { Object mixedSeeds_item = new Object(770, 1); if (statueObj.addItem(mixedSeeds_item.getOne()) != null) { // Statue is full, flag it as being eaten statueObj.modData[IslandGatherers.ateCropsFlag] = true.ToString(); } } } if ((int)__instance.regrowAfterHarvest == -1) { return(false); } __instance.fullyGrown.Value = true; if (__instance.dayOfCurrentPhase.Value == (int)__instance.regrowAfterHarvest) { __instance.updateDrawMath(___tilePosition); } __instance.dayOfCurrentPhase.Value = __instance.regrowAfterHarvest; } } return(false); }
/// <summary> /// Generate every item known to man, or at least those we're interested /// in using for categorization. /// </summary> /// <remarks> /// Substantially based on code from Pathoschild's LookupAnything mod. /// </remarks> /// <returns>A collection of all of the item entries.</returns> private IEnumerable <DiscoveredItem> DiscoverItems() { // get tools yield return(new DiscoveredItem(ItemType.Tool, ToolFactory.axe, ToolFactory.getToolFromDescription(ToolFactory.axe, Tool.stone))); yield return(new DiscoveredItem(ItemType.Tool, ToolFactory.hoe, ToolFactory.getToolFromDescription(ToolFactory.hoe, Tool.stone))); yield return(new DiscoveredItem(ItemType.Tool, ToolFactory.pickAxe, ToolFactory.getToolFromDescription(ToolFactory.pickAxe, Tool.stone))); yield return(new DiscoveredItem(ItemType.Tool, ToolFactory.wateringCan, ToolFactory.getToolFromDescription(ToolFactory.wateringCan, Tool.stone))); yield return(new DiscoveredItem(ItemType.Tool, ToolFactory.fishingRod, ToolFactory.getToolFromDescription(ToolFactory.fishingRod, Tool.stone))); yield return (new DiscoveredItem(ItemType.Tool, CustomIDOffset, new MilkPail())); // these don't have any sort of ID, so we'll just assign some arbitrary ones yield return(new DiscoveredItem(ItemType.Tool, CustomIDOffset + 1, new Shears())); yield return(new DiscoveredItem(ItemType.Tool, CustomIDOffset + 2, new Pan())); // equipment foreach (int id in Game1.content.Load <Dictionary <int, string> >("Data\\Boots").Keys) { yield return(new DiscoveredItem(ItemType.Boots, id, new Boots(id))); } foreach (int id in Game1.content.Load <Dictionary <int, string> >("Data\\hats").Keys) { yield return(new DiscoveredItem(ItemType.Hat, id, new Hat(id))); } foreach (int id in Game1.objectInformation.Keys) { if (id >= Ring.ringLowerIndexRange && id <= Ring.ringUpperIndexRange) { yield return(new DiscoveredItem(ItemType.Ring, id, new Ring(id))); } } // weapons foreach (int id in Game1.content.Load <Dictionary <int, string> >("Data\\weapons").Keys) { Item weapon = (id >= 32 && id <= 34) ? (Item) new Slingshot(id) : new MeleeWeapon(id); yield return(new DiscoveredItem(ItemType.Weapon, id, weapon)); } // furniture /*foreach (int id in Game1.content.Load<Dictionary<int, string>>("Data\\Furniture").Keys) * { * if (id == 1466 || id == 1468) * yield return new DiscoveredItem(ItemType.Furniture, id, new TV(id, Vector2.Zero)); * else * yield return new DiscoveredItem(ItemType.Furniture, id, new Furniture(id, Vector2.Zero)); * }*/ // craftables /*foreach (int id in Game1.bigCraftablesInformation.Keys) * yield return new DiscoveredItem(ItemType.BigCraftable, id, new StardewObject(Vector2.Zero, id));*/ // objects foreach (int id in Game1.objectInformation.Keys) { if (id >= Ring.ringLowerIndexRange && id <= Ring.ringUpperIndexRange) { continue; // handled separated } StardewObject item = new StardewObject(id, 1); yield return(new DiscoveredItem(ItemType.Object, id, item)); } }
public override void receiveLeftClick(int x, int y, bool playSound = true) { base.receiveLeftClick(x, y, !this.destroyItemOnClick); // Item test= this.inputInventory.leftClick(x, y, this.heldItem, false); Item test = this.heldItem; /* * if (test == machine) * { * if ((test as ExpandableInventoryObject).inventory == expandableObject.inventory) * { * if (this.inputInventory.isWithinBounds(x, y) == false) * { * //if this is within my inventory return. Don't want to shove a bag into itself. * return; * } * * } * } */ if (this.organizeButton.containsPoint(x, y)) { MachineInventory.organizeItemsInList(this.inputInventory.actualInventory); } if (this.organizeButton.containsPoint(x, y)) { MachineInventory.organizeItemsInList(this.outputInventory.actualInventory); } if (inventory.isWithinBounds(x, y) == true) { if (this.inputInventory.actualInventory == null) { //Log.AsyncG("WTF HOW IS THIS NULL!?!?!?!?!"); } bool f = Util.isInventoryFull(this.inputInventory.actualInventory, true); if (f == false) { this.heldItem = this.inputInventory.leftClick(x, y, this.heldItem, false); if (this.heldItem != null) { //if (Serialize.WriteToXMLFileSafetyCheck(Path.Combine(Serialize.PlayerDataPath, ""), i, false) == false) //{ // return; // } Util.addItemToOtherInventory(this.inputInventory.actualInventory, this.heldItem); // Log.AsyncG("item swap"); if (this.machine == null) //Log.AsyncC("OK MY MACHINE IS NULL"); { if (this.inputInventory == null) //Log.AsyncG("Input is null"); { if (this.outputInventory == null) //Log.AsyncO("output is null"); //Game1.activeClickableMenu = new MachineInventory(this.machine, this.inputInventory.actualInventory,this.outputInventory.actualInventory, this.Rows, false, true, new InventoryMenu.highlightThisItem(InventoryMenu.highlightAllItems), this.behaviorFunction, null, this.behaviorOnItemGrab, false, true, true, true, true, this.source, this.sourceItem); { Game1.activeClickableMenu = new Revitalize.Menus.Machines.MachineInventory(this.machine, this.inputInventory.actualInventory, this.outputInventory.actualInventory, 3); } } } // Game1.playSound("Ship"); this.heldItem = null; return; // Log.AsyncG("not full"); } } else { //Log.AsyncO("Inventory is full?????"); return; } // this.inputInventory.inventory.Add(new ClickableComponent(new Rectangle(inputInventory.xPositionOnScreen + inputInventory.actualInventory.Count-1 % (this.capacity / this.inputInventory.rows) * Game1.tileSize + this.inputInventory.horizontalGap * (inputInventory.actualInventory.Count-1 % (this.capacity / this.inputInventory.rows)), inputInventory.yPositionOnScreen + inputInventory.actualInventory.Count-1 / (this.capacity / this.inputInventory.rows) * (Game1.tileSize + this.inputInventory.verticalGap) + (inputInventory.actualInventory.Count-1 / (this.capacity / this.inputInventory.rows) - 1) * Game1.pixelZoom - (Game1.tileSize / 5), Game1.tileSize, Game1.tileSize), string.Concat(inputInventory.actualInventory.Count-1))); if (this.okButton.containsPoint(x, y) == false && this.organizeButton.containsPoint(x, y) == false && f == false && this.LeftButton.containsPoint(x, y) == false && this.RightButton.containsPoint(x, y) == false) { // Game1.activeClickableMenu = new Revitalize.Menus.Machines.MachineInventory(this.machine, this.inputInventory.actualInventory, this.outputInventory.actualInventory, 3); //Game1.activeClickableMenu = new MachineInventory(this.machine, machine.inputInventory,machine.outputInventory, this.Rows, false, true, new InventoryMenu.highlightThisItem(InventoryMenu.highlightAllItems), this.behaviorFunction, null, this.behaviorOnItemGrab, false, true, true, true, true, this.source, this.sourceItem); // Game1.playSound("Ship"); } } else if (outputInventory.isWithinBounds(x, y) == true) { //outputInventory.actualInventory.Add(new Decoration(3, Vector2.Zero)); if (this.outputInventory.actualInventory == null) { //Log.AsyncG("WTF HOW IS THIS NULL!?!?!?!?!"); } this.heldItem = this.outputInventory.leftClick(x, y, this.heldItem, false); if (this.heldItem != null) { // if (Serialize.WriteToXMLFileSafetyCheck(Path.Combine(Serialize.PlayerDataPath, ""), this.heldItem, false) == false) // { // return; // } foreach (ClickableComponent current in outputInventory.inventory) { if (current.containsPoint(x, y)) { int num = Convert.ToInt32(current.name); // Log.AsyncO(num); this.outputInventory.actualInventory.RemoveAt(num); // Log.AsyncO("Remaining " + inputInventory.actualInventory.Count); } } // j= this.inputInventory.leftClick(x, y, this.heldItem, false); Util.addItemToInventoryElseDrop(this.heldItem); this.heldItem = null; return; } //Util.addItemToOtherInventory(this.inputInventory.actualInventory, this.heldItem); // Log.AsyncG("not full"); // this.inputInventory.inventory.Add(new ClickableComponent(new Rectangle(inputInventory.xPositionOnScreen + inputInventory.actualInventory.Count-1 % (this.capacity / this.inputInventory.rows) * Game1.tileSize + this.inputInventory.horizontalGap * (inputInventory.actualInventory.Count-1 % (this.capacity / this.inputInventory.rows)), inputInventory.yPositionOnScreen + inputInventory.actualInventory.Count-1 / (this.capacity / this.inputInventory.rows) * (Game1.tileSize + this.inputInventory.verticalGap) + (inputInventory.actualInventory.Count-1 / (this.capacity / this.inputInventory.rows) - 1) * Game1.pixelZoom - (Game1.tileSize / 5), Game1.tileSize, Game1.tileSize), string.Concat(inputInventory.actualInventory.Count-1))); if (this.okButton.containsPoint(x, y) == false && this.organizeButton.containsPoint(x, y) == false && this.LeftButton.containsPoint(x, y) == false && this.RightButton.containsPoint(x, y) == false) { // Game1.activeClickableMenu = new Revitalize.Menus.Machines.MachineInventory(this.machine, this.inputInventory.actualInventory, this.outputInventory.actualInventory, 3); //Game1.activeClickableMenu = new MachineInventory(this.machine, machine.inputInventory,machine.outputInventory, this.Rows, false, true, new InventoryMenu.highlightThisItem(InventoryMenu.highlightAllItems), this.behaviorFunction, null, this.behaviorOnItemGrab, false, true, true, true, true, this.source, this.sourceItem); // Game1.playSound("Ship"); } } else if (inputInventory.isWithinBounds(x, y) == true) { if (Game1.player.isInventoryFull() == true) { Item i = new StardewValley.Object(); Item j = new StardewValley.Object(); j = this.inputInventory.leftClick(x, y, this.heldItem, false); i = this.heldItem; if (i != null) { //if (Serialize.WriteToXMLFileSafetyCheck(Path.Combine(Serialize.PlayerDataPath, ""), i, false) == false) //{ // return; // } } Util.addItemToInventoryElseDrop(this.heldItem); // this.heldItem = null; foreach (ClickableComponent current in inputInventory.inventory) { if (current.containsPoint(x, y)) { int num = Convert.ToInt32(current.name); // Log.AsyncO(num); this.inputInventory.actualInventory.RemoveAt(num); // Log.AsyncO("Remaining " + inputInventory.actualInventory.Count); } } // j= this.inputInventory.leftClick(x, y, this.heldItem, false); // Util.addItemToOtherInventory(this.inputInventory.actualInventory, i); // Log.AsyncG("item swap"); if (this.machine == null) //Log.AsyncC("OK MY MACHINE IS NULL"); { if (this.inputInventory == null) //Log.AsyncG("Input is null"); { if (this.outputInventory == null) //Log.AsyncO("output is null"); //Game1.activeClickableMenu = new MachineInventory(this.machine, this.inputInventory.actualInventory,this.outputInventory.actualInventory, this.Rows, false, true, new InventoryMenu.highlightThisItem(InventoryMenu.highlightAllItems), this.behaviorFunction, null, this.behaviorOnItemGrab, false, true, true, true, true, this.source, this.sourceItem); { Game1.activeClickableMenu = new Revitalize.Menus.Machines.MachineInventory(this.machine, this.inputInventory.actualInventory, this.outputInventory.actualInventory, 3); } } } // Game1.playSound("Ship"); this.heldItem = null; return; } this.heldItem = this.inputInventory.leftClick(x, y, this.heldItem, false); Util.addItemToInventoryElseDrop(this.heldItem); this.heldItem = null; foreach (ClickableComponent current in inputInventory.inventory) { if (current.containsPoint(x, y)) { int num = Convert.ToInt32(current.name); // Log.AsyncO(num); this.inputInventory.actualInventory.RemoveAt(num); // Log.AsyncO("Remaining " + inputInventory.actualInventory.Count); } } Game1.activeClickableMenu = new MachineInventory(this.machine, this.inputInventory.actualInventory, this.outputInventory.actualInventory, this.Rows, false, true, new InventoryMenu.highlightThisItem(InventoryMenu.highlightAllItems), this.behaviorFunction, null, this.behaviorOnItemGrab, false, true, true, true, true, this.source, this.sourceItem); // Game1.playSound("Ship"); } return; if (this.shippingBin && this.lastShippedHolder.containsPoint(x, y)) { if (Game1.getFarm().lastItemShipped != null && Game1.player.addItemToInventoryBool(Game1.getFarm().lastItemShipped, false)) { Game1.playSound("coin"); Game1.getFarm().shippingBin.Remove(Game1.getFarm().lastItemShipped); Game1.getFarm().lastItemShipped = null; if (Game1.player.ActiveObject != null) { Game1.player.showCarrying(); Game1.player.Halt(); } } return; } if (this.chestColorPicker != null) { this.chestColorPicker.receiveLeftClick(x, y, true); if (this.sourceItem != null && this.sourceItem is Chest) { (this.sourceItem as Chest).playerChoiceColor = this.chestColorPicker.getColorFromSelection(this.chestColorPicker.colorSelection); } } if (this.colorPickerToggleButton != null && this.colorPickerToggleButton.containsPoint(x, y)) { Game1.player.showChestColorPicker = !Game1.player.showChestColorPicker; this.chestColorPicker.visible = Game1.player.showChestColorPicker; Game1.soundBank.PlayCue("drumkit6"); } if (this.heldItem == null && this.showReceivingMenu) { this.heldItem = this.inputInventory.leftClick(x, y, this.heldItem, false); // Log.AsyncC("YAY"); if (this.heldItem != null && this.behaviorOnItemGrab != null) { this.behaviorOnItemGrab(this.heldItem, Game1.player); if (Game1.activeClickableMenu != null && Game1.activeClickableMenu is MachineInventory) { (Game1.activeClickableMenu as MachineInventory).setSourceItem(this.sourceItem); } } if (this.heldItem is StardewValley.Object && (this.heldItem as StardewValley.Object).parentSheetIndex == 326) { this.heldItem = null; Game1.player.canUnderstandDwarves = true; this.poof = new TemporaryAnimatedSprite(Game1.animations, new Rectangle(0, 320, 64, 64), 50f, 8, 0, new Vector2((float)(x - x % Game1.tileSize + Game1.tileSize / 4), (float)(y - y % Game1.tileSize + Game1.tileSize / 4)), false, false); Game1.playSound("fireball"); } else if (this.heldItem is StardewValley.Object && (this.heldItem as StardewValley.Object).parentSheetIndex == 102) { this.heldItem = null; Game1.player.foundArtifact(102, 1); this.poof = new TemporaryAnimatedSprite(Game1.animations, new Rectangle(0, 320, 64, 64), 50f, 8, 0, new Vector2((float)(x - x % Game1.tileSize + Game1.tileSize / 4), (float)(y - y % Game1.tileSize + Game1.tileSize / 4)), false, false); Game1.playSound("fireball"); } else if (this.heldItem is StardewValley.Object && (this.heldItem as StardewValley.Object).isRecipe) { string key = this.heldItem.Name.Substring(0, this.heldItem.Name.IndexOf("Recipe") - 1); try { if ((this.heldItem as StardewValley.Object).category == -7) { Game1.player.cookingRecipes.Add(key, 0); } else { Game1.player.craftingRecipes.Add(key, 0); } this.poof = new TemporaryAnimatedSprite(Game1.animations, new Rectangle(0, 320, 64, 64), 50f, 8, 0, new Vector2((float)(x - x % Game1.tileSize + Game1.tileSize / 4), (float)(y - y % Game1.tileSize + Game1.tileSize / 4)), false, false); Game1.playSound("newRecipe"); } catch (Exception) { } this.heldItem = null; } else if (Game1.player.addItemToInventoryBool(this.heldItem, false)) { this.heldItem = null; Game1.playSound("coin"); } } else if ((this.reverseGrab || this.behaviorFunction != null) && this.isWithinBounds(x, y)) { this.behaviorFunction(this.heldItem, Game1.player); if (Game1.activeClickableMenu != null && Game1.activeClickableMenu is MachineInventory) { (Game1.activeClickableMenu as MachineInventory).setSourceItem(this.sourceItem); } if (this.destroyItemOnClick) { this.heldItem = null; return; } } if (this.organizeButton != null && this.organizeButton.containsPoint(x, y)) { MachineInventory.organizeItemsInList(this.inputInventory.actualInventory); Game1.activeClickableMenu = new MachineInventory(this.machine, this.inputInventory.actualInventory, this.outputInventory.actualInventory, this.Rows, false, true, new InventoryMenu.highlightThisItem(InventoryMenu.highlightAllItems), this.behaviorFunction, null, this.behaviorOnItemGrab, false, true, true, true, true, this.source, this.sourceItem); Game1.playSound("Ship"); return; } if (this.heldItem != null && !this.isWithinBounds(x, y) && this.heldItem.canBeTrashed()) { Game1.playSound("throwDownITem"); Game1.createItemDebris(this.heldItem, Game1.player.getStandingPosition(), Game1.player.FacingDirection); this.heldItem = null; } }
public void AddItemsToSmelt(int objectId, int amount) { StardewValley.Object item = new StardewValley.Object(objectId, amount); input.addItem(item); }
private static Rectangle GetSourceRect(int index, IndoorPot __instance) { if (!Config.EnableMod || __instance.modData.ContainsKey("aedenthorn.WallPlanter/offset") || !IsConnectedPot(__instance)) { return(Object.getSourceRectForBigCraftable(index)); } drawingConnectedPot = false; bool[] potTiles = new bool[9]; Vector2 tile = __instance.TileLocation; for (int x = 0; x < 3; x++) { for (int y = 0; y < 3; y++) { int i = 3 * y + x; potTiles[i] = Game1.currentLocation.objects.TryGetValue(tile + new Vector2(x - 1, y - 1), out Object obj) && obj is IndoorPot && !obj.modData.ContainsKey("aedenthorn.WallPlanter/offset"); } } topIndex = -2; leftIndex = -2; rightIndex = -2; drawingConnectedPot = true; if (!potTiles[1]) // none top { if (!potTiles[3]) // none left { if (!potTiles[5]) // pot below { topIndex = 6; potIndex = 0; } else if (!potTiles[7]) // pot right { topIndex = 0; potIndex = 2; } else // pot right pot below { topIndex = 0; potIndex = 0; } } else if (!potTiles[5]) // pot left none right { if (!potTiles[7]) // pot left { topIndex = 4; potIndex = 6; } else // pot left pot below { topIndex = 4; potIndex = 0; } } else if (!potTiles[7]) // pot left pot right { topIndex = 2; potIndex = 4; } else // pot left pot right pot below { topIndex = 2; potIndex = 0; } } else // pot top { if (!potTiles[3]) // none left { if (!potTiles[5]) // none right { if (!potTiles[7]) // pot top { potIndex = 8; } else // pot top pot bottom { potIndex = 0; } } else // pot right { if (!potTiles[7]) // pot top pot right { potIndex = 2; } else // pot top pot right pot bottom { potIndex = 0; } } } else if (!potTiles[5]) // pot left none right { if (!potTiles[7]) // pot top pot left { potIndex = 6; } else // pot top pot left pot below { potIndex = 0; } } else if (!potTiles[7]) // pot top pot left pot right { potIndex = 4; } else // pot top pot left pot right pot below { potIndex = 0; } } if (potIndex == 0) { if (!potTiles[3]) { leftIndex = potTiles[6] ? 2 : 0; } else if (!potTiles[6]) { leftIndex = 4; } if (!potTiles[5]) { rightIndex = potTiles[8] ? 2 : 0; } else if (!potTiles[8]) { rightIndex = 4; } } if (__instance.showNextIndex.Value) { potIndex++; topIndex++; leftIndex++; rightIndex++; } return(new Rectangle(potIndex * 16, 0, 16, 32)); }
public static bool passOutFromTired_Prefix(SObject __instance, Farmer who) { try { if (ModEntry.config.reduceEnergyWhenPassingOut) { if (!who.IsLocalPlayer) { modEntry.Monitor.Log($"{who.displayName} is not local player. Stop.", LogLevel.Trace); return(true); } modEntry.Monitor.Log($"Energy loss on passout is enabled.", LogLevel.Trace); int percentToTake = ModEntry.config.percentEnergyLostWhenPassingOut; float currentStamina = who.Stamina; int staminaToTake = (int)Math.Floor(who.Stamina * (100 / percentToTake)); if (currentStamina - staminaToTake < 2.0) { staminaToTake = (int)currentStamina - 2; } modEntry.Monitor.Log($"Remove {staminaToTake} energy.", LogLevel.Trace); who.Stamina -= staminaToTake; } GameLocation passOutLocation = Game1.currentLocation; modEntry.Monitor.Log($"Game Location for {who.displayName} is {passOutLocation.Name}", LogLevel.Trace); //turn this into a configurable list of locations. if (letModHandlePassout(who, passOutLocation)) { modEntry.Monitor.Log($"{who.displayName} in mod controlled location. Game Location is {passOutLocation.Name}", LogLevel.Trace); //we need to handle most of the passing out logic again here so we can deal with the money and messaging //stuff in the middle. Sad sad panda. if (!who.IsLocalPlayer) { modEntry.Monitor.Log($"{who.displayName} is not local player. Stop.", LogLevel.Trace); return(true); } modEntry.Monitor.Log($"{who.displayName} is mounted. Dismount.", LogLevel.Trace); if (who.isRidingHorse()) { who.mount.dismount(false); } if (Game1.activeClickableMenu != null) { Game1.activeClickableMenu.emergencyShutDown(); Game1.exitActiveMenu(); } who.completelyStopAnimatingOrDoingAction(); if ((bool)((NetFieldBase <bool, NetBool>)who.bathingClothes)) { who.changeOutOfSwimSuit(); } who.swimming.Value = false; who.CanMove = false; if (who == Game1.player && (FarmerTeam.SleepAnnounceModes)((NetFieldBase <FarmerTeam.SleepAnnounceModes, NetEnum <FarmerTeam.SleepAnnounceModes> >)Game1.player.team.sleepAnnounceMode) != FarmerTeam.SleepAnnounceModes.Off) { string str = "PassedOut"; int num = 0; for (int index = 0; index < 2; ++index) { if (Game1.random.NextDouble() < 0.25) { ++num; } } if (mHelper != null) { String message = who.displayName + " has passed out."; if (Game1.IsMultiplayer) { mHelper.Multiplayer.SendMessage <String>(message, "PassoutMessage"); } } } Vector2 bed = Utility.PointToVector2(Utility.getHomeOfFarmer(Game1.player).getBedSpot()) * 64f; bed.X -= 64f; LocationRequest.Callback callback = (LocationRequest.Callback)(() => { who.Position = bed; who.currentLocation.lastTouchActionLocation = bed; if (!Game1.IsMultiplayer || Game1.timeOfDay >= 2600) { Game1.PassOutNewDay(); } Game1.changeMusicTrack("none", false, Game1.MusicContext.Default); if (ModEntry.config.enableRobberyOnFarm || ModEntry.config.enableRobberyOnNonFarmSafeLocations) { modEntry.Monitor.Log($"Robbery enabled. Check for robbery.", LogLevel.Trace); if ((ModEntry.config.enableRobberyOnFarm && isFarmLocation(passOutLocation)) || (ModEntry.config.enableRobberyOnNonFarmSafeLocations && !isFarmLocation(passOutLocation))) { //eligible to be robbed Random random1 = new Random((int)Game1.uniqueIDForThisGame + (int)Game1.stats.DaysPlayed + (int)Game1.player.UniqueMultiplayerID); int robbedRoll = random1.Next(100); modEntry.Monitor.Log($"Robbery roll:. {robbedRoll}", LogLevel.Trace); if (robbedRoll < ModEntry.config.percentRobberyChance) { //we got robbed, sad sad panda. int percentTaken = random1.Next(ModEntry.config.percentFundsLostMinimumInRobbery, ModEntry.config.percentFundsLostMaximumInRobbery); int amountTaken = who.Money * (percentTaken / 100); List <int> list = new List <int>(); list.Add(2); //the willy letter. list.Add(4); //the marlon letter. int letterNumber = Utility.GetRandom <int>(list, random1); string letter = "passedOut" + (object)letterNumber + " " + (object)amountTaken; modEntry.Monitor.Log($"Got robbed send letter: {letter}", LogLevel.Trace); if (amountTaken > 0) { who.Money -= amountTaken; who.mailForTomorrow.Add(letter); } } } } }); if (!(bool)((NetFieldBase <bool, NetBool>)who.isInBed) || who.currentLocation != null && !who.currentLocation.Equals((object)who.homeLocation.Value)) { modEntry.Monitor.Log($"{who.displayName} is not in bed. Send home.", LogLevel.Trace); LocationRequest locationRequest = Game1.getLocationRequest(who.homeLocation.Value, false); Game1.warpFarmer(locationRequest, (int)bed.X / 64, (int)bed.Y / 64, 2); locationRequest.OnWarp += callback; who.FarmerSprite.setCurrentSingleFrame(5, (short)3000, false, false); who.FarmerSprite.PauseForSingleAnimation = true; } else { callback(); } modEntry.Monitor.Log($"Skip regular passout behavior.", LogLevel.Trace); return(false); } modEntry.Monitor.Log($"Execute standard passout behavior.", LogLevel.Trace); return(true); } catch (Exception ex) { modEntry.Monitor.Log($"Failed in {nameof(passOutFromTired_Prefix)}:\n{ex}", LogLevel.Error); return(true); // run original logic } }
private void DrawHoverTooltip(object sender, EventArgs e) { //StardewValley.Object tile = Game1.currentLocation.Objects.SafeGet(Game1.currentCursorTile); //TerrainFeature feature = null; if (_currentTileBuilding != null) { if (_currentTileBuilding is Mill millBuilding) { if (!millBuilding.input.isEmpty()) { int wheatCount = 0; int beetCount = 0; foreach (var item in millBuilding.input.items) { switch (item.Name) { case "Wheat": wheatCount = item.Stack; break; case "Beet": beetCount = item.Stack; break; } } StringBuilder builder = new StringBuilder(); if (wheatCount > 0) { builder.Append(wheatCount + " wheat"); } if (beetCount > 0) { if (wheatCount > 0) { builder.Append(Environment.NewLine); } builder.Append(beetCount + " beets"); } if (builder.Length > 0) { IClickableMenu.drawHoverText( Game1.spriteBatch, builder.ToString(), Game1.smallFont); } } } } else if (_currentTile != null && (!_currentTile.bigCraftable || _currentTile.minutesUntilReady > 0)) { if (_currentTile.bigCraftable && _currentTile.minutesUntilReady > 0 && _currentTile.Name != "Heater") { StringBuilder hoverText = new StringBuilder(); if (_currentTile is Cask) { Cask currentCask = _currentTile as Cask; hoverText.Append((int)(currentCask.daysToMature / currentCask.agingRate)) .Append(" " + _helper.SafeGetString( LanguageKeys.DaysToMature)); } else if (_currentTile is StardewValley.Buildings.Mill) { } else { int totalDays = (int)Math.Floor(_currentTile.minutesUntilReady / 60.0 / 24.0); int hours = _currentTile.minutesUntilReady / 60 % 24; int minutes = _currentTile.minutesUntilReady % 60; if (totalDays > 0) { hoverText.Append(totalDays).Append(" ") .Append(_helper.SafeGetString( LanguageKeys.DaysToMature)) .Append(": "); } if (hours > 0) { hoverText.Append(hours).Append(" ") .Append(_helper.SafeGetString( LanguageKeys.Hours)) .Append(", "); } hoverText.Append(minutes).Append(" ") .Append(_helper.SafeGetString( LanguageKeys.Minutes)); } IClickableMenu.drawHoverText( Game1.spriteBatch, hoverText.ToString(), Game1.smallFont); } } else if (_terrain != null) { if (_terrain is HoeDirt) { HoeDirt hoeDirt = _terrain as HoeDirt; if (hoeDirt.crop != null && !hoeDirt.crop.dead) { int num = 0; if (hoeDirt.crop.fullyGrown && hoeDirt.crop.dayOfCurrentPhase > 0) { num = hoeDirt.crop.dayOfCurrentPhase; } else { for (int i = 0; i < hoeDirt.crop.phaseDays.Count - 1; ++i) { if (hoeDirt.crop.currentPhase == i) { num -= hoeDirt.crop.dayOfCurrentPhase; } if (hoeDirt.crop.currentPhase <= i) { num += hoeDirt.crop.phaseDays[i]; } } } if (hoeDirt.crop.indexOfHarvest > 0) { String hoverText = _indexOfCropNames.SafeGet(hoeDirt.crop.indexOfHarvest); if (String.IsNullOrEmpty(hoverText)) { hoverText = new StardewValley.Object(new Debris(hoeDirt.crop.indexOfHarvest, Vector2.Zero, Vector2.Zero).chunkType, 1).DisplayName; _indexOfCropNames.Add(hoeDirt.crop.indexOfHarvest, hoverText); } StringBuilder finalHoverText = new StringBuilder(); finalHoverText.Append(hoverText).Append(": "); if (num > 0) { finalHoverText.Append(num).Append(" ") .Append(_helper.SafeGetString( LanguageKeys.Days)); } else { finalHoverText.Append(_helper.SafeGetString( LanguageKeys.ReadyToHarvest)); } IClickableMenu.drawHoverText( Game1.spriteBatch, finalHoverText.ToString(), Game1.smallFont); } } } else if (_terrain is FruitTree) { FruitTree tree = _terrain as FruitTree; if (tree.daysUntilMature > 0) { IClickableMenu.drawHoverText( Game1.spriteBatch, tree.daysUntilMature + " " + _helper.SafeGetString( LanguageKeys.DaysToMature), Game1.smallFont); } } } }
/// <summary>Apply the tool to the given tile.</summary> /// <param name="tile">The tile to modify.</param> /// <param name="tileObj">The object on the tile.</param> /// <param name="tileFeature">The feature on the tile.</param> /// <param name="player">The current player.</param> /// <param name="tool">The tool selected by the player (if any).</param> /// <param name="item">The item selected by the player (if any).</param> /// <param name="location">The current location.</param> public abstract bool Apply(Vector2 tile, SObject tileObj, TerrainFeature tileFeature, Farmer player, Tool tool, Item item, GameLocation location);
/// <summary>Get whether a given object is a weed.</summary> /// <param name="obj">The world object.</param> protected bool IsWeed(SObject obj) { return(!(obj is Chest) && obj?.Name == "Weeds"); }
public override bool IsAugmentable(Object Item) { return(MachineInfo.TryGetMachineInfo(Item, out MachineInfo Info) && Info.AttachableAugmentors.Contains(AugmentorType.Production)); }
public SObject?GetOutputObject(Item inputItem) { if (inputItem is SObject inputObject) { bool turnIntoGeneric = false; SObject outputObject; // Handle roe/aged roe if (inputObject is ColoredObject coloredObject) { outputObject = new ColoredObject(inputObject.ParentSheetIndex, 1, coloredObject.color.Value); } else { outputObject = new SObject(Vector2.Zero, inputObject.ParentSheetIndex, 1); // If input is honey, copy honey type if (outputObject.Name.Contains("Honey")) { outputObject.honeyType.Value = inputObject.honeyType.Value; if (config.TurnHoneyIntoGenericHoney) { turnIntoGeneric = true; } } } outputObject.Quality = SObject.lowQuality; switch (inputObject.preserve.Value) { case SObject.PreserveType.AgedRoe: case SObject.PreserveType.Roe: if (config.TurnRoeIntoGenericRoe) { turnIntoGeneric = true; } break; case SObject.PreserveType.Jelly: if (config.TurnJellyIntoGenericJelly) { turnIntoGeneric = true; } break; case SObject.PreserveType.Juice: if (config.TurnJuiceIntoGenericJuice) { turnIntoGeneric = true; } break; case SObject.PreserveType.Pickle: if (config.PicklesIntoGenericPickles) { turnIntoGeneric = true; } break; case SObject.PreserveType.Wine: if (config.TurnWineIntoGenericWine) { turnIntoGeneric = true; } break; default: break; } if (!turnIntoGeneric) { outputObject.Name = inputObject.Name; outputObject.Price = inputObject.Price; // Preserve value has to be defined here, otherwise the output will be named "Weeds {preservetype}" outputObject.preserve.Value = inputObject.preserve.Value; // Handle preserves (Wine, Juice, Jelly, Pickle) // preservedParentSheetIndex + preserve type define the object's DisplayName outputObject.preservedParentSheetIndex.Value = inputObject.preservedParentSheetIndex.Value; } return(outputObject); } return(null); }
/// <summary>Get a machine, container, or connector instance for a given object.</summary> /// <param name="obj">The in-game object.</param> /// <param name="location">The location to check.</param> /// <param name="tile">The tile position to check.</param> /// <returns>Returns an instance or <c>null</c>.</returns> public IAutomatable?GetFor(SObject obj, GameLocation location, in Vector2 tile)
/// <param name="DrawStack">True if <see cref="Item.Stack"/> should be drawn</param> /// <param name="DrawQuality">True if <see cref="Object.Quality"/> should be drawn</param> /// <param name="IconScale">Does not affect the scaling for the quality, quantity, or other special rendered things like the capacity bar for a watering can</param> public static void DrawItem(SpriteBatch b, Rectangle Destination, Item Item, bool DrawStack, bool DrawQuality, float IconScale, float Transparency, Color Overlay, Color StackColor) { if (Destination.Width != Destination.Height) { throw new InvalidOperationException("Can only call DrawItem on a perfect square Destination"); } // Normally I'd just use Item.drawInMenu but that method doesn't scale stack size, qualities, or shadows correctly and thus will only display correctly at the default size of 64x64. // Some items also render several textures to the destination point, and use hardcoded offsets for the sprites that also don't respect desired scaling. (Such as wallpapers or watering cans) // So this method is my attempt at re-creating the Item.drawInMenu implementations in a way that will correctly scale to the desired Destination rectangle. // It doesn't handle all cases correctly, but whatever, it's close enough DrawStack = DrawStack && (Item.maximumStackSize() > 1 || Item.Stack > 1); DrawQuality = DrawQuality && Item is Object Obj && Enum.IsDefined(typeof(ObjectQuality), Obj.Quality); int ScaledIconSize = (int)(Destination.Width * IconScale * 0.8f); Rectangle ScaledIconDestination = new Rectangle(Destination.Center.X - ScaledIconSize / 2, Destination.Center.Y - ScaledIconSize / 2, ScaledIconSize, ScaledIconSize); Texture2D SourceTexture = null; Rectangle?SourceTextureRectangle = null; if (Item is ItemBag Bag) { float BaseScale = Destination.Width / (float)BagInventoryMenu.DefaultInventoryIconSize; Vector2 OffsetDueToScaling = new Vector2((BaseScale - 1.0f) * BagInventoryMenu.DefaultInventoryIconSize * 0.5f); // I honestly forget why I needed this lmao. Maybe ItemBag.drawInMenu override was scaling around a different origin or some shit Bag.drawInMenu(b, new Vector2(Destination.X, Destination.Y) + OffsetDueToScaling, IconScale * Destination.Width / 64f * 0.8f, Transparency, 1.0f, StackDrawType.Hide, Overlay, false); } else if (Item is Tool Tool) { if (Item is MeleeWeapon Weapon) { SourceTexture = MeleeWeapon.weaponsTexture; SourceTextureRectangle = new Rectangle?(Game1.getSquareSourceRectForNonStandardTileSheet(SourceTexture, 16, 16, Tool.IndexOfMenuItemView)); } else { SourceTexture = Game1.toolSpriteSheet; SourceTextureRectangle = new Rectangle?(Game1.getSquareSourceRectForNonStandardTileSheet(SourceTexture, 16, 16, Tool.IndexOfMenuItemView)); } } else if (Item is Ring Ring) { SourceTexture = Game1.objectSpriteSheet; SourceTextureRectangle = new Rectangle?(Game1.getSourceRectForStandardTileSheet(SourceTexture, Ring.indexInTileSheet, 16, 16)); } else if (Item is Hat Hat) { SourceTexture = FarmerRenderer.hatsTexture; SourceTextureRectangle = new Rectangle?(new Rectangle(Hat.which * 20 % SourceTexture.Width, Hat.which * 20 / SourceTexture.Width * 20 * 4, 20, 20)); } else if (Item is Boots Boots) { SourceTexture = Game1.objectSpriteSheet; SourceTextureRectangle = new Rectangle?(Game1.getSourceRectForStandardTileSheet(SourceTexture, Boots.indexInTileSheet.Value, 16, 16)); } else if (Item is Clothing Clothing) { Color clothes_color = Clothing.clothesColor; if (Clothing.isPrismatic.Value) { clothes_color = Utility.GetPrismaticColor(0); } if (Clothing.clothesType.Value != 0) { if (Clothing.clothesType.Value == 1) { b.Draw(FarmerRenderer.pantsTexture, Destination, new Rectangle?(new Rectangle(192 * (Clothing.indexInTileSheetMale.Value % (FarmerRenderer.pantsTexture.Width / 192)), 688 * (Clothing.indexInTileSheetMale.Value / (FarmerRenderer.pantsTexture.Width / 192)) + 672, 16, 16)), Utility.MultiplyColor(clothes_color, Color.White) * Transparency, 0f, Vector2.Zero, SpriteEffects.None, 1f); //b.Draw(FarmerRenderer.pantsTexture, location + new Vector2(32f, 32f), //new Rectangle?(new Rectangle(192 * (this.indexInTileSheetMale.Value % (FarmerRenderer.pantsTexture.Width / 192)), 688 * (this.indexInTileSheetMale.Value / (FarmerRenderer.pantsTexture.Width / 192)) + 672, 16, 16)), //Utility.MultiplyColor(clothes_color, color) * transparency, 0f, new Vector2(8f, 8f), scaleSize * 4f, SpriteEffects.None, layerDepth); } } else { b.Draw(FarmerRenderer.shirtsTexture, Destination, new Rectangle?(new Rectangle(Clothing.indexInTileSheetMale.Value * 8 % 128, Clothing.indexInTileSheetMale.Value * 8 / 128 * 32, 8, 8)), Color.White * Transparency, 0f, Vector2.Zero, SpriteEffects.None, 1f); b.Draw(FarmerRenderer.shirtsTexture, Destination, new Rectangle?(new Rectangle(Clothing.indexInTileSheetMale.Value * 8 % 128 + 128, Clothing.indexInTileSheetMale.Value * 8 / 128 * 32, 8, 8)), Utility.MultiplyColor(clothes_color, Color.White) * Transparency, 0f, Vector2.Zero, SpriteEffects.None, 1f); //b.Draw(FarmerRenderer.shirtsTexture, location + new Vector2(32f, 32f), new Rectangle?(new Rectangle(this.indexInTileSheetMale.Value * 8 % 128, this.indexInTileSheetMale.Value * 8 / 128 * 32, 8, 8)), color * transparency, 0f, new Vector2(4f, 4f), scaleSize * 4f, SpriteEffects.None, layerDepth); //b.Draw(FarmerRenderer.shirtsTexture, location + new Vector2(32f, 32f), new Rectangle?(new Rectangle(this.indexInTileSheetMale.Value * 8 % 128 + 128, this.indexInTileSheetMale.Value * 8 / 128 * 32, 8, 8)), Utility.MultiplyColor(clothes_color, color) * transparency, 0f, new Vector2(4f, 4f), scaleSize * 4f, SpriteEffects.None, layerDepth + dye_portion_layer_offset); } } else if (Item is Fence Fence) { int DrawSum = Fence.getDrawSum(Game1.currentLocation); int SourceRectPosition = Fence.fenceDrawGuide[DrawSum]; SourceTexture = Fence.fenceTexture.Value; if (Fence.isGate) { if (DrawSum == 110) { SourceTextureRectangle = new Rectangle?(new Rectangle(0, 512, 88, 24)); } else if (DrawSum == 1500) { SourceTextureRectangle = new Rectangle?(new Rectangle(112, 512, 16, 64)); } } SourceTextureRectangle = new Rectangle?(Game1.getArbitrarySourceRect(SourceTexture, 64, 128, SourceRectPosition)); } else if (Item is Furniture Furniture) { SourceTexture = Furniture.furnitureTexture; SourceTextureRectangle = Furniture.defaultSourceRect; } else if (Item is Wallpaper WP) { SourceTexture = Wallpaper.wallpaperTexture; SourceTextureRectangle = WP.sourceRect; } else { if (Item is Object BigCraftable && BigCraftable.bigCraftable.Value) { SourceTexture = Game1.bigCraftableSpriteSheet; SourceTextureRectangle = Object.getSourceRectForBigCraftable(Item.ParentSheetIndex); //ScaledIconDestination = new Rectangle(ScaledIconDestination.X + ScaledIconDestination.Width / 8, ScaledIconDestination.Y - ScaledIconDestination.Height / 8, // ScaledIconDestination.Width - ScaledIconDestination.Width / 4, ScaledIconDestination.Height + ScaledIconDestination.Height / 4); ScaledIconDestination = new Rectangle(ScaledIconDestination.X + ScaledIconDestination.Width / 4, ScaledIconDestination.Y, ScaledIconDestination.Width - ScaledIconDestination.Width / 2, ScaledIconDestination.Height); //From decompiled .exe code: //spriteBatch.Draw(Game1.bigCraftableSpriteSheet, location + new Vector2(32f, 32f), new Rectangle?(sourceRect), color * transparency, // 0f, new Vector2(8f, 16f), 4f * ((double)scaleSize < 0.2 ? scaleSize : scaleSize / 2f), SpriteEffects.None, layerDepth); }
public IEnumerable <SearchableItem> GetAll() { // // // Be careful about closure variable capture here! // // SearchableItem stores the Func<Item> to create new instances later. Loop variables passed into the // function will be captured, so every func in the loop will use the value from the last iteration. Use the // TryCreate(type, id, entity => item) form to avoid the issue, or create a local variable to pass in. // // IEnumerable <SearchableItem> GetAllRaw() { // get tools for (int q = Tool.stone; q <= Tool.iridium; q++) { int quality = q; yield return(this.TryCreate(ItemType.Tool, ToolFactory.axe, _ => ToolFactory.getToolFromDescription(ToolFactory.axe, quality))); yield return(this.TryCreate(ItemType.Tool, ToolFactory.hoe, _ => ToolFactory.getToolFromDescription(ToolFactory.hoe, quality))); yield return(this.TryCreate(ItemType.Tool, ToolFactory.pickAxe, _ => ToolFactory.getToolFromDescription(ToolFactory.pickAxe, quality))); yield return(this.TryCreate(ItemType.Tool, ToolFactory.wateringCan, _ => ToolFactory.getToolFromDescription(ToolFactory.wateringCan, quality))); if (quality != Tool.iridium) { yield return(this.TryCreate(ItemType.Tool, ToolFactory.fishingRod, _ => ToolFactory.getToolFromDescription(ToolFactory.fishingRod, quality))); } } yield return(this.TryCreate(ItemType.Tool, this.CustomIDOffset, _ => new MilkPail())); // these don't have any sort of ID, so we'll just assign some arbitrary ones yield return(this.TryCreate(ItemType.Tool, this.CustomIDOffset + 1, _ => new Shears())); yield return(this.TryCreate(ItemType.Tool, this.CustomIDOffset + 2, _ => new Pan())); yield return(this.TryCreate(ItemType.Tool, this.CustomIDOffset + 3, _ => new Wand())); // clothing { // items HashSet <int> clothingIds = new HashSet <int>(); foreach (int id in Game1.clothingInformation.Keys) { if (id < 0) { continue; // placeholder data for character customization clothing below } clothingIds.Add(id); yield return(this.TryCreate(ItemType.Clothing, id, p => new Clothing(p.ID))); } // character customization shirts (some shirts in this range have no data, but game has special logic to handle them) for (int id = 1000; id <= 1111; id++) { if (!clothingIds.Contains(id)) { yield return(this.TryCreate(ItemType.Clothing, id, p => new Clothing(p.ID))); } } } // wallpapers for (int id = 0; id < 112; id++) { yield return(this.TryCreate(ItemType.Wallpaper, id, p => new Wallpaper(p.ID) { Category = SObject.furnitureCategory })); } // flooring for (int id = 0; id < 56; id++) { yield return(this.TryCreate(ItemType.Flooring, id, p => new Wallpaper(p.ID, isFloor: true) { Category = SObject.furnitureCategory })); } // equipment foreach (int id in this.TryLoad <int, string>("Data\\Boots").Keys) { yield return(this.TryCreate(ItemType.Boots, id, p => new Boots(p.ID))); } foreach (int id in this.TryLoad <int, string>("Data\\hats").Keys) { yield return(this.TryCreate(ItemType.Hat, id, p => new Hat(p.ID))); } // weapons foreach (int id in this.TryLoad <int, string>("Data\\weapons").Keys) { yield return(this.TryCreate(ItemType.Weapon, id, p => (p.ID >= 32 && p.ID <= 34) ? (Item) new Slingshot(p.ID) : new MeleeWeapon(p.ID) )); } // furniture foreach (int id in this.TryLoad <int, string>("Data\\Furniture").Keys) { if (id == 1466 || id == 1468 || id == 1680) { yield return(this.TryCreate(ItemType.Furniture, id, p => new TV(p.ID, Vector2.Zero))); } else { yield return(this.TryCreate(ItemType.Furniture, id, p => new Furniture(p.ID, Vector2.Zero))); } } // craftables foreach (int id in Game1.bigCraftablesInformation.Keys) { yield return(this.TryCreate(ItemType.BigCraftable, id, p => new SObject(Vector2.Zero, p.ID))); } // objects foreach (int id in Game1.objectInformation.Keys) { string[] fields = Game1.objectInformation[id]?.Split('/'); // secret notes if (id == 79) { foreach (int secretNoteId in this.TryLoad <int, string>("Data\\SecretNotes").Keys) { yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset + secretNoteId, _ => { SObject note = new SObject(79, 1); note.name = $"{note.name} #{secretNoteId}"; return note; })); } } // ring else if (id != 801 && fields?.Length >= 4 && fields[3] == "Ring") // 801 = wedding ring, which isn't an equippable ring { yield return(this.TryCreate(ItemType.Ring, id, p => new Ring(p.ID))); } // item else { // spawn main item SObject item = null; yield return(this.TryCreate(ItemType.Object, id, p => { return item = (p.ID == 812 // roe ? new ColoredObject(p.ID, 1, Color.White) : new SObject(p.ID, 1) ); })); if (item == null) { continue; } // flavored items switch (item.Category) { // fruit products case SObject.FruitsCategory: // wine yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 2 + id, _ => new SObject(348, 1) { Name = $"{item.Name} Wine", Price = item.Price * 3, preserve = { SObject.PreserveType.Wine }, preservedParentSheetIndex = { item.ParentSheetIndex } })); // jelly yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 3 + id, _ => new SObject(344, 1) { Name = $"{item.Name} Jelly", Price = 50 + item.Price * 2, preserve = { SObject.PreserveType.Jelly }, preservedParentSheetIndex = { item.ParentSheetIndex } })); break; // vegetable products case SObject.VegetableCategory: // juice yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 4 + id, _ => new SObject(350, 1) { Name = $"{item.Name} Juice", Price = (int)(item.Price * 2.25d), preserve = { SObject.PreserveType.Juice }, preservedParentSheetIndex = { item.ParentSheetIndex } })); // pickled yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 5 + id, _ => new SObject(342, 1) { Name = $"Pickled {item.Name}", Price = 50 + item.Price * 2, preserve = { SObject.PreserveType.Pickle }, preservedParentSheetIndex = { item.ParentSheetIndex } })); break; // flower honey case SObject.flowersCategory: yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 5 + id, _ => { SObject honey = new SObject(Vector2.Zero, 340, $"{item.Name} Honey", false, true, false, false) { Name = $"{item.Name} Honey", preservedParentSheetIndex = { item.ParentSheetIndex } }; honey.Price += item.Price * 2; return honey; })); break; // roe and aged roe (derived from FishPond.GetFishProduce) case SObject.sellAtFishShopCategory when id == 812: foreach (var pair in Game1.objectInformation) { // get input SObject input = this.TryCreate(ItemType.Object, pair.Key, p => new SObject(p.ID, 1))?.Item as SObject; if (input == null || input.Category != SObject.FishCategory) { continue; } Color color = this.GetRoeColor(input); // yield roe SObject roe = null; yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 7 + id, _ => { roe = new ColoredObject(812, 1, color) { name = $"{input.Name} Roe", preserve = { Value = SObject.PreserveType.Roe }, preservedParentSheetIndex = { Value = input.ParentSheetIndex } }; roe.Price += input.Price / 2; return roe; })); // aged roe if (roe != null && pair.Key != 698) // aged sturgeon roe is caviar, which is a separate item { yield return(this.TryCreate(ItemType.Object, this.CustomIDOffset * 7 + id, _ => new ColoredObject(447, 1, color) { name = $"Aged {input.Name} Roe", Category = -27, preserve = { Value = SObject.PreserveType.AgedRoe }, preservedParentSheetIndex = { Value = input.ParentSheetIndex }, Price = roe.Price * 2 })); } } break; } } } } return(GetAllRaw().Where(p => p != null)); }
public override bool isTileOccupiedForPlacement(Vector2 tileLocation, StardewValley.Object toPlace = null) { // Preventing player from placing items here return(true); }
/// <summary>Get the color to use a given fish's roe.</summary> /// <param name="fish">The fish whose roe to color.</param> /// <remarks>Derived from <see cref="StardewValley.Buildings.FishPond.GetFishProduce"/>.</remarks> private Color GetRoeColor(SObject fish) { return(fish.ParentSheetIndex == 698 // sturgeon ? new Color(61, 55, 42) : (TailoringMenu.GetDyeColor(fish) ?? Color.Orange)); }
public static int digUpArtifactSpot(int xLocation, int yLocation, Farmer who, string name) { Random random = new Random(xLocation * 2000 + yLocation + (int)Game1.uniqueIDForThisGame / 2 + (int)Game1.stats.DaysPlayed); bool archaeologyEnchant = who != null && who.CurrentTool != null && who.CurrentTool is Hoe && who.CurrentTool.hasEnchantmentOfType <ArchaeologistEnchantment>(); int objectIndex = -1; foreach (KeyValuePair <int, string> keyValuePair in Game1.objectInformation) { string[] strArray1 = keyValuePair.Value.Split('/'); if (strArray1[3].Contains("Arch")) { string[] strArray2 = strArray1[6].Split(' '); int index = 0; while (index < strArray2.Length) { if (strArray2[index].Equals(Game1.currentLocation.Name) && random.NextDouble() < (archaeologyEnchant ? 2 : 1) * Convert.ToDouble(strArray2[index + 1], CultureInfo.InvariantCulture)) { objectIndex = keyValuePair.Key; break; } index += 2; } } if (objectIndex != -1) { break; } } if (random.NextDouble() < 0.2 && !(Game1.currentLocation is Farm)) { objectIndex = 102; } if (objectIndex == 102 && who.archaeologyFound.ContainsKey(102) && who.archaeologyFound[102][0] >= 21) { objectIndex = 770; } if (objectIndex != -1) { return(objectIndex); } else if (Game1.currentSeason.Equals("winter") && random.NextDouble() < 0.5 && !(Game1.currentLocation is Desert)) { if (random.NextDouble() < 0.4) { random.NextDouble(); return(416); } else { random.NextDouble(); return(412); } } else { //* if (random.NextDouble() <= 0.2 && Game1.player.team.SpecialOrderRuleActive("DROP_QI_BEANS")) { return(890); } if (Game1.GetSeasonForLocation(Game1.currentLocation).Equals("spring") && random.NextDouble() < 0.0625 && !(Game1.currentLocation is Desert) && !(Game1.currentLocation is Beach)) { return(273); } if (Game1.random.NextDouble() <= 0.2 && (Game1.MasterPlayer.mailReceived.Contains("guntherBones") || (Game1.player.team.specialOrders.Where(( SpecialOrder x ) => ( string )x.questKey == "Gunther") != null && Game1.player.team.specialOrders.Where(( SpecialOrder x ) => ( string )x.questKey == "Gunther").Count() > 0))) { return(881); } //*/ Dictionary <string, string> dictionary = Game1.content.Load <Dictionary <string, string> >("Data\\Locations"); if (!dictionary.ContainsKey(Game1.currentLocation.name)) { return(-1); } string[] strArray = dictionary[Game1.currentLocation.Name].Split('/')[8].Split(' '); if (strArray.Length == 0 || strArray[0].Equals("-1")) { return(-1); } int index1 = 0; while (index1 < strArray.Length) { if (random.NextDouble() <= Convert.ToDouble(strArray[index1 + 1])) { int index2 = Convert.ToInt32(strArray[index1]); if (Game1.objectInformation.ContainsKey(index2)) { if (Game1.objectInformation[index2].Split('/')[3].Contains("Arch") || index2 == 102) { if (index2 == 102 && Game1.netWorldState.Value.LostBooksFound.Value >= 21) { index2 = 770; } return(index2); } } if (index2 == 330 && Game1.currentLocation.HasUnlockedAreaSecretNotes(who) && random.NextDouble() < 0.11) { SObject unseenSecretNote = Game1.currentLocation.tryToCreateUnseenSecretNote(who); if (unseenSecretNote != null) { return(79); } } else if (index2 == 330 && Game1.stats.DaysPlayed > 28 && random.NextDouble() < 0.1) { return(688 + random.Next(3)); } return(index2); } index1 += 2; } } return(-1); }
/// <summary>When a menu is open (<see cref="Game1.activeClickableMenu"/> isn't null), raised after that menu is drawn to the sprite batch but before it's rendered to the screen.</summary> /// <param name="sender">The event sender.</param> /// <param name="e">The event arguments.</param> private void OnRenderedActiveMenu(object sender, RenderedActiveMenuEventArgs e) { if (!(Game1.activeClickableMenu is ShopMenu menu)) { return; } if (!(menu.hoveredItem is Item hoverItem)) { return; } // draw shop harvest prices bool isSeeds = hoverItem is StardewValley.Object hoverObject && hoverObject.Type == "Seeds"; bool isSapling = hoverItem.Name.EndsWith("Sapling"); int value = 0; if (isSeeds && hoverItem.Name != "Mixed Seeds" && hoverItem.Name != "Winter Seeds") { bool itemHasPriceInfo = Tools.GetTruePrice(hoverItem) > 0; if (itemHasPriceInfo) { StardewValley.Object temp = new StardewValley.Object( new Debris( new Crop( hoverItem.ParentSheetIndex, 0, 0) .indexOfHarvest.Value, Game1.player.position, Game1.player.position).chunkType.Value, 1); value = temp.Price; } else { switch (hoverItem.ParentSheetIndex) { case 802: value = 75; break; // Cactus } } } else if (isSapling) { switch (hoverItem.ParentSheetIndex) { case 628: value = 50; break; // Cherry case 629: value = 80; break; // Apricot case 630: // Orange case 633: value = 100; break; // Apple case 631: // Peach case 632: value = 140; break; // Pomegranate } } if (value > 0) { int xPosition = menu.xPositionOnScreen - 30; int yPosition = menu.yPositionOnScreen + 580; IClickableMenu.drawTextureBox( Game1.spriteBatch, xPosition + 20, yPosition - 52, 264, 108, Color.White); // Title "Harvest Price" string textToRender = _helper.SafeGetString(LanguageKeys.HarvestPrice); Game1.spriteBatch.DrawString( Game1.dialogueFont, textToRender, new Vector2(xPosition + 30, yPosition - 38), Color.Black * 0.2f); Game1.spriteBatch.DrawString( Game1.dialogueFont, textToRender, new Vector2(xPosition + 32, yPosition - 40), Color.Black * 0.8f); // Tree Icon xPosition += 80; Game1.spriteBatch.Draw( Game1.mouseCursors, new Vector2(xPosition, yPosition), new Rectangle(60, 428, 10, 10), Color.White, 0, Vector2.Zero, Game1.pixelZoom, SpriteEffects.None, 0.85f); // Coin Game1.spriteBatch.Draw( Game1.debrisSpriteSheet, new Vector2(xPosition + 32, yPosition + 10), Game1.getSourceRectForStandardTileSheet(Game1.debrisSpriteSheet, 8, 16, 16), Color.White, 0, new Vector2(8, 8), 4, SpriteEffects.None, 0.95f); // Price string text = " " + value; Game1.spriteBatch.DrawString( Game1.dialogueFont, text, new Vector2(xPosition - 2, yPosition + 6), Color.Black * 0.2f); Game1.spriteBatch.DrawString( Game1.dialogueFont, text, new Vector2(xPosition, yPosition + 4), Color.Black * 0.8f); /* * I have no Idea why this is here... * As far as I can see it only overrides the existing Tooltip with a price that is 500 coins higher? * * string hoverText = _helper.Reflection.GetField<string>(menu, "hoverText").GetValue(); * string hoverTitle = _helper.Reflection.GetField<string>(menu, "boldTitleText").GetValue(); * IReflectedMethod getHoveredItemExtraItemIndex = _helper.Reflection.GetMethod(menu, "getHoveredItemExtraItemIndex"); * IReflectedMethod getHoveredItemExtraItemAmount = _helper.Reflection.GetMethod(menu, "getHoveredItemExtraItemAmount"); * IClickableMenu.drawToolTip( * Game1.spriteBatch, * hoverText, * hoverTitle, * hoverItem, * menu.heldItem != null, * -1, * menu.currency, * getHoveredItemExtraItemIndex.Invoke<int>(new object[0]), * getHoveredItemExtraItemAmount.Invoke<int>(new object[0]), * null, * menu.hoverPrice); */ } }
public static void LoadContentPacks(object sender, EventArgs e) { foreach (IContentPack contentPack in MailFrameworkModEntry.ModHelper.ContentPacks.GetOwned()) { if (File.Exists(Path.Combine(contentPack.DirectoryPath, "mail.json"))) { bool hasTranslation = contentPack.Translation.GetTranslations().Any(); MailFrameworkModEntry.ModMonitor.Log($"Reading content pack: {contentPack.Manifest.Name} {contentPack.Manifest.Version} from {contentPack.DirectoryPath}"); List <MailItem> mailItems = contentPack.ReadJsonFile <List <MailItem> >("mail.json"); foreach (MailItem mailItem in mailItems) { Dictionary <int, string> objects = null; Dictionary <int, string> bigObjects = null; //Populate all Indexs based on the given name. Ignore the letter otherwise. if (mailItem.CollectionConditions != null && mailItem.CollectionConditions.Any(c => { if (c.Name != null) { objects = objects ?? MailFrameworkModEntry.ModHelper.Content.Load <Dictionary <int, string> >("Data\\ObjectInformation", ContentSource.GameContent); KeyValuePair <int, string> pair = objects.FirstOrDefault(o => o.Value.StartsWith(c.Name + "/")); if (pair.Value != null) { c.Index = pair.Key; } else { MailFrameworkModEntry.ModMonitor.Log($"No object found with the name '{c.Name}' for a condition for letter '{mailItem.Id}'.\n This letter will be ignored.", LogLevel.Warn); MailDao.RemoveLetter(new Letter(mailItem.Id, null, null)); return(true); } } return(false); })) { break; } bool Condition(Letter l) => (!Game1.player.mailReceived.Contains(l.Id) || mailItem.Repeatable) && (mailItem.Recipe == null || !Game1.player.cookingRecipes.ContainsKey(mailItem.Recipe)) && (mailItem.Date == null || SDate.Now() >= new SDate(Convert.ToInt32(mailItem.Date.Split(' ')[0]), mailItem.Date.Split(' ')[1], Convert.ToInt32(mailItem.Date.Split(' ')[2].Replace("Y", "")))) && (mailItem.Days == null || mailItem.Days.Contains(SDate.Now().Day)) && (mailItem.Seasons == null || mailItem.Seasons.Contains(SDate.Now().Season)) && (mailItem.Weather == null || (Game1.isRaining && "rainy".Equals(mailItem.Weather)) || (!Game1.isRaining && "sunny".Equals(mailItem.Weather))) && (mailItem.FriendshipConditions == null || (mailItem.FriendshipConditions.TrueForAll(f => Game1.player.getFriendshipHeartLevelForNPC(f.NpcName) >= f.FriendshipLevel)) && mailItem.FriendshipConditions.TrueForAll(f => f.FriendshipStatus == null || (Game1.player.friendshipData.ContainsKey(f.NpcName) && f.FriendshipStatus.Any(s => s == Game1.player.friendshipData[f.NpcName].Status)))) && (mailItem.SkillConditions == null || mailItem.SkillConditions.TrueForAll(s => Game1.player.getEffectiveSkillLevel((int)s.SkillName) >= s.SkillLevel)) && (mailItem.StatsConditions == null || (mailItem.StatsConditions.TrueForAll(s => s.StatsLabel == null || Game1.player.stats.getStat(s.StatsLabel) >= s.Amount) && mailItem.StatsConditions.TrueForAll(s => s.StatsName == null || MailFrameworkModEntry.ModHelper.Reflection.GetProperty <uint>(Game1.player.stats, s.StatsName.ToString()).GetValue() >= s.Amount))) && (mailItem.CollectionConditions == null || (mailItem.CollectionConditions.TrueForAll(c => (c.Collection == Collection.Shipped && Game1.player.basicShipped.ContainsKey(c.Index) && Game1.player.basicShipped[c.Index] >= c.Amount) || (c.Collection == Collection.Fish && Game1.player.fishCaught.ContainsKey(c.Index) && Game1.player.fishCaught[c.Index][0] >= c.Amount) || (c.Collection == Collection.Artifacts && Game1.player.archaeologyFound.ContainsKey(c.Index) && Game1.player.archaeologyFound[c.Index][0] >= c.Amount) || (c.Collection == Collection.Minerals && Game1.player.mineralsFound.ContainsKey(c.Index) && Game1.player.mineralsFound[c.Index] >= c.Amount) || (c.Collection == Collection.Cooking && Game1.player.recipesCooked.ContainsKey(c.Index) && Game1.player.recipesCooked[c.Index] >= c.Amount) ))) && (mailItem.RandomChance == null || new Random((int)(((ulong)Game1.stats.DaysPlayed * 1000000000000000) + (((ulong)l.Id.GetHashCode()) % 1000000000 * 1000000) + Game1.uniqueIDForThisGame % 1000000)).NextDouble() < mailItem.RandomChance) && (mailItem.Buildings == null || (mailItem.RequireAllBuildings ? mailItem.Buildings.TrueForAll(b => Game1.getFarm().isBuildingConstructed(b)) : mailItem.Buildings.Any(b => Game1.getFarm().isBuildingConstructed(b)))) && (mailItem.MailReceived == null || (mailItem.RequireAllMailReceived ? !mailItem.MailReceived.Except(Game1.player.mailReceived).Any() : mailItem.MailReceived.Intersect(Game1.player.mailReceived).Any())) && (mailItem.MailNotReceived == null || !mailItem.MailNotReceived.Intersect(Game1.player.mailReceived).Any()) && (mailItem.EventsSeen == null || (mailItem.RequireAllEventsSeen ? !mailItem.EventsSeen.Except(Game1.player.eventsSeen).Any() : mailItem.EventsSeen.Intersect(Game1.player.eventsSeen).Any())) && (mailItem.EventsNotSeen == null || !mailItem.EventsNotSeen.Intersect(Game1.player.eventsSeen).Any()) ; if (mailItem.Attachments != null && mailItem.Attachments.Count > 0) { List <Item> attachments = new List <Item>(); mailItem.Attachments.ForEach(i => { switch (i.Type) { case ItemType.Object: if (i.Name != null) { objects = objects ?? MailFrameworkModEntry.ModHelper.Content.Load <Dictionary <int, string> >("Data\\ObjectInformation", ContentSource.GameContent); KeyValuePair <int, string> pair = objects.FirstOrDefault(o => o.Value.StartsWith(i.Name + "/")); if (pair.Value != null) { i.Index = pair.Key; } else { MailFrameworkModEntry.ModMonitor.Log($"No object found with the name {i.Name} for letter {mailItem.Id}.", LogLevel.Warn); } } if (i.Index.HasValue) { attachments.Add(new StardewValley.Object(Vector2.Zero, i.Index.Value, i.Stack ?? 1)); } else { MailFrameworkModEntry.ModMonitor.Log($"An index value is required to attach an object for letter {mailItem.Id}.", LogLevel.Warn); } break; case ItemType.BigObject: case ItemType.BigCraftable: if (i.Name != null) { bigObjects = bigObjects ?? MailFrameworkModEntry.ModHelper.Content.Load <Dictionary <int, string> >("Data\\BigCraftablesInformation", ContentSource.GameContent); KeyValuePair <int, string> pair = bigObjects.FirstOrDefault(o => o.Value.StartsWith(i.Name + "/")); if (pair.Value != null) { i.Index = pair.Key; } else { MailFrameworkModEntry.ModMonitor.Log($"No big craftable found with the name {i.Name} for letter {mailItem.Id}.", LogLevel.Warn); } } if (i.Index.HasValue) { Item item = new StardewValley.Object(Vector2.Zero, i.Index.Value); if (i.Stack.HasValue) { item.Stack = i.Stack.Value; } attachments.Add(item); } else { MailFrameworkModEntry.ModMonitor.Log($"An index value is required to attach a big craftable for letter {mailItem.Id}.", LogLevel.Warn); } break; case ItemType.Tool: switch (i.Name) { case "Axe": attachments.Add(new Axe()); break; case "Hoe": attachments.Add(new Hoe()); break; case "Watering Can": attachments.Add(new WateringCan()); break; case "Scythe": attachments.Add(new MeleeWeapon(47)); break; case "Pickaxe": attachments.Add(new Pickaxe()); break; default: MailFrameworkModEntry.ModMonitor.Log($"Tool with name {i.Name} not found for letter {mailItem.Id}.", LogLevel.Warn); break; } break; } }); MailDao.SaveLetter( new Letter( mailItem.Id , hasTranslation? contentPack.Translation.Get(mailItem.Text) : mailItem.Text , attachments , Condition , (l) => Game1.player.mailReceived.Add(l.Id) , mailItem.WhichBG ) { TextColor = mailItem.TextColor, Title = hasTranslation && mailItem.Title != null ? contentPack.Translation.Get(mailItem.Title) : mailItem.Title, GroupId = mailItem.GroupId }); } else { MailDao.SaveLetter( new Letter( mailItem.Id , hasTranslation ? contentPack.Translation.Get(mailItem.Text) : mailItem.Text , mailItem.Recipe , Condition , (l) => Game1.player.mailReceived.Add(l.Id) , mailItem.WhichBG ) { TextColor = mailItem.TextColor, Title = hasTranslation && mailItem.Title != null ? contentPack.Translation.Get(mailItem.Title) : mailItem.Title, GroupId = mailItem.GroupId }); } } } else { MailFrameworkModEntry.ModMonitor.Log($"Ignoring content pack: {contentPack.Manifest.Name} {contentPack.Manifest.Version} from {contentPack.DirectoryPath}\nIt does not have an mail.json file.", LogLevel.Warn); } } }
/// <summary>The prefix for the UpdateTapperProduct method.</summary> /// <param name="tapper_instance">The tapper object on the tree.</param> /// <returns>True, meaning the original method will get ran.</returns> internal static bool UpdateTapperProductPrefix(SObject tapper_instance) { // TODO: determine how the minutesUntilReady should get calculated return(true); }
/********* ** Public methods *********/ /// <summary>Construct an instance.</summary> /// <param name="machine">The underlying machine.</param> /// <param name="location">The location containing the machine.</param> /// <param name="tile">The machine's position in its location.</param> public BeeHouseMachine(SObject machine, GameLocation location, Vector2 tile) : base(machine) { this.Location = location; this.Tile = tile; }
/********* ** Public methods *********/ /// <summary>Construct an instance.</summary> /// <param name="machine">The underlying machine.</param> public MushroomBoxMachine(SObject machine) : base(machine) { }
private static void out_items(object sender, EventArgsCommand e) { for (var i = 0; i < 1000; i++) { try { Item it = new Object(i, 1); if (it.Name != "Error Item") Console.WriteLine(i + "| " + it.Name); } catch { } } }
public static void DrawFishingInfoBox(SpriteBatch batch, BobberBar bar, SpriteFont font) { int width = 0, height = 120; float scale = 1.0f; int whichFish = Reflection.GetField <int>(bar, "whichFish").GetValue(); int fishSize = Reflection.GetField <int>(bar, "fishSize").GetValue(); int fishQuality = Reflection.GetField <int>(bar, "fishQuality").GetValue(); bool treasure = Reflection.GetField <bool>(bar, "treasure").GetValue(); bool treasureCaught = Reflection.GetField <bool>(bar, "treasureCaught").GetValue(); float treasureAppearTimer = Reflection.GetField <float>(bar, "treasureAppearTimer").GetValue() / 1000; bool perfect = Reflection.GetField <bool>(bar, "perfect").GetValue(); if (perfect) { if (fishQuality >= 2) { fishQuality = 4; } else if (fishQuality >= 1) { fishQuality = 3; } } Object fish = new Object(whichFish, 1, quality: fishQuality); int salePrice = fish.sellToStorePrice(); if (LocalizedContentManager.CurrentLanguageCode == LocalizedContentManager.LanguageCode.en) { scale = 0.7f; } string speciesText = Util.TryFormat(Translation.Get("fishinfo.species").ToString(), fish.DisplayName); string sizeText = Util.TryFormat(Translation.Get("fishinfo.size").ToString(), GetFinalSize(fishSize)); string qualityText1 = Translation.Get("fishinfo.quality").ToString(); string qualityText2 = Translation.Get(GetKeyForQuality(fishQuality)).ToString(); string incomingText = Util.TryFormat(Translation.Get("fishinfo.treasure.incoming").ToString(), treasureAppearTimer); string appearedText = Translation.Get("fishinfo.treasure.appear").ToString(); string caughtText = Translation.Get("fishinfo.treasure.caught").ToString(); string priceText = Util.TryFormat(Translation.Get("fishinfo.price"), salePrice); { Vector2 size = font.MeasureString(speciesText) * scale; if (size.X > width) { width = (int)size.X; } height += (int)size.Y; size = font.MeasureString(sizeText) * scale; if (size.X > width) { width = (int)size.X; } height += (int)size.Y; Vector2 temp = font.MeasureString(qualityText1); Vector2 temp2 = font.MeasureString(qualityText2); size = new Vector2(temp.X + temp2.X, Math.Max(temp.Y, temp2.Y)); if (size.X > width) { width = (int)size.X; } height += (int)size.Y; size = font.MeasureString(priceText) * scale; if (size.X > width) { width = (int)size.X; } height += (int)size.Y; } if (treasure) { if (treasureAppearTimer > 0) { Vector2 size = font.MeasureString(incomingText) * scale; if (size.X > width) { width = (int)size.X; } height += (int)size.Y; } else { if (!treasureCaught) { Vector2 size = font.MeasureString(appearedText) * scale; if (size.X > width) { width = (int)size.X; } height += (int)size.Y; } else { Vector2 size = font.MeasureString(caughtText) * scale; if (size.X > width) { width = (int)size.X; } height += (int)size.Y; } } } width += 64; int x = bar.xPositionOnScreen + bar.width + 96; if (x + width > Game1.viewport.Width) { x = bar.xPositionOnScreen - width - 96; } int y = (int)Util.Cap(bar.yPositionOnScreen, 0, Game1.viewport.Height - height); Util.DrawWindow(x, y, width, height); fish.drawInMenu(batch, new Vector2(x + width / 2 - 32, y + 16), 1.0f, 1.0f, 0.9f, StackDrawType.Hide); Vector2 vec2 = new Vector2(x + 32, y + 96); Util.DrawString(batch, font, ref vec2, speciesText, Color.Black, scale); Util.DrawString(batch, font, ref vec2, sizeText, Color.Black, scale); Util.DrawString(batch, font, ref vec2, qualityText1, Color.Black, scale, true); Util.DrawString(batch, font, ref vec2, qualityText2, GetColorForQuality(fishQuality), scale); vec2.X = x + 32; Util.DrawString(batch, font, ref vec2, priceText, Color.Black, scale); if (treasure) { if (!treasureCaught) { if (treasureAppearTimer > 0f) { Util.DrawString(batch, font, ref vec2, incomingText, Color.Red, scale); } else { Util.DrawString(batch, font, ref vec2, appearedText, Color.LightGoldenrodYellow, scale); } } else { Util.DrawString(batch, font, ref vec2, caughtText, Color.ForestGreen, scale); } } }
public static MachineRemove Create(GameLocation location, SVObject machine) => new(
/// <summary>Get whether a given object is a weed.</summary> /// <param name="obj">The world object.</param> protected bool IsTwig(SObject obj) { return(obj?.ParentSheetIndex == 294 || obj?.ParentSheetIndex == 295); }