Пример #1
0
        public void Export(string path, ScoreBook book)
        {
            SusArgs args  = CustomArgs;
            var     notes = book.Score.Notes;

            notes.Taps    = notes.Taps.Distinct().ToList();
            notes.DTaps   = notes.DTaps.Distinct().ToList();
            notes.HTaps   = notes.HTaps.Distinct().ToList();
            notes.LTaps   = notes.LTaps.Distinct().ToList();
            notes.Traces  = notes.Traces.Distinct().ToList();
            notes.DTraces = notes.DTraces.Distinct().ToList();
            notes.HTraces = notes.HTraces.Distinct().ToList();
            notes.LTraces = notes.LTraces.Distinct().ToList();
            notes.Holds   = notes.Holds.Distinct().ToList();
            notes.DHolds  = notes.DHolds.Distinct().ToList();
            notes.HHolds  = notes.HHolds.Distinct().ToList();
            notes.LHolds  = notes.LHolds.Distinct().ToList();

            using (var writer = new StreamWriter(path))
            {
                writer.WriteLine("#TITLE \"{0}\"", book.Title);
                writer.WriteLine("#ARTIST \"{0}\"", book.ArtistName);
                writer.WriteLine("#DESIGNER \"{0}\"", book.NotesDesignerName);
                writer.WriteLine("#DIFFICULTY {0}", (int)args.PlayDifficulty + (string.IsNullOrEmpty(args.ExtendedDifficulty) ? "" : ":" + args.ExtendedDifficulty));
                writer.WriteLine("#PLAYLEVEL {0}", args.PlayLevel);
                writer.WriteLine("#WAVE \"{0}\"", args.SoundFileName);
                writer.WriteLine("#WAVEOFFSET {0}", args.SoundOffset);

                writer.WriteLine();

                int barTick            = book.Score.TicksPerBeat * 4;
                var barIndexCalculator = new BarIndexCalculator(barTick, book.Score.Events.TimeSignatureChangeEvents, args.HasPaddingBar);

                foreach (var item in barIndexCalculator.TimeSignatures)
                {
                    writer.WriteLine("#{0:000}02: {1}", item.StartBarIndex + (args.HasPaddingBar && item.StartBarIndex == 1 ? -1 : 0), 4f * item.TimeSignature.Numerator / item.TimeSignature.Denominator);
                }

                writer.WriteLine();

                var bpmlist = book.Score.Events.BPMChangeEvents
                              .GroupBy(p => p.BPM)
                              .SelectMany((p, i) => p.Select(q => new { Index = i, Value = q, BarPosition = barIndexCalculator.GetBarPositionFromTick(q.Tick) }))
                              .ToList();

                if (bpmlist.Count >= 36 * 36)
                {
                    throw new ArgumentException("BPM定義数が上限を超えました。");
                }

                var bpmIdentifiers = EnumerateIdentifiers(2).Skip(1).Take(bpmlist.Count).ToList();
                foreach (var item in bpmlist.GroupBy(p => p.Index).Select(p => p.First()))
                {
                    writer.WriteLine("#BPM{0}: {1}", bpmIdentifiers[item.Index], item.Value.BPM);
                }

                if (args.HasPaddingBar)
                {
                    writer.WriteLine("#{0:000}08: {1:x2}", 0, bpmIdentifiers[bpmlist.OrderBy(p => p.Value.Tick).First().Index]);
                }

                foreach (var eventInBar in bpmlist.GroupBy(p => p.BarPosition.BarIndex))
                {
                    var sig       = barIndexCalculator.GetTimeSignatureFromBarIndex(eventInBar.Key);
                    int barLength = barTick * sig.Numerator / sig.Denominator;
                    var dic       = eventInBar.ToDictionary(p => p.BarPosition.TickOffset, p => p);
                    int gcd       = eventInBar.Select(p => p.BarPosition.TickOffset).Aggregate(barLength, (p, q) => GetGcd(p, q));
                    writer.Write("#{0:000}08: ", eventInBar.Key);
                    for (int i = 0; i *gcd < barLength; i++)
                    {
                        int tickOffset = i * gcd;
                        writer.Write(dic.ContainsKey(tickOffset) ? bpmIdentifiers[dic[tickOffset].Index] : "00");
                    }
                    writer.WriteLine();
                }

                writer.WriteLine();

                foreach (var EventVar in book.Score.Events.HighSpeedChangeEvents)
                {
                    var barPos = barIndexCalculator.GetBarPositionFromTick(EventVar.Tick);
                    writer.Write("#{0:000}07: ", barPos.BarIndex);
                    writer.WriteLine(EventVar.SpeedRatio);
                }

                foreach (var EventVar in book.Score.Events.SplitLaneEvents)
                {
                    var barPos = barIndexCalculator.GetBarPositionFromTick(EventVar.Tick);
                    writer.Write("#{0:000}05: ", barPos.BarIndex);
                    writer.WriteLine(EventVar.ToString().ToCharArray());
                }

                writer.WriteLine();

                var shortNotes = notes.Taps.Cast <TappableBase>().Select(p => new { Type = '1', Note = p })
                                 .Concat(notes.DTaps.Cast <TappableBase>().Select(p => new { Type = '2', Note = p }))
                                 .Concat(notes.HTaps.Cast <TappableBase>().Select(p => new { Type = '3', Note = p }))
                                 .Concat(notes.LTaps.Cast <TappableBase>().Select(p => new { Type = '4', Note = p }))
                                 .Concat(notes.Traces.Cast <TappableBase>().Select(p => new { Type = '5', Note = p }))
                                 .Concat(notes.DTraces.Cast <TappableBase>().Select(p => new { Type = '6', Note = p }))
                                 .Concat(notes.HTraces.Cast <TappableBase>().Select(p => new { Type = '7', Note = p }))
                                 .Concat(notes.LTraces.Cast <TappableBase>().Select(p => new { Type = '8', Note = p }))
                                 .Concat(notes.Flicks.Cast <TappableBase>().Select(p => new { Type = '9', Note = p }))
                                 .Concat(notes.Damages.Cast <TappableBase>().Select(p => new { Type = 'A', Note = p }))
                                 .Select(p => new
                {
                    BarPosition = barIndexCalculator.GetBarPositionFromTick(p.Note.Tick),
                    LaneIndex   = p.Note.LaneIndex,
                    Width       = p.Note.Width,
                    Type        = p.Type
                });

                foreach (var notesInBar in shortNotes.GroupBy(p => p.BarPosition.BarIndex))
                {
                    foreach (var notesInLane in notesInBar.GroupBy(p => p.LaneIndex))
                    {
                        var sig       = barIndexCalculator.GetTimeSignatureFromBarIndex(notesInBar.Key);
                        int barLength = barTick * sig.Numerator / sig.Denominator;

                        var offsetList     = notesInLane.GroupBy(p => p.BarPosition.TickOffset).Select(p => p.ToList());
                        var separatedNotes = Enumerable.Range(0, offsetList.Max(p => p.Count)).Select(p => offsetList.Where(q => q.Count >= p + 1).Select(q => q[p]));

                        foreach (var dic in separatedNotes.Select(p => p.ToDictionary(q => q.BarPosition.TickOffset, q => q)))
                        {
                            int gcd = dic.Values.Select(p => p.BarPosition.TickOffset).Aggregate(barLength, (p, q) => GetGcd(p, q));
                            writer.Write("#{0:000}1{1}:", notesInBar.Key, notesInLane.Key.ToString("x"));
                            for (int i = 0; i *gcd < barLength; i++)
                            {
                                int tickOffset = i * gcd;
                                writer.Write(dic.ContainsKey(tickOffset) ? dic[tickOffset].Type + ToLaneWidthString(dic[tickOffset].Width) : "00");
                            }
                            writer.WriteLine();
                        }
                    }
                }

                var identifier = new IdentifierAllocationManager();

                var holds = book.Score.Notes.Holds
                            .OrderBy(p => p.StartTick)
                            .Select(p => new
                {
                    Identifier = identifier.Allocate(p.StartTick, p.Duration),
                    StartTick  = p.StartTick,
                    EndTick    = p.StartTick + p.Duration,
                    Width      = p.Width,
                    LaneIndex  = p.LaneIndex
                });

                foreach (var hold in holds)
                {
                    var startBarPosition = barIndexCalculator.GetBarPositionFromTick(hold.StartTick);
                    var endBarPosition   = barIndexCalculator.GetBarPositionFromTick(hold.EndTick);
                    if (startBarPosition.BarIndex == endBarPosition.BarIndex)
                    {
                        var sig       = barIndexCalculator.GetTimeSignatureFromBarIndex(startBarPosition.BarIndex);
                        int barLength = barTick * sig.Numerator / sig.Denominator;
                        writer.Write("#{0:000}2{1}{2}:", startBarPosition.BarIndex, hold.LaneIndex.ToString("x"), hold.Identifier);
                        int gcd = GetGcd(GetGcd(startBarPosition.TickOffset, endBarPosition.TickOffset), barLength);
                        for (int i = 0; i *gcd < barLength; i++)
                        {
                            int tickOffset = i * gcd;
                            if (startBarPosition.TickOffset == tickOffset)
                            {
                                writer.Write("1" + ToLaneWidthString(hold.Width));
                            }
                            else if (endBarPosition.TickOffset == tickOffset)
                            {
                                writer.Write("2" + ToLaneWidthString(hold.Width));
                            }
                            else
                            {
                                writer.Write("00");
                            }
                        }
                        writer.WriteLine();
                    }
                    else
                    {
                        var startSig       = barIndexCalculator.GetTimeSignatureFromBarIndex(startBarPosition.BarIndex);
                        int startBarLength = barTick * startSig.Numerator / startSig.Denominator;
                        writer.Write("#{0:000}2{1}{2}:", startBarPosition.BarIndex, hold.LaneIndex.ToString("x"), hold.Identifier);
                        int gcd = GetGcd(startBarPosition.TickOffset, startBarLength);
                        for (int i = 0; i *gcd < startBarLength; i++)
                        {
                            int tickOffset = i * gcd;
                            if (startBarPosition.TickOffset == tickOffset)
                            {
                                writer.Write("1" + ToLaneWidthString(hold.Width));
                            }
                            else
                            {
                                writer.Write("00");
                            }
                        }
                        writer.WriteLine();

                        var endSig       = barIndexCalculator.GetTimeSignatureFromBarIndex(endBarPosition.BarIndex);
                        int endBarLength = barTick * endSig.Numerator / endSig.Denominator;
                        writer.Write("#{0:000}2{1}{2}:", endBarPosition.BarIndex, hold.LaneIndex.ToString("x"), hold.Identifier);
                        gcd = GetGcd(endBarPosition.TickOffset, endBarLength);
                        for (int i = 0; i *gcd < endBarLength; i++)
                        {
                            int tickOffset = i * gcd;
                            if (endBarPosition.TickOffset == tickOffset)
                            {
                                writer.Write("2" + ToLaneWidthString(hold.Width));
                            }
                            else
                            {
                                writer.Write("00");
                            }
                        }
                        writer.WriteLine();
                    }
                }

                var identifier2 = new IdentifierAllocationManager();

                var dholds = book.Score.Notes.DHolds
                             .OrderBy(p => p.StartTick)
                             .Select(p => new
                {
                    Identifier2 = identifier2.Allocate(p.StartTick, p.Duration),
                    StartTick   = p.StartTick,
                    EndTick     = p.StartTick + p.Duration,
                    Width       = p.Width,
                    LaneIndex   = p.LaneIndex
                });
                foreach (var dhold in dholds)
                {
                    var startBarPosition = barIndexCalculator.GetBarPositionFromTick(dhold.StartTick);
                    var endBarPosition   = barIndexCalculator.GetBarPositionFromTick(dhold.EndTick);
                    if (startBarPosition.BarIndex == endBarPosition.BarIndex)
                    {
                        var sig       = barIndexCalculator.GetTimeSignatureFromBarIndex(startBarPosition.BarIndex);
                        int barLength = barTick * sig.Numerator / sig.Denominator;
                        writer.Write("#{0:000}3{1}{2}:", startBarPosition.BarIndex, dhold.LaneIndex.ToString("x"), dhold.Identifier2);
                        int gcd = GetGcd(GetGcd(startBarPosition.TickOffset, endBarPosition.TickOffset), barLength);
                        for (int i = 0; i *gcd < barLength; i++)
                        {
                            int tickOffset = i * gcd;
                            if (startBarPosition.TickOffset == tickOffset)
                            {
                                writer.Write("1" + ToLaneWidthString(dhold.Width));
                            }
                            else if (endBarPosition.TickOffset == tickOffset)
                            {
                                writer.Write("2" + ToLaneWidthString(dhold.Width));
                            }
                            else
                            {
                                writer.Write("00");
                            }
                        }
                        writer.WriteLine();
                    }
                    else
                    {
                        var startSig       = barIndexCalculator.GetTimeSignatureFromBarIndex(startBarPosition.BarIndex);
                        int startBarLength = barTick * startSig.Numerator / startSig.Denominator;
                        writer.Write("#{0:000}3{1}{2}:", startBarPosition.BarIndex, dhold.LaneIndex.ToString("x"), dhold.Identifier2);
                        int gcd = GetGcd(startBarPosition.TickOffset, startBarLength);
                        for (int i = 0; i *gcd < startBarLength; i++)
                        {
                            int tickOffset = i * gcd;
                            if (startBarPosition.TickOffset == tickOffset)
                            {
                                writer.Write("1" + ToLaneWidthString(dhold.Width));
                            }
                            else
                            {
                                writer.Write("00");
                            }
                        }
                        writer.WriteLine();

                        var endSig       = barIndexCalculator.GetTimeSignatureFromBarIndex(endBarPosition.BarIndex);
                        int endBarLength = barTick * endSig.Numerator / endSig.Denominator;
                        writer.Write("#{0:000}3{1}{2}:", endBarPosition.BarIndex, dhold.LaneIndex.ToString("x"), dhold.Identifier2);
                        gcd = GetGcd(endBarPosition.TickOffset, endBarLength);
                        for (int i = 0; i *gcd < endBarLength; i++)
                        {
                            int tickOffset = i * gcd;
                            if (endBarPosition.TickOffset == tickOffset)
                            {
                                writer.Write("2" + ToLaneWidthString(dhold.Width));
                            }
                            else
                            {
                                writer.Write("00");
                            }
                        }
                        writer.WriteLine();
                    }
                }

                var identifier3 = new IdentifierAllocationManager();

                var hholds = book.Score.Notes.DHolds
                             .OrderBy(p => p.StartTick)
                             .Select(p => new
                {
                    Identifier3 = identifier3.Allocate(p.StartTick, p.Duration),
                    StartTick   = p.StartTick,
                    EndTick     = p.StartTick + p.Duration,
                    Width       = p.Width,
                    LaneIndex   = p.LaneIndex
                });
                foreach (var hhold in hholds)
                {
                    var startBarPosition = barIndexCalculator.GetBarPositionFromTick(hhold.StartTick);
                    var endBarPosition   = barIndexCalculator.GetBarPositionFromTick(hhold.EndTick);
                    if (startBarPosition.BarIndex == endBarPosition.BarIndex)
                    {
                        var sig       = barIndexCalculator.GetTimeSignatureFromBarIndex(startBarPosition.BarIndex);
                        int barLength = barTick * sig.Numerator / sig.Denominator;
                        writer.Write("#{0:000}4{1}{2}:", startBarPosition.BarIndex, hhold.LaneIndex.ToString("x"), hhold.Identifier3);
                        int gcd = GetGcd(GetGcd(startBarPosition.TickOffset, endBarPosition.TickOffset), barLength);
                        for (int i = 0; i *gcd < barLength; i++)
                        {
                            int tickOffset = i * gcd;
                            if (startBarPosition.TickOffset == tickOffset)
                            {
                                writer.Write("1" + ToLaneWidthString(hhold.Width));
                            }
                            else if (endBarPosition.TickOffset == tickOffset)
                            {
                                writer.Write("2" + ToLaneWidthString(hhold.Width));
                            }
                            else
                            {
                                writer.Write("00");
                            }
                        }
                        writer.WriteLine();
                    }
                    else
                    {
                        var startSig       = barIndexCalculator.GetTimeSignatureFromBarIndex(startBarPosition.BarIndex);
                        int startBarLength = barTick * startSig.Numerator / startSig.Denominator;
                        writer.Write("#{0:000}4{1}{2}:", startBarPosition.BarIndex, hhold.LaneIndex.ToString("x"), hhold.Identifier3);
                        int gcd = GetGcd(startBarPosition.TickOffset, startBarLength);
                        for (int i = 0; i *gcd < startBarLength; i++)
                        {
                            int tickOffset = i * gcd;
                            if (startBarPosition.TickOffset == tickOffset)
                            {
                                writer.Write("1" + ToLaneWidthString(hhold.Width));
                            }
                            else
                            {
                                writer.Write("00");
                            }
                        }
                        writer.WriteLine();

                        var endSig       = barIndexCalculator.GetTimeSignatureFromBarIndex(endBarPosition.BarIndex);
                        int endBarLength = barTick * endSig.Numerator / endSig.Denominator;
                        writer.Write("#{0:000}4{1}{2}:", endBarPosition.BarIndex, hhold.LaneIndex.ToString("x"), hhold.Identifier3);
                        gcd = GetGcd(endBarPosition.TickOffset, endBarLength);
                        for (int i = 0; i *gcd < endBarLength; i++)
                        {
                            int tickOffset = i * gcd;
                            if (endBarPosition.TickOffset == tickOffset)
                            {
                                writer.Write("2" + ToLaneWidthString(hhold.Width));
                            }
                            else
                            {
                                writer.Write("00");
                            }
                        }
                        writer.WriteLine();
                    }

                    identifier.Clear();
                }

                var identifier4 = new IdentifierAllocationManager();

                var lholds = book.Score.Notes.DHolds
                             .OrderBy(p => p.StartTick)
                             .Select(p => new
                {
                    Identifier4 = identifier4.Allocate(p.StartTick, p.Duration),
                    StartTick   = p.StartTick,
                    EndTick     = p.StartTick + p.Duration,
                    Width       = p.Width,
                    LaneIndex   = p.LaneIndex
                });
                foreach (var lhold in lholds)
                {
                    var startBarPosition = barIndexCalculator.GetBarPositionFromTick(lhold.StartTick);
                    var endBarPosition   = barIndexCalculator.GetBarPositionFromTick(lhold.EndTick);
                    if (startBarPosition.BarIndex == endBarPosition.BarIndex)
                    {
                        var sig       = barIndexCalculator.GetTimeSignatureFromBarIndex(startBarPosition.BarIndex);
                        int barLength = barTick * sig.Numerator / sig.Denominator;
                        writer.Write("#{0:000}5{1}{2}:", startBarPosition.BarIndex, lhold.LaneIndex.ToString("x"), lhold.Identifier4);
                        int gcd = GetGcd(GetGcd(startBarPosition.TickOffset, endBarPosition.TickOffset), barLength);
                        for (int i = 0; i *gcd < barLength; i++)
                        {
                            int tickOffset = i * gcd;
                            if (startBarPosition.TickOffset == tickOffset)
                            {
                                writer.Write("1" + ToLaneWidthString(lhold.Width));
                            }
                            else if (endBarPosition.TickOffset == tickOffset)
                            {
                                writer.Write("2" + ToLaneWidthString(lhold.Width));
                            }
                            else
                            {
                                writer.Write("00");
                            }
                        }
                        writer.WriteLine();
                    }
                    else
                    {
                        var startSig       = barIndexCalculator.GetTimeSignatureFromBarIndex(startBarPosition.BarIndex);
                        int startBarLength = barTick * startSig.Numerator / startSig.Denominator;
                        writer.Write("#{0:000}5{1}{2}:", startBarPosition.BarIndex, lhold.LaneIndex.ToString("x"), lhold.Identifier4);
                        int gcd = GetGcd(startBarPosition.TickOffset, startBarLength);
                        for (int i = 0; i *gcd < startBarLength; i++)
                        {
                            int tickOffset = i * gcd;
                            if (startBarPosition.TickOffset == tickOffset)
                            {
                                writer.Write("1" + ToLaneWidthString(lhold.Width));
                            }
                            else
                            {
                                writer.Write("00");
                            }
                        }
                        writer.WriteLine();

                        var endSig       = barIndexCalculator.GetTimeSignatureFromBarIndex(endBarPosition.BarIndex);
                        int endBarLength = barTick * endSig.Numerator / endSig.Denominator;
                        writer.Write("#{0:000}5{1}{2}:", endBarPosition.BarIndex, lhold.LaneIndex.ToString("x"), lhold.Identifier4);
                        gcd = GetGcd(endBarPosition.TickOffset, endBarLength);
                        for (int i = 0; i *gcd < endBarLength; i++)
                        {
                            int tickOffset = i * gcd;
                            if (endBarPosition.TickOffset == tickOffset)
                            {
                                writer.Write("2" + ToLaneWidthString(lhold.Width));
                            }
                            else
                            {
                                writer.Write("00");
                            }
                        }
                        writer.WriteLine();
                    }
                }
                identifier.Clear();
                identifier2.Clear();
                identifier3.Clear();
                identifier4.Clear();
            }
        }
Пример #2
0
 /// <summary>Dispatch a SmartEvent specified by the caller.</summary>
 public void DispatchEvent(EventVar e)
 {
     e.Dispatch();
 }
Пример #3
0
        public static History StartHistory(int years)
        {
            const bool DISPLAY = true;
            EventList  el      = new EventList();
            History    h       = new History();

            h.Map = new Map(@"Dependencies\Maps\NewMap.png");

            Console.Clear();
            if (DISPLAY)
            {
                Console.Clear();
                Console.WriteLine("Year: ");
                Console.WriteLine("Event: ");
            }
            List <Race>    races    = new List <Race>();
            List <Faction> factions = new List <Faction>();

            for (int i = 0; i < Race.RacesAmount(); i++)
            {
                races.Add(new Race(i, new Random().Next(30000)));
            }

            Random rand = new Random();

            for (int i = 0; i < races.Count; i++)
            {
                Race  race = races[i];
                int[] vals = race.GetVals();
                factions.Add(new Faction(races[i], "Main City: " + race.Name));
                int mainCityInd = factions.Count - 1;
                for (int j = 0; j <= vals[3]; j++)
                {
                    int num = rand.Next(100);
                    if (num < 80)
                    {
                        factions[mainCityInd].Pop++;
                        num = 101;
                    }
                    if (num < 95)
                    {
                        bool   done  = false;
                        Random rand2 = new Random();
                        while (!done)
                        {
                            int     num2 = rand2.Next(factions.Count);
                            Faction f    = factions[num2];
                            if (f.Race == race)
                            {
                                done = true;
                                factions[num2].Pop++;
                            }
                        }
                        num = 101;
                    }
                    if (num < 100)
                    {
                        bool    exists = false;
                        Faction f      = new Faction(race);
                        for (int k = 0; k < factions.Count; k++)
                        {
                            if (factions[k].Name == f.Name)
                            {
                                exists = true;
                                factions[k].Pop++;
                            }
                        }
                        if (!exists)
                        {
                            factions.Add(new Faction(race));
                            factions[factions.Count - 1].Pop++;
                        }
                    }
                }
            }

            int    totalPeople        = 0;
            double averagePopSeverity = 0;

            while (factions.Count >= h.Map.GetLandCount())
            {
                double avePop = 0;
                foreach (Faction f in factions.ToArray())
                {
                    avePop += f.Pop;
                }
                avePop /= factions.Count;
                foreach (Faction f in factions.ToArray())
                {
                    if (f.Pop < avePop - avePop / 2)
                    {
                        factions.Remove(f);
                    }
                }
            }
            foreach (Faction fac in factions.ToArray())
            {
                h.Map.InitFaction(fac);
            }
            for (int i = 0; i <= years; i++)
            {
                if (DISPLAY)
                {
                    Console.SetCursorPosition(6, 0);
                    Console.Write("                ");
                    Console.SetCursorPosition(6, 0);
                    Console.Write(i);
                }
                totalPeople        = 0;
                averagePopSeverity = 0;
                foreach (Faction f in factions)
                {
                    totalPeople += f.Pop;
                }
                foreach (Faction f in factions)
                {
                    f.PopSeverity       = (double)f.Pop / totalPeople;
                    averagePopSeverity += f.PopSeverity;
                }
                averagePopSeverity /= factions.Count;
                #region events
                int chainAmount = 0;
                for (int j = 0; j < factions.Count; j++)
                {
                    Faction f = factions[j];
                    do
                    {
                        Event    newEvent = new Event(el);
                        EventVar e        = newEvent.Chosen;
                        if (DISPLAY)
                        {
                            Console.SetCursorPosition(7, 1);
                            Console.Write("                ");
                            Console.SetCursorPosition(7, 1);
                            Console.Write(e.Name);
                        }
                        switch (e.Name)
                        {
                            #region none
                        case "None":
                            break;

                            #endregion
                            #region chain event
                        case "Chain Event":
                            chainAmount += 3;
                            break;

                            #endregion
                            #region famine
                        case "Famine":
                            int    deathChance = new Random().Next(70);
                            Random rando       = new Random();
                            f.Pop -= Convert.ToInt32(f.Pop * (deathChance / 100.0));
                            if (deathChance < 10)
                            {
                                f.HistoricalEvents.Add(new HistoricalEvent("slight famine", i));
                                break;
                            }
                            if (deathChance < 30)
                            {
                                f.HistoricalEvents.Add(new HistoricalEvent("mild famine", i));
                                break;
                            }
                            if (deathChance < 70)
                            {
                                f.HistoricalEvents.Add(new HistoricalEvent("severe famine", i));
                                break;
                            }
                            if (deathChance < 100)
                            {
                                f.HistoricalEvents.Add(new HistoricalEvent("extreme famine", i));
                                break;
                            }
                            break;

                            #endregion
                            #region popup
                        case "Population Up":
                            int percentUp = new Random().Next(1, 20);
                            f.Pop += Convert.ToInt32(f.Pop * (percentUp / 100.0));
                            break;

                            #endregion
                            #region popdown
                        case "Population Down":
                            int percentDown = new Random().Next(1, 10);
                            f.Pop += Convert.ToInt32(f.Pop * (percentDown / 100.0));
                            break;

                            #endregion
                        case "War Declaration":
                            bool canFind = false;
                            for (int k = 0; k < factions.Count; k++)
                            {
                                if (factions[k].Race != f.Race && factions[k] != f && f.Pop > factions[k].Pop / 2 && f.Pop < factions[k].Pop * 2)
                                {
                                    canFind = true;
                                }
                            }
                            if (!canFind)
                            {
                                break;
                            }
                            bool    doneFinding = false;
                            Faction opp         = new Faction(new Race(0, 0));
                            while (!doneFinding)
                            {
                                int num = rand.Next(factions.Count);
                                opp = factions[num];
                                if (opp.Race != f.Race && opp != f && f.Pop > opp.Pop / 2 && f.Pop < opp.Pop * 2)
                                {
                                    doneFinding = true;
                                }
                            }
                            f.Wars.Add(new War(i, f, opp));
                            break;

                        case "Discovery":
                            break;

                        case "New Faction":
                            int     breakOff   = HelperClasses.RandomNumber(1, f.Pop);
                            Faction newFaction = new Faction(f.Race);
                            newFaction.Pop += breakOff;
                            f.Pop          -= breakOff;
                            factions.Add(newFaction);
                            newFaction.HistoricalEvents.Add(new HistoricalEvent("Broke off from " + f.Name, i));
                            h.Map.InitFaction(newFaction);
                            if (DISPLAY)
                            {
                                Console.SetCursorPosition(0, 3);
                                Console.Write("                                                                      ");
                                Console.SetCursorPosition(0, 3);
                                Console.Write("{0} has been created!", newFaction.Name);
                            }
                            break;

                            #region default
                        default:
                            Console.Clear();
                            Console.WriteLine("An unknown event has occured, event name: {0}", e.Name);
                            Console.ReadKey();
                            break;
                            #endregion
                        }
                        chainAmount--;
                    } while (chainAmount > 0);
                    #region pophandling
                    int popNum = Convert.ToInt32(f.PopSeverity * 100000);
                    if (popNum > 0)
                    {
                        int avePopNum  = Convert.ToInt32(averagePopSeverity * 100000);
                        int popRand    = HelperClasses.RandomNumber(0, popNum);
                        int avePopRand = HelperClasses.RandomNumber(0, avePopNum);
                        if (popRand > avePopNum)
                        {
                            foreach (EventVar ev in el.Events)
                            {
                                ev.Chance += ev.Rate;
                                ev.ChanceCheck();
                            }
                        }
                        else
                        {
                            foreach (EventVar ev in el.Events)
                            {
                                ev.Chance = ev.DefChance;
                            }
                        }
                    }
                    #endregion
                }
                #endregion
                #region warhandling
                for (int j = 0; j < factions.Count; j++)
                {
                    Faction    f     = factions[j];
                    bool       inWar = false;
                    List <War> wars  = new List <War>();
                    foreach (War w in f.Wars)
                    {
                        if (w.OnGoing)
                        {
                            inWar = true;
                            wars.Add(w);
                        }
                    }
                    if (inWar)
                    {
                        for (int k = 0; k < wars.Count; k++)
                        {
                            Faction  warWith = wars[k].Side2;
                            WarEvent we      = new WarEvent();
                            int      num1;
                            int      num2;
                            switch (we.Name)
                            {
                            case "None":
                                wars[k].Length++;
                                break;

                            case "Attack":
                                for (int l = 0; l < f.Pop + warWith.Pop; l++)
                                {
                                    num1 = HelperClasses.RandomNumber(0, f.Race.GetVals()[2] + (f.Race.GetVals()[1] / 2) + f.Race.GetVals()[0]);
                                    num2 = HelperClasses.RandomNumber(0, warWith.Race.GetVals()[1] + (warWith.Race.GetVals()[2] / 2) + warWith.Race.GetVals()[0]);
                                    if (num1 >= num2)
                                    {
                                        warWith.Pop--;
                                    }
                                    else
                                    {
                                        f.Pop--;
                                    }
                                }
                                wars[k].Length++;
                                break;

                            case "Defend":
                                for (int l = 0; l < f.Pop + warWith.Pop; l++)
                                {
                                    num1 = HelperClasses.RandomNumber(0, warWith.Race.GetVals()[1] + (warWith.Race.GetVals()[2] / 2) + warWith.Race.GetVals()[0]);
                                    num2 = HelperClasses.RandomNumber(0, f.Race.GetVals()[2] + (f.Race.GetVals()[1] / 2) + f.Race.GetVals()[0]);
                                    if (num1 >= num2)
                                    {
                                        f.Pop--;
                                    }
                                    else
                                    {
                                        warWith.Pop--;
                                    }
                                }
                                wars[k].Length++;
                                break;

                            case "End War":
                                wars[k].OnGoing = false;
                                f.HistoricalEvents.Add(new HistoricalEvent(string.Format("At war with {0} for {1} years", wars[k].Side2, wars[k].Length), i));
                                break;

                            default:
                                Console.Clear();
                                Console.WriteLine("An unknown event has occured, name: {0}", we.Name);
                                Console.ReadKey();
                                break;
                            }
                        }
                    }
                }
                if (i == years - 1)
                {
                    foreach (Faction fac in factions.ToArray())
                    {
                        List <War> wars = new List <War>(fac.Wars);
                        if (wars.Count != 0)
                        {
                            foreach (War w in wars.ToArray())
                            {
                                if (!w.OnGoing)
                                {
                                    wars.Remove(w);
                                }
                            }
                            foreach (War w in wars)
                            {
                                fac.HistoricalEvents.Add(new HistoricalEvent(String.Format("At war with {0} since {1}", w.Side2, w.StartYear), w.StartYear));
                            }
                        }
                    }
                }
                bool exists;
                foreach (Tile t in h.Map.Tiles)
                {
                    exists = false;
                    foreach (Faction fac in factions)
                    {
                        if (fac == t.Occ || t.Type == "W")
                        {
                            exists = true;
                        }
                    }
                    if (!exists)
                    {
                        t.Occ  = null;
                        t.Type = "L";
                    }
                }
                for (int i1 = 0; i1 < factions.Count; i1++)
                {
                    Faction f = factions[i1];
                    if (f.Pop <= 0)
                    {
                        factions.Remove(f);
                        if (DISPLAY)
                        {
                            Console.SetCursorPosition(0, 2);
                            Console.Write("                                                                      ");
                            Console.SetCursorPosition(0, 2);
                            Console.Write("{0} has fallen!", f.Name);
                        }
                    }
                }
                #endregion
                HelperClasses.form.LoadMap(h.Map);
            }

            h.Races    = races;
            h.Factions = factions;
            return(h);
        }