Пример #1
0
    public static int getMaxLevel(int level, Difficulty difficulty, RuneType runeType, ToyType toyType)
    {
        //this is only relevant for between levels, and this is OK because the Castle doesn't have any level caps.
        difficulty = difficulty == Difficulty.Null ? Difficulty.Normal : difficulty;
        level      = level == -1 ? 1 : level;


        LevelMod mod = getLevelMod(level, difficulty);

        if (mod.tower_max_level_settings == null && difficulty != Difficulty.Normal)
        {
            mod = getLevelMod(level, Difficulty.Normal);
        }


        for (int i = 0; i < mod.tower_max_level_settings.Count; i++)
        {
            if (mod.tower_max_level_settings[i].runeType == runeType && mod.tower_max_level_settings[i].toyType == toyType)
            {
                return(mod.tower_max_level_settings[i].maxLevel);
            }
        }

        if (difficulty != Difficulty.Normal)
        {
            return(getMaxLevel(level, Difficulty.Normal, runeType, toyType));
        }

        Debug.Log($"LevelStore does not have a difficulty setting for level: {level} {difficulty} toy: {runeType} {toyType}\n");
        return(0);
    }
Пример #2
0
 public StatSum(int level, float xp, StatBit[] stats, RuneType runetype)
 {
     this.level    = level;
     this.xp       = xp;
     this.stats    = stats;
     this.runetype = runetype;
 }
Пример #3
0
        /// <summary>
        /// Whether there are enough runes in this set to satisfy the given cost requirements
        /// </summary>
        public bool HasEnoughRunes(Spell spell)
        {
            var costs = spell.RuneCostEntry;

            if (costs == null || !costs.CostsRunes || Owner.Auras.GetModifiedInt(SpellModifierType.PowerCost, spell, 1) != 1)
            {
                // if we have any rune-related power cost modifier, we have no rune costs at all (only used for Freezing Fog right now)
                return(true);
            }
            for (RuneType type = 0; type < (RuneType)costs.CostPerType.Length; type++)
            {
                var cost = costs.CostPerType[(int)type];
                if (cost > 0)
                {
                    for (var i = 0; i < SpellConstants.MaxRuneCount; i++)
                    {
                        if ((ActiveRunes[i] == type || ActiveRunes[i] == RuneType.Death) &&
                            Cooldowns[i] <= 0)
                        {
                            cost--;
                        }
                    }
                    if (cost > 0)
                    {
                        return(false);
                    }
                }
            }
            return(true);
        }
Пример #4
0
 public void OnRuneCollected(RuneType rune)
 {
     if (rune == lockRune1 || rune == lockRune2)
     {
         ClosedDoorParent.SetActive(false);
     }
 }
Пример #5
0
    public void loadSnapshot(RuneSaver saver)
    {
        runetype       = saver.runetype;
        toy_type       = saver.toy_type;
        invested_cost  = saver.invested_cost;
        ID             = saver.ID;
        level          = saver.level;
        xp             = saver.xp;
        distance_bonus = saver.distance_bonus;
        order          = saver.order;

        if (saver.max_level < 0)
        {
            saver.max_level = 0;
        }
        int max_level = Mathf.Max(saver.max_level,
                                  LevelStore.getMaxLevel(Central.Instance.current_lvl, Peripheral.Instance.difficulty, runetype, toy_type));

        setMaxLevel(max_level);

        Sun.OnDayTimeChange += OnDayTimeChange;
        StaticRune.assignStatBits(ref stats, this);

        foreach (StatBitSaver s in saver.stats)
        {
            StatBit stat = getStat(s.effect_type);
            stat.loadSnapshot(s, this);
        }

        UpdateTimeOfDay();
        setXpReqs();
        UpdateStats();
    }
Пример #6
0
    public void RemveNewItem(RuneType type)
    {
        List <PItem> rune = RuneShow(type);

        RemoveItem(rune);
        NewHintShow();
    }
Пример #7
0
        private bool IsRunePingEnabledFor(RuneType rune)
        {
            switch (rune)
            {
            case RuneType.DoubleDamage:
                return(bottledRune.Value.IsEnabled("item_bottle_doubledamage"));

            case RuneType.Haste:
                return(bottledRune.Value.IsEnabled("item_bottle_haste"));

            case RuneType.Illusion:
                return(bottledRune.Value.IsEnabled("item_bottle_illusion"));

            case RuneType.Invisibility:
                return(bottledRune.Value.IsEnabled("item_bottle_invisibility"));

            case RuneType.Regeneration:
                return(bottledRune.Value.IsEnabled("item_bottle_regeneration"));

            case RuneType.Arcane:
                return(bottledRune.Value.IsEnabled("item_bottle_arcane"));

            default:
                return(false);
            }
        }
Пример #8
0
        public bool IsNeedShowRuneAddTip()
        {
            if (uCurRunePageData == null || uCurRunePageData.dRuneTempSlotInfo == null)
            {
                return(false);
            }

            foreach (int nRuneIdKey in uCurRunePageData.dRuneTempSlotInfo.Keys)
            {
                int nPoints = uCurRunePageData.dRuneTempSlotInfo[nRuneIdKey];
                if (nPoints > 0)
                {
                    continue;
                }

                RuneType eRuneType = GetRuneTypeByRuneSlotID(nRuneIdKey);
                if (dicRuneInlayTypeLeftStoreInfo.ContainsKey((int)eRuneType))
                {
                    if (dicRuneInlayTypeLeftStoreInfo[(int)eRuneType].Count > 0)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Пример #9
0
        /// <summary>
        /// Whether there are enough runes in this set to satisfy the given cost requirements
        /// </summary>
        public bool HasEnoughRunes(Spell spell)
        {
            RuneCostEntry runeCostEntry = spell.RuneCostEntry;

            if (runeCostEntry == null || !runeCostEntry.CostsRunes ||
                this.Owner.Auras.GetModifiedInt(SpellModifierType.PowerCost, spell, 1) != 1)
            {
                return(true);
            }
            for (RuneType runeType = RuneType.Blood; runeType < (RuneType)runeCostEntry.CostPerType.Length; ++runeType)
            {
                int num = runeCostEntry.CostPerType[(int)runeType];
                if (num > 0)
                {
                    for (int index = 0; index < 6; ++index)
                    {
                        if ((this.ActiveRunes[index] == runeType || this.ActiveRunes[index] == RuneType.Death) &&
                            (double)this.Cooldowns[index] <= 0.0)
                        {
                            --num;
                        }
                    }

                    if (num > 0)
                    {
                        return(false);
                    }
                }
            }

            return(true);
        }
Пример #10
0
    public static CostType costType(RuneType rune_type, ToyType toy_type)
    {
        //{ Dreams, Wishes, SensibleHeroPoint, AiryHeroPoint, VexingHeroPoint, ScorePoint };

        if (toy_type == ToyType.Hero)
        {
            switch (rune_type)
            {
            case RuneType.SensibleCity:
                return(CostType.SensibleCityHeroPoint);

            case RuneType.Sensible:
                return(CostType.SensibleHeroPoint);

            case RuneType.Airy:
                return(CostType.AiryHeroPoint);

            case RuneType.Vexing:
                return(CostType.VexingHeroPoint);

            default:
                Debug.Log("Invalid costtype for " + rune_type + " " + toy_type + " \n");
                return(CostType.Dreams);
            }
        }
        else if (toy_type == ToyType.Temporary)
        {
            return(CostType.Wishes);
        }
        else
        {
            return(CostType.Dreams);
        }
    }
Пример #11
0
    public static float GetTimeBonus(RuneType rune_type, ToyType toytype)
    {
        //if (Central.Instance.state != GameState.InGame) return 0f;

        //if (toytype == ToyType.Hero) return 0f;  //meh this makes things confusing cuz the hero towers are identical to regular towers but somehow do less damage during the day??
        //if (rune_type == Rune)
        TimeName now = Sun.Instance.GetCurrentTime();

        float default_time_bonus = 0.33f;
        float ghost_time_bonus   = 0.33f;

        switch (rune_type)
        {
        case RuneType.Sensible:
            return((now == TimeName.Dawn || now == TimeName.Day) ? default_time_bonus : 0f);

        case RuneType.Airy:
            return((now == TimeName.Dawn || now == TimeName.Day) ? default_time_bonus : 0f);

        case RuneType.Vexing:
            return((now == TimeName.Dawn || now == TimeName.Day) ? default_time_bonus : 0f);

        case RuneType.Slow:
            return((now == TimeName.Night || now == TimeName.Dusk) ? ghost_time_bonus : 0f);

        case RuneType.Time:
            return((now == TimeName.Night || now == TimeName.Dusk) ? ghost_time_bonus : 0f);

        case RuneType.Fast:
            return((now == TimeName.Night || now == TimeName.Dusk) ? ghost_time_bonus : 0f);
        }
        return(0f);
    }
Пример #12
0
        // Constructor
        public Stage(
            string nDescription          = "",
            float nCastDuration          = 0.0f,
            float nCooldown              = 0.0f,
            PositionType nPosType        = PositionType.AtHitPoint,
            Vector3 nPosOffset           = default(Vector3),
            RotationType nRotType        = RotationType.None,
            CastAnimation nAnimType      = CastAnimation.None,
            SkillEffectId nEffectId      = SkillEffectId.None,
            GameObject nCastEffectPrefab = null,
            //ParticlesType nAttackParticlesType = ParticlesType.None,
            AudioClip[] nCastVoices     = null,
            float nPowerMultiplier      = 1.0f,
            float nStaggerDuration      = 0.0f,
            float nBlockCostAbs         = 0.0f,
            float nLifeDrainRel         = 0.0f,
            bool nCanMoveWhileCasting   = true,
            bool nCanMoveWhileAttacking = true,
            bool nIsRuneDetonator       = false,
            RuneType nRuneType          = RuneType.None
            )
        {
            description  = nDescription;
            castDuration = nCastDuration;
            //nCooldown = 0.0f;
            originalCooldown = nCooldown;
            cooldown         = nCooldown;
            posType          = nPosType;
            posOffset        = nPosOffset;
            rotType          = nRotType;
            animType         = nAnimType;
            effectId         = nEffectId;
            castEffectPrefab = nCastEffectPrefab;
            //attackParticlesType = nAttackParticlesType;
            castVoices      = nCastVoices;
            effect          = SkillEffect.skillEffectList[(int)effectId];
            energyCostAbs   = nBlockCostAbs;
            lifeDrainRel    = nLifeDrainRel;
            powerMultiplier = nPowerMultiplier;
            staggerDuration = nStaggerDuration;

            // Check
            if (lifeDrainRel > 1f)
            {
                LogManager.General.LogError("More than 100% life drain is not allowed for ranking reasons!");
            }

            if (castVoices == null)
            {
                castVoices = new AudioClip[0];
            }

            canMoveWhileCasting   = nCanMoveWhileCasting;
            canMoveWhileAttacking = nCanMoveWhileAttacking;

            // Runes
            isRuneDetonator = nIsRuneDetonator;
            runeType        = nRuneType;
        }
Пример #13
0
    public string GetToyFromRune(RuneType r)
    {
        string effect_toy = null;

        effect_toys.TryGetValue(r, out effect_toy);

        return(effect_toy);
    }
Пример #14
0
 public Rune(string name, RuneType type, RuneLevel level, string description)
 {
     Id          = Guid.NewGuid();
     Name        = name;
     Type        = type;
     this.level  = level;
     Description = description;
 }
Пример #15
0
 void onCanUpgrade(RuneType type)
 {
     //     Debug.Log("received on can upgrade");
     if (text.Equals("") || type.ToString().Equals(text))
     {
         selected = true;
     }
 }
Пример #16
0
 public int CompareTo(RuneType runetype, ToyType toy_type)
 {
     if (runetype == this.rune_type && toy_type == this.toy_type)
     {
         return(0);
     }
     return(1);
 }
Пример #17
0
 void onPlacedToy(string content, RuneType runetype, ToyType toytype)
 {
     //     Debug.Log("trigger Got onplacedtoy " + content + ", need " + text + "\n");
     if (text.Equals("") || content.Contains(text))
     {
         selected = true;
     }
 }
Пример #18
0
    public bool HaveHero(RuneType type)
    {
        int current_point = -1;

        hero_points.TryGetValue(type, out current_point);
        //  Debug.Log("Have hero " + type + "? " + current_point);
        return(current_point > 0);
    }
Пример #19
0
    public IEnumerator DelayedReturnRune(RuneType runeType)
    {
        yield return(new WaitForUpdate());

        if (RuneStock.Inst != null)
        {
            AddRune(runeType);
        }
    }
Пример #20
0
    public static string getImage(RuneType rune_type, ToyType toy_type)
    {
        //{ Dreams, Wishes, SensibleHeroPoint, AiryHeroPoint, VexingHeroPoint, ScorePoint };


        switch (rune_type)
        {
        case RuneType.SensibleCity:
            return("sensible_city");

        case RuneType.Sensible:

            if (toy_type == ToyType.Hero)
            {
                return("sensible_tower_hero");
            }
            else
            {
                return("sensible_tower");
            }

        case RuneType.Airy:
            if (toy_type == ToyType.Hero)
            {
                return("airy_tower_hero");
            }
            else
            {
                return("airy_tower");
            }

        case RuneType.Vexing:
            if (toy_type == ToyType.Hero)
            {
                return("vexing_tower_hero");
            }
            else
            {
                return("vexing_tower");
            }

        case RuneType.Slow:
            return("slow_ghost");

        case RuneType.Fast:
            return("sensible_tower_ghost");

        case RuneType.Time:
            return("time_ghost");

        case RuneType.Modulator:
            return("modulator");

        default:
            return("selected_island_image");
        }
    }
Пример #21
0
    void Equip(int where)
    {
        Debug.Log(possess_Rune[where]);
        int size = 0;

        if ((int)possess_Rune[where] < 4 || (int)possess_Rune[where] > 7)
        {
            size = 1;
            Debug.Log("들옴");
        }
        else
        {
            size = 2;
        }
        //
        if (size == 1)
        {
            bool enable = false;
            for (int i = 0; i < 5; i++)
            {
                if (UsesmallRune[i] == RuneType.none)
                {
                    UsesmallRune[i] = possess_Rune[where];
                    Equiptext_uppload((int)UsesmallRune[i]);
                    Destroy(possess_Rune_gb[where]);
                    possess_Rune.RemoveRange(where, 1);
                    possess_Rune_gb.RemoveRange(where, 1);
                    enable = true;
                    Wheres = -1;
                    break;
                }
                if (enable == true)
                {
                }
            }
        }
        if (size == 2)
        {
            if (ShowUseBigRune != null)
            {
                possess_Rune.Add(UseBigRune);
                Destroy(ShowUseBigRune);
            }
            UseBigRune = possess_Rune[Wheres];
            Destroy(possess_Rune_gb[Wheres]);
            possess_Rune.RemoveRange(Wheres, 1);
            possess_Rune_gb.RemoveRange(Wheres, 1);

            ShowUseBigRune = Instantiate(RunePrefebs[(int)UseBigRune]);
            ShowUseBigRune.transform.SetParent(transform);
            ShowUseBigRune.transform.localScale    = new Vector3(1.1f, 1.1f, 1.1f);
            ShowUseBigRune.transform.localPosition = new Vector3(0, 295, -1);
        }
        ShowRunePage();
        RuneEffect();
    }
Пример #22
0
        public static void SendConvertRune(IRealmClient client, uint index, RuneType type)
        {
            using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_CONVERT_RUNE, 2))
            {
                packet.Write((byte)index);
                packet.Write((byte)type);

                client.Send(packet, addEnd: false);
            }
        }
Пример #23
0
//{"name":"slow_ghost",          "toy_type": "temporary","cost":"2","scale":{"x":"1","z":"1"},"ammo":"5", "arrow":"slow","required_building":"sensible_city","islandtype":"temporary","rune_type":"Slow"}


    public RuneType getRuneType()
    {
        RuneType rt = EnumUtil.EnumFromString <RuneType>(rune_type, RuneType.Null);

        if (rt == RuneType.Null)
        {
            Debug.LogError("Attempting to get an invalid runetype from InitToy " + name + "\n");
        }
        return(rt);
    }
Пример #24
0
        protected void SpawnRune(double X, double Y, RuneType type, RuneSize size = RuneSize.Normal)
        {
            var rune = new InternalRuneData(type, size, new Frame3D(X, Y, 0));
            var id   = world.IdGenerator.CreateNewId(rune);

            var p = rune.Location;

            world.GetEngine <IPudgeWorldEngine>().SpawnRune(rune.Type, rune.Size, p.X, p.Y, p.Z, id);
            world.SpawnedRunes.Add(rune);
        }
Пример #25
0
    public void CollectRune(RuneType type)
    {
        CollectedRunes.Add(type);
        RuneCollected.Invoke(type);

        var image = RuneUIImages[CollectedRunes.Count - 1];

        image.sprite = RuneSpriteDisambiguator.GetSpriteByType(type);
        image.color  = Color.white;
    }
Пример #26
0
 public StoreConfirmParam(Rune rune, RuneType type, pd_GoodsData goods, OnOkDeleage _del, bool is_event)
 {
     title         = rune.GetName();
     this.icon_id  = goods.goods_type.ToString();
     this.price    = goods.goods_value;
     rune_item     = rune;
     message       = Localization.Get(type + "Confirm");
     OnOk          = _del;
     this.is_event = is_event;
 }
Пример #27
0
        public void DrawRune(RuneType type, HexXY p)
        {
            if (!knownRunes.Contains(type))
            {
                if (ActionFailure != null)
                {
                    ActionFailure();
                }
                return;
            }

            DoAfterMoveTo(() =>
            {
                bool isSuccess = !isWalking && Rune.CanDraw(this, type, p) && knownRunes.Contains(type);
                if (isSuccess)
                {
                    var runeData     = Data.runeDatas[type];
                    var existingRune = Level.S.GetEntities(p).OfType <Rune>().FirstOrDefault();
                    if (existingRune != null)
                    {
                        if (existingRune.entityType == (uint)type)
                        {
                            if (runeData.isDirectional)
                            {
                                //Rotate rune
                                existingRune.dir = (existingRune.dir + 1) % 6;
                                existingRune.UpdateInterface();
                            }
                            else if (ActionFailure != null)
                            {
                                ActionFailure();
                            }
                        }
                        else
                        {
                            //Erase old rune
                            existingRune.Die();
                            existingRune = null;
                        }
                    }

                    if (existingRune == null)
                    {
                        //Draw new rune
                        var rune        = new Rune(0);
                        rune.entityType = (uint)type;
                        rune.Spawn(p);
                    }
                }
                else if (ActionFailure != null)
                {
                    ActionFailure();
                }
            }, p, 1);
        }
Пример #28
0
 static public int GetRuneIndex(RuneType type, String name)
 {
     if (type == RuneType.Button)
     {
         return(Runes.buttons.FindIndex(e => e.type == type && e.names.Contains(name)));
     }
     else
     {
         return(Runes.runes.FindIndex(e => e.type == type && e.names.Contains(name)));
     }
 }
Пример #29
0
 public int GetIndexOfFirstRuneOfType(RuneType type, bool onlyIfNotOnCooldown = false)
 {
     for (var i = 0; i < SpellConstants.MaxRuneCount; i++)
     {
         if (ActiveRunes[i] == type && (!onlyIfNotOnCooldown || Cooldowns[i] <= 0))
         {
             return i;
         }
     }
     return -1;
 }
Пример #30
0
 public static string ToString(RuneType runetype)
 {
     switch (runetype)
     {
         case RuneType.Champion: return Resources.Champion;
         case RuneType.Spell: return Resources.Spell;
         case RuneType.Relic: return Resources.Relic;
         case RuneType.Equipment: return Resources.Equipment;
         default: throw new InvalidEnumArgumentException("runetype", (int)runetype, typeof(RuneType));
     }
 }
Пример #31
0
 public Firearm getHero(RuneType type)
 {
     foreach (Firearm f in firearms)
     {
         if (f.toy.toy_type == ToyType.Hero && f.toy.runetype == type)
         {
             return(f);
         }
     }
     return(null);
 }
Пример #32
0
 static public Runes GetRune(RuneType type, String name)
 {
     if (type == RuneType.Button)
     {
         return(Runes.buttons.Find(e => e.type == type && e.names.Contains(name.ToLower())));
     }
     else
     {
         return(Runes.runes.Find(e => e.type == type && e.names.Contains(name.ToLower())));
     }
 }
Пример #33
0
 public bool Convert(RuneType from, RuneType to, bool onlyIfNotOnCooldown = true)
 {
     for (var i = 0u; i < SpellConstants.MaxRuneCount; i++)
     {
         if (ActiveRunes[i] == from && (!onlyIfNotOnCooldown || Cooldowns[i] <= 0))
         {
             Convert(i, to);
             return true;
         }
     }
     return false;
 }
Пример #34
0
		public static void MakeRuneConversionProc(SpellLineId line, SpellLineId trigger1, SpellLineId trigger2, RuneType to, params RuneType[] from)
		{
			line.Apply(spell =>
			{
				spell.ProcTriggerFlags = ProcTriggerFlags.SpellCast;

				var effect = spell.GetEffect(AuraType.Dummy2);
				// should not have an amplitude 
				// (although it's probably the timeout for when the death rune is converted back to its original but it's not mentioned in the tooltip)
				effect.Amplitude = 0;

				effect.ClearAffectMask();
				effect.AddAffectingSpells(trigger1, trigger2);
				effect.IsProc = true;
				effect.AuraEffectHandlerCreator = () => new ProcRuneConversionHandler(to, from);
			});
		}
Пример #35
0
 public void ModCooldown(RuneType type, float delta)
 {
     SetCooldown(type, GetCooldown(type) + delta);
 }
Пример #36
0
 public void SetCooldown(RuneType type, float cdPerSecond)
 {
     Owner.SetFloat(PlayerFields.RUNE_REGEN_1 + (int)type, cdPerSecond);
 }
Пример #37
0
 /// <summary>
 /// Gets the cooldown of the given RuneType in rune refreshment per second.
 /// For example:
 /// 1 = a rune refreshes in one second;
 /// 0.1 = a rune refrehes in 10 seconds.
 /// </summary>
 public float GetCooldown(RuneType type)
 {
     return Owner.GetFloat(PlayerFields.RUNE_REGEN_1 + (int)type);
 }
Пример #38
0
 /// <summary>
 /// Returns how many runes of the given type are ready
 /// </summary>
 public int GetReadyRunes(RuneType type)
 {
     var count = 0;
     for (var i = 0; i < SpellConstants.MaxRuneCount; i++)
     {
         if (ActiveRunes[i] == type && Cooldowns[i] <= 0)
         {
             count++;
         }
     }
     return count;
 }
Пример #39
0
 public RuneProxy(GetUnitDelegate del, RuneType type)
     : base(del)
 {
     this.type = type;
 }
Пример #40
0
			public ProcRuneConversionHandler(RuneType to, RuneType[] @from)
			{
				To = to;
				From = from;
			}
Пример #41
0
		public static bool HasAnyFlag(this RuneMask mask, RuneType type)
		{
			return (mask & type.ToMask()) != 0;
		}
Пример #42
0
		public static void SendConvertRune(IRealmClient client, uint index, RuneType type)
		{
			using (var packet = new RealmPacketOut(RealmServerOpCode.SMSG_CONVERT_RUNE, 2))
			{
				packet.Write((byte)index);
				packet.Write((byte)type);

				client.Send(packet);
			}
		}
Пример #43
0
 public Rune(RuneType t, uint c) {
     this.Type = t;
     this.Cost = c;
 }
Пример #44
0
		public int GetCost(RuneType type)
		{
			return CostPerType[(int) type];
		}
Пример #45
0
 public RuneData()
 {
     key = -1;
     type = RuneType.Energy;
     no = 1;
     rank = 1;
     level = 0;
     mainOption = new RuneOption(RuneParam.None, 0);
     subOption =  new RuneOption(RuneParam.None, 0);
     bonusOption = new List<RuneOption>();
     bonusOption.Add(new RuneOption(RuneParam.None, 0));
     bonusOption.Add(new RuneOption(RuneParam.None, 0));
     bonusOption.Add(new RuneOption(RuneParam.None, 0));
     bonusOption.Add(new RuneOption(RuneParam.None, 0));
 }
Пример #46
0
 public void Convert(uint index, RuneType to)
 {
     ActiveRunes[index] = to;
     SpellHandler.SendConvertRune(Owner.Client, index, to);
 }
Пример #47
0
 private void PopulateRunes(PoxNoraRune[] pnRunes, RuneType runeType)
 {
     foreach (PoxNoraRune item in pnRunes)
     {
         // create a Rune object by populating it with data from the PoxNoraRune object
         Rune r = new Rune
         {
             Name = item.Name,
             BaseID = item.BaseID,
             Factions = new List<Faction>(item.Factions.Select(faction => m_FactionMap[faction])),
             Rarity = m_RarityMap[item.Rarity],
             RuneType = runeType,
         };
         m_Runes.Add(r);
     }
 }