Index: src/tools/stuffextract/StuffExtract.cpp =================================================================== --- src/tools/stuffextract/StuffExtract.cpp (revision 355) +++ src/tools/stuffextract/StuffExtract.cpp (working copy) @@ -187,6 +187,14 @@ s << (*it).getFloat(field); return s.str(); } + else if(format[field]=='c') + { + if((*it).getUChar(field) == 0 && skip_null) + return ""; // do not explicitly write float fields that are 0 + std::stringstream s; + s << (int)(*it).getUChar(field); + return s.str(); + } else if(format[field]=='s' && (*it).getUInt(field)) { return (*it).getString(field); @@ -254,10 +262,11 @@ bool ConvertDBC(void) { std::map racemap; // needed to extract other dbc files correctly + std::map classmask; //from CharBaseInfo.dbc SCPStorageMap EmoteDataStorage,RaceDataStorage,SoundDataStorage,MapDataStorage,ZoneDataStorage,ItemDisplayInfoStorage, - CreatureModelStorage,CreatureDisplayInfoStorage,NPCSoundStorage,CharSectionStorage, GameObjectDisplayInfoStorage; // will store the converted data from dbc files + CreatureModelStorage,CreatureDisplayInfoStorage,NPCSoundStorage,CharSectionStorage, GameObjectDisplayInfoStorage, ChrBaseInfoStorage; // will store the converted data from dbc files DBCFile EmotesText,EmotesTextData,EmotesTextSound,ChrRaces,SoundEntries,Map,AreaTable,ItemDisplayInfo, - CreatureModelData,CreatureDisplayInfo,NPCSounds,CharSections,GameObjectDisplayInfo; + CreatureModelData,CreatureDisplayInfo,NPCSounds,CharSections,GameObjectDisplayInfo, ChrBaseInfo; printf("Opening DBC archive...\n"); MPQHelper mpq("dbc"); @@ -275,10 +284,20 @@ GameObjectDisplayInfo.openmem(mpq.ExtractFile("DBFilesClient\\GameObjectDisplayInfo.dbc")); NPCSounds.openmem(mpq.ExtractFile("DBFilesClient\\NPCSounds.dbc")); CharSections.openmem(mpq.ExtractFile("DBFilesClient\\CharSections.dbc")); + ChrBaseInfo.openmem(mpq.ExtractFile("DBFilesClient\\CharBaseInfo.dbc")); //... printf("DBC files opened.\n"); //... - printf("Reading data: races.."); + printf("Reading data: chrbaseinfo.."); + for(DBCFile::Iterator it = ChrBaseInfo.begin(); it != ChrBaseInfo.end(); ++it) + { + uint32 race = (uint32)(*it).getUChar(CBI_RACE); + uint32 cclass = (uint32)(*it).getUChar(CBI_CLASS); + classmask[race] |= 1<(offset+field*4); } + unsigned char getUChar(size_t field) const + { + assert(field < file.fieldCount); + return *reinterpret_cast(offset+field); + } const char *getString(size_t field) const { assert(field < file.fieldCount); Index: src/Client/GUI/CImageLoaderBLP.cpp =================================================================== --- src/Client/GUI/CImageLoaderBLP.cpp (revision 355) +++ src/Client/GUI/CImageLoaderBLP.cpp (working copy) @@ -5,12 +5,6 @@ #include "SImage.h" #include "CImageLoaderBLP.h" -#if defined(_DEBUG) && !defined(DEBUG) -#define DEBUG(code) code; -#else -#define DEBUG(code) ; -#endif - namespace irr { namespace video Index: src/Client/GUI/PseuGUI.cpp =================================================================== --- src/Client/GUI/PseuGUI.cpp (revision 355) +++ src/Client/GUI/PseuGUI.cpp (working copy) @@ -317,13 +317,11 @@ case SCENESTATE_REALMSELECT: _scene = new SceneCharSelection(this); _scene->SetData(ISCENE_CHARSEL_REALMFIRST, 1); - _scene->OnResize(); _scenestate_new = SCENESTATE_CHARSELECT; break; case SCENESTATE_CHARSELECT: _scene = new SceneCharSelection(this); _scene->SetData(ISCENE_CHARSEL_REALMFIRST, 0); - _scene->OnResize(); break; default: _scene = new Scene(this); // will draw nothing, just yield the gui } Index: src/Client/GUI/SceneData.h =================================================================== --- src/Client/GUI/SceneData.h (revision 355) +++ src/Client/GUI/SceneData.h (working copy) @@ -62,11 +62,14 @@ DSCENE_CHARSEL_BUTTON_BACK = 4, DSCENE_CHARSEL_REALMWIN_OK = 5, DSCENE_CHARSEL_REALMWIN_CANCEL = 6, + DSCENE_CHARSEL_NEWCHARWIN_OK = 7, + DSCENE_CHARSEL_NEWCHARWIN_CANCEL = 8, }; enum SceneCharSelectLabels { DSCENE_CHARSEL_LABEL_REALMWIN = 0, + DSCENE_CHARSEL_LABEL_NEWCHARWIN = 1, }; Index: src/Client/GUI/SceneCharselection.cpp =================================================================== --- src/Client/GUI/SceneCharselection.cpp (revision 355) +++ src/Client/GUI/SceneCharselection.cpp (working copy) @@ -15,22 +15,77 @@ BUTTON_SELECT_REALM = 0x10, BUTTON_REALMWIN_OK = 0x20, BUTTON_REALMWIN_CANCEL = 0x40, + BUTTON_NEWCHARWIN_OK = 0x80, + BUTTON_NEWCHARWIN_CANCEL = 0x100, }; SceneCharSelection::SceneCharSelection(PseuGUI *gui) : Scene(gui) { textdb = instance->dbmgr.GetDB("gui_charselect_text"); + racedb = instance->dbmgr.GetDB("race"); + classdb = instance->dbmgr.GetDB("class"); eventrecv = new GUIEventReceiver(); device->setEventReceiver(eventrecv); - eventrecv->keyToButtonMap[KEY_ESCAPE] = BUTTON_BACK | BUTTON_REALMWIN_CANCEL; - eventrecv->keyToButtonMap[KEY_RETURN] = BUTTON_ENTER_WORLD | BUTTON_REALMWIN_OK; + eventrecv->keyToButtonMap[KEY_ESCAPE] = BUTTON_BACK | BUTTON_REALMWIN_CANCEL | BUTTON_NEWCHARWIN_CANCEL; + eventrecv->keyToButtonMap[KEY_RETURN] = BUTTON_ENTER_WORLD | BUTTON_REALMWIN_OK | BUTTON_NEWCHARWIN_OK; eventrecv->customHandledEvents.insert(EGET_LISTBOX_SELECTED_AGAIN); dimension2d scrn = driver->getScreenSize(); + + guienv->addButton(CalcRelativeScreenPos(driver, 0.45f ,0.9f, 0.15f, 0.05f), NULL, BUTTON_ENTER_WORLD, + GetStringFromDB(ISCENE_CHARSEL_BUTTONS, DSCENE_CHARSEL_BUTTON_ENTERWORLD).c_str()); + guienv->addButton(CalcRelativeScreenPos(driver, 0.9f, 0.92f, 0.08f, 0.03f), NULL, BUTTON_BACK, + GetStringFromDB(ISCENE_CHARSEL_BUTTONS, DSCENE_CHARSEL_BUTTON_BACK).c_str()); + guienv->addButton(CalcRelativeScreenPos(driver, 0.85f, 0.05f, 0.12f, 0.04f), NULL, BUTTON_SELECT_REALM, + GetStringFromDB(ISCENE_CHARSEL_BUTTONS, DSCENE_CHARSEL_BUTTON_CHANGEREALM).c_str()); + guienv->addButton(CalcRelativeScreenPos(driver, 0.85f, 0.8f, 0.1f, 0.04f), NULL, BUTTON_NEW_CHARACTER, + GetStringFromDB(ISCENE_CHARSEL_BUTTONS, DSCENE_CHARSEL_BUTTON_NEWCHAR).c_str()); + guienv->addButton(CalcRelativeScreenPos(driver, 0.78f, 0.92f, 0.1f, 0.03f), NULL, BUTTON_DELETE_CHARACTER, + GetStringFromDB(ISCENE_CHARSEL_BUTTONS, DSCENE_CHARSEL_BUTTON_DELCHAR).c_str()); + rect clb_rect = CalcRelativeScreenPos(driver, 0.65f, 0.12f, 0.34f, 0.67f); + charlistbox = guienv->addListBox(clb_rect); - OnResize(); // call this manually to draw all buttons and stuff + mutex.acquire(); + WorldSession *ws = instance->GetWSession(); + if(ws) + { + uint32 ffaction = racedb->GetFieldId("faction"); + for(uint32 i = 0; i < ws->GetCharsCount(); i++) + { + CharacterListExt& c = ws->GetCharFromList(i); + core::stringw entry; + entry += c.p._name.c_str(); + entry += L", "; + entry += L"Level "; + entry += c.p._level; + entry += "L "; + entry += c.race.c_str(); + entry += L" "; + entry += c.class_.c_str(); + entry += L", "; + entry += c.zone.c_str(); + entry += L" ("; + entry += c.map_.c_str(); + entry += L")"; + charlistbox->addItem(entry.c_str()); + uint32 faction = racedb->GetInt(c.p._race, ffaction); + + SColor col; + switch(faction) + { + case 1: col.set(0xFF, 0xFF, 0x30, 0x30); break; + case 7: col.set(0xFF, 0x30, 0x30, 0xFF); break; + default: col.set(0xFFFFFFFF); + } + charlistbox->setItemOverrideColor(i,EGUI_LBC_TEXT,col); + charlistbox->setItemOverrideColor(i,EGUI_LBC_TEXT_HIGHLIGHT,col); + + } + } + mutex.release(); + if(soundengine) { ISoundSource *main_theme = soundengine->getSoundSource("data/misc/main_theme.ogg"); @@ -58,9 +113,40 @@ eventrecv->buttons |= BUTTON_ENTER_WORLD; } } + if(eventrecv->guievent.GUIEvent.EventType == EGET_ELEMENT_CLOSED) + { + if(eventrecv->guievent.GUIEvent.Caller == realmwin)//realmwin got closed via the close button, remove pointer + { + realmwin=NULL; + } + if(eventrecv->guievent.GUIEvent.Caller == newcharwin)//got closed via the close button, remove pointer + { + newcharwin=NULL; + } + } + if(eventrecv->guievent.GUIEvent.EventType == EGET_COMBO_BOX_CHANGED) + { + if(eventrecv->guievent.GUIEvent.Caller == raceselect) + { + classselect->clear(); + u32 class_name = classdb->GetFieldId("name"); + u32 race_classmask = racedb->GetFieldId("classmask"); + u32 classmask = racedb->GetInt(racemap[raceselect->getSelected()],race_classmask); + for(u32 i=1;i<=classdb->GetRowsCount();i++) + { + if(classmask & 1<GetString(i,class_name); + classmap[classselect->addItem(name.c_str())]=i; + } + } + + + } + } } - if(eventrecv->buttons & BUTTON_ENTER_WORLD && !realmwin) + if(eventrecv->buttons & BUTTON_ENTER_WORLD && !realmwin && !newcharwin) { logdebug("GUI: SceneCharSelect: Entering world"); WorldSession *ws = instance->GetWSession(); @@ -77,7 +163,7 @@ else logerror("GUI: BUTTON_ENTER_ WORLD pressed, but no WorldSession exists!"); } - if(eventrecv->buttons & BUTTON_BACK && !realmwin) // cant cancel with realmwin open (important for ESC key handling) + if(eventrecv->buttons & BUTTON_BACK && !realmwin && !newcharwin) // cant cancel with any window open (important for ESC key handling) { logdebug("GUI: SceneCharSelect: Back to Loginscreen"); gui->SetSceneState(SCENESTATE_LOGINSCREEN); @@ -87,84 +173,49 @@ if(WorldSession *ws = instance->GetWSession()) ws->SetMustDie(); } + if(eventrecv->buttons & BUTTON_DELETE_CHARACTER) { guienv->addMessageBox(L"Not yet implemented!", L"Deleting a character does not yet work!"); } if(eventrecv->buttons & BUTTON_NEW_CHARACTER) { - guienv->addMessageBox(L"Not yet implemented!", L"Creating a new character does not yet work!"); - } - if(eventrecv->buttons & BUTTON_SELECT_REALM) - { - if(instance->GetRSession()) + dimension2d dim; + rect pos; + newcharwin = guienv->addWindow(CalcRelativeScreenPos(driver, 0.2f, 0.2f, 0.6f, 0.6f), true, + GetStringFromDB(ISCENE_CHARSEL_LABELS, DSCENE_CHARSEL_LABEL_NEWCHARWIN).c_str()); + pos = newcharwin->getAbsolutePosition(); // get absolute position and trandform to absolute in-window position + dim.Width = pos.LowerRightCorner.X - pos.UpperLeftCorner.X; + dim.Height = pos.LowerRightCorner.Y - pos.UpperLeftCorner.Y; + newcharwin->addChild(guienv->addButton(CalcRelativeScreenPos(dim, 0.7f, 0.93f, 0.12f, 0.05f), newcharwin, BUTTON_NEWCHARWIN_OK, + GetStringFromDB(ISCENE_CHARSEL_BUTTONS, DSCENE_CHARSEL_NEWCHARWIN_OK).c_str())); + newcharwin->addChild(guienv->addButton(CalcRelativeScreenPos(dim, 0.85f, 0.93f, 0.12f, 0.05f), newcharwin, BUTTON_NEWCHARWIN_CANCEL, + GetStringFromDB(ISCENE_CHARSEL_BUTTONS, DSCENE_CHARSEL_NEWCHARWIN_CANCEL).c_str())); + raceselect = guienv->addComboBox(CalcRelativeScreenPos(dim, 0.1f,0.1f,0.8f,0.05f), newcharwin); + u32 race_name = racedb->GetFieldId("name"); + u32 race_classmask = racedb->GetFieldId("classmask"); + for(u32 i=1;i<=racedb->GetRowsCount();i++) { - scenedata[ISCENE_CHARSEL_REALMFIRST] = 1; // show realm selection window - OnResize(); // force gui redraw to remove window - // TODO: there should exist a better way without full redraw - } - else - { - guienv->addMessageBox(L"Not yet implemented!", L"This action is not yet supported.\nYou can change the realm only while still connected to the realm server."); - } - } - if(eventrecv->buttons & BUTTON_REALMWIN_OK) - { - RealmSession *rs = instance->GetRSession(); - if(rs) - { - u32 selected = realmlistbox->getSelected(); - if(selected < rs->GetRealmCount()) + if(racedb->GetUint32(i,race_classmask)>0)//If the race has a classmask, it is playable { - rs->SetRealmAddr(rs->GetRealm(selected).addr_port); - instance->CreateWorldSession(); - eventrecv->buttons |= BUTTON_REALMWIN_CANCEL; // easiest way to close the window without much additional code + core::stringw name = racedb->GetString(i,race_name); + racemap[raceselect->addItem(name.c_str())]=i; } - else - logerror("Realmlist selection out of bounds! (%u)",selected); } - } - // realmlist window - if(eventrecv->buttons & BUTTON_REALMWIN_CANCEL) - { - scenedata[ISCENE_CHARSEL_REALMFIRST] = 0; // do not show realm selection window - OnResize(); // force gui redraw to remove window - // TODO: there should exist a better way without full redraw + newcharwin->addChild(raceselect); + classselect = guienv->addComboBox(CalcRelativeScreenPos(dim, 0.1f,0.2f,0.8f,0.05f), newcharwin); + //newcharwin->addChild(classselect); + guienv->addStaticText(L"Char Name", CalcRelativeScreenPos(dim,0.1f,0.3f,0.8f,0.05f),false,true,newcharwin); + charname = guienv->addEditBox(L"", CalcRelativeScreenPos(dim,0.1f,0.35f,0.8f,0.05f),true, newcharwin); +//guienv->addMessageBox(L"Not yet implemented!", L"Creating a new character does not yet work!"); } - - eventrecv->buttons = 0; -} - -void SceneCharSelection::OnDelete(void) -{ -} - - -void SceneCharSelection::OnResize(void) -{ - // this seems to be necessary since after a window resize == 0x00000001 for some unknown reason (=CRASH!) - // if anyone knows how to fix that or whats causing it... please do so. - // note: used VC71. also tested it with resizing SceneLogin, there the ptr stays fine. wtf?! - textdb = instance->dbmgr.GetDB("gui_charselect_text"); - - guienv->clear(); // drop all elements and redraw - guienv->addButton(CalcRelativeScreenPos(driver, 0.45f ,0.9f, 0.15f, 0.05f), NULL, BUTTON_ENTER_WORLD, - GetStringFromDB(ISCENE_CHARSEL_BUTTONS, DSCENE_CHARSEL_BUTTON_ENTERWORLD).c_str()); - guienv->addButton(CalcRelativeScreenPos(driver, 0.9f, 0.92f, 0.08f, 0.03f), NULL, BUTTON_BACK, - GetStringFromDB(ISCENE_CHARSEL_BUTTONS, DSCENE_CHARSEL_BUTTON_BACK).c_str()); - guienv->addButton(CalcRelativeScreenPos(driver, 0.85f, 0.05f, 0.12f, 0.04f), NULL, BUTTON_SELECT_REALM, - GetStringFromDB(ISCENE_CHARSEL_BUTTONS, DSCENE_CHARSEL_BUTTON_CHANGEREALM).c_str()); - guienv->addButton(CalcRelativeScreenPos(driver, 0.85f, 0.8f, 0.1f, 0.04f), NULL, BUTTON_NEW_CHARACTER, - GetStringFromDB(ISCENE_CHARSEL_BUTTONS, DSCENE_CHARSEL_BUTTON_NEWCHAR).c_str()); - guienv->addButton(CalcRelativeScreenPos(driver, 0.78f, 0.92f, 0.1f, 0.03f), NULL, BUTTON_DELETE_CHARACTER, - GetStringFromDB(ISCENE_CHARSEL_BUTTONS, DSCENE_CHARSEL_BUTTON_DELCHAR).c_str()); - - realmwin = NULL; - mutex.acquire(); - if(scenedata[ISCENE_CHARSEL_REALMFIRST]) + if(eventrecv->buttons & BUTTON_SELECT_REALM || scenedata[ISCENE_CHARSEL_REALMFIRST]) { + scenedata[ISCENE_CHARSEL_REALMFIRST]=0; + if(instance->GetRSession()) + { dimension2d dim; rect pos; realmwin = guienv->addWindow(CalcRelativeScreenPos(driver, 0.2f, 0.2f, 0.6f, 0.6f), true, @@ -176,10 +227,9 @@ GetStringFromDB(ISCENE_CHARSEL_BUTTONS, DSCENE_CHARSEL_REALMWIN_OK).c_str())); realmwin->addChild(guienv->addButton(CalcRelativeScreenPos(dim, 0.85f, 0.93f, 0.12f, 0.05f), realmwin, BUTTON_REALMWIN_CANCEL, GetStringFromDB(ISCENE_CHARSEL_BUTTONS, DSCENE_CHARSEL_REALMWIN_CANCEL).c_str())); - realmlistbox = guienv->addListBox(CalcRelativeScreenPos(dim, 0.1f, 0.1f, 0.8f, 0.8f), realmwin); realmwin->addChild(realmlistbox); - + mutex.acquire(); RealmSession *rs = instance->GetRSession(); for(uint32 i = 0; i < rs->GetRealmCount(); i++) @@ -219,49 +269,81 @@ } if(realmlistbox->getItemCount()) realmlistbox->setSelected(0); + mutex.release(); + } + else + { + guienv->addMessageBox(L"Not yet implemented!", L"This action is not yet supported.\nYou can change the realm only while still connected to the realm server."); + } + } + if(eventrecv->buttons & BUTTON_REALMWIN_OK) + { + RealmSession *rs = instance->GetRSession(); + if(rs) + { + u32 selected = realmlistbox->getSelected(); + if(selected < rs->GetRealmCount()) + { + rs->SetRealmAddr(rs->GetRealm(selected).addr_port); + instance->CreateWorldSession(); + eventrecv->buttons |= BUTTON_REALMWIN_CANCEL; // easiest way to close the window without much additional code + } + else + logerror("Realmlist selection out of bounds! (%u)",selected); + } } - rect clb_rect = CalcRelativeScreenPos(driver, 0.65f, 0.12f, 0.34f, 0.67f); - charlistbox = guienv->addListBox(clb_rect); - WorldSession *ws = instance->GetWSession(); - if(ws) + if(eventrecv->buttons & BUTTON_NEWCHARWIN_OK) { - SCPDatabase *racedb = instance->dbmgr.GetDB("race"); - uint32 ffaction = racedb->GetFieldId("faction"); - for(uint32 i = 0; i < ws->GetCharsCount(); i++) + core::stringc tmp=charname->getText(); + u8 race = racemap[raceselect->getSelected()]; + u8 cclass = classmap[classselect->getSelected()]; + logdebug("Creating character Race %i Class %i Name %s",race,cclass,tmp.c_str()); + if(tmp.size() && race && cclass) { - CharacterListExt& c = ws->GetCharFromList(i); - core::stringw entry; - entry += c.p._name.c_str(); - entry += L", "; - entry += L"Level "; - entry += c.p._level; - entry += "L "; - entry += c.race.c_str(); - entry += L" "; - entry += c.class_.c_str(); - entry += L", "; - entry += c.zone.c_str(); - entry += L" ("; - entry += c.map_.c_str(); - entry += L")"; - charlistbox->addItem(entry.c_str()); - - uint32 faction = racedb->GetInt(c.p._race, ffaction); - - SColor col; - switch(faction) + WorldSession *ws=instance->GetWSession(); + if(ws) { - case 1: col.set(0xFF, 0xFF, 0x30, 0x30); break; - case 7: col.set(0xFF, 0x30, 0x30, 0xFF); break; - default: col.set(0xFFFFFFFF); + WorldPacket packet(CMSG_CHAR_CREATE,(tmp.size()+1)+1+1+1+1+1+1+1+1+1); + packet<AddSendWorldPacket(packet); + eventrecv->buttons |= BUTTON_NEWCHARWIN_CANCEL; // easiest way to close the window without much additional code } - charlistbox->setItemOverrideColor(i,EGUI_LBC_TEXT,col); - charlistbox->setItemOverrideColor(i,EGUI_LBC_TEXT_HIGHLIGHT,col); - + else + logerror("Trying to create new Character, but no WorldSession exists."); } + else + logerror("Race, Class or Name not set!"); } - mutex.release(); + // realmlist window + + if(eventrecv->buttons & BUTTON_REALMWIN_CANCEL) + { + realmwin->remove(); + realmwin=NULL; + } + + // new character window + if(eventrecv->buttons & BUTTON_NEWCHARWIN_CANCEL) + { + newcharwin->remove(); + newcharwin=NULL; + } + + eventrecv->buttons = 0; } +void SceneCharSelection::OnDelete(void) +{ +} + + +void SceneCharSelection::OnResize(void) +{ +//TODO: Handle Resizes correctly. This goes for the loginscreen as well + +} + Index: src/Client/GUI/Scene.h =================================================================== --- src/Client/GUI/Scene.h (revision 355) +++ src/Client/GUI/Scene.h (working copy) @@ -63,7 +63,7 @@ CCursorController *cursor; SceneState _scenestate; uint32 scenedata[SCENEDATA_SIZE]; // generic storage for anything the PseuInstance thread wants to tell us - SCPDatabase *textdb; + SCPDatabase *textdb, *racedb, *classdb; ZThread::FastMutex mutex; }; @@ -107,6 +107,12 @@ IGUIWindow *realmwin; IGUIListBox *realmlistbox; IGUIListBox *charlistbox; // temporary until something better found + //Character creation //temporary. maybe a whole new character creation scene should be used? + IGUIWindow *newcharwin; + IGUIComboBox *raceselect; + IGUIComboBox *classselect; + IGUIEditBox *charname; + std::map racemap, classmap; // maps DB IDs in db to IDs in the combobox, because irrlicht does not allow custom ids in comboboxes }; Index: src/Client/World/WorldSession.cpp =================================================================== --- src/Client/World/WorldSession.cpp (revision 355) +++ src/Client/World/WorldSession.cpp (working copy) @@ -577,17 +577,19 @@ PlayerEnum plr[10]; // max characters per realm is 10 uint8 dummy8; uint32 dummy32; - + bool char_found; _charList.clear(); recvPacket >> num; if(num==0) { - logerror("No chars found!"); - GetInstance()->SetError(); - return; + logdetail("No chars found!"); + char_found = false; + //GetInstance()->SetError(); + //return; } - + else + { logdetail("Chars in list: %u",num); _LoadCache(); // we are about to login, so we need cache data // TODO: load cache on loadingscreen @@ -623,7 +625,7 @@ plrNameCache.AddInfo(plr[i]._guid, plr[i]._name); // TODO: set after loadingscreen, after loading cache } - bool char_found=false; + char_found=false; SCPDatabase *zonedb = GetDBMgr().GetDB("zone"), *racedb = GetDBMgr().GetDB("race"), @@ -667,13 +669,14 @@ if(plr[i]._items[inv].displayId) logdebug("-> Has Item: Model=%u InventoryType=%u",plr[i]._items[inv].displayId,plr[i]._items[inv].inventorytype); } - if(plr[i]._name==GetInstance()->GetConf()->charname || num == 1) + if(plr[i]._name==GetInstance()->GetConf()->charname) { charId = i; char_found=true; } } + } if(!char_found) { if(PseuGUI *gui = GetInstance()->GetGUI()) Index: bin/data/scp/gui_charselect_text.scp =================================================================== --- bin/data/scp/gui_charselect_text.scp (revision 355) +++ bin/data/scp/gui_charselect_text.scp (working copy) @@ -8,7 +8,10 @@ 4=Back 5=OK 6=Cancel +7=Create +8=Cancel [2] 0=Realmlist +1=Create New Character Index: bin/data/scp/race.scp =================================================================== --- bin/data/scp/race.scp (revision 355) +++ bin/data/scp/race.scp (working copy) @@ -6,6 +6,7 @@ faction=7 name_general=Human name=Human +classmask=886 [2] model_m=51 @@ -14,6 +15,7 @@ faction=1 name_general=Orc name=Orc +classmask=730 [3] model_m=53 @@ -22,6 +24,7 @@ faction=7 name_general=Dwarf name=Dwarf +classmask=126 [4] model_m=55 @@ -30,6 +33,7 @@ faction=7 name_general=NightElf name=Night Elf +classmask=2170 [5] model_m=57 @@ -38,6 +42,7 @@ faction=1 name_general=Scourge name=Undead +classmask=882 [6] model_m=59 @@ -46,6 +51,7 @@ faction=1 name_general=Tauren name=Tauren +classmask=2250 [7] model_m=1563 @@ -54,6 +60,7 @@ faction=7 name_general=Gnome name=Gnome +classmask=850 [8] model_m=1478 @@ -62,6 +69,7 @@ faction=1 name_general=Troll name=Troll +classmask=506 [9] model_m=6894 @@ -70,6 +78,7 @@ faction=7 name_general=Goblin name=Goblin +classmask=0 [10] model_m=15476 @@ -78,6 +87,7 @@ faction=1 name_general=BloodElf name=Blood Elf +classmask=892 [11] model_m=16125 @@ -86,6 +96,7 @@ faction=7 name_general=Draenei name=Draenei +classmask=494 [12] model_m=16981 @@ -94,6 +105,7 @@ faction=7 name_general=FelOrc name=Fel Orc +classmask=0 [13] model_m=17402 @@ -102,6 +114,7 @@ faction=7 name_general=Naga_ name=Naga +classmask=0 [14] model_m=17576 @@ -110,6 +123,7 @@ faction=7 name_general=Broken name=Broken +classmask=0 [15] model_m=17578 @@ -118,6 +132,7 @@ faction=7 name_general=Skeleton name=Skeleton +classmask=0 [16] model_m=21685 @@ -126,6 +141,7 @@ faction=7 name_general=Vrykul name=Vrykul +classmask=0 [17] model_m=21780 @@ -134,6 +150,7 @@ faction=7 name_general=Tuskarr name=Tuskarr +classmask=0 [18] model_m=21963 @@ -142,6 +159,7 @@ faction=7 name_general=ForestTroll name=Forest Troll +classmask=0 [19] model_m=26316 @@ -150,6 +168,7 @@ faction=7 name_general=Taunka name=Taunka +classmask=0 [20] model_m=26871 @@ -158,6 +177,7 @@ faction=7 name_general=NorthrendSkeleton name=Northrend Skeleton +classmask=0 [21] model_m=26873 @@ -166,4 +186,5 @@ faction=7 name_general=IceTroll name=Ice Troll +classmask=0