public void draw(SpriteBatch b, FarmerSprite.AnimationFrame animationFrame, int currentFrame, Rectangle sourceRect, Vector2 position, Vector2 origin, float layerDepth, int facingDirection, Color overrideColor, float rotation, float scale, Farmer who)
        {
            bool sick_frame = currentFrame == 104 || currentFrame == 105;

            if (_sickFrame != sick_frame)
            {
                _sickFrame   = sick_frame;
                _shirtDirty  = true;
                _spriteDirty = true;
            }
            executeRecolorActions(who);
            position           = new Vector2((float)Math.Floor(position.X), (float)Math.Floor(position.Y));
            rotationAdjustment = Vector2.Zero;
            positionOffset.Y   = animationFrame.positionOffset * 4;
            positionOffset.X   = animationFrame.xOffset * 4;
            if (!isDrawingForUI && (bool)who.swimming)
            {
                sourceRect.Height /= 2;
                sourceRect.Height -= (int)who.yOffset / 4;
                position.Y        += 64f;
            }
            if (facingDirection == 3 || facingDirection == 1)
            {
                facingDirection = ((!animationFrame.flip) ? 1 : 3);
            }
            b.Draw(baseTexture, position + origin + positionOffset, sourceRect, overrideColor, rotation, origin, 4f * scale, animationFrame.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, layerDepth);
            if (!isDrawingForUI && (bool)who.swimming)
            {
                if (who.currentEyes != 0 && who.FacingDirection != 0 && (Game1.timeOfDay < 2600 || (who.isInBed.Value && who.timeWentToBed.Value != 0)) && (!who.FarmerSprite.PauseForSingleAnimation || (who.UsingTool && who.CurrentTool is FishingRod)))
                {
                    b.Draw(baseTexture, position + origin + positionOffset + new Vector2(featureXOffsetPerFrame[currentFrame] * 4 + 20 + ((who.FacingDirection == 1) ? 12 : ((who.FacingDirection == 3) ? 4 : 0)), featureYOffsetPerFrame[currentFrame] * 4 + 40), new Rectangle(5, 16, (who.FacingDirection == 2) ? 6 : 2, 2), overrideColor, 0f, origin, 4f * scale, SpriteEffects.None, layerDepth + 5E-08f);
                    b.Draw(baseTexture, position + origin + positionOffset + new Vector2(featureXOffsetPerFrame[currentFrame] * 4 + 20 + ((who.FacingDirection == 1) ? 12 : ((who.FacingDirection == 3) ? 4 : 0)), featureYOffsetPerFrame[currentFrame] * 4 + 40), new Rectangle(264 + ((who.FacingDirection == 3) ? 4 : 0), 2 + (who.currentEyes - 1) * 2, (who.FacingDirection == 2) ? 6 : 2, 2), overrideColor, 0f, origin, 4f * scale, SpriteEffects.None, layerDepth + 1.2E-07f);
                }
                drawHairAndAccesories(b, facingDirection, who, position, origin, scale, currentFrame, rotation, overrideColor, layerDepth);
                b.Draw(Game1.staminaRect, new Rectangle((int)position.X + (int)who.yOffset + 8, (int)position.Y - 128 + sourceRect.Height * 4 + (int)origin.Y - (int)who.yOffset, sourceRect.Width * 4 - (int)who.yOffset * 2 - 16, 4), Game1.staminaRect.Bounds, Color.White * 0.75f, 0f, Vector2.Zero, SpriteEffects.None, layerDepth + 0.001f);
                return;
            }
            Rectangle pants_rect = new Rectangle(sourceRect.X, sourceRect.Y, sourceRect.Width, sourceRect.Height);

            pants_rect.X += ClampPants(who.GetPantsIndex()) % 10 * 192;
            pants_rect.Y += ClampPants(who.GetPantsIndex()) / 10 * 688;
            if (!who.IsMale)
            {
                pants_rect.X += 96;
            }
            b.Draw(pantsTexture, position + origin + positionOffset, pants_rect, overrideColor.Equals(Color.White) ? Utility.MakeCompletelyOpaque(who.GetPantsColor()) : overrideColor, rotation, origin, 4f * scale, animationFrame.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, layerDepth + ((who.FarmerSprite.CurrentAnimationFrame.frame == 5) ? 0.00092f : 9.2E-08f));
            sourceRect.Offset(288, 0);
            FishingRod fishing_rod;

            if (who.currentEyes != 0 && facingDirection != 0 && (Game1.timeOfDay < 2600 || (who.isInBed.Value && who.timeWentToBed.Value != 0)) && (!who.FarmerSprite.PauseForSingleAnimation || (who.UsingTool && who.CurrentTool is FishingRod)) && (!who.UsingTool || (fishing_rod = who.CurrentTool as FishingRod) == null || fishing_rod.isFishing))
            {
                int x_adjustment = 5;
                x_adjustment = (animationFrame.flip ? (x_adjustment - featureXOffsetPerFrame[currentFrame]) : (x_adjustment + featureXOffsetPerFrame[currentFrame]));
                switch (facingDirection)
                {
                case 1:
                    x_adjustment += 3;
                    break;

                case 3:
                    x_adjustment++;
                    break;
                }
                x_adjustment *= 4;
                b.Draw(baseTexture, position + origin + positionOffset + new Vector2(x_adjustment, featureYOffsetPerFrame[currentFrame] * 4 + ((who.IsMale && who.FacingDirection != 2) ? 36 : 40)), new Rectangle(5, 16, (facingDirection == 2) ? 6 : 2, 2), overrideColor, 0f, origin, 4f * scale, SpriteEffects.None, layerDepth + 5E-08f);
                b.Draw(baseTexture, position + origin + positionOffset + new Vector2(x_adjustment, featureYOffsetPerFrame[currentFrame] * 4 + ((who.FacingDirection == 1 || who.FacingDirection == 3) ? 40 : 44)), new Rectangle(264 + ((facingDirection == 3) ? 4 : 0), 2 + (who.currentEyes - 1) * 2, (facingDirection == 2) ? 6 : 2, 2), overrideColor, 0f, origin, 4f * scale, SpriteEffects.None, layerDepth + 1.2E-07f);
            }
            drawHairAndAccesories(b, facingDirection, who, position, origin, scale, currentFrame, rotation, overrideColor, layerDepth);
            float arm_layer_offset = 4.9E-05f;

            if (facingDirection == 0)
            {
                arm_layer_offset = -1E-07f;
            }
            sourceRect.Offset(-288 + (animationFrame.secondaryArm ? 192 : 96), 0);
            b.Draw(baseTexture, position + origin + positionOffset + who.armOffset, sourceRect, overrideColor, rotation, origin, 4f * scale, animationFrame.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, layerDepth + arm_layer_offset);
            if (!who.usingSlingshot || !(who.CurrentTool is Slingshot))
            {
                return;
            }
            Slingshot slingshot        = who.CurrentTool as Slingshot;
            Point     point            = Utility.Vector2ToPoint(slingshot.AdjustForHeight(Utility.PointToVector2(slingshot.aimPos.Value)));
            int       mouseX           = point.X;
            int       y                = point.Y;
            int       backArmDistance  = slingshot.GetBackArmDistance(who);
            Vector2   shoot_origin     = slingshot.GetShootOrigin(who);
            float     frontArmRotation = (float)Math.Atan2((float)y - shoot_origin.Y, (float)mouseX - shoot_origin.X) + (float)Math.PI;

            if (!Game1.options.useLegacySlingshotFiring)
            {
                frontArmRotation -= (float)Math.PI;
                if (frontArmRotation < 0f)
                {
                    frontArmRotation += (float)Math.PI * 2f;
                }
            }
            switch (facingDirection)
            {
            case 0:
                b.Draw(baseTexture, position + new Vector2(4f + frontArmRotation * 8f, -44f), new Rectangle(173, 238, 9, 14), Color.White, 0f, new Vector2(4f, 11f), 4f * scale, SpriteEffects.None, layerDepth + ((facingDirection != 0) ? 5.9E-05f : (-0.0005f)));
                break;

            case 1:
            {
                b.Draw(baseTexture, position + new Vector2(52 - backArmDistance, -32f), new Rectangle(147, 237, 10, 4), Color.White, 0f, new Vector2(8f, 3f), 4f * scale, SpriteEffects.None, layerDepth + ((facingDirection != 0) ? 5.9E-05f : 0f));
                b.Draw(baseTexture, position + new Vector2(36f, -44f), new Rectangle(156, 244, 9, 10), Color.White, frontArmRotation, new Vector2(0f, 3f), 4f * scale, SpriteEffects.None, layerDepth + ((facingDirection != 0) ? 1E-08f : 0f));
                int slingshotAttachX = (int)(Math.Cos(frontArmRotation + (float)Math.PI / 2f) * (double)(20 - backArmDistance - 8) - Math.Sin(frontArmRotation + (float)Math.PI / 2f) * -68.0);
                int slingshotAttachY = (int)(Math.Sin(frontArmRotation + (float)Math.PI / 2f) * (double)(20 - backArmDistance - 8) + Math.Cos(frontArmRotation + (float)Math.PI / 2f) * -68.0);
                Utility.drawLineWithScreenCoordinates((int)(position.X + 52f - (float)backArmDistance), (int)(position.Y - 32f - 4f), (int)(position.X + 32f + (float)(slingshotAttachX / 2)), (int)(position.Y - 32f - 12f + (float)(slingshotAttachY / 2)), b, Color.White);
                break;
            }

            case 3:
            {
                b.Draw(baseTexture, position + new Vector2(40 + backArmDistance, -32f), new Rectangle(147, 237, 10, 4), Color.White, 0f, new Vector2(9f, 4f), 4f * scale, SpriteEffects.FlipHorizontally, layerDepth + ((facingDirection != 0) ? 5.9E-05f : 0f));
                b.Draw(baseTexture, position + new Vector2(24f, -40f), new Rectangle(156, 244, 9, 10), Color.White, frontArmRotation + (float)Math.PI, new Vector2(8f, 3f), 4f * scale, SpriteEffects.FlipHorizontally, layerDepth + ((facingDirection != 0) ? 1E-08f : 0f));
                int slingshotAttachX = (int)(Math.Cos(frontArmRotation + (float)Math.PI * 2f / 5f) * (double)(20 + backArmDistance - 8) - Math.Sin(frontArmRotation + (float)Math.PI * 2f / 5f) * -68.0);
                int slingshotAttachY = (int)(Math.Sin(frontArmRotation + (float)Math.PI * 2f / 5f) * (double)(20 + backArmDistance - 8) + Math.Cos(frontArmRotation + (float)Math.PI * 2f / 5f) * -68.0);
                Utility.drawLineWithScreenCoordinates((int)(position.X + 4f + (float)backArmDistance), (int)(position.Y - 32f - 8f), (int)(position.X + 26f + (float)slingshotAttachX * 4f / 10f), (int)(position.Y - 32f - 8f + (float)slingshotAttachY * 4f / 10f), b, Color.White);
                break;
            }

            case 2:
                b.Draw(baseTexture, position + new Vector2(4f, -32 - backArmDistance / 2), new Rectangle(148, 244, 4, 4), Color.White, 0f, Vector2.Zero, 4f * scale, SpriteEffects.None, layerDepth + ((facingDirection != 0) ? 5.9E-05f : 0f));
                Utility.drawLineWithScreenCoordinates((int)(position.X + 16f), (int)(position.Y - 28f - (float)(backArmDistance / 2)), (int)(position.X + 44f - frontArmRotation * 10f), (int)(position.Y - 16f - 8f), b, Color.White);
                Utility.drawLineWithScreenCoordinates((int)(position.X + 16f), (int)(position.Y - 28f - (float)(backArmDistance / 2)), (int)(position.X + 56f - frontArmRotation * 10f), (int)(position.Y - 16f - 8f), b, Color.White);
                b.Draw(baseTexture, position + new Vector2(44f - frontArmRotation * 10f, -16f), new Rectangle(167, 235, 7, 9), Color.White, 0f, new Vector2(3f, 5f), 4f * scale, SpriteEffects.None, layerDepth + ((facingDirection != 0) ? 5.9E-05f : 0f));
                break;
            }
        }
        public static bool PerformFire_Prefix(Slingshot __instance, ref GameLocation location, ref Farmer who)
        {
            if (__instance != null &&
                (__instance.hasEnchantmentOfType <Enchantments.PreservingEnchantment>() ||
                 __instance.hasEnchantmentOfType <SwiftEnchantment>()))
            {
                AccessTools.FieldRef <Slingshot, NetPoint> aimPos       = AccessTools.FieldRefAccess <Slingshot, NetPoint>("aimPos");
                AccessTools.FieldRef <Slingshot, bool>     canPlaySound = AccessTools.FieldRefAccess <Slingshot, bool>("canPlaySound");
                var updateAimPosMethod = typeof(Slingshot).GetMethod("updateAimPos", BindingFlags.NonPublic | BindingFlags.Instance);

                if (__instance.attachments[0] != null)
                {
                    updateAimPosMethod.Invoke(__instance, null);
                    int     mouseX          = aimPos(__instance).X;
                    int     mouseY          = aimPos(__instance).Y;
                    int     backArmDistance = __instance.GetBackArmDistance(who);
                    Vector2 shoot_origin    = __instance.GetShootOrigin(who);
                    Vector2 v = Utility.getVelocityTowardPoint(__instance.GetShootOrigin(who), __instance.AdjustForHeight(new Vector2(mouseX, mouseY)), (15 + Game1.random.Next(4, 6)) * (1f + who.weaponSpeedModifier));
                    if (backArmDistance > 4 && !canPlaySound(__instance))
                    {
                        StardewValley.Object ammunition = (StardewValley.Object)__instance.attachments[0].getOne();
                        if (__instance.hasEnchantmentOfType <Enchantments.PreservingEnchantment>() && Game1.random.NextDouble() < 0.5)
                        {
                            __instance.attachments[0].Stack--;
                        }

                        if (__instance.attachments[0].Stack <= 0)
                        {
                            __instance.attachments[0] = null;
                        }

                        int damage = 1;
                        BasicProjectile.onCollisionBehavior collisionBehavior = null;
                        string collisionSound = "hammer";

                        float damageMod = 1f;
                        if (__instance.InitialParentTileIndex == 33)
                        {
                            damageMod = 2f;
                        }
                        else if (__instance.InitialParentTileIndex == 34)
                        {
                            damageMod = 3f;                                                                         //new damage
                        }
                        else if (__instance.InitialParentTileIndex == ModEntry.Instance.config.InfinitySlingshotId) //Infinity Sling
                        {
                            damageMod = 4f;
                        }

                        switch (ammunition.ParentSheetIndex)
                        {
                        case 388:
                            damage = 2;
                            ammunition.ParentSheetIndex++;
                            break;

                        case 390:
                            damage = 5;
                            ammunition.ParentSheetIndex++;
                            break;

                        case 378:
                            damage = 10;
                            ammunition.ParentSheetIndex++;
                            break;

                        case 380:
                            damage = 20;
                            ammunition.ParentSheetIndex++;
                            break;

                        case 384:
                            damage = 30;
                            ammunition.ParentSheetIndex++;
                            break;

                        case 382:
                            damage = 15;
                            ammunition.ParentSheetIndex++;
                            break;

                        case 386:
                            damage = 50;
                            ammunition.ParentSheetIndex++;
                            break;

                        case 441:
                            damage            = 20;
                            collisionBehavior = BasicProjectile.explodeOnImpact;
                            collisionSound    = "explosion";
                            break;
                        }

                        if (ammunition.Category == -5)
                        {
                            collisionSound = "slimedead";
                        }

                        if (!Game1.options.useLegacySlingshotFiring)
                        {
                            v.X *= -1f;
                            v.Y *= -1f;
                        }

                        if (__instance.hasEnchantmentOfType <SwiftEnchantment>())
                        {
                            v.X *= 2;
                            v.Y *= 2;
                        }

                        BasicProjectile projectile = new BasicProjectile(
                            (int)(damageMod * (damage + Game1.random.Next(-(damage / 2), damage + 2)) * (1f + who.attackIncreaseModifier)),
                            ammunition.ParentSheetIndex,
                            0,
                            0,
                            (float)(Math.PI / (64f + Game1.random.Next(-63, 64))),
                            0f - v.X,
                            0f - v.Y,
                            shoot_origin - new Vector2(32f, 32f),
                            collisionSound,
                            "",
                            explode: false,
                            damagesMonsters: true,
                            location,
                            who,
                            spriteFromObjectSheet: true,
                            collisionBehavior)
                        {
                            IgnoreLocationCollision = (Game1.currentLocation.currentEvent != null || Game1.currentMinigame != null)
                        };

                        location.projectiles.Add(projectile);
                    }
                }
                else
                {
                    Game1.showRedMessage(Game1.content.LoadString("Strings\\StringsFromCSFiles:Slingshot.cs.14254"));
                }
                canPlaySound(__instance) = true;
                return(false);
            }
            else
            {
                return(true);
            }
        }