* implemented realm and character selection from the GUI
* added support for map tile sound emitters (MCSE-chunks) (needs more debugging) * added MasterSoundVolume=0..1 conf option to /conf/gui.conf * fixed window resize & added related functions to the scenes (OnResize()). TODO: fix SceneLogin resize. * implemented "Community Site" button functionality on Win32 * misc stuff * TODO: fix crypt error on realm change. * moved linux configure.ac script to PseuWoW root dir instead of /src
This commit is contained in:
parent
4ee4f6f5d4
commit
d7d36c544e
@ -8,7 +8,7 @@
|
|||||||
// 3: OpenGL
|
// 3: OpenGL
|
||||||
// 4: DirectX 8.1
|
// 4: DirectX 8.1
|
||||||
// 5: DirectX 9.0c
|
// 5: DirectX 9.0c
|
||||||
driver=5
|
driver=3
|
||||||
|
|
||||||
// resolution and more
|
// resolution and more
|
||||||
resx=1024
|
resx=1024
|
||||||
@ -28,6 +28,12 @@ depth=32
|
|||||||
// 0: No (default)
|
// 0: No (default)
|
||||||
UseSound=1
|
UseSound=1
|
||||||
|
|
||||||
|
// Master Sound Volume. Multiplier that affects all sounds that are played
|
||||||
|
// 1.0 - max volume
|
||||||
|
// 0.5 - half sound volume
|
||||||
|
// 0 - silent
|
||||||
|
MasterSoundVolume=1.0
|
||||||
|
|
||||||
|
|
||||||
//================================================================================================
|
//================================================================================================
|
||||||
// Expert options: Renderer finetuning
|
// Expert options: Renderer finetuning
|
||||||
|
|||||||
14
bin/data/scp/gui_charselect_text.scp
Normal file
14
bin/data/scp/gui_charselect_text.scp
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#dbname=gui_charselect_text
|
||||||
|
|
||||||
|
[1]
|
||||||
|
0=Enter World
|
||||||
|
1=New Character
|
||||||
|
2=Delete Character
|
||||||
|
3=Change Realm
|
||||||
|
4=Back
|
||||||
|
5=OK
|
||||||
|
6=Cancel
|
||||||
|
|
||||||
|
[2]
|
||||||
|
0=Realmlist
|
||||||
|
|
||||||
@ -23,3 +23,13 @@
|
|||||||
0=Oh noes!
|
0=Oh noes!
|
||||||
1=You have to enter account name and password!
|
1=You have to enter account name and password!
|
||||||
|
|
||||||
|
// the text box labels
|
||||||
|
[3]
|
||||||
|
0=Account:
|
||||||
|
1=Password:
|
||||||
|
|
||||||
|
// the buttons
|
||||||
|
[4]
|
||||||
|
0=Login
|
||||||
|
1=Quit
|
||||||
|
2=Community Site
|
||||||
|
|||||||
@ -4,10 +4,10 @@ if ?{not ?{IsHooked _startup}}
|
|||||||
HookAdd db_loader_load_all
|
HookAdd db_loader_load_all
|
||||||
HookEnd
|
HookEnd
|
||||||
|
|
||||||
// set up paths; ./data/scp and ./cache are set in the core already
|
// Set up paths; ./data/scp and ./cache are set in the core already.
|
||||||
// the SCP files placed in this directory are used to override some values
|
// The SCP files placed in this directory are used to override some values
|
||||||
// in already present SCP files or to add custom fields or content
|
// in already present SCP files or to add custom fields or content.
|
||||||
// note: it DOES matter in which order paths are added!!
|
// Note: it DOES matter in which order paths are added!!
|
||||||
AddDBPath ./data/scp-patches
|
AddDBPath ./data/scp-patches
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -29,11 +29,12 @@ LoadDB creaturemodeldata
|
|||||||
LoadDB gameobjectdisplayinfo
|
LoadDB gameobjectdisplayinfo
|
||||||
// LoadDB itemdisplayinfo // not yet used
|
// LoadDB itemdisplayinfo // not yet used
|
||||||
// LoadDB charsections // not yet used
|
// LoadDB charsections // not yet used
|
||||||
// LoadDB sound // not yet used
|
LoadDB sound
|
||||||
// LoadDB npcsound // not yet used
|
// LoadDB npcsound // not yet used
|
||||||
|
|
||||||
// GUI related databases
|
// GUI related databases
|
||||||
LoadDB gui_login_text
|
LoadDB gui_login_text
|
||||||
|
LoadDB gui_charselect_text
|
||||||
|
|
||||||
|
|
||||||
log ** Databases loaded.
|
log ** Databases loaded.
|
||||||
|
|||||||
@ -4,8 +4,8 @@
|
|||||||
AC_PREREQ(2.61)
|
AC_PREREQ(2.61)
|
||||||
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
|
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
|
||||||
AM_INIT_AUTOMAKE(pseuwow, 0.1)
|
AM_INIT_AUTOMAKE(pseuwow, 0.1)
|
||||||
#AC_CONFIG_SRCDIR([shared/ProgressBar.h])
|
#AC_CONFIG_SRCDIR([src/shared/ProgressBar.h])
|
||||||
AM_CONFIG_HEADER([config.h])
|
AM_CONFIG_HEADER([src/config.h])
|
||||||
|
|
||||||
# Checks for programs.
|
# Checks for programs.
|
||||||
AC_PROG_CXX
|
AC_PROG_CXX
|
||||||
@ -58,18 +58,18 @@ AC_FUNC_UTIME_NULL
|
|||||||
AC_FUNC_VPRINTF
|
AC_FUNC_VPRINTF
|
||||||
AC_CHECK_FUNCS([floor ftime ftruncate getcwd gethostbyaddr gethostbyname gethostname gettimeofday memmove memset mkdir pow realpath select socket sqrt strerror strrchr strstr strtol strtoul uname utime])
|
AC_CHECK_FUNCS([floor ftime ftruncate getcwd gethostbyaddr gethostbyname gethostname gettimeofday memmove memset mkdir pow realpath select socket sqrt strerror strrchr strstr strtol strtoul uname utime])
|
||||||
|
|
||||||
#AC_CONFIG_FILES([dep/src/irrlicht/Makefile
|
#AC_CONFIG_FILES([src/dep/src/irrlicht/Makefile
|
||||||
# dep/src/zlib/Makefile
|
# src/dep/src/zlib/Makefile
|
||||||
# dep/src/zthread/Makefile])
|
# src/dep/src/zthread/Makefile])
|
||||||
#AC_CONFIG_SUBDIRS([dep/src/irrlicht/jpeglib
|
#AC_CONFIG_SUBDIRS([src/dep/src/irrlicht/jpeglib
|
||||||
# dep/src/irrlicht/libpng])
|
# src/dep/src/irrlicht/libpng])
|
||||||
AC_CONFIG_FILES([Makefile
|
AC_CONFIG_FILES([src/Makefile
|
||||||
shared/Makefile
|
src/shared/Makefile
|
||||||
shared/Auth/Makefile
|
src/shared/Auth/Makefile
|
||||||
shared/Network/Makefile
|
src/shared/Network/Makefile
|
||||||
Client/Makefile
|
src/Client/Makefile
|
||||||
Client/GUI/Makefile
|
src/Client/GUI/Makefile
|
||||||
Client/Realm/Makefile
|
src/Client/Realm/Makefile
|
||||||
Client/World/Makefile
|
src/Client/World/Makefile
|
||||||
Client/DefScript/Makefile])
|
src/Client/DefScript/Makefile])
|
||||||
AC_OUTPUT
|
AC_OUTPUT
|
||||||
@ -1019,6 +1019,18 @@ DefReturnResult DefScriptPackage::SCGui(CmdSet &Set)
|
|||||||
{
|
{
|
||||||
ins->GetGUI()->SetSceneState(SCENESTATE_LOGINSCREEN);
|
ins->GetGUI()->SetSceneState(SCENESTATE_LOGINSCREEN);
|
||||||
}
|
}
|
||||||
|
else if(ins->GetRSession() && !ins->GetWSession())
|
||||||
|
{
|
||||||
|
ins->GetGUI()->SetSceneState(SCENESTATE_REALMSELECT);
|
||||||
|
}
|
||||||
|
else if(ins->GetRSession() && ins->GetWSession())
|
||||||
|
{
|
||||||
|
ins->GetGUI()->SetSceneState(SCENESTATE_CHARSELECT);
|
||||||
|
}
|
||||||
|
/*else if(ins->GetWSession() && !ins->GetWSession()->InWorld())
|
||||||
|
{
|
||||||
|
ins->GetGUI()->SetSceneState(SCENESTATE_LOGINSCREEN);
|
||||||
|
}*/ // TODO: uncomment after implemented
|
||||||
else if(ins->GetWSession() && ins->GetWSession()->InWorld())
|
else if(ins->GetWSession() && ins->GetWSession()->InWorld())
|
||||||
{
|
{
|
||||||
ins->GetGUI()->SetSceneState(SCENESTATE_WORLD);
|
ins->GetGUI()->SetSceneState(SCENESTATE_WORLD);
|
||||||
|
|||||||
88
src/Client/GUI/GUIEventReceiver.h
Normal file
88
src/Client/GUI/GUIEventReceiver.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#ifndef GUIEVENTRECEIVER_H
|
||||||
|
#define GUIEVENTRECEIVER_H
|
||||||
|
|
||||||
|
|
||||||
|
class GUIEventReceiver : public IEventReceiver
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GUIEventReceiver()
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
else if(event.EventType == EET_KEY_INPUT_EVENT)
|
||||||
|
{
|
||||||
|
keyevent = event;
|
||||||
|
keyevent_proc = false;
|
||||||
|
}
|
||||||
|
else if(event.EventType == EET_MOUSE_INPUT_EVENT)
|
||||||
|
{
|
||||||
|
mouseevent = event;
|
||||||
|
mouseevent_proc = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool proc = false;
|
||||||
|
//GUI EVENT
|
||||||
|
if (event.EventType == EET_GUI_EVENT)
|
||||||
|
{
|
||||||
|
s32 id = event.GUIEvent.Caller->getID();
|
||||||
|
|
||||||
|
printf("event type %u ID %u\n",event.GUIEvent.EventType,id);
|
||||||
|
|
||||||
|
switch(event.GUIEvent.EventType)
|
||||||
|
{
|
||||||
|
case EGET_BUTTON_CLICKED:
|
||||||
|
buttons += id;
|
||||||
|
proc = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EGET_MESSAGEBOX_OK: // triggered on enter or ok button click
|
||||||
|
case EGET_MESSAGEBOX_CANCEL: // triggered on escape
|
||||||
|
react_to_keys = true; // popup is gone, main window can react to keys again
|
||||||
|
proc = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(customHandledEvents.find(event.GUIEvent.EventType) != customHandledEvents.end())
|
||||||
|
proc = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(react_to_keys && event.EventType == EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown)
|
||||||
|
{
|
||||||
|
std::map<u32,u32>::iterator it = keyToButtonMap.find(event.KeyInput.Key);
|
||||||
|
if( it != keyToButtonMap.end() )
|
||||||
|
{
|
||||||
|
buttons += it->second;
|
||||||
|
proc = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return proc;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool react_to_keys;
|
||||||
|
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;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@ -121,6 +121,7 @@ void PseuGUI::_Init(void)
|
|||||||
_smgr = _device->getSceneManager();
|
_smgr = _device->getSceneManager();
|
||||||
_guienv = _device->getGUIEnvironment();
|
_guienv = _device->getGUIEnvironment();
|
||||||
_timer = _device->getTimer();
|
_timer = _device->getTimer();
|
||||||
|
_screendimension = _driver->getScreenSize();
|
||||||
//...
|
//...
|
||||||
|
|
||||||
// disable crappy irrlicht logging
|
// disable crappy irrlicht logging
|
||||||
@ -139,7 +140,14 @@ void PseuGUI::_Init(void)
|
|||||||
{
|
{
|
||||||
_soundengine = createIrrKlangDevice();
|
_soundengine = createIrrKlangDevice();
|
||||||
if(_soundengine)
|
if(_soundengine)
|
||||||
|
{
|
||||||
logdetail("PseuGUI: Sound Driver: %s",_soundengine->getDriverName());
|
logdetail("PseuGUI: Sound Driver: %s",_soundengine->getDriverName());
|
||||||
|
_soundengine->setSoundVolume(GetInstance()->GetConf()->masterSoundVolume);
|
||||||
|
// accept only values between 0 and 1
|
||||||
|
if(_soundengine->getSoundVolume() < 0.0f || _soundengine->getSoundVolume() >= 1.0f)
|
||||||
|
_soundengine->setSoundVolume(1.0f);
|
||||||
|
logdetail("PseuGUI: Master Sound Volume: %.3f",_soundengine->getSoundVolume());
|
||||||
|
}
|
||||||
else
|
else
|
||||||
logerror("PseuGUI: Failed to initialize sound engine!");
|
logerror("PseuGUI: Failed to initialize sound engine!");
|
||||||
}
|
}
|
||||||
@ -194,7 +202,6 @@ void PseuGUI::Run(void)
|
|||||||
_lastpasstime = _passtime;
|
_lastpasstime = _passtime;
|
||||||
_passtime = _timer->getTime();
|
_passtime = _timer->getTime();
|
||||||
_passtimediff = _passtime - _lastpasstime;
|
_passtimediff = _passtime - _lastpasstime;
|
||||||
// _HandleWindowResize(); // not yet used; doesnt work
|
|
||||||
|
|
||||||
if (!_device->isWindowActive())
|
if (!_device->isWindowActive())
|
||||||
{
|
{
|
||||||
@ -209,6 +216,18 @@ void PseuGUI::Run(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(_screendimension != _driver->getScreenSize())
|
||||||
|
{
|
||||||
|
_scene->OnResize();
|
||||||
|
_screendimension = _driver->getScreenSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_updateScene)
|
||||||
|
{
|
||||||
|
_updateScene = false;
|
||||||
|
_scene->OnManualUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
_scene->OnUpdate(_passtimediff); // custom: process input, set camera, etc
|
_scene->OnUpdate(_passtimediff); // custom: process input, set camera, etc
|
||||||
_driver->beginScene(true, true, _scene->GetBackgroundColor()); // irr: call driver to start drawing
|
_driver->beginScene(true, true, _scene->GetBackgroundColor()); // irr: call driver to start drawing
|
||||||
_scene->OnDrawBegin(); // custom: draw everything before irrlicht draws everything by itself
|
_scene->OnDrawBegin(); // custom: draw everything before irrlicht draws everything by itself
|
||||||
@ -295,6 +314,17 @@ void PseuGUI::_UpdateSceneState(void)
|
|||||||
case SCENESTATE_GUISTART: _scene = new SceneGuiStart(this); break;
|
case SCENESTATE_GUISTART: _scene = new SceneGuiStart(this); break;
|
||||||
case SCENESTATE_LOGINSCREEN: _scene = new SceneLogin(this); break;
|
case SCENESTATE_LOGINSCREEN: _scene = new SceneLogin(this); break;
|
||||||
case SCENESTATE_WORLD: _scene = new SceneWorld(this); break;
|
case SCENESTATE_WORLD: _scene = new SceneWorld(this); break;
|
||||||
|
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
|
default: _scene = new Scene(this); // will draw nothing, just yield the gui
|
||||||
}
|
}
|
||||||
_scene->SetState(_scenestate_new);
|
_scene->SetState(_scenestate_new);
|
||||||
@ -334,25 +364,3 @@ WorldPosition PseuGUI::GetWorldPosition(void)
|
|||||||
return WorldPosition();
|
return WorldPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PseuGUI::_HandleWindowResize(void)
|
|
||||||
{
|
|
||||||
dimension2d<s32> scrn = _driver->getScreenSize();
|
|
||||||
if(_screendimension.Width != scrn.Width)
|
|
||||||
{
|
|
||||||
scrn.Height = s32(scrn.Width * 0.8f); // for now use aspect ratio 5:4
|
|
||||||
_screendimension = scrn;
|
|
||||||
_driver->OnResize(scrn);
|
|
||||||
DEBUG(logdebug("DEBUG: Width resize handled, Height adjusted"));
|
|
||||||
|
|
||||||
}
|
|
||||||
else if(_screendimension.Height != scrn.Height)
|
|
||||||
{
|
|
||||||
scrn.Width = s32(scrn.Height * 1.25); // 5:4 here too
|
|
||||||
_screendimension = scrn;
|
|
||||||
_driver->OnResize(scrn);
|
|
||||||
DEBUG(logdebug("DEBUG: Height resize handled, Width adjusted"));
|
|
||||||
|
|
||||||
}
|
|
||||||
// TODO: how to set irrlicht window size ?!
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@ -17,7 +17,7 @@ enum SceneState
|
|||||||
SCENESTATE_NULL = 0,
|
SCENESTATE_NULL = 0,
|
||||||
SCENESTATE_GUISTART,
|
SCENESTATE_GUISTART,
|
||||||
SCENESTATE_LOGINSCREEN,
|
SCENESTATE_LOGINSCREEN,
|
||||||
SCENESTATE_REALMSELECT,
|
SCENESTATE_REALMSELECT, // actually both realm and char select will call the same scene, but with slightly different data
|
||||||
SCENESTATE_CHARSELECT,
|
SCENESTATE_CHARSELECT,
|
||||||
SCENESTATE_LOADING,
|
SCENESTATE_LOADING,
|
||||||
SCENESTATE_WORLD,
|
SCENESTATE_WORLD,
|
||||||
@ -73,6 +73,7 @@ class PseuGUI
|
|||||||
friend class SceneWorld;
|
friend class SceneWorld;
|
||||||
friend class SceneGuiStart;
|
friend class SceneGuiStart;
|
||||||
friend class SceneLogin;
|
friend class SceneLogin;
|
||||||
|
friend class SceneCharSelection;
|
||||||
// ...
|
// ...
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -103,6 +104,7 @@ public:
|
|||||||
void SetSceneState(SceneState);
|
void SetSceneState(SceneState);
|
||||||
bool SetSceneData(uint32, uint32);
|
bool SetSceneData(uint32, uint32);
|
||||||
uint32 GetSceneState(void);
|
uint32 GetSceneState(void);
|
||||||
|
inline void UpdateScene(void) { _updateScene = true; }
|
||||||
|
|
||||||
// helpers
|
// helpers
|
||||||
WorldPosition GetWorldPosition(void);
|
WorldPosition GetWorldPosition(void);
|
||||||
@ -110,7 +112,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
void _Init(void);
|
void _Init(void);
|
||||||
void _UpdateSceneState(void);
|
void _UpdateSceneState(void);
|
||||||
void _HandleWindowResize(void);
|
|
||||||
uint16 _xres,_yres,_colordepth;
|
uint16 _xres,_yres,_colordepth;
|
||||||
bool _windowed,_vsync,_shadows;
|
bool _windowed,_vsync,_shadows;
|
||||||
bool _initialized,_mustdie;
|
bool _initialized,_mustdie;
|
||||||
@ -129,6 +130,7 @@ private:
|
|||||||
uint32 _passtime, _lastpasstime, _passtimediff;
|
uint32 _passtime, _lastpasstime, _passtimediff;
|
||||||
irr::core::dimension2d<irr::s32> _screendimension;
|
irr::core::dimension2d<irr::s32> _screendimension;
|
||||||
uint32 _throttle;//used for frameratelimiting
|
uint32 _throttle;//used for frameratelimiting
|
||||||
|
bool _updateScene; // manually update scene?
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -14,6 +14,7 @@ Scene::Scene(PseuGUI *g)
|
|||||||
driver = gui->_driver;
|
driver = gui->_driver;
|
||||||
smgr = gui->_smgr;
|
smgr = gui->_smgr;
|
||||||
guienv = gui->_guienv;
|
guienv = gui->_guienv;
|
||||||
|
rootgui = guienv->getRootGUIElement();
|
||||||
cursor = new CCursorController(device->getCursorControl(), driver);
|
cursor = new CCursorController(device->getCursorControl(), driver);
|
||||||
cursor->setOSCursorVisible(true);
|
cursor->setOSCursorVisible(true);
|
||||||
cursor->setVisible(false);
|
cursor->setVisible(false);
|
||||||
@ -35,6 +36,15 @@ void Scene::OnUpdate(s32)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Scene::OnManualUpdate(void)
|
||||||
|
{
|
||||||
|
OnResize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Scene::OnResize(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
void Scene::OnDrawBegin(void)
|
void Scene::OnDrawBegin(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,8 +13,24 @@ using namespace gui;
|
|||||||
using namespace irrklang;
|
using namespace irrklang;
|
||||||
|
|
||||||
|
|
||||||
|
inline core::rect<s32> CalcRelativeScreenPos(core::dimension2d<s32> dim, f32 x, f32 y, f32 w, f32 h)
|
||||||
|
{
|
||||||
|
core::rect<s32> r;
|
||||||
|
r.UpperLeftCorner.X = dim.Width * x;
|
||||||
|
r.UpperLeftCorner.Y = dim.Height* y;
|
||||||
|
r.LowerRightCorner.X = r.UpperLeftCorner.X + (dim.Width * w);
|
||||||
|
r.LowerRightCorner.Y = r.UpperLeftCorner.Y + (dim.Height * h);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline core::rect<s32> CalcRelativeScreenPos(video::IVideoDriver* drv, f32 x, f32 y, f32 w, f32 h)
|
||||||
|
{
|
||||||
|
return CalcRelativeScreenPos(drv->getScreenSize(),x,y,w,h);
|
||||||
|
}
|
||||||
|
|
||||||
class PseuGUI;
|
class PseuGUI;
|
||||||
class CCursorController;
|
class CCursorController;
|
||||||
|
class GUIEventReceiver;
|
||||||
|
|
||||||
// base class
|
// base class
|
||||||
class Scene
|
class Scene
|
||||||
@ -27,11 +43,14 @@ public:
|
|||||||
inline void SetState(SceneState sc) { _scenestate = sc; }
|
inline void SetState(SceneState sc) { _scenestate = sc; }
|
||||||
inline SceneState GetState(void) { return _scenestate; }
|
inline SceneState GetState(void) { return _scenestate; }
|
||||||
virtual void OnUpdate(s32);
|
virtual void OnUpdate(s32);
|
||||||
|
virtual void OnManualUpdate(void);
|
||||||
virtual void OnDraw(void);
|
virtual void OnDraw(void);
|
||||||
virtual void OnDrawBegin(void);
|
virtual void OnDrawBegin(void);
|
||||||
virtual void OnDelete(void);
|
virtual void OnDelete(void);
|
||||||
|
virtual void OnResize(void);
|
||||||
virtual video::SColor GetBackgroundColor(void);
|
virtual video::SColor GetBackgroundColor(void);
|
||||||
virtual void SetData(uint32 index, uint32 value) { scenedata[index] = value; }
|
virtual void SetData(uint32 index, uint32 value) { scenedata[index] = value; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PseuInstance *instance;
|
PseuInstance *instance;
|
||||||
PseuGUI *gui;
|
PseuGUI *gui;
|
||||||
@ -39,6 +58,7 @@ protected:
|
|||||||
irr::video::IVideoDriver* driver;
|
irr::video::IVideoDriver* driver;
|
||||||
irr::scene::ISceneManager* smgr;
|
irr::scene::ISceneManager* smgr;
|
||||||
irr::gui::IGUIEnvironment* guienv;
|
irr::gui::IGUIEnvironment* guienv;
|
||||||
|
irr::gui::IGUIElement* rootgui;
|
||||||
irrklang::ISoundEngine *soundengine;
|
irrklang::ISoundEngine *soundengine;
|
||||||
CCursorController *cursor;
|
CCursorController *cursor;
|
||||||
SceneState _scenestate;
|
SceneState _scenestate;
|
||||||
@ -56,8 +76,6 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class GUIEventReceiver;
|
|
||||||
|
|
||||||
class SceneLogin : public Scene
|
class SceneLogin : public Scene
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -66,14 +84,33 @@ public:
|
|||||||
void OnDelete(void);
|
void OnDelete(void);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
gui::IGUIElement* root;
|
|
||||||
IGUIImage *irrlogo, *background;
|
IGUIImage *irrlogo, *background;
|
||||||
GUIEventReceiver *eventrecv;
|
GUIEventReceiver *eventrecv;
|
||||||
PseuGUI* _gui;
|
|
||||||
gui::IGUIElement *msgbox;
|
gui::IGUIElement *msgbox;
|
||||||
|
gui::IGUIWindow *popup;
|
||||||
uint32 msgbox_textid;
|
uint32 msgbox_textid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CharSelectGUIEventReceiver;
|
||||||
|
|
||||||
|
class SceneCharSelection : public Scene
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SceneCharSelection(PseuGUI *gui);
|
||||||
|
void OnUpdate(s32);
|
||||||
|
void OnDelete(void);
|
||||||
|
void OnResize(void);
|
||||||
|
|
||||||
|
private:
|
||||||
|
GUIEventReceiver *eventrecv;
|
||||||
|
IGUIWindow *realmwin;
|
||||||
|
IGUIListBox *realmlistbox;
|
||||||
|
IGUIListBox *charlistbox; // temporary until something better found
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ShTlTerrainSceneNode;
|
class ShTlTerrainSceneNode;
|
||||||
class MCameraFPS;
|
class MCameraFPS;
|
||||||
class MCameraOrbit;
|
class MCameraOrbit;
|
||||||
@ -101,7 +138,7 @@ public:
|
|||||||
void InitTerrain(void);
|
void InitTerrain(void);
|
||||||
void RelocateCamera(void);
|
void RelocateCamera(void);
|
||||||
void RelocateCameraBehindChar(void);
|
void RelocateCameraBehindChar(void);
|
||||||
void UpdateDoodads(void);
|
void UpdateMapSceneNodes(std::map<uint32,SceneNodeWithGridPos>&);
|
||||||
scene::ISceneNode *GetMyCharacterSceneNode(void);
|
scene::ISceneNode *GetMyCharacterSceneNode(void);
|
||||||
video::SColor GetBackgroundColor(void);
|
video::SColor GetBackgroundColor(void);
|
||||||
|
|
||||||
@ -112,7 +149,6 @@ private:
|
|||||||
MCameraFPS *camera;
|
MCameraFPS *camera;
|
||||||
MyEventReceiver *eventrecv;
|
MyEventReceiver *eventrecv;
|
||||||
ZThread::FastMutex mutex;
|
ZThread::FastMutex mutex;
|
||||||
PseuGUI *gui;
|
|
||||||
uint32 map_gridX, map_gridY;
|
uint32 map_gridX, map_gridY;
|
||||||
WorldSession *wsession;
|
WorldSession *wsession;
|
||||||
World *world;
|
World *world;
|
||||||
@ -120,6 +156,7 @@ private:
|
|||||||
IGUIStaticText *debugText;
|
IGUIStaticText *debugText;
|
||||||
bool debugmode;
|
bool debugmode;
|
||||||
std::map<uint32,SceneNodeWithGridPos> _doodads;
|
std::map<uint32,SceneNodeWithGridPos> _doodads;
|
||||||
|
std::map<uint32,SceneNodeWithGridPos> _sound_emitters;
|
||||||
scene::ISceneNode *sky;
|
scene::ISceneNode *sky;
|
||||||
scene::ISceneNode *selectedNode, *oldSelectedNode, *focusedNode, *oldFocusedNode;
|
scene::ISceneNode *selectedNode, *oldSelectedNode, *focusedNode, *oldFocusedNode;
|
||||||
video::SColor envBasicColor;
|
video::SColor envBasicColor;
|
||||||
|
|||||||
259
src/Client/GUI/SceneCharselection.cpp
Normal file
259
src/Client/GUI/SceneCharselection.cpp
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
#include "common.h"
|
||||||
|
#include "PseuGUI.h"
|
||||||
|
#include "PseuWoW.h"
|
||||||
|
#include "Scene.h"
|
||||||
|
#include "GUIEventReceiver.h"
|
||||||
|
#include "RealmSession.h"
|
||||||
|
#include "WorldSession.h"
|
||||||
|
|
||||||
|
enum GuiElementID
|
||||||
|
{
|
||||||
|
BUTTON_ENTER_WORLD = 0x1,
|
||||||
|
BUTTON_BACK = 0x2,
|
||||||
|
BUTTON_NEW_CHARACTER = 0x4,
|
||||||
|
BUTTON_DELETE_CHARACTER = 0x8,
|
||||||
|
BUTTON_SELECT_REALM = 0x10,
|
||||||
|
BUTTON_REALMWIN_OK = 0x20,
|
||||||
|
BUTTON_REALMWIN_CANCEL = 0x40,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
SceneCharSelection::SceneCharSelection(PseuGUI *gui) : Scene(gui)
|
||||||
|
{
|
||||||
|
textdb = instance->dbmgr.GetDB("gui_charselect_text");
|
||||||
|
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->customHandledEvents.insert(EGET_LISTBOX_SELECTED_AGAIN);
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// treat doubleclick on realmlist as OK button click
|
||||||
|
if(!eventrecv->guievent_proc)
|
||||||
|
{
|
||||||
|
eventrecv->guievent_proc = true;
|
||||||
|
if(eventrecv->guievent.GUIEvent.EventType == EGET_LISTBOX_SELECTED_AGAIN && eventrecv->guievent.GUIEvent.Caller == realmlistbox)
|
||||||
|
{
|
||||||
|
eventrecv->buttons |= BUTTON_REALMWIN_OK;
|
||||||
|
}
|
||||||
|
//...
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
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;
|
||||||
|
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);
|
||||||
|
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++)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
#ifndef SCENEDATA_H
|
#ifndef SCENEDATA_H
|
||||||
#define SCENEDATA_H
|
#define SCENEDATA_H
|
||||||
|
|
||||||
#define SCENEDATA_SIZE 255
|
#define SCENEDATA_SIZE 256
|
||||||
|
|
||||||
// I: index, enums should start with 1
|
// I: index, enums should start with 1
|
||||||
// D: data value
|
// D: data value
|
||||||
@ -10,8 +10,10 @@
|
|||||||
enum SceneLoginDataIndexes
|
enum SceneLoginDataIndexes
|
||||||
{
|
{
|
||||||
ISCENE_LOGIN_CONN_STATUS = 1,
|
ISCENE_LOGIN_CONN_STATUS = 1,
|
||||||
ISCENE_LOGIN_MSGBOX_DUMMY = 2,
|
ISCENE_LOGIN_MSGBOX_DUMMY = 2, // text
|
||||||
ISCENE_LOGIN_END = 3
|
ISCENE_LOGIN_LABELS = 3, // text
|
||||||
|
ISCENE_LOGIN_BUTTONS = 4, // text
|
||||||
|
ISCENE_LOGIN_END
|
||||||
};
|
};
|
||||||
|
|
||||||
enum SceneLoginConnStatus
|
enum SceneLoginConnStatus
|
||||||
@ -29,6 +31,44 @@ enum SceneLoginConnStatus
|
|||||||
DSCENE_LOGIN_UNK_ERROR = 10,
|
DSCENE_LOGIN_UNK_ERROR = 10,
|
||||||
DSCENE_LOGIN_FILE_TRANSFER = 11,
|
DSCENE_LOGIN_FILE_TRANSFER = 11,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SceneLoginLabels
|
||||||
|
{
|
||||||
|
DSCENE_LOGIN_LABEL_ACC = 0,
|
||||||
|
DSCENE_LOGIN_LABEL_PASS = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SceneLoginButtons
|
||||||
|
{
|
||||||
|
DSCENE_LOGIN_BUTTON_LOGIN = 0,
|
||||||
|
DSCENE_LOGIN_BUTTON_QUIT = 1,
|
||||||
|
DSCENE_LOGIN_BUTTON_SITE = 2,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SceneCharSelectDataIndexes
|
||||||
|
{
|
||||||
|
ISCENE_CHARSEL_BUTTONS = 1, // text
|
||||||
|
ISCENE_CHARSEL_LABELS = 2, // text
|
||||||
|
ISCENE_CHARSEL_REALMFIRST = 255, // flag that is set when connecting to a realm wasnt possible and the realm list must be shown first
|
||||||
|
ISCENE_CHARSEL_END
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SceneCharSelectButtons
|
||||||
|
{
|
||||||
|
DSCENE_CHARSEL_BUTTON_ENTERWORLD = 0,
|
||||||
|
DSCENE_CHARSEL_BUTTON_NEWCHAR = 1,
|
||||||
|
DSCENE_CHARSEL_BUTTON_DELCHAR = 2,
|
||||||
|
DSCENE_CHARSEL_BUTTON_CHANGEREALM = 3,
|
||||||
|
DSCENE_CHARSEL_BUTTON_BACK = 4,
|
||||||
|
DSCENE_CHARSEL_REALMWIN_OK = 5,
|
||||||
|
DSCENE_CHARSEL_REALMWIN_CANCEL = 6,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SceneCharSelectLabels
|
||||||
|
{
|
||||||
|
DSCENE_CHARSEL_LABEL_REALMWIN = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
#include "PseuWoW.h"
|
#include "PseuWoW.h"
|
||||||
#include "Scene.h"
|
#include "Scene.h"
|
||||||
#include "RealmSession.h"
|
#include "RealmSession.h"
|
||||||
|
#include "GUIEventReceiver.h"
|
||||||
|
|
||||||
enum GuiElementID
|
enum GuiElementID
|
||||||
{
|
{
|
||||||
@ -13,37 +14,6 @@ enum GuiElementID
|
|||||||
BUTTON_LOGON = 0x10,
|
BUTTON_LOGON = 0x10,
|
||||||
};
|
};
|
||||||
|
|
||||||
class GUIEventReceiver : public IEventReceiver
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
GUIEventReceiver()
|
|
||||||
{
|
|
||||||
buttons=0;
|
|
||||||
}
|
|
||||||
virtual bool OnEvent(const SEvent& event)
|
|
||||||
{
|
|
||||||
//GUI EVENT
|
|
||||||
if (event.EventType == EET_GUI_EVENT)
|
|
||||||
{
|
|
||||||
s32 id = event.GUIEvent.Caller->getID();
|
|
||||||
|
|
||||||
switch(event.GUIEvent.EventType)
|
|
||||||
{
|
|
||||||
case EGET_BUTTON_CLICKED:
|
|
||||||
logdebug("user clicked button %u",id);
|
|
||||||
buttons+=id;
|
|
||||||
return true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
u32 buttons;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//TODO: Reposition elements on resize
|
//TODO: Reposition elements on resize
|
||||||
//the code happens only ones, We need to, in the main loop ( usually while(driver->run()) ) set the
|
//the code happens only ones, We need to, in the main loop ( usually while(driver->run()) ) set the
|
||||||
//positions of each gui element based on the current screensize ( gotten with driver->getScreenSize(); )
|
//positions of each gui element based on the current screensize ( gotten with driver->getScreenSize(); )
|
||||||
@ -53,29 +23,39 @@ SceneLogin::SceneLogin(PseuGUI *gui) : Scene(gui)
|
|||||||
textdb = instance->dbmgr.GetDB("gui_login_text");
|
textdb = instance->dbmgr.GetDB("gui_login_text");
|
||||||
msgbox_textid = 0;
|
msgbox_textid = 0;
|
||||||
eventrecv = new GUIEventReceiver();
|
eventrecv = new GUIEventReceiver();
|
||||||
|
eventrecv->keyToButtonMap[KEY_RETURN] = BUTTON_LOGON;
|
||||||
|
eventrecv->keyToButtonMap[KEY_ESCAPE] = BUTTON_QUIT;
|
||||||
device->setEventReceiver(eventrecv);
|
device->setEventReceiver(eventrecv);
|
||||||
root = guienv->getRootGUIElement();
|
|
||||||
|
|
||||||
dimension2d<s32> scrn = driver->getScreenSize();
|
dimension2d<s32> scrn = driver->getScreenSize();
|
||||||
|
|
||||||
irrlogo = guienv->addImage(driver->getTexture("data/misc/irrlichtlogo.png"), core::position2d<s32>(5,5),true,root);
|
irrlogo = guienv->addImage(driver->getTexture("data/misc/irrlichtlogo.png"), core::position2d<s32>(5,5),true,rootgui);
|
||||||
background = guienv->addImage(driver->getTexture("data/misc/sky.jpg"), core::position2d<s32>(5,5),true,root);
|
background = guienv->addImage(driver->getTexture("data/misc/sky.jpg"), core::position2d<s32>(5,5),true,rootgui);
|
||||||
background->setRelativePosition(rect<s32>(0,0,scrn.Width,scrn.Height));
|
background->setRelativePosition(rect<s32>(0,0,scrn.Width,scrn.Height));
|
||||||
irrlogo->setScaleImage(true);
|
irrlogo->setScaleImage(true);
|
||||||
|
|
||||||
guienv->addStaticText(L"Account:",rect<s32>((scrn.Width*0.5f)-90, (scrn.Height*0.3f)-10, (scrn.Width*0.5f)+90, (scrn.Height*0.3f)+10), false, false, 0, 0);
|
core::stringw accn;
|
||||||
guienv->addStaticText(L"Password:", rect<s32>((scrn.Width*0.5f)-90, (scrn.Height*0.3f)+50, (scrn.Width*0.5f)+90, (scrn.Height*0.3f)+70), false, false, 0, 0);
|
accn += instance->GetConf()->accname.c_str();
|
||||||
guienv->addEditBox(L"", rect<s32>((scrn.Width*0.5f)-90, (scrn.Height*0.3f)+10, (scrn.Width*0.5f)+90, (scrn.Height*0.3f)+30), true, 0, 1);
|
|
||||||
|
guienv->addStaticText(GetStringFromDB(ISCENE_LOGIN_LABELS,DSCENE_LOGIN_LABEL_ACC).c_str(),rect<s32>((scrn.Width*0.5f)-90, (scrn.Height*0.3f)-10, (scrn.Width*0.5f)+90, (scrn.Height*0.3f)+10), false, false, 0, 0);
|
||||||
|
guienv->addStaticText(GetStringFromDB(ISCENE_LOGIN_LABELS,DSCENE_LOGIN_LABEL_PASS).c_str(), rect<s32>((scrn.Width*0.5f)-90, (scrn.Height*0.3f)+50, (scrn.Width*0.5f)+90, (scrn.Height*0.3f)+70), false, false, 0, 0);
|
||||||
|
guienv->addEditBox(accn.c_str(), rect<s32>((scrn.Width*0.5f)-90, (scrn.Height*0.3f)+10, (scrn.Width*0.5f)+90, (scrn.Height*0.3f)+30), true, 0, 1);
|
||||||
guienv->addEditBox(L"", rect<s32>((scrn.Width*0.5f)-90, (scrn.Height*0.3f)+70, (scrn.Width*0.5f)+90, (scrn.Height*0.3f)+90), true, 0, 2)->setPasswordBox(true);
|
guienv->addEditBox(L"", rect<s32>((scrn.Width*0.5f)-90, (scrn.Height*0.3f)+70, (scrn.Width*0.5f)+90, (scrn.Height*0.3f)+90), true, 0, 2)->setPasswordBox(true);
|
||||||
guienv->addButton(rect<s32>(scrn.Width-120, scrn.Height-40, scrn.Width-10, scrn.Height-10), 0, 4, L"Quit");
|
guienv->addButton(rect<s32>(scrn.Width-120, scrn.Height-40, scrn.Width-10, scrn.Height-10), 0, 4, GetStringFromDB(ISCENE_LOGIN_BUTTONS,DSCENE_LOGIN_BUTTON_QUIT).c_str());
|
||||||
guienv->addButton(rect<s32>(10, scrn.Height-40, 120, scrn.Height-10), 0, 8, L"Community Site");
|
guienv->addButton(rect<s32>(10, scrn.Height-40, 120, scrn.Height-10), 0, 8, GetStringFromDB(ISCENE_LOGIN_BUTTONS,DSCENE_LOGIN_BUTTON_SITE).c_str());
|
||||||
guienv->addButton(rect<s32>((scrn.Width*0.5f)-60, (scrn.Height*0.3f)+100, (scrn.Width*0.5f)+60, (scrn.Height*0.3f)+130), 0, 16, L"Logon");
|
guienv->addButton(rect<s32>((scrn.Width*0.5f)-60, (scrn.Height*0.3f)+100, (scrn.Width*0.5f)+60, (scrn.Height*0.3f)+130), 0, 16, GetStringFromDB(ISCENE_LOGIN_BUTTONS,DSCENE_LOGIN_BUTTON_LOGIN).c_str());
|
||||||
msgbox = guienv->addStaticText(GetStringFromDB(ISCENE_LOGIN_CONN_STATUS,DSCENE_LOGIN_NOT_CONNECTED).c_str(),rect<s32>((scrn.Width*0.5f)-90, (scrn.Height*0.3f)+150, (scrn.Width*0.5f)+90, (scrn.Height*0.3f)+180),true,true);
|
msgbox = guienv->addStaticText(GetStringFromDB(ISCENE_LOGIN_CONN_STATUS,DSCENE_LOGIN_NOT_CONNECTED).c_str(),rect<s32>((scrn.Width*0.5f)-90, (scrn.Height*0.3f)+150, (scrn.Width*0.5f)+90, (scrn.Height*0.3f)+180),true,true);
|
||||||
|
|
||||||
if(soundengine)
|
if(soundengine)
|
||||||
{
|
{
|
||||||
soundengine->play2D("data/misc/main_theme.ogg",true);
|
ISoundSource *main_theme = soundengine->getSoundSource("data/misc/main_theme.ogg");
|
||||||
|
if(main_theme && !soundengine->isCurrentlyPlaying(main_theme))
|
||||||
|
{
|
||||||
|
soundengine->play2D(main_theme,true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
popup = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SceneLogin::OnUpdate(s32 timepassed)
|
void SceneLogin::OnUpdate(s32 timepassed)
|
||||||
@ -92,12 +72,11 @@ void SceneLogin::OnUpdate(s32 timepassed)
|
|||||||
}
|
}
|
||||||
if(eventrecv->buttons & BUTTON_LOGON)
|
if(eventrecv->buttons & BUTTON_LOGON)
|
||||||
{
|
{
|
||||||
eventrecv->buttons=0;
|
|
||||||
logdebug("Commencing Logon");
|
logdebug("Commencing Logon");
|
||||||
core::stringc tmp;
|
core::stringc tmp;
|
||||||
tmp=root->getElementFromId(TEXTBOX_NAME,true)->getText();
|
tmp=rootgui->getElementFromId(TEXTBOX_NAME,true)->getText();
|
||||||
std::string accname =tmp.c_str();
|
std::string accname =tmp.c_str();
|
||||||
tmp=root->getElementFromId(TEXTBOX_PASSWORD,true)->getText();
|
tmp=rootgui->getElementFromId(TEXTBOX_PASSWORD,true)->getText();
|
||||||
std::string accpass=tmp.c_str();
|
std::string accpass=tmp.c_str();
|
||||||
if(accname.size() && accpass.size())
|
if(accname.size() && accpass.size())
|
||||||
{
|
{
|
||||||
@ -106,14 +85,27 @@ void SceneLogin::OnUpdate(s32 timepassed)
|
|||||||
// we can safely override the conf settings
|
// we can safely override the conf settings
|
||||||
instance->GetConf()->accname = accname;
|
instance->GetConf()->accname = accname;
|
||||||
instance->GetConf()->accpass = accpass;
|
instance->GetConf()->accpass = accpass;
|
||||||
|
// ...but do not set the defscript vars; its just not safe
|
||||||
instance->CreateRealmSession();
|
instance->CreateRealmSession();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
guienv->addMessageBox(GetStringFromDB(ISCENE_LOGIN_MSGBOX_DUMMY,0).c_str(),
|
popup = guienv->addMessageBox(GetStringFromDB(ISCENE_LOGIN_MSGBOX_DUMMY,0).c_str(),
|
||||||
GetStringFromDB(ISCENE_LOGIN_MSGBOX_DUMMY,1).c_str());
|
GetStringFromDB(ISCENE_LOGIN_MSGBOX_DUMMY,1).c_str());
|
||||||
|
eventrecv->react_to_keys = false; // prevent main window from processing key input; it must be processed by the msgbox's event recv!
|
||||||
|
// our eventrecv will handle msgbox close event by itself and enable input again.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
if(eventrecv->buttons & BUTTON_COMMUNITY)
|
||||||
|
{
|
||||||
|
#if PLATFORM == PLATFORM_WIN32
|
||||||
|
ShellExecute(NULL, "open", "http://www.mangosclient.org", NULL, NULL, SW_SHOWNORMAL);
|
||||||
|
#elif PLATFORM == PLATFORM_UNIX
|
||||||
|
// linux code here
|
||||||
|
#elif PLATFORM == PLATFORM_APPLE
|
||||||
|
// mac code here
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
eventrecv->buttons = 0;
|
eventrecv->buttons = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@
|
|||||||
#include "CCursorController.h"
|
#include "CCursorController.h"
|
||||||
#include "MovementMgr.h"
|
#include "MovementMgr.h"
|
||||||
#include "DrawObject.h"
|
#include "DrawObject.h"
|
||||||
|
#include "irrKlangSceneNode.h"
|
||||||
|
|
||||||
// TODO: replace this by conf value
|
// TODO: replace this by conf value
|
||||||
#define MAX_CAM_DISTANCE 70
|
#define MAX_CAM_DISTANCE 70
|
||||||
@ -35,6 +36,11 @@ SceneWorld::SceneWorld(PseuGUI *g) : Scene(g)
|
|||||||
_CalcXYMoveVect(mychar->GetO());
|
_CalcXYMoveVect(mychar->GetO());
|
||||||
old_char_o = mychar->GetO();
|
old_char_o = mychar->GetO();
|
||||||
|
|
||||||
|
if(soundengine)
|
||||||
|
{
|
||||||
|
soundengine->stopAllSounds();
|
||||||
|
}
|
||||||
|
|
||||||
ILightSceneNode* light = smgr->addLightSceneNode(0, core::vector3df(0,0,0), SColorf(255, 255, 255, 255), 1000.0f);
|
ILightSceneNode* light = smgr->addLightSceneNode(0, core::vector3df(0,0,0), SColorf(255, 255, 255, 255), 1000.0f);
|
||||||
SLight ldata = light->getLightData();
|
SLight ldata = light->getLightData();
|
||||||
ldata.AmbientColor = video::SColorf(0.2f,0.2f,0.2f);
|
ldata.AmbientColor = video::SColorf(0.2f,0.2f,0.2f);
|
||||||
@ -369,7 +375,7 @@ void SceneWorld::OnUpdate(s32 timediff)
|
|||||||
device->getCursorControl()->setPosition(mouse_pos);
|
device->getCursorControl()->setPosition(mouse_pos);
|
||||||
|
|
||||||
// rotate character if right mouse button pressed.
|
// rotate character if right mouse button pressed.
|
||||||
if(mouse_pressed_right)
|
if(mouse_pressed_right && !_freeCameraMove)
|
||||||
{
|
{
|
||||||
mychar->GetPositionPtr()->o = PI*3/2 - DEG_TO_RAD(camera->getHeading());
|
mychar->GetPositionPtr()->o = PI*3/2 - DEG_TO_RAD(camera->getHeading());
|
||||||
// send update to server only if we turned by some amount and not always when we turn
|
// send update to server only if we turned by some amount and not always when we turn
|
||||||
@ -473,6 +479,7 @@ void SceneWorld::OnDelete(void)
|
|||||||
{
|
{
|
||||||
DEBUG(logdebug("~SceneWorld()"));
|
DEBUG(logdebug("~SceneWorld()"));
|
||||||
_doodads.clear();
|
_doodads.clear();
|
||||||
|
_sound_emitters.clear();
|
||||||
gui->domgr.Clear();
|
gui->domgr.Clear();
|
||||||
delete camera;
|
delete camera;
|
||||||
delete eventrecv;
|
delete eventrecv;
|
||||||
@ -543,7 +550,8 @@ void SceneWorld::UpdateTerrain(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateDoodads(); // drop doodads on maps not loaded anymore. no maptile pointers are dereferenced here, so it can be done before acquiring the mutex
|
UpdateMapSceneNodes(_doodads); // drop doodads on maps not loaded anymore. no maptile pointers are dereferenced here, so it can be done before acquiring the mutex
|
||||||
|
UpdateMapSceneNodes(_sound_emitters); // same with sound emitters
|
||||||
|
|
||||||
mutex.acquire(); // prevent other threads from deleting maptiles
|
mutex.acquire(); // prevent other threads from deleting maptiles
|
||||||
|
|
||||||
@ -637,6 +645,63 @@ void SceneWorld::UpdateTerrain(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// create sound emitters
|
||||||
|
logdebug("Loading %u sound emitters for tile (%u, %u)", maptile->GetSoundEmitterCount(), tile_real_x, tile_real_y);
|
||||||
|
uint32 fieldId[10]; // SCP: file1 - file10 (index 0 not used)
|
||||||
|
char fieldname_t[10];
|
||||||
|
SCPDatabase *sounddb = gui->GetInstance()->dbmgr.GetDB("sound");
|
||||||
|
if(sounddb)
|
||||||
|
{
|
||||||
|
for(uint32 i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
sprintf(fieldname_t,"file%u",i + 1); // starts with "file1"
|
||||||
|
fieldId[i] = sounddb->GetFieldId(fieldname_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(uint32 i = 0; i < maptile->GetSoundEmitterCount(); i++)
|
||||||
|
{
|
||||||
|
MCSE_chunk *snd = maptile->GetSoundEmitter(i);
|
||||||
|
if(_sound_emitters.find(snd->soundPointID) == _sound_emitters.end())
|
||||||
|
{
|
||||||
|
CIrrKlangSceneNode *snode = new CIrrKlangSceneNode(soundengine, smgr->getRootSceneNode(), smgr, snd->soundPointID);
|
||||||
|
snode->drop();
|
||||||
|
snode->setPosition(core::vector3df(-snd->x, snd->z, -snd->y));
|
||||||
|
snode->getDebugCube()->setPosition(snode->getPosition());
|
||||||
|
snode->setMinMaxSoundDistance(snd->minDistance,snd->maxDistance);
|
||||||
|
bool exists = sounddb->GetRowByIndex(snd->soundNameID);
|
||||||
|
if(exists)
|
||||||
|
{
|
||||||
|
for(uint32 s = 0; s < 10; s++)
|
||||||
|
{
|
||||||
|
u32 offs = sounddb->GetInt(snd->soundNameID, fieldId[s]);
|
||||||
|
if(fieldId[s] != SCP_INVALID_INT && offs && offs != SCP_INVALID_INT)
|
||||||
|
{
|
||||||
|
std::string fn = "data/sound/";
|
||||||
|
fn += sounddb->GetString(snd->soundNameID, fieldId[s]);
|
||||||
|
snode->addSoundFileName(fn.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
snode->setLoopingStreamMode();
|
||||||
|
}
|
||||||
|
|
||||||
|
core::stringw txt;
|
||||||
|
txt += (exists ? sounddb->GetString(snd->soundNameID, "name") : "[NA SoundEmitter]");
|
||||||
|
txt += L" (";
|
||||||
|
txt += u32(snd->soundNameID);
|
||||||
|
txt += L")";
|
||||||
|
snode->getDebugText()->setPosition(snode->getPosition());
|
||||||
|
snode->getDebugText()->setText(txt.c_str());
|
||||||
|
|
||||||
|
SceneNodeWithGridPos gp;
|
||||||
|
gp.gx = mapmgr->GetGridX() + tilex - 1;
|
||||||
|
gp.gy = mapmgr->GetGridY() + tiley - 1;
|
||||||
|
gp.scenenode = snode;
|
||||||
|
_sound_emitters[snd->soundPointID] = gp;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -679,21 +744,21 @@ void SceneWorld::UpdateTerrain(void)
|
|||||||
RelocateCameraBehindChar();
|
RelocateCameraBehindChar();
|
||||||
}
|
}
|
||||||
|
|
||||||
// drop unneeded doodads from the map
|
// drop unneeded map SceneNodes from the map
|
||||||
void SceneWorld::UpdateDoodads(void)
|
void SceneWorld::UpdateMapSceneNodes(std::map<uint32,SceneNodeWithGridPos>& node_map)
|
||||||
{
|
{
|
||||||
uint32 s = _doodads.size();
|
uint32 s = node_map.size();
|
||||||
std::set<uint32> tmp; // temporary storage for all doodad unique ids
|
std::set<uint32> tmp; // temporary storage for all doodad unique ids
|
||||||
// too bad erasing from a map causes pointer invalidation, so first store all unique ids, and then erase
|
// too bad erasing from a map causes pointer invalidation, so first store all unique ids, and then erase
|
||||||
for(std::map<uint32,SceneNodeWithGridPos>::iterator it = _doodads.begin(); it != _doodads.end(); it++ )
|
for(std::map<uint32,SceneNodeWithGridPos>::iterator it = node_map.begin(); it != node_map.end(); it++ )
|
||||||
if(!mapmgr->GetTile(it->second.gx, it->second.gy))
|
if(!mapmgr->GetTile(it->second.gx, it->second.gy))
|
||||||
tmp.insert(it->first);
|
tmp.insert(it->first);
|
||||||
for(std::set<uint32>::iterator it = tmp.begin(); it != tmp.end(); it++)
|
for(std::set<uint32>::iterator it = tmp.begin(); it != tmp.end(); it++)
|
||||||
{
|
{
|
||||||
_doodads[*it].scenenode->remove();
|
node_map[*it].scenenode->remove();
|
||||||
_doodads.erase(*it);
|
node_map.erase(*it);
|
||||||
}
|
}
|
||||||
logdebug("SceneWorld: Doodads cleaned up, before: %u, after: %u, dropped: %u", s, _doodads.size(), s - _doodads.size());
|
logdebug("SceneWorld: MapSceneNodes cleaned up, before: %u, after: %u, dropped: %u", s, node_map.size(), s - node_map.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -29,12 +29,17 @@ CIrrKlangSceneNode::CIrrKlangSceneNode(irrklang::ISoundEngine* soundEngine,
|
|||||||
|
|
||||||
if (SoundEngine)
|
if (SoundEngine)
|
||||||
SoundEngine->grab();
|
SoundEngine->grab();
|
||||||
|
|
||||||
|
cube = mgr->addCubeSceneNode(0.5f);
|
||||||
|
cube->setMaterialTexture(0,mgr->getVideoDriver()->getTexture("data/misc/square.jpg"));
|
||||||
|
text = mgr->addTextSceneNode(mgr->getGUIEnvironment()->getBuiltInFont(), L"", video::SColor(0xFF00AF00));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CIrrKlangSceneNode::~CIrrKlangSceneNode()
|
CIrrKlangSceneNode::~CIrrKlangSceneNode()
|
||||||
{
|
{
|
||||||
stop();
|
stop();
|
||||||
|
cube->remove();
|
||||||
|
|
||||||
if (SoundEngine)
|
if (SoundEngine)
|
||||||
SoundEngine->drop();
|
SoundEngine->drop();
|
||||||
@ -52,6 +57,9 @@ void CIrrKlangSceneNode::OnRegisterSceneNode()
|
|||||||
|
|
||||||
void CIrrKlangSceneNode::OnAnimate(u32 timeMs)
|
void CIrrKlangSceneNode::OnAnimate(u32 timeMs)
|
||||||
{
|
{
|
||||||
|
if(!SoundFileNames.size())
|
||||||
|
return;
|
||||||
|
|
||||||
ISceneNode::OnAnimate(timeMs);
|
ISceneNode::OnAnimate(timeMs);
|
||||||
|
|
||||||
// play the sound
|
// play the sound
|
||||||
@ -84,7 +92,8 @@ void CIrrKlangSceneNode::OnAnimate(u32 timeMs)
|
|||||||
else
|
else
|
||||||
if (!Sound && (!TimeMsDelayFinished || timeMs > TimeMsDelayFinished))
|
if (!Sound && (!TimeMsDelayFinished || timeMs > TimeMsDelayFinished))
|
||||||
{
|
{
|
||||||
// play new sound
|
// play new sound; select one from the possible files
|
||||||
|
core::stringc& SoundFileName = SoundFileNames[ rand() % SoundFileNames.size() ];
|
||||||
|
|
||||||
if (SoundFileName.size())
|
if (SoundFileName.size())
|
||||||
Sound = SoundEngine->play3D(SoundFileName.c_str(), pos, false, true, true);
|
Sound = SoundEngine->play3D(SoundFileName.c_str(), pos, false, true, true);
|
||||||
@ -105,6 +114,7 @@ void CIrrKlangSceneNode::OnAnimate(u32 timeMs)
|
|||||||
{
|
{
|
||||||
if (!Sound)
|
if (!Sound)
|
||||||
{
|
{
|
||||||
|
core::stringc& SoundFileName = SoundFileNames[ rand() % SoundFileNames.size() ];
|
||||||
if (SoundFileName.size())
|
if (SoundFileName.size())
|
||||||
Sound = SoundEngine->play3D(SoundFileName.c_str(), pos, true, true, true);
|
Sound = SoundEngine->play3D(SoundFileName.c_str(), pos, true, true, true);
|
||||||
|
|
||||||
@ -142,6 +152,7 @@ void CIrrKlangSceneNode::OnAnimate(u32 timeMs)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// start
|
// start
|
||||||
|
core::stringc& SoundFileName = SoundFileNames[ rand() % SoundFileNames.size() ];
|
||||||
|
|
||||||
if (SoundFileName.size())
|
if (SoundFileName.size())
|
||||||
Sound = SoundEngine->play3D(SoundFileName.c_str(), pos, false, true, true);
|
Sound = SoundEngine->play3D(SoundFileName.c_str(), pos, false, true, true);
|
||||||
@ -234,7 +245,7 @@ void CIrrKlangSceneNode::render()
|
|||||||
material.Lighting = false;
|
material.Lighting = false;
|
||||||
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||||
material.MaterialTypeParam = 255;
|
material.MaterialTypeParam = 255;
|
||||||
material.TextureLayer[0].Texture = driver->getTexture("textures/editor_defaults/default_sound.png");
|
material.TextureLayer[0].Texture = driver->getTexture("data/misc/square.jpg");
|
||||||
|
|
||||||
core::matrix4 mat;
|
core::matrix4 mat;
|
||||||
driver->setTransform(video::ETS_WORLD, mat);
|
driver->setTransform(video::ETS_WORLD, mat);
|
||||||
@ -256,122 +267,6 @@ const c8* const IrrKlangPlayModeNames[] =
|
|||||||
"nothing", "random", "looping", "play_once", 0
|
"nothing", "random", "looping", "play_once", 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//! Writes attributes of the scene node.
|
|
||||||
void CIrrKlangSceneNode::serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const
|
|
||||||
{
|
|
||||||
if (!out)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ISceneNode::serializeAttributes(out, options);
|
|
||||||
const char** soundNames = 0;
|
|
||||||
|
|
||||||
if ( SoundEngine && options && ( options->Flags & io::EARWF_FOR_EDITOR ) )
|
|
||||||
{
|
|
||||||
// show a list of all loaded sound files in editor
|
|
||||||
|
|
||||||
int count = SoundEngine->getSoundSourceCount();
|
|
||||||
soundNames = new const char*[count+3];
|
|
||||||
|
|
||||||
for (int i=0; i<count; ++i)
|
|
||||||
soundNames[i] = SoundEngine->getSoundSource(i)->getName();
|
|
||||||
|
|
||||||
soundNames[count] = "";
|
|
||||||
soundNames[count+1] = "<select>"; // editor file selector
|
|
||||||
soundNames[count+2] = 0;
|
|
||||||
|
|
||||||
out->addEnum("SoundFileName", SoundFileName.c_str(), soundNames);
|
|
||||||
|
|
||||||
delete [] soundNames;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// only store string of sound file if not in editor
|
|
||||||
out->addString("SoundFileName", SoundFileName.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// add play modes
|
|
||||||
|
|
||||||
out->addEnum("PlayMode", PlayMode, IrrKlangPlayModeNames);
|
|
||||||
out->addFloat("MinDistance", MinDistance);
|
|
||||||
out->addFloat("MaxDistance", MaxDistance);
|
|
||||||
|
|
||||||
// only save the necessary attributes
|
|
||||||
|
|
||||||
switch(PlayMode)
|
|
||||||
{
|
|
||||||
case EPM_ONCE:
|
|
||||||
out->addBool("DeleteWhenFinished", DeleteWhenFinished);
|
|
||||||
break;
|
|
||||||
case EPM_RANDOM:
|
|
||||||
out->addInt("MinTimeMsInterval", MinTimeMsInterval);
|
|
||||||
out->addInt("MaxTimeMsInterval", MaxTimeMsInterval);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Reads attributes of the scene node.
|
|
||||||
void CIrrKlangSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options)
|
|
||||||
{
|
|
||||||
if (!in)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ISceneNode::deserializeAttributes(in);
|
|
||||||
|
|
||||||
core::stringc oldFileName = SoundFileName;
|
|
||||||
SoundFileName = in->getAttributeAsString("SoundFileName");
|
|
||||||
EPlayMode newMode = (EPlayMode)in->getAttributeAsEnumeration("PlayMode", IrrKlangPlayModeNames);
|
|
||||||
|
|
||||||
f32 minDistance = in->getAttributeAsFloat("MinDistance");
|
|
||||||
f32 maxDistance = in->getAttributeAsFloat("MaxDistance");
|
|
||||||
|
|
||||||
setMinMaxSoundDistance(minDistance, maxDistance);
|
|
||||||
|
|
||||||
DeleteWhenFinished = in->getAttributeAsBool("DeleteWhenFinished");
|
|
||||||
|
|
||||||
if (in->existsAttribute("MinTimeMsInterval"))
|
|
||||||
MinTimeMsInterval = in->getAttributeAsInt("MinTimeMsInterval");
|
|
||||||
if (in->existsAttribute("MaxTimeMsInterval"))
|
|
||||||
MaxTimeMsInterval = in->getAttributeAsInt("MaxTimeMsInterval");
|
|
||||||
|
|
||||||
if (newMode != PlayMode || oldFileName != SoundFileName)
|
|
||||||
{
|
|
||||||
stop();
|
|
||||||
TimeMsDelayFinished = 0;
|
|
||||||
PlayMode = newMode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//! Creates a clone of this scene node and its children.
|
|
||||||
ISceneNode* CIrrKlangSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
|
|
||||||
{
|
|
||||||
// this method is only implemented to let irrEdit be able to copy the
|
|
||||||
// scene node via CTRL+C, it's not necessary
|
|
||||||
|
|
||||||
if (!newParent) newParent = Parent;
|
|
||||||
if (!newManager) newManager = SceneManager;
|
|
||||||
|
|
||||||
CIrrKlangSceneNode* nb = new CIrrKlangSceneNode(SoundEngine, newParent, newManager, ID);
|
|
||||||
|
|
||||||
nb->cloneMembers(this, newManager);
|
|
||||||
|
|
||||||
nb->SoundFileName = SoundFileName;
|
|
||||||
nb->MinDistance = MinDistance;
|
|
||||||
nb->Box = Box;
|
|
||||||
nb->PlayMode = PlayMode;
|
|
||||||
nb->TimeMsDelayFinished = TimeMsDelayFinished;
|
|
||||||
nb->DeleteWhenFinished = DeleteWhenFinished;
|
|
||||||
nb->MaxTimeMsInterval = MaxTimeMsInterval;
|
|
||||||
nb->MinTimeMsInterval = MinTimeMsInterval;
|
|
||||||
|
|
||||||
nb->drop();
|
|
||||||
return nb;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//! Returns type of the scene node
|
//! Returns type of the scene node
|
||||||
ESCENE_NODE_TYPE CIrrKlangSceneNode::getType() const
|
ESCENE_NODE_TYPE CIrrKlangSceneNode::getType() const
|
||||||
{
|
{
|
||||||
@ -426,19 +321,17 @@ void CIrrKlangSceneNode::setRandomMode(int minTimeMs, int maxTimeMs)
|
|||||||
|
|
||||||
|
|
||||||
//! Sets the sound filename to play
|
//! Sets the sound filename to play
|
||||||
void CIrrKlangSceneNode::setSoundFileName(const char* soundFilename)
|
void CIrrKlangSceneNode::addSoundFileName(const char* soundFilename)
|
||||||
{
|
{
|
||||||
if (soundFilename)
|
if (soundFilename && strlen(soundFilename))
|
||||||
SoundFileName = soundFilename;
|
SoundFileNames.push_back(soundFilename);
|
||||||
else
|
|
||||||
SoundFileName = "";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//! Gets the sound filename to play
|
//! Gets the sound filename to play
|
||||||
const char* CIrrKlangSceneNode::getSoundFileName() const
|
const char* CIrrKlangSceneNode::getSoundFileName(u32 id) const
|
||||||
{
|
{
|
||||||
return SoundFileName.c_str();
|
return SoundFileNames.size() < id ? SoundFileNames[id].c_str() : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -72,11 +72,11 @@ public:
|
|||||||
|
|
||||||
// Sound parameters
|
// Sound parameters
|
||||||
|
|
||||||
//! Sets the sound filename to play
|
//! Adds a sound filename to play
|
||||||
void setSoundFileName(const char* soundFilename);
|
void addSoundFileName(const char* soundFilename);
|
||||||
|
|
||||||
//! Gets the sound filename to play
|
//! Gets the sound filename to play
|
||||||
const char* getSoundFileName() const;
|
const char* getSoundFileName(u32 id) const;
|
||||||
|
|
||||||
//! Sets the minimal and maximal 3D sound distances.
|
//! Sets the minimal and maximal 3D sound distances.
|
||||||
//! Set to negative values if you want to use the default values of the sound engine.
|
//! Set to negative values if you want to use the default values of the sound engine.
|
||||||
@ -92,9 +92,9 @@ public:
|
|||||||
virtual void render();
|
virtual void render();
|
||||||
virtual const core::aabbox3d<f32>& getBoundingBox() const;
|
virtual const core::aabbox3d<f32>& getBoundingBox() const;
|
||||||
virtual ESCENE_NODE_TYPE getType() const;
|
virtual ESCENE_NODE_TYPE getType() const;
|
||||||
ISceneNode* clone(ISceneNode* newParent, ISceneManager* newManager);
|
|
||||||
void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const;
|
scene::ISceneNode *getDebugCube(void) { return cube; }
|
||||||
void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options);
|
scene::ITextSceneNode *getDebugText(void) { return text; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ protected:
|
|||||||
irrklang::ISoundEngine* SoundEngine;
|
irrklang::ISoundEngine* SoundEngine;
|
||||||
irrklang::ISound* Sound;
|
irrklang::ISound* Sound;
|
||||||
|
|
||||||
core::stringc SoundFileName;
|
core::array<core::stringc> SoundFileNames;
|
||||||
f32 MinDistance;
|
f32 MinDistance;
|
||||||
f32 MaxDistance;
|
f32 MaxDistance;
|
||||||
|
|
||||||
@ -120,6 +120,8 @@ protected:
|
|||||||
s32 MaxTimeMsInterval;
|
s32 MaxTimeMsInterval;
|
||||||
s32 MinTimeMsInterval;
|
s32 MinTimeMsInterval;
|
||||||
s32 PlayedCount;
|
s32 PlayedCount;
|
||||||
|
scene::ISceneNode *cube;
|
||||||
|
scene::ITextSceneNode *text;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -518,6 +518,7 @@ void PseuInstanceConf::ApplyFromVarSet(VarSet &v)
|
|||||||
fogfar = atof(v.Get("GUI::FOGFAR").c_str());
|
fogfar = atof(v.Get("GUI::FOGFAR").c_str());
|
||||||
fognear = atof(v.Get("GUI::FOGNEAR").c_str());
|
fognear = atof(v.Get("GUI::FOGNEAR").c_str());
|
||||||
fov = atof(v.Get("GUI::FOV").c_str());
|
fov = atof(v.Get("GUI::FOV").c_str());
|
||||||
|
masterSoundVolume = atof(v.Get("GUI::MASTERSOUNDVOLUME").c_str());
|
||||||
|
|
||||||
log_setloglevel(debug);
|
log_setloglevel(debug);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -69,6 +69,9 @@ class PseuInstanceConf
|
|||||||
float fognear;
|
float fognear;
|
||||||
float fov;
|
float fov;
|
||||||
|
|
||||||
|
// sound related
|
||||||
|
float masterSoundVolume;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -41,8 +41,6 @@ enum eAuthResults
|
|||||||
REALM_AUTH_PARENTAL_CONTROL=0x0f ///< Access to this account has been blocked by parental controls. Your settings may be changed in your account preferences at <site>
|
REALM_AUTH_PARENTAL_CONTROL=0x0f ///< Access to this account has been blocked by parental controls. Your settings may be changed in your account preferences at <site>
|
||||||
};
|
};
|
||||||
|
|
||||||
#define ChunkSize 2048
|
|
||||||
|
|
||||||
struct SRealmHeader
|
struct SRealmHeader
|
||||||
{
|
{
|
||||||
uint8 cmd; // OP code = CMD_REALM_LIST
|
uint8 cmd; // OP code = CMD_REALM_LIST
|
||||||
@ -51,19 +49,6 @@ struct SRealmHeader
|
|||||||
uint8 count; // quantity of realms
|
uint8 count; // quantity of realms
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SRealmInfo
|
|
||||||
{
|
|
||||||
uint8 icon; // icon near realm
|
|
||||||
uint8 locked; // added in 2.0.x
|
|
||||||
uint8 color; // color of record
|
|
||||||
std::string name; // Text zero terminated name of Realm
|
|
||||||
std::string addr_port; // Text zero terminated address of Realm ("ip:port")
|
|
||||||
float population; // 1.6 -> population value. lower == lower population and vice versa
|
|
||||||
uint8 chars_here; // number of characters on this server
|
|
||||||
uint8 timezone; // timezone
|
|
||||||
uint8 unknown; //
|
|
||||||
};
|
|
||||||
|
|
||||||
struct AuthHandler
|
struct AuthHandler
|
||||||
{
|
{
|
||||||
uint32 cmd;
|
uint32 cmd;
|
||||||
@ -260,39 +245,47 @@ void RealmSession::_HandleRealmList(ByteBuffer& pkt)
|
|||||||
if(count==0)
|
if(count==0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// alloc space for as many realms as needed
|
_realms.clear();
|
||||||
SRealmInfo *realms=new SRealmInfo[count];
|
_realms.resize(count);
|
||||||
|
|
||||||
// readout realms
|
// readout realms
|
||||||
for(uint8 i=0;i<count;i++)
|
for(uint8 i=0;i<count;i++)
|
||||||
{
|
{
|
||||||
pkt >> realms[i].icon;
|
pkt >> _realms[i].icon;
|
||||||
pkt >> realms[i].locked;
|
pkt >> _realms[i].locked;
|
||||||
pkt >> realms[i].color;
|
pkt >> _realms[i].color;
|
||||||
pkt >> realms[i].name;
|
pkt >> _realms[i].name;
|
||||||
pkt >> realms[i].addr_port;
|
pkt >> _realms[i].addr_port;
|
||||||
pkt >> realms[i].population;
|
pkt >> _realms[i].population;
|
||||||
pkt >> realms[i].chars_here;
|
pkt >> _realms[i].chars_here;
|
||||||
pkt >> realms[i].timezone;
|
pkt >> _realms[i].timezone;
|
||||||
pkt >> realms[i].unknown;
|
pkt >> _realms[i].unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
// the rest of the packet is not interesting
|
// the rest of the packet is not interesting
|
||||||
|
|
||||||
for(uint8 i=0;i<count;i++)
|
for(uint8 i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if(realms[i].name==GetInstance()->GetConf()->realmname)
|
if(!stricmp(_realms[i].name.c_str(), GetInstance()->GetConf()->realmname.c_str()))
|
||||||
{
|
{
|
||||||
realmAddr=realms[i].addr_port;
|
realmAddr = _realms[i].addr_port;
|
||||||
}
|
}
|
||||||
logcustom(0,LGREEN,"Realm: %s (%s)",realms[i].name.c_str(),realms[i].addr_port.c_str());
|
logcustom(0,LGREEN,"Realm: %s (%s)",_realms[i].name.c_str(),_realms[i].addr_port.c_str());
|
||||||
logdetail(" [chars:%d][population:%f][timezone:%d]",realms[i].chars_here,realms[i].population,realms[i].timezone);
|
logdetail(" [chars:%d][population:%f][timezone:%d]",_realms[i].chars_here,_realms[i].population,_realms[i].timezone);
|
||||||
}
|
}
|
||||||
delete [] realms;
|
|
||||||
|
|
||||||
// now setup where the worldserver is and how to login there
|
// now setup where the worldserver is and how to login there
|
||||||
if(realmAddr.empty()){
|
if(realmAddr.empty())
|
||||||
log("Realm \"%s\" was not found on the realmlist!",GetInstance()->GetConf()->realmname.c_str());
|
{
|
||||||
|
if(PseuGUI *gui = GetInstance()->GetGUI())
|
||||||
|
{
|
||||||
|
logdebug("RealmSession: GUI exists, switching to realm selection screen");
|
||||||
|
gui->SetSceneState(SCENESTATE_REALMSELECT); // realm select is a sub-window of character selection
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logerror("Realm \"%s\" was not found on the realmlist!",GetInstance()->GetConf()->realmname.c_str());
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,17 +293,24 @@ void RealmSession::_HandleRealmList(ByteBuffer& pkt)
|
|||||||
// -> convert the worldserver port from string to int
|
// -> convert the worldserver port from string to int
|
||||||
// -> write it into the config & set appropriate vars
|
// -> write it into the config & set appropriate vars
|
||||||
|
|
||||||
uint16 colonpos=realmAddr.find(":");
|
SetRealmAddr(realmAddr);
|
||||||
GetInstance()->GetConf()->worldhost=realmAddr.substr(0,colonpos);
|
|
||||||
GetInstance()->GetConf()->worldport=atoi(realmAddr.substr(colonpos+1,realmAddr.length()-colonpos-1).c_str());
|
|
||||||
// set vars
|
|
||||||
GetInstance()->GetScripts()->variables.Set("WORLDHOST",GetInstance()->GetConf()->worldhost);
|
|
||||||
GetInstance()->GetScripts()->variables.Set("WORLDPORT",DefScriptTools::toString((uint64)(GetInstance()->GetConf()->worldport)));
|
|
||||||
|
|
||||||
// now we have the correct addr/port, time to create the WorldSession
|
// now we have the correct addr/port, time to create the WorldSession
|
||||||
GetInstance()->CreateWorldSession(); // will be done at next PseuInstance::Update()
|
GetInstance()->CreateWorldSession(); // will be done at next PseuInstance::Update()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RealmSession::SetRealmAddr(std::string host)
|
||||||
|
{
|
||||||
|
logdebug("SetRealmAddr [%s]", host.c_str());
|
||||||
|
uint16 colonpos=host.find(":");
|
||||||
|
ASSERT(colonpos != std::string::npos);
|
||||||
|
GetInstance()->GetConf()->worldhost=host.substr(0,colonpos);
|
||||||
|
GetInstance()->GetConf()->worldport=atoi(host.substr(colonpos+1,host.length()-colonpos-1).c_str());
|
||||||
|
// set vars
|
||||||
|
GetInstance()->GetScripts()->variables.Set("WORLDHOST",GetInstance()->GetConf()->worldhost);
|
||||||
|
GetInstance()->GetScripts()->variables.Set("WORLDPORT",DefScriptTools::toString((uint64)(GetInstance()->GetConf()->worldport)));
|
||||||
|
}
|
||||||
|
|
||||||
void RealmSession::SetLogonData(void)
|
void RealmSession::SetLogonData(void)
|
||||||
{
|
{
|
||||||
_accname=GetInstance()->GetConf()->accname;
|
_accname=GetInstance()->GetConf()->accname;
|
||||||
@ -557,7 +557,7 @@ void RealmSession::_HandleLogonProof(ByteBuffer& pkt)
|
|||||||
if(gui)
|
if(gui)
|
||||||
gui->SetSceneData(ISCENE_LOGIN_CONN_STATUS, DSCENE_LOGIN_AUTH_FAILED);
|
gui->SetSceneData(ISCENE_LOGIN_CONN_STATUS, DSCENE_LOGIN_AUTH_FAILED);
|
||||||
logerror("Wrong password or invalid account information or authentication error");
|
logerror("Wrong password or invalid account information or authentication error");
|
||||||
DieOrReconnect(true);
|
DieOrReconnect(false);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// cover all other cases. continue only if success.
|
// cover all other cases. continue only if success.
|
||||||
|
|||||||
@ -4,6 +4,19 @@
|
|||||||
#include "common.h"
|
#include "common.h"
|
||||||
#include "Auth/MD5Hash.h"
|
#include "Auth/MD5Hash.h"
|
||||||
|
|
||||||
|
struct SRealmInfo
|
||||||
|
{
|
||||||
|
uint8 icon; // icon near realm
|
||||||
|
uint8 locked; // added in 2.0.x
|
||||||
|
uint8 color; // color of record
|
||||||
|
std::string name; // Text zero terminated name of Realm
|
||||||
|
std::string addr_port; // Text zero terminated address of Realm ("ip:port")
|
||||||
|
float population; // 1.6 -> population value. lower == lower population and vice versa
|
||||||
|
uint8 chars_here; // number of characters on this server
|
||||||
|
uint8 timezone; // timezone
|
||||||
|
uint8 unknown; //
|
||||||
|
};
|
||||||
|
|
||||||
struct AuthHandler;
|
struct AuthHandler;
|
||||||
class RealmSocket;
|
class RealmSocket;
|
||||||
|
|
||||||
@ -22,6 +35,9 @@ public:
|
|||||||
bool MustDie(void);
|
bool MustDie(void);
|
||||||
void SetMustDie(void);
|
void SetMustDie(void);
|
||||||
bool SocketGood(void);
|
bool SocketGood(void);
|
||||||
|
void SetRealmAddr(std::string);
|
||||||
|
inline uint32 GetRealmCount(void) { return _realms.size(); }
|
||||||
|
inline SRealmInfo& GetRealm(uint32 i) { return _realms[i]; }
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -48,6 +64,7 @@ private:
|
|||||||
uint64 _file_done, _file_size;
|
uint64 _file_done, _file_size;
|
||||||
ByteBuffer _filebuf;
|
ByteBuffer _filebuf;
|
||||||
ByteBuffer _transbuf; // stores parts of unfinished packets
|
ByteBuffer _transbuf; // stores parts of unfinished packets
|
||||||
|
std::vector<SRealmInfo> _realms;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -142,7 +142,7 @@ uint32 SCPDatabase::GetFieldType(char *entry)
|
|||||||
{
|
{
|
||||||
std::map<std::string,SCPFieldDef>::iterator it = _fielddefs.find(entry);
|
std::map<std::string,SCPFieldDef>::iterator it = _fielddefs.find(entry);
|
||||||
if(it != _fielddefs.end())
|
if(it != _fielddefs.end())
|
||||||
return _fielddefs[entry].type;
|
return it->second.type;
|
||||||
return SCP_INVALID_INT;
|
return SCP_INVALID_INT;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,7 +150,7 @@ uint32 SCPDatabase::GetFieldId(char *entry)
|
|||||||
{
|
{
|
||||||
std::map<std::string,SCPFieldDef>::iterator it = _fielddefs.find(entry);
|
std::map<std::string,SCPFieldDef>::iterator it = _fielddefs.find(entry);
|
||||||
if(it != _fielddefs.end())
|
if(it != _fielddefs.end())
|
||||||
return _fielddefs[entry].id;
|
return it->second.id;
|
||||||
return SCP_INVALID_INT;
|
return SCP_INVALID_INT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -42,9 +42,18 @@ WorldSession::~WorldSession()
|
|||||||
{
|
{
|
||||||
if(PseuGUI *gui = GetInstance()->GetGUI())
|
if(PseuGUI *gui = GetInstance()->GetGUI())
|
||||||
{
|
{
|
||||||
gui->SetSceneState(SCENESTATE_LOGINSCREEN); // kick back to login gui
|
// if the realm session still exists, the connection to the world server was not successful
|
||||||
|
// and we need to show realmlist window again
|
||||||
|
if(_instance->GetRSession())
|
||||||
|
{
|
||||||
|
gui->SetSceneState(SCENESTATE_REALMSELECT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gui->SetSceneState(SCENESTATE_LOGINSCREEN); // kick back to login gui
|
||||||
|
}
|
||||||
logdebug("~WorldSession(): Waiting until world GUI is deleted");
|
logdebug("~WorldSession(): Waiting until world GUI is deleted");
|
||||||
while(gui->GetSceneState() != SCENESTATE_LOGINSCREEN) // .. and wait until the world gui is really deleted
|
while(gui->GetSceneState() == SCENESTATE_WORLD) // .. and wait until the world gui is really deleted
|
||||||
GetInstance()->Sleep(1); // (it can cause crash otherwise)
|
GetInstance()->Sleep(1); // (it can cause crash otherwise)
|
||||||
logdebug("~WorldSession(): ... world GUI deleted, continuing to close session");
|
logdebug("~WorldSession(): ... world GUI deleted, continuing to close session");
|
||||||
}
|
}
|
||||||
@ -87,10 +96,6 @@ void WorldSession::Start(void)
|
|||||||
log("Connecting to '%s' on port %u",GetInstance()->GetConf()->worldhost.c_str(),GetInstance()->GetConf()->worldport);
|
log("Connecting to '%s' on port %u",GetInstance()->GetConf()->worldhost.c_str(),GetInstance()->GetConf()->worldport);
|
||||||
_socket=new WorldSocket(_sh,this);
|
_socket=new WorldSocket(_sh,this);
|
||||||
_socket->Open(GetInstance()->GetConf()->worldhost,GetInstance()->GetConf()->worldport);
|
_socket->Open(GetInstance()->GetConf()->worldhost,GetInstance()->GetConf()->worldport);
|
||||||
if(GetInstance()->GetRSession())
|
|
||||||
{
|
|
||||||
GetInstance()->GetRSession()->SetMustDie(); // realm session is no longer needed
|
|
||||||
}
|
|
||||||
_sh.Add(_socket);
|
_sh.Add(_socket);
|
||||||
|
|
||||||
// if we cant connect, wait until the socket gives up (after 5 secs)
|
// if we cant connect, wait until the socket gives up (after 5 secs)
|
||||||
@ -546,6 +551,8 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
|
|||||||
uint8 dummy8;
|
uint8 dummy8;
|
||||||
uint32 dummy32;
|
uint32 dummy32;
|
||||||
|
|
||||||
|
_charList.clear();
|
||||||
|
|
||||||
recvPacket >> num;
|
recvPacket >> num;
|
||||||
if(num==0)
|
if(num==0)
|
||||||
{
|
{
|
||||||
@ -556,6 +563,7 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
|
|||||||
|
|
||||||
logdetail("Chars in list: %u",num);
|
logdetail("Chars in list: %u",num);
|
||||||
_LoadCache(); // we are about to login, so we need cache data
|
_LoadCache(); // we are about to login, so we need cache data
|
||||||
|
// TODO: load cache on loadingscreen
|
||||||
for(unsigned int i=0;i<num;i++)
|
for(unsigned int i=0;i<num;i++)
|
||||||
{
|
{
|
||||||
recvPacket >> plr[i]._guid;
|
recvPacket >> plr[i]._guid;
|
||||||
@ -585,7 +593,8 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
|
|||||||
{
|
{
|
||||||
recvPacket >> plr[i]._items[inv].displayId >> plr[i]._items[inv].inventorytype >> dummy32;
|
recvPacket >> plr[i]._items[inv].displayId >> plr[i]._items[inv].inventorytype >> dummy32;
|
||||||
}
|
}
|
||||||
plrNameCache.AddInfo(plr[i]._guid, plr[i]._name);
|
plrNameCache.AddInfo(plr[i]._guid, plr[i]._name); // TODO: set after loadingscreen, after loading cache
|
||||||
|
|
||||||
}
|
}
|
||||||
bool char_found=false;
|
bool char_found=false;
|
||||||
|
|
||||||
@ -607,6 +616,14 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
|
|||||||
if(classdb)
|
if(classdb)
|
||||||
classname = classdb->GetString(plr[i]._class, "name");
|
classname = classdb->GetString(plr[i]._class, "name");
|
||||||
|
|
||||||
|
CharacterListExt cx;
|
||||||
|
cx.p = plr[i];
|
||||||
|
cx.class_ = classname;
|
||||||
|
cx.race = racename;
|
||||||
|
cx.zone = zonename;
|
||||||
|
cx.map_ = mapname;
|
||||||
|
_charList.push_back(cx);
|
||||||
|
|
||||||
logcustom(0,LGREEN,"## %s (%u) [%s/%s] Map: %s; Zone: %s",
|
logcustom(0,LGREEN,"## %s (%u) [%s/%s] Map: %s; Zone: %s",
|
||||||
plr[i]._name.c_str(),
|
plr[i]._name.c_str(),
|
||||||
plr[i]._level,
|
plr[i]._level,
|
||||||
@ -623,43 +640,76 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
|
|||||||
if(plr[i]._items[inv].displayId)
|
if(plr[i]._items[inv].displayId)
|
||||||
logdebug("-> Has Item: Model=%u InventoryType=%u",plr[i]._items[inv].displayId,plr[i]._items[inv].inventorytype);
|
logdebug("-> Has Item: Model=%u InventoryType=%u",plr[i]._items[inv].displayId,plr[i]._items[inv].inventorytype);
|
||||||
}
|
}
|
||||||
if(plr[i]._name==GetInstance()->GetConf()->charname)
|
if(plr[i]._name==GetInstance()->GetConf()->charname || num == 1)
|
||||||
{
|
{
|
||||||
charId = i;
|
charId = i;
|
||||||
char_found=true;
|
char_found=true;
|
||||||
_myGUID=plr[i]._guid;
|
|
||||||
GetInstance()->GetScripts()->variables.Set("@myguid",DefScriptTools::toString(plr[i]._guid));
|
|
||||||
GetInstance()->GetScripts()->variables.Set("@myrace",DefScriptTools::toString((uint64)plr[i]._race));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
if(!char_found)
|
if(!char_found)
|
||||||
{
|
{
|
||||||
logerror("Character \"%s\" was not found on char list!", GetInstance()->GetConf()->charname.c_str());
|
if(PseuGUI *gui = GetInstance()->GetGUI())
|
||||||
GetInstance()->SetError();
|
{
|
||||||
return;
|
gui->SetSceneState(SCENESTATE_CHARSELECT);
|
||||||
|
gui->UpdateScene();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logerror("Character \"%s\" was not found on char list, can't connect!", GetInstance()->GetConf()->charname.c_str());
|
||||||
|
GetInstance()->SetError();
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
log("Entering World with Character \"%s\"...", plr[charId]._name.c_str());
|
EnterWorldWithCharacter(plr[charId]._name.c_str());
|
||||||
|
|
||||||
// create the character and add it to the objmgr.
|
|
||||||
// note: this is the only object that has to stay in memory unless its explicitly deleted by the server!
|
|
||||||
// that means even if the server sends create object with that guid, do NOT recreate it!!
|
|
||||||
MyCharacter *my = new MyCharacter();
|
|
||||||
my->Create(_myGUID);
|
|
||||||
my->SetName(plr[charId]._name);
|
|
||||||
objmgr.Add(my);
|
|
||||||
|
|
||||||
// TODO: initialize the world here, and load required maps.
|
|
||||||
// must remove appropriate code from _HandleLoginVerifyWorldOpcode() then!!
|
|
||||||
|
|
||||||
WorldPacket pkt(CMSG_PLAYER_LOGIN,8);
|
|
||||||
pkt << _myGUID;
|
|
||||||
SendWorldPacket(pkt);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WorldSession::EnterWorldWithCharacter(std::string name)
|
||||||
|
{
|
||||||
|
logdebug("EnterWorldWithCharacter(%s)",name.c_str());
|
||||||
|
_myGUID = 0;
|
||||||
|
for(CharList::iterator it = _charList.begin(); it != _charList.end(); it++)
|
||||||
|
{
|
||||||
|
if(!stricmp(it->p._name.c_str(), name.c_str()))
|
||||||
|
{
|
||||||
|
_myGUID = it->p._guid;
|
||||||
|
GetInstance()->GetScripts()->variables.Set("@myguid",DefScriptTools::toString(_myGUID));
|
||||||
|
GetInstance()->GetScripts()->variables.Set("@myrace",DefScriptTools::toString(it->p._race));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!_myGUID)
|
||||||
|
{
|
||||||
|
logerror("Character '%s' does not exist on this account");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log("Entering World with Character \"%s\"...", name.c_str());
|
||||||
|
|
||||||
|
// create the character and add it to the objmgr.
|
||||||
|
// note: this is the only object that has to stay in memory unless its explicitly deleted by the server!
|
||||||
|
// that means even if the server sends create object with that guid, do NOT recreate it!!
|
||||||
|
MyCharacter *my = new MyCharacter();
|
||||||
|
my->Create(_myGUID);
|
||||||
|
my->SetName(name);
|
||||||
|
objmgr.Add(my);
|
||||||
|
|
||||||
|
// TODO: initialize the world here, and load required maps.
|
||||||
|
// must remove appropriate code from _HandleLoginVerifyWorldOpcode() then!!
|
||||||
|
|
||||||
|
WorldPacket pkt(CMSG_PLAYER_LOGIN,8);
|
||||||
|
pkt << _myGUID;
|
||||||
|
SendWorldPacket(pkt);
|
||||||
|
|
||||||
|
// close realm session when logging into world
|
||||||
|
if(!MustDie() && _socket->IsOk() && GetInstance()->GetRSession())
|
||||||
|
{
|
||||||
|
GetInstance()->GetRSession()->SetMustDie(); // realm session is no longer needed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void WorldSession::_HandleSetProficiencyOpcode(WorldPacket& recvPacket)
|
void WorldSession::_HandleSetProficiencyOpcode(WorldPacket& recvPacket)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -39,7 +39,19 @@ struct DelayedWorldPacket
|
|||||||
clock_t when;
|
clock_t when;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// helper used for GUI
|
||||||
|
struct CharacterListExt
|
||||||
|
{
|
||||||
|
PlayerEnum p;
|
||||||
|
std::string zone;
|
||||||
|
std::string class_;
|
||||||
|
std::string race;
|
||||||
|
std::string map_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef std::vector<WhoListEntry> WhoList;
|
typedef std::vector<WhoListEntry> WhoList;
|
||||||
|
typedef std::vector<CharacterListExt> CharList;
|
||||||
typedef std::deque<DelayedWorldPacket> DelayedPacketQueue;
|
typedef std::deque<DelayedWorldPacket> DelayedPacketQueue;
|
||||||
|
|
||||||
class WorldSession
|
class WorldSession
|
||||||
@ -75,6 +87,10 @@ public:
|
|||||||
std::string GetOrRequestPlayerName(uint64);
|
std::string GetOrRequestPlayerName(uint64);
|
||||||
std::string DumpPacket(WorldPacket& pkt, int errpos = -1, char *errstr = NULL);
|
std::string DumpPacket(WorldPacket& pkt, int errpos = -1, char *errstr = NULL);
|
||||||
|
|
||||||
|
inline uint32 GetCharsCount(void) { return _charList.size(); }
|
||||||
|
inline CharacterListExt& GetCharFromList(uint32 id) { return _charList[id]; }
|
||||||
|
void EnterWorldWithCharacter(std::string);
|
||||||
|
|
||||||
|
|
||||||
// CMSGConstructor
|
// CMSGConstructor
|
||||||
void SendChatMessage(uint32 type, uint32 lang, std::string msg, std::string to="");
|
void SendChatMessage(uint32 type, uint32 lang, std::string msg, std::string to="");
|
||||||
@ -160,8 +176,10 @@ private:
|
|||||||
uint64 _myGUID;
|
uint64 _myGUID;
|
||||||
World *_world;
|
World *_world;
|
||||||
WhoList _whoList;
|
WhoList _whoList;
|
||||||
|
CharList _charList;
|
||||||
uint32 _lag_ms;
|
uint32 _lag_ms;
|
||||||
std::bitset<MAX_OPCODE_ID> _disabledOpcodes;
|
std::bitset<MAX_OPCODE_ID> _disabledOpcodes;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -127,4 +127,5 @@ void WorldSocket::InitCrypt(BigNumber *k)
|
|||||||
{
|
{
|
||||||
_crypt.SetKey(k);
|
_crypt.SetKey(k);
|
||||||
_crypt.Init();
|
_crypt.Init();
|
||||||
|
logdebug("WorldSocket: Crypt initialized");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -444,6 +444,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath=".\Client\Gui\DrawObjMgr.h">
|
RelativePath=".\Client\Gui\DrawObjMgr.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Client\Gui\GUIEventReceiver.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Client\Gui\MCamera.h">
|
RelativePath=".\Client\Gui\MCamera.h">
|
||||||
</File>
|
</File>
|
||||||
@ -462,6 +465,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath=".\Client\Gui\Scene.h">
|
RelativePath=".\Client\Gui\Scene.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Client\Gui\SceneCharselection.cpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Client\Gui\SceneData.h">
|
RelativePath=".\Client\Gui\SceneData.h">
|
||||||
</File>
|
</File>
|
||||||
|
|||||||
@ -593,6 +593,10 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
RelativePath=".\Client\Gui\GUIEventReceiver.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
RelativePath=".\Client\Gui\DrawObjMgr.h"
|
RelativePath=".\Client\Gui\DrawObjMgr.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
@ -617,6 +621,10 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
|
RelativePath=".\Client\Gui\SceneCharselection.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
RelativePath=".\Client\Gui\Scene.h"
|
RelativePath=".\Client\Gui\Scene.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
|||||||
@ -93,6 +93,9 @@ void MapTile::ImportFromADT(ADTFile *adt)
|
|||||||
_doodads.push_back(d);
|
_doodads.push_back(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// copy sound emitters
|
||||||
|
_soundemm = adt->_soundemm;
|
||||||
|
|
||||||
_xbase = _chunks[0].basex;
|
_xbase = _chunks[0].basex;
|
||||||
_ybase = _chunks[0].basey;
|
_ybase = _chunks[0].basey;
|
||||||
_hbase = _chunks[0].baseheight;
|
_hbase = _chunks[0].baseheight;
|
||||||
|
|||||||
@ -51,6 +51,8 @@ public:
|
|||||||
inline float GetBaseHeight(void) { return _hbase; }
|
inline float GetBaseHeight(void) { return _hbase; }
|
||||||
inline uint32 GetDoodadCount(void) { return _doodads.size(); }
|
inline uint32 GetDoodadCount(void) { return _doodads.size(); }
|
||||||
inline Doodad *GetDoodad(uint32 i) { return &_doodads[i]; }
|
inline Doodad *GetDoodad(uint32 i) { return &_doodads[i]; }
|
||||||
|
inline uint32 GetSoundEmitterCount(void) { return _soundemm.size(); }
|
||||||
|
inline MCSE_chunk *GetSoundEmitter(uint32 i) { return &_soundemm[i]; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
MapChunk _chunks[256]; // 16x16
|
MapChunk _chunks[256]; // 16x16
|
||||||
@ -58,6 +60,7 @@ private:
|
|||||||
std::vector<std::string> _wmos;
|
std::vector<std::string> _wmos;
|
||||||
std::vector<std::string> _models;
|
std::vector<std::string> _models;
|
||||||
std::vector<Doodad> _doodads;
|
std::vector<Doodad> _doodads;
|
||||||
|
std::vector<MCSE_chunk> _soundemm;
|
||||||
|
|
||||||
float _xbase,_ybase,_hbase;
|
float _xbase,_ybase,_hbase;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user