* added posibility to create chars from the GUI. thx shlainn!
-> stuffextract: extract classmask field * implemented irrlicht event message queueing. might fix some gui bugs.
This commit is contained in:
parent
53e88fca44
commit
585046fce2
@ -8,7 +8,10 @@
|
||||
4=Back
|
||||
5=OK
|
||||
6=Cancel
|
||||
7=Create
|
||||
8=Cancel
|
||||
|
||||
[2]
|
||||
0=Realmlist
|
||||
1=Create New Character
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ name_short=Hu
|
||||
faction=7
|
||||
name_general=Human
|
||||
name=Human
|
||||
classmask=886
|
||||
|
||||
[2]
|
||||
model_m=51
|
||||
@ -14,6 +15,7 @@ name_short=Or
|
||||
faction=1
|
||||
name_general=Orc
|
||||
name=Orc
|
||||
classmask=730
|
||||
|
||||
[3]
|
||||
model_m=53
|
||||
@ -22,6 +24,7 @@ name_short=Dw
|
||||
faction=7
|
||||
name_general=Dwarf
|
||||
name=Dwarf
|
||||
classmask=126
|
||||
|
||||
[4]
|
||||
model_m=55
|
||||
@ -30,6 +33,7 @@ name_short=Ni
|
||||
faction=7
|
||||
name_general=NightElf
|
||||
name=Night Elf
|
||||
classmask=2170
|
||||
|
||||
[5]
|
||||
model_m=57
|
||||
@ -38,6 +42,7 @@ name_short=Sc
|
||||
faction=1
|
||||
name_general=Scourge
|
||||
name=Undead
|
||||
classmask=882
|
||||
|
||||
[6]
|
||||
model_m=59
|
||||
@ -46,6 +51,7 @@ name_short=Ta
|
||||
faction=1
|
||||
name_general=Tauren
|
||||
name=Tauren
|
||||
classmask=2250
|
||||
|
||||
[7]
|
||||
model_m=1563
|
||||
@ -54,6 +60,7 @@ name_short=Gn
|
||||
faction=7
|
||||
name_general=Gnome
|
||||
name=Gnome
|
||||
classmask=850
|
||||
|
||||
[8]
|
||||
model_m=1478
|
||||
@ -62,6 +69,7 @@ name_short=Tr
|
||||
faction=1
|
||||
name_general=Troll
|
||||
name=Troll
|
||||
classmask=506
|
||||
|
||||
[9]
|
||||
model_m=6894
|
||||
@ -70,6 +78,7 @@ name_short=Go
|
||||
faction=7
|
||||
name_general=Goblin
|
||||
name=Goblin
|
||||
classmask=0
|
||||
|
||||
[10]
|
||||
model_m=15476
|
||||
@ -78,6 +87,7 @@ name_short=Be
|
||||
faction=1
|
||||
name_general=BloodElf
|
||||
name=Blood Elf
|
||||
classmask=892
|
||||
|
||||
[11]
|
||||
model_m=16125
|
||||
@ -86,6 +96,7 @@ name_short=Dr
|
||||
faction=7
|
||||
name_general=Draenei
|
||||
name=Draenei
|
||||
classmask=494
|
||||
|
||||
[12]
|
||||
model_m=16981
|
||||
@ -94,6 +105,7 @@ name_short=Fo
|
||||
faction=7
|
||||
name_general=FelOrc
|
||||
name=Fel Orc
|
||||
classmask=0
|
||||
|
||||
[13]
|
||||
model_m=17402
|
||||
@ -102,6 +114,7 @@ name_short=Na
|
||||
faction=7
|
||||
name_general=Naga_
|
||||
name=Naga
|
||||
classmask=0
|
||||
|
||||
[14]
|
||||
model_m=17576
|
||||
@ -110,6 +123,7 @@ name_short=Br
|
||||
faction=7
|
||||
name_general=Broken
|
||||
name=Broken
|
||||
classmask=0
|
||||
|
||||
[15]
|
||||
model_m=17578
|
||||
@ -118,6 +132,7 @@ name_short=Sk
|
||||
faction=7
|
||||
name_general=Skeleton
|
||||
name=Skeleton
|
||||
classmask=0
|
||||
|
||||
[16]
|
||||
model_m=21685
|
||||
@ -126,6 +141,7 @@ name_short=Vr
|
||||
faction=7
|
||||
name_general=Vrykul
|
||||
name=Vrykul
|
||||
classmask=0
|
||||
|
||||
[17]
|
||||
model_m=21780
|
||||
@ -134,6 +150,7 @@ name_short=Tu
|
||||
faction=7
|
||||
name_general=Tuskarr
|
||||
name=Tuskarr
|
||||
classmask=0
|
||||
|
||||
[18]
|
||||
model_m=21963
|
||||
@ -142,6 +159,7 @@ name_short=Ft
|
||||
faction=7
|
||||
name_general=ForestTroll
|
||||
name=Forest Troll
|
||||
classmask=0
|
||||
|
||||
[19]
|
||||
model_m=26316
|
||||
@ -150,6 +168,7 @@ name_short=Wt
|
||||
faction=7
|
||||
name_general=Taunka
|
||||
name=Taunka
|
||||
classmask=0
|
||||
|
||||
[20]
|
||||
model_m=26871
|
||||
@ -158,6 +177,7 @@ name_short=NS
|
||||
faction=7
|
||||
name_general=NorthrendSkeleton
|
||||
name=Northrend Skeleton
|
||||
classmask=0
|
||||
|
||||
[21]
|
||||
model_m=26873
|
||||
@ -166,4 +186,5 @@ name_short=It
|
||||
faction=7
|
||||
name_general=IceTroll
|
||||
name=Ice Troll
|
||||
classmask=0
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
#ifndef GUIEVENTRECEIVER_H
|
||||
#define GUIEVENTRECEIVER_H
|
||||
|
||||
#include <queue>
|
||||
|
||||
|
||||
class GUIEventReceiver : public IEventReceiver
|
||||
{
|
||||
@ -9,30 +11,24 @@ public:
|
||||
{
|
||||
buttons = 0;
|
||||
react_to_keys = true;
|
||||
memset(&guievent, 0 , sizeof(SEvent));
|
||||
memset(&keyevent, 0 , sizeof(SEvent));
|
||||
memset(&mouseevent, 0 , sizeof(SEvent));
|
||||
guievent_proc = false;
|
||||
mouseevent_proc = false;
|
||||
keyevent_proc = false;
|
||||
store_gui = true;
|
||||
store_keys = true;
|
||||
store_mouse = true;
|
||||
}
|
||||
virtual bool OnEvent(const SEvent& event)
|
||||
{
|
||||
// copy all 3 event types into different stores for later external use
|
||||
if(event.EventType == EET_GUI_EVENT)
|
||||
{
|
||||
guievent = event;
|
||||
guievent_proc = false;
|
||||
guieventqueue.push_back(event.GUIEvent);
|
||||
}
|
||||
else if(event.EventType == EET_KEY_INPUT_EVENT)
|
||||
{
|
||||
keyevent = event;
|
||||
keyevent_proc = false;
|
||||
keyeventqueue.push_back(event.KeyInput);
|
||||
}
|
||||
else if(event.EventType == EET_MOUSE_INPUT_EVENT)
|
||||
{
|
||||
mouseevent = event;
|
||||
mouseevent_proc = false;
|
||||
mouseeventqueue.push_back(event.MouseInput);
|
||||
}
|
||||
|
||||
bool proc = false;
|
||||
@ -74,13 +70,45 @@ public:
|
||||
return proc;
|
||||
}
|
||||
|
||||
bool react_to_keys;
|
||||
inline bool HasMouseEvent(void) { return mouseeventqueue.size(); }
|
||||
inline bool HasGUIEvent(void) { return guieventqueue.size(); }
|
||||
inline bool HasKeyEvent(void) { return keyeventqueue.size(); }
|
||||
|
||||
|
||||
inline SEvent::SMouseInput NextMouseEvent(void)
|
||||
{
|
||||
ASSERT(HasMouseEvent())
|
||||
const SEvent::SMouseInput ev = mouseeventqueue.front();
|
||||
mouseeventqueue.pop_front();
|
||||
return ev;
|
||||
}
|
||||
|
||||
inline SEvent::SGUIEvent NextGUIEvent(void)
|
||||
{
|
||||
ASSERT(HasGUIEvent())
|
||||
SEvent::SGUIEvent ev = guieventqueue.front();
|
||||
guieventqueue.pop_front();
|
||||
return ev;
|
||||
}
|
||||
|
||||
inline SEvent::SKeyInput NextKeyEvent(void)
|
||||
{
|
||||
ASSERT(HasKeyEvent())
|
||||
SEvent::SKeyInput ev = keyeventqueue.front();
|
||||
keyeventqueue.pop_front();
|
||||
return ev;
|
||||
}
|
||||
|
||||
bool react_to_keys, store_mouse, store_keys, store_gui;
|
||||
u32 buttons;
|
||||
SEvent guievent, mouseevent, keyevent;
|
||||
bool keyevent_proc, mouseevent_proc, guievent_proc;
|
||||
std::map<u32,u32> keyToButtonMap; // to simulate button press on key input
|
||||
std::set<u32> customHandledEvents;
|
||||
|
||||
protected:
|
||||
std::list<SEvent::SGUIEvent> guieventqueue;
|
||||
std::list<SEvent::SMouseInput> mouseeventqueue;
|
||||
std::list<SEvent::SKeyInput> keyeventqueue;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -317,13 +317,11 @@ void PseuGUI::_UpdateSceneState(void)
|
||||
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
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ protected:
|
||||
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 @@ private:
|
||||
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<u32,u32> racemap, classmap; //<comboBoxId,dbId> maps DB IDs in db to IDs in the combobox, because irrlicht does not allow custom ids in comboboxes
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -15,141 +15,28 @@ enum GuiElementID
|
||||
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)
|
||||
{
|
||||
realmwin = NULL;
|
||||
newcharwin = NULL;
|
||||
|
||||
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);
|
||||
eventrecv->store_mouse = false; // do not queue mouse input
|
||||
|
||||
dimension2d<s32> scrn = driver->getScreenSize();
|
||||
|
||||
OnResize(); // call this manually to draw all buttons and stuff
|
||||
|
||||
if(soundengine)
|
||||
{
|
||||
ISoundSource *main_theme = soundengine->getSoundSource("data/misc/main_theme.ogg");
|
||||
if(main_theme && !soundengine->isCurrentlyPlaying(main_theme))
|
||||
{
|
||||
soundengine->play2D(main_theme,true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneCharSelection::OnUpdate(s32 timepassed)
|
||||
{
|
||||
// treat doubleclick on listboxes as OK button click
|
||||
if(!eventrecv->guievent_proc)
|
||||
{
|
||||
eventrecv->guievent_proc = true;
|
||||
if(eventrecv->guievent.GUIEvent.EventType == EGET_LISTBOX_SELECTED_AGAIN)
|
||||
{
|
||||
if(eventrecv->guievent.GUIEvent.Caller == realmlistbox)
|
||||
{
|
||||
eventrecv->buttons |= BUTTON_REALMWIN_OK;
|
||||
}
|
||||
else if(eventrecv->guievent.GUIEvent.Caller == charlistbox)
|
||||
{
|
||||
eventrecv->buttons |= BUTTON_ENTER_WORLD;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(eventrecv->buttons & BUTTON_ENTER_WORLD && !realmwin)
|
||||
{
|
||||
logdebug("GUI: SceneCharSelect: Entering world");
|
||||
WorldSession *ws = instance->GetWSession();
|
||||
if(ws)
|
||||
{
|
||||
u32 selected = charlistbox->getSelected();
|
||||
if(selected < ws->GetCharsCount())
|
||||
{
|
||||
ws->EnterWorldWithCharacter(ws->GetCharFromList(selected).p._name);
|
||||
}
|
||||
else
|
||||
logerror("Character selection out of bounds! (%u)",selected);
|
||||
}
|
||||
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)
|
||||
{
|
||||
logdebug("GUI: SceneCharSelect: Back to Loginscreen");
|
||||
gui->SetSceneState(SCENESTATE_LOGINSCREEN);
|
||||
// disconnect from realm server if connected
|
||||
if(RealmSession *rs = instance->GetRSession())
|
||||
rs->SetMustDie();
|
||||
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())
|
||||
{
|
||||
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())
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
eventrecv->buttons = 0;
|
||||
}
|
||||
|
||||
void SceneCharSelection::OnDelete(void)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void SceneCharSelection::OnResize(void)
|
||||
{
|
||||
// this seems to be necessary since after a window resize <textdb> == 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,
|
||||
@ -160,73 +47,13 @@ void SceneCharSelection::OnResize(void)
|
||||
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])
|
||||
{
|
||||
dimension2d<s32> dim;
|
||||
rect<s32> pos;
|
||||
realmwin = guienv->addWindow(CalcRelativeScreenPos(driver, 0.2f, 0.2f, 0.6f, 0.6f), true,
|
||||
GetStringFromDB(ISCENE_CHARSEL_LABELS, DSCENE_CHARSEL_LABEL_REALMWIN).c_str());
|
||||
pos = realmwin->getAbsolutePosition(); // get absolute position and trandform <dim> to absolute in-window position
|
||||
dim.Width = pos.LowerRightCorner.X - pos.UpperLeftCorner.X;
|
||||
dim.Height = pos.LowerRightCorner.Y - pos.UpperLeftCorner.Y;
|
||||
realmwin->addChild(guienv->addButton(CalcRelativeScreenPos(dim, 0.7f, 0.93f, 0.12f, 0.05f), realmwin, BUTTON_REALMWIN_OK,
|
||||
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);
|
||||
|
||||
RealmSession *rs = instance->GetRSession();
|
||||
|
||||
for(uint32 i = 0; i < rs->GetRealmCount(); i++)
|
||||
{
|
||||
SRealmInfo& r = rs->GetRealm(i);
|
||||
core::stringw entry;
|
||||
entry += r.name.c_str();
|
||||
entry += L", ";
|
||||
switch(r.icon) // icon means here RealmType
|
||||
{
|
||||
case 0: entry += "Normal"; break;
|
||||
case 1: entry += "PvP"; break;
|
||||
case 4: entry += "Normal(4)"; break;
|
||||
case 6: entry += "RP"; break;
|
||||
case 8: entry += "RP-PvP"; break;
|
||||
case 16: entry += "FFA-PvP"; break; // MaNGOS custom realm type
|
||||
default: entry += "Unknown"; break;
|
||||
}
|
||||
entry += L", (";
|
||||
entry += r.chars_here;
|
||||
entry += L") Chars";
|
||||
entry += L" [";
|
||||
entry += r.addr_port.c_str();
|
||||
entry += L"]";
|
||||
realmlistbox->addItem(entry.c_str(), -1);
|
||||
SColor col;
|
||||
switch(r.color)
|
||||
{
|
||||
case 0: col.set(0xFF, 0x00, 0xFF, 0x00); break;
|
||||
case 1: col.set(0xFF, 0xFF, 0x00, 0x00); break;
|
||||
case 2: col.set(0xFF, 0x7F, 0x7F, 0x7F); break;
|
||||
case 3: col.set(0xFF, 0xB0, 0xB0, 0x00); break;
|
||||
default: col.set(0xFFFFFFFF);
|
||||
}
|
||||
realmlistbox->setItemOverrideColor(i,EGUI_LBC_TEXT,col);
|
||||
realmlistbox->setItemOverrideColor(i,EGUI_LBC_TEXT_HIGHLIGHT,col);
|
||||
}
|
||||
if(realmlistbox->getItemCount())
|
||||
realmlistbox->setSelected(0);
|
||||
}
|
||||
|
||||
rect<s32> clb_rect = CalcRelativeScreenPos(driver, 0.65f, 0.12f, 0.34f, 0.67f);
|
||||
charlistbox = guienv->addListBox(clb_rect);
|
||||
|
||||
mutex.acquire();
|
||||
WorldSession *ws = instance->GetWSession();
|
||||
if(ws)
|
||||
{
|
||||
SCPDatabase *racedb = instance->dbmgr.GetDB("race");
|
||||
uint32 ffaction = racedb->GetFieldId("faction");
|
||||
for(uint32 i = 0; i < ws->GetCharsCount(); i++)
|
||||
{
|
||||
@ -236,7 +63,7 @@ void SceneCharSelection::OnResize(void)
|
||||
entry += L", ";
|
||||
entry += L"Level ";
|
||||
entry += c.p._level;
|
||||
entry += "L ";
|
||||
entry += L" ";
|
||||
entry += c.race.c_str();
|
||||
entry += L" ";
|
||||
entry += c.class_.c_str();
|
||||
@ -262,6 +89,265 @@ void SceneCharSelection::OnResize(void)
|
||||
}
|
||||
}
|
||||
mutex.release();
|
||||
|
||||
if(soundengine)
|
||||
{
|
||||
ISoundSource *main_theme = soundengine->getSoundSource("data/misc/main_theme.ogg");
|
||||
if(main_theme && !soundengine->isCurrentlyPlaying(main_theme))
|
||||
{
|
||||
soundengine->play2D(main_theme,true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SceneCharSelection::OnUpdate(s32 timepassed)
|
||||
{
|
||||
// treat doubleclick on listboxes as OK button click
|
||||
if(eventrecv->HasGUIEvent())
|
||||
{
|
||||
SEvent::SGUIEvent& ev = eventrecv->NextGUIEvent();
|
||||
if(ev.EventType == EGET_LISTBOX_SELECTED_AGAIN)
|
||||
{
|
||||
if(ev.Caller == realmlistbox)
|
||||
{
|
||||
eventrecv->buttons |= BUTTON_REALMWIN_OK;
|
||||
}
|
||||
else if(ev.Caller == charlistbox)
|
||||
{
|
||||
eventrecv->buttons |= BUTTON_ENTER_WORLD;
|
||||
}
|
||||
}
|
||||
if(ev.EventType == EGET_ELEMENT_CLOSED)
|
||||
{
|
||||
if(ev.Caller == realmwin)//realmwin got closed via the close button, remove pointer
|
||||
{
|
||||
realmwin = NULL;
|
||||
}
|
||||
if(ev.Caller == newcharwin)//got closed via the close button, remove pointer
|
||||
{
|
||||
newcharwin = NULL;
|
||||
}
|
||||
}
|
||||
if(ev.EventType == EGET_COMBO_BOX_CHANGED)
|
||||
{
|
||||
if(ev.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<<i)//if class is in classmask, put it into the list
|
||||
{
|
||||
core::stringw name = classdb->GetString(i,class_name);
|
||||
classmap[classselect->addItem(name.c_str())]=i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(eventrecv->buttons & BUTTON_ENTER_WORLD && !realmwin && !newcharwin)
|
||||
{
|
||||
logdebug("GUI: SceneCharSelect: Entering world");
|
||||
WorldSession *ws = instance->GetWSession();
|
||||
if(ws)
|
||||
{
|
||||
u32 selected = charlistbox->getSelected();
|
||||
if(selected < ws->GetCharsCount())
|
||||
{
|
||||
ws->EnterWorldWithCharacter(ws->GetCharFromList(selected).p._name);
|
||||
}
|
||||
else
|
||||
logerror("Character selection out of bounds! (%u)",selected);
|
||||
}
|
||||
else
|
||||
logerror("GUI: BUTTON_ENTER_ WORLD pressed, but no WorldSession exists!");
|
||||
}
|
||||
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);
|
||||
// disconnect from realm server if connected
|
||||
if(RealmSession *rs = instance->GetRSession())
|
||||
rs->SetMustDie();
|
||||
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)
|
||||
{
|
||||
dimension2d<s32> dim;
|
||||
rect<s32> 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 transform <dim> 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++)
|
||||
{
|
||||
if(racedb->GetUint32(i,race_classmask)) //If the race has a classmask, it is playable
|
||||
{
|
||||
core::stringw name = racedb->GetString(i,race_name);
|
||||
racemap[raceselect->addItem(name.c_str())] = i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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!");
|
||||
}
|
||||
if(eventrecv->buttons & BUTTON_SELECT_REALM || scenedata[ISCENE_CHARSEL_REALMFIRST])
|
||||
{
|
||||
scenedata[ISCENE_CHARSEL_REALMFIRST] = 0;
|
||||
if(instance->GetRSession())
|
||||
{
|
||||
dimension2d<s32> dim;
|
||||
rect<s32> pos;
|
||||
realmwin = guienv->addWindow(CalcRelativeScreenPos(driver, 0.2f, 0.2f, 0.6f, 0.6f), true,
|
||||
GetStringFromDB(ISCENE_CHARSEL_LABELS, DSCENE_CHARSEL_LABEL_REALMWIN).c_str());
|
||||
pos = realmwin->getAbsolutePosition(); // get absolute position and transform <dim> to absolute in-window position
|
||||
dim.Width = pos.LowerRightCorner.X - pos.UpperLeftCorner.X;
|
||||
dim.Height = pos.LowerRightCorner.Y - pos.UpperLeftCorner.Y;
|
||||
realmwin->addChild(guienv->addButton(CalcRelativeScreenPos(dim, 0.7f, 0.93f, 0.12f, 0.05f), realmwin, BUTTON_REALMWIN_OK,
|
||||
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++)
|
||||
{
|
||||
SRealmInfo& r = rs->GetRealm(i);
|
||||
core::stringw entry;
|
||||
entry += r.name.c_str();
|
||||
entry += L", ";
|
||||
switch(r.icon) // icon means here RealmType
|
||||
{
|
||||
case 0: entry += "Normal"; break;
|
||||
case 1: entry += "PvP"; break;
|
||||
case 4: entry += "Normal(4)"; break;
|
||||
case 6: entry += "RP"; break;
|
||||
case 8: entry += "RP-PvP"; break;
|
||||
case 16: entry += "FFA-PvP"; break; // MaNGOS custom realm type
|
||||
default: entry += "Unknown"; break;
|
||||
}
|
||||
entry += L", (";
|
||||
entry += r.chars_here;
|
||||
entry += L") Chars";
|
||||
entry += L" [";
|
||||
entry += r.addr_port.c_str();
|
||||
entry += L"]";
|
||||
realmlistbox->addItem(entry.c_str(), -1);
|
||||
SColor col;
|
||||
switch(r.color)
|
||||
{
|
||||
case 0: col.set(0xFF, 0x00, 0xFF, 0x00); break;
|
||||
case 1: col.set(0xFF, 0xFF, 0x00, 0x00); break;
|
||||
case 2: col.set(0xFF, 0x7F, 0x7F, 0x7F); break;
|
||||
case 3: col.set(0xFF, 0xB0, 0xB0, 0x00); break;
|
||||
default: col.set(0xFFFFFFFF);
|
||||
}
|
||||
realmlistbox->setItemOverrideColor(i,EGUI_LBC_TEXT,col);
|
||||
realmlistbox->setItemOverrideColor(i,EGUI_LBC_TEXT_HIGHLIGHT,col);
|
||||
}
|
||||
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 && realmwin)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
if(eventrecv->buttons & BUTTON_NEWCHARWIN_OK && newcharwin)
|
||||
{
|
||||
core::stringc tmp=charname->getText();
|
||||
u8 race = racemap[raceselect->getSelected()];
|
||||
u8 cclass = classmap[classselect->getSelected()];
|
||||
log("Creating character Race %i Class %i Name %s",race,cclass,tmp.c_str());
|
||||
if(tmp.size() && race && cclass)
|
||||
{
|
||||
WorldSession *ws=instance->GetWSession();
|
||||
if(ws)
|
||||
{
|
||||
WorldPacket packet(CMSG_CHAR_CREATE,(tmp.size()+1)+1+1+1+1+1+1+1+1+1);
|
||||
packet<<tmp.c_str();
|
||||
// name, race, class, gender, skin, face, hairstyle, haircolor, facialhair, outfitID
|
||||
packet << race << cclass <<(u8)0 <<(u8)0 <<(u8)0 <<(u8)0 <<(u8)0 <<(u8)0 <<(u8)0;
|
||||
ws->AddSendWorldPacket(packet);
|
||||
eventrecv->buttons |= BUTTON_NEWCHARWIN_CANCEL; // easiest way to close the window without much additional code
|
||||
}
|
||||
else
|
||||
logerror("Trying to create new Character, but no WorldSession exists.");
|
||||
}
|
||||
else
|
||||
logerror("Race, Class or Name not set!");
|
||||
}
|
||||
|
||||
// realmlist window
|
||||
|
||||
if(eventrecv->buttons & BUTTON_REALMWIN_CANCEL && realmwin)
|
||||
{
|
||||
realmwin->remove();
|
||||
realmwin=NULL;
|
||||
}
|
||||
|
||||
// new character window
|
||||
if(eventrecv->buttons & BUTTON_NEWCHARWIN_CANCEL && newcharwin)
|
||||
{
|
||||
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
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -62,11 +62,14 @@ enum SceneCharSelectButtons
|
||||
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,
|
||||
};
|
||||
|
||||
|
||||
|
||||
@ -577,17 +577,19 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
|
||||
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 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
|
||||
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 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
|
||||
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())
|
||||
|
||||
@ -427,6 +427,16 @@ static const char *GameObjectDisplayInfoFormat = {
|
||||
};
|
||||
|
||||
|
||||
// GameObjectDisplayInfo
|
||||
|
||||
enum ChrBaseInfoEnum
|
||||
{
|
||||
CBI_RACE = 0,
|
||||
CBI_CLASS = 1,
|
||||
CBI_END = 2
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@ -187,6 +187,14 @@ std::string AutoGetDataString(DBCFile::Iterator& it, const char* format, uint32
|
||||
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 @@ void OutMD5(char *path, MD5FileMap& fm)
|
||||
bool ConvertDBC(void)
|
||||
{
|
||||
std::map<uint8,std::string> racemap; // needed to extract other dbc files correctly
|
||||
std::map<uint8,uint32> 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 @@ bool ConvertDBC(void)
|
||||
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<<cclass;
|
||||
|
||||
}
|
||||
|
||||
printf("races..");
|
||||
for(DBCFile::Iterator it = ChrRaces.begin(); it != ChrRaces.end(); ++it)
|
||||
{
|
||||
uint32 id = (*it).getUInt(CHRRACES_RACEID);
|
||||
@ -292,6 +311,9 @@ bool ConvertDBC(void)
|
||||
RaceDataStorage[id].push_back(std::string(ChrRacesFieldNames[field]).append("=").append(value));
|
||||
}
|
||||
}
|
||||
std::stringstream temp;
|
||||
temp << classmask[id];
|
||||
RaceDataStorage[id].push_back(std::string("classmask").append("=").append(temp.str()));
|
||||
}
|
||||
|
||||
printf("emotes..");
|
||||
@ -562,7 +584,6 @@ bool ConvertDBC(void)
|
||||
}
|
||||
|
||||
|
||||
|
||||
//...
|
||||
printf("DONE!\n");
|
||||
//...
|
||||
|
||||
@ -76,7 +76,8 @@ bool DBCFile::openmem(ByteBuffer bb)
|
||||
|
||||
if(fieldCount*4 != recordSize)
|
||||
{
|
||||
return false;
|
||||
printf("DBCFile::openmem():Nonstandard record size\n");
|
||||
// return false;//records in CharBaseData are 2*1byte
|
||||
}
|
||||
|
||||
data = new unsigned char[recordSize*recordCount+stringSize];
|
||||
|
||||
@ -54,6 +54,11 @@ public:
|
||||
assert(field < file.fieldCount);
|
||||
return *reinterpret_cast<int*>(offset+field*4);
|
||||
}
|
||||
unsigned char getUChar(size_t field) const
|
||||
{
|
||||
assert(field < file.fieldCount);
|
||||
return *reinterpret_cast<unsigned char*>(offset+field);
|
||||
}
|
||||
const char *getString(size_t field) const
|
||||
{
|
||||
assert(field < file.fieldCount);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user