Ejemplo n.º 1
0
        private static void fakeOne(int harvestIndex, bool giantCrop,
                                    Farmer near = null)
        {
            near ??= Game1.player;
            GameLocation location = near.currentLocation;

            var tiles = Utility.recursiveFindOpenTiles(location,
                                                       near.getTileLocation(), 1, 100);

            if (tiles.Count == 0)
            {
                throw new Exception($"Could not find an open tile in {location.Name}.");
            }
            Vector2 tileLocation = tiles[0];

            Crop crop = Utilities.MakeNonceCrop(harvestIndex,
                                                Utility.Vector2ToPoint(tileLocation));

            TerrainFeature feature;

            if (giantCrop)
            {
                if (location is Farm farm)
                {
                    feature = new GiantCrop(harvestIndex, tileLocation);
                    farm.resourceClumps.Add(feature as ResourceClump);
                }
                else
                {
                    throw new Exception($"Cannot fake a Giant Cropbeast in {location.Name}.");
                }
            }
            else
            {
                feature = new HoeDirt(0, crop);
                location.terrainFeatures.Add(tileLocation, feature);
            }

            CropTile cropTile = new CropTile(feature, crop, giantCrop, location,
                                             Utility.Vector2ToPoint(tileLocation), fake: true);

            if (cropTile.state != CropTile.State.Available)
            {
                cropTile.cleanUpFake();
                throw new Exception($"Faked a {cropTile.logDescription} but it had no available cropbeast mapping.");
            }

            cropTile.choose();
            DelayedAction.functionAfterDelay(() => Spawner.Spawn(cropTile), 0);
        }
Ejemplo n.º 2
0
        // Chooses a crop tile to become a cropbeast.
        public virtual CropTile choose(bool console = false,
                                       bool force   = false, string filter = null)
        {
            // Use a predictable RNG seeded by game, day and time.
            Random rng = new Random((int)Game1.uniqueIDForThisGame / 2 +
                                    (int)Game1.stats.DaysPlayed + Game1.timeOfDay);

            // Choose the location to evaluate.
            GameLocation location = Game1.currentLocation;

            if (!(location.IsFarm && location.IsOutdoors) && !location.IsGreenhouse)
            {
                GameLocation farm       = Game1.getLocationFromName("Farm");
                GameLocation greenhouse = Game1.getLocationFromName("Greenhouse");
                if (farm != null && farm.farmers.Count() > 0)
                {
                    location = farm;
                }
                else if (greenhouse != null && greenhouse.farmers.Count() > 0)
                {
                    location = greenhouse;
                }
            }

            // Check preconditions unless forced.
            if (!force && !shouldChoose(rng, location, console: console))
            {
                return(null);
            }

            // Get the maximum distance on the current map for weighting use.
            var   mapLayer    = location.map.Layers[0];
            float mapDiagonal = Vector2.Distance(new Vector2(0, 0),
                                                 new Vector2(mapLayer.LayerWidth, mapLayer.LayerHeight));

            // Find all candidate crop tiles, sort pseudorandomly with
            // weighting based on type and towards those closer to a farmer.
            SortedList <double, CropTile> candidates =
                new SortedList <double, CropTile>
                    (findCandidateCropTiles(location, filter, console)
                    .ToDictionary((tile) =>
            {
                Utilities.FindNearestFarmer(tile.location, tile.tileLocation,
                                            out float distance);
                return(rng.NextDouble() * 1.5
                       - tile.mapping.choiceWeight
                       + distance / mapDiagonal * 2.0);
            }));

            // If the list is empty, give up.
            if (candidates.Count == 0)
            {
                Monitor.Log($"At {Game1.getTimeOfDayString (Game1.timeOfDay)}, {location.Name} met preconditions but had no candidate crops to become cropbeasts.",
                            console ? LogLevel.Warn : LogLevel.Trace);
                return(null);
            }

            // Choose the top of the list as the winner.
            CropTile winner = candidates.First().Value;

            Monitor.Log($"At {Game1.getTimeOfDayString (Game1.timeOfDay)}, chose {winner.logDescription} to become {winner.mapping.beastName}.",
                        console ? LogLevel.Info : LogLevel.Debug);

            // Record progress towards daily limit for location.
            if (location.IsOutdoors)
            {
                ++outdoorSpawnCount;
            }
            else
            {
                ++indoorSpawnCount;
            }

            // Make sure this tile isn't chosen again.
            chosenTiles[winner.tileLocation] = winner;
            winner.choose();

            return(winner);
        }