// For Automate We now need to get all seed makers available. // So making this a method on its own private void populateSeedmakersBase() { allSeedMakers.Clear(); if (hasAutomate) { allChests.Clear(); } foreach (GameLocation location in Game1.locations) { OverlaidDictionary allObjects = location.objects; foreach (StardewValley.Object ob in allObjects.Values) { if (ob.name.Equals("Seed Maker")) { if (!allSeedMakers.ContainsKey(ob)) { allSeedMakers.Add(ob, new AllSeedMakerValueContainer(null, location, ob != null ? true : false)); } } if (hasAutomate) { if ((ob is Chest) && (ob as Chest).playerChest) { if (!allChests.ContainsKey(ob)) { allChests.Add(ob, new AllChestsValueContainer(null, location, false)); } } } } } previousLocation = Game1.player.currentLocation; }
public static void checkAndRemoveDynamicObject(OverlaidDictionary objects, Vector2 key) { if (objects[key] is IBigCraftable) { objects[key] = ((IBigCraftable)objects[key]).baseObject; } }
public static void ReplaceWith(this OverlaidDictionary collection, OverlaidDictionary source) { collection.Clear(); foreach (var kvp in source.Pairs) { collection.Add(kvp.Key, kvp.Value); } }
public static void checkAndInjectDynamicObject(OverlaidDictionary objects, Vector2 key) { if (!(objects[key] is IBigCraftable) && wrappers.ContainsKey(objects[key].name)) { IBigCraftableWrapper wrapper = wrappers[objects[key].name]; objects[key] = (IBigCraftable)Activator.CreateInstance(wrapper.dynamicObjectType, objects[key], wrapper); } }
public static void injectDynamicsInCurrentLocation() { OverlaidDictionary objects = Game1.currentLocation.objects; foreach (Vector2 key in objects.Keys) { IBigCraftableWrapper.checkAndInjectDynamicObject(objects, key); } }
public static void removeDynamicsInAllLocations() { foreach (GameLocation location in Game1.locations) { OverlaidDictionary objects = location.objects; foreach (Vector2 key in objects.Keys) { IBigCraftableWrapper.checkAndRemoveDynamicObject(objects, key); } } }
/// <summary>Raised after objects are added or removed in a location.</summary> /// <param name="sender">The event sender.</param> /// <param name="e">The event data.</param> private void OnObjectListChanged(object sender, ObjectListChangedEventArgs e) { this.gateList = new SerializableDictionary <Vector2, SObject>(); OverlaidDictionary objects = Game1.currentLocation.objects; foreach (Vector2 key in objects.Keys) { if (objects[key].name.Equals("Gate")) { this.gateList.Add(key, objects[key]); //this.Monitor.Log(string.Format("{0}", (object)key.ToString()), (LogLevel)1); } } }
private void EnteredNewLocation(object sender, EventArgsPlayerWarped e) { this.gateList = new SerializableDictionary <Vector2, StardewValley.Object>(); OverlaidDictionary <Vector2, SObject> objects = Game1.currentLocation.objects; foreach (Vector2 key in objects.Keys) { if (objects[key].name.Equals("Gate")) { this.gateList.Add(key, objects[key]); //this.Monitor.Log(string.Format("{0}", (object)key.ToString()), (LogLevel)1); } } }
private void DogSpawn(StardewValley.Characters.Pet thePet = null, NPC theNPC = null) { // Spawn gift // Remove old gift if there's still one on the floor OverlaidDictionary obs = Game1.getLocationFromName("Farm").Objects; Vector2 spawnPos = new Vector2(tile.X, tile.Y); for (int i = 0; i < obs.Count(); i++) { Vector2 currentPos = obs.Keys.ElementAt(i); if (currentPos == spawnPos) { obs.Remove(obs.Keys.ElementAt(i)); } } Game1.getLocationFromName("Farm").dropObject(new StardewValley.Object(giftId, 1, false, -1, 0), spawnPos * 64f, Game1.viewport, true, (Farmer)null); //this.Monitor.Log("Object dropped!"); // Convert drop location to dirt (if we would do this beforehand, spawn would be impeded) Game1.getLocationFromName("Farm").terrainFeatures[tile] = new HoeDirt(); // Warp dog Vector2 warpPos = this.FindSafePosition(tile); // If we find a safe location near the treasure, warp the pet if (warpPos != tile) { if (theNPC == null) { thePet.Position = warpPos * 64f; } else if (thePet == null) { theNPC.Position = warpPos * 64f; } } this.Monitor.Log("Warped him ... most likely, to " + warpPos.X + "/" + warpPos.Y); warpedToday = true; Game1.playSound("dog_bark"); }
private StardewValley.Object checkChests(StardewValley.Object seedmaker) { OverlaidDictionary allObjectsinLocation = allSeedMakers[seedmaker].location.objects; OverlaidDictionary.KeysCollection keyCollection = allObjectsinLocation.Keys; foreach (Vector2 objectKey in keyCollection) { if (allObjectsinLocation[objectKey] is Chest && Vector2.Distance(objectKey, seedmaker.TileLocation) <= 1.0) { Chest thisChest = (allObjectsinLocation[objectKey] as Chest); Netcode.NetObjectList <Item> currentItems = thisChest.items; for (int index = 0; index < currentItems.Count; index++) { if (currentItems[index] == null || currentItems[index].ParentSheetIndex == 433) { continue; } { Dictionary <int, string> dictionary = Game1.temporaryContent.Load <Dictionary <int, string> >("Data\\Crops"); foreach (KeyValuePair <int, string> keyValuePair in dictionary) { if (Convert.ToInt32(keyValuePair.Value.Split('/')[3]) == currentItems[index].ParentSheetIndex) { allChests[thisChest].previousItem = currentItems[index]; return(currentItems[index] as StardewValley.Object); } } } } if (allChests[thisChest].previousItem != null) { Item returnItem = allChests[thisChest].previousItem; allChests[thisChest].previousItem = null; return(returnItem as StardewValley.Object); } } } return(null); }
private static int GetGroupSetOffset(OverlaidDictionary objects, int x, int y) { Dictionary <int, List <Vector2> > offsets = new Dictionary <int, List <Vector2> >(); GetSurroundingOffsets(objects, new List <Vector2>(), offsets, new Vector2(x, y)); int offset = 0; int count = 0; int dCount = 0; string debug = ""; if (!check.Contains(new Vector2(x, y)) && offsets.Count > 1) { check.Add(new Vector2(x, y)); debug += $"multi: {x},{y}'s group has {offsets.Count} different sets"; } foreach (var k in offsets.Keys) { dCount += offsets[k].Count; if (debug != "") { debug += $"\noffset {k}: {string.Join(" | ", offsets[k])}"; } if (offsets[k].Count > count || (offsets[k].Count == count && k > offset)) { count = offsets[k].Count; offset = k; } } if (debug != "") { debug += $"\nfinal offset: {offset}, pieces: {dCount}"; SMonitor.Log(debug); } return(offset); }
//Converts all hoppers in Objects to ToType that are FromType private void ConvertHopper <FromType, ToType>(OverlaidDictionary <Vector2, SObject> Objects) where ToType : SObject where FromType : SObject { if (Objects == null) { return; } IList <Vector2> hopperLocations = new List <Vector2>(); foreach (KeyValuePair <Vector2, SObject> kvp in Objects.Pairs) { if (typeof(ToType) == typeof(SObject) ? kvp.Value is FromType : kvp.Value.name.Contains("Hopper")) { hopperLocations.Add(kvp.Key); break; } } foreach (Vector2 hopperLocation in hopperLocations) { Objects[hopperLocation] = (ToType)Activator.CreateInstance(typeof(ToType), new object[] { hopperLocation, 99, false }); } }
private static void GetSurroundingOffsets(OverlaidDictionary objects, List <Vector2> tiles, Dictionary <int, List <Vector2> > offsets, Vector2 tile) { if (!tiles.Contains(tile)) { tiles.Add(tile); } int offset = GetSetOffset(objects[tile].parentSheetIndex); if (!offsets.ContainsKey(offset)) { offsets.Add(offset, new List <Vector2>() { tile }); } else { offsets[offset].Add(tile); } if (!tiles.Contains(tile + new Vector2(-1, 0)) && IsRock(objects, (int)tile.X - 1, (int)tile.Y)) { GetSurroundingOffsets(objects, tiles, offsets, tile + new Vector2(-1, 0)); } if (!tiles.Contains(tile + new Vector2(1, 0)) && IsRock(objects, (int)tile.X + 1, (int)tile.Y)) { GetSurroundingOffsets(objects, tiles, offsets, tile + new Vector2(1, 0)); } if (!tiles.Contains(tile + new Vector2(0, -1)) && IsRock(objects, (int)tile.X, (int)tile.Y - 1)) { GetSurroundingOffsets(objects, tiles, offsets, tile + new Vector2(0, -1)); } if (!tiles.Contains(tile + new Vector2(0, 1)) && IsRock(objects, (int)tile.X, (int)tile.Y + 1)) { GetSurroundingOffsets(objects, tiles, offsets, tile + new Vector2(0, 1)); } }
private static void FindAllInstances(object value, List <string> propNames, HashSet <object> exploredObjects, Dictionary <object, List <object> > found, object parent) { if (value == null || exploredObjects.Contains(value)) { return; } exploredObjects.Add(value); IDictionary dict = value as IDictionary; IList list = value as IList; ICollection col = value as ICollection; OverlaidDictionary <Vector2, SObject> ovd = value as OverlaidDictionary <Vector2, SObject>; NetObjectList <Item> noli = value as NetObjectList <Item>; IList <Building> buildings = value as IList <Building>; if (dict != null) { foreach (object item in dict.Values) { FindAllInstances(item, propNames, exploredObjects, found, dict); } } else if (list != null) { foreach (object item in list) { FindAllInstances(item, propNames, exploredObjects, found, list); } } else if (col != null) { foreach (object item in col) { FindAllInstances(item, propNames, exploredObjects, found, col); } } else if (ovd != null) { foreach (object item in ovd.Values) { FindAllInstances(item, propNames, exploredObjects, found, ovd); } } else if (noli != null) { foreach (object item in noli) { FindAllInstances(item, propNames, exploredObjects, found, noli); } } else if (buildings != null) { foreach (object item in buildings) { FindAllInstances(item, propNames, exploredObjects, found, buildings); } } else { if (found.ContainsKey(parent)) { found[parent].Add(value); } else { found.Add(parent, new List <object>() { value }); } Type type = value.GetType(); FieldInfo[] properties = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetProperty); foreach (FieldInfo property in properties) { if (!propNames.Contains(property.Name)) { continue; } object propertyValue = property.GetValue(value); if (propertyValue != null && propertyValue.GetType() is Type t && t.IsClass) { FindAllInstances(propertyValue, propNames, exploredObjects, found, new KeyValuePair <FieldInfo, object>(property, value)); } } } }
private static bool IsRock(OverlaidDictionary objects, int x, int y) { return(objects.ContainsKey(new Vector2(x, y)) && (rocks.Contains(objects[new Vector2(x, y)].parentSheetIndex) || treasures.Contains(objects[new Vector2(x, y)].parentSheetIndex))); }
private static void GetTileInfo(OverlaidDictionary objects, int x, int y, NetInt parentSheetIndex, bool flip, out int tileIndex) { int setOffset = GetGroupSetOffset(objects, x, y); if (IsRock(objects, x - 1, y)) // rock to left { if (IsRock(objects, x + 1, y)) // rock to right { if (IsRock(objects, x, y - 1)) // rock above { if (IsRock(objects, x, y + 1)) // rock below { // full tileIndex = 7; } else { // no bottom tileIndex = 10; } } else { if (IsRock(objects, x, y + 1)) { // no top tileIndex = 2; } else { // no top or bottom tileIndex = 6; } } } else // no right { if (IsRock(objects, x, y - 1)) // rock above { if (IsRock(objects, x, y + 1)) // rock below { // no right tileIndex = flip ? 3 : 11; } else { // no right or bottom tileIndex = flip ? 8 : 9; } } else // no right or above { if (IsRock(objects, x, y + 1)) // rock below { // no right or above tileIndex = flip ? 0 : 1; } else { // only left tileIndex = flip ? 5 : 13; } } } } else // no left { if (IsRock(objects, x + 1, y)) // rock to right { if (IsRock(objects, x, y - 1)) // rock top { if (IsRock(objects, x, y + 1)) // rock bottom { // no left tileIndex = flip ? 11 : 3; } else { // no left or bottom tileIndex = flip ? 9 : 8; } } else { if (IsRock(objects, x, y + 1)) { // no left or top tileIndex = flip ? 1 : 0; } else { // only right tileIndex = flip ? 13 : 5; } } } else // no right { if (IsRock(objects, x, y - 1)) // rock top { if (IsRock(objects, x, y + 1)) // rock bottom { // no right or left tileIndex = 14; } else { // only top tileIndex = 12; } } else // no left, right or top { if (IsRock(objects, x, y + 1)) // rock bottom { // only bottom tileIndex = 4; } else { // none tileIndex = -1; return; } } } } tileIndex += sheetWidth * setOffset * 2; }
public static bool FarmAnimalDayUpdate(ref FarmAnimal __instance, GameLocation environtment) { __instance.controller = null; __instance.health.Value = 3; bool flag1 = false; if (__instance.home != null && !(__instance.home.indoors.Value as AnimalHouse).animals.ContainsKey(__instance.myID) && environtment is Farm) { if (!__instance.home.animalDoorOpen.Value) { __instance.moodMessage.Value = 6; flag1 = true; __instance.happiness.Value /= 2; } else { (environtment as Farm).animals.Remove(__instance.myID.Value); (__instance.home.indoors.Value as AnimalHouse).animals.Add(__instance.myID.Value, __instance); if (Game1.timeOfDay > 1800 && __instance.controller == null) { __instance.happiness.Value /= 2; } environtment = __instance.home.indoors.Value; __instance.setRandomPosition(environtment); return(false); } } ++__instance.daysSinceLastLay.Value; if (!__instance.wasPet.Value) { __instance.friendshipTowardFarmer.Value = Math.Max(0, __instance.friendshipTowardFarmer.Value - (10 - __instance.friendshipTowardFarmer / 200)); __instance.happiness.Value = (byte)Math.Max(0, __instance.happiness.Value - __instance.happinessDrain.Value * 5); } __instance.wasPet.Value = false; if ((__instance.fullness.Value < 200 || Game1.timeOfDay < 1700) && environtment is AnimalHouse) { for (int index = environtment.objects.Count() - 1; index >= 0; --index) { KeyValuePair <Vector2, SObject> keyValuePair = environtment.objects.Pairs.ElementAt(index); if (keyValuePair.Value.Name.Equals("Hay")) { OverlaidDictionary objects = environtment.objects; keyValuePair = environtment.objects.Pairs.ElementAt(index); Vector2 key = keyValuePair.Key; objects.Remove(key); __instance.fullness.Value = Byte.MaxValue; break; } } } var random = new Random((int)(long)__instance.myID / 2 + (int)Game1.stats.DaysPlayed); if (__instance.fullness > 200 || random.NextDouble() < (__instance.fullness.Value - 30) / 170.0) { ++__instance.age.Value; if (__instance.age.Value == __instance.ageWhenMature.Value) { __instance.Sprite.LoadTexture("Animals\\" + __instance.type.Value); if (__instance.type.Value.Contains("Sheep")) { __instance.currentProduce.Value = __instance.defaultProduceIndex; } __instance.daysSinceLastLay.Value = 99; } __instance.happiness.Value = (byte)Math.Min(Byte.MaxValue, __instance.happiness.Value + __instance.happinessDrain.Value * 2); } if (__instance.fullness.Value < 200) { __instance.happiness.Value = (byte)Math.Max(0, __instance.happiness.Value - 100); __instance.friendshipTowardFarmer.Value = Math.Max(0, __instance.friendshipTowardFarmer.Value - 20); } bool flag2 = __instance.daysSinceLastLay.Value >= __instance.daysToLay.Value - (!__instance.type.Value.Equals("Sheep") || !Game1.getFarmer(__instance.ownerID.Value).professions.Contains(3) ? 0 : 1) && random.NextDouble() < __instance.fullness.Value / 200.0 && random.NextDouble() < __instance.happiness.Value / 70.0; int parentSheetIndex; if (!flag2 || __instance.age.Value < __instance.ageWhenMature.Value) { parentSheetIndex = -1; } else { __instance.daysSinceLastLay.Value = 0; parentSheetIndex = __instance.defaultProduceIndex.Value; if (parentSheetIndex == 107 && Loader.CONFIG.InfertileEggs) { parentSheetIndex = Loader.DATA["Dino Egg"]; } if (random.NextDouble() < __instance.happiness.Value / 150.0) { float num1 = __instance.happiness.Value > 200 ? __instance.happiness.Value * 1.5f : (__instance.happiness.Value <= 100 ? __instance.happiness.Value - 100 : 0.0f); if (__instance.type.Value.Equals("Duck") && random.NextDouble() < (__instance.friendshipTowardFarmer.Value + (double)num1) / 5000.0 + Game1.player.team.AverageDailyLuck(null) + Game1.player.team.AverageLuckLevel(null) * 0.01) { parentSheetIndex = __instance.deluxeProduceIndex.Value; } else if (__instance.type.Value.Equals("Rabbit") && random.NextDouble() < (__instance.friendshipTowardFarmer.Value + (double)num1) / 5000.0 + Game1.player.team.AverageDailyLuck(null) + Game1.player.team.AverageLuckLevel(null) * 0.02) { parentSheetIndex = __instance.deluxeProduceIndex.Value; } else if (__instance.type.Value.Equals("Blue Chicken") && random.NextDouble() < (__instance.friendshipTowardFarmer.Value + (double)num1) / 5000.0 + Game1.player.team.AverageDailyLuck() + Game1.player.team.AverageLuckLevel() * 0.01) { parentSheetIndex = Loader.DATA["Blue Chicken Egg"]; } switch (parentSheetIndex) { case 176: ++Game1.stats.ChickenEggsLayed; break; case 180: ++Game1.stats.ChickenEggsLayed; break; case 440: ++Game1.stats.RabbitWoolProduced; break; case 442: ++Game1.stats.DuckEggsLayed; break; } if (random.NextDouble() < (__instance.friendshipTowardFarmer.Value + num1) / 1200.0 && !__instance.type.Value.Equals("Duck") && (!__instance.type.Value.Equals("Rabbit") && !__instance.type.Value.Equals("Blue Chicken") && __instance.deluxeProduceIndex.Value != -1) && __instance.friendshipTowardFarmer.Value >= 200) { parentSheetIndex = __instance.deluxeProduceIndex.Value; } double num2 = __instance.friendshipTowardFarmer.Value / 1000.0 - (1.0 - __instance.happiness.Value / 225.0); if (!__instance.isCoopDweller() && Game1.getFarmer(__instance.ownerID.Value).professions.Contains(3) || __instance.isCoopDweller() && Game1.getFarmer(__instance.ownerID.Value).professions.Contains(2)) { num2 += 0.33; } if (num2 >= 0.95 && random.NextDouble() < num2 / 2.0) { __instance.produceQuality.Value = 4; } else if (random.NextDouble() < num2 / 2.0) { __instance.produceQuality.Value = 2; } else if (random.NextDouble() < num2) { __instance.produceQuality.Value = 1; } else { __instance.produceQuality.Value = 0; } } } if (__instance.harvestType == 1 & flag2) { __instance.currentProduce.Value = parentSheetIndex; parentSheetIndex = -1; } if (parentSheetIndex != -1 && __instance.home != null) { bool flag3 = true; foreach (SObject @object in __instance.home.indoors.Value.objects.Values) { if (@object.bigCraftable.Value && @object.parentSheetIndex.Value == 165 && @object.heldObject.Value != null) { if ((@object.heldObject.Value as Chest).addItem(new SObject(Vector2.Zero, parentSheetIndex, null, false, true, false, false) { Quality = __instance.produceQuality.Value }) == null) { @object.showNextIndex.Value = true; flag3 = false; break; } } } if (flag3 && !__instance.home.indoors.Value.Objects.ContainsKey(__instance.getTileLocation())) { __instance.home.indoors.Value.Objects.Add(__instance.getTileLocation(), new SObject(Vector2.Zero, parentSheetIndex, null, false, true, false, true) { Quality = __instance.produceQuality.Value }); } } if (!flag1) { if (__instance.fullness.Value < 30) { __instance.moodMessage.Value = 4; } else if (__instance.happiness.Value < 30) { __instance.moodMessage.Value = 3; } else if (__instance.happiness.Value < 200) { __instance.moodMessage.Value = 2; } else { __instance.moodMessage.Value = 1; } } if (Game1.timeOfDay < 1700) { __instance.fullness.Value = (byte)Math.Max(0, __instance.fullness.Value - __instance.fullnessDrain.Value * (1700 - Game1.timeOfDay) / 100); } __instance.fullness.Value = 0; if (Utility.isFestivalDay(Game1.dayOfMonth, Game1.currentSeason)) { __instance.fullness.Value = 250; } __instance.reload(__instance.home); return(false); }
private static void FindAllInstances(object value, List <string> propNames, HashSet <object> exploredObjects, Dictionary <object, List <object> > found, object parent) { if (value == null || exploredObjects.Contains(value)) { return; } exploredObjects.Add(value); IDictionary dict = value as IDictionary; IList list = value as IList; ICollection col = value as ICollection; OverlaidDictionary ovd = value as OverlaidDictionary; NetObjectList <Item> noli = value as NetObjectList <Item>; NetCollection <Building> netBuildings = value as NetCollection <Building>; NetCollection <Furniture> netFurniture = value as NetCollection <Furniture>; NetArray <SObject, NetRef <SObject> > netObjectArray = value as NetArray <SObject, NetRef <SObject> >; NetVector2Dictionary <TerrainFeature, NetRef <TerrainFeature> > terrain = value as NetVector2Dictionary <TerrainFeature, NetRef <TerrainFeature> >; if (dict != null) { foreach (object item in dict.Keys) { if (dict[item] != null) { FindAllInstances(dict[item], propNames, exploredObjects, found, new KeyValuePair <IDictionary, object>(dict, item)); } } } else if (list != null) { foreach (object item in list) { FindAllInstances(item, propNames, exploredObjects, found, list); } } else if (col != null) { foreach (object item in col) { FindAllInstances(item, propNames, exploredObjects, found, col); } } else if (ovd != null) { foreach (Vector2 item in ovd.Keys) { if (ovd[item] != null) { FindAllInstances(ovd[item], propNames, exploredObjects, found, new KeyValuePair <OverlaidDictionary, object>(ovd, item)); } FindAllInstances(item, propNames, exploredObjects, found, ovd); } } else if (noli != null) { foreach (object item in noli) { FindAllInstances(item, propNames, exploredObjects, found, noli); } } else if (netBuildings != null) { foreach (object item in netBuildings) { FindAllInstances(item, propNames, exploredObjects, found, netBuildings); } } else if (netFurniture != null) { foreach (object item in netFurniture) { FindAllInstances(item, propNames, exploredObjects, found, netFurniture); } } else if (netObjectArray != null) { foreach (SObject item in netObjectArray.Where(no => no != null)) { FindAllInstances(item, propNames, exploredObjects, found, netObjectArray); } } else if (terrain != null) { var fd = terrain.FieldDict; foreach (var item in terrain.Keys.Where(v => terrain[v] != null && terrain[v] is ISaveElement || getDataString(terrain[v]).StartsWith(newPrefix))) { FindAllInstances(fd[item], propNames, exploredObjects, found, new KeyValuePair <IDictionary, object>(fd, item)); } } else { if (found.ContainsKey(parent)) { found[parent].Add(value); } else { found.Add(parent, new List <object>() { value }); } Type type = value.GetType(); FieldInfo[] fields; if (fieldInfoChache.ContainsKey(type)) { fields = fieldInfoChache[type]; } else { fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); fieldInfoChache.Add(type, fields); } foreach (FieldInfo field in fields.Where(f => propNames.Contains(f.Name))) { object propertyValue = field.GetValue(value); if (propertyValue != null && propertyValue.GetType() is Type ty && ty.IsClass) { FindAllInstances(propertyValue, propNames, exploredObjects, found, new KeyValuePair <FieldInfo, object>(field, value)); } } } }
// If the cat gave a gift, warp him next to it the first time the player enters the farm public void Warped(object sender, EventArgs e) { if (Game1.currentLocation is Farm && giftToday && !warpedToday) { foreach (NPC pet in Game1.getLocationFromName("Farm").getCharacters()) { if (pet is StardewValley.Characters.Cat || pet is StardewValley.Characters.Dog) { //this.Monitor.Log("Found pet for warping."); thePet = (StardewValley.Characters.Pet)pet; } } if (thePet != null) { if (thePet is StardewValley.Characters.Cat) { // Have a chance of Dusty digging up something instead of the cat if (Game1.currentLocation.characters.Contains(Game1.getCharacterFromName("Dusty", true)) && Game1.random.Next(1, 10) > 8) { this.DogSpawn(null, Game1.getCharacterFromName("Dusty", true)); } else { int x = (int)Game1.player.Position.X / 64; int y = (int)Game1.player.Position.Y / 64; // Spawn gift // Remove old gift if there's still one on the floor OverlaidDictionary obs = Game1.getLocationFromName("Farm").Objects; Vector2 spawnPos = new Vector2(x, y + 1); for (int i = 0; i < obs.Count(); i++) { Vector2 currentPos = obs.Keys.ElementAt(i); if (currentPos == spawnPos) { obs.Remove(obs.Keys.ElementAt(i)); } } Game1.getLocationFromName("Farm").dropObject(new StardewValley.Object(giftId, 1, false, -1, 0), spawnPos * 64f, Game1.viewport, true, (Farmer)null); // Warp cat // Check if field is free Vector2 warpPos = new Vector2(x + 1, y + 2); Vector2 safePos = new Vector2(x + 1, y + 2); // If field is free, warp cat there if (Game1.getLocationFromName("Farm").isTileLocationTotallyClearAndPlaceableIgnoreFloors(warpPos)) { //this.Monitor.Log(warpPos.X + "/" + warpPos.Y + " is free, warping cat there"); thePet.Position = warpPos * 64f; } else { // Otherwise, find a nearby free location. If we find one, warp the cat there. Otherwise, just don't warp. safePos = this.FindSafePosition(warpPos); if (safePos != warpPos) { thePet.Position = safePos * 64f; } } // this.Monitor.Log("Warped him."); warpedToday = true; Game1.playSound("cat"); } } if (thePet is StardewValley.Characters.Dog) { // Have a chance of Dusty digging something up instead of the dog if (Game1.currentLocation.characters.Contains(Game1.getCharacterFromName("Dusty", true)) && Game1.random.Next(1, 10) > 8) { this.DogSpawn(null, Game1.getCharacterFromName("Dusty", true)); } else { this.DogSpawn(thePet, null); } } String dog = ""; if (thePet is StardewValley.Characters.Dog) { dog = " Search your farm carefully to find it!"; isCat = false; } msgDisplayed = true; Helper.Content.InvalidateCache(@"LooseSprites\Cursors.xnb"); HUDMessage msg = new HUDMessage(thePet.Name + " brought you a gift." + dog, 1); Game1.addHUDMessage(msg); } //else //this.Monitor.Log("Didn't find the pet."); } }