private void UpdateEscaping(UpdateContext updateContext, CGoldenGoblinAI goldenGoblinAI, CTransform2D transform, float speedMultiplier)
        {
            // Escape speed is a bit faster than normal speed (3.5f)
            const float Speed = SkypieaConstants.PixelsPerMeter * 4f;

            Vector2 velocity = FlaiMath.NormalizeOrZero(transform.Position - _playerTransform.Transform.Position) * Speed * speedMultiplier * updateContext.DeltaSeconds;
            goldenGoblinAI.Velocity = FlaiMath.ClampLength(goldenGoblinAI.Velocity + velocity, Speed);

            transform.Position += goldenGoblinAI.Velocity * updateContext.DeltaSeconds;
            transform.RotationVector = goldenGoblinAI.Velocity;

            // if the goblin is outside the map, delete it
            if (!SkypieaConstants.MapAreaInPixels.Inflate(128, 128).Contains(transform.Position))
            {
                goldenGoblinAI.Entity.Delete();
            }
        }
        private bool ShouldEscape(Entity zombie, CGoldenGoblinAI goldenGoblinAI)
        {
            // is player too close?
            const float DistanceToStartEscape = SkypieaConstants.PixelsPerMeter * 3;
            if (Vector2.Distance(_playerTransform.Position, zombie.Transform.Position) < DistanceToStartEscape)
            {
                return true;
            }

            // is at last waypoint
            if (goldenGoblinAI.CurrentWaypointIndex >= goldenGoblinAI.Waypoints.Count)
            {
                return true;
            }

            // has golden goblin been hit too much?
            const float EscapeLifeBoundary = 0.6f; // awful name.. basically how much life must be taken (in %) for the goblin to start escaping?
            CHealth health = zombie.Get<CHealth>();
            return health.CurrentHealth < health.MaximumHealth * EscapeLifeBoundary;
        }
        // waypoint stun is atm 0 so this code doesn't even matter at all. but it should work just fine
        private void UpdateWaypointStun(UpdateContext updateContext, CGoldenGoblinAI goldenGoblinAI, CTransform2D transform)
        {
            // this is frame-rate dependent but shouldnt matter too much
            goldenGoblinAI.Velocity *= 0.98f;
            transform.Position += goldenGoblinAI.Velocity * updateContext.DeltaSeconds;

            if (goldenGoblinAI.WaypointStunTimer.HasFinished)
            {
                goldenGoblinAI.State = GoldenGoblinState.TravellingToWaypoint;
            }
        }
        private void UpdateTravelling(UpdateContext updateContext, CTransform2D transform, CGoldenGoblinAI goldenGoblinAI, float speedMultiplier)
        {
            const float Speed = SkypieaConstants.PixelsPerMeter * 3.5f;

            // calculate the new velocity
            Vector2 velocity = FlaiMath.NormalizeOrZero(goldenGoblinAI.CurrentWaypoint - transform.Position) * Speed * speedMultiplier; // * updateContext.DeltaSeconds;
            goldenGoblinAI.Velocity = FlaiMath.ClampLength(goldenGoblinAI.Velocity + velocity * updateContext.DeltaSeconds, Speed);
            goldenGoblinAI.Velocity += new Vector2(velocity.Y, velocity.X) * FlaiMath.Sin(updateContext.DeltaSeconds * 3) / 8;

            // if the goblin is near enough to a waypoint, move to the next waypoint
            if (Vector2.Distance(transform.Position, goldenGoblinAI.CurrentWaypoint) < SkypieaConstants.PixelsPerMeter * 2)
            {
                // if the current waypoint is the last one, then change the state to escape
                if (goldenGoblinAI.CurrentWaypointIndex + 1 >= goldenGoblinAI.Waypoints.Count)
                {
                    goldenGoblinAI.State = GoldenGoblinState.EscapingFromPlayer;
                    return;
                }

                // change state to WaypointStun
                goldenGoblinAI.CurrentWaypointIndex++;
                goldenGoblinAI.WaypointStunTimer.Restart();
                goldenGoblinAI.State = GoldenGoblinState.WaypointStun;

                if (goldenGoblinAI.CurrentWaypointIndex >= goldenGoblinAI.Waypoints.Count)
                {
                    goldenGoblinAI.CurrentWaypointIndex = goldenGoblinAI.CurrentWaypointIndex;
                }
            }
            else
            {
                // otherwise move to the current waypoint
                transform.Position += goldenGoblinAI.Velocity * updateContext.DeltaSeconds;
                transform.RotationVector = goldenGoblinAI.Velocity;
            }
        }