* 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
|
||||
// 4: DirectX 8.1
|
||||
// 5: DirectX 9.0c
|
||||
driver=5
|
||||
driver=3
|
||||
|
||||
// resolution and more
|
||||
resx=1024
|
||||
@ -28,6 +28,12 @@ depth=32
|
||||
// 0: No (default)
|
||||
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
|
||||
|
||||
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!
|
||||
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
|
||||
HookEnd
|
||||
|
||||
// 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
|
||||
// in already present SCP files or to add custom fields or content
|
||||
// note: it DOES matter in which order paths are added!!
|
||||
// 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
|
||||
// in already present SCP files or to add custom fields or content.
|
||||
// Note: it DOES matter in which order paths are added!!
|
||||
AddDBPath ./data/scp-patches
|
||||
endif
|
||||
|
||||
@ -29,11 +29,12 @@ LoadDB creaturemodeldata
|
||||
LoadDB gameobjectdisplayinfo
|
||||
// LoadDB itemdisplayinfo // not yet used
|
||||
// LoadDB charsections // not yet used
|
||||
// LoadDB sound // not yet used
|
||||
LoadDB sound
|
||||
// LoadDB npcsound // not yet used
|
||||
|
||||
// GUI related databases
|
||||
LoadDB gui_login_text
|
||||
LoadDB gui_charselect_text
|
||||
|
||||
|
||||
log ** Databases loaded.
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
AC_PREREQ(2.61)
|
||||
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
|
||||
AM_INIT_AUTOMAKE(pseuwow, 0.1)
|
||||
#AC_CONFIG_SRCDIR([shared/ProgressBar.h])
|
||||
AM_CONFIG_HEADER([config.h])
|
||||
#AC_CONFIG_SRCDIR([src/shared/ProgressBar.h])
|
||||
AM_CONFIG_HEADER([src/config.h])
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CXX
|
||||
@ -58,18 +58,18 @@ AC_FUNC_UTIME_NULL
|
||||
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_CONFIG_FILES([dep/src/irrlicht/Makefile
|
||||
# dep/src/zlib/Makefile
|
||||
# dep/src/zthread/Makefile])
|
||||
#AC_CONFIG_SUBDIRS([dep/src/irrlicht/jpeglib
|
||||
# dep/src/irrlicht/libpng])
|
||||
AC_CONFIG_FILES([Makefile
|
||||
shared/Makefile
|
||||
shared/Auth/Makefile
|
||||
shared/Network/Makefile
|
||||
Client/Makefile
|
||||
Client/GUI/Makefile
|
||||
Client/Realm/Makefile
|
||||
Client/World/Makefile
|
||||
Client/DefScript/Makefile])
|
||||
#AC_CONFIG_FILES([src/dep/src/irrlicht/Makefile
|
||||
# src/dep/src/zlib/Makefile
|
||||
# src/dep/src/zthread/Makefile])
|
||||
#AC_CONFIG_SUBDIRS([src/dep/src/irrlicht/jpeglib
|
||||
# src/dep/src/irrlicht/libpng])
|
||||
AC_CONFIG_FILES([src/Makefile
|
||||
src/shared/Makefile
|
||||
src/shared/Auth/Makefile
|
||||
src/shared/Network/Makefile
|
||||
src/Client/Makefile
|
||||
src/Client/GUI/Makefile
|
||||
src/Client/Realm/Makefile
|
||||
src/Client/World/Makefile
|
||||
src/Client/DefScript/Makefile])
|
||||
AC_OUTPUT
|
||||
@ -1019,6 +1019,18 @@ DefReturnResult DefScriptPackage::SCGui(CmdSet &Set)
|
||||
{
|
||||
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())
|
||||
{
|
||||
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();
|
||||
_guienv = _device->getGUIEnvironment();
|
||||
_timer = _device->getTimer();
|
||||
_screendimension = _driver->getScreenSize();
|
||||
//...
|
||||
|
||||
// disable crappy irrlicht logging
|
||||
@ -139,7 +140,14 @@ void PseuGUI::_Init(void)
|
||||
{
|
||||
_soundengine = createIrrKlangDevice();
|
||||
if(_soundengine)
|
||||
{
|
||||
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
|
||||
logerror("PseuGUI: Failed to initialize sound engine!");
|
||||
}
|
||||
@ -194,7 +202,6 @@ void PseuGUI::Run(void)
|
||||
_lastpasstime = _passtime;
|
||||
_passtime = _timer->getTime();
|
||||
_passtimediff = _passtime - _lastpasstime;
|
||||
// _HandleWindowResize(); // not yet used; doesnt work
|
||||
|
||||
if (!_device->isWindowActive())
|
||||
{
|
||||
@ -209,6 +216,18 @@ void PseuGUI::Run(void)
|
||||
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
|
||||
_driver->beginScene(true, true, _scene->GetBackgroundColor()); // irr: call driver to start drawing
|
||||
_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_LOGINSCREEN: _scene = new SceneLogin(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
|
||||
}
|
||||
_scene->SetState(_scenestate_new);
|
||||
@ -334,25 +364,3 @@ WorldPosition PseuGUI::GetWorldPosition(void)
|
||||
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_GUISTART,
|
||||
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_LOADING,
|
||||
SCENESTATE_WORLD,
|
||||
@ -73,6 +73,7 @@ class PseuGUI
|
||||
friend class SceneWorld;
|
||||
friend class SceneGuiStart;
|
||||
friend class SceneLogin;
|
||||
friend class SceneCharSelection;
|
||||
// ...
|
||||
|
||||
public:
|
||||
@ -103,6 +104,7 @@ public:
|
||||
void SetSceneState(SceneState);
|
||||
bool SetSceneData(uint32, uint32);
|
||||
uint32 GetSceneState(void);
|
||||
inline void UpdateScene(void) { _updateScene = true; }
|
||||
|
||||
// helpers
|
||||
WorldPosition GetWorldPosition(void);
|
||||
@ -110,7 +112,6 @@ public:
|
||||
private:
|
||||
void _Init(void);
|
||||
void _UpdateSceneState(void);
|
||||
void _HandleWindowResize(void);
|
||||
uint16 _xres,_yres,_colordepth;
|
||||
bool _windowed,_vsync,_shadows;
|
||||
bool _initialized,_mustdie;
|
||||
@ -129,6 +130,7 @@ private:
|
||||
uint32 _passtime, _lastpasstime, _passtimediff;
|
||||
irr::core::dimension2d<irr::s32> _screendimension;
|
||||
uint32 _throttle;//used for frameratelimiting
|
||||
bool _updateScene; // manually update scene?
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -14,6 +14,7 @@ Scene::Scene(PseuGUI *g)
|
||||
driver = gui->_driver;
|
||||
smgr = gui->_smgr;
|
||||
guienv = gui->_guienv;
|
||||
rootgui = guienv->getRootGUIElement();
|
||||
cursor = new CCursorController(device->getCursorControl(), driver);
|
||||
cursor->setOSCursorVisible(true);
|
||||
cursor->setVisible(false);
|
||||
@ -35,6 +36,15 @@ void Scene::OnUpdate(s32)
|
||||
{
|
||||
}
|
||||
|
||||
void Scene::OnManualUpdate(void)
|
||||
{
|
||||
OnResize();
|
||||
}
|
||||
|
||||
void Scene::OnResize(void)
|
||||
{
|
||||
}
|
||||
|
||||
void Scene::OnDrawBegin(void)
|
||||
{
|
||||
}
|
||||
|
||||
@ -13,8 +13,24 @@ using namespace gui;
|
||||
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 CCursorController;
|
||||
class GUIEventReceiver;
|
||||
|
||||
// base class
|
||||
class Scene
|
||||
@ -27,11 +43,14 @@ public:
|
||||
inline void SetState(SceneState sc) { _scenestate = sc; }
|
||||
inline SceneState GetState(void) { return _scenestate; }
|
||||
virtual void OnUpdate(s32);
|
||||
virtual void OnManualUpdate(void);
|
||||
virtual void OnDraw(void);
|
||||
virtual void OnDrawBegin(void);
|
||||
virtual void OnDelete(void);
|
||||
virtual void OnResize(void);
|
||||
virtual video::SColor GetBackgroundColor(void);
|
||||
virtual void SetData(uint32 index, uint32 value) { scenedata[index] = value; }
|
||||
|
||||
protected:
|
||||
PseuInstance *instance;
|
||||
PseuGUI *gui;
|
||||
@ -39,6 +58,7 @@ protected:
|
||||
irr::video::IVideoDriver* driver;
|
||||
irr::scene::ISceneManager* smgr;
|
||||
irr::gui::IGUIEnvironment* guienv;
|
||||
irr::gui::IGUIElement* rootgui;
|
||||
irrklang::ISoundEngine *soundengine;
|
||||
CCursorController *cursor;
|
||||
SceneState _scenestate;
|
||||
@ -56,8 +76,6 @@ private:
|
||||
|
||||
};
|
||||
|
||||
class GUIEventReceiver;
|
||||
|
||||
class SceneLogin : public Scene
|
||||
{
|
||||
public:
|
||||
@ -66,14 +84,33 @@ public:
|
||||
void OnDelete(void);
|
||||
|
||||
private:
|
||||
gui::IGUIElement* root;
|
||||
IGUIImage *irrlogo, *background;
|
||||
GUIEventReceiver *eventrecv;
|
||||
PseuGUI* _gui;
|
||||
gui::IGUIElement *msgbox;
|
||||
gui::IGUIWindow *popup;
|
||||
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 MCameraFPS;
|
||||
class MCameraOrbit;
|
||||
@ -101,7 +138,7 @@ public:
|
||||
void InitTerrain(void);
|
||||
void RelocateCamera(void);
|
||||
void RelocateCameraBehindChar(void);
|
||||
void UpdateDoodads(void);
|
||||
void UpdateMapSceneNodes(std::map<uint32,SceneNodeWithGridPos>&);
|
||||
scene::ISceneNode *GetMyCharacterSceneNode(void);
|
||||
video::SColor GetBackgroundColor(void);
|
||||
|
||||
@ -112,7 +149,6 @@ private:
|
||||
MCameraFPS *camera;
|
||||
MyEventReceiver *eventrecv;
|
||||
ZThread::FastMutex mutex;
|
||||
PseuGUI *gui;
|
||||
uint32 map_gridX, map_gridY;
|
||||
WorldSession *wsession;
|
||||
World *world;
|
||||
@ -120,6 +156,7 @@ private:
|
||||
IGUIStaticText *debugText;
|
||||
bool debugmode;
|
||||
std::map<uint32,SceneNodeWithGridPos> _doodads;
|
||||
std::map<uint32,SceneNodeWithGridPos> _sound_emitters;
|
||||
scene::ISceneNode *sky;
|
||||
scene::ISceneNode *selectedNode, *oldSelectedNode, *focusedNode, *oldFocusedNode;
|
||||
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
|
||||
#define SCENEDATA_H
|
||||
|
||||
#define SCENEDATA_SIZE 255
|
||||
#define SCENEDATA_SIZE 256
|
||||
|
||||
// I: index, enums should start with 1
|
||||
// D: data value
|
||||
@ -10,8 +10,10 @@
|
||||
enum SceneLoginDataIndexes
|
||||
{
|
||||
ISCENE_LOGIN_CONN_STATUS = 1,
|
||||
ISCENE_LOGIN_MSGBOX_DUMMY = 2,
|
||||
ISCENE_LOGIN_END = 3
|
||||
ISCENE_LOGIN_MSGBOX_DUMMY = 2, // text
|
||||
ISCENE_LOGIN_LABELS = 3, // text
|
||||
ISCENE_LOGIN_BUTTONS = 4, // text
|
||||
ISCENE_LOGIN_END
|
||||
};
|
||||
|
||||
enum SceneLoginConnStatus
|
||||
@ -29,6 +31,44 @@ enum SceneLoginConnStatus
|
||||
DSCENE_LOGIN_UNK_ERROR = 10,
|
||||
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
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
#include "PseuWoW.h"
|
||||
#include "Scene.h"
|
||||
#include "RealmSession.h"
|
||||
#include "GUIEventReceiver.h"
|
||||
|
||||
enum GuiElementID
|
||||
{
|
||||
@ -13,37 +14,6 @@ enum GuiElementID
|
||||
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
|
||||
//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(); )
|
||||
@ -53,29 +23,39 @@ SceneLogin::SceneLogin(PseuGUI *gui) : Scene(gui)
|
||||
textdb = instance->dbmgr.GetDB("gui_login_text");
|
||||
msgbox_textid = 0;
|
||||
eventrecv = new GUIEventReceiver();
|
||||
eventrecv->keyToButtonMap[KEY_RETURN] = BUTTON_LOGON;
|
||||
eventrecv->keyToButtonMap[KEY_ESCAPE] = BUTTON_QUIT;
|
||||
device->setEventReceiver(eventrecv);
|
||||
root = guienv->getRootGUIElement();
|
||||
|
||||
dimension2d<s32> scrn = driver->getScreenSize();
|
||||
|
||||
irrlogo = guienv->addImage(driver->getTexture("data/misc/irrlichtlogo.png"), core::position2d<s32>(5,5),true,root);
|
||||
background = guienv->addImage(driver->getTexture("data/misc/sky.jpg"), 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,rootgui);
|
||||
background->setRelativePosition(rect<s32>(0,0,scrn.Width,scrn.Height));
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
core::stringw accn;
|
||||
accn += instance->GetConf()->accname.c_str();
|
||||
|
||||
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->addButton(rect<s32>(scrn.Width-120, scrn.Height-40, scrn.Width-10, scrn.Height-10), 0, 4, L"Quit");
|
||||
guienv->addButton(rect<s32>(10, scrn.Height-40, 120, scrn.Height-10), 0, 8, L"Community Site");
|
||||
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-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, 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, 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);
|
||||
|
||||
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)
|
||||
@ -92,12 +72,11 @@ void SceneLogin::OnUpdate(s32 timepassed)
|
||||
}
|
||||
if(eventrecv->buttons & BUTTON_LOGON)
|
||||
{
|
||||
eventrecv->buttons=0;
|
||||
logdebug("Commencing Logon");
|
||||
core::stringc tmp;
|
||||
tmp=root->getElementFromId(TEXTBOX_NAME,true)->getText();
|
||||
tmp=rootgui->getElementFromId(TEXTBOX_NAME,true)->getText();
|
||||
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();
|
||||
if(accname.size() && accpass.size())
|
||||
{
|
||||
@ -106,14 +85,27 @@ void SceneLogin::OnUpdate(s32 timepassed)
|
||||
// we can safely override the conf settings
|
||||
instance->GetConf()->accname = accname;
|
||||
instance->GetConf()->accpass = accpass;
|
||||
// ...but do not set the defscript vars; its just not safe
|
||||
instance->CreateRealmSession();
|
||||
}
|
||||
else
|
||||
{
|
||||
guienv->addMessageBox(GetStringFromDB(ISCENE_LOGIN_MSGBOX_DUMMY,0).c_str(),
|
||||
GetStringFromDB(ISCENE_LOGIN_MSGBOX_DUMMY,1).c_str());
|
||||
popup = guienv->addMessageBox(GetStringFromDB(ISCENE_LOGIN_MSGBOX_DUMMY,0).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;
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#include "CCursorController.h"
|
||||
#include "MovementMgr.h"
|
||||
#include "DrawObject.h"
|
||||
#include "irrKlangSceneNode.h"
|
||||
|
||||
// TODO: replace this by conf value
|
||||
#define MAX_CAM_DISTANCE 70
|
||||
@ -35,6 +36,11 @@ SceneWorld::SceneWorld(PseuGUI *g) : Scene(g)
|
||||
_CalcXYMoveVect(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);
|
||||
SLight ldata = light->getLightData();
|
||||
ldata.AmbientColor = video::SColorf(0.2f,0.2f,0.2f);
|
||||
@ -369,7 +375,7 @@ void SceneWorld::OnUpdate(s32 timediff)
|
||||
device->getCursorControl()->setPosition(mouse_pos);
|
||||
|
||||
// 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());
|
||||
// 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()"));
|
||||
_doodads.clear();
|
||||
_sound_emitters.clear();
|
||||
gui->domgr.Clear();
|
||||
delete camera;
|
||||
delete eventrecv;
|
||||
@ -543,7 +550,8 @@ void SceneWorld::UpdateTerrain(void)
|
||||
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
|
||||
|
||||
@ -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
|
||||
{
|
||||
@ -679,21 +744,21 @@ void SceneWorld::UpdateTerrain(void)
|
||||
RelocateCameraBehindChar();
|
||||
}
|
||||
|
||||
// drop unneeded doodads from the map
|
||||
void SceneWorld::UpdateDoodads(void)
|
||||
// drop unneeded map SceneNodes from the map
|
||||
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
|
||||
// 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))
|
||||
tmp.insert(it->first);
|
||||
for(std::set<uint32>::iterator it = tmp.begin(); it != tmp.end(); it++)
|
||||
{
|
||||
_doodads[*it].scenenode->remove();
|
||||
_doodads.erase(*it);
|
||||
node_map[*it].scenenode->remove();
|
||||
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)
|
||||
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()
|
||||
{
|
||||
stop();
|
||||
cube->remove();
|
||||
|
||||
if (SoundEngine)
|
||||
SoundEngine->drop();
|
||||
@ -52,6 +57,9 @@ void CIrrKlangSceneNode::OnRegisterSceneNode()
|
||||
|
||||
void CIrrKlangSceneNode::OnAnimate(u32 timeMs)
|
||||
{
|
||||
if(!SoundFileNames.size())
|
||||
return;
|
||||
|
||||
ISceneNode::OnAnimate(timeMs);
|
||||
|
||||
// play the sound
|
||||
@ -84,7 +92,8 @@ void CIrrKlangSceneNode::OnAnimate(u32 timeMs)
|
||||
else
|
||||
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())
|
||||
Sound = SoundEngine->play3D(SoundFileName.c_str(), pos, false, true, true);
|
||||
@ -105,6 +114,7 @@ void CIrrKlangSceneNode::OnAnimate(u32 timeMs)
|
||||
{
|
||||
if (!Sound)
|
||||
{
|
||||
core::stringc& SoundFileName = SoundFileNames[ rand() % SoundFileNames.size() ];
|
||||
if (SoundFileName.size())
|
||||
Sound = SoundEngine->play3D(SoundFileName.c_str(), pos, true, true, true);
|
||||
|
||||
@ -142,6 +152,7 @@ void CIrrKlangSceneNode::OnAnimate(u32 timeMs)
|
||||
else
|
||||
{
|
||||
// start
|
||||
core::stringc& SoundFileName = SoundFileNames[ rand() % SoundFileNames.size() ];
|
||||
|
||||
if (SoundFileName.size())
|
||||
Sound = SoundEngine->play3D(SoundFileName.c_str(), pos, false, true, true);
|
||||
@ -234,7 +245,7 @@ void CIrrKlangSceneNode::render()
|
||||
material.Lighting = false;
|
||||
material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
|
||||
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;
|
||||
driver->setTransform(video::ETS_WORLD, mat);
|
||||
@ -256,122 +267,6 @@ const c8* const IrrKlangPlayModeNames[] =
|
||||
"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
|
||||
ESCENE_NODE_TYPE CIrrKlangSceneNode::getType() const
|
||||
{
|
||||
@ -426,19 +321,17 @@ void CIrrKlangSceneNode::setRandomMode(int minTimeMs, int maxTimeMs)
|
||||
|
||||
|
||||
//! Sets the sound filename to play
|
||||
void CIrrKlangSceneNode::setSoundFileName(const char* soundFilename)
|
||||
void CIrrKlangSceneNode::addSoundFileName(const char* soundFilename)
|
||||
{
|
||||
if (soundFilename)
|
||||
SoundFileName = soundFilename;
|
||||
else
|
||||
SoundFileName = "";
|
||||
if (soundFilename && strlen(soundFilename))
|
||||
SoundFileNames.push_back(soundFilename);
|
||||
}
|
||||
|
||||
|
||||
//! 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
|
||||
|
||||
//! Sets the sound filename to play
|
||||
void setSoundFileName(const char* soundFilename);
|
||||
//! Adds a sound filename to play
|
||||
void addSoundFileName(const char* soundFilename);
|
||||
|
||||
//! Gets the sound filename to play
|
||||
const char* getSoundFileName() const;
|
||||
const char* getSoundFileName(u32 id) const;
|
||||
|
||||
//! Sets the minimal and maximal 3D sound distances.
|
||||
//! 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 const core::aabbox3d<f32>& getBoundingBox() const;
|
||||
virtual ESCENE_NODE_TYPE getType() const;
|
||||
ISceneNode* clone(ISceneNode* newParent, ISceneManager* newManager);
|
||||
void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options) const;
|
||||
void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options);
|
||||
|
||||
scene::ISceneNode *getDebugCube(void) { return cube; }
|
||||
scene::ITextSceneNode *getDebugText(void) { return text; }
|
||||
|
||||
protected:
|
||||
|
||||
@ -110,7 +110,7 @@ protected:
|
||||
irrklang::ISoundEngine* SoundEngine;
|
||||
irrklang::ISound* Sound;
|
||||
|
||||
core::stringc SoundFileName;
|
||||
core::array<core::stringc> SoundFileNames;
|
||||
f32 MinDistance;
|
||||
f32 MaxDistance;
|
||||
|
||||
@ -120,6 +120,8 @@ protected:
|
||||
s32 MaxTimeMsInterval;
|
||||
s32 MinTimeMsInterval;
|
||||
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());
|
||||
fognear = atof(v.Get("GUI::FOGNEAR").c_str());
|
||||
fov = atof(v.Get("GUI::FOV").c_str());
|
||||
masterSoundVolume = atof(v.Get("GUI::MASTERSOUNDVOLUME").c_str());
|
||||
|
||||
log_setloglevel(debug);
|
||||
}
|
||||
|
||||
@ -69,6 +69,9 @@ class PseuInstanceConf
|
||||
float fognear;
|
||||
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>
|
||||
};
|
||||
|
||||
#define ChunkSize 2048
|
||||
|
||||
struct SRealmHeader
|
||||
{
|
||||
uint8 cmd; // OP code = CMD_REALM_LIST
|
||||
@ -51,19 +49,6 @@ struct SRealmHeader
|
||||
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
|
||||
{
|
||||
uint32 cmd;
|
||||
@ -260,39 +245,47 @@ void RealmSession::_HandleRealmList(ByteBuffer& pkt)
|
||||
if(count==0)
|
||||
return;
|
||||
|
||||
// alloc space for as many realms as needed
|
||||
SRealmInfo *realms=new SRealmInfo[count];
|
||||
_realms.clear();
|
||||
_realms.resize(count);
|
||||
|
||||
// readout realms
|
||||
for(uint8 i=0;i<count;i++)
|
||||
{
|
||||
pkt >> realms[i].icon;
|
||||
pkt >> realms[i].locked;
|
||||
pkt >> realms[i].color;
|
||||
pkt >> realms[i].name;
|
||||
pkt >> realms[i].addr_port;
|
||||
pkt >> realms[i].population;
|
||||
pkt >> realms[i].chars_here;
|
||||
pkt >> realms[i].timezone;
|
||||
pkt >> realms[i].unknown;
|
||||
pkt >> _realms[i].icon;
|
||||
pkt >> _realms[i].locked;
|
||||
pkt >> _realms[i].color;
|
||||
pkt >> _realms[i].name;
|
||||
pkt >> _realms[i].addr_port;
|
||||
pkt >> _realms[i].population;
|
||||
pkt >> _realms[i].chars_here;
|
||||
pkt >> _realms[i].timezone;
|
||||
pkt >> _realms[i].unknown;
|
||||
}
|
||||
|
||||
// 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());
|
||||
logdetail(" [chars:%d][population:%f][timezone:%d]",realms[i].chars_here,realms[i].population,realms[i].timezone);
|
||||
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);
|
||||
}
|
||||
delete [] realms;
|
||||
|
||||
// now setup where the worldserver is and how to login there
|
||||
if(realmAddr.empty()){
|
||||
log("Realm \"%s\" was not found on the realmlist!",GetInstance()->GetConf()->realmname.c_str());
|
||||
if(realmAddr.empty())
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
@ -300,17 +293,24 @@ void RealmSession::_HandleRealmList(ByteBuffer& pkt)
|
||||
// -> convert the worldserver port from string to int
|
||||
// -> write it into the config & set appropriate vars
|
||||
|
||||
uint16 colonpos=realmAddr.find(":");
|
||||
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)));
|
||||
SetRealmAddr(realmAddr);
|
||||
|
||||
// now we have the correct addr/port, time to create the WorldSession
|
||||
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)
|
||||
{
|
||||
_accname=GetInstance()->GetConf()->accname;
|
||||
@ -557,7 +557,7 @@ void RealmSession::_HandleLogonProof(ByteBuffer& pkt)
|
||||
if(gui)
|
||||
gui->SetSceneData(ISCENE_LOGIN_CONN_STATUS, DSCENE_LOGIN_AUTH_FAILED);
|
||||
logerror("Wrong password or invalid account information or authentication error");
|
||||
DieOrReconnect(true);
|
||||
DieOrReconnect(false);
|
||||
return;
|
||||
|
||||
// cover all other cases. continue only if success.
|
||||
|
||||
@ -4,6 +4,19 @@
|
||||
#include "common.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;
|
||||
class RealmSocket;
|
||||
|
||||
@ -22,6 +35,9 @@ public:
|
||||
bool MustDie(void);
|
||||
void SetMustDie(void);
|
||||
bool SocketGood(void);
|
||||
void SetRealmAddr(std::string);
|
||||
inline uint32 GetRealmCount(void) { return _realms.size(); }
|
||||
inline SRealmInfo& GetRealm(uint32 i) { return _realms[i]; }
|
||||
|
||||
|
||||
private:
|
||||
@ -48,6 +64,7 @@ private:
|
||||
uint64 _file_done, _file_size;
|
||||
ByteBuffer _filebuf;
|
||||
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);
|
||||
if(it != _fielddefs.end())
|
||||
return _fielddefs[entry].type;
|
||||
return it->second.type;
|
||||
return SCP_INVALID_INT;
|
||||
}
|
||||
|
||||
@ -150,7 +150,7 @@ uint32 SCPDatabase::GetFieldId(char *entry)
|
||||
{
|
||||
std::map<std::string,SCPFieldDef>::iterator it = _fielddefs.find(entry);
|
||||
if(it != _fielddefs.end())
|
||||
return _fielddefs[entry].id;
|
||||
return it->second.id;
|
||||
return SCP_INVALID_INT;
|
||||
}
|
||||
|
||||
|
||||
@ -42,9 +42,18 @@ WorldSession::~WorldSession()
|
||||
{
|
||||
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");
|
||||
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)
|
||||
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);
|
||||
_socket=new WorldSocket(_sh,this);
|
||||
_socket->Open(GetInstance()->GetConf()->worldhost,GetInstance()->GetConf()->worldport);
|
||||
if(GetInstance()->GetRSession())
|
||||
{
|
||||
GetInstance()->GetRSession()->SetMustDie(); // realm session is no longer needed
|
||||
}
|
||||
_sh.Add(_socket);
|
||||
|
||||
// if we cant connect, wait until the socket gives up (after 5 secs)
|
||||
@ -546,6 +551,8 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
|
||||
uint8 dummy8;
|
||||
uint32 dummy32;
|
||||
|
||||
_charList.clear();
|
||||
|
||||
recvPacket >> num;
|
||||
if(num==0)
|
||||
{
|
||||
@ -556,6 +563,7 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
|
||||
|
||||
logdetail("Chars in list: %u",num);
|
||||
_LoadCache(); // we are about to login, so we need cache data
|
||||
// TODO: load cache on loadingscreen
|
||||
for(unsigned int i=0;i<num;i++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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;
|
||||
|
||||
@ -607,6 +616,14 @@ void WorldSession::_HandleCharEnumOpcode(WorldPacket& recvPacket)
|
||||
if(classdb)
|
||||
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",
|
||||
plr[i]._name.c_str(),
|
||||
plr[i]._level,
|
||||
@ -623,43 +640,76 @@ 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)
|
||||
if(plr[i]._name==GetInstance()->GetConf()->charname || num == 1)
|
||||
{
|
||||
charId = i;
|
||||
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)
|
||||
{
|
||||
logerror("Character \"%s\" was not found on char list!", GetInstance()->GetConf()->charname.c_str());
|
||||
GetInstance()->SetError();
|
||||
return;
|
||||
if(PseuGUI *gui = GetInstance()->GetGUI())
|
||||
{
|
||||
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
|
||||
{
|
||||
log("Entering World with Character \"%s\"...", 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);
|
||||
EnterWorldWithCharacter(plr[charId]._name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
@ -39,7 +39,19 @@ struct DelayedWorldPacket
|
||||
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<CharacterListExt> CharList;
|
||||
typedef std::deque<DelayedWorldPacket> DelayedPacketQueue;
|
||||
|
||||
class WorldSession
|
||||
@ -75,6 +87,10 @@ public:
|
||||
std::string GetOrRequestPlayerName(uint64);
|
||||
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
|
||||
void SendChatMessage(uint32 type, uint32 lang, std::string msg, std::string to="");
|
||||
@ -160,8 +176,10 @@ private:
|
||||
uint64 _myGUID;
|
||||
World *_world;
|
||||
WhoList _whoList;
|
||||
CharList _charList;
|
||||
uint32 _lag_ms;
|
||||
std::bitset<MAX_OPCODE_ID> _disabledOpcodes;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@ -127,4 +127,5 @@ void WorldSocket::InitCrypt(BigNumber *k)
|
||||
{
|
||||
_crypt.SetKey(k);
|
||||
_crypt.Init();
|
||||
logdebug("WorldSocket: Crypt initialized");
|
||||
}
|
||||
|
||||
@ -444,6 +444,9 @@
|
||||
<File
|
||||
RelativePath=".\Client\Gui\DrawObjMgr.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\Gui\GUIEventReceiver.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\Gui\MCamera.h">
|
||||
</File>
|
||||
@ -462,6 +465,9 @@
|
||||
<File
|
||||
RelativePath=".\Client\Gui\Scene.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\Gui\SceneCharselection.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\Gui\SceneData.h">
|
||||
</File>
|
||||
|
||||
@ -593,6 +593,10 @@
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\Gui\GUIEventReceiver.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\Gui\DrawObjMgr.h"
|
||||
>
|
||||
</File>
|
||||
@ -617,6 +621,10 @@
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\Gui\SceneCharselection.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Client\Gui\Scene.h"
|
||||
>
|
||||
</File>
|
||||
|
||||
@ -93,6 +93,9 @@ void MapTile::ImportFromADT(ADTFile *adt)
|
||||
_doodads.push_back(d);
|
||||
}
|
||||
|
||||
// copy sound emitters
|
||||
_soundemm = adt->_soundemm;
|
||||
|
||||
_xbase = _chunks[0].basex;
|
||||
_ybase = _chunks[0].basey;
|
||||
_hbase = _chunks[0].baseheight;
|
||||
|
||||
@ -51,6 +51,8 @@ public:
|
||||
inline float GetBaseHeight(void) { return _hbase; }
|
||||
inline uint32 GetDoodadCount(void) { return _doodads.size(); }
|
||||
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:
|
||||
MapChunk _chunks[256]; // 16x16
|
||||
@ -58,6 +60,7 @@ private:
|
||||
std::vector<std::string> _wmos;
|
||||
std::vector<std::string> _models;
|
||||
std::vector<Doodad> _doodads;
|
||||
std::vector<MCSE_chunk> _soundemm;
|
||||
|
||||
float _xbase,_ybase,_hbase;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user