csharp/aedenthorn/StardewValleyMods/aedenthorn-StardewValleyMods-24e99f3/Familiars/ButterflyFamiliar.cs

ButterflyFamiliar.cs
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Netcode;
using StardewValley;
using StardewValley.Menus;
using StardewValley.Monsters;
using System;
using System.Collections.Generic;
using System.Reflection;

namespace Familiars
{
    public clast ButterflyFamiliar : Familiar
    {
        public ButterflyFamiliar()
        {
        }


        public ButterflyFamiliar(Vector2 position, long _owner, bool existing = false) : base("Butterfly", position, new AnimatedSprite(ModEntry.Config.ButterflyTexture, 0, 16, 16))
        {
            Name = "ButterflyFamiliar";
            ownerId = _owner;
            flapSpeed = Game1.random.Next(35, 55);

            base.Slipperiness = 20 + Game1.random.Next(-5, 6);
            farmerPastesThrough = true;
            Halt();
            base.IsWalkingTowardPlayer = false;
            base.HideShadow = true;
            ignoreMovementAnimations = true;
            damageToFarmer.Value = 0;

            if (!existing)
            {

                if (Game1.random.NextDouble() < 0.5)
                {
                    baseFrame = (Game1.random.NextDouble() < 0.5) ? (Game1.random.Next(3) * 3 + 160) : (Game1.random.Next(3) * 3 + 180);
                }
                else
                {
                    baseFrame = (Game1.random.NextDouble() < 0.5) ? (Game1.random.Next(3) * 4 + 128) : (Game1.random.Next(3) * 4 + 148);
                    summerButterfly = true;
                }
                Sprite.currentFrame = baseFrame;
                sprite.Value.loop = false;

                if (ModEntry.Config.ButterflyColorType.ToLower() == "random")
                {
                    mainColor = new Color(Game1.random.Next(256), Game1.random.Next(256), Game1.random.Next(256));
                    redColor = new Color(Game1.random.Next(256), Game1.random.Next(256), Game1.random.Next(256));
                    greenColor = new Color(Game1.random.Next(256), Game1.random.Next(256), Game1.random.Next(256));
                    blueColor = new Color(Game1.random.Next(256), Game1.random.Next(256), Game1.random.Next(256));
                }
                else
                {
                    mainColor = ModEntry.Config.ButterflyMainColor;
                    redColor = ModEntry.Config.ButterflyRedColor;
                    greenColor = ModEntry.Config.ButterflyGreenColor;
                    blueColor = ModEntry.Config.ButterflyBlueColor;
                }
                reloadSprite();
            }
        }

        public override void reloadSprite()
        {
            if (Sprite == null)
            {
                Sprite = new AnimatedSprite(ModEntry.Config.ButterflyTexture, baseFrame, 16, 16);
            }
            else
            {
                Sprite.textureName.Value = ModEntry.Config.ButterflyTexture;
            }
            if (ModEntry.Config.DustColorType.ToLower() != "default")
            {
                Sprite.spriteTexture = FamiliarsUtils.ColorFamiliar(Sprite.Texture, mainColor, redColor, greenColor, blueColor);
            }
        }
        public override void draw(SpriteBatch b)
        {

        }
        public override void draw(SpriteBatch b, float alpha)
        {

        }

        public override void update(GameTime time, GameLocation location)
        {
            if (followingOwner || location.getTileIndexAt(getTileLocationPoint(), "Back") != -1)
                lastPosition = position;
            else
                position.Value = lastPosition;

            flapTimer -= time.ElapsedGameTime.Milliseconds;
            if (flapTimer  (summerButterfly ? 3 : 2))
            {
                position.Value += new Vector2(0, -4);
            }
            else
            {
                position.Value += new Vector2(0, 2);
            }
            Sprite.draw(b, Game1.GlobalToLocal(Game1.viewport, position + new Vector2(-64f, -128f + yJumpOffset + yOffset)), position.Y / 10000f, 0, 0, Color.White, flip, 4f * scale, 0f, false);
        }

        public override Rectangle GetBoundingBox()
        {
            Vector2 pos = position + new Vector2(-64f, -128f + yJumpOffset + yOffset);
            return new Rectangle((int)pos.X - 16, (int)pos.Y - 16, 32, 32);
        }

        protected override void initNetFields()
        {
            base.initNetFields();
            base.NetFields.AddFields(new INetSerializable[]
            {
            wasitCounter,
            lastBuff,
            turningRight,
            seenPlayer,
            cursedDoll,
            hauntedSkull
            });
        }

        public override int takeDamage(int damage, int xTrajectory, int yTrajectory, bool isBomb, double addedPrecision, Farmer who)
        {
            if (who != null)
            {
                return 0;
            }
            return base.takeDamage(damage, xTrajectory, yTrajectory, isBomb, addedPrecision, who);
        }

        public override void shedChunks(int number, float scale)
        {
        }



        public override void behaviorAtGameTick(GameTime time)
        {
            invincibleCountdown = 1000;
            if (timeBeforeAIMovementAgain > 0f)
            {
                timeBeforeAIMovementAgain -= time.ElapsedGameTime.Milliseconds;
            }
            if (lastBuff >= 0)
            {
                lastBuff.Value -= time.ElapsedGameTime.Milliseconds;
            }

            if (wasitCounter >= 0)
            {
                wasitCounter.Value -= time.ElapsedGameTime.Milliseconds;
            }

            if (followingOwner)
            {

                Vector2 center = Position + new Vector2(8, 8);
                Vector2 playerCenter = GetOwner().position + new Vector2(64, 92);
                if (Vector2.Distance(playerCenter, center) > 256)
                {
                    Position = Vector2.Distance(playerCenter, center) * 0.03f * Vector2.Normalize(playerCenter - center) + center - new Vector2(8,8);

                }

                float xSlope = (float)(-(float)(playerCenter.X - center.X));
                float ySlope = (float)(playerCenter.Y - center.Y);
                float t = Math.Max(1f, Math.Abs(xSlope) + Math.Abs(ySlope));
                if (t < (float)((extraVelocity > 0f) ? 192 : 64))
                {
                    xVelocity = Math.Max(-maxSpeed, Math.Min(maxSpeed, xVelocity * 1.05f));
                    yVelocity = Math.Max(-maxSpeed, Math.Min(maxSpeed, yVelocity * 1.05f));
                }
                xSlope /= t;
                ySlope /= t;
                if (wasitCounter  2.748893571891069 && Game1.random.NextDouble() < 0.5)
                    {
                        turningRight.Value = true;
                    }
                    else if ((double)(Math.Abs(targetRotation) - Math.Abs(rotation)) < 0.39269908169872414)
                    {
                        turningRight.Value = false;
                    }
                    if (turningRight)
                    {
                        rotation -= (float)Math.Sign(targetRotation - rotation) * 0.0490873866f;
                    }
                    else
                    {
                        rotation += (float)Math.Sign(targetRotation - rotation) * 0.0490873866f;
                    }
                    rotation %= 6.28318548f;
                    wasitCounter.Value = 0;
                }
                float maxAccel = Math.Min(5f, Math.Max(1f, 5f - t / 64f / 2f)) + extraVelocity;
                xSlope = (float)Math.Cos((double)rotation + 1.5707963267948966);
                ySlope = -(float)Math.Sin((double)rotation + 1.5707963267948966);
                xVelocity += -xSlope * maxAccel / 6f + (float)Game1.random.Next(-10, 10) / 100f;
                yVelocity += -ySlope * maxAccel / 6f + (float)Game1.random.Next(-10, 10) / 100f;
                if (Math.Abs(xVelocity) > Math.Abs(-xSlope * maxSpeed))
                {
                    xVelocity -= -xSlope * maxAccel / 6f;
                }
                if (Math.Abs(yVelocity) > Math.Abs(-ySlope * maxSpeed))
                {
                    yVelocity -= -ySlope * maxAccel / 6f;
                }
                if (lastBuff