private void CreateMissionsCards()
    {
        Vector3 position = missionCard.transform.position;

        if (MissionsService.missions.Length > 0)
        {
            missionCard.SetActive(true);
        }
        else
        {
            noMissionsCard.SetActive(true);
        }

        foreach (Mission mission in MissionsService.missions)
        {
            position = new Vector3(position.x, position.y, position.z);
            GameObject card = (GameObject)Instantiate(missionCard, position, Quaternion.identity);
            card.transform.SetParent(GameObject.Find("List").transform, false);

            MissionCard missionCardScript = card.GetComponent <MissionCard>();
            missionCardScript.UpdateMissionCard(mission);
        }

        missionCard.gameObject.SetActive(false);
        AlertsService.removeLoadingAlert();
    }
Example #2
0
    public void ShowMissionCard(MissionCard cd, Action <bool> action = null)
    {
        dynamicMissionCard.gameObject.SetActive(true);
        dynamicMissionCard.InitCard(cd);
        callback = action;

        gameObject.SetActive(true);
        fader.color = new Color(0, 0, 0, 0);
        fader.DOFade(.95f, .5f);
        cg2.DOFade(1, .5f);
        transform.GetChild(2).localScale = new Vector3(.85f, .85f, .85f);
        transform.GetChild(2).DOScale(1, .5f).SetEase(Ease.OutExpo);
    }
Example #3
0
 public void initMissionPanel(List <Quest> list)
 {
     for (int i = 0; i < list.Count; i++)
     {
         Quest     quest = list[i];
         Transform C     = Instantiate(_Card) as Transform;
         C.SetParent(CardSR.content);
         C.localScale = Vector3.one;
         C.gameObject.SetActive(true);
         MissionCard _c = C.GetComponent <MissionCard>();
         _c.MP = this;
         _c.initMissionCard(quest);
         CardList.Add(_c);
     }
 }
Example #4
0
        }                                               //...should allow PSSE to work longer without needing an update.

        #endregion Properties

        public Database()
        {
            //bin init
            MegaStone    = Properties.Resources.megaStone;
            MissionCard  = Properties.Resources.missionCard;
            MonAbility   = Properties.Resources.pokemonAbility;
            MonData      = Properties.Resources.pokemonData;
            MonLevel     = Properties.Resources.pokemonLevel;
            StagesMain   = Properties.Resources.stageData;
            StagesEvent  = Properties.Resources.stageDataEvent;
            StagesExpert = Properties.Resources.stageDataExtra;
            byte[][] files       = { MegaStone, MonData, StagesMain, StagesEvent, StagesExpert, MonLevel, MonAbility, MissionCard };
            string[] filenames   = { "megaStone.bin", "pokemonData.bin", "stageData.bin", "stageDataEvent.bin", "stageDataExtra.bin", "pokemonLevel.bin", "pokemonAbility.bin", "missionCard.bin" };
            string   resourcedir = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + Path.DirectorySeparatorChar + "resources" + Path.DirectorySeparatorChar;

            #region old "resource" code
            //I don't want PSSE to populate the resource folder by itself anymore but it could still be handy
            //if (!Directory.Exists(resourcedir))
            //    Directory.CreateDirectory(resourcedir);
            //for (int i = 0; i < files.Length; i++)
            //{
            //    if (!File.Exists(resourcedir + filenames[i]))
            //        File.WriteAllBytes(resourcedir + filenames[i], files[i]);
            //    else
            //        files[i] = File.ReadAllBytes(resourcedir + filenames[i]);
            //}
            #endregion
            if (Directory.Exists(resourcedir))
            {
                for (int i = 0; i < files.Length; i++)
                {
                    if (File.Exists(resourcedir + filenames[i]))
                    {
                        files[i] = File.ReadAllBytes(resourcedir + filenames[i]);
                    }
                }
            }

            //txt init
            SpeciesList    = Properties.Resources.species.Split(new[] { Environment.NewLine, "\n" }, StringSplitOptions.RemoveEmptyEntries);
            MonsList       = Properties.Resources.mons.Split(new[] { Environment.NewLine, "\n" }, StringSplitOptions.RemoveEmptyEntries);
            PokathlonList  = Properties.Resources.pokathlon.Split(new[] { Environment.NewLine, "\n" }, StringSplitOptions.RemoveEmptyEntries);
            MegaStartIndex = MonsList.ToList().IndexOf("Mega Venusaur");
            MonStopIndex   = MonsList.ToList().IndexOf("---", 1);

            //megas
            int entrylen = BitConverter.ToInt32(MonData, 0x4);
            Megas = new Tuple <int, int> [BitConverter.ToUInt32(MegaStone, 0) - 1];
            for (int i = 0; i < Megas.Length; i++)
            {
                int    monIndex = BitConverter.ToUInt16(MegaStone, MegaStone[0x10] + (i + 1) * 4) & 0x3FF;
                string str      = "Mega " + MonsList[monIndex];
                if (monIndex == 6 || monIndex == 150)
                {
                    str += (monIndex != (BitConverter.ToUInt16(MegaStone, MegaStone[0x10] + i * 4) & 0x3FF)) ? " X" : " Y";
                }
                byte[] data       = MonData.Skip(0x50 + entrylen * MonsList.ToList().IndexOf(str)).Take(entrylen).ToArray();
                int    maxSpeedup = (BitConverter.ToInt32(data, 0xA) >> 7) & 0x7F;
                Megas[i] = new Tuple <int, int>(monIndex, maxSpeedup);
            }
            MegaList = new List <int>();
            for (int i = 0; i < Megas.Length; i++)
            {
                MegaList.Add(Megas[i].Item1);
            }
            HasMega = new bool[MonsList.Length][];
            for (int i = 0; i < MonsList.Length; i++)
            {
                HasMega[i] = new bool[2];
            }
            for (int i = 0; i < Megas.Length; i++)
            {
                HasMega[BitConverter.ToUInt16(MegaStone, 0x54 + i * 4) & 0x3FF][(MegaStone[0x54 + (i * 4) + 1] >> 3) & 1] = true;
            }

            //pokemons
            Forms = new int[SpeciesList.Length];
            Mons  = new Tuple <int, int, bool, int, int, int[], int, Tuple <int, int> > [BitConverter.ToUInt32(MonData, 0)];
            Rest  = new Tuple <int, int> [Mons.Length];
            for (int i = 0; i < Mons.Length; i++)
            {
                byte[] data   = MonData.Skip(0x50 + entrylen * i).Take(entrylen).ToArray();
                bool   isMega = i >= MegaStartIndex && i <= MonsList.Count() - 1;
                int    spec   = (isMega && i <= MegaStartIndex + Megas.Length - 1)
                    ? SpeciesList.ToList().IndexOf(MonsList[Megas[i - MegaStartIndex].Item1].Substring(0, (MonsList[Megas[i - MegaStartIndex].Item1].LastIndexOf(' ') <= 0) ? MonsList[Megas[i - MegaStartIndex].Item1].Length : MonsList[Megas[i - MegaStartIndex].Item1].LastIndexOf(' ')))
                    : (BitConverter.ToInt32(data, 0xE) >> 6) & 0x7FF;
                int   raiseMaxLevel = (BitConverter.ToInt16(data, 0x4)) & 0x3F;
                int   basePower = (BitConverter.ToInt16(data, 0x3)) & 0x7; //ranges 1-7 for now (30-90 BP), may need an update later on
                int[] skillsadr = new int[] { 0x02, 0x20, 0x21, 0x22, 0x23 }, skill = new int[skillsadr.Length];
                int   j = 0, skillCount = 0;
                foreach (int adr in skillsadr)
                {
                    skill[j] = data[adr] & 0x7F; //ranges 1-~100 for now ("Opportunist" to "Transform"), ordered list in MESSAGE_XX/message_PokedexXX.bin
                    if (skill[j] != 0)
                    {
                        skillCount++;
                    }
                    j++;
                }
                skillCount = Math.Max(skillCount, 1);
                int type  = (BitConverter.ToInt16(data, 0x01) >> 3) & 0x1F; //ranges 0-17 (normal - fairy) (https://gbatemp.net/threads/psse-pokemon-shuffle-save-editor.396499/page-33#post-6278446)
                int index = (BitConverter.ToInt16(data, 0)) & 0x3FF;        //ranges 1-999, it's the number you can see on the team selection menu
                Rest[i] = new Tuple <int, int>(index, skillCount);          //Mons has more than 7 arguments so 8th one and beyond must be included in another Tuple
                Mons[i] = new Tuple <int, int, bool, int, int, int[], int, Tuple <int, int> >(spec, Forms[spec], isMega, raiseMaxLevel, basePower, skill, type, Rest[i]);
                Forms[spec]++;
            }

            //pokathlon
            PokathlonRand = new int[PokathlonList.Length / 2][];
            for (int i = 0; i < PokathlonRand.Length; i++)
            {
                PokathlonRand[i] = new int[2];
                Int32.TryParse(PokathlonList[2 * i], out PokathlonRand[i][0]);
                Int32.TryParse(PokathlonList[1 + 2 * i], out PokathlonRand[i][1]);
            }

            //missions
            Missions = new bool[BitConverter.ToInt32(MissionCard, 0)][];
            for (int i = 0; i < Missions.Length; i++)
            {
                Missions[i] = new bool[10];
                int    ientrylen = BitConverter.ToInt32(MissionCard, 0x4);
                byte[] data      = MissionCard.Skip(BitConverter.ToInt32(MissionCard, 0x10) + i * ientrylen).Take(ientrylen).ToArray();
                for (int j = 0; j < Missions[i].Length; j++)
                {
                    Missions[i][j] = BitConverter.ToInt16(data, 0x8 + 2 * j) != 0;
                }
            }

            //dictionnary, this is some really bad code here
            byte[]        HexValue = Properties.Resources.messagePokedex_US;
            string        StrValue = "";
            List <string> List     = new List <string>();
            for (int i = 0; i < HexValue.Length; i += 2)
            {
                if (BitConverter.ToChar(HexValue, i) == '\0' && StrValue != "" && !(StrValue.EndsWith("\u0001ă\u0001\u0003\u0003慮敭") || StrValue.EndsWith("\u0001ă\u0001\u0003\u0005敭慧慎敭")))
                {
                    List.Add(StrValue.Replace("\u0001ă\u0001\u0003\u0003慮敭\0", "[name]").Replace("\u0001ă\u0001\u0003\u0005敭慧慎敭\0", "[name]"));
                    StrValue = "";
                }
                else
                {
                    StrValue += BitConverter.ToChar(HexValue, i);
                }
            }
            SkillsList     = List.Skip(List.IndexOf("Opportunist")).Take(List.IndexOf("Attacks can occasionally deal\ngreater damage than usual.") - List.IndexOf("Opportunist")).ToArray();
            SkillsTextList = List.Skip(List.IndexOf("Attacks can occasionally deal\ngreater damage than usual.")).Take(List.IndexOf("Attacks can occasionally deal\ngreater damage than usual.") - List.IndexOf("Opportunist")).ToArray();
        }
Example #5
0
    public void InitCard(MissionCard card)
    {
        missionCard = card;

        Func <string[], string, string> parse = (string[] toParse, string sep) =>
        {
            string t = "";
            for (int i = 0; i < toParse.Length; i++)
            {
                t += toParse[i];
                if (i < toParse.Length - 1)
                {
                    t += $"{sep}";
                }
            }
            return(t);
        };

        //card color
        if (missionCard.missionType.Any(x => x == MissionType.Finale))
        {
            cardImage.color = Color.yellow;
        }
        else if (missionCard.missionType.Any(x => x == MissionType.Story))
        {
            cardImage.color = new Color(0, 164f / 255f, 1);
        }
        else if (missionCard.missionType.Any(x => x == MissionType.Personal))
        {
            cardImage.color = Color.red;
        }
        else if (missionCard.missionType.Any(x => x == MissionType.Ally))
        {
            cardImage.color = Color.green;
        }
        else if (missionCard.missionType.Any(x => x == MissionType.Agenda))
        {
            cardImage.color = new Color(0, 82f / 255f, 128f / 255f);
        }
        else if (missionCard.missionType.Any(x => x == MissionType.Threat))
        {
            cardImage.color = new Color(1, 142f / 255f, 0);
        }
        else
        {
            cardImage.color = Color.gray;
        }

        //description + bonus text
        descriptionText.text  = missionCard.descriptionText.Replace("<i>", "").Replace("</i>", "").Replace("\n", "\n\n");
        descriptionText.text += $"\n\n<color=orange>{missionCard.bonusText}</color>";

        //tags
        titleTagsText.text = $"{missionCard.name}\n<size=20><color=orange>{parse( missionCard.tagsText, " - " )}";

        //reward
        rewardText.text = $"{DataStore.uiLanguage.uiMainApp.rewardUC}: " + missionCard.rebelRewardText + missionCard.imperialRewardText;
        rewardBox.SetActive(!string.IsNullOrEmpty(missionCard.rebelRewardText) || !string.IsNullOrEmpty(missionCard.imperialRewardText));

        //hero/villain name
        heroVillainText.text = missionCard.heroText + missionCard.villainText + missionCard.allyText;
        heroBox.SetActive(!string.IsNullOrEmpty(heroVillainText.text));
        if (!string.IsNullOrEmpty(missionCard.heroText) || !string.IsNullOrEmpty(missionCard.allyText))
        {
            heroBox.GetComponent <Image>().color = new Color(0, 1, 160f / 255f);
        }
        else
        {
            heroBox.GetComponent <Image>().color = new Color(1, 40f / 255f, 0);
        }
        //hero icon?
        if (!string.IsNullOrEmpty(missionCard.heroText))
        {
            mugshot.sprite = Resources.Load <Sprite>($"Cards/Heroes/{missionCard.hero}");
        }
        //villain icon?
        else if (missionCard.villain.Length > 0)
        {
            mugshot.sprite = Resources.Load <Sprite>($"Cards/Villains/{missionCard.villain[0].Replace( "DG", "M" )}");
        }
        //ally icon?
        else if (missionCard.ally.Length > 0)
        {
            mugshot.sprite = Resources.Load <Sprite>($"Cards/Allies/{missionCard.ally[0].Replace( "A", "M" )}");
        }

        //page # and expansion
        string page = missionCard.page > 0 ? $"{DataStore.uiLanguage.uiMainApp.pageUC} {missionCard.page}, " : "";

        typePageExpansionText.text = $"{page}{missionCard.expansionText}";

        //timeline
        dateBox.SetActive(missionCard.timePeriod.Length > 0);
        if (missionCard.timePeriod.Length > 0)
        {
            dateText.text = $"Time Period: {missionCard.timePeriod[0]}-{missionCard.timePeriod[1]}";
        }

        //expansion icon
        expansionImage.sprite = expansionSprites[(int)missionCard.expansion];
        if (missionCard.expansion == Expansion.Other && !missionCard.missionType.Contains(MissionType.Agenda))
        {
            expansionImage.sprite = expansionSprites[8];
        }
    }
Example #6
0
        }                                               //...should allow PSSE to work longer without needing an update.

        #endregion Properties

        public Database(bool shwmsg = false, bool dev = false)
        {
            //if a new resource file is needed, don't forget to add a line to Resource_Popup's TLP !
            string[] filenames   = { "megaStone.bin", "pokemonData.bin", "stageData.bin", "stageDataEvent.bin", "stageDataExtra.bin", "pokemonLevel.bin", "pokemonAbility.bin", "missionCard.bin", "messagePokedex_US.bin", "pokeLoad.bin" };
            string   resourcedir = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + Path.DirectorySeparatorChar + "resources" + Path.DirectorySeparatorChar;

            bool[] overRide = new bool[filenames.Length];
            for (int i = 0; i < overRide.Length; i++)
            {
                overRide[i] = true;
            }
            if (shwmsg)
            {
                string[] fn = new string[filenames.Length];
                for (int i = 0; i < fn.Length; i++)
                {
                    fn[i] = filenames[i];
                }
                Array.Sort(fn, (x, y) => String.Compare(x, y));
                using (var form = new Resources_Popup(fn, resourcedir, dev))
                {
                    form.ShowDialog();
                    if (form.DialogResult == DialogResult.OK && dev)
                    {
                        for (int i = 0; i < overRide.Length; i++)
                        {
                            overRide[i] = form.retChk[Array.IndexOf(fn, filenames[i])];
                        }
                    }
                }
            }

            //bin init
            MegaStone    = Properties.Resources.megaStone;
            MissionCard  = Properties.Resources.missionCard;
            MonAbility   = Properties.Resources.pokemonAbility;
            MonData      = Properties.Resources.pokemonData;
            MonLevel     = Properties.Resources.pokemonLevel;
            StagesMain   = Properties.Resources.stageData;
            StagesEvent  = Properties.Resources.stageDataEvent;
            StagesExpert = Properties.Resources.stageDataExtra;
            MessageDex   = Properties.Resources.messagePokedex_US;
            PokeLoad     = Properties.Resources.pokeLoad;

            //resources override
            if (Directory.Exists(resourcedir))
            {
                for (int i = 0; i < filenames.Length; i++)
                {
                    if (File.Exists(resourcedir + filenames[i]) && overRide[i])
                    {
                        switch (i) //don't forget that part or resources files won't override Database files, add an entry if a file is added above
                        {
                        case 0:
                            MegaStone = File.ReadAllBytes(resourcedir + filenames[i]);
                            break;

                        case 1:
                            MonData = File.ReadAllBytes(resourcedir + filenames[i]);
                            break;

                        case 2:
                            StagesMain = File.ReadAllBytes(resourcedir + filenames[i]);
                            break;

                        case 3:
                            StagesEvent = File.ReadAllBytes(resourcedir + filenames[i]);
                            break;

                        case 4:
                            StagesExpert = File.ReadAllBytes(resourcedir + filenames[i]);
                            break;

                        case 5:
                            MonLevel = File.ReadAllBytes(resourcedir + filenames[i]);
                            break;

                        case 6:
                            MonAbility = File.ReadAllBytes(resourcedir + filenames[i]);
                            break;

                        case 7:
                            MissionCard = File.ReadAllBytes(resourcedir + filenames[i]);
                            break;

                        case 8:
                            MessageDex = File.ReadAllBytes(resourcedir + filenames[i]);
                            break;

                        case 9:
                            PokeLoad = File.ReadAllBytes(resourcedir + filenames[i]);
                            break;

                        default:
                            MessageBox.Show("Error loading resources :\nfilename = " + (filenames[i] != null ? filenames[i] : "null") + "\ni = " + i);
                            break;
                        }
                    }
                }
            }


            //txt init
            SpeciesList = Properties.Resources.species.Split(new[] { Environment.NewLine, "\n" }, StringSplitOptions.RemoveEmptyEntries);
            MonsList    = Properties.Resources.mons.Split(new[] { Environment.NewLine, "\n" }, StringSplitOptions.RemoveEmptyEntries);
            //PokathlonList = Properties.Resources.pokathlon.Split(new[] { Environment.NewLine, "\n" }, StringSplitOptions.RemoveEmptyEntries);
            MegaStartIndex = MonsList.ToList().IndexOf("Mega Venusaur");
            MonStopIndex   = MonsList.ToList().IndexOf("---", 1);

            //megas
            int entrylen = BitConverter.ToInt32(MonData, 0x4);

            Megas = new Tuple <int, int> [BitConverter.ToUInt32(MegaStone, 0) - 1];
            for (int i = 0; i < Megas.Length; i++)
            {
                int    monIndex = BitConverter.ToUInt16(MegaStone, MegaStone[0x10] + (i + 1) * 4) & 0x3FF;
                string str      = "Mega " + MonsList[monIndex];
                int    spec     = (BitConverter.ToInt32(MonData.Skip(0x50 + entrylen * monIndex).Take(entrylen).ToArray(), 0xE) >> 6) & 0x7FF;
                if (spec == 6 || spec == 150)
                {
                    str += (monIndex != (BitConverter.ToUInt16(MegaStone, MegaStone[0x10] + i * 4) & 0x3FF)) ? " X" : " Y";
                }
                byte[] data       = MonData.Skip(0x50 + entrylen * MonsList.ToList().IndexOf(str)).Take(entrylen).ToArray();
                int    maxSpeedup = (BitConverter.ToInt32(data, 0xA) >> 7) & 0x7F;
                Megas[i] = new Tuple <int, int>(monIndex, maxSpeedup);
            }
            MegaList = new List <int>();
            for (int i = 0; i < Megas.Length; i++)
            {
                MegaList.Add(Megas[i].Item1);
            }
            HasMega = new bool[MonsList.Length][];
            for (int i = 0; i < MonsList.Length; i++)
            {
                HasMega[i] = new bool[2];
            }
            for (int i = 0; i < Megas.Length; i++)
            {
                HasMega[BitConverter.ToUInt16(MegaStone, 0x54 + i * 4) & 0x3FF][(MegaStone[0x54 + (i * 4) + 1] >> 3) & 1] = true;
            }

            //pokemons
            Forms = new int[SpeciesList.Length];
            Mons  = new dbItem[BitConverter.ToUInt32(MonData, 0)];
            for (int i = 0; i < Mons.Length; i++)
            {
                byte[] data   = MonData.Skip(0x50 + entrylen * i).Take(entrylen).ToArray();
                bool   isMega = i >= MegaStartIndex && i <= MonsList.Count() - 1;
                int    spec   = (isMega && i <= MegaStartIndex + Megas.Length - 1)
                    ? SpeciesList.ToList().IndexOf(MonsList[Megas[i - MegaStartIndex].Item1].Substring(0, (MonsList[Megas[i - MegaStartIndex].Item1].LastIndexOf(' ') <= 0) ? MonsList[Megas[i - MegaStartIndex].Item1].Length : MonsList[Megas[i - MegaStartIndex].Item1].LastIndexOf(' ')))
                    : (BitConverter.ToInt32(data, 0xE) >> 6) & 0x7FF;
                int   raiseMaxLevel = (BitConverter.ToInt16(data, 0x4)) & 0x3F;
                int   basePower = (BitConverter.ToInt16(data, 0x3)) & 0x7; //ranges 1-7 for now (30-90 BP), may need an update later on
                int[] skillsadr = new int[] { 0x02, 0x20, 0x21, 0x22, 0x23 }, skill = new int[skillsadr.Length];
                int   j = 0, skillCount = 0;
                foreach (int adr in skillsadr)
                {
                    skill[j] = data[adr]; //ranges 1-~130 for now, ordered list in MESSAGE_XX/message_PokedexXX.bin ("Opportunist" to "Transform" then a bunch more with a lot of placeholders)
                    if (skill[j] != 0)
                    {
                        skillCount++;
                    }
                    j++;
                }
                skillCount = Math.Max(skillCount, 1);
                int type  = (BitConverter.ToInt16(data, 0x01) >> 3) & 0x1F; //ranges 0-17 (normal - fairy) (https://gbatemp.net/threads/psse-pokemon-shuffle-save-editor.396499/page-33#post-6278446)
                int index = (BitConverter.ToInt16(data, 0)) & 0x3FF;        //ranges 1-999, it's the number you can see on the team selection menu
                Mons[i] = new dbItem(spec, Forms[spec], isMega, raiseMaxLevel, basePower, skill, type, index, skillCount);
                Forms[spec]++;
            }

            //Survival mode
            int smEntry = BitConverter.ToInt32(PokeLoad, 0x4), smSkip = BitConverter.ToInt32(PokeLoad, 0x10), smTake = BitConverter.ToInt32(PokeLoad, 0x14);

            Pokathlon = new List <int> [BitConverter.ToInt16(PokeLoad.Skip(smSkip + smTake - smEntry).Take(smEntry).ToArray(), 0) & 0x3FF]; //# of entries doesn't match # of steps since some are collided so I take the last entry and read its 'lowStep' value (should compare to 'highStep' but I don't want to overcomplicate thigns for now)
            for (int i = 0; i < BitConverter.ToInt32(PokeLoad, 0); i++)
            {
                byte[]     data = PokeLoad.Skip(smSkip + i * smEntry).Take(smEntry).ToArray();
                int        lowStep = BitConverter.ToInt16(data, 0) & 0x3FF, highStep = (BitConverter.ToInt16(data, 0x01) >> 2) & 0x3FF; //if highStep !=0 then data[] applies to all steps in the lowStep - highStep range
                int        min = (BitConverter.ToInt16(data, 0x02) >> 4) & 0xFFF, max = BitConverter.ToInt16(data, 0x04) & 0xFFF;       //if max !=0 then all stages in min-max range are possibilities for corresponding step(s)
                List <int> stagesList = Enumerable.Range(min, max != 0 ? max - min + 1 : 1).ToList();
                for (int j = 0x08; j < (data.Length - 3); j += 4)                                                                       //weird pattern for excluded stages : each 32-bits block starting at 0x08 contains 3 10-bits long stages #
                {
                    int exception = 0;
                    for (int w = 0; w < 3; w++)
                    {
                        exception = (BitConverter.ToInt32(data, j) >> (w * 10)) & 0x3FF;
                        if (exception == 0)
                        {
                            break;
                        }
                        else if (stagesList.Contains(exception))
                        {
                            stagesList.Remove(exception);
                        }
                    }
                    if (exception == 0)
                    {
                        break;
                    }
                }
                foreach (int step in Enumerable.Range(lowStep, 1 + Math.Max(0, highStep - lowStep)))
                {
                    Pokathlon[step - 1] = stagesList;
                }
            }

            #region old Survival
            //pokathlon
            //PokathlonRand = new int[PokathlonList.Length / 2][];
            //for (int i = 0; i < PokathlonRand.Length; i++)
            //{
            //    PokathlonRand[i] = new int[2];
            //    Int32.TryParse(PokathlonList[2 * i], out PokathlonRand[i][0]);
            //    Int32.TryParse(PokathlonList[1 + 2 * i], out PokathlonRand[i][1]);
            //}
            #endregion

            //missions
            Missions = new bool[BitConverter.ToInt32(MissionCard, 0)][];
            for (int i = 0; i < Missions.Length; i++)
            {
                Missions[i] = new bool[10];
                int    ientrylen = BitConverter.ToInt32(MissionCard, 0x4);
                byte[] data      = MissionCard.Skip(BitConverter.ToInt32(MissionCard, 0x10) + i * ientrylen).Take(ientrylen).ToArray();
                for (int j = 0; j < Missions[i].Length; j++)
                {
                    Missions[i][j] = BitConverter.ToInt16(data, 0x8 + 2 * j) != 0;
                }
            }

            //dictionnary (new)
            string temp = Encoding.Unicode.GetString(MessageDex.Skip(BitConverter.ToInt32(MessageDex, 0x08)).Take(BitConverter.ToInt32(MessageDex, 0x0C) - 0x17).ToArray());                                      //Relevant chunk specified in .bin file, UTF16 Encoding, 17 bytes at the end are a useless stamp (data.messagePokedex)
            temp = temp.Replace(Encoding.Unicode.GetString(MessageDex.Skip(BitConverter.ToInt32(MessageDex, 0x08)).Take(0x10).ToArray()), "[name]");                                                              //because this variable ends with 0x00 it messes with Split() later on, so I replace it here
            temp = temp.Replace(Encoding.Unicode.GetString(new byte[] { 0x01, 0x00, 0x03, 0x01, 0x01, 0x00, 0x03, 0x00, 0x05, 0x00, 0x6D, 0x65, 0x67, 0x61, 0x4E, 0x61, 0x6D, 0x65, 0x00, 0x00 }), "[megaName]"); //same but this variable isn't declared on a fixed position so I copied it directly
            string[] arr = temp.Split((char)0x00);                                                                                                                                                                //split the single string in an array
            arr = arr.Skip(Array.IndexOf(arr, "Opportunist")).ToArray();                                                                                                                                          //we only care for skills so I get rid of anything before Opportunist
            for (int i = 0; i < arr.Length; i++)
            {
                if (String.IsNullOrEmpty(arr[i]))
                {
                    arr[i] = "-Placeholder-"; //make sure there is no empty strings just in case
                }
            }

            /* This code below separates Skills entries from Text entries while ignoring a few mega-skills entries :
             * Right now (1.5.7) the list of strings looks like that : [Skills1][Text for Skills1][Text for mega skills][Skills2][Text for Skills2][Skills3][Text for Skills3].
             * If another group of [Skills][Text for skills] is ever added this will need a 3rd string to concatenate.
             * Also, note that there is no [Mega Skills], which is why I didn't implement it yet (the names of Mega Skills are probably inside another file).
             */

            int      a = Array.IndexOf(arr, "Opportunist"), b = Array.IndexOf(arr, "Transform") + 1, c = Array.IndexOf(arr, "Big Wave"), d = Array.IndexOf(arr, "Super Cheer") + 1, e = Array.IndexOf(arr, "Not Caught"), f = Array.IndexOf(arr, "Hammering Streak") + 1;
            string[] s1     = arr.Skip(a).Take(b - a).ToArray(), s2 = arr.Skip(c).Take(d - c).ToArray(), s3 = arr.Skip(e).Take(f - e).ToArray();
            string[] st1    = arr.Skip(b).Take(b - a).ToArray(), st2 = arr.Skip(d).Take(d - c).ToArray(), st3 = arr.Skip(f).Take(f - e).ToArray();
            string[] Skills = new string[s1.Length + s2.Length + s3.Length], SkillsT = new string[Skills.Length];;
            s1.CopyTo(Skills, 0);
            s2.CopyTo(Skills, s1.Length);
            SkillsList = Skills;
            st1.CopyTo(SkillsT, 0);
            st2.CopyTo(SkillsT, s1.Length);
            SkillsTextList = SkillsT;
        }