Exemplo n.º 1
0
        public void CreateItemExpList()
        {
            ILevelable levitem = (ILevelable)m_Item;

            AddLabel(75, 275, LabelHue, @"Max levels on item:");
            AddLabel(198, 275, LabelHue, levitem.MaxLevel.ToString());

            AddLabel(75, 297, LabelHue, @"Experience:");
            AddLabel(154, 297, LabelHue, levitem.Experience.ToString());

            int tolevel = 0;

            for (int i = 0; i < LevelItemManager.ExpTable.Length; ++i)
            {
                if (levitem.Experience < LevelItemManager.ExpTable[i])
                {
                    tolevel = LevelItemManager.ExpTable[i] - levitem.Experience;
                    break;
                }
            }
            AddLabel(75, 319, LabelHue, @"Exp. to next level:");
            AddLabel(191, 319, LabelHue, tolevel.ToString());

            AddLabel(75, 341, LabelHue, @"Spending Points(sp) Avail:");
            AddLabel(230, 341, LabelHue, levitem.Points.ToString());
        }
        public ItemInfoGump( ILevelable item )
            : base(50, 50)
        {
            this.Closable=true;
            this.Disposable=true;
            this.Dragable=true;
            this.Resizable=false;

            this.AddPage(0);
            this.AddBackground(0, 0, 273, 388, 2620);
            this.AddAlphaRegion(5, 7, 262, 373);
            this.AddLabel(45, 15, 955, @"Levelable Weapon Information");
            this.AddLabel(20, 50, 955, @"This item's attributes are level based.");
            this.AddLabel(20, 68, 955, @"You can gain levels by fighting the");
            this.AddLabel(20, 86, 955, @"monsters in the following list.");
            this.AddButton(233, 354, 4017, 4018, (int)Buttons.Close, GumpButtonType.Reply, 0);
            this.AddLabel(192, 354, 955, @"Close");

            StringBuilder builder = new StringBuilder();

            builder.Append("<div align=center><i>MONSTER LIST</i></div>");

            if (item.Types != null)
            {
                for (int i = 0; i < item.Types.Length; ++i)
                {
                    builder.Append(item.Types[i].Name);
                    builder.Append("<br>");
                }
            }

            builder.Append(item.GetHtml());

            this.AddHtml(13, 110, 247, 235, builder.ToString(), (bool)true, (bool)true);
        }
Exemplo n.º 3
0
        public static void CheckLevelable(ILevelable item, Mobile killer, Mobile killed)
        {
            if ((item.Level >= LevelItems.MaxLevelsCap) || (item.Level >= item.MaxLevel))
            {
                return;
            }

            int exp      = CalcExp(killed);
            int oldLevel = item.Level;
            int expcap   = CalcExpCap(oldLevel);

            if (LevelItems.EnableExpCap && exp > expcap)
            {
                exp = expcap;
            }

            item.Experience += exp;

            InvalidateLevel(item);

            if (item.Level != oldLevel)
            {
                OnLevel(item, oldLevel, item.Level, killer);
            }

            if (item is Item)
            {
                ((Item)item).InvalidateProperties();
            }
        }
Exemplo n.º 4
0
        private Object HandleSetPercentageRequest(JObject request)
        {
            SetPercentageRequestPayload payload =
                JsonConvert.DeserializeObject <SetPercentageRequestPayload>(
                    request["payload"].ToString()
                    );
            string     DeviceID        = payload.Appliance.ApplianceId;
            double     setPercent      = payload.PercentageState.Value;
            ushort     scaledPercent   = Convert.ToUInt16(Math.Round(setPercent * 655.35, 0));
            Appliance  device          = DeviceList.GetDevice(DeviceID);
            ILevelable levelableDevice = device as ILevelable;

            if (levelableDevice != null)
            {
                levelableDevice.SetLevel(scaledPercent);
            }
            // TODO: return an error if not levelable
            return(new Response()
            {
                Header = new Header()
                {
                    Namespace = "Alexa.ConnectedHome.Control",
                    Name = DirectiveName.SetPercentageConfirmation,
                    PayloadVersion = "2",
                    MessageID = Guid.NewGuid(),
                },
                Payload = new Dictionary <string, string> {
                },
            });
        }
 public void Construct(IIdentifiable <int> identifiable, IPayloadViewController payloadViewController,
                       IColorable colorable, ILevelable levelable, IScalable scalable)
 {
     m_Identifiable          = identifiable;
     m_PayloadViewController = payloadViewController;
     m_Colorable             = colorable;
     m_Levelable             = levelable;
     m_Scalable = scalable;
 }
Exemplo n.º 6
0
        public static void InvalidateLevel(ILevelable item)
        {
            for (int i = 0; i < ExpTable.Length; ++i)
            {
                if (item.Experience < ExpTable[i])
                {
                    return;
                }

                item.Level = i + 1;
            }
        }
Exemplo n.º 7
0
        public static void SetLevelableProperty(this ILevelable levelable, List <FieldInfo> levelablePropertiesInfoCached)
        {
            if (!levelable.LevelablePropertiesList.Any() ||
                !levelable.LevelablePropertiesList.Last().levelablePropertiesInfo.IsNullOrEmpty())
            {
                return;
            }

            var lastStruct = levelable.LevelablePropertiesList.Last();

            lastStruct.levelablePropertiesInfo = levelablePropertiesInfoCached.Select(f => f.Name).ToList();

            levelable.LevelablePropertiesList.RemoveAt(levelable.LevelablePropertiesList.Count - 1);
            levelable.LevelablePropertiesList.Add(lastStruct);
        }
Exemplo n.º 8
0
        public static void OnLevel(ILevelable item, int oldLevel, int newLevel, Mobile from)
        {
            /* This is where we control all our props
             * and their maximum value. */
            int    index;
            string itemdesc;

            index = newLevel % 10;
            if (index == 0)
            {
                item.Points += LevelItems.PointsPerLevel * 2;
            }
            else
            {
                item.Points += LevelItems.PointsPerLevel;
            }

            from.PlaySound(0x20F);
            from.FixedParticles(0x376A, 1, 31, 9961, 1160, 0, EffectLayer.Waist);
            from.FixedParticles(0x37C4, 1, 31, 9502, 43, 2, EffectLayer.Waist);

            if (item is BaseWeapon)
            {
                itemdesc = "weapon";
            }
            else if (item is BaseArmor)
            {
                itemdesc = "armor";
            }
            else if (item is BaseJewel)
            {
                itemdesc = "jewelry";
            }
            else if (item is BaseClothing)
            {
                itemdesc = "clothing";
            }
            else
            {
                itemdesc = "item";
            }

            from.SendMessage("Your " + itemdesc + " has gained a level. It is now level {0}.", newLevel);
        }
Exemplo n.º 9
0
            protected override void OnTarget(Mobile from, object target)
            {
                if (target is Mobile)
                {
                    from.SendMessage("This scroll cannot be applied to that!");
                }
                else if (target is Item)
                {
                    Item item = (Item)target;

                    if (item.RootParent != from || !item.IsChildOf(from.Backpack)) // Make sure its in their pack or they are wearing it
                    {
                        from.SendMessage("The item must be in your pack to level it up.");
                    }
                    else
                    {
                        if (target is ILevelable)
                        {
                            ILevelable b = (ILevelable)target;

                            if ((b.MaxLevel + m_Scroll.Value) > LevelItems.MaxLevelsCap)
                            {
                                from.SendMessage("The level on this item is already too high to use this scroll!");
                            }
                            else
                            {
                                b.MaxLevel += m_Scroll.Value;
                                from.SendMessage("Your item has leveled up by " + m_Scroll.Value + " levels.");
                                m_Scroll.Delete();
                            }
                        }
                        else
                        {
                            from.SendMessage("Invalid Target Type.  Levelable Weapons, Armor, and Clothing only!");
                        }
                    }
                }
                else
                {
                    from.SendMessage("Invalid Target Type.  Levelable Weapons, Armor, and Clothing only!");
                }
            }
Exemplo n.º 10
0
            protected override void OnTarget(Mobile from, object target)
            {
                if (target is Mobile)
                {
                    from.SendMessage("This rune cannot enhance that!");
                }
                else if (target is Item)
                {
                    Item item = (Item)target;

                    if (item.RootParent != from || !item.IsChildOf(from.Backpack)) // Make sure its in their pack or they are wearing it
                    {
                        from.SendMessage("The legendary artifact must be in your pack to enhance.");
                    }
                    else
                    {
                        if (target is ILevelable)
                        {
                            ILevelable b = (ILevelable)target;

                            if ((b.MaxLevel + m_Scroll.Value) > LevelItems.MaxLevelsCap)
                            {
                                from.SendMessage("The level on this legendary artifact is already too high to use this rune!");
                            }
                            else
                            {
                                b.MaxLevel += m_Scroll.Value;
                                from.SendMessage("Your legendary artifact has been enhanced by " + m_Scroll.Value + " levels.");
                                m_Scroll.Delete();
                            }
                        }
                        else
                        {
                            from.SendMessage("This rune cannot enhance that!");
                        }
                    }
                }
                else
                {
                    from.SendMessage("This rune cannot enhance that!");
                }
            }
Exemplo n.º 11
0
        private Object HandleDeltaPercentageRequest(JObject request, string eventName, DirectiveName responseType)
        {
            DeltaPercentageRequestPayload payload =
                JsonConvert.DeserializeObject <DeltaPercentageRequestPayload>(
                    request["payload"].ToString()
                    );
            string DeviceID      = payload.Appliance.ApplianceId;
            double setPercent    = payload.DeltaPercentage.Value;
            ushort scaledPercent = Convert.ToUInt16(Math.Round(setPercent * 655.35, 0));

            Appliance  device          = DeviceList.GetDevice(DeviceID);
            ILevelable levelableDevice = device as ILevelable;

            if (levelableDevice != null)
            {
                if (eventName == "raise")
                {
                    levelableDevice.RaiseLevel(scaledPercent);
                }
                else if (eventName == "lower")
                {
                    levelableDevice.LowerLevel(scaledPercent);
                }
            }

            return(new Response()
            {
                Header = new Header()
                {
                    Namespace = "Alexa.ConnectedHome.Control",
                    Name = responseType,
                    PayloadVersion = "2",
                    MessageID = Guid.NewGuid(),
                },
                Payload = new Dictionary <string, string> {
                },
            });
        }
Exemplo n.º 12
0
        public static void SetAbilityLevel(this ILevelable ability, int level,
                                           List <FieldInfo> levelablePropertiesInfo, IActor actor, IActor target = null)
        {
            ability.Level = level;

            foreach (var levelableProperty in ability.LevelablePropertiesList)
            {
                var fieldInfo =
                    levelablePropertiesInfo.FirstOrDefault(f => f.Name == levelableProperty.propertyName);

                if (fieldInfo == null || fieldInfo.FieldType != levelableProperty.modifier.GetType())
                {
                    continue;
                }

                var fieldValue = fieldInfo.GetValue(ability);

                var newValue = 0.0f;

                switch (levelableProperty.levelablePropertyAction)
                {
                case ModifiablePropertiesActions.Multiply:
                    newValue = target == null || target == actor.Owner
                            ?  (float)fieldValue * levelableProperty.modifier
                            : (float)((float)fieldValue * Math.Pow(levelableProperty.modifier, ability.Level - 1));
                    break;

                case ModifiablePropertiesActions.Add:
                    newValue = target == null || target == actor.Owner
                            ? (float)fieldValue + levelableProperty.modifier
                            : (float)fieldValue + (ability.Level - 1) * levelableProperty.modifier;
                    break;
                }

                fieldInfo.SetValue(ability, newValue);
            }
        }
        public static void CheckLevelable( ILevelable item, Mobile killer, Mobile killed )
        {
            if ( item.Types == null )
                return;

            if ( item.Level >= Levels )
                return;

            for( int i = 0; i < item.Types.Length; ++i )
            {
                if ( killed.GetType() == item.Types[i] )
                {
                    int exp = CalcExp( killed );
                    int oldLevel = item.Level;

                    item.Experience += exp;

                    InvalidateLevel( item );

                    if ( item.Level != oldLevel )
                        item.OnLevel( oldLevel, item.Level );

                    if ( item is Item )
                        ((Item)item).InvalidateProperties();
                }
            }
        }
        public static void InvalidateLevel( ILevelable item )
        {
            for( int i = 0; i < ExpTable.Length; ++i )
            {
                if ( item.Experience < ExpTable[i] )
                    return;

                item.Level = i + 1;
            }
        }
Exemplo n.º 15
0
 /// <summary>
 /// Set the Level Controller Interface
 /// </summary>
 /// <param name="levelController">Interface levelController</param>
 public void SetLevelControl(ILevelable levelController)
 {
     levelControl = levelController;
 }
Exemplo n.º 16
0
        public override void OnResponse(NetState sender, RelayInfo info)
        {
            if (info.ButtonID <= 0)
            {
                return;                 // Canceled
            }
            ILevelable levitem = (ILevelable)m_Item;

            int buttonID = info.ButtonID - 1;
            int type     = buttonID % 7;
            int index    = buttonID / 7;

            int cost      = 0;
            int attrvalue = 0;

            switch (type)
            {
            case 0:                     // Cancel
            {
                break;
            }

            case 1:                     // Select Attribute Type
            {
                switch (index)
                {
                case 0:                                 // Melee
                {
                    m_From.SendGump(new ItemExperienceGump(m_From, m_Item, AttributeCategory.Melee, GumpPage.AttributeList));

                    break;
                }

                case 1:                                 // Magic
                {
                    m_From.SendGump(new ItemExperienceGump(m_From, m_Item, AttributeCategory.Magic, GumpPage.AttributeList));

                    break;
                }

                case 2:                                 // Char Stats
                {
                    m_From.SendGump(new ItemExperienceGump(m_From, m_Item, AttributeCategory.Stats, GumpPage.AttributeList));

                    break;
                }

                case 3:                                 // Resistances
                {
                    m_From.SendGump(new ItemExperienceGump(m_From, m_Item, AttributeCategory.Resists, GumpPage.AttributeList));

                    break;
                }

                case 4:                                 // Weapon Hits
                {
                    m_From.SendGump(new ItemExperienceGump(m_From, m_Item, AttributeCategory.Hits, GumpPage.AttributeList));

                    break;
                }

                case 5:                                 // Misc.
                {
                    m_From.SendGump(new ItemExperienceGump(m_From, m_Item, AttributeCategory.Misc, GumpPage.AttributeList));

                    break;
                }
                }

                break;
            }

            case 2:                     // Attribute selected
            {
                cost = GetPointCost(m_Item, LevelAttributes.m_Attributes[index].m_XP);

                if ((levitem.Points - cost) >= 0)
                {
                    //add point to selected attribute
                    if (index >= 0 && index < LevelAttributes.m_Attributes.Length)
                    {
                        if (m_Item is BaseWeapon)
                        {
                            attrvalue = ((BaseWeapon)m_Item).Attributes[LevelAttributes.m_Attributes[index].m_Attribute];
                            if (attrvalue < LevelAttributes.m_Attributes[index].m_MaxValue)
                            {
                                ((BaseWeapon)m_Item).Attributes[LevelAttributes.m_Attributes[index].m_Attribute] += 1;
                                levitem.Points -= cost;
                            }
                        }
                        else if (m_Item is BaseArmor)
                        {
                            attrvalue = ((BaseArmor)m_Item).Attributes[LevelAttributes.m_Attributes[index].m_Attribute];
                            if (attrvalue < LevelAttributes.m_Attributes[index].m_MaxValue)
                            {
                                ((BaseArmor)m_Item).Attributes[LevelAttributes.m_Attributes[index].m_Attribute] += 1;
                                levitem.Points -= cost;
                            }
                        }
                        else if (m_Item is BaseJewel)
                        {
                            attrvalue = ((BaseJewel)m_Item).Attributes[LevelAttributes.m_Attributes[index].m_Attribute];
                            if (attrvalue < LevelAttributes.m_Attributes[index].m_MaxValue)
                            {
                                ((BaseJewel)m_Item).Attributes[LevelAttributes.m_Attributes[index].m_Attribute] += 1;
                                levitem.Points -= cost;
                            }
                        }
                        else if (m_Item is BaseClothing)
                        {
                            attrvalue = ((BaseClothing)m_Item).Attributes[LevelAttributes.m_Attributes[index].m_Attribute];
                            if (attrvalue < LevelAttributes.m_Attributes[index].m_MaxValue)
                            {
                                ((BaseClothing)m_Item).Attributes[LevelAttributes.m_Attributes[index].m_Attribute] += 1;
                                levitem.Points -= cost;
                            }
                        }
                        else
                        {
                            return;
                        }
                    }
                }
                else
                {
                    m_From.SendMessage("You don't have enough points available!  This attribute costs " + cost + " points.");
                }

                m_From.SendGump(new ItemExperienceGump(m_From, m_Item, LevelAttributes.m_Attributes[index].m_Category, GumpPage.AttributeList));

                break;
            }

            case 3:     // WeaponAttribute selected
            {
                cost = GetPointCost(m_Item, LevelAttributes.m_WeaponAttributes[index].m_XP);

                if ((levitem.Points - cost) >= 0)
                {
                    //add point to selected weapon attribute
                    if (index >= 0 && index < LevelAttributes.m_WeaponAttributes.Length)
                    {
                        if (LevelAttributes.m_WeaponAttributes[index].m_Attribute == AosWeaponAttribute.DurabilityBonus)
                        {
                            attrvalue = ((BaseWeapon)m_Item).MaxHitPoints;
                        }
                        else
                        {
                            attrvalue = ((BaseWeapon)m_Item).WeaponAttributes[LevelAttributes.m_WeaponAttributes[index].m_Attribute];
                        }

                        if (attrvalue < LevelAttributes.m_WeaponAttributes[index].m_MaxValue)
                        {
                            ((BaseWeapon)m_Item).WeaponAttributes[LevelAttributes.m_WeaponAttributes[index].m_Attribute] += 1;
                            levitem.Points -= cost;
                        }
                    }
                }
                else
                {
                    m_From.SendMessage("You don't have enough points available!  This attribute costs " + cost + " points.");
                }

                m_From.SendGump(new ItemExperienceGump(m_From, m_Item, LevelAttributes.m_WeaponAttributes[index].m_Category, GumpPage.AttributeList));

                break;
            }

            case 4:     // Armor Attributes Selected
            {
                cost = GetPointCost(m_Item, LevelAttributes.m_ArmorAttributes[index].m_XP);
                if ((levitem.Points - cost) >= 0)
                {
                    //add point to selected weapon attribute
                    if (index >= 0 && index < LevelAttributes.m_ArmorAttributes.Length)
                    {
                        if (LevelAttributes.m_ArmorAttributes[index].m_Attribute == AosArmorAttribute.DurabilityBonus)
                        {
                            attrvalue = ((BaseArmor)m_Item).MaxHitPoints;
                        }
                        else
                        {
                            attrvalue = ((BaseArmor)m_Item).ArmorAttributes[LevelAttributes.m_ArmorAttributes[index].m_Attribute];
                        }

                        if (attrvalue < LevelAttributes.m_ArmorAttributes[index].m_MaxValue)
                        {
                            ((BaseArmor)m_Item).ArmorAttributes[LevelAttributes.m_ArmorAttributes[index].m_Attribute] += 1;
                            levitem.Points -= cost;
                        }
                    }
                }
                else
                {
                    m_From.SendMessage("You don't have enough points available!  This attribute costs " + cost + " points.");
                }

                m_From.SendGump(new ItemExperienceGump(m_From, m_Item, LevelAttributes.m_ArmorAttributes[index].m_Category, GumpPage.AttributeList));

                break;
            }

            case 5:     // Armor Resists Selected
            {
                cost = GetPointCost(m_Item, LevelAttributes.m_ResistanceTypes[index].m_XP);
                if ((levitem.Points - cost) >= 0)
                {
                    //add point to selected weapon attribute
                    if (index >= 0 && index < LevelAttributes.m_ResistanceTypes.Length)
                    {
                        if (LevelAttributes.m_ResistanceTypes[index].m_Attribute == ResistanceType.Physical)
                        {
                            attrvalue = ((BaseArmor)m_Item).PhysicalBonus;
                            if (attrvalue < LevelAttributes.m_ResistanceTypes[index].m_MaxValue)
                            {
                                ((BaseArmor)m_Item).PhysicalBonus += 1;
                                levitem.Points -= cost;
                            }
                        }
                        else if (LevelAttributes.m_ResistanceTypes[index].m_Attribute == ResistanceType.Fire)
                        {
                            attrvalue = ((BaseArmor)m_Item).FireBonus;
                            if (attrvalue < LevelAttributes.m_ResistanceTypes[index].m_MaxValue)
                            {
                                ((BaseArmor)m_Item).FireBonus += 1;
                                levitem.Points -= cost;
                            }
                        }
                        else if (LevelAttributes.m_ResistanceTypes[index].m_Attribute == ResistanceType.Cold)
                        {
                            attrvalue = ((BaseArmor)m_Item).ColdBonus;
                            if (attrvalue < LevelAttributes.m_ResistanceTypes[index].m_MaxValue)
                            {
                                ((BaseArmor)m_Item).ColdBonus += 1;
                                levitem.Points -= cost;
                            }
                        }
                        else if (LevelAttributes.m_ResistanceTypes[index].m_Attribute == ResistanceType.Poison)
                        {
                            attrvalue = ((BaseArmor)m_Item).PoisonBonus;
                            if (attrvalue < LevelAttributes.m_ResistanceTypes[index].m_MaxValue)
                            {
                                ((BaseArmor)m_Item).PoisonBonus += 1;
                                levitem.Points -= cost;
                            }
                        }
                        else if (LevelAttributes.m_ResistanceTypes[index].m_Attribute == ResistanceType.Energy)
                        {
                            attrvalue = ((BaseArmor)m_Item).EnergyBonus;
                            if (attrvalue < LevelAttributes.m_ResistanceTypes[index].m_MaxValue)
                            {
                                ((BaseArmor)m_Item).EnergyBonus += 1;
                                levitem.Points -= cost;
                            }
                        }
                        else
                        {
                            return;
                        }
                    }
                }
                else
                {
                    m_From.SendMessage("You don't have enough points available!  This attribute costs " + cost + " points.");
                }

                m_From.SendGump(new ItemExperienceGump(m_From, m_Item, LevelAttributes.m_ResistanceTypes[index].m_Category, GumpPage.AttributeList));

                break;
            }

            case 6:     // Jewelry & Clothing Resists Selected
            {
                cost = GetPointCost(m_Item, LevelAttributes.m_ElementAttributes[index].m_XP);
                if ((levitem.Points - cost) >= 0)
                {
                    //add point to selected weapon attribute
                    if (index >= 0 && index < LevelAttributes.m_ElementAttributes.Length)
                    {
                        if (m_Item is BaseJewel)
                        {
                            attrvalue = ((BaseJewel)m_Item).Resistances[LevelAttributes.m_ElementAttributes[index].m_Attribute];
                            if (attrvalue < LevelAttributes.m_ElementAttributes[index].m_MaxValue)
                            {
                                ((BaseJewel)m_Item).Resistances[LevelAttributes.m_ElementAttributes[index].m_Attribute] += 1;
                                levitem.Points -= cost;
                            }
                        }
                        else
                        {
                            attrvalue = ((BaseClothing)m_Item).Resistances[LevelAttributes.m_ElementAttributes[index].m_Attribute];
                            if (attrvalue < LevelAttributes.m_ElementAttributes[index].m_MaxValue)
                            {
                                ((BaseClothing)m_Item).Resistances[LevelAttributes.m_ElementAttributes[index].m_Attribute] += 1;
                                levitem.Points -= cost;
                            }
                        }
                    }
                }
                else
                {
                    m_From.SendMessage("You don't have enough points available!  This attribute costs " + cost + " points.");
                }

                m_From.SendGump(new ItemExperienceGump(m_From, m_Item, LevelAttributes.m_ElementAttributes[index].m_Category, GumpPage.AttributeList));

                break;
            }
            }
        }
Exemplo n.º 17
0
        private Message Action(CommandCaller caller, IReadOnlyList <string> args)
        {
            int    idx = 0;
            string arg = string.Empty;

            bool NextArg()
            {
                if (args.Count <= idx)
                {
                    return(false);
                }
                arg = args[idx++];
                return(true);
            }

            AnimPlayer player = caller.Player.GetModPlayer <AnimPlayer>();

            if (!player.DebugEnabled)
            {
                return(Error("This command cannot be used outside of debug mode."));
            }
            if (!AnimLoader.HasMods)
            {
                return(Error($"This command cannot be used when no mods are using {nameof(AnimLib)}."));
            }
            if (!NextArg())
            {
                return(Error($"This command requires arguments. Usage: {Usage}"));
            }

            Mod targetMod = ModLoader.GetMod(arg);

            if (targetMod is null)
            {
                // We'll allow not specifying mod only if exactly one mod is using AnimLib
                AnimLoader.GetLoadedMods(out var loadedMod);
                if (loadedMod.Count > 1)
                {
                    return(Error($"Must specify mod when more than one mod is using {nameof(AnimLib)}."));
                }

                // Only one mod is loaded, command implicitly refers to that mod
                targetMod = loadedMod[0];
                idx--;
            }

            if (!NextArg())
            {
                return(Error("This command requires at least 2 arguments."));
            }
            if (!AnimLoader.LoadedMods.Contains(targetMod))
            {
                return(Error($"Mod {targetMod} does not use AnimLib."));
            }

            AbilityManager manager = player.characters[mod].abilityManager;

            if (manager is null)
            {
                return(Error($"Mod {targetMod} does not have abilities."));
            }

            Ability ability = null;

            if (int.TryParse(arg, out int id))
            {
                if (!manager.TryGet(id, out ability))
                {
                    return(Error("Specified ability ID is out of range."));
                }
                ability = manager[id];
            }
            else
            {
                foreach (Ability a in manager)
                {
                    if (string.Equals(a.GetType().Name, arg, StringComparison.OrdinalIgnoreCase))
                    {
                        ability = a;
                        break;
                    }
                }

                if (ability is null)
                {
                    return(Error($"\"{arg}\" is not a valid ability name."));
                }
            }

            ILevelable levelable = ability as ILevelable;

            if (NextArg())
            {
                if (!int.TryParse(arg, out int level))
                {
                    return(Error("Argument must be a number."));
                }
                if (level < 0)
                {
                    return(Error("Argument must be a positive number."));
                }
                if (levelable is null)
                {
                    return(new Message($"{ability} cannot be leveled."));
                }
                levelable.Level = level;
                return(level > levelable.MaxLevel
          ? SuccessWarn($"{ability.GetType().Name} level set to {levelable.Level}/{levelable.MaxLevel}. This level is above max level, and is not supported.")
          : Success($"{ability.GetType().Name} level set to {levelable.Level}/{levelable.MaxLevel}."));
            }

            return(Success(levelable is null
        ? $"{ability.GetType().Name} is currently {(ability.Unlocked ? "Unlocked" : "Locked")} "
        : $"{ability.GetType().Name} is currently {(ability.Unlocked ? "Unlocked" : "Locked")} at level {levelable.Level}/{levelable.MaxLevel}"));
        }
 public LevelInfoEntry( ILevelable item )
     : base(98, 3)
 {
     m_Item = item;
 }