Example #1
0
 private ActionResult BuildActionResult(SportType sportType, Dictionary<DateTime, List<Dictionary<BetOddType, BetItemTransport>>> data)
 {
     return new ActionResultCached(data != null,
         () => data.MaxOrDefault(d => d.Key, DateTime.MinValue),
         () => {
             var res = new List<Dictionary<string, double>>();
             var addDraw = BetHelper.SportTypeWithOdds[sportType].Contains(BetOddType.Draw);
             data
                 .OrderBy(d => d.Key)
                 .Each(betItems => {
                     var list = betItems.Value;
                     var dict = new Dictionary<string, double> {
                         {"d", (betItems.Key - ProjectBConsts.DefaultLinuxUtc).TotalMilliseconds},
                         {"w1", BetOddInterfaceHelper.GetOddValue(sportType, BetOddType.Win1, list, Enumerable.Max)},
                         {"w2", BetOddInterfaceHelper.GetOddValue(sportType, BetOddType.Win2, list, Enumerable.Max)},
                         {"r1x2", BetOddInterfaceHelper.GetBetOddRoi(RoiType.Roi1X2, sportType, list)},
                         {"h1", BetOddInterfaceHelper.GetOddValue(sportType, BetOddType.Handicap1, list, Enumerable.Max)},
                         {"h2", BetOddInterfaceHelper.GetOddValue(sportType, BetOddType.Handicap2, list, Enumerable.Max)},
                         {"rh", BetOddInterfaceHelper.GetBetOddRoi(RoiType.RoiHandicap, sportType, list)},
                         {"tu", BetOddInterfaceHelper.GetOddValue(sportType, BetOddType.TotalUnder, list, Enumerable.Max)},
                         {"to", BetOddInterfaceHelper.GetOddValue(sportType, BetOddType.TotalOver, list, Enumerable.Max)},
                         {"rt", BetOddInterfaceHelper.GetBetOddRoi(RoiType.RoiTotal, sportType, list)},
                     };
                     if (addDraw) {
                         dict["x"] = BetOddInterfaceHelper.GetOddValue(sportType, BetOddType.Draw, list, Enumerable.Max);
                     }
                     res.Add(dict);
                 });
             return new JsonResult {
                 Data = res
             };
         });
 }
Example #2
0
        static void LaneClear()
        {
            var useQ    = Menu["LaneClear"].GetValue <MenuBool>("UseQLC");
            var useW    = Menu["LaneClear"].GetValue <MenuBool>("UseWLC");
            var minions = GameObjects.EnemyMinions.Where(x => x.IsValidTarget(Q.Range)).ToList();

            if (minions.Count() == 0)
            {
                minions = GameObjects.Jungle.Where(x => x.IsValidTarget(Q.Range)).OrderBy(x => x.MaxHealth).ToList();
            }

            if (minions.Count() > 0)
            {
                if (useW && W.Instance.Ammo > 0 && (minions.Count() > 2 || minions[0].Team == GameObjectTeam.Neutral))
                {
                    var p = Player.Position.ToVector2().Extend(minions[0].Position.ToVector2(), W.Range);
                    W.Cast(p);
                    return;
                }

                if (useQ && Qline.IsReady() && (minions.Count() >= 2 || minions[0].Team == GameObjectTeam.Neutral))
                {
                    var positions = new Dictionary <Vector3, int>();

                    foreach (var soldier in SoldiersManager.AllSoldiers)
                    {
                        Qline.UpdateSourcePosition(soldier.Position, ObjectManager.Player.Position);
                        foreach (var minion in minions)
                        {
                            var hits = Qline.GetLineFarmLocation(minions).MinionsHit;
                            if (hits >= 2 || minions[0].Team == GameObjectTeam.Neutral)
                            {
                                if (!positions.ContainsKey(minion.Position))
                                {
                                    positions.Add(minion.Position, hits);
                                }
                            }
                        }
                    }

                    if (positions.Count > 0)
                    {
                        Qline.Cast(positions.MaxOrDefault(k => k.Value).Key);
                    }
                }
                return;
            }
        }
Example #3
0
        private bool CastQ(Obj_AI_Hero target)
        {
            Dictionary <SharpDX.Vector3, int> maxhit = (from hero in HeroManager.Enemies.Where(h => h.IsValidTarget() &&
                                                                                               !h.IsInvulnerable && Vector3.Distance(h.ServerPosition, player.ServerPosition) < Q.Range)
                                                        select Q.GetPrediction(hero) into prediction where prediction.CollisionObjects.Count > 0 &&
                                                        prediction.Hitchance >= HitChance.High let enemieshit = prediction.CollisionObjects.Where(x => x is Obj_AI_Hero) select prediction).ToDictionary(prediction => prediction.CastPosition, prediction => prediction.CollisionObjects.Count);

            var bestpair = maxhit.MaxOrDefault(x => x.Value);

            if (bestpair.Value > 0)
            {
                Vector3 bestpos = bestpair.Key;
                Q.Cast(bestpos);
                return(true);
            }


            var distbw = Vector3.Distance(player.ServerPosition, target.ServerPosition);

            if (distbw < Q.Range)
            {
                var prediction2 = Q.GetPrediction(target);
                if (prediction2.Hitchance >= HitChance.High)
                {
                    Q.Cast(prediction2.CastPosition);
                    return(true);
                }
            }

            if (distbw > Q.Range && distbw < Q.Range)
            {
                var testQ    = Q.GetPrediction(target);
                var collobjs = testQ.CollisionObjects;
                if ((testQ.Hitchance == HitChance.Collision || collobjs.Count > 0) && collobjs.All(x => x.IsTargetable))
                {
                    var pred = Q.GetPrediction(target);
                    if (pred.Hitchance >= HitChance.High)
                    {
                        Q.Cast(pred.CastPosition);
                        return(true);
                    }
                }
            }
            return(false);
        }
Example #4
0
    public static void ProvideCarrier(CarrierAnt ant)
    {
        GameObject go;
        int        requests;

        lock (_Sync)
        {
            _CarrierRequester.MaxOrDefault(out go, out requests);

            if (go == null || requests == 0)
            {
                _AvailableCarrierAnts++;

                Destroy(ant);
            }
            else
            {
                _CarrierRequester.SafelyDecrement(go);

                ant.Carry  = Bearables.None;
                ant.Target = go.transform;
            }
        }
    }
Example #5
0
        static void LaneClear()
        {
            var useQ = Menu.SubMenu("LaneClear").Item("UseQLC").GetValue<bool>();
            var useW = Menu.SubMenu("LaneClear").Item("UseWLC").GetValue<bool>();

            var minions = MinionManager.GetMinions(Q.Range);
            if(minions.Count == 0)
            {
                minions = MinionManager.GetMinions(Q.Range, MinionTypes.All, MinionTeam.Neutral, MinionOrderTypes.MaxHealth);
            }

            if (minions.Count > 0)
            {
                if (useW && W.Instance.Ammo > 0 && (minions.Count > 2 || minions[0].Team == GameObjectTeam.Neutral))
                {
                    var p = Player.Position.To2D().Extend(minions[0].Position.To2D(), W.Range);
                    W.Cast(p);
                    return;
                }

                if (useQ && Qline.IsReady() && (minions.Count >= 2 || minions[0].Team == GameObjectTeam.Neutral))
                {
                    var positions = new Dictionary<Vector3, int>();

                    foreach (var soldier in SoldiersManager.AllSoldiers)
                    {
                        Qline.UpdateSourcePosition(soldier.ServerPosition, ObjectManager.Player.ServerPosition);
                        foreach (var minion in minions)
                        {
                            var hits = Qline.CountHits(minions.Select(m => m.ServerPosition).ToList(), minion.ServerPosition);
                            if (hits >= 2 || minions[0].Team == GameObjectTeam.Neutral)
                            {
                                if(!positions.ContainsKey(minion.ServerPosition))
                                {
                                    positions.Add(minion.ServerPosition, hits);
                                }
                            }
                        }
                    }

                    if(positions.Count > 0)
                    {
                        Qline.Cast(positions.MaxOrDefault(k => k.Value).Key);
                    }
                }
                return;
            }
        }
Example #6
0
        // Token: 0x0600004A RID: 74 RVA: 0x0000FBAC File Offset: 0x0000DDAC
        private void GetAreaOfEffectPrediction(PredictionInput9 input, PredictionOutput9 output)
        {
            List <PredictionOutput9> targets             = new List <PredictionOutput9>();
            IEnumerable <Unit9>      areaOfEffectTargets = input.AreaOfEffectTargets;

            Func <Unit9, bool> < > 9__2;
            Func <Unit9, bool> predicate;

            if ((predicate = < > 9__2) == null)
            {
                predicate = (< > 9__2 = ((Unit9 x) => !x.Equals(output.Target)));
            }
            foreach (Unit9 target in areaOfEffectTargets.Where(predicate))
            {
                PredictionInput9 input2 = new PredictionInput9
                {
                    Target         = target,
                    Caster         = input.Caster,
                    Delay          = input.Delay,
                    Speed          = input.Speed,
                    CastRange      = input.CastRange,
                    Radius         = input.Radius,
                    RequiresToTurn = input.RequiresToTurn
                };
                PredictionOutput9 simplePrediction = this.GetSimplePrediction(input2);
                float             num = (input.SkillShotType == SkillShotType.Line) ? (input.Range + input.CastRange) : input.Range;
                if (input.Caster.Distance(simplePrediction.CastPosition) < num)
                {
                    targets.Add(simplePrediction);
                }
            }
            switch (input.SkillShotType)
            {
            case SkillShotType.AreaOfEffect:
                targets.Insert(0, output);
                output.CastPosition  = ((input.CastRange > 0f) ? input.Caster.InFront(input.CastRange, 0f, true) : input.Caster.Position);
                output.AoeTargetsHit = (from x in targets
                                        where output.CastPosition.IsInRange(x.TargetPosition, input.Radius)
                                        select x).ToList <PredictionOutput9>();
                return;

            case SkillShotType.RangedAreaOfEffect:
                targets.Insert(0, output);
                output.CastPosition  = input.Target.Position;
                output.AoeTargetsHit = (from x in targets
                                        where output.CastPosition.IsInRange(x.TargetPosition, input.Radius)
                                        select x).ToList <PredictionOutput9>();
                if (!output.AoeTargetsHit.Contains(output))
                {
                    output.AoeTargetsHit.Add(output);
                    return;
                }
                break;

            case SkillShotType.Line:
                targets.Insert(0, output);
                if (targets.Count > 1)
                {
                    Dictionary <Polygon.Rectangle, List <PredictionOutput9> > dictionary = new Dictionary <Polygon.Rectangle, List <PredictionOutput9> >();
                    if (input.UseBlink)
                    {
                        Vector3 targetPosition        = output.TargetPosition;
                        List <PredictionOutput9> list = targets.Skip(1).ToList <PredictionOutput9>();
                        using (List <PredictionOutput9> .Enumerator enumerator2 = list.GetEnumerator())
                        {
                            while (enumerator2.MoveNext())
                            {
                                PredictionOutput9 predictionOutput = enumerator2.Current;
                                Vector3           targetPosition2  = predictionOutput.TargetPosition;
                                Vector3           vector           = (targetPosition + targetPosition2) / 2f;
                                Vector3           vector2          = targetPosition.Extend2D(targetPosition2, -100f);
                                Vector3           end = vector2.Extend2D(targetPosition2, input.Range);
                                Polygon.Rectangle rec = new Polygon.Rectangle(vector2, end, input.Radius);
                                foreach (PredictionOutput9 predictionOutput2 in list)
                                {
                                    if (!(predictionOutput2.Target == predictionOutput.Target))
                                    {
                                        Vector3           to        = (vector + predictionOutput2.TargetPosition) / 2f;
                                        Vector3           vector3   = targetPosition.Extend2D(to, -100f);
                                        Vector3           end2      = vector3.Extend2D(to, input.Range);
                                        Polygon.Rectangle rectangle = new Polygon.Rectangle(vector3, end2, input.Radius + 50f);
                                        if (rectangle.IsInside(targetPosition2) && rectangle.IsInside(predictionOutput2.TargetPosition))
                                        {
                                            rec = rectangle;
                                        }
                                    }
                                }
                                dictionary[rec] = (from x in targets
                                                   where rec.IsInside(x.TargetPosition)
                                                   select x).ToList <PredictionOutput9>();
                            }
                            goto IL_C36;
                        }
                    }
                    Vector3 position = input.Caster.Position;
                    foreach (PredictionOutput9 predictionOutput3 in targets)
                    {
                        Vector3           end3 = position.Extend2D(predictionOutput3.TargetPosition, input.Range);
                        Polygon.Rectangle rec  = new Polygon.Rectangle(position, end3, input.Radius * 1.3f);
                        if (!rec.IsOutside(output.TargetPosition.To2D()))
                        {
                            dictionary[rec] = (from x in targets
                                               where rec.IsInside(x.TargetPosition)
                                               select x).ToList <PredictionOutput9>();
                        }
                    }
IL_C36:
                    KeyValuePair <Polygon.Rectangle, List <PredictionOutput9> > keyValuePair = dictionary.MaxOrDefault((KeyValuePair <Polygon.Rectangle, List <PredictionOutput9> > x) => x.Value.Count);
                    if (keyValuePair.Key != null)
                    {
                        List <PredictionOutput9> list2 = keyValuePair.Value.ToList <PredictionOutput9>();
                        Vector3 to2 = list2.Aggregate(default(Vector3), (Vector3 sum, PredictionOutput9 pos) => sum + pos.TargetPosition) / (float)list2.Count;
                        if (list2.Count == 0)
                        {
                            output.HitChance = HitChance.Impossible;
                            return;
                        }
                        float val = list2.Max(delegate(PredictionOutput9 x)
                        {
                            if (!input.UseBlink)
                            {
                                return(input.Caster.Distance(x.TargetPosition));
                            }
                            return(output.TargetPosition.Distance(x.TargetPosition));
                        });
                        float distance = Math.Min(input.UseBlink ? input.Range : input.CastRange, val);
                        output.CastPosition  = (input.UseBlink ? output.TargetPosition.Extend2D(to2, distance) : input.Caster.Position.Extend2D(to2, distance));
                        output.AoeTargetsHit = keyValuePair.Value;
                    }
                }
                else
                {
                    output.AoeTargetsHit.Add(output);
                    if (input.UseBlink)
                    {
                        input.AreaOfEffect = false;
                    }
                }
                if (input.UseBlink)
                {
                    output.BlinkLinePosition = ((input.Caster.Distance(output.TargetPosition) > input.CastRange) ? input.Caster.Position.Extend2D(output.TargetPosition, input.CastRange) : output.TargetPosition.Extend2D(output.CastPosition, -100f));
                    if (input.Caster.Distance(output.BlinkLinePosition) > input.CastRange)
                    {
                        output.HitChance = HitChance.Impossible;
                    }
                }
                break;

            case SkillShotType.Circle:
            {
                targets.Insert(0, output);
                if (targets.Count == 1)
                {
                    output.AoeTargetsHit.Add(output);
                    return;
                }
                Func <PredictionOutput9, bool> < > 9__4;
                Func <PredictionOutput9, float> < > 9__5;
                while (targets.Count > 1)
                {
                    MEC.MecCircle mec = MEC.GetMec((from x in targets
                                                    select x.TargetPosition.ToVector2()).ToList <Vector2>());
                    if (mec.Radius > 0f && mec.Radius < input.Radius && input.Caster.Distance(mec.Center.ToVector3(0f)) < input.Range)
                    {
                        output.CastPosition = new Vector3((targets.Count <= 2) ? ((targets[0].TargetPosition.ToVector2() + targets[1].TargetPosition.ToVector2()) / 2f) : mec.Center, output.CastPosition.Z);
                        PredictionOutput9 output2 = output;
                        IEnumerable <PredictionOutput9> targets3 = targets;
                        Func <PredictionOutput9, bool>  predicate2;
                        if ((predicate2 = < > 9__4) == null)
                        {
                            predicate2 = (< > 9__4 = ((PredictionOutput9 x) => output.CastPosition.IsInRange(x.TargetPosition, input.Radius)));
                        }
                        output2.AoeTargetsHit = targets3.Where(predicate2).ToList <PredictionOutput9>();
                        return;
                    }
                    IEnumerable <PredictionOutput9> targets2 = targets;
                    Func <PredictionOutput9, float> comparer;
                    if ((comparer = < > 9__5) == null)
                    {
                        comparer = (< > 9__5 = ((PredictionOutput9 x) => targets[0].TargetPosition.DistanceSquared(x.TargetPosition)));
                    }
                    PredictionOutput9 item = targets2.MaxOrDefault(comparer);
                    targets.Remove(item);
                    output.AoeTargetsHit.Add(output);
                }
                return;
            }

            case SkillShotType.Cone:
                targets.Insert(0, output);
                if (targets.Count > 1)
                {
                    Dictionary <Polygon.Trapezoid, List <PredictionOutput9> > dictionary2 = new Dictionary <Polygon.Trapezoid, List <PredictionOutput9> >();
                    if (input.UseBlink)
                    {
                        Vector3 targetPosition3        = output.TargetPosition;
                        List <PredictionOutput9> list3 = targets.Skip(1).ToList <PredictionOutput9>();
                        using (List <PredictionOutput9> .Enumerator enumerator2 = list3.GetEnumerator())
                        {
                            while (enumerator2.MoveNext())
                            {
                                PredictionOutput9 predictionOutput4 = enumerator2.Current;
                                Vector3           targetPosition4   = predictionOutput4.TargetPosition;
                                Vector3           vector4           = (targetPosition3 + targetPosition4) / 2f;
                                Vector3           vector5           = targetPosition3.Extend2D(targetPosition4, -100f);
                                Vector3           end4 = vector5.Extend2D(targetPosition4, input.Range);
                                Polygon.Trapezoid rec  = new Polygon.Trapezoid(vector5, end4, input.Radius, input.EndRadius);
                                foreach (PredictionOutput9 predictionOutput5 in list3)
                                {
                                    if (!(predictionOutput5.Target == predictionOutput4.Target))
                                    {
                                        Vector3           to3       = (vector4 + predictionOutput5.TargetPosition) / 2f;
                                        Vector3           vector6   = targetPosition3.Extend2D(to3, -100f);
                                        Vector3           end5      = vector6.Extend2D(to3, input.Range);
                                        Polygon.Trapezoid trapezoid = new Polygon.Trapezoid(vector6, end5, input.Radius + 50f, input.EndRadius + 50f);
                                        if (trapezoid.IsInside(targetPosition4) && trapezoid.IsInside(predictionOutput5.TargetPosition))
                                        {
                                            rec = trapezoid;
                                        }
                                    }
                                }
                                dictionary2[rec] = (from x in targets
                                                    where rec.IsInside(x.TargetPosition)
                                                    select x).ToList <PredictionOutput9>();
                            }
                            goto IL_751;
                        }
                    }
                    Vector3 position2 = input.Caster.Position;
                    foreach (PredictionOutput9 predictionOutput6 in targets)
                    {
                        Vector3           end6 = position2.Extend2D(predictionOutput6.TargetPosition, input.Range);
                        Polygon.Trapezoid rec  = new Polygon.Trapezoid(position2, end6, input.Radius * 1.4f, input.EndRadius * 1.8f);
                        if (!rec.IsOutside(output.TargetPosition.To2D()))
                        {
                            dictionary2[rec] = (from x in targets
                                                where rec.IsInside(x.TargetPosition)
                                                select x).ToList <PredictionOutput9>();
                        }
                    }
IL_751:
                    KeyValuePair <Polygon.Trapezoid, List <PredictionOutput9> > keyValuePair2 = dictionary2.MaxOrDefault((KeyValuePair <Polygon.Trapezoid, List <PredictionOutput9> > x) => x.Value.Count);
                    if (keyValuePair2.Key != null)
                    {
                        List <PredictionOutput9> list4 = keyValuePair2.Value.ToList <PredictionOutput9>();
                        Vector3 to4 = list4.Aggregate(default(Vector3), (Vector3 sum, PredictionOutput9 pos) => sum + pos.TargetPosition) / (float)list4.Count;
                        if (list4.Count == 0)
                        {
                            output.HitChance = HitChance.Impossible;
                            return;
                        }
                        float val2 = list4.Max(delegate(PredictionOutput9 x)
                        {
                            if (!input.UseBlink)
                            {
                                return(input.Caster.Distance(x.TargetPosition));
                            }
                            return(output.TargetPosition.Distance(x.TargetPosition));
                        });
                        float distance2 = Math.Min(input.UseBlink ? input.Range : input.CastRange, val2);
                        output.CastPosition  = (input.UseBlink ? output.TargetPosition.Extend2D(to4, distance2) : input.Caster.Position.Extend2D(to4, distance2));
                        output.AoeTargetsHit = keyValuePair2.Value;
                    }
                }
                else
                {
                    output.AoeTargetsHit.Add(output);
                    if (input.UseBlink)
                    {
                        input.AreaOfEffect = false;
                    }
                }
                if (input.UseBlink)
                {
                    output.BlinkLinePosition = ((input.Caster.Distance(output.TargetPosition) > input.CastRange) ? input.Caster.Position.Extend2D(output.TargetPosition, input.CastRange) : output.TargetPosition.Extend2D(output.CastPosition, -100f));
                    if (input.Caster.Distance(output.BlinkLinePosition) > input.CastRange)
                    {
                        output.HitChance = HitChance.Impossible;
                        return;
                    }
                }
                break;

            default:
                return;
            }
        }
        private void DrawHistory(Bitmap target, Dictionary <string, MonthActivities> history)
        {
            // Figure out when first activity started and when last activity ended (for the whole month)
            var firstTime = history.MinOrDefault(c => c.Value.Days.MinOrDefault(d => d.Value.First().StartSecond));
            var lastTime  = history.MaxOrDefault(c => c.Value.Days.MaxOrDefault(d => d.Value.Last().EndSecond));

            // Create list of programs used, the most used first
            var programs = history.SelectMany(c => c.Value.Days.Values.SelectMany(x => x.Where(a => a.WasActive)
                                                                                  .Select(a => new
            {
                Id      = c.Value.ApplicationNames[a.ApplicationNameIndex],
                Seconds = a.EndSecond - a.StartSecond
            })))
                           .GroupBy(z => z.Id).ToDictionary(x => x.Key, a => a.Sum(s => s.Seconds))
                           .OrderByDescending(x => x.Value);

            // Assign unique colors to the most used programs
            var brushLookup = programs.Zip(_programBrushes, (program, color) => new { program, color })
                              .ToDictionary(x => x.program.Key, x => x.color);
            var idleBrush = new SolidBrush(Color.Gray);

            _graphFirstSecond = firstTime;

            var graphicsObj = Graphics.FromImage(_historyGraph);
            var pen         = new Pen(Color.Olive, 1);

            _graphWidth   = (uint)(target.Width - 80);
            _graphSeconds = lastTime - firstTime;
            if (_graphSeconds == 0)
            {
                _graphSeconds = 1;
            }
            var daylineHeight = 2;

            // Draw hour lines
            var greypen   = new Pen(Color.LightGray, 1);
            var firstHour = (int)Math.Ceiling(firstTime / 3600.0);
            var lastHour  = (int)Math.Floor(lastTime / 3600.0);

            for (int x = firstHour; x <= lastHour; x++)
            {
                var xpixel = (((x * 3600) - firstTime) * _graphWidth) / _graphSeconds + GraphStartPixel;
                graphicsObj.DrawLine(greypen, xpixel, 10, xpixel, target.Height);
            }

            // Draw each day
            DaySlots.Clear();
            int currentY = GraphSpacing;

            foreach (var dayNumber in _indexToDaynumber)
            {
                DaySlots.Add(dayNumber, new List <ScreenSlot>());
                var dayHistory = history.Where(x => x.Value.Days.ContainsKey(dayNumber))
                                 .ToDictionary(x => x.Key, x => x.Value.Days[dayNumber]);

                // At what pixel is this day's first and last activities?
                var todaysFirstSecond = dayHistory.Min(x => x.Value.FirstActiveSecond);
                var todaysLastSecond  = dayHistory.Max(x => x.Value.LastActiveSecond);

                var startpixel = (todaysFirstSecond - firstTime) * _graphWidth / _graphSeconds;
                var endPixel   = (todaysLastSecond - firstTime) * _graphWidth / _graphSeconds;

                // Draw a small line representing the whole day
                var graphbox = new Rectangle((int)startpixel + GraphStartPixel,
                                             currentY + GraphHeight / 2 - daylineHeight / 2, (int)(endPixel - startpixel) + 1, daylineHeight);
                graphicsObj.DrawRectangle(pen, graphbox);

                var startz = dayHistory.SelectMany(x => x.Value)
                             .GroupBy(a => (a.StartSecond - firstTime) * _graphWidth / _graphSeconds)
                             .ToDictionary(x => x.Key, x => x.ToList());
                var endz = dayHistory.SelectMany(x => x.Value)
                           .GroupBy(a => (a.EndSecond - firstTime) * _graphWidth / _graphSeconds)
                           .ToDictionary(x => x.Key, x => x.ToList());
                var allPixels = startz.Keys.Concat(endz.Keys).Distinct()
                                .OrderBy(x => x).ToList();

                var activeActivities = new HashSet <ActivitySpan>();
                for (var index = 0; index < allPixels.Count - 1; index++)
                {
                    startpixel = allPixels[index];
                    endPixel   = allPixels[index + 1] - 0;
                    // Add new activities
                    if (startz.ContainsKey(startpixel))
                    {
                        activeActivities.AddRange(startz[startpixel]);
                    }
                    // Remove ending activities
                    if (endz.ContainsKey(startpixel))
                    {
                        foreach (var endedSpan in endz[startpixel])
                        {
                            activeActivities.Remove(endedSpan);
                        }
                    }

                    var span = new ScreenSlot(startpixel, endPixel, currentY, activeActivities);
                    DaySlots[dayNumber].Add(span);

                    // Select brush
                    Brush thisBrush;
                    if (!span.WasActive)
                    {
                        thisBrush = idleBrush;
                    }
                    else if (activeActivities.Count(x => x.WasActive) == 1)
                    {
                        thisBrush = ActivityBrush(activeActivities.Single(x => x.WasActive), brushLookup);
                    }
                    else
                    {
                        var colorList = activeActivities.Select(a => ActivityBrush(a, brushLookup).Color)
                                        .Distinct().OrderBy(x => x.Name).ToList();
                        var key = string.Join("|", colorList.Select(x => x.Name));
                        if (_textureBrushes.ContainsKey(key))
                        {
                            thisBrush = _textureBrushes[key];
                        }
                        else
                        {
                            var scale = 3;
                            var img   = new Bitmap(1, colorList.Count * scale);
                            var ix    = 0;
                            foreach (var color in colorList)
                            {
                                for (int i = 0; i < scale; i++)
                                {
                                    img.SetPixel(0, ix++, color);
                                }
                            }
                            thisBrush            = new TextureBrush(img);
                            _textureBrushes[key] = thisBrush;
                        }
                    }

                    // Draw
                    graphicsObj.FillRectangle(thisBrush, span.DrawBox);
                }

                currentY += GraphSpacing + GraphHeight;
            }
            graphicsObj.Dispose();
        }