Пример #1
0
 public static bool IsHarvestableBush(Bush bush)
 {
     return(bush != null && !bush.townBush.Value && bush.inBloom(Game1.GetSeasonForLocation(bush.currentLocation), Game1.dayOfMonth) && bush.size.Value != Bush.greenTeaBush && bush.size.Value != Bush.walnutBush);
 }
Пример #2
0
 internal static void ShakeBush(Bush bush, Vector2?tileLocation = null)
 {
     bush.performUseAction(tileLocation ?? Game1.player.getTileLocation() + new Vector2(0, -2), Game1.player.currentLocation);
 }
Пример #3
0
 public static Color GetColor(Bush b) 
     => Color.Lerp(Color.LightGreen, Color.DarkGreen, b.BerryFraction);
Пример #4
0
        /// <summary>SMAPI console command. Creates a new bush with the specified size.</summary>
        /// <param name="command">The console command's name.</param>
        /// <param name="args">The space-delimited arguments entered with the command.</param>
        public static void AddBush(string command, string[] args)
        {
            if (!Context.IsWorldReady) //if the player is not currently in a loaded game
            {
                return;                //do nothing
            }
            if (args.Length <= 0)      //"add_bush" (invalid)
            {
                ModEntry.Instance.Monitor.Log($"Invalid number of arguments. Please include a bush size, e.g. \"{command} {Bush.largeBush}\". Type \"help {command}\" for formatting information.", LogLevel.Info);
                return;
            }
            else if (args.Length == 2) //"add_bush <size> [x]" (invalid)
            {
                ModEntry.Instance.Monitor.Log($"Invalid number of arguments. Please include both X and Y, e.g. \"{command} {Bush.largeBush} 64 19\". Type \"help {command}\" for formatting information.", LogLevel.Info);
                return;
            }

            int?size = ParseBushSize(args[0]); //attempt to parse the size argument

            if (size == null)                  //if parsing failed
            {
                ModEntry.Instance.Monitor.Log($"\"{args[0]}\" is not a recognized bush size. Type \"help {command}\" for formatting information.", LogLevel.Info);
                return;
            }

            int x;
            int y;

            if (args.Length >= 3)                          //if x y arguments were provided
            {
                if (int.TryParse(args[1], out x) == false) //try to parse the x argument; if it fails,
                {
                    ModEntry.Instance.Monitor.Log($"\"{args[1]}\" could not be parsed as an integer (x). Type \"help {command}\" for formatting information.", LogLevel.Info);
                    return;
                }
                else if (int.TryParse(args[2], out y) == false) //try to parse the y argument; if it fails,
                {
                    ModEntry.Instance.Monitor.Log($"\"{args[2]}\" could not be parsed as an integer (y). Type \"help {command}\" for formatting information.", LogLevel.Info);
                    return;
                }
            }
            else //if x y arguments were NOT provided
            {
                //get the player's current tile position
                x = Game1.player.getTileX();
                y = Game1.player.getTileY();
            }

            GameLocation location;

            if (args.Length >= 4) //if a location argument was provided
            {
                //combine the remaining arguments into a single string
                string locationName = args[3];                    //get the first location argument
                for (int count = 4; count < args.Length; count++) //for each argument after args[3]
                {
                    locationName += " " + args[count];            //add this argument to the location name, separated by a space
                }

                location = Game1.getLocationFromName(locationName); //attempt to get a location with the combined name
                if (location == null)                               //if no location matched the name
                {
                    ModEntry.Instance.Monitor.Log($"No location named \"{locationName}\" could be found. Type \"help {command}\" for formatting information.", LogLevel.Info);
                    return;
                }
            }
            else
            {
                location = Game1.player.currentLocation; //use the player's current location
                if (location == null)                    //if the player's location was null
                {
                    return;                              //do nothing
                }
            }

            //all necessary information has been parsed

            Bush bush = new Bush(new Vector2(x, y), size.Value, location); //create the new bush

            Rectangle playerBox = Game1.player.GetBoundingBox();

            while (playerBox.Intersects(bush.getBoundingBox()))                                          //while this bush is colliding with the player
            {
                switch (Game1.player.FacingDirection)                                                    //based on which direction the player is facing
                {
                default:                                                                                 //unknown facing position (should be unreachable)
                case 0:                                                                                  //up
                    bush.tilePosition.Value = new Vector2(bush.tilePosition.X, bush.tilePosition.Y - 1); //move bush up 1 tile
                    break;

                case 1:                                                                                  //right
                    bush.tilePosition.Value = new Vector2(bush.tilePosition.X + 1, bush.tilePosition.Y); //move bush right 1 tile
                    break;

                case 2:                                                                                  //down
                    bush.tilePosition.Value = new Vector2(bush.tilePosition.X, bush.tilePosition.Y + 1); //move bush down 1 tile
                    break;

                case 3:                                                                                  //left
                    bush.tilePosition.Value = new Vector2(bush.tilePosition.X - 1, bush.tilePosition.Y); //move bush left 1 tile
                    break;
                }
            }

            location.largeTerrainFeatures.Add(bush); //add the bush to the location
        }
Пример #5
0
 /*********
 ** Private methods
 *********/
 /// <summary>Get whether the given bush produces berries.</summary>
 /// <param name="bush">The berry busy.</param>
 private bool IsBerryBush(Bush bush)
 {
     return(bush.size.Value == Bush.mediumBush && !bush.townBush.Value);
 }
Пример #6
0
        static void Main(string[] args)
        {
            string[] inputs;

            Strategy.myTeam = int.Parse(Console.ReadLine());

            int bushAndSpawnPointCount = int.Parse(Console.ReadLine()); // useful from wood1, represents the number of bushes and the number of places where neutral units can spawn

            for (int i = 0; i < bushAndSpawnPointCount; i++)
            {
                inputs = Console.ReadLine().Split(' ');
                string entityType = inputs[0]; // BUSH, from wood1 it can also be SPAWN
                int    x          = int.Parse(inputs[1]);
                int    y          = int.Parse(inputs[2]);
                int    radius     = int.Parse(inputs[3]);

                if (entityType == "BUSH")
                {
                    Bush newBush = new Bush();
                    newBush.pos         = new Vector(x, y, 0);
                    newBush.attackRange = radius;

                    Strategy.bushes.Add(newBush);
                }
            }

            int itemCount = int.Parse(Console.ReadLine()); // useful from wood2

            for (int i = 0; i < itemCount; i++)
            {
                inputs = Console.ReadLine().Split(' ');
                string itemName         = inputs[0];            // contains keywords such as BRONZE, SILVER and BLADE, BOOTS connected by "_" to help you sort easier
                int    itemCost         = int.Parse(inputs[1]); // BRONZE items have lowest cost, the most expensive items are LEGENDARY
                int    damage           = int.Parse(inputs[2]); // keyword BLADE is present if the most important item stat is damage
                int    health           = int.Parse(inputs[3]);
                int    maxHealth        = int.Parse(inputs[4]);
                int    mana             = int.Parse(inputs[5]);
                int    maxMana          = int.Parse(inputs[6]);
                int    moveSpeed        = int.Parse(inputs[7]); // keyword BOOTS is present if the most important item stat is moveSpeed
                int    manaRegeneration = int.Parse(inputs[8]);
                int    isPotion         = int.Parse(inputs[9]); // 0 if it's not instantly consumed

                Item newItem = new Item
                {
                    name      = itemName,
                    cost      = itemCost,
                    damage    = damage,
                    health    = health,
                    maxHealth = maxHealth,
                    mana      = mana,
                    maxMana   = maxMana,
                    speed     = moveSpeed,
                    manaRegen = manaRegeneration,
                    isPotion  = isPotion == 1,
                };

                Strategy.items.Add(itemName, newItem);

                newItem.CalculateItemValue();
                newItem.PrintStats();
            }

            // game loop
            while (true)
            {
                Game.NewRound();

                Strategy.myGold    = int.Parse(Console.ReadLine());
                Strategy.enemyGold = int.Parse(Console.ReadLine());

                int roundType = int.Parse(Console.ReadLine()); // a positive value will show the number of heroes that await a command


                int entityCount = int.Parse(Console.ReadLine());
                for (int i = 0; i < entityCount; i++)
                {
                    inputs = Console.ReadLine().Split(' ');
                    int    unitId           = int.Parse(inputs[0]);
                    int    team             = int.Parse(inputs[1]);
                    string unitType         = inputs[2]; // UNIT, HERO, TOWER, can also be GROOT from wood1
                    int    x                = int.Parse(inputs[3]);
                    int    y                = int.Parse(inputs[4]);
                    int    attackRange      = int.Parse(inputs[5]);
                    int    health           = int.Parse(inputs[6]);
                    int    maxHealth        = int.Parse(inputs[7]);
                    int    shield           = int.Parse(inputs[8]); // useful in bronze
                    int    attackDamage     = int.Parse(inputs[9]);
                    int    movementSpeed    = int.Parse(inputs[10]);
                    int    stunDuration     = int.Parse(inputs[11]); // useful in bronze
                    int    goldValue        = int.Parse(inputs[12]);
                    int    countDown1       = int.Parse(inputs[13]); // all countDown and mana variables are useful starting in bronze
                    int    countDown2       = int.Parse(inputs[14]);
                    int    countDown3       = int.Parse(inputs[15]);
                    int    mana             = int.Parse(inputs[16]);
                    int    maxMana          = int.Parse(inputs[17]);
                    int    manaRegeneration = int.Parse(inputs[18]);
                    string heroType         = inputs[19];            // DEADPOOL, VALKYRIE, DOCTOR_STRANGE, HULK, IRONMAN
                    int    isVisible        = int.Parse(inputs[20]); // 0 if it isn't
                    int    itemsOwned       = int.Parse(inputs[21]); // useful from wood1

                    Entity newUnit;

                    //UNIT, HERO, TOWER
                    if (unitType == "TOWER")
                    {
                        newUnit = new Tower();
                    }
                    else if (unitType == "GROOT")
                    {
                        newUnit = new Groot();
                    }
                    else if (unitType == "HERO")
                    {
                        newUnit = new Hero();

                        Hero newHero = newUnit as Hero;

                        newHero.cooldowns[0] = countDown1;
                        newHero.cooldowns[1] = countDown2;
                        newHero.cooldowns[2] = countDown3;

                        foreach (HeroType type in Enum.GetValues(typeof(HeroType)))
                        {
                            if (type.ToString() == heroType)
                            {
                                newHero.heroType = type;
                                break;
                            }
                        }

                        newHero.InitSpells();
                    }
                    else
                    {
                        newUnit = new Unit();
                    }

                    newUnit.id           = unitId;
                    newUnit.pos          = new Vector(x, y, 0);
                    newUnit.team         = Strategy.myTeam == team ? Team.Ally : Team.Enemy;
                    newUnit.attackRange  = attackRange;
                    newUnit.health       = health;
                    newUnit.maxHealth    = maxHealth;
                    newUnit.shield       = shield;
                    newUnit.damage       = attackDamage;
                    newUnit.speed        = movementSpeed;
                    newUnit.stunDuration = stunDuration;
                    newUnit.goldValue    = goldValue;

                    //countdown
                    newUnit.mana       = mana;
                    newUnit.maxMana    = maxMana;
                    newUnit.manaRegen  = manaRegeneration;
                    newUnit.isVisible  = isVisible == 1;
                    newUnit.itemsOwned = itemsOwned;

                    newUnit.isAlly    = Strategy.myTeam == team && team != -1;
                    newUnit.isEnemy   = Strategy.myTeam != team && team != -1;
                    newUnit.isNeutral = team == -1;

                    Strategy.allUnits.Add(newUnit.id, newUnit);

                    if (newUnit is Hero)
                    {
                        Strategy.allHeros.Add(newUnit as Hero);
                    }

                    if (newUnit.isAlly)
                    {
                        Strategy.allyUnits.Add(newUnit.id, newUnit);

                        if (newUnit is Hero)
                        {
                            Hero myHero = newUnit as Hero;

                            Strategy.myHeros.Add(myHero);

                            myHero.InitStrategy();
                        }
                        else if (newUnit is Tower)
                        {
                            Strategy.myTower = newUnit as Tower;
                        }
                        else if (newUnit is Unit)
                        {
                            Strategy.allyMinions.Add(newUnit);
                        }
                    }
                    else if (newUnit.isEnemy)
                    {
                        Strategy.enemyUnits.Add(newUnit.id, newUnit);

                        if (newUnit is Hero)
                        {
                            Hero hero = newUnit as Hero;

                            Strategy.enemyHeros.Add(hero);
                        }
                        else if (newUnit is Tower)
                        {
                            Strategy.enemyTower = newUnit as Tower;
                        }
                        else if (newUnit is Unit)
                        {
                            Strategy.enemyMinions.Add(newUnit);
                        }
                    }
                    else
                    {
                        Strategy.neutralUnits.Add(newUnit.id, newUnit);
                    }
                }

                Game.MakeMove(roundType);
            }
        }
        /// <summary>If this bush was destroyed, this adds it to this mod's "destroyed bushes" list. It also drops an amount of wood designated by this mod's config.json file settings.</summary>
        /// <param name="t">The <see cref="Tool"/> used on this bush.</param>
        /// <param name="tileLocation">The tile on which the tool is being used.</param>
        /// <param name="location">The location of the bush and tool.</param>
        /// <param name="__instance">The <see cref="Bush"/> on which a tool is being used.</param>
        /// <param name="__result">True if this bush was destroyed."/></param>
        public static void performToolAction_Postfix(Tool t, Vector2 tileLocation, GameLocation location, Bush __instance, bool __result)
        {
            try
            {
                if (__result)                      //if this bush was destroyed
                {
                    int  amountOfWood;             //the amount of wood this bush should drop
                    bool shouldRegrow = false;     //whether this bush should eventually be respawned

                    switch (__instance.size.Value) //based on the bush's size, set the amount of wood
                    {
                    case Bush.smallBush:
                        amountOfWood = ModEntry.Config?.AmountOfWoodDropped?.SmallBushes ?? 0;
                        shouldRegrow = true;
                        break;

                    case Bush.mediumBush:
                        amountOfWood = ModEntry.Config?.AmountOfWoodDropped?.MediumBushes ?? 0;
                        shouldRegrow = true;
                        break;

                    case Bush.largeBush:
                        amountOfWood = ModEntry.Config?.AmountOfWoodDropped?.LargeBushes ?? 0;
                        shouldRegrow = true;
                        break;

                    case Bush.greenTeaBush:
                        amountOfWood = ModEntry.Config?.AmountOfWoodDropped?.GreenTeaBushes ?? 0;
                        break;

                    default:
                        amountOfWood = 0;
                        break;
                    }

                    if (shouldRegrow)                                                                                                                      //if this bush should eventually be respawned
                    {
                        ModData.DestroyedBush destroyed = new ModData.DestroyedBush(location?.Name, __instance.tilePosition.Value, __instance.size.Value); //create a record of this bush

                        if (Context.IsMainPlayer)                                                                                                          //if this code is run by the main player
                        {
                            ModEntry.Data.DestroyedBushes.Add(destroyed);                                                                                  //add the record to the list of destroyed bushes
                        }
                        else //if this code is run by a multiplayer farmhand
                        {
                            ModEntry.Instance.Helper.Multiplayer.SendMessage //send the record to the main player
                            (
                                message: destroyed,
                                messageType: "DestroyedBush",
                                modIDs: new[] { ModEntry.Instance.ModManifest.UniqueID },
                                playerIDs: new[] { Game1.serverHost.Value.UniqueMultiplayerID }
                            );
                        }
                    }

                    if (amountOfWood > 0)                                                                //if this bush should drop any wood
                    {
                        if (t?.getLastFarmerToUse() is Farmer farmer && farmer.professions.Contains(12)) //if the player destroying this bush has the "Forester" profession
                        {
                            double multipliedWood = 1.25 * amountOfWood;                                 //increase wood by 25%
                            amountOfWood = (int)Math.Floor(multipliedWood);                              //update the amount of wood (round down)
                            if (multipliedWood > amountOfWood)                                           //if the multiplied wood had a decimal
                            {
                                multipliedWood -= amountOfWood;                                          //get the decimal amount of wood
                                if (Game1.random.NextDouble() < multipliedWood)                          //use the decimal as a random chance
                                {
                                    amountOfWood++;                                                      //add 1 wood
                                }
                            }
                        }

                        //drop the amount of wood at this bush's location
                        Game1.createRadialDebris(location, 12, (int)tileLocation.X, (int)tileLocation.Y, amountOfWood, true, -1, false, -1);
                    }
                }
            }
            catch (Exception ex)
            {
                ModEntry.Instance.Monitor.LogOnce($"Harmony patch \"{nameof(performToolAction_Postfix)}\" has encountered an error:\n{ex.ToString()}", LogLevel.Error);
            }
        }
Пример #8
0
        /// <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 override bool Apply(Vector2 tile, SObject tileObj, TerrainFeature tileFeature, Farmer player, Tool tool, Item item, GameLocation location)
        {
            // spawned forage
            if (this.TryHarvestForage(tileObj, location, tile, player))
            {
                return(true);
            }

            // crop or indoor pot
            if (this.TryGetHoeDirt(tileFeature, tileObj, out HoeDirt dirt, out bool dirtCoveredByObj, out IndoorPot pot))
            {
                // crop or spring onion (if an object like a scarecrow isn't placed on top of it)
                if (!dirtCoveredByObj && this.TryHarvestCrop(dirt, location, tile, player, tool))
                {
                    return(true);
                }

                // indoor pot bush
                if (this.TryHarvestBush(pot?.bush.Value, location))
                {
                    return(true);
                }
            }

            // machine
            if (this.TryHarvestMachine(tileObj))
            {
                return(true);
            }

            // fruit tree
            if (this.TryHarvestFruitTree(tileFeature as FruitTree, location, tile))
            {
                return(true);
            }

            // grass
            if (this.TryHarvestGrass(tileFeature as Grass, location, tile, tool))
            {
                return(true);
            }

            // weeds
            if (this.TryHarvestWeeds(tileObj, location, tile, player, tool))
            {
                return(true);
            }

            // bush
            Rectangle tileArea = this.GetAbsoluteTileArea(tile);

            if (this.Config.HarvestForage)
            {
                Bush bush = tileFeature as Bush ?? location.largeTerrainFeatures.FirstOrDefault(p => p.getBoundingBox(p.tilePosition.Value).Intersects(tileArea)) as Bush;
                if (this.TryHarvestBush(bush, location))
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #9
0
 /*********
 ** Private methods
 *********/
 /// <summary>Build a subject.</summary>
 /// <param name="bush">The entity to look up.</param>
 private ISubject BuildSubject(Bush bush)
 {
     return(new BushSubject(this.GameHelper, bush, this.Reflection));
 }
        /// <summary>Get whether a given bush should be chopped.</summary>
        /// <param name="bush">The bush to check.</param>
        private bool ShouldCut(Bush bush)
        {
            var config = this.Config;

            return(config.CutBushes);
        }