public List <HitFrame> findOverAimHits()
        {
            var result   = new List <HitFrame>();
            int keyIndex = 0;

            for (int i = 0; i < hits.Count; ++i)
            {
                CircleObject note = hits[i].note;
                //bool hover = false;

                //searches for init circle object hover
                for (int j = keyIndex; j < replay.ReplayFrames.Count; ++j)
                {
                    ReplayFrame frame = replay.ReplayFrames[j];
                    if (note.ContainsPoint(new BMAPI.Point2(frame.X, frame.Y)) && Math.Abs(frame.Time - note.StartTime) <= hitTimeWindow)
                    {
                        while (note.ContainsPoint(new BMAPI.Point2(frame.X, frame.Y)) && frame.Time < hits[i].frame.Time)
                        {
                            ++j;
                            frame = replay.ReplayFrames[j];
                        }
                        if (!note.ContainsPoint(new BMAPI.Point2(frame.X, frame.Y)))
                        {
                            result.Add(hits[i]);
                        }
                    }
                }
            }
            return(result);
        }
Example #2
0
        private void AddCircleObjectComponentsTo(GameObject gameObject, XElement goXml)
        {
            var xml = goXml.Element("CircleObjectComponent");

            if (xml != null)
            {
                CircleObject tmxCircle = gameObject.AddComponent <Tiled2Unity.CircleObject>();
                FillBaseTmxObjectProperties(tmxCircle, xml);
            }
        }
Example #3
0
    public CircleObject Spawn(CircleObject prefab, Vector2 point)
    {
        var instance = GameObject.Instantiate(prefab);

        instance.name = prefab.name;
        instance.transform.SetParent(GameObject.Find("SortObjects").transform);
        instance.gameObject.SetActive(true);
        instance.Position           = point;
        instance.transform.position = new Vector2(point.x, point.y * Config.Instance.VerticalScale);
        instance.Init();
        return(instance);
    }
    public override void FirstInit()
    {
        for (int i = 0; i < spawnCount; ++i)
        {
            CircleObject circle = Instantiate(noteObject).GetComponent <CircleObject>();

            circle.Initialize();
            circle.gameObject.SetActive(false);

            circleList.Add(circle);
        }
    }
Example #5
0
    public CircleObject SpawnAtRandomFreePlace(CircleObject prefab)
    {
        for (int i = 0; i < SpawnAttempts; i++)
        {
            var point = WalkZone.Instance.GetRandomPoint(prefab.Radius);
            if (!WalkZone.Instance.CollideAny(point, prefab.Radius, null))
            {
                return(Spawn(prefab, point));
            }
        }

        Debug.LogError("Can't spawn " + prefab.name);
        return(null);
    }
Example #6
0
        public static List <CircleObject> stream(int points, Point2 center, double radius, double angle1, double angle2)
        {
            var result = new List <CircleObject>();

            double dangle = (angle2 - angle1) / (points - 1);

            for (int i = 0; i < points; ++i)
            {
                CircleObject o1 = new CircleObject();
                o1.Location = new Point2(center.X + (float)(radius * Math.Cos(angle1 + i * dangle)), center.Y - (float)(radius * Math.Sin(angle1 + i * dangle)));
                result.Add(o1);
            }

            return(result);
        }
Example #7
0
        public static List <CircleObject> stream(int points, Point2 from, Point2 to)
        {
            var result = new List <CircleObject>();

            float dx = (to.X - from.X) / points;
            float dy = (to.Y - from.Y) / points;

            for (int i = 0; i < points; ++i)
            {
                CircleObject o1 = new CircleObject();
                o1.Location = new Point2(from.X + i * dx, from.Y + i * dy);
                result.Add(o1);
            }

            return(result);
        }
Example #8
0
        private void applyStackingOld()
        {
            double ApproachTimeWindow = Math.Min(1800 - 120 * ApproachRate, 1950 - 150 * ApproachRate);
            double stackTimeWindow    = (ApproachTimeWindow * (StackLeniency ?? 7));
            float  stack_distance     = 3;

            for (int i = 0; i < HitObjects.Count; i++)
            {
                CircleObject currHitObject = HitObjects[i];

                if (currHitObject.StackHeight != 0 && !(currHitObject is SliderObject))
                {
                    continue;
                }

                double startTime   = currHitObject.EndTime;
                int    sliderStack = 0;

                for (int j = i + 1; j < HitObjects.Count; j++)
                {
                    if (HitObjects[j].StartTime - stackTimeWindow > startTime)
                    {
                        break;
                    }

                    // The start position of the hitobject, or the position at the end of the path if the hitobject is a slider
                    Vector2 position2 = currHitObject is SliderObject currSlider
                        ? currSlider.EndBaseLocation
                        : currHitObject.BaseLocation.ToVector2();

                    if (Vector2.Distance(HitObjects[j].BaseLocation.ToVector2(), currHitObject.BaseLocation.ToVector2()) < stack_distance)
                    {
                        currHitObject.StackHeight++;
                        startTime = HitObjects[j].EndTime;
                    }
                    else if (Vector2.Distance(HitObjects[j].BaseLocation.ToVector2(), position2) < stack_distance)
                    {
                        // Case for sliders - bump notes down and right, rather than up and left.
                        sliderStack++;
                        HitObjects[j].StackHeight -= sliderStack;
                        startTime = HitObjects[j].EndTime;
                    }
                }
            }
        }
Example #9
0
    public CircleObject GetCollider(Vector2 position, float radius, CircleObject except, System.Func <CircleObject, bool> filter = null)
    {
        foreach (var circle in CircleObject.All)
        {
            if (circle != except)
            {
                if (filter == null || filter(circle))
                {
                    var distance = (position - circle.Position).magnitude;
                    if (distance < radius + circle.Radius)
                    {
                        return(circle);
                    }
                }
            }
        }

        return(null);
    }
Example #10
0
    public void CheckInteractive()
    {
        InteractiveObject = null;
        var curentPriority = 0;

        foreach (var circle in CircleObject.All)
        {
            if (circle != this)
            {
                var priority = GetInteractivePriority(circle);
                if (curentPriority < priority)
                {
                    var delta    = this.Position - circle.Position;
                    var distance = delta.magnitude - Radius - circle.Radius;
                    if (distance < Config.Instance.InteractiveDistance)
                    {
                        InteractiveObject = circle;
                        curentPriority    = priority;
                    }
                }
            }
        }

        if (Input.GetKeyDown(KeyCode.E))
        {
            if (InteractiveObject != null)
            {
                if (InteractiveObject is Gnome gnome)
                {
                    GrabeGnome(gnome);
                }
                else if (InteractiveObject is Resource resource)
                {
                    var newGnome = PlaceGnomeAt(resource.Position + new Vector2(0, -1));
                    newGnome.StartMining(resource);
                }
            }
            else
            {
                FreePlaceGnome();
            }
        }
    }
Example #11
0
        public static List <CircleObject> polygon(int points, Point2 center, int size, double angle)
        {
            var result = new List <CircleObject>();

            double dangle = Math.PI / points * 2;

            double offset = Math.PI - dangle / 2;

            for (int i = 0; i < points; ++i)
            {
                CircleObject o1 = new CircleObject();
                o1.Location = new Point2(center.X + size * (float)Math.Cos(offset), center.Y - size * (float)Math.Sin(offset));
                result.Add(o1);
                offset -= dangle;
            }

            rotate(result, center, angle);

            return(result);
        }
Example #12
0
        public static List <CircleObject> generateVerticalJump(Point2 start, int spacing, double angle, bool randomize)
        {
            var result = new List <CircleObject>();

            CircleObject o1 = new CircleObject();

            o1.Location = start;
            result.Add(o1);

            CircleObject o2 = new CircleObject();

            o2.Location    = new Point2(start);
            o2.Location.Y -= spacing;
            result.Add(o2);

            Point2 center = new Point2(o1.Location);

            center.Y = (o1.Location.Y + o2.Location.Y) / 2;

            rotate(result, center, angle);

            return(result);
        }
Example #13
0
    private int GetInteractivePriority(CircleObject circle)
    {
        switch (circle.Type)
        {
        case CircleType.Gnome:
            return(GrabbedGnome == null ? 3 : 0);

        case CircleType.DrillCar:
            return(2);

        case CircleType.Resource:
            if (GrabbedGnome != null)
            {
                if ((circle as Resource).CurrentGnome == null)
                {
                    return(1);
                }
            }
            return(0);

        default:
            return(0);
        }
    }
 public SpinnerObject(CircleObject baseInstance)
     : base(baseInstance)
 {
 }
Example #15
0
 public bool CollideAny(Vector2 position, float radius, CircleObject except, System.Func <CircleObject, bool> filter = null)
 {
     return(GetCollider(position, radius, except, filter) != null);
 }
Example #16
0
 public static double pixelPerfectHitFactor(ReplayFrame frame, CircleObject obj)
 {
     return(dist(frame.X, frame.Y, obj.Location.X, obj.Location.Y) / obj.Radius);
 }
Example #17
0
 public void SetCircleObject(CircleObject circleObject)
 {
     this.CircleObject = circleObject;
 }
Example #18
0
 public bool GetCollider(CircleObject circle, System.Func <CircleObject, bool> filter = null)
 {
     return(GetCollider(circle.Position, circle.Radius, circle, filter));
 }
Example #19
0
 public static string printInfo(ReplayFrame frame, CircleObject obj)
 {
     return("Hit " + obj.Type.ToString() + " (starting at " + obj.StartTime + ")" + " at " + frame.Time);
 }
Example #20
0
        /// <summary>
        /// Converts given objects to theorems holding in a given configuration. These theorems
        /// represent the same statement, provided we can justify the used collinear and concyclic points.
        /// </summary>
        /// <param name="geometricObjects">Flattened geometric objects that are converted to theorems.</param>
        /// <returns>The theorems.</returns>
        protected IEnumerable <Theorem> ToTheorems(IEnumerable <GeometricObject> geometricObjects)
        {
            // Map geometric objects to theorem objects
            return(geometricObjects.Select(geometricObject =>
            {
                // Switch on the object type
                switch (geometricObject)
                {
                // In point case we have just the object
                case PointObject point:
                    return new List <TheoremObject> {
                        new PointTheoremObject(point.ConfigurationObject)
                    };

                // In case of an object with points
                case DefinableByPoints objectWithPoints:

                    // Get the possible point definitions
                    var pointDefinitions = objectWithPoints.Points
                                           // Take the subsets of the needed number of defining points
                                           .Subsets(objectWithPoints.NumberOfNeededPoints)
                                           // Get the inner configuration objects
                                           .Select(points => points.Select(point => point.ConfigurationObject).ToArray());

                    // Prepare the resulting theorem objects list
                    var objectsList = new List <TheoremObject>();

                    // For every definition create the right theorem object
                    pointDefinitions.Select(points =>
                    {
                        // Switch base on the object type to find the right constructor
                        return objectWithPoints switch
                        {
                            // In line case we have 2 points
                            LineObject _ => new LineTheoremObject(points[0], points[1]) as TheoremObject,

                            // In circle case we have 3 points
                            CircleObject _ => new CircleTheoremObject(points[0], points[1], points[2]),

                            // Unhandled cases
                            _ => throw new TheoremFinderException($"Unhandled type of {nameof(TheoremObjectWithPoints)}: {objectWithPoints.GetType()}")
                        };
                    })
                    // Add each newly created object to the resulting list
                    .ForEach(objectsList.Add);

                    // If the object has the configuration object set
                    if (objectWithPoints.ConfigurationObject != null)
                    {
                        // Then we have one more definition, an explicit one
                        var explicitObject = objectWithPoints switch
                        {
                            // Line case
                            LineObject _ => new LineTheoremObject(objectWithPoints.ConfigurationObject) as TheoremObject,

                            // Circle case
                            CircleObject _ => new CircleTheoremObject(objectWithPoints.ConfigurationObject),

                            // Unhandled cases
                            _ => throw new TheoremFinderException($"Unhandled type of {nameof(TheoremObjectWithPoints)}: {objectWithPoints.GetType()}")
                        };

                        // Add this newly created object to the resulting list
                        objectsList.Add(explicitObject);
                    }

                    // Finally return the resulting list
                    return objectsList;

                // Unhandled cases
                default:
                    throw new TheoremFinderException($"Unhandled type of {nameof(GeometricObject)}: {geometricObject.GetType()}");
                }
            })
                   // Combine every possible definition of each object
                   .Combine()
                   // Now we can finally use the helper method to get the theorem from these objects
                   .Select(objects => Theorem.DeriveFromFlattenedObjects(Type, objects)));
        }
        private void associateHits()
        {
            int        keyIndex = 0;
            Keys       lastKey;
            KeyCounter keyCounter = new KeyCounter();

            if ((replay.Mods & Mods.HardRock) > 0)
            {
                applyHardrock();
            }

            int breakIndex = 0;
            int combo      = 0;

            for (int i = 0; i < beatmap.HitObjects.Count; ++i)
            {
                CircleObject note                 = beatmap.HitObjects[i];
                bool         noteHitFlag          = false;
                bool         noteAttemptedHitFlag = false;

                if ((note.Type.HasFlag(HitObjectType.Spinner)))
                {
                    continue;
                }

                for (int j = keyIndex; j < replay.ReplayFrames.Count; ++j)
                {
                    ReplayFrame frame = replay.ReplayFrames[j];
                    lastKey = j > 0 ? replay.ReplayFrames[j - 1].Keys : Keys.None;

                    Keys pressedKey = Utils.getKey(lastKey, frame.Keys);

                    if (breakIndex < breaks.Count && frame.Time > breaks[breakIndex].EndTime)
                    {
                        ++breakIndex;
                    }

                    if (frame.Time >= beatmap.HitObjects[0].StartTime - hitTimeWindow && (breakIndex >= breaks.Count || frame.Time < this.breaks[breakIndex].StartTime - hitTimeWindow))
                    {
                        keyCounter.Update(lastKey, frame.Keys);
                    }

                    frame.keyCounter = new KeyCounter(keyCounter);

                    if (frame.Time - note.StartTime > hitTimeWindow)
                    {
                        break;
                    }

                    if (pressedKey > 0 && Math.Abs(frame.Time - note.StartTime) <= hitTimeWindow)
                    {
                        if (note.ContainsPoint(new BMAPI.Point2(frame.X, frame.Y)))
                        {
                            noteAttemptedHitFlag = true;
                            ++combo;
                            frame.combo = combo;
                            noteHitFlag = true;
                            HitFrame hitFrame = new HitFrame(note, frame, pressedKey);
                            hits.Add(hitFrame);
                            lastKey  = frame.Keys;
                            keyIndex = j + 1;
                            break;
                        }
                        else
                        {
                            if (Utils.dist(note.Location.X, note.Location.Y, frame.X, frame.Y) > 150)
                            {
                                extraHits.Add(new ClickFrame(frame, Utils.getKey(lastKey, frame.Keys)));
                            }
                            else
                            {
                                noteAttemptedHitFlag = true;
                                attemptedHits.Add(new HitFrame(note, frame, pressedKey));
                            }
                        }
                    }
                    if (pressedKey > 0 && Math.Abs(frame.Time - note.StartTime) <= 3 * hitTimeWindow && note.ContainsPoint(new BMAPI.Point2(frame.X, frame.Y)))
                    {
                        noteAttemptedHitFlag = true;
                        attemptedHits.Add(new HitFrame(note, frame, pressedKey));
                    }

                    lastKey = frame.Keys;

                    frame.combo = combo;
                }

                if (!noteHitFlag)
                {
                    misses.Add(new ReplayMissFrame(replay.ReplayFrames[keyIndex], keyIndex, note));
                }
                if (!noteAttemptedHitFlag)
                {
                    effortlessMisses.Add(note);
                }
            }
        }
Example #22
0
 private float GetDangerPrice(CircleObject objcet)
 {
     return((objcet as Enemy).EnemyConfig.DangerPrice);
 }
Example #23
0
 private bool BulletFilter(CircleObject circle)
 {
     return(circle.Health > 0 && !circle.Type.IsPassable() && circle.Type != CircleType.Hero);
 }
Example #24
0
        private void Parse(string bm)
        {
            Info.Filename    = bm;
            Info.BeatmapHash = MD5FromFile(bm);
            using (StreamReader sR = new StreamReader(bm))
            {
                string currentSection = "";

                while (sR.Peek() != -1)
                {
                    string line = sR.ReadLine();

                    //Check for section tag
                    if (line.StartsWith("["))
                    {
                        currentSection = line;
                        continue;
                    }

                    //Check for commented-out line
                    //or blank lines
                    if (line.StartsWith("//") || line.Length == 0)
                    {
                        continue;
                    }

                    //Check for version string
                    if (line.StartsWith("osu file format"))
                    {
                        Info.Format = Convert.ToInt32(line.Substring(17).Replace(Environment.NewLine, "").Replace(" ", ""));
                    }

                    //Do work for [General], [Metadata], [Difficulty] and [Editor] sections
                    if ((currentSection == "[General]") || (currentSection == "[Metadata]") || (currentSection == "[Difficulty]") || (currentSection == "[Editor]"))
                    {
                        string[] reSplit   = line.Split(':');
                        string   cProperty = reSplit[0].TrimEnd();

                        bool isValidProperty = false;
                        foreach (string k in BM_Sections.Keys)
                        {
                            if (k.Contains(cProperty))
                            {
                                isValidProperty = true;
                            }
                        }
                        if (!isValidProperty)
                        {
                            continue;
                        }

                        //Check for blank value
                        string cValue = reSplit[1].Trim();

                        //Import properties into Info
                        switch (cProperty)
                        {
                        case "EditorBookmarks":
                        {
                            string[] marks = cValue.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                            foreach (string m in marks.Where(m => m != ""))
                            {
                                Info.EditorBookmarks.Add(Convert.ToInt32(m));
                            }
                        }
                        break;

                        case "Bookmarks":
                        {
                            string[] marks = cValue.Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                            foreach (string m in marks.Where(m => m != ""))
                            {
                                Info.Bookmarks.Add(Convert.ToInt32(m));
                            }
                        }
                        break;

                        case "Tags":
                            string[] tags = cValue.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                            foreach (string t in tags)
                            {
                                Info.Tags.Add(t);
                            }
                            break;

                        case "Mode":
                            Info.Mode = (GameMode)Convert.ToInt32(cValue);
                            break;

                        case "OverlayPosition":
                            Info.OverlayPosition = (OverlayOptions)Enum.Parse(typeof(OverlayOptions), cValue);
                            break;

                        case "AlwaysShowPlayfield":
                            Info.AlwaysShowPlayfield = Convert.ToBoolean(Convert.ToInt32(cValue));
                            break;

                        default:
                            FieldInfo    fi = Info.GetType().GetField(cProperty);
                            PropertyInfo pi = Info.GetType().GetProperty(cProperty);
                            if (fi != null)
                            {
                                if (fi.FieldType == typeof(float?))
                                {
                                    fi.SetValue(Info, (float?)Convert.ToDouble(cValue));
                                }
                                if (fi.FieldType == typeof(float))
                                {
                                    fi.SetValue(Info, (float)Convert.ToDouble(cValue));
                                }
                                else if ((fi.FieldType == typeof(int?)) || (fi.FieldType == typeof(int)))
                                {
                                    fi.SetValue(Info, Convert.ToInt32(cValue));
                                }
                                else if (fi.FieldType == typeof(string))
                                {
                                    fi.SetValue(Info, cValue);
                                }
                                break;
                            }
                            if (pi.PropertyType == typeof(float?))
                            {
                                pi.SetValue(Info, (float?)Convert.ToDouble(cValue), null);
                            }
                            if (pi.PropertyType == typeof(float))
                            {
                                pi.SetValue(Info, (float)Convert.ToDouble(cValue), null);
                            }
                            else if ((pi.PropertyType == typeof(int?)) || (pi.PropertyType == typeof(int)))
                            {
                                pi.SetValue(Info, Convert.ToInt32(cValue), null);
                            }
                            else if (pi.PropertyType == typeof(string))
                            {
                                pi.SetValue(Info, cValue, null);
                            }
                            break;
                        }
                        continue;
                    }

                    //The following are version-dependent, the version is stored as a numeric value inside Info.Format
                    //Do work for [Events] section
                    if (currentSection == "[Events]")
                    {
                        string[] reSplit = line.Split(',');
                        switch (reSplit[0].ToLower())
                        {
                        case "0":
                        case "1":
                        case "video":
                            Info.Events.Add(new ContentEvent
                            {
                                Type      = reSplit[0].ToLower() == "1" || reSplit[0].ToLower() == "video" ? ContentType.Video : ContentType.Image,
                                StartTime = Convert.ToInt32(reSplit[1]),
                                Filename  = reSplit[2].Replace("\"", "")
                            });
                            break;

                        case "2":
                            Info.Events.Add(new BreakEvent
                            {
                                StartTime = Convert.ToInt32(reSplit[1]),
                                EndTime   = Convert.ToInt32(reSplit[2])
                            });
                            break;

                        case "3":
                            Info.Events.Add(new BackgroundColourEvent
                            {
                                StartTime = Convert.ToInt32(reSplit[1]),
                                Colour    = new Colour
                                {
                                    R = Convert.ToInt32(reSplit[2]),
                                    G = Convert.ToInt32(reSplit[3]),
                                    B = Convert.ToInt32(reSplit[4])
                                },
                            });
                            break;
                        }
                    }

                    //Do work for [TimingPoints] section
                    if (currentSection == "[TimingPoints]")
                    {
                        TimingPoint tempTimingPoint = new TimingPoint();

                        float[]  values  = { 0, 0, 4, 0, 0, 100, 0, 0, 0 };
                        string[] reSplit = line.Split(',');
                        for (int i = 0; i < reSplit.Length; i++)
                        {
                            values[i] = (float)Convert.ToDouble(reSplit[i]);
                        }
                        tempTimingPoint.Time             = (float)Convert.ToDouble(values[0]);
                        tempTimingPoint.BpmDelay         = (float)Convert.ToDouble(values[1]);
                        tempTimingPoint.TimeSignature    = Convert.ToInt32(values[2]);
                        tempTimingPoint.SampleSet        = Convert.ToInt32(values[3]);
                        tempTimingPoint.CustomSampleSet  = Convert.ToInt32(values[4]);
                        tempTimingPoint.VolumePercentage = Convert.ToInt32(values[5]);
                        tempTimingPoint.InheritsBPM      = !Convert.ToBoolean(Convert.ToInt32(values[6]));
                        tempTimingPoint.VisualOptions    = (TimingPointOptions)Convert.ToInt32(values[7]);
                        Info.TimingPoints.Add(tempTimingPoint);
                    }

                    //Do work for [Colours] section
                    if (currentSection == "[Colours]")
                    {
                        string   property = line.Substring(0, line.IndexOf(':', 1)).Trim();
                        string   value    = line.Substring(line.IndexOf(':', 1) + 1).Trim();
                        string[] reSplit  = value.Split(',');

                        if (property.Length > 5 && property.Substring(0, 5) == "Combo")
                        {
                            Combo newCombo = new Combo
                            {
                                Colour = new Colour
                                {
                                    R = Convert.ToInt32(reSplit[0]),
                                    G = Convert.ToInt32(reSplit[1]),
                                    B = Convert.ToInt32(reSplit[2])
                                }
                            };
                            try
                            {
                                newCombo.ComboNumber = Convert.ToInt32(property.Substring(5, 1));
                            }
                            catch
                            {
                                Debug.Assert(false, "Invalid combonumber at index 5. " + line);
                                continue;
                            }
                        }
                        else if (property.Length > 5 && property == "SliderBorder")
                        {
                            Info.SliderBorder = new Colour
                            {
                                R = Convert.ToInt32(reSplit[0]),
                                G = Convert.ToInt32(reSplit[1]),
                                B = Convert.ToInt32(reSplit[2])
                            };
                        }
                    }

                    //Do work for [HitObjects] section
                    if (currentSection == "[HitObjects]")
                    {
                        string[]     reSplit   = line.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                        CircleObject newObject = new CircleObject
                        {
                            Radius    = 40 - 4 * (Info.CircleSize - 2),
                            Location  = new Point2(Convert.ToInt32(reSplit[0]), Convert.ToInt32(reSplit[1])),
                            StartTime = (float)Convert.ToDouble(reSplit[2]),
                            Type      = (HitObjectType)Convert.ToInt32(reSplit[3]),
                            Effect    = (EffectType)Convert.ToInt32(reSplit[4])
                        };
                        if ((newObject.Type & HitObjectType.Slider) > 0)
                        {
                            newObject = new SliderObject(newObject);
                            ((SliderObject)newObject).Velocity = Info.SliderMultiplier;
                            switch (reSplit[5].Substring(0, 1))
                            {
                            case "B":
                                ((SliderObject)newObject).Type = SliderType.Bezier;
                                break;

                            case "C":
                                ((SliderObject)newObject).Type = SliderType.CSpline;
                                break;

                            case "L":
                                ((SliderObject)newObject).Type = SliderType.Linear;
                                break;

                            case "P":
                                ((SliderObject)newObject).Type = SliderType.PSpline;
                                break;
                            }
                            string[] pts = reSplit[5].Split(new[] { "|" }, StringSplitOptions.None);

                            //Todo: Check this
                            if (Format <= 4)
                            {
                                ((SliderObject)newObject).Points.Add(newObject.Location);
                            }

                            //Always exclude index 1, this will contain the type
                            for (int i = 1; i <= pts.Length - 1; i++)
                            {
                                Point2 p = new Point2((float)Convert.ToDouble(pts[i].Substring(0, pts[i].IndexOf(":", StringComparison.InvariantCulture))),
                                                      (float)Convert.ToDouble(pts[i].Substring(pts[i].IndexOf(":", StringComparison.InvariantCulture) + 1)));
                                ((SliderObject)newObject).Points.Add(p);
                            }
                            ((SliderObject)newObject).RepeatCount = Convert.ToInt32(reSplit[6]);
                            float tempMaxPoints;
                            if (float.TryParse(reSplit[7], out tempMaxPoints))
                            {
                                ((SliderObject)newObject).MaxPoints = tempMaxPoints;
                            }
                        }
                        if ((newObject.Type & HitObjectType.Spinner) > 0)
                        {
                            newObject = new SpinnerObject(newObject);
                            ((SpinnerObject)newObject).EndTime = (float)Convert.ToDouble(reSplit[5]);
                        }
                        Info.HitObjects.Add(newObject);
                    }
                }
            }

            //Copy the fields/properties of Info locally
            foreach (FieldInfo fi in Info.GetType().GetFields())
            {
                FieldInfo ff = GetType().GetField(fi.Name);
                ff.SetValue(this, fi.GetValue(Info));
            }
            foreach (PropertyInfo pi in Info.GetType().GetProperties())
            {
                PropertyInfo ff = GetType().GetProperty(pi.Name);
                ff.SetValue(this, pi.GetValue(Info, null), null);
            }
        }
Example #25
0
    public CircleObject SpawnEnemy(CircleObject prefab)
    {
        var point = WalkZone.Instance.GetRandomEnemyPoint(prefab.Radius);

        return(Spawn(prefab, point));
    }
Example #26
0
 public SpinnerObject(CircleObject baseInstance) : base(baseInstance)
 {
 }
 public ReplayMissFrame(ReplayFrame replayFrame, int segmentIndex, CircleObject hitObject)
 {
     this.replayFrame  = replayFrame;
     this.segmentIndex = segmentIndex;
     this.note         = hitObject;
 }
Example #28
0
        protected override void _Draw()
        {
            int screenX = GameSettings.WindowWidth;
            int screenY = GameSettings.WindowHeight;

            bool mouseInScreen = 0 <= Mouse.X && Mouse.X < screenX && 0 <= Mouse.Y && Mouse.Y < screenY;

            if (!Keyboard.IsHit(DX.KEY_INPUT_SPACE))
            {
                DrawSensorColorImage();
            }
            else
            {
                DrawSensorDepthImage();
            }

            if (this.Status == States.Resumed)
            {
                DrawHologram();

                DX.SetFontSize(20);

                MoveCamera();

                DrawBullet(bulletHit);
                if (drawDokuro)
                {
                    DX.DrawExtendGraph(dokuroX - dokuroWidth2, dokuroY - dokuroWidth2, dokuroX + dokuroWidth2, dokuroY + dokuroWidth2, dokuroImage, DX.TRUE);
                }

                DebugWindow.Draw();

                if (mouseInScreen)
                {
                    if (Mouse.Middle)
                    {
                        CircleObject obj = new CircleObject();
                        obj.Init(GameSettings);
                        obj.Radius = 10;
                        obj.X = Mouse.X;
                        obj.Y = Mouse.Y;
                        gameObjects.Add(obj);
                    }
                }

                foreach (var obj in gameObjects)
                {
                    obj.Draw();
                }

                if (mouseInScreen)
                {
                    DX.SetMouseDispFlag(DX.FALSE);
                    DX.DrawCircle(Mouse.X, Mouse.Y, 10, DX.GetColor(0, 255, 0), DX.FALSE);
                    DX.DrawCircle(Mouse.X, Mouse.Y, 8, DX.GetColor(0, 255, 0), DX.FALSE);
                }
                else
                {
                    DX.SetMouseDispFlag(DX.TRUE);
                }
            }
            else
            {
                DX.SetMouseDispFlag(DX.TRUE);
            }
        }
        // Create object in room upon user click
        private void MakeSpaceObject(string texName, Image tex, DrawPoint mp)
        {
            texName = texName.Replace(".png", "");

            string[] lastname_ary= (string[])texName.Split('\\');
            string lastname = lastname_ary[lastname_ary.Length-1];

            string texStripName = texName.Replace(lastname,"strips\\"+lastname) + "_strip";

            //int numberOfFrames = SpaceObject.GetNumberOfFrames(texName);

            Vector2 screenposition = Conversion.DrawPointToVector2(mp);
            Vector2 gameposition = new Vector2(screenposition.X / CASSWorld.SCALE, screenposition.Y / CASSWorld.SCALE);

            if (rb_AnimationObjects.Checked)
            {
                AnimationObject ao;
                // TODO : i'm not a fan of these ifs, since the only thing that's changing are those last two numbers
                //        having to do with the animation. is there a way they could be passed in, or even better,
                //        derived from the strip image?
                if (lastname == "fan")
                    ao = new AnimationObject(world.World, texStripName, texName, tex.Width, tex.Height, 20, 7);
                else if (lastname == "broken_platform")
                    ao = new AnimationObject(world.World, texStripName, texName, tex.Width, tex.Height, 20, 8);
                else if (lastname == "light" || lastname == "fire")
                {
                    ao = new AnimationObject(world.World, texStripName, texName, tex.Width, tex.Height, 20, 8,false, false);
                    //ao.RemoveFromWorld();
                    //world.World.DestroyBody(ao.Body);
                }
                else if (lastname == "rollingpin")
                {
                    ao = new AnimationObject(world.World, texStripName, texName, tex.Width, tex.Height, 20, 8, true, true);
                }
                else
                {
                    ao = new AnimationObject(world.World, texStripName, texName, tex.Width, tex.Height, 20, 8);
                }
                ao.Position = gameposition;
                world.AddObject(ao);
            }
            else if (rb_BoxObjects.Checked)
            {
                BoxObject bo;
                bo = new BoxObject(world.World, texName, 0, .5f, 0, 1, false);
                bo.Position = gameposition;
                world.AddObject(bo);
            }
            else if (rb_CircleObjects.Checked)
            {
                CircleObject co;
                co = new CircleObject(world.World, texName, 1, .5f, 0, 1);
                co.Position = gameposition;
                world.AddObject(co);
            }
            else if (rb_WinDoorObject.Checked)
            {
                WinDoorObject so;
                // HACK - hard-coded for the win-door
                so = new WinDoorObject(world.World, texStripName, texName, tex.Width, tex.Height, 20, 5);
                so.Position = gameposition;
                world.AddObject(so);
            }
            else if (rb_PistonObject.Checked)
            {
                PistonObject po;
                Console.WriteLine("{0}", gameposition);
                po = new PistonObject(world.World, .5f, .5f, 12f, 13f, 9.7f, 12.6f, .01f, .1f, gameposition);
                po.Position = gameposition;
                world.AddObject(po);
            }
            else if(rb_SeeSawObject.Checked)
            {
                SeeSawObject ss;
                ss = new SeeSawObject(world.World, texName, 1.5f, gameposition);
                ss.Position = gameposition;
                world.AddObject(ss);

            }
            else if (rb_SwitchObject.Checked)
            {
                SwitchObject ss1;
             //       ss1 = new SwitchObject(world.World, "Art\\Objects\\SwitchObjects\\button_strip","Art\\Objects\\SwitchObjects\\button", 181, 84, 20, 2);
                //brokenMovingPlatform1 = new SwitchObject(World, "broken_strip", "broken_moving_platform", 89, 32, 20, 8);
             //       ss1.Position = gameposition;
              //  world.AddObject(ss1);

                if (lastname == "button")
                {
                    ss1 = new SwitchObject(world.World, "Art\\Objects\\SwitchObjects\\button_strip", "Art\\Objects\\SwitchObjects\\button", 181, 84, 20, 2);

                    ss1.Position = gameposition;
                    world.AddObject(ss1);
                }
                else if (lastname == "death")
                {

                    DeathPlatform ss2;
                    ss2 = new DeathPlatform(world.World, "Art\\Objects\\SwitchObjects\\button_death_strip", "Art\\Objects\\SwitchObjects\\death", 181, 84, 20, 2);

                    //brokenMovingPlatform1 = new SwitchObject(World, "broken_strip", "broken_moving_platform", 89, 32, 20, 8);
                    ss2.Position = gameposition;
                    world.AddObject(ss2);
                }
                else
                {
                    FailButtonObject ss2;
                    ss2 = new FailButtonObject(world.World, "Art\\Objects\\SwitchObjects\\button_strip", "Art\\Objects\\SwitchObjects\\fail_button", 181, 84, 20, 2);

                    //brokenMovingPlatform1 = new SwitchObject(World, "broken_strip", "broken_moving_platform", 89, 32, 20, 8);
                    ss2.Position = gameposition;
                    world.AddObject(ss2);
                }

            }
            else if (rb_HoleObject.Checked)
            {
                HoleObject ss;
                ss = new HoleObject(world.World, "Art\\Objects\\HoleObjects\\hole_strip", "Art\\Objects\\HoleObjects\\hole");
                //hole1 = new HoleObject(World, "Art\\Objects\\HoleObjects\\hole_strip", "Art\\Objects\\HoleObjects\\hole");
                ss.Position = gameposition;
                world.AddObject(ss);

            }
            else if (rb_MovingPlatform.Checked)
            {
                MovingObject ss;
              //  ss = new MovingObject(world.World, "Art\\Objects\\MovingPlatformObjects\\moving_platform", 1000, 0.5f, 0, 1, false, null, new Vector2(0, -11500), 4.5f, 14.2f);
               // movPlatform1 = new MovingObject(World, "moving platform", 1000f, .5f, 0, 1, false, brokenMovingPlatform1, new Vector2(0, -11500), 4.5f, 14.2f);
               // ss.Position = gameposition;
              //  world.AddObject(ss);

                if (lastname == "moving_platform")
                    ss = new MovingObject(world.World, "Art\\Objects\\MovingPlatformObjects\\moving_platform", 0, 0.5f, 0, 1, false, null, new Vector2(0, -11500), 4.5f, 14.2f);
                else if (lastname == "gate")
                {
                    SwitchObject ssfine;
                    ssfine = new SwitchObject(world.World, "Art\\Objects\\SwitchObjects\\button_strip", "Art\\Objects\\SwitchObjects\\button", 181, 84, 20, 2);
                    ss = new MovingObject(world.World, "Art\\Objects\\MovingPlatformObjects\\gate", 0, 0.5f, 0, 1, false, ssfine, new Vector2(0, -11500), 4.5f, 14.2f);
                    //brokenMovingPlatform1 = new SwitchObject(World, "broken_strip", "broken_moving_platform", 89, 32, 20, 8);
                    ssfine.Position = gameposition;
                    world.AddObject(ssfine);
                }
                else
                {

                    SwitchObject ss1;
                    ss1 = new SwitchObject(world.World, "Art\\Objects\\SwitchObjects\\button_strip", "Art\\Objects\\SwitchObjects\\button", 181, 84, 20, 2);
                    ss = new MovingObject(world.World, "Art\\Objects\\MovingPlatformObjects\\switchmoving_platform", 0, 0.5f, 0, 1, false, ss1, new Vector2(0, -11500), 4.5f, 14.2f);
                    //brokenMovingPlatform1 = new SwitchObject(World, "broken_strip", "broken_moving_platform", 89, 32, 20, 8);
                    ss1.Position = gameposition;
                    world.AddObject(ss1);
                }

                ss.Position = gameposition;
                world.AddObject(ss);

            }
            else if (rb_HorizontalMovingPlatform.Checked)
            {
                HorizontalMovingObject ss;
              //  ss = new HorizontalMovingObject(world.World, "Art\\Objects\\HorizontalMovingPlatformObjects\\moving_platform", 0, 0.5f, 0, 1, false, null, new Vector2(0, -11500), 4.5f, 14.2f);
               // movPlatform2 = new HorizontalMovingObject(World, "Art\\Objects\\HorizontalMovingPlatformObjects\\moving_platform", 0f, 0.5f, 0, 1, false, null, new Vector2(0, -11500), 32f, 38f);

                if (lastname == "moving_platform")
                    ss = new HorizontalMovingObject(world.World, "Art\\Objects\\HorizontalMovingPlatformObjects\\moving_platform", 0, 0.5f, 0, 1, false, null, new Vector2(0, -11500), 4.5f, 14.2f);
                else
                {

                    SwitchObject ss1;
                    ss1 = new SwitchObject(world.World, "Art\\Objects\\SwitchObjects\\button_strip", "Art\\Objects\\SwitchObjects\\button", 181, 84, 20, 2);
                    ss = new HorizontalMovingObject(world.World, "Art\\Objects\\HorizontalMovingPlatformObjects\\switchmoving_platform", 0, 0.5f, 0, 1, false, ss1, new Vector2(0, -11500), 4.5f, 14.2f);
                    //brokenMovingPlatform1 = new SwitchObject(World, "broken_strip", "broken_moving_platform", 89, 32, 20, 8);
                    ss1.Position = gameposition;
                    world.AddObject(ss1);
                }

                ss.Position = gameposition;
                world.AddObject(ss);

            }
            else if (rb_PaintedObjects.Checked)
            {
                switch (lastname)
                {
                    case "block_long":
                        InstasteelObject io;
                        io = new InstasteelObject(world.World, texName, 580, 1, .5f, 0, 1, false);
                        io.Position = gameposition;
                        world.AddObject(io);
                        break;
                    case "disk_long":
                        InstasteelCircleObject ico;
                        ico = new InstasteelCircleObject(world.World, texName, 480, 1, .5f, 0, 1);
                        ico.Position = gameposition;
                        world.AddObject(ico);
                        break;
                    case "line_long":
                        InstasteelObject ilo;
                        ilo = new InstasteelObject(world.World, texName, 190, 1, .5f, 0, 1, false);
                        ilo.Position = gameposition;
                        world.AddObject(ilo);
                        break;
                    default:
                        break;
                }
            }
                /*
            else if (rb_PaintedObjects.Checked)
            {
                PaintedObject po;
                List<Vector2> blobs = new List<Vector2>();
                float radius;
                float sidelength;
                Vector2 centeroff;
                switch (lastname)
                {
                    case "line_short":
                        float linelength_short = (30f/60f) * 1.2f;
                        blobs.Add(gameposition + new Vector2(linelength_short/2f, 0f));
                        blobs.Add(gameposition + new Vector2(-linelength_short/2f, 0f));
                        centeroff = new Vector2(0,0);
                        break;
                    case "line":
                        float linelength = 1.2f;
                        blobs.Add(gameposition + new Vector2(linelength/2, 0f));
                        blobs.Add(gameposition + new Vector2(-linelength/2f, 0f));
                        centeroff = new Vector2(0,0);
                        break;
                    case "line_long":
                        float linelength_long = (200f/60f) * 1.2f;
                        blobs.Add(gameposition + new Vector2(linelength_long/2f, 0f));
                        blobs.Add(gameposition + new Vector2(-linelength_long/2f, 0f));
                        centeroff = new Vector2(0,0);
                        break;
                    case "disk_short":
                        radius =  (30f/60f) *0.6f;
                        blobs = paintedCircle(radius, gameposition); // radius of 0.6f
                        centeroff = -1 * new Vector2(radius, radius);
                        centeroff = new Vector2(0,0);
                        break;
                    case "disk_small":
                        radius =  (40f/60f) *0.6f;
                        blobs = paintedCircle(radius, gameposition); // radius of 0.6f
                        centeroff = -1 * new Vector2(radius, radius);
                        centeroff = new Vector2(0,0);
                        break;
                    case "disk":
                        radius =  0.6f;
                        blobs = paintedCircle(radius, gameposition); // radius of 0.6f
                        centeroff = -1 * new Vector2(radius, radius);
                        centeroff = new Vector2(0,0);
                        break;
                    case "disk_long":
                        radius =  (150f/60f) * 0.6f;
                        blobs = paintedCircle(radius, gameposition); // radius of 0.6f
                        centeroff = -1 * new Vector2(radius, radius);
                        centeroff = new Vector2(0,0);
                        break;
                    case "block_short":
                        sidelength =  (30f/60f) *0.6f;
                        blobs = paintedSquare((30f/60f) * 1.2f, gameposition); // sidelength of 1.2f
                        centeroff = -1 * new Vector2(sidelength, sidelength);
                        break;
                    case "block_small":
                        sidelength =  (40f/60f) *0.6f;
                        blobs = paintedSquare((40f/60f) * 1.2f, gameposition); // sidelength of 1.2f
                        centeroff = -1 * new Vector2(sidelength, sidelength);
                        break;
                    case "block":
                        sidelength =  0.6f;
                        blobs = paintedSquare(1.2f, gameposition); // sidelength of 1.2f
                        centeroff = -1 * new Vector2(sidelength, sidelength);
                        break;
                    case "block_long":
                        sidelength =  (150f/60f) * 0.6f;
                        blobs = paintedSquare((150f/60f) * 1.2f, gameposition); // sidelength of 1.2f
                        centeroff = -1 * new Vector2(sidelength, sidelength);
                        break;
                    default:
                        blobs.Add(gameposition + new Vector2(0.6f, 0f));
                        blobs.Add(gameposition + new Vector2(-0.6f, 0f));
                        centeroff = new Vector2(0,0);
                        break;
                }
                po = new PaintedObject(world.World, "paint", "paintedsegment", blobs);
                po.TextureFilename = "Art\\Objects\\PaintedObjects\\" + lastname;
                po.Position = gameposition + centeroff;
                world.AddObject(po);
            }
            */
            else if (rb_BackgroundObjects.Checked)
            {
                BackgroundObject bo;
                bo = new BackgroundObject(world.World, world, texName,gameposition);
                bo.Position = gameposition;
                world.AddObject(bo);

            }

                /*
            else if (rb_Player.Checked)
            {
                mp.X -= (int)((texture.Width * Constants.PLAYER_SCALE) / 2);
                mp.Y -= (int)((texture.Height * Constants.PLAYER_SCALE) / 2);

                world.player = new Player(
                    Conversion.DrawPointToVector2(mp),
                    currdir + "\\" + texName + ".tri"
                    );

                world.CurrentRoom = currentlySelectedRoom;
                world.player.TextureName = texName;
            }
            */
        }
Example #30
0
        public List <CircleObject> generateRandomJumps(MapContextAwareness mapContext, int numberOfNotes, int spacing)
        {
            var result = new List <CircleObject>();

            int c = 0;

            for (int i = 0; i < numberOfNotes && mapContext.Offset < mapContext.endOffset; ++i)
            {
                Point2 next;
                if (i > 0)
                {
                    next = PatternGenerator.findNextPosition(mapContext.X, mapContext.Y, spacing);
                }
                else
                {
                    next = PatternGenerator.findNextPosition(mapContext.X, mapContext.Y, 0);
                }

                int stackNumber;

                if (useOnly)
                {
                    stackNumber = maxStack;
                }
                else
                {
                    stackNumber = Utils.rng.Next(1, maxStack + 1);
                }

                for (int j = 0; j < stackNumber; ++j)
                {
                    CircleObject note = new CircleObject();

                    if (j == 0)
                    {
                        note.Type |= BMAPI.v1.HitObjectType.NewCombo;
                    }

                    note.Location = next;
                    result.Add(note);

                    mapContext.X = (int)next.X;
                    mapContext.Y = (int)next.Y;

                    note.StartTime = (int)mapContext.Offset;

                    if (j < stackNumber - 1)
                    {
                        mapContext.Offset += mapContext.bpm / 2;
                    }
                }
                if (stackNumber % 2 == 0)
                {
                    ++c;
                }

                mapContext.Offset += mapContext.bpm;
            }

            if (c % 2 == 1)
            {
                mapContext.Offset += mapContext.bpm / 2;
            }

            return(result);
        }
Example #31
0
 public HitFrame(CircleObject note, ReplayFrame frame, Keys key)
 {
     this.frame = frame;
     this.note  = note;
     this.key   = key;
 }
Example #32
0
        private void applyStacking()
        {
            double ApproachTimeWindow = Math.Min(1800 - 120 * ApproachRate, 1950 - 150 * ApproachRate);
            double stackTimeWindow    = (ApproachTimeWindow * (StackLeniency ?? 7));
            float  stack_distance     = 3;

            //Console.WriteLine(ApproachTimeWindow);
            //Console.WriteLine(StackLeniency);
            //Console.WriteLine(stackTimeWindow);

            for (int i = HitObjects.Count - 1; i > 0; i--)
            {
                int n = i;

                /* We should check every note which has not yet got a stack.
                 * Consider the case we have two interwound stacks and this will make sense.
                 *
                 * o <-1      o <-2
                 *  o <-3      o <-4
                 *
                 * We first process starting from 4 and handle 2,
                 * then we come backwards on the i loop iteration until we reach 3 and handle 1.
                 * 2 and 1 will be ignored in the i loop because they already have a stack value.
                 */

                CircleObject objectI = HitObjects[i];
                if (objectI.StackHeight != 0 || objectI.Type.HasFlag(HitObjectType.Spinner))
                {
                    continue;
                }

                /* If this object is a hitcircle, then we enter this "special" case.
                 * It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider.
                 * Any other case is handled by the "is Slider" code below this.
                 */
                if (objectI.Type.HasFlag(HitObjectType.Circle))
                {
                    while (--n >= 0)
                    {
                        CircleObject objectN = HitObjects[n];
                        if (objectN.Type.HasFlag(HitObjectType.Spinner))
                        {
                            continue;
                        }

                        double endTime = objectN.EndTime;

                        if (objectI.StartTime - endTime > stackTimeWindow)
                        {
                            // We are no longer within stacking range of the previous object.
                            break;
                        }

                        /* This is a special case where hticircles are moved DOWN and RIGHT (negative stacking) if they are under the *last* slider in a stacked pattern.
                         *    o==o <- slider is at original location
                         *        o <- hitCircle has stack of -1
                         *         o <- hitCircle has stack of -2
                         */
                        if (objectN.Type.HasFlag(HitObjectType.Slider) && Vector2.Distance(objectN.EndBaseLocation, objectI.BaseLocation.ToVector2()) < stack_distance)
                        {
                            int offset = objectI.StackHeight - objectN.StackHeight + 1;

                            for (int j = n + 1; j <= i; j++)
                            {
                                // For each object which was declared under this slider, we will offset it to appear *below* the slider end (rather than above).
                                CircleObject objectJ = HitObjects[j];
                                if (Vector2.Distance(objectN.EndBaseLocation, objectJ.BaseLocation.ToVector2()) < stack_distance)
                                {
                                    objectJ.StackHeight -= offset;
                                }
                            }

                            // We have hit a slider.  We should restart calculation using this as the new base.
                            // Breaking here will mean that the slider still has StackCount of 0, so will be handled in the i-outer-loop.
                            break;
                        }

                        if (Vector2.Distance(objectN.BaseLocation.ToVector2(), objectI.BaseLocation.ToVector2()) < stack_distance)
                        {
                            // Keep processing as if there are no sliders.  If we come across a slider, this gets cancelled out.
                            //NOTE: Sliders with start positions stacking are a special case that is also handled here.

                            objectN.StackHeight = objectI.StackHeight + 1;
                            objectI             = objectN;
                        }
                    }
                }
                else if (objectI.Type.HasFlag(HitObjectType.Slider))
                {
                    /* We have hit the first slider in a possible stack.
                     * From this point on, we ALWAYS stack positive regardless.
                     */
                    while (--n >= 0)
                    {
                        CircleObject objectN = HitObjects[n];
                        if (objectN.Type.HasFlag(HitObjectType.Spinner))
                        {
                            continue;
                        }

                        if (objectI.StartTime - objectN.StartTime > stackTimeWindow)
                        {
                            // We are no longer within stacking range of the previous object.
                            break;
                        }

                        if (Vector2.Distance(objectN.EndBaseLocation, objectI.BaseLocation.ToVector2()) < stack_distance)
                        {
                            objectN.StackHeight = objectI.StackHeight + 1;
                            objectI             = objectN;
                        }
                    }
                }
            }
        }