CODE: Encapsulating The Spell Book menu

User Tag List

Results 1 to 1 of 1
  1. #1
    EmilyStrange's Avatar Active Member
    Reputation
    34
    Join Date
    Jul 2009
    Posts
    125
    Thanks G/R
    0/0
    Trade Feedback
    0 (0%)
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    CODE: Encapsulating The Spell Book

    This code snippet encapsulates the player character's spell book into a re-usable class. It hides away all of the details about reading data structures from game client memory. You can use it to test if a player has learnt a particular spell when determining how your bot AI should set up the rotations, etc.

    I have removed the spell database reading functions due to code dependencies that made this snippet too large to easily explain. I may post an updated version later with the database functionality restored.

    You will need to change the section of code that references your memory reading/writing library in the class.

    Code:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using Voodoo;
    using WarcraftVoodoo.Version41014333;
    using WarcraftVoodoo.Structures;
    
    namespace WarcraftVoodoo
    {
        /// <summary>
        /// Encapsulates the character's spell book into a single class that can be queried for
        /// known and learnt spells.
        /// 
        /// Edit: 11/06/28 -- removed spell database lookups when released to public due to too many code dependencies.
        /// </summary>
        public class SpellBook
        {
            // Which game client does this spell book refer to
            private GameClient m_gameClient;
    
            // The number of known spells in the spell book.
            private CachedValue<int> m_knownSpellCount;
    
            ///A list of all the spell information in the spell book.
            private CachedValue<List<SpellInfo>> m_allSpells;
    
            /// <summary>
            /// Construct a new spell book encapsulation
            /// </summary>
            /// <param name="gc">The game client this spell book refers to</param>
            public SpellBook(GameClient gc)
            {
                m_gameClient = gc;
                // set up the cache for reading the known spell count
                m_knownSpellCount = new CachedValue<int>(() =>
                {
                    return m_gameClient.MemoryEditor.ReadInt(m_gameClient.ToAbsoluteAddress(LocalPlayerAddress.SpellBookSpellCount));
                });
    
                // we only need to refresh the number of known spells every now and again
                m_knownSpellCount.UpdateInterval = TimeSpan.FromSeconds(30);
    
                // set up the cache for reading the list of spells
                m_allSpells = new CachedValue<List<SpellInfo>>(() =>
                {
                    return GetAllSpells();
                });
    
                // we only need to refresh the list of known spells every now and again
                m_allSpells.UpdateInterval = TimeSpan.FromSeconds(30);
            }
    
            /// <summary>
            /// Return the number of known spells in the spell book
            /// </summary>
            public int KnownSpellCount
            {
                get
                {
                    return m_knownSpellCount.Value;
                }
    
            }
    
            /// <summary>
            /// Return the number of learnt spells in the spell book
            /// </summary>
            public int LearntSpellCount
            {
                get
                {
                    return LearntSpells.Count();
                }
            }
    
            /// <summary>
            /// Return all of the spell information in the spellbook.
            /// </summary>
            /// <returns>List of spell information structures.</returns>
            private List<SpellInfo> GetAllSpells()
            {
                int numberOfSpellsKnown = KnownSpellCount;
                List<SpellInfo> spells = new List<SpellInfo>();
                uint firstSpellPtr = m_gameClient.MemoryEditor.ReadUInt(m_gameClient.ToAbsoluteAddress(LocalPlayerAddress.SpellBook));
                for (uint spellIdx = 0; spellIdx < numberOfSpellsKnown; spellIdx++)
                {
                    uint currSpellPtr = m_gameClient.MemoryEditor.ReadUInt(firstSpellPtr + spellIdx * sizeof(uint));
                    SpellInfo spellData = (SpellInfo)(m_gameClient.MemoryEditor.ReadObject(currSpellPtr, typeof(SpellInfo)));
                    spells.Add(spellData);
                }
    
                return spells;
            }
    
            /// <summary>
            /// Return a list of all learnt spell identifiers.
            /// </summary>
            public IEnumerable<uint> LearntSpells
            {
                get
                {
                    return AllSpells.Where(s => s.State == SpellInfo.SpellState.IsLearnt).Select(s => s.ID);
                }
    
            }
    
            /// <summary>
            /// Return a list of all known spell identifiers, irrelevant of whether they can be cast or not.
            /// </summary>
            public IEnumerable<uint> KnownSpells
            {
                get
                {
                    return AllSpells.Where(s => s.State == SpellInfo.SpellState.IsKnown).Select(s => s.ID);
                }
    
            }
    
            /// <summary>
            /// Return a list of all spells in the player's spellbook, irrelevant of
            /// whether we know them or can cast them.
            /// </summary>
            public IEnumerable<SpellInfo> AllSpells
            {
                get
                {
                    return m_allSpells.Value;
                }
    
            }
    
            /// <summary>
            /// Determine whether the character has learnt any of the specified spells.
            /// </summary>
            /// <param name="spellList">A list of spell identifiers to search for.</param>
            /// <returns>True if the character has learnt the spell.</returns>
            public bool HasLearntSpell(IEnumerable<uint> spellList)
            {
                return spellList.Intersect(LearntSpells).Any();
            }
    
            /// <summary>
            /// Determine whether the character knows about any of the specified spells.
            /// </summary>
            /// <param name="spellList">A list of spell identifiers to search for.</param>
            /// <returns>True if the character knows the spell.</returns>
            public bool HasSpell(IEnumerable<uint> spellList)
            {
                return spellList.Intersect(KnownSpells).Any();
            }
    
        }
    
    }
    This is the SpellInfo structure as read from the game client's memory.
    Code:
    namespace WarcraftVoodoo.Structures
    {
        /// <summary>
        /// Spell Information structure in the player character's spell book
        /// </summary>
        [StructLayout(LayoutKind.Explicit, Size = 0x08)]
        public struct SpellInfo
        {
            /// <summary>
            /// The possible states of a spell in the spell book
            /// </summary>
            public enum SpellState : int
            {
                IsLearnt = 1, // the spell has been learnt and can be cast
                IsKnown = 2 // the spell is known but not yet learnt
            };
    
            /// <summary>
            /// The state of the spell in the spell book
            /// </summary>
            [FieldOffset(0x0)]
            public SpellState State;
    
            /// <summary>
            /// The spell identifier of the spell in the spell book
            /// </summary>
            [FieldOffset(0x04)]
            public uint ID;
    
        }
    
    }
    And this is how I use it:
    Code:
            private void Debug_DumpLeadersKnownSpells()
            {
                PlayerCharacter leadPlayerCharacter = PartyManager.LeadPlayerCharacter;
                if (leadPlayerCharacter == null)
                {
                    return;
                }
    
                WowLocalPlayer localPlayer = leadPlayerCharacter.LocalPlayer;
                if (localPlayer == null)
                {
                    return;
                }
    
                Log.LogDebug(String.Format("These are all of the spells that {0} knows about.", localPlayer.Name));
                IEnumerable<uint> learntSpells = localPlayer.SpellBook.LearntSpells;
                foreach (uint spellID in learntSpells)
                {
                    Log.LogDebug(String.Format("Spell ID #{0}", spellID));
                }
    
            }

    CODE: Encapsulating The Spell Book

Similar Threads

  1. CODE: Encapsulating The Key Bindings
    By EmilyStrange in forum WoW Memory Editing
    Replies: 1
    Last Post: 06-29-2011, 04:38 PM
  2. troll male - torment of the worgen book character
    By Edjado in forum WoW ME Questions and Requests
    Replies: 1
    Last Post: 07-21-2007, 08:08 PM
  3. All the spells from the PTR
    By Fishy80 in forum World of Warcraft Model Editing
    Replies: 0
    Last Post: 04-20-2007, 02:32 PM
  4. If You Had to Change the Spelling of One Word..
    By Clypso in forum Community Chat
    Replies: 17
    Last Post: 03-28-2007, 10:43 AM
  5. [VIDEO] How to take away the spell effect
    By Hakonj in forum World of Warcraft Exploits
    Replies: 15
    Last Post: 03-02-2007, 09:35 PM
All times are GMT -5. The time now is 06:50 AM. Powered by vBulletin® Version 4.2.3
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. User Alert System provided by Advanced User Tagging (Pro) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Google Authenticator verification provided by Two-Factor Authentication (Free) - vBulletin Mods & Addons Copyright © 2025 DragonByte Technologies Ltd.
Digital Point modules: Sphinx-based search