Exemplo n.º 1
0
        /// <summary>
        /// Initializes the Level.
        /// </summary>
        /// <param name="randomSeed">Randomizer Seed</param>
        /// <param name="slots">List of Slots</param>
        public void Init(int randomSeed, params LevelSlot[] slots)
        {
            // Init only allowed in Uninit-Mode.
            if (Mode != LevelMode.Uninit)
            {
                throw new NotSupportedException("Level is not ready for init");
            }

            // Initialize the Randomizer.
            RandomSeed = (int)DateTime.Now.Ticks;
            if (randomSeed != 0)
            {
                RandomSeed = randomSeed;
            }

            // Generate the Simulation Context for this Level.
            Context = new SimulationContext(
                Context.Resolver,
                Context.Settings,
                new Random(RandomSeed));

            // Check for the right number of Slots.
            if (slots.Length > MAX_SLOTS)
            {
                var exception = new ArgumentOutOfRangeException("There are too many Slots");
                SetMode(LevelMode.InitFailed, exception);
                throw exception;
            }

            // Generate Engine
            engine = new Engine(Context.Resolver);

            // Generate Map and validate.
            Map map = GetMap();

            if (map == null)
            {
                var exception = new NotSupportedException("No Map was created");
                SetMode(LevelMode.InitFailed, exception);
                throw exception;
            }
            map.CheckMap();

            int minPlayer = LevelDescription.MinPlayerCount;
            int maxPlayer = LevelDescription.MaxPlayerCount;

            // TODO: Ermitteln der Filter Attribute
            //object[] levelFilters = GetType().GetCustomAttributes(typeof(FactionFilterAttribute), false);
            //var filters = new Dictionary<int, List<FactionFilterAttribute>>();
            //foreach (FactionFilterAttribute item in levelFilters)
            //{
            //    if (!filters.ContainsKey(item.SlotIndex))
            //        filters.Add(item.SlotIndex, new List<FactionFilterAttribute>());
            //    filters[item.SlotIndex].Add(item);
            //}

            // Check for Color Collisions.
            var colors = new List <PlayerColor>();

            foreach (var slot in slots)
            {
                if (slot != null)
                {
                    if (colors.Contains(slot.Color))
                    {
                        var exception = new NotSupportedException("There are two Players with the same color");
                        SetMode(LevelMode.InitFailed, exception);
                        throw exception;
                    }
                    colors.Add(slot.Color);
                }
            }

            // Gegencheck mit Level-Attributen
            int playerCount = 0;
            int highestSlot = 0;

            for (int i = 0; i < slots.Length; i++)
            {
                if (slots[i] != null)
                {
                    // Counter
                    playerCount++;
                    highestSlot = i;

                    // TODO: Filter
                    //if (filters.ContainsKey(i) && filters[i].Count > 0)
                    //{
                    //    if (filters[i].Any(item => item.FactionType == slots[i].GetType()))
                    //        continue;

                    //    Mode = LevelMode.InitFailed;
                    //    Factions = null;
                    //    throw new NotSupportedException(string.Format(
                    //        "Faction '{0}' is not allowed in Slot {1}",
                    //        slots[i].GetType(), i));
                    //}
                }
            }

            // Faction Counts mit Map- und Level-Requirements gegenchecken
            if (playerCount < minPlayer)
            {
                var exception = new NotSupportedException(string.Format("Not enought player. Requires {0} Player", minPlayer));
                SetMode(LevelMode.InitFailed, exception);
                throw exception;
            }

            if (playerCount > maxPlayer)
            {
                var exception = new NotSupportedException(string.Format("Too many player. Requires a Maximum of {0} Player", maxPlayer));
                SetMode(LevelMode.InitFailed, exception);
                throw exception;
            }

            if (highestSlot > map.GetPlayerCount())
            {
                var exception = new NotSupportedException(string.Format("Too many Slots used. Map has only {0} Slots", map.GetPlayerCount()));
                SetMode(LevelMode.InitFailed, exception);
                throw exception;
            }

            // Factions erzeugen
            Factions = new Faction[MAX_SLOTS];
            for (int i = 0; i < slots.Length; i++)
            {
                if (slots[i] == null)
                {
                    continue;
                }

                SimulationContext factionContext = new SimulationContext(Context.Resolver, slotSettings[i]);

                // Identify and generate Faction
                try
                {
                    Factions[i] = Context.Resolver.CreateFaction(factionContext, slots[i].FactoryType, this);
                }
                catch (Exception ex)
                {
                    SetMode(LevelMode.InitFailed, ex);
                    throw;
                }

                // In Case the Faction could not be found...
                if (Factions[i] == null)
                {
                    var exception = new Exception(string.Format("Cound not identify Faction for player {0}.", slots[i].Name));
                    SetMode(LevelMode.InitFailed, exception);
                    throw exception;
                }
            }

            // State erzeugen
            mapState             = new MapState();
            mapState.BlockBorder = map.BlockBorder;
            mapState.Tiles       = (MapTile[, ])map.Tiles.Clone();

            engine.Init(map);
            engine.OnInsertItem += engine_OnInsertItem;
            engine.OnRemoveItem += engine_OnRemoveItem;

            // Fraktionen ins Spiel einbetten
            for (byte i = 0; i < Factions.Length; i++)
            {
                try
                {
                    InitFaction(i, slots[i], Factions[i]);
                }
                catch (Exception ex)
                {
                    SetMode(LevelMode.PlayerException, ex, i);
                    Factions = null;
                    throw;
                }
            }

            // Initialisierung des Levels
            try
            {
                OnInit();
            }
            catch (Exception ex)
            {
                SetMode(LevelMode.InitFailed, ex);
                Factions = null;
                throw;
            }

            SetMode(LevelMode.Running);
        }