changeset 198:e6e348d66a75

Some work on spellbook
author Nomad
date Sat, 16 Feb 2013 21:46:07 +0200
parents 5979fc0de9ae
children 66db86fa4ed2 1609e46161fd
files GUIWindow.cpp GUIWindow.h Party.cpp Player.cpp Player.h mm7_4.cpp mm7_5.cpp mm7_data.cpp mm7_data.h
diffstat 9 files changed, 194 insertions(+), 226 deletions(-) [+]
line wrap: on
line diff
--- a/GUIWindow.cpp	Sat Feb 16 20:24:31 2013 +0200
+++ b/GUIWindow.cpp	Sat Feb 16 21:46:07 2013 +0200
@@ -962,66 +962,64 @@
 
 
 //----- (00411621) --------------------------------------------------------
-GUIButton *GUIWindow::OpenSpellBook()
+void GUIWindow::OpenSpellBook()
 {
   Player *pPlayer; // edi@1
-  GUIWindow *pWindow; // esi@1
-  unsigned int v3; // ebp@1
+  //GUIWindow *pWindow; // esi@1
+  //unsigned int v3; // ebp@1
   int v4; // eax@3
-  GUIButton *result; // eax@25
+  ///GUIButton *result; // eax@25
   int a2; // [sp+10h] [bp-8h]@1
-  int v7; // [sp+14h] [bp-4h]@1
-
-  //__debugbreak();
+  //int v7; // [sp+14h] [bp-4h]@1
 
   pPlayer = pPlayers[uActiveCharacter];
-  pWindow = this;
-  LoadSpellbook(pPlayer->pNumSpellBookPage);
-  v3 = 0;
+  //pWindow = this;
+  LoadSpellbook(pPlayer->lastOpenedSpellbookPage);
+  //v3 = 0;
   a2 = 0;
-  v7 = (int)&pPlayer->spellbook.pChapters[pPlayer->pNumSpellBookPage];
-  do
+
+  auto chapter = &pPlayer->spellbook.pChapters[pPlayer->lastOpenedSpellbookPage];
+  for (uint i = 0; i < 11; ++i)
   {
-    if ( *(char *)(v7 + v3) )
-    {
-      v4 = 2 * (12 * pPlayer->pNumSpellBookPage + (unsigned __int8)*(&byte_4E2431[12 * pPlayer->pNumSpellBookPage] + v3));
-      pWindow->CreateButton(pViewport->uViewportX + dword_4E20D0[v4],
-        pViewport->uViewportY + dword_4E20D0[v4 + 1],
-        dword_506408[v3 + 1]->uTextureWidth,
-        dword_506408[v3 + 1]->uTextureHeight,
-        1, 79, 0x56u, v3, 0, "", 0);
+    if (!chapter->bIsSpellAvailable[i])
+      continue;
+
+      v4 = 2 * (12 * pPlayer->lastOpenedSpellbookPage + pSpellbookSpellIndices[pPlayer->lastOpenedSpellbookPage][i + 1]);
+      CreateButton(pViewport->uViewportX + dword_4E20D0[v4],
+                   pViewport->uViewportY + dword_4E20D0[v4 + 1],
+                   dword_506408[i + 1]->uTextureWidth,
+                   dword_506408[i + 1]->uTextureHeight,
+                   1, 79, 0x56u, i, 0, "", 0);
       ++a2;
-    }
-    ++v3;
+    //++v3;
   }
-  while ( (signed int)v3 < 11 );
-  pWindow->CreateButton(0, 0, 0, 0, 1, 0, 0x33u, 0, 9u, "", 0);
+  //while ( (signed int)v3 < 11 );
+
+  CreateButton(0, 0, 0, 0, 1, 0, 0x33u, 0, 9u, "", 0);
   if ( a2 )
-    pWindow->_41D08F(a2, 0, 0, 0);
-  if ( pPlayer->pActiveSkills[12] )
-    pWindow->CreateButton(0x18Fu, 0xAu, 0x32u, 0x24u, 1, 0, 0x57u, 0, 0, aSpellSchoolNames[0], 0);
-  if ( pPlayer->pActiveSkills[13] )
-    pWindow->CreateButton(0x18Fu, 0x2Eu, 0x32u, 0x24u, 1, 0, 0x57u, 1u, 0, aSpellSchoolNames[1], 0);
-  if ( pPlayer->pActiveSkills[14] )
-    pWindow->CreateButton(0x18Fu, 0x53u, 0x32u, 0x24u, 1, 0, 0x57u, 2u, 0, aSpellSchoolNames[2], 0);
-  if ( pPlayer->pActiveSkills[15] )
-    pWindow->CreateButton(0x18Fu, 0x79u, 0x32u, 0x24u, 1, 0, 0x57u, 3u, 0, aSpellSchoolNames[3], 0);
-  if ( pPlayer->pActiveSkills[16] )
-    pWindow->CreateButton(0x18Fu, 0x9Eu, 0x32u, 0x24u, 1, 0, 0x57u, 4u, 0, aSpellSchoolNames[4], 0);
-  if ( pPlayer->pActiveSkills[17] )
-    pWindow->CreateButton(0x190u, 0xC4u, 0x32u, 0x24u, 1, 0, 0x57u, 5u, 0, aSpellSchoolNames[5], 0);
-  if ( pPlayer->pActiveSkills[18] )
-    pWindow->CreateButton(0x190u, 0xEAu, 0x32u, 0x24u, 1, 0, 0x57u, 6u, 0, aSpellSchoolNames[6], 0);
-  if ( pPlayer->pActiveSkills[19] )
-    pWindow->CreateButton(0x190u, 0x10Fu, 0x32u, 0x24u, 1, 0, 0x57u, 7u, 0, aSpellSchoolNames[7], 0);
-  if ( pPlayer->pActiveSkills[20] )
-    pWindow->CreateButton(0x190u, 0x133u, 0x32u, 0x24u, 1, 0, 0x57u, 8u, 0, aSpellSchoolNames[8], 0);
-  pWindow->CreateButton(0x1DCu, 0x1C2u, pTexture_506444->uTextureWidth, pTexture_506444->uTextureHeight, 1, 78, 0x58u, 0, 0, "", 0);
-  pBtn_InstallRemoveSpell = pWindow->CreateButton(0x1DCu, 0x1C2u, 0x30u, 0x20u, 1, 78, 0x58u, 0, 0, "", pTexture_506444, 0);
-  pWindow->CreateButton(0x231u, 0x1C2u, ptr_506440->uTextureWidth, ptr_506440->uTextureHeight, 1, 0, 0x71u, 0, 0, pGlobalTXT_LocalizationStrings[79], 0);
-  pBtn_CloseBook = pWindow->CreateButton(0x231u, 0x1C2u, 0x30u, 0x20u, 1, 0, 0x71u, 0, 0, pGlobalTXT_LocalizationStrings[79], ptr_506440, 0);
-  result = pBtn_CloseBook;
-  return result;
+    _41D08F(a2, 0, 0, 0);
+  if (pPlayer->pActiveSkills[PLAYER_SKILL_FIRE])
+    CreateButton(0x18Fu, 0xAu, 0x32u, 0x24u, 1, 0, 0x57u, 0, 0, aSpellSchoolNames[0], 0);
+  if (pPlayer->pActiveSkills[PLAYER_SKILL_AIR])
+    CreateButton(0x18Fu, 0x2Eu, 0x32u, 0x24u, 1, 0, 0x57u, 1u, 0, aSpellSchoolNames[1], 0);
+  if (pPlayer->pActiveSkills[PLAYER_SKILL_WATER])
+    CreateButton(0x18Fu, 0x53u, 0x32u, 0x24u, 1, 0, 0x57u, 2u, 0, aSpellSchoolNames[2], 0);
+  if (pPlayer->pActiveSkills[PLAYER_SKILL_EARTH])
+    CreateButton(0x18Fu, 0x79u, 0x32u, 0x24u, 1, 0, 0x57u, 3u, 0, aSpellSchoolNames[3], 0);
+  if (pPlayer->pActiveSkills[PLAYER_SKILL_SPIRIT])
+    CreateButton(0x18Fu, 0x9Eu, 0x32u, 0x24u, 1, 0, 0x57u, 4u, 0, aSpellSchoolNames[4], 0);
+  if (pPlayer->pActiveSkills[PLAYER_SKILL_MIND])
+    CreateButton(0x190u, 0xC4u, 0x32u, 0x24u, 1, 0, 0x57u, 5u, 0, aSpellSchoolNames[5], 0);
+  if (pPlayer->pActiveSkills[PLAYER_SKILL_BODY])
+    CreateButton(0x190u, 0xEAu, 0x32u, 0x24u, 1, 0, 0x57u, 6u, 0, aSpellSchoolNames[6], 0);
+  if (pPlayer->pActiveSkills[PLAYER_SKILL_LIGHT])
+    CreateButton(0x190u, 0x10Fu, 0x32u, 0x24u, 1, 0, 0x57u, 7u, 0, aSpellSchoolNames[7], 0);
+  if (pPlayer->pActiveSkills[PLAYER_SKILL_DARK])
+    CreateButton(0x190u, 0x133u, 0x32u, 0x24u, 1, 0, 0x57u, 8u, 0, aSpellSchoolNames[8], 0);
+  CreateButton(0x1DCu, 0x1C2u, pTexture_506444->uTextureWidth, pTexture_506444->uTextureHeight, 1, 78, 0x58u, 0, 0, "", 0);
+  pBtn_InstallRemoveSpell = CreateButton(0x1DCu, 0x1C2u, 0x30u, 0x20u, 1, 78, 0x58u, 0, 0, "", pTexture_506444, 0);
+  CreateButton(0x231u, 0x1C2u, ptr_506440->uTextureWidth, ptr_506440->uTextureHeight, 1, 0, 0x71u, 0, 0, pGlobalTXT_LocalizationStrings[79], 0);
+  pBtn_CloseBook = CreateButton(0x231u, 0x1C2u, 0x30u, 0x20u, 1, 0, 0x71u, 0, 0, pGlobalTXT_LocalizationStrings[79], ptr_506440, 0);
 }
 // 50640C: using guessed type int dword_50640C[];
 
--- a/GUIWindow.h	Sat Feb 16 20:24:31 2013 +0200
+++ b/GUIWindow.h	Sat Feb 16 21:46:07 2013 +0200
@@ -103,7 +103,7 @@
 	            unsigned __int16 uDefaultColor, const char *pInString, unsigned int uLineSpacing);
   char *_4B1854(__int64 a2);
   void _4B3157();
-  GUIButton *OpenSpellBook();
+  void OpenSpellBook();
   void InitializeBookView();
   void DrawMessageBox(int arg0);
   GUIButton *GetControl(unsigned int uID);
--- a/Party.cpp	Sat Feb 16 20:24:31 2013 +0200
+++ b/Party.cpp	Sat Feb 16 21:46:07 2013 +0200
@@ -392,7 +392,7 @@
 	    if (pPlayers[uNumPlayers].pActiveSkills[12+i])
 			++uSpellBookPageCount;
     }
-    pCharacter->pNumSpellBookPage = uSpellBookPageCount;
+    pCharacter->lastOpenedSpellbookPage = uSpellBookPageCount;
 //LABEL_10:
     pCharacter->uExpressionTimePassed = 0;
     Dst.Reset();
--- a/Player.cpp	Sat Feb 16 20:24:31 2013 +0200
+++ b/Player.cpp	Sat Feb 16 21:46:07 2013 +0200
@@ -1761,6 +1761,8 @@
   unsigned int uSlota; // [sp+14h] [bp+4h]@1
 
   pIndices = &this->pInventoryIndices[uSlot];
+
+  __debugbreak();  // the following indexing is invalid
   v3 = (ItemGen *)&this->spellbook.pDarkSpellbook.bIsSpellAvailable[36 * *pIndices + 5];
   v4 = v3->uItemID;
   v3->Reset();
@@ -2315,6 +2317,8 @@
   field_FC = 0;
   field_100 = 0;
   field_104 = 0;
+
+  lastOpenedSpellbookPage = 0;
 }
 
 //----- (0048C6F6) --------------------------------------------------------
@@ -6534,15 +6538,15 @@
 
     switch (i)
     {
-      case PLAYER_SKILL_FIRE:   spellbook.pFireSpellbook.bIsSpellbookAvailable = true;   break;
-      case PLAYER_SKILL_AIR:    spellbook.pAirSpellbook.bIsSpellbookAvailable = true;    break;
-      case PLAYER_SKILL_WATER:  spellbook.pWaterSpellbook.bIsSpellbookAvailable = true;  break;
-      case PLAYER_SKILL_EARTH:  spellbook.pEarthSpellbook.bIsSpellbookAvailable = true;  break;
-      case PLAYER_SKILL_SPIRIT: spellbook.pSpiritSpellbook.bIsSpellbookAvailable = true; break;
-      case PLAYER_SKILL_MIND:   spellbook.pMindSpellbook.bIsSpellbookAvailable = 1; break;
-      case PLAYER_SKILL_BODY:   spellbook.pBodySpellbook.bIsSpellbookAvailable = 1; break;
-      case PLAYER_SKILL_LIGHT:  spellbook.pLightSpellbook.bIsSpellbookAvailable = 1; break;
-      case PLAYER_SKILL_DARK:   spellbook.pDarkSpellbook.bIsSpellbookAvailable = 1; break;
+      case PLAYER_SKILL_FIRE:   spellbook.pFireSpellbook.bIsSpellAvailable[0] = true;   break;
+      case PLAYER_SKILL_AIR:    spellbook.pAirSpellbook.bIsSpellAvailable[0] = true;    break;
+      case PLAYER_SKILL_WATER:  spellbook.pWaterSpellbook.bIsSpellAvailable[0] = true;  break;
+      case PLAYER_SKILL_EARTH:  spellbook.pEarthSpellbook.bIsSpellAvailable[0] = true;  break;
+      case PLAYER_SKILL_SPIRIT: spellbook.pSpiritSpellbook.bIsSpellAvailable[0] = true; break;
+      case PLAYER_SKILL_MIND:   spellbook.pMindSpellbook.bIsSpellAvailable[0] = true;   break;
+      case PLAYER_SKILL_BODY:   spellbook.pBodySpellbook.bIsSpellAvailable[0] = true;   break;
+      case PLAYER_SKILL_LIGHT:  spellbook.pLightSpellbook.bIsSpellAvailable[0] = true;  break;
+      case PLAYER_SKILL_DARK:   spellbook.pDarkSpellbook.bIsSpellAvailable[0] = true;   break;
     }
   }
 
--- a/Player.h	Sat Feb 16 20:24:31 2013 +0200
+++ b/Player.h	Sat Feb 16 21:46:07 2013 +0200
@@ -195,26 +195,26 @@
   PLAYER_SKILL_WATER = 14,
   PLAYER_SKILL_EARTH = 15,
   PLAYER_SKILL_SPIRIT = 16,
-  PLAYER_SKILL_MIND = 0x11,
+  PLAYER_SKILL_MIND = 17,
   PLAYER_SKILL_BODY = 18,
-  PLAYER_SKILL_LIGHT = 0x13,
-  PLAYER_SKILL_DARK = 0x14,
-  PLAYER_SKILL_ITEM_ID = 0x15,
-  PLAYER_SKILL_MERCHANT = 0x16,
-  PLAYER_SKILL_REPAIR = 0x17,
-  PLAYER_SKILL_BODYBUILDING = 0x18,
-  PLAYER_SKILL_MEDITATION = 0x19,
-  PLAYER_SKILL_PERCEPTION = 0x1A,
-  PLAYER_SKILL_DIPLOMACY = 0x1B,
-  PLAYER_SKILL_TIEVERY = 0x1C,
+  PLAYER_SKILL_LIGHT = 19,
+  PLAYER_SKILL_DARK = 20,
+  PLAYER_SKILL_ITEM_ID = 21,
+  PLAYER_SKILL_MERCHANT = 22,
+  PLAYER_SKILL_REPAIR = 23,
+  PLAYER_SKILL_BODYBUILDING = 24,
+  PLAYER_SKILL_MEDITATION = 25,
+  PLAYER_SKILL_PERCEPTION = 26,
+  PLAYER_SKILL_DIPLOMACY = 27,
+  PLAYER_SKILL_TIEVERY = 28,
   PLAYER_SKILL_TRAP_DISARM = 29,
-  PLAYER_SKILL_DODGE = 0x1E,
-  PLAYER_SKILL_UNARMED = 0x1F,
-  PLAYER_SKILL_MONSTER_ID = 0x20,
+  PLAYER_SKILL_DODGE = 30,
+  PLAYER_SKILL_UNARMED = 31,
+  PLAYER_SKILL_MONSTER_ID = 32,
   PLAYER_SKILL_ARMSMASTER = 33,
   PLAYER_SKILL_STEALING = 34,
   PLAYER_SKILL_ALCHEMY = 35,
-  PLAYER_SKILL_LEARNING = 0x24,
+  PLAYER_SKILL_LEARNING = 36,
 };
 
 /*  329 */
@@ -255,8 +255,7 @@
 #pragma pack(push, 1)
 struct PlayerSpellbookChapter
 {
-  unsigned __int8 bIsSpellbookAvailable;
-  char bIsSpellAvailable[10];
+  char bIsSpellAvailable[11];
 };
 #pragma pack(pop)
 
@@ -666,7 +665,7 @@
   int field_1988[49];
   char field_1A4C;
   char field_1A4D;
-  char pNumSpellBookPage;
+  char lastOpenedSpellbookPage;
   unsigned __int8 uQuickSpell;
   char field_1A50[64];
   char _some_attack_bonus;
--- a/mm7_4.cpp	Sat Feb 16 20:24:31 2013 +0200
+++ b/mm7_4.cpp	Sat Feb 16 21:46:07 2013 +0200
@@ -1,5 +1,6 @@
 #include <io.h>
 #include <direct.h>
+#include <assert.h>
 
 #include "MapInfo.h"
 #include "Game.h"
@@ -5861,7 +5862,7 @@
   signed int uSkillIdx; // eax@45
   int v15; // eax@70
   signed int v16; // ecx@70
-  unsigned int v18; // [sp-4h] [bp-84h]@48
+  //unsigned int v18; // [sp-4h] [bp-84h]@48
   ItemGen item; // [sp+Ch] [bp-74h]@37
   char v20[32]; // [sp+30h] [bp-50h]@29
   //char v21; // [sp+31h] [bp-4Fh]@29
@@ -5999,7 +6000,7 @@
       if ( pPlayer->pActiveSkills[12+i] )
         ++uSpellBookPageCount;
     }
-    pPlayer->pNumSpellBookPage = uSpellBookPageCount;
+    pPlayer->lastOpenedSpellbookPage = uSpellBookPageCount;
     pItemsTable->GenerateItem(2, 40, &item);
     pPlayer->AddItem2(-1, &item);
     uSkillIdx = 0;
@@ -6010,96 +6011,66 @@
       {
         switch ( uSkillIdx )
         {
-          case 0:
-            v18 = 61;
-            pPlayer->AddItem(-1, v18);
-            break;
-          case 1:
-            v18 = 1;
-            pPlayer->AddItem(-1, v18);
-            break;
-          case 2:
-            v18 = 15;
-			pPlayer->AddItem(-1, v18);
-            break;
-          case 3:
-            v18 = 23;
-			pPlayer->AddItem(-1, v18);
-            break;
-          case 4:
-            v18 = 31;
-			pPlayer->AddItem(-1, v18);
-            break;
-          case 5:
-            v18 = 47;
-			pPlayer->AddItem(-1, v18);
-            break;
-          case 6:
-            v18 = 50;
-			pPlayer->AddItem(-1, v18);
-            break;
-          case 8:
-            v18 = 84;
-  			pPlayer->AddItem(-1, v18);
-            break;
-          case 9:
-            v18 = 66;
-			pPlayer->AddItem(-1, v18);
-            break;
-          case 10:
-            v18 = 71;
-			pPlayer->AddItem(-1, v18);
-            break;
-          case 11:
-            v18 = 76;
-			pPlayer->AddItem(-1, v18);
-            break;
-          case 12:
+          case PLAYER_SKILL_STAFF:   pPlayer->AddItem(-1, 61); break;
+          case PLAYER_SKILL_SWORD:   pPlayer->AddItem(-1, 1); break;
+          case PLAYER_SKILL_DAGGER:  pPlayer->AddItem(-1, 15); break;
+          case PLAYER_SKILL_AXE:     pPlayer->AddItem(-1, 23); break;
+          case PLAYER_SKILL_SPEAR:   pPlayer->AddItem(-1, 31); break;
+          case PLAYER_SKILL_BOW:     pPlayer->AddItem(-1, 47); break;
+          case PLAYER_SKILL_MACE:    pPlayer->AddItem(-1, 50); break;
+          case PLAYER_SKILL_BLASTER: assert(false); break;
+          case PLAYER_SKILL_SHIELD:  pPlayer->AddItem(-1, 84); break;
+          case PLAYER_SKILL_LEATHER: pPlayer->AddItem(-1, 66); break;
+          case PLAYER_SKILL_CHAIN:   pPlayer->AddItem(-1, 71); break;
+          case PLAYER_SKILL_PLATE:   pPlayer->AddItem(-1, 76); break;
+          case PLAYER_SKILL_FIRE:
             pPlayer->AddItem(-1, 0x191);
-            pPlayer->spellbook.pFireSpellbook.bIsSpellbookAvailable = 1;
-            break;
-          case 13:
+            pPlayer->spellbook.pFireSpellbook.bIsSpellAvailable[0] = true;
+          break;
+          case PLAYER_SKILL_AIR:
             pPlayer->AddItem(-1, 0x19C);
-            pPlayer->spellbook.pAirSpellbook.bIsSpellbookAvailable = 1;
-            break;
-          case 14:
+            pPlayer->spellbook.pAirSpellbook.bIsSpellAvailable[0] = true;
+          break;
+          case PLAYER_SKILL_WATER:
             pPlayer->AddItem(-1, 0x1A7);
-			pPlayer->spellbook.pWaterSpellbook.bIsSpellbookAvailable = 1;
-            break;
-          case 15:
+			pPlayer->spellbook.pWaterSpellbook.bIsSpellAvailable[0] = true;
+          break;
+          case PLAYER_SKILL_EARTH:
             pPlayer->AddItem(-1, 0x1B2);
-			pPlayer->spellbook.pEarthSpellbook.bIsSpellbookAvailable = 1;
-            break;
-          case 16:
+			pPlayer->spellbook.pEarthSpellbook.bIsSpellAvailable[0] = true;
+          break;
+          case PLAYER_SKILL_SPIRIT:
             pPlayer->AddItem(-1, 0x1BD);
-			pPlayer->spellbook.pSpiritSpellbook.bIsSpellbookAvailable = 1;
-            break;
-          case 17:
+			pPlayer->spellbook.pSpiritSpellbook.bIsSpellAvailable[0] = true;
+          break;
+          case PLAYER_SKILL_MIND:
             pPlayer->AddItem(-1, 0x1C8);
-			pPlayer->spellbook.pMindSpellbook.bIsSpellbookAvailable = 1;
-            break;
-          case 18:
+			pPlayer->spellbook.pMindSpellbook.bIsSpellAvailable[0] = true;
+          break;
+          case PLAYER_SKILL_BODY:
             pPlayer->AddItem(-1, 0x1D3);
-			pPlayer->spellbook.pBodySpellbook.bIsSpellbookAvailable = 1;
-            break;
-          case 21:
-          case 23:
-          case 25:
-          case 26:
-          case 29:
-          case 36:
+			pPlayer->spellbook.pBodySpellbook.bIsSpellAvailable[0] = true;
+          break;
+          case PLAYER_SKILL_LIGHT:
+          case PLAYER_SKILL_DARK:
+          case PLAYER_SKILL_DIPLOMACY:
+            assert(false);
+          break;
+          case PLAYER_SKILL_ITEM_ID:
+          case PLAYER_SKILL_REPAIR:
+          case PLAYER_SKILL_MEDITATION:
+          case PLAYER_SKILL_PERCEPTION:
+          case PLAYER_SKILL_TRAP_DISARM:
+          case PLAYER_SKILL_LEARNING:
             pPlayer->AddItem(-1, 0xDC);
-            v18 = 5 * (rand() % 3 + 40);
-			pPlayer->AddItem(-1, v18);
-            break;
-          case 30:
-            v18 = 115;
-			pPlayer->AddItem(-1, v18);
-            break;
-          case 31:
-            v18 = 110;
-            pPlayer->AddItem(-1, v18);
-            break;
+			pPlayer->AddItem(-1, 5 * (rand() % 3 + 40));
+          break;
+          case PLAYER_SKILL_DODGE:
+			pPlayer->AddItem(-1, 115);
+          break;
+          case PLAYER_SKILL_UNARMED:
+            pPlayer->AddItem(-1, 110);
+          break;
           default:
             break;
         }
--- a/mm7_5.cpp	Sat Feb 16 20:24:31 2013 +0200
+++ b/mm7_5.cpp	Sat Feb 16 21:46:07 2013 +0200
@@ -2962,7 +2962,7 @@
         case UIMSG_4E:
           if ( dword_50654C && byte_506550 )
           {
-            v173 = pSpellStats->pInfos[dword_50654C + 11 * pPlayers[uActiveCharacter]->pNumSpellBookPage].pName;
+            v173 = pSpellStats->pInfos[dword_50654C + 11 * pPlayers[uActiveCharacter]->lastOpenedSpellbookPage].pName;
             v157 = pGlobalTXT_LocalizationStrings[483];
 _sprintex_2args_draw_status_and_continue:
             sprintf(pTmpBuf, v157, v173);
@@ -3019,7 +3019,7 @@
             v127 = 203;
             goto _play_sound_and_continue;
           }
-          v99 = dword_50654C + 11 * pPlayers[uActiveCharacter]->pNumSpellBookPage;
+          v99 = dword_50654C + 11 * pPlayers[uActiveCharacter]->lastOpenedSpellbookPage;
           pPlayers[uActiveCharacter]->uQuickSpell = v99;
           stru_A750F8[uActiveCharacter + 3]._494836(v99, uActiveCharacter);
           if ( uActiveCharacter )
@@ -3038,7 +3038,7 @@
           {
             if ( *(short *)thisl )
             {
-              if ( pPlayer3->pNumSpellBookPage == v101 )
+              if ( pPlayer3->lastOpenedSpellbookPage == v101 )
                 uAction = (int)pNPCData4;
               v102 = (int)pNPCData4;
               pNPCData4 = (NPCData *)((char *)pNPCData4 + 1);
@@ -3073,7 +3073,7 @@
               uAction = 0;
           }
           sub_41140B();
-          pPlayers[uActiveCharacter]->pNumSpellBookPage = LOBYTE(v217[uAction]);
+          pPlayers[uActiveCharacter]->lastOpenedSpellbookPage = LOBYTE(v217[uAction]);
           pGUIWindow_CurrentMenu->OpenSpellBook();
           v165 = 0;
           v151 = 0;
@@ -3085,10 +3085,10 @@
           v127 = rand() % 2 + 204;
           goto _play_sound_and_continue;
         case UIMSG_57:
-          if ( pTurnEngine->field_4 == 3 || !uActiveCharacter || uMessageParam == pPlayers[uActiveCharacter]->pNumSpellBookPage )
+          if ( pTurnEngine->field_4 == 3 || !uActiveCharacter || uMessageParam == pPlayers[uActiveCharacter]->lastOpenedSpellbookPage )
             continue;
           sub_41140B();
-          pPlayers[uActiveCharacter]->pNumSpellBookPage = uMessageParam;
+          pPlayers[uActiveCharacter]->lastOpenedSpellbookPage = uMessageParam;
           pGUIWindow_CurrentMenu->OpenSpellBook();
           v165 = 0;
           v151 = 0;
@@ -12738,7 +12738,7 @@
 
   v1 = pPlayers[uActiveCharacter];
   v10 = _this;
-  v2 = &pSpellStats->pInfos[(signed int)((char *)_this + 11 * v1->pNumSpellBookPage) + 1];
+  v2 = &pSpellStats->pInfos[(signed int)((char *)_this + 11 * v1->lastOpenedSpellbookPage) + 1];
   if ( pMouse->GetCursorPos(&a2)->y <= 250 )
     v3 = pMouse->GetCursorPos(&a2)->y + 30;
   else
@@ -12797,14 +12797,14 @@
   a1.DrawText(pFontSmallnum, 120, 44, 0, pTmpBuf2, 0, 0, 0);
   a1.uFrameWidth = 108;
   a1.uFrameZ = a1.uFrameX + 107;
-  a1.DrawTitleText(pFontComic, 0xCu, 0x4Bu, 0, pSkillNames[v1->pNumSpellBookPage + 12], 3u);
+  a1.DrawTitleText(pFontComic, 0xCu, 0x4Bu, 0, pSkillNames[v1->lastOpenedSpellbookPage + 12], 3u);
   sprintf(
     pTmpBuf,
     "%s\n%d",
     pGlobalTXT_LocalizationStrings[522],
     *(&pSpellDatas[0].field_12 //temp_fix field_14
-    + ((unsigned int)LOBYTE(v1->pActiveSkills[v1->pNumSpellBookPage + 12]) >> 6)
-    + 10 * (int)((char *)v10 + 11 * v1->pNumSpellBookPage)));
+    + ((unsigned int)LOBYTE(v1->pActiveSkills[v1->lastOpenedSpellbookPage + 12]) >> 6)
+    + 10 * (int)((char *)v10 + 11 * v1->lastOpenedSpellbookPage)));
   a1.DrawTitleText(pFontComic, 0xCu, a1.uFrameHeight - LOBYTE(pFontComic->uFontHeight) - 16, 0, pTmpBuf, 3u);
   dword_507B00_spell_info_to_draw_in_popup = 0;
 }
@@ -13130,56 +13130,44 @@
 // 4E1D3A: using guessed type __int16 word_4E1D3A[];
 
 //----- (00411300) --------------------------------------------------------
-Texture *__fastcall LoadSpellbook(unsigned int uID)
-{
-  unsigned int v1; // esi@1
+void LoadSpellbook(unsigned int school)
+{
+  //unsigned int v1; // esi@1
   Player *pPlayer; // ecx@1
   char v3; // al@1
-  int v4; // edi@5
-  Texture *result; // eax@6
-  char *v6; // edi@7
-  unsigned int v7; // eax@7
-  unsigned __int8 v8; // sf@8
-  unsigned __int8 v9; // of@8
+  //int v4; // edi@5
+  //Texture *result; // eax@6
+  //unsigned char *v6; // edi@7
+  //unsigned int v7; // eax@7
+  //unsigned __int8 v8; // sf@8
+  //unsigned __int8 v9; // of@8
   char pContainer[20]; // [sp+Ch] [bp-1Ch]@7
   Texture *v11; // [sp+20h] [bp-8h]@5
-  int v12; // [sp+24h] [bp-4h]@5
+  //int v12; // [sp+24h] [bp-4h]@5
 
   byte_506550 = 0;
-  v1 = uID;
+  //v1 = uID;
   pPlayer = pPlayers[uActiveCharacter];
   v3 = pPlayer->uQuickSpell;
-  if ( v3 && (unsigned __int8)v3 / 11 == v1 )
-    dword_50654C = (unsigned __int8)v3 - 11 * v1;
+  if ( v3 && (unsigned __int8)v3 / 11 == school )
+    dword_50654C = (unsigned __int8)v3 - 11 * school;
   else
     dword_50654C = 0;
-  v4 = 1;
-  v12 = 1;
-  v11 = (Texture *)&pPlayer->field_152[11 * v1 + 63];
-  do
-  {
-    result = v11;
-    if ( v11->pName[v4] )
-    {
-      v6 = &byte_4E2430[12 * v1] + v4;
-      sprintf(pContainer, "SB%sS%02d", spellbook_texture_filename_suffices[v1], (unsigned __int8)*v6);
-      v7 = pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE);
-      dword_506408[v12] = &pIcons_LOD->pTextures[v7];
-      sprintf(pContainer, "SB%sC%02d", spellbook_texture_filename_suffices[v1], (unsigned __int8)*v6);
-      result = &pIcons_LOD->pTextures[pIcons_LOD->LoadTexture(pContainer, TEXTURE_16BIT_PALETTE)];
-      dword_5063D8[v12] = result;
-    }
-    v4 = v12 + 1;
-    v9 = v12++ > 12;//v9 = __OFSUB__(v12 + 1, 12);
-    v8 = v12++ - 11 < 0;
-  }
-  while ( v8 ^ v9 );
-  return result;
-}
-// 4E1D18: using guessed type char *spellbook_texture_filename_suffices[8];
-// 506408: using guessed type int dword_506408[];
-// 50654C: using guessed type int dword_50654C;
-// 506550: using guessed type char byte_506550;
+
+  v11 = (Texture *)&pPlayer->field_152[11 * school + 63];
+
+  for (uint i = 1; i < 12; ++i)
+  {
+    if ( v11->pName[i] )
+    {
+      sprintf(pContainer, "SB%sS%02d", spellbook_texture_filename_suffices[school], pSpellbookSpellIndices[school][i]);
+      dword_506408[i] = pIcons_LOD->LoadTexturePtr(pContainer, TEXTURE_16BIT_PALETTE);
+
+      sprintf(pContainer, "SB%sC%02d", spellbook_texture_filename_suffices[school], pSpellbookSpellIndices[school][i]);
+      dword_5063D8[i] = pIcons_LOD->LoadTexturePtr(pContainer, TEXTURE_16BIT_PALETTE);
+    }
+  }
+}
 
 //----- (0041140B) --------------------------------------------------------
 GUIWindow *__cdecl sub_41140B()
@@ -13279,7 +13267,7 @@
 
   v0 = 0;
   if ( uActiveCharacter )
-	  v0 = pParty->pPlayers[uActiveCharacter-1].pNumSpellBookPage;//*((char *)&pParty->pPartyBuffs[5].uExpireTime + 6972 * uActiveCharacter + 2);
+	  v0 = pParty->pPlayers[uActiveCharacter-1].lastOpenedSpellbookPage;//*((char *)&pParty->pPartyBuffs[5].uExpireTime + 6972 * uActiveCharacter + 2);
   pRenderer->DrawTextureIndexed(8u, 8u, pTextures_5064A0[v0]);
   pRenderer->DrawTextureIndexed(0x1DCu, 0x1C2u, pTexture_50643C);
   pRenderer->DrawTextureIndexed(0x231u, 0x1C2u, pTexture_506448);
@@ -13318,7 +13306,7 @@
 
   sub_412AF9();
   v0 = pPlayers[uActiveCharacter];
-  v1 = 11 * v0->pNumSpellBookPage;
+  v1 = 11 * v0->lastOpenedSpellbookPage;
   v2 = pIcons_LOD->FindTextureByName("Pending");
   v3 = (Texture *)(v2 != -1 ? (int)&pIcons_LOD->pTextures[v2] : 0);
   pRenderer->ClearZBuffer(0, 479);
@@ -13344,14 +13332,14 @@
           }
           if ( v6->pLevelOfDetail0 )
           {
-            v7 = 2 * (12 * v0->pNumSpellBookPage + (unsigned __int8)*(&byte_4E2430[12 * v0->pNumSpellBookPage + v4]));
+            v7 = 2 * (12 * v0->lastOpenedSpellbookPage + pSpellbookSpellIndices[v0->lastOpenedSpellbookPage][v4]);
             v19 = pViewport->uViewportY + dword_4E20D0[v7 + 1];
             v17 = pViewport->uViewportX + dword_4E20D0[v7];
             if ( BYTE1(v6->pBits) & 2 )
               pRenderer->DrawTextureTransparent(v17, v19, v6);
             else
               pRenderer->DrawTextureIndexed(v17, v19, v6);
-            v8 = 2 * (12 * v0->pNumSpellBookPage + (unsigned __int8)*(&byte_4E2430[12 * v0->pNumSpellBookPage] + v4));
+            v8 = 2 * (12 * v0->lastOpenedSpellbookPage + pSpellbookSpellIndices[v0->lastOpenedSpellbookPage][v4]);
             pRenderer->_4A612A(dword_4E20D0[v8], dword_4E20D0[v8 + 1], v23, v4);
           }
         }
@@ -13368,7 +13356,7 @@
     if ( v11->pLevelOfDetail0 )
     {
       v21 = dword_5063D8[v10];
-      v12 = 2 * (12 * v0->pNumSpellBookPage + (unsigned __int8)*(&byte_4E2430[12 * v0->pNumSpellBookPage] + v10));
+      v12 = 2 * (12 * v0->lastOpenedSpellbookPage + pSpellbookSpellIndices[v0->lastOpenedSpellbookPage][v10]);
       v20 = pViewport->uViewportY + dword_4E20D0[v12 + 1];
       v18 = pViewport->uViewportX + dword_4E20D0[v12];
       if ( BYTE1(v11->pBits) & 2 )
@@ -13386,7 +13374,7 @@
   {
     if ( *(short *)a2.x )
     {
-      if ( v0->pNumSpellBookPage == v13 )
+      if ( v0->lastOpenedSpellbookPage == v13 )
       {
         pPageTexture = pTextures_tabs[v13][1];
         switch ( v13 )
--- a/mm7_data.cpp	Sat Feb 16 20:24:31 2013 +0200
+++ b/mm7_data.cpp	Sat Feb 16 21:46:07 2013 +0200
@@ -384,9 +384,19 @@
 __int16 pTownPortalBook_ws[6];
 __int16 pTownPortalBook_hs[6];
 int dword_4E20D0[777]; // idb
-char byte_4E2430[777]; // weak
-char byte_4E2431[777]; // weak
-unsigned int pLloydsBeaconsPreviewXs[5] = {61, 281,  61, 281, 171};
+unsigned char pSpellbookSpellIndices[9][12] = // 4E2430
+{
+   {0,  3,  1,  8, 11,  7,  4, 10,  6,  2,  5,  9},
+   {0, 11,  2,  9,  6,  8,  5, 10,  3,  7,  1,  4},
+   {0,  4,  8,  9,  1, 10,  3, 11,  7,  6,  2,  5}, 
+   {0,  7, 10,  8,  2, 11,  1,  5,  3,  6,  4,  9},
+   {0,  5, 10, 11,  7,  2,  8,  1,  4,  9,  3,  6},
+   {0,  5,  9,  8,  3,  7,  6,  4,  1, 11,  2, 10}, 
+   {0,  1,  6,  9,  3,  5,  8, 11,  7, 10,  4,  2},
+   {0,  1, 10, 11,  9,  4,  3,  6,  5,  7,  8,  2},
+   {0,  9,  3,  7,  1,  5,  2, 10, 11,  8,  6,  4}
+};
+unsigned int pLloydsBeaconsPreviewXs[5] = {61, 281,  61, 281, 171}; // 004E249C
 unsigned int pLloydsBeaconsPreviewYs[5] = {84,  84, 228, 228, 155};
 unsigned int pLloydsBeacons_SomeXs[5] = {59, 279, 59, 279, 169};
 unsigned int pLloydsBeacons_SomeYs[5] = {82, 82, 226, 226, 153};
--- a/mm7_data.h	Sat Feb 16 20:24:31 2013 +0200
+++ b/mm7_data.h	Sat Feb 16 21:46:07 2013 +0200
@@ -374,9 +374,8 @@
 extern __int16 pTownPortalBook_ws[6];
 extern __int16 pTownPortalBook_hs[6];
 extern int dword_4E20D0[]; // idb
-extern char byte_4E2430[]; // weak
-extern char byte_4E2431[]; // weak
-extern unsigned int pLloydsBeaconsPreviewXs[5];
+extern unsigned char pSpellbookSpellIndices[9][12]; // 4E2430
+extern unsigned int pLloydsBeaconsPreviewXs[5]; // 004E249C
 extern unsigned int pLloydsBeaconsPreviewYs[5];
 extern unsigned int pLloydsBeacons_SomeXs[5];
 extern unsigned int pLloydsBeacons_SomeYs[5]; // idb
@@ -1154,7 +1153,6 @@
 extern __int64 qword_506350; // weak
 extern char byte_506360; // weak
 extern int dword_506364; // weak
-extern Texture *dword_506408[]; // weak
 extern Texture *dword_50640C[]; // weak
 extern unsigned int uTextureID_506438;
 extern int dword_50651C; // weak
@@ -1827,7 +1825,7 @@
 signed int __fastcall sub_410D99_get_map_index(int a1);
 unsigned int __cdecl DrawLloydBeaconsScreen();
 char *__cdecl DrawTownPortalScreen();
-struct Texture *__fastcall LoadSpellbook(unsigned int uID); // idb
+void LoadSpellbook(unsigned int uID); // idb
 struct GUIWindow *__cdecl sub_41140B();
 void __cdecl sub_411473();
 void __cdecl OnCloseSpellook();