using System;
using System.Collections.Generic;
using UnityEngine;

public class GameSpecialisations
{
    public static bool[] hasAuftragstaktik;

    public static bool[] hasProximityFuse;

    public static bool[] hasFieldMedics;

    public static bool[] hasBanzaiCharge;

    public static bool[] hasBushidoCode;

    public static bool[] hasForcedLabour;

    public static bool[] hasTokyoExpress;

    public static bool[] hasRadarI;

    public static bool[] hasRadarII;

    public static bool[] hasDamageControl;

    public static bool[] hasDropTank;

    public static bool[] hasUnrestrictedSubWar;

    public static bool[] hasWolfPack;

    public static bool[] hasLibertyShips;

    public static bool[] hasTorpImprovements;

    public static bool[] hasMetalDetector;

    public static bool[] hasBomberStream;

    public static bool[] hasHobartsFunnies;

    public static bool[] hasGoliath;

    public static bool[] hasPakFront;

    public static bool[] hasPanzerKeil;

    public GameSpecialisations()
    {
    }

    public static void AddLegacySpecialisation(int oldSpecId, Alliance alliance)
    {
        SpecialisationType specialisationTypeByName = null;
        if (oldSpecId == 0)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("banzai_charge");
        }
        else if (oldSpecId == 1)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("bushido_code");
        }
        else if (oldSpecId == 2)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("forced_labour");
        }
        else if (oldSpecId == 3)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("tokyo_express");
        }
        else if (oldSpecId == 4)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("super_sensha");
            if (App.mode != App.modes.editor)
            {
                foreach (Faction faction in alliance.factions)
                {
                    bool flag = false;
                    foreach (Unit unit in faction.state.units)
                    {
                        if (!(unit.state.unitType.name == "type100_o-i") || !unit.IsAlive())
                        {
                            continue;
                        }
                        faction.AddResources(unit.state.unitType.stats.costs[0], App.game.actualGameState);
                        flag = true;
                        break;
                    }
                }
            }
        }
        else if (oldSpecId == 5)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("advanced_aeronautics");
        }
        else if (oldSpecId == 6)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("kamikaze");
        }
        else if (oldSpecId == 7)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("gruppe_monsun");
        }
        else if (oldSpecId == 8)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("yanagi_missions");
        }
        else if (oldSpecId == 9)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("build_bunkers");
        }
        else if (oldSpecId == 10)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("field_medics");
        }
        else if (oldSpecId == 11)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("landing_craft_infantry");
        }
        else if (oldSpecId == 12)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("war_economy");
        }
        else if (oldSpecId == 13)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("flight_school");
        }
        else if (oldSpecId == 14)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("radar_i");
        }
        else if (oldSpecId == 15)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("radar_i");
        }
        else if (oldSpecId == 16)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("landing_craft_tank");
        }
        else if (oldSpecId == 17)
        {
            specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("advanced_aeronautics");
        }
        else if (oldSpecId != 18)
        {
            if (oldSpecId == 19)
            {
                specialisationTypeByName = GameSpecialisations.GetSpecialisationTypeByName("nuclear_bomb");
            }
        }
        if (specialisationTypeByName != null)
        {
            foreach (Faction faction1 in alliance.factions)
            {
                if (!specialisationTypeByName.factionTypes.Contains(faction1.factionType))
                {
                    continue;
                }
                Specialisation specialisation = new Specialisation()
                {
                    id = alliance.id * 1000000 + faction1.id * 100 + oldSpecId,
                    type = specialisationTypeByName,
                    faction = faction1
                };
                specialisation.faction.specialisations.Add(specialisation);
            }
        }
    }

    public static void ApplyCampaignEffect(Specialisation specialisation)
    {
        List<string> strs;
        if (specialisation.type.effect == GameSpecialisations.effects.field_medics)
        {
            UnitType unitTypeByName = App.GetUnitTypeByName("willys_redcross");
            Unit unit = App.game.CreateUnit(specialisation.faction, unitTypeByName, null, 1, 0, new ActualGameState(), true);
            UnitHistory unitHistory = unit.history;
            strs = new List<string>()
            {
                "enlisted",
                string.Empty,
                string.Empty,
                App.game.campaign.currentDate.ToString()
            };
            unitHistory.AddHistory(strs);
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.gruppe_monsun)
        {
            Faction factionByName = App.game.campaign.GetFactionByName("germany");
            UnitType unitType = App.GetUnitTypeByName("sub_typeix_submerged");
            for (int i = 0; i < 2; i++)
            {
                Unit unit1 = App.game.CreateUnit(factionByName, unitType, null, 1, 0, new ActualGameState(), true);
                UnitHistory unitHistory1 = unit1.history;
                strs = new List<string>()
                {
                    "enlisted",
                    string.Empty,
                    string.Empty,
                    App.game.campaign.currentDate.ToString()
                };
                unitHistory1.AddHistory(strs);
            }
            App.game.campaign.cores[0].factions.Add(factionByName);
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.british_pacific_fleet)
        {
            Faction faction = App.game.campaign.GetFactionByName("britain");
            UnitType unitTypeByName1 = App.GetUnitTypeByName("bb_kinggeorgev");
            Unit unit2 = App.game.CreateUnit(faction, unitTypeByName1, null, 1, 0, new ActualGameState(), true);
            UnitHistory unitHistory2 = unit2.history;
            strs = new List<string>()
            {
                "enlisted",
                string.Empty,
                string.Empty,
                App.game.campaign.currentDate.ToString()
            };
            unitHistory2.AddHistory(strs);
            UnitType unitType1 = App.GetUnitTypeByName("cv_implacable");
            unit2 = App.game.CreateUnit(faction, unitType1, null, 1, 0, new ActualGameState(), true);
            UnitHistory unitHistory3 = unit2.history;
            strs = new List<string>()
            {
                "enlisted",
                string.Empty,
                string.Empty,
                App.game.campaign.currentDate.ToString()
            };
            unitHistory3.AddHistory(strs);
            UnitType unitTypeByName2 = App.GetUnitTypeByName("dd_battle");
            unit2 = App.game.CreateUnit(faction, unitTypeByName2, null, 1, 0, new ActualGameState(), true);
            UnitHistory unitHistory4 = unit2.history;
            strs = new List<string>()
            {
                "enlisted",
                string.Empty,
                string.Empty,
                App.game.campaign.currentDate.ToString()
            };
            unitHistory4.AddHistory(strs);
            unit2 = App.game.CreateUnit(faction, unitTypeByName2, null, 1, 0, new ActualGameState(), true);
            UnitHistory unitHistory5 = unit2.history;
            strs = new List<string>()
            {
                "enlisted",
                string.Empty,
                string.Empty,
                App.game.campaign.currentDate.ToString()
            };
            unitHistory5.AddHistory(strs);
            UnitType unitType2 = App.GetUnitTypeByName("supermarine_seafire");
            unit2 = App.game.CreateUnit(faction, unitType2, null, 1, 0, new ActualGameState(), true);
            UnitHistory unitHistory6 = unit2.history;
            strs = new List<string>()
            {
                "enlisted",
                string.Empty,
                string.Empty,
                App.game.campaign.currentDate.ToString()
            };
            unitHistory6.AddHistory(strs);
            UnitType unitTypeByName3 = App.GetUnitTypeByName("tbm-3e_avenger_britain_b");
            unit2 = App.game.CreateUnit(faction, unitTypeByName3, null, 1, 0, new ActualGameState(), true);
            UnitHistory unitHistory7 = unit2.history;
            strs = new List<string>()
            {
                "enlisted",
                string.Empty,
                string.Empty,
                App.game.campaign.currentDate.ToString()
            };
            unitHistory7.AddHistory(strs);
            App.game.campaign.cores[0].factions.Add(faction);
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.yanagi_missions)
        {
            if (Random.Range(0, 2) != 0)
            {
                UnitType unitType3 = App.GetUnitTypeByName("nebelwerfer_japan");
                Unit unit3 = App.game.CreateUnit(App.game.campaign.GetFactionByName("japan"), unitType3, null, 1, 0, new ActualGameState(), true);
                UnitHistory unitHistory8 = unit3.history;
                strs = new List<string>()
                {
                    "enlisted",
                    string.Empty,
                    string.Empty,
                    App.game.campaign.currentDate.ToString()
                };
                unitHistory8.AddHistory(strs);
            }
            else
            {
                UnitType unitTypeByName4 = App.GetUnitTypeByName("pzkw_vi_tiger_japan");
                Unit unit4 = App.game.CreateUnit(App.game.campaign.GetFactionByName("japan"), unitTypeByName4, null, 1, 0, new ActualGameState(), true);
                UnitHistory unitHistory9 = unit4.history;
                strs = new List<string>()
                {
                    "enlisted",
                    string.Empty,
                    string.Empty,
                    App.game.campaign.currentDate.ToString()
                };
                unitHistory9.AddHistory(strs);
            }
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.waffen_ss)
        {
            Debug.Log("add waffen SS");
            Faction faction1 = GameSpecialisations.FindOrAddCoreFaction(App.GetFactionTypeByName("waffenss"), specialisation.faction.alliance);
            faction1.AddResources(100, App.game.actualGameState);
            App.campaignController.CheckSpecialUnlocks("wiking");
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.waffen_ss_ii)
        {
            Faction faction2 = GameSpecialisations.FindOrAddCoreFaction(App.GetFactionTypeByName("waffenss"), specialisation.faction.alliance);
            faction2.AddResources(150, App.game.actualGameState);
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.waffen_ss_iii)
        {
            Faction faction3 = GameSpecialisations.FindOrAddCoreFaction(App.GetFactionTypeByName("waffenss"), specialisation.faction.alliance);
            faction3.AddResources(200, App.game.actualGameState);
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.elite_air_groups)
        {
            int num = 0;
            foreach (Unit unit5 in specialisation.faction.state.units)
            {
                if (unit5.core != -1 && unit5.IsAlive() && (unit5.state.unitType.uClass.id == 6 || unit5.state.unitType.uClass.id == 7 || unit5.state.unitType.uClass.id == 8))
                {
                    GameExperience.AddExperienceStars(unit5, 6, App.game.actualGameState);
                    num++;
                }
                if (num != 3)
                {
                    continue;
                }
                break;
            }
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.arbeitnehmer)
        {
            UnitType unitType4 = App.GetUnitTypeByName("german_bautruppe");
            UnitType unitTypeByName5 = App.GetUnitTypeByName("german_truck");
            if (unitType4 != null && unitTypeByName5 != null)
            {
                Unit unit6 = App.game.CreateUnit(-1, specialisation.faction, unitType4, unitTypeByName5, null, 1, 0, App.game.actualGameState, true);
                UnitHistory unitHistory10 = unit6.history;
                strs = new List<string>()
                {
                    "enlisted",
                    string.Empty,
                    string.Empty,
                    App.game.campaign.currentDate.ToString()
                };
                unitHistory10.AddHistory(strs);
            }
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.super_sensha)
        {
            if (App.game.campaign.currentDate.year >= 1945)
            {
                UnitType unitType5 = App.GetUnitTypeByName("type100_o-i");
                foreach (Unit unit7 in specialisation.faction.state.units)
                {
                    if (unit7.state.unitType != unitType5)
                    {
                        continue;
                    }
                    return;
                }
                Unit unit8 = App.game.CreateUnit(specialisation.faction, unitType5, null, 1, 0, App.game.actualGameState, true);
                UnitHistory unitHistory11 = unit8.history;
                strs = new List<string>()
                {
                    "enlisted",
                    string.Empty,
                    string.Empty,
                    App.game.campaign.currentDate.ToString()
                };
                unitHistory11.AddHistory(strs);
            }
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.plan_z)
        {
            specialisation.faction.AddResources(100, App.game.actualGameState);
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.elite_air_groups)
        {
            int num1 = 0;
            for (int j = 0; j < specialisation.faction.state.units.Count; j++)
            {
                Unit item = specialisation.faction.state.units[j];
                if (item.core != -1 && item.IsAlive() && (item.state.unitType.uClass.id == 6 || item.state.unitType.uClass.id == 7 || item.state.unitType.uClass.id == 8))
                {
                    num1++;
                    GameExperience.AddExperienceStars(item, 6, App.game.actualGameState);
                    if (num1 == 3)
                    {
                        break;
                    }
                }
            }
        }
    }

    public static void ApplyScenarioEffect(Specialisation specialisation)
    {
        GameState item = App.game.actualGameState;
        if (specialisation.type.effect == GameSpecialisations.effects.landing_craft_infantry)
        {
            foreach (Unit unit in specialisation.faction.state.units)
            {
                if (!unit.IsDeployed() || !unit.state.unitType.transportNaval || unit.state.originalType.uClass.id != 0)
                {
                    continue;
                }
                unit.SwitchTo(App.GetUnitTypeByName("lcvp"), item);
            }
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.war_economy)
        {
            if (specialisation.faction.state.command[0] > 0)
            {
                IList<int> nums = specialisation.faction.state.command;
                nums[0] = nums[0] + 2;
            }
            if (specialisation.faction.state.command[1] > 0)
            {
                IList<int> item1 = specialisation.faction.state.command;
                item1[1] = item1[1] + 2;
            }
            if (specialisation.faction.state.command[2] > 0)
            {
                IList<int> nums1 = specialisation.faction.state.command;
                nums1[2] = nums1[2] + 1;
            }
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.female_laborers)
        {
            if (specialisation.faction.state.command[0] > 0)
            {
                IList<int> item2 = specialisation.faction.state.command;
                item2[0] = item2[0] + 2;
            }
            if (specialisation.faction.state.command[1] > 0)
            {
                IList<int> nums2 = specialisation.faction.state.command;
                nums2[1] = nums2[1] + 2;
            }
            if (specialisation.faction.state.command[2] > 0)
            {
                IList<int> item3 = specialisation.faction.state.command;
                item3[2] = item3[2] + 1;
            }
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.rationing)
        {
            if (specialisation.faction.state.command[0] > 0)
            {
                IList<int> nums3 = specialisation.faction.state.command;
                nums3[0] = nums3[0] + 2;
            }
            if (specialisation.faction.state.command[1] > 0)
            {
                IList<int> item4 = specialisation.faction.state.command;
                item4[1] = item4[1] + 2;
            }
            if (specialisation.faction.state.command[2] > 0)
            {
                IList<int> nums4 = specialisation.faction.state.command;
                nums4[2] = nums4[2] + 1;
            }
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.air_cp_bonus)
        {
            if (specialisation.faction.state.command[2] > 0)
            {
                IList<int> item5 = specialisation.faction.state.command;
                item5[2] = item5[2] + 2;
            }
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.landing_craft_tank)
        {
            foreach (Unit unit1 in specialisation.faction.state.units)
            {
                if (!unit1.IsDeployed() || !unit1.state.unitType.transportNaval || unit1.state.originalType.uClass.id != 2)
                {
                    continue;
                }
                unit1.SwitchTo(App.GetUnitTypeByName("lct"), item);
            }
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.gruppe_monsun)
        {
            FactionType factionTypeByName = App.GetFactionTypeByName("germany");
            Faction faction = GameSpecialisations.FindOrAddCoreFaction(factionTypeByName, specialisation.faction.alliance);
            faction.SetState(item).command[1] = faction.state.command[1] + App.GetUnitTypeByName("sub_typeix_submerged").stats.supply[1] * 2;
            App.game.scenario.GetFactionByName("germany").state.resources = 50;
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.british_pacific_fleet)
        {
            FactionType factionType = App.GetFactionTypeByName("britain");
            Faction faction1 = GameSpecialisations.FindOrAddCoreFaction(factionType, specialisation.faction.alliance);
            faction1.SetState(item).command[1] = faction1.state.command[1] + 20;
            faction1.SetState(item).command[2] = faction1.state.command[2] + 10;
            App.game.scenario.GetFactionByName("britain").state.resources = 50;
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.waffen_ss || specialisation.type.effect == GameSpecialisations.effects.waffen_ss_ii || specialisation.type.effect == GameSpecialisations.effects.waffen_ss_iii)
        {
            if (specialisation.type.effect == GameSpecialisations.effects.waffen_ss && (GameSpecialisations.HasFactionSpecialisationEffect(specialisation.faction, GameSpecialisations.effects.waffen_ss_ii) || GameSpecialisations.HasFactionSpecialisationEffect(specialisation.faction, GameSpecialisations.effects.waffen_ss_iii)))
            {
                return;
            }
            if (specialisation.type.effect == GameSpecialisations.effects.waffen_ss_ii && GameSpecialisations.HasFactionSpecialisationEffect(specialisation.faction, GameSpecialisations.effects.waffen_ss_iii))
            {
                return;
            }
            FactionType factionTypeByName1 = App.GetFactionTypeByName("waffenss");
            Faction faction2 = GameSpecialisations.FindOrAddCoreFaction(factionTypeByName1, specialisation.faction.alliance);
            Faction factionByType = App.game.scenario.GetFactionByType(App.GetFactionTypeByName("germany"));
            int num = 0;
            if (specialisation.type.effect == GameSpecialisations.effects.waffen_ss_iii)
            {
                faction2.SetState(item).command[0] = faction2.State(item).command[0] + 18;
                num = 10;
            }
            else if (specialisation.type.effect != GameSpecialisations.effects.waffen_ss_ii)
            {
                faction2.SetState(item).command[0] = faction2.State(item).command[0] + 6;
                num = 2;
            }
            else
            {
                faction2.SetState(item).command[0] = faction2.State(item).command[0] + 12;
                num = 5;
            }
            num = Mathf.Min(num, factionByType.State(item).income / 5);
            factionByType.AddIncome(-num, item);
            faction2.AddIncome(num, item);
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.super_sensha)
        {
            if (App.game.scenario.state.date.year >= 1945)
            {
                UnitType unitTypeByName = App.GetUnitTypeByName("type100_o-i");
                foreach (Unit unit2 in specialisation.faction.state.units)
                {
                    if (unit2.state.unitType != unitTypeByName)
                    {
                        continue;
                    }
                    return;
                }
                Unit unit3 = App.game.CreateUnit(specialisation.faction, unitTypeByName, null, 1, 0, App.game.actualGameState, false);
                UnitHistory unitHistory = unit3.history;
                List<string> strs = new List<string>()
                {
                    "enlisted",
                    string.Empty,
                    Localisation.GetLocalScenarioText("scenario_name"),
                    App.game.scenario.state.date.ToString()
                };
                unitHistory.AddHistory(strs);
            }
        }
        else if (specialisation.type.effect == GameSpecialisations.effects.plan_z && specialisation.faction.state.command[1] > 0)
        {
            IList<int> nums5 = specialisation.faction.state.command;
            nums5[1] = nums5[1] + 4;
        }
    }

    private static Faction FindOrAddCoreFaction(FactionType factionType, Alliance targetAlliance)
    {
        Faction factionByType = null;
        if (App.game.campaign != null)
        {
            bool flag = false;
            foreach (Faction faction in App.game.campaign.GetPlayerCore().factions)
            {
                if (faction.factionType != factionType)
                {
                    continue;
                }
                flag = true;
                factionByType = faction;
                break;
            }
            if (!flag)
            {
                Debug.Log("adding");
                factionByType = App.game.campaign.GetFactionByType(factionType);
                if (factionByType == null)
                {
                    factionByType = App.game.campaign.AddFaction(factionType, targetAlliance);
                    factionByType.index = App.game.campaign.factions.Count - 1;
                }
                App.game.campaign.GetPlayerCore().factions.Add(factionByType);
            }
        }
        if (App.game.scenario != null)
        {
            factionByType = App.game.scenario.GetFactionByType(factionType);
            if (factionByType == null)
            {
                factionByType = new Faction(App.game.scenario.AssignNextFactionId(), factionType)
                {
                    stats = new FactionStats(factionByType)
                };
                App.game.scenario.factions.Add(factionByType);
                App.map.CreateUnitPlateEmblem(factionByType);
                factionByType.index = App.game.scenario.factions.Count - 1;
            }
            if (factionByType.alliance != targetAlliance)
            {
                factionByType.SetAlliance(targetAlliance);
            }
        }
        return factionByType;
    }

    public static SpecialisationType GetSpecialisationTypeById(int id)
    {
        for (int i = 0; i < App.specialisationTypes.Count; i++)
        {
            if (App.specialisationTypes[i].id == id)
            {
                return App.specialisationTypes[i];
            }
        }
        return null;
    }

    public static SpecialisationType GetSpecialisationTypeByName(string name)
    {
        for (int i = 0; i < App.specialisationTypes.Count; i++)
        {
            if (App.specialisationTypes[i].name == name)
            {
                return App.specialisationTypes[i];
            }
        }
        return null;
    }

    public static bool HasFactionSpecialisationEffect(Faction faction, GameSpecialisations.effects effect)
    {
        for (int i = 0; i < faction.specialisations.Count; i++)
        {
            if (faction.specialisations[i].type.effect == effect)
            {
                return true;
            }
        }
        return false;
    }

    public static bool HasFactionSpecialisationType(Faction faction, string name)
    {
        return GameSpecialisations.HasFactionSpecialisationType(faction, GameSpecialisations.GetSpecialisationTypeByName(name));
    }

    public static bool HasFactionSpecialisationType(Faction faction, SpecialisationType specType)
    {
        for (int i = 0; i < faction.specialisations.Count; i++)
        {
            if (faction.specialisations[i].type.id == specType.id)
            {
                return true;
            }
        }
        return false;
    }

    public static void Init()
    {
        Debug.Log("init specs");
        int count = App.factionTypes.Count;
        GameSpecialisations.hasAuftragstaktik = new bool[count];
        GameSpecialisations.hasProximityFuse = new bool[count];
        GameSpecialisations.hasFieldMedics = new bool[count];
        GameSpecialisations.hasBanzaiCharge = new bool[count];
        GameSpecialisations.hasBushidoCode = new bool[count];
        GameSpecialisations.hasForcedLabour = new bool[count];
        GameSpecialisations.hasTokyoExpress = new bool[count];
        GameSpecialisations.hasRadarI = new bool[count];
        GameSpecialisations.hasRadarII = new bool[count];
        GameSpecialisations.hasDamageControl = new bool[count];
        GameSpecialisations.hasDropTank = new bool[count];
        GameSpecialisations.hasUnrestrictedSubWar = new bool[count];
        GameSpecialisations.hasWolfPack = new bool[count];
        GameSpecialisations.hasLibertyShips = new bool[count];
        GameSpecialisations.hasTorpImprovements = new bool[count];
        GameSpecialisations.hasMetalDetector = new bool[count];
        GameSpecialisations.hasBomberStream = new bool[count];
        GameSpecialisations.hasHobartsFunnies = new bool[count];
        GameSpecialisations.hasGoliath = new bool[count];
        GameSpecialisations.hasPakFront = new bool[count];
        GameSpecialisations.hasPanzerKeil = new bool[count];
        foreach (Faction faction in App.game.scenario.factions)
        {
            GameSpecialisations.hasAuftragstaktik[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.auftragstaktik);
            GameSpecialisations.hasProximityFuse[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.proximity_fuse);
            GameSpecialisations.hasFieldMedics[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.field_medics);
            GameSpecialisations.hasBanzaiCharge[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.banzai_charge);
            GameSpecialisations.hasBushidoCode[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.bushido_code);
            GameSpecialisations.hasForcedLabour[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.forced_labour);
            GameSpecialisations.hasTokyoExpress[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.destroyer_supply_bonus);
            GameSpecialisations.hasRadarI[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.radar_i);
            GameSpecialisations.hasRadarII[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.radar_ii);
            GameSpecialisations.hasDamageControl[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.damage_control);
            GameSpecialisations.hasDropTank[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.drop_tank);
            GameSpecialisations.hasUnrestrictedSubWar[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.unrestricted_submarine_warface);
            GameSpecialisations.hasWolfPack[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.wolfpack);
            GameSpecialisations.hasLibertyShips[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.liberty_ships);
            GameSpecialisations.hasTorpImprovements[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.torpedo_improvements);
            GameSpecialisations.hasMetalDetector[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.metal_detector);
            GameSpecialisations.hasBomberStream[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.bomber_stream);
            GameSpecialisations.hasHobartsFunnies[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.hobarts_funnies);
            GameSpecialisations.hasGoliath[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.goliath);
            GameSpecialisations.hasPakFront[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.pak_front);
            GameSpecialisations.hasPanzerKeil[faction.index] = GameSpecialisations.HasFactionSpecialisationEffect(faction, GameSpecialisations.effects.panzer_keil);
        }
    }

    public static void Unlock(Faction faction, SpecialisationType specialisationType)
    {
        GameSpecialisations.Unlock(faction, specialisationType, false);
    }

    public static void Unlock(Faction faction, SpecialisationType specialisationType, bool free)
    {
        if (GameSpecialisations.HasFactionSpecialisationType(faction, specialisationType))
        {
            return;
        }
        if (!free)
        {
            if (faction.specialisationPoints < specialisationType.cost)
            {
                return;
            }
            faction.specialisationPoints -= specialisationType.cost;
        }
        Specialisation specialisation = new Specialisation(faction, specialisationType);
        specialisation.AssignId(App.game.campaign.factions);
        if (App.mode == App.modes.campaign)
        {
            GameSpecialisations.ApplyCampaignEffect(specialisation);
        }
    }

    public static void UnlockFree(Faction faction, SpecialisationType specialisationType)
    {
        GameSpecialisations.Unlock(faction, specialisationType, true);
    }

    public enum effects
    {
        radar_i,
        landing_craft_infantry,
        land_cp_bonus,
        landing_craft_tank,
        wolfpack,
        british_pacific_fleet,
        hidden_nests,
        field_medics,
        aircraft_experience,
        proximity_fuse,
        forced_labour,
        destroyer_supply_bonus,
        kamikaze,
        super_sensha,
        plan_z,
        advanced_aeronautics,
        banzai_charge,
        auftragstaktik,
        beutepanzer,
        tank_experience,
        panzer_lehr,
        pak_front,
        panzer_keil,
        waffen_ss,
        nuke,
        naval_experience,
        damage_control,
        beaching,
        armed_merchants,
        pilot_rotation,
        drop_tank,
        winter_gear,
        infantry_experience,
        bushido_code,
        rationing,
        elite_air_groups,
        radar_ii,
        scrambling,
        build_bunkers,
        yanagi_missions,
        war_economy,
        female_laborers,
        gruppe_monsun,
        unrestricted_submarine_warface,
        block_construction,
        liberty_ships,
        flugzeugtrager,
        schlachtschiffe,
        torpedo_improvements,
        lend_lease,
        home_guard,
        metal_detector,
        hobarts_funnies,
        free_french,
        resistance_fighters,
        special_services,
        bomber_stream,
        waffen_ss_ii,
        waffen_ss_iii,
        arbeitnehmer,
        goliath,
        air_cp_bonus,
        baukommando_becker,
        panzer_fibel
    }
}