예제 #1
0
        public string CropTypeAt(JunimoHut hut, Vector2 pos)
        {
            if (Map is null)
            {
                return(null);
            }

            if (hut is null)
            {
                return(null);
            }

            int radius = BetterJunimos.Config.JunimoHuts.MaxRadius;

            int dx = (int)pos.X - hut.tileX.Value;
            int dy = (int)pos.Y - hut.tileY.Value;

            int mx = radius - 1 + dx;
            int my = radius - 1 + dy;


            string ct;

            try {
                ct = Map[mx, my];
            }
            catch (IndexOutOfRangeException) {
                // BetterJunimos.SMonitor.Log($"CropTypeAt: [{mx} {my}] out of bounds", LogLevel.Warn);
                ct = null;
            }

            // BetterJunimos.SMonitor.Log($"CropTypeAt: hut [{hut.tileX} {hut.tileY}] pos [{pos.X} {pos.Y}] radius {radius} d [{dx} {dy}] m [{mx} {my}]: {ct}", LogLevel.Debug);
            return(ct);
        }
 private static Point EndPointInFarm(JunimoHut hut, int radius)
 {
     return(Utility.Vector2ToPoint(
                new Vector2(
                    hut.tileX.Value + 1 + Game1.random.Next(-radius, radius + 1),
                    hut.tileY.Value + 1 + Game1.random.Next(-radius, radius + 1))));
 }
예제 #3
0
        public static void SpawnJunimoAtPosition(Vector2 pos, JunimoHut hut, int junimoNumber)
        {
            if (hut == null)
            {
                return;
            }
            Farm farm = Game1.getFarm();

            /*
             * Added by Mizzion. This will set the color of the junimos based on what gem is inside the hut.
             */
            bool  isPrismatic = false;
            Color?gemColor    = getGemColor(ref isPrismatic, hut);//Reflection.GetMethod(hut, "getGemColor").Invoke<Color>(isPrismatic);

            /*
             * End added By Mizzion
             */

            JunimoHarvester junimoHarvester = new JunimoHarvester(pos, hut, junimoNumber, gemColor);

            junimoHarvester.isPrismatic.Value = isPrismatic; //Added by Mizzion, Fixes the Prismatic Junimos.
            farm.characters.Add((NPC)junimoHarvester);
            hut.myJunimos.Add(junimoHarvester);

            if (Game1.isRaining)
            {
                var alpha = Reflection.GetField <float>(junimoHarvester, "alpha");
                alpha.SetValue(Config.FunChanges.RainyJunimoSpiritFactor);
            }
            if (!Utility.isOnScreen(Utility.Vector2ToPoint(pos), 64, farm))
            {
                return;
            }
            farm.playSound("junimoMeep1");
        }
        public static void Postfix(JunimoHut __instance, GameTime time, int __state)
        {
            var junimoSendOutTimer = Util.Reflection.GetField <int>(__instance, "junimoSendOutTimer");
            int sendOutTimer       = __state;

            // from Update
            junimoSendOutTimer.SetValue(sendOutTimer - time.ElapsedGameTime.Milliseconds);
            if (sendOutTimer > 0 || __instance.myJunimos.Count() >= Util.Config.JunimoHuts.MaxJunimos ||
                !__instance.areThereMatureCropsWithinRadius() || Game1.farmEvent != null)
            {
                return;
            }
            // Winter
            if (Game1.IsWinter && !Util.Config.JunimoImprovements.CanWorkInWinter)
            {
                return;
            }
            // Rain
            if (Game1.isRaining && !Util.Config.JunimoImprovements.CanWorkInRain)
            {
                return;
            }

            Util.SpawnJunimoAtHut(__instance);
            junimoSendOutTimer.SetValue(1000);
        }
        // This is to prevent the update function from running, other than base.Update()
        // Capture sendOutTimer and use to stop execution
        public static void Prefix(JunimoHut __instance, int __state)
        {
            var junimoSendOutTimer = Util.Reflection.GetField <int>(__instance, "junimoSendOutTimer");

            __state = junimoSendOutTimer.GetValue();
            junimoSendOutTimer.SetValue(0);
        }
예제 #6
0
        // search for crops + open plantable spots
        private static bool SearchAroundHut(JunimoHut hut)
        {
            var          id     = Util.GetHutIdFromHut(hut);
            var          radius = Util.CurrentWorkingRadius;
            GameLocation farm   = Game1.getFarm();

            // SearchHutGrid manages hut.lastKnownCropLocation and Util.Abilities.lastKnownCropLocations
            var foundWork = SearchHutGrid(hut, radius, farm, id);

            if (BetterJunimos.Config.JunimoImprovements.CanWorkInGreenhouse)
            {
                var ghb = Util.Greenhouse.GreenhouseBuildingNearHut(id);
                var gh  = Game1.getLocationFromName("Greenhouse");

                if (!Util.Greenhouse.HutHasGreenhouse(id))
                {
                    // BetterJunimos.SMonitor.Log($"PatchSearchAroundHut: hut has no greenhouse", LogLevel.Debug);
                    return(foundWork);
                }
                // SearchGreenhouseGrid manages hut.lastKnownCropLocation (a hack!) and Util.Abilities.lastKnownCropLocations
                foundWork |= SearchGreenhouseGrid(hut, id);
                Util.Abilities.lastKnownCropLocations.TryGetValue((hut, gh), out var lkc);

                // BetterJunimos.SMonitor.Log($"PatchSearchAroundHut: greenhouse lkc {lkc.X} {lkc.Y}", LogLevel.Trace);
            }

            // BetterJunimos.SMonitor.Log($"PatchSearchAroundHut: foundWork {foundWork}", LogLevel.Trace);
            return(foundWork);
        }
예제 #7
0
 public static bool Prefix(JunimoHut __instance, ref int __result)
 {
     for (int index = 0; index < Util.Config.JunimoHuts.MaxJunimos; ++index)
     {
         if (index >= __instance.myJunimos.Count())
         {
             __result = index;
             return(false);
         }
         bool flag = false;
         foreach (JunimoHarvester junimo in __instance.myJunimos)
         {
             if (junimo.whichJunimoFromThisHut == index)
             {
                 flag = true;
                 break;
             }
         }
         if (!flag)
         {
             __result = index;
             return(false);
         }
     }
     __result = 2;
     return(false);
 }
예제 #8
0
        internal void UpdateHutItems(Guid id)
        {
            JunimoHut hut   = Util.GetHutFromId(id);
            Chest     chest = hut.output.Value;

            UpdateHutContainsItems(id, chest, RequiredItems.ToList <int>());
        }
예제 #9
0
        public static void SpawnJunimoAtHut(JunimoHut hut)
        {
            // I don't know why we're multiplying by 64 here
            var pos = new Vector2((float)hut.tileX.Value + 1, (float)hut.tileY.Value + 1) * 64f + new Vector2(0.0f, 32f);

            SpawnJunimoAtPosition(Game1.getFarm(), pos, hut, hut.getUnusedJunimoNumber());
        }
예제 #10
0
        // search for crops + open plantable spots
        internal static bool searchAroundHut(JunimoHut hut)
        {
            Guid id     = Util.GetHutIdFromHut(hut);
            int  radius = Util.MaxRadius;

            for (int x = hut.tileX.Value + 1 - radius; x < hut.tileX.Value + 2 + radius; ++x)
            {
                for (int y = hut.tileY.Value + 1 - radius; y < hut.tileY.Value + 2 + radius; ++y)
                {
                    // skip if we find the same lastKnownCropLocation twice
                    if (x == hut.lastKnownCropLocation.X && y == hut.lastKnownCropLocation.Y)
                    {
                        continue;
                    }
                    Vector2        pos     = new Vector2((float)x, (float)y);
                    IJunimoAbility ability = Util.Abilities.IdentifyJunimoAbility(pos, id);
                    if (ability != null)
                    {
                        hut.lastKnownCropLocation = new Point(x, y);
                        return(true);
                    }
                }
            }
            hut.lastKnownCropLocation = Point.Zero;
            return(false);
        }
예제 #11
0
        /*
         * Added by Mizzion. This method is used to get the gem color, so the junimos can be colored
         * I ripped this from SDV and edited it to work with this mod.
         */
        public static Color?getGemColor(ref bool isPrismatic, JunimoHut hut)
        {
            List <Color> colorList = new List <Color>();
            Chest        chest     = hut.output.Value;

            foreach (Item dye_object in chest.items)
            {
                if (dye_object != null && (dye_object.Category == MineralCategory || dye_object.Category == GemCategory))
                {
                    Color?dyeColor = TailoringMenu.GetDyeColor(dye_object);
                    if (dye_object.Name == "Prismatic Shard")
                    {
                        isPrismatic = true;
                    }
                    if (dyeColor.HasValue)
                    {
                        colorList.Add(dyeColor.Value);
                    }
                }
            }
            if (colorList.Count > 0)
            {
                return(new Color?(colorList[Game1.random.Next(colorList.Count)]));
            }
            return(new Color?());
        }
예제 #12
0
        // This is to prevent the update function from running, other than base.Update()
        // Capture sendOutTimer and use to stop execution
        public static void Prefix(JunimoHut __instance, ref int ___junimoSendOutTimer, ref int __state)
        {
            int timer = ___junimoSendOutTimer;

            __state = timer;
            ___junimoSendOutTimer = 0;
        }
예제 #13
0
 private static void CheckForProgressionItems(JunimoHut hut)
 {
     if (!Config.Progression.Enabled)
     {
         return;
     }
     Util.Progression.ReceiveProgressionItems(hut);
 }
예제 #14
0
 internal static bool ShouldPlantFruitTreeOnTile(GameLocation location, JunimoHut hut, Vector2 pos)
 {
     if (Util.BlocksDoor(location, hut, pos))
     {
         return(false);
     }
     return(IsTileInPattern(pos) && CanPlantFruitTreeOnTile(location, pos));
 }
예제 #15
0
        internal void UpdateHutItems(Guid id)
        {
            JunimoHut hut   = Util.GetHutFromId(id);
            Chest     chest = hut.output.Value;

            UpdateHutContainsItemCategory(id, chest, SObject.fertilizerCategory);
            UpdateHutContainsItemCategory(id, chest, SObject.SeedsCategory);
        }
예제 #16
0
 private void CheckForWages(JunimoHut hut)
 {
     if (!Util.Payments.WereJunimosPaidToday && Util.Payments.ReceivePaymentItems(hut))
     {
         Util.Payments.WereJunimosPaidToday = true;
         Util.MaxRadius = Config.JunimoHuts.MaxRadius;
         Util.SendMessage("Junimos are happy with their payment!");
     }
 }
예제 #17
0
        public static void Postfix(JunimoHarvester __instance)
        {
            JunimoHut hut    = Util.GetHutFromId(Util.GetHutIdFromJunimo(__instance));
            int       radius = Util.MaxRadius;

            __instance.controller = new PathFindController(__instance, __instance.currentLocation, Utility.Vector2ToPoint(
                                                               new Vector2((float)(hut.tileX.Value + 1 + Game1.random.Next(-radius, radius + 1)), (float)(hut.tileY.Value + 1 + Game1.random.Next(-radius, radius + 1)))),
                                                           -1, new PathFindController.endBehavior(__instance.reachFirstDestinationFromHut), 100);
        }
예제 #18
0
        internal void ClearCropMapForHut(JunimoHut hut)
        {
            var pos = new Vector2(hut.tileX.Value, hut.tileY.Value);

            if (HutCropMap.ContainsKey(pos))
            {
                HutCropMap.Remove(pos);
            }
        }
        // is this tile plantable?
        internal static bool ShouldPlantWildTreeHere(GameLocation location, JunimoHut hut, Vector2 pos)
        {
            if (Util.BlocksDoor(location, hut, pos))
            {
                return(false);
            }

            // is this tile in the planting pattern?
            return(IsTileInPattern(pos) && Plantable(location, pos));
        }
예제 #20
0
        public static void Postfix(JunimoHut __instance, ref int ___junimoSendOutTimer)
        {
            int time = Util.Progression.CanWorkInEvenings ? 2400 : 1900;

            if (__instance.myJunimos.Count() < Util.Progression.MaxJunimosUnlocked &&
                Game1.timeOfDay < time)
            {
                ___junimoSendOutTimer = 1;
            }
        }
예제 #21
0
        public static void Postfix(JunimoHut __instance, ref int ___junimoSendOutTimer)
        {
            int time = Util.Config.JunimoImprovements.CanWorkInEvenings ? 2400 : 1900;

            if (__instance.myJunimos.Count() < Util.Config.JunimoHuts.MaxJunimos &&
                Game1.timeOfDay < time)
            {
                ___junimoSendOutTimer = 1;
            }
        }
예제 #22
0
        public bool ReceivePaymentItems(JunimoHut hut)
        {
            Farm  farm        = Game1.getFarm();
            Chest chest       = hut.output.Value;
            bool  paidForage  = ReceiveItems(chest, Payment.DailyWage.ForagedItems, Util.ForageCategory);
            bool  paidFlowers = ReceiveItems(chest, Payment.DailyWage.Flowers, Util.FlowerCategory);
            bool  paidFruit   = ReceiveItems(chest, Payment.DailyWage.Fruit, Util.FruitCategory);
            bool  paidWine    = ReceiveItems(chest, Payment.DailyWage.Wine, Util.WineCategory);

            return(paidForage && paidFlowers && paidFruit && paidWine);
        }
예제 #23
0
        public void UpdateHutContainsItemCategory(Guid id, int itemCategory)
        {
            JunimoHut            hut   = Util.GetHutFromId(id);
            NetObjectList <Item> chest = hut.output.Value.items;

            if (!ItemsInHuts.ContainsKey(id))
            {
                ItemsInHuts.Add(id, new Dictionary <int, bool>());
            }
            ItemsInHuts[id][itemCategory] = chest.Any(item => item.category == itemCategory);
        }
예제 #24
0
        public bool ReceivePaymentItems(JunimoHut hut)
        {
            Farm  farm        = Game1.getFarm();
            Chest chest       = hut.output.Value;
            bool  paidForage  = ReceiveItems(chest, Payment.DailyWage.ForagedItems, "Forage");
            bool  paidFlowers = ReceiveItems(chest, Payment.DailyWage.Flowers, "Flower");
            bool  paidFruit   = ReceiveItems(chest, Payment.DailyWage.Fruit, "Fruit");
            bool  paidWine    = ReceiveItems(chest, Payment.DailyWage.Wine, "Artisan Goods");

            return(paidForage && paidFlowers && paidFruit && paidWine);
        }
예제 #25
0
        public JunimoHarvester(Vector2 position, JunimoHut myHome, int whichJunimoNumberFromThisHut, Color?c)
            : base(new AnimatedSprite("Characters\\Junimo", 0, 16, 16), position, 2, "Junimo")
        {
            home = myHome;
            whichJunimoFromThisHut = whichJunimoNumberFromThisHut;
            if (!c.HasValue)
            {
                pickColor();
            }
            else
            {
                color.Value = c.Value;
            }
            nextPosition     = GetBoundingBox();
            base.Breather    = false;
            base.speed       = 3;
            forceUpdateTimer = 9999;
            collidesWithOtherCharacters.Value = true;
            ignoreMovementAnimation           = true;
            farmerPassesThrough = true;
            base.Scale          = 0.75f;
            base.willDestroyObjectsUnderfoot = false;
            base.currentLocation             = Game1.getFarm();
            Vector2 tileToPathfindTo = Vector2.Zero;

            switch (whichJunimoNumberFromThisHut)
            {
            case 0:
                tileToPathfindTo = Utility.recursiveFindOpenTileForCharacter(this, base.currentLocation, new Vector2((int)home.tileX + 1, (int)home.tileY + (int)home.tilesHigh + 1), 30);
                break;

            case 1:
                tileToPathfindTo = Utility.recursiveFindOpenTileForCharacter(this, base.currentLocation, new Vector2((int)home.tileX - 1, (int)home.tileY), 30);
                break;

            case 2:
                tileToPathfindTo = Utility.recursiveFindOpenTileForCharacter(this, base.currentLocation, new Vector2((int)home.tileX + (int)home.tilesWide, (int)home.tileY), 30);
                break;
            }
            if (tileToPathfindTo != Vector2.Zero)
            {
                controller = new PathFindController(this, base.currentLocation, Utility.Vector2ToPoint(tileToPathfindTo), -1, reachFirstDestinationFromHut, 100);
            }
            if ((controller == null || controller.pathToEndPoint == null) && Game1.IsMasterGame)
            {
                pathfindToRandomSpotAroundHut();
                if (controller == null || controller.pathToEndPoint == null)
                {
                    destroy = true;
                }
            }
            collidesWithOtherCharacters.Value = false;
        }
예제 #26
0
        public static bool Prefix(JunimoHut __instance, ref bool __result)
        {
            // Prevent unnecessary searching when unpaid
            if (Util.Config.JunimoPayment.WorkForWages && !Util.Payments.WereJunimosPaidToday)
            {
                __instance.lastKnownCropLocation = Point.Zero;
                return(false);
            }

            __result = searchAroundHut(__instance);
            return(false);
        }
예제 #27
0
        public void ReceiveProgressionItems(JunimoHut hut)
        {
            var chest = hut.output.Value;

            foreach (var ability in Progressions().Where(LockedAndPrompted))
            {
                if (!ReceiveItems(chest, ability))
                {
                    continue;
                }
                SetUnlocked(ability);
                Util.SendMessage(GetSuccessText(ability));
            }
        }
        public static void Postfix(JunimoHarvester __instance, ref NetGuid ___netHome)
        {
            JunimoHut hut    = Util.GetHutFromId(___netHome.Value);
            int       radius = Util.MaxRadius;
            int       retry  = 0;

            do
            {
                __instance.controller = new PathFindController(__instance, __instance.currentLocation, Utility.Vector2ToPoint(
                                                                   new Vector2((float)(hut.tileX.Value + 1 + Game1.random.Next(-radius, radius + 1)), (float)(hut.tileY.Value + 1 + Game1.random.Next(-radius, radius + 1)))),
                                                               -1, new PathFindController.endBehavior(__instance.reachFirstDestinationFromHut), 100);
                retry++;
            } while (retry <= 5 && (__instance.controller == null || __instance.controller.pathToEndPoint == null));
        }
예제 #29
0
        public static void AddItemToHut(Guid id, SObject item)
        {
            JunimoHut hut = GetHutFromId(id);
            Item      obj = hut.output.Value.addItem(item);

            if (obj == null)
            {
                return;
            }
            for (int index = 0; index < obj.Stack; ++index)
            {
                Game1.createObjectDebris(item.parentSheetIndex, hut.tileX + 1, hut.tileY + 1, -1, item.quality, 1f, Game1.getFarm());
            }
        }
예제 #30
0
 private static void CheckForWages(JunimoHut hut)
 {
     if (!Config.JunimoPayment.WorkForWages)
     {
         return;
     }
     if (Util.Payments.WereJunimosPaidToday)
     {
         return;
     }
     if (Util.Payments.ReceivePaymentItems(hut))
     {
         Util.Payments.WereJunimosPaidToday = true;
     }
 }