Merge branch 'atys' into merge-into-atys

feature/develop-atys
Nuno 4 years ago
commit 6c3d6403b0

@ -1,27 +1,28 @@
4eddbaff0c5e5d685db96ee3e8427aa0fd96ac83 v0.8.0 4eddbaff0c5e5d685db96ee3e8427aa0fd96ac83 ryzomcore/v0.8.0
00d9b6e29e95f56785fbf85abe60afd34674f402 v0.9.0 00d9b6e29e95f56785fbf85abe60afd34674f402 ryzomcore/v0.9.0
79776c337176dd5b02e1a74fe5dfb703b91747aa v0.9.1 79776c337176dd5b02e1a74fe5dfb703b91747aa ryzomcore/v0.9.1
fedf2aa443d09707beed814b0f499c6a5519cc84 v0.10.0 fedf2aa443d09707beed814b0f499c6a5519cc84 ryzomcore/v0.10.0
edaa3624a56420b02ccc64c26059801a389927ee v0.11.0 edaa3624a56420b02ccc64c26059801a389927ee ryzomcore/v0.11.0
e3fe4855f22c3e75722e015dc33c091c340b3ad7 v0.11.1 e3fe4855f22c3e75722e015dc33c091c340b3ad7 ryzomcore/v0.11.1
9e583b717fd63be0be9fd60b99087abf1691ea49 v0.11.2 9e583b717fd63be0be9fd60b99087abf1691ea49 ryzomcore/v0.11.2
bfe5628e14a024ba7ea32e4b326ae433a07856b9 v0.11.3 bfe5628e14a024ba7ea32e4b326ae433a07856b9 ryzomcore/v0.11.3
9a6120735daa97c96ac5d85ca35c7f21f607bd87 v0.12.0 9a6120735daa97c96ac5d85ca35c7f21f607bd87 ryzomcore/v0.12.0
3e92c7104c20d6bc6c2147b4b5fc289e8621d322 v1.0.0 3e17907af67e8d66d80e6b714707bbf912607f2a ryzom-patch-3.0.0
8eb94c3549be898fdc4a7c6d791d2477bdc11a18 v1.0.1 153e0b605c9e0c83ba05b6428c62838b49cc84b2 ryzom-patch-3.0.1
3e17907af67e8d66d80e6b714707bbf912607f2a ryzom/3.0.0 9d41f2994d44b9aad92b83f945f114e4b6bed44a ryzom-patch-3.0.2
153e0b605c9e0c83ba05b6428c62838b49cc84b2 ryzom/3.0.1 4300cc14aad098b1f86ea4c55577b7fa4a4cb5d2 ryzom-patch-3.1.0
9d41f2994d44b9aad92b83f945f114e4b6bed44a ryzom/3.0.2 d4060f217f4f834cc62a33f2f1ccdf3c28298066 ryzom-patch-3.1.0-hotfix
4300cc14aad098b1f86ea4c55577b7fa4a4cb5d2 ryzom/3.1.0 043aaeb3d8a2a54177581b57bda87a9deaad510e ryzom-patch-3.1.0-april_patch
d4060f217f4f834cc62a33f2f1ccdf3c28298066 ryzom/3.1.0-hotfix 4036ecf59e83960f03acebc2089eb2ff5eeaed0a ryzom-patch-3.2.0
043aaeb3d8a2a54177581b57bda87a9deaad510e ryzom/3.1.0-april_patch 18403bb9485da3d9742c6f007a16d5619ebfb196 ryzom-patch-3.2.1
4036ecf59e83960f03acebc2089eb2ff5eeaed0a ryzom/3.2.0 822ff8f8917ad66e09e2c21c983282f6f693b9f6 ryzom-patch-3.3.0
18403bb9485da3d9742c6f007a16d5619ebfb196 ryzom/3.2.1 00dde390a394fce9da06c2f3264140282158d39f ryzom-patch-3.3.0
822ff8f8917ad66e09e2c21c983282f6f693b9f6 ryzom/3.3.0 dcd4c4d161ef775136e18c7e8f5072b75dede27e ryzom-patch-3.3.1
00dde390a394fce9da06c2f3264140282158d39f ryzom/3.3.0 fc4be8ebec5ca754ef4453bc6a9faef90837c674 ryzom-patch-3.4.0
dcd4c4d161ef775136e18c7e8f5072b75dede27e ryzom/3.3.1 70eba02e8eab6920586dbabf74e9e8180c729980 ryzom-patch-3.4.0 Steam Fix
fc4be8ebec5ca754ef4453bc6a9faef90837c674 ryzom/3.4.0 3941482843f9cd130cfc16634efc08d34a98ed35 ryzom-patch-3.4.0 Atysmas
70eba02e8eab6920586dbabf74e9e8180c729980 ryzom/3.4.0-steam_fix ecae9feb4cceb78103e5d7236caccaf450796cdb ryzom-patch-3.5.0
3941482843f9cd130cfc16634efc08d34a98ed35 ryzom/3.4.0-atysmas 95783afa226f241062134eb62f4323295d29ac84 ryzom-patch-3.5.0.9637
ecae9feb4cceb78103e5d7236caccaf450796cdb ryzom/3.5.0 2102fb276eb69d49ed4923042215312a63c47c08 Live-746
95783afa226f241062134eb62f4323295d29ac84 ryzom/3.5.0.9637 8eb94c3549be898fdc4a7c6d791d2477bdc11a18 ryzomcore/v1.0.1
3e92c7104c20d6bc6c2147b4b5fc289e8621d322 ryzomcore/v1.0.0

@ -102,6 +102,7 @@ SET(RYZOM_CLIENT_CREATE_ACCOUNT_URL "https://open.ryzom.dev/ams/" CACHE STRING
SET(RYZOM_CLIENT_EDIT_ACCOUNT_URL "https://open.ryzom.dev/ams/" CACHE STRING "Ryzom Client Edit Account URL") SET(RYZOM_CLIENT_EDIT_ACCOUNT_URL "https://open.ryzom.dev/ams/" CACHE STRING "Ryzom Client Edit Account URL")
SET(RYZOM_CLIENT_FORGET_PASSWORD_URL "https://open.ryzom.dev/ams/" CACHE STRING "Ryzom Client Forget Password URL") SET(RYZOM_CLIENT_FORGET_PASSWORD_URL "https://open.ryzom.dev/ams/" CACHE STRING "Ryzom Client Forget Password URL")
SET(RYZOM_CLIENT_PATCH_URL "https://cdn.ryzom.dev/open/patch/" CACHE STRING "Ryzom Client Patch URL") SET(RYZOM_CLIENT_PATCH_URL "https://cdn.ryzom.dev/open/patch/" CACHE STRING "Ryzom Client Patch URL")
SET(RYZOM_CLIENT_APP_NAME "default")
SET(RYZOM_WEBIG_MAIN_URL "https://open.ryzom.dev/" CACHE STRING "Ryzom Client WebIG Main URL") SET(RYZOM_WEBIG_MAIN_URL "https://open.ryzom.dev/" CACHE STRING "Ryzom Client WebIG Main URL")
SET(RYZOM_WEBIG_TRUSTED_DOMAIN "open.ryzom.dev" CACHE STRING "Ryzom Client WebIG Trusted Domain") SET(RYZOM_WEBIG_TRUSTED_DOMAIN "open.ryzom.dev" CACHE STRING "Ryzom Client WebIG Trusted Domain")
@ -114,6 +115,7 @@ IF(WITH_RYZOM_LIVE)
SET(RYZOM_CLIENT_EDIT_ACCOUNT_URL "https://account.ryzom.com/payment_profile/index.php") SET(RYZOM_CLIENT_EDIT_ACCOUNT_URL "https://account.ryzom.com/payment_profile/index.php")
SET(RYZOM_CLIENT_FORGET_PASSWORD_URL "https://account.ryzom.com/payment_profile/lost_secure_password.php") SET(RYZOM_CLIENT_FORGET_PASSWORD_URL "https://account.ryzom.com/payment_profile/lost_secure_password.php")
SET(RYZOM_CLIENT_PATCH_URL "http://dl.ryzom.com/patch_live") SET(RYZOM_CLIENT_PATCH_URL "http://dl.ryzom.com/patch_live")
SET(RYZOM_CLIENT_APP_NAME "ryzom_live")
SET(RYZOM_WEBIG_MAIN_URL "https://app.ryzom.com/") SET(RYZOM_WEBIG_MAIN_URL "https://app.ryzom.com/")
SET(RYZOM_WEBIG_TRUSTED_DOMAIN "app.ryzom.com") SET(RYZOM_WEBIG_TRUSTED_DOMAIN "app.ryzom.com")
@ -175,6 +177,20 @@ IF(WITH_STATIC)
IF(LIBLZMA_LIBRARIES) IF(LIBLZMA_LIBRARIES)
SET(LIBXML2_LIBRARIES ${LIBXML2_LIBRARIES} ${LIBLZMA_LIBRARIES}) SET(LIBXML2_LIBRARIES ${LIBXML2_LIBRARIES} ${LIBLZMA_LIBRARIES})
ENDIF() ENDIF()
# under Linux and OS X, recent libxml2 versions are linked against libicu
# FIND_PACKAGE(Icu)
FIND_LIBRARY(ICU_LIBRARY icuuc)
IF(ICU_LIBRARY)
FIND_LIBRARY(ICU_DATA_LIBRARY icudata)
IF(ICU_LIBRARY)
MESSAGE(STATUS "ICU UC was found: ${ICU_LIBRARY}")
ELSE()
MESSAGE(STATUS "ICU UC was NOT found")
ENDIF()
SET(LIBXML2_LIBRARIES ${LIBXML2_LIBRARIES} ${ICU_DATA_LIBRARY} ${ICU_LIBRARY})
ENDIF()
ENDIF() ENDIF()
ENDIF() ENDIF()

@ -37,6 +37,7 @@
#cmakedefine RYZOM_CLIENT_EDIT_ACCOUNT_URL "${RYZOM_CLIENT_EDIT_ACCOUNT_URL}" #cmakedefine RYZOM_CLIENT_EDIT_ACCOUNT_URL "${RYZOM_CLIENT_EDIT_ACCOUNT_URL}"
#cmakedefine RYZOM_CLIENT_FORGET_PASSWORD_URL "${RYZOM_CLIENT_FORGET_PASSWORD_URL}" #cmakedefine RYZOM_CLIENT_FORGET_PASSWORD_URL "${RYZOM_CLIENT_FORGET_PASSWORD_URL}"
#cmakedefine RYZOM_CLIENT_PATCH_URL "${RYZOM_CLIENT_PATCH_URL}" #cmakedefine RYZOM_CLIENT_PATCH_URL "${RYZOM_CLIENT_PATCH_URL}"
#cmakedefine RYZOM_CLIENT_APP_NAME "${RYZOM_CLIENT_APP_NAME}"
#cmakedefine RYZOM_WEBIG_MAIN_URL "${RYZOM_WEBIG_MAIN_URL}" #cmakedefine RYZOM_WEBIG_MAIN_URL "${RYZOM_WEBIG_MAIN_URL}"
#cmakedefine RYZOM_WEBIG_TRUSTED_DOMAIN "${RYZOM_WEBIG_TRUSTED_DOMAIN}" #cmakedefine RYZOM_WEBIG_TRUSTED_DOMAIN "${RYZOM_WEBIG_TRUSTED_DOMAIN}"

@ -177,6 +177,7 @@ namespace NLGUI
bool _MouseDown : 1; bool _MouseDown : 1;
bool _CallingAH : 1; bool _CallingAH : 1;
bool _Cancelable : 1; // true if the slider may be cancelled when pressed on the mouse right button bool _Cancelable : 1; // true if the slider may be cancelled when pressed on the mouse right button
bool _Keyboard : 1;
bool _Frozen : 1; bool _Frozen : 1;
bool _Scale : 1; bool _Scale : 1;

@ -127,6 +127,16 @@ namespace NLGUI
void setTexturePushed(const std::string &l, const std::string &m, const std::string &r); void setTexturePushed(const std::string &l, const std::string &m, const std::string &r);
void setTextureOver(const std::string &l, const std::string &m, const std::string &r); void setTextureOver(const std::string &l, const std::string &m, const std::string &r);
// lua
void setTextureLua (const std::string &name);
void setTexturePushedLua (const std::string &name);
void setTextureOverLua (const std::string &name);
// return texture _l.tga
std::string getTexture () const;
std::string getTexturePushed () const;
std::string getTextureOver() const;
int luaGetViewText(CLuaState &ls); int luaGetViewText(CLuaState &ls);
REFLECT_EXPORT_START(CCtrlTextButton, CCtrlBaseButton) REFLECT_EXPORT_START(CCtrlTextButton, CCtrlBaseButton)
@ -137,6 +147,9 @@ namespace NLGUI
REFLECT_SINT32("wmin", getWMin, setWMin) REFLECT_SINT32("wmin", getWMin, setWMin)
REFLECT_SINT32("hmin", getHMin, setHMin) REFLECT_SINT32("hmin", getHMin, setHMin)
REFLECT_LUA_METHOD("getViewText", luaGetViewText) REFLECT_LUA_METHOD("getViewText", luaGetViewText)
REFLECT_STRING("texture", getTexture, setTextureLua);
REFLECT_STRING("texture_pushed", getTexturePushed, setTexturePushedLua);
REFLECT_STRING("texture_over", getTextureOver, setTextureOverLua);
REFLECT_EXPORT_END REFLECT_EXPORT_END
void onRemoved(); void onRemoved();

@ -27,6 +27,7 @@
#include "nel/gui/ctrl_button.h" #include "nel/gui/ctrl_button.h"
#include "nel/gui/group_table.h" #include "nel/gui/group_table.h"
#include "nel/gui/html_element.h" #include "nel/gui/html_element.h"
#include "nel/gui/html_parser.h"
#include "nel/gui/css_style.h" #include "nel/gui/css_style.h"
// forward declaration // forward declaration
@ -115,6 +116,9 @@ namespace NLGUI
// Browse error // Browse error
void browseError (const char *msg); void browseError (const char *msg);
// Error message with html content
void browseErrorHtml(const std::string &html);
bool isBrowsing(); bool isBrowsing();
// Update coords // Update coords
@ -375,7 +379,9 @@ namespace NLGUI
// true if renderer is waiting for css files to finish downloading (link rel=stylesheet) // true if renderer is waiting for css files to finish downloading (link rel=stylesheet)
bool _WaitingForStylesheet; bool _WaitingForStylesheet;
// list of css file urls that are queued up for download // list of css file urls that are queued up for download
std::vector<std::string> _StylesheetQueue; std::vector<CHtmlParser::StyleLink> _StylesheetQueue;
// <style> and downloaded <link rel=stylesheet> elements
std::vector<std::string> _HtmlStyles;
// Valid base href was found // Valid base href was found
bool _IgnoreBaseUrlTag; bool _IgnoreBaseUrlTag;
@ -854,6 +860,7 @@ namespace NLGUI
CCurlWWWData *data; CCurlWWWData *data;
std::string url; std::string url;
std::string dest; std::string dest;
std::string tmpdest;
std::string luaScript; std::string luaScript;
std::string md5sum; std::string md5sum;
TDataType type; TDataType type;
@ -889,7 +896,7 @@ namespace NLGUI
std::string localBnpName(const std::string &url); std::string localBnpName(const std::string &url);
// add css file from <link href=".." rel="stylesheet"> to download queue // add css file from <link href=".." rel="stylesheet"> to download queue
void addStylesheetDownload(std::vector<std::string> links); void addStylesheetDownload(std::vector<CHtmlParser::StyleLink> links);
// stop all curl downalods (html and data) // stop all curl downalods (html and data)
void releaseDownloads(); void releaseDownloads();

@ -54,6 +54,8 @@ namespace NLGUI
Right Right
}; };
enum TTextAlign { AlignLeft = 0, AlignCenter, AlignRight, AlignJustify };
///constructor ///constructor
CGroupParagraph(const TCtorParam &param); CGroupParagraph(const TCtorParam &param);
@ -97,6 +99,8 @@ namespace NLGUI
// the same, but with id taken from the database // the same, but with id taken from the database
void addTextChildID (const std::string &dbPath, bool multiLine = true); void addTextChildID (const std::string &dbPath, bool multiLine = true);
void setTextAlign(const TTextAlign align) { _TextAlign = align; }
protected: protected:
void delChild (CViewBase* child); void delChild (CViewBase* child);
@ -270,6 +274,9 @@ namespace NLGUI
// (the element drawn are stored in _views, _contrlos or _childrengroups of cinterfacegroup // (the element drawn are stored in _views, _contrlos or _childrengroups of cinterfacegroup
std::vector<CElementInfo> _Elements; std::vector<CElementInfo> _Elements;
// Horizontal align for elements
TTextAlign _TextAlign;
// Last parent width // Last parent width
sint32 _LastW; sint32 _LastW;

@ -31,14 +31,23 @@ namespace NLGUI
class CHtmlParser class CHtmlParser
{ {
public: public:
// <link rel=stylesheet>
struct StyleLink
{
uint Index;
std::string Url;
StyleLink(uint i, const std::string &url) : Index(i), Url(url)
{ }
};
bool parseHtml(std::string htmlString) const; bool parseHtml(std::string htmlString) const;
// parse html string into DOM, extract <style> tags into styleString, <link stylesheet> urls into links // parse html string into DOM, extract <style> and <link stylesheet> urls
void getDOM(std::string htmlString, CHtmlElement &parent, std::string &styleString, std::vector<std::string> &links) const; void getDOM(std::string htmlString, CHtmlElement &parent, std::vector<std::string> &styles, std::vector<StyleLink> &links) const;
private: private:
// iterate over libxml html tree, build DOM, and join all <style> tags together // iterate over libxml html tree, build DOM
void parseNode(xmlNode *a_node, CHtmlElement &parent, std::string &styleString, std::vector<std::string> &links) const; void parseNode(xmlNode *a_node, CHtmlElement &parent, std::vector<std::string> &styles, std::vector<StyleLink> &links) const;
// read <style> tag and add its content to styleString // read <style> tag and add its content to styleString
void parseStyle(xmlNode *a_node, std::string &styleString) const; void parseStyle(xmlNode *a_node, std::string &styleString) const;

@ -444,9 +444,13 @@ namespace NLGUI
SGlobalTexture () SGlobalTexture ()
{ {
FromGlobaleTexture = true; FromGlobaleTexture = true;
Scale = 1.f;
} }
uint32 Width, Height; uint32 Width, Height;
uint32 DefaultWidth, DefaultHeight; uint32 DefaultWidth, DefaultHeight;
// used by texture atlas to unscale individual texture
// getTextureSizeFromId() calls to return 1x size for GUI.
float Scale;
NL3D::UTexture *Texture; NL3D::UTexture *Texture;
std::string Name; std::string Name;
bool FromGlobaleTexture; bool FromGlobaleTexture;

@ -246,9 +246,10 @@ inline bool fromString(const std::string &str, sint64 &val) { bool ret = sscanf(
inline bool fromString(const std::string &str, float &val) { bool ret = sscanf(str.c_str(), "%f", &val) == 1; if (!ret) val = 0.0f; return ret; } inline bool fromString(const std::string &str, float &val) { bool ret = sscanf(str.c_str(), "%f", &val) == 1; if (!ret) val = 0.0f; return ret; }
inline bool fromString(const std::string &str, double &val) { bool ret = sscanf(str.c_str(), "%lf", &val) == 1; if (!ret) val = 0.0; return ret; } inline bool fromString(const std::string &str, double &val) { bool ret = sscanf(str.c_str(), "%lf", &val) == 1; if (!ret) val = 0.0; return ret; }
// Fast string to bool, reliably defined for strings starting with 0, 1, t, T, f, F, y, Y, n, N, anything else is undefined. /// Fast string to bool, reliably defined for strings starting with 0, 1, t, T, f, F, y, Y, n, N, and empty strings, anything else is undefined.
// (str[0] == '1' || (str[0] & 0xD2) == 0x50) /// - Kaetemi
// - Kaetemi inline bool toBool(const char *str) { return str[0] == '1' || (str[0] & 0xD2) == 0x50; }
inline bool toBool(const std::string &str) { return toBool(str.c_str()); } // Safe because first byte may be null
bool fromString(const std::string &str, bool &val); bool fromString(const std::string &str, bool &val);

@ -0,0 +1,74 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef XML_MACROS_H
#define XML_MACROS_H
//
// xmlNodePtr cur;
// CXMLAutoPtr prop;
//
// sint i;
// XML_READ_SINT(cur, "prop_name", i, -1);
//
#define XML_READ_UINT(node, name, var, def) { \
uint tmp; \
prop = (char *) xmlGetProp(node, (xmlChar*)name); \
if (prop && fromString((const char*)prop, tmp)) \
var = tmp; \
else \
var = def; \
}
#define XML_READ_SINT(node, name, var, def) { \
sint tmp; \
prop = (char *) xmlGetProp(node, (xmlChar*)name); \
if (prop && fromString((const char*)prop, tmp)) \
var = tmp; \
else \
var = def; \
}
#define XML_READ_BOOL(node, name, var, def) { \
prop = (char *) xmlGetProp(node, (xmlChar*)name); \
if (prop) \
var = NLMISC::toBool((const char*)prop); \
else \
var = def; \
}
#define XML_READ_COLOR(node, name, var, def) { \
NLMISC::CRGBA tmp; \
prop = (char *) xmlGetProp(node, (xmlChar*)name); \
if (prop && fromString((const char*)prop, tmp)) \
var = tmp; \
else \
var = def; \
}
#define XML_READ_STRING(node, name, var, def) { \
prop = (char *) xmlGetProp(node, (xmlChar*)name); \
if (prop) \
var = (const char*)prop; \
else \
var = def; \
}
#endif // XML_MACROS_H

@ -191,7 +191,7 @@ public:
/// Create a native music channel, only supported by the FMod driver. /// Create a native music channel, only supported by the FMod driver.
virtual IMusicChannel *createMusicChannel() { return NULL; } virtual IMusicChannel *createMusicChannel() { return NULL; }
/** Get music info. Returns false if the song is not found or the function is not implemented. /** Get music info. Returns false if the song is not found or the function is not implemented.
* \param filepath path to file, CPath::lookup done by driver * \param filepath full path to file
* \param artist returns the song artist (empty if not available) * \param artist returns the song artist (empty if not available)
* \param title returns the title (empty if not available) * \param title returns the title (empty if not available)
*/ */

@ -1275,7 +1275,7 @@ static bool setupNVFragmentProgram2(const char *glext)
{ {
H_AUTO_OGL(setupNVFragmentProgram2); H_AUTO_OGL(setupNVFragmentProgram2);
CHECK_EXT("GL_NV_fragment_program2"); CHECK_EXT("GL_NV_fragment_program2");
return true; return true;
} }
@ -1284,7 +1284,7 @@ static bool setupARBFragmentShader(const char *glext)
{ {
H_AUTO_OGL(setupNVFragmentProgram2); H_AUTO_OGL(setupNVFragmentProgram2);
CHECK_EXT("GL_ARB_fragment_shader"); CHECK_EXT("GL_ARB_fragment_shader");
return true; return true;
} }
@ -1584,6 +1584,14 @@ void registerGlExtensions(CGlExtensions &ext)
{ {
H_AUTO_OGL(registerGlExtensions); H_AUTO_OGL(registerGlExtensions);
#ifdef NL_OS_MAC
CGLContextObj ctx = CGLGetCurrentContext();
if (ctx == NULL)
{
nlerror("No OpenGL context set");
}
#endif
// OpenGL 1.2 ?? // OpenGL 1.2 ??
const char *nglVersion = (const char *)glGetString (GL_VERSION); const char *nglVersion = (const char *)glGetString (GL_VERSION);
@ -1691,12 +1699,12 @@ void registerGlExtensions(CGlExtensions &ext)
ext.EXTVertexShader = false; ext.EXTVertexShader = false;
ext.ARBVertexProgram = false; ext.ARBVertexProgram = false;
} }
// Check pixel program // Check pixel program
// Disable feature ??? // Disable feature ???
if (!ext.DisableHardwarePixelProgram) if (!ext.DisableHardwarePixelProgram)
{ {
ext.ARBFragmentProgram = setupARBFragmentProgram(glext); ext.ARBFragmentProgram = setupARBFragmentProgram(glext);
ext.NVFragmentProgram2 = setupNVFragmentProgram2(glext); ext.NVFragmentProgram2 = setupNVFragmentProgram2(glext);
ext.ARBFragmentShader = setupARBFragmentShader(glext); ext.ARBFragmentShader = setupARBFragmentShader(glext);
} }

@ -1072,6 +1072,9 @@ bool CDriverGL::setDisplay(nlWindow wnd, const GfxMode &mode, bool show, bool re
[_ctx flushBuffer]; [_ctx flushBuffer];
[_glView display]; [_glView display];
// Set context as thread context
CGLSetCurrentContext((CGLContextObj)[_ctx CGLContextObj]);
_EventEmitter.init(this, _glView, _DestroyWindow); _EventEmitter.init(this, _glView, _DestroyWindow);
#elif defined(NL_OS_UNIX) #elif defined(NL_OS_UNIX)

@ -57,6 +57,7 @@ namespace NLGUI
_MouseDown = false; _MouseDown = false;
_CallingAH = false; _CallingAH = false;
_Cancelable = false; _Cancelable = false;
_Keyboard = false;
_Target = NULL; _Target = NULL;
_Inverted = false; _Inverted = false;
_IsDBLink = false; _IsDBLink = false;
@ -225,6 +226,11 @@ namespace NLGUI
return toString( _Cancelable ); return toString( _Cancelable );
} }
else else
if( name == "keyboard" )
{
return toString( _Keyboard );
}
else
if( name == "frozen" ) if( name == "frozen" )
{ {
return toString( _Frozen ); return toString( _Frozen );
@ -405,6 +411,14 @@ namespace NLGUI
return; return;
} }
else else
if( name == "keyboard" )
{
bool b;
if( fromString( value, b ) )
_Keyboard = b;
return;
}
else
if( name == "frozen" ) if( name == "frozen" )
{ {
bool b; bool b;
@ -474,6 +488,7 @@ namespace NLGUI
xmlSetProp( node, BAD_CAST "target_stepy", BAD_CAST toString( _TargetStepY ).c_str() ); xmlSetProp( node, BAD_CAST "target_stepy", BAD_CAST toString( _TargetStepY ).c_str() );
xmlSetProp( node, BAD_CAST "step_value", BAD_CAST toString( _StepValue ).c_str() ); xmlSetProp( node, BAD_CAST "step_value", BAD_CAST toString( _StepValue ).c_str() );
xmlSetProp( node, BAD_CAST "cancelable", BAD_CAST toString( _Cancelable ).c_str() ); xmlSetProp( node, BAD_CAST "cancelable", BAD_CAST toString( _Cancelable ).c_str() );
xmlSetProp( node, BAD_CAST "keyboard", BAD_CAST toString( _Keyboard ).c_str() );
xmlSetProp( node, BAD_CAST "frozen", BAD_CAST toString( _Frozen ).c_str() ); xmlSetProp( node, BAD_CAST "frozen", BAD_CAST toString( _Frozen ).c_str() );
return node; return node;
@ -589,6 +604,9 @@ namespace NLGUI
prop = (char*) xmlGetProp( node, (xmlChar*)"cancelable" ); prop = (char*) xmlGetProp( node, (xmlChar*)"cancelable" );
if (prop) _Cancelable = convertBool(prop); if (prop) _Cancelable = convertBool(prop);
prop = (char*) xmlGetProp( node, (xmlChar*)"keyboard" );
if (prop) _Keyboard = convertBool(prop);
prop= (char*) xmlGetProp (node, (xmlChar*)"frozen"); prop= (char*) xmlGetProp (node, (xmlChar*)"frozen");
_Frozen = false; _Frozen = false;
if (prop) if (prop)
@ -854,6 +872,7 @@ namespace NLGUI
if (CCtrlBase::handleEvent(event)) return true; if (CCtrlBase::handleEvent(event)) return true;
if (!_Active || _Frozen) if (!_Active || _Frozen)
return false; return false;
if (event.getType() == NLGUI::CEventDescriptor::mouse) if (event.getType() == NLGUI::CEventDescriptor::mouse)
{ {
const NLGUI::CEventDescriptorMouse &eventDesc = (const NLGUI::CEventDescriptorMouse &)event; const NLGUI::CEventDescriptorMouse &eventDesc = (const NLGUI::CEventDescriptorMouse &)event;
@ -912,6 +931,30 @@ namespace NLGUI
return true; return true;
} }
} }
else if (event.getType() == NLGUI::CEventDescriptor::key)
{
const NLGUI::CEventDescriptorKey &eventDesc = (const NLGUI::CEventDescriptorKey &)event;
if (eventDesc.getKeyEventType() == NLGUI::CEventDescriptorKey::keydown)
{
if (_Keyboard)
{
sint32 i = 0;
// direction
if (eventDesc.getKey() == KeyNEXT) i++;
else if (eventDesc.getKey() == KeyPRIOR) i--;
else
return false;
if (_Vertical)
moveTrackY(-(i * _TargetStepY));
else
moveTrackX(-(i * _TargetStepX));
return true;
}
}
}
return false; return false;
} }
@ -1213,6 +1256,7 @@ namespace NLGUI
if(wReal <= maxWReal) if(wReal <= maxWReal)
return; return;
// compute the new ofsX. // compute the new ofsX.
sint32 ofsX= _Target->getOfsX(); sint32 ofsX= _Target->getOfsX();
ofsX+= dx; ofsX+= dx;

@ -1077,6 +1077,69 @@ namespace NLGUI
// *************************************************************************** // ***************************************************************************
void CCtrlTextButton::setTextureLua(const std::string &name)
{
_TextureIdNormal[0].setTexture(std::string(name + "_l.tga").c_str());
_TextureIdNormal[1].setTexture(std::string(name + "_m.tga").c_str());
_TextureIdNormal[2].setTexture(std::string(name + "_r.tga").c_str());
}
// ***************************************************************************
void CCtrlTextButton::setTexturePushedLua(const std::string &name)
{
_TextureIdPushed[0].setTexture(std::string(name + "_l.tga").c_str());
_TextureIdPushed[1].setTexture(std::string(name + "_m.tga").c_str());
_TextureIdPushed[2].setTexture(std::string(name + "_r.tga").c_str());
}
// ***************************************************************************
void CCtrlTextButton::setTextureOverLua(const std::string &name)
{
_TextureIdOver[0].setTexture(std::string(name + "_l.tga").c_str());
_TextureIdOver[1].setTexture(std::string(name + "_m.tga").c_str());
_TextureIdOver[2].setTexture(std::string(name + "_r.tga").c_str());
}
// ***************************************************************************
std::string CCtrlTextButton::getTexture() const
{
std::string tx = CViewRenderer::getInstance()->getTextureNameFromId(_TextureIdNormal[0]);
std::string::size_type i = tx.rfind("_l.tga");
if (i != std::string::npos)
tx = tx.substr(0, i);
return tx;
}
// ***************************************************************************
std::string CCtrlTextButton::getTexturePushed() const
{
std::string tx = CViewRenderer::getInstance()->getTextureNameFromId(_TextureIdOver[0]);
std::string::size_type i = tx.rfind("_l.tga");
if (i != std::string::npos)
tx = tx.substr(0, i);
return tx;
}
// ***************************************************************************
std::string CCtrlTextButton::getTextureOver() const
{
std::string tx = CViewRenderer::getInstance()->getTextureNameFromId(_TextureIdPushed[0]);
std::string::size_type i = tx.rfind("_l.tga");
if (i != std::string::npos)
tx = tx.substr(0, i);
return tx;
}
// ***************************************************************************
int CCtrlTextButton::luaGetViewText(CLuaState &ls) int CCtrlTextButton::luaGetViewText(CLuaState &ls)
{ {
const char *funcName = "getViewText"; const char *funcName = "getViewText";

@ -524,18 +524,19 @@ namespace NLGUI
return false; return false;
} }
string tmpdest = download.dest + ".tmp"; // use browser Id so that two browsers would not use same temp file
download.tmpdest = localImageName(_Id + download.dest) + ".tmp";
// erase the tmp file if exists // erase the tmp file if exists
if (CFile::fileExists(tmpdest)) if (CFile::fileExists(download.tmpdest))
{ {
CFile::deleteFile(tmpdest); CFile::deleteFile(download.tmpdest);
} }
FILE *fp = nlfopen (tmpdest, "wb"); FILE *fp = nlfopen (download.tmpdest, "wb");
if (fp == NULL) if (fp == NULL)
{ {
nlwarning("Can't open file '%s' for writing: code=%d '%s'", tmpdest.c_str (), errno, strerror(errno)); nlwarning("Can't open file '%s' for writing: code=%d '%s'", download.tmpdest.c_str (), errno, strerror(errno));
return false; return false;
} }
@ -543,7 +544,7 @@ namespace NLGUI
if (!curl) if (!curl)
{ {
fclose(fp); fclose(fp);
CFile::deleteFile(tmpdest); CFile::deleteFile(download.tmpdest);
nlwarning("Creating cURL handle failed, unable to download '%s'", download.url.c_str()); nlwarning("Creating cURL handle failed, unable to download '%s'", download.url.c_str());
return false; return false;
@ -607,54 +608,57 @@ namespace NLGUI
void CGroupHTML::finishCurlDownload(const CDataDownload &download) void CGroupHTML::finishCurlDownload(const CDataDownload &download)
{ {
std::string tmpfile = download.dest + ".tmp";
if (download.type == ImgType) if (download.type == ImgType)
{ {
// there is race condition if two browser instances are downloading same file if (CFile::fileExists(download.tmpdest) && CFile::getFileSize(download.tmpdest) > 0)
// second instance deletes first tmpfile and creates new file for itself.
if (CFile::getFileSize(tmpfile) > 0)
{ {
try try
{ {
// verify that image is not corrupted // verify that image is not corrupted
uint32 w, h; uint32 w, h;
CBitmap::loadSize(tmpfile, w, h); CBitmap::loadSize(download.tmpdest, w, h);
if (w != 0 && h != 0) if (w != 0 && h != 0)
{ {
// if not tmpfile, then img is already in cache if (CFile::fileExists(download.dest))
if (CFile::fileExists(tmpfile)) CFile::deleteFile(download.dest);
{
if (CFile::fileExists(download.dest))
{
CFile::deleteFile(download.dest);
}
// to reload image on page, the easiest seems to be changing texture
// to temp file temporarily. that forces driver to reload texture from disk
// ITexture::touch() seem not to do this.
// cache was updated, first set texture as temp file
for(uint i = 0; i < download.imgs.size(); i++)
{
setImage(download.imgs[i].Image, tmpfile, download.imgs[i].Type);
setImageSize(download.imgs[i].Image, download.imgs[i].Style);
}
CFile::moveFile(download.dest, tmpfile);
}
// to reload image on page, the easiest seems to be changing texture
// to temp file temporarily. that forces driver to reload texture from disk
// ITexture::touch() seem not to do this.
// cache was updated, first set texture as temp file
for(uint i = 0; i < download.imgs.size(); i++) for(uint i = 0; i < download.imgs.size(); i++)
{ {
setImage(download.imgs[i].Image, download.dest, download.imgs[i].Type); setImage(download.imgs[i].Image, download.tmpdest, download.imgs[i].Type);
setImageSize(download.imgs[i].Image, download.imgs[i].Style); setImageSize(download.imgs[i].Image, download.imgs[i].Style);
} }
CFile::moveFile(download.dest, download.tmpdest);
} }
} }
catch(const NLMISC::Exception &e) catch(const NLMISC::Exception &e)
{ {
// exception message has .tmp file name, so keep it for further analysis // exception message has .tmp file name, so keep it for further analysis
nlwarning("Invalid image (%s): %s", download.url.c_str(), e.what()); nlwarning("Invalid image (%s) from url (%s): %s", download.tmpdest.c_str(), download.url.c_str(), e.what());
}
}
if (CFile::fileExists(download.dest) && CFile::getFileSize(download.dest) > 0)
{
try
{
// verify that image is not corrupted
uint32 w, h;
CBitmap::loadSize(download.dest, w, h);
if (w != 0 && h != 0)
for(uint i = 0; i < download.imgs.size(); i++)
{
setImage(download.imgs[i].Image, download.dest, download.imgs[i].Type);
setImageSize(download.imgs[i].Image, download.imgs[i].Style);
}
}
catch(const NLMISC::Exception &e)
{
nlwarning("Invalid image (%s) from url (%s): %s", download.dest.c_str(), download.url.c_str(), e.what());
} }
} }
@ -663,13 +667,13 @@ namespace NLGUI
if (download.type == StylesheetType) if (download.type == StylesheetType)
{ {
if (CFile::fileExists(tmpfile)) if (CFile::fileExists(download.tmpdest))
{ {
if (CFile::fileExists(download.dest)) if (CFile::fileExists(download.dest))
{ {
CFile::deleteFile(download.dest); CFile::deleteFile(download.dest);
} }
CFile::moveFile(download.dest, tmpfile); CFile::moveFile(download.dest, download.tmpdest);
} }
cssDownloadFinished(download.url, download.dest); cssDownloadFinished(download.url, download.dest);
@ -680,20 +684,20 @@ namespace NLGUI
{ {
bool verified = false; bool verified = false;
// no tmpfile if file was already in cache // no tmpfile if file was already in cache
if (CFile::fileExists(tmpfile)) if (CFile::fileExists(download.tmpdest))
{ {
verified = download.md5sum.empty() || (download.md5sum != getMD5(tmpfile).toString()); verified = download.md5sum.empty() || (download.md5sum != getMD5(download.tmpdest).toString());
if (verified) if (verified)
{ {
if (CFile::fileExists(download.dest)) if (CFile::fileExists(download.dest))
{ {
CFile::deleteFile(download.dest); CFile::deleteFile(download.dest);
} }
CFile::moveFile(download.dest, tmpfile); CFile::moveFile(download.dest, download.tmpdest);
} }
else else
{ {
CFile::deleteFile(tmpfile); CFile::deleteFile(download.tmpdest);
} }
} }
else if (CFile::fileExists(download.dest)) else if (CFile::fileExists(download.dest))
@ -745,7 +749,7 @@ namespace NLGUI
if (type != OverImage) if (type != OverImage)
{ {
std::string temp = dest; std::string temp = dest;
if (!CFile::fileExists(temp)) if (!CFile::fileExists(temp) || CFile::getFileSize(temp) == 0)
{ {
temp = placeholder; temp = placeholder;
} }
@ -857,21 +861,16 @@ namespace NLGUI
CFile::createDirectory( pathName ); CFile::createDirectory( pathName );
} }
void CGroupHTML::addStylesheetDownload(std::vector<std::string> links) void CGroupHTML::addStylesheetDownload(const std::vector<CHtmlParser::StyleLink> links)
{ {
for(uint i = 0; i < links.size(); ++i) for(uint i = 0; i < links.size(); ++i)
{ {
std::string url = getAbsoluteUrl(links[i]); _StylesheetQueue.push_back(links[i]);
std::string local = localImageName(url); std::string url = getAbsoluteUrl(links[i].Url);
_StylesheetQueue.back().Url = url;
// insert only if url not already downloading // push to the front of the queue
std::vector<std::string>::const_iterator it = std::find(_StylesheetQueue.begin(), _StylesheetQueue.end(), url); Curls.push_front(CDataDownload(url, localImageName(url), StylesheetType, NULL, "", ""));
if (it == _StylesheetQueue.end())
{
_StylesheetQueue.push_back(url);
// push to the front of the queue
Curls.push_front(CDataDownload(url, local, StylesheetType, NULL, "", ""));
}
} }
pumpCurlQueue(); pumpCurlQueue();
} }
@ -971,9 +970,9 @@ namespace NLGUI
{ {
fclose(it->fp); fclose(it->fp);
if (CFile::fileExists(it->dest + ".tmp")) if (CFile::fileExists(it->tmpdest))
{ {
CFile::deleteFile(it->dest + ".tmp"); CFile::deleteFile(it->tmpdest);
} }
} }
} }
@ -2549,6 +2548,17 @@ namespace NLGUI
newParagraph->setResizeFromChildH(true); newParagraph->setResizeFromChildH(true);
newParagraph->setMarginLeft(getIndent()); newParagraph->setMarginLeft(getIndent());
if (!_Style.Current.TextAlign.empty())
{
if (_Style.Current.TextAlign == "left")
newParagraph->setTextAlign(CGroupParagraph::AlignLeft);
else if (_Style.Current.TextAlign == "center")
newParagraph->setTextAlign(CGroupParagraph::AlignCenter);
else if (_Style.Current.TextAlign == "right")
newParagraph->setTextAlign(CGroupParagraph::AlignRight);
else if (_Style.Current.TextAlign == "justify")
newParagraph->setTextAlign(CGroupParagraph::AlignJustify);
}
// Add to the group // Add to the group
addHtmlGroup (newParagraph, beginSpace); addHtmlGroup (newParagraph, beginSpace);
@ -2642,6 +2652,17 @@ namespace NLGUI
invalidateCoords(); invalidateCoords();
} }
void CGroupHTML::browseErrorHtml(const std::string &html)
{
releaseDownloads();
removeContent();
renderHtmlString(html);
updateRefreshButton();
invalidateCoords();
}
// *************************************************************************** // ***************************************************************************
bool CGroupHTML::isBrowsing() bool CGroupHTML::isBrowsing()
@ -3964,11 +3985,22 @@ namespace NLGUI
{ {
if (!success) if (!success)
{ {
CUrlParser uri(_CurlWWW->Url);
// potentially unwanted chars
std::string url = _CurlWWW->Url;
url = strFindReplaceAll(url, string("<"), string("%3C"));
url = strFindReplaceAll(url, string(">"), string("%3E"));
url = strFindReplaceAll(url, string("\""), string("%22"));
url = strFindReplaceAll(url, string("'"), string("%27"));
std::string err; std::string err;
err = "Connection failed with cURL error: "; err = "<html><head><title>cURL error</title></head><body>";
err += "<h1>Connection failed with cURL error</h1>";
err += error; err += error;
err += "\nURL '" + _CurlWWW->Url + "'"; err += "<hr>(" + uri.scheme + "://" + uri.host + ") <a href=\"" + url + "\">reload</a>";
browseError(err.c_str()); err += "</body></html>";
browseErrorHtml(err);
return; return;
} }
@ -4080,10 +4112,9 @@ namespace NLGUI
obj.LastModified = data.data->getLastModified(); obj.LastModified = data.data->getLastModified();
CHttpCache::getInstance()->store(data.dest, obj); CHttpCache::getInstance()->store(data.dest, obj);
std::string tmpfile = data.dest + ".tmp"; if (code == 304 && CFile::fileExists(data.tmpdest))
if (code == 304 && CFile::fileExists(tmpfile))
{ {
CFile::deleteFile(tmpfile); CFile::deleteFile(data.tmpdest);
} }
} }
else if ((code >= 301 && code <= 303) || code == 307 || code == 308) else if ((code >= 301 && code <= 303) || code == 307 || code == 308)
@ -4111,10 +4142,9 @@ namespace NLGUI
LOG_DL("Redirect '%s'", location.c_str()); LOG_DL("Redirect '%s'", location.c_str());
// no finished callback called, so cleanup old temp // no finished callback called, so cleanup old temp
std::string tmpfile = data.dest + ".tmp"; if (CFile::fileExists(data.tmpdest))
if (CFile::fileExists(tmpfile))
{ {
CFile::deleteFile(tmpfile); CFile::deleteFile(data.tmpdest);
} }
return; return;
} }
@ -4187,19 +4217,28 @@ namespace NLGUI
// *************************************************************************** // ***************************************************************************
void CGroupHTML::cssDownloadFinished(const std::string &url, const std::string &local) void CGroupHTML::cssDownloadFinished(const std::string &url, const std::string &local)
{ {
// remove file from download queue for(std::vector<CHtmlParser::StyleLink>::iterator it = _StylesheetQueue.begin();
std::vector<std::string>::iterator it = std::find(_StylesheetQueue.begin(), _StylesheetQueue.end(), url); it != _StylesheetQueue.end(); ++it)
if (it != _StylesheetQueue.end())
{ {
_StylesheetQueue.erase(it); if (it->Url == url)
} {
// read downloaded file into HtmlStyles
if (CFile::fileExists(local) && it->Index < _HtmlStyles.size())
{
CIFile in;
if (in.open(local))
{
if (!in.readAll(_HtmlStyles[it->Index]))
{
nlwarning("Failed to read downloaded css file(%s), url(%s)", local.c_str(), url.c_str());
}
}
}
if (!CFile::fileExists(local)) _StylesheetQueue.erase(it);
{ break;
return; }
} }
parseStylesheetFile(local);
} }
void CGroupHTML::renderDocument() void CGroupHTML::renderDocument()
@ -4217,6 +4256,16 @@ namespace NLGUI
beginBuild(); beginBuild();
removeContent(); removeContent();
// process all <style> and <link rel=stylesheet> elements
for(uint i = 0; i < _HtmlStyles.size(); ++i)
{
if (!_HtmlStyles[i].empty())
{
_Style.parseStylesheet(_HtmlStyles[i]);
}
}
_HtmlStyles.clear();
std::list<CHtmlElement>::iterator it = _HtmlDOM.Children.begin(); std::list<CHtmlElement>::iterator it = _HtmlDOM.Children.begin();
while(it != _HtmlDOM.Children.end()) while(it != _HtmlDOM.Children.end())
{ {
@ -4826,9 +4875,6 @@ namespace NLGUI
// *************************************************************************** // ***************************************************************************
bool CGroupHTML::parseHtml(const std::string &htmlString) bool CGroupHTML::parseHtml(const std::string &htmlString)
{ {
std::vector<std::string> links;
std::string styleString;
CHtmlElement *parsedDOM; CHtmlElement *parsedDOM;
if (_CurrentHTMLElement == NULL) if (_CurrentHTMLElement == NULL)
{ {
@ -4841,16 +4887,28 @@ namespace NLGUI
parsedDOM = _CurrentHTMLElement; parsedDOM = _CurrentHTMLElement;
} }
std::vector<CHtmlParser::StyleLink> links;
CHtmlParser parser; CHtmlParser parser;
parser.getDOM(htmlString, *parsedDOM, styleString, links); parser.getDOM(htmlString, *parsedDOM, _HtmlStyles, links);
if (!styleString.empty()) // <link> elements inserted from lua::parseHtml are ignored
if (_CurrentHTMLElement == NULL && !links.empty())
{ {
_Style.parseStylesheet(styleString); addStylesheetDownload(links);
} }
if (!links.empty()) else if (_CurrentHTMLElement != NULL)
{ {
addStylesheetDownload(links); // Called from active element (lua)
// <style> order is not preserved as document is already being rendered
for(uint i = 0; i < _HtmlStyles.size(); ++i)
{
if (!_HtmlStyles[i].empty())
{
_Style.parseStylesheet(_HtmlStyles[i]);
}
}
_HtmlStyles.clear();
} }
// this should rarely fail as first element should be <html> // this should rarely fail as first element should be <html>
@ -4861,7 +4919,7 @@ namespace NLGUI
{ {
if (it->Type == CHtmlElement::ELEMENT_NODE && it->Value == "html") if (it->Type == CHtmlElement::ELEMENT_NODE && it->Value == "html")
{ {
// more newly parsed childs from <body> into siblings // move newly parsed childs from <body> into siblings
if (_CurrentHTMLElement) { if (_CurrentHTMLElement) {
std::list<CHtmlElement>::iterator it2 = it->Children.begin(); std::list<CHtmlElement>::iterator it2 = it->Children.begin();
while(it2 != it->Children.end()) while(it2 != it->Children.end())
@ -5358,6 +5416,11 @@ namespace NLGUI
cellParams.Align = CGroupCell::Center; cellParams.Align = CGroupCell::Center;
else if (align == "right") else if (align == "right")
cellParams.Align = CGroupCell::Right; cellParams.Align = CGroupCell::Right;
else if (align != "justify")
align.clear();
// copy td align (can be empty) attribute back into css
_Style.Current.TextAlign = align;
} }
{ {
@ -5503,7 +5566,7 @@ namespace NLGUI
string suri = elm.getAttribute("href"); string suri = elm.getAttribute("href");
if(suri.find("ah:") == 0) if(suri.find("ah:") == 0)
{ {
if (_TrustedDomain) if (_TrustedDomain || suri.find("ah:script:") == 0)
_Link.back() = suri; _Link.back() = suri;
} }
else else
@ -6360,11 +6423,13 @@ namespace NLGUI
void CGroupHTML::htmlOBJECTend(const CHtmlElement &elm) void CGroupHTML::htmlOBJECTend(const CHtmlElement &elm)
{ {
if (!_TrustedDomain)
return;
if (_ObjectType=="application/ryzom-data") if (_ObjectType=="application/ryzom-data")
{ {
if (!_TrustedDomain)
return;
if (!_ObjectData.empty()) if (!_ObjectData.empty())
{ {
if (addBnpDownload(_ObjectData, _ObjectAction, _ObjectScript, _ObjectMD5Sum)) if (addBnpDownload(_ObjectData, _ObjectAction, _ObjectScript, _ObjectMD5Sum))
@ -6374,6 +6439,20 @@ namespace NLGUI
_ObjectScript.clear(); _ObjectScript.clear();
} }
} }
else if (_ObjectType=="application/ryzom-tutorial")
{
while(strFindReplace(_ObjectScript, "[", ""));
while(strFindReplace(_ObjectScript, "]", ""));
CLuaManager::getInstance().executeLuaScript("\ngame:executeTutorial([["+_ObjectScript+"]])\n", true);
_ObjectScript.clear();
}
else if (_ObjectType=="application/ryzom-script")
{
while(strFindReplace(_ObjectScript, "[", ""));
while(strFindReplace(_ObjectScript, "]", ""));
CLuaManager::getInstance().executeLuaScript("\ngame:executeRyzomScript([["+_ObjectScript+"]])\n", true);
_ObjectScript.clear();
}
_Object = false; _Object = false;
} }
@ -6767,6 +6846,9 @@ namespace NLGUI
// setting ModulateGlobalColor must be after addImageDownload // setting ModulateGlobalColor must be after addImageDownload
if (_Style.checkStyle("-ryzom-modulate-bgcolor", "true")) if (_Style.checkStyle("-ryzom-modulate-bgcolor", "true"))
table->setModulateGlobalColor(true); table->setModulateGlobalColor(true);
else if (_Style.checkStyle("-ryzom-modulate-bgcolor", "false"))
table->setModulateGlobalColor(false);
table->setMarginLeft(getIndent()); table->setMarginLeft(getIndent());
addHtmlGroup (table, 0); addHtmlGroup (table, 0);

@ -64,6 +64,7 @@ namespace NLGUI
_Indent = 0; _Indent = 0;
_FirstViewIndentView = false; _FirstViewIndentView = false;
_TextId = 0; _TextId = 0;
_TextAlign = AlignLeft;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -713,6 +714,10 @@ namespace NLGUI
CViewText *viewText = dynamic_cast<CViewText*>(_Elements[i].Element); CViewText *viewText = dynamic_cast<CViewText*>(_Elements[i].Element);
if (viewText) if (viewText)
{ {
// FIXME: this does not work with multiple view text on same line
if (_TextAlign == AlignCenter && elmCount == 1)
viewText->setTextMode(CViewText::Centered);
viewText->setFirstLineX(x + ((i==0)?_FirstViewIndentView:0)); viewText->setFirstLineX(x + ((i==0)?_FirstViewIndentView:0));
viewText->setX(0); viewText->setX(0);
viewText->updateTextContext(); viewText->updateTextContext();
@ -730,6 +735,12 @@ namespace NLGUI
// Does we balance the last line height ? // Does we balance the last line height ?
if (viewText) if (viewText)
{ {
if (_TextAlign == AlignCenter && elmCount == 1)
{
sint pad = width - viewText->getWReal();
viewText->setX(pad/2);
}
changeLine = viewText->getNumLine() > 1; changeLine = viewText->getNumLine() > 1;
if (!viewText->getText().empty() && *(viewText->getText().rbegin()) == (ucchar) '\n') if (!viewText->getText().empty() && *(viewText->getText().rbegin()) == (ucchar) '\n')
{ {

@ -57,7 +57,7 @@ namespace NLGUI
// *************************************************************************** // ***************************************************************************
// recursive function to walk html document // recursive function to walk html document
void CHtmlParser::parseNode(xmlNode *a_node, CHtmlElement &parent, std::string &styleString, std::vector<std::string> &links) const void CHtmlParser::parseNode(xmlNode *a_node, CHtmlElement &parent, std::vector<std::string> &styles, std::vector<StyleLink> &links) const
{ {
uint childIndex = 0; uint childIndex = 0;
uint element_number; uint element_number;
@ -66,7 +66,15 @@ namespace NLGUI
{ {
if (node->type == XML_TEXT_NODE) if (node->type == XML_TEXT_NODE)
{ {
parent.Children.push_back(CHtmlElement(CHtmlElement::TEXT_NODE, (const char*)(node->content))); // linebreak right after pre,textare open tag should be removed
if (parent.Children.empty() && (*node->content == '\n') && (parent.ID == HTML_PRE || parent.ID == HTML_TEXTAREA))
{
parent.Children.push_back(CHtmlElement(CHtmlElement::TEXT_NODE, (const char*)(node->content) + 1));
}
else
{
parent.Children.push_back(CHtmlElement(CHtmlElement::TEXT_NODE, (const char*)(node->content)));
}
} }
else else
if (node->type == XML_ELEMENT_NODE) if (node->type == XML_ELEMENT_NODE)
@ -145,7 +153,9 @@ namespace NLGUI
if (useStyle) if (useStyle)
{ {
parseStyle(node->children, styleString); std::string style;
parseStyle(node->children, style);
styles.push_back(style);
} }
// style tag is kept in dom // style tag is kept in dom
} }
@ -163,13 +173,24 @@ namespace NLGUI
if (useStyle) if (useStyle)
{ {
links.push_back(elm.getAttribute("href")); styles.push_back("");
links.push_back(StyleLink(styles.size()-1, elm.getAttribute("href")));
} }
// link tag is kept in dom // link tag is kept in dom
} }
else if (node->children) else if (node->children)
{ {
parseNode(node->children, elm, styleString, links); parseNode(node->children, elm, styles, links);
if (!elm.Children.empty() && elm.ID == HTML_PRE && elm.Children.back().Type == CHtmlElement::TEXT_NODE)
{
std::string::size_type size = elm.Children.back().Value.size();
// strip last '\n' from non-empty line
if (size > 1 && elm.Children.back().Value[size-1] == '\n')
{
elm.Children.back().Value = elm.Children.back().Value.substr(0, size - 1);
}
}
// must cleanup nested tags that libxml2 does not fix // must cleanup nested tags that libxml2 does not fix
// dt without end tag: <dl><dt><dt></dl> // dt without end tag: <dl><dt><dt></dl>
@ -406,7 +427,7 @@ namespace NLGUI
} }
// *************************************************************************** // ***************************************************************************
void CHtmlParser::getDOM(std::string htmlString, CHtmlElement &dom, std::string &styleString, std::vector<std::string> &links) const void CHtmlParser::getDOM(std::string htmlString, CHtmlElement &dom, std::vector<std::string> &styles, std::vector<StyleLink> &links) const
{ {
htmlParserCtxtPtr parser = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL, XML_CHAR_ENCODING_UTF8); htmlParserCtxtPtr parser = htmlCreatePushParserCtxt(NULL, NULL, NULL, 0, NULL, XML_CHAR_ENCODING_UTF8);
if (!parser) if (!parser)
@ -428,8 +449,7 @@ namespace NLGUI
xmlNode *root = xmlDocGetRootElement(parser->myDoc); xmlNode *root = xmlDocGetRootElement(parser->myDoc);
if (root) if (root)
{ {
styleString.clear(); parseNode(root, dom, styles, links);
parseNode(root, dom, styleString, links);
} }
else else
{ {

@ -1028,21 +1028,16 @@ namespace NLGUI
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool CInterfaceElement::convertBool (const char *ptr) bool CInterfaceElement::convertBool (const char *ptr)
{ {
std::string str = toLower(ptr); return NLMISC::toBool(ptr);
bool b = false;
fromString( str, b );
return b;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
NLMISC::CVector CInterfaceElement::convertVector (const char *ptr) NLMISC::CVector CInterfaceElement::convertVector (const char *ptr)
{ {
float x = 0.0f, y = 0.0f, z = 0.0f; float x = 0.0f, y = 0.0f, z = 0.0f;
sscanf (ptr, "%f %f %f", &x, &y, &z); sscanf (ptr, "%f %f %f", &x, &y, &z);
return CVector(x,y,z); return CVector(x,y,z);
} }
@ -1168,6 +1163,8 @@ namespace NLGUI
{ {
_Active = state; _Active = state;
invalidateCoords(); invalidateCoords();
// force invalidate CViewText/CGroupTable inner elements
invalidateContent();
} }
} }

@ -621,9 +621,7 @@ namespace NLGUI
return; return;
sint32 txw, txh; sint32 txw, txh;
SImage &rImage = *getSImage(nTxId); getTextureSizeFromId(nTxId, txw, txh);
txw = (sint32)((rImage.UVMax.U - rImage.UVMin.U)*rImage.GlobalTexturePtr->Width+0.5f);
txh = (sint32)((rImage.UVMax.V - rImage.UVMin.V)*rImage.GlobalTexturePtr->Height+0.5f);
drawRotFlipBitmap (layerId, x, y, txw, txh, rot, flipv, nTxId, col); drawRotFlipBitmap (layerId, x, y, txw, txh, rot, flipv, nTxId, col);
} }
@ -859,6 +857,14 @@ namespace NLGUI
CIFile ifTmp; CIFile ifTmp;
if (ifTmp.open(filename)) if (ifTmp.open(filename))
CBitmap::loadSize (ifTmp, gt.Width, gt.Height); CBitmap::loadSize (ifTmp, gt.Width, gt.Height);
// extract textures scale from filename
// texture_interface_v3_2x.tga / texture_interface_v3_4x.tga
if (textureFileName.find("_2x.") != std::string::npos)
gt.Scale = 2.f;
else if (textureFileName.find("_4x.") != std::string::npos)
gt.Scale = 4.f;
gt.Texture = driver->createTextureFile (filename); gt.Texture = driver->createTextureFile (filename);
// Force to generate the texture now. This way we can extract the mouse bitmaps from it now without having to load it again. // Force to generate the texture now. This way we can extract the mouse bitmaps from it now without having to load it again.
// Its why we don't release it at the end, because it is likely to be uploaded soon) // Its why we don't release it at the end, because it is likely to be uploaded soon)
@ -932,6 +938,10 @@ namespace NLGUI
CBitmap curs; CBitmap curs;
curs.resize(x1 - x0, y1 - y0); curs.resize(x1 - x0, y1 - y0);
curs.blit(*texDatas, x0, y0, (x1 - x0), (y1 - y0), 0, 0); curs.blit(*texDatas, x0, y0, (x1 - x0), (y1 - y0), 0, 0);
// TODO: scaled cursors not supported
if (gt.Scale > 1.f) {
curs.resample((sint)(curs.getWidth() / gt.Scale), (sint)(curs.getHeight() / gt.Scale));
}
driver->addCursor(image.Name, curs); driver->addCursor(image.Name, curs);
} }
} }
@ -1357,8 +1367,8 @@ namespace NLGUI
else else
{ {
SImage &rImage = *getSImage(id); SImage &rImage = *getSImage(id);
width = (sint32)((rImage.UVMax.U - rImage.UVMin.U)*rImage.GlobalTexturePtr->Width+0.5f); width = (sint32)(((rImage.UVMax.U - rImage.UVMin.U)*rImage.GlobalTexturePtr->Width / rImage.GlobalTexturePtr->Scale)+0.5f);
height = (sint32)((rImage.UVMax.V - rImage.UVMin.V)*rImage.GlobalTexturePtr->Height+0.5f); height = (sint32)(((rImage.UVMax.V - rImage.UVMin.V)*rImage.GlobalTexturePtr->Height / rImage.GlobalTexturePtr->Scale)+0.5f);
} }
} }
/* /*
@ -1373,9 +1383,11 @@ namespace NLGUI
SImage &rImage = *getSImage(id); SImage &rImage = *getSImage(id);
SGlobalTexture &rGT = *rImage.GlobalTexturePtr; SGlobalTexture &rGT = *rImage.GlobalTexturePtr;
// get (possibly) scaled width/height
sint32 width, height; sint32 width, height;
width = (sint32)((rImage.UVMax.U - rImage.UVMin.U)*rGT.Width+0.5f); getTextureSizeFromId(id, width, height);
height = (sint32)((rImage.UVMax.V - rImage.UVMin.V)*rGT.Height+0.5f); if (width == 0 || height == 0)
return CRGBA(255,255,255);
float xRatio = ((float)x) / ((float)(width)); float xRatio = ((float)x) / ((float)(width));
float yRatio = ((float)y) / ((float)(height)); float yRatio = ((float)y) / ((float)(height));
UTexture *pTF = rGT.Texture; UTexture *pTF = rGT.Texture;

@ -2296,7 +2296,7 @@ namespace NLGUI
// Hide menu if the key is pushed // Hide menu if the key is pushed
// if ((eventDesc.getKeyEventType() == CEventDescriptorKey::keydown) && !_ModalStack.empty() && !eventDesc.getKeyAlt() && !eventDesc.getKeyCtrl() && !eventDesc.getKeyShift()) // if ((eventDesc.getKeyEventType() == CEventDescriptorKey::keydown) && !_ModalStack.empty() && !eventDesc.getKeyAlt() && !eventDesc.getKeyCtrl() && !eventDesc.getKeyShift())
// Hide menu (or popup menu) is ESCAPE pressed // Hide menu (or popup menu) is ESCAPE pressed
if( eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == NLMISC::KeyESCAPE ) if( eventDesc.getKeyEventType() == CEventDescriptorKey::keydown && eventDesc.getKey() == NLMISC::KeyESCAPE )
{ {
if( hasModal() ) if( hasModal() )
{ {
@ -2307,7 +2307,7 @@ namespace NLGUI
} }
// Manage "quit window" If the Key is ESCAPE, no captureKeyboard // Manage "quit window" If the Key is ESCAPE, no captureKeyboard
if( eventDesc.getKeyEventType() == CEventDescriptorKey::keychar && eventDesc.getChar() == NLMISC::KeyESCAPE ) if( eventDesc.getKeyEventType() == CEventDescriptorKey::keydown && eventDesc.getKey() == NLMISC::KeyESCAPE )
{ {
// Get the last escapable active top window. NB: this is ergonomically better. // Get the last escapable active top window. NB: this is ergonomically better.
CInterfaceGroup *win= getLastEscapableTopWindow(); CInterfaceGroup *win= getLastEscapableTopWindow();

@ -3269,77 +3269,79 @@ CRGBAF CBitmap::getColor (float x, float y) const
uint32 i; uint32 i;
bool isValid = true;
for (i = 0; i < 4; ++i) for (i = 0; i < 4; ++i)
{ {
nlassert (nX[i] >= 0); if (nX[i] < 0 || nY[i] < 0 || nX[i] >= nWidth || nY[i] >= nHeight)
nlassert (nY[i] >= 0 ); isValid = false;
nlassert (nX[i] < nWidth);
nlassert (nY[i] < nHeight);
} }
// Decimal part of (x,y) if (isValid)
x = x - (float)nX[0];
y = y - (float)nY[0];
switch (this->PixelFormat)
{ {
case RGBA: // Decimal part of (x,y)
case DXTC1: x = x - (float)nX[0];
case DXTC1Alpha: y = y - (float)nY[0];
case DXTC3:
case DXTC5:
{
CRGBAF finalVal;
CRGBA val[4];
if (this->PixelFormat == RGBA) switch (this->PixelFormat)
{
case RGBA:
case DXTC1:
case DXTC1Alpha:
case DXTC3:
case DXTC5:
{ {
for (i = 0; i < 4; ++i) CRGBAF finalVal;
CRGBA val[4];
if (this->PixelFormat == RGBA)
{ {
val[i] = CRGBA (rBitmap[(nX[i]+nY[i]*nWidth)*4+0], for (i = 0; i < 4; ++i)
rBitmap[(nX[i]+nY[i]*nWidth)*4+1], {
rBitmap[(nX[i]+nY[i]*nWidth)*4+2], val[i] = CRGBA (rBitmap[(nX[i]+nY[i]*nWidth)*4+0],
rBitmap[(nX[i]+nY[i]*nWidth)*4+3]); rBitmap[(nX[i]+nY[i]*nWidth)*4+1],
rBitmap[(nX[i]+nY[i]*nWidth)*4+2],
rBitmap[(nX[i]+nY[i]*nWidth)*4+3]);
}
} }
} else
else
{
// slower version : get from DXT
for (i = 0; i < 4; ++i)
{ {
val[i] = getPixelColor(nX[i], nY[i]); // slower version : get from DXT
for (i = 0; i < 4; ++i)
{
val[i] = getPixelColor(nX[i], nY[i]);
}
} }
}
finalVal.R = getColorInterp (x, y, val[0].R, val[1].R, val[2].R, val[3].R); finalVal.R = getColorInterp (x, y, val[0].R, val[1].R, val[2].R, val[3].R);
finalVal.G = getColorInterp (x, y, val[0].G, val[1].G, val[2].G, val[3].G); finalVal.G = getColorInterp (x, y, val[0].G, val[1].G, val[2].G, val[3].G);
finalVal.B = getColorInterp (x, y, val[0].B, val[1].B, val[2].B, val[3].B); finalVal.B = getColorInterp (x, y, val[0].B, val[1].B, val[2].B, val[3].B);
finalVal.A = getColorInterp (x, y, val[0].A, val[1].A, val[2].A, val[3].A); finalVal.A = getColorInterp (x, y, val[0].A, val[1].A, val[2].A, val[3].A);
finalVal /= 255.f; finalVal /= 255.f;
return finalVal; return finalVal;
} }
break; break;
case Alpha: case Alpha:
case Luminance: case Luminance:
{ {
float finalVal; float finalVal;
float val[4]; float val[4];
for (i = 0; i < 4; ++i) for (i = 0; i < 4; ++i)
val[i] = rBitmap[(nX[i]+nY[i]*nWidth)]; val[i] = rBitmap[(nX[i]+nY[i]*nWidth)];
finalVal = getColorInterp (x, y, val[0], val[1], val[2], val[3]); finalVal = getColorInterp (x, y, val[0], val[1], val[2], val[3]);
finalVal /= 255.f; finalVal /= 255.f;
if (this->PixelFormat == Alpha) if (this->PixelFormat == Alpha)
return CRGBAF (1.f, 1.f, 1.f, finalVal); return CRGBAF (1.f, 1.f, 1.f, finalVal);
else // Luminance else // Luminance
return CRGBAF (finalVal, finalVal, finalVal, 1.f); return CRGBAF (finalVal, finalVal, finalVal, 1.f);
}
break;
default: break;
} }
break;
default: break;
} }
return CRGBAF (0.0f, 0.0f, 0.0f, 0.0f); return CRGBAF (0.0f, 0.0f, 0.0f, 0.0f);
@ -3568,7 +3570,7 @@ void CBitmap::loadSize(NLMISC::IStream &f, uint32 &retWidth, uint32 &retHeight)
} }
while(!eof); while(!eof);
} }
else if(fileType == JPG_HEADER) else if(memcmp(&fileType, &JPG_HEADER, 2) == 0)
{ {
uint8 blockMarker1 = 0; uint8 blockMarker1 = 0;
uint8 blockMarker2 = 0; uint8 blockMarker2 = 0;
@ -3626,7 +3628,7 @@ void CBitmap::loadSize(NLMISC::IStream &f, uint32 &retWidth, uint32 &retHeight)
{ {
uint8 imagePrecision = 0; // sample precision uint8 imagePrecision = 0; // sample precision
uint32 imageSize = 0; // width and height uint32 imageSize = 0; // width and height
f.serial(imagePrecision); f.serial(imagePrecision);
f.serial(imageSize); f.serial(imageSize);
NLMISC_BSWAP32(imageSize); NLMISC_BSWAP32(imageSize);

@ -179,7 +179,6 @@
#else #else
# include <sys/types.h> # include <sys/types.h>
# include <sys/stat.h> # include <sys/stat.h>
# include <sys/sysctl.h>
# include <fcntl.h> # include <fcntl.h>
# include <unistd.h> # include <unistd.h>
# include <cerrno> # include <cerrno>
@ -189,6 +188,7 @@
# endif // NL_CPU_INTEL # endif // NL_CPU_INTEL
# ifdef NL_OS_MAC # ifdef NL_OS_MAC
# include <sys/mount.h> # include <sys/mount.h>
# include <sys/sysctl.h>
# else # else
# include <sys/vfs.h> # include <sys/vfs.h>
# endif # endif

@ -116,10 +116,9 @@ IAudioDecoder *IAudioDecoder::createAudioDecoder(const std::string &type, NLMISC
bool IAudioDecoder::getInfo(const std::string &filepath, std::string &artist, std::string &title, float &length) bool IAudioDecoder::getInfo(const std::string &filepath, std::string &artist, std::string &title, float &length)
{ {
std::string lookup = CPath::lookup(filepath, false); if (filepath.empty() || !CFile::fileExists(filepath))
if (lookup.empty())
{ {
nlwarning("Music file %s does not exist!", filepath.c_str()); nlwarning("Music file '%s' does not exist!", filepath.c_str());
return false; return false;
} }
@ -127,7 +126,7 @@ bool IAudioDecoder::getInfo(const std::string &filepath, std::string &artist, st
CIFile ifile; CIFile ifile;
ifile.setCacheFileOnOpen(false); ifile.setCacheFileOnOpen(false);
ifile.allowBNPCacheFileOnOpen(false); ifile.allowBNPCacheFileOnOpen(false);
if (ifile.open(lookup)) if (ifile.open(filepath))
return CAudioDecoderFfmpeg::getInfo(&ifile, artist, title, length); return CAudioDecoderFfmpeg::getInfo(&ifile, artist, title, length);
#else #else
std::string type = CFile::getExtension(filepath); std::string type = CFile::getExtension(filepath);
@ -138,7 +137,7 @@ bool IAudioDecoder::getInfo(const std::string &filepath, std::string &artist, st
CIFile ifile; CIFile ifile;
ifile.setCacheFileOnOpen(false); ifile.setCacheFileOnOpen(false);
ifile.allowBNPCacheFileOnOpen(false); ifile.allowBNPCacheFileOnOpen(false);
if (ifile.open(lookup)) if (ifile.open(filepath))
return CAudioDecoderVorbis::getInfo(&ifile, artist, title, length); return CAudioDecoderVorbis::getInfo(&ifile, artist, title, length);
nlwarning("Unable to open: '%s'", filepath.c_str()); nlwarning("Unable to open: '%s'", filepath.c_str());
@ -149,7 +148,7 @@ bool IAudioDecoder::getInfo(const std::string &filepath, std::string &artist, st
CIFile ifile; CIFile ifile;
ifile.setCacheFileOnOpen(false); ifile.setCacheFileOnOpen(false);
ifile.allowBNPCacheFileOnOpen(false); ifile.allowBNPCacheFileOnOpen(false);
if (ifile.open(lookup)) if (ifile.open(filepath))
return CAudioDecoderMP3::getInfo(&ifile, artist, title, length); return CAudioDecoderMP3::getInfo(&ifile, artist, title, length);
nlwarning("Unable to open: '%s'", filepath.c_str()); nlwarning("Unable to open: '%s'", filepath.c_str());

@ -496,36 +496,20 @@ bool getTag (std::string &result, const char *tag, FSOUND_STREAM *stream)
} }
/** Get music info. Returns false if the song is not found or the function is not implemented. /** Get music info. Returns false if the song is not found or the function is not implemented.
* \param filepath path to file, CPath::lookup done by driver * \param filepath full path to file
* \param artist returns the song artist (empty if not available) * \param artist returns the song artist (empty if not available)
* \param title returns the title (empty if not available) * \param title returns the title (empty if not available)
*/ */
bool CSoundDriverFMod::getMusicInfo(const std::string &filepath, std::string &artist, std::string &title, float &length) bool CSoundDriverFMod::getMusicInfo(const std::string &filepath, std::string &artist, std::string &title, float &length)
{ {
/* Open a stream, get the tag if it exists, close the stream */ if (filepath.empty() || !CFile::fileExists(filepath))
string pathName = CPath::lookup(filepath, false);
uint32 fileOffset = 0, fileSize = 0;
if (pathName.empty())
{ {
nlwarning("NLSOUND FMod Driver: Music file %s not found!", filepath.c_str()); nlwarning("NLSOUND FMod Driver: Music file %s not found!", filepath.c_str());
return false; return false;
} }
// if the file is in a bnp
if (pathName.find('@') != string::npos)
{
if (CBigFile::getInstance().getFileInfo(pathName, fileSize, fileOffset))
{
// set pathname to bnp
pathName = pathName.substr(0, pathName.find('@'));
}
else
{
nlwarning("NLSOUND FMod Driver: BNP BROKEN");
return false;
}
}
FSOUND_STREAM *stream = FSOUND_Stream_Open((const char *)CPath::lookup(filepath, false).c_str(), FSOUND_2D, (sint)fileOffset, (sint)fileSize); uint32 fileOffset = 0, fileSize = 0;
FSOUND_STREAM *stream = FSOUND_Stream_Open(filepath.c_str(), FSOUND_2D, (sint)fileOffset, (sint)fileSize);
if (stream) if (stream)
{ {
getTag(artist, "ARTIST", stream); getTag(artist, "ARTIST", stream);

@ -112,7 +112,7 @@ public:
virtual IMusicChannel *createMusicChannel(); virtual IMusicChannel *createMusicChannel();
/** Get music info. Returns false if the song is not found or the function is not implemented. /** Get music info. Returns false if the song is not found or the function is not implemented.
* \param filepath path to file, CPath::lookup done by driver * \param filepath full path to file
* \param artist returns the song artist (empty if not available) * \param artist returns the song artist (empty if not available)
* \param title returns the title (empty if not available) * \param title returns the title (empty if not available)
*/ */

@ -8,7 +8,7 @@ IF(WITH_RYZOM_CLIENT)
ADD_SUBDIRECTORY(unix) ADD_SUBDIRECTORY(unix)
ENDIF() ENDIF()
INSTALL(FILES client_default.cfg DESTINATION ${RYZOM_ETC_PREFIX}) #INSTALL(FILES client_default.cfg DESTINATION ${RYZOM_ETC_PREFIX})
IF(WITH_RYZOM_PATCH) IF(WITH_RYZOM_PATCH)
IF(APPLE) IF(APPLE)

@ -1,612 +0,0 @@
//////////////////////////
//////////////////////////
/// CLIENT CONFIG FILE ///
//////////////////////////
//////////////////////////
// If you set this variable to 1, your client.cfg will be overwritten when you quit the client.
// You will loose all the comments and identation in this file.
SaveConfig = 1;
///////////////////
// WINDOW CONFIG //
///////////////////
Driver3D="Auto"; // Valid values are "Auto" or "0", "OpengGL" or "1" & "Direct3D" or "2"
// "Auto" will choose the best suited driver depending on hardware
FullScreen = 0;
Width = 0;
Height = 0;
PositionX = 0;
PositionY = 0;
Frequency = 0;
Depth = 32;
Sleep = -1;
ProcessPriority = 0; // -2 = idle, -1 = below normal, 0 = normal, 1 = above normal, 2 = high, 3 = real time
Contrast = 0.0; // -1.0 ~ 1.0
Luminosity = 0.0; // -1.0 ~ 1.0
Gamma = 0.0; // -1.0 ~ 1.0
Contrast_min = -1.0;
Luminosity_min = -1.0;
Gamma_min = -1.0;
Contrast_max = 1.0;
Luminosity_max = 1.0;
Gamma_max = 1.0;
/////////////
// NETWORK //
/////////////
Application = { "ryzom_live", "./client_ryzom_r.exe", "./" };
BackgroundDownloader = 0;
StartupHost = "shard.ryzom.com:40916";
StartupPage = "/login/r2_login.php";
StartupVerify = 1;
ConditionsTermsURL = "https://app.ryzom.com/app_forum/index.php?page=topic/view/21885/1&post148782=en#1";
LoginSupportURL = "https://app.ryzom.com/app_forum/index.php?page=topic/view/22047/1&post149889=en#1";
NamingPolicyURL = "https://app.ryzom.com/app_forum/index.php?page=topic/view/21885/1&post148784=en#3";
// Full path and filename where cURL can find certificate bundle file
// cacert.pem file can be downloaded from https://curl.haxx.se/docs/caextract.html
// and added to client data path or system specific bundle can be used
// Ubuntu has "/etc/ssl/certs/ca-certificates.crt"
// % = defaultConfigFilePath
CurlCABundle = "%cacert.pem";
////////////////
// INTERFACES //
////////////////
// the language to use as in ISO 639-2
LanguageCode = "en"; // english
XMLInputFile = "input_config_v3.xml";
XMLLoginInterfaceFiles = {
"login_config.xml",
"login_widgets.xml",
"login_main.xml",
"login_keys.xml",
};
XMLOutGameInterfaceFiles = {
"out_v2_config.xml",
"out_v2_widgets.xml",
"out_v2_connect.xml",
"out_v2_intro.xml",
"out_v2_select.xml",
"out_v2_appear.xml",
"out_v2_location.xml",
"out_v2_crash.xml",
"out_v2_hierarchy.xml",
"out_v2_keys.xml",
};
TexturesInterface = "texture_interfaces_v3";
TexturesInterfaceDXTC = "texture_interfaces_dxtc";
// The ligo primitive class file
LigoPrimitiveClass = "world_editor_classes.xml";
VerboseLog = 1;
///////////
// MOUSE //
///////////
HardwareCursor = 1;
CursorSpeed = 1.0; // In pixels per mickey
CursorSpeed_min = 0.5;
CursorSpeed_max = 2.0;
CursorAcceleration = 40; // Threshold in mickey
CursorAcceleration_min = 20;
CursorAcceleration_max = 80;
FreeLookSpeed = 0.004; // In radian per mickey
FreeLookSpeed_min = 0.0001;
FreeLookSpeed_max = 0.01;
FreeLookAcceleration = 40; // Threshold in mickey
FreeLookAcceleration_min = 20;
FreeLookAcceleration_max = 80;
FreeLookInverted = 0;
FreeLookTablet = 0;
AutomaticCamera = 0;
DblClickMode = 1;
AutoEquipTool = 1;
///////////////////
// RENDER CONFIG //
///////////////////
// NB: thoses variables configure also the InGameConfigurator:
// _min and _max define the bounds
// _step defines the step (NB: take care of _min and _max!!)
// _ps0 is the LOW preset, _ps1 is the MEDIUM preset, _ps2 is the NORMAL Preset, and _ps3 is the HIGH one
// *** LANDSCAPE
LandscapeTileNear = 50.000000;
LandscapeTileNear_min = 20.000000;
LandscapeTileNear_max = 100.000000;
LandscapeTileNear_step = 10.0;
LandscapeTileNear_ps0 = 20.0;
LandscapeTileNear_ps1 = 40.0;
LandscapeTileNear_ps2 = 50.0;
LandscapeTileNear_ps3 = 80.0;
// NB: threshold is inverted ULandscape::setThreshold(), to be more intelligible
LandscapeThreshold = 1000.0;
LandscapeThreshold_min = 100.0; // Low quality => 0.01 threshold
LandscapeThreshold_max = 2000.0; // High quality => 0.0005 threshold
LandscapeThreshold_step = 100.0;
LandscapeThreshold_ps0 = 100.0;
LandscapeThreshold_ps1 = 500.0;
LandscapeThreshold_ps2 = 1000.0;
LandscapeThreshold_ps3 = 2000.0;
Vision = 500.000000;
Vision_min = 200.000000;
Vision_max = 800.000000;
Vision_step = 100.000000;
Vision_ps0 = 200.0;
Vision_ps1 = 400.0;
Vision_ps2 = 500.0;
Vision_ps3 = 800.0;
MicroVeget = 1; // Enable/Disable MicroVeget.
MicroVeget_ps0 = 0;
MicroVeget_ps1 = 1;
MicroVeget_ps2 = 1;
MicroVeget_ps3 = 1;
MicroVegetDensity = 80.0;
MicroVegetDensity_min = 10.0;
MicroVegetDensity_max = 100.0;
MicroVegetDensity_step = 10.0;
MicroVegetDensity_ps0 = 10.0; // not used since disabled!
MicroVegetDensity_ps1 = 30.0;
MicroVegetDensity_ps2 = 80.0;
MicroVegetDensity_ps3 = 100.0;
// *** FX
FxNbMaxPoly = 20000;
FxNbMaxPoly_min = 2000;
FxNbMaxPoly_max = 50000;
FxNbMaxPoly_step= 2000;
FxNbMaxPoly_ps0 = 2000;
FxNbMaxPoly_ps1 = 10000;
FxNbMaxPoly_ps2 = 20000;
FxNbMaxPoly_ps3 = 50000;
Cloud = 1;
Cloud_ps0 = 0 ;
Cloud_ps1 = 1 ;
Cloud_ps2 = 1 ;
Cloud_ps3 = 1 ;
CloudQuality = 160.0;
CloudQuality_min = 80.0;
CloudQuality_max = 320.0;
CloudQuality_step = 20.0;
CloudQuality_ps0 = 80.0; // not used since disabled!
CloudQuality_ps1 = 80.0;
CloudQuality_ps2 = 160.0;
CloudQuality_ps3 = 320.0;
CloudUpdate = 1;
CloudUpdate_min = 1;
CloudUpdate_max = 8;
CloudUpdate_step= 1;
CloudUpdate_ps0 = 1; // not used since disabled!
CloudUpdate_ps1 = 1;
CloudUpdate_ps2 = 1;
CloudUpdate_ps3 = 3;
Shadows = 1;
Shadows_ps0 = 0;
Shadows_ps1 = 1;
Shadows_ps2 = 1;
Shadows_ps3 = 1;
FXAA = 1;
FXAA_ps0 = 0;
FXAA_ps1 = 1;
FXAA_ps2 = 1;
FXAA_ps3 = 1;
AnisotropicFilter = 0;
Bloom = 1;
Bloom_ps0 = 0;
Bloom_ps1 = 1;
Bloom_ps2 = 1;
Bloom_ps3 = 1;
SquareBloom = 1;
SquareBloom_ps0 = 0;
SquareBloom_ps1 = 1;
SquareBloom_ps2 = 1;
SquareBloom_ps3 = 1;
DensityBloom = 255.0;
DensityBloom_min = 0.0;
DensityBloom_max = 255.0;
DensityBloom_step = 1.0;
DensityBloom_ps0 = 255.0;
DensityBloom_ps1 = 255.0;
DensityBloom_ps2 = 255.0;
DensityBloom_ps3 = 255.0;
// *** CHARACTERS
SkinNbMaxPoly = 100000;
SkinNbMaxPoly_min = 5000;
SkinNbMaxPoly_max = 250000;
SkinNbMaxPoly_step = 5000;
SkinNbMaxPoly_ps0 = 10000;
SkinNbMaxPoly_ps1 = 70000;
SkinNbMaxPoly_ps2 = 100000;
SkinNbMaxPoly_ps3 = 200000;
NbMaxSkeletonNotCLod = 125;
NbMaxSkeletonNotCLod_min = 5;
NbMaxSkeletonNotCLod_max = 255;
NbMaxSkeletonNotCLod_step = 5;
NbMaxSkeletonNotCLod_ps0 = 10;
NbMaxSkeletonNotCLod_ps1 = 50;
NbMaxSkeletonNotCLod_ps2 = 125;
NbMaxSkeletonNotCLod_ps3 = 255;
CharacterFarClip = 200.0;
CharacterFarClip_min = 50.0;
CharacterFarClip_max = 500.0;
CharacterFarClip_step = 10.0;
CharacterFarClip_ps0 = 50.0;
CharacterFarClip_ps1 = 100.0;
CharacterFarClip_ps2 = 200.0;
CharacterFarClip_ps3 = 500.0;
EnableRacialAnimation = 1;
// *** MISC
// This is the actual aspect ratio of your screen (no relation with the resolution!!). Set 1.7777 if you got a 16/9 screen for instance
ScreenAspectRatio = 0.0;
ForceDXTC = 1; // Enable/Disable DXTC.
DivideTextureSizeBy2= 0; // Divide texture size
DisableVtxProgram = 0; // Disable Hardware Vertex Program.
DisableVtxAGP = 0; // Disable Hardware Vertex AGP.
DisableTextureShdr = 0; // Disable Hardware Texture Shader.
HDEntityTexture = 1;
HDTextureInstalled = 1;
WaitVBL = 0; // 0 or 1 to wait Vertical Sync.
//////////////////
// GAME OPTIONS //
//////////////////
SelectWithRClick = 1;
DisplayWeapons = 1;
RotKeySpeedMax = 2.0;
RotKeySpeedMax_min = 1.0;
RotKeySpeedMax_max = 4.0;
RotKeySpeedMin = 1.0;
RotKeySpeedMin_min = 0.5;
RotKeySpeedMin_max = 2.0;
RotAccel = 3.0;
FollowOnAtk = 0;
AtkOnSelect = 0;
ZCPacsPrim = "gen_bt_col_ext.pacs_prim";
/////////////////
// PREFERENCES //
/////////////////
FPV = 0; // FPV(First Person View) : default is false (Third Person View).
CameraHeight = 2.2; // Camera Height (in meter) from the ground (for the Third Person View).
CameraDistance = 3.0; // Camera Distance(in meter) from the user (for the Third Person View).
CameraDistStep = 1.0;
CameraDistMin = 1.0;
CameraDistMax = 25.0;
CameraAccel = 5.0;
CameraSpeedMin = 2.0;
CameraSpeedMax = 100.0;
CameraResetSpeed = 10.0; // Speed in radian/s
// Values for UI Scale
InterfaceScale = 1.0;
InterfaceScale_min = 0.8;
InterfaceScale_max = 2.0;
InterfaceScale_step = 0.05;
// Enable biliner filtering for UI textures
// Texture atlas needs to be generated with border duplication
// or there will be visible texture bleeding
BilinearUI = 1;
// Default values for map
MaxMapScale = 2.0;
R2EDMaxMapScale = 8.0;
WindowSnapInvert = 0;
WindowSnapDistance = 10;
WindowSnapDistance_min = 0;
WindowSnapDistance_max = 50;
WindowSnapDistance_step = 1;
//////////////////
// SOUND CONFIG //
//////////////////
SoundForceSoftwareBuffer= 1;
SoundOn = 1;
UseEax = 0;
MaxTrack = 32;
MaxTrack_min = 4;
MaxTrack_max = 32;
MaxTrack_step = 4;
// This is the volume for "InGame" sound FXs
SoundSFXVolume = 1.0;
SoundSFXVolume_min = 0.0;
SoundSFXVolume_max = 1.0;
SoundSFXVolume_step = 0.001;
// This is volume for "InGame" music. Does not affect the MP3 player
SoundGameMusicVolume = 0.5;
SoundGameMusicVolume_min = 0.0;
SoundGameMusicVolume_max = 1.0;
SoundGameMusicVolume_step = 0.001;
// MP3 player
MediaPlayerDirectory = "music";
MediaPlayerAutoPlay = false;
// MISC
PreDataPath = { "user", "patch", "data", "examples" };
NeedComputeVS = 0;
NegFiltersDebug = {"Update DB", "Reading:", "Read Value :", "impulseCallBack", "CLIMPD:", "LNET" };
NegFiltersInfo = { "CLIMPD:", "CPath::lookup" , "LNET" };
NegFiltersWarning = { "'basics.Equipment Slot'.", "_usercolor.tga", "PACS" };
// Big screen shot
ScreenShotWidth = 0;
ScreenShotHeight = 0;
ScreenShotFullDetail = 1; // 1 to switch full detail mode for characters (both standard & big screenshots)
// Read : "ID", "R G B A MODE [FX]"
SystemInfoColors =
{
// OLD STUFF Here for compatibility
"RG", "0 0 0 255 normal", // Black to see when there is an error
"BC", "0 0 0 255 normal", // Black to see when there is an error
"JA", "0 0 0 255 normal", // Black to see when there is an error
"BL", "0 0 0 255 normal", // Black to see when there is an error
"VE", "0 0 0 255 normal", // Black to see when there is an error
"VI", "0 0 0 255 normal", // Black to see when there is an error
// NEW System Info Categories
"SYS", "255 255 255 255 normal", // Default system messages
"BC", "255 255 255 255 centeraround", // Broadcast messages
"TAGBC", "255 255 255 255 centeraround", // Taged broadcast messages : color should remain white as some word are tagged
"XP", "255 255 64 255 over", // XP Gain
"SP", "255 255 64 255 over", // SP Gain
"TTL", "255 255 64 255 over", // Title
"TSK", "255 255 255 255 over", // Task
"ZON", "255 255 255 255 center", // Zone
"DG", "255 0 0 255 normal", // Damage to me
"DMG", "255 0 0 255 normal", // Damage to me
"DGP", "200 0 0 255 normal", // Damage to me from player
"DGM", "255 128 64 255 normal", // Damage from me
"MIS", "150 150 150 255 normal", // The opponent misses
"MISM", "255 255 255 255 normal", // I miss
"ITM", "0 200 0 255 over", // Item
"ITMO", "170 170 255 255 overonly", // Item other in group
"ITMF", "220 0 220 255 over", // Item failed
"SPL", "50 50 250 255 normal", // Spell to me
"SPLM", "50 150 250 255 normal", // Spell from me
"EMT", "255 150 150 255 normal", // Emote
"MTD", "255 255 0 255 over", // Message Of The Day
"FORLD","64 255 64 255 overonly", // Forage Locate Deposit
"CHK", "255 120 60 255 center", // Tous ce qui ne remplit pas une condition
"CHKCB","255 255 0 255 center", // Tous ce qui ne remplit pas une condition en combat (trop loin, cible invalide, pas assez de mana, etc.)
"PVPTM","255 120 60 255 overonly", // PVP timer
"THM", "255 255 64 255 over misc_levelup.ps", // Thema finished
"AMB", "255 255 64 255 center", // Ambiance
"ISE", "192 208 255 255 normal", // Item special effect
"ISE2", "192 208 255 255 center", // Item special effect with center text (for effects without flying text)
"OSM", "128 160 255 255 center", // Outpost state message
"AROUND","255 255 0 255 around", // Only in around channel
"R2_INVITE","0 255 0 255 around", // Ring invitation
};
loadingTexts = {
"0", "132", "30 144 255 255", "18", "uiS2",
"0", "105", "255 188 0 255", "14", "uiS2E0",
"0", "65", "255 255 255 255", "12", "NEWS"
};
DisplayMissingAnimFile = 0;
LoadingStringCount = 54;
// Some R2 parameters ...
R2Mode = 1;
R2EDEnabled = 1;
R2EDExtendedDebug = 0;
R2EDLightPalette = 0;
R2ClientGw = "r2linux01";
LoadLuaDebugger = 0;
CheckR2ScenarioMD5 = 1;
LevelDesignEnabled = 0;
DmCameraDistMax = 25;
DmRun = 20;
DmWalk = 6;
R2EDReloadFiles = {
"r2ed.xml",
"r2_basic_bricks.lua",
"r2_components.lua",
"r2_core.lua",
"r2_features_default.lua",
"r2_features_fauna.lua",
"r2_features_npc_groups.lua",
"r2_palette.lua",
"r2_scenario.lua",
"r2_ui.lua"
};
XMLInterfaceFiles = {
"config.xml",
"widgets.xml",
"webig_widgets.xml",
"appzone.xml",
"player.xml",
"inventory.xml",
"interaction.xml",
"phrase.xml",
"harvest.xml",
"macros.xml",
"info_player.xml",
"outpost.xml",
"guild.xml",
"taskbar.xml",
"game_config.xml",
"game_context_menu.xml",
"player_trade.xml",
"bot_chat_v4.xml",
"compass.xml",
"map.xml",
"hierarchy.xml",
"reset.xml",
"actions.xml",
"help.xml",
"encyclopedia.xml",
"commands.xml",
"commands2.xml",
"ring_access_point_filter.xml",
"ring_window.xml",
"bg_downloader.xml",
"ryzhome_toolbar.xml",
"tp_interface.xml"
};
XMLR2EDInterfaceFiles =
{
"r2ed.xml",
"r2_triggers.xml",
"r2_logic_entities.xml",
"r2ed_acts.xml",
"r2ed_scenario.xml",
"r2ed_connect.xml"
};
FogDistAndDepthLookupBias = 20; // bias for lookup of fog distance and depth
// Hardware cursor textures
// These will be extracted from the corresponding packed ui .tga files when they are loaded
// *
// * individual .tga files for hardware cursor bitmap not looked for, and not supported yet
HardwareCursors =
{
"curs_can_pan.tga",
"curs_can_pan_dup.tga",
"curs_create.tga",
"curs_create_multi.tga",
"curs_create_vertex_invalid.tga",
"curs_default.tga",
"curs_dup.tga",
"curs_L.tga",
"curs_M.tga",
"curs_pan.tga",
"curs_pan_dup.tga",
"curs_pick.tga",
"curs_pick_dup.tga",
"curs_R.tga",
"curs_resize_BL_TR.tga",
"curs_resize_BR_TL.tga",
"curs_resize_LR.tga",
"curs_resize_TB.tga",
"curs_rotate.tga",
"curs_scale.tga",
"curs_stop.tga",
"text_cursor.tga",
"r2_hand_can_pan.tga",
"r2_hand_pan.tga",
"r2ed_tool_can_pick.tga",
"r2ed_tool_can_rotate.tga",
"r2ed_tool_pick.tga",
"r2ed_tool_rotate.tga",
"r2ed_tool_rotating.tga"
};
Loading_BG = "new_loading_bg.tga"; // Default name for the loading background file.
Launch_BG = "new_launcher_bg.tga"; // Default name for the launch background file.
TeleportKami_BG = "new_teleport_kami_bg.tga";
TeleportKaravan_BG = "new_teleport_caravan_bg.tga";
Elevator_BG = "new_elevator_bg.tga"; // Default name for the loading background file.
ResurectKami_BG = "new_resurect_kami_bg.tga";
ResurectKaravan_BG = "new_resurect_caravane_bg.tga";
End_BG = "end_bg.tga"; // Default name for the last background file.
ScenarioSavePath = "./my_scenarios/";
// list ofpredefined keyset
// name will be looked up in the translation file by searching 'uiCP_KeysetName_" + id
// tooltip will be looked up in the translation file by searching 'uiCP_KeysetTooltip_" + id
// 'bi.' stands for built-in
// note : we add a dot in the name to be sure that there cannot be a conflict with character keyset name
BuiltInKeySets =
{
"", // default ryzom keyboard layout
"bi.zqsd", // european keyboard fps displacement style (NB : don't change this layout name, ryzom will automatically select it if keyboard is french or belgian)
"bi.wasd", // english keyboard fps displacement style (NB : don't change this layout name, ryzom will automatically select it if keyboard is not french nor belgian)
"bi.wow_alike" // 'world of warcraft' like keyboard style. (NB : not available for ring)
};
// "Newbie Training", "Story Telling", "Mistery", "Hack & Slash", "Guild Training", "Other"
ScenarioTypes = {"so_newbie_training","so_story_telling","so_mistery","so_hack_slash","so_guild_training","so_other"};
ScenarioLanguages = {"fr","de","en","other_lang"};
// Map each language to a forum help page
HelpPages =
{
"fr=https://app.ryzom.com/app_forum/index.php?page=topic/view/6629/1&lang=fr",
"en=https://app.ryzom.com/app_forum/index.php?page=topic/view/6629/1&lang=en",
"wk=https://app.ryzom.com/app_forum/index.php?page=topic/view/6629/1",
"de=https://app.ryzom.com/app_forum/index.php?page=topic/view/6629/1&lang=de",
"es=https://app.ryzom.com/app_forum/index.php?page=topic/view/6629/1&lang=es",
"ru=https://app.ryzom.com/app_forum/index.php?page=topic/view/6629/1&lang=ru"
};
// User created channel
ChannelIgnoreFilter =
{
"Uni Français", "English Uni", "Español Uni",
"русский Uni", "Deutsch Uni", "Karavan",
"Kami", "Ranger", "Marauder", "Fyros",
"Matis", "Tryker", "Zoraï"
};
// interval in minutes for webig notify thread to run
WebIgNotifInterval = 10;
WebIgMainDomain = "app.ryzom.com";
WebIgTrustedDomains = {
"api.ryzom.com", "app.ryzom.com"
};
PatchletUrl = "https://app.ryzom.com/app_patchlet/index.php?patch=preload";
SelectedSlot = 0;
BuildName = "RELEASE_HEAD";

@ -82,7 +82,7 @@ IF(WITH_RYZOM_CLIENT)
ADD_CUSTOM_COMMAND(TARGET ryzom_client PRE_BUILD COMMAND mkdir -p ${RYZOM_RESOURCES_DIR}) ADD_CUSTOM_COMMAND(TARGET ryzom_client PRE_BUILD COMMAND mkdir -p ${RYZOM_RESOURCES_DIR})
ADD_CUSTOM_COMMAND(TARGET ryzom_client POST_BUILD COMMAND cp ARGS -p ${MAC_RESOURCES_DIR}/PkgInfo ${RYZOM_CONTENTS_DIR}) ADD_CUSTOM_COMMAND(TARGET ryzom_client POST_BUILD COMMAND cp ARGS -p ${MAC_RESOURCES_DIR}/PkgInfo ${RYZOM_CONTENTS_DIR})
ADD_CUSTOM_COMMAND(TARGET ryzom_client POST_BUILD COMMAND cp ARGS -p ${MAC_RESOURCES_DIR}/ryzom.icns ${RYZOM_RESOURCES_DIR}) ADD_CUSTOM_COMMAND(TARGET ryzom_client POST_BUILD COMMAND cp ARGS -p ${MAC_RESOURCES_DIR}/ryzom.icns ${RYZOM_RESOURCES_DIR})
ADD_CUSTOM_COMMAND(TARGET ryzom_client POST_BUILD COMMAND cp ARGS -p ${CMAKE_SOURCE_DIR}/ryzom/client/client_default.cfg ${RYZOM_RESOURCES_DIR}) #ADD_CUSTOM_COMMAND(TARGET ryzom_client POST_BUILD COMMAND cp ARGS -p ${CMAKE_SOURCE_DIR}/ryzom/client/client_default.cfg ${RYZOM_RESOURCES_DIR})
# remove any present installscript_osx.vdf before signing # remove any present installscript_osx.vdf before signing
ADD_CUSTOM_COMMAND(TARGET ryzom_client POST_BUILD COMMAND rm -f ${RYZOM_OUTPUT_DIR}/installscript_osx.vdf) ADD_CUSTOM_COMMAND(TARGET ryzom_client POST_BUILD COMMAND rm -f ${RYZOM_OUTPUT_DIR}/installscript_osx.vdf)

@ -180,6 +180,7 @@ int main(int argc, char **argv)
Args.setVersion(getDisplayVersion()); Args.setVersion(getDisplayVersion());
Args.setDescription("Ryzom client"); Args.setDescription("Ryzom client");
Args.addArg("n", "nopatch", "value", "Use this to not use patch system");
Args.addArg("p", "profile", "id", "Use this profile to determine what directory to use by default"); Args.addArg("p", "profile", "id", "Use this profile to determine what directory to use by default");
Args.addAdditionalArg("login", "Login to use", true, false); Args.addAdditionalArg("login", "Login to use", true, false);
Args.addAdditionalArg("password", "Password to use", true, false); Args.addAdditionalArg("password", "Password to use", true, false);

@ -326,17 +326,8 @@ CClientConfig::CClientConfig()
Local = false; // Default is Net Mode. Local = false; // Default is Net Mode.
FSHost = ""; // Default Host. FSHost = ""; // Default Host.
#if 1 // Yubo hack TexturesInterface.push_back("texture_interfaces_v3_2x");
// The order is important here, because in a layer, global texture are rendered through this order TexturesInterfaceDXTC.push_back("texture_interfaces_dxtc_2x");
TexturesInterface.push_back("texture_interfaces_v3");
// DXTC contain all items and bricks bitmaps, they must come after standard texture
TexturesInterface.push_back("new_texture_interfaces_dxtc");
// Added icons by Yubo's Team 2009
TexturesInterface.push_back("texture_extra");
#else
TexturesInterface.push_back("texture_interfaces_v3");
TexturesInterfaceDXTC.push_back("texture_interfaces_dxtc");
#endif
TexturesOutGameInterface.push_back("texture_interfaces_v3_outgame_ui"); TexturesOutGameInterface.push_back("texture_interfaces_v3_outgame_ui");
@ -448,8 +439,8 @@ CClientConfig::CClientConfig()
CurlMaxConnections = 5; CurlMaxConnections = 5;
CurlCABundle.clear(); CurlCABundle.clear();
RingReleaseNotePath = WebIgMainDomain + "/releasenotes_ring/index.php"; RingReleaseNotePath = WebIgMainDomain + "/app_releasenotes/index.php";
ReleaseNotePath = WebIgMainDomain + "/releasenotes/index.php"; ReleaseNotePath = WebIgMainDomain + "/app_releasenotes/index.php";
/////////////// ///////////////
@ -791,8 +782,8 @@ void CClientConfig::setValues()
READ_STRINGVECTOR_FV(TexturesOutGameInterfaceDXTC); READ_STRINGVECTOR_FV(TexturesOutGameInterfaceDXTC);
// interface textures ingame and r2 // interface textures ingame and r2
READ_STRINGVECTOR_FV(TexturesInterface); //READ_STRINGVECTOR_FV(TexturesInterface);
READ_STRINGVECTOR_FV(TexturesInterfaceDXTC); //READ_STRINGVECTOR_FV(TexturesInterfaceDXTC);
// interface files login menus // interface files login menus
READ_STRINGVECTOR_FV(XMLLoginInterfaceFiles); READ_STRINGVECTOR_FV(XMLLoginInterfaceFiles);
@ -1126,7 +1117,7 @@ void CClientConfig::setValues()
if (ClientCfg.getDefaultConfigLocation(defaultConfigFileName)) if (ClientCfg.getDefaultConfigLocation(defaultConfigFileName))
ClientCfg.CurlCABundle = CFile::getPath(defaultConfigFileName)+ClientCfg.CurlCABundle.substr(1); ClientCfg.CurlCABundle = CFile::getPath(defaultConfigFileName)+ClientCfg.CurlCABundle.substr(1);
} }
/////////////// ///////////////
// ANIMATION // // ANIMATION //
// AnimatedAngleThreshold // AnimatedAngleThreshold

@ -549,6 +549,6 @@ bool CSBrickSheet::mustDisplayLevel() const
// NB: Yoyo Hack. special interface with indexInFamily==63 means "want to display the level" // NB: Yoyo Hack. special interface with indexInFamily==63 means "want to display the level"
return !( isMandatory() || return !( isMandatory() ||
isRoot() || isRoot() ||
(BrickFamily>= BRICK_FAMILIES::BeginInterface && BrickFamily<= BRICK_FAMILIES::EndInterface && IndexInFamily!=63) || //(BrickFamily>= BRICK_FAMILIES::BeginInterface && BrickFamily<= BRICK_FAMILIES::EndInterface && IndexInFamily!=63) ||
Level==0 ); Level==0 );
} }

@ -33,6 +33,7 @@
#include "nel/misc/time_nl.h" #include "nel/misc/time_nl.h"
#include "nel/misc/algo.h" #include "nel/misc/algo.h"
#include "nel/misc/system_utils.h" #include "nel/misc/system_utils.h"
#include "nel/misc/stream.h"
// 3D Interface. // 3D Interface.
#include "nel/3d/u_driver.h" #include "nel/3d/u_driver.h"
#include "nel/3d/u_text_context.h" #include "nel/3d/u_text_context.h"
@ -149,6 +150,7 @@ ucstring PlayerSelectedHomeShardName;
ucstring PlayerSelectedHomeShardNameWithParenthesis; ucstring PlayerSelectedHomeShardNameWithParenthesis;
extern std::string CurrentCookie; extern std::string CurrentCookie;
ucstring NewKeysCharNameWanted; // name of the character for which a new keyset must be created ucstring NewKeysCharNameWanted; // name of the character for which a new keyset must be created
ucstring NewKeysCharNameValidated; ucstring NewKeysCharNameValidated;
std::string GameKeySet = "keys.xml"; std::string GameKeySet = "keys.xml";
@ -157,9 +159,11 @@ std::string RingEditorKeySet = "keys_r2ed.xml";
string ScenarioFileName; string ScenarioFileName;
sint LoginCharsel = -1; sint LoginCharsel = -1;
static const char *KeySetVarName = "BuiltInKeySets"; std::string ImportCharacter;
static const char *KeySetVarName = "BuiltInKeySets";
#define GROUP_LIST_CHARACTER "ui:outgame:charsel_import:import_list"
#define GROUP_LIST_MAINLAND "ui:outgame:appear_mainland:mainland_list" #define GROUP_LIST_MAINLAND "ui:outgame:appear_mainland:mainland_list"
#define GROUP_LIST_KEYSET "ui:outgame:appear_keyset:keyset_list" #define GROUP_LIST_KEYSET "ui:outgame:appear_keyset:keyset_list"
vector<CMainlandSummary> Mainlands; vector<CMainlandSummary> Mainlands;
@ -189,6 +193,7 @@ bool hasPrivilegeG() { return (UserPrivileges.find(":G:") != std::string::npos);
bool hasPrivilegeEM() { return (UserPrivileges.find(":EM:") != std::string::npos); } bool hasPrivilegeEM() { return (UserPrivileges.find(":EM:") != std::string::npos); }
bool hasPrivilegeEG() { return (UserPrivileges.find(":EG:") != std::string::npos); } bool hasPrivilegeEG() { return (UserPrivileges.find(":EG:") != std::string::npos); }
bool hasPrivilegeOBSERVER() { return (UserPrivileges.find(":OBSERVER:") != std::string::npos); } bool hasPrivilegeOBSERVER() { return (UserPrivileges.find(":OBSERVER:") != std::string::npos); }
bool hasPrivilegeTESTER() { return (UserPrivileges.find(":TESTER:") != std::string::npos); }
// Restore the video mode (fullscreen for example) after the connection (done in a window) // Restore the video mode (fullscreen for example) after the connection (done in a window)
@ -2124,7 +2129,7 @@ public:
virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */) virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */)
{ {
CInterfaceManager *pIM = CInterfaceManager::getInstance(); //CInterfaceManager *pIM = CInterfaceManager::getInstance();
CInterfaceGroup *pList = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_MAINLAND)); CInterfaceGroup *pList = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_MAINLAND));
if (pList == NULL) if (pList == NULL)
@ -2203,7 +2208,7 @@ public:
virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */) virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */)
{ {
CInterfaceManager *pIM = CInterfaceManager::getInstance(); //CInterfaceManager *pIM = CInterfaceManager::getInstance();
CInterfaceGroup *pList = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_MAINLAND)); CInterfaceGroup *pList = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_MAINLAND));
pList->clearGroups(); pList->clearGroups();
} }
@ -2214,32 +2219,56 @@ REGISTER_ACTION_HANDLER (CAHResetMainlandList, "reset_mainland_list");
// *************************************************************************** // ***************************************************************************
class CAHMainlandSelect : public IActionHandler class CAHMainlandSelect : public IActionHandler
{ {
virtual void execute (CCtrlBase *pCaller, const string &/* Params */) virtual void execute (CCtrlBase *pCaller, const std::string &Params)
{ {
nlinfo("CAHMainlandSelect called"); //nlinfo("CAHMainlandSelect called");
struct CUnpush : public CInterfaceElementVisitor
CInterfaceManager *pIM = CInterfaceManager::getInstance(); {
CCtrlBase *Ref;
virtual void visitCtrl(CCtrlBase *ctrl)
{
if (ctrl == Ref) return;
CCtrlBaseButton *but = dynamic_cast<CCtrlBaseButton*>(ctrl);
if (but)
{
but->setPushed(false);
}
}
};
CInterfaceGroup *list = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_MAINLAND));
if (!list)
return;
CCtrlButton *pCB = NULL; // unselect
// Unselect if (Params.empty())
if (MainlandSelected.asInt() != 0)
{ {
pCB = dynamic_cast<CCtrlButton*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_MAINLAND ":"+toString(MainlandSelected)+":but")); CUnpush unpusher;
if (pCB != NULL) unpusher.Ref = pCaller;
pCB->setPushed(false); list->visit(&unpusher);
} }
pCB = dynamic_cast<CCtrlButton*>(pCaller); // now select
if (pCB != NULL) uint32 mainland;
if (Params.empty())
{ {
string name = pCB->getId(); CCtrlButton *pCB = dynamic_cast<CCtrlButton*>(pCaller);
name = name.substr(0,name.rfind(':')); if (!pCB)
uint32 mainland; return;
fromString(name.substr(name.rfind(':')+1,name.size()), mainland);
MainlandSelected = (TSessionId)mainland; std::string name = pCB->getId();
name = name.substr(0, name.rfind(':'));
if (!fromString(name.substr(name.rfind(':')+1, name.size()), mainland))
return;
pCB->setPushed(true); pCB->setPushed(true);
} }
else
if (!fromString(Params, mainland))
return;
// and store
MainlandSelected = (TSessionId)mainland;
} }
}; };
REGISTER_ACTION_HANDLER (CAHMainlandSelect, "mainland_select"); REGISTER_ACTION_HANDLER (CAHMainlandSelect, "mainland_select");
@ -2444,7 +2473,7 @@ public:
virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */) virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */)
{ {
CInterfaceManager *pIM = CInterfaceManager::getInstance(); //CInterfaceManager *pIM = CInterfaceManager::getInstance();
CInterfaceGroup *pList = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_KEYSET)); CInterfaceGroup *pList = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_KEYSET));
pList->clearGroups(); pList->clearGroups();
} }
@ -2455,59 +2484,66 @@ REGISTER_ACTION_HANDLER (CAHResetKeysetList, "reset_keyset_list");
// *************************************************************************** // ***************************************************************************
class CAHResetKeysetSelect : public IActionHandler class CAHResetKeysetSelect : public IActionHandler
{ {
public:
std::string getIdPostFix(const std::string fullId) std::string getIdPostFix(const std::string fullId)
{ {
std::string::size_type pos = fullId.find_last_of(":"); std::string::size_type pos = fullId.find_last_of(":");
if (pos != std::string::npos) if (pos != std::string::npos)
{
return fullId.substr(pos + 1); return fullId.substr(pos + 1);
}
return ""; return "";
} }
virtual void execute (CCtrlBase *pCaller, const string &/* Params */)
virtual void execute(CCtrlBase *pCaller, const std::string &Params)
{ {
if (!pCaller) return;
// 'unpush' all groups but the caller // 'unpush' all groups but the caller
//
struct CUnpush : public CInterfaceElementVisitor struct CUnpush : public CInterfaceElementVisitor
{ {
CCtrlBase *Ref; CCtrlBase *Ref;
virtual void visitCtrl(CCtrlBase *ctrl) virtual void visitCtrl(CCtrlBase *ctrl)
{ {
if (ctrl == Ref) return; if (ctrl == Ref) return;
CCtrlBaseButton *but = dynamic_cast<CCtrlBaseButton *>(ctrl); CCtrlBaseButton *but = dynamic_cast<CCtrlBaseButton*>(ctrl);
if (but) if (but)
{ {
but->setPushed(false); but->setPushed(false);
} }
} }
}; };
CInterfaceManager *pIM = CInterfaceManager::getInstance(); CInterfaceGroup *list = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_KEYSET));
CInterfaceGroup * list = dynamic_cast<CInterfaceGroup *>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_KEYSET)); if (!list)
if (list) return;
{
CUnpush unpusher; // unselect
unpusher.Ref = pCaller; CUnpush unpusher;
list->visit(&unpusher); unpusher.Ref = pCaller;
} list->visit(&unpusher);
CCtrlBaseButton *but = dynamic_cast<CCtrlBaseButton *>(pCaller);
// now select
CCtrlBaseButton *but = dynamic_cast<CCtrlBaseButton*>(pCaller);
if (but) if (but)
{
but->setPushed(true); but->setPushed(true);
std::string id;
if (Params.empty())
{
if (!pCaller) return;
if (!pCaller->getParent()) return;
id = getIdPostFix(pCaller->getParent()->getId());
} }
// else
id = getIdPostFix(Params);
GameKeySet = "keys.xml"; GameKeySet = "keys.xml";
RingEditorKeySet = "keys_r2ed.xml"; RingEditorKeySet = "keys_r2ed.xml";
if (!pCaller->getParent()) return;
// compute the 2 filenames from the id // compute the two filenames from the id
// if id is in the built-in keysets : // if id is in the built-in keysets
CConfigFile::CVar *keySetVar = ClientCfg.ConfigFile.getVarPtr(KeySetVarName); CConfigFile::CVar *keySetVar = ClientCfg.ConfigFile.getVarPtr(KeySetVarName);
if (keySetVar && keySetVar->size() != 0) if (keySetVar && keySetVar->size() > 0)
{ {
for (uint k = 0; k < keySetVar->size(); ++k) for (uint k = 0; k < keySetVar->size(); ++k)
{ {
std::string id = getIdPostFix(pCaller->getParent()->getId());
if (keySetVar->asString(k) == id) if (keySetVar->asString(k) == id)
{ {
GameKeySet = "keys" + string(id.empty() ? "" : "_") + id + ".xml"; GameKeySet = "keys" + string(id.empty() ? "" : "_") + id + ".xml";
@ -2516,17 +2552,15 @@ public:
} }
} }
} }
// ... else maybe from a previous character ?
if (CFile::isExists("save/keys_" + getIdPostFix(pCaller->getParent()->getId()) + ".xml") )
{
GameKeySet = "keys_" + getIdPostFix(pCaller->getParent()->getId()) + ".xml";
}
if (CFile::isExists("save/keys_r2ed_" + getIdPostFix(pCaller->getParent()->getId()) + ".xml") )
{
RingEditorKeySet = "keys_r2ed_" + getIdPostFix(pCaller->getParent()->getId()) + ".xml";
}
// NB : key file will be copied for real when the new 'character summary' is
// else maybe from a previous character?
if (CFile::isExists("save/keys_" + id + ".xml"))
GameKeySet = "keys_" + id + ".xml";
if (CFile::isExists("save/keys_r2ed_" + id + ".xml"))
RingEditorKeySet = "keys_r2ed_" + id + ".xml";
// NB: key file will be copied for real when the new character summary is
} }
}; };
REGISTER_ACTION_HANDLER (CAHResetKeysetSelect, "keyset_select"); REGISTER_ACTION_HANDLER (CAHResetKeysetSelect, "keyset_select");
@ -3421,3 +3455,239 @@ class CAHOpenRingSessions : public IActionHandler
} }
}; };
REGISTER_ACTION_HANDLER (CAHOpenRingSessions, "open_ring_sessions"); REGISTER_ACTION_HANDLER (CAHOpenRingSessions, "open_ring_sessions");
// ***************************************************************************
class CAHInitImportCharacter : public IActionHandler
{
virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */)
{
CInterfaceGroup *list = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_CHARACTER));
if (!list)
{
nlwarning("element " GROUP_LIST_CHARACTER " not found probably bad outgame.xml");
return;
}
// retrieve saved files
std::vector<string> savedCharacters;
CPath::getPathContent("save/", false, false, true, savedCharacters);
CInterfaceGroup *newLine;
CInterfaceGroup *prevLine;
for (uint i = 0; i < savedCharacters.size(); ++i)
{
// search saved characters only
if (testWildCard(CFile::getFilename(savedCharacters[i]), "character_*.save"))
{
const std::string id = CFile::getFilenameWithoutExtension(savedCharacters[i]).substr(strlen("character_"));
if (id.empty())
continue;
std::vector<pair<string, string>> params;
params.clear();
params.push_back(std::pair<string, string>("id", id));
// adjust ref
if (list->getNumGroup() > 0)
params.push_back(std::pair<string, string>("posref", "BL TL"));
newLine = CWidgetManager::getInstance()->getParser()->createGroupInstance("t_import", GROUP_LIST_CHARACTER, params);
if (newLine)
{
CViewText *text = dynamic_cast<CViewText*>(newLine->getView("name"));
if (text)
text->setText(ucstring(savedCharacters[i]));
// first button is pushed
CCtrlButton *button = dynamic_cast<CCtrlButton*>(newLine->getCtrl("but"));
if (button && list->getNumGroup() == 0)
button->setPushed(true);
// add to the list now
newLine->setParent(list);
newLine->setParentSize(list);
newLine->setParentPos(prevLine);
list->addGroup(newLine);
prevLine = newLine;
}
}
}
// none case
if (list->getNumGroup() == 0)
CLuaManager::getInstance().executeLuaScript("outgame:procCharselNotifaction(3)");
list->invalidateCoords();
}
};
REGISTER_ACTION_HANDLER( CAHInitImportCharacter, "import_char_init" );
// ***************************************************************************
class CAHResetImportCharacter : public IActionHandler
{
virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */)
{
CInterfaceGroup *list = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_CHARACTER));
if (list)
list->clearGroups();
if (!ImportCharacter.empty())
ImportCharacter = "";
}
};
REGISTER_ACTION_HANDLER( CAHResetImportCharacter, "import_char_reset" );
// ***************************************************************************
class CAHSelectImportCharacter : public IActionHandler
{
virtual void execute (CCtrlBase *pCaller, const std::string &Params)
{
struct CUnpush : public CInterfaceElementVisitor
{
CCtrlBase *Ref;
virtual void visitCtrl(CCtrlBase *ctrl)
{
if (ctrl == Ref) return;
CCtrlBaseButton *but = dynamic_cast<CCtrlBaseButton*>(ctrl);
if (but)
{
but->setPushed(false);
}
}
};
CInterfaceGroup *list = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_CHARACTER));
if (!list)
return;
// unselect
if (Params.empty())
{
CUnpush unpusher;
unpusher.Ref = pCaller;
list->visit(&unpusher);
}
// now select
std::string name;
if (Params.empty())
{
CCtrlButton *pCB = dynamic_cast<CCtrlButton*>(pCaller);
if (!pCB)
return;
std::string id = pCB->getId();
id = id.substr(0, id.rfind(':'));
if (!fromString(id.substr(id.rfind(':')+1, id.size()), name))
return;
pCB->setPushed(true);
}
else
if (!fromString(Params, name))
return;
ImportCharacter = "";
// check filename and store
if (CFile::fileExists(toString("save/character_%s.save", name.c_str())))
ImportCharacter = name;
}
};
REGISTER_ACTION_HANDLER( CAHSelectImportCharacter, "import_char_select" );
// ***************************************************************************
class CAHImportCharacter : public IActionHandler
{
virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */)
{
if (ImportCharacter.empty())
return;
if (!CFile::fileExists(toString("save/character_%s.save", ImportCharacter.c_str())))
return;
bool success = false;
CIFile fd;
CCharacterSummary CS;
// use temporary file until close()
if (fd.open(toString("save/character_%s.save", ImportCharacter.c_str())))
{
try
{
CS.serial(fd);
SCharacter3DSetup::setupDBFromCharacterSummary("UI:TEMP:CHAR3D", CS);
// validate import
CDBManager::getInstance()->getDbProp("UI:TEMP:IMPORT")->setValue32(1);
success = true;
}
catch (const EStream &e)
{
nlwarning(e.what());
}
fd.close();
}
else
nlwarning("Failed to open file: save/character_%s.save", ImportCharacter.c_str());
// user notification
if (!success)
CLuaManager::getInstance().executeLuaScript("outgame:procCharselNotifaction(2)");
else
CAHManager::getInstance()->runActionHandler("proc", NULL, "proc_charsel_create_new");
}
};
REGISTER_ACTION_HANDLER( CAHImportCharacter, "import_char" );
// ***************************************************************************
class CAHExportCharacter : public IActionHandler
{
virtual void execute (CCtrlBase * /* pCaller */, const std::string &Params)
{
if (Params.empty())
return;
sint32 slot = -1;
if (!fromString(getParam(Params, "slot"), slot))
return;
if (slot >= CharacterSummaries.size() || slot < 0)
return;
// retrieve infos
CCharacterSummary &CS = CharacterSummaries[slot];
if (CS.Name.empty())
return;
// extract name
const std::string name = buildPlayerNameForSaveFile(CS.Name.toString());
COFile fd;
bool success = false;
// use temporary file until close()
if (fd.open(toString("save/character_%s.save", name.c_str()), false, false, true))
{
try
{
fd.serial(CS);
fd.flush();
// validate
success = true;
}
catch (const EStream &e)
{
nlwarning(e.what());
}
fd.close();
}
else
nlwarning("Failed to open file: save/character_%s.save", name.c_str());
const uint8 val = (success == true) ? 0 : 1;
// user notification
CLuaManager::getInstance().executeLuaScript(toString("outgame:procCharselNotifaction(%i)", val));
}
};
REGISTER_ACTION_HANDLER( CAHExportCharacter, "export_char" );

@ -52,6 +52,7 @@ bool hasPrivilegeEM();
bool hasPrivilegeEG(); bool hasPrivilegeEG();
bool hasPrivilegeVG(); bool hasPrivilegeVG();
bool hasPrivilegeOBSERVER(); bool hasPrivilegeOBSERVER();
bool hasPrivilegeTESTER();
// connection with the server. (login, shard list, etc.). // connection with the server. (login, shard list, etc.).

@ -172,16 +172,12 @@ void CEventsListener::operator()(const CEvent& event)
// Get in pixel space, centered // Get in pixel space, centered
uint32 drW, drH; uint32 drW, drH;
Driver->getWindowSize(drW, drH); Driver->getWindowSize(drW, drH);
float fX = mouseEvent->X; // from 0 to 1.0 sint scX = (sint32)(mouseEvent->X * (float)drW) - ((sint32)drW >> 1); // in pixels, centered
float fY = (ClientCfg.FreeLookInverted ? -mouseEvent->Y : mouseEvent->Y); sint scY = (sint32)(mouseEvent->Y * (float)drH) - ((sint32)drH >> 1);
sint scX = (sint32)(fX * (float)drW) - ((sint32)drW >> 1); // in pixels, centered
sint scY = (sint32)(fY * (float)drH) - ((sint32)drH >> 1);
if (!s_MouseFreeLookReady) if (!s_MouseFreeLookReady)
{ {
float pfX = _MouseX; sint pscX = (sint32)(_MouseX * (float)drW) - ((sint32)drW >> 1); // in pixels, centered
float pfY = (ClientCfg.FreeLookInverted ? -_MouseY : _MouseY); sint pscY = (sint32)(_MouseY * (float)drH) - ((sint32)drH >> 1);
sint pscX = (sint32)(pfX * (float)drW) - ((sint32)drW >> 1); // in pixels, centered
sint pscY = (sint32)(pfY * (float)drH) - ((sint32)drH >> 1);
s_MouseFreeLookReady = true; s_MouseFreeLookReady = true;
s_MouseFreeLookLastX = pscX; s_MouseFreeLookLastX = pscX;
s_MouseFreeLookLastY = pscY; s_MouseFreeLookLastY = pscY;
@ -199,13 +195,12 @@ void CEventsListener::operator()(const CEvent& event)
} }
// Get delta since last center // Get delta since last center
sint scXd = scX - s_MouseFreeLookLastX; s_MouseFreeLookFrameX += (scX - s_MouseFreeLookLastX);
sint scYd = scY - s_MouseFreeLookLastY; s_MouseFreeLookFrameY += (scY - s_MouseFreeLookLastY) * (ClientCfg.FreeLookInverted ? -1 : 1);
s_MouseFreeLookLastX = scX; s_MouseFreeLookLastX = scX;
s_MouseFreeLookLastY = scY; s_MouseFreeLookLastY = scY;
s_MouseFreeLookFrameX += scXd;
s_MouseFreeLookFrameY += scYd;
// updateFreeLookPos is called in updateMouseSmoothing per frame // updateFreeLookPos is called in updateMouseSmoothing per frame
// Center cursor // Center cursor

@ -49,12 +49,12 @@
#include "login_progress_post_thread.h" #include "login_progress_post_thread.h"
#include "interface_v3/action_handler_base.h" #include "interface_v3/action_handler_base.h"
#include "item_group_manager.h" #include "item_group_manager.h"
#include "nel/misc/cmd_args.h"
#ifdef DEBUG_NEW #ifdef DEBUG_NEW
#define new DEBUG_NEW #define new DEBUG_NEW
#endif #endif
using namespace NLMISC; using namespace NLMISC;
using namespace NLNET; using namespace NLNET;
using namespace NL3D; using namespace NL3D;
@ -210,6 +210,7 @@ extern bool IsInRingSession;
extern void selectTipsOfTheDay (uint tips); extern void selectTipsOfTheDay (uint tips);
#define BAR_STEP_TP 2 #define BAR_STEP_TP 2
extern NLMISC::CCmdArgs Args;
CLoginStateMachine::TEvent CLoginStateMachine::waitEvent() CLoginStateMachine::TEvent CLoginStateMachine::waitEvent()
{ {
@ -462,12 +463,14 @@ void CLoginStateMachine::run()
case st_check_patch: case st_check_patch:
/// check the data to check if patch needed /// check the data to check if patch needed
CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_PostLogin, "login_step_post_login")); CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_PostLogin, "login_step_post_login"));
if (!ClientCfg.PatchWanted)
if (!ClientCfg.PatchWanted || (Args.haveArg("n") && Args.getLongArg("nopatch").front() == "1"))
{ {
// client don't want to be patched ! // client don't want to be patched !
_CurrentState = st_display_eula; _CurrentState = st_display_eula;
break; break;
} }
initPatchCheck(); initPatchCheck();
SM_BEGIN_EVENT_TABLE SM_BEGIN_EVENT_TABLE
if (isBGDownloadEnabled()) if (isBGDownloadEnabled())
@ -1517,4 +1520,3 @@ void CFarTP::farTPmainLoop()
if(welcomeWindow) if(welcomeWindow)
initWelcomeWindow(); initWelcomeWindow();
} }

@ -267,7 +267,7 @@ void CGameContextMenu::update()
setupContextMenuCantTalk(); // can't talk by default setupContextMenuCantTalk(); // can't talk by default
bool showGMOptions = (hasPrivilegeDEV() || hasPrivilegeSGM() || hasPrivilegeGM() || hasPrivilegeVG() || hasPrivilegeSG() || hasPrivilegeEM() || hasPrivilegeEG() || hasPrivilegeOBSERVER()); bool showGMOptions = (hasPrivilegeDEV() || hasPrivilegeSGM() || hasPrivilegeGM() || hasPrivilegeVG() || hasPrivilegeSG() || hasPrivilegeEM() || hasPrivilegeEG() || hasPrivilegeOBSERVER() || hasPrivilegeTESTER());
if (_TextInvisible) if (_TextInvisible)
_TextInvisible->setActive(showGMOptions); _TextInvisible->setActive(showGMOptions);
@ -451,18 +451,19 @@ void CGameContextMenu::update()
else if (continent == "lepaysmalade.continent") else if (continent == "lepaysmalade.continent")
fameIndex = CStaticFames::getInstance().getFactionIndex("zorai"); fameIndex = CStaticFames::getInstance().getFactionIndex("zorai");
if (fameIndex != CStaticFames::INVALID_FACTION_INDEX) if (fameIndex != CStaticFames::INVALID_FACTION_INDEX)
{ {
CCDBNodeLeaf *pLeafFame = NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:FAME:PLAYER%d:VALUE", fameIndex), false); CCDBNodeLeaf *pLeafFame = NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:FAME:PLAYER%d:VALUE", fameIndex), false);
if (pLeafFame != NULL) if (pLeafFame != NULL)
fameValue = pLeafFame->getValue8(); fameValue = pLeafFame->getValue8();
} }
if (_TextNews) if (_TextNews)
_TextNews->setActive(selection && !canAttack() && selection->isNPC() && fameValue >= -30); _TextNews->setActive(!UserEntity->isFighting() && !UserEntity->isRiding() && selection && !canAttack() && selection->isNPC() && fameValue >= -30);
if (_TextNewsAgressive) if (_TextNewsAgressive)
_TextNewsAgressive->setActive(selection && !canAttack() && selection->isNPC() && fameValue < -30); _TextNewsAgressive->setActive(!UserEntity->isFighting() && !UserEntity->isRiding() && selection && !canAttack() && selection->isNPC() && fameValue < -30);
if (_TextDuel && _TextUnDuel) if (_TextDuel && _TextUnDuel)

@ -112,6 +112,23 @@ class CAHToggleARKPACSBorders : public IActionHandler
}; };
REGISTER_ACTION_HANDLER (CAHToggleARKPACSBorders, "ark_pacs_borders"); REGISTER_ACTION_HANDLER (CAHToggleARKPACSBorders, "ark_pacs_borders");
// ***************************************************************************
class CAHToggleFly : public IActionHandler
{
virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */)
{
// Change to AI Mode.
if(UserControls.mode() != CUserControls::AIMode)
UserControls.mode(CUserControls::AIMode);
// Leave the AI Mode.
else
UserEntity->viewMode(UserEntity->viewMode());
}
};
// ***************************************************************************
REGISTER_ACTION_HANDLER (CAHToggleFly, "toggle_fly");
#if !FINAL_VERSION #if !FINAL_VERSION
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
class CAHProfile : public IActionHandler class CAHProfile : public IActionHandler
@ -270,22 +287,6 @@ class CAHSwitchConsoleDisplay : public IActionHandler
// *************************************************************************** // ***************************************************************************
REGISTER_ACTION_HANDLER (CAHSwitchConsoleDisplay, "switch_console_display"); REGISTER_ACTION_HANDLER (CAHSwitchConsoleDisplay, "switch_console_display");
// ***************************************************************************
class CAHToggleFly : public IActionHandler
{
virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */)
{
// Change to AI Mode.
if(UserControls.mode() != CUserControls::AIMode)
UserControls.mode(CUserControls::AIMode);
// Leave the AI Mode.
else
UserEntity->viewMode(UserEntity->viewMode());
}
};
// ***************************************************************************
REGISTER_ACTION_HANDLER (CAHToggleFly, "toggle_fly");
// *************************************************************************** // ***************************************************************************
class CAHReloadLandscapeIg : public IActionHandler class CAHReloadLandscapeIg : public IActionHandler
{ {

@ -4655,6 +4655,45 @@ public:
}; };
REGISTER_ACTION_HANDLER( CHandlerSortTribeFame, "sort_tribefame"); REGISTER_ACTION_HANDLER( CHandlerSortTribeFame, "sort_tribefame");
// ***************************************************************************
class CHandlerOutgameNaviGetKeys : public IActionHandler
{
virtual void execute (CCtrlBase *pCaller, const std::string &Params)
{
if (!pCaller->getParent())
return;
if (pCaller->getParent()->getId() != "ui:outgame")
return;
if (Params.empty())
{
sint32 event = -1;
if (Driver->AsyncListener.isKeyPushed(KeyESCAPE)) event = 0;
if (Driver->AsyncListener.isKeyPushed(KeyDELETE)) event = 1;
if (Driver->AsyncListener.isKeyPushed(KeyRETURN)) event = 2;
if (Driver->AsyncListener.isKeyPushed(KeyDOWN)) event = 3;
if (Driver->AsyncListener.isKeyPushed(KeyUP)) event = 4;
if (Driver->AsyncListener.isKeyPushed(KeyI)) event = 5;
if (Driver->AsyncListener.isKeyPushed(KeyP)) event = 6;
if (Driver->AsyncListener.isKeyPushed(KeyE)) event = 7;
if (Driver->AsyncListener.isKeyPushed(KeyLEFT)) event = 8;
if (Driver->AsyncListener.isKeyPushed(KeyRIGHT)) event = 9;
std::string id = "create";
if (pCaller->getId() == "ui:outgame:charsel")
id = "sel";
if (event != -1)
CLuaManager::getInstance().executeLuaScript(toString("outgame:eventChar%sKeyGet(%i)", id.c_str(), event));
}
// reset previous input
Driver->AsyncListener.reset();
}
};
REGISTER_ACTION_HANDLER( CHandlerOutgameNaviGetKeys, "navigate_outgame" );
// *************************************************************************** // ***************************************************************************
class CHandlerTriggerIconBuffs : public IActionHandler class CHandlerTriggerIconBuffs : public IActionHandler
{ {

@ -136,7 +136,7 @@ public:
if (pCSDst->isShortCut()) if (pCSDst->isShortCut())
pPM->CompositionPhraseMemoryLineDest= pPM->getSelectedMemoryLineDB(); pPM->CompositionPhraseMemoryLineDest= pPM->getSelectedMemoryLineDB();
else else
pPM->CompositionPhraseMemoryLineDest= 0; pPM->CompositionPhraseMemoryLineDest= pPM->getSelectedMemoryAltLineDB();
pPM->CompositionPhraseMemorySlotDest= pCSDst->getIndexInDB(); pPM->CompositionPhraseMemorySlotDest= pCSDst->getIndexInDB();
} }
@ -536,7 +536,7 @@ public:
CInterfaceManager *pIM= CInterfaceManager::getInstance(); CInterfaceManager *pIM= CInterfaceManager::getInstance();
// Launch the modal to select the faber plan // Launch the modal to select the faber plan
extern void fillFaberPlanSelection(const std::string &brickDB, uint maxSelection, TOOL_TYPE::TCraftingToolType toolType); extern void fillFaberPlanSelection(const std::string &brickDB, uint maxSelection, TOOL_TYPE::TCraftingToolType toolType);
// from sphrase_manager.cpp // from sphrase_manager.cpp
extern TOOL_TYPE::TCraftingToolType getRightHandCraftToolType(); extern TOOL_TYPE::TCraftingToolType getRightHandCraftToolType();
fillFaberPlanSelection(CDBGroupBuildPhrase::BrickSelectionDB, CDBGroupBuildPhrase::MaxSelection, getRightHandCraftToolType()); fillFaberPlanSelection(CDBGroupBuildPhrase::BrickSelectionDB, CDBGroupBuildPhrase::MaxSelection, getRightHandCraftToolType());
@ -750,8 +750,8 @@ class CHandlerMemorizePhraseOrMacro : public IActionHandler
{ {
public: public:
virtual void execute (CCtrlBase *pCaller, const string &Params); virtual void execute (CCtrlBase *pCaller, const string &Params);
void memorizePhraseOrMacro(uint dstMemoryIndex, bool isMacro, sint32 phraseId, sint32 macroId); void memorizePhraseOrMacro(sint32 memoryLine, uint dstMemoryIndex, bool isMacro, sint32 phraseId, sint32 macroId);
void memorizePhraseSheet(uint dstMemoryIndex, uint32 sheetId); void memorizePhraseSheet(sint32 memoryLine, uint dstMemoryIndex, uint32 sheetId);
}; };
REGISTER_ACTION_HANDLER( CHandlerMemorizePhraseOrMacro, "memorize_phrase_or_macro"); REGISTER_ACTION_HANDLER( CHandlerMemorizePhraseOrMacro, "memorize_phrase_or_macro");
@ -771,7 +771,11 @@ void CHandlerMemorizePhraseOrMacro::execute (CCtrlBase *pCaller, const string &P
// The dest must be a memory or a macro memory // The dest must be a memory or a macro memory
if (!pCSDst->isSPhraseIdMemory() && !pCSDst->isMacroMemory()) return; if (!pCSDst->isSPhraseIdMemory() && !pCSDst->isMacroMemory()) return;
// get the memory line and memory index // get the memory line and memory index
sint32 dstMemoryLine= pPM->getSelectedMemoryLineDB(); sint32 dstMemoryLine;
if (pCSDst->isShortCut())
dstMemoryLine = pPM->getSelectedMemoryLineDB();
else
dstMemoryLine = pPM->getSelectedMemoryAltLineDB();
uint dstMemoryIndex= pCSDst->getIndexInDB(); uint dstMemoryIndex= pCSDst->getIndexInDB();
bool srcIsMacro; bool srcIsMacro;
@ -806,7 +810,7 @@ void CHandlerMemorizePhraseOrMacro::execute (CCtrlBase *pCaller, const string &P
pPM->sendLearnToServer(newPhraseId); pPM->sendLearnToServer(newPhraseId);
// memorize the new phrase // memorize the new phrase
memorizePhraseOrMacro(dstMemoryIndex, srcIsMacro, newPhraseId, srcMacroId); memorizePhraseOrMacro(dstMemoryLine, dstMemoryIndex, srcIsMacro, newPhraseId, srcMacroId);
} }
} }
else else
@ -833,7 +837,7 @@ void CHandlerMemorizePhraseOrMacro::execute (CCtrlBase *pCaller, const string &P
if(pCSSrc->isSPhrase()) if(pCSSrc->isSPhrase())
{ {
// learn and memorize this phrase // learn and memorize this phrase
memorizePhraseSheet(dstMemoryIndex, pCSSrc->getSheetId()); memorizePhraseSheet(dstMemoryLine, dstMemoryIndex, pCSSrc->getSheetId());
} }
else else
{ {
@ -842,7 +846,7 @@ void CHandlerMemorizePhraseOrMacro::execute (CCtrlBase *pCaller, const string &P
pPM->fullDeletePhraseIfLast(dstMemoryLine, dstMemoryIndex); pPM->fullDeletePhraseIfLast(dstMemoryLine, dstMemoryIndex);
// memorize the phrase or macro // memorize the phrase or macro
memorizePhraseOrMacro(dstMemoryIndex, srcIsMacro, srcPhraseId, srcMacroId); memorizePhraseOrMacro(dstMemoryLine, dstMemoryIndex, srcIsMacro, srcPhraseId, srcMacroId);
} }
} }
// Else the src is a memory too // Else the src is a memory too
@ -868,7 +872,7 @@ void CHandlerMemorizePhraseOrMacro::execute (CCtrlBase *pCaller, const string &P
pPM->sendLearnToServer(newPhraseId); pPM->sendLearnToServer(newPhraseId);
// memorize the new phrase // memorize the new phrase
memorizePhraseOrMacro(dstMemoryIndex, srcIsMacro, newPhraseId, srcMacroId); memorizePhraseOrMacro(dstMemoryLine, dstMemoryIndex, srcIsMacro, newPhraseId, srcMacroId);
} }
else else
{ {
@ -876,7 +880,7 @@ void CHandlerMemorizePhraseOrMacro::execute (CCtrlBase *pCaller, const string &P
pPM->fullDeletePhraseIfLast(dstMemoryLine, dstMemoryIndex); pPM->fullDeletePhraseIfLast(dstMemoryLine, dstMemoryIndex);
// memorize the macro (still a reference) // memorize the macro (still a reference)
memorizePhraseOrMacro(dstMemoryIndex, srcIsMacro, srcPhraseId, srcMacroId); memorizePhraseOrMacro(dstMemoryLine, dstMemoryIndex, srcIsMacro, srcPhraseId, srcMacroId);
} }
} }
// else this is a swap! // else this is a swap!
@ -887,17 +891,23 @@ void CHandlerMemorizePhraseOrMacro::execute (CCtrlBase *pCaller, const string &P
{ {
// get the memory index for src // get the memory index for src
uint srcMemoryIndex= pCSSrc->getIndexInDB(); uint srcMemoryIndex= pCSSrc->getIndexInDB();
// get the memory line for src
sint32 srcMemoryLine;
if (pCSSrc->isShortCut())
srcMemoryLine = pPM->getSelectedMemoryLineDB();
else
srcMemoryLine = pPM->getSelectedMemoryAltLineDB();
// memorize dst into src // memorize dst into src
memorizePhraseOrMacro(srcMemoryIndex, dstIsMacro, dstPhraseId, dstMacroId); memorizePhraseOrMacro(srcMemoryLine, srcMemoryIndex, dstIsMacro, dstPhraseId, dstMacroId);
// memorize src into dst // memorize src into dst
memorizePhraseOrMacro(dstMemoryIndex, srcIsMacro, srcPhraseId, srcMacroId); memorizePhraseOrMacro(dstMemoryLine, dstMemoryIndex, srcIsMacro, srcPhraseId, srcMacroId);
} }
// else, it's a move // else, it's a move
else else
{ {
// copy // copy
memorizePhraseOrMacro(dstMemoryIndex, srcIsMacro, srcPhraseId, srcMacroId); memorizePhraseOrMacro(dstMemoryLine, dstMemoryIndex, srcIsMacro, srcPhraseId, srcMacroId);
// forget src (after shorctut change!) // forget src (after shorctut change!)
CAHManager::getInstance()->runActionHandler("forget_phrase_or_macro", pCSSrc); CAHManager::getInstance()->runActionHandler("forget_phrase_or_macro", pCSSrc);
@ -909,14 +919,13 @@ void CHandlerMemorizePhraseOrMacro::execute (CCtrlBase *pCaller, const string &P
// memorize a spell // memorize a spell
void CHandlerMemorizePhraseOrMacro::memorizePhraseOrMacro(uint memoryIndex, bool isMacro, sint32 phraseId, sint32 macroId) void CHandlerMemorizePhraseOrMacro::memorizePhraseOrMacro(sint32 memoryLine, uint memoryIndex, bool isMacro, sint32 phraseId, sint32 macroId)
{ {
CSPhraseManager *pPM= CSPhraseManager::getInstance(); CSPhraseManager *pPM= CSPhraseManager::getInstance();
sint32 memoryLine= pPM->getSelectedMemoryLineDB(); if (memoryLine<0)
if(memoryLine<0) return;
return;
if(isMacro) if(isMacro)
{ {
pPM->memorizeMacro(memoryLine, memoryIndex, macroId); pPM->memorizeMacro(memoryLine, memoryIndex, macroId);
@ -931,11 +940,10 @@ void CHandlerMemorizePhraseOrMacro::memorizePhraseOrMacro(uint memoryIndex, bool
} }
// memorize a default spell // memorize a default spell
void CHandlerMemorizePhraseOrMacro::memorizePhraseSheet(uint memoryIndex, uint32 sheetId) void CHandlerMemorizePhraseOrMacro::memorizePhraseSheet(sint32 memoryLine, uint memoryIndex, uint32 sheetId)
{ {
CSPhraseManager *pPM= CSPhraseManager::getInstance(); CSPhraseManager *pPM= CSPhraseManager::getInstance();
sint32 memoryLine= pPM->getSelectedMemoryLineDB();
if(memoryLine<0) if(memoryLine<0)
return; return;
@ -989,7 +997,11 @@ public:
return; return;
// Ok, the user try to forget a phrase slot. // Ok, the user try to forget a phrase slot.
sint32 memoryLine= pPM->getSelectedMemoryLineDB(); sint32 memoryLine;
if (pCSDst->isShortCut())
memoryLine = pPM->getSelectedMemoryLineDB();
else
memoryLine = pPM->getSelectedMemoryAltLineDB();
if(memoryLine<0) if(memoryLine<0)
return; return;
@ -1026,6 +1038,9 @@ public:
if (!pCSDst->isSPhraseIdMemory() && !pCSDst->isMacroMemory()) if (!pCSDst->isSPhraseIdMemory() && !pCSDst->isMacroMemory())
return; return;
// is alternative action bar
bool isMain = pCSDst->isShortCut();
// get the memory index // get the memory index
uint memoryIndex = pCSDst->getIndexInDB(); uint memoryIndex = pCSDst->getIndexInDB();
@ -1034,7 +1049,9 @@ public:
// build params string // build params string
string sParams; string sParams;
sParams.append("memoryIndex="); sParams.append("isMain=");
sParams.append(toString(isMain));
sParams.append("|memoryIndex=");
sParams.append(toString(memoryIndex)); sParams.append(toString(memoryIndex));
sParams.append("|isMacro="); sParams.append("|isMacro=");
sParams.append(toString(isMacro)); sParams.append(toString(isMacro));
@ -1066,11 +1083,10 @@ public:
// Ok, the user try to forget a phrase slot // Ok, the user try to forget a phrase slot
CSPhraseManager *pPM = CSPhraseManager::getInstance(); CSPhraseManager *pPM = CSPhraseManager::getInstance();
sint32 memoryLine = pPM->getSelectedMemoryLineDB();
if (memoryLine<0)
return;
// get params // get params
bool isMain;
fromString(getParam(Params, "isMain"), isMain);
uint memoryIndex; uint memoryIndex;
fromString(getParam(Params, "memoryIndex"), memoryIndex); fromString(getParam(Params, "memoryIndex"), memoryIndex);
bool isMacro; bool isMacro;
@ -1078,6 +1094,14 @@ public:
sint32 phraseId; sint32 phraseId;
fromString(getParam(Params, "phraseId"),phraseId); fromString(getParam(Params, "phraseId"),phraseId);
sint32 memoryLine;
if (isMain)
memoryLine = pPM->getSelectedMemoryLineDB();
else
memoryLine = pPM->getSelectedMemoryAltLineDB();
if (memoryLine<0)
return;
if (isMacro) if (isMacro)
{ {
pPM->forgetMacro(memoryLine, memoryIndex); pPM->forgetMacro(memoryLine, memoryIndex);
@ -1513,7 +1537,7 @@ public:
if (pCSDst->isShortCut()) if (pCSDst->isShortCut())
memoryLine = pPM->getSelectedMemoryLineDB(); memoryLine = pPM->getSelectedMemoryLineDB();
else else
memoryLine = 0; memoryLine = pPM->getSelectedMemoryAltLineDB();
if(memoryLine<0) if(memoryLine<0)
return; return;

@ -86,6 +86,12 @@ void CBotChatManager::setCurrPage(CBotChatPage *page)
UserEntity->trader(CLFECOMMON::INVALID_SLOT); UserEntity->trader(CLFECOMMON::INVALID_SLOT);
} }
_CurrPage = page; _CurrPage = page;
if (page == NULL && !_AHAfterEnd.empty())
{
CAHManager::getInstance()->runActionHandler(_AHAfterEnd, NULL, "");
_AHAfterEnd = "";
}
} }
// ******************************************************************************************** // ********************************************************************************************

@ -93,12 +93,15 @@ public:
// Called for local client debugging // Called for local client debugging
void debugLocalReceiveMissionInfo(); void debugLocalReceiveMissionInfo();
void setAHAfterEnd(const std::string &ah) { _AHAfterEnd = ah ;}
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
private: private:
CBotChatPage *_CurrPage; CBotChatPage *_CurrPage;
uint16 _SessionID; uint16 _SessionID;
std::string _AHAfterEnd;
static CBotChatManager *_Instance; static CBotChatManager *_Instance;
//uint _ChosenMissionFlags; //uint _ChosenMissionFlags;

@ -161,6 +161,7 @@ void CBotChatPageMission::acceptMission()
/// close the botchat /// close the botchat
//CBotChatManager::getInstance()->setCurrPage(NULL); //CBotChatManager::getInstance()->setCurrPage(NULL);
_CurrSel = NULL; _CurrSel = NULL;
CBotChatManager::getInstance()->setAHAfterEnd("context_choose_mission");
} }

@ -51,6 +51,7 @@ private:
// an observer to update big mission list from littles pages in server database // an observer to update big mission list from littles pages in server database
CHugeListObs _MissionPagesObs; CHugeListObs _MissionPagesObs;
CDBCtrlSheet *_CurrSel; CDBCtrlSheet *_CurrSel;
bool _HaveAcceptedMission;
MISSION_DESC::TClientMissionType _MType; MISSION_DESC::TClientMissionType _MType;
}; };

@ -588,7 +588,8 @@ void CBotChatPageTrade::updateTradeModal()
if ((_BuyMean == MoneyGuildXP) || (_BuyMean == GuildMoney) || (_BuyMean == GuildMoneyGuildXP)) if ((_BuyMean == MoneyGuildXP) || (_BuyMean == GuildMoney) || (_BuyMean == GuildMoneyGuildXP))
{ {
uint64 totalPrice = (uint64) priceWithoutFame * (uint64) quantity; uint64 totalPrice = (uint64) priceWithoutFame * (uint64) quantity;
NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:TRADE_ITEM:PRICE")->setValue64(totalPrice); NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:TRADE_ITEM:UNIT_PRICE")->setValue64(totalPrice);
NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:TRADE_ITEM:UNIT_PRICE_WITH_FAME")->setValue64(totalPrice);
uint64 totalXP = (uint64) getCurrItemXP() * (uint64) quantity; uint64 totalXP = (uint64) getCurrItemXP() * (uint64) quantity;
CGuildManager *pGM = CGuildManager::getInstance(); CGuildManager *pGM = CGuildManager::getInstance();

@ -422,6 +422,53 @@ CViewBase *CChatTextManager::createMsgTextComplex(const ucstring &msg, NLMISC::C
return para; return para;
} }
ucstring::size_type pos = 0;
string::size_type startTr = msg.find(ucstring("{:"));
string::size_type endOfOriginal = msg.find(ucstring("}@{"));
// Original/Translated case, example: {:enHello the world!}@{ Bonjour le monde !
if (startTr != string::npos && endOfOriginal != string::npos)
{
string lang = toUpper(msg.substr(startTr+2, 2)).toString();
bool inverse = false;
bool hideFlag = false;
CCDBNodeLeaf *nodeInverse = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:TRANSLATION:" + lang + ":INVERSE_DISPLAY", false);
if (nodeInverse)
inverse = nodeInverse->getValueBool();
CCDBNodeLeaf *nodeHideFlag = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:TRANSLATION:" + lang + ":HIDE_FLAG", false);
if (nodeHideFlag)
hideFlag = nodeHideFlag->getValueBool();
CViewBase *vt = createMsgTextSimple(msg.substr(0, startTr), col, justified, NULL);
para->addChild(vt);
string texture = "flag-"+toLower(msg.substr(startTr+2, 2)).toString()+".tga";
ucstring original = msg.substr(startTr+5, endOfOriginal-startTr-5);
ucstring translation = msg.substr(endOfOriginal+4);
CCtrlButton *ctrlButton = new CCtrlButton(CViewBase::TCtorParam());
ctrlButton->setTexture(texture);
ctrlButton->setTextureOver(texture);
ctrlButton->setTexturePushed(texture);
if (!inverse)
{
ctrlButton->setDefaultContextHelp(original);
pos = endOfOriginal+4;
}
else
{
ctrlButton->setDefaultContextHelp(translation);
pos = startTr+5;
textSize = endOfOriginal;
}
ctrlButton->setId("tr");
if (hideFlag) {
delete ctrlButton;
} else {
para->addChild(ctrlButton);
}
}
// quickly check if text has links or not // quickly check if text has links or not
bool hasUrl; bool hasUrl;
@ -430,8 +477,7 @@ CViewBase *CChatTextManager::createMsgTextComplex(const ucstring &msg, NLMISC::C
hasUrl = (s.find(ucstring("http://")) || s.find(ucstring("https://"))); hasUrl = (s.find(ucstring("http://")) || s.find(ucstring("https://")));
} }
ucstring::size_type pos = 0; for (ucstring::size_type i = pos; i< textSize;)
for (ucstring::size_type i = 0; i< textSize;)
{ {
if (hasUrl && isUrlTag(msg, i, textSize)) if (hasUrl && isUrlTag(msg, i, textSize))
{ {

@ -215,29 +215,52 @@ void CChatWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CChatGr
CChatTextManager &ctm = getChatTextMngr(); CChatTextManager &ctm = getChatTextMngr();
gl = dynamic_cast<CGroupList *>(_Chat->getGroup("cb:text_list")); gl = dynamic_cast<CGroupList *>(_Chat->getGroup("cb:text_list"));
if (gl) gl->addChild(ctm.createMsgText(msg, col));
// if the group is closed, make it blink
if (!_Chat->isOpen())
{ bool noTranslation = false;
if (numBlinks) _Chat->enableBlink(numBlinks); CCDBNodeLeaf *nodeNoTranslation = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:TRANSLATION:" + toUpper(CChatGroup::groupTypeToString(gt)) + ":DISABLE", false);
if (nodeNoTranslation)
noTranslation = nodeNoTranslation->getValueBool();
ucstring msgNoTranslate = msg;
if (noTranslation) {
string::size_type startTr = msg.find(ucstring("{:"));
string::size_type endOfOriginal = msg.find(ucstring("}@{"));
if (startTr != string::npos && endOfOriginal != string::npos) {
msgNoTranslate = msg.substr(0, startTr) + msg.substr(startTr+5, endOfOriginal-startTr-5);
}
} }
if (_ParentBlink)
CViewBase *child = ctm.createMsgText(msgNoTranslate, col);
if (child)
{ {
CGroupContainer *father = dynamic_cast<CGroupContainer *>(_Chat->getParent()); if (gl) gl->addChild(child);
if (father && !father->isOpen())
// if the group is closed, make it blink
if (!_Chat->isOpen())
{ {
father->enableBlink(numBlinks); if (numBlinks) _Chat->enableBlink(numBlinks);
} }
if (_ParentBlink)
{
CGroupContainer *father = dynamic_cast<CGroupContainer *>(_Chat->getParent());
if (father && !father->isOpen())
{
father->enableBlink(numBlinks);
}
}
if (windowVisible != NULL)
{
*windowVisible = isVisible();
}
/*for(std::vector<IObserver *>::iterator it = _Observers.begin(); it != _Observers.end(); ++it)
{
(*it)->displayMessage(this, msg, col, numBlinks);
}*/
} }
if (windowVisible != NULL)
{
*windowVisible = isVisible();
}
/*for(std::vector<IObserver *>::iterator it = _Observers.begin(); it != _Observers.end(); ++it)
{
(*it)->displayMessage(this, msg, col, numBlinks);
}*/
} }
//================================================================================= //=================================================================================
@ -563,12 +586,31 @@ void CChatGroupWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CC
ucstring newmsg = msg; ucstring newmsg = msg;
ucstring prefix; ucstring prefix;
bool noTranslation = false;
CCDBNodeLeaf *nodeNoTranslation = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:TRANSLATION:" + toUpper(CChatGroup::groupTypeToString(gt)) + ":DISABLE", false);
if (nodeNoTranslation)
noTranslation = nodeNoTranslation->getValueBool();
if (noTranslation) {
string::size_type startTr = msg.find(ucstring("{:"));
string::size_type endOfOriginal = msg.find(ucstring("}@{"));
if (startTr != string::npos && endOfOriginal != string::npos) {
newmsg = newmsg.substr(0, startTr) + newmsg.substr(startTr+5, endOfOriginal-startTr-5);
}
}
CViewBase *child = NULL;
if (gl != NULL) if (gl != NULL)
{ {
gl->addChild(ctm.createMsgText(newmsg, col)); child = ctm.createMsgText(newmsg, col);
if (!gl->getParent()->getActive()) if (child)
if (tab != NULL) {
tab->setTextColorNormal(newMsgColor); gl->addChild(child);
if (!gl->getParent()->getActive())
if (tab != NULL)
tab->setTextColorNormal(newMsgColor);
}
} }
// *** Display the message in the UserChat (special case) // *** Display the message in the UserChat (special case)
@ -590,7 +632,7 @@ void CChatGroupWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CC
case CChatGroup::guild: if (ci.Guild.isListeningWindow(cw)) gl = gl2; break; case CChatGroup::guild: if (ci.Guild.isListeningWindow(cw)) gl = gl2; break;
case CChatGroup::system: if (ci.SystemInfo.isListeningWindow(cw)) gl = gl2; break; case CChatGroup::system: if (ci.SystemInfo.isListeningWindow(cw)) gl = gl2; break;
case CChatGroup::universe: if (ci.Universe.isListeningWindow(cw)) gl = gl2; break; case CChatGroup::universe: if (ci.Universe.isListeningWindow(cw)) gl = gl2; break;
case CChatGroup::dyn_chat: case CChatGroup::dyn_chat:
if (ci.DynamicChat[dynamicChatDbIndex].isListeningWindow(cw)) if (ci.DynamicChat[dynamicChatDbIndex].isListeningWindow(cw))
{ {
gl = gl2; gl = gl2;
@ -608,7 +650,7 @@ void CChatGroupWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CC
pos = newmsg.find(ucstring("}")); pos = newmsg.find(ucstring("}"));
prefix += " "; prefix += " ";
} }
if (pos == ucstring::npos) if (pos == ucstring::npos)
newmsg = prefix + newmsg; newmsg = prefix + newmsg;
else else
@ -635,31 +677,37 @@ void CChatGroupWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CC
if (gl != NULL) if (gl != NULL)
{ {
gl->addChild(ctm.createMsgText(newmsg, col)); child = ctm.createMsgText(newmsg, col);
if (!gl->getParent()->getActive()) if (child)
if (tab != NULL) {
tab->setTextColorNormal(newMsgColor); gl->addChild(child);
if (!gl->getParent()->getActive())
if (tab != NULL)
tab->setTextColorNormal(newMsgColor);
}
} }
} }
if (child)
// *** Blink and visibility event
// if the group is closed, make it blink
if (!_Chat->isOpen())
{ {
if (numBlinks) _Chat->enableBlink(numBlinks); // *** Blink and visibility event
} // if the group is closed, make it blink
if (_ParentBlink) if (!_Chat->isOpen())
{
CGroupContainer *father = dynamic_cast<CGroupContainer *>(_Chat->getParent());
if (father && !father->isOpen())
{ {
father->enableBlink(numBlinks); if (numBlinks) _Chat->enableBlink(numBlinks);
}
if (_ParentBlink)
{
CGroupContainer *father = dynamic_cast<CGroupContainer *>(_Chat->getParent());
if (father && !father->isOpen())
{
father->enableBlink(numBlinks);
}
}
if (windowVisible != NULL)
{
*windowVisible = isVisible();
} }
}
if (windowVisible != NULL)
{
*windowVisible = isVisible();
} }
} }
@ -685,8 +733,9 @@ void CChatGroupWindow::displayTellMessage(const ucstring &msg, NLMISC::CRGBA col
nlwarning("<CChatGroupWindow::displayTellMessage> can't get text_list."); nlwarning("<CChatGroupWindow::displayTellMessage> can't get text_list.");
return; return;
} }
CViewBase *child = getChatTextMngr().createMsgText(msg, col);
gl->addChild(getChatTextMngr().createMsgText(msg, col)); if (child)
gl->addChild(child);
} }
//================================================================================= //=================================================================================

@ -56,6 +56,7 @@
#include "../r2/editor.h" #include "../r2/editor.h"
#include "nel/gui/lua_manager.h" #include "nel/gui/lua_manager.h"
#include "nel/misc/xml_macros.h"
extern CSheetManager SheetMngr; extern CSheetManager SheetMngr;
@ -543,6 +544,15 @@ CCtrlDraggable(param)
_RegenText = NULL; _RegenText = NULL;
_RegenTextValue = 0; _RegenTextValue = 0;
_RegenTextEnabled = true;
_RegenTextShadow = true;
_RegenTextOutline = false;
_RegenTextFctLua = false;
_RegenTextY = 2;
_RegenTextFontSize = 8;
_RegenTextColor = NLMISC::CRGBA::White;
_RegenTextShadowColor = NLMISC::CRGBA::Black;
_RegenTextOutlineColor = NLMISC::CRGBA::Black;
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -567,6 +577,11 @@ CDBCtrlSheet::~CDBCtrlSheet()
Driver->deleteTextureFile(_GuildSymb); Driver->deleteTextureFile(_GuildSymb);
_GuildSymb = NULL; _GuildSymb = NULL;
} }
if (_RegenText)
{
delete _RegenText;
_RegenText = NULL;
}
// ensure erase static // ensure erase static
if(this==_CurrMenuSheet) _CurrMenuSheet = NULL; if(this==_CurrMenuSheet) _CurrMenuSheet = NULL;
@ -650,6 +665,17 @@ bool CDBCtrlSheet::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup)
prop = (char*) xmlGetProp( cur, (xmlChar*)"focus_buff_icon" ); prop = (char*) xmlGetProp( cur, (xmlChar*)"focus_buff_icon" );
if (prop) _FocusBuffIcon = string((const char *)prop); if (prop) _FocusBuffIcon = string((const char *)prop);
XML_READ_BOOL(cur, "regen_text", _RegenTextEnabled, true);
XML_READ_BOOL(cur, "regen_text_shadow", _RegenTextShadow, true);
XML_READ_BOOL(cur, "regen_text_outline", _RegenTextOutline, false);
XML_READ_SINT(cur, "regen_text_y", _RegenTextY, 2);
XML_READ_UINT(cur, "regen_text_fontsize", _RegenTextFontSize, 8);
XML_READ_COLOR(cur, "regen_text_color", _RegenTextColor, NLMISC::CRGBA::White);
XML_READ_COLOR(cur, "regen_text_shadow_color", _RegenTextShadowColor, NLMISC::CRGBA::Black);
XML_READ_COLOR(cur, "regen_text_outline_color", _RegenTextOutlineColor, NLMISC::CRGBA::Black);
XML_READ_STRING(cur, "regen_text_fct", _RegenTextFct, "");
_RegenTextFctLua = startsWith(_RegenTextFct, "lua:");
updateActualType(); updateActualType();
// Init size for Type // Init size for Type
initSheetSize(); initSheetSize();
@ -1081,6 +1107,7 @@ void CDBCtrlSheet::clearIconBuffs()
{ {
_EnchantIcons.clear(); _EnchantIcons.clear();
_BuffIcons.clear(); _BuffIcons.clear();
_BoostIcons.clear();
} }
// *************************************************************************** // ***************************************************************************
@ -1112,12 +1139,27 @@ void CDBCtrlSheet::infoReceived()
const CSBrickSheet *brick = pBM->getBrick(itemInfo->Enchantment.Bricks[i]); const CSBrickSheet *brick = pBM->getBrick(itemInfo->Enchantment.Bricks[i]);
if (brick) if (brick)
{ {
if (!brick->isRoot() && !brick->isCredit() && !brick->isParameter()) if (brick->BrickFamily == BRICK_FAMILIES::BSGMCB) // Boost of Allegories, use it as boost icon
{
_BoostIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(brick->getIcon()), brick->IconColor));
rVR.getTextureSizeFromId(_BoostIcons.back().TextureId, _BoostIcons.back().IconW, _BoostIcons.back().IconH);
}
else if (!brick->isRoot() && !brick->isCredit() && !brick->isParameter())
{ {
if (!haveRoot) if (!haveRoot)
{ {
_EnchantIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(brick->getIconBack()), brick->IconBackColor)); haveRoot = true;
rVR.getTextureSizeFromId(_EnchantIcons.back().TextureId, _EnchantIcons.back().IconW, _EnchantIcons.back().IconH); if (brick->getIconBack().empty())
{
// use blank texture with size from main icon
_EnchantIcons.push_back(SBuffIcon(rVR.getTextureIdFromName("blank.tga"), NLMISC::CRGBA::White));
rVR.getTextureSizeFromId(rVR.getTextureIdFromName(brick->getIcon()), _EnchantIcons.back().IconW, _EnchantIcons.back().IconH);
}
else
{
_EnchantIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(brick->getIconBack()), brick->IconBackColor));
rVR.getTextureSizeFromId(_EnchantIcons.back().TextureId, _EnchantIcons.back().IconW, _EnchantIcons.back().IconH);
}
} }
_EnchantIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(brick->getIcon()), brick->IconColor)); _EnchantIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(brick->getIcon()), brick->IconColor));
rVR.getTextureSizeFromId(_EnchantIcons.back().TextureId, _EnchantIcons.back().IconW, _EnchantIcons.back().IconH); rVR.getTextureSizeFromId(_EnchantIcons.back().TextureId, _EnchantIcons.back().IconW, _EnchantIcons.back().IconH);
@ -2092,35 +2134,8 @@ void CDBCtrlSheet::draw()
rVR.drawQuad(_RenderLayer + 1, regenTris[tri], backTex, CRGBA::White, false); rVR.drawQuad(_RenderLayer + 1, regenTris[tri], backTex, CRGBA::White, false);
} }
if (!_RegenText) { if (_RegenTextEnabled)
_RegenText = new CViewText(CViewBase::TCtorParam()); drawRegenText();
_RegenText->setId(getId() + ":regen");
_RegenText->setParent(_Parent);
_RegenText->setOverflowText(ucstring(""));
_RegenText->setModulateGlobalColor(false);
_RegenText->setMultiLine(false);
_RegenText->setTextMode(CViewText::ClipWord);
_RegenText->setFontSizing("0", "0");
// TODO: font size / color hardcoded.
_RegenText->setFontSize(8);
_RegenText->setColor(CRGBA::White);
_RegenText->setShadow(true);
_RegenText->setActive(true);
_RegenText->updateTextContext();
}
// TODO: ticks in second hardcoded
uint32 nextValue = _RegenTickRange.EndTick > LastGameCycle ? (_RegenTickRange.EndTick - LastGameCycle) / 10 : 0;
if (_RegenTextValue != nextValue)
{
_RegenTextValue = nextValue;
_RegenText->setText(toString("%d", _RegenTextValue));
_RegenText->updateTextContext();
}
_RegenText->setXReal(_XReal+1);
_RegenText->setYReal(_YReal+2);
_RegenText->setRenderLayer(_RenderLayer+2);
_RegenText->draw();
} }
} }
@ -2150,6 +2165,118 @@ void CDBCtrlSheet::draw()
} }
} }
// ----------------------------------------------------------------------------
void CDBCtrlSheet::drawRegenText()
{
if (!_RegenText) {
_RegenText = new CViewText(CViewBase::TCtorParam());
_RegenText->setId(getId() + ":regen");
_RegenText->setParent(_Parent);
_RegenText->setOverflowText(std::string());
_RegenText->setModulateGlobalColor(false);
_RegenText->setMultiLine(true);
_RegenText->setTextMode(CViewText::ClipWord);
_RegenText->setFontSize(_RegenTextFontSize);
_RegenText->setColor(_RegenTextColor);
// do not set shadow if outline is set to avoid clearing it on draw (would call invalidate)
_RegenText->setShadow(_RegenTextShadow && !_RegenTextOutline);
_RegenText->setShadowOutline(false);
_RegenText->setShadowColor(_RegenTextShadowColor);
_RegenText->setActive(true);
_RegenText->updateTextContext();
}
// TODO: 10 hardcoded (ticks in second)
sint32 nextValue;
if (_RegenTickRange.EndTick > LastGameCycle)
nextValue = (_RegenTickRange.EndTick - LastGameCycle) / 10;
else if (_RegenTextFctLua)
nextValue = ((sint64)_RegenTickRange.EndTick - (sint64)LastGameCycle) / 10;
else
nextValue = 0;
if (_RegenTextValue != nextValue)
{
_RegenTextValue = nextValue;
if (_RegenTextFct.empty())
{
// format as "10m", "9'59", "59"
if (_RegenTextValue > 600)
{
_RegenText->setText(toString("%dm", _RegenTextValue / 60));
}
else if (_RegenTextValue > 0)
{
if (_RegenTextValue < 60)
_RegenText->setText(toString("%d", _RegenTextValue));
else
_RegenText->setText(toString("%d'%02d", _RegenTextValue / 60, _RegenTextValue % 60));
}
else
{
_RegenText->setText(ucstring());
}
}
else
{
std::string fct;
if (_RegenTextFctLua)
{
CCDBNodeBranch *root = getRootBranch();
if (root)
fct = toString("%s(%d, '%s')", _RegenTextFct.c_str(), _RegenTextValue, root->getFullName().c_str());
else
fct = toString("%s(%d, nil)", _RegenTextFct.c_str(), _RegenTextValue);
}
else
{
fct = toString("%s(%d)", _RegenTextFct.c_str(), _RegenTextValue);
}
// if using color tags in format, then RegenText color should be set to CRGBA::White
// as tag color is modulated with main color
std::string result;
if (CInterfaceExpr::evalAsString(fct, result))
_RegenText->setTextFormatTaged(result);
}
_RegenText->updateTextContext();
// todo: posref
// note: if x,y is moved outside icon area it might get cliped and not be visible (wreal/hreal == 0)
_RegenText->setX(_WReal / 2 -_RegenText->getMaxUsedW() / 2);
// move RegenTextY=0 to baseline
_RegenText->setY(_RegenTextY - _RegenText->getFontLegHeight());
}
_RegenText->setXReal(_XReal + _RegenText->getX());
_RegenText->setYReal(_YReal + _RegenText->getY());
_RegenText->setRenderLayer(_RenderLayer+2);
// TODO: create shader for this
if (_RegenTextOutline)
{
// player.xml t_bonus_text template way of drawing
sint x = _RegenText->getXReal();
sint y = _RegenText->getYReal();
_RegenText->setColor(_RegenTextShadowColor);
_RegenText->setXReal(x-1); _RegenText->setYReal(y+0); _RegenText->draw();
_RegenText->setXReal(x+1); _RegenText->setYReal(y+0); _RegenText->draw();
_RegenText->setXReal(x+0); _RegenText->setYReal(y-1); _RegenText->draw();
_RegenText->setXReal(x+0); _RegenText->setYReal(y+1); _RegenText->draw();
_RegenText->setColor(_RegenTextColor);
_RegenText->setXReal(x); _RegenText->setYReal(y);
_RegenText->draw();
_RegenText->draw();
}
else
{
_RegenText->draw();
_RegenText->draw();
}
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void CDBCtrlSheet::drawRotatedQuad(CViewRenderer &vr, float angle, float scale, uint renderLayer, uint32 texId, sint32 texWidth, sint32 texHeight) void CDBCtrlSheet::drawRotatedQuad(CViewRenderer &vr, float angle, float scale, uint renderLayer, uint32 texId, sint32 texWidth, sint32 texHeight)
@ -2439,10 +2566,17 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti
} }
yIcon -= hIcon; yIcon -= hIcon;
rVR.drawRotFlipBitmap(_RenderLayer + 1, xIcon, yIcon, wIcon, hIcon, 0, false, _EnchantIcons[0].TextureId, fastMulRGB(curSheetColor, _EnchantIcons[0].Color)); rVR.drawRotFlipBitmap(_RenderLayer + 1, xIcon, yIcon, wIcon, hIcon, 0, false, _EnchantIcons[0].TextureId, fastMulRGB(curSheetColor, _EnchantIcons[0].Color));
rVR.drawRotFlipBitmap(_RenderLayer+1, xIcon, yIcon, wIcon, hIcon, 0, false, _EnchantIcons[i].TextureId, fastMulRGB(curSheetColor, _EnchantIcons[i].Color)); rVR.drawRotFlipBitmap(_RenderLayer + 1, xIcon, yIcon, wIcon, hIcon, 0, false, _EnchantIcons[i].TextureId, fastMulRGB(curSheetColor, _EnchantIcons[i].Color));
if ((i - 1) < _BoostIcons.size()) {
rVR.drawRotFlipBitmap(_RenderLayer + 2, xIcon+wIcon-_BoostIcons[i-1].IconW, yIcon, _BoostIcons[i-1].IconW, _BoostIcons[i-1].IconH, 0, false, _BoostIcons[i-1].TextureId, fastMulRGB(curSheetColor, _BoostIcons[i-1].Color));
}
} }
} }
// Draw Quality. -1 for lookandfeel. Draw it with global color // Draw Quality. -1 for lookandfeel. Draw it with global color
if (_DispQuality != -1) if (_DispQuality != -1)
{ {
@ -2870,7 +3004,7 @@ bool CDBCtrlSheet::handleEvent (const NLGUI::CEventDescriptor &event)
} }
else else
{ {
validClic = isDraggable() && !isDragged() && ((!getItemWeared()&&!getGrayed()) || isShortCut()); validClic = isDraggable() && !isDragged() && ((!getItemWeared()&&!getGrayed()) || isSPhraseId());
} }
} }
if (_Type == SheetType_Macro) if (_Type == SheetType_Macro)
@ -3799,6 +3933,7 @@ void CDBCtrlSheet::resetAllTexIDs()
_ItemInfoChanged = true; _ItemInfoChanged = true;
_EnchantIcons.clear(); _EnchantIcons.clear();
_BuffIcons.clear(); _BuffIcons.clear();
_BoostIcons.clear();
} }
@ -4738,6 +4873,12 @@ std::string CDBCtrlSheet::getContextHelpWindowName() const
return CCtrlBase::getContextHelpWindowName(); return CCtrlBase::getContextHelpWindowName();
} }
// ***************************************************************************
void CDBCtrlSheet::setRegenTextFct(const std::string &s)
{
_RegenTextFct = s;
_RegenTextFctLua = startsWith(s, "lua:");
}
// *************************************************************************** // ***************************************************************************
void CDBCtrlSheet::setRegenTickRange(const CTickRange &tickRange) void CDBCtrlSheet::setRegenTickRange(const CTickRange &tickRange)

@ -602,6 +602,25 @@ public:
void setRegenTickRange(const CTickRange &tickRange); void setRegenTickRange(const CTickRange &tickRange);
const CTickRange &getRegenTickRange() const { return _RegenTickRange; } const CTickRange &getRegenTickRange() const { return _RegenTickRange; }
// Default regen text is displayed on bottom of icon.
void setRegenText(bool b) { _RegenTextEnabled = b; }
// Allow to override default formatter.
// First parameter will be replaced with current timer value (always >= 0)
// If its a lua function, then parameters are
// 1: current timer value; can be negative
// 2: DB path for ctrl root (ie UI:VARIABLES:BONUSES:0), or nil
//
// ie: "secondsToTimeStringShort" -> CInterfaceExpr::evalAsString("secondsToTimeStringShort(123)", ret)
// ie: "lua:secondsToTimeStringShort" -> CInterfaceExpr::evalAsString("lua:secondsToTimeStringShort(123, 'UI:VARIABLES:BONUSES:0')", ret)
void setRegenTextFct(const std::string &s);
void setRegenTextY(sint32 y) { _RegenTextY = y; }
void setRegenTextShadow(bool b) { _RegenTextShadow = b; }
void setRegenTextShadowColor(NLMISC::CRGBA c) { _RegenTextShadowColor = c; }
void setRegenTextOutline(bool b) { _RegenTextOutline = b; }
void setRegenTextOutlineColor(NLMISC::CRGBA c) { _RegenTextOutlineColor = c; }
void setRegenTextFontSize(uint32 s) { _RegenTextFontSize = s; }
void setRegenTextColor(NLMISC::CRGBA c) { _RegenTextColor = c; }
// start notify anim (at the end of regen usually) // start notify anim (at the end of regen usually)
void startNotifyAnim(); void startNotifyAnim();
@ -682,6 +701,7 @@ protected:
}; };
std::vector<SBuffIcon> _BuffIcons; std::vector<SBuffIcon> _BuffIcons;
std::vector<SBuffIcon> _EnchantIcons; std::vector<SBuffIcon> _EnchantIcons;
std::vector<SBuffIcon> _BoostIcons;
// Level Brick or Quality // Level Brick or Quality
union union
@ -738,7 +758,19 @@ protected:
CTickRange _RegenTickRange; CTickRange _RegenTickRange;
NLGUI::CViewText *_RegenText; NLGUI::CViewText *_RegenText;
uint32 _RegenTextValue; sint32 _RegenTextValue;
//
std::string _RegenTextFct;
bool _RegenTextFctLua;
bool _RegenTextEnabled;
bool _RegenTextShadow;
bool _RegenTextOutline;
sint32 _RegenTextY;
uint32 _RegenTextFontSize;
NLMISC::CRGBA _RegenTextShadowColor;
NLMISC::CRGBA _RegenTextOutlineColor;
NLMISC::CRGBA _RegenTextColor;
/// D'n'd /// D'n'd
sint32 _DragX, _DragY; sint32 _DragX, _DragY;
@ -852,6 +884,9 @@ private:
// gelper to draw the notify animation // gelper to draw the notify animation
void drawRotatedQuad(CViewRenderer &vr, float angle, float scale, uint renderLayer, uint32 textureId, sint32 texWidth, sint32 texHeight); void drawRotatedQuad(CViewRenderer &vr, float angle, float scale, uint renderLayer, uint32 textureId, sint32 texWidth, sint32 texHeight);
// create and draw regen text over icon
void drawRegenText();
}; };
/** User type (used with expression system of the interface, see interface_expr.h, that contains a pointer to a CDBCtrlSheet /** User type (used with expression system of the interface, see interface_expr.h, that contains a pointer to a CDBCtrlSheet

@ -23,7 +23,7 @@
#include "stdpch.h" #include "stdpch.h"
#include "dbgroup_list_sheet_bonus_malus.h" #include "dbgroup_list_sheet_bonus_malus.h"
#include "interface_manager.h" #include "interface_manager.h"
#include "nel/misc/xml_macros.h"
using namespace std; using namespace std;
using namespace NLMISC; using namespace NLMISC;
@ -35,87 +35,106 @@ NLMISC_REGISTER_OBJECT(CViewBase, CDBGroupListSheetBonusMalus, std::string, "lis
// *************************************************************************** // ***************************************************************************
CDBGroupListSheetBonusMalus::CDBGroupListSheetBonusMalus(const TCtorParam &param) CDBGroupListSheetBonusMalus::CDBGroupListSheetBonusMalus(const TCtorParam &param)
: CDBGroupListSheet(param) : CDBGroupListSheet(param),
_RegenTextEnabled(true),
_RegenTextY(-14), _RegenTextFontSize(8),
_RegenTextColor(NLMISC::CRGBA::White),
_RegenTextDisabledColor(NLMISC::CRGBA(127,127,127))
{ {
_TextId= -1;
// want leave space between controls in the list // want leave space between controls in the list
// Yoyo: I think it's better like this, + this is important for space consideration and because of XPCat/PVPOutpost // Yoyo: I think it's better like this, + this is important for space consideration and because of XPCat/PVPOutpost
//_ListLeaveSpace= false; //_ListLeaveSpace= false;
} }
// *************************************************************************** // ***************************************************************************
bool CDBGroupListSheetBonusMalus::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup) CDBGroupListSheetBonusMalus::CSheetChildTimer::CSheetChildTimer()
: TimerDB(NULL), DisabledDB(NULL), TimerCache(0),
_RegenTextColor(NLMISC::CRGBA::White),
_RegenTextDisabledColor(NLMISC::CRGBA(127,127,127))
{ {
CInterfaceManager *pIM= CInterfaceManager::getInstance(); }
if(!CDBGroupListSheet::parse(cur, parentGroup)) // ***************************************************************************
return false; void CDBGroupListSheetBonusMalus::CSheetChildTimer::init(CDBGroupListSheet *pFather, uint index)
{
// init my parent
CSheetChild::init(pFather, index);
// read the texture CCDBNodeBranch *root = Ctrl->getRootBranch();
CXMLAutoPtr prop; if (root)
prop = (char*) xmlGetProp( cur, (xmlChar*)"disable_texture" );
if (prop)
{ {
CInterfaceManager *pIM = CInterfaceManager::getInstance(); TimerDB = dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("DISABLED_TIME"), false));
CViewRenderer &rVR = *CViewRenderer::getInstance(); DisabledDB = dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("DISABLED"), false));
_TextId= rVR.getTextureIdFromName ((const char *)prop);
} }
// get the Node leaves to be tested each frame if (Ctrl)
uint i= 0;
for(;;)
{ {
string db= toString("%s:%d:" DISABLE_LEAF, _DbBranchName.c_str(), i); CDBGroupListSheetBonusMalus *owner = dynamic_cast<CDBGroupListSheetBonusMalus *>(pFather);
CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(db, false); if (owner)
if(!node)
{ {
break; _RegenTextColor = owner->_RegenTextColor;
_RegenTextDisabledColor = owner->_RegenTextDisabledColor;
Ctrl->setRegenText(owner->_RegenTextEnabled);
Ctrl->setRegenTextY(owner->_RegenTextY);
Ctrl->setRegenTextColor(owner->_RegenTextColor);
Ctrl->setRegenTextFontSize(owner->_RegenTextFontSize);
if (!owner->_RegenTextFct.empty())
Ctrl->setRegenTextFct(owner->_RegenTextFct);
} }
else
{
_DisableStates.push_back(node);
i++;
}
}
return true; Ctrl->setRegenTextOutline(true);
}
} }
// *************************************************************************** // ***************************************************************************
void CDBGroupListSheetBonusMalus::draw () void CDBGroupListSheetBonusMalus::CSheetChildTimer::update(CDBGroupListSheet * /* pFather */)
{ {
CDBGroupListSheet::draw(); if(!TimerDB)
return;
// CInterfaceManager *pIM= CInterfaceManager::getInstance();
// CViewRenderer &rVR= *CViewRenderer::getInstance();
// sint32 drl= getRenderLayer()+1;
// May draw disable bitmaps on the ctrl sheets if disabled. NLMISC::TGameCycle tick = TimerDB->getValue32();
uint numCtrls= (uint)min(_SheetChildren.size(), _DisableStates.size()); if (TimerCache != tick)
for(uint i=0;i<numCtrls;i++)
{ {
CDBCtrlSheet *ctrl= _SheetChildren[i]->Ctrl; TimerCache = TimerDB->getValue32();
// if the ctrl is displayed, and if the state is disabled Ctrl->setRegenTickRange(CTickRange(LastGameCycle, TimerCache));
if(ctrl->getActive()) if (DisabledDB)
{ {
if(_DisableStates[i]->getValue32()!=0) if (DisabledDB->getValue32() == 0)
{ {
ctrl->setGrayed(true); // active timer
/* Ctrl->setGrayed(false);
// YOYO: for now, don't display the gray bitmap. cross not cool. Ctrl->setRegenTextColor(_RegenTextColor);
CRGBA crossColor= ctrl->getSheetColor();
crossColor.A>>= 2;
// Draw the disable bitmap on this control. +1 for the slot (ugly)
rVR.drawRotFlipBitmap(drl, ctrl->getXReal()+1, ctrl->getYReal()+1,
CCtrlSheetInfo::BrickSheetWidth, CCtrlSheetInfo::BrickSheetHeight, 0, 0, _TextId, crossColor);
*/
} }
else else
ctrl->setGrayed(false); {
// skill disabled timer
Ctrl->setGrayed(true);
Ctrl->setRegenTextColor(_RegenTextDisabledColor);
}
}
else
{
Ctrl->setGrayed(true);
} }
} }
} }
// ***************************************************************************
bool CDBGroupListSheetBonusMalus::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup)
{
CInterfaceManager *pIM= CInterfaceManager::getInstance();
if(!CDBGroupListSheet::parse(cur, parentGroup))
return false;
CXMLAutoPtr prop;
XML_READ_BOOL(cur, "regen_text", _RegenTextEnabled, true);
XML_READ_SINT(cur, "regen_text_y", _RegenTextY, -14);
XML_READ_UINT(cur, "regen_text_fontsize", _RegenTextFontSize, 8);
XML_READ_COLOR(cur, "regen_text_color", _RegenTextColor, NLMISC::CRGBA::White);
XML_READ_COLOR(cur, "regen_text_disabled_color", _RegenTextDisabledColor, NLMISC::CRGBA(127, 127, 127));
XML_READ_STRING(cur, "regen_text_fct", _RegenTextFct, "");
return true;
}

@ -25,7 +25,6 @@
#include "nel/misc/types_nl.h" #include "nel/misc/types_nl.h"
#include "dbgroup_list_sheet.h" #include "dbgroup_list_sheet.h"
// *************************************************************************** // ***************************************************************************
/** /**
* Special list_sheet that display some disalbe bitmap if needed according to DB * Special list_sheet that display some disalbe bitmap if needed according to DB
@ -40,14 +39,34 @@ public:
/// Constructor /// Constructor
CDBGroupListSheetBonusMalus(const TCtorParam &param); CDBGroupListSheetBonusMalus(const TCtorParam &param);
virtual bool parse (xmlNodePtr cur, CInterfaceGroup *parentGroup); // A child node
struct CSheetChildTimer : public CDBGroupListSheet::CSheetChild
{
CSheetChildTimer();
virtual void init(CDBGroupListSheet *pFather, uint index) NL_OVERRIDE;
virtual void update(CDBGroupListSheet *pFather) NL_OVERRIDE;
NLMISC::CCDBNodeLeaf *TimerDB;
NLMISC::CCDBNodeLeaf *DisabledDB;
uint TimerCache;
NLMISC::CRGBA _RegenTextColor;
NLMISC::CRGBA _RegenTextDisabledColor;
};
virtual bool parse(xmlNodePtr cur, CInterfaceGroup *parentGroup) NL_OVERRIDE;
virtual void draw (); virtual CSheetChild *createSheetChild() NL_OVERRIDE { return new CSheetChildTimer; }
private: private:
sint32 _TextId; friend CSheetChildTimer;
std::vector<NLMISC::CCDBNodeLeaf*> _DisableStates; bool _RegenTextEnabled;
std::string _RegenTextFct;
sint32 _RegenTextY;
uint32 _RegenTextFontSize;
NLMISC::CRGBA _RegenTextColor;
NLMISC::CRGBA _RegenTextDisabledColor;
}; };

@ -257,7 +257,7 @@ void CDBGroupListSheetTrade::CSheetChildTrade::updateViewText(CDBGroupListSheetT
case CDBCtrlSheet::Pact: text= CI18N::get("uiBotChatPact") + text; break; case CDBCtrlSheet::Pact: text= CI18N::get("uiBotChatPact") + text; break;
case CDBCtrlSheet::Skill: text= CI18N::get("uiBotChatSkill") + text; break; case CDBCtrlSheet::Skill: text= CI18N::get("uiBotChatSkill") + text; break;
case CDBCtrlSheet::GuildFlag: text= CI18N::get("uiBotChatSkill") + text; break; case CDBCtrlSheet::GuildFlag: text= CI18N::get("uiBotChatSkill") + text; break;
case CDBCtrlSheet::Phrase: text= CI18N::get("uiBotChatPhrase") + text; break; case CDBCtrlSheet::Phrase: text= text; break;
default: break; default: break;
} }
@ -536,12 +536,12 @@ bool CDBGroupListSheetTrade::CSheetChildTrade::isSheetValid(CDBGroupListSheetTex
nlwarning("Brick %d has type %s", (int) k, BRICK_TYPE::toString(bs->getBrickType()).c_str()); nlwarning("Brick %d has type %s", (int) k, BRICK_TYPE::toString(bs->getBrickType()).c_str());
} }
else else
{ {
nlwarning("Brick %d : not a brick sheet", (int) k); nlwarning("Brick %d : not a brick sheet", (int) k);
} }
} }
} }
*/ */
if (phraseSheet) if (phraseSheet)
{ {
@ -563,7 +563,7 @@ bool CDBGroupListSheetTrade::CSheetChildTrade::isSheetValid(CDBGroupListSheetTex
break; break;
} }
} }
return true; return true;

@ -28,6 +28,7 @@
#include "nel/gui/action_handler.h" #include "nel/gui/action_handler.h"
#include "../entities.h" #include "../entities.h"
#include "nel/gui/group_paragraph.h" // For CCtrlLink #include "nel/gui/group_paragraph.h" // For CCtrlLink
#include "nel/gui/view_bitmap.h"
#include "../net_manager.h" #include "../net_manager.h"
#include "../string_manager_client.h" #include "../string_manager_client.h"
#include "../login.h" #include "../login.h"
@ -644,14 +645,42 @@ void CGroupInSceneBubbleManager::addMessagePopupCenter (const ucstring &message,
"ui:interface", templateParams.empty()?NULL:&(templateParams[0]), (uint)templateParams.size()); "ui:interface", templateParams.empty()?NULL:&(templateParams[0]), (uint)templateParams.size());
if (group) if (group)
{ {
ucstring finalMessage = message;
ucstring::size_type pos = message.find(ucstring("|"));
if (pos != std::string::npos)
{
CViewBitmap *pViewIcon = dynamic_cast<CViewBitmap*>(group->getView("iconA"));
if (pViewIcon != NULL)
{
string texture = message.substr(0, pos).toString();
pViewIcon->setTexture(texture);
}
ucstring::size_type end = message.find(ucstring("|"), pos+1);
if (end != std::string::npos)
{
CViewBitmap *pViewIcon = dynamic_cast<CViewBitmap*>(group->getView("iconZ"));
if (pViewIcon != NULL)
{
string texture = message.substr(end+1).toString();
pViewIcon->setTexture(texture);
}
finalMessage = message.substr(pos+1, end-pos-1);
}
else
finalMessage = message.substr(pos+1);
}
// Skill name // Skill name
CViewText *pViewName = dynamic_cast<CViewText*>(group->getView("name")); CViewText *pViewName = dynamic_cast<CViewText*>(group->getView("name"));
if (pViewName != NULL) if (pViewName != NULL)
{ {
pViewName->setTextFormatTaged(message); pViewName->setTextFormatTaged(finalMessage);
pViewName->setColor (color); pViewName->setColor (color);
} }
// Link to the interface // Link to the interface
CWidgetManager::getInstance()->addWindowToMasterGroup("ui:interface", group); CWidgetManager::getInstance()->addWindowToMasterGroup("ui:interface", group);
CInterfaceGroup *pRoot = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId("ui:interface")); CInterfaceGroup *pRoot = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId("ui:interface"));
@ -843,6 +872,33 @@ void CGroupInSceneBubbleManager::chatOpen (uint32 nUID, const ucstring &ucsText,
if (pChar == NULL || nUID==CLFECOMMON::INVALID_CLIENT_DATASET_INDEX) return; if (pChar == NULL || nUID==CLFECOMMON::INVALID_CLIENT_DATASET_INDEX) return;
if (bubbleTimer == 0) bubbleTimer = CWidgetManager::getInstance()->getSystemOption(CWidgetManager::OptionTimeoutBubbles).getValSInt32(); if (bubbleTimer == 0) bubbleTimer = CWidgetManager::getInstance()->getSystemOption(CWidgetManager::OptionTimeoutBubbles).getValSInt32();
// Clean bubble from translation system
ucstring::size_type pos = 0;
ucstring::size_type textSize = ucsText.size();
string::size_type startTr = ucsText.find(ucstring("{:"));
string::size_type endOfOriginal = ucsText.find(ucstring("}@{"));
if (startTr != string::npos && endOfOriginal != string::npos) {
bool inverse = false;
string lang = toUpper(ucsText.substr(startTr+2, 2)).toString();
CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:TRANSLATION:" + lang + ":INVERSE_DISPLAY", false);
if (node)
inverse = node->getValueBool();
if (!inverse)
{
pos = endOfOriginal+4;
}
else
{
pos = startTr+5;
textSize = endOfOriginal;
}
}
// Output the message in a bubble // Output the message in a bubble
bool show = false; bool show = false;
@ -862,7 +918,7 @@ void CGroupInSceneBubbleManager::chatOpen (uint32 nUID, const ucstring &ucsText,
return; return;
// Get a bubble // Get a bubble
CGroupInSceneBubble *bubble = newBubble (ucsText); CGroupInSceneBubble *bubble = newBubble (ucsText.substr(pos, textSize-pos));
if (bubble) if (bubble)
{ {
// Link the bubble // Link the bubble

@ -463,19 +463,26 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (CEntityCL *entity)
//else //else
// stringSpace += textH; // stringSpace += textH;
bool have2pvptags = false;
if (rpTags) if (rpTags)
{ {
CPlayerCL * pPlayer = dynamic_cast<CPlayerCL*>(entity); CPlayerCL * pPlayer = dynamic_cast<CPlayerCL*>(entity);
CViewBitmap *rp1 = dynamic_cast<CViewBitmap*>(leftGroup->getView ("rp_logo_1")); CViewBitmap *rp1 = dynamic_cast<CViewBitmap*>(info->getView ("rp_logo_1"));
CViewBitmap *rp2 = dynamic_cast<CViewBitmap*>(leftGroup->getView ("rp_logo_2")); CViewBitmap *rp2 = dynamic_cast<CViewBitmap*>(info->getView ("rp_logo_2"));
CViewBitmap *rp3 = dynamic_cast<CViewBitmap*>(leftGroup->getView ("rp_logo_3")); CViewBitmap *rp3 = dynamic_cast<CViewBitmap*>(info->getView ("rp_logo_3"));
CViewBitmap *rp4 = dynamic_cast<CViewBitmap*>(leftGroup->getView ("rp_logo_4")); CViewBitmap *rp4 = dynamic_cast<CViewBitmap*>(info->getView ("rp_logo_4"));
if (entityTag1.toString() == "_") entityTag1.clear(); if (entityTag1.toString() == "_") entityTag1.clear();
if (entityTag2.toString() == "_") entityTag2.clear(); if (entityTag2.toString() == "_") entityTag2.clear();
if (entityTag3.toString() == "_") entityTag3.clear(); if (entityTag3.toString() == "_") entityTag3.clear();
if (entityTag4.toString() == "_") entityTag4.clear(); if (entityTag4.toString() == "_") entityTag4.clear();
if (pPlayer && (pPlayer->getPvpMode() == PVP_MODE::None))
{
entityTag1.clear();
entityTag2.clear();
}
if (rp1) rp1->setTexture(entityTag1.toString()); if (rp1) rp1->setTexture(entityTag1.toString());
if (rp2) rp2->setTexture(entityTag2.toString()); if (rp2) rp2->setTexture(entityTag2.toString());
if (rp3) rp3->setTexture(entityTag3.toString()); if (rp3) rp3->setTexture(entityTag3.toString());
@ -486,6 +493,8 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (CEntityCL *entity)
if (rp2) rp2->setActive(!entityTag2.empty()); if (rp2) rp2->setActive(!entityTag2.empty());
if (rp3) rp3->setActive(!entityTag3.empty()); if (rp3) rp3->setActive(!entityTag3.empty());
if (rp4) rp4->setActive(!entityTag4.empty()); if (rp4) rp4->setActive(!entityTag4.empty());
have2pvptags = !entityTag1.empty() && !entityTag2.empty();
} }
// Get the permanent content bitmap // Get the permanent content bitmap
@ -654,6 +663,7 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (CEntityCL *entity)
} }
CViewBase * pvpFactionLogo = info->getView ("pvp_faction_logo"); CViewBase * pvpFactionLogo = info->getView ("pvp_faction_logo");
CViewBase * pvpFactionLogo2 = info->getView ("pvp_faction_logo2");
CViewBase * pvpOutpostLogo = info->getView ("pvp_outpost_logo"); CViewBase * pvpOutpostLogo = info->getView ("pvp_outpost_logo");
CViewBase * pvpDuelLogo = info->getView ("pvp_duel_logo"); CViewBase * pvpDuelLogo = info->getView ("pvp_duel_logo");
@ -667,6 +677,7 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (CEntityCL *entity)
{ {
pvpFactionLogo->setActive(true); pvpFactionLogo->setActive(true);
CViewBitmap * pvpFactionBitmap = dynamic_cast<CViewBitmap *>(pvpFactionLogo); CViewBitmap * pvpFactionBitmap = dynamic_cast<CViewBitmap *>(pvpFactionLogo);
CViewBitmap * pvpFactionBitmap2 = dynamic_cast<CViewBitmap *>(pvpFactionLogo2);
if( pvpFactionBitmap ) if( pvpFactionBitmap )
{ {
if (user) if (user)
@ -714,6 +725,12 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (CEntityCL *entity)
pvpFactionLogo->setActive(false); pvpFactionLogo->setActive(false);
} }
} }
if( pvpFactionLogo && pvpFactionBitmap2 )
{
pvpFactionBitmap2->setTexture(pvpFactionBitmap->getTexture());
pvpFactionLogo2->setActive(have2pvptags);
}
} }
if (pvpOutpostLogo) if (pvpOutpostLogo)
@ -731,13 +748,6 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (CEntityCL *entity)
else else
pvpDuelLogo->setActive(false); pvpDuelLogo->setActive(false);
} }
}
else
{
CInterfaceGroup* grp = info->getGroup("right_pvp");
if (grp)
info->delGroup(grp);
} }
} }

@ -2472,7 +2472,8 @@ void CGroupMap::updateMatchedLandmarks()
std::vector<std::pair<string,string> > params; std::vector<std::pair<string,string> > params;
params.clear(); params.clear();
params.push_back(std::pair<string,string>("id", toString("lm%d", k))); params.push_back(std::pair<string,string>("id", toString("lm%d", k)));
params.push_back(std::pair<string,string>("tooltip", _MatchedLandmarks[k].Title.toUtf8())); // ctrl base expects utf8 string to start with "u:"
params.push_back(std::pair<string,string>("tooltip", "u:" + _MatchedLandmarks[k].Title.toUtf8()));
params.push_back(std::pair<string,string>("index", toString(k))); params.push_back(std::pair<string,string>("index", toString(k)));
CInterfaceGroup *g = CWidgetManager::getInstance()->getParser()->createGroupInstance("lm_search_result", pL->getId(), params); CInterfaceGroup *g = CWidgetManager::getInstance()->getParser()->createGroupInstance("lm_search_result", pL->getId(), params);
@ -2653,7 +2654,7 @@ void CGroupMap::createContinentLandMarks()
static void hideTeleportButtonsInPopupMenuIfNotEnoughPriv() static void hideTeleportButtonsInPopupMenuIfNotEnoughPriv()
{ {
bool showTeleport = (hasPrivilegeDEV() || hasPrivilegeSGM() || hasPrivilegeGM() || hasPrivilegeVG() || hasPrivilegeSG() || hasPrivilegeEM() || hasPrivilegeEG() || hasPrivilegeOBSERVER()); bool showTeleport = (hasPrivilegeDEV() || hasPrivilegeSGM() || hasPrivilegeGM() || hasPrivilegeVG() || hasPrivilegeSG() || hasPrivilegeEM() || hasPrivilegeEG() || hasPrivilegeOBSERVER()|| hasPrivilegeTESTER());
CInterfaceManager *im = CInterfaceManager::getInstance(); CInterfaceManager *im = CInterfaceManager::getInstance();
CInterfaceElement *ie = CWidgetManager::getInstance()->getElementFromId("ui:interface:map_menu:teleport"); CInterfaceElement *ie = CWidgetManager::getInstance()->getElementFromId("ui:interface:map_menu:teleport");
@ -2680,7 +2681,7 @@ void CGroupMap::setLandmarkFilter(const std::string &s)
if (!s.empty()) { if (!s.empty()) {
ucstring ucs; ucstring ucs;
ucs.fromUtf8(s); ucs.fromUtf8(s);
splitUCString(toLower(s), ucstring(" "), _LandmarkFilter); splitUCString(toLower(ucs), ucstring(" "), _LandmarkFilter);
} }
// recreate landmarks // recreate landmarks
@ -2754,6 +2755,8 @@ CGroupMap::CLandMarkButton *CGroupMap::createArkPointButton(const CArkPoint &poi
lmb->setParamsOnLeftClick(point.LeftClickParam); lmb->setParamsOnLeftClick(point.LeftClickParam);
lmb->setActionOnRightClick(point.RightClickAction); lmb->setActionOnRightClick(point.RightClickAction);
lmb->setParamsOnRightClick(point.RightClickParam); lmb->setParamsOnRightClick(point.RightClickParam);
lmb->setActionOnOver(point.OverClickAction);
lmb->setParamsOnOver(point.OverClickParam);
lmb->setColor(point.Color); lmb->setColor(point.Color);
lmb->setColorOver(point.Color); lmb->setColorOver(point.Color);
lmb->setColorPushed(point.Color); lmb->setColorPushed(point.Color);

@ -95,6 +95,8 @@ public:
std::string LeftClickParam; std::string LeftClickParam;
std::string RightClickAction; std::string RightClickAction;
std::string RightClickParam; std::string RightClickParam;
std::string OverClickAction;
std::string OverClickParam;
public: public:
CArkPoint() CArkPoint()
@ -230,7 +232,7 @@ public:
void addUserLandMark(const NLMISC::CVector2f &pos, const ucstring &title, NLMISC::CRGBA color); void addUserLandMark(const NLMISC::CVector2f &pos, const ucstring &title, NLMISC::CRGBA color);
void addUserRespawnPoint(const NLMISC::CVector2f &pos); void addUserRespawnPoint(const NLMISC::CVector2f &pos);
void delArkPoints(); void delArkPoints();
// set landmarks visibility based text query // set landmarks visibility based text query
void setLandmarkFilter(const std::string &s); void setLandmarkFilter(const std::string &s);
@ -602,7 +604,7 @@ private:
CLandMarkButton *createLandMarkButton(const CLandMarkOptions &options); CLandMarkButton *createLandMarkButton(const CLandMarkOptions &options);
// Create a Ark landmark button, but do not add it to this group // Create a Ark landmark button, but do not add it to this group
CLandMarkButton *createArkPointButton(const CArkPoint &point); CLandMarkButton *createArkPointButton(const CArkPoint &point);
// update a landmark button // update a landmark button
void updateLandMarkButton(CLandMarkButton *lmb, const CLandMarkOptions &options); void updateLandMarkButton(CLandMarkButton *lmb, const CLandMarkOptions &options);

@ -74,6 +74,8 @@ bool CGroupQuickHelp::submitEvent (const char *event)
// Update the text // Update the text
updateParagraph (); updateParagraph ();
CLuaManager::getInstance().executeLuaScript(toString("\ngame:processTutorialEvent(\"%s\")\n", event), true);
} }
} }
return false; return false;

@ -67,6 +67,7 @@ NLMISC_REGISTER_OBJECT(CViewBase, CDBGroupListAscensor, std::string, "list_sheet
#define VIEW_TEXT_GUILD_QUIT "ui:interface:guild:content:tab_guild_info:quit_guild" #define VIEW_TEXT_GUILD_QUIT "ui:interface:guild:content:tab_guild_info:quit_guild"
#define CTRL_SHEET_GUILD_BLASON "ui:interface:guild:content:tab_guild_info:blason" #define CTRL_SHEET_GUILD_BLASON "ui:interface:guild:content:tab_guild_info:blason"
#define VIEW_TEXT_GUILD_MEMBER_COUNT "ui:interface:guild:content:tab_guild_info:member_count" #define VIEW_TEXT_GUILD_MEMBER_COUNT "ui:interface:guild:content:tab_guild_info:member_count"
#define VIEW_TEXT_GUILD_MEMBER_COUNT_ONLINE "ui:interface:guild:content:tab_guild_info:member_count_online"
#define LIST_GUILD_MEMBERS "ui:interface:guild:content:tab_guild:list_member:guild_members" #define LIST_GUILD_MEMBERS "ui:interface:guild:content:tab_guild:list_member:guild_members"
@ -817,6 +818,7 @@ class CAHGuildSheetOpen : public IActionHandler
if (pParent == NULL) return; if (pParent == NULL) return;
pParent->clearGroups(); pParent->clearGroups();
pParent->setDynamicDisplaySize(false); pParent->setDynamicDisplaySize(false);
uint member_online = 0;
for (uint i = 0; i < rGuildMembers.size(); i++) for (uint i = 0; i < rGuildMembers.size(); i++)
{ {
// create the member line // create the member line
@ -855,11 +857,13 @@ class CAHGuildSheetOpen : public IActionHandler
switch(rGuildMembers[i].Online) switch(rGuildMembers[i].Online)
{ {
case ccs_online: case ccs_online:
member_online++;
onlineView->setTexture("w_online.tga"); onlineView->setTexture("w_online.tga");
if (toolTip) if (toolTip)
toolTip->setDefaultContextHelp(CI18N::get("uittGuildMemberOnline")); toolTip->setDefaultContextHelp(CI18N::get("uittGuildMemberOnline"));
break; break;
case ccs_online_abroad: case ccs_online_abroad:
member_online++;
onlineView->setTexture("w_online_abroad.tga"); onlineView->setTexture("w_online_abroad.tga");
if (toolTip) if (toolTip)
toolTip->setDefaultContextHelp(CI18N::get("uittGuildMemberOnlineAbroad")); toolTip->setDefaultContextHelp(CI18N::get("uittGuildMemberOnlineAbroad"));
@ -895,6 +899,12 @@ class CAHGuildSheetOpen : public IActionHandler
pLine->setParent (pParent); pLine->setParent (pParent);
pParent->addChild (pLine); pParent->addChild (pLine);
} }
// update member online count view
CViewText *pOnlineMember = dynamic_cast<CViewText*>(CWidgetManager::getInstance()->getElementFromId(VIEW_TEXT_GUILD_MEMBER_COUNT_ONLINE));
if (pOnlineMember)
pOnlineMember->setText(toString(member_online));
} }
} }
}; };

@ -1044,6 +1044,10 @@ void CInterfaceManager::initInGame()
gc->setTarget(gc->getSavedTarget()); gc->setTarget(gc->getSavedTarget());
} }
// rebuild mp3 player playlist if user reselected a char (songs are already scanned)
CAHManager::getInstance()->runActionHandler("music_player", NULL, "update_playlist");
CAHManager::getInstance()->runActionHandler("music_player", NULL, "stop");
CCDBNodeLeaf *node = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CHATLOG_STATE", false); CCDBNodeLeaf *node = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CHATLOG_STATE", false);
if (node) if (node)
{ {
@ -2519,6 +2523,17 @@ void CInterfaceManager::displaySystemInfo(const ucstring &str, const string &cat
CClientConfig::SSysInfoParam::TMode mode = CClientConfig::SSysInfoParam::Normal; CClientConfig::SSysInfoParam::TMode mode = CClientConfig::SSysInfoParam::Normal;
CRGBA color = CRGBA::White; CRGBA color = CRGBA::White;
ucstring cleanStr = str;
ucstring::size_type pos = str.find(ucstring("|"));
if (pos != std::string::npos)
{
ucstring::size_type end = str.find(ucstring("|"), pos+1);
if (end != std::string::npos)
cleanStr = str.substr(pos+1, end-pos-1);
else
cleanStr = str.substr(pos+1);
}
// If broadcast, parse lua code // If broadcast, parse lua code
if (toLower(cat) == "bc" && str.size() > 3 && str[0]=='@' && str[1]=='L' && str[2]=='U' && str[3]=='A') if (toLower(cat) == "bc" && str.size() > 3 && str[0]=='@' && str[1]=='L' && str[2]=='U' && str[3]=='A')
{ {
@ -2538,11 +2553,11 @@ void CInterfaceManager::displaySystemInfo(const ucstring &str, const string &cat
if (mode != CClientConfig::SSysInfoParam::OverOnly && mode != CClientConfig::SSysInfoParam::Around) if (mode != CClientConfig::SSysInfoParam::OverOnly && mode != CClientConfig::SSysInfoParam::Around)
{ {
if (PeopleInterraction.SystemInfo) if (PeopleInterraction.SystemInfo)
PeopleInterraction.ChatInput.SystemInfo.displayMessage(str, color, 2); PeopleInterraction.ChatInput.SystemInfo.displayMessage(cleanStr, color, 2);
else else
{ {
CPeopleInterraction::CSysMsg sysMsg; CPeopleInterraction::CSysMsg sysMsg;
sysMsg.Str = str; sysMsg.Str = cleanStr;
sysMsg.Cat = cat; sysMsg.Cat = cat;
PeopleInterraction.SystemMessageBuffer.push_back( sysMsg ); PeopleInterraction.SystemMessageBuffer.push_back( sysMsg );
} }
@ -2553,10 +2568,10 @@ void CInterfaceManager::displaySystemInfo(const ucstring &str, const string &cat
// If over popup a string at the bottom of the screen // If over popup a string at the bottom of the screen
if ((mode == CClientConfig::SSysInfoParam::Over) || (mode == CClientConfig::SSysInfoParam::OverOnly)) if ((mode == CClientConfig::SSysInfoParam::Over) || (mode == CClientConfig::SSysInfoParam::OverOnly))
InSceneBubbleManager.addMessagePopup(str, color); InSceneBubbleManager.addMessagePopup(cleanStr, color);
else if ( (mode == CClientConfig::SSysInfoParam::Around || mode == CClientConfig::SSysInfoParam::CenterAround) else if ( (mode == CClientConfig::SSysInfoParam::Around || mode == CClientConfig::SSysInfoParam::CenterAround)
&& PeopleInterraction.AroundMe.Window) && PeopleInterraction.AroundMe.Window)
PeopleInterraction.ChatInput.AroundMe.displayMessage(str, color, 2); PeopleInterraction.ChatInput.AroundMe.displayMessage(cleanStr, color, 2);
} }

@ -3769,6 +3769,21 @@ void CInventoryManager::sortBag()
if (pIconList != NULL) pIconList->needToSort(); if (pIconList != NULL) pIconList->needToSort();
pList = dynamic_cast<CDBGroupListSheetBag*>(CWidgetManager::getInstance()->getElementFromId(LIST_PA3_TEXT)); pList = dynamic_cast<CDBGroupListSheetBag*>(CWidgetManager::getInstance()->getElementFromId(LIST_PA3_TEXT));
if (pList != NULL) pList->needToSort(); if (pList != NULL) pList->needToSort();
pIconList = dynamic_cast<CDBGroupIconListBag*>(CWidgetManager::getInstance()->getElementFromId(LIST_PA4_ICONS));
if (pIconList != NULL) pIconList->needToSort();
pList = dynamic_cast<CDBGroupListSheetBag*>(CWidgetManager::getInstance()->getElementFromId(LIST_PA4_TEXT));
if (pList != NULL) pList->needToSort();
pIconList = dynamic_cast<CDBGroupIconListBag*>(CWidgetManager::getInstance()->getElementFromId(LIST_PA5_ICONS));
if (pIconList != NULL) pIconList->needToSort();
pList = dynamic_cast<CDBGroupListSheetBag*>(CWidgetManager::getInstance()->getElementFromId(LIST_PA5_TEXT));
if (pList != NULL) pList->needToSort();
pIconList = dynamic_cast<CDBGroupIconListBag*>(CWidgetManager::getInstance()->getElementFromId(LIST_PA6_ICONS));
if (pIconList != NULL) pIconList->needToSort();
pList = dynamic_cast<CDBGroupListSheetBag*>(CWidgetManager::getInstance()->getElementFromId(LIST_PA6_TEXT));
if (pList != NULL) pList->needToSort();
} }
// *************************************************************************** // ***************************************************************************

@ -822,6 +822,15 @@ private:
#define LIST_PA3_TEXT "ui:interface:inv_pa3:content:iil:bag_list" #define LIST_PA3_TEXT "ui:interface:inv_pa3:content:iil:bag_list"
#define LIST_PA3_ICONS "ui:interface:inv_pa3:content:iil:bag_icons" #define LIST_PA3_ICONS "ui:interface:inv_pa3:content:iil:bag_icons"
#define LIST_PA4_TEXT "ui:interface:inv_pa4:content:iil:bag_list"
#define LIST_PA4_ICONS "ui:interface:inv_pa4:content:iil:bag_icons"
#define LIST_PA5_TEXT "ui:interface:inv_pa5:content:iil:bag_list"
#define LIST_PA5_ICONS "ui:interface:inv_pa5:content:iil:bag_icons"
#define LIST_PA6_TEXT "ui:interface:inv_pa6:content:iil:bag_list"
#define LIST_PA6_ICONS "ui:interface:inv_pa6:content:iil:bag_icons"
// Theorically never used // Theorically never used
#define LIST_BAG2_TEXT "ui:interface:inv_bag:content:iil:bag_list" #define LIST_BAG2_TEXT "ui:interface:inv_bag:content:iil:bag_list"
#define LIST_BAG2_ICONS "ui:interface:inv_bag:content:iil:bag_icons" #define LIST_BAG2_ICONS "ui:interface:inv_bag:content:iil:bag_icons"

@ -96,6 +96,7 @@
#include "../continent_manager.h" #include "../continent_manager.h"
#include "../zone_util.h" #include "../zone_util.h"
#include "../motion/user_controls.h" #include "../motion/user_controls.h"
#include "../events_listener.h"
#include "group_html_cs.h" #include "group_html_cs.h"
#include "group_map.h" #include "group_map.h"
#include "bonus_malus.h" #include "bonus_malus.h"
@ -153,6 +154,7 @@ using namespace R2;
extern NLMISC::CLog g_log; extern NLMISC::CLog g_log;
extern CContinentManager ContinentMngr; extern CContinentManager ContinentMngr;
extern CClientChatManager ChatMngr; extern CClientChatManager ChatMngr;
extern CEventsListener EventsListener; // Inputs Manager
// *************************************************************************** // ***************************************************************************
class CHandlerLUA : public IActionHandler class CHandlerLUA : public IActionHandler
@ -184,6 +186,21 @@ private:
REGISTER_ACTION_HANDLER(CHandlerLUA, "lua"); REGISTER_ACTION_HANDLER(CHandlerLUA, "lua");
std::deque<CRefPtr<CCtrlBase> > CHandlerLUA::_UICallerStack; std::deque<CRefPtr<CCtrlBase> > CHandlerLUA::_UICallerStack;
// ***************************************************************************
class CHandlerSCRIPT : public IActionHandler
{
public:
void execute(CCtrlBase *pCaller, const std::string &sParams)
{
string script = sParams;
while(strFindReplace(script, "[", ""));
while(strFindReplace(script, "]", ""));
strFindReplace(script, "|", "\n");
CLuaManager::getInstance().executeLuaScript("\ngame:executeRyzomScript([["+script+"]])\n", true);
}
};
REGISTER_ACTION_HANDLER(CHandlerSCRIPT, "script");
// *************************************************************************** // ***************************************************************************
// Allow also to call script from expression // Allow also to call script from expression
static DECLARE_INTERFACE_USER_FCT(lua) static DECLARE_INTERFACE_USER_FCT(lua)
@ -428,6 +445,7 @@ void CLuaIHMRyzom::RegisterRyzomFunctions(NLGUI::CLuaState &ls)
ls.registerFunc("launchContextMenuInGame", launchContextMenuInGame); ls.registerFunc("launchContextMenuInGame", launchContextMenuInGame);
ls.registerFunc("parseInterfaceFromString", parseInterfaceFromString); ls.registerFunc("parseInterfaceFromString", parseInterfaceFromString);
ls.registerFunc("updateAllLocalisedElements", updateAllLocalisedElements); ls.registerFunc("updateAllLocalisedElements", updateAllLocalisedElements);
ls.registerFunc("getTimestampHuman", getTimestampHuman);
ls.registerFunc("formatUI", formatUI); ls.registerFunc("formatUI", formatUI);
ls.registerFunc("formatDB", formatDB); ls.registerFunc("formatDB", formatDB);
ls.registerFunc("dumpUI", dumpUI); ls.registerFunc("dumpUI", dumpUI);
@ -454,6 +472,8 @@ void CLuaIHMRyzom::RegisterRyzomFunctions(NLGUI::CLuaState &ls)
ls.registerFunc("getMouseDown", getMouseDown), ls.registerFunc("getMouseDown", getMouseDown),
ls.registerFunc("getMouseMiddleDown", getMouseMiddleDown), ls.registerFunc("getMouseMiddleDown", getMouseMiddleDown),
ls.registerFunc("getMouseRightDown", getMouseRightDown), ls.registerFunc("getMouseRightDown", getMouseRightDown),
ls.registerFunc("isShiftDown", isShiftDown),
ls.registerFunc("isCtrlDown", isCtrlDown),
ls.registerFunc("getShapeIdAt", getShapeIdAt), ls.registerFunc("getShapeIdAt", getShapeIdAt),
ls.registerFunc("getPlayerFront", getPlayerFront); ls.registerFunc("getPlayerFront", getPlayerFront);
ls.registerFunc("getPlayerDirection", getPlayerDirection); ls.registerFunc("getPlayerDirection", getPlayerDirection);
@ -565,6 +585,8 @@ void CLuaIHMRyzom::RegisterRyzomFunctions(NLGUI::CLuaState &ls)
LUABIND_FUNC(isDynStringAvailable), LUABIND_FUNC(isDynStringAvailable),
LUABIND_FUNC(isFullyPatched), LUABIND_FUNC(isFullyPatched),
LUABIND_FUNC(getSheetType), LUABIND_FUNC(getSheetType),
LUABIND_FUNC(getSheetShape),
LUABIND_FUNC(getCharacterSheetScale),
LUABIND_FUNC(getSheetFamily), LUABIND_FUNC(getSheetFamily),
LUABIND_FUNC(getSheetName), LUABIND_FUNC(getSheetName),
LUABIND_FUNC(getFameIndex), LUABIND_FUNC(getFameIndex),
@ -1245,7 +1267,7 @@ int CLuaIHMRyzom::getMousePos(CLuaState &ls)
CTool::getMousePos(x, y); CTool::getMousePos(x, y);
ls.push(x); ls.push(x);
ls.push(y); ls.push(y);
return 2; return 2;
} }
@ -1254,10 +1276,10 @@ int CLuaIHMRyzom::getMouseDown(CLuaState &ls)
sint32 x, y; sint32 x, y;
bool down; bool down;
CTool::getMouseDown(down, x, y); CTool::getMouseDown(down, x, y);
ls.push(down); ls.push(EventsListener.isMouseButtonPushed(leftButton));
ls.push(x); ls.push(x);
ls.push(y); ls.push(y);
return 3; return 3;
} }
@ -1266,11 +1288,10 @@ int CLuaIHMRyzom::getMouseMiddleDown(CLuaState &ls)
sint32 x, y; sint32 x, y;
bool down; bool down;
CTool::getMouseMiddleDown(down, x, y); CTool::getMouseMiddleDown(down, x, y);
ls.push(EventsListener.isMouseButtonPushed(middleButton));
ls.push(down);
ls.push(x); ls.push(x);
ls.push(y); ls.push(y);
return 3; return 3;
} }
@ -1279,14 +1300,31 @@ int CLuaIHMRyzom::getMouseRightDown(CLuaState &ls)
sint32 x, y; sint32 x, y;
bool down; bool down;
CTool::getMouseRightDown(down, x, y); CTool::getMouseRightDown(down, x, y);
ls.push(down); ls.push(EventsListener.isMouseButtonPushed(rightButton));
ls.push(x); ls.push(x);
ls.push(y); ls.push(y);
return 3; return 3;
} }
int CLuaIHMRyzom::isShiftDown(CLuaState &ls)
{
ls.push(Driver->AsyncListener.isKeyDown(KeySHIFT) ||
Driver->AsyncListener.isKeyDown(KeyLSHIFT) ||
Driver->AsyncListener.isKeyDown(KeyRSHIFT));
return 1;
}
int CLuaIHMRyzom::isCtrlDown(CLuaState &ls)
{
ls.push(Driver->AsyncListener.isKeyDown(KeyCONTROL) ||
Driver->AsyncListener.isKeyDown(KeyLCONTROL) ||
Driver->AsyncListener.isKeyDown(KeyRCONTROL));
return 1;
}
int CLuaIHMRyzom::getShapeIdAt(CLuaState &ls) int CLuaIHMRyzom::getShapeIdAt(CLuaState &ls)
{ {
@ -1294,10 +1332,10 @@ int CLuaIHMRyzom::getShapeIdAt(CLuaState &ls)
CLuaIHM::checkArgCount(ls, funcName, 2); CLuaIHM::checkArgCount(ls, funcName, 2);
CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
CLuaIHM::checkArgType(ls, funcName, 2, LUA_TNUMBER); CLuaIHM::checkArgType(ls, funcName, 2, LUA_TNUMBER);
uint32 x = (uint32)ls.toInteger(1); uint32 x = (uint32)ls.toInteger(1);
uint32 y = (uint32)ls.toInteger(2); uint32 y = (uint32)ls.toInteger(2);
uint32 w, h; uint32 w, h;
CViewRenderer &viewRender = *CViewRenderer::getInstance(); CViewRenderer &viewRender = *CViewRenderer::getInstance();
viewRender.getScreenSize(w, h); viewRender.getScreenSize(w, h);
@ -1308,11 +1346,11 @@ int CLuaIHMRyzom::getShapeIdAt(CLuaState &ls)
float cursX = (float)x/(float)w; float cursX = (float)x/(float)w;
float cursY = (float)y/(float)h; float cursY = (float)y/(float)h;
sint32 instance_idx; sint32 instance_idx;
EntitiesMngr.getShapeInstanceUnderPos(cursX, cursY, instance_idx); EntitiesMngr.getShapeInstanceUnderPos(cursX, cursY, instance_idx);
ls.push(instance_idx); ls.push(instance_idx);
return 1; return 1;
} }
@ -1339,7 +1377,7 @@ int CLuaIHMRyzom::getGroundAtMouse(CLuaState &ls)
worldViewRay.Up = camMatrix.getK().normed(); worldViewRay.Up = camMatrix.getK().normed();
CVector sceneInter; CVector sceneInter;
CTool::TRayIntersectionType rayInterType = CTool::computeLandscapeRayIntersection(worldViewRay, sceneInter); CTool::TRayIntersectionType rayInterType = CTool::computeLandscapeRayIntersection(worldViewRay, sceneInter);
ls.push(sceneInter.x); ls.push(sceneInter.x);
ls.push(sceneInter.y); ls.push(sceneInter.y);
ls.push(sceneInter.z); ls.push(sceneInter.z);
@ -1367,7 +1405,7 @@ int CLuaIHMRyzom::moveCam(CLuaState &ls)
float z = (float)ls.toNumber(3); float z = (float)ls.toNumber(3);
CVector moves(x, y, z); CVector moves(x, y, z);
UserEntity->setCameraMoves(moves); UserEntity->setCameraMoves(moves);
return 0; return 0;
} }
@ -1541,7 +1579,7 @@ int CLuaIHMRyzom::moveToTarget(CLuaState &ls)
const std::string &url = ls.toString(1); const std::string &url = ls.toString(1);
CEntityCL *target = getTargetEntity(); CEntityCL *target = getTargetEntity();
if (!target) return 0; if (!target) return 0;
CLuaManager::getInstance().executeLuaScript("ArkTargetUrl = [["+url+"]]", 0); CLuaManager::getInstance().executeLuaScript("ArkTargetUrl = [["+url+"]]", 0);
UserEntity->moveTo(UserEntity->selection(), 1.0, CUserEntity::OpenArkUrl); UserEntity->moveTo(UserEntity->selection(), 1.0, CUserEntity::OpenArkUrl);
return 0; return 0;
@ -2103,6 +2141,31 @@ int CLuaIHMRyzom::updateAllLocalisedElements(CLuaState &ls)
return 0; return 0;
} }
// ***************************************************************************
int CLuaIHMRyzom::getTimestampHuman(CLuaState &ls)
{
//H_AUTO(Lua_CLuaIHM_getIslandId)
const char *funcName = "getTimestampHuman";
CLuaIHM::checkArgCount(ls, funcName, 1);
CLuaIHM::check(ls, ls.isString(1), "getTimestampHuman() requires a string in param 1");
static char cstime[25];
time_t date;
time (&date);
struct tm *tms = localtime(&date);
string param = ls.toString(1);
if (tms)
strftime(cstime, 25, param.c_str(), tms);
else
strcpy(cstime, "");
ls.push(string(cstime));
return 1;
}
// *************************************************************************** // ***************************************************************************
int CLuaIHMRyzom::getCompleteIslands(CLuaState &ls) int CLuaIHMRyzom::getCompleteIslands(CLuaState &ls)
{ {
@ -2180,7 +2243,7 @@ int CLuaIHMRyzom::addShape(CLuaState &ls)
CLuaIHM::checkArgType(ls, funcName, 1, LUA_TSTRING); CLuaIHM::checkArgType(ls, funcName, 1, LUA_TSTRING);
sint32 idx = -1; sint32 idx = -1;
if (!Scene) if (!Scene)
{ {
nlwarning("No scene available"); nlwarning("No scene available");
@ -2189,7 +2252,7 @@ int CLuaIHMRyzom::addShape(CLuaState &ls)
} }
string shape = ls.toString(1); string shape = ls.toString(1);
float x = 0.0f, y = 0.0f, z = 0.0f; float x = 0.0f, y = 0.0f, z = 0.0f;
float scale = 1.0f; float scale = 1.0f;
string context, url, skeleton, texture; string context, url, skeleton, texture;
@ -2197,7 +2260,7 @@ int CLuaIHMRyzom::addShape(CLuaState &ls)
bool transparency = false; bool transparency = false;
bool collision = true; bool collision = true;
bool inIgZone = false; bool inIgZone = false;
if (ls.getTop() >= 2) if (ls.getTop() >= 2)
{ {
CLuaIHM::checkArgType(ls, funcName, 2, LUA_TNUMBER); CLuaIHM::checkArgType(ls, funcName, 2, LUA_TNUMBER);
@ -2223,14 +2286,14 @@ int CLuaIHMRyzom::addShape(CLuaState &ls)
y = UserEntity->pos().y; y = UserEntity->pos().y;
z = UserEntity->pos().z; z = UserEntity->pos().z;
} }
CVector userDir = UserEntity->dir(); CVector userDir = UserEntity->dir();
if (ls.getTop() >= 5) if (ls.getTop() >= 5)
{ {
CLuaIHM::checkArgType(ls, funcName, 5, LUA_TSTRING); CLuaIHM::checkArgType(ls, funcName, 5, LUA_TSTRING);
string angle = ls.toString(5); string angle = ls.toString(5);
if (angle != "user") if (angle != "user")
{ {
float a; float a;
@ -2238,7 +2301,7 @@ int CLuaIHMRyzom::addShape(CLuaState &ls)
userDir = CVector(sin(a), cos(a), 0.f); userDir = CVector(sin(a), cos(a), 0.f);
} }
} }
if (ls.getTop() >= 6) if (ls.getTop() >= 6)
{ {
CLuaIHM::checkArgType(ls, funcName, 6, LUA_TNUMBER); CLuaIHM::checkArgType(ls, funcName, 6, LUA_TNUMBER);
@ -2250,19 +2313,19 @@ int CLuaIHMRyzom::addShape(CLuaState &ls)
CLuaIHM::checkArgType(ls, funcName, 7, LUA_TBOOLEAN); CLuaIHM::checkArgType(ls, funcName, 7, LUA_TBOOLEAN);
collision = ls.toBoolean(7); collision = ls.toBoolean(7);
} }
if (ls.getTop() >= 8) if (ls.getTop() >= 8)
{ {
CLuaIHM::checkArgType(ls, funcName, 8, LUA_TSTRING); CLuaIHM::checkArgType(ls, funcName, 8, LUA_TSTRING);
context = ls.toString(8); context = ls.toString(8);
} }
if (ls.getTop() >= 9) if (ls.getTop() >= 9)
{ {
CLuaIHM::checkArgType(ls, funcName, 9, LUA_TSTRING); CLuaIHM::checkArgType(ls, funcName, 9, LUA_TSTRING);
url = ls.toString(9); url = ls.toString(9);
} }
if (ls.getTop() >= 10) if (ls.getTop() >= 10)
{ {
CLuaIHM::checkArgType(ls, funcName, 10, LUA_TBOOLEAN); CLuaIHM::checkArgType(ls, funcName, 10, LUA_TBOOLEAN);
@ -2274,37 +2337,52 @@ int CLuaIHMRyzom::addShape(CLuaState &ls)
CLuaIHM::checkArgType(ls, funcName, 11, LUA_TBOOLEAN); CLuaIHM::checkArgType(ls, funcName, 11, LUA_TBOOLEAN);
transparency = ls.toBoolean(11); transparency = ls.toBoolean(11);
} }
if (ls.getTop() >= 12) if (ls.getTop() >= 12)
{ {
CLuaIHM::checkArgType(ls, funcName, 12, LUA_TSTRING); CLuaIHM::checkArgType(ls, funcName, 12, LUA_TSTRING);
texture = ls.toString(12); texture = ls.toString(12);
} }
if (ls.getTop() >= 13) if (ls.getTop() >= 13)
{ {
CLuaIHM::checkArgType(ls, funcName, 13, LUA_TSTRING); CLuaIHM::checkArgType(ls, funcName, 13, LUA_TSTRING);
skeleton = ls.toString(13); skeleton = ls.toString(13);
} }
if (ls.getTop() >= 14) if (ls.getTop() >= 14)
{ {
CLuaIHM::checkArgType(ls, funcName, 14, LUA_TBOOLEAN); CLuaIHM::checkArgType(ls, funcName, 14, LUA_TBOOLEAN);
inIgZone = ls.toBoolean(14); inIgZone = ls.toBoolean(14);
} }
CShapeInstanceReference instref = EntitiesMngr.createInstance(shape, CVector(x, y, z), context, url, collision, inIgZone, idx); CShapeInstanceReference instref = EntitiesMngr.createInstance(shape, CVector(x, y, z), context, url, collision, inIgZone, idx);
UInstance instance = instref.Instance; UInstance instance = instref.Instance;
if(!instance.empty()) if(!instance.empty())
{ {
if (texture == "#season#" || texture.empty())
{
uint8 selectedTextureSet = (uint8)::computeCurrSeason();
instance.selectTextureSet(selectedTextureSet);
texture = "";
}
else if (texture[0] == '#')
{
uint8 selectedTextureSet;
fromString(texture.substr(1), selectedTextureSet);
instance.selectTextureSet(selectedTextureSet);
texture = "";
}
for(uint j=0;j<instance.getNumMaterials();j++) for(uint j=0;j<instance.getNumMaterials();j++)
{ {
if (!highlight) if (!highlight)
{ {
instance.getMaterial(j).setAmbient(CRGBA(0,0,0,255)); /*instance.getMaterial(j).setAmbient(CRGBA(0,0,0,255));
instance.getMaterial(j).setEmissive(CRGBA(255,255,255,255)); instance.getMaterial(j).setEmissive(CRGBA(255,255,255,255));
instance.getMaterial(j).setShininess(10.0f); instance.getMaterial(j).setShininess(10.0f);*/
} }
else else
{ {
@ -2358,9 +2436,9 @@ int CLuaIHMRyzom::addShape(CLuaState &ls)
instance.setPos(CVector(x, y, z)); instance.setPos(CVector(x, y, z));
instance.setRotQuat(dir.getRot()); instance.setRotQuat(dir.getRot());
} }
instance.setTransformMode(UTransformable::RotEuler); instance.setTransformMode(UTransformable::RotEuler);
// if the shape is a particle system, additionnal parameters are user params // if the shape is a particle system, additionnal parameters are user params
UParticleSystemInstance psi; UParticleSystemInstance psi;
psi.cast (instance); psi.cast (instance);
@ -2383,7 +2461,7 @@ int CLuaIHMRyzom::addShape(CLuaState &ls)
} }
} }
}*/ }*/
UMovePrimitive *primitive = instref.Primitive; UMovePrimitive *primitive = instref.Primitive;
if (primitive) if (primitive)
{ {
@ -2393,7 +2471,7 @@ int CLuaIHMRyzom::addShape(CLuaState &ls)
primitive->setReactionType(UMovePrimitive::Slide); primitive->setReactionType(UMovePrimitive::Slide);
primitive->setTriggerType(UMovePrimitive::NotATrigger); primitive->setTriggerType(UMovePrimitive::NotATrigger);
primitive->setAbsorbtion(0); primitive->setAbsorbtion(0);
primitive->setPrimitiveType(UMovePrimitive::_2DOrientedBox); primitive->setPrimitiveType(UMovePrimitive::_2DOrientedBox);
primitive->setSize((bbox.getMax().x - bbox.getMin().x)*scale, (bbox.getMax().y - bbox.getMin().y)*scale); primitive->setSize((bbox.getMax().x - bbox.getMin().x)*scale, (bbox.getMax().y - bbox.getMin().y)*scale);
primitive->setHeight((bbox.getMax().z - bbox.getMin().z)*scale); primitive->setHeight((bbox.getMax().z - bbox.getMin().z)*scale);
@ -2401,10 +2479,10 @@ int CLuaIHMRyzom::addShape(CLuaState &ls)
primitive->setCollisionMask(MaskColPlayer | MaskColNpc | MaskColDoor); primitive->setCollisionMask(MaskColPlayer | MaskColNpc | MaskColDoor);
primitive->setOcclusionMask(MaskColPlayer | MaskColNpc | MaskColDoor); primitive->setOcclusionMask(MaskColPlayer | MaskColNpc | MaskColDoor);
primitive->setObstacle(true); primitive->setObstacle(true);
primitive->setGlobalPosition(instance.getPos(), dynamicWI); primitive->setGlobalPosition(instance.getPos(), dynamicWI);
primitive->insertInWorldImage(dynamicWI); primitive->insertInWorldImage(dynamicWI);
} }
} }
@ -2419,9 +2497,9 @@ int CLuaIHMRyzom::setupShape(CLuaState &ls)
CLuaIHM::checkArgCount(ls, funcName, 2); CLuaIHM::checkArgCount(ls, funcName, 2);
CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
CLuaIHM::checkArgType(ls, funcName, 2, LUA_TTABLE); CLuaIHM::checkArgType(ls, funcName, 2, LUA_TTABLE);
uint32 idx = (uint32)ls.toInteger(1); uint32 idx = (uint32)ls.toInteger(1);
std::vector<string> keys; std::vector<string> keys;
std::vector<string> values; std::vector<string> values;
CLuaObject params; CLuaObject params;
@ -2444,12 +2522,12 @@ int CLuaIHMRyzom::setupShape(CLuaState &ls)
values.push_back(it.nextValue().toString()); values.push_back(it.nextValue().toString());
keys.push_back(it.nextKey().toString()); keys.push_back(it.nextKey().toString());
} }
if (EntitiesMngr.setupInstance(idx, keys, values)) if (EntitiesMngr.setupInstance(idx, keys, values))
ls.push(1); ls.push(1);
else else
ls.pushNil(); ls.pushNil();
return 1; return 1;
} }
@ -2461,15 +2539,15 @@ int CLuaIHMRyzom::moveShape(CLuaState &ls)
CLuaIHM::checkArgType(ls, funcName, 2, LUA_TSTRING); CLuaIHM::checkArgType(ls, funcName, 2, LUA_TSTRING);
CLuaIHM::checkArgType(ls, funcName, 3, LUA_TSTRING); CLuaIHM::checkArgType(ls, funcName, 3, LUA_TSTRING);
CLuaIHM::checkArgType(ls, funcName, 4, LUA_TSTRING); CLuaIHM::checkArgType(ls, funcName, 4, LUA_TSTRING);
uint32 idx = (uint32)ls.toInteger(1); uint32 idx = (uint32)ls.toInteger(1);
CVector pos = EntitiesMngr.getInstancePos(idx); CVector pos = EntitiesMngr.getInstancePos(idx);
string x = ls.toString(2); string x = ls.toString(2);
string y = ls.toString(3); string y = ls.toString(3);
string z = ls.toString(4); string z = ls.toString(4);
float move_x = 0; float move_x = 0;
float move_y = 0; float move_y = 0;
float move_z = 0; float move_z = 0;
@ -2487,7 +2565,7 @@ int CLuaIHMRyzom::moveShape(CLuaState &ls)
pos.x = move_x; pos.x = move_x;
} }
} }
if (!y.empty()) if (!y.empty())
{ {
if (y[0] == '+') if (y[0] == '+')
@ -2501,7 +2579,7 @@ int CLuaIHMRyzom::moveShape(CLuaState &ls)
pos.y = move_y; pos.y = move_y;
} }
} }
if (!z.empty()) if (!z.empty())
{ {
if (z[0] == '+') if (z[0] == '+')
@ -2515,12 +2593,12 @@ int CLuaIHMRyzom::moveShape(CLuaState &ls)
pos.z = move_z; pos.z = move_z;
} }
} }
if (EntitiesMngr.setInstancePos(idx, pos)) if (EntitiesMngr.setInstancePos(idx, pos))
ls.push(1); ls.push(1);
else else
ls.pushNil(); ls.pushNil();
return 1; return 1;
} }
@ -2532,9 +2610,9 @@ int CLuaIHMRyzom::rotateShape(CLuaState &ls)
CLuaIHM::checkArgType(ls, funcName, 2, LUA_TSTRING); CLuaIHM::checkArgType(ls, funcName, 2, LUA_TSTRING);
CLuaIHM::checkArgType(ls, funcName, 3, LUA_TSTRING); CLuaIHM::checkArgType(ls, funcName, 3, LUA_TSTRING);
CLuaIHM::checkArgType(ls, funcName, 4, LUA_TSTRING); CLuaIHM::checkArgType(ls, funcName, 4, LUA_TSTRING);
uint32 idx = (uint32)ls.toInteger(1); uint32 idx = (uint32)ls.toInteger(1);
CVector rot = EntitiesMngr.getInstanceRot(idx); CVector rot = EntitiesMngr.getInstanceRot(idx);
string x = ls.toString(2); string x = ls.toString(2);
@ -2558,7 +2636,7 @@ int CLuaIHMRyzom::rotateShape(CLuaState &ls)
rot.x = rot_x; rot.x = rot_x;
} }
} }
if (!y.empty()) if (!y.empty())
{ {
if (y[0] == '+') if (y[0] == '+')
@ -2572,7 +2650,7 @@ int CLuaIHMRyzom::rotateShape(CLuaState &ls)
rot.y = rot_y; rot.y = rot_y;
} }
} }
if (!z.empty()) if (!z.empty())
{ {
if (z[0] == '+') if (z[0] == '+')
@ -2586,12 +2664,12 @@ int CLuaIHMRyzom::rotateShape(CLuaState &ls)
rot.z = rot_z; rot.z = rot_z;
} }
} }
if (EntitiesMngr.setInstanceRot(idx, rot)) if (EntitiesMngr.setInstanceRot(idx, rot))
ls.push(1); ls.push(1);
else else
ls.pushNil(); ls.pushNil();
return 1; return 1;
} }
@ -2600,7 +2678,7 @@ int CLuaIHMRyzom::deleteShape(CLuaState &ls)
const char* funcName = "deleteShape"; const char* funcName = "deleteShape";
CLuaIHM::checkArgCount(ls, funcName, 1); CLuaIHM::checkArgCount(ls, funcName, 1);
CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
if (EntitiesMngr.deleteInstance((uint32)ls.toInteger(1))) if (EntitiesMngr.deleteInstance((uint32)ls.toInteger(1)))
ls.push(1); ls.push(1);
else else
@ -2614,9 +2692,9 @@ int CLuaIHMRyzom::getShapePos(CLuaState &ls)
const char* funcName = "getShapePos"; const char* funcName = "getShapePos";
CLuaIHM::checkArgCount(ls, funcName, 1); CLuaIHM::checkArgCount(ls, funcName, 1);
CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
uint32 idx = (uint32)ls.toInteger(1); uint32 idx = (uint32)ls.toInteger(1);
CVector pos = EntitiesMngr.getInstancePos(idx); CVector pos = EntitiesMngr.getInstancePos(idx);
ls.push(pos.x); ls.push(pos.x);
@ -2630,9 +2708,9 @@ int CLuaIHMRyzom::getShapeRot(CLuaState &ls)
const char* funcName = "getShapeRot"; const char* funcName = "getShapeRot";
CLuaIHM::checkArgCount(ls, funcName, 1); CLuaIHM::checkArgCount(ls, funcName, 1);
CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
uint32 idx = (uint32)ls.toInteger(1); uint32 idx = (uint32)ls.toInteger(1);
CVector rot = EntitiesMngr.getInstanceRot(idx); CVector rot = EntitiesMngr.getInstanceRot(idx);
ls.push(rot.x); ls.push(rot.x);
@ -2646,11 +2724,11 @@ int CLuaIHMRyzom::getShapeScale(CLuaState &ls)
const char* funcName = "getShapeScale"; const char* funcName = "getShapeScale";
CLuaIHM::checkArgCount(ls, funcName, 1); CLuaIHM::checkArgCount(ls, funcName, 1);
CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
uint32 idx = (uint32)ls.toInteger(1); uint32 idx = (uint32)ls.toInteger(1);
CVector scale = EntitiesMngr.getInstanceScale(idx); CVector scale = EntitiesMngr.getInstanceScale(idx);
ls.push(scale.x); ls.push(scale.x);
ls.push(scale.y); ls.push(scale.y);
ls.push(scale.z); ls.push(scale.z);
@ -2662,11 +2740,11 @@ int CLuaIHMRyzom::getShapeColPos(CLuaState &ls)
const char* funcName = "getShapeColPos"; const char* funcName = "getShapeColPos";
CLuaIHM::checkArgCount(ls, funcName, 1); CLuaIHM::checkArgCount(ls, funcName, 1);
CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
uint32 idx = (uint32)ls.toInteger(1); uint32 idx = (uint32)ls.toInteger(1);
CVector pos = EntitiesMngr.getInstanceColPos(idx); CVector pos = EntitiesMngr.getInstanceColPos(idx);
ls.push(pos.x); ls.push(pos.x);
ls.push(pos.y); ls.push(pos.y);
ls.push(pos.z); ls.push(pos.z);
@ -2678,11 +2756,11 @@ int CLuaIHMRyzom::getShapeColScale(CLuaState &ls)
const char* funcName = "getShapeColScale"; const char* funcName = "getShapeColScale";
CLuaIHM::checkArgCount(ls, funcName, 1); CLuaIHM::checkArgCount(ls, funcName, 1);
CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
uint32 idx = (uint32)ls.toInteger(1); uint32 idx = (uint32)ls.toInteger(1);
CVector scale = EntitiesMngr.getInstanceColScale(idx); CVector scale = EntitiesMngr.getInstanceColScale(idx);
ls.push(scale.x); ls.push(scale.x);
ls.push(scale.y); ls.push(scale.y);
ls.push(scale.z); ls.push(scale.z);
@ -2694,11 +2772,11 @@ int CLuaIHMRyzom::getShapeColOrient(CLuaState &ls)
const char* funcName = "getShapeColOrient"; const char* funcName = "getShapeColOrient";
CLuaIHM::checkArgCount(ls, funcName, 1); CLuaIHM::checkArgCount(ls, funcName, 1);
CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER);
uint32 idx = (uint32)ls.toInteger(1); uint32 idx = (uint32)ls.toInteger(1);
double orient = EntitiesMngr.getInstanceColOrient(idx); double orient = EntitiesMngr.getInstanceColOrient(idx);
ls.push(orient); ls.push(orient);
return 1; return 1;
} }
@ -3454,6 +3532,38 @@ std::string CLuaIHMRyzom::getSheetType(const std::string &sheet)
return CEntitySheet::typeToString(sheetPtr->Type); return CEntitySheet::typeToString(sheetPtr->Type);
} }
// ***************************************************************************
std::string CLuaIHMRyzom::getSheetShape(const std::string &sheet)
{
//H_AUTO(Lua_CLuaIHM_getSheetType)
const CEntitySheet *sheetPtr = SheetMngr.get(CSheetId(sheet));
if (!sheetPtr)
return "";
if (sheetPtr->type() == CEntitySheet::ITEM)
{
CItemSheet *sheet = (CItemSheet*)sheetPtr;
return sheet->getShape();
}
else if (sheetPtr->type() == CEntitySheet::FAUNA)
{
CCharacterSheet *sheet = (CCharacterSheet*)(sheetPtr);
return sheet->Body.getItem();
}
return "";
}
// ***************************************************************************
float CLuaIHMRyzom::getCharacterSheetScale(const std::string &sheet)
{
const CEntitySheet *sheetPtr = SheetMngr.get(CSheetId(sheet));
const CCharacterSheet *charSheet = dynamic_cast<const CCharacterSheet*>(sheetPtr);
if (charSheet) return charSheet->Scale;
return 1;
}
// *************************************************************************** // ***************************************************************************
std::string CLuaIHMRyzom::getSheetFamily(const std::string &sheet) std::string CLuaIHMRyzom::getSheetFamily(const std::string &sheet)
@ -3466,7 +3576,7 @@ std::string CLuaIHMRyzom::getSheetFamily(const std::string &sheet)
if (pIS) if (pIS)
return ITEMFAMILY::toString(pIS->Family); return ITEMFAMILY::toString(pIS->Family);
} }
return ""; return "";
} }
@ -3697,7 +3807,7 @@ float CLuaIHMRyzom::setChar3dDBfromVPX(const std::string &branch, const std::str
cs.People = EGSPD::CPeople::fromString(people); cs.People = EGSPD::CPeople::fromString(people);
SCharacter3DSetup::setupDBFromCharacterSummary(branch, cs); SCharacter3DSetup::setupDBFromCharacterSummary(branch, cs);
return cs.VisualPropC.PropertySubData.CharacterHeight; return cs.VisualPropC.PropertySubData.CharacterHeight;
} }
@ -3803,7 +3913,9 @@ void CLuaIHMRyzom::updateTooltipCoords()
CWidgetManager::getInstance()->updateTooltipCoords(); CWidgetManager::getInstance()->updateTooltipCoords();
} }
// *************************************************************************** // ***************************************************************************
// WARNING PROBABLY DON'T WORKS
bool CLuaIHMRyzom::isCtrlKeyDown() bool CLuaIHMRyzom::isCtrlKeyDown()
{ {
//H_AUTO(Lua_CLuaIHM_isCtrlKeyDown) //H_AUTO(Lua_CLuaIHM_isCtrlKeyDown)
@ -3816,6 +3928,7 @@ bool CLuaIHMRyzom::isCtrlKeyDown()
return ctrlDown; return ctrlDown;
} }
// *************************************************************************** // ***************************************************************************
std::string CLuaIHMRyzom::encodeURLUnicodeParam(const ucstring &text) std::string CLuaIHMRyzom::encodeURLUnicodeParam(const ucstring &text)
{ {
@ -3865,41 +3978,41 @@ sint32 CLuaIHMRyzom::getPlayerLevel()
std::string CLuaIHMRyzom::getPlayerVpaHex() std::string CLuaIHMRyzom::getPlayerVpaHex()
{ {
sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPA))->getValue64(); sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPA))->getValue64();
return NLMISC::toString("%X", prop); return NLMISC::toString("%" NL_I64 "X", prop);
} }
// *************************************************************************** // ***************************************************************************
std::string CLuaIHMRyzom::getPlayerVpbHex() std::string CLuaIHMRyzom::getPlayerVpbHex()
{ {
sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64(); sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64();
return NLMISC::toString("%X", prop); return NLMISC::toString("%" NL_I64 "X", prop);
} }
// *************************************************************************** // ***************************************************************************
std::string CLuaIHMRyzom::getPlayerVpcHex() std::string CLuaIHMRyzom::getPlayerVpcHex()
{ {
sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64(); sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPC))->getValue64();
return NLMISC::toString("%X", prop); return NLMISC::toString("%" NL_I64 "X", prop);
} }
// *************************************************************************** // ***************************************************************************
sint64 CLuaIHMRyzom::getPlayerVpa() uint64 CLuaIHMRyzom::getPlayerVpa()
{ {
sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPA))->getValue64(); uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPA))->getValue64();
return prop; return prop;
} }
// *************************************************************************** // ***************************************************************************
sint64 CLuaIHMRyzom::getPlayerVpb() uint64 CLuaIHMRyzom::getPlayerVpb()
{ {
sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64(); uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64();
return prop; return prop;
} }
// *************************************************************************** // ***************************************************************************
sint64 CLuaIHMRyzom::getPlayerVpc() uint64 CLuaIHMRyzom::getPlayerVpc()
{ {
sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64(); uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPC))->getValue64();
return prop; return prop;
} }
@ -3950,7 +4063,7 @@ std::string CLuaIHMRyzom::getTargetVpaHex()
if (!target) return 0; if (!target) return 0;
sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPA))->getValue64(); sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPA))->getValue64();
return NLMISC::toString("%X", prop); return NLMISC::toString("%" NL_I64 "X", prop);
} }
// *************************************************************************** // ***************************************************************************
@ -3960,7 +4073,7 @@ std::string CLuaIHMRyzom::getTargetVpbHex()
if (!target) return 0; if (!target) return 0;
sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64(); sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64();
return NLMISC::toString("%X", prop); return NLMISC::toString("%" NL_I64 "X", prop);
} }
// *************************************************************************** // ***************************************************************************
@ -3969,40 +4082,37 @@ std::string CLuaIHMRyzom::getTargetVpcHex()
CEntityCL *target = getTargetEntity(); CEntityCL *target = getTargetEntity();
if (!target) return 0; if (!target) return 0;
sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64(); sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPC))->getValue64();
return NLMISC::toString("%X", prop); return NLMISC::toString("%" NL_I64 "X", prop);
} }
// *************************************************************************** // ***************************************************************************
sint64 CLuaIHMRyzom::getTargetVpa() uint64 CLuaIHMRyzom::getTargetVpa()
{ {
CEntityCL *target = getTargetEntity(); CEntityCL *target = getTargetEntity();
if (!target) return 0; if (!target) return 0;
sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPA))->getValue64(); uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPA))->getValue64();
return prop; return prop;
} }
// *************************************************************************** // ***************************************************************************
sint64 CLuaIHMRyzom::getTargetVpb() uint64 CLuaIHMRyzom::getTargetVpb()
{ {
CEntityCL *target = getTargetEntity(); CEntityCL *target = getTargetEntity();
if (!target) return 0; if (!target) return 0;
sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64(); uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64();
return prop; return prop;
} }
// *************************************************************************** // ***************************************************************************
sint64 CLuaIHMRyzom::getTargetVpc() uint64 CLuaIHMRyzom::getTargetVpc()
{ {
CEntityCL *target = getTargetEntity(); CEntityCL *target = getTargetEntity();
if (!target) return 0; if (!target) return 0;
sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64(); uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPC))->getValue64();
return prop; return prop;
} }
@ -4138,7 +4248,7 @@ int CLuaIHMRyzom::addLandMark(CLuaState &ls)
{ {
const char* funcName = "addLandMark"; const char* funcName = "addLandMark";
CLuaIHM::checkArgMin(ls, funcName, 4); CLuaIHM::checkArgMin(ls, funcName, 4);
CLuaIHM::checkArgMax(ls, funcName, 9); CLuaIHM::checkArgMax(ls, funcName, 11);
CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); // x CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); // x
CLuaIHM::checkArgType(ls, funcName, 2, LUA_TNUMBER); // y CLuaIHM::checkArgType(ls, funcName, 2, LUA_TNUMBER); // y
CLuaIHM::checkArgType(ls, funcName, 3, LUA_TSTRING); // title CLuaIHM::checkArgType(ls, funcName, 3, LUA_TSTRING); // title
@ -4147,6 +4257,9 @@ int CLuaIHMRyzom::addLandMark(CLuaState &ls)
CLuaIHM::checkArgType(ls, funcName, 6, LUA_TSTRING); // left click param CLuaIHM::checkArgType(ls, funcName, 6, LUA_TSTRING); // left click param
CLuaIHM::checkArgType(ls, funcName, 7, LUA_TSTRING); // right click action CLuaIHM::checkArgType(ls, funcName, 7, LUA_TSTRING); // right click action
CLuaIHM::checkArgType(ls, funcName, 8, LUA_TSTRING); // right click params CLuaIHM::checkArgType(ls, funcName, 8, LUA_TSTRING); // right click params
CLuaIHM::checkArgType(ls, funcName, 9, LUA_TSTRING); // over click action
CLuaIHM::checkArgType(ls, funcName, 10, LUA_TSTRING); // over click params
// 11 : Color
CArkPoint point; CArkPoint point;
point.x = (sint32)(ls.toNumber(1)*1000.f); point.x = (sint32)(ls.toNumber(1)*1000.f);
@ -4157,12 +4270,14 @@ int CLuaIHMRyzom::addLandMark(CLuaState &ls)
point.LeftClickParam = ls.toString(6); point.LeftClickParam = ls.toString(6);
point.RightClickAction = ls.toString(7); point.RightClickAction = ls.toString(7);
point.RightClickParam = ls.toString(8); point.RightClickParam = ls.toString(8);
point.OverClickAction = ls.toString(9);
point.OverClickParam = ls.toString(10);
point.Color = CRGBA(255,255,255,255); point.Color = CRGBA(255,255,255,255);
if (ls.getTop() >= 9) if (ls.getTop() >= 11)
CLuaIHM::pop(ls, point.Color); CLuaIHM::pop(ls, point.Color);
CGroupMap *pMap = dynamic_cast<CGroupMap*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:map:content:map_content:actual_map")); CGroupMap *pMap = dynamic_cast<CGroupMap*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:map:content:map_content:actual_map"));
if (pMap != NULL) if (pMap != NULL)
pMap->addArkPoint(point); pMap->addArkPoint(point);

@ -15,7 +15,7 @@ private:
static int luaClientCfgIndex(CLuaState &ls); static int luaClientCfgIndex(CLuaState &ls);
static int luaClientCfgNewIndex(CLuaState &ls); static int luaClientCfgNewIndex(CLuaState &ls);
// CInterfaceElement management on stack, stored by a CRefPtr. // CInterfaceElement management on stack, stored by a CRefPtr.
public: public:
@ -48,6 +48,9 @@ private:
static int launchContextMenuInGame(CLuaState &ls); // params : menu name static int launchContextMenuInGame(CLuaState &ls); // params : menu name
static int parseInterfaceFromString(CLuaState &ls); // params : intreface script static int parseInterfaceFromString(CLuaState &ls); // params : intreface script
static int updateAllLocalisedElements(CLuaState &ls); static int updateAllLocalisedElements(CLuaState &ls);
static int isShiftDown(CLuaState &ls);
static int isCtrlDown(CLuaState &ls);
static int getTimestampHuman(CLuaState &ls);
static int breakPoint(CLuaState &ls); static int breakPoint(CLuaState &ls);
static int i18n(CLuaState &ls); // retrieve an unicode string from CI18N static int i18n(CLuaState &ls); // retrieve an unicode string from CI18N
static int setTextFormatTaged(CLuaState &ls); // set a text that may contains Tag Format infos static int setTextFormatTaged(CLuaState &ls); // set a text that may contains Tag Format infos
@ -204,6 +207,8 @@ private:
static bool isDynStringAvailable(sint32 dynStringId); static bool isDynStringAvailable(sint32 dynStringId);
static bool isFullyPatched(); static bool isFullyPatched();
static std::string getSheetType(const std::string &sheet); static std::string getSheetType(const std::string &sheet);
static std::string getSheetShape(const std::string &sheet);
static float getCharacterSheetScale(const std::string &sheet);
static std::string getSheetFamily(const std::string &sheet); static std::string getSheetFamily(const std::string &sheet);
static std::string getSheetName(uint32 sheetId); static std::string getSheetName(uint32 sheetId);
static sint32 getFameIndex(const std::string &factionName); static sint32 getFameIndex(const std::string &factionName);
@ -251,7 +256,7 @@ private:
static int addRespawnPoint(CLuaState &ls); static int addRespawnPoint(CLuaState &ls);
static int delArkPoints(CLuaState &ls); static int delArkPoints(CLuaState &ls);
static int setArkPowoOptions(CLuaState &ls); static int setArkPowoOptions(CLuaState &ls);
// open the window to do a tell to 'player', if 'msg' is not empty, then the message will be sent immediatly // open the window to do a tell to 'player', if 'msg' is not empty, then the message will be sent immediatly
// else, current command of the chat window will be replaced with tell 'player' // else, current command of the chat window will be replaced with tell 'player'
@ -260,7 +265,7 @@ private:
static void updateTooltipCoords(); static void updateTooltipCoords();
// test if the ctrl key is down (NB nico : I didn't add other key, // test if the ctrl key is down (NB nico : I didn't add other key,
// because it would be too easy to write a key recorder ...) // because it would be too easy to write a key recorder ...)
static bool isCtrlKeyDown(); static bool isCtrlKeyDown();
static std::string encodeURLUnicodeParam(const ucstring &text); static std::string encodeURLUnicodeParam(const ucstring &text);
static std::string encodeURLParam(const std::string &text); static std::string encodeURLParam(const std::string &text);
@ -271,9 +276,9 @@ private:
static std::string getPlayerVpaHex(); static std::string getPlayerVpaHex();
static std::string getPlayerVpbHex(); static std::string getPlayerVpbHex();
static std::string getPlayerVpcHex(); static std::string getPlayerVpcHex();
static sint64 getPlayerVpa(); static uint64 getPlayerVpa();
static sint64 getPlayerVpb(); static uint64 getPlayerVpb();
static sint64 getPlayerVpc(); static uint64 getPlayerVpc();
static sint32 getTargetLevel(); // get current, precise level of the selected target, or -1 if there's no such selected target static sint32 getTargetLevel(); // get current, precise level of the selected target, or -1 if there's no such selected target
static sint32 getTargetForceRegion(); // get 'force region' for current target, or -1 if there's no selected target static sint32 getTargetForceRegion(); // get 'force region' for current target, or -1 if there's no selected target
static sint32 getTargetLevelForce(); // get 'level force' for current target, or -1 if there's no selected target static sint32 getTargetLevelForce(); // get 'level force' for current target, or -1 if there's no selected target
@ -281,9 +286,9 @@ private:
static std::string getTargetVpaHex(); static std::string getTargetVpaHex();
static std::string getTargetVpbHex(); static std::string getTargetVpbHex();
static std::string getTargetVpcHex(); static std::string getTargetVpcHex();
static sint64 getTargetVpa(); static uint64 getTargetVpa();
static sint64 getTargetVpb(); static uint64 getTargetVpb();
static sint64 getTargetVpc(); static uint64 getTargetVpc();
static bool isTargetNPC(); // return 'true' if the target is an npc static bool isTargetNPC(); // return 'true' if the target is an npc
static bool isTargetPlayer(); // return 'true' if the target is a player static bool isTargetPlayer(); // return 'true' if the target is a player
static bool isTargetUser(); // return 'true' if the target is the user static bool isTargetUser(); // return 'true' if the target is the user

@ -174,28 +174,30 @@ void CMusicPlayer::playSongs (const std::vector<std::string> &filenames)
// If pause, stop, else play will resume // If pause, stop, else play will resume
if (_State == Paused || _Songs.empty()) if (_State == Paused || _Songs.empty())
_State = Stopped; stop();
// get song title/duration using worker thread // get song title/duration using worker thread
MusicPlayerWorker.getSongsInfo(filenames); MusicPlayerWorker.getSongsInfo(filenames);
} }
// *************************************************************************** // ***************************************************************************
void CMusicPlayer::updatePlaylist(sint prevIndex) void CMusicPlayer::updatePlaylist(uint index, bool state)
{ {
CInterfaceElement *pIE; if (index >= _Songs.size()) return;
std::string rowId;
std::string rowId = toString("%s:s%d:bg", MP3_PLAYER_PLAYLIST_LIST, index);
CInterfaceElement *pIE = dynamic_cast<CInterfaceElement*>(CWidgetManager::getInstance()->getElementFromId(rowId));
if (pIE) pIE->setActive(state);
}
void CMusicPlayer::updatePlaylist(sint prevIndex)
{
if (prevIndex >= 0 && prevIndex < _Songs.size()) if (prevIndex >= 0 && prevIndex < _Songs.size())
{ {
rowId = toString("%s:s%d:bg", MP3_PLAYER_PLAYLIST_LIST, prevIndex); updatePlaylist(prevIndex, false);
pIE = dynamic_cast<CInterfaceElement*>(CWidgetManager::getInstance()->getElementFromId(rowId));
if (pIE) pIE->setActive(false);
} }
rowId = toString("%s:s%d:bg", MP3_PLAYER_PLAYLIST_LIST, _CurrentSongIndex); updatePlaylist(_CurrentSongIndex, true);
pIE = dynamic_cast<CInterfaceElement*>(CWidgetManager::getInstance()->getElementFromId(rowId));
if (pIE) pIE->setActive(true);
} }
// *************************************************************************** // ***************************************************************************
@ -361,7 +363,7 @@ void CMusicPlayer::play (sint index)
if (_Songs.empty()) if (_Songs.empty())
{ {
_State = Stopped; stop();
return; return;
} }
@ -432,11 +434,15 @@ void CMusicPlayer::stop ()
return; return;
// stop the music only if we are really playing (else risk to stop a background music!) // stop the music only if we are really playing (else risk to stop a background music!)
SoundMngr->stopMusic(0); if (_State != Stopped)
SoundMngr->stopMusic(0);
_State = Stopped; _State = Stopped;
_PlayStart = 0; _PlayStart = 0;
_PauseTime = 0; _PauseTime = 0;
clearPlayingInfo();
NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:MP3_PLAYING")->setValueBool(false); NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:MP3_PLAYING")->setValueBool(false);
} }
@ -472,12 +478,38 @@ void CMusicPlayer::next ()
} }
// *************************************************************************** // ***************************************************************************
void CMusicPlayer::updatePlayingInfo(const std::string info)
{
CViewText *pVT = dynamic_cast<CViewText*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:mp3_player:screen:text"));
if (pVT)
{
pVT->setText(ucstring::makeFromUtf8(info));
}
}
// ***************************************************************************
void CMusicPlayer::clearPlayingInfo()
{
if (_Songs.empty())
{
updatePlayingInfo(CI18N::get("uiNoFiles").toUtf8());
}
else
{
updatePlayingInfo("");
}
}
// ***************************************************************************
void CMusicPlayer::update () void CMusicPlayer::update ()
{ {
if(!SoundMngr) if(!SoundMngr)
{ {
_State = Stopped; if (_State != Stopped)
{
_State = Stopped;
clearPlayingInfo();
}
return; return;
} }
@ -488,8 +520,6 @@ void CMusicPlayer::update ()
if (_State == Playing) if (_State == Playing)
{ {
CViewText *pVT = dynamic_cast<CViewText*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:mp3_player:screen:text"));
if (pVT)
{ {
TTime dur = (CTime::getLocalTime() - _PlayStart) / 1000; TTime dur = (CTime::getLocalTime() - _PlayStart) / 1000;
uint min = (dur / 60) % 60; uint min = (dur / 60) % 60;
@ -499,7 +529,7 @@ void CMusicPlayer::update ()
std::string title(toString("%02d:%02d", min, sec)); std::string title(toString("%02d:%02d", min, sec));
if (hour > 0) title = toString("%02d:", hour) + title; if (hour > 0) title = toString("%02d:", hour) + title;
title += " " + _CurrentSong.Title; title += " " + _CurrentSong.Title;
pVT->setText(ucstring::makeFromUtf8(title)); updatePlayingInfo(title);
} }
if (SoundMngr->isMusicEnded ()) if (SoundMngr->isMusicEnded ())
@ -520,8 +550,13 @@ void CMusicPlayer::update ()
} }
else else
{ {
SoundMngr->stopMusic(0); // remove active highlight from playlist
_State = Stopped; updatePlaylist(_CurrentSongIndex, false);
stop();
// restart from top on next 'play'
_CurrentSongIndex = 0;
} }
} }
} }

@ -62,6 +62,10 @@ public:
void update (); void update ();
// update currently playing song info/duration on main gui
void updatePlayingInfo(const std::string info);
void clearPlayingInfo();
bool isRepeatEnabled() const; bool isRepeatEnabled() const;
bool isShuffleEnabled() const; bool isShuffleEnabled() const;
@ -71,6 +75,8 @@ public:
void shuffleAndRebuildPlaylist(); void shuffleAndRebuildPlaylist();
// Update playlist active row // Update playlist active row
void updatePlaylist(sint prevIndex = -1); void updatePlaylist(sint prevIndex = -1);
// set/remove playlist highlight
void updatePlaylist(uint index, bool state);
// Update single song title/duration on _Songs and on playlist // Update single song title/duration on _Songs and on playlist
void updateSong(const CSongs &song); void updateSong(const CSongs &song);

@ -90,7 +90,7 @@ static const sint PARTY_CHAT_SPAWN_DELTA = 20; // to avoid that all party chat a
////////////////////////////////// //////////////////////////////////
/** Display an error msg in the system info window, and also in the last window that triggered the command (so that the user is sure to see it) /** Display an error msg in the system info window, and also in the last window that triggered the command (so that the user is sure to see it)
*/ */
static void displayVisibleSystemMsg(const ucstring &msg, const string &cat = "CHK"); static void displayVisibleSystemMsg(const ucstring &msg, const string &cat = "CHK");
@ -289,13 +289,13 @@ void CChatStdInput::registerListeningWindow(CChatWindow *cw)
//=========================================================================================================== //===========================================================================================================
CPeopleInterraction::CPeopleInterraction() : Region(NULL), CPeopleInterraction::CPeopleInterraction() : Region(NULL),
Universe(NULL), Universe(NULL),
TeamChat(NULL), TeamChat(NULL),
GuildChat(NULL), GuildChat(NULL),
SystemInfo(NULL), SystemInfo(NULL),
TellWindow(NULL), TellWindow(NULL),
DebugInfo(NULL), DebugInfo(NULL),
CurrPartyChatID(0) CurrPartyChatID(0)
{ {
for(uint i=0;i<CChatGroup::MaxDynChanPerPlayer;i++) for(uint i=0;i<CChatGroup::MaxDynChanPerPlayer;i++)
{ {
@ -311,6 +311,8 @@ void CPeopleInterraction::release()
ChatInput.Tell.removeListeningPeopleList(&TeamList); ChatInput.Tell.removeListeningPeopleList(&TeamList);
ChatInput.Team.removeListeningPeopleList(&TeamList); ChatInput.Team.removeListeningPeopleList(&TeamList);
FriendList.saveContactGroups();
CChatWindowManager &cwm = getChatWndMgr(); CChatWindowManager &cwm = getChatWndMgr();
AroundMe.release(); AroundMe.release();
@ -333,7 +335,7 @@ void CPeopleInterraction::release()
SystemInfo = NULL; SystemInfo = NULL;
TellWindow = NULL; TellWindow = NULL;
DebugInfo = NULL; DebugInfo = NULL;
// TellWindow = NULL; // TellWindow = NULL;
for(uint i=0;i<CChatGroup::MaxDynChanPerPlayer;i++) for(uint i=0;i<CChatGroup::MaxDynChanPerPlayer;i++)
{ {
@ -390,7 +392,7 @@ void CPeopleInterraction::removeAllPartyChat()
//=========================================================================================================== //===========================================================================================================
bool CPeopleInterraction::isUserChat(CChatWindow *cw) const bool CPeopleInterraction::isUserChat(CChatWindow *cw) const
{ {
// if (cw == MainChat.Window) return true; // if (cw == MainChat.Window) return true;
if (cw == ChatGroup.Window) return true; if (cw == ChatGroup.Window) return true;
for(uint k = 0; k < MaxNumUserChats; ++k) for(uint k = 0; k < MaxNumUserChats; ++k)
{ {
@ -432,8 +434,8 @@ void CPeopleInterraction::init()
void CPeopleInterraction::initAfterLoad() void CPeopleInterraction::initAfterLoad()
{ {
/* activate the USER chat per default. /* activate the USER chat per default.
Important: we must do it after ChatGroup.Window var init, DB color init etc... Important: we must do it after ChatGroup.Window var init, DB color init etc...
because the latest are used in chat_group_filter ActionHandler because the latest are used in chat_group_filter ActionHandler
*/ */
CChatGroupWindow *pCGW= PeopleInterraction.getChatGroupWindow(); CChatGroupWindow *pCGW= PeopleInterraction.getChatGroupWindow();
if(pCGW) if(pCGW)
@ -562,12 +564,12 @@ void CPeopleInterraction::createFriendList()
// //
FriendList.create(peopleListDesc); FriendList.create(peopleListDesc);
FriendList.setPeopleMenuEx("ui:interface:friend_list_menu_offline_unblocked", FriendList.setPeopleMenuEx("ui:interface:friend_list_menu_offline_unblocked",
"ui:interface:friend_list_menu_online_unblocked", "ui:interface:friend_list_menu_online_unblocked",
"ui:interface:friend_list_menu_online_abroad_unblocked", "ui:interface:friend_list_menu_online_abroad_unblocked",
"ui:interface:friend_list_menu_offline_blocked", "ui:interface:friend_list_menu_offline_blocked",
"ui:interface:friend_list_menu_online_blocked", "ui:interface:friend_list_menu_online_blocked",
"ui:interface:friend_list_menu_online_abroad_blocked" "ui:interface:friend_list_menu_online_abroad_blocked"
); );
FriendList.setMenu("ui:interface:sort_menu"); FriendList.setMenu("ui:interface:sort_menu");
} }
@ -703,21 +705,21 @@ void CPeopleInterraction::createUniverseWindow()
void CPeopleInterraction::createTellWindow() void CPeopleInterraction::createTellWindow()
{ {
/*CChatWindowDesc chatDesc; /*CChatWindowDesc chatDesc;
chatDesc.FatherContainer = "ui:interface"; chatDesc.FatherContainer = "ui:interface";
chatDesc.Title = "uiTellWindow"; chatDesc.Title = "uiTellWindow";
chatDesc.Listener = NULL; chatDesc.Listener = NULL;
chatDesc.Savable = true; chatDesc.Savable = true;
chatDesc.Localize = true; chatDesc.Localize = true;
chatDesc.Id = "tell"; chatDesc.Id = "tell";
chatDesc.ChatTemplate ="chat_no_eb_id"; chatDesc.ChatTemplate ="chat_no_eb_id";
chatDesc.AHOnActive = "set"; chatDesc.AHOnActive = "set";
chatDesc.AHOnActiveParams = "dblink=UI:SAVE:ISDETACHED:TELL|value=1"; chatDesc.AHOnActiveParams = "dblink=UI:SAVE:ISDETACHED:TELL|value=1";
chatDesc.AHOnDeactive = "set"; chatDesc.AHOnDeactive = "set";
chatDesc.AHOnDeactiveParams = "dblink=UI:SAVE:ISDETACHED:TELL|value=0"; chatDesc.AHOnDeactiveParams = "dblink=UI:SAVE:ISDETACHED:TELL|value=0";
TellWindow = getChatWndMgr().createChatWindow(chatDesc); TellWindow = getChatWndMgr().createChatWindow(chatDesc);
if (!TellWindow) return; if (!TellWindow) return;
TellWindow->setMenu("ui:interface:base_chat_box_menu"); */ TellWindow->setMenu("ui:interface:base_chat_box_menu"); */
} }
//=========================================================================================================== //===========================================================================================================
@ -826,13 +828,13 @@ class CHandlerUserChatActive : public IActionHandler
CChatGroup::TGroupType m = PeopleInterraction.TheUserChat.Filter.getTargetGroup(); CChatGroup::TGroupType m = PeopleInterraction.TheUserChat.Filter.getTargetGroup();
switch(m) switch(m)
{ {
default: default:
case CChatGroup::arround: case CChatGroup::arround:
case CChatGroup::say: pUserBut->setHardText("uiFilterAround"); break; case CChatGroup::say: pUserBut->setHardText("uiFilterAround"); break;
case CChatGroup::region: pUserBut->setHardText("uiFilterRegion"); break; case CChatGroup::region: pUserBut->setHardText("uiFilterRegion"); break;
case CChatGroup::universe: pUserBut->setHardText("uiFilterUniverse"); break; case CChatGroup::universe: pUserBut->setHardText("uiFilterUniverse"); break;
case CChatGroup::team: pUserBut->setHardText("uiFilterTeam"); break; case CChatGroup::team: pUserBut->setHardText("uiFilterTeam"); break;
case CChatGroup::guild: pUserBut->setHardText("uiFilterGuild"); break; case CChatGroup::guild: pUserBut->setHardText("uiFilterGuild"); break;
} }
pUserBut->getParent()->updateCoords(); pUserBut->getParent()->updateCoords();
pUserBut->updateCoords(); pUserBut->updateCoords();
@ -925,29 +927,29 @@ class CHandlerChatGroupFilter : public IActionHandler
CChatGroup::TGroupType m = PeopleInterraction.TheUserChat.Filter.getTargetGroup(); CChatGroup::TGroupType m = PeopleInterraction.TheUserChat.Filter.getTargetGroup();
switch(m) switch(m)
{ {
default: default:
case CChatGroup::arround: case CChatGroup::arround:
case CChatGroup::say: pUserBut->setHardText("uiFilterAround"); break; case CChatGroup::say: pUserBut->setHardText("uiFilterAround"); break;
case CChatGroup::region: pUserBut->setHardText("uiFilterRegion"); break; case CChatGroup::region: pUserBut->setHardText("uiFilterRegion"); break;
case CChatGroup::team: pUserBut->setHardText("uiFilterTeam"); break; case CChatGroup::team: pUserBut->setHardText("uiFilterTeam"); break;
case CChatGroup::guild: pUserBut->setHardText("uiFilterGuild"); break; case CChatGroup::guild: pUserBut->setHardText("uiFilterGuild"); break;
case CChatGroup::universe: pUserBut->setHardText("uiFilterUniverse"); break; case CChatGroup::universe: pUserBut->setHardText("uiFilterUniverse"); break;
case CChatGroup::dyn_chat: case CChatGroup::dyn_chat:
uint32 index = PeopleInterraction.TheUserChat.Filter.getTargetDynamicChannelDbIndex(); uint32 index = PeopleInterraction.TheUserChat.Filter.getTargetDynamicChannelDbIndex();
uint32 textId = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:DYN_CHAT:CHANNEL"+toString(index)+":NAME")->getValue32(); uint32 textId = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:DYN_CHAT:CHANNEL"+toString(index)+":NAME")->getValue32();
ucstring title; ucstring title;
STRING_MANAGER::CStringManagerClient::instance()->getDynString(textId, title); STRING_MANAGER::CStringManagerClient::instance()->getDynString(textId, title);
if (title.empty()) if (title.empty())
{ {
// Dyn channel not available yet, so set to around // Dyn channel not available yet, so set to around
PeopleInterraction.TheUserChat.Filter.setTargetGroup(CChatGroup::arround); PeopleInterraction.TheUserChat.Filter.setTargetGroup(CChatGroup::arround);
pUserBut->setHardText("uiFilterAround"); pUserBut->setHardText("uiFilterAround");
} }
else else
{ {
pUserBut->setHardText(title.toUtf8()); pUserBut->setHardText(title.toUtf8());
} }
break; break;
} }
pUserBut->setActive(true); pUserBut->setActive(true);
@ -1252,8 +1254,8 @@ void CPeopleInterraction::askRemoveContact(uint peopleIndex, CPeopleList *pl)
//================================================================================================================= //=================================================================================================================
void CPeopleInterraction::initContactLists( const std::vector<uint32> &vFriendListName, void CPeopleInterraction::initContactLists( const std::vector<uint32> &vFriendListName,
const std::vector<TCharConnectionState> &vFriendListOnline, const std::vector<TCharConnectionState> &vFriendListOnline,
const std::vector<ucstring> &vIgnoreListName ) const std::vector<ucstring> &vIgnoreListName )
{ {
// clear the current lists if any // clear the current lists if any
@ -1266,6 +1268,9 @@ void CPeopleInterraction::initContactLists( const std::vector<uint32> &vFriendLi
addContactInList(contactIdPool++, vFriendListName[i], vFriendListOnline[i], 0); addContactInList(contactIdPool++, vFriendListName[i], vFriendListOnline[i], 0);
for (uint i = 0; i < vIgnoreListName.size(); ++i) for (uint i = 0; i < vIgnoreListName.size(); ++i)
addContactInList(contactIdPool++, vIgnoreListName[i], ccs_offline, 1); addContactInList(contactIdPool++, vIgnoreListName[i], ccs_offline, 1);
FriendList.readContactGroups();
CPeopleList::TSortOrder order = (CPeopleList::TSortOrder)(NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CONTACT_LIST:SORT_ORDER")->getValue32());
FriendList.sortEx(order);
updateAllFreeTellerHeaders(); updateAllFreeTellerHeaders();
} }
@ -1278,6 +1283,8 @@ void CPeopleInterraction::addContactInList(uint32 contactId, const ucstring &nam
// remove the shard name if possible // remove the shard name if possible
ucstring name= CEntityCL::removeShardFromName(nameIn); ucstring name= CEntityCL::removeShardFromName(nameIn);
// add the contact to this list // add the contact to this list
sint index = pl.getIndexFromName(name); sint index = pl.getIndexFromName(name);
// try to create if not found // try to create if not found
@ -1477,7 +1484,7 @@ bool CPeopleInterraction::testValidPartyChatName(const ucstring &title)
index = IgnoreList.getIndexFromName(title); index = IgnoreList.getIndexFromName(title);
if (index != -1) return false; if (index != -1) return false;
// TODO_GAMEDEV server test for the name (not only local), & modify callers of this function // TODO_GAMEDEV server test for the name (not only local), & modify callers of this function
// The party chat should NOT have the name of a player // The party chat should NOT have the name of a player
// A player name is NOT valid if it is the same that a party chat name // A player name is NOT valid if it is the same that a party chat name
return true; return true;
} }
@ -1547,14 +1554,14 @@ bool CPeopleInterraction::createNewPartyChat(const ucstring &title)
{ {
// popup the container // popup the container
/* /*
newPartyChat->getContainer()->setup(); newPartyChat->getContainer()->setup();
newPartyChat->getContainer()->setOpen(true); newPartyChat->getContainer()->setOpen(true);
newPartyChat->getContainer()->popupCurrentPos(); newPartyChat->getContainer()->popupCurrentPos();
newPartyChat->getContainer()->updateCoords(); newPartyChat->getContainer()->updateCoords();
newPartyChat->getContainer()->center(); newPartyChat->getContainer()->center();
newPartyChat->getContainer()->setX(newPartyChat->getContainer()->getX() + (sint32) (rand() % PARTY_CHAT_SPAWN_DELTA)); newPartyChat->getContainer()->setX(newPartyChat->getContainer()->getX() + (sint32) (rand() % PARTY_CHAT_SPAWN_DELTA));
newPartyChat->getContainer()->setY(newPartyChat->getContainer()->getY() + (sint32) (rand() % PARTY_CHAT_SPAWN_DELTA)); newPartyChat->getContainer()->setY(newPartyChat->getContainer()->getY() + (sint32) (rand() % PARTY_CHAT_SPAWN_DELTA));
newPartyChat->getContainer()->enableBlink(2); newPartyChat->getContainer()->enableBlink(2);
*/ */
CPartyChatInfo pci; CPartyChatInfo pci;
@ -1742,15 +1749,15 @@ bool CPeopleInterraction::loadUserChatsInfos(NLMISC::IStream &f)
f.serialCheck(NELID("TAHC")); f.serialCheck(NELID("TAHC"));
if (ver>=1) if (ver>=1)
{ {
// CChatGroupWindow *pCGW = PeopleInterraction.getChatGroupWindow(); // CChatGroupWindow *pCGW = PeopleInterraction.getChatGroupWindow();
sint32 index; sint32 index;
f.serial(index); f.serial(index);
/* Yoyo: decide to always start with the default channel (user) activated /* Yoyo: decide to always start with the default channel (user) activated
because complex (at this time, the buttons are not all active, must wait guild loading, UI:SAVE loading etc...) because complex (at this time, the buttons are not all active, must wait guild loading, UI:SAVE loading etc...)
Hence this doesn't work for anything but User and Sysinfo (if it is activated....) Hence this doesn't work for anything but User and Sysinfo (if it is activated....)
NB: must still load the index for file format reason NB: must still load the index for file format reason
//if (pCGW) pCGW->setTabIndex(index); //if (pCGW) pCGW->setTabIndex(index);
*/ */
f.serial(present); f.serial(present);
if (present) if (present)
{ {
@ -2012,17 +2019,17 @@ public:
if (list == &PeopleInterraction.TeamList) // check for good list if (list == &PeopleInterraction.TeamList) // check for good list
{ {
/* /*
const string msgName = "TEAM:SET_LEADER"; const string msgName = "TEAM:SET_LEADER";
CBitMemStream out; CBitMemStream out;
if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) if(GenericMsgHeaderMngr.pushNameToStream(msgName, out))
{ {
uint8 teamMember = (uint8)(peopleIndex); uint8 teamMember = (uint8)(peopleIndex);
out.serial(teamMember); out.serial(teamMember);
NetMngr.push(out); NetMngr.push(out);
//nlinfo("impulseCallBack : %s %d sent", msgName.c_str(), teamMember); //nlinfo("impulseCallBack : %s %d sent", msgName.c_str(), teamMember);
} }
else else
nlwarning("command 'set_leader': unknown message named '%s'.", msgName.c_str()); nlwarning("command 'set_leader': unknown message named '%s'.", msgName.c_str());
*/ */
NLMISC::ICommand::execute("a setTeamLeader " + toString(peopleIndex), g_log); NLMISC::ICommand::execute("a setTeamLeader " + toString(peopleIndex), g_log);
} }
@ -2177,8 +2184,8 @@ public:
void execute (CCtrlBase *pCaller, const std::string &sParams) void execute (CCtrlBase *pCaller, const std::string &sParams)
{ {
/** This msg may have been triggered from valid button or from the edit box itself, so retrieve /** This msg may have been triggered from valid button or from the edit box itself, so retrieve
* the edit box from the enclosing group * the edit box from the enclosing group
*/ */
// Get enclosing container to know in which people list we are // Get enclosing container to know in which people list we are
if (pCaller) if (pCaller)
{ {
@ -2221,8 +2228,8 @@ public:
CInterfaceManager *pIM = CInterfaceManager::getInstance(); CInterfaceManager *pIM = CInterfaceManager::getInstance();
/** This msg may have been triggered from valid button or from the edit box itself, so retrieve /** This msg may have been triggered from valid button or from the edit box itself, so retrieve
* the edit box from the enclosing group * the edit box from the enclosing group
*/ */
// Get enclosing container to know in which people list we are // Get enclosing container to know in which people list we are
if (!LastFatherAddContactId.empty() && pCaller) if (!LastFatherAddContactId.empty() && pCaller)
{ {
@ -2292,13 +2299,13 @@ public:
} }
switch(listIndex) switch(listIndex)
{ {
case 0: case 0:
destList = &PeopleInterraction.IgnoreList; destList = &PeopleInterraction.IgnoreList;
break; break;
case 1: case 1:
destList = &PeopleInterraction.FriendList; destList = &PeopleInterraction.FriendList;
break; break;
default: nlwarning("Bad list index"); return; default: nlwarning("Bad list index"); return;
} }
PeopleInterraction.askMoveContact(peopleIndex, srcList, destList); PeopleInterraction.askMoveContact(peopleIndex, srcList, destList);
@ -2307,6 +2314,56 @@ public:
}; };
REGISTER_ACTION_HANDLER( CHandlerMoveContact, "move_contact"); REGISTER_ACTION_HANDLER( CHandlerMoveContact, "move_contact");
uint lastPeopleIndexChangeGroup;
//=================================================================================================================
class CHandlerChangeContactGroupBegin : public IActionHandler
{
public:
void execute (CCtrlBase * pCaller, const std::string &sParams)
{
// retrieve the index of the people
CPeopleList *srcList;
if (PeopleInterraction.getPeopleFromCurrentMenu(srcList, lastPeopleIndexChangeGroup))
{
string groupName= getParam(sParams, "group");
CInterfaceGroup *gc = dynamic_cast<CInterfaceGroup *>(CWidgetManager::getInstance()->getElementFromId(groupName));
if (gc)
{
CGroupEditBox *geb = dynamic_cast<CGroupEditBox *>(gc->getGroup("change_contact_group_eb:eb"));
geb->setInputString(ucstring(""));
}
CAHManager::getInstance()->runActionHandler("enter_modal", pCaller, sParams);
}
}
};
REGISTER_ACTION_HANDLER( CHandlerChangeContactGroupBegin, "change_contact_group_begin");
//=================================================================================================================
// Change the group of a contact in the list
class CHandlerChangeContactGroup : public IActionHandler
{
public:
void execute (CCtrlBase *pCaller, const std::string &/* sParams */)
{
CInterfaceManager *pIM = CInterfaceManager::getInstance();
if (pCaller)
{
// Get the modal edit box
CGroupEditBox *geb = dynamic_cast<CGroupEditBox *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:change_contact_group:change_contact_group_eb:eb"));
if (geb)
{
PeopleInterraction.FriendList.changeGroup(lastPeopleIndexChangeGroup, geb->getInputString());
geb->setInputString(ucstring(""));
CPeopleList::TSortOrder order = (CPeopleList::TSortOrder)(NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CONTACT_LIST:SORT_ORDER")->getValue32());
PeopleInterraction.FriendList.sortEx(order);
}
}
CAHManager::getInstance()->runActionHandler("leave_modal", pCaller, "");
}
};
REGISTER_ACTION_HANDLER( CHandlerChangeContactGroup, "change_contact_group");
//================================================================================================================= //=================================================================================================================
class CHandlerSortContacts : public IActionHandler class CHandlerSortContacts : public IActionHandler
@ -2372,7 +2429,7 @@ REGISTER_ACTION_HANDLER( CHandlerContactDirectChat, "contact_direct_chat");
//================================================================================================================= //=================================================================================================================
/** Menu to create a new party chat /** Menu to create a new party chat
*/ */
class CHandlerNewPartyChat : public IActionHandler class CHandlerNewPartyChat : public IActionHandler
{ {
public: public:
@ -2406,7 +2463,7 @@ REGISTER_ACTION_HANDLER( CHandlerNewPartyChat, "new_party_chat");
//================================================================================================================= //=================================================================================================================
/** The name of a party chat has been validated /** The name of a party chat has been validated
*/ */
class CHandlerValidatePartyChatName : public IActionHandler class CHandlerValidatePartyChatName : public IActionHandler
{ {
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
@ -2439,12 +2496,12 @@ REGISTER_ACTION_HANDLER(CHandlerValidatePartyChatName, "validate_party_chat_name
//================================================================================================================= //=================================================================================================================
/** Menu to create a new party chat /** Menu to create a new party chat
*/ */
//================================================================================================================= //=================================================================================================================
/** Menu to remove a currenlty created party chat /** Menu to remove a currenlty created party chat
*/ */
class CHandlerRemovePartyChat : public IActionHandler class CHandlerRemovePartyChat : public IActionHandler
{ {
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
@ -2457,7 +2514,7 @@ REGISTER_ACTION_HANDLER( CHandlerRemovePartyChat, "remove_party_chat");
//================================================================================================================= //=================================================================================================================
/** TEMP : just create an 'invite' command in the 'around me' edit box /** TEMP : just create an 'invite' command in the 'around me' edit box
*/ */
class CHandlerPartyChatInvite : public IActionHandler class CHandlerPartyChatInvite : public IActionHandler
{ {
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
@ -2483,12 +2540,12 @@ REGISTER_ACTION_HANDLER( CHandlerPartyChatInvite, "party_chat_invite" );
//================================================================================================================= //=================================================================================================================
/** Add all members of the team to the party chat /** Add all members of the team to the party chat
*/ */
class CHandlerAddAllTeamMembersToPartyChat : public IActionHandler class CHandlerAddAllTeamMembersToPartyChat : public IActionHandler
{ {
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
{ {
// CChatWindow *chat = getChatWndMgr().getChatWindowFromCaller(CWidgetManager::getInstance()->getCtrlLaunchingModal()); // CChatWindow *chat = getChatWndMgr().getChatWindowFromCaller(CWidgetManager::getInstance()->getCtrlLaunchingModal());
// TODO GAMEDEV : add all team members // TODO GAMEDEV : add all team members
} }
}; };
@ -2496,12 +2553,12 @@ REGISTER_ACTION_HANDLER( CHandlerAddAllTeamMembersToPartyChat, "add_all_team_mem
//================================================================================================================= //=================================================================================================================
/** Remove all members of the team to the party chat /** Remove all members of the team to the party chat
*/ */
class CHandlerRemoveAllTeamMembersToPartyChat : public IActionHandler class CHandlerRemoveAllTeamMembersToPartyChat : public IActionHandler
{ {
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
{ {
// CChatWindow *chat = getChatWndMgr().getChatWindowFromCaller(CWidgetManager::getInstance()->getCtrlLaunchingModal()); // CChatWindow *chat = getChatWndMgr().getChatWindowFromCaller(CWidgetManager::getInstance()->getCtrlLaunchingModal());
// TODO GAMEDEV : remove all team members // TODO GAMEDEV : remove all team members
} }
}; };
@ -2509,12 +2566,12 @@ REGISTER_ACTION_HANDLER( CHandlerRemoveAllTeamMembersToPartyChat, "remove_all_te
//================================================================================================================= //=================================================================================================================
/** Add all members of the guild to the party chat /** Add all members of the guild to the party chat
*/ */
class CHandlerAddAllGuildMembersToPartyChat : public IActionHandler class CHandlerAddAllGuildMembersToPartyChat : public IActionHandler
{ {
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
{ {
// CChatWindow *chat = getChatWndMgr().getChatWindowFromCaller(CWidgetManager::getInstance()->getCtrlLaunchingModal()); // CChatWindow *chat = getChatWndMgr().getChatWindowFromCaller(CWidgetManager::getInstance()->getCtrlLaunchingModal());
// TODO GAMEDEV : add all guild members // TODO GAMEDEV : add all guild members
} }
}; };
@ -2522,12 +2579,12 @@ REGISTER_ACTION_HANDLER( CHandlerAddAllGuildMembersToPartyChat, "add_all_guild_m
//================================================================================================================= //=================================================================================================================
/** Remove all members of the team to the party chat /** Remove all members of the team to the party chat
*/ */
class CHandlerRemoveAllGuildMembersToPartyChat : public IActionHandler class CHandlerRemoveAllGuildMembersToPartyChat : public IActionHandler
{ {
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
{ {
// CChatWindow *chat = getChatWndMgr().getChatWindowFromCaller(CWidgetManager::getInstance()->getCtrlLaunchingModal()); // CChatWindow *chat = getChatWndMgr().getChatWindowFromCaller(CWidgetManager::getInstance()->getCtrlLaunchingModal());
// TODO_GAMEDEV : remove all guild members // TODO_GAMEDEV : remove all guild members
} }
}; };
@ -2539,8 +2596,8 @@ REGISTER_ACTION_HANDLER( CHandlerRemoveAllGuildMembersToPartyChat, "remove_all_g
//================================================================================================================= //=================================================================================================================
/** Select the target on a filtered chat window /** Select the target on a filtered chat window
* This create a menu with the standard window (team, around me ...) + the party chat windows * This create a menu with the standard window (team, around me ...) + the party chat windows
*/ */
class CHandlerSelectChatTarget : public IActionHandler class CHandlerSelectChatTarget : public IActionHandler
{ {
public: public:
@ -2603,7 +2660,7 @@ public:
{ {
CInterfaceManager *pIM = CInterfaceManager::getInstance(); CInterfaceManager *pIM = CInterfaceManager::getInstance();
cw = PeopleInterraction.TheUserChat.Window; cw = PeopleInterraction.TheUserChat.Window;
// CChatStdInput &ci = PeopleInterraction.ChatInput; // CChatStdInput &ci = PeopleInterraction.ChatInput;
CGroupMenu *pMenu = dynamic_cast<CGroupMenu*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:user_chat_target_menu")); CGroupMenu *pMenu = dynamic_cast<CGroupMenu*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:user_chat_target_menu"));
CViewTextMenu *pMenuAround = dynamic_cast<CViewTextMenu*>(pMenu->getElement("ui:interface:user_chat_target_menu:around")); CViewTextMenu *pMenuAround = dynamic_cast<CViewTextMenu*>(pMenu->getElement("ui:interface:user_chat_target_menu:around"));
CViewTextMenu *pMenuRegion = dynamic_cast<CViewTextMenu*>(pMenu->getElement("ui:interface:user_chat_target_menu:region")); CViewTextMenu *pMenuRegion = dynamic_cast<CViewTextMenu*>(pMenu->getElement("ui:interface:user_chat_target_menu:region"));
@ -2659,7 +2716,7 @@ REGISTER_ACTION_HANDLER( CHandlerSelectChatTarget, "select_chat_target");
//================================================================================================================= //=================================================================================================================
/** A target has been selected for a filtered chat /** A target has been selected for a filtered chat
*/ */
class CHandlerChatTargetSelected : public IActionHandler class CHandlerChatTargetSelected : public IActionHandler
{ {
void execute (CCtrlBase * /* pCaller */, const std::string &sParams) void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
@ -2748,7 +2805,7 @@ REGISTER_ACTION_HANDLER( CHandlerChatTargetSelected, "chat_target_selected");
//================================================================================================================= //=================================================================================================================
/** If no more in team, leave team chat mode /** If no more in team, leave team chat mode
*/ */
class CHandlerLeaveTeamChat : public IActionHandler class CHandlerLeaveTeamChat : public IActionHandler
{ {
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
@ -2773,7 +2830,7 @@ REGISTER_ACTION_HANDLER( CHandlerLeaveTeamChat, "leave_team_chat");
/** Create checkbox for a menu. /** Create checkbox for a menu.
*/ */
static CInterfaceGroup *createMenuCheckBox(const std::string &onclickL, const std::string &paramsL, bool checked) static CInterfaceGroup *createMenuCheckBox(const std::string &onclickL, const std::string &paramsL, bool checked)
{ {
pair<string, string> params [2]; pair<string, string> params [2];
@ -2795,7 +2852,7 @@ static CInterfaceGroup *createMenuCheckBox(const std::string &onclickL, const st
//================================================================================================================= //=================================================================================================================
/** Display a menu to select the source on a filtered chat /** Display a menu to select the source on a filtered chat
*/ */
class CHandlerSelectChatSource : public IActionHandler class CHandlerSelectChatSource : public IActionHandler
{ {
void execute (CCtrlBase *pCaller, const std::string &/* sParams */) void execute (CCtrlBase *pCaller, const std::string &/* sParams */)
@ -2977,7 +3034,7 @@ REGISTER_ACTION_HANDLER(CHandlerSelectChatSource, "select_chat_source");
//================================================================================================================= //=================================================================================================================
/** A new source has been selected / unselected from a filtered chat /** A new source has been selected / unselected from a filtered chat
*/ */
class CHandlerChatSourceSelected : public IActionHandler class CHandlerChatSourceSelected : public IActionHandler
{ {
void execute (CCtrlBase * /* pCaller */, const std::string &sParams) void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
@ -3001,10 +3058,10 @@ class CHandlerChatSourceSelected : public IActionHandler
/*CCtrlBaseButton *button = dynamic_cast<CCtrlBaseButton *>(pCaller); /*CCtrlBaseButton *button = dynamic_cast<CCtrlBaseButton *>(pCaller);
if (button) if (button)
{ {
button->setPushed(!button->getPushed()); button->setPushed(!button->getPushed());
}*/ }*/
// GUILD // GUILD
if (nlstricmp(sParams, "guild") == 0) if (nlstricmp(sParams, "guild") == 0)
{ {
@ -3012,71 +3069,71 @@ class CHandlerChatSourceSelected : public IActionHandler
else ci.Guild.addListeningWindow(cw); else ci.Guild.addListeningWindow(cw);
} }
else else
// TEAM // TEAM
if (nlstricmp(sParams, "team") == 0) if (nlstricmp(sParams, "team") == 0)
{
if (ci.Team.isListeningWindow(cw)) ci.Team.removeListeningWindow(cw);
else ci.Team.addListeningWindow(cw);
}
else
// AROUND ME
if (nlstricmp(sParams, "am") == 0)
{
if (ci.AroundMe.isListeningWindow(cw)) ci.AroundMe.removeListeningWindow(cw);
else ci.AroundMe.addListeningWindow(cw);
}
else
// REGION
if (nlstricmp(sParams, "region") == 0)
{
if (ci.Region.isListeningWindow(cw)) ci.Region.removeListeningWindow(cw);
else ci.Region.addListeningWindow(cw);
}
else
// UNIVERSE
if (nlstricmp(sParams, "universe") == 0)
{
if (ci.Universe.isListeningWindow(cw)) ci.Universe.removeListeningWindow(cw);
else ci.Universe.addListeningWindow(cw);
}
else
// TELL
if (nlstricmp(sParams, "tell") == 0)
{
if (ci.Tell.isListeningWindow(cw)) ci.Tell.removeListeningWindow(cw);
else ci.Tell.addListeningWindow(cw);
}
else
// SYSTEM INFOS
if (nlstricmp(sParams, "si") == 0)
{
if (ci.SystemInfo.isListeningWindow(cw)) ci.SystemInfo.removeListeningWindow(cw);
else ci.SystemInfo.addListeningWindow(cw);
}
else
// PARTY CHAT
if (fromString(sParams, partyChatID))
{
std::vector<CPartyChatInfo> &partyChats = PeopleInterraction.PartyChats;
for(uint k = 0; k < partyChats.size(); ++k)
{ {
if (partyChats[k].ID == (uint) partyChatID) if (ci.Team.isListeningWindow(cw)) ci.Team.removeListeningWindow(cw);
else ci.Team.addListeningWindow(cw);
}
else
// AROUND ME
if (nlstricmp(sParams, "am") == 0)
{ {
if (partyChats[k].Filter != NULL) if (ci.AroundMe.isListeningWindow(cw)) ci.AroundMe.removeListeningWindow(cw);
else ci.AroundMe.addListeningWindow(cw);
}
else
// REGION
if (nlstricmp(sParams, "region") == 0)
{ {
if (partyChats[k].Filter->isListeningWindow(cw)) partyChats[k].Filter->removeListeningWindow(partyChats[k].Window); if (ci.Region.isListeningWindow(cw)) ci.Region.removeListeningWindow(cw);
else partyChats[k].Filter->addListeningWindow(cw); else ci.Region.addListeningWindow(cw);
} }
} else
} // UNIVERSE
} if (nlstricmp(sParams, "universe") == 0)
else if (nlstricmp(sParams.substr(0, 3), "dyn") == 0) {
{ if (ci.Universe.isListeningWindow(cw)) ci.Universe.removeListeningWindow(cw);
uint8 i = 0; else ci.Universe.addListeningWindow(cw);
fromString(sParams.substr(3), i); }
if (ci.DynamicChat[i].isListeningWindow(cw)) ci.DynamicChat[i].removeListeningWindow(cw); else
else ci.DynamicChat[i].addListeningWindow(cw); // TELL
} if (nlstricmp(sParams, "tell") == 0)
{
if (ci.Tell.isListeningWindow(cw)) ci.Tell.removeListeningWindow(cw);
else ci.Tell.addListeningWindow(cw);
}
else
// SYSTEM INFOS
if (nlstricmp(sParams, "si") == 0)
{
if (ci.SystemInfo.isListeningWindow(cw)) ci.SystemInfo.removeListeningWindow(cw);
else ci.SystemInfo.addListeningWindow(cw);
}
else
// PARTY CHAT
if (fromString(sParams, partyChatID))
{
std::vector<CPartyChatInfo> &partyChats = PeopleInterraction.PartyChats;
for(uint k = 0; k < partyChats.size(); ++k)
{
if (partyChats[k].ID == (uint) partyChatID)
{
if (partyChats[k].Filter != NULL)
{
if (partyChats[k].Filter->isListeningWindow(cw)) partyChats[k].Filter->removeListeningWindow(partyChats[k].Window);
else partyChats[k].Filter->addListeningWindow(cw);
}
}
}
}
else if (nlstricmp(sParams.substr(0, 3), "dyn") == 0)
{
uint8 i = 0;
fromString(sParams.substr(3), i);
if (ci.DynamicChat[i].isListeningWindow(cw)) ci.DynamicChat[i].removeListeningWindow(cw);
else ci.DynamicChat[i].addListeningWindow(cw);
}
} }
}; };
REGISTER_ACTION_HANDLER( CHandlerChatSourceSelected, "chat_source_selected"); REGISTER_ACTION_HANDLER( CHandlerChatSourceSelected, "chat_source_selected");
@ -3186,80 +3243,80 @@ NLMISC_COMMAND(ignore, "add or remove a player from the ignore list", "<player n
} // ignore // } // ignore //
/* /*
**** ****
Yoyo: Party chat is not ended: DON'T LET THOSE COMMANDS AVAILABLE! Yoyo: Party chat is not ended: DON'T LET THOSE COMMANDS AVAILABLE!
they made the client crash (cf createNewPartyChat)... they made the client crash (cf createNewPartyChat)...
**** ****
// create a new party chat with the given name // create a new party chat with the given name
NLMISC_COMMAND(party_chat, "Create a new party chat", "<party_chat_name>") NLMISC_COMMAND(party_chat, "Create a new party chat", "<party_chat_name>")
{ {
if (args.size() != 1) if (args.size() != 1)
{ {
displayVisibleSystemMsg(CI18N::get("uiPartyChatCmd")); displayVisibleSystemMsg(CI18N::get("uiPartyChatCmd"));
return true; return true;
} }
CPeopleInterraction &pi = PeopleInterraction; CPeopleInterraction &pi = PeopleInterraction;
ucstring title = args[0]; ucstring title = args[0];
if (!pi.testValidPartyChatName(title)) if (!pi.testValidPartyChatName(title))
{ {
displayVisibleSystemMsg(CI18N::get("uiInvalidPartyChatName")); displayVisibleSystemMsg(CI18N::get("uiInvalidPartyChatName"));
return true; return true;
} }
PeopleInterraction.createNewPartyChat(title); PeopleInterraction.createNewPartyChat(title);
return true; return true;
} }
// Remove the party chat with the given name // Remove the party chat with the given name
NLMISC_COMMAND(remove_party_chat, "Remove a party chat", "<party_chat_name>") NLMISC_COMMAND(remove_party_chat, "Remove a party chat", "<party_chat_name>")
{ {
if (args.size() != 1) if (args.size() != 1)
{ {
displayVisibleSystemMsg(CI18N::get("uiRemovePartyChatCmd")); displayVisibleSystemMsg(CI18N::get("uiRemovePartyChatCmd"));
return true; return true;
} }
ucstring title = ucstring(args[0]); ucstring title = ucstring(args[0]);
CChatWindow *chat = getChatWndMgr().getChatWindow(title); CChatWindow *chat = getChatWndMgr().getChatWindow(title);
if (!chat) if (!chat)
{ {
displayVisibleSystemMsg(title + ucstring(" : ") + CI18N::get("uiBadPartyChatName")); displayVisibleSystemMsg(title + ucstring(" : ") + CI18N::get("uiBadPartyChatName"));
return true; return true;
} }
if (!PeopleInterraction.removePartyChat(chat)) if (!PeopleInterraction.removePartyChat(chat))
{ {
displayVisibleSystemMsg(title + ucstring(" : ") + CI18N::get("uiCantRemovePartyChat")); displayVisibleSystemMsg(title + ucstring(" : ") + CI18N::get("uiCantRemovePartyChat"));
return true; return true;
} }
return true; return true;
} }
// Join a party chat whose name is known // Join a party chat whose name is known
NLMISC_COMMAND(add_to_party_chat, "Join the given party chat", "<party_chat_name>") NLMISC_COMMAND(add_to_party_chat, "Join the given party chat", "<party_chat_name>")
{ {
if (args.size() != 1) if (args.size() != 1)
{ {
displayVisibleSystemMsg(CI18N::get("uiAddPartyChatCmd")); displayVisibleSystemMsg(CI18N::get("uiAddPartyChatCmd"));
return true; return true;
} }
// TODO GAMEDEV : join the party chat // TODO GAMEDEV : join the party chat
return true; return true;
} }
// Invite someone in a party chat // Invite someone in a party chat
NLMISC_COMMAND(invite, "Invite someone to a party chat", "<people_name> <party_chat_name>") NLMISC_COMMAND(invite, "Invite someone to a party chat", "<people_name> <party_chat_name>")
{ {
if (args.size() != 2) if (args.size() != 2)
{ {
displayVisibleSystemMsg(CI18N::get("uiInviteCmd")); displayVisibleSystemMsg(CI18N::get("uiInviteCmd"));
return true; return true;
} }
// TODO GAMEDEV : Send invite message to the server // TODO GAMEDEV : Send invite message to the server
// Check that the inviter has created the chat ? // Check that the inviter has created the chat ?
// The people being invited should receive a popup to announce that he is being invited // The people being invited should receive a popup to announce that he is being invited
return true; return true;
} }
*/ */

@ -31,6 +31,7 @@
#include "chat_text_manager.h" #include "chat_text_manager.h"
#include "people_interraction.h" #include "people_interraction.h"
#include "../user_entity.h" #include "../user_entity.h"
#include "nel/misc/o_xml.h"
using namespace std; using namespace std;
using namespace NLMISC; using namespace NLMISC;
@ -49,9 +50,9 @@ extern CClientChatManager ChatMngr;
//================================================================== //==================================================================
CPeopleList::CPeopleList() : _ChatWindow(NULL), CPeopleList::CPeopleList() : _ChatWindow(NULL),
_ContactType(CPeopleListDesc::Unknown), _ContactType(CPeopleListDesc::Unknown),
_CurrPeopleID(0), _CurrPeopleID(0),
_Savable(false) _Savable(false)
{ {
// Construct // Construct
@ -191,34 +192,41 @@ sint CPeopleList::getIndexFromContainerID(const std::string &id) const
//================================================================== //==================================================================
bool CPeopleList::sortExByContactId(const CPeople& a, const CPeople& b) bool CPeopleList::sortExByContactId(const CPeople& a, const CPeople& b)
{ {
return (a.ContactId < b.ContactId); if (a.Group == b.Group)
return (a.ContactId < b.ContactId);
else
return (a.Group < b.Group);
} }
//================================================================== //==================================================================
bool CPeopleList::sortExByName(const CPeople& a, const CPeople& b) bool CPeopleList::sortExByName(const CPeople& a, const CPeople& b)
{ {
ucstring name_a = toUpper(a.getName()); if (a.Group == b.Group) {
ucstring name_b = toUpper(b.getName()); ucstring name_a = toUpper(a.getName());
ucstring name_b = toUpper(b.getName());
return (name_a < name_b); return (name_a < name_b);
}
else
return (a.Group < b.Group);
} }
//================================================================== //==================================================================
bool CPeopleList::sortExByOnline(const CPeople& a, const CPeople& b) bool CPeopleList::sortExByOnline(const CPeople& a, const CPeople& b)
{ {
ucstring name_a = toUpper(a.getName()); if (a.Group == b.Group) {
ucstring name_b = toUpper(b.getName()); ucstring name_a = toUpper(a.getName());
ucstring name_b = toUpper(b.getName());
// We want order: online/alpha, offworld/alpha, offline/alpha
if (a.Online == b.Online) // We want order: online/alpha, offworld/alpha, offline/alpha
{ if (a.Online == b.Online)
return (name_a < name_b); {
} return (name_a < name_b);
else }
{ else
// Compare online status
switch (a.Online)
{ {
// Compare online status
switch (a.Online)
{
case ccs_online: case ccs_online:
// a is > if a is online // a is > if a is online
return true; return true;
@ -232,11 +240,11 @@ bool CPeopleList::sortExByOnline(const CPeople& a, const CPeople& b)
// b is always > if a is offline // b is always > if a is offline
return false; return false;
break; break;
}
} }
} }
else
// Should not get here so just return something return (a.Group < b.Group);
return true;
} }
//================================================================== //==================================================================
@ -245,29 +253,54 @@ void CPeopleList::sortEx(TSortOrder order)
// remove all people from the father container // remove all people from the father container
if (!_BaseContainer) return; if (!_BaseContainer) return;
uint k; uint k;
for(k = 0; k < _Peoples.size(); ++k) for(k = 0; k < _Peoples.size(); ++k)
{ {
_BaseContainer->detachContainer(_Peoples[k].Container); CGroupContainer *parentContainer = _Peoples[k].Container->getProprietaryContainer();
parentContainer->detachContainer(_Peoples[k].Container);
} }
for (k = 0; k < _GroupContainers.size(); ++k)
{
if (_GroupContainers[k].second->getProprietaryContainer() != NULL)
_BaseContainer->detachContainer(_GroupContainers[k].second);
}
switch (order) switch (order)
{ {
default: default:
case sort_index: case sort_index:
std::sort(_Peoples.begin(), _Peoples.end(), CPeopleList::sortExByContactId); std::sort(_Peoples.begin(), _Peoples.end(), CPeopleList::sortExByContactId);
break; break;
case sort_name: case sort_name:
std::sort(_Peoples.begin(), _Peoples.end(), CPeopleList::sortExByName); std::sort(_Peoples.begin(), _Peoples.end(), CPeopleList::sortExByName);
break; break;
case sort_online: case sort_online:
std::sort(_Peoples.begin(), _Peoples.end(), CPeopleList::sortExByOnline); std::sort(_Peoples.begin(), _Peoples.end(), CPeopleList::sortExByOnline);
break; break;
} }
CGroupContainer *group = _BaseContainer;
uint groupIndex = 0;
for(k = 0; k < _Peoples.size(); ++k) for(k = 0; k < _Peoples.size(); ++k)
{ {
_BaseContainer->attachContainer(_Peoples[k].Container); bool newGroup = false;
if (k == 0)
{
newGroup = true;
}
while (groupIndex < _GroupContainers.size() && _GroupContainers[groupIndex].first != _Peoples[k].Group.toString())
{
newGroup = true;
++groupIndex;
}
if (newGroup && groupIndex < _GroupContainers.size() && _GroupContainers.size() > 1)
{
group = _GroupContainers[groupIndex].second;
_BaseContainer->attachContainer(group);
}
group->attachContainer(_Peoples[k].Container);
} }
} }
@ -299,34 +332,34 @@ bool CPeopleList::isPeopleChatVisible(uint index) const
return (_Peoples[index].Chat != NULL); return (_Peoples[index].Chat != NULL);
} }
/* /*
bool CPeopleList::isPeopleWindowVisible(uint index) const bool CPeopleList::isPeopleWindowVisible(uint index) const
{ {
if (index >= _Peoples.size()) if (index >= _Peoples.size())
{ {
nlwarning("Bad index"); nlwarning("Bad index");
return false; return false;
} }
if (!_Peoples[index].Container) return false; if (!_Peoples[index].Container) return false;
if (_Peoples[index].Container->isOpen()) if (_Peoples[index].Container->isOpen())
{ {
CInterfaceGroup *ig = _Peoples[index].Container; CInterfaceGroup *ig = _Peoples[index].Container;
do do
{ {
if (ig->isGroupContainer()) if (ig->isGroupContainer())
{ {
if (!static_cast<CGroupContainer *>(ig)->isOpen()) break; if (!static_cast<CGroupContainer *>(ig)->isOpen()) break;
} }
if (!ig->getActive()) break; if (!ig->getActive()) break;
ig = ig->getParent(); ig = ig->getParent();
} }
while(ig); while(ig);
return ig == NULL; // all parent windows must be open & visible return ig == NULL; // all parent windows must be open & visible
} }
else else
{ {
return false; return false;
} }
} }
*/ */
//================================================================== //==================================================================
@ -354,12 +387,12 @@ sint CPeopleList::addPeople(const ucstring &name, uint teamMateIndex /*= 0*/)
std::string templateName; std::string templateName;
switch (_ContactType) switch (_ContactType)
{ {
case CPeopleListDesc::Team: templateName = "mate_id"; break; case CPeopleListDesc::Team: templateName = "mate_id"; break;
case CPeopleListDesc::Contact: templateName = "contact_id_friend"; break; case CPeopleListDesc::Contact: templateName = "contact_id_friend"; break;
case CPeopleListDesc::Ignore: templateName = "contact_id_ignore"; break; case CPeopleListDesc::Ignore: templateName = "contact_id_ignore"; break;
default: default:
nlwarning("<CPeopleList::addPeople> Unknown contact type"); nlwarning("<CPeopleList::addPeople> Unknown contact type");
return -1; return -1;
break; break;
} }
@ -379,10 +412,10 @@ sint CPeopleList::addPeople(const ucstring &name, uint teamMateIndex /*= 0*/)
gc->setSavable(false); gc->setSavable(false);
// //
/*if (_ChatWindow) /*if (_ChatWindow)
{ {
_ChatWindow->getContainer()->attachContainer(gc); _ChatWindow->getContainer()->attachContainer(gc);
} }
else*/ else*/
{ {
_BaseContainer->attachContainer(gc); _BaseContainer->attachContainer(gc);
} }
@ -415,8 +448,9 @@ void CPeopleList::removePeople(uint index)
} }
else else
{ {
if (_BaseContainer) CGroupContainer *parentContainer = _Peoples[index].Container->getProprietaryContainer();
_BaseContainer->detachContainer(_Peoples[index].Container); if (parentContainer)
parentContainer->detachContainer(_Peoples[index].Container);
} }
CInterfaceManager *im = CInterfaceManager::getInstance(); CInterfaceManager *im = CInterfaceManager::getInstance();
CInterfaceGroup *pRoot = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId("ui:interface")); CInterfaceGroup *pRoot = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId("ui:interface"));
@ -447,6 +481,169 @@ void CPeopleList::setContactId(uint index, uint32 contactId)
_Peoples[index].ContactId = contactId; _Peoples[index].ContactId = contactId;
} }
//==================================================================
void CPeopleList::changeGroup(uint index, const ucstring &groupName)
{
if (index >= _Peoples.size())
{
nlwarning("<CPeopleList::changeGroup> bad index.");
return;
}
ucstring group = groupName;
if (group.toString() == "General")
group = ucstring("");
_Peoples[index].Group = group;
for (uint k = 0; k < _GroupContainers.size(); ++k)
{
if (_GroupContainers[k].first == group.toString())
return;
}
vector<pair<string, string> > properties;
properties.push_back(make_pair(string("posparent"), string("parent")));
properties.push_back(make_pair(string("id"), _ContainerID + "_group_" + toString(_GroupContainers.size())));
if (group.toString() == "")
properties.push_back(make_pair(string("title"), "General"));
else
properties.push_back(make_pair(string("title"), group.toString()));
CGroupContainer *gc = dynamic_cast<CGroupContainer *>(CWidgetManager::getInstance()->getParser()->createGroupInstance("people_list_group_header", "ui:interface", properties, false));
if (group.toString() == "")
gc->setUCTitle(ucstring("General"));
else
gc->setUCTitle(group.toString());
gc->setSavable(false);
CInterfaceGroup *pRoot = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId("ui:interface"));
pRoot->addGroup (gc);
_BaseContainer->attachContainer(gc);
_GroupContainers.push_back(make_pair(group.toString(), gc));
std::sort(_GroupContainers.begin(), _GroupContainers.end());
}
//==================================================================
void CPeopleList::readContactGroups()
{
_GroupContainers.clear();
// Create default group even if no groups defined
vector<pair<string, string> > properties;
properties.push_back(make_pair(string("posparent"), string("parent")));
properties.push_back(make_pair(string("id"), _ContainerID + "_group_0"));
properties.push_back(make_pair(string("title"), "General"));
CInterfaceGroup *group = CWidgetManager::getInstance()->getParser()->createGroupInstance("people_list_group_header", "ui:interface", properties, false);
CGroupContainer *gc = dynamic_cast<CGroupContainer *>(group);
gc->setUCTitle(ucstring("General"));
gc->setSavable(false);
CInterfaceGroup *pRoot = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId("ui:interface"));
pRoot->addGroup (gc);
_BaseContainer->attachContainer(gc);
_GroupContainers.push_back(make_pair("", gc));
const std::string filename = CInterfaceManager::getInstance()->getSaveFileName("contactgroups", "xml");
try
{
CIFile fd;
if (fd.open(CPath::lookup(filename)))
{
CIXml stream;
stream.init(fd);
xmlKeepBlanksDefault(0);
xmlNodePtr root = stream.getRootNode();
if (!root) return;
xmlNodePtr node = root->children;
uint nb = 0;
while (node)
{
CXMLAutoPtr propName;
propName = (char*) xmlGetProp(node, (xmlChar*)"name");
CXMLAutoPtr propGroup;
propGroup = (char*) xmlGetProp(node, (xmlChar*)"group");
if (propName && propGroup)
{
sint index = getIndexFromName(propName.str());
if (index < _Peoples.size())
{
_Peoples[index].Group = propGroup.str();
if (_GroupContainers.empty() || _GroupContainers.back().first != propGroup.str()) {
vector<pair<string, string> > properties;
properties.push_back(make_pair(string("posparent"), string("parent")));
properties.push_back(make_pair(string("id"), _ContainerID + "_group_" + toString(_GroupContainers.size())));
if (propGroup.str() == "")
properties.push_back(make_pair(string("title"), "General"));
else
properties.push_back(make_pair(string("title"), propGroup.str()));
CInterfaceGroup *group = CWidgetManager::getInstance()->getParser()->createGroupInstance("people_list_group_header", "ui:interface", properties, false);
CGroupContainer *gc = dynamic_cast<CGroupContainer *>(group);
if (propGroup.str() == "")
gc->setUCTitle(ucstring("General"));
else
gc->setUCTitle(propGroup.str());
gc->setSavable(false);
CInterfaceGroup *pRoot = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId("ui:interface"));
pRoot->addGroup (gc);
_BaseContainer->attachContainer(gc);
_GroupContainers.push_back(make_pair(propGroup.str(), gc));
}
}
}
node = node->next;
nb++;
}
fd.close();
}
std::sort(_GroupContainers.begin(), _GroupContainers.end());
}
catch (const Exception &e)
{
nlwarning("Error while parsing xml file %s : %s", filename.c_str(), e.what());
}
}
//==================================================================
void CPeopleList::saveContactGroups()
{
const std::string filename = CInterfaceManager::getInstance()->getSaveFileName("contactgroups", "xml");
try
{
COFile fd;
if (fd.open(filename, false, false, true))
{
COXml stream;
stream.init(&fd);
xmlDocPtr doc = stream.getDocument();
xmlNodePtr node = xmlNewDocNode(doc, NULL, (const xmlChar*)"contact_groups", NULL);
xmlDocSetRootElement(doc, node);
for (uint k = 0; k < _Peoples.size(); ++k)
{
xmlNodePtr newNode = xmlNewChild(node, NULL, (const xmlChar*)"contact", NULL);
xmlSetProp(newNode, (const xmlChar*)"name", (const xmlChar*)_Peoples[k].getName().toString().c_str());
xmlSetProp(newNode, (const xmlChar*)"group", (const xmlChar*)_Peoples[k].Group.toString().c_str());
}
stream.flush();
fd.close();
}
nlinfo("save %s", filename.c_str());
}
catch (const Exception &e)
{
nlwarning("Error while writing the file %s : %s", filename.c_str(), e.what());
}
}
//================================================================== //==================================================================
void CPeopleList::displayLocalPlayerTell(const ucstring &receiver, uint index, const ucstring &msg,uint numBlinks /*=0*/) void CPeopleList::displayLocalPlayerTell(const ucstring &receiver, uint index, const ucstring &msg,uint numBlinks /*=0*/)
{ {
@ -480,17 +677,21 @@ void CPeopleList::displayLocalPlayerTell(const ucstring &receiver, uint index, c
ucstring s = CI18N::get("youTellPlayer"); ucstring s = CI18N::get("youTellPlayer");
strFindReplace(s, "%name", receiver); strFindReplace(s, "%name", receiver);
strFindReplace(finalMsg, CI18N::get("youTell"), s); strFindReplace(finalMsg, CI18N::get("youTell"), s);
gl->addChild(getChatTextMngr().createMsgText(finalMsg, prop.getRGBA())); CViewBase *child = getChatTextMngr().createMsgText(finalMsg, prop.getRGBA());
CInterfaceManager::getInstance()->log(finalMsg, CChatGroup::groupTypeToString(CChatGroup::tell)); if (child)
// if the group is closed, make it blink
if (!gc->isOpen())
{
if (numBlinks) gc->enableBlink(numBlinks);
}
if (_BaseContainer && !_BaseContainer->isOpen())
{ {
_BaseContainer->enableBlink(numBlinks); gl->addChild(child);
CInterfaceManager::getInstance()->log(finalMsg, CChatGroup::groupTypeToString(CChatGroup::tell));
// if the group is closed, make it blink
if (!gc->isOpen())
{
if (numBlinks) gc->enableBlink(numBlinks);
}
if (_BaseContainer && !_BaseContainer->isOpen())
{
_BaseContainer->enableBlink(numBlinks);
}
} }
} }
@ -539,8 +740,9 @@ void CPeopleList::displayMessage(uint index, const ucstring &msg, NLMISC::CRGBA
nlwarning("<CPeopleList::displayMessage> can't get text_list."); nlwarning("<CPeopleList::displayMessage> can't get text_list.");
return; return;
} }
CViewBase *child = getChatTextMngr().createMsgText(msg, col);
gl->addChild(getChatTextMngr().createMsgText(msg, col)); if (child)
gl->addChild(child);
} }
@ -602,7 +804,12 @@ void CPeopleList::removeAllPeoples()
{ {
_BaseContainer->removeAllContainers(); _BaseContainer->removeAllContainers();
} }
for (uint k = 0; k < _GroupContainers.size(); ++k)
{
_GroupContainers[k].second->removeAllContainers();
}
NLMISC::contReset(_Peoples); NLMISC::contReset(_Peoples);
NLMISC::contReset(_GroupContainers);
} }
//================================================================== //==================================================================
@ -612,12 +819,12 @@ void CPeopleList::setPeopleMenu(const std::string &menuName)
} }
void CPeopleList::setPeopleMenuEx(const std::string &offlineUnblockedMenuName, void CPeopleList::setPeopleMenuEx(const std::string &offlineUnblockedMenuName,
const std::string &onlineUnblockedMenuName, const std::string &onlineUnblockedMenuName,
const std::string &onlineAbroadUnblockedMenuName, const std::string &onlineAbroadUnblockedMenuName,
const std::string &offlineBockedMenuName, const std::string &offlineBockedMenuName,
const std::string &onlineBlockedMenuName, const std::string &onlineBlockedMenuName,
const std::string &onlineAbroadBlockedMenuName const std::string &onlineAbroadBlockedMenuName
) )
{ {
_PeopleMenuOfflineUnblocked = offlineUnblockedMenuName; _PeopleMenuOfflineUnblocked = offlineUnblockedMenuName;
_PeopleMenuOnlineUnblocked = onlineUnblockedMenuName; _PeopleMenuOnlineUnblocked = onlineUnblockedMenuName;
@ -777,7 +984,7 @@ void CPeopleList::setOnline(uint index, TCharConnectionState online)
CCtrlBase *chatButton = hc->getCtrl("chat_button"); CCtrlBase *chatButton = hc->getCtrl("chat_button");
if (chatButton != NULL) if (chatButton != NULL)
chatButton->setActive(online != ccs_offline); chatButton->setActive(online != ccs_offline);
CCtrlBase *inviteButton = hc->getCtrl("invite_button"); CCtrlBase *inviteButton = hc->getCtrl("invite_button");
if (inviteButton != NULL) if (inviteButton != NULL)
inviteButton->setActive(online != ccs_offline); inviteButton->setActive(online != ccs_offline);

@ -110,6 +110,11 @@ public:
void setContactId(uint index, uint32 contactId); void setContactId(uint index, uint32 contactId);
sint getIndexFromContactId(uint32 contactId); sint getIndexFromContactId(uint32 contactId);
// For Friend Groups management
void changeGroup(uint index, const ucstring &groupName);
void readContactGroups();
void saveContactGroups();
/** Display a message for the given people /** Display a message for the given people
* If the window is closed, it causes it to blink (and also the parent window) * If the window is closed, it causes it to blink (and also the parent window)
*/ */
@ -151,19 +156,21 @@ public:
private: private:
struct CPeople struct CPeople
{ {
CPeople() : Container(NULL), Chat(NULL), Online(ccs_offline), Blocked(false), ContactId(0) {} CPeople() : Container(NULL), Chat(NULL), Online(ccs_offline), Blocked(false), ContactId(0), Group("") {}
NLMISC::CRefPtr<CGroupContainer> Container; // todo : replace this with a CChatWindow one day, for consistency NLMISC::CRefPtr<CGroupContainer> Container; // todo : replace this with a CChatWindow one day, for consistency
NLMISC::CRefPtr<CGroupContainer> Chat; NLMISC::CRefPtr<CGroupContainer> Chat;
uint GlobalID; uint GlobalID;
TCharConnectionState Online; TCharConnectionState Online;
bool Blocked; bool Blocked;
uint32 ContactId; uint32 ContactId;
ucstring Group;
bool operator < (const CPeople &other) const { return getName() < other.getName(); } bool operator < (const CPeople &other) const { return getName() < other.getName(); }
ucstring getName() const { return Container->getUCTitle(); } ucstring getName() const { return Container->getUCTitle(); }
}; };
typedef std::vector<CPeople> TPeopleVect; typedef std::vector<CPeople> TPeopleVect;
private: private:
CGroupContainerPtr _BaseContainer; CGroupContainerPtr _BaseContainer;
std::vector<std::pair<std::string, NLMISC::CRefPtr<CGroupContainer> > > _GroupContainers;
NLMISC::CRefPtr<CChatWindow> _ChatWindow; NLMISC::CRefPtr<CChatWindow> _ChatWindow;
TPeopleVect _Peoples; TPeopleVect _Peoples;
CPeopleListDesc::TContactType _ContactType; CPeopleListDesc::TContactType _ContactType;

@ -411,7 +411,7 @@ void CSPhraseManager::forgetPhrase(uint32 memoryLine, uint32 memorySlot)
_Memories[memoryLine].Slot[memorySlot].Id= 0; _Memories[memoryLine].Slot[memorySlot].Id= 0;
// must update DB? // must update DB?
if((sint32)memoryLine==_SelectedMemoryDB) if((sint32)memoryLine==_SelectedMemoryDB || (sint32)memoryLine==_SelectedMemoryDBalt)
{ {
// update the db // update the db
updateMemoryDBSlot(memorySlot); updateMemoryDBSlot(memorySlot);
@ -465,7 +465,7 @@ void CSPhraseManager::memorizePhrase(uint32 memoryLine, uint32 memorySlot, ui
_Memories[memoryLine].Slot[memorySlot].Id= slot; _Memories[memoryLine].Slot[memorySlot].Id= slot;
// must update DB? // must update DB?
if((sint32)memoryLine==_SelectedMemoryDB) if((sint32)memoryLine==_SelectedMemoryDB || (sint32)memoryLine==_SelectedMemoryDBalt)
{ {
// update the DB // update the DB
updateMemoryDBSlot(memorySlot); updateMemoryDBSlot(memorySlot);
@ -3276,7 +3276,7 @@ void CSPhraseManager::memorizeMacro(uint32 memoryLine, uint32 memorySlot, uint32
_Memories[memoryLine].Slot[memorySlot].Id= macroId; _Memories[memoryLine].Slot[memorySlot].Id= macroId;
// must update DB? // must update DB?
if((sint32)memoryLine==_SelectedMemoryDB) if((sint32)memoryLine==_SelectedMemoryDB || (sint32)memoryLine==_SelectedMemoryDBalt)
{ {
// update the DB // update the DB
updateMemoryDBSlot(memorySlot); updateMemoryDBSlot(memorySlot);
@ -3302,7 +3302,7 @@ void CSPhraseManager::forgetMacro(uint32 memoryLine, uint32 memorySlot)
_Memories[memoryLine].Slot[memorySlot].Id= 0; _Memories[memoryLine].Slot[memorySlot].Id= 0;
// must update DB? // must update DB?
if((sint32)memoryLine==_SelectedMemoryDB) if((sint32)memoryLine==_SelectedMemoryDB || (sint32)memoryLine==_SelectedMemoryDBalt)
{ {
// update the db // update the db
updateMemoryDBSlot(memorySlot); updateMemoryDBSlot(memorySlot);

@ -733,6 +733,12 @@ std::string CItemGroupManager::toDbPath(INVENTORIES::TInventory inventory)
return LIST_PA2_TEXT; break; return LIST_PA2_TEXT; break;
case INVENTORIES::pet_animal4: case INVENTORIES::pet_animal4:
return LIST_PA3_TEXT; break; return LIST_PA3_TEXT; break;
case INVENTORIES::pet_animal5:
return LIST_PA4_TEXT; break;
case INVENTORIES::pet_animal6:
return LIST_PA5_TEXT; break;
case INVENTORIES::pet_animal7:
return LIST_PA6_TEXT; break;
case INVENTORIES::player_room: case INVENTORIES::player_room:
return LIST_ROOM_TEXT;break; return LIST_ROOM_TEXT;break;
case INVENTORIES::guild: case INVENTORIES::guild:

@ -161,8 +161,12 @@ CLoginStateMachine LoginSM;
bool CStartupHttpClient::connectToLogin() bool CStartupHttpClient::connectToLogin()
{ {
return connect(ClientCfg.ConfigFile.getVar("StartupHost").asString(0)) bool checkConnect = connect(ClientCfg.ConfigFile.getVar("StartupHost").asString(0));
&& verifyServer(ClientCfg.ConfigFile.getVar("StartupVerify").asBool(0));
if (ClientCfg.ConfigFile.exists("StartupVerify"))
checkConnect = checkConnect && verifyServer(ClientCfg.ConfigFile.getVar("StartupVerify").asBool(0));
return checkConnect;
} }
CStartupHttpClient HttpClient; CStartupHttpClient HttpClient;
@ -1969,7 +1973,7 @@ class CAHOpenURL : public IActionHandler
} }
// modify existing languages // modify existing languages
// old site // old site
string::size_type pos_lang = url.find("/en/"); string::size_type pos_lang = url.find("/en/");

@ -245,7 +245,7 @@ void CPatchManager::init(const std::vector<std::string>& patchURIs, const std::s
#endif #endif
// App name matches Domain on the SQL server // App name matches Domain on the SQL server
std::string appName = cf->getVarPtr("Application") std::string appName = cf->getVarPtr("Application")
? cf->getVar("Application").asString(0) ? cf->getVar("Application").asString(0)
: "default"; : "default";
@ -1280,6 +1280,19 @@ void CPatchManager::readDescFile(sint32 nVersion)
CBNPFileSet &bnpFS = const_cast<CBNPFileSet &>(DescFile.getFiles()); CBNPFileSet &bnpFS = const_cast<CBNPFileSet &>(DescFile.getFiles());
// TODO: .ref files are expected to follow platform category naming (they are in 'main' category)
std::set<std::string>::const_iterator it;
for(it = forceRemovePatchCategories.begin(); it != forceRemovePatchCategories.end(); ++it)
{
std::string name = *it;
std::string::size_type pos = name.find("_");
if (pos != std::string::npos)
{
name = name.substr(pos+1) + "_.ref";
bnpFS.removeFile(name);
}
}
for (cat = 0; cat < DescFile.getCategories().categoryCount();) for (cat = 0; cat < DescFile.getCategories().categoryCount();)
{ {
const CBNPCategory &bnpCat = DescFile.getCategories().getCategory(cat); const CBNPCategory &bnpCat = DescFile.getCategories().getCategory(cat);
@ -1354,7 +1367,7 @@ void CPatchManager::getServerFile (const std::string &name, bool bZipped, const
{ {
//nlwarning("EXCEPTION CATCH: getServerFile() failed - try to find an alternative: %i: %s",UsedServer,PatchServers[UsedServer].DisplayedServerPath.c_str()); //nlwarning("EXCEPTION CATCH: getServerFile() failed - try to find an alternative: %i: %s",UsedServer,PatchServers[UsedServer].DisplayedServerPath.c_str());
nlwarning("EXCEPTION CATCH: getServerFile() failed - try to find an alternative :"); nlwarning("EXCEPTION CATCH: getServerFile() failed - try to find an alternative : %s", (serverPath+srcName).c_str());
nlwarning("%i", UsedServer); nlwarning("%i", UsedServer);
if (UsedServer >= 0 && UsedServer < (int) PatchServers.size()) if (UsedServer >= 0 && UsedServer < (int) PatchServers.size())
{ {
@ -2676,6 +2689,7 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
string OutFilename; string OutFilename;
bool usePatchFile = true; bool usePatchFile = true;
bool haveAllreadyTryiedDownloadingOfFile = false;
// compute the total size of patch to download // compute the total size of patch to download
uint32 totalPatchSize = 0; uint32 totalPatchSize = 0;
@ -2743,6 +2757,7 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
{ {
// can not load the 7zip file, use normal patching // can not load the 7zip file, use normal patching
usePatchFile = true; usePatchFile = true;
haveAllreadyTryiedDownloadingOfFile = true;
break; break;
} }
@ -2754,6 +2769,7 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
{ {
// fallback to standard patch method // fallback to standard patch method
usePatchFile = true; usePatchFile = true;
haveAllreadyTryiedDownloadingOfFile = true;
break; break;
} }
} }
@ -2766,6 +2782,7 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
nlwarning("Failed to unpack lzma file %s", (pPM->ClientPatchPath+lzmaFile).c_str()); nlwarning("Failed to unpack lzma file %s", (pPM->ClientPatchPath+lzmaFile).c_str());
// fallback to standard patch method // fallback to standard patch method
usePatchFile = true; usePatchFile = true;
haveAllreadyTryiedDownloadingOfFile = true;
break; break;
} }
@ -2874,34 +2891,109 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
sTranslate = CI18N::get("uiApplyingDelta") + " " + CFile::getFilename(PatchName); sTranslate = CI18N::get("uiApplyingDelta") + " " + CFile::getFilename(PatchName);
pPM->setState(true, sTranslate); pPM->setState(true, sTranslate);
xDeltaPatch(PatchName, SourceNameXD, OutFilename); bool deltaPatchResult = xDeltaPatch(PatchName, SourceNameXD, OutFilename);
if (rFTP.LocalFileExists)
pPM->deleteFile(SourceName);
pPM->deleteFile(PatchName);
if (j > 0) if (!deltaPatchResult && !haveAllreadyTryiedDownloadingOfFile) // Patch failed, try to download and apply lzma
{ {
pPM->deleteFile(SourceNameXD, false, false); // File can exists if bad BNP loading breakable
} {
tmpSourceName = OutFilename; // compute the seven zip filename
PatchSizeProgress += rFTP.PatcheSizes[j]; string lzmaFile = rFTP.FileName+".lzma";
currentPatchedSize += rFTP.PatcheSizes[j];
}
if (tmpSourceName != DestinationName) // download the 7zip file
{ try
pPM->deleteFile(SourceName, false, false); // File can exists if bad BNP loading {
if (!_CommitPatch) // first, try in the file version subfolfer
{ try
// let the patch in the unpack directory {
pPM->renameFile(tmpSourceName, pPM->ClientPatchPath + rFTP.FileName + ".tmp"); progress.Scale = 1.f;
progress.Bias = 0.f;
if (!rFTP.Patches.empty())
{
pPM->getServerFile(toString("%05u/", rFTP.Patches.back())+lzmaFile, false, "", &progress);
}
// else -> file comes from a previous download (with .tmp extension, and is up to date)
// the remaining code will just rename it with good name and exit
}
catch (const NLMISC::EWriteError &)
{
// this is a local error, rethrow ...
throw;
}
catch(...)
{
// failed with version subfolder, try in the root patch directory
pPM->getServerFile(lzmaFile, false, "", &progress);
}
}
catch (const NLMISC::EWriteError &)
{
// this is a local error, rethrow ...
throw;
}
catch (...)
{
break;
}
OutFilename = pPM->ClientPatchPath + NLMISC::CFile::getFilename(rFTP.FileName);
// try to unpack the file
try
{
if (!unpackLZMA(pPM->ClientPatchPath+lzmaFile, OutFilename+".tmp"))
{
break;
}
}
catch (const NLMISC::EWriteError&)
{
throw;
}
catch (...)
{
nlwarning("Failed to unpack lzma file %s", (pPM->ClientPatchPath+lzmaFile).c_str());
break;
}
if (rFTP.LocalFileExists)
pPM->deleteFile(SourceName);
pPM->deleteFile(pPM->ClientPatchPath+lzmaFile); // delete the archive file
pPM->deleteFile(SourceName, false, false); // File can exists if bad BNP loading
if (_CommitPatch)
{
pPM->renameFile(OutFilename+".tmp", DestinationName);
}
}
} }
else else
{ {
pPM->renameFile(tmpSourceName, DestinationName); if (rFTP.LocalFileExists)
pPM->deleteFile(SourceName);
pPM->deleteFile(PatchName);
if (j > 0)
{
pPM->deleteFile(SourceNameXD, false, false); // File can exists if bad BNP loading
}
tmpSourceName = OutFilename;
PatchSizeProgress += rFTP.PatcheSizes[j];
currentPatchedSize += rFTP.PatcheSizes[j];
} }
} }
if (tmpSourceName != DestinationName)
{
pPM->deleteFile(SourceName, false, false); // File can exists if bad BNP loading
if (!_CommitPatch)
{
// let the patch in the unpack directory
pPM->renameFile(tmpSourceName, pPM->ClientPatchPath + rFTP.FileName + ".tmp");
}
else
{
pPM->renameFile(tmpSourceName, DestinationName);
}
}
} }
else else
{ {
@ -2915,7 +3007,7 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
} }
// **************************************************************************** // ****************************************************************************
void CPatchThread::xDeltaPatch(const string &patch, const string &src, const string &out) bool CPatchThread::xDeltaPatch(const string &patch, const string &src, const string &out)
{ {
// Internal xdelta // Internal xdelta
@ -2941,12 +3033,13 @@ void CPatchThread::xDeltaPatch(const string &patch, const string &src, const str
break; break;
default: default:
{ {
std::string str = toString("Error applying %s to %s giving %s", patch.c_str(), src.c_str(), out.c_str()); nlinfo("Error applying %s to %s giving %s", patch.c_str(), src.c_str(), out.c_str());
throw Exception (str); return false;
} }
break; break;
} }
} } else
return true;
// Launching xdelta // Launching xdelta

@ -269,6 +269,7 @@ public:
void setStartRyzomAtEnd(bool startAtEnd){ _StartRyzomAtEnd = startAtEnd; } void setStartRyzomAtEnd(bool startAtEnd){ _StartRyzomAtEnd = startAtEnd; }
// Forward message to installation software if needed // Forward message to installation software if needed
void fatalError(const std::string& errorId, const std::string& param1, const std::string& param2); void fatalError(const std::string& errorId, const std::string& param1, const std::string& param2);
bool bnpUnpack(const std::string &srcBigfile, const std::string &dstPath, std::vector<std::string> &vFilenames);
const std::string & getServerVersion () { return ServerVersion; } const std::string & getServerVersion () { return ServerVersion; }
private: private:
@ -320,8 +321,6 @@ private:
void getPatchFromDesc(SFileToPatch &ftpOut, const CBNPFile &fIn, bool forceCheckSumTest); void getPatchFromDesc(SFileToPatch &ftpOut, const CBNPFile &fIn, bool forceCheckSumTest);
bool bnpUnpack(const std::string &srcBigfile, const std::string &dstPath, std::vector<std::string> &vFilenames);
// stop the threads (called when knowing the thread ended) // stop the threads (called when knowing the thread ended)
void stopCheckThread(); void stopCheckThread();
void stopPatchThread(); void stopPatchThread();
@ -547,7 +546,7 @@ private:
void run(); void run();
void processFile (CPatchManager::SFileToPatch &rFTP); void processFile (CPatchManager::SFileToPatch &rFTP);
void xDeltaPatch(const std::string &patch, const std::string &src, const std::string &out); bool xDeltaPatch(const std::string &patch, const std::string &src, const std::string &out);
}; };
/** /**

@ -33,6 +33,7 @@
#include "game_share/chat_group.h" #include "game_share/chat_group.h"
#include "game_share/character_summary.h" #include "game_share/character_summary.h"
#include "game_share/sphrase_com.h" #include "game_share/sphrase_com.h"
#include "game_share/outpost.h"
#include "game_share/msg_client_server.h" #include "game_share/msg_client_server.h"
#include "game_share/ryzom_database_banks.h" #include "game_share/ryzom_database_banks.h"
#include "game_share/msg_encyclopedia.h" #include "game_share/msg_encyclopedia.h"
@ -147,6 +148,7 @@ extern bool CharNameValidArrived;
extern bool CharNameValid; extern bool CharNameValid;
bool IsInRingSession = false; bool IsInRingSession = false;
TSessionId HighestMainlandSessionId; // highest in the position stack TSessionId HighestMainlandSessionId; // highest in the position stack
ucstring lastUniversMessage;
extern const char *CDBBankNames[INVALID_CDB_BANK+1]; extern const char *CDBBankNames[INVALID_CDB_BANK+1];
@ -770,7 +772,11 @@ void CInterfaceChatDisplayer::displayChat(TDataSetIndex compressedSenderIndex, c
} }
else if (mode == CChatGroup::universe) else if (mode == CChatGroup::universe)
{ {
PeopleInterraction.ChatInput.Universe.displayMessage(finalString, col, 2, &windowVisible); if (lastUniversMessage != finalString)
{
PeopleInterraction.ChatInput.Universe.displayMessage(finalString, col, 2, &windowVisible);
lastUniversMessage = finalString;
}
} }
else if (mode == CChatGroup::dyn_chat) else if (mode == CChatGroup::dyn_chat)
{ {
@ -3200,9 +3206,11 @@ void impulseUserBars(NLMISC::CBitMemStream &impulse)
void impulseOutpostChooseSide(NLMISC::CBitMemStream &impulse) void impulseOutpostChooseSide(NLMISC::CBitMemStream &impulse)
{ {
// read message // read message
uint8 type;
bool outpostInFire; bool outpostInFire;
bool playerGuildInConflict; bool playerGuildInConflict;
bool playerGuildIsAttacker; bool playerGuildIsAttacker;
impulse.serial(type);
impulse.serial(outpostInFire); impulse.serial(outpostInFire);
impulse.serial(playerGuildInConflict); impulse.serial(playerGuildInConflict);
impulse.serial(playerGuildIsAttacker); impulse.serial(playerGuildIsAttacker);
@ -3214,7 +3222,7 @@ void impulseOutpostChooseSide(NLMISC::CBitMemStream &impulse)
impulse.serial( declTimer ); impulse.serial( declTimer );
// start // start
OutpostManager.startPvpJoinProposal(outpostInFire, playerGuildInConflict, playerGuildIsAttacker, OutpostManager.startPvpJoinProposal((OUTPOSTENUMS::TPVPType)type, outpostInFire, playerGuildInConflict, playerGuildIsAttacker,
ownerGuildNameId, attackerGuildNameId, declTimer); ownerGuildNameId, attackerGuildNameId, declTimer);
} }

@ -680,6 +680,7 @@ bool CNetworkConnection::connect(string &result)
_LatestLoginTime = ryzomGetLocalTime (); _LatestLoginTime = ryzomGetLocalTime ();
_LatestSyncTime = _LatestLoginTime; _LatestSyncTime = _LatestLoginTime;
_LatestProbeTime = _LatestLoginTime; _LatestProbeTime = _LatestLoginTime;
m_LoginAttempts = 0;
nlinfo("CNET[%p]: Client connected to shard, attempting login", this); nlinfo("CNET[%p]: Client connected to shard, attempting login", this);
return true; return true;
@ -1091,6 +1092,17 @@ bool CNetworkConnection::stateLogin()
{ {
sendSystemLogin(); sendSystemLogin();
_LatestLoginTime = _UpdateTime; _LatestLoginTime = _UpdateTime;
if (m_LoginAttempts > 24)
{
m_LoginAttempts = 0;
disconnect(); // will send disconnection message
nlwarning("CNET[%p]: Too many LOGIN attempts, connection problem", this);
return false; // exit now from loop, don't expect a new state
}
else
{
++m_LoginAttempts;
}
} }
return false; return false;
@ -2308,6 +2320,7 @@ bool CNetworkConnection::stateProbe()
else else
{ {
nlwarning("CNET[%p]: received normal in state Probe", this); nlwarning("CNET[%p]: received normal in state Probe", this);
_LatestProbeTime = _UpdateTime;
} }
} }
} }

@ -822,6 +822,7 @@ private:
void sendSystemLogin(); void sendSystemLogin();
bool stateLogin(); bool stateLogin();
NLMISC::TTime _LatestLoginTime; NLMISC::TTime _LatestLoginTime;
int m_LoginAttempts;
// //
void receiveSystemSync(NLMISC::CBitMemStream &msgin); void receiveSystemSync(NLMISC::CBitMemStream &msgin);

@ -40,7 +40,7 @@ COutpostManager::COutpostManager()
// *************************************************************************** // ***************************************************************************
void COutpostManager::startPvpJoinProposal(bool outpostInFire, bool playerGuildInConflict, bool playerGuildIsAttacker, void COutpostManager::startPvpJoinProposal(OUTPOSTENUMS::TPVPType type, bool outpostInFire, bool playerGuildInConflict, bool playerGuildIsAttacker,
uint32 ownerGuildNameId, uint32 attackerGuildNameId, uint32 declTimer) uint32 ownerGuildNameId, uint32 attackerGuildNameId, uint32 declTimer)
{ {
// reset counter that force player to be neutral (eg: 10 seconds) // reset counter that force player to be neutral (eg: 10 seconds)
@ -58,16 +58,28 @@ void COutpostManager::startPvpJoinProposal(bool outpostInFire, bool playerGuildI
node= NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:OUTPOST:PVP_PROPOSAL_DEFENDER"); node= NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:OUTPOST:PVP_PROPOSAL_DEFENDER");
if(node) node->setValue32(ownerGuildNameId); if(node) node->setValue32(ownerGuildNameId);
node= NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:OUTPOST:PVP_PROPOSAL_TICK_END"); node= NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:OUTPOST:PVP_PROPOSAL_TICK_END");
if(node) node->setValue32(_EndTickForPvpJoinProposal); if(node) node->setValue32(_EndTickForPvpJoinProposal);
// open Popup // open Popup
CCtrlBase *ctrl = dynamic_cast<CCtrlBase *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal:content:random")); CCtrlBase *ctrl = dynamic_cast<CCtrlBase *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal:content:random"));
if (ctrl) if (ctrl)
ctrl->setActive(outpostInFire); ctrl->setActive(type != OUTPOSTENUMS::GVE && outpostInFire);
ctrl = dynamic_cast<CCtrlBase *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal:content:neutral")); ctrl = dynamic_cast<CCtrlBase *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal:content:neutral"));
if (ctrl) if (ctrl)
ctrl->setActive(!outpostInFire); ctrl->setActive(type == OUTPOSTENUMS::GVE || !outpostInFire);
// GvE: only attacker guild can have the option
ctrl = dynamic_cast<CCtrlBase *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal:content:attack"));
if (ctrl && type == OUTPOSTENUMS::GVE)
ctrl->setActive(playerGuildIsAttacker);
// GvE : No defend option
ctrl = dynamic_cast<CCtrlBase *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal:content:defend"));
if (ctrl && type == OUTPOSTENUMS::GVE)
ctrl->setActive(false);
CGroupContainer *pGC = dynamic_cast<CGroupContainer*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal")); CGroupContainer *pGC = dynamic_cast<CGroupContainer*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal"));
if (pGC) if (pGC)

@ -40,7 +40,7 @@ public:
COutpostManager(); COutpostManager();
/// Called when the server ask to join for PVP in a Outpost Zone /// Called when the server ask to join for PVP in a Outpost Zone
void startPvpJoinProposal(bool outpostInFire, bool playerGuildInConflict, bool playerGuildIsAttacker, void startPvpJoinProposal(OUTPOSTENUMS::TPVPType type, bool outpostInFire, bool playerGuildInConflict, bool playerGuildIsAttacker,
uint32 ownerGuildNameId, uint32 attackerGuildNameId, uint32 declTimer); uint32 ownerGuildNameId, uint32 attackerGuildNameId, uint32 declTimer);
/// Called when the client answer to the join for PVP in a Outpost Zone /// Called when the client answer to the join for PVP in a Outpost Zone

@ -240,8 +240,8 @@ void releaseMainLoopReselect()
// alredy called from farTPMainLoop() // alredy called from farTPMainLoop()
// --R2::getEditor().autoConfigRelease(IsInRingSession); // --R2::getEditor().autoConfigRelease(IsInRingSession);
// Pause any user played music // stop any user played music
MusicPlayer.pause(); MusicPlayer.stop();
// only really needed at exit // only really needed at exit
// --STRING_MANAGER::CStringManagerClient::instance()->flushStringCache(); // --STRING_MANAGER::CStringManagerClient::instance()->flushStringCache();
@ -390,8 +390,8 @@ void releaseMainLoop(bool closeConnection)
// Release R2 editor if applicable // Release R2 editor if applicable
R2::getEditor().autoConfigRelease(IsInRingSession); R2::getEditor().autoConfigRelease(IsInRingSession);
// Pause any user played music // stop any user played music
MusicPlayer.pause(); MusicPlayer.stop();
// flush the server string cache // flush the server string cache
STRING_MANAGER::CStringManagerClient::instance()->flushStringCache(); STRING_MANAGER::CStringManagerClient::instance()->flushStringCache();

@ -390,7 +390,7 @@ restartLoop4:
else else
{ {
result = it->second; result = it->second;
if (result.size() > 9 && result.substr(0, 9) == ucstring("<missing:")) if (result.size() > 9 && result.substr(0, 9) == ucstring("<missing:"))
{ {
map<ucstring, ucstring>::iterator itds = _DynStrings.find(result.substr(9, result.size()-10)); map<ucstring, ucstring>::iterator itds = _DynStrings.find(result.substr(9, result.size()-10));
if (itds != _DynStrings.end()) if (itds != _DynStrings.end())
@ -747,6 +747,12 @@ restartLoop:
str = CEntityCL::removeTitleFromName(str); str = CEntityCL::removeTitleFromName(str);
} }
// if the string contains a special rename of creature, remove it
if (str.size() > 2 && str[0] == '<' && str[1] == '#')
{
str = toUpper(str[2])+str.substr(3);
}
// append this string // append this string
temp.append(move, src+param.ReplacementPoint); temp.append(move, src+param.ReplacementPoint);
temp += str; temp += str;
@ -1625,7 +1631,7 @@ const ucchar *CStringManagerClient::getTitleLocalizedName(const ucstring &titleI
_TitleWords.push_back(listInfos[0]); _TitleWords.push_back(listInfos[0]);
return getLocalizedName(_TitleWords.back()); return getLocalizedName(_TitleWords.back());
} }
return getLocalizedName(titleId); return getLocalizedName(titleId);
} }

@ -2674,17 +2674,6 @@ void CUserEntity::selection(const CLFECOMMON::TCLEntityId &slot) // virtual
{ {
playerGiftNeeded->setValue32(0); playerGiftNeeded->setValue32(0);
} }
//
missionOption = NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:TARGET:CONTEXT_MENU:MISSIONS_OPTIONS:%d:TITLE", (int) k), false);
if (missionOption)
{
missionOption->setValue32(0);
}
playerGiftNeeded = NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:TARGET:CONTEXT_MENU:MISSIONS_OPTIONS:%d:PLAYER_GIFT_NEEDED", (int) k), false);
if (playerGiftNeeded)
{
playerGiftNeeded->setValue32(0);
}
} }
/* TODO ULU : Add RP tags */ /* TODO ULU : Add RP tags */

@ -264,6 +264,19 @@ namespace BRICK_FAMILIES
NL_STRING_CONVERSION_TABLE_ENTRY(BCOKARM02) NL_STRING_CONVERSION_TABLE_ENTRY(BCOKARM02)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOKARR02) NL_STRING_CONVERSION_TABLE_ENTRY(BCOKARR02)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOKART02) NL_STRING_CONVERSION_TABLE_ENTRY(BCOKART02)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOMARM01)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOMARR01)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOMART01)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOMARM02)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOMARR02)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOMART02)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOGENM01)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOGENR01)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOGENT01)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOGENM02)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOGENR02)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOGENT02)
// Faber options // Faber options
NL_STRING_CONVERSION_TABLE_ENTRY(BCOA) NL_STRING_CONVERSION_TABLE_ENTRY(BCOA)
@ -558,6 +571,7 @@ namespace BRICK_FAMILIES
NL_STRING_CONVERSION_TABLE_ENTRY(BSCMC) NL_STRING_CONVERSION_TABLE_ENTRY(BSCMC)
NL_STRING_CONVERSION_TABLE_ENTRY(BSCMD) NL_STRING_CONVERSION_TABLE_ENTRY(BSCMD)
NL_STRING_CONVERSION_TABLE_ENTRY(BSGMC) NL_STRING_CONVERSION_TABLE_ENTRY(BSGMC)
NL_STRING_CONVERSION_TABLE_ENTRY(BSGMCB)
NL_STRING_CONVERSION_TABLE_ENTRY(BSXCA) NL_STRING_CONVERSION_TABLE_ENTRY(BSXCA)

@ -297,7 +297,20 @@ namespace BRICK_FAMILIES
BCOKARM02, BCOKARM02,
BCOKARR02, BCOKARR02,
BCOKART02, BCOKART02,
EndFaberMandatory = BCOKART02, BCOMARM01,
BCOMARR01,
BCOMART01,
BCOMARM02,
BCOMARR02,
BCOMART02,
BCOGENM01,
BCOGENR01,
BCOGENT01,
BCOGENM02,
BCOGENR02,
BCOGENT02,
EndFaberMandatory = BCOGENT02,
// OPTION FABER // OPTION FABER
BeginFaberOption, BeginFaberOption,
@ -675,7 +688,8 @@ namespace BRICK_FAMILIES
BSCMD, // heal Focus BSCMD, // heal Focus
EndPowerParameter = BSCMD, EndPowerParameter = BSCMD,
BSGMC, // jewels s2e0 BSGMC, // allegories
BSGMCB, // boost allegories
BeginMagicPowerCredit, BeginMagicPowerCredit,
BSXCA = BeginMagicPowerCredit, // recast time BSXCA = BeginMagicPowerCredit, // recast time

@ -323,19 +323,6 @@ namespace EFFECT_FAMILIES
{ "thorn_wall_aura.sbrick", PowerThornWall }, { "thorn_wall_aura.sbrick", PowerThornWall },
{ "water_wall_aura.sbrick", PowerWaterWall }, { "water_wall_aura.sbrick", PowerWaterWall },
{ "lightning_wall_aura.sbrick", PowerLightningWall }, { "lightning_wall_aura.sbrick", PowerLightningWall },
{ "life_aura.sbrick", PowerRootLifeAura },
{ "stamina_aura.sbrick", PowerRootStaminaAura },
{ "sap_aura.sbrick", PowerRootSapAura },
{ "umbrella_aura.sbrick", PowerRootUmbrella },
{ "melee_protection_aura.sbrick", PowerRootProtection },
{ "anti_magic_shield_aura.sbrick", PowerRootAntiMagicShield },
{ "war_cry_aura.sbrick", PowerRootWarCry },
{ "fire_wall_aura.sbrick", PowerRootFireWall },
{ "thorn_wall_aura.sbrick", PowerRootThornWall },
{ "water_wall_aura.sbrick", PowerRootWaterWall },
{ "lightning_wall_aura.sbrick", PowerRootLightningWall },
{ "chg_charac.sbrick", PowerChgCharac }, { "chg_charac.sbrick", PowerChgCharac },
{ "mod_defense.sbrick", PowerModDefenseSkill }, { "mod_defense.sbrick", PowerModDefenseSkill },
{ "mod_dodge.sbrick", PowerModDodgeSkill }, { "mod_dodge.sbrick", PowerModDodgeSkill },

@ -534,7 +534,7 @@ void CStaticFames::loadTribeThreshold( const string& filename )
// check table structure // check table structure
uint nbTribe = ws.size()-2; uint nbTribe = ws.size()-2;
nlassert(nbTribe<=_FameTableSize); nlassert(nbTribe<=_FameTableSize);
nlassert(ws.ColCount == 16); // 5 ( 4 people + neutral ) * 3 cult + 1 for tribe name nlassert(ws.ColCount == 17); // 5 ( 4 people + neutral ) * 3 cult + 1 for tribe name + marauder
_TribeCultThresholdPerCiv.resize(nbTribe); _TribeCultThresholdPerCiv.resize(nbTribe);
@ -548,7 +548,7 @@ void CStaticFames::loadTribeThreshold( const string& filename )
_TribeCultThresholdPerCiv[i-2].FameIndex = index; _TribeCultThresholdPerCiv[i-2].FameIndex = index;
for( uint c=1; c<ws.ColCount; c+=3) for( uint c=1; c<ws.ColCount-1; c+=3)
{ {
sint32 thresholdKami, thresholdKaravan, thresholdNeutral; sint32 thresholdKami, thresholdKaravan, thresholdNeutral;
fromString(ws.getData(i, c).toString(), thresholdKami); fromString(ws.getData(i, c).toString(), thresholdKami);
@ -585,6 +585,15 @@ void CStaticFames::loadTribeThreshold( const string& filename )
// This message removed by Sadge because there is no context displayed, meaning that message must be useless // This message removed by Sadge because there is no context displayed, meaning that message must be useless
// nldebug(" %s", ws.getData(i, c).toString().c_str() ); // nldebug(" %s", ws.getData(i, c).toString().c_str() );
} }
// Special case for Marauders
sint32 thresholdMarauder;
fromString(ws.getData(i, ws.ColCount-1).toString(), thresholdMarauder);
CTribeCultThreshold * tc;
tc = &_TribeCultThresholdPerCiv[i-2].Marauder;
tc->setMarauder(thresholdMarauder*6000);
} }
} }
} }
@ -624,7 +633,7 @@ sint32 CStaticFames::getStaticFameIndexed(uint factionIndex1, uint factionIndex2
if (factionIndex1 >= _FameTableSize || factionIndex2 >= _FameTableSize) if (factionIndex1 >= _FameTableSize || factionIndex2 >= _FameTableSize)
{ {
nlwarning("FAME: CStaticFames::getStaticFame invalid faction, return 0"); //nlwarning("FAME: CStaticFames::getStaticFame invalid faction, return 0");
return 0; return 0;
} }

@ -52,26 +52,30 @@ public:
Kami = 0; Kami = 0;
Karavan = 0; Karavan = 0;
Neutral = 0; Neutral = 0;
Marauder = 0;
} }
void setKami(sint32 t) { Kami = t; } void setKami(sint32 t) { Kami = t; }
void setKaravan(sint32 t) { Karavan = t; } void setKaravan(sint32 t) { Karavan = t; }
void setNeutral(sint32 t) { Neutral = t; } void setNeutral(sint32 t) { Neutral = t; }
void setMarauder(sint32 t) { Marauder = t; }
sint32 getKami() const { return Kami; } sint32 getKami() const { return Kami; }
sint32 getKaravan() const { return Karavan; } sint32 getKaravan() const { return Karavan; }
sint32 getNeutral() const { return Neutral; } sint32 getNeutral() const { return Neutral; }
sint32 getMarauder() const { return Marauder; }
private: private:
sint32 Kami; sint32 Kami;
sint32 Karavan; sint32 Karavan;
sint32 Neutral; sint32 Neutral;
sint32 Marauder;
}; };
class CTribeCultThresholdPerCiv class CTribeCultThresholdPerCiv
{ {
public: public:
bool getCultThresholdForCiv( PVP_CLAN::TPVPClan civ, sint32& kami, sint32& karavan, sint32& neutral) const bool getCultThresholdForCiv( PVP_CLAN::TPVPClan civ, sint32& kami, sint32& karavan, sint32& neutral, sint32& marauder) const
{ {
const CTribeCultThreshold * tc = 0; const CTribeCultThreshold * tc = 0;
switch( civ ) switch( civ )
@ -88,12 +92,16 @@ public:
case PVP_CLAN::Neutral: case PVP_CLAN::Neutral:
tc = &Neutral; tc = &Neutral;
break; break;
case PVP_CLAN::Marauder:
tc = &Marauder;
break;
default: default:
return false; return false;
} }
kami = tc->getKami(); kami = tc->getKami();
karavan = tc->getKaravan(); karavan = tc->getKaravan();
neutral = tc->getNeutral(); neutral = tc->getNeutral();
marauder = tc->getMarauder();
return true; return true;
} }
@ -103,6 +111,7 @@ public:
CTribeCultThreshold Tryker; CTribeCultThreshold Tryker;
CTribeCultThreshold Zorai; CTribeCultThreshold Zorai;
CTribeCultThreshold Neutral; CTribeCultThreshold Neutral;
CTribeCultThreshold Marauder;
}; };
// declare scoped constant value // declare scoped constant value

@ -136,6 +136,7 @@ namespace MAGICFX
OtherFireWall = 14, OtherFireWall = 14,
TeleportKami = 15, // No effect aura TeleportKami = 15, // No effect aura
TeleportKara = 16, // No effect aura TeleportKara = 16, // No effect aura
TeleportMarauder = 17, // No effect aura
}; };
} }

@ -32,6 +32,8 @@ namespace OUTPOSTENUMS
NL_STRING_CONVERSION_TABLE_ENTRY(PVP) NL_STRING_CONVERSION_TABLE_ENTRY(PVP)
NL_STRING_CONVERSION_TABLE_ENTRY(RVR) NL_STRING_CONVERSION_TABLE_ENTRY(RVR)
NL_STRING_CONVERSION_TABLE_ENTRY(Full) NL_STRING_CONVERSION_TABLE_ENTRY(Full)
NL_STRING_CONVERSION_TABLE_ENTRY(GVE)
NL_STRING_CONVERSION_TABLE_ENTRY(GVG)
NL_STRING_CONVERSION_TABLE_ENTRY(UnknownPVPType) NL_STRING_CONVERSION_TABLE_ENTRY(UnknownPVPType)
NL_END_STRING_CONVERSION_TABLE(TPVPType, StaticCOutpostTPVPTypeConversion, UnknownPVPType) NL_END_STRING_CONVERSION_TABLE(TPVPType, StaticCOutpostTPVPTypeConversion, UnknownPVPType)

@ -50,7 +50,9 @@ namespace OUTPOSTENUMS
PVE, // can only be attacked if the outpost is held by a tribe and if the attacking guild comes from the same continent as the outpost PVE, // can only be attacked if the outpost is held by a tribe and if the attacking guild comes from the same continent as the outpost
PVP, // can only be attacked if the attacking guild comes from the same continent as the outpost PVP, // can only be attacked if the attacking guild comes from the same continent as the outpost
RVR, // can only be attacked if the attacking guild comes from another continent as the outpost RVR, // can only be attacked if the attacking guild comes from another continent as the outpost
Full // same as RVR but cant be set by the high council Full, // same as RVR but cant be set by the high council
GVE, // Only one guild vs tribes
GVG, // Only one guild vs another guild
}; };
enum TPVPSide enum TPVPSide

@ -37,7 +37,7 @@ struct SPropVisualA
uint64 JacketColor : 3; // max: 8 current: 8 uint64 JacketColor : 3; // max: 8 current: 8
uint64 TrouserModel : 8; // max: 256 current: 104 uint64 TrouserModel : 8; // max: 256 current: 104
uint64 TrouserColor : 3; // max: 8 current: 8 uint64 TrouserColor : 3; // max: 8 current: 8
uint64 WeaponRightHand : 10; // max: 1024 current: 457 uint64 WeaponRightHand : 10; // max: 1024 current: 625
uint64 WeaponLeftHand : 8; // max: 256 current: 63 uint64 WeaponLeftHand : 8; // max: 256 current: 63
uint64 ArmModel : 8; // max: 256 current: 94 uint64 ArmModel : 8; // max: 256 current: 94
uint64 ArmColor : 3; // max: 8 current: 8 uint64 ArmColor : 3; // max: 8 current: 8

@ -191,7 +191,8 @@ struct CClientPatcherTranslations : public NLMISC::CI18N::ILoadProxy
}; };
// hardcoded URL to not depend on external files // hardcoded URL to not depend on external files
static const std::string PatchUrl = RYZOM_CLIENT_PATCH_URL; // "https://cdn.ryzom.dev/open/patch"; static const std::string DefaultPatchUrl = RYZOM_CLIENT_PATCH_URL; // "https://cdn.ryzom.dev/open/patch";
static const std::string DefaultAppName = RYZOM_CLIENT_APP_NAME; // "default"
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
@ -200,9 +201,40 @@ int main(int argc, char *argv[])
Args.setVersion(getDisplayVersion()); Args.setVersion(getDisplayVersion());
Args.setDescription("Ryzom client"); Args.setDescription("Ryzom client");
Args.addArg("p", "patch", "patch", "Name of the file to use tp xdelta the source file");
Args.addArg("s", "source", "source", "Name of source file to xdelta with patch file");
Args.addArg("d", "destination", "destination", "Name of destination operation (patch or unpack)");
Args.addArg("u", "unpack", "unpack", "Name of bnp file to unpack");
Args.addArg("", "url", "PatchUrl", "Patch server url, ie 'https://dl.ryzom.com/patch_live'");
Args.addArg("", "app", "Application", "Patch application name for version file, ie 'ryzom_live' requests ryzom_live.version from PatchUrl");
if (!Args.parse(argc, argv)) return 1; if (!Args.parse(argc, argv)) return 1;
if (Args.haveArg("p") && Args.haveArg("s") && Args.haveArg("d"))
{
string patchName = Args.getArg("p").front();
string sourceName = Args.getArg("s").front();
string destinationName = Args.getArg("d").front();
std::string errorMsg;
CXDeltaPatch::TApplyResult ar = CXDeltaPatch::apply(patchName, sourceName, destinationName, errorMsg);
nlinfo("%s", errorMsg.c_str());
return ar;
}
// initialize patch manager and set the ryzom full path, before it's used
CPatchManager *pPM = CPatchManager::getInstance();
if (Args.haveArg("u") && Args.haveArg("d"))
{
string bnpName = Args.getArg("u").front();
string destinationName = Args.getArg("d").front();
vector<string> vFilenames;
if (pPM->bnpUnpack(bnpName, destinationName, vFilenames))
return 0;
return 1;
}
// create logs in temporary directory // create logs in temporary directory
createDebug(CPath::getTemporaryDirectory().c_str(), true, true); createDebug(CPath::getTemporaryDirectory().c_str(), true, true);
@ -240,16 +272,32 @@ int main(int argc, char *argv[])
// now translations are read, we don't need it anymore // now translations are read, we don't need it anymore
delete trans; delete trans;
// create minimal client.cfg file in memory for patcher
{
CConfigFile::CVar patchUrl;
patchUrl.forceAsString(DefaultPatchUrl);
if (Args.haveLongArg("url") && !Args.getLongArg("url").empty())
patchUrl.forceAsString(Args.getLongArg("url").front());
CConfigFile::CVar appName;
appName.forceAsString(DefaultAppName);
if (Args.haveLongArg("app") && !Args.getLongArg("app").empty())
appName.forceAsString(Args.getLongArg("app").front());
ClientCfg.ConfigFile.insertVar("PatchUrl", patchUrl);
ClientCfg.ConfigFile.insertVar("Application", appName);
}
//
Args.displayVersion(); Args.displayVersion();
printf("\n"); printf("\n");
printf("Checking %s files to patch...\n", convert(CI18N::get("TheSagaOfRyzom")).c_str()); printf("Checking %s files to patch...\n", convert(CI18N::get("TheSagaOfRyzom")).c_str());
printf("Using '%s/%s.version'\n", ClientCfg.ConfigFile.getVar("PatchUrl").asString().c_str(),
// initialize patch manager and set the ryzom full path, before it's used ClientCfg.ConfigFile.getVar("Application").asString().c_str());
CPatchManager *pPM = CPatchManager::getInstance();
// use PatchUrl // use PatchUrl
vector<string> patchURLs; vector<string> patchURLs;
pPM->init(patchURLs, PatchUrl, ""); pPM->init(patchURLs, ClientCfg.ConfigFile.getVar("PatchUrl").asString(), "");
pPM->startCheckThread(true /* include background patchs */); pPM->startCheckThread(true /* include background patchs */);
ucstring state; ucstring state;

Loading…
Cancel
Save