Merge branch 'atys' into ryzom/ark/features

ryzom/ark/features
Nuno 4 years ago
commit 7964a42927

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

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

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

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

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

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

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

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

@ -1030,19 +1030,14 @@ namespace NLGUI
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool CInterfaceElement::convertBool (const char *ptr) bool CInterfaceElement::convertBool (const char *ptr)
{ {
std::string str = toLower(ptr); return NLMISC::toBool(ptr);
bool b = false;
fromString( str, b );
return b;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
NLMISC::CVector CInterfaceElement::convertVector (const char *ptr) NLMISC::CVector CInterfaceElement::convertVector (const char *ptr)
{ {
float x = 0.0f, y = 0.0f, z = 0.0f; float x = 0.0f, y = 0.0f, z = 0.0f;
sscanf (ptr, "%f %f %f", &x, &y, &z); sscanf (ptr, "%f %f %f", &x, &y, &z);
return CVector(x,y,z); return CVector(x,y,z);
} }

@ -3570,7 +3570,7 @@ void CBitmap::loadSize(NLMISC::IStream &f, uint32 &retWidth, uint32 &retHeight)
} }
while(!eof); while(!eof);
} }
else if(fileType == JPG_HEADER) else if(memcmp(&fileType, &JPG_HEADER, 2) == 0)
{ {
uint8 blockMarker1 = 0; uint8 blockMarker1 = 0;
uint8 blockMarker2 = 0; uint8 blockMarker2 = 0;

@ -179,7 +179,6 @@
#else #else
# include <sys/types.h> # include <sys/types.h>
# include <sys/stat.h> # include <sys/stat.h>
# include <sys/sysctl.h>
# include <fcntl.h> # include <fcntl.h>
# include <unistd.h> # include <unistd.h>
# include <cerrno> # include <cerrno>

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

@ -326,8 +326,8 @@ CClientConfig::CClientConfig()
Local = false; // Default is Net Mode. Local = false; // Default is Net Mode.
FSHost = ""; // Default Host. FSHost = ""; // Default Host.
TexturesInterface.push_back("texture_interfaces_v3"); TexturesInterface.push_back("texture_interfaces_v3_2x");
TexturesInterfaceDXTC.push_back("texture_interfaces_dxtc"); TexturesInterfaceDXTC.push_back("texture_interfaces_dxtc_2x");
TexturesOutGameInterface.push_back("texture_interfaces_v3_outgame_ui"); TexturesOutGameInterface.push_back("texture_interfaces_v3_outgame_ui");
@ -782,8 +782,8 @@ void CClientConfig::setValues()
READ_STRINGVECTOR_FV(TexturesOutGameInterfaceDXTC); READ_STRINGVECTOR_FV(TexturesOutGameInterfaceDXTC);
// interface textures ingame and r2 // interface textures ingame and r2
READ_STRINGVECTOR_FV(TexturesInterface); //READ_STRINGVECTOR_FV(TexturesInterface);
READ_STRINGVECTOR_FV(TexturesInterfaceDXTC); //READ_STRINGVECTOR_FV(TexturesInterfaceDXTC);
// interface files login menus // interface files login menus
READ_STRINGVECTOR_FV(XMLLoginInterfaceFiles); READ_STRINGVECTOR_FV(XMLLoginInterfaceFiles);

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

@ -193,6 +193,7 @@ bool hasPrivilegeG() { return (UserPrivileges.find(":G:") != std::string::npos);
bool hasPrivilegeEM() { return (UserPrivileges.find(":EM:") != std::string::npos); } bool hasPrivilegeEM() { return (UserPrivileges.find(":EM:") != std::string::npos); }
bool hasPrivilegeEG() { return (UserPrivileges.find(":EG:") != std::string::npos); } bool hasPrivilegeEG() { return (UserPrivileges.find(":EG:") != std::string::npos); }
bool hasPrivilegeOBSERVER() { return (UserPrivileges.find(":OBSERVER:") != std::string::npos); } bool hasPrivilegeOBSERVER() { return (UserPrivileges.find(":OBSERVER:") != std::string::npos); }
bool hasPrivilegeTESTER() { return (UserPrivileges.find(":TESTER:") != std::string::npos); }
// Restore the video mode (fullscreen for example) after the connection (done in a window) // Restore the video mode (fullscreen for example) after the connection (done in a window)

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

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

@ -267,7 +267,7 @@ void CGameContextMenu::update()
setupContextMenuCantTalk(); // can't talk by default setupContextMenuCantTalk(); // can't talk by default
bool showGMOptions = (hasPrivilegeDEV() || hasPrivilegeSGM() || hasPrivilegeGM() || hasPrivilegeVG() || hasPrivilegeSG() || hasPrivilegeEM() || hasPrivilegeEG() || hasPrivilegeOBSERVER()); bool showGMOptions = (hasPrivilegeDEV() || hasPrivilegeSGM() || hasPrivilegeGM() || hasPrivilegeVG() || hasPrivilegeSG() || hasPrivilegeEM() || hasPrivilegeEG() || hasPrivilegeOBSERVER() || hasPrivilegeTESTER());
if (_TextInvisible) if (_TextInvisible)
_TextInvisible->setActive(showGMOptions); _TextInvisible->setActive(showGMOptions);

@ -4686,7 +4686,7 @@ class CHandlerOutgameNaviGetKeys : public IActionHandler
id = "sel"; id = "sel";
if (event != -1) if (event != -1)
- CLuaManager::getInstance().executeLuaScript(toString("outgame:eventChar%sKeyGet(%i)", id.c_str(), event)); CLuaManager::getInstance().executeLuaScript(toString("outgame:eventChar%sKeyGet(%i)", id.c_str(), event));
} }
// reset previous input // reset previous input
Driver->AsyncListener.reset(); Driver->AsyncListener.reset();

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

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

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

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

@ -424,30 +424,37 @@ CViewBase *CChatTextManager::createMsgTextComplex(const ucstring &msg, NLMISC::C
ucstring::size_type pos = 0; ucstring::size_type pos = 0;
// Manage Translations
CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CHAT:SHOW_TRANSLATION_ONLY_AS_TOOLTIP_CB", false);
bool originalFirst = node->getValueBool();
string::size_type startTr = msg.find(ucstring("{:")); string::size_type startTr = msg.find(ucstring("{:"));
string::size_type endOfOriginal = msg.find(ucstring("}@{")); string::size_type endOfOriginal = msg.find(ucstring("}@{"));
// Original/Translated case, example: {:enHello the world!}@{ Bonjour le monde ! // Original/Translated case, example: {:enHello the world!}@{ Bonjour le monde !
if (startTr != string::npos && endOfOriginal != string::npos) 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); CViewBase *vt = createMsgTextSimple(msg.substr(0, startTr), col, justified, NULL);
para->addChild(vt); para->addChild(vt);
string texture = "flag-"+toLower(msg.substr(startTr+2, 2)).toString()+".tga"; string texture = "flag-"+toLower(msg.substr(startTr+2, 2)).toString()+".tga";
ucstring original = msg.substr(startTr+5, endOfOriginal-startTr-5); ucstring original = msg.substr(startTr+5, endOfOriginal-startTr-5);
ucstring translation = msg.substr(endOfOriginal+3); ucstring translation = msg.substr(endOfOriginal+4);
CCtrlButton *ctrlButton = new CCtrlButton(CViewBase::TCtorParam()); CCtrlButton *ctrlButton = new CCtrlButton(CViewBase::TCtorParam());
ctrlButton->setTexture(texture); ctrlButton->setTexture(texture);
ctrlButton->setTextureOver(texture); ctrlButton->setTextureOver(texture);
ctrlButton->setTexturePushed(texture); ctrlButton->setTexturePushed(texture);
if (!originalFirst) if (!inverse)
{ {
ctrlButton->setDefaultContextHelp(original); ctrlButton->setDefaultContextHelp(original);
pos = endOfOriginal+3; pos = endOfOriginal+4;
} }
else else
{ {
@ -456,8 +463,12 @@ CViewBase *CChatTextManager::createMsgTextComplex(const ucstring &msg, NLMISC::C
textSize = endOfOriginal; textSize = endOfOriginal;
} }
ctrlButton->setId("tr"); ctrlButton->setId("tr");
if (hideFlag) {
delete ctrlButton;
} else {
para->addChild(ctrlButton); para->addChild(ctrlButton);
} }
}
// quickly check if text has links or not // quickly check if text has links or not
bool hasUrl; bool hasUrl;

@ -216,7 +216,25 @@ void CChatWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CChatGr
gl = dynamic_cast<CGroupList *>(_Chat->getGroup("cb:text_list")); gl = dynamic_cast<CGroupList *>(_Chat->getGroup("cb:text_list"));
CViewBase *child = 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 (child)
{ {
if (gl) gl->addChild(child); if (gl) gl->addChild(child);
@ -568,6 +586,18 @@ void CChatGroupWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CC
ucstring newmsg = msg; ucstring newmsg = msg;
ucstring prefix; ucstring prefix;
CCDBNodeLeaf *nodeNoTranslation = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:TRANSLATION:" + toUpper(CChatGroup::groupTypeToString(gt)) + ":DISABLE", false);
bool 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; CViewBase *child = NULL;
if (gl != NULL) if (gl != NULL)
{ {

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

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

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

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

@ -28,6 +28,7 @@
#include "nel/gui/action_handler.h" #include "nel/gui/action_handler.h"
#include "../entities.h" #include "../entities.h"
#include "nel/gui/group_paragraph.h" // For CCtrlLink #include "nel/gui/group_paragraph.h" // For CCtrlLink
#include "nel/gui/view_bitmap.h"
#include "../net_manager.h" #include "../net_manager.h"
#include "../string_manager_client.h" #include "../string_manager_client.h"
#include "../login.h" #include "../login.h"
@ -644,14 +645,42 @@ void CGroupInSceneBubbleManager::addMessagePopupCenter (const ucstring &message,
"ui:interface", templateParams.empty()?NULL:&(templateParams[0]), (uint)templateParams.size()); "ui:interface", templateParams.empty()?NULL:&(templateParams[0]), (uint)templateParams.size());
if (group) if (group)
{ {
ucstring finalMessage = message;
ucstring::size_type pos = message.find(ucstring("|"));
if (pos != std::string::npos)
{
CViewBitmap *pViewIcon = dynamic_cast<CViewBitmap*>(group->getView("iconA"));
if (pViewIcon != NULL)
{
string texture = message.substr(0, pos).toString();
pViewIcon->setTexture(texture);
}
ucstring::size_type end = message.find(ucstring("|"), pos+1);
if (end != std::string::npos)
{
CViewBitmap *pViewIcon = dynamic_cast<CViewBitmap*>(group->getView("iconZ"));
if (pViewIcon != NULL)
{
string texture = message.substr(end+1).toString();
pViewIcon->setTexture(texture);
}
finalMessage = message.substr(pos+1, end-pos-1);
}
else
finalMessage = message.substr(pos+1);
}
// Skill name // Skill name
CViewText *pViewName = dynamic_cast<CViewText*>(group->getView("name")); CViewText *pViewName = dynamic_cast<CViewText*>(group->getView("name"));
if (pViewName != NULL) if (pViewName != NULL)
{ {
pViewName->setTextFormatTaged(message); pViewName->setTextFormatTaged(finalMessage);
pViewName->setColor (color); pViewName->setColor (color);
} }
// Link to the interface // Link to the interface
CWidgetManager::getInstance()->addWindowToMasterGroup("ui:interface", group); CWidgetManager::getInstance()->addWindowToMasterGroup("ui:interface", group);
CInterfaceGroup *pRoot = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId("ui:interface")); CInterfaceGroup *pRoot = dynamic_cast<CInterfaceGroup*>(CWidgetManager::getInstance()->getElementFromId("ui:interface"));
@ -846,16 +875,20 @@ void CGroupInSceneBubbleManager::chatOpen (uint32 nUID, const ucstring &ucsText,
// Clean bubble from translation system // Clean bubble from translation system
CCDBNodeLeaf *node= NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CHAT:SHOW_TRANSLATION_ONLY_AS_TOOLTIP_CB", false);
bool originalFirst = node->getValueBool();
ucstring::size_type pos = 0; ucstring::size_type pos = 0;
ucstring::size_type textSize = ucsText.size(); ucstring::size_type textSize = ucsText.size();
string::size_type startTr = ucsText.find(ucstring("{:")); string::size_type startTr = ucsText.find(ucstring("{:"));
string::size_type endOfOriginal = ucsText.find(ucstring("}@{")); string::size_type endOfOriginal = ucsText.find(ucstring("}@{"));
if (endOfOriginal != string::npos)
{ if (startTr != string::npos && endOfOriginal != string::npos) {
if (!originalFirst) 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; pos = endOfOriginal+4;
} }

@ -2654,7 +2654,7 @@ void CGroupMap::createContinentLandMarks()
static void hideTeleportButtonsInPopupMenuIfNotEnoughPriv() static void hideTeleportButtonsInPopupMenuIfNotEnoughPriv()
{ {
bool showTeleport = (hasPrivilegeDEV() || hasPrivilegeSGM() || hasPrivilegeGM() || hasPrivilegeVG() || hasPrivilegeSG() || hasPrivilegeEM() || hasPrivilegeEG() || hasPrivilegeOBSERVER()); bool showTeleport = (hasPrivilegeDEV() || hasPrivilegeSGM() || hasPrivilegeGM() || hasPrivilegeVG() || hasPrivilegeSG() || hasPrivilegeEM() || hasPrivilegeEG() || hasPrivilegeOBSERVER()|| hasPrivilegeTESTER());
CInterfaceManager *im = CInterfaceManager::getInstance(); CInterfaceManager *im = CInterfaceManager::getInstance();
CInterfaceElement *ie = CWidgetManager::getInstance()->getElementFromId("ui:interface:map_menu:teleport"); CInterfaceElement *ie = CWidgetManager::getInstance()->getElementFromId("ui:interface:map_menu:teleport");

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

@ -2523,6 +2523,17 @@ void CInterfaceManager::displaySystemInfo(const ucstring &str, const string &cat
CClientConfig::SSysInfoParam::TMode mode = CClientConfig::SSysInfoParam::Normal; CClientConfig::SSysInfoParam::TMode mode = CClientConfig::SSysInfoParam::Normal;
CRGBA color = CRGBA::White; CRGBA color = CRGBA::White;
ucstring cleanStr = str;
ucstring::size_type pos = str.find(ucstring("|"));
if (pos != std::string::npos)
{
ucstring::size_type end = str.find(ucstring("|"), pos+1);
if (end != std::string::npos)
cleanStr = str.substr(pos+1, end-pos-1);
else
cleanStr = str.substr(pos+1);
}
// If broadcast, parse lua code // If broadcast, parse lua code
if (toLower(cat) == "bc" && str.size() > 3 && str[0]=='@' && str[1]=='L' && str[2]=='U' && str[3]=='A') if (toLower(cat) == "bc" && str.size() > 3 && str[0]=='@' && str[1]=='L' && str[2]=='U' && str[3]=='A')
{ {
@ -2542,11 +2553,11 @@ void CInterfaceManager::displaySystemInfo(const ucstring &str, const string &cat
if (mode != CClientConfig::SSysInfoParam::OverOnly && mode != CClientConfig::SSysInfoParam::Around) if (mode != CClientConfig::SSysInfoParam::OverOnly && mode != CClientConfig::SSysInfoParam::Around)
{ {
if (PeopleInterraction.SystemInfo) if (PeopleInterraction.SystemInfo)
PeopleInterraction.ChatInput.SystemInfo.displayMessage(str, color, 2); PeopleInterraction.ChatInput.SystemInfo.displayMessage(cleanStr, color, 2);
else else
{ {
CPeopleInterraction::CSysMsg sysMsg; CPeopleInterraction::CSysMsg sysMsg;
sysMsg.Str = str; sysMsg.Str = cleanStr;
sysMsg.Cat = cat; sysMsg.Cat = cat;
PeopleInterraction.SystemMessageBuffer.push_back( sysMsg ); PeopleInterraction.SystemMessageBuffer.push_back( sysMsg );
} }
@ -2557,10 +2568,10 @@ void CInterfaceManager::displaySystemInfo(const ucstring &str, const string &cat
// If over popup a string at the bottom of the screen // If over popup a string at the bottom of the screen
if ((mode == CClientConfig::SSysInfoParam::Over) || (mode == CClientConfig::SSysInfoParam::OverOnly)) if ((mode == CClientConfig::SSysInfoParam::Over) || (mode == CClientConfig::SSysInfoParam::OverOnly))
InSceneBubbleManager.addMessagePopup(str, color); InSceneBubbleManager.addMessagePopup(cleanStr, color);
else if ( (mode == CClientConfig::SSysInfoParam::Around || mode == CClientConfig::SSysInfoParam::CenterAround) else if ( (mode == CClientConfig::SSysInfoParam::Around || mode == CClientConfig::SSysInfoParam::CenterAround)
&& PeopleInterraction.AroundMe.Window) && PeopleInterraction.AroundMe.Window)
PeopleInterraction.ChatInput.AroundMe.displayMessage(str, color, 2); PeopleInterraction.ChatInput.AroundMe.displayMessage(cleanStr, color, 2);
} }

@ -184,6 +184,21 @@ private:
REGISTER_ACTION_HANDLER(CHandlerLUA, "lua"); REGISTER_ACTION_HANDLER(CHandlerLUA, "lua");
std::deque<CRefPtr<CCtrlBase> > CHandlerLUA::_UICallerStack; std::deque<CRefPtr<CCtrlBase> > CHandlerLUA::_UICallerStack;
// ***************************************************************************
class CHandlerSCRIPT : public IActionHandler
{
public:
void execute(CCtrlBase *pCaller, const std::string &sParams)
{
string script = sParams;
while(strFindReplace(script, "[", ""));
while(strFindReplace(script, "]", ""));
strFindReplace(script, "|", "\n");
CLuaManager::getInstance().executeLuaScript("\ngame:executeRyzomScript([["+script+"]])\n", true);
}
};
REGISTER_ACTION_HANDLER(CHandlerSCRIPT, "script");
// *************************************************************************** // ***************************************************************************
// Allow also to call script from expression // Allow also to call script from expression
static DECLARE_INTERFACE_USER_FCT(lua) static DECLARE_INTERFACE_USER_FCT(lua)
@ -566,6 +581,7 @@ void CLuaIHMRyzom::RegisterRyzomFunctions(NLGUI::CLuaState &ls)
LUABIND_FUNC(isFullyPatched), LUABIND_FUNC(isFullyPatched),
LUABIND_FUNC(getSheetType), LUABIND_FUNC(getSheetType),
LUABIND_FUNC(getSheetShape), LUABIND_FUNC(getSheetShape),
LUABIND_FUNC(getCharacterSheetScale),
LUABIND_FUNC(getSheetFamily), LUABIND_FUNC(getSheetFamily),
LUABIND_FUNC(getSheetName), LUABIND_FUNC(getSheetName),
LUABIND_FUNC(getFameIndex), LUABIND_FUNC(getFameIndex),
@ -3493,7 +3509,15 @@ std::string CLuaIHMRyzom::getSheetShape(const std::string &sheet)
return ""; return "";
} }
// ***************************************************************************
float CLuaIHMRyzom::getCharacterSheetScale(const std::string &sheet)
{
const CEntitySheet *sheetPtr = SheetMngr.get(CSheetId(sheet));
const CCharacterSheet *charSheet = dynamic_cast<const CCharacterSheet*>(sheetPtr);
if (charSheet) return charSheet->Scale;
return 1;
}
// *************************************************************************** // ***************************************************************************
std::string CLuaIHMRyzom::getSheetFamily(const std::string &sheet) std::string CLuaIHMRyzom::getSheetFamily(const std::string &sheet)
@ -3904,40 +3928,40 @@ sint32 CLuaIHMRyzom::getPlayerLevel()
// *************************************************************************** // ***************************************************************************
std::string CLuaIHMRyzom::getPlayerVpaHex() std::string CLuaIHMRyzom::getPlayerVpaHex()
{ {
uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPA))->getValue64(); sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPA))->getValue64();
return NLMISC::toString("%X", prop); return NLMISC::toString("%" NL_I64 "X", prop);
} }
// *************************************************************************** // ***************************************************************************
std::string CLuaIHMRyzom::getPlayerVpbHex() std::string CLuaIHMRyzom::getPlayerVpbHex()
{ {
uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64(); sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64();
return NLMISC::toString("%X", prop); return NLMISC::toString("%" NL_I64 "X", prop);
} }
// *************************************************************************** // ***************************************************************************
std::string CLuaIHMRyzom::getPlayerVpcHex() std::string CLuaIHMRyzom::getPlayerVpcHex()
{ {
uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPC))->getValue64(); sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPC))->getValue64();
return NLMISC::toString("%X", prop); return NLMISC::toString("%" NL_I64 "X", prop);
} }
// *************************************************************************** // ***************************************************************************
sint64 CLuaIHMRyzom::getPlayerVpa() uint64 CLuaIHMRyzom::getPlayerVpa()
{ {
uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPA))->getValue64(); uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPA))->getValue64();
return prop; return prop;
} }
// *************************************************************************** // ***************************************************************************
sint64 CLuaIHMRyzom::getPlayerVpb() uint64 CLuaIHMRyzom::getPlayerVpb()
{ {
uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64(); uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64();
return prop; return prop;
} }
// *************************************************************************** // ***************************************************************************
sint64 CLuaIHMRyzom::getPlayerVpc() uint64 CLuaIHMRyzom::getPlayerVpc()
{ {
uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPC))->getValue64(); uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E0:P" + toString("%d", CLFECOMMON::PROPERTY_VPC))->getValue64();
return prop; return prop;
@ -3989,8 +4013,8 @@ std::string CLuaIHMRyzom::getTargetVpaHex()
CEntityCL *target = getTargetEntity(); CEntityCL *target = getTargetEntity();
if (!target) return 0; if (!target) return 0;
uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPA))->getValue64(); sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPA))->getValue64();
return NLMISC::toString("%X", prop); return NLMISC::toString("%" NL_I64 "X", prop);
} }
// *************************************************************************** // ***************************************************************************
@ -3999,8 +4023,8 @@ std::string CLuaIHMRyzom::getTargetVpbHex()
CEntityCL *target = getTargetEntity(); CEntityCL *target = getTargetEntity();
if (!target) return 0; if (!target) return 0;
uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64(); sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64();
return NLMISC::toString("%X", prop); return NLMISC::toString("%" NL_I64 "X", prop);
} }
// *************************************************************************** // ***************************************************************************
@ -4009,40 +4033,37 @@ std::string CLuaIHMRyzom::getTargetVpcHex()
CEntityCL *target = getTargetEntity(); CEntityCL *target = getTargetEntity();
if (!target) return 0; if (!target) return 0;
uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPC))->getValue64(); sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPC))->getValue64();
return NLMISC::toString("%X", prop); return NLMISC::toString("%" NL_I64 "X", prop);
} }
// *************************************************************************** // ***************************************************************************
sint64 CLuaIHMRyzom::getTargetVpa() uint64 CLuaIHMRyzom::getTargetVpa()
{ {
CEntityCL *target = getTargetEntity(); CEntityCL *target = getTargetEntity();
if (!target) return 0; if (!target) return 0;
uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPA))->getValue64(); uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPA))->getValue64();
return prop; return prop;
} }
// *************************************************************************** // ***************************************************************************
sint64 CLuaIHMRyzom::getTargetVpb() uint64 CLuaIHMRyzom::getTargetVpb()
{ {
CEntityCL *target = getTargetEntity(); CEntityCL *target = getTargetEntity();
if (!target) return 0; if (!target) return 0;
sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64(); uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64();
return prop; return prop;
} }
// *************************************************************************** // ***************************************************************************
sint64 CLuaIHMRyzom::getTargetVpc() uint64 CLuaIHMRyzom::getTargetVpc()
{ {
CEntityCL *target = getTargetEntity(); CEntityCL *target = getTargetEntity();
if (!target) return 0; if (!target) return 0;
sint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPC))->getValue64(); uint64 prop = NLGUI::CDBManager::getInstance()->getDbProp("SERVER:Entities:E" + toString("%d", getTargetSlotNr()) + ":P" + toString("%d", CLFECOMMON::PROPERTY_VPC))->getValue64();
return prop; return prop;
} }

@ -204,6 +204,8 @@ private:
static bool isDynStringAvailable(sint32 dynStringId); static bool isDynStringAvailable(sint32 dynStringId);
static bool isFullyPatched(); static bool isFullyPatched();
static std::string getSheetType(const std::string &sheet); static std::string getSheetType(const std::string &sheet);
static std::string getSheetShape(const std::string &sheet);
static float getCharacterSheetScale(const std::string &sheet);
static std::string getSheetFamily(const std::string &sheet); static std::string getSheetFamily(const std::string &sheet);
static std::string getSheetName(uint32 sheetId); static std::string getSheetName(uint32 sheetId);
static sint32 getFameIndex(const std::string &factionName); static sint32 getFameIndex(const std::string &factionName);
@ -271,9 +273,9 @@ private:
static std::string getPlayerVpaHex(); static std::string getPlayerVpaHex();
static std::string getPlayerVpbHex(); static std::string getPlayerVpbHex();
static std::string getPlayerVpcHex(); static std::string getPlayerVpcHex();
static sint64 getPlayerVpa(); static uint64 getPlayerVpa();
static sint64 getPlayerVpb(); static uint64 getPlayerVpb();
static sint64 getPlayerVpc(); static uint64 getPlayerVpc();
static sint32 getTargetLevel(); // get current, precise level of the selected target, or -1 if there's no such selected target static sint32 getTargetLevel(); // get current, precise level of the selected target, or -1 if there's no such selected target
static sint32 getTargetForceRegion(); // get 'force region' for current target, or -1 if there's no selected target static sint32 getTargetForceRegion(); // get 'force region' for current target, or -1 if there's no selected target
static sint32 getTargetLevelForce(); // get 'level force' for current target, or -1 if there's no selected target static sint32 getTargetLevelForce(); // get 'level force' for current target, or -1 if there's no selected target
@ -281,9 +283,9 @@ private:
static std::string getTargetVpaHex(); static std::string getTargetVpaHex();
static std::string getTargetVpbHex(); static std::string getTargetVpbHex();
static std::string getTargetVpcHex(); static std::string getTargetVpcHex();
static sint64 getTargetVpa(); static uint64 getTargetVpa();
static sint64 getTargetVpb(); static uint64 getTargetVpb();
static sint64 getTargetVpc(); static uint64 getTargetVpc();
static bool isTargetNPC(); // return 'true' if the target is an npc static bool isTargetNPC(); // return 'true' if the target is an npc
static bool isTargetPlayer(); // return 'true' if the target is a player static bool isTargetPlayer(); // return 'true' if the target is a player
static bool isTargetUser(); // return 'true' if the target is the user static bool isTargetUser(); // return 'true' if the target is the user

@ -33,6 +33,7 @@
#include "game_share/chat_group.h" #include "game_share/chat_group.h"
#include "game_share/character_summary.h" #include "game_share/character_summary.h"
#include "game_share/sphrase_com.h" #include "game_share/sphrase_com.h"
#include "game_share/outpost.h"
#include "game_share/msg_client_server.h" #include "game_share/msg_client_server.h"
#include "game_share/ryzom_database_banks.h" #include "game_share/ryzom_database_banks.h"
#include "game_share/msg_encyclopedia.h" #include "game_share/msg_encyclopedia.h"
@ -3205,9 +3206,11 @@ void impulseUserBars(NLMISC::CBitMemStream &impulse)
void impulseOutpostChooseSide(NLMISC::CBitMemStream &impulse) void impulseOutpostChooseSide(NLMISC::CBitMemStream &impulse)
{ {
// read message // read message
uint8 type;
bool outpostInFire; bool outpostInFire;
bool playerGuildInConflict; bool playerGuildInConflict;
bool playerGuildIsAttacker; bool playerGuildIsAttacker;
impulse.serial(type);
impulse.serial(outpostInFire); impulse.serial(outpostInFire);
impulse.serial(playerGuildInConflict); impulse.serial(playerGuildInConflict);
impulse.serial(playerGuildIsAttacker); impulse.serial(playerGuildIsAttacker);
@ -3219,7 +3222,7 @@ void impulseOutpostChooseSide(NLMISC::CBitMemStream &impulse)
impulse.serial( declTimer ); impulse.serial( declTimer );
// start // start
OutpostManager.startPvpJoinProposal(outpostInFire, playerGuildInConflict, playerGuildIsAttacker, OutpostManager.startPvpJoinProposal((OUTPOSTENUMS::TPVPType)type, outpostInFire, playerGuildInConflict, playerGuildIsAttacker,
ownerGuildNameId, attackerGuildNameId, declTimer); ownerGuildNameId, attackerGuildNameId, declTimer);
} }

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

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

@ -40,7 +40,7 @@ COutpostManager::COutpostManager()
// *************************************************************************** // ***************************************************************************
void COutpostManager::startPvpJoinProposal(bool outpostInFire, bool playerGuildInConflict, bool playerGuildIsAttacker, void COutpostManager::startPvpJoinProposal(OUTPOSTENUMS::TPVPType type, bool outpostInFire, bool playerGuildInConflict, bool playerGuildIsAttacker,
uint32 ownerGuildNameId, uint32 attackerGuildNameId, uint32 declTimer) uint32 ownerGuildNameId, uint32 attackerGuildNameId, uint32 declTimer)
{ {
// reset counter that force player to be neutral (eg: 10 seconds) // reset counter that force player to be neutral (eg: 10 seconds)
@ -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")); CCtrlBase *ctrl = dynamic_cast<CCtrlBase *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal:content:random"));
if (ctrl) if (ctrl)
ctrl->setActive(outpostInFire); ctrl->setActive(type != OUTPOSTENUMS::GVE && outpostInFire);
ctrl = dynamic_cast<CCtrlBase *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal:content:neutral")); ctrl = dynamic_cast<CCtrlBase *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal:content:neutral"));
if (ctrl) if (ctrl)
ctrl->setActive(!outpostInFire); ctrl->setActive(type == OUTPOSTENUMS::GVE || !outpostInFire);
// GvE: only attacker guild can have the option
ctrl = dynamic_cast<CCtrlBase *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal:content:attack"));
if (ctrl && type == OUTPOSTENUMS::GVE)
ctrl->setActive(playerGuildIsAttacker);
// GvE : No defend option
ctrl = dynamic_cast<CCtrlBase *>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal:content:defend"));
if (ctrl && type == OUTPOSTENUMS::GVE)
ctrl->setActive(false);
CGroupContainer *pGC = dynamic_cast<CGroupContainer*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal")); CGroupContainer *pGC = dynamic_cast<CGroupContainer*>(CWidgetManager::getInstance()->getElementFromId("ui:interface:join_pvp_outpost_proposal"));
if (pGC) if (pGC)

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

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

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

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

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

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

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

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

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

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

Loading…
Cancel
Save