示例#1
0
        private PreparedSpell[][] TryFindSpells(int[] spellslots, string spellcastingDescription, string spellListClass, List <Spell> spells, ref List <String> errors, out int _spellTableStart, out int _spellTableEnd)
        {
            _spellTableStart = 0;
            _spellTableEnd   = 0;
            var spellList = new PreparedSpell[10][];

            for (var i = 0; i <= 9; i++)
            {
                if (i == 0 || spellslots[i - 1] > 0)
                {
                    var spellsInLevel = new List <PreparedSpell>();
                    var startStr      = i == 0
                        ? "Cantrips (at will): "
                        : thIfy(i) + " level (" + spellslots[i - 1] + " slot" + (spellslots[i - 1] > 1 ? "s): " : "): ");
                    if (spellListClass.Equals("warlock"))
                    {
                        startStr = i == 0
                            ? "Cantrips (at will): "
                            : "1st-" + thIfy(i) + " level (" + spellslots[i - 1] + " " + thIfy(i) + "-level slot" + (spellslots[i - 1] > 1 ? "s): " : "): ");
                    }
                    var startIndex = spellcastingDescription.IndexOf(startStr, StringComparison.Ordinal);
                    if (startIndex != -1)
                    {
                        if (_spellTableStart == 0 || _spellTableStart > startIndex)
                        {
                            _spellTableStart = startIndex;
                        }
                        startIndex += startStr.Length;
                        var endIndex = spellcastingDescription.IndexOf("\n", startIndex, StringComparison.Ordinal);
                        if (endIndex == -1)
                        {
                            endIndex = spellcastingDescription.Length;
                        }
                        if (_spellTableEnd < endIndex)
                        {
                            _spellTableEnd = endIndex;
                        }
                        var spellsStr = spellcastingDescription.Substring(startIndex, endIndex - startIndex).Trim().Split(',');
                        foreach (var spell in spellsStr)
                        {
                            var marked   = spell.Contains('*');
                            var name     = spell.Trim().Trim('*');
                            var spellObj = spells.FirstOrDefault(s => s.Name.ToLower().Equals(name.ToLower()));
                            if (spellObj == null)
                            {
                                errors.Add("could not find spell " + name + " in description " + spellcastingDescription);
                            }
                            spellsInLevel.Add(new PreparedSpell(name, spellObj.Id, marked));
                        }
                        spellList[i] = spellsInLevel.ToArray();
                        continue;
                    }
                    errors.Add("could not find spell of level " + i + " in description " + spellcastingDescription);
                }
            }
            return(spellList);
        }
示例#2
0
        public override void draw(SpriteBatch b)
        {
            var spellbook = Game1.player.getSpellBook();

            var hotbarH = 12 + 48 * 4 + 12 * 3 + 12;
            var gap     = (WINDOW_HEIGHT - hotbarH * 2) / 3;

            drawTextureBox(b, xPositionOnScreen + WINDOW_WIDTH, yPositionOnScreen + gap, 48 + 24, hotbarH, Color.White);
            drawTextureBox(b, xPositionOnScreen + WINDOW_WIDTH, yPositionOnScreen + WINDOW_HEIGHT - hotbarH - gap, 48 + 24, hotbarH, Color.White);
            drawTextureBox(b, xPositionOnScreen, yPositionOnScreen, WINDOW_WIDTH, WINDOW_HEIGHT, Color.White);
            drawTextureBox(b, xPositionOnScreen, yPositionOnScreen, WINDOW_WIDTH / 2, WINDOW_HEIGHT, Color.White);
            b.Draw(Game1.staminaRect, new Rectangle(xPositionOnScreen + 12, yPositionOnScreen + 12, WINDOW_WIDTH / 2 - 24, WINDOW_HEIGHT - 24), Color.Black);
            drawTextureBox(b, xPositionOnScreen - SCHOOL_ICON_SIZE - 12, yPositionOnScreen, SCHOOL_ICON_SIZE + 24, WINDOW_HEIGHT, Color.White);

            {
                int ix = xPositionOnScreen - SCHOOL_ICON_SIZE - 12, iy = yPositionOnScreen;
                foreach (string schoolId in School.getSchoolList())
                {
                    if (!spellbook.knownSchools.Contains(schoolId))
                    {
                        continue;
                    }

                    var school = School.getSchool(schoolId);
                    drawTextureBox(b, Game1.menuTexture, new Rectangle(0, 256, 60, 60), ix, iy, SCHOOL_ICON_SIZE + 24, SCHOOL_ICON_SIZE + 24, Color.White, 1f, false);
                    //drawTextureBox(b, ix, iy, 64 + 24, 64 + 24, Color.White);
                    b.Draw(Game1.staminaRect, new Rectangle(ix + 12, iy + 12, SCHOOL_ICON_SIZE, SCHOOL_ICON_SIZE), Color.Aqua);

                    if (justLeftClicked && new Rectangle(ix + 12, iy + 12, SCHOOL_ICON_SIZE, SCHOOL_ICON_SIZE).Contains(Game1.getOldMouseX(), Game1.getOldMouseY()))
                    {
                        if (this.school == null)
                        {
                            active = School.getSchool(schoolId);
                        }
                        justLeftClicked = false;
                    }

                    iy += SCHOOL_ICON_SIZE + 12;
                }
            }

            if (active != null)
            {
                Spell[] t1 = active.GetSpellsTier1();
                Spell[] t2 = active.GetSpellsTier2();
                Spell[] t3 = active.GetSpellsTier3();

                Spell[][] spells = new Spell[][] { t1, t2, t3 };

                int sy = spells.Length + 1;
                for (int t = 0; t < spells.Length; ++t)
                {
                    int y  = yPositionOnScreen + (WINDOW_HEIGHT - 24) / sy * (t + 1);
                    int sx = spells[t].Length + 1;
                    for (int s = 0; s < spells[t].Length; ++s)
                    {
                        int x = xPositionOnScreen + (WINDOW_WIDTH / 2 - 24) / sx * (s + 1);

                        var spell = spells[t][s];
                        if (justLeftClicked && new Rectangle(x - SPELL_ICON_SIZE / 2, y - SPELL_ICON_SIZE / 2, SPELL_ICON_SIZE, SPELL_ICON_SIZE).Contains(Game1.getOldMouseX(), Game1.getOldMouseY()))
                        {
                            sel             = spell;
                            justLeftClicked = false;
                        }

                        drawTextureBox(b, x - SPELL_ICON_SIZE / 2 - 12, y - SPELL_ICON_SIZE / 2 - 12, SPELL_ICON_SIZE + 24, SPELL_ICON_SIZE + 24, spell == sel ? Color.Green : Color.White);

                        if (spell == null)
                        {
                            continue;
                        }
                        var icon = spell.Icons != null ? spell.Icons[spell.Icons.Length - 1] : Game1.staminaRect;
                        if (icon == null)
                        {
                            icon = spell.Icons[0];
                            if (icon == null)
                            {
                                continue;
                            }
                        }

                        b.Draw(icon, new Rectangle(x - SPELL_ICON_SIZE / 2, y - SPELL_ICON_SIZE / 2, SPELL_ICON_SIZE, SPELL_ICON_SIZE), Color.White);
                    }
                }
            }

            if (sel != null)
            {
                var title = Mod.instance.Helper.Translation.Get("spell." + sel.FullId + ".name");
                var desc  = WrapText(Mod.instance.Helper.Translation.Get("spell." + sel.FullId + ".desc"), (int)((WINDOW_WIDTH / 2) / 0.75f));

                b.DrawString(Game1.dialogueFont, title, new Vector2(xPositionOnScreen + WINDOW_WIDTH / 2 + (WINDOW_WIDTH / 2 - Game1.dialogueFont.MeasureString(title).X) / 2, yPositionOnScreen + 30), Color.Black);

                var icon = sel.Icons != null ? sel.Icons[sel.Icons.Length - 1] : Game1.staminaRect;
                if (icon == null)
                {
                    icon = sel.Icons[0];
                }
                if (icon != null)
                {
                    b.Draw(icon, new Rectangle(xPositionOnScreen + WINDOW_WIDTH / 2 + (WINDOW_WIDTH / 2 - SEL_ICON_SIZE) / 2, yPositionOnScreen + 85, SEL_ICON_SIZE, SEL_ICON_SIZE), Color.White);
                }
                b.DrawString(Game1.dialogueFont, desc, new Vector2(xPositionOnScreen + WINDOW_WIDTH / 2 + 12, yPositionOnScreen + 280), Color.Black, 0, Vector2.Zero, 0.75f, SpriteEffects.None, 0);

                int sx = sel.Icons.Length + 1;
                for (int i = 0; i < sel.Icons.Length; ++i)
                {
                    int x = xPositionOnScreen + WINDOW_WIDTH / 2 + (WINDOW_WIDTH / 2) / sx * (i + 1);
                    int y = yPositionOnScreen + WINDOW_HEIGHT - 12 - SPELL_ICON_SIZE - 32 - 40;

                    Color stateCol = Color.Gray;
                    if (Game1.player.knowsSpell(sel, i))
                    {
                        stateCol = Color.Green;
                    }
                    else if (i == 0 || Game1.player.knowsSpell(sel, i - 1))
                    {
                        stateCol = Color.White;
                    }

                    var r = new Rectangle(x - SPELL_ICON_SIZE / 2, y, SPELL_ICON_SIZE, SPELL_ICON_SIZE);
                    drawTextureBox(b, r.Left - 12, r.Top - 12, r.Width + 24, r.Height + 24, stateCol);
                    if (sel.Icons[i] != null)
                    {
                        b.Draw(sel.Icons[i], r, Color.White);
                    }
                    if (r.Contains(Game1.getOldMouseX(), Game1.getOldMouseY()))
                    {
                        if (justLeftClicked && Game1.player.knowsSpell(sel, i))
                        {
                            dragging        = new PreparedSpell(sel.FullId, i);
                            justLeftClicked = false;
                        }
                        else if (i == 0 || Game1.player.knowsSpell(sel, i - 1))
                        {
                            if (justLeftClicked)
                            {
                                Game1.player.learnSpell(sel, i);
                            }
                            else if (justRightClicked)
                            {
                                Game1.player.forgetSpell(sel, i);
                            }
                        }
                    }
                }

                b.DrawString(Game1.dialogueFont, "Free points: " + Game1.player.getFreeSpellPoints(), new Vector2(xPositionOnScreen + WINDOW_WIDTH / 2 + 12 + 24, yPositionOnScreen + WINDOW_HEIGHT - 12 - 32 - 20), Color.Black);
            }

            {
                int y = yPositionOnScreen + gap + 12;
                foreach (var preps in spellbook.prepared)
                {
                    for (int i = 0; i < preps.Length; ++i)
                    {
                        var prep = preps[i];

                        var r = new Rectangle(xPositionOnScreen + WINDOW_WIDTH + 12, y, HOTBAR_ICON_SIZE, HOTBAR_ICON_SIZE);
                        if (r.Contains(Game1.getOldMouseX(), Game1.getOldMouseY()))
                        {
                            if (justRightClicked)
                            {
                                preps[i] = prep = null;
                            }
                            else if (justLeftClicked)
                            {
                                preps[i]        = prep = dragging;
                                dragging        = null;
                                justLeftClicked = false;
                            }
                        }

                        drawTextureBox(b, Game1.menuTexture, new Rectangle(0, 256, 60, 60), r.X - 12, y - 12, HOTBAR_ICON_SIZE + 24, HOTBAR_ICON_SIZE + 24, Color.White, 1f, false);

                        if (prep != null)
                        {
                            Spell spell = SpellBook.get(prep.SpellId);
                            if (spell != null)
                            {
                                Texture2D[] icons = spell.Icons;
                                if (icons != null && icons.Length > prep.Level && icons[prep.Level] != null)
                                {
                                    Texture2D icon = icons[prep.Level];
                                    b.Draw(icon, r, Color.White);
                                }
                            }
                        }
                        y += HOTBAR_ICON_SIZE + 12;
                    }
                    y += gap + 12;
                }
            }

            if (justLeftClicked)
            {
                dragging        = null;
                justLeftClicked = false;
            }
            justRightClicked = false;

            base.draw(b);
            if (dragging != null)
            {
                Spell spell = SpellBook.get(dragging.SpellId);
                if (spell != null)
                {
                    Texture2D[] icons = spell.Icons;
                    if (icons != null && icons.Length > dragging.Level && icons[dragging.Level] != null)
                    {
                        Texture2D icon = icons[dragging.Level];

                        b.Draw(icon, new Rectangle(Game1.getOldMouseX(), Game1.getOldMouseY(), HOTBAR_ICON_SIZE, HOTBAR_ICON_SIZE), Color.White);
                    }
                }
            }
            drawMouse(b);
        }
示例#3
0
        /// <inheritdoc />
        public override void draw(SpriteBatch b)
        {
            // get info
            SpellBook spellBook         = Game1.player.GetSpellBook();
            bool      hasFifthSpellSlot = Game1.player.HasCustomProfession(Skill.MemoryProfession);
            int       hotbarHeight      = 12 + 48 * (hasFifthSpellSlot ? 5 : 4) + 12 * (hasFifthSpellSlot ? 4 : 3) + 12;
            int       gap       = (MagicMenu.WindowHeight - hotbarHeight * 2) / 3 + (hasFifthSpellSlot ? 25 : 0);
            string    hoverText = null;

            // draw main window
            IClickableMenu.drawTextureBox(b, this.xPositionOnScreen, this.yPositionOnScreen, MagicMenu.WindowWidth, MagicMenu.WindowHeight, Color.White);
            IClickableMenu.drawTextureBox(b, this.xPositionOnScreen, this.yPositionOnScreen, MagicMenu.WindowWidth / 2, MagicMenu.WindowHeight, Color.White);

            // draw school icons
            {
                int x = this.xPositionOnScreen - MagicMenu.SchoolIconSize - 12;
                int y = this.yPositionOnScreen;
                foreach (string schoolId in School.GetSchoolList())
                {
                    School school      = School.GetSchool(schoolId);
                    bool   knowsSchool = spellBook.KnowsSchool(school);

                    float     alpha      = knowsSchool ? 1f : 0.2f;
                    Rectangle iconBounds = new(x + 12, y + 12, MagicMenu.SchoolIconSize, MagicMenu.SchoolIconSize);

                    IClickableMenu.drawTextureBox(b, Game1.menuTexture, new Rectangle(0, 256, 60, 60), x, y, MagicMenu.SchoolIconSize + 24, MagicMenu.SchoolIconSize + 24, (this.SelectedSchool == school ? Color.Green : Color.White), 1f, false);
                    b.Draw(school.Icon, iconBounds, Color.White * alpha);

                    if (iconBounds.Contains(Game1.getOldMouseX(), Game1.getOldMouseY()))
                    {
                        if (knowsSchool)
                        {
                            hoverText = school.DisplayName;

                            if (this.JustLeftClicked)
                            {
                                this.SelectSchool(schoolId, spellBook);
                                this.JustLeftClicked = false;
                            }
                        }
                        else
                        {
                            hoverText = "???";
                        }
                    }

                    y += MagicMenu.SchoolIconSize + 12;
                }
            }

            // draw spell icon area
            if (this.SelectedSchool != null)
            {
                Spell[][] spells = this.SelectedSchool.GetAllSpellTiers().ToArray();

                int sy = spells.Length + 1;
                for (int t = 0; t < spells.Length; ++t)
                {
                    Spell[] spellGroup = spells[t];
                    if (spellGroup == null)
                    {
                        continue;
                    }

                    int y  = this.yPositionOnScreen + (MagicMenu.WindowHeight - 24) / sy * (t + 1);
                    int sx = spellGroup.Length + 1;
                    for (int s = 0; s < spellGroup.Length; ++s)
                    {
                        Spell spell = spellGroup[s];
                        if (spell == null || !spellBook.KnowsSpell(spell, 0))
                        {
                            continue;
                        }

                        int       x          = this.xPositionOnScreen + (MagicMenu.WindowWidth / 2 - 24) / sx * (s + 1);
                        Rectangle iconBounds = new Rectangle(x - MagicMenu.SpellIconSize / 2, y - MagicMenu.SpellIconSize / 2, MagicMenu.SpellIconSize, MagicMenu.SpellIconSize);

                        if (iconBounds.Contains(Game1.getOldMouseX(), Game1.getOldMouseY()))
                        {
                            hoverText = spell.GetTooltip();

                            if (this.JustLeftClicked)
                            {
                                this.SelectedSpell   = spell;
                                this.JustLeftClicked = false;
                            }
                        }

                        if (spell == this.SelectedSpell)
                        {
                            IClickableMenu.drawTextureBox(b, x - MagicMenu.SpellIconSize / 2 - 12, y - MagicMenu.SpellIconSize / 2 - 12, MagicMenu.SpellIconSize + 24, MagicMenu.SpellIconSize + 24, Color.Green);
                        }

                        Texture2D icon = spell.Icons[spell.Icons.Length - 1];
                        b.Draw(icon, iconBounds, Color.White);
                    }
                }
            }

            // draw selected spell area
            if (this.SelectedSpell != null)
            {
                // draw title
                string title = this.SelectedSpell.GetTranslatedName();
                b.DrawString(Game1.dialogueFont, title, new Vector2(this.xPositionOnScreen + MagicMenu.WindowWidth / 2 + (MagicMenu.WindowWidth / 2 - Game1.dialogueFont.MeasureString(title).X) / 2, this.yPositionOnScreen + 30), Color.Black);

                // draw icon
                var icon = this.SelectedSpell.Icons[this.SelectedSpell.Icons.Length - 1];
                b.Draw(icon, new Rectangle(this.xPositionOnScreen + MagicMenu.WindowWidth / 2 + (MagicMenu.WindowWidth / 2 - MagicMenu.SelIconSize) / 2, this.yPositionOnScreen + 85, MagicMenu.SelIconSize, MagicMenu.SelIconSize), Color.White);

                // draw description
                string desc = this.WrapText(this.SelectedSpell.GetTranslatedDescription(), (int)((MagicMenu.WindowWidth / 2) / 0.75f));
                b.DrawString(Game1.dialogueFont, desc, new Vector2(this.xPositionOnScreen + MagicMenu.WindowWidth / 2 + 12, this.yPositionOnScreen + 280), Color.Black, 0, Vector2.Zero, 0.75f, SpriteEffects.None, 0);

                // draw level icons
                int sx = this.SelectedSpell.Icons.Length + 1;
                for (int i = 0; i < this.SelectedSpell.Icons.Length; ++i)
                {
                    // get icon position
                    int  x         = this.xPositionOnScreen + MagicMenu.WindowWidth / 2 + (MagicMenu.WindowWidth / 2) / sx * (i + 1);
                    int  y         = this.yPositionOnScreen + MagicMenu.WindowHeight - 12 - MagicMenu.SpellIconSize - 32 - 40;
                    var  bounds    = new Rectangle(x - MagicMenu.SpellIconSize / 2, y, MagicMenu.SpellIconSize, MagicMenu.SpellIconSize);
                    bool isHovered = bounds.Contains(Game1.getOldMouseX(), Game1.getOldMouseY());

                    // get state
                    bool isKnown           = spellBook.KnowsSpell(this.SelectedSpell, i);
                    bool hasPreviousLevels = isKnown || i == 0 || spellBook.KnowsSpell(this.SelectedSpell, i - 1);

                    // get border color
                    Color stateCol;
                    if (isKnown)
                    {
                        if (isHovered)
                        {
                            hoverText = I18n.Tooltip_Spell_Known(spell: I18n.Tooltip_Spell_NameAndLevel(title, level: i + 1));
                        }
                        stateCol = Color.Green;
                    }
                    else if (hasPreviousLevels)
                    {
                        if (isHovered)
                        {
                            hoverText = spellBook.FreePoints > 0
                                ? I18n.Tooltip_Spell_CanLearn(spell: I18n.Tooltip_Spell_NameAndLevel(title, level: i + 1))
                                : I18n.Tooltip_Spell_NeedFreePoints(spell: I18n.Tooltip_Spell_NameAndLevel(title, level: i + 1));
                        }
                        stateCol = Color.White;
                    }
                    else
                    {
                        if (isHovered)
                        {
                            hoverText = I18n.Tooltip_Spell_NeedPreviousLevels();
                        }
                        stateCol = Color.Gray;
                    }

                    // draw border
                    if (isKnown)
                    {
                        IClickableMenu.drawTextureBox(b, bounds.Left - 12, bounds.Top - 12, bounds.Width + 24, bounds.Height + 24, Color.Green);
                    }

                    // draw icon
                    float alpha = hasPreviousLevels ? 1f : 0.5f;
                    b.Draw(this.SelectedSpell.Icons[i], bounds, Color.White * alpha);

                    // handle click
                    if (isHovered && (this.JustLeftClicked || this.JustRightClicked))
                    {
                        if (this.JustLeftClicked && isKnown)
                        {
                            this.Dragging        = new PreparedSpell(this.SelectedSpell.FullId, i);
                            this.JustLeftClicked = false;
                        }
                        else if (hasPreviousLevels)
                        {
                            if (this.JustLeftClicked && spellBook.FreePoints > 0)
                            {
                                spellBook.Mutate(_ => spellBook.LearnSpell(this.SelectedSpell, i));
                            }
                            else if (this.JustRightClicked && i != 0)
                            {
                                spellBook.Mutate(_ => spellBook.ForgetSpell(this.SelectedSpell, i));
                            }
                        }
                    }
                }

                // draw free points count
                b.DrawString(Game1.dialogueFont, $"Free points: {spellBook.FreePoints}", new Vector2(this.xPositionOnScreen + MagicMenu.WindowWidth / 2 + 12 + 24, this.yPositionOnScreen + MagicMenu.WindowHeight - 12 - 32 - 20), Color.Black);
            }

            // draw spell bars
            {
                int y = this.yPositionOnScreen + gap + 12 + (hasFifthSpellSlot ? -32 : 0);
                foreach (var spellBar in spellBook.Prepared)
                {
                    for (int i = 0; i < (hasFifthSpellSlot ? 5 : 4); ++i)
                    {
                        PreparedSpell prep      = spellBar.GetSlot(i);
                        Rectangle     bounds    = new(this.xPositionOnScreen + MagicMenu.WindowWidth + 12, y, MagicMenu.HotbarIconSize, MagicMenu.HotbarIconSize);
                        bool          isHovered = bounds.Contains(Game1.getOldMouseX(), Game1.getOldMouseY());

                        if (isHovered)
                        {
                            if (this.JustRightClicked)
                            {
                                spellBook.Mutate(_ => spellBar.SetSlot(i, prep = null));
                            }
                            else if (this.JustLeftClicked)
                            {
                                spellBook.Mutate(_ => spellBar.SetSlot(i, prep = this.Dragging));
                                this.Dragging        = null;
                                this.JustLeftClicked = false;
                            }
                        }

                        IClickableMenu.drawTextureBox(b, Game1.menuTexture, new Rectangle(0, 256, 60, 60), bounds.X - 12, y - 12, MagicMenu.HotbarIconSize + 24, MagicMenu.HotbarIconSize + 24, Color.White, 1f, false);

                        if (prep != null)
                        {
                            Spell spell = SpellManager.Get(prep.SpellId);

                            Texture2D[] icons = spell?.Icons;
                            if (icons?.Length > prep.Level && icons[prep.Level] != null)
                            {
                                Texture2D icon = icons[prep.Level];
                                b.Draw(icon, bounds, Color.White);
                            }

                            if (isHovered)
                            {
                                hoverText = spell.GetTooltip(level: prep.Level);
                            }
                        }
                        y += MagicMenu.HotbarIconSize + 12;
                    }
                    y += gap + 12;
                }
            }

            // reset dragging
            if (this.JustLeftClicked)
            {
                this.Dragging        = null;
                this.JustLeftClicked = false;
            }
            this.JustRightClicked = false;

            // draw base menu
            base.draw(b);

            // draw dragged spell
            if (this.Dragging != null)
            {
                Spell       spell = SpellManager.Get(this.Dragging.SpellId);
                Texture2D[] icons = spell?.Icons;
                if (icons != null && icons.Length > this.Dragging.Level && icons[this.Dragging.Level] != null)
                {
                    Texture2D icon = icons[this.Dragging.Level];

                    b.Draw(icon, new Rectangle(Game1.getOldMouseX(), Game1.getOldMouseY(), MagicMenu.HotbarIconSize, MagicMenu.HotbarIconSize), Color.White);
                }
            }

            // draw hover text
            if (hoverText != null)
            {
                drawHoverText(b, hoverText, Game1.smallFont);
            }

            // draw cursor
            this.drawMouse(b);
        }
示例#4
0
        public override void draw(SpriteBatch b)
        {
            var  spellBook         = Game1.player.GetSpellBook();
            bool hasFifthSpellSlot = Game1.player.HasCustomProfession(Skill.ProfessionFifthSpellSlot);

            int hotbarH = 12 + 48 * (hasFifthSpellSlot ? 5 : 4) + 12 * (hasFifthSpellSlot ? 4 : 3) + 12;
            int gap     = (MagicMenu.WindowHeight - hotbarH * 2) / 3 + (hasFifthSpellSlot ? 25 : 0);

            //drawTextureBox(b, xPositionOnScreen + WINDOW_WIDTH, yPositionOnScreen + gap, 48 + 24, hotbarH, Color.White);
            //drawTextureBox(b, xPositionOnScreen + WINDOW_WIDTH, yPositionOnScreen + WINDOW_HEIGHT - hotbarH - gap, 48 + 24, hotbarH, Color.White);
            IClickableMenu.drawTextureBox(b, this.xPositionOnScreen, this.yPositionOnScreen, MagicMenu.WindowWidth, MagicMenu.WindowHeight, Color.White);
            IClickableMenu.drawTextureBox(b, this.xPositionOnScreen, this.yPositionOnScreen, MagicMenu.WindowWidth / 2, MagicMenu.WindowHeight, Color.White);
            b.Draw(Game1.staminaRect, new Rectangle(this.xPositionOnScreen + 12, this.yPositionOnScreen + 12, MagicMenu.WindowWidth / 2 - 24, MagicMenu.WindowHeight - 24), Color.Black);
            IClickableMenu.drawTextureBox(b, this.xPositionOnScreen - MagicMenu.SchoolIconSize - 12, this.yPositionOnScreen, MagicMenu.SchoolIconSize + 24, MagicMenu.WindowHeight, Color.White);

            {
                int ix = this.xPositionOnScreen - MagicMenu.SchoolIconSize - 12, iy = this.yPositionOnScreen;
                foreach (string schoolId in School.GetSchoolList())
                {
                    var school = School.GetSchool(schoolId);
                    IClickableMenu.drawTextureBox(b, Game1.menuTexture, new Rectangle(0, 256, 60, 60), ix, iy, MagicMenu.SchoolIconSize + 24, MagicMenu.SchoolIconSize + 24, this.Active == school ? Color.Green : Color.White, 1f, false);
                    //drawTextureBox(b, ix, iy, 64 + 24, 64 + 24, Color.White);
                    b.Draw(Game1.staminaRect, new Rectangle(ix + 12, iy + 12, MagicMenu.SchoolIconSize, MagicMenu.SchoolIconSize), Color.Aqua);

                    if (this.JustLeftClicked && new Rectangle(ix + 12, iy + 12, MagicMenu.SchoolIconSize, MagicMenu.SchoolIconSize).Contains(Game1.getOldMouseX(), Game1.getOldMouseY()))
                    {
                        if (this.School == null)
                        {
                            this.Active = School.GetSchool(schoolId);
                        }
                        this.JustLeftClicked = false;
                    }

                    iy += MagicMenu.SchoolIconSize + 12;
                }
            }

            if (this.Active != null)
            {
                Spell[] t1 = this.Active.GetSpellsTier1();
                Spell[] t2 = this.Active.GetSpellsTier2();
                Spell[] t3 = this.Active.GetSpellsTier3();

                Spell[][] spells = new[] { t1, t2, t3 };

                int sy = spells.Length + 1;
                for (int t = 0; t < spells.Length; ++t)
                {
                    int y  = this.yPositionOnScreen + (MagicMenu.WindowHeight - 24) / sy * (t + 1);
                    int sx = spells[t].Length + 1;
                    for (int s = 0; s < spells[t].Length; ++s)
                    {
                        int x = this.xPositionOnScreen + (MagicMenu.WindowWidth / 2 - 24) / sx * (s + 1);

                        var spell = spells[t][s];
                        if (!spellBook.KnowsSpell(spell, 0))
                        {
                            continue;
                        }
                        if (this.JustLeftClicked && new Rectangle(x - MagicMenu.SpellIconSize / 2, y - MagicMenu.SpellIconSize / 2, MagicMenu.SpellIconSize, MagicMenu.SpellIconSize).Contains(Game1.getOldMouseX(), Game1.getOldMouseY()))
                        {
                            this.Sel             = spell;
                            this.JustLeftClicked = false;
                        }

                        IClickableMenu.drawTextureBox(b, x - MagicMenu.SpellIconSize / 2 - 12, y - MagicMenu.SpellIconSize / 2 - 12, MagicMenu.SpellIconSize + 24, MagicMenu.SpellIconSize + 24, spell == this.Sel ? Color.Green : Color.White);

                        if (spell == null)
                        {
                            continue;
                        }
                        var icon = spell.Icons != null ? spell.Icons[spell.Icons.Length - 1] : Game1.staminaRect;
                        if (icon == null)
                        {
                            icon = spell.Icons[0];
                            if (icon == null)
                            {
                                continue;
                            }
                        }

                        b.Draw(icon, new Rectangle(x - MagicMenu.SpellIconSize / 2, y - MagicMenu.SpellIconSize / 2, MagicMenu.SpellIconSize, MagicMenu.SpellIconSize), Color.White);
                    }
                }
            }

            if (this.Sel != null)
            {
                string title = this.Sel.GetTranslatedName();
                string desc  = this.WrapText(this.Sel.GetTranslatedDescription(), (int)((MagicMenu.WindowWidth / 2) / 0.75f));

                b.DrawString(Game1.dialogueFont, title, new Vector2(this.xPositionOnScreen + MagicMenu.WindowWidth / 2 + (MagicMenu.WindowWidth / 2 - Game1.dialogueFont.MeasureString(title).X) / 2, this.yPositionOnScreen + 30), Color.Black);

                var icon =
                    (this.Sel.Icons != null ? this.Sel.Icons[this.Sel.Icons.Length - 1] : Game1.staminaRect)
                    ?? this.Sel.Icons[0];
                if (icon != null)
                {
                    b.Draw(icon, new Rectangle(this.xPositionOnScreen + MagicMenu.WindowWidth / 2 + (MagicMenu.WindowWidth / 2 - MagicMenu.SelIconSize) / 2, this.yPositionOnScreen + 85, MagicMenu.SelIconSize, MagicMenu.SelIconSize), Color.White);
                }
                b.DrawString(Game1.dialogueFont, desc, new Vector2(this.xPositionOnScreen + MagicMenu.WindowWidth / 2 + 12, this.yPositionOnScreen + 280), Color.Black, 0, Vector2.Zero, 0.75f, SpriteEffects.None, 0);

                int sx = this.Sel.Icons.Length + 1;
                for (int i = 0; i < this.Sel.Icons.Length; ++i)
                {
                    int x = this.xPositionOnScreen + MagicMenu.WindowWidth / 2 + (MagicMenu.WindowWidth / 2) / sx * (i + 1);
                    int y = this.yPositionOnScreen + MagicMenu.WindowHeight - 12 - MagicMenu.SpellIconSize - 32 - 40;

                    Color stateCol = Color.Gray;
                    if (spellBook.KnowsSpell(this.Sel, i))
                    {
                        stateCol = Color.Green;
                    }
                    else if (i == 0 || spellBook.KnowsSpell(this.Sel, i - 1))
                    {
                        stateCol = Color.White;
                    }

                    var r = new Rectangle(x - MagicMenu.SpellIconSize / 2, y, MagicMenu.SpellIconSize, MagicMenu.SpellIconSize);
                    IClickableMenu.drawTextureBox(b, r.Left - 12, r.Top - 12, r.Width + 24, r.Height + 24, stateCol);
                    if (this.Sel.Icons[i] != null)
                    {
                        b.Draw(this.Sel.Icons[i], r, Color.White);
                    }
                    if (r.Contains(Game1.getOldMouseX(), Game1.getOldMouseY()))
                    {
                        if (this.JustLeftClicked && spellBook.KnowsSpell(this.Sel, i))
                        {
                            this.Dragging        = new PreparedSpell(this.Sel.FullId, i);
                            this.JustLeftClicked = false;
                        }
                        else if (i == 0 || spellBook.KnowsSpell(this.Sel, i - 1))
                        {
                            if (this.JustLeftClicked)
                            {
                                spellBook.LearnSpell(this.Sel, i);
                            }
                            else if (this.JustRightClicked && i != 0)
                            {
                                spellBook.ForgetSpell(this.Sel, i);
                            }
                        }
                    }
                }

                b.DrawString(Game1.dialogueFont, "Free points: " + spellBook.FreePoints, new Vector2(this.xPositionOnScreen + MagicMenu.WindowWidth / 2 + 12 + 24, this.yPositionOnScreen + MagicMenu.WindowHeight - 12 - 32 - 20), Color.Black);
            }
            //*
            {
                int y = this.yPositionOnScreen + gap + 12 + (hasFifthSpellSlot ? -32 : 0);
                foreach (var spellBar in spellBook.Prepared)
                {
                    for (int i = 0; i < (hasFifthSpellSlot ? 5 : 4); ++i)
                    {
                        var prep = spellBar.GetSlot(i);

                        var r = new Rectangle(this.xPositionOnScreen + MagicMenu.WindowWidth + 12, y, MagicMenu.HotbarIconSize, MagicMenu.HotbarIconSize);
                        if (r.Contains(Game1.getOldMouseX(), Game1.getOldMouseY()))
                        {
                            if (this.JustRightClicked)
                            {
                                spellBar.SetSlot(i, prep = null);
                            }
                            else if (this.JustLeftClicked)
                            {
                                spellBar.SetSlot(i, prep = this.Dragging);
                                this.Dragging            = null;
                                this.JustLeftClicked     = false;
                            }
                        }

                        IClickableMenu.drawTextureBox(b, Game1.menuTexture, new Rectangle(0, 256, 60, 60), r.X - 12, y - 12, MagicMenu.HotbarIconSize + 24, MagicMenu.HotbarIconSize + 24, Color.White, 1f, false);

                        if (prep != null)
                        {
                            Spell       spell = SpellManager.Get(prep.SpellId);
                            Texture2D[] icons = spell?.Icons;
                            if (icons != null && icons.Length > prep.Level && icons[prep.Level] != null)
                            {
                                Texture2D icon = icons[prep.Level];
                                b.Draw(icon, r, Color.White);
                            }
                        }
                        y += MagicMenu.HotbarIconSize + 12;
                    }
                    y += gap + 12;
                }
            }
            //*/

            if (this.JustLeftClicked)
            {
                this.Dragging        = null;
                this.JustLeftClicked = false;
            }
            this.JustRightClicked = false;

            base.draw(b);
            if (this.Dragging != null)
            {
                Spell       spell = SpellManager.Get(this.Dragging.SpellId);
                Texture2D[] icons = spell?.Icons;
                if (icons != null && icons.Length > this.Dragging.Level && icons[this.Dragging.Level] != null)
                {
                    Texture2D icon = icons[this.Dragging.Level];

                    b.Draw(icon, new Rectangle(Game1.getOldMouseX(), Game1.getOldMouseY(), MagicMenu.HotbarIconSize, MagicMenu.HotbarIconSize), Color.White);
                }
            }
            this.drawMouse(b);
        }