Merge branch 'atys' into merge-into-atys

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

@ -1,27 +1,28 @@
4eddbaff0c5e5d685db96ee3e8427aa0fd96ac83 v0.8.0
00d9b6e29e95f56785fbf85abe60afd34674f402 v0.9.0
79776c337176dd5b02e1a74fe5dfb703b91747aa v0.9.1
fedf2aa443d09707beed814b0f499c6a5519cc84 v0.10.0
edaa3624a56420b02ccc64c26059801a389927ee v0.11.0
e3fe4855f22c3e75722e015dc33c091c340b3ad7 v0.11.1
9e583b717fd63be0be9fd60b99087abf1691ea49 v0.11.2
bfe5628e14a024ba7ea32e4b326ae433a07856b9 v0.11.3
9a6120735daa97c96ac5d85ca35c7f21f607bd87 v0.12.0
3e92c7104c20d6bc6c2147b4b5fc289e8621d322 v1.0.0
8eb94c3549be898fdc4a7c6d791d2477bdc11a18 v1.0.1
3e17907af67e8d66d80e6b714707bbf912607f2a ryzom/3.0.0
153e0b605c9e0c83ba05b6428c62838b49cc84b2 ryzom/3.0.1
9d41f2994d44b9aad92b83f945f114e4b6bed44a ryzom/3.0.2
4300cc14aad098b1f86ea4c55577b7fa4a4cb5d2 ryzom/3.1.0
d4060f217f4f834cc62a33f2f1ccdf3c28298066 ryzom/3.1.0-hotfix
043aaeb3d8a2a54177581b57bda87a9deaad510e ryzom/3.1.0-april_patch
4036ecf59e83960f03acebc2089eb2ff5eeaed0a ryzom/3.2.0
18403bb9485da3d9742c6f007a16d5619ebfb196 ryzom/3.2.1
822ff8f8917ad66e09e2c21c983282f6f693b9f6 ryzom/3.3.0
00dde390a394fce9da06c2f3264140282158d39f ryzom/3.3.0
dcd4c4d161ef775136e18c7e8f5072b75dede27e ryzom/3.3.1
fc4be8ebec5ca754ef4453bc6a9faef90837c674 ryzom/3.4.0
70eba02e8eab6920586dbabf74e9e8180c729980 ryzom/3.4.0-steam_fix
3941482843f9cd130cfc16634efc08d34a98ed35 ryzom/3.4.0-atysmas
ecae9feb4cceb78103e5d7236caccaf450796cdb ryzom/3.5.0
95783afa226f241062134eb62f4323295d29ac84 ryzom/3.5.0.9637
4eddbaff0c5e5d685db96ee3e8427aa0fd96ac83 ryzomcore/v0.8.0
00d9b6e29e95f56785fbf85abe60afd34674f402 ryzomcore/v0.9.0
79776c337176dd5b02e1a74fe5dfb703b91747aa ryzomcore/v0.9.1
fedf2aa443d09707beed814b0f499c6a5519cc84 ryzomcore/v0.10.0
edaa3624a56420b02ccc64c26059801a389927ee ryzomcore/v0.11.0
e3fe4855f22c3e75722e015dc33c091c340b3ad7 ryzomcore/v0.11.1
9e583b717fd63be0be9fd60b99087abf1691ea49 ryzomcore/v0.11.2
bfe5628e14a024ba7ea32e4b326ae433a07856b9 ryzomcore/v0.11.3
9a6120735daa97c96ac5d85ca35c7f21f607bd87 ryzomcore/v0.12.0
3e17907af67e8d66d80e6b714707bbf912607f2a ryzom-patch-3.0.0
153e0b605c9e0c83ba05b6428c62838b49cc84b2 ryzom-patch-3.0.1
9d41f2994d44b9aad92b83f945f114e4b6bed44a ryzom-patch-3.0.2
4300cc14aad098b1f86ea4c55577b7fa4a4cb5d2 ryzom-patch-3.1.0
d4060f217f4f834cc62a33f2f1ccdf3c28298066 ryzom-patch-3.1.0-hotfix
043aaeb3d8a2a54177581b57bda87a9deaad510e ryzom-patch-3.1.0-april_patch
4036ecf59e83960f03acebc2089eb2ff5eeaed0a ryzom-patch-3.2.0
18403bb9485da3d9742c6f007a16d5619ebfb196 ryzom-patch-3.2.1
822ff8f8917ad66e09e2c21c983282f6f693b9f6 ryzom-patch-3.3.0
00dde390a394fce9da06c2f3264140282158d39f ryzom-patch-3.3.0
dcd4c4d161ef775136e18c7e8f5072b75dede27e ryzom-patch-3.3.1
fc4be8ebec5ca754ef4453bc6a9faef90837c674 ryzom-patch-3.4.0
70eba02e8eab6920586dbabf74e9e8180c729980 ryzom-patch-3.4.0 Steam Fix
3941482843f9cd130cfc16634efc08d34a98ed35 ryzom-patch-3.4.0 Atysmas
ecae9feb4cceb78103e5d7236caccaf450796cdb ryzom-patch-3.5.0
95783afa226f241062134eb62f4323295d29ac84 ryzom-patch-3.5.0.9637
2102fb276eb69d49ed4923042215312a63c47c08 Live-746
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_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_APP_NAME "default")
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")
@ -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_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_APP_NAME "ryzom_live")
SET(RYZOM_WEBIG_MAIN_URL "https://app.ryzom.com/")
SET(RYZOM_WEBIG_TRUSTED_DOMAIN "app.ryzom.com")
@ -175,6 +177,20 @@ IF(WITH_STATIC)
IF(LIBLZMA_LIBRARIES)
SET(LIBXML2_LIBRARIES ${LIBXML2_LIBRARIES} ${LIBLZMA_LIBRARIES})
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()

@ -37,6 +37,7 @@
#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_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_TRUSTED_DOMAIN "${RYZOM_WEBIG_TRUSTED_DOMAIN}"

@ -177,6 +177,7 @@ namespace NLGUI
bool _MouseDown : 1;
bool _CallingAH : 1;
bool _Cancelable : 1; // true if the slider may be cancelled when pressed on the mouse right button
bool _Keyboard : 1;
bool _Frozen : 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 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);
REFLECT_EXPORT_START(CCtrlTextButton, CCtrlBaseButton)
@ -137,6 +147,9 @@ namespace NLGUI
REFLECT_SINT32("wmin", getWMin, setWMin)
REFLECT_SINT32("hmin", getHMin, setHMin)
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
void onRemoved();

@ -27,6 +27,7 @@
#include "nel/gui/ctrl_button.h"
#include "nel/gui/group_table.h"
#include "nel/gui/html_element.h"
#include "nel/gui/html_parser.h"
#include "nel/gui/css_style.h"
// forward declaration
@ -115,6 +116,9 @@ namespace NLGUI
// Browse error
void browseError (const char *msg);
// Error message with html content
void browseErrorHtml(const std::string &html);
bool isBrowsing();
// Update coords
@ -375,7 +379,9 @@ namespace NLGUI
// true if renderer is waiting for css files to finish downloading (link rel=stylesheet)
bool _WaitingForStylesheet;
// 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
bool _IgnoreBaseUrlTag;
@ -854,6 +860,7 @@ namespace NLGUI
CCurlWWWData *data;
std::string url;
std::string dest;
std::string tmpdest;
std::string luaScript;
std::string md5sum;
TDataType type;
@ -889,7 +896,7 @@ namespace NLGUI
std::string localBnpName(const std::string &url);
// 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)
void releaseDownloads();

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

@ -31,14 +31,23 @@ namespace NLGUI
class CHtmlParser
{
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;
// parse html string into DOM, extract <style> tags into styleString, <link stylesheet> urls into links
void getDOM(std::string htmlString, CHtmlElement &parent, std::string &styleString, std::vector<std::string> &links) const;
// parse html string into DOM, extract <style> and <link stylesheet> urls
void getDOM(std::string htmlString, CHtmlElement &parent, std::vector<std::string> &styles, std::vector<StyleLink> &links) const;
private:
// iterate over libxml html tree, build DOM, and join all <style> tags together
void parseNode(xmlNode *a_node, CHtmlElement &parent, std::string &styleString, std::vector<std::string> &links) const;
// iterate over libxml html tree, build DOM
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
void parseStyle(xmlNode *a_node, std::string &styleString) const;

@ -444,9 +444,13 @@ namespace NLGUI
SGlobalTexture ()
{
FromGlobaleTexture = true;
Scale = 1.f;
}
uint32 Width, Height;
uint32 DefaultWidth, DefaultHeight;
// used by texture atlas to unscale individual texture
// getTextureSizeFromId() calls to return 1x size for GUI.
float Scale;
NL3D::UTexture *Texture;
std::string Name;
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, 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.
// (str[0] == '1' || (str[0] & 0xD2) == 0x50)
// - Kaetemi
/// 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.
/// - 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);

@ -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.
virtual IMusicChannel *createMusicChannel() { return NULL; }
/** 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 title returns the title (empty if not available)
*/

@ -1584,6 +1584,14 @@ void registerGlExtensions(CGlExtensions &ext)
{
H_AUTO_OGL(registerGlExtensions);
#ifdef NL_OS_MAC
CGLContextObj ctx = CGLGetCurrentContext();
if (ctx == NULL)
{
nlerror("No OpenGL context set");
}
#endif
// OpenGL 1.2 ??
const char *nglVersion = (const char *)glGetString (GL_VERSION);

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

@ -57,6 +57,7 @@ namespace NLGUI
_MouseDown = false;
_CallingAH = false;
_Cancelable = false;
_Keyboard = false;
_Target = NULL;
_Inverted = false;
_IsDBLink = false;
@ -225,6 +226,11 @@ namespace NLGUI
return toString( _Cancelable );
}
else
if( name == "keyboard" )
{
return toString( _Keyboard );
}
else
if( name == "frozen" )
{
return toString( _Frozen );
@ -405,6 +411,14 @@ namespace NLGUI
return;
}
else
if( name == "keyboard" )
{
bool b;
if( fromString( value, b ) )
_Keyboard = b;
return;
}
else
if( name == "frozen" )
{
bool b;
@ -474,6 +488,7 @@ namespace NLGUI
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 "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() );
return node;
@ -589,6 +604,9 @@ namespace NLGUI
prop = (char*) xmlGetProp( node, (xmlChar*)"cancelable" );
if (prop) _Cancelable = convertBool(prop);
prop = (char*) xmlGetProp( node, (xmlChar*)"keyboard" );
if (prop) _Keyboard = convertBool(prop);
prop= (char*) xmlGetProp (node, (xmlChar*)"frozen");
_Frozen = false;
if (prop)
@ -854,6 +872,7 @@ namespace NLGUI
if (CCtrlBase::handleEvent(event)) return true;
if (!_Active || _Frozen)
return false;
if (event.getType() == NLGUI::CEventDescriptor::mouse)
{
const NLGUI::CEventDescriptorMouse &eventDesc = (const NLGUI::CEventDescriptorMouse &)event;
@ -912,6 +931,30 @@ namespace NLGUI
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;
}
@ -1213,6 +1256,7 @@ namespace NLGUI
if(wReal <= maxWReal)
return;
// compute the new ofsX.
sint32 ofsX= _Target->getOfsX();
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)
{
const char *funcName = "getViewText";

@ -524,18 +524,19 @@ namespace NLGUI
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
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)
{
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;
}
@ -543,7 +544,7 @@ namespace NLGUI
if (!curl)
{
fclose(fp);
CFile::deleteFile(tmpdest);
CFile::deleteFile(download.tmpdest);
nlwarning("Creating cURL handle failed, unable to download '%s'", download.url.c_str());
return false;
@ -607,28 +608,19 @@ namespace NLGUI
void CGroupHTML::finishCurlDownload(const CDataDownload &download)
{
std::string tmpfile = download.dest + ".tmp";
if (download.type == ImgType)
{
// there is race condition if two browser instances are downloading same file
// second instance deletes first tmpfile and creates new file for itself.
if (CFile::getFileSize(tmpfile) > 0)
if (CFile::fileExists(download.tmpdest) && CFile::getFileSize(download.tmpdest) > 0)
{
try
{
// verify that image is not corrupted
uint32 w, h;
CBitmap::loadSize(tmpfile, w, h);
CBitmap::loadSize(download.tmpdest, w, h);
if (w != 0 && h != 0)
{
// if not tmpfile, then img is already in cache
if (CFile::fileExists(tmpfile))
{
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
@ -636,25 +628,37 @@ namespace NLGUI
// 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);
setImage(download.imgs[i].Image, download.tmpdest, download.imgs[i].Type);
setImageSize(download.imgs[i].Image, download.imgs[i].Style);
}
CFile::moveFile(download.dest, tmpfile);
CFile::moveFile(download.dest, download.tmpdest);
}
}
catch(const NLMISC::Exception &e)
{
// exception message has .tmp file name, so keep it for further analysis
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)
{
// 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.dest.c_str(), download.url.c_str(), e.what());
}
}
@ -663,13 +667,13 @@ namespace NLGUI
if (download.type == StylesheetType)
{
if (CFile::fileExists(tmpfile))
if (CFile::fileExists(download.tmpdest))
{
if (CFile::fileExists(download.dest))
{
CFile::deleteFile(download.dest);
}
CFile::moveFile(download.dest, tmpfile);
CFile::moveFile(download.dest, download.tmpdest);
}
cssDownloadFinished(download.url, download.dest);
@ -680,20 +684,20 @@ namespace NLGUI
{
bool verified = false;
// 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 (CFile::fileExists(download.dest))
{
CFile::deleteFile(download.dest);
}
CFile::moveFile(download.dest, tmpfile);
CFile::moveFile(download.dest, download.tmpdest);
}
else
{
CFile::deleteFile(tmpfile);
CFile::deleteFile(download.tmpdest);
}
}
else if (CFile::fileExists(download.dest))
@ -745,7 +749,7 @@ namespace NLGUI
if (type != OverImage)
{
std::string temp = dest;
if (!CFile::fileExists(temp))
if (!CFile::fileExists(temp) || CFile::getFileSize(temp) == 0)
{
temp = placeholder;
}
@ -857,21 +861,16 @@ namespace NLGUI
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)
{
std::string url = getAbsoluteUrl(links[i]);
std::string local = localImageName(url);
_StylesheetQueue.push_back(links[i]);
std::string url = getAbsoluteUrl(links[i].Url);
_StylesheetQueue.back().Url = url;
// insert only if url not already downloading
std::vector<std::string>::const_iterator it = std::find(_StylesheetQueue.begin(), _StylesheetQueue.end(), url);
if (it == _StylesheetQueue.end())
{
_StylesheetQueue.push_back(url);
// push to the front of the queue
Curls.push_front(CDataDownload(url, local, StylesheetType, NULL, "", ""));
}
Curls.push_front(CDataDownload(url, localImageName(url), StylesheetType, NULL, "", ""));
}
pumpCurlQueue();
}
@ -971,9 +970,9 @@ namespace NLGUI
{
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->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
addHtmlGroup (newParagraph, beginSpace);
@ -2642,6 +2652,17 @@ namespace NLGUI
invalidateCoords();
}
void CGroupHTML::browseErrorHtml(const std::string &html)
{
releaseDownloads();
removeContent();
renderHtmlString(html);
updateRefreshButton();
invalidateCoords();
}
// ***************************************************************************
bool CGroupHTML::isBrowsing()
@ -3964,11 +3985,22 @@ namespace NLGUI
{
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;
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 += "\nURL '" + _CurlWWW->Url + "'";
browseError(err.c_str());
err += "<hr>(" + uri.scheme + "://" + uri.host + ") <a href=\"" + url + "\">reload</a>";
err += "</body></html>";
browseErrorHtml(err);
return;
}
@ -4080,10 +4112,9 @@ namespace NLGUI
obj.LastModified = data.data->getLastModified();
CHttpCache::getInstance()->store(data.dest, obj);
std::string tmpfile = data.dest + ".tmp";
if (code == 304 && CFile::fileExists(tmpfile))
if (code == 304 && CFile::fileExists(data.tmpdest))
{
CFile::deleteFile(tmpfile);
CFile::deleteFile(data.tmpdest);
}
}
else if ((code >= 301 && code <= 303) || code == 307 || code == 308)
@ -4111,10 +4142,9 @@ namespace NLGUI
LOG_DL("Redirect '%s'", location.c_str());
// no finished callback called, so cleanup old temp
std::string tmpfile = data.dest + ".tmp";
if (CFile::fileExists(tmpfile))
if (CFile::fileExists(data.tmpdest))
{
CFile::deleteFile(tmpfile);
CFile::deleteFile(data.tmpdest);
}
return;
}
@ -4187,19 +4217,28 @@ namespace NLGUI
// ***************************************************************************
void CGroupHTML::cssDownloadFinished(const std::string &url, const std::string &local)
{
// remove file from download queue
std::vector<std::string>::iterator it = std::find(_StylesheetQueue.begin(), _StylesheetQueue.end(), url);
if (it != _StylesheetQueue.end())
for(std::vector<CHtmlParser::StyleLink>::iterator it = _StylesheetQueue.begin();
it != _StylesheetQueue.end(); ++it)
{
_StylesheetQueue.erase(it);
}
if (!CFile::fileExists(local))
if (it->Url == url)
{
return;
// 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());
}
}
}
parseStylesheetFile(local);
_StylesheetQueue.erase(it);
break;
}
}
}
void CGroupHTML::renderDocument()
@ -4217,6 +4256,16 @@ namespace NLGUI
beginBuild();
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();
while(it != _HtmlDOM.Children.end())
{
@ -4826,9 +4875,6 @@ namespace NLGUI
// ***************************************************************************
bool CGroupHTML::parseHtml(const std::string &htmlString)
{
std::vector<std::string> links;
std::string styleString;
CHtmlElement *parsedDOM;
if (_CurrentHTMLElement == NULL)
{
@ -4841,16 +4887,28 @@ namespace NLGUI
parsedDOM = _CurrentHTMLElement;
}
std::vector<CHtmlParser::StyleLink> links;
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>
@ -4861,7 +4919,7 @@ namespace NLGUI
{
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) {
std::list<CHtmlElement>::iterator it2 = it->Children.begin();
while(it2 != it->Children.end())
@ -5358,6 +5416,11 @@ namespace NLGUI
cellParams.Align = CGroupCell::Center;
else if (align == "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");
if(suri.find("ah:") == 0)
{
if (_TrustedDomain)
if (_TrustedDomain || suri.find("ah:script:") == 0)
_Link.back() = suri;
}
else
@ -6360,11 +6423,13 @@ namespace NLGUI
void CGroupHTML::htmlOBJECTend(const CHtmlElement &elm)
{
if (!_TrustedDomain)
return;
if (_ObjectType=="application/ryzom-data")
{
if (!_TrustedDomain)
return;
if (!_ObjectData.empty())
{
if (addBnpDownload(_ObjectData, _ObjectAction, _ObjectScript, _ObjectMD5Sum))
@ -6374,6 +6439,20 @@ namespace NLGUI
_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;
}
@ -6767,6 +6846,9 @@ namespace NLGUI
// setting ModulateGlobalColor must be after addImageDownload
if (_Style.checkStyle("-ryzom-modulate-bgcolor", "true"))
table->setModulateGlobalColor(true);
else if (_Style.checkStyle("-ryzom-modulate-bgcolor", "false"))
table->setModulateGlobalColor(false);
table->setMarginLeft(getIndent());
addHtmlGroup (table, 0);

@ -64,6 +64,7 @@ namespace NLGUI
_Indent = 0;
_FirstViewIndentView = false;
_TextId = 0;
_TextAlign = AlignLeft;
}
// ----------------------------------------------------------------------------
@ -713,6 +714,10 @@ namespace NLGUI
CViewText *viewText = dynamic_cast<CViewText*>(_Elements[i].Element);
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->setX(0);
viewText->updateTextContext();
@ -730,6 +735,12 @@ namespace NLGUI
// Does we balance the last line height ?
if (viewText)
{
if (_TextAlign == AlignCenter && elmCount == 1)
{
sint pad = width - viewText->getWReal();
viewText->setX(pad/2);
}
changeLine = viewText->getNumLine() > 1;
if (!viewText->getText().empty() && *(viewText->getText().rbegin()) == (ucchar) '\n')
{

@ -57,7 +57,7 @@ namespace NLGUI
// ***************************************************************************
// 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 element_number;
@ -65,9 +65,17 @@ namespace NLGUI
while(node)
{
if (node->type == XML_TEXT_NODE)
{
// 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
if (node->type == XML_ELEMENT_NODE)
{
@ -145,7 +153,9 @@ namespace NLGUI
if (useStyle)
{
parseStyle(node->children, styleString);
std::string style;
parseStyle(node->children, style);
styles.push_back(style);
}
// style tag is kept in dom
}
@ -163,13 +173,24 @@ namespace NLGUI
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
}
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
// 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);
if (!parser)
@ -428,8 +449,7 @@ namespace NLGUI
xmlNode *root = xmlDocGetRootElement(parser->myDoc);
if (root)
{
styleString.clear();
parseNode(root, dom, styleString, links);
parseNode(root, dom, styles, links);
}
else
{

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

@ -621,9 +621,7 @@ namespace NLGUI
return;
sint32 txw, txh;
SImage &rImage = *getSImage(nTxId);
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);
getTextureSizeFromId(nTxId, txw, txh);
drawRotFlipBitmap (layerId, x, y, txw, txh, rot, flipv, nTxId, col);
}
@ -859,6 +857,14 @@ namespace NLGUI
CIFile ifTmp;
if (ifTmp.open(filename))
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);
// 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)
@ -932,6 +938,10 @@ namespace NLGUI
CBitmap curs;
curs.resize(x1 - x0, y1 - y0);
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);
}
}
@ -1357,8 +1367,8 @@ namespace NLGUI
else
{
SImage &rImage = *getSImage(id);
width = (sint32)((rImage.UVMax.U - rImage.UVMin.U)*rImage.GlobalTexturePtr->Width+0.5f);
height = (sint32)((rImage.UVMax.V - rImage.UVMin.V)*rImage.GlobalTexturePtr->Height+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 / rImage.GlobalTexturePtr->Scale)+0.5f);
}
}
/*
@ -1373,9 +1383,11 @@ namespace NLGUI
SImage &rImage = *getSImage(id);
SGlobalTexture &rGT = *rImage.GlobalTexturePtr;
// get (possibly) scaled width/height
sint32 width, height;
width = (sint32)((rImage.UVMax.U - rImage.UVMin.U)*rGT.Width+0.5f);
height = (sint32)((rImage.UVMax.V - rImage.UVMin.V)*rGT.Height+0.5f);
getTextureSizeFromId(id, width, height);
if (width == 0 || height == 0)
return CRGBA(255,255,255);
float xRatio = ((float)x) / ((float)(width));
float yRatio = ((float)y) / ((float)(height));
UTexture *pTF = rGT.Texture;

@ -2296,7 +2296,7 @@ namespace NLGUI
// Hide menu if the key is pushed
// if ((eventDesc.getKeyEventType() == CEventDescriptorKey::keydown) && !_ModalStack.empty() && !eventDesc.getKeyAlt() && !eventDesc.getKeyCtrl() && !eventDesc.getKeyShift())
// 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() )
{
@ -2307,7 +2307,7 @@ namespace NLGUI
}
// 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.
CInterfaceGroup *win= getLastEscapableTopWindow();

@ -3269,14 +3269,15 @@ CRGBAF CBitmap::getColor (float x, float y) const
uint32 i;
bool isValid = true;
for (i = 0; i < 4; ++i)
{
nlassert (nX[i] >= 0);
nlassert (nY[i] >= 0 );
nlassert (nX[i] < nWidth);
nlassert (nY[i] < nHeight);
if (nX[i] < 0 || nY[i] < 0 || nX[i] >= nWidth || nY[i] >= nHeight)
isValid = false;
}
if (isValid)
{
// Decimal part of (x,y)
x = x - (float)nX[0];
y = y - (float)nY[0];
@ -3341,6 +3342,7 @@ CRGBAF CBitmap::getColor (float x, float y) const
break;
default: break;
}
}
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);
}
else if(fileType == JPG_HEADER)
else if(memcmp(&fileType, &JPG_HEADER, 2) == 0)
{
uint8 blockMarker1 = 0;
uint8 blockMarker2 = 0;

@ -179,7 +179,6 @@
#else
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/sysctl.h>
# include <fcntl.h>
# include <unistd.h>
# include <cerrno>
@ -189,6 +188,7 @@
# endif // NL_CPU_INTEL
# ifdef NL_OS_MAC
# include <sys/mount.h>
# include <sys/sysctl.h>
# else
# include <sys/vfs.h>
# 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)
{
std::string lookup = CPath::lookup(filepath, false);
if (lookup.empty())
if (filepath.empty() || !CFile::fileExists(filepath))
{
nlwarning("Music file %s does not exist!", filepath.c_str());
nlwarning("Music file '%s' does not exist!", filepath.c_str());
return false;
}
@ -127,7 +126,7 @@ bool IAudioDecoder::getInfo(const std::string &filepath, std::string &artist, st
CIFile ifile;
ifile.setCacheFileOnOpen(false);
ifile.allowBNPCacheFileOnOpen(false);
if (ifile.open(lookup))
if (ifile.open(filepath))
return CAudioDecoderFfmpeg::getInfo(&ifile, artist, title, length);
#else
std::string type = CFile::getExtension(filepath);
@ -138,7 +137,7 @@ bool IAudioDecoder::getInfo(const std::string &filepath, std::string &artist, st
CIFile ifile;
ifile.setCacheFileOnOpen(false);
ifile.allowBNPCacheFileOnOpen(false);
if (ifile.open(lookup))
if (ifile.open(filepath))
return CAudioDecoderVorbis::getInfo(&ifile, artist, title, length);
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;
ifile.setCacheFileOnOpen(false);
ifile.allowBNPCacheFileOnOpen(false);
if (ifile.open(lookup))
if (ifile.open(filepath))
return CAudioDecoderMP3::getInfo(&ifile, artist, title, length);
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.
* \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 title returns the title (empty if not available)
*/
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 */
string pathName = CPath::lookup(filepath, false);
uint32 fileOffset = 0, fileSize = 0;
if (pathName.empty())
if (filepath.empty() || !CFile::fileExists(filepath))
{
nlwarning("NLSOUND FMod Driver: Music file %s not found!", filepath.c_str());
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)
{
getTag(artist, "ARTIST", stream);

@ -112,7 +112,7 @@ public:
virtual IMusicChannel *createMusicChannel();
/** 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 title returns the title (empty if not available)
*/

@ -8,7 +8,7 @@ IF(WITH_RYZOM_CLIENT)
ADD_SUBDIRECTORY(unix)
ENDIF()
INSTALL(FILES client_default.cfg DESTINATION ${RYZOM_ETC_PREFIX})
#INSTALL(FILES client_default.cfg DESTINATION ${RYZOM_ETC_PREFIX})
IF(WITH_RYZOM_PATCH)
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 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 ${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
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.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.addAdditionalArg("login", "Login to use", true, false);
Args.addAdditionalArg("password", "Password to use", true, false);

@ -326,17 +326,8 @@ CClientConfig::CClientConfig()
Local = false; // Default is Net Mode.
FSHost = ""; // Default Host.
#if 1 // Yubo hack
// The order is important here, because in a layer, global texture are rendered through this order
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
TexturesInterface.push_back("texture_interfaces_v3_2x");
TexturesInterfaceDXTC.push_back("texture_interfaces_dxtc_2x");
TexturesOutGameInterface.push_back("texture_interfaces_v3_outgame_ui");
@ -448,8 +439,8 @@ CClientConfig::CClientConfig()
CurlMaxConnections = 5;
CurlCABundle.clear();
RingReleaseNotePath = WebIgMainDomain + "/releasenotes_ring/index.php";
ReleaseNotePath = WebIgMainDomain + "/releasenotes/index.php";
RingReleaseNotePath = WebIgMainDomain + "/app_releasenotes/index.php";
ReleaseNotePath = WebIgMainDomain + "/app_releasenotes/index.php";
///////////////
@ -791,8 +782,8 @@ void CClientConfig::setValues()
READ_STRINGVECTOR_FV(TexturesOutGameInterfaceDXTC);
// interface textures ingame and r2
READ_STRINGVECTOR_FV(TexturesInterface);
READ_STRINGVECTOR_FV(TexturesInterfaceDXTC);
//READ_STRINGVECTOR_FV(TexturesInterface);
//READ_STRINGVECTOR_FV(TexturesInterfaceDXTC);
// interface files login menus
READ_STRINGVECTOR_FV(XMLLoginInterfaceFiles);

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

@ -33,6 +33,7 @@
#include "nel/misc/time_nl.h"
#include "nel/misc/algo.h"
#include "nel/misc/system_utils.h"
#include "nel/misc/stream.h"
// 3D Interface.
#include "nel/3d/u_driver.h"
#include "nel/3d/u_text_context.h"
@ -149,6 +150,7 @@ ucstring PlayerSelectedHomeShardName;
ucstring PlayerSelectedHomeShardNameWithParenthesis;
extern std::string CurrentCookie;
ucstring NewKeysCharNameWanted; // name of the character for which a new keyset must be created
ucstring NewKeysCharNameValidated;
std::string GameKeySet = "keys.xml";
@ -157,9 +159,11 @@ std::string RingEditorKeySet = "keys_r2ed.xml";
string ScenarioFileName;
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_KEYSET "ui:outgame:appear_keyset:keyset_list"
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 hasPrivilegeEG() { return (UserPrivileges.find(":EG:") != 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)
@ -2124,7 +2129,7 @@ public:
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));
if (pList == NULL)
@ -2203,7 +2208,7 @@ public:
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));
pList->clearGroups();
}
@ -2214,32 +2219,56 @@ REGISTER_ACTION_HANDLER (CAHResetMainlandList, "reset_mainland_list");
// ***************************************************************************
class CAHMainlandSelect : public IActionHandler
{
virtual void execute (CCtrlBase *pCaller, const string &/* Params */)
virtual void execute (CCtrlBase *pCaller, const std::string &Params)
{
nlinfo("CAHMainlandSelect called");
CInterfaceManager *pIM = CInterfaceManager::getInstance();
//nlinfo("CAHMainlandSelect called");
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_MAINLAND));
if (!list)
return;
CCtrlButton *pCB = NULL;
// Unselect
if (MainlandSelected.asInt() != 0)
// unselect
if (Params.empty())
{
pCB = dynamic_cast<CCtrlButton*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_MAINLAND ":"+toString(MainlandSelected)+":but"));
if (pCB != NULL)
pCB->setPushed(false);
CUnpush unpusher;
unpusher.Ref = pCaller;
list->visit(&unpusher);
}
pCB = dynamic_cast<CCtrlButton*>(pCaller);
if (pCB != NULL)
// now select
uint32 mainland;
if (Params.empty())
{
string name = pCB->getId();
CCtrlButton *pCB = dynamic_cast<CCtrlButton*>(pCaller);
if (!pCB)
return;
std::string name = pCB->getId();
name = name.substr(0, name.rfind(':'));
uint32 mainland;
fromString(name.substr(name.rfind(':')+1,name.size()), mainland);
MainlandSelected = (TSessionId)mainland;
if (!fromString(name.substr(name.rfind(':')+1, name.size()), mainland))
return;
pCB->setPushed(true);
}
else
if (!fromString(Params, mainland))
return;
// and store
MainlandSelected = (TSessionId)mainland;
}
};
REGISTER_ACTION_HANDLER (CAHMainlandSelect, "mainland_select");
@ -2444,7 +2473,7 @@ public:
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));
pList->clearGroups();
}
@ -2455,21 +2484,18 @@ REGISTER_ACTION_HANDLER (CAHResetKeysetList, "reset_keyset_list");
// ***************************************************************************
class CAHResetKeysetSelect : public IActionHandler
{
public:
std::string getIdPostFix(const std::string fullId)
{
std::string::size_type pos = fullId.find_last_of(":");
if (pos != std::string::npos)
{
return fullId.substr(pos + 1);
}
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
//
struct CUnpush : public CInterfaceElementVisitor
{
CCtrlBase *Ref;
@ -2483,31 +2509,41 @@ public:
}
}
};
CInterfaceManager *pIM = CInterfaceManager::getInstance();
CInterfaceGroup *list = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_KEYSET));
if (list)
{
if (!list)
return;
// unselect
CUnpush unpusher;
unpusher.Ref = pCaller;
list->visit(&unpusher);
}
// now select
CCtrlBaseButton *but = dynamic_cast<CCtrlBaseButton*>(pCaller);
if (but)
{
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";
RingEditorKeySet = "keys_r2ed.xml";
if (!pCaller->getParent()) return;
// compute the 2 filenames from the id
// if id is in the built-in keysets :
// compute the two filenames from the id
// if id is in the built-in keysets
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)
{
std::string id = getIdPostFix(pCaller->getParent()->getId());
if (keySetVar->asString(k) == id)
{
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");
@ -3421,3 +3455,239 @@ class CAHOpenRingSessions : public IActionHandler
}
};
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 hasPrivilegeVG();
bool hasPrivilegeOBSERVER();
bool hasPrivilegeTESTER();
// connection with the server. (login, shard list, etc.).

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

@ -49,12 +49,12 @@
#include "login_progress_post_thread.h"
#include "interface_v3/action_handler_base.h"
#include "item_group_manager.h"
#include "nel/misc/cmd_args.h"
#ifdef DEBUG_NEW
#define new DEBUG_NEW
#endif
using namespace NLMISC;
using namespace NLNET;
using namespace NL3D;
@ -210,6 +210,7 @@ extern bool IsInRingSession;
extern void selectTipsOfTheDay (uint tips);
#define BAR_STEP_TP 2
extern NLMISC::CCmdArgs Args;
CLoginStateMachine::TEvent CLoginStateMachine::waitEvent()
{
@ -462,12 +463,14 @@ void CLoginStateMachine::run()
case st_check_patch:
/// check the data to check if patch needed
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 !
_CurrentState = st_display_eula;
break;
}
initPatchCheck();
SM_BEGIN_EVENT_TABLE
if (isBGDownloadEnabled())
@ -1517,4 +1520,3 @@ void CFarTP::farTPmainLoop()
if(welcomeWindow)
initWelcomeWindow();
}

@ -267,7 +267,7 @@ void CGameContextMenu::update()
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)
_TextInvisible->setActive(showGMOptions);
@ -458,11 +458,12 @@ void CGameContextMenu::update()
if (pLeafFame != NULL)
fameValue = pLeafFame->getValue8();
}
if (_TextNews)
_TextNews->setActive(selection && !canAttack() && selection->isNPC() && fameValue >= -30);
_TextNews->setActive(!UserEntity->isFighting() && !UserEntity->isRiding() && selection && !canAttack() && selection->isNPC() && fameValue >= -30);
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)

@ -112,6 +112,23 @@ class CAHToggleARKPACSBorders : public IActionHandler
};
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
// ------------------------------------------------------------------------------------------------
class CAHProfile : public IActionHandler
@ -270,22 +287,6 @@ class CAHSwitchConsoleDisplay : public IActionHandler
// ***************************************************************************
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
{

@ -4655,6 +4655,45 @@ public:
};
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
{

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

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

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

@ -161,6 +161,7 @@ void CBotChatPageMission::acceptMission()
/// close the botchat
//CBotChatManager::getInstance()->setCurrPage(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
CHugeListObs _MissionPagesObs;
CDBCtrlSheet *_CurrSel;
bool _HaveAcceptedMission;
MISSION_DESC::TClientMissionType _MType;
};

@ -588,7 +588,8 @@ void CBotChatPageTrade::updateTradeModal()
if ((_BuyMean == MoneyGuildXP) || (_BuyMean == GuildMoney) || (_BuyMean == GuildMoneyGuildXP))
{
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;
CGuildManager *pGM = CGuildManager::getInstance();

@ -422,6 +422,53 @@ CViewBase *CChatTextManager::createMsgTextComplex(const ucstring &msg, NLMISC::C
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
bool hasUrl;
@ -430,8 +477,7 @@ CViewBase *CChatTextManager::createMsgTextComplex(const ucstring &msg, NLMISC::C
hasUrl = (s.find(ucstring("http://")) || s.find(ucstring("https://")));
}
ucstring::size_type pos = 0;
for (ucstring::size_type i = 0; i< textSize;)
for (ucstring::size_type i = pos; i< textSize;)
{
if (hasUrl && isUrlTag(msg, i, textSize))
{

@ -215,7 +215,29 @@ void CChatWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CChatGr
CChatTextManager &ctm = getChatTextMngr();
gl = dynamic_cast<CGroupList *>(_Chat->getGroup("cb:text_list"));
if (gl) gl->addChild(ctm.createMsgText(msg, col));
bool noTranslation = false;
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);
}
}
CViewBase *child = ctm.createMsgText(msgNoTranslate, col);
if (child)
{
if (gl) gl->addChild(child);
// if the group is closed, make it blink
if (!_Chat->isOpen())
@ -239,6 +261,7 @@ void CChatWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CChatGr
(*it)->displayMessage(this, msg, col, numBlinks);
}*/
}
}
//=================================================================================
void CChatWindow::setMenu(const std::string &menuName)
@ -563,13 +586,32 @@ void CChatGroupWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CC
ucstring newmsg = msg;
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)
{
gl->addChild(ctm.createMsgText(newmsg, col));
child = ctm.createMsgText(newmsg, col);
if (child)
{
gl->addChild(child);
if (!gl->getParent()->getActive())
if (tab != NULL)
tab->setTextColorNormal(newMsgColor);
}
}
// *** Display the message in the UserChat (special case)
{
@ -635,14 +677,19 @@ void CChatGroupWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CC
if (gl != NULL)
{
gl->addChild(ctm.createMsgText(newmsg, col));
child = ctm.createMsgText(newmsg, col);
if (child)
{
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())
@ -662,6 +709,7 @@ void CChatGroupWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CC
*windowVisible = isVisible();
}
}
}
//=================================================================================
void CChatGroupWindow::displayTellMessage(const ucstring &msg, NLMISC::CRGBA col, const ucstring &sender)
@ -685,8 +733,9 @@ void CChatGroupWindow::displayTellMessage(const ucstring &msg, NLMISC::CRGBA col
nlwarning("<CChatGroupWindow::displayTellMessage> can't get text_list.");
return;
}
gl->addChild(getChatTextMngr().createMsgText(msg, col));
CViewBase *child = getChatTextMngr().createMsgText(msg, col);
if (child)
gl->addChild(child);
}
//=================================================================================

@ -56,6 +56,7 @@
#include "../r2/editor.h"
#include "nel/gui/lua_manager.h"
#include "nel/misc/xml_macros.h"
extern CSheetManager SheetMngr;
@ -543,6 +544,15 @@ CCtrlDraggable(param)
_RegenText = NULL;
_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);
_GuildSymb = NULL;
}
if (_RegenText)
{
delete _RegenText;
_RegenText = NULL;
}
// ensure erase static
if(this==_CurrMenuSheet) _CurrMenuSheet = NULL;
@ -650,6 +665,17 @@ bool CDBCtrlSheet::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup)
prop = (char*) xmlGetProp( cur, (xmlChar*)"focus_buff_icon" );
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();
// Init size for Type
initSheetSize();
@ -1081,6 +1107,7 @@ void CDBCtrlSheet::clearIconBuffs()
{
_EnchantIcons.clear();
_BuffIcons.clear();
_BoostIcons.clear();
}
// ***************************************************************************
@ -1112,13 +1139,28 @@ void CDBCtrlSheet::infoReceived()
const CSBrickSheet *brick = pBM->getBrick(itemInfo->Enchantment.Bricks[i]);
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)
{
haveRoot = true;
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));
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);
}
if (!_RegenText) {
_RegenText = new CViewText(CViewBase::TCtorParam());
_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();
if (_RegenTextEnabled)
drawRegenText();
}
}
@ -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)
@ -2440,8 +2567,15 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti
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[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
if (_DispQuality != -1)
@ -2870,7 +3004,7 @@ bool CDBCtrlSheet::handleEvent (const NLGUI::CEventDescriptor &event)
}
else
{
validClic = isDraggable() && !isDragged() && ((!getItemWeared()&&!getGrayed()) || isShortCut());
validClic = isDraggable() && !isDragged() && ((!getItemWeared()&&!getGrayed()) || isSPhraseId());
}
}
if (_Type == SheetType_Macro)
@ -3799,6 +3933,7 @@ void CDBCtrlSheet::resetAllTexIDs()
_ItemInfoChanged = true;
_EnchantIcons.clear();
_BuffIcons.clear();
_BoostIcons.clear();
}
@ -4738,6 +4873,12 @@ std::string CDBCtrlSheet::getContextHelpWindowName() const
return CCtrlBase::getContextHelpWindowName();
}
// ***************************************************************************
void CDBCtrlSheet::setRegenTextFct(const std::string &s)
{
_RegenTextFct = s;
_RegenTextFctLua = startsWith(s, "lua:");
}
// ***************************************************************************
void CDBCtrlSheet::setRegenTickRange(const CTickRange &tickRange)

@ -602,6 +602,25 @@ public:
void setRegenTickRange(const CTickRange &tickRange);
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)
void startNotifyAnim();
@ -682,6 +701,7 @@ protected:
};
std::vector<SBuffIcon> _BuffIcons;
std::vector<SBuffIcon> _EnchantIcons;
std::vector<SBuffIcon> _BoostIcons;
// Level Brick or Quality
union
@ -738,7 +758,19 @@ protected:
CTickRange _RegenTickRange;
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
sint32 _DragX, _DragY;
@ -852,6 +884,9 @@ private:
// gelper to draw the notify animation
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

@ -23,7 +23,7 @@
#include "stdpch.h"
#include "dbgroup_list_sheet_bonus_malus.h"
#include "interface_manager.h"
#include "nel/misc/xml_macros.h"
using namespace std;
using namespace NLMISC;
@ -35,87 +35,106 @@ NLMISC_REGISTER_OBJECT(CViewBase, CDBGroupListSheetBonusMalus, std::string, "lis
// ***************************************************************************
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
// Yoyo: I think it's better like this, + this is important for space consideration and because of XPCat/PVPOutpost
//_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
CXMLAutoPtr prop;
prop = (char*) xmlGetProp( cur, (xmlChar*)"disable_texture" );
if (prop)
CCDBNodeBranch *root = Ctrl->getRootBranch();
if (root)
{
CInterfaceManager *pIM = CInterfaceManager::getInstance();
CViewRenderer &rVR = *CViewRenderer::getInstance();
_TextId= rVR.getTextureIdFromName ((const char *)prop);
TimerDB = dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("DISABLED_TIME"), false));
DisabledDB = dynamic_cast<CCDBNodeLeaf *>(root->getNode(ICDBNode::CTextId("DISABLED"), false));
}
// get the Node leaves to be tested each frame
uint i= 0;
for(;;)
{
string db= toString("%s:%d:" DISABLE_LEAF, _DbBranchName.c_str(), i);
CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp(db, false);
if(!node)
if (Ctrl)
{
break;
}
else
CDBGroupListSheetBonusMalus *owner = dynamic_cast<CDBGroupListSheetBonusMalus *>(pFather);
if (owner)
{
_DisableStates.push_back(node);
i++;
}
_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);
}
return true;
Ctrl->setRegenTextOutline(true);
}
}
// ***************************************************************************
void CDBGroupListSheetBonusMalus::draw ()
void CDBGroupListSheetBonusMalus::CSheetChildTimer::update(CDBGroupListSheet * /* pFather */)
{
CDBGroupListSheet::draw();
// CInterfaceManager *pIM= CInterfaceManager::getInstance();
// CViewRenderer &rVR= *CViewRenderer::getInstance();
if(!TimerDB)
return;
// sint32 drl= getRenderLayer()+1;
// May draw disable bitmaps on the ctrl sheets if disabled.
uint numCtrls= (uint)min(_SheetChildren.size(), _DisableStates.size());
for(uint i=0;i<numCtrls;i++)
NLMISC::TGameCycle tick = TimerDB->getValue32();
if (TimerCache != tick)
{
CDBCtrlSheet *ctrl= _SheetChildren[i]->Ctrl;
// if the ctrl is displayed, and if the state is disabled
if(ctrl->getActive())
TimerCache = TimerDB->getValue32();
Ctrl->setRegenTickRange(CTickRange(LastGameCycle, TimerCache));
if (DisabledDB)
{
if(_DisableStates[i]->getValue32()!=0)
if (DisabledDB->getValue32() == 0)
{
ctrl->setGrayed(true);
/*
// YOYO: for now, don't display the gray bitmap. cross not cool.
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);
*/
// active timer
Ctrl->setGrayed(false);
Ctrl->setRegenTextColor(_RegenTextColor);
}
else
{
// skill disabled timer
Ctrl->setGrayed(true);
Ctrl->setRegenTextColor(_RegenTextDisabledColor);
}
}
else
ctrl->setGrayed(false);
{
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 "dbgroup_list_sheet.h"
// ***************************************************************************
/**
* Special list_sheet that display some disalbe bitmap if needed according to DB
@ -40,14 +39,34 @@ public:
/// Constructor
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:
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::Skill: 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;
}

@ -28,6 +28,7 @@
#include "nel/gui/action_handler.h"
#include "../entities.h"
#include "nel/gui/group_paragraph.h" // For CCtrlLink
#include "nel/gui/view_bitmap.h"
#include "../net_manager.h"
#include "../string_manager_client.h"
#include "../login.h"
@ -644,14 +645,42 @@ void CGroupInSceneBubbleManager::addMessagePopupCenter (const ucstring &message,
"ui:interface", templateParams.empty()?NULL:&(templateParams[0]), (uint)templateParams.size());
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
CViewText *pViewName = dynamic_cast<CViewText*>(group->getView("name"));
if (pViewName != NULL)
{
pViewName->setTextFormatTaged(message);
pViewName->setTextFormatTaged(finalMessage);
pViewName->setColor (color);
}
// Link to the interface
CWidgetManager::getInstance()->addWindowToMasterGroup("ui:interface", group);
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 (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
bool show = false;
@ -862,7 +918,7 @@ void CGroupInSceneBubbleManager::chatOpen (uint32 nUID, const ucstring &ucsText,
return;
// Get a bubble
CGroupInSceneBubble *bubble = newBubble (ucsText);
CGroupInSceneBubble *bubble = newBubble (ucsText.substr(pos, textSize-pos));
if (bubble)
{
// Link the bubble

@ -463,19 +463,26 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (CEntityCL *entity)
//else
// stringSpace += textH;
bool have2pvptags = false;
if (rpTags)
{
CPlayerCL * pPlayer = dynamic_cast<CPlayerCL*>(entity);
CViewBitmap *rp1 = dynamic_cast<CViewBitmap*>(leftGroup->getView ("rp_logo_1"));
CViewBitmap *rp2 = dynamic_cast<CViewBitmap*>(leftGroup->getView ("rp_logo_2"));
CViewBitmap *rp3 = dynamic_cast<CViewBitmap*>(leftGroup->getView ("rp_logo_3"));
CViewBitmap *rp4 = dynamic_cast<CViewBitmap*>(leftGroup->getView ("rp_logo_4"));
CViewBitmap *rp1 = dynamic_cast<CViewBitmap*>(info->getView ("rp_logo_1"));
CViewBitmap *rp2 = dynamic_cast<CViewBitmap*>(info->getView ("rp_logo_2"));
CViewBitmap *rp3 = dynamic_cast<CViewBitmap*>(info->getView ("rp_logo_3"));
CViewBitmap *rp4 = dynamic_cast<CViewBitmap*>(info->getView ("rp_logo_4"));
if (entityTag1.toString() == "_") entityTag1.clear();
if (entityTag2.toString() == "_") entityTag2.clear();
if (entityTag3.toString() == "_") entityTag3.clear();
if (entityTag4.toString() == "_") entityTag4.clear();
if (pPlayer && (pPlayer->getPvpMode() == PVP_MODE::None))
{
entityTag1.clear();
entityTag2.clear();
}
if (rp1) rp1->setTexture(entityTag1.toString());
if (rp2) rp2->setTexture(entityTag2.toString());
if (rp3) rp3->setTexture(entityTag3.toString());
@ -486,6 +493,8 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (CEntityCL *entity)
if (rp2) rp2->setActive(!entityTag2.empty());
if (rp3) rp3->setActive(!entityTag3.empty());
if (rp4) rp4->setActive(!entityTag4.empty());
have2pvptags = !entityTag1.empty() && !entityTag2.empty();
}
// Get the permanent content bitmap
@ -654,6 +663,7 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (CEntityCL *entity)
}
CViewBase * pvpFactionLogo = info->getView ("pvp_faction_logo");
CViewBase * pvpFactionLogo2 = info->getView ("pvp_faction_logo2");
CViewBase * pvpOutpostLogo = info->getView ("pvp_outpost_logo");
CViewBase * pvpDuelLogo = info->getView ("pvp_duel_logo");
@ -667,6 +677,7 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (CEntityCL *entity)
{
pvpFactionLogo->setActive(true);
CViewBitmap * pvpFactionBitmap = dynamic_cast<CViewBitmap *>(pvpFactionLogo);
CViewBitmap * pvpFactionBitmap2 = dynamic_cast<CViewBitmap *>(pvpFactionLogo2);
if( pvpFactionBitmap )
{
if (user)
@ -714,6 +725,12 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (CEntityCL *entity)
pvpFactionLogo->setActive(false);
}
}
if( pvpFactionLogo && pvpFactionBitmap2 )
{
pvpFactionBitmap2->setTexture(pvpFactionBitmap->getTexture());
pvpFactionLogo2->setActive(have2pvptags);
}
}
if (pvpOutpostLogo)
@ -731,13 +748,6 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (CEntityCL *entity)
else
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;
params.clear();
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)));
CInterfaceGroup *g = CWidgetManager::getInstance()->getParser()->createGroupInstance("lm_search_result", pL->getId(), params);
@ -2653,7 +2654,7 @@ void CGroupMap::createContinentLandMarks()
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();
CInterfaceElement *ie = CWidgetManager::getInstance()->getElementFromId("ui:interface:map_menu:teleport");
@ -2680,7 +2681,7 @@ void CGroupMap::setLandmarkFilter(const std::string &s)
if (!s.empty()) {
ucstring ucs;
ucs.fromUtf8(s);
splitUCString(toLower(s), ucstring(" "), _LandmarkFilter);
splitUCString(toLower(ucs), ucstring(" "), _LandmarkFilter);
}
// recreate landmarks
@ -2754,6 +2755,8 @@ CGroupMap::CLandMarkButton *CGroupMap::createArkPointButton(const CArkPoint &poi
lmb->setParamsOnLeftClick(point.LeftClickParam);
lmb->setActionOnRightClick(point.RightClickAction);
lmb->setParamsOnRightClick(point.RightClickParam);
lmb->setActionOnOver(point.OverClickAction);
lmb->setParamsOnOver(point.OverClickParam);
lmb->setColor(point.Color);
lmb->setColorOver(point.Color);
lmb->setColorPushed(point.Color);

@ -95,6 +95,8 @@ public:
std::string LeftClickParam;
std::string RightClickAction;
std::string RightClickParam;
std::string OverClickAction;
std::string OverClickParam;
public:
CArkPoint()

@ -74,6 +74,8 @@ bool CGroupQuickHelp::submitEvent (const char *event)
// Update the text
updateParagraph ();
CLuaManager::getInstance().executeLuaScript(toString("\ngame:processTutorialEvent(\"%s\")\n", event), true);
}
}
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 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_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"
@ -817,6 +818,7 @@ class CAHGuildSheetOpen : public IActionHandler
if (pParent == NULL) return;
pParent->clearGroups();
pParent->setDynamicDisplaySize(false);
uint member_online = 0;
for (uint i = 0; i < rGuildMembers.size(); i++)
{
// create the member line
@ -855,11 +857,13 @@ class CAHGuildSheetOpen : public IActionHandler
switch(rGuildMembers[i].Online)
{
case ccs_online:
member_online++;
onlineView->setTexture("w_online.tga");
if (toolTip)
toolTip->setDefaultContextHelp(CI18N::get("uittGuildMemberOnline"));
break;
case ccs_online_abroad:
member_online++;
onlineView->setTexture("w_online_abroad.tga");
if (toolTip)
toolTip->setDefaultContextHelp(CI18N::get("uittGuildMemberOnlineAbroad"));
@ -895,6 +899,12 @@ class CAHGuildSheetOpen : public IActionHandler
pLine->setParent (pParent);
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());
}
// 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);
if (node)
{
@ -2519,6 +2523,17 @@ void CInterfaceManager::displaySystemInfo(const ucstring &str, const string &cat
CClientConfig::SSysInfoParam::TMode mode = CClientConfig::SSysInfoParam::Normal;
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 (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 (PeopleInterraction.SystemInfo)
PeopleInterraction.ChatInput.SystemInfo.displayMessage(str, color, 2);
PeopleInterraction.ChatInput.SystemInfo.displayMessage(cleanStr, color, 2);
else
{
CPeopleInterraction::CSysMsg sysMsg;
sysMsg.Str = str;
sysMsg.Str = cleanStr;
sysMsg.Cat = cat;
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 ((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)
&& 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();
pList = dynamic_cast<CDBGroupListSheetBag*>(CWidgetManager::getInstance()->getElementFromId(LIST_PA3_TEXT));
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_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
#define LIST_BAG2_TEXT "ui:interface:inv_bag:content:iil:bag_list"
#define LIST_BAG2_ICONS "ui:interface:inv_bag:content:iil:bag_icons"

@ -96,6 +96,7 @@
#include "../continent_manager.h"
#include "../zone_util.h"
#include "../motion/user_controls.h"
#include "../events_listener.h"
#include "group_html_cs.h"
#include "group_map.h"
#include "bonus_malus.h"
@ -153,6 +154,7 @@ using namespace R2;
extern NLMISC::CLog g_log;
extern CContinentManager ContinentMngr;
extern CClientChatManager ChatMngr;
extern CEventsListener EventsListener; // Inputs Manager
// ***************************************************************************
class CHandlerLUA : public IActionHandler
@ -184,6 +186,21 @@ private:
REGISTER_ACTION_HANDLER(CHandlerLUA, "lua");
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
static DECLARE_INTERFACE_USER_FCT(lua)
@ -428,6 +445,7 @@ void CLuaIHMRyzom::RegisterRyzomFunctions(NLGUI::CLuaState &ls)
ls.registerFunc("launchContextMenuInGame", launchContextMenuInGame);
ls.registerFunc("parseInterfaceFromString", parseInterfaceFromString);
ls.registerFunc("updateAllLocalisedElements", updateAllLocalisedElements);
ls.registerFunc("getTimestampHuman", getTimestampHuman);
ls.registerFunc("formatUI", formatUI);
ls.registerFunc("formatDB", formatDB);
ls.registerFunc("dumpUI", dumpUI);
@ -454,6 +472,8 @@ void CLuaIHMRyzom::RegisterRyzomFunctions(NLGUI::CLuaState &ls)
ls.registerFunc("getMouseDown", getMouseDown),
ls.registerFunc("getMouseMiddleDown", getMouseMiddleDown),
ls.registerFunc("getMouseRightDown", getMouseRightDown),
ls.registerFunc("isShiftDown", isShiftDown),
ls.registerFunc("isCtrlDown", isCtrlDown),
ls.registerFunc("getShapeIdAt", getShapeIdAt),
ls.registerFunc("getPlayerFront", getPlayerFront);
ls.registerFunc("getPlayerDirection", getPlayerDirection);
@ -565,6 +585,8 @@ void CLuaIHMRyzom::RegisterRyzomFunctions(NLGUI::CLuaState &ls)
LUABIND_FUNC(isDynStringAvailable),
LUABIND_FUNC(isFullyPatched),
LUABIND_FUNC(getSheetType),
LUABIND_FUNC(getSheetShape),
LUABIND_FUNC(getCharacterSheetScale),
LUABIND_FUNC(getSheetFamily),
LUABIND_FUNC(getSheetName),
LUABIND_FUNC(getFameIndex),
@ -1254,7 +1276,7 @@ int CLuaIHMRyzom::getMouseDown(CLuaState &ls)
sint32 x, y;
bool down;
CTool::getMouseDown(down, x, y);
ls.push(down);
ls.push(EventsListener.isMouseButtonPushed(leftButton));
ls.push(x);
ls.push(y);
@ -1266,8 +1288,7 @@ int CLuaIHMRyzom::getMouseMiddleDown(CLuaState &ls)
sint32 x, y;
bool down;
CTool::getMouseMiddleDown(down, x, y);
ls.push(down);
ls.push(EventsListener.isMouseButtonPushed(middleButton));
ls.push(x);
ls.push(y);
@ -1280,13 +1301,30 @@ int CLuaIHMRyzom::getMouseRightDown(CLuaState &ls)
bool down;
CTool::getMouseRightDown(down, x, y);
ls.push(down);
ls.push(EventsListener.isMouseButtonPushed(rightButton));
ls.push(x);
ls.push(y);
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)
{
@ -2103,6 +2141,31 @@ int CLuaIHMRyzom::updateAllLocalisedElements(CLuaState &ls)
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)
{
@ -2298,13 +2361,28 @@ int CLuaIHMRyzom::addShape(CLuaState &ls)
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++)
{
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).setShininess(10.0f);
instance.getMaterial(j).setShininess(10.0f);*/
}
else
{
@ -3454,6 +3532,38 @@ std::string CLuaIHMRyzom::getSheetType(const std::string &sheet)
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)
@ -3803,7 +3913,9 @@ void CLuaIHMRyzom::updateTooltipCoords()
CWidgetManager::getInstance()->updateTooltipCoords();
}
// ***************************************************************************
// WARNING PROBABLY DON'T WORKS
bool CLuaIHMRyzom::isCtrlKeyDown()
{
//H_AUTO(Lua_CLuaIHM_isCtrlKeyDown)
@ -3816,6 +3928,7 @@ bool CLuaIHMRyzom::isCtrlKeyDown()
return ctrlDown;
}
// ***************************************************************************
std::string CLuaIHMRyzom::encodeURLUnicodeParam(const ucstring &text)
{
@ -3865,41 +3978,41 @@ sint32 CLuaIHMRyzom::getPlayerLevel()
std::string CLuaIHMRyzom::getPlayerVpaHex()
{
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()
{
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()
{
sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64();
return NLMISC::toString("%X", prop);
sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPC))->getValue64();
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;
}
// ***************************************************************************
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;
}
// ***************************************************************************
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;
}
@ -3950,7 +4063,7 @@ std::string CLuaIHMRyzom::getTargetVpaHex()
if (!target) return 0;
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;
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();
if (!target) return 0;
sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64();
return NLMISC::toString("%X", prop);
sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPC))->getValue64();
return NLMISC::toString("%" NL_I64 "X", prop);
}
// ***************************************************************************
sint64 CLuaIHMRyzom::getTargetVpa()
uint64 CLuaIHMRyzom::getTargetVpa()
{
CEntityCL *target = getTargetEntity();
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;
}
// ***************************************************************************
sint64 CLuaIHMRyzom::getTargetVpb()
uint64 CLuaIHMRyzom::getTargetVpb()
{
CEntityCL *target = getTargetEntity();
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;
}
// ***************************************************************************
sint64 CLuaIHMRyzom::getTargetVpc()
uint64 CLuaIHMRyzom::getTargetVpc()
{
CEntityCL *target = getTargetEntity();
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;
}
@ -4138,7 +4248,7 @@ int CLuaIHMRyzom::addLandMark(CLuaState &ls)
{
const char* funcName = "addLandMark";
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, 2, LUA_TNUMBER); // y
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, 7, LUA_TSTRING); // right click action
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;
point.x = (sint32)(ls.toNumber(1)*1000.f);
@ -4157,10 +4270,12 @@ int CLuaIHMRyzom::addLandMark(CLuaState &ls)
point.LeftClickParam = ls.toString(6);
point.RightClickAction = ls.toString(7);
point.RightClickParam = ls.toString(8);
point.OverClickAction = ls.toString(9);
point.OverClickParam = ls.toString(10);
point.Color = CRGBA(255,255,255,255);
if (ls.getTop() >= 9)
if (ls.getTop() >= 11)
CLuaIHM::pop(ls, point.Color);
CGroupMap *pMap = dynamic_cast<CGroupMap*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:map:content:map_content:actual_map"));

@ -48,6 +48,9 @@ private:
static int launchContextMenuInGame(CLuaState &ls); // params : menu name
static int parseInterfaceFromString(CLuaState &ls); // params : intreface script
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 i18n(CLuaState &ls); // retrieve an unicode string from CI18N
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 isFullyPatched();
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 getSheetName(uint32 sheetId);
static sint32 getFameIndex(const std::string &factionName);
@ -271,9 +276,9 @@ private:
static std::string getPlayerVpaHex();
static std::string getPlayerVpbHex();
static std::string getPlayerVpcHex();
static sint64 getPlayerVpa();
static sint64 getPlayerVpb();
static sint64 getPlayerVpc();
static uint64 getPlayerVpa();
static uint64 getPlayerVpb();
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 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
@ -281,9 +286,9 @@ private:
static std::string getTargetVpaHex();
static std::string getTargetVpbHex();
static std::string getTargetVpcHex();
static sint64 getTargetVpa();
static sint64 getTargetVpb();
static sint64 getTargetVpc();
static uint64 getTargetVpa();
static uint64 getTargetVpb();
static uint64 getTargetVpc();
static bool isTargetNPC(); // return 'true' if the target is an npc
static bool isTargetPlayer(); // return 'true' if the target is a player
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 (_State == Paused || _Songs.empty())
_State = Stopped;
stop();
// get song title/duration using worker thread
MusicPlayerWorker.getSongsInfo(filenames);
}
// ***************************************************************************
void CMusicPlayer::updatePlaylist(sint prevIndex)
void CMusicPlayer::updatePlaylist(uint index, bool state)
{
CInterfaceElement *pIE;
std::string rowId;
if (index >= _Songs.size()) return;
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())
{
rowId = toString("%s:s%d:bg", MP3_PLAYER_PLAYLIST_LIST, prevIndex);
pIE = dynamic_cast<CInterfaceElement*>(CWidgetManager::getInstance()->getElementFromId(rowId));
if (pIE) pIE->setActive(false);
updatePlaylist(prevIndex, false);
}
rowId = toString("%s:s%d:bg", MP3_PLAYER_PLAYLIST_LIST, _CurrentSongIndex);
pIE = dynamic_cast<CInterfaceElement*>(CWidgetManager::getInstance()->getElementFromId(rowId));
if (pIE) pIE->setActive(true);
updatePlaylist(_CurrentSongIndex, true);
}
// ***************************************************************************
@ -361,7 +363,7 @@ void CMusicPlayer::play (sint index)
if (_Songs.empty())
{
_State = Stopped;
stop();
return;
}
@ -432,11 +434,15 @@ void CMusicPlayer::stop ()
return;
// stop the music only if we are really playing (else risk to stop a background music!)
if (_State != Stopped)
SoundMngr->stopMusic(0);
_State = Stopped;
_PlayStart = 0;
_PauseTime = 0;
clearPlayingInfo();
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 ()
{
if(!SoundMngr)
{
if (_State != Stopped)
{
_State = Stopped;
clearPlayingInfo();
}
return;
}
@ -488,8 +520,6 @@ void CMusicPlayer::update ()
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;
uint min = (dur / 60) % 60;
@ -499,7 +529,7 @@ void CMusicPlayer::update ()
std::string title(toString("%02d:%02d", min, sec));
if (hour > 0) title = toString("%02d:", hour) + title;
title += " " + _CurrentSong.Title;
pVT->setText(ucstring::makeFromUtf8(title));
updatePlayingInfo(title);
}
if (SoundMngr->isMusicEnded ())
@ -520,8 +550,13 @@ void CMusicPlayer::update ()
}
else
{
SoundMngr->stopMusic(0);
_State = Stopped;
// remove active highlight from playlist
updatePlaylist(_CurrentSongIndex, false);
stop();
// restart from top on next 'play'
_CurrentSongIndex = 0;
}
}
}

@ -62,6 +62,10 @@ public:
void update ();
// update currently playing song info/duration on main gui
void updatePlayingInfo(const std::string info);
void clearPlayingInfo();
bool isRepeatEnabled() const;
bool isShuffleEnabled() const;
@ -71,6 +75,8 @@ public:
void shuffleAndRebuildPlaylist();
// Update playlist active row
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
void updateSong(const CSongs &song);

@ -311,6 +311,8 @@ void CPeopleInterraction::release()
ChatInput.Tell.removeListeningPeopleList(&TeamList);
ChatInput.Team.removeListeningPeopleList(&TeamList);
FriendList.saveContactGroups();
CChatWindowManager &cwm = getChatWndMgr();
AroundMe.release();
@ -1266,6 +1268,9 @@ void CPeopleInterraction::initContactLists( const std::vector<uint32> &vFriendLi
addContactInList(contactIdPool++, vFriendListName[i], vFriendListOnline[i], 0);
for (uint i = 0; i < vIgnoreListName.size(); ++i)
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();
}
@ -1278,6 +1283,8 @@ void CPeopleInterraction::addContactInList(uint32 contactId, const ucstring &nam
// remove the shard name if possible
ucstring name= CEntityCL::removeShardFromName(nameIn);
// add the contact to this list
sint index = pl.getIndexFromName(name);
// try to create if not found
@ -2307,6 +2314,56 @@ public:
};
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

@ -31,6 +31,7 @@
#include "chat_text_manager.h"
#include "people_interraction.h"
#include "../user_entity.h"
#include "nel/misc/o_xml.h"
using namespace std;
using namespace NLMISC;
@ -191,21 +192,28 @@ sint CPeopleList::getIndexFromContainerID(const std::string &id) const
//==================================================================
bool CPeopleList::sortExByContactId(const CPeople& a, const CPeople& b)
{
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)
{
if (a.Group == b.Group) {
ucstring name_a = toUpper(a.getName());
ucstring name_b = toUpper(b.getName());
return (name_a < name_b);
}
else
return (a.Group < b.Group);
}
//==================================================================
bool CPeopleList::sortExByOnline(const CPeople& a, const CPeople& b)
{
if (a.Group == b.Group) {
ucstring name_a = toUpper(a.getName());
ucstring name_b = toUpper(b.getName());
@ -234,9 +242,9 @@ bool CPeopleList::sortExByOnline(const CPeople& a, const CPeople& b)
break;
}
}
// Should not get here so just return something
return true;
}
else
return (a.Group < b.Group);
}
//==================================================================
@ -245,9 +253,16 @@ void CPeopleList::sortEx(TSortOrder order)
// remove all people from the father container
if (!_BaseContainer) return;
uint 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)
@ -265,9 +280,27 @@ void CPeopleList::sortEx(TSortOrder order)
break;
}
CGroupContainer *group = _BaseContainer;
uint groupIndex = 0;
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);
}
}
@ -415,8 +448,9 @@ void CPeopleList::removePeople(uint index)
}
else
{
if (_BaseContainer)
_BaseContainer->detachContainer(_Peoples[index].Container);
CGroupContainer *parentContainer = _Peoples[index].Container->getProprietaryContainer();
if (parentContainer)
parentContainer->detachContainer(_Peoples[index].Container);
}
CInterfaceManager *im = CInterfaceManager::getInstance();
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;
}
//==================================================================
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*/)
{
@ -480,7 +677,10 @@ void CPeopleList::displayLocalPlayerTell(const ucstring &receiver, uint index, c
ucstring s = CI18N::get("youTellPlayer");
strFindReplace(s, "%name", receiver);
strFindReplace(finalMsg, CI18N::get("youTell"), s);
gl->addChild(getChatTextMngr().createMsgText(finalMsg, prop.getRGBA()));
CViewBase *child = getChatTextMngr().createMsgText(finalMsg, prop.getRGBA());
if (child)
{
gl->addChild(child);
CInterfaceManager::getInstance()->log(finalMsg, CChatGroup::groupTypeToString(CChatGroup::tell));
// if the group is closed, make it blink
@ -493,6 +693,7 @@ void CPeopleList::displayLocalPlayerTell(const ucstring &receiver, uint index, c
_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.");
return;
}
gl->addChild(getChatTextMngr().createMsgText(msg, col));
CViewBase *child = getChatTextMngr().createMsgText(msg, col);
if (child)
gl->addChild(child);
}
@ -602,7 +804,12 @@ void CPeopleList::removeAllPeoples()
{
_BaseContainer->removeAllContainers();
}
for (uint k = 0; k < _GroupContainers.size(); ++k)
{
_GroupContainers[k].second->removeAllContainers();
}
NLMISC::contReset(_Peoples);
NLMISC::contReset(_GroupContainers);
}
//==================================================================

@ -110,6 +110,11 @@ public:
void setContactId(uint index, 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
* If the window is closed, it causes it to blink (and also the parent window)
*/
@ -151,19 +156,21 @@ public:
private:
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> Chat;
uint GlobalID;
TCharConnectionState Online;
bool Blocked;
uint32 ContactId;
ucstring Group;
bool operator < (const CPeople &other) const { return getName() < other.getName(); }
ucstring getName() const { return Container->getUCTitle(); }
};
typedef std::vector<CPeople> TPeopleVect;
private:
CGroupContainerPtr _BaseContainer;
std::vector<std::pair<std::string, NLMISC::CRefPtr<CGroupContainer> > > _GroupContainers;
NLMISC::CRefPtr<CChatWindow> _ChatWindow;
TPeopleVect _Peoples;
CPeopleListDesc::TContactType _ContactType;

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

@ -733,6 +733,12 @@ std::string CItemGroupManager::toDbPath(INVENTORIES::TInventory inventory)
return LIST_PA2_TEXT; break;
case INVENTORIES::pet_animal4:
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:
return LIST_ROOM_TEXT;break;
case INVENTORIES::guild:

@ -161,8 +161,12 @@ CLoginStateMachine LoginSM;
bool CStartupHttpClient::connectToLogin()
{
return connect(ClientCfg.ConfigFile.getVar("StartupHost").asString(0))
&& verifyServer(ClientCfg.ConfigFile.getVar("StartupVerify").asBool(0));
bool checkConnect = connect(ClientCfg.ConfigFile.getVar("StartupHost").asString(0));
if (ClientCfg.ConfigFile.exists("StartupVerify"))
checkConnect = checkConnect && verifyServer(ClientCfg.ConfigFile.getVar("StartupVerify").asBool(0));
return checkConnect;
}
CStartupHttpClient HttpClient;

@ -1280,6 +1280,19 @@ void CPatchManager::readDescFile(sint32 nVersion)
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();)
{
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 :");
nlwarning("EXCEPTION CATCH: getServerFile() failed - try to find an alternative : %s", (serverPath+srcName).c_str());
nlwarning("%i", UsedServer);
if (UsedServer >= 0 && UsedServer < (int) PatchServers.size())
{
@ -2676,6 +2689,7 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
string OutFilename;
bool usePatchFile = true;
bool haveAllreadyTryiedDownloadingOfFile = false;
// compute the total size of patch to download
uint32 totalPatchSize = 0;
@ -2743,6 +2757,7 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
{
// can not load the 7zip file, use normal patching
usePatchFile = true;
haveAllreadyTryiedDownloadingOfFile = true;
break;
}
@ -2754,6 +2769,7 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
{
// fallback to standard patch method
usePatchFile = true;
haveAllreadyTryiedDownloadingOfFile = true;
break;
}
}
@ -2766,6 +2782,7 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
nlwarning("Failed to unpack lzma file %s", (pPM->ClientPatchPath+lzmaFile).c_str());
// fallback to standard patch method
usePatchFile = true;
haveAllreadyTryiedDownloadingOfFile = true;
break;
}
@ -2874,8 +2891,83 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
sTranslate = CI18N::get("uiApplyingDelta") + " " + CFile::getFilename(PatchName);
pPM->setState(true, sTranslate);
xDeltaPatch(PatchName, SourceNameXD, OutFilename);
bool deltaPatchResult = xDeltaPatch(PatchName, SourceNameXD, OutFilename);
if (!deltaPatchResult && !haveAllreadyTryiedDownloadingOfFile) // Patch failed, try to download and apply lzma
{
breakable
{
// compute the seven zip filename
string lzmaFile = rFTP.FileName+".lzma";
// download the 7zip file
try
{
// first, try in the file version subfolfer
try
{
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
{
if (rFTP.LocalFileExists)
pPM->deleteFile(SourceName);
pPM->deleteFile(PatchName);
@ -2888,7 +2980,7 @@ void CPatchThread::processFile (CPatchManager::SFileToPatch &rFTP)
PatchSizeProgress += rFTP.PatcheSizes[j];
currentPatchedSize += rFTP.PatcheSizes[j];
}
}
if (tmpSourceName != DestinationName)
{
pPM->deleteFile(SourceName, false, false); // File can exists if bad BNP loading
@ -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
@ -2941,12 +3033,13 @@ void CPatchThread::xDeltaPatch(const string &patch, const string &src, const str
break;
default:
{
std::string str = toString("Error applying %s to %s giving %s", patch.c_str(), src.c_str(), out.c_str());
throw Exception (str);
nlinfo("Error applying %s to %s giving %s", patch.c_str(), src.c_str(), out.c_str());
return false;
}
break;
}
}
} else
return true;
// Launching xdelta

@ -269,6 +269,7 @@ public:
void setStartRyzomAtEnd(bool startAtEnd){ _StartRyzomAtEnd = startAtEnd; }
// Forward message to installation software if needed
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; }
private:
@ -320,8 +321,6 @@ private:
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)
void stopCheckThread();
void stopPatchThread();
@ -547,7 +546,7 @@ private:
void run();
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/character_summary.h"
#include "game_share/sphrase_com.h"
#include "game_share/outpost.h"
#include "game_share/msg_client_server.h"
#include "game_share/ryzom_database_banks.h"
#include "game_share/msg_encyclopedia.h"
@ -147,6 +148,7 @@ extern bool CharNameValidArrived;
extern bool CharNameValid;
bool IsInRingSession = false;
TSessionId HighestMainlandSessionId; // highest in the position stack
ucstring lastUniversMessage;
extern const char *CDBBankNames[INVALID_CDB_BANK+1];
@ -769,8 +771,12 @@ void CInterfaceChatDisplayer::displayChat(TDataSetIndex compressedSenderIndex, c
PeopleInterraction.ChatInput.Region.displayMessage(finalString, col, 2, &windowVisible);
}
else if (mode == CChatGroup::universe)
{
if (lastUniversMessage != finalString)
{
PeopleInterraction.ChatInput.Universe.displayMessage(finalString, col, 2, &windowVisible);
lastUniversMessage = finalString;
}
}
else if (mode == CChatGroup::dyn_chat)
{
@ -3200,9 +3206,11 @@ void impulseUserBars(NLMISC::CBitMemStream &impulse)
void impulseOutpostChooseSide(NLMISC::CBitMemStream &impulse)
{
// read message
uint8 type;
bool outpostInFire;
bool playerGuildInConflict;
bool playerGuildIsAttacker;
impulse.serial(type);
impulse.serial(outpostInFire);
impulse.serial(playerGuildInConflict);
impulse.serial(playerGuildIsAttacker);
@ -3214,7 +3222,7 @@ void impulseOutpostChooseSide(NLMISC::CBitMemStream &impulse)
impulse.serial( declTimer );
// start
OutpostManager.startPvpJoinProposal(outpostInFire, playerGuildInConflict, playerGuildIsAttacker,
OutpostManager.startPvpJoinProposal((OUTPOSTENUMS::TPVPType)type, outpostInFire, playerGuildInConflict, playerGuildIsAttacker,
ownerGuildNameId, attackerGuildNameId, declTimer);
}

@ -680,6 +680,7 @@ bool CNetworkConnection::connect(string &result)
_LatestLoginTime = ryzomGetLocalTime ();
_LatestSyncTime = _LatestLoginTime;
_LatestProbeTime = _LatestLoginTime;
m_LoginAttempts = 0;
nlinfo("CNET[%p]: Client connected to shard, attempting login", this);
return true;
@ -1091,6 +1092,17 @@ bool CNetworkConnection::stateLogin()
{
sendSystemLogin();
_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;
@ -2308,6 +2320,7 @@ bool CNetworkConnection::stateProbe()
else
{
nlwarning("CNET[%p]: received normal in state Probe", this);
_LatestProbeTime = _UpdateTime;
}
}
}

@ -822,6 +822,7 @@ private:
void sendSystemLogin();
bool stateLogin();
NLMISC::TTime _LatestLoginTime;
int m_LoginAttempts;
//
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)
{
// reset counter that force player to be neutral (eg: 10 seconds)
@ -64,10 +64,22 @@ void COutpostManager::startPvpJoinProposal(bool outpostInFire, bool playerGuildI
CCtrlBase *ctrl = dynamic_cast<CCtrlBase *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal:content:random"));
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"));
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"));
if (pGC)

@ -40,7 +40,7 @@ public:
COutpostManager();
/// 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);
/// Called when the client answer to the join for PVP in a Outpost Zone

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

@ -747,6 +747,12 @@ restartLoop:
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
temp.append(move, src+param.ReplacementPoint);
temp += str;

@ -2674,17 +2674,6 @@ void CUserEntity::selection(const CLFECOMMON::TCLEntityId &slot) // virtual
{
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 */

@ -264,6 +264,19 @@ namespace BRICK_FAMILIES
NL_STRING_CONVERSION_TABLE_ENTRY(BCOKARM02)
NL_STRING_CONVERSION_TABLE_ENTRY(BCOKARR02)
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
NL_STRING_CONVERSION_TABLE_ENTRY(BCOA)
@ -558,6 +571,7 @@ namespace BRICK_FAMILIES
NL_STRING_CONVERSION_TABLE_ENTRY(BSCMC)
NL_STRING_CONVERSION_TABLE_ENTRY(BSCMD)
NL_STRING_CONVERSION_TABLE_ENTRY(BSGMC)
NL_STRING_CONVERSION_TABLE_ENTRY(BSGMCB)
NL_STRING_CONVERSION_TABLE_ENTRY(BSXCA)

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

@ -323,19 +323,6 @@ namespace EFFECT_FAMILIES
{ "thorn_wall_aura.sbrick", PowerThornWall },
{ "water_wall_aura.sbrick", PowerWaterWall },
{ "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 },
{ "mod_defense.sbrick", PowerModDefenseSkill },
{ "mod_dodge.sbrick", PowerModDodgeSkill },

@ -534,7 +534,7 @@ void CStaticFames::loadTribeThreshold( const string& filename )
// check table structure
uint nbTribe = ws.size()-2;
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);
@ -548,7 +548,7 @@ void CStaticFames::loadTribeThreshold( const string& filename )
_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;
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
// 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)
{
nlwarning("FAME: CStaticFames::getStaticFame invalid faction, return 0");
//nlwarning("FAME: CStaticFames::getStaticFame invalid faction, return 0");
return 0;
}

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

@ -136,6 +136,7 @@ namespace MAGICFX
OtherFireWall = 14,
TeleportKami = 15, // 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(RVR)
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_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
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
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

@ -37,7 +37,7 @@ struct SPropVisualA
uint64 JacketColor : 3; // max: 8 current: 8
uint64 TrouserModel : 8; // max: 256 current: 104
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 ArmModel : 8; // max: 256 current: 94
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
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[])
{
@ -200,9 +201,40 @@ int main(int argc, char *argv[])
Args.setVersion(getDisplayVersion());
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.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
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
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();
printf("\n");
printf("Checking %s files to patch...\n", convert(CI18N::get("TheSagaOfRyzom")).c_str());
// initialize patch manager and set the ryzom full path, before it's used
CPatchManager *pPM = CPatchManager::getInstance();
printf("Using '%s/%s.version'\n", ClientCfg.ConfigFile.getVar("PatchUrl").asString().c_str(),
ClientCfg.ConfigFile.getVar("Application").asString().c_str());
// use PatchUrl
vector<string> patchURLs;
pPM->init(patchURLs, PatchUrl, "");
pPM->init(patchURLs, ClientCfg.ConfigFile.getVar("PatchUrl").asString(), "");
pPM->startCheckThread(true /* include background patchs */);
ucstring state;

Loading…
Cancel
Save