I'm probably just doing this wrong.. I'm trying to make it so when the race human purchase from an NPC they get the normal stuff however with any other race other then a Human purchase from an NPC they get a another entirely set of items meant for just that race.

Since the other races kinda of just use the same armor, I figured it would be easier to just state if human, use X items else use X items. (Else should be the other races) .

When I use my custom race or human to purchase from the vendor it only shows me the default human items. Which is fine for human but not what I'm aiming for for other races.

I edited BaseVendor.cs and added
Code:
        private Mobile m;
       
        public virtual bool IsHumanRace
        {
            get
            {    
                return ( m is PlayerMobile && ( m.Race == Race.Human ));
            }
        }

Then I edited my custom blacksmith NPC, here is the Code for the blacksmith NPC.

Code:
using System;
using System.Collections.Generic;
using Server.Engines.BulkOrders;

namespace Server.Mobiles
{
    public class BlacksmithTest : BaseVendor
    {

        private readonly List<SBInfo> m_SBInfos = new List<SBInfo>();
        protected override List<SBInfo> SBInfos
        {
            get
            {
                return this.m_SBInfos;
            }
        }

        public override NpcGuild NpcGuild
        {
            get
            {
                return NpcGuild.BlacksmithsGuild;
            }
        }

        [Constructable]
        public BlacksmithTest()
            : base("the BlacksmithTest")
        {
            this.SetSkill(SkillName.ArmsLore, 36.0, 68.0);
            this.SetSkill(SkillName.Blacksmith, 65.0, 88.0);
            this.SetSkill(SkillName.Fencing, 60.0, 83.0);
            this.SetSkill(SkillName.Macing, 61.0, 93.0);
            this.SetSkill(SkillName.Swords, 60.0, 83.0);
            this.SetSkill(SkillName.Tactics, 60.0, 83.0);
            this.SetSkill(SkillName.Parry, 61.0, 93.0);
        }

        public override void InitSBInfo()
        {
            /*m_SBInfos.Add( new SBSmithTools() );
            m_SBInfos.Add( new SBMetalShields() );
            m_SBInfos.Add( new SBWoodenShields() );
            m_SBInfos.Add( new SBPlateArmor() );
            m_SBInfos.Add( new SBHelmetArmor() );
            m_SBInfos.Add( new SBChainmailArmor() );
            m_SBInfos.Add( new SBRingmailArmor() );
            m_SBInfos.Add( new SBAxeWeapon() );
            m_SBInfos.Add( new SBPoleArmWeapon() );
            m_SBInfos.Add( new SBRangedWeapon() );
            m_SBInfos.Add( new SBKnifeWeapon() );
            m_SBInfos.Add( new SBMaceWeapon() );
            m_SBInfos.Add( new SBSpearForkWeapon() );
            m_SBInfos.Add( new SBSwordWeapon() );*/


            if (this.IsHumanRace)
            {
                this.m_SBInfos.Add(new SBSABlacksmith());
                this.m_SBInfos.Add(new SBSAArmor());
                this.m_SBInfos.Add(new SBSAWeapons());
            }
            else
            {
                this.m_SBInfos.Add(new SBBlacksmith());
                this.m_SBInfos.Add(new SBSEArmor());
                this.m_SBInfos.Add(new SBSEWeapons());
            }
        }

        public override VendorShoeType ShoeType
        {
            get
            {
                return VendorShoeType.None;
            }
        }

        public override void InitOutfit()
        {
            base.InitOutfit();

            Item item = (Utility.RandomBool() ? null : new Server.Items.RingmailChest());

            if (item != null && !this.EquipItem(item))
            {
                item.Delete();
                item = null;
            }

            if (item == null)
                this.AddItem(new Server.Items.FullApron());

            this.AddItem(new Server.Items.Bascinet());
            this.AddItem(new Server.Items.SmithHammer());
        }

        #region Bulk Orders
        public override Item CreateBulkOrder(Mobile from, bool fromContextMenu)
        {
            PlayerMobile pm = from as PlayerMobile;

            if (pm != null && pm.NextSmithBulkOrder == TimeSpan.Zero && (fromContextMenu || 0.2 > Utility.RandomDouble()))
            {
                double theirSkill = pm.Skills[SkillName.Blacksmith].Base;

                if (theirSkill >= 70.1)
                    pm.NextSmithBulkOrder = TimeSpan.FromHours(6.0);
                else if (theirSkill >= 50.1)
                    pm.NextSmithBulkOrder = TimeSpan.FromHours(2.0);
                else
                    pm.NextSmithBulkOrder = TimeSpan.FromHours(1.0);

                if (theirSkill >= 70.1 && ((theirSkill - 40.0) / 300.0) > Utility.RandomDouble())
                    return new LargeSmithBOD();

                return SmallSmithBOD.CreateRandomFor(from);
            }

            return null;
        }

        public override bool IsValidBulkOrder(Item item)
        {
            return (item is SmallSmithBOD || item is LargeSmithBOD);
        }

        public override bool SupportsBulkOrders(Mobile from)
        {
            return (from is PlayerMobile && from.Skills[SkillName.Blacksmith].Base > 0);
        }

        public override TimeSpan GetNextBulkOrder(Mobile from)
        {
            if (from is PlayerMobile)
                return ((PlayerMobile)from).NextSmithBulkOrder;

            return TimeSpan.Zero;
        }

        public override void OnSuccessfulBulkOrderReceive(Mobile from)
        {
            if (Core.SE && from is PlayerMobile)
                ((PlayerMobile)from).NextSmithBulkOrder = TimeSpan.Zero;
        }

        #endregion

        public BlacksmithTest(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();
        }
    }
}
 
You want to have an Npc that sells human normal items and gargoyle items to a gargoyle for example?

I think you would have to reinit the sb info on vendorbuy and vendorsell in that case.
Also I dont know if that also restocks the npc but I think its something to note at this point
 
So with the above information , I've created the below script. It does work in the idea of allowing a single Race to use the vendor, however if another race uses it, there is no context menu at all except training skills.

Is there a way to make multiple entries for race on a single NPC vendor? Using the current method I would have to make numerous NPC's, as opposed to having just one that does race checks and provides the configured SB file.

Here is the full Blacksmith File I'm Using with the custom race entries for it.



Code:
using System;
using Server;
using Server.ContextMenus;
using System.Collections.Generic;
using Server.Engines.BulkOrders;

namespace Server.Mobiles
{
    public class BlacksmithTest : BaseVendor
    {
        private readonly List<SBInfo> m_SBInfos = new List<SBInfo>();
        protected override List<SBInfo> SBInfos
        {
            get
            {
                return this.m_SBInfos;
            }
        }

        public override NpcGuild NpcGuild
        {
            get
            {
                return NpcGuild.BlacksmithsGuild;
            }
        }

        [Constructable]
        public BlacksmithTest()
            : base("the blacksmith")
        {
            this.SetSkill(SkillName.ArmsLore, 36.0, 68.0);
            this.SetSkill(SkillName.Blacksmith, 65.0, 88.0);
            this.SetSkill(SkillName.Fencing, 60.0, 83.0);
            this.SetSkill(SkillName.Macing, 61.0, 93.0);
            this.SetSkill(SkillName.Swords, 60.0, 83.0);
            this.SetSkill(SkillName.Tactics, 60.0, 83.0);
            this.SetSkill(SkillName.Parry, 61.0, 93.0);
        }

        public override void InitSBInfo()
        {
            /*m_SBInfos.Add( new SBSmithTools() );
            m_SBInfos.Add( new SBMetalShields() );
            m_SBInfos.Add( new SBWoodenShields() );
            m_SBInfos.Add( new SBPlateArmor() );
            m_SBInfos.Add( new SBHelmetArmor() );
            m_SBInfos.Add( new SBChainmailArmor() );
            m_SBInfos.Add( new SBRingmailArmor() );
            m_SBInfos.Add( new SBAxeWeapon() );
            m_SBInfos.Add( new SBPoleArmWeapon() );
            m_SBInfos.Add( new SBRangedWeapon() );
            m_SBInfos.Add( new SBKnifeWeapon() );
            m_SBInfos.Add( new SBMaceWeapon() );
            m_SBInfos.Add( new SBSpearForkWeapon() );
            m_SBInfos.Add( new SBSwordWeapon() );*/

            if (!this.IsStygianVendor)
            {
                this.m_SBInfos.Add(new SBBlacksmith());
                if (this.IsTokunoVendor)
                {
                    this.m_SBInfos.Add(new SBSEArmor());
                    this.m_SBInfos.Add(new SBSEWeapons());
                   
//                    this.m_SBInfos.Add(new SBElvenCook());
                }
            }
            else
            {
                this.m_SBInfos.Add(new SBSABlacksmith());
                this.m_SBInfos.Add(new SBSAArmor());
                this.m_SBInfos.Add(new SBSAWeapons());
            }
        }

        public override VendorShoeType ShoeType
        {
            get
            {
                return VendorShoeType.None;
            }
        }

        public override void InitOutfit()
        {
            base.InitOutfit();

            Item item = (Utility.RandomBool() ? null : new Server.Items.RingmailChest());

            if (item != null && !this.EquipItem(item))
            {
                item.Delete();
                item = null;
            }

            if (item == null)
                this.AddItem(new Server.Items.FullApron());

            this.AddItem(new Server.Items.Bascinet());
            this.AddItem(new Server.Items.SmithHammer());
        }

        #region Bulk Orders
        public override Item CreateBulkOrder(Mobile from, bool fromContextMenu)
        {
            PlayerMobile pm = from as PlayerMobile;

            if (pm != null && pm.NextSmithBulkOrder == TimeSpan.Zero && (fromContextMenu || 0.2 > Utility.RandomDouble()))
            {
                double theirSkill = pm.Skills[SkillName.Blacksmith].Base;

                if (theirSkill >= 70.1)
                    pm.NextSmithBulkOrder = TimeSpan.FromHours(6.0);
                else if (theirSkill >= 50.1)
                    pm.NextSmithBulkOrder = TimeSpan.FromHours(2.0);
                else
                    pm.NextSmithBulkOrder = TimeSpan.FromHours(1.0);

                if (theirSkill >= 70.1 && ((theirSkill - 40.0) / 300.0) > Utility.RandomDouble())
                    return new LargeSmithBOD();

                return SmallSmithBOD.CreateRandomFor(from);
            }

            return null;
        }

        public override bool IsValidBulkOrder(Item item)
        {
            return (item is SmallSmithBOD || item is LargeSmithBOD);
        }

        public override bool SupportsBulkOrders(Mobile from)
        {
            return (from is PlayerMobile && from.Skills[SkillName.Blacksmith].Base > 0);
        }

        public override TimeSpan GetNextBulkOrder(Mobile from)
        {
            if (from is PlayerMobile)
                return ((PlayerMobile)from).NextSmithBulkOrder;

            return TimeSpan.Zero;
        }

        public override void OnSuccessfulBulkOrderReceive(Mobile from)
        {
            if (Core.SE && from is PlayerMobile)
                ((PlayerMobile)from).NextSmithBulkOrder = TimeSpan.Zero;
        }

        #endregion

        public override void AddCustomContextEntries( Mobile from, List<ContextMenuEntry> list )
        {
            if ( from.Alive && IsActiveVendor && from.Race == Race.CaitSith )
            {
                if ( IsActiveSeller)
                    list.Add( new VendorBuyEntry( from, this ) );

                if ( IsActiveBuyer)
                    list.Add( new VendorSellEntry( from, this ) );
            }
        }
       
        public BlacksmithTest(Serial serial)
            : base(serial)
        {
        }

        public override void Serialize(GenericWriter writer)
        {
            base.Serialize(writer);

            writer.Write((int)0); // version
        }

        public override void Deserialize(GenericReader reader)
        {
            base.Deserialize(reader);

            int version = reader.ReadInt();
        }
    }
}
 
An option would be to simply reinit the shop info (like I said, it may also have a drawback) or you could further open up the system to use more than one sb definition and only show the ones that the current race is allowed to see
 
Back