Merge commit '230639bf0ead1a3736aca3af8866aa00f0608074'

ryzomclassic-develop
kaetemi 5 years ago
commit 3ff031b5ff

@ -106,7 +106,10 @@ public:
class ITexture : public CBitmap, public NLMISC::CRefCount, public NLMISC::IStreamable class ITexture : public CBitmap, public NLMISC::CRefCount, public NLMISC::IStreamable
{ {
public: public:
#ifndef RYZOM_FORGE
NL_USES_DEFAULT_ARENA_OBJECT_ALLOCATOR // for fast alloc NL_USES_DEFAULT_ARENA_OBJECT_ALLOCATOR // for fast alloc
#endif
// Those enums MUST be the same than in UTexture!! // Those enums MUST be the same than in UTexture!!
enum TWrapMode enum TWrapMode
{ {

@ -167,11 +167,8 @@ namespace NLGUI
return Current.FontSize-2; return Current.FontSize-2;
} }
sint styleStackIndex = 0;
inline void pushStyle() inline void pushStyle()
{ {
styleStackIndex++;
_StyleStack.push_back(Current); _StyleStack.push_back(Current);
Current.DisplayBlock = false; Current.DisplayBlock = false;
@ -186,7 +183,6 @@ namespace NLGUI
inline void popStyle() inline void popStyle()
{ {
styleStackIndex--;
if (_StyleStack.empty()) if (_StyleStack.empty())
{ {
Current = Root; Current = Root;

@ -124,9 +124,11 @@ namespace NLGUI
// Event part // Event part
void setActionOnLeftClick (const std::string &actionHandlerName) { _AHOnLeftClickString = actionHandlerName; _AHOnLeftClick = CAHManager::getInstance()->getAH(actionHandlerName, _AHLeftClickParams); } void setActionOnLeftClick (const std::string &actionHandlerName) { _AHOnLeftClickString = actionHandlerName; _AHOnLeftClick = CAHManager::getInstance()->getAH(actionHandlerName, _AHLeftClickParams); }
void setActionOnLeftClickParams(const std::string &params) { _AHOnLeftClickStringParams = params; } void setActionOnLeftClickParams(const std::string &params) { _AHOnLeftClickStringParams = params; }
void setActionOnOver (const std::string &actionHandlerName) { _AHOnOver = CAHManager::getInstance()->getAH(actionHandlerName, _AHOverParams); }
void setActionOnRightClick (const std::string &actionHandlerName) { _AHOnRightClick = CAHManager::getInstance()->getAH(actionHandlerName, _AHRightClickParams); } void setActionOnRightClick (const std::string &actionHandlerName) { _AHOnRightClick = CAHManager::getInstance()->getAH(actionHandlerName, _AHRightClickParams); }
void setActionOnClockTick (const std::string &ahName) { _AHOnClockTick = CAHManager::getInstance()->getAH(ahName, _AHClockTickParams); } void setActionOnClockTick (const std::string &ahName) { _AHOnClockTick = CAHManager::getInstance()->getAH(ahName, _AHClockTickParams); }
void setParamsOnLeftClick (const std::string &paramsHandlerName) { _AHLeftClickParams = paramsHandlerName; } void setParamsOnLeftClick (const std::string &paramsHandlerName) { _AHLeftClickParams = paramsHandlerName; }
void setParamsOnOver (const std::string &paramsHandlerName) { _AHOverParams = paramsHandlerName; }
void setParamsOnRightClick (const std::string &paramsHandlerName) { _AHRightClickParams = paramsHandlerName; } void setParamsOnRightClick (const std::string &paramsHandlerName) { _AHRightClickParams = paramsHandlerName; }
void setParamsOnClockTick (const std::string &ahParamsName) { _AHClockTickParams = ahParamsName; } void setParamsOnClockTick (const std::string &ahParamsName) { _AHClockTickParams = ahParamsName; }
@ -143,12 +145,14 @@ namespace NLGUI
IActionHandler *getActionOnClockTick () const { return _AHOnClockTick; } IActionHandler *getActionOnClockTick () const { return _AHOnClockTick; }
std::string _getParamsOnOver() const{ return _AHOverParams.toString(); } std::string _getParamsOnOver() const{ return _AHOverParams.toString(); }
std::string _getParamsOnLeftClick () const { return _AHLeftClickParams.toString(); } std::string _getParamsOnLeftClick () const { return _AHLeftClickParams.toString(); }
std::string _getParamsOnRightClick () const { return _AHRightClickParams.toString(); }
const std::string &getParamsOnLeftClick () const { return _AHLeftClickParams; } const std::string &getParamsOnLeftClick () const { return _AHLeftClickParams; }
const std::string &getParamsOnRightClick () const { return _AHRightClickParams; } const std::string &getParamsOnRightClick () const { return _AHRightClickParams; }
const std::string &getParamsOnClockTick () const { return _AHClockTickParams; } const std::string &getParamsOnClockTick () const { return _AHClockTickParams; }
// run action on left click // run action on left click
void runLeftClickAction(); void runLeftClickAction();
void runRightClickAction();
// Context menu accessor/ One for each button // Context menu accessor/ One for each button
void setListMenuLeft (const std::string &cm) { _ListMenuLeft = cm; } void setListMenuLeft (const std::string &cm) { _ListMenuLeft = cm; }
@ -161,6 +165,7 @@ namespace NLGUI
int luaRunLeftClickAction(CLuaState &ls); int luaRunLeftClickAction(CLuaState &ls);
int luaRunRightClickAction(CLuaState &ls);
REFLECT_EXPORT_START(CCtrlBaseButton, CCtrlBase) REFLECT_EXPORT_START(CCtrlBaseButton, CCtrlBase)
REFLECT_BOOL("pushed", getPushed, setPushed); REFLECT_BOOL("pushed", getPushed, setPushed);
REFLECT_STRING("col_normal", getColorAsString, setColorAsString); REFLECT_STRING("col_normal", getColorAsString, setColorAsString);
@ -174,6 +179,11 @@ namespace NLGUI
REFLECT_STRING("onclick_l", _getActionOnLeftClick, setActionOnLeftClick); REFLECT_STRING("onclick_l", _getActionOnLeftClick, setActionOnLeftClick);
REFLECT_STRING("params_l", _getParamsOnLeftClick, setParamsOnLeftClick); REFLECT_STRING("params_l", _getParamsOnLeftClick, setParamsOnLeftClick);
REFLECT_LUA_METHOD("runLeftClickAction", luaRunLeftClickAction); REFLECT_LUA_METHOD("runLeftClickAction", luaRunLeftClickAction);
REFLECT_STRING("onclick_r", _getActionOnRightClick, setActionOnRightClick);
REFLECT_STRING("params_r", _getParamsOnRightClick, setParamsOnRightClick);
REFLECT_LUA_METHOD("runRightClickAction", luaRunRightClickAction);
REFLECT_STRING("onover", _getActionOnOver, setActionOnOver);
REFLECT_STRING("params_over", _getParamsOnOver, setParamsOnOver);
REFLECT_EXPORT_END REFLECT_EXPORT_END
protected: protected:

@ -274,10 +274,13 @@ namespace NLGUI
// Lua exports // Lua exports
int luaBlink(CLuaState &ls); int luaBlink(CLuaState &ls);
int luaSetHeaderColor(CLuaState &ls); int luaSetHeaderColor(CLuaState &ls);
int luaSetModalParentList(CLuaState &ls);
REFLECT_EXPORT_START(CGroupContainer, CGroupContainerBase) REFLECT_EXPORT_START(CGroupContainer, CGroupContainerBase)
REFLECT_LUA_METHOD("blink", luaBlink); REFLECT_LUA_METHOD("blink", luaBlink);
REFLECT_LUA_METHOD("setHeaderColor", luaSetHeaderColor); REFLECT_LUA_METHOD("setHeaderColor", luaSetHeaderColor);
REFLECT_LUA_METHOD("setModalParentList", luaSetModalParentList);
REFLECT_STRING("title", getTitle, setTitle); REFLECT_STRING("title", getTitle, setTitle);
REFLECT_STRING("title_opened", getTitleOpened, setTitleOpened); REFLECT_STRING("title_opened", getTitleOpened, setTitleOpened);
REFLECT_STRING("title_closed", getTitleClosed, setTitleClosed); REFLECT_STRING("title_closed", getTitleClosed, setTitleClosed);

@ -211,6 +211,8 @@ namespace NLGUI
// Browser home // Browser home
std::string Home; std::string Home;
// Get Home URL
virtual std::string home();
// Undo browse: Browse the precedent url browsed. no op if none // Undo browse: Browse the precedent url browsed. no op if none
void browseUndo (); void browseUndo ();
@ -225,6 +227,10 @@ namespace NLGUI
std::string getURL() const { return _URL; } std::string getURL() const { return _URL; }
void setURL(const std::string &url); void setURL(const std::string &url);
std::string getHTML() const { return _DocumentHtml; }
void setHTML(const std::string &html);
void setHome(const std::string &home);
int luaClearRefresh(CLuaState &ls); int luaClearRefresh(CLuaState &ls);
int luaClearUndoRedo(CLuaState &ls); int luaClearUndoRedo(CLuaState &ls);
@ -237,6 +243,7 @@ namespace NLGUI
int luaShowDiv(CLuaState &ls); int luaShowDiv(CLuaState &ls);
int luaParseHtml(CLuaState &ls); int luaParseHtml(CLuaState &ls);
int luaRenderHtml(CLuaState &ls); int luaRenderHtml(CLuaState &ls);
int luaSetBackground(CLuaState &ls);
REFLECT_EXPORT_START(CGroupHTML, CGroupScrollText) REFLECT_EXPORT_START(CGroupHTML, CGroupScrollText)
REFLECT_LUA_METHOD("browse", luaBrowse) REFLECT_LUA_METHOD("browse", luaBrowse)
@ -250,7 +257,10 @@ namespace NLGUI
REFLECT_LUA_METHOD("showDiv", luaShowDiv) REFLECT_LUA_METHOD("showDiv", luaShowDiv)
REFLECT_LUA_METHOD("parseHtml", luaParseHtml) REFLECT_LUA_METHOD("parseHtml", luaParseHtml)
REFLECT_LUA_METHOD("renderHtml", luaRenderHtml) REFLECT_LUA_METHOD("renderHtml", luaRenderHtml)
REFLECT_LUA_METHOD("setBackground", luaSetBackground)
REFLECT_STRING("url", getURL, setURL) REFLECT_STRING("url", getURL, setURL)
REFLECT_STRING("html", getHTML, setHTML)
REFLECT_STRING("home", home, setHome)
REFLECT_FLOAT("timeout", getTimeout, setTimeout) REFLECT_FLOAT("timeout", getTimeout, setTimeout)
REFLECT_STRING("title", getTitle, setTitle) REFLECT_STRING("title", getTitle, setTitle)
REFLECT_EXPORT_END REFLECT_EXPORT_END
@ -280,9 +290,6 @@ namespace NLGUI
// Add POST params to the libwww list // Add POST params to the libwww list
virtual void addHTTPPostParams (SFormFields &formfields, bool trustedDomain); virtual void addHTTPPostParams (SFormFields &formfields, bool trustedDomain);
// Get Home URL
virtual std::string home();
// parse dom node and all child nodes recursively // parse dom node and all child nodes recursively
void renderDOM(CHtmlElement &elm); void renderDOM(CHtmlElement &elm);
@ -355,7 +362,7 @@ namespace NLGUI
// Current URL // Current URL
std::string _DocumentUrl; std::string _DocumentUrl;
std::string _DocumentDomain; std::string _DocumentDomain;
std::string _DocumentHtml; // not updated, only set by first render std::string _DocumentHtml; // not updated only set by first render
// If true, then render _DocumentHtml on next update (replaces content) // If true, then render _DocumentHtml on next update (replaces content)
bool _RenderNextTime; bool _RenderNextTime;
// 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)

@ -137,6 +137,9 @@ namespace NLGUI
const std::string getActionHandler(uint lineIndex) const; const std::string getActionHandler(uint lineIndex) const;
const std::string getActionHandlerParam(uint lineIndex) const; const std::string getActionHandlerParam(uint lineIndex) const;
void setActionHandler(uint lineIndex, const std::string &ah = "");
void setActionHandlerParam(uint lineIndex, const std::string &params = "");
void openSubMenu (sint32 nb); void openSubMenu (sint32 nb);
void hideSubMenus (); void hideSubMenus ();
@ -330,6 +333,8 @@ namespace NLGUI
const std::string getActionHandler(uint lineIndex) const; const std::string getActionHandler(uint lineIndex) const;
const std::string getActionHandlerParam(uint lineIndex) const; const std::string getActionHandlerParam(uint lineIndex) const;
void setActionHandler(uint lineIndex, const std::string &ah = "");
void setActionHandlerParam(uint lineIndex, const std::string &params = "");
void addLine (const ucstring &name, const std::string &ah = "", const std::string &params = "", void addLine (const ucstring &name, const std::string &ah = "", const std::string &params = "",
const std::string &id = std::string(), const std::string &id = std::string(),

@ -321,6 +321,8 @@ namespace NLGUI
void deleteLUAEnvTable(bool recurse = false); void deleteLUAEnvTable(bool recurse = false);
// Set the LUA script to execute at checkCoords time (empty to reset) // Set the LUA script to execute at checkCoords time (empty to reset)
void setLuaScriptOnDraw(const std::string &script); void setLuaScriptOnDraw(const std::string &script);
// Get the LUA script executed at checkCoords time
inline CStringShared getLuaScriptOnDraw() { return _LUAOnDraw; }
// //
void executeLuaScriptOnDraw(); void executeLuaScriptOnDraw();
// Set the LUA script to execute when a list of DB change (of forms: "@DB1,@DB2" ....). The dbList is the key // Set the LUA script to execute when a list of DB change (of forms: "@DB1,@DB2" ....). The dbList is the key

@ -161,6 +161,7 @@ namespace NLGUI
static int luaMethodCall(lua_State *ls); static int luaMethodCall(lua_State *ls);
static int setOnDraw(CLuaState &ls); // params: CInterfaceGroup*, "script". return: none static int setOnDraw(CLuaState &ls); // params: CInterfaceGroup*, "script". return: none
static int getOnDraw(CLuaState &ls); // params: CInterfaceGroup*. return: "script" (nil if none)
static int addOnDbChange(CLuaState &ls); // params: CInterfaceGroup*, "dblist", "script". return: none static int addOnDbChange(CLuaState &ls); // params: CInterfaceGroup*, "dblist", "script". return: none
static int removeOnDbChange(CLuaState &ls);// params: CInterfaceGroup*. return: none static int removeOnDbChange(CLuaState &ls);// params: CInterfaceGroup*. return: none
static int setCaptureKeyboard(CLuaState &ls); static int setCaptureKeyboard(CLuaState &ls);

@ -276,6 +276,19 @@ template <class T> T trimRightWhiteSpaces (const T &str)
return str.substr (0, end); return str.substr (0, end);
} }
// remove spaces and tabs at the begin and end of the string
template <class T> T trimSeparators (const T &str)
{
typename T::size_type start = 0;
typename T::size_type size = str.size();
while (start < size && (str[start] == ' ' || str[start] == '\t'))
start++;
typename T::size_type end = size;
while (end > start && (str[end-1] == ' ' || str[end-1] == '\t'))
end--;
return str.substr (start, end-start);
}
// if both first and last char are quotes (' or "), then remove them // if both first and last char are quotes (' or "), then remove them
template <class T> T trimQuotes (const T &str) template <class T> T trimQuotes (const T &str)
{ {

@ -14,12 +14,6 @@
// You should have received a copy of the GNU Affero General Public License // 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/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef FACTORY_H #ifndef FACTORY_H
#define FACTORY_H #define FACTORY_H

@ -123,9 +123,14 @@ namespace NLGUI
if (prop) if (prop)
{ {
const char *propPtr = prop; const char *propPtr = prop;
#ifdef RYZOM_FORGE
if (strlen(propPtr) > 2 && propPtr[0] == 'u' && propPtr[1] == ':')
_ContextHelp = ucstring::makeFromUtf8(std::string(propPtr).substr(2));
else
#endif
_ContextHelp = ucstring(propPtr); _ContextHelp = ucstring(propPtr);
if( !editorMode && ( strlen(propPtr) > 2 ) ) if( !editorMode && ( strlen(propPtr) > 2 ) )
{ {
if ((propPtr[0] == 'u') && (propPtr[1] == 'i')) if ((propPtr[0] == 'u') && (propPtr[1] == 'i'))
@ -256,7 +261,7 @@ namespace NLGUI
{ {
if( name == "tooltip" ) if( name == "tooltip" )
{ {
_ContextHelp = value; _ContextHelp = ucstring::makeFromUtf8(value);
return; return;
} }
else else

@ -996,5 +996,27 @@ namespace NLGUI
return 0; return 0;
} }
// ***************************************************************************
void CCtrlBaseButton::runRightClickAction()
{
if(_AHOnRightClick != NULL)
{
CAHManager::getInstance()->submitEvent( "button_click:" + getId() );
CAHManager::getInstance()->runActionHandler (_AHOnRightClick, this, _AHRightClickParams);
}
}
// ***************************************************************************
int CCtrlBaseButton::luaRunRightClickAction(CLuaState &ls)
{
const char *funcName = "onRightClick";
CLuaIHM::checkArgCount(ls, funcName, 0);
runRightClickAction();
return 0;
}
} }

@ -4756,6 +4756,7 @@ namespace NLGUI
if (_Resizer[k]) _Resizer[k]->HMax = maxH; if (_Resizer[k]) _Resizer[k]->HMax = maxH;
} }
} }
// *************************************************************************** // ***************************************************************************
int CGroupContainer::luaSetHeaderColor(CLuaState &ls) int CGroupContainer::luaSetHeaderColor(CLuaState &ls)
{ {
@ -4766,6 +4767,16 @@ namespace NLGUI
return 0; return 0;
} }
// ***************************************************************************
int CGroupContainer::luaSetModalParentList(CLuaState &ls)
{
const char *funcName = "setModalParentList";
CLuaIHM::checkArgCount(ls, funcName, 1);
CLuaIHM::checkArgType(ls, funcName, 1, LUA_TSTRING);
setModalParentList(ls.toString(1));
return 0;
}
// *************************************************************************** // ***************************************************************************
CRGBA CGroupContainer::getDrawnHeaderColor () const CRGBA CGroupContainer::getDrawnHeaderColor () const
{ {

@ -1001,7 +1001,7 @@ namespace NLGUI
string fullstyle = style[1]; string fullstyle = style[1];
for (uint j=2; j < style.size(); j++) for (uint j=2; j < style.size(); j++)
fullstyle += ":"+style[j]; fullstyle += ":"+style[j];
styles[trim(style[0])] = trim(fullstyle); styles[trim(style[0])] = trimSeparators(fullstyle);
} }
} }
@ -2772,17 +2772,19 @@ namespace NLGUI
string buttonTemplate = DefaultButtonGroup; string buttonTemplate = DefaultButtonGroup;
// Action handler parameters : "name=group_html_id|form=id_of_the_form|submit_button=button_name" // Action handler parameters : "name=group_html_id|form=id_of_the_form|submit_button=button_name"
string param = "name=" + this->_Id + "|url=" + getLink(); string param = "name=" + this->_Id + "|url=" + getLink();
string name;
if (!_AnchorName.empty())
name = _AnchorName.back();
typedef pair<string, string> TTmplParam; typedef pair<string, string> TTmplParam;
vector<TTmplParam> tmplParams; vector<TTmplParam> tmplParams;
tmplParams.push_back(TTmplParam("id", "")); tmplParams.push_back(TTmplParam("id", ""));
tmplParams.push_back(TTmplParam("onclick", "browse")); tmplParams.push_back(TTmplParam("onclick", "browse"));
tmplParams.push_back(TTmplParam("onclick_param", param)); tmplParams.push_back(TTmplParam("onclick_param", param));
tmplParams.push_back(TTmplParam("active", "true")); tmplParams.push_back(TTmplParam("active", "true"));
CInterfaceGroup *buttonGroup = CWidgetManager::getInstance()->getParser()->createGroupInstance(buttonTemplate, _Paragraph->getId(), tmplParams); CInterfaceGroup *buttonGroup = CWidgetManager::getInstance()->getParser()->createGroupInstance(buttonTemplate, getId()+":"+name, tmplParams);
if (buttonGroup) if (buttonGroup)
{ {
buttonGroup->setId(getId()+":"+name);
// Add the ctrl button // Add the ctrl button
CCtrlTextButton *ctrlButton = dynamic_cast<CCtrlTextButton*>(buttonGroup->getCtrl("button")); CCtrlTextButton *ctrlButton = dynamic_cast<CCtrlTextButton*>(buttonGroup->getCtrl("button"));
if (!ctrlButton) ctrlButton = dynamic_cast<CCtrlTextButton*>(buttonGroup->getCtrl("b")); if (!ctrlButton) ctrlButton = dynamic_cast<CCtrlTextButton*>(buttonGroup->getCtrl("b"));
@ -4532,6 +4534,23 @@ namespace NLGUI
return 0; return 0;
} }
// ***************************************************************************
int CGroupHTML::luaSetBackground(CLuaState &ls)
{
const char *funcName = "setBackground";
CLuaIHM::checkArgCount(ls, funcName, 3);
CLuaIHM::checkArgType(ls, funcName, 1, LUA_TSTRING);
CLuaIHM::checkArgType(ls, funcName, 2, LUA_TBOOLEAN);
CLuaIHM::checkArgType(ls, funcName, 3, LUA_TBOOLEAN);
std::string image = ls.toString(1);
bool scale = ls.toBoolean(2);
bool repeat = ls.toBoolean(3);
setBackground(image, scale, repeat);
return 0;
}
// *************************************************************************** // ***************************************************************************
int CGroupHTML::luaInsertText(CLuaState &ls) int CGroupHTML::luaInsertText(CLuaState &ls)
{ {
@ -4638,6 +4657,16 @@ namespace NLGUI
browse(url.c_str()); browse(url.c_str());
} }
void CGroupHTML::setHTML(const std::string &html)
{
renderHtmlString(html);
}
void CGroupHTML::setHome(const std::string &home)
{
Home = home;
}
// *************************************************************************** // ***************************************************************************
void CGroupHTML::parseStylesheetFile(const std::string &fname) void CGroupHTML::parseStylesheetFile(const std::string &fname)
{ {

@ -1663,6 +1663,28 @@ namespace NLGUI
return _Lines[lineIndex].AHParams; return _Lines[lineIndex].AHParams;
} }
// ------------------------------------------------------------------------------------------------
void CGroupSubMenu::setActionHandler(uint lineIndex, const std::string &ah)
{
if (lineIndex > _Lines.size())
{
nlwarning("Bad index");
return;
}
_Lines[lineIndex].AHName = ah;
}
// ------------------------------------------------------------------------------------------------
void CGroupSubMenu::setActionHandlerParam(uint lineIndex, const std::string &params)
{
if (lineIndex > _Lines.size())
{
nlwarning("Bad index");
return;
}
_Lines[lineIndex].AHParams = params;
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void CGroupSubMenu::setSelectable(uint lineIndex, bool selectable) void CGroupSubMenu::setSelectable(uint lineIndex, bool selectable)
{ {
@ -2596,6 +2618,20 @@ namespace NLGUI
return _RootMenu ? _RootMenu->getActionHandlerParam(lineIndex) : ""; return _RootMenu ? _RootMenu->getActionHandlerParam(lineIndex) : "";
} }
// ------------------------------------------------------------------------------------------------
void CGroupMenu::setActionHandler(uint lineIndex, const std::string &ah)
{
if (_RootMenu)
_RootMenu->setActionHandler(lineIndex, ah);
}
// ------------------------------------------------------------------------------------------------
void CGroupMenu::setActionHandlerParam(uint lineIndex, const std::string &params)
{
if (_RootMenu)
_RootMenu->setActionHandlerParam(lineIndex, params);
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void CGroupMenu::setUserGroupRight(uint line, CInterfaceGroup *gr, bool ownerShip /*=true*/) void CGroupMenu::setUserGroupRight(uint line, CInterfaceGroup *gr, bool ownerShip /*=true*/)
{ {

@ -794,6 +794,35 @@ namespace NLGUI
return 0; return 0;
} }
// ***************************************************************************
int CLuaIHM::getOnDraw(CLuaState &ls)
{
//H_AUTO(Lua_CLuaIHM_getOnDraw
CLuaStackChecker lsc(&ls, 1);
// params: CInterfaceElement*.
// return: "script" (nil if empty)
CLuaIHM::checkArgCount(ls, "getOnDraw", 1);
CLuaIHM::check(ls, CLuaIHM::isUIOnStack(ls, 1), "getOnDraw() requires a UI object in param 1");
// retrieve arguments
CInterfaceElement *pIE = CLuaIHM::getUIOnStack(ls, 1);
if (pIE)
{
// must be a group
CInterfaceGroup *group = dynamic_cast<CInterfaceGroup*>(pIE);
if (group)
{
if (!group->getLuaScriptOnDraw().empty()) {
ls.push(group->getLuaScriptOnDraw());
return 1;
}
}
}
ls.pushNil();
return 1;
}
// *************************************************************************** // ***************************************************************************
int CLuaIHM::addOnDbChange(CLuaState &ls) int CLuaIHM::addOnDbChange(CLuaState &ls)
{ {
@ -1589,6 +1618,7 @@ namespace NLGUI
// *** Register Functions // *** Register Functions
ls.registerFunc("setOnDraw", setOnDraw); ls.registerFunc("setOnDraw", setOnDraw);
ls.registerFunc("getOnDraw", getOnDraw);
ls.registerFunc("setCaptureKeyboard", setCaptureKeyboard); ls.registerFunc("setCaptureKeyboard", setCaptureKeyboard);
ls.registerFunc("resetCaptureKeyboard", resetCaptureKeyboard); ls.registerFunc("resetCaptureKeyboard", resetCaptureKeyboard);
ls.registerFunc("setTopWindow", setTopWindow); ls.registerFunc("setTopWindow", setTopWindow);

@ -323,7 +323,7 @@ namespace NLGUI
prop = (char*) xmlGetProp( cur, (xmlChar*)"texture" ); prop = (char*) xmlGetProp( cur, (xmlChar*)"texture" );
if (prop) if (prop)
{ {
string TxName = toLower((const char *) prop); string TxName = (const char *) prop;
setTexture (TxName); setTexture (TxName);
//CInterfaceManager *pIM = CInterfaceManager::getInstance(); //CInterfaceManager *pIM = CInterfaceManager::getInstance();
//CViewRenderer &rVR = *CViewRenderer::getInstance(); //CViewRenderer &rVR = *CViewRenderer::getInstance();
@ -478,7 +478,7 @@ namespace NLGUI
} }
} }
else else
_TextureId.setTexture (TxName.c_str (), _TxtOffsetX, _TxtOffsetY, _TxtWidth, _TxtHeight, false); _TextureId.setTexture (toLower(TxName).c_str (), _TxtOffsetX, _TxtOffsetY, _TxtWidth, _TxtHeight, false);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

@ -382,9 +382,15 @@ std::string CI18N::getSystemLanguageCode ()
} }
} }
#else #else
// only keep 2 first characters
if (lang.size() > 1) if (lang.size() > 1)
_SystemLanguageCode = NLMISC::toLower(lang).substr(0, 2); {
// only keep 2 first characters
lang = NLMISC::toLower(lang).substr(0, 2);
// language code supported?
if (isLanguageCodeSupported(lang))
_SystemLanguageCode = lang;
}
#endif #endif
} }
} }

@ -334,12 +334,12 @@ void CLog::displayNL (const char *format, ...)
} }
char *str; char *str;
NLMISC_CONVERT_VARGS (str, format, 256/*NLMISC::MaxCStringSize*/); NLMISC_CONVERT_VARGS (str, format, 1024/*NLMISC::MaxCStringSize*/);
if (strlen(str)<256/*NLMISC::MaxCStringSize*/-1) if (strlen(str)<1024/*NLMISC::MaxCStringSize*/-1)
strcat (str, "\n"); strcat (str, "\n");
else else
str[256/*NLMISC::MaxCStringSize*/-2] = '\n'; str[1024/*NLMISC::MaxCStringSize*/-2] = '\n';
displayString (str); displayString (str);
} }
@ -359,7 +359,7 @@ void CLog::display (const char *format, ...)
} }
char *str; char *str;
NLMISC_CONVERT_VARGS (str, format, 256/*NLMISC::MaxCStringSize*/); NLMISC_CONVERT_VARGS (str, format, 1024/*NLMISC::MaxCStringSize*/);
displayString (str); displayString (str);
} }
@ -453,12 +453,12 @@ void CLog::displayRawNL( const char *format, ... )
} }
char *str; char *str;
NLMISC_CONVERT_VARGS (str, format, 256/*NLMISC::MaxCStringSize*/); NLMISC_CONVERT_VARGS (str, format, 1024/*NLMISC::MaxCStringSize*/);
if (strlen(str)<256/*NLMISC::MaxCStringSize*/-1) if (strlen(str)<1024/*NLMISC::MaxCStringSize*/-1)
strcat (str, "\n"); strcat (str, "\n");
else else
str[256/*NLMISC::MaxCStringSize*/-2] = '\n'; str[1024/*NLMISC::MaxCStringSize*/-2] = '\n';
displayRawString(str); displayRawString(str);
} }
@ -478,7 +478,7 @@ void CLog::displayRaw( const char *format, ... )
} }
char *str; char *str;
NLMISC_CONVERT_VARGS (str, format, 256/*NLMISC::MaxCStringSize*/); NLMISC_CONVERT_VARGS (str, format, 1024/*NLMISC::MaxCStringSize*/);
displayRawString(str); displayRawString(str);
} }
@ -496,7 +496,7 @@ void CLog::forceDisplayRaw (const char *format, ...)
} }
char *str; char *str;
NLMISC_CONVERT_VARGS (str, format, 256/*NLMISC::MaxCStringSize*/); NLMISC_CONVERT_VARGS (str, format, 1024/*NLMISC::MaxCStringSize*/);
TDisplayInfo args; TDisplayInfo args;
CDisplayers::iterator idi; CDisplayers::iterator idi;

@ -415,6 +415,7 @@ void CMoveContainer::updateCells (CMovePrimitive *primitive, uint8 worldImage)
CPrimitiveWorldImage *wI=primitive->getWorldImage (worldImage); CPrimitiveWorldImage *wI=primitive->getWorldImage (worldImage);
#if !FINAL_VERSION #if !FINAL_VERSION
#ifndef RYZOM_FORGE
// Check BB width not too large // Check BB width not too large
if (wI->getBBXMax() - wI->getBBXMin() > _CellWidth) if (wI->getBBXMax() - wI->getBBXMin() > _CellWidth)
{ {
@ -426,6 +427,7 @@ void CMoveContainer::updateCells (CMovePrimitive *primitive, uint8 worldImage)
{ {
nlwarning ("Primitives have moved more than a cell."); nlwarning ("Primitives have moved more than a cell.");
} }
#endif
#endif #endif
// Get coordinate in the cell array // Get coordinate in the cell array

@ -65,11 +65,11 @@ IF(WITH_RYZOM_CLIENT)
SET(RYZOM_BUILD ${RYZOM_VERSION_SHORT}) SET(RYZOM_BUILD ${RYZOM_VERSION_SHORT})
ENDIF() ENDIF()
SET(MACOSX_BUNDLE_INFO_STRING "Ryzom Core Client") SET(MACOSX_BUNDLE_INFO_STRING "Ryzom Classic")
SET(MACOSX_BUNDLE_ICON_FILE "ryzom.icns") SET(MACOSX_BUNDLE_ICON_FILE "ryzom.icns")
SET(MACOSX_BUNDLE_GUI_IDENTIFIER "") SET(MACOSX_BUNDLE_GUI_IDENTIFIER "dev.ryzom.classic")
SET(MACOSX_BUNDLE_LONG_VERSION_STRING ${RYZOM_VERSION}) SET(MACOSX_BUNDLE_LONG_VERSION_STRING ${RYZOM_VERSION})
SET(MACOSX_BUNDLE_BUNDLE_NAME "Ryzom Core Client") SET(MACOSX_BUNDLE_BUNDLE_NAME "Ryzom Classic")
SET(MACOSX_BUNDLE_SHORT_VERSION_STRING ${RYZOM_VERSION_SHORT}) SET(MACOSX_BUNDLE_SHORT_VERSION_STRING ${RYZOM_VERSION_SHORT})
SET(MACOSX_BUNDLE_BUNDLE_VERSION ${RYZOM_BUILD}) SET(MACOSX_BUNDLE_BUNDLE_VERSION ${RYZOM_BUILD})
SET(MACOSX_BUNDLE_COPYRIGHT ${COPYRIGHT}) SET(MACOSX_BUNDLE_COPYRIGHT ${COPYRIGHT})
@ -190,7 +190,7 @@ IF(WITH_RYZOM_CLIENT)
ADD_DEFINITIONS(${LIBXML2_DEFINITIONS} ${CURL_DEFINITIONS} ${LUABIND_DEFINITIONS}) ADD_DEFINITIONS(${LIBXML2_DEFINITIONS} ${CURL_DEFINITIONS} ${LUABIND_DEFINITIONS})
NL_DEFAULT_PROPS(ryzom_client "Ryzom, Client: Ryzom Core Client") NL_DEFAULT_PROPS(ryzom_client "Ryzom, Client: Ryzom Classic")
NL_ADD_RUNTIME_FLAGS(ryzom_client) NL_ADD_RUNTIME_FLAGS(ryzom_client)
IF(FINAL_VERSION) IF(FINAL_VERSION)

@ -330,13 +330,15 @@ CClientConfig::CClientConfig()
TexturesLoginInterface.push_back("texture_interfaces_v3_login"); TexturesLoginInterface.push_back("texture_interfaces_v3_login");
DisplayAccountButtons = true; DisplayAccountButtons = true;
CreateAccountURL = "http://shard.ryzomcore.org/ams/index.php?page=register"; #ifdef RYZOM_FORGE
ConditionsTermsURL = "http://www.gnu.org/licenses/agpl-3.0.html"; CreateAccountURL = "https://account.ryzom.com/signup/from_client.php";
EditAccountURL = "http://shard.ryzomcore.org/ams/index.php?page=settings"; EditAccountURL = "https://account.ryzom.com/payment_profile/index.php";
BetaAccountURL = "http://shard.ryzomcore.org/ams/index.php?page=settings"; ForgetPwdURL = "https://account.ryzom.com/payment_profile/lost_secure_password.php";
ForgetPwdURL = "http://shard.ryzomcore.org/ams/index.php?page=forgot_password"; #else
FreeTrialURL = "http://shard.ryzomcore.org/ams/index.php?page=register"; CreateAccountURL = "https://classic.ryzom.dev/signup/from_client.php";
LoginSupportURL = "http://shard.ryzomcore.org/ams/index.php"; EditAccountURL = "https://classic.ryzom.dev/payment_profile/index.php";
ForgetPwdURL = "https://classic.ryzom.dev/payment_profile/lost_secure_password.php";
#endif
Position = CVector(0.f, 0.f, 0.f); // Default Position. Position = CVector(0.f, 0.f, 0.f); // Default Position.
Heading = CVector(0.f, 1.f, 0.f); // Default Heading. Heading = CVector(0.f, 1.f, 0.f); // Default Heading.
EyesHeight = 1.5f; // Default User Eyes Height. EyesHeight = 1.5f; // Default User Eyes Height.
@ -432,7 +434,7 @@ CClientConfig::CClientConfig()
PatchletUrl.clear(); PatchletUrl.clear();
PatchVersion.clear(); PatchVersion.clear();
WebIgMainDomain = "shard.ryzomcore.org"; WebIgMainDomain = "classic.ryzom.dev";
WebIgTrustedDomains.push_back(WebIgMainDomain); WebIgTrustedDomains.push_back(WebIgMainDomain);
WebIgNotifInterval = 10; // time in minutes WebIgNotifInterval = 10; // time in minutes
@ -899,19 +901,13 @@ void CClientConfig::setValues()
READ_BOOL_DEV(DisplayAccountButtons) READ_BOOL_DEV(DisplayAccountButtons)
READ_STRING_DEV(CreateAccountURL) READ_STRING_DEV(CreateAccountURL)
READ_STRING_DEV(EditAccountURL) READ_STRING_DEV(EditAccountURL)
READ_STRING_DEV(ConditionsTermsURL)
READ_STRING_DEV(BetaAccountURL)
READ_STRING_DEV(ForgetPwdURL) READ_STRING_DEV(ForgetPwdURL)
READ_STRING_DEV(BetaAccountURL)
READ_STRING_DEV(FreeTrialURL) READ_STRING_DEV(FreeTrialURL)
READ_STRING_DEV(LoginSupportURL)
READ_STRING_FV(CreateAccountURL) // defined in client_default.cfg
READ_STRING_FV(EditAccountURL)
READ_STRING_FV(ConditionsTermsURL) READ_STRING_FV(ConditionsTermsURL)
READ_STRING_FV(NamingPolicyURL) READ_STRING_FV(NamingPolicyURL)
READ_STRING_FV(BetaAccountURL)
READ_STRING_FV(ForgetPwdURL)
READ_STRING_FV(FreeTrialURL)
READ_STRING_FV(LoginSupportURL) READ_STRING_FV(LoginSupportURL)
#ifndef RZ_NO_CLIENT #ifndef RZ_NO_CLIENT
@ -1108,6 +1104,12 @@ void CClientConfig::setValues()
ClientCfg.CurlMaxConnections = 2; ClientCfg.CurlMaxConnections = 2;
READ_STRING_FV(CurlCABundle); READ_STRING_FV(CurlCABundle);
if (!ClientCfg.CurlCABundle.empty() && ClientCfg.CurlCABundle[0] == '%') // Path is relative to client_default.cfg path (used by ryzom patch)
{
string defaultConfigFileName;
if (ClientCfg.getDefaultConfigLocation(defaultConfigFileName))
ClientCfg.CurlCABundle = CFile::getPath(defaultConfigFileName)+ClientCfg.CurlCABundle.substr(1);
}
/////////////// ///////////////
// ANIMATION // // ANIMATION //
@ -2023,19 +2025,34 @@ void CClientConfig::init(const string &configFileName)
// now we can continue loading and parsing the config file // now we can continue loading and parsing the config file
// if the config file will be modified, it calls automatically the function setValuesOnFileChange() // if the config file will be modified, it calls automatically the function setValuesOnFileChange()
ClientCfg.ConfigFile.setCallback (CClientConfig::setValuesOnFileChange); ClientCfg.ConfigFile.setCallback (CClientConfig::setValuesOnFileChange);
// load the config files // load the config files
ClientCfg.ConfigFile.load (configFileName); ClientCfg.ConfigFile.load (configFileName);
CConfigFile::CVar *varPtr;
// check language code is supported
varPtr = ClientCfg.ConfigFile.getVarPtr("LanguageCode");
if (varPtr)
{
std::string lang = varPtr->asString();
if (!CI18N::isLanguageCodeSupported(lang))
{
nlinfo("Unsupported language code \"%s\" fallback on default", lang.c_str());
// fallback to default language
ClientCfg.LanguageCode = CI18N::getSystemLanguageCode();
// update ConfigFile variable
varPtr->setAsString(ClientCfg.LanguageCode);
ClientCfg.ConfigFile.save();
}
}
// update the ConfigFile variable in the config file // update the ConfigFile variable in the config file
CConfigFile::CVar *varPtr = ClientCfg.ConfigFile.getVarPtr ("ClientVersion"); varPtr = ClientCfg.ConfigFile.getVarPtr("ClientVersion");
if (varPtr) if (varPtr)
{ {
string str = varPtr->asString (); std::string str = varPtr->asString ();
if (str != getVersion() && ClientCfg.SaveConfig) if (str != getVersion() && ClientCfg.SaveConfig)
{ {
nlinfo ("Update and save the ClientVersion variable in config file %s -> %s", str.c_str(), getVersion().c_str()); nlinfo ("Update and save the ClientVersion variable in config file %s -> %s", str.c_str(), getVersion().c_str());

@ -1386,7 +1386,7 @@ NLMISC_COMMAND(setItemName, "set name of items, sbrick, etc..","<sheet_id> <name
ucstring desc2; ucstring desc2;
if (args.size() > 2) if (args.size() > 2)
desc.fromUtf8(args[2]); desc.fromUtf8(args[2]);
if (args.size() > 2) if (args.size() > 3)
desc2.fromUtf8(args[3]); desc2.fromUtf8(args[3]);
STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance(); STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance();
@ -4031,15 +4031,6 @@ NLMISC_COMMAND(displayActionCounter, "display the action counters", "")
return true; return true;
} }
NLMISC_COMMAND (url, "launch a browser to the specified url", "<url>")
{
if (args.size () != 1)
return false;
return openURL(args[0]);
}
NLMISC_COMMAND( reconnect, "Reconnect to the same shard (self Far TP)", "") NLMISC_COMMAND( reconnect, "Reconnect to the same shard (self Far TP)", "")
{ {
// If the server is up, the egs will begin the quit sequence (shortened only if we are in edition or animation mode). // If the server is up, the egs will begin the quit sequence (shortened only if we are in edition or animation mode).
@ -4502,6 +4493,13 @@ NLMISC_COMMAND(debugItemInfoWaiters, "log ItemInfoWaiters", "")
return true; return true;
} }
NLMISC_COMMAND(debugItemInfoCache, "log ItemInfoCache", "")
{
getInventory().debugItemInfoCache();
return true;
}
NLMISC_COMMAND(debugInfoWindows, "log info windows sheetId", "") NLMISC_COMMAND(debugInfoWindows, "log info windows sheetId", "")
{ {
CInterfaceHelp::debugOpenedInfoWindows(); CInterfaceHelp::debugOpenedInfoWindows();
@ -5855,6 +5853,14 @@ NLMISC_COMMAND(failMission, "clear the content of a mission", "<mission index>")
// *************************************************************************** // ***************************************************************************
NLMISC_COMMAND (url, "launch a browser to the specified url", "<url>")
{
if (args.size () != 1)
return false;
return openURL(args[0]);
}
NLMISC_COMMAND(em, "emote command", "<emote phrase>") NLMISC_COMMAND(em, "emote command", "<emote phrase>")
{ {

@ -89,7 +89,6 @@ void contextExtractRM (bool rightClick, bool dblClick);
void contextMission (bool rightClick, bool dblClick); void contextMission (bool rightClick, bool dblClick);
void contextWebPage (bool rightClick, bool dblClick); void contextWebPage (bool rightClick, bool dblClick);
void contextWebIG (bool rightClick, bool dblClick); void contextWebIG (bool rightClick, bool dblClick);
void contextARKitect (bool rightClick, bool dblClick);
void contextRingMission (bool rightClick, bool dblClick); void contextRingMission (bool rightClick, bool dblClick);
void contextOutpost (bool rightClick, bool dblClick); void contextOutpost (bool rightClick, bool dblClick);
void contextBuildTotem (bool rightClick, bool dblClick); void contextBuildTotem (bool rightClick, bool dblClick);
@ -128,7 +127,6 @@ void initContextualCursor()
ContextCur.add(true, "MISSION", string(""), 0.0f, checkUnderCursor, contextMission); ContextCur.add(true, "MISSION", string(""), 0.0f, checkUnderCursor, contextMission);
ContextCur.add(true, "WEB PAGE", string(""), 0.0f, checkUnderCursor, contextWebPage); ContextCur.add(true, "WEB PAGE", string(""), 0.0f, checkUnderCursor, contextWebPage);
ContextCur.add(true, "WEBIG", string(""), 0.0f, checkUnderCursor, contextWebIG); ContextCur.add(true, "WEBIG", string(""), 0.0f, checkUnderCursor, contextWebIG);
ContextCur.add(false, "ARKITECT", string("curs_create.tga"), 0.0f, checkUnderCursor, contextARKitect);
ContextCur.add(true, "OUTPOST", string(""), 0.0f, checkUnderCursor, contextOutpost); ContextCur.add(true, "OUTPOST", string(""), 0.0f, checkUnderCursor, contextOutpost);
ContextCur.add(true, "RING MISSION", string(""), 0.0f, checkUnderCursor, contextRingMission); ContextCur.add(true, "RING MISSION", string(""), 0.0f, checkUnderCursor, contextRingMission);
ContextCur.add(true, "BUILD_TOTEM", string("uimGcmChooseBuilding"), 0.0f, checkUnderCursor, contextBuildTotem); ContextCur.add(true, "BUILD_TOTEM", string("uimGcmChooseBuilding"), 0.0f, checkUnderCursor, contextBuildTotem);
@ -559,8 +557,6 @@ void checkUnderCursor()
cursor->setCursor("r2ed_tool_select_move_over.tga"); cursor->setCursor("r2ed_tool_select_move_over.tga");
InstanceId = instance_idx; InstanceId = instance_idx;
if (ContextCur.context("ARKITECT", 0.f, ucstring("Edit")))
return;
} }
else else
{ {
@ -899,25 +895,8 @@ void contextWebIG(bool rightClick, bool dblClick)
pGC->setActive(false); pGC->setActive(false);
CAHManager::getInstance()->runActionHandler("browse", NULL, "name=ui:interface:webig:content:html|url="+selectedInstanceURL); CAHManager::getInstance()->runActionHandler("browse", NULL, "name=ui:interface:webig:content:html|url="+selectedInstanceURL);
} }
}// contextWebIG //
//-----------------------------------------------
// contextARKitect :
//-----------------------------------------------
void contextARKitect(bool rightClick, bool dblClick)
{
string header;
if (rightClick)
{
header = toString("rightClick = true\nSelectedInstanceId = %u\n", InstanceId);
} else {
header = toString("rightClick = false\nSelectedInstanceId = %u\n", InstanceId);
}
CLuaManager::getInstance().executeLuaScript(string(header)+selectedInstanceURL, true);
}// contextARKitect //
}// contextWebIG //
//----------------------------------------------- //-----------------------------------------------
// contextOutpost // contextOutpost

@ -184,8 +184,12 @@ struct CStatThread : public NLMISC::IRunnable
CURL *curl = curl_easy_init(); CURL *curl = curl_easy_init();
if(!curl) return; if(!curl) return;
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10 (.NET CLR 3.5.30729)"); // FIXME curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10 (.NET CLR 3.5.30729)");
curl_easy_setopt(curl, CURLOPT_REFERER, string("http://www.ryzomcore.org/" + referer).c_str()); #ifdef RYZOM_FORGE
curl_easy_setopt(curl, CURLOPT_REFERER, string("http://www.ryzom.com/" + referer).c_str());
#else
curl_easy_setopt(curl, CURLOPT_REFERER, string("https://ryzom.dev/" + referer).c_str());
#endif
curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
CURLcode res = curl_easy_perform(curl); CURLcode res = curl_easy_perform(curl);
curl_easy_cleanup(curl); curl_easy_cleanup(curl);
@ -240,7 +244,11 @@ struct CStatThread : public NLMISC::IRunnable
addParam(params, "page", ""); addParam(params, "page", "");
addParam(params, "pagetitle", referer); addParam(params, "pagetitle", referer);
addParam(params, "screen", toString("%dx%d", ClientCfg.ConfigFile.getVar("Width").asInt(), ClientCfg.ConfigFile.getVar("Height").asInt())); addParam(params, "screen", toString("%dx%d", ClientCfg.ConfigFile.getVar("Width").asInt(), ClientCfg.ConfigFile.getVar("Height").asInt()));
addParam(params, "referer", "http%3A%2F%2Fwww.ryzomcore.org%2F" + referer); #ifdef RYZOM_FORGE
addParam(params, "referer", "http%3A%2F%2Fwww.ryzom.com%2F" + referer);
#else
addParam(params, "referer", "https%3A%2F%2Fryzom.dev%2F" + referer);
#endif
time_t rawtime; time_t rawtime;
struct tm * timeinfo; struct tm * timeinfo;
char buffer [80]; char buffer [80];
@ -263,7 +271,9 @@ struct CStatThread : public NLMISC::IRunnable
default: shard= "unknown"; break; default: shard= "unknown"; break;
} }
addParam(params, "cv_Shard", shard); addParam(params, "cv_Shard", shard);
/* get("http://ryzom.com.woopra-ns.com/visit/" + params); */// FIXME #ifdef RYZOM_FORGE
get("http://ryzom.com.woopra-ns.com/visit/"+params);
#endif
return true; return true;
} }
@ -273,7 +283,9 @@ struct CStatThread : public NLMISC::IRunnable
std::string params; std::string params;
addParam(params, "cookie", cookie()); addParam(params, "cookie", cookie());
addParam(params, "ra", randomString()); addParam(params, "ra", randomString());
/* get("http://ryzom.com.woopra-ns.com/ping/" + params); */// FIXME #ifdef RYZOM_FORGE
get("http://ryzom.com.woopra-ns.com/ping/"+params);
#endif
} }
void run() void run()

@ -4636,3 +4636,17 @@ public:
}; };
REGISTER_ACTION_HANDLER( CHandlerSortTribeFame, "sort_tribefame"); REGISTER_ACTION_HANDLER( CHandlerSortTribeFame, "sort_tribefame");
// ***************************************************************************
class CHandlerTriggerIconBuffs : public IActionHandler
{
public:
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
{
CCDBNodeLeaf *node = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:SHOW_ICON_BUFFS", false);
// no node - show,
// node == false - hide
CDBCtrlSheet::setShowIconBuffs(!node || node->getValueBool());
}
};
REGISTER_ACTION_HANDLER(CHandlerTriggerIconBuffs, "trigger_show_icon_buffs");

@ -73,45 +73,47 @@ REGISTER_UI_CLASS(CDBCtrlSheet)
const uint64 NOTIFY_ANIM_MS_DURATION = 1000; const uint64 NOTIFY_ANIM_MS_DURATION = 1000;
// *************************************************************************** // state kept and changed by UI:SAVE:SHOW_ICON_BUFFS
bool CDBCtrlSheet::_ShowIconBuffs = true;
// ***************************************************************************
// ********************************************************************************************************** void CControlSheetInfoWaiter::sendRequest()
class CControlSheetTooltipInfoWaiter : public IItemInfoWaiter
{ {
public: Requesting = true;
// The item used to open this window getInventory().addItemInfoWaiter(this);
CDBCtrlSheet* CtrlSheet; }
string LuaMethodName;
public:
ucstring infoValidated(CDBCtrlSheet* ctrlSheet, string luaMethodName);
virtual void infoReceived();
};
static CControlSheetTooltipInfoWaiter ControlSheetTooltipUpdater;
void CControlSheetTooltipInfoWaiter::infoReceived() void CControlSheetInfoWaiter::infoReceived()
{ {
getInventory().removeItemInfoWaiter(&ControlSheetTooltipUpdater); if (!Requesting) {
infoValidated(CtrlSheet, LuaMethodName); return;
}
getInventory().removeItemInfoWaiter(this);
infoValidated();
CtrlSheet->infoReceived();
Requesting = false;
} }
ucstring CControlSheetTooltipInfoWaiter::infoValidated(CDBCtrlSheet* ctrlSheet, string luaMethodName) ucstring CControlSheetInfoWaiter::infoValidated() const
{ {
ucstring help; ucstring help;
if (CtrlSheet && !LuaMethodName.empty())
{
// delegate setup of context he help ( & window ) to lua // delegate setup of context he help ( & window ) to lua
CInterfaceManager *im = CInterfaceManager::getInstance(); CInterfaceManager *im = CInterfaceManager::getInstance();
CLuaState *ls= CLuaManager::getInstance().getLuaState(); CLuaState *ls= CLuaManager::getInstance().getLuaState();
{ {
CLuaStackRestorer lsr(ls, 0); CLuaStackRestorer lsr(ls, 0);
CLuaIHM::pushReflectableOnStack(*ls, (CReflectableRefPtrTarget *)ctrlSheet); CLuaIHM::pushReflectableOnStack(*ls, (CReflectableRefPtrTarget *)CtrlSheet);
ls->pushGlobalTable(); ls->pushGlobalTable();
CLuaObject game(*ls); CLuaObject game(*ls);
game = game["game"]; game = game["game"];
game.callMethodByNameNoThrow(luaMethodName.c_str(), 1, 1); game.callMethodByNameNoThrow(LuaMethodName.c_str(), 1, 1);
// retrieve result from stack // retrieve result from stack
if (!ls->empty()) if (!ls->empty())
@ -120,7 +122,8 @@ ucstring CControlSheetTooltipInfoWaiter::infoValidated(CDBCtrlSheet* ctrlSheet,
} }
else else
{ {
nlwarning(toString("Ucstring result expected when calling '%s', possible script error", luaMethodName.c_str()).c_str()); nlwarning(toString("Ucstring result expected when calling '%s', possible script error", LuaMethodName.c_str()).c_str());
}
} }
} }
@ -135,54 +138,40 @@ int CDBCtrlSheet::luaGetDraggedSheet(CLuaState &ls)
} }
// *************************************************************************** // ***************************************************************************
int CDBCtrlSheet::luaGetHpBuff(CLuaState &ls) int CDBCtrlSheet::luaGetItemInfo(CLuaState &ls)
{ {
CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet *>(this); CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet *>(this);
uint32 itemSlotId = getInventory().getItemSlotId(ctrlSheet); uint32 itemSlotId = getInventory().getItemSlotId(ctrlSheet);
CClientItemInfo itemInfo = getInventory().getItemInfo(itemSlotId); CClientItemInfo itemInfo = getInventory().getItemInfo(itemSlotId);
ls.push(itemInfo.HpBuff); ls.newTable();
CLuaObject out(ls);
// for now all but magic
out.setValue("CurrentDamage", itemInfo.CurrentDamage);
out.setValue("MaxDamage", itemInfo.MaxDamage);
out.setValue("DodgeModifier", itemInfo.DodgeModifier);
out.setValue("ParryModifier", itemInfo.ParryModifier);
out.setValue("AdversaryDodgeModifier", itemInfo.AdversaryDodgeModifier);
out.setValue("AdversaryParryModifier", itemInfo.AdversaryParryModifier);
out.setValue("Hp", itemInfo.Hp);
out.setValue("HpMax", itemInfo.HpMax);
out.setValue("Range", itemInfo.Range);
out.setValue("HpBuff", itemInfo.HpBuff);
out.setValue("SapBuff", itemInfo.SapBuff);
out.setValue("StaBuff", itemInfo.StaBuff);
out.setValue("FocusBuff", itemInfo.FocusBuff);
out.setValue("SapLoadCurrent", itemInfo.SapLoadCurrent);
out.setValue("SapLoadMax", itemInfo.SapLoadMax);
out.setValue("ProtectionFactor", itemInfo.ProtectionFactor);
out.setValue("MaxSlashingProtection", itemInfo.MaxSlashingProtection);
out.setValue("MaxPiercingProtection", itemInfo.MaxPiercingProtection);
out.setValue("MaxBluntProtection", itemInfo.MaxBluntProtection);
out.setValue("WearEquipmentMalus", itemInfo.WearEquipmentMalus);
out.push();
return 1; return 1;
} }
// ***************************************************************************
int CDBCtrlSheet::luaGetSapBuff(CLuaState &ls)
{
CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet*>(this);
uint32 itemSlotId= getInventory().getItemSlotId(ctrlSheet);
CClientItemInfo itemInfo = getInventory().getItemInfo(itemSlotId);
ls.push(itemInfo.SapBuff);
return 1;
}
// ***************************************************************************
int CDBCtrlSheet::luaGetFocusBuff(CLuaState &ls)
{
CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet*>(this);
uint32 itemSlotId= getInventory().getItemSlotId(ctrlSheet);
CClientItemInfo itemInfo = getInventory().getItemInfo(itemSlotId);
ls.push(itemInfo.FocusBuff);
return 1;
}
// ***************************************************************************
int CDBCtrlSheet::luaGetStaBuff(CLuaState &ls)
{
CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet*>(this);
uint32 itemSlotId= getInventory().getItemSlotId(ctrlSheet);
CClientItemInfo itemInfo = getInventory().getItemInfo(itemSlotId);
ls.push(itemInfo.StaBuff);
return 1;
}
// *************************************************************************** // ***************************************************************************
int CDBCtrlSheet::luaGetName(CLuaState &ls) int CDBCtrlSheet::luaGetName(CLuaState &ls)
{ {
@ -251,7 +240,6 @@ int CDBCtrlSheet::luaWaitInfo(CLuaState &ls)
int CDBCtrlSheet::luaBuildCrystallizedSpellListBrick(CLuaState &ls) int CDBCtrlSheet::luaBuildCrystallizedSpellListBrick(CLuaState &ls)
{ {
CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet*>(this); CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet*>(this);
uint32 itemSlotId= getInventory().getItemSlotId(ctrlSheet); uint32 itemSlotId= getInventory().getItemSlotId(ctrlSheet);
CClientItemInfo itemInfo = getInventory().getItemInfo(itemSlotId); CClientItemInfo itemInfo = getInventory().getItemInfo(itemSlotId);
@ -519,6 +507,7 @@ CCtrlDraggable(param)
_Useable= true; _Useable= true;
_GrayedLink= NULL; _GrayedLink= NULL;
_NeedSetup= true; _NeedSetup= true;
_ItemInfoChanged = true;
_IconW = 0; _IconW = 0;
_IconH = 0; _IconH = 0;
_SetupInit= false; _SetupInit= false;
@ -542,6 +531,11 @@ CCtrlDraggable(param)
_ItemRMClassType= NULL; _ItemRMClassType= NULL;
_ItemRMFaberStatType= NULL; _ItemRMFaberStatType= NULL;
_NotifyAnimEndTime = 0; _NotifyAnimEndTime = 0;
_HpBuffIcon = "ico_heal.tga";
_SapBuffIcon = "ico_sap.tga";
_StaBuffIcon = "ico_stamina.tga";
_FocusBuffIcon = "ico_focus.tga";
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -549,6 +543,11 @@ CDBCtrlSheet::~CDBCtrlSheet()
{ {
NL3D::UDriver *Driver = CViewRenderer::getInstance()->getDriver(); NL3D::UDriver *Driver = CViewRenderer::getInstance()->getDriver();
if (_ItemInfoWaiter.Requesting)
{
getInventory().removeItemInfoWaiter(&_ItemInfoWaiter);
}
if (_GuildBack) if (_GuildBack)
{ {
if (Driver) if (Driver)
@ -627,6 +626,22 @@ bool CDBCtrlSheet::parse(xmlNodePtr cur, CInterfaceGroup * parentGroup)
prop = (char*) xmlGetProp( cur, (xmlChar*)"slot" ); prop = (char*) xmlGetProp( cur, (xmlChar*)"slot" );
if(prop) _DrawSlot= CInterfaceElement::convertBool(prop); if(prop) _DrawSlot= CInterfaceElement::convertBool(prop);
//
_HpBuffIcon = "ico_heal.tga";
prop = (char*) xmlGetProp( cur, (xmlChar*)"hp_buff_icon" );
if (prop) _HpBuffIcon = string((const char *)prop);
_SapBuffIcon = "ico_sap.tga";
prop = (char*) xmlGetProp( cur, (xmlChar*)"sap_buff_icon" );
if (prop) _SapBuffIcon = string((const char *)prop);
_StaBuffIcon = "ico_stamina.tga";
prop = (char*) xmlGetProp( cur, (xmlChar*)"sta_buff_icon" );
if (prop) _StaBuffIcon = string((const char *)prop);
_FocusBuffIcon = "ico_focus.tga";
prop = (char*) xmlGetProp( cur, (xmlChar*)"focus_buff_icon" );
if (prop) _FocusBuffIcon = string((const char *)prop);
updateActualType(); updateActualType();
// Init size for Type // Init size for Type
@ -991,11 +1006,10 @@ void CDBCtrlSheet::updateCoords ()
{ {
if (getActive()) if (getActive())
{ {
if(!_SetupInit)
setupInit();
if (_Type != CCtrlSheetInfo::SheetType_Macro) if (_Type != CCtrlSheetInfo::SheetType_Macro)
{ {
if (!_SetupInit) setupInit();
if (_LastSheetId != _SheetId.getSInt32()) if (_LastSheetId != _SheetId.getSInt32())
{ {
updateActualType(); updateActualType();
@ -1049,6 +1063,72 @@ void CDBCtrlSheet::updateIconSize()
} }
} }
// ***************************************************************************
void CDBCtrlSheet::clearIconBuffs()
{
_EnchantIcons.clear();
_BuffIcons.clear();
}
// ***************************************************************************
void CDBCtrlSheet::infoReceived()
{
if (!_ItemSheet)
{
clearIconBuffs();
return;
}
const CClientItemInfo *itemInfo = getInventory().getItemInfoCache(getItemSerial(), getItemCreateTime());
if (itemInfo == NULL)
{
// schedule for recheck on next draw()
_ItemInfoChanged = true;
return;
}
clearIconBuffs();
// crystallized spell
{
CViewRenderer &rVR = *CViewRenderer::getInstance();
CSBrickManager *pBM= CSBrickManager::getInstance();
for(uint i=0; i<itemInfo->Enchantment.Bricks.size(); ++i)
{
const CSBrickSheet *brick = pBM->getBrick(itemInfo->Enchantment.Bricks[i]);
if (brick)
{
if (!brick->isRoot() && !brick->isCredit() && !brick->isParameter())
{
_EnchantIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(brick->getIcon()), brick->IconColor));
rVR.getTextureSizeFromId(_EnchantIcons.back().TextureId, _EnchantIcons.back().IconW, _EnchantIcons.back().IconH);
}
else if (brick->isRoot())
{
// there should be single root icon and it should be first one
_EnchantIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(brick->getIconBack()), brick->IconBackColor));
rVR.getTextureSizeFromId(_EnchantIcons.back().TextureId, _EnchantIcons.back().IconW, _EnchantIcons.back().IconH);
}
}
}
}
// buff icons
{
CViewRenderer &rVR = *CViewRenderer::getInstance();
if (itemInfo->HpBuff > 0) _BuffIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(_HpBuffIcon)));
if (itemInfo->SapBuff > 0) _BuffIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(_SapBuffIcon)));
if (itemInfo->StaBuff > 0) _BuffIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(_StaBuffIcon)));
if (itemInfo->FocusBuff > 0) _BuffIcons.push_back(SBuffIcon(rVR.getTextureIdFromName(_FocusBuffIcon)));
// update sizes
for(uint i = 0; i < _BuffIcons.size(); ++i)
{
rVR.getTextureSizeFromId(_BuffIcons[i].TextureId, _BuffIcons[i].IconW, _BuffIcons[i].IconH);
}
}
}
// *************************************************************************** // ***************************************************************************
void CDBCtrlSheet::setupPact() void CDBCtrlSheet::setupPact()
@ -1091,6 +1171,20 @@ void CDBCtrlSheet::setupPact()
} }
} }
// ***************************************************************************
bool CDBCtrlSheet::useItemInfoForFamily(ITEMFAMILY::EItemFamily family) const
{
return family == ITEMFAMILY::CRYSTALLIZED_SPELL
|| family == ITEMFAMILY::JEWELRY
|| family == ITEMFAMILY::ARMOR
|| family == ITEMFAMILY::MELEE_WEAPON
|| family == ITEMFAMILY::RANGE_WEAPON
|| family == ITEMFAMILY::SHIELD
|| family == ITEMFAMILY::CRAFTING_TOOL
|| family == ITEMFAMILY::HARVEST_TOOL
|| family == ITEMFAMILY::TAMING_TOOL
|| family == ITEMFAMILY::TRAINING_TOOL;
}
// *************************************************************************** // ***************************************************************************
void CDBCtrlSheet::setupItem () void CDBCtrlSheet::setupItem ()
@ -1098,6 +1192,7 @@ void CDBCtrlSheet::setupItem ()
CInterfaceManager *pIM= CInterfaceManager::getInstance(); CInterfaceManager *pIM= CInterfaceManager::getInstance();
sint32 sheet = _SheetId.getSInt32(); sint32 sheet = _SheetId.getSInt32();
// If this is the same sheet, need to resetup // If this is the same sheet, need to resetup
if (_LastSheetId != sheet || _NeedSetup) if (_LastSheetId != sheet || _NeedSetup)
{ {
@ -1198,6 +1293,9 @@ void CDBCtrlSheet::setupItem ()
// Special Item requirement // Special Item requirement
updateItemCharacRequirement(_LastSheetId); updateItemCharacRequirement(_LastSheetId);
// update item info markers
_ItemInfoChanged = true;
} }
else else
{ {
@ -1272,6 +1370,13 @@ void CDBCtrlSheet::setupItem ()
_Useable = CSkillManager::getInstance()->checkBaseSkillMetRequirement(_ItemSheet->RequiredSkill, _ItemSheet->RequiredSkillLevel); _Useable = CSkillManager::getInstance()->checkBaseSkillMetRequirement(_ItemSheet->RequiredSkill, _ItemSheet->RequiredSkillLevel);
} }
*/ */
// at each frame, update item info icon if changed
if (_ItemInfoChanged)
{
_ItemInfoChanged = false;
setupItemInfoWaiter();
}
} }
@ -2215,6 +2320,69 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti
rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, _DispOver2BmpId, fastMulRGB(curSheetColor, _IconOver2Color)); rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, _DispOver2BmpId, fastMulRGB(curSheetColor, _IconOver2Color));
} }
if (_ShowIconBuffs && !_BuffIcons.empty())
{
// there is max 4 icons
sint32 hArea = (hSheet / 4);
sint32 xIcon = x;
sint32 yIcon = y;
for (uint i = 0; i < _BuffIcons.size(); ++i)
{
sint32 wIcon = _BuffIcons[i].IconW;
sint32 hIcon = _BuffIcons[i].IconH;
if (hIcon > hArea)
{
wIcon = wIcon * ((float)hArea / hIcon);
hIcon = hArea;
}
rVR.drawRotFlipBitmap (_RenderLayer+1, xIcon, yIcon, wIcon, hIcon, 0, false, _BuffIcons[i].TextureId, fastMulRGB(curSheetColor, _BuffIcons[i].Color));
xIcon += wIcon;
// move up the row for 3rd/4th icon
if (i % 3 == 1) {
xIcon = x;
yIcon += hIcon;
}
}
}
// Is the item enchanted ?
sint32 enchant = _Enchant.getSInt32();
if (enchant > 0)
{
// Yes draw the additionnal bitmap and the charge (number of enchanted spell we can launch with the enchanted item)
enchant--;
rVR.draw11RotFlipBitmap (_RenderLayer+1, x, y, 0, false, rVR.getSystemTextureId(CViewRenderer::ItemEnchantedTexture), curSheetColor);
drawNumber(x+1, y-2+hSheet-rVR.getFigurTextureH(), wSheet, hSheet, numberColor, enchant, false);
}
if (_ShowIconBuffs && !_EnchantIcons.empty())
{
// should only only 2 icons at most
// draw them in single line, top-right
sint32 hArea = (hSheet / 3);
sint32 xIcon = x + wSheet - 1;
sint32 yIcon = y + hSheet - 1/* - hArea*/;
// 0 is expected to be background
for (uint i = 1; i < _EnchantIcons.size(); ++i)
{
sint32 wIcon = _EnchantIcons[i].IconW;
sint32 hIcon = _EnchantIcons[i].IconH;
if (hIcon > hArea)
{
wIcon = wIcon * ((float)hArea / hIcon);
hIcon = hArea;
}
// need to move x before draw because of right aligned
if (i == 1)
{
xIcon -= wIcon;
}
yIcon -= hIcon;
rVR.drawRotFlipBitmap(_RenderLayer + 1, xIcon, yIcon, wIcon, hIcon, 0, false, _EnchantIcons[0].TextureId, fastMulRGB(curSheetColor, _EnchantIcons[0].Color));
rVR.drawRotFlipBitmap(_RenderLayer+1, xIcon, yIcon, wIcon, hIcon, 0, false, _EnchantIcons[i].TextureId, fastMulRGB(curSheetColor, _EnchantIcons[i].Color));
}
}
// 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)
{ {
@ -2237,15 +2405,6 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti
} }
drawNumber(x+1+crossW, y+1, wSheet, hSheet, curSheetColor, quantity, false); drawNumber(x+1+crossW, y+1, wSheet, hSheet, curSheetColor, quantity, false);
} }
// Is the item enchanted ?
sint32 enchant = _Enchant.getSInt32();
if (enchant > 0)
{
// Yes draw the additionnal bitmap and the charge (number of enchanted spell we can launch with the enchanted item)
enchant--;
rVR.draw11RotFlipBitmap (_RenderLayer+2, x, y, 0, false, rVR.getSystemTextureId(CViewRenderer::ItemEnchantedTexture), curSheetColor);
drawNumber(x+1, y-2+hSheet-rVR.getFigurTextureH(), wSheet, hSheet, numberColor, enchant, false);
}
// if a raw material for example, must add special icon text. // if a raw material for example, must add special icon text.
displayCharBitmaps(_RenderLayer+2, x, y, curSheetColor); displayCharBitmaps(_RenderLayer+2, x, y, curSheetColor);
@ -3109,6 +3268,62 @@ const COutpostBuildingSheet *CDBCtrlSheet::asOutpostBuildingSheet() const
return NULL; return NULL;
} }
// ***************************************************************************
void CDBCtrlSheet::setupItemInfoWaiter()
{
const CItemSheet *item = asItemSheet();
if(!item)
{
clearIconBuffs();
return;
}
if (!useItemInfoForFamily(item->Family))
{
clearIconBuffs();
return;
}
if (getItemSerial() == 0 || getItemCreateTime() == 0)
{
clearIconBuffs();
return;
}
string luaMethodName = ((item->Family == ITEMFAMILY::CRYSTALLIZED_SPELL) ? "updateCrystallizedSpellTooltip" : "updateBuffItemTooltip");
CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet*>(this);
uint itemSlotId = getInventory().getItemSlotId(ctrlSheet);
// Prepare the waiter for tooltips
_ItemInfoWaiter.ItemSheet= ctrlSheet->getSheetId();
_ItemInfoWaiter.LuaMethodName = luaMethodName;
_ItemInfoWaiter.ItemSlotId= itemSlotId;
_ItemInfoWaiter.CtrlSheet = ctrlSheet;
// send out request only if cache is not set
const CClientItemInfo *itemInfo = getInventory().getItemInfoCache(getItemSerial(), getItemCreateTime());
if (itemInfo)
{
infoReceived();
}
else
{
// Using isInventoryPresent/Available() will fail for packers when out of range
// Getting server item however will work correctly for packer/room/guild
const CItemImage *itemImage = getInventory().getServerItem(itemSlotId);
if (itemImage)
{
_ItemInfoWaiter.sendRequest();
}
else
{
// schedule for next draw() - if inventory should not be available (ie guild),
// but user opens it anyway, then this will loop back here on every draw()
_ItemInfoChanged = true;
}
}
}
// *************************************************************************** // ***************************************************************************
void CDBCtrlSheet::getContextHelp(ucstring &help) const void CDBCtrlSheet::getContextHelp(ucstring &help) const
{ {
@ -3120,36 +3335,70 @@ void CDBCtrlSheet::getContextHelp(ucstring &help) const
} }
else if(getType() == CCtrlSheetInfo::SheetType_Macro) else if(getType() == CCtrlSheetInfo::SheetType_Macro)
{ {
// TODO Find the name + params of the action
help = _ContextHelp; help = _ContextHelp;
const CMacroCmd *macro = CMacroCmdManager::getInstance()->getMacroFromMacroID(getMacroId());
if (!macro)
return;
ucstring macroName = macro->Name;
if (macroName.empty())
macroName = CI18N::get("uiNotAssigned");
ucstring assignedTo = macro->Combo.toUCString();
if (assignedTo.empty())
assignedTo = CI18N::get("uiNotAssigned");
ucstring dispText;
ucstring dispCommands;
const CMacroCmdManager *pMCM = CMacroCmdManager::getInstance();
uint nb = 0;
for (uint i = 0; i < macro->Commands.size(); ++i)
{
ucstring commandName;
for (uint j = 0; j < pMCM->ActionManagers.size(); ++j)
{
CAction::CName c(macro->Commands[i].Name.c_str(), macro->Commands[i].Params.c_str());
if (pMCM->ActionManagers[j]->getBaseAction(c) != NULL)
{
commandName = pMCM->ActionManagers[j]->getBaseAction(c)->getActionLocalizedText(c);
// display a few commands
if (nb < 5)
dispCommands += "\n" + commandName;
++nb;
break;
}
}
}
// formats
dispText = ucstring("%n (@{6F6F}%k@{FFFF})\n%c");
if (nb > 5) // more?
dispCommands += toString(" ... @{6F6F}%i@{FFFF}+", nb-5);
strFindReplace(dispText, ucstring("%n"), macroName);
strFindReplace(dispText, ucstring("%k"), assignedTo);
strFindReplace(dispText, ucstring("%c"), dispCommands);
help = dispText;
} }
else if(getType() == CCtrlSheetInfo::SheetType_Item) else if(getType() == CCtrlSheetInfo::SheetType_Item)
{ {
const CItemSheet *item= asItemSheet(); const CItemSheet *item= asItemSheet();
if(item) if(item)
{ {
if (item->Family == ITEMFAMILY::CRYSTALLIZED_SPELL || item->Family == ITEMFAMILY::JEWELRY || item->Family == ITEMFAMILY::ARMOR) if (useItemInfoForFamily(item->Family))
{ {
string luaMethodName = ( (item->Family == ITEMFAMILY::CRYSTALLIZED_SPELL) ? "updateCrystallizedSpellTooltip" : "updateBuffItemTooltip"); // call lua function to update tooltip window
CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet*>(this); _ItemInfoWaiter.sendRequest();
if ( ! getInventory().isItemInfoUpToDate(getInventory().getItemSlotId(ctrlSheet))) help = _ItemInfoWaiter.infoValidated();
{
// Prepare the waiter
ControlSheetTooltipUpdater.ItemSheet= ctrlSheet->getSheetId();
ControlSheetTooltipUpdater.LuaMethodName = luaMethodName;
ControlSheetTooltipUpdater.ItemSlotId= getInventory().getItemSlotId(ctrlSheet);
ControlSheetTooltipUpdater.CtrlSheet = ctrlSheet;
// Add the waiter
getInventory().addItemInfoWaiter(&ControlSheetTooltipUpdater);
} }
else if (!_ContextHelp.empty())
help = ControlSheetTooltipUpdater.infoValidated(ctrlSheet, luaMethodName); {
help = _ContextHelp;
} }
else else
{
help = getItemActualName(); help = getItemActualName();
}
} }
else else
help= _ContextHelp; help= _ContextHelp;
@ -3265,24 +3514,10 @@ void CDBCtrlSheet::getContextHelpToolTip(ucstring &help) const
const CItemSheet *item = asItemSheet(); const CItemSheet *item = asItemSheet();
if (item) if (item)
{ {
if (item->Family == ITEMFAMILY::CRYSTALLIZED_SPELL if (useItemInfoForFamily(item->Family))
|| item->Family == ITEMFAMILY::JEWELRY || item->Family == ITEMFAMILY::ARMOR)
{ {
string luaMethodName = (item->Family == ITEMFAMILY::CRYSTALLIZED_SPELL) ? "updateCrystallizedSpellTooltip" : "updateBuffItemTooltip"; _ItemInfoWaiter.sendRequest();
CDBCtrlSheet *ctrlSheet = const_cast<CDBCtrlSheet*>(this); help = _ItemInfoWaiter.infoValidated();
if ( ! getInventory().isItemInfoUpToDate(getInventory().getItemSlotId(ctrlSheet)))
{
// Prepare the waiter
ControlSheetTooltipUpdater.ItemSheet= ctrlSheet->getSheetId();
ControlSheetTooltipUpdater.LuaMethodName = luaMethodName;
ControlSheetTooltipUpdater.ItemSlotId= getInventory().getItemSlotId(ctrlSheet);
ControlSheetTooltipUpdater.CtrlSheet = ctrlSheet;
// Add the waiter
getInventory().addItemInfoWaiter(&ControlSheetTooltipUpdater);
}
help = ControlSheetTooltipUpdater.infoValidated(ctrlSheet, luaMethodName);
return; return;
} }
} }
@ -3497,6 +3732,10 @@ void CDBCtrlSheet::resetAllTexIDs()
_Stackable= 1; _Stackable= 1;
_IconW = 0; _IconW = 0;
_IconH = 0; _IconH = 0;
_ItemInfoChanged = true;
_EnchantIcons.clear();
_BuffIcons.clear();
} }
@ -4421,13 +4660,13 @@ std::string CDBCtrlSheet::getContextHelpWindowName() const
if (getType() == CCtrlSheetInfo::SheetType_Item) if (getType() == CCtrlSheetInfo::SheetType_Item)
{ {
const CItemSheet *item= asItemSheet(); const CItemSheet *item= asItemSheet();
if(item) if(item && useItemInfoForFamily(item->Family))
{ {
if (item->Family == ITEMFAMILY::CRYSTALLIZED_SPELL) if (item->Family == ITEMFAMILY::CRYSTALLIZED_SPELL)
{ {
return "crystallized_spell_context_help"; return "crystallized_spell_context_help";
} }
else if (item->Family == ITEMFAMILY::JEWELRY || item->Family == ITEMFAMILY::ARMOR) else
{ {
return "buff_item_context_help"; return "buff_item_context_help";
} }
@ -4449,7 +4688,3 @@ void CDBCtrlSheet::startNotifyAnim()
_NotifyAnimEndTime = T1 + NOTIFY_ANIM_MS_DURATION; _NotifyAnimEndTime = T1 + NOTIFY_ANIM_MS_DURATION;
} }

@ -34,9 +34,10 @@
#include "game_share/skills.h" #include "game_share/skills.h"
#include "game_share/slot_types.h" #include "game_share/slot_types.h"
#include "game_share/rm_family.h" #include "game_share/rm_family.h"
#include "game_share/item_family.h"
// //
#include "../time_client.h" #include "../time_client.h"
#include "item_info_waiter.h"
class CItemSheet; class CItemSheet;
class CPactSheet; class CPactSheet;
@ -52,6 +53,25 @@ namespace NLGUI
class CViewRenderer; class CViewRenderer;
} }
class CDBCtrlSheet;
// ***************************************************************************
// Item info request from server
class CControlSheetInfoWaiter : public IItemInfoWaiter
{
public:
CDBCtrlSheet* CtrlSheet;
string LuaMethodName;
bool Requesting;
CControlSheetInfoWaiter()
: IItemInfoWaiter(), Requesting(false)
{ }
public:
ucstring infoValidated() const;
void sendRequest();
virtual void infoReceived();
};
// *************************************************************************** // ***************************************************************************
/** Common info for CDBCtrlSheet and CDBGroupListSheet /** Common info for CDBCtrlSheet and CDBGroupListSheet
@ -279,22 +299,16 @@ public:
REFLECT_STRING ("on_drop_params", getParamsOnDrop, setParamsOnDrop); REFLECT_STRING ("on_drop_params", getParamsOnDrop, setParamsOnDrop);
REFLECT_STRING ("on_can_drop", getActionOnCanDrop, setActionOnCanDrop); REFLECT_STRING ("on_can_drop", getActionOnCanDrop, setActionOnCanDrop);
REFLECT_STRING ("on_can_drop_params", getParamsOnCanDrop, setParamsOnCanDrop); REFLECT_STRING ("on_can_drop_params", getParamsOnCanDrop, setParamsOnCanDrop);
REFLECT_LUA_METHOD("getDraggedSheet", luaGetDraggedSheet) REFLECT_LUA_METHOD("getDraggedSheet", luaGetDraggedSheet);
REFLECT_LUA_METHOD("getHpBuff", luaGetHpBuff) REFLECT_LUA_METHOD("getItemInfo", luaGetItemInfo);
REFLECT_LUA_METHOD("getSapBuff", luaGetSapBuff) REFLECT_LUA_METHOD("getName", luaGetName);
REFLECT_LUA_METHOD("getFocusBuff", luaGetFocusBuff) REFLECT_LUA_METHOD("getCreatorName", luaGetCreatorName);
REFLECT_LUA_METHOD("getStaBuff", luaGetStaBuff) REFLECT_LUA_METHOD("waitInfo", luaWaitInfo);
REFLECT_LUA_METHOD("getName", luaGetName) REFLECT_LUA_METHOD("buildCrystallizedSpellListBrick", luaBuildCrystallizedSpellListBrick);
REFLECT_LUA_METHOD("getCreatorName", luaGetCreatorName)
REFLECT_LUA_METHOD("waitInfo", luaWaitInfo)
REFLECT_LUA_METHOD("buildCrystallizedSpellListBrick", luaBuildCrystallizedSpellListBrick)
REFLECT_EXPORT_END REFLECT_EXPORT_END
int luaGetDraggedSheet(CLuaState &ls); int luaGetDraggedSheet(CLuaState &ls);
int luaGetHpBuff(CLuaState &ls); int luaGetItemInfo(CLuaState &ls);
int luaGetSapBuff(CLuaState &ls);
int luaGetFocusBuff(CLuaState &ls);
int luaGetStaBuff(CLuaState &ls);
int luaGetName(CLuaState &ls); int luaGetName(CLuaState &ls);
int luaGetCreatorName(CLuaState &ls); int luaGetCreatorName(CLuaState &ls);
int luaWaitInfo(CLuaState &ls); int luaWaitInfo(CLuaState &ls);
@ -585,7 +599,14 @@ public:
// start notify anim (at the end of regen usually) // start notify anim (at the end of regen usually)
void startNotifyAnim(); void startNotifyAnim();
// callback from info waiter
void infoReceived();
// set enchant/buff marker visiblility
static void setShowIconBuffs(bool b) { _ShowIconBuffs = b; }
protected: protected:
inline bool useItemInfoForFamily(ITEMFAMILY::EItemFamily family) const;
void setupItem(); void setupItem();
void setupPact(); void setupPact();
@ -625,6 +646,7 @@ protected:
NLMISC::CCDBNodeLeaf *_ItemRMFaberStatType; NLMISC::CCDBNodeLeaf *_ItemRMFaberStatType;
mutable sint32 _LastSheetId; mutable sint32 _LastSheetId;
bool _ItemInfoChanged;
/// Display /// Display
sint32 _DispSlotBmpId; // Display slot bitmap id sint32 _DispSlotBmpId; // Display slot bitmap id
@ -635,6 +657,26 @@ protected:
sint32 _DispOverBmpId; // Over Icon sint32 _DispOverBmpId; // Over Icon
sint32 _DispOver2BmpId; // Over Icon N0 2 for bricks / items. Useful for items when _DispOverBmpId is used to paint user color on the item. sint32 _DispOver2BmpId; // Over Icon N0 2 for bricks / items. Useful for items when _DispOverBmpId is used to paint user color on the item.
std::string _HpBuffIcon;
std::string _SapBuffIcon;
std::string _StaBuffIcon;
std::string _FocusBuffIcon;
// texture ids to show
struct SBuffIcon
{
SBuffIcon(sint32 txid, NLMISC::CRGBA col=NLMISC::CRGBA::White)
:TextureId(txid), Color(col), IconW(0), IconH(0)
{ }
sint32 TextureId;
NLMISC::CRGBA Color;
sint32 IconW;
sint32 IconH;
};
std::vector<SBuffIcon> _BuffIcons;
std::vector<SBuffIcon> _EnchantIcons;
// Level Brick or Quality // Level Brick or Quality
union union
{ {
@ -754,16 +796,21 @@ protected:
sint64 _NotifyAnimEndTime; sint64 _NotifyAnimEndTime;
mutable CControlSheetInfoWaiter _ItemInfoWaiter;
private: private:
mutable TSheetType _ActualType; mutable TSheetType _ActualType;
static CDBCtrlSheet *_CurrSelection; static CDBCtrlSheet *_CurrSelection;
static CDBCtrlSheet *_CurrMenuSheet; static CDBCtrlSheet *_CurrMenuSheet;
static bool _ShowIconBuffs;
private: private:
void updateActualType() const; void updateActualType() const;
void updateIconSize(); void updateIconSize();
void resetAllTexIDs(); void resetAllTexIDs();
void setupInit(); void setupInit();
// remove enchant and buff markers from item icon
void clearIconBuffs();
void setupCharBitmaps(sint32 maxW, sint32 maxLine, sint32 maxWChar= 1000, bool topDown= false); void setupCharBitmaps(sint32 maxW, sint32 maxLine, sint32 maxWChar= 1000, bool topDown= false);
void resetCharBitmaps(); void resetCharBitmaps();
@ -772,6 +819,9 @@ private:
// special for items // special for items
void updateItemCharacRequirement(sint32 sheetId); void updateItemCharacRequirement(sint32 sheetId);
// Send ITEM_INFO:GET request to server to fetch Buffs, Enchant info
void setupItemInfoWaiter();
// update armour color, and cache // update armour color, and cache
void updateArmourColor(sint8 col); void updateArmourColor(sint8 col);

@ -32,6 +32,7 @@
#include "nel/gui/action_handler.h" #include "nel/gui/action_handler.h"
#include "../dummy_progress.h" #include "../dummy_progress.h"
#include "group_compas.h" #include "group_compas.h"
#include "group_html_cs.h"
#include "../connection.h" #include "../connection.h"
#include "../net_manager.h" #include "../net_manager.h"
#include "people_interraction.h" // for MaxNumPeopleInTeam #include "people_interraction.h" // for MaxNumPeopleInTeam

@ -60,13 +60,13 @@ NLMISC_REGISTER_OBJECT(CViewBase, CDBGroupListAscensor, std::string, "list_sheet
#define WIN_GUILD "ui:interface:guild" #define WIN_GUILD "ui:interface:guild"
#define WIN_GUILD_CHAT "ui:interface:guild_chat" #define WIN_GUILD_CHAT "ui:interface:guild_chat"
#define WIN_GUILD_FORUM "ui:interface:guild_forum" #define WIN_GUILD_FORUM "ui:interface:guild_forum"
#define VIEW_TEXT_GUILD_QUIT "ui:interface:guild:content:tab_guild:quit_guild" #define VIEW_TEXT_GUILD_QUIT "ui:interface:guild:content:tab_guild_info:quit_guild"
#define CTRL_SHEET_GUILD_BLASON "ui:interface:guild:content:tab_guild:blason" #define CTRL_SHEET_GUILD_BLASON "ui:interface:guild:content:tab_guild_info:blason"
#define VIEW_TEXT_GUILD_MEMBER_COUNT "ui:interface:guild:content:tab_guild:member_count" #define VIEW_TEXT_GUILD_MEMBER_COUNT "ui:interface:guild:content:tab_guild_info:member_count"
#define LIST_GUILD_MEMBERS "ui:interface:guild:content:tab_guild:list_member:guild_members" #define LIST_GUILD_MEMBERS "ui:interface:guild:content:tab_guild:list_member:guild_members"
#define CTRL_QUIT_GUILD "ui:interface:guild:content:tab_guild:quit_guild" #define CTRL_QUIT_GUILD "ui:interface:guild:content:tab_guild_info:quit_guild"
#define TEMPLATE_GUILD_MEMBER "member_template" #define TEMPLATE_GUILD_MEMBER "member_template"
#define TEMPLATE_GUILD_MEMBER_NAME "name" #define TEMPLATE_GUILD_MEMBER_NAME "name"
#define TEMPLATE_GUILD_MEMBER_GRADE "grade" #define TEMPLATE_GUILD_MEMBER_GRADE "grade"
@ -868,6 +868,10 @@ class CAHGuildSheetOpen : public IActionHandler
} }
} }
CCtrlBase *inviteButton = pLine->getCtrl("invite_button");
if (inviteButton != NULL)
inviteButton->setActive(rGuildMembers[i].Online != ccs_offline && rGuildMembers[i].Name != UserEntity->getEntityName());
// Enter Date // Enter Date
CViewText *pViewEnterDate = dynamic_cast<CViewText*>(pLine->getView(TEMPLATE_GUILD_MEMBER_ENTER_DATE)); CViewText *pViewEnterDate = dynamic_cast<CViewText*>(pLine->getView(TEMPLATE_GUILD_MEMBER_ENTER_DATE));
if (pViewEnterDate != NULL) if (pViewEnterDate != NULL)

@ -691,6 +691,24 @@ CInterfaceElement* CInterface3DScene::getElement (const string &id)
return NULL; return NULL;
} }
int CInterface3DScene::luaGetElement(CLuaState &ls)
{
CLuaIHM::checkArgCount(ls, "CInterfaceGroup::find", 1);
CLuaIHM::checkArgType(ls, "CInterfaceGroup::find", 1, LUA_TSTRING);
std::string id = ls.toString(1);
CInterfaceElement* element = getElement(id);
if (!element)
{
ls.pushNil();
}
else
{
CLuaIHM::pushUIOnStack(ls, element);
}
return 1;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
string CInterface3DScene::getCurrentCamera() const string CInterface3DScene::getCurrentCamera() const
{ {
@ -1237,6 +1255,7 @@ CInterface3DShape::~CInterface3DShape()
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
bool CInterface3DShape::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup) bool CInterface3DShape::parse (xmlNodePtr cur, CInterfaceGroup *parentGroup)
{ {
nlinfo("SHAPE ID PARENT = %s", parentGroup->getId().c_str());
if (!CInterfaceElement::parse(cur, parentGroup)) if (!CInterfaceElement::parse(cur, parentGroup))
return false; return false;

@ -146,6 +146,144 @@ void CItemImage::build(CCDBNodeBranch *branch)
nlassert(Sheet && Quality && Quantity && UserColor && Weight && NameId && InfoVersion); nlassert(Sheet && Quality && Quantity && UserColor && Weight && NameId && InfoVersion);
} }
uint64 CItemImage::getItemId() const
{
return ((uint64)getSerial() << 32) | getCreateTime();
}
// *************************************************************************************************
void CItemInfoCache::load(const std::string &filename)
{
try
{
CIFile f;
if (f.open(filename))
{
serial(f);
}
} catch(...)
{ }
}
void CItemInfoCache::save(const std::string &filename)
{
try
{
COFile f;
if (f.open(filename))
{
serial(f);
}
}catch(...)
{ }
}
void CItemInfoCache::serial(NLMISC::IStream &s)
{
s.serialCheck(NELID("METI"));
uint ver = 1;
s.serialVersion(ver);
uint8 byte = 1;
if (s.isReading())
{
_ItemInfoCacheMap.clear();
while(true)
{
uint64 key;
s.serial(byte);
if (byte == 0)
{
break;
}
s.serial(key);
s.serial(_ItemInfoCacheMap[key].CacheCycle);
_ItemInfoCacheMap[key].serial(s);
// these are not used in item info cache
_ItemInfoCacheMap[key].InfoVersionFromMsg = 0;
_ItemInfoCacheMap[key].InfoVersionFromSlot = 0;
_ItemInfoCacheMap[key].InfoVersionSlotServerWaiting = 0;
}
}
else
{
byte = 1;
TItemInfoCacheMap::iterator it = _ItemInfoCacheMap.begin();
while (it != _ItemInfoCacheMap.end())
{
// purge item from cache if not encountered in X save
if (it->second.CacheCycle < 10000)
{
// 'record exists' byte
s.serial(byte);
// item id (serial << 32 | createTime)
uint64 key = it->first;
s.serial(key);
uint32 cycle = it->second.CacheCycle+1;
s.serial(cycle);
// item info
it->second.serial(s);
}
++it;
}
// eof of records byte
byte = 0;
s.serial(byte);
}
}
const CClientItemInfo *CItemInfoCache::getItemInfo(uint32 serial, uint32 createTime) const
{
if (serial > 0 && createTime > 0)
{
uint64 itemId = ((uint64)serial << 32) | createTime;
return getItemInfo(itemId);
}
return NULL;
}
const CClientItemInfo *CItemInfoCache::getItemInfo(uint64 itemId) const
{
if (itemId > 0)
{
TItemInfoCacheMap::const_iterator it = _ItemInfoCacheMap.find(itemId);
if (it != _ItemInfoCacheMap.end())
return &(it->second);
}
return NULL;
}
void CItemInfoCache::readFromImpulse(uint64 itemId, CItemInfos itemInfo)
{
if (itemId > 0)
{
_ItemInfoCacheMap[itemId].readFromImpulse(itemInfo);
_ItemInfoCacheMap[itemId].CacheCycle = 0;
}
}
void CItemInfoCache::debugItemInfoCache() const
{
nlinfo("ItemInfoCache: %d entries", _ItemInfoCacheMap.size());
uint count = 0;
for (auto it = _ItemInfoCacheMap.begin(); it != _ItemInfoCacheMap.end(); ++it)
{
uint32 serial = (it->first >> 32) & 0xFFFFFFFF;
uint32 created = it->first & 0xFFFFFFFF;
nlinfo("[%-4d] cacheCycle:%d, serial:%d, createTime:%d", count++, it->second.CacheCycle, serial, created);
}
CInterfaceManager *pIM= CInterfaceManager::getInstance();
pIM->displaySystemInfo(toString("ItemInfoCache: %d entries written to client.log", _ItemInfoCacheMap.size()));
}
// ************************************************************************************************* // *************************************************************************************************
// CInventoryManager // CInventoryManager
// ************************************************************************************************* // *************************************************************************************************
@ -174,12 +312,16 @@ CInventoryManager::CInventoryManager()
BagItemEquipped[i]= false; BagItemEquipped[i]= false;
} }
_ItemInfoCacheFilename = toString("save/item_infos_%d.cache", CharacterHomeSessionId.asInt());
_ItemInfoCache.load(_ItemInfoCacheFilename);
nlctassert(NumInventories== sizeof(InventoryIndexes)/sizeof(InventoryIndexes[0])); nlctassert(NumInventories== sizeof(InventoryIndexes)/sizeof(InventoryIndexes[0]));
} }
// *************************************************************************** // ***************************************************************************
CInventoryManager::~CInventoryManager() CInventoryManager::~CInventoryManager()
{ {
_ItemInfoCache.save(_ItemInfoCacheFilename);
} }
// ************************************************************************************************* // *************************************************************************************************
@ -251,6 +393,11 @@ CItemImage &CInventoryManager::getServerBagItem(uint index)
nlassert(index < MAX_BAGINV_ENTRIES); nlassert(index < MAX_BAGINV_ENTRIES);
return ServerBag[index]; return ServerBag[index];
} }
const CItemImage &CInventoryManager::getServerBagItem(uint index) const
{
nlassert(index < MAX_BAGINV_ENTRIES);
return ServerBag[index];
}
// ************************************************************************************************* // *************************************************************************************************
CItemImage &CInventoryManager::getServerTempItem(uint index) CItemImage &CInventoryManager::getServerTempItem(uint index)
@ -258,6 +405,11 @@ CItemImage &CInventoryManager::getServerTempItem(uint index)
nlassert(index < MAX_TEMPINV_ENTRIES); nlassert(index < MAX_TEMPINV_ENTRIES);
return ServerTempInv[index]; return ServerTempInv[index];
} }
const CItemImage &CInventoryManager::getServerTempItem(uint index) const
{
nlassert(index < MAX_TEMPINV_ENTRIES);
return ServerTempInv[index];
}
// ************************************************************************************************* // *************************************************************************************************
CItemImage *CInventoryManager::getServerHandItem(uint index) CItemImage *CInventoryManager::getServerHandItem(uint index)
@ -3225,22 +3377,53 @@ uint CInventoryManager::getItemSheetForSlotId(uint slotId) const
return 0; return 0;
} }
// ***************************************************************************
const CClientItemInfo *CInventoryManager::getItemInfoCache(uint32 serial, uint32 createTime) const
{
return _ItemInfoCache.getItemInfo(serial, createTime);
}
// *************************************************************************** // ***************************************************************************
const CClientItemInfo &CInventoryManager::getItemInfo(uint slotId) const const CClientItemInfo &CInventoryManager::getItemInfo(uint slotId) const
{ {
TItemInfoMap::const_iterator it= _ItemInfoMap.find(slotId); TItemInfoMap::const_iterator it= _ItemInfoMap.find(slotId);
static CClientItemInfo empty; static CClientItemInfo empty;
if (it == _ItemInfoMap.end() || !isItemInfoUpToDate(slotId))
{
// if slot has not been populated yet or out of date, then return info from cache if possible
const CItemImage *item = getServerItem(slotId);
if (item && item->getItemId() > 0) {
const CClientItemInfo *ret = _ItemInfoCache.getItemInfo(item->getItemId());
if (ret != NULL)
{
return *ret;
}
}
}
if (it == _ItemInfoMap.end()) if (it == _ItemInfoMap.end())
{
return empty; return empty;
else }
return it->second; return it->second;
} }
// *************************************************************************** // ***************************************************************************
bool CInventoryManager::isItemInfoUpToDate(uint slotId) bool CInventoryManager::isItemInfoAvailable(uint slotId) const
{ {
TItemInfoMap::const_iterator it= _ItemInfoMap.find(slotId);
return it != _ItemInfoMap.end();
}
// ***************************************************************************
bool CInventoryManager::isItemInfoUpToDate(uint slotId) const
{
TItemInfoMap::const_iterator it= _ItemInfoMap.find(slotId);
if (it == _ItemInfoMap.end())
return true;
// true if the version already matches // true if the version already matches
return getItemInfo(slotId).InfoVersionFromMsg == getItemInfo(slotId).InfoVersionFromSlot; return it->second.InfoVersionFromMsg == it->second.InfoVersionFromSlot;
} }
// *************************************************************************** // ***************************************************************************
@ -3277,8 +3460,10 @@ void CInventoryManager::removeItemInfoWaiter(IItemInfoWaiter *waiter)
void CInventoryManager::updateItemInfoWaiters(uint itemSlotId) void CInventoryManager::updateItemInfoWaiters(uint itemSlotId)
{ {
// First verify if the versions matches. If differ, no need to update waiters since not good. // First verify if the versions matches. If differ, no need to update waiters since not good.
if(getItemInfo(itemSlotId).InfoVersionFromMsg != getItemInfo(itemSlotId).InfoVersionFromSlot) if (!isItemInfoUpToDate(itemSlotId))
{
return; return;
}
bool isItemFromTrading= (itemSlotId>>CItemInfos::SlotIdIndexBitSize)==INVENTORIES::trading; bool isItemFromTrading= (itemSlotId>>CItemInfos::SlotIdIndexBitSize)==INVENTORIES::trading;
@ -3372,10 +3557,15 @@ void CInventoryManager::onReceiveItemSheet(ICDBNode* node)
// *************************************************************************** // ***************************************************************************
void CInventoryManager::onReceiveItemInfo(const CItemInfos &itemInfo) void CInventoryManager::onReceiveItemInfo(const CItemInfos &itemInfo)
{ {
uint itemSlotId;
// update the Info // update the Info
itemSlotId= itemInfo.slotId; uint itemSlotId = itemInfo.slotId;
const CItemImage *item = getServerItem(itemSlotId);
if (item && item->getItemId() > 0)
{
_ItemInfoCache.readFromImpulse(item->getItemId(), itemInfo);
}
// write in map, from DB. // write in map, from DB.
_ItemInfoMap[itemSlotId].readFromImpulse(itemInfo); _ItemInfoMap[itemSlotId].readFromImpulse(itemInfo);
@ -3485,6 +3675,12 @@ void CInventoryManager::debugItemInfoWaiters()
} }
} }
// ***************************************************************************
void CInventoryManager::debugItemInfoCache() const
{
_ItemInfoCache.debugItemInfoCache();
}
// *************************************************************************** // ***************************************************************************
void CInventoryManager::sortBag() void CInventoryManager::sortBag()
{ {
@ -3640,6 +3836,14 @@ CItemImage &CInventoryManager::getServerPAItem(uint beastIndex, uint index)
return ServerPAInv[beastIndex][index]; return ServerPAInv[beastIndex][index];
} }
const CItemImage &CInventoryManager::getServerPAItem(uint beastIndex, uint index) const
{
nlassert(beastIndex < MAX_INVENTORY_ANIMAL);
nlassert(index < MAX_ANIMALINV_ENTRIES);
return ServerPAInv[beastIndex][index];
}
// *************************************************************************** // ***************************************************************************
CItemImage &CInventoryManager::getLocalItem(uint inv, uint index) CItemImage &CInventoryManager::getLocalItem(uint inv, uint index)
{ {
@ -3666,6 +3870,93 @@ CItemImage &CInventoryManager::getServerItem(uint inv, uint index)
return dummy; return dummy;
} }
// ***************************************************************************
const CItemImage *CInventoryManager::getServerItem(uint slotId) const
{
uint inv, index;
getSlotInvIndex(slotId, inv, index);
if (inv == INVENTORIES::bag)
{
return &getServerBagItem(index);
}
else if (inv >= INVENTORIES::pet_animal && inv <INVENTORIES::pet_animal+MAX_INVENTORY_ANIMAL)
{
return &getServerPAItem(inv-INVENTORIES::pet_animal, index);
}
else if (inv == INVENTORIES::temporary)
{
return &getServerTempItem(index);
}
else if (inv == INVENTORIES::guild)
{
// player is in guild outpost or in guild hall
if (getInventory().isInventoryAvailable(INVENTORIES::guild))
{
CCDBNodeBranch *itemBranch = NLGUI::CDBManager::getInstance()->getDbBranch("SERVER:GUILD:INVENTORY:" + toString(index));
if (itemBranch)
{
static CItemImage image;
image.build(itemBranch);
return &image;
}
}
return NULL;
}
else if (inv == INVENTORIES::player_room)
{
// player is in their room
if (getInventory().isInventoryAvailable(INVENTORIES::player_room))
{
CCDBNodeBranch *itemBranch = NLGUI::CDBManager::getInstance()->getDbBranch(SERVER_INVENTORY ":ROOM:" + toString(index));
if (itemBranch)
{
static CItemImage image;
image.build(itemBranch);
return &image;
}
}
return NULL;
}
else if (inv == INVENTORIES::trading)
{
CCDBNodeBranch *itemBranch = NLGUI::CDBManager::getInstance()->getDbBranch("LOCAL:TRADING:" + toString(index));
if (itemBranch)
{
static CItemImage image;
image.build(itemBranch);
return &image;
}
}
else if (inv == INVENTORIES::exchange)
{
CCDBNodeBranch *itemBranch = NLGUI::CDBManager::getInstance()->getDbBranch("LOCAL:EXCHANGE:GIVE:" + toString(index));
if (itemBranch)
{
static CItemImage image;
image.build(itemBranch);
return &image;
}
}
else if (inv == INVENTORIES::exchange_proposition)
{
CCDBNodeBranch *itemBranch = NLGUI::CDBManager::getInstance()->getDbBranch("LOCAL:EXCHANGE:RECEIVE:" + toString(index));
if (itemBranch)
{
static CItemImage image;
image.build(itemBranch);
return &image;
}
}
else
{
nlwarning("getServerItem: invalid inventory %d for slotId %d", inv, slotId);
}
// invalid inventory
return NULL;
}
// *************************************************************************** // ***************************************************************************
CInventoryManager::TInvType CInventoryManager::invTypeFromString(const string &str) CInventoryManager::TInvType CInventoryManager::invTypeFromString(const string &str)
{ {
@ -3679,3 +3970,11 @@ CInventoryManager::TInvType CInventoryManager::invTypeFromString(const string &s
if (sTmp == "inv_room") return InvRoom; if (sTmp == "inv_room") return InvRoom;
return InvUnknown; return InvUnknown;
} }
// ***************************************************************************
void CInventoryManager::getSlotInvIndex(uint slotId, uint &inv, uint &index) const
{
inv = slotId >> CItemInfos::SlotIdIndexBitSize;
index = slotId & CItemInfos::SlotIdIndexBitMask;
}

@ -31,7 +31,7 @@ namespace NLMISC{
class CCDBNodeBranch; class CCDBNodeBranch;
} }
class CDBCtrlSheet; class CDBCtrlSheet;
class IItermInfoWaiter;
const uint MAX_TEMPINV_ENTRIES = INVENTORIES::NbTempInvSlots; const uint MAX_TEMPINV_ENTRIES = INVENTORIES::NbTempInvSlots;
const uint MAX_BAGINV_ENTRIES = INVENTORIES::NbBagSlots; const uint MAX_BAGINV_ENTRIES = INVENTORIES::NbBagSlots;
@ -108,11 +108,15 @@ public:
// This is the InfoVersionFromSlot when last request was sent to server // This is the InfoVersionFromSlot when last request was sent to server
uint16 InfoVersionSlotServerWaiting; uint16 InfoVersionSlotServerWaiting;
// Used to track cache age (reset on use, +1 on every save)
uint32 CacheCycle;
CClientItemInfo() CClientItemInfo()
{ {
InfoVersionFromMsg= 0; InfoVersionFromMsg= 0;
InfoVersionFromSlot= 0; InfoVersionFromSlot= 0;
InfoVersionSlotServerWaiting= 0; InfoVersionSlotServerWaiting= 0;
CacheCycle= 0;
} }
/// Set InfoVersion from Info message (info requested by the player) /// Set InfoVersion from Info message (info requested by the player)
@ -122,21 +126,25 @@ public:
void refreshInfoVersion(uint8 infoVersion) { InfoVersionFromMsg= infoVersion; } void refreshInfoVersion(uint8 infoVersion) { InfoVersionFromMsg= infoVersion; }
}; };
class CItemInfoCache
class IItemInfoWaiter
{ {
public: public:
IItemInfoWaiter() {ItemSlotId= 0; ItemSheet= 0;} void load(const std::string &filename);
virtual ~IItemInfoWaiter() {} void save(const std::string &filename);
// The item SheetId. If differ from current sheet in the SlotId, the infos are not updated / requested void serial(NLMISC::IStream &s);
uint ItemSheet;
// The item SlotId to retrieve info. // retrieve pointer to item info or null if error
uint ItemSlotId; const CClientItemInfo *getItemInfo(uint32 serial, uint32 createTime) const;
const CClientItemInfo *getItemInfo(uint64 itemId) const;
// Called when the info is received for this slot.
virtual void infoReceived() =0;
};
// set/update item info in cache
void readFromImpulse(uint64 itemId, CItemInfos itemInfo);
void debugItemInfoCache() const;
private:
typedef std::map<uint64, CClientItemInfo> TItemInfoCacheMap;
TItemInfoCacheMap _ItemInfoCacheMap;
};
// *************************************************************************** // ***************************************************************************
/** This manager gives direct access to inventory slots (bag, temporary inventory, hands, and equip inventory) /** This manager gives direct access to inventory slots (bag, temporary inventory, hands, and equip inventory)
@ -189,8 +197,10 @@ public:
// SERVER INVENTORY // SERVER INVENTORY
// get item of bag (local inventory) // get item of bag (local inventory)
CItemImage &getServerBagItem(uint index); CItemImage &getServerBagItem(uint index);
const CItemImage &getServerBagItem(uint index) const;
// get temporary item (local inventory) // get temporary item (local inventory)
CItemImage &getServerTempItem(uint index); CItemImage &getServerTempItem(uint index);
const CItemImage &getServerTempItem(uint index) const;
// get hand item (local inventory) // get hand item (local inventory)
CItemImage *getServerHandItem(uint index); CItemImage *getServerHandItem(uint index);
// get equip item (local inventory) // get equip item (local inventory)
@ -200,8 +210,11 @@ public:
void setServerMoney(uint64 value); void setServerMoney(uint64 value);
// get item of pack animal (server inventory). beastIndex ranges from 0 to MAX_INVENTORY_ANIMAL-1 // get item of pack animal (server inventory). beastIndex ranges from 0 to MAX_INVENTORY_ANIMAL-1
CItemImage &getServerPAItem(uint beastIndex, uint index); CItemImage &getServerPAItem(uint beastIndex, uint index);
const CItemImage &getServerPAItem(uint beastIndex, uint index) const;
// get the item Image for the given inventory. assert if bad inventory // get the item Image for the given inventory. assert if bad inventory
CItemImage &getServerItem(uint inv, uint index); CItemImage &getServerItem(uint inv, uint index);
// get the item Image for the given slotId or NULL if bad
const CItemImage *getServerItem(uint slotId) const;
// Drag'n'Drop Management // Drag'n'Drop Management
enum TFrom { Slot, TextList, IconList, Nowhere }; enum TFrom { Slot, TextList, IconList, Nowhere };
@ -267,9 +280,13 @@ public:
uint16 getItemSlotId(CDBCtrlSheet *ctrl); uint16 getItemSlotId(CDBCtrlSheet *ctrl);
uint16 getItemSlotId(const std::string &itemDb, uint slotIndex); uint16 getItemSlotId(const std::string &itemDb, uint slotIndex);
const CClientItemInfo &getItemInfo(uint slotId) const; const CClientItemInfo &getItemInfo(uint slotId) const;
// get item info from cache
const CClientItemInfo *getItemInfoCache(uint32 serial, uint32 createTime) const;
uint getItemSheetForSlotId(uint slotId) const; uint getItemSheetForSlotId(uint slotId) const;
// Returns true if the item info is already in slot cache
bool isItemInfoAvailable(uint slotId) const;
// Returns true if the item info version already matches // Returns true if the item info version already matches
bool isItemInfoUpToDate(uint slotId); bool isItemInfoUpToDate(uint slotId) const;
// Add a Waiter on ItemInfo (ItemHelp opening). no-op if here, but reorder (returns true if the version already matches or if waiter is NULL) // Add a Waiter on ItemInfo (ItemHelp opening). no-op if here, but reorder (returns true if the version already matches or if waiter is NULL)
void addItemInfoWaiter(IItemInfoWaiter *waiter); void addItemInfoWaiter(IItemInfoWaiter *waiter);
// remove a Waiter on ItemInfo (ItemHelp closing). no-op if not here. NB: no delete // remove a Waiter on ItemInfo (ItemHelp closing). no-op if not here. NB: no delete
@ -279,6 +296,7 @@ public:
void onRefreshItemInfoVersion(uint16 slotId, uint8 infoVersion); void onRefreshItemInfoVersion(uint16 slotId, uint8 infoVersion);
// Log for debug // Log for debug
void debugItemInfoWaiters(); void debugItemInfoWaiters();
void debugItemInfoCache() const;
void sortBag(); void sortBag();
@ -294,6 +312,9 @@ public:
enum TInvType { InvBag, InvPA0, InvPA1, InvPA2, InvPA3, InvGuild, InvRoom, InvUnknown }; enum TInvType { InvBag, InvPA0, InvPA1, InvPA2, InvPA3, InvGuild, InvRoom, InvUnknown };
static TInvType invTypeFromString(const std::string &str); static TInvType invTypeFromString(const std::string &str);
// inventory and slot from slotId
void getSlotInvIndex(uint slotId, uint &inv, uint &index) const;
private: private:
// LOCAL INVENTORY // LOCAL INVENTORY
@ -318,6 +339,8 @@ private:
CDBCtrlSheet *DNDCurrentItem; CDBCtrlSheet *DNDCurrentItem;
// ItemExtraInfo management. // ItemExtraInfo management.
std::string _ItemInfoCacheFilename;
CItemInfoCache _ItemInfoCache;
typedef std::map<uint, CClientItemInfo> TItemInfoMap; typedef std::map<uint, CClientItemInfo> TItemInfoMap;
TItemInfoMap _ItemInfoMap; TItemInfoMap _ItemInfoMap;
typedef std::list<IItemInfoWaiter*> TItemInfoWaiters; typedef std::list<IItemInfoWaiter*> TItemInfoWaiters;

@ -0,0 +1,39 @@
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// 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 RZ_ITEM_INFO_WAITER_H
#define RZ_ITEM_INFO_WAITER_H
class IItemInfoWaiter
{
public:
IItemInfoWaiter() {ItemSlotId= 0; ItemSheet= 0;}
virtual ~IItemInfoWaiter() {}
// The item SheetId. If differ from current sheet in the SlotId, the infos are not updated / requested
uint ItemSheet;
// The item SlotId to retrieve info.
uint ItemSlotId;
// Called when the info is received for this slot.
virtual void infoReceived() =0;
};
#endif // RZ_DBCTRL_SHEET_INFO_WAITER_H
/* End of item_info_waiter.h */

@ -456,6 +456,7 @@ void CLuaIHMRyzom::RegisterRyzomFunctions(NLGUI::CLuaState &ls)
ls.registerFunc("getTargetTitle", getTargetTitle); ls.registerFunc("getTargetTitle", getTargetTitle);
ls.registerFunc("addSearchPathUser", addSearchPathUser); ls.registerFunc("addSearchPathUser", addSearchPathUser);
ls.registerFunc("displaySystemInfo", displaySystemInfo); ls.registerFunc("displaySystemInfo", displaySystemInfo);
ls.registerFunc("displayChatMessage", displayChatMessage);
ls.registerFunc("disableContextHelpForControl", disableContextHelpForControl); ls.registerFunc("disableContextHelpForControl", disableContextHelpForControl);
ls.registerFunc("disableContextHelp", disableContextHelp); ls.registerFunc("disableContextHelp", disableContextHelp);
ls.registerFunc("setWeatherValue", setWeatherValue); ls.registerFunc("setWeatherValue", setWeatherValue);
@ -470,6 +471,7 @@ void CLuaIHMRyzom::RegisterRyzomFunctions(NLGUI::CLuaState &ls)
ls.registerFunc("getUserRace", getUserRace); ls.registerFunc("getUserRace", getUserRace);
ls.registerFunc("getSheet2idx", getSheet2idx); ls.registerFunc("getSheet2idx", getSheet2idx);
ls.registerFunc("getTargetSlot", getTargetSlot); ls.registerFunc("getTargetSlot", getTargetSlot);
ls.registerFunc("unsetTargetAsInterlocutor", unsetTargetAsInterlocutor);
ls.registerFunc("getSlotDataSetId", getSlotDataSetId); ls.registerFunc("getSlotDataSetId", getSlotDataSetId);
ls.registerFunc("addShape", addShape); ls.registerFunc("addShape", addShape);
ls.registerFunc("moveShape", moveShape); ls.registerFunc("moveShape", moveShape);
@ -493,8 +495,11 @@ void CLuaIHMRyzom::RegisterRyzomFunctions(NLGUI::CLuaState &ls)
LUABIND_FUNC(getDbProp), LUABIND_FUNC(getDbProp),
LUABIND_FUNC(getDbProp64), LUABIND_FUNC(getDbProp64),
LUABIND_FUNC(setDbProp), LUABIND_FUNC(setDbProp),
LUABIND_FUNC(setDbProp64),
LUABIND_FUNC(addDbProp), LUABIND_FUNC(addDbProp),
LUABIND_FUNC(delDbProp), LUABIND_FUNC(delDbProp),
LUABIND_FUNC(getDbRGBA),
LUABIND_FUNC(setDbRGBA),
LUABIND_FUNC(debugInfo), LUABIND_FUNC(debugInfo),
LUABIND_FUNC(rawDebugInfo), LUABIND_FUNC(rawDebugInfo),
LUABIND_FUNC(dumpCallStack), LUABIND_FUNC(dumpCallStack),
@ -531,6 +536,7 @@ void CLuaIHMRyzom::RegisterRyzomFunctions(NLGUI::CLuaState &ls)
LUABIND_FUNC(isDynStringAvailable), LUABIND_FUNC(isDynStringAvailable),
LUABIND_FUNC(isFullyPatched), LUABIND_FUNC(isFullyPatched),
LUABIND_FUNC(getSheetType), LUABIND_FUNC(getSheetType),
LUABIND_FUNC(getSheetFamily),
LUABIND_FUNC(getSheetName), LUABIND_FUNC(getSheetName),
LUABIND_FUNC(getFameIndex), LUABIND_FUNC(getFameIndex),
LUABIND_FUNC(getFameName), LUABIND_FUNC(getFameName),
@ -2585,10 +2591,12 @@ sint64 CLuaIHMRyzom::getDbProp64(const std::string &dbProp)
CCDBNodeLeaf *node = NLGUI::CDBManager::getInstance()->getDbProp(dbProp, false); CCDBNodeLeaf *node = NLGUI::CDBManager::getInstance()->getDbProp(dbProp, false);
if (node) if (node)
{
return node->getValue64(); return node->getValue64();
}
else else
{ {
debugInfo(toString("getDbProp(): '%s' dbProp Not found", dbProp.c_str())); debugInfo(toString("getDbProp64(): '%s' dbProp Not found", dbProp.c_str()));
return 0; return 0;
} }
} }
@ -2623,6 +2631,36 @@ void CLuaIHMRyzom::setDbProp(const std::string &dbProp, sint32 value)
debugInfo(toString("setDbProp(): '%s' dbProp Not found", dbProp.c_str())); debugInfo(toString("setDbProp(): '%s' dbProp Not found", dbProp.c_str()));
} }
void CLuaIHMRyzom::setDbProp64(const std::string &dbProp, sint64 value)
{
//H_AUTO(Lua_CLuaIHM_setDbProp)
// Do not allow Write on SERVER: or LOCAL:
static const std::string dbServer = "SERVER:";
static const std::string dbLocal = "LOCAL:";
static const std::string dbLocalR2 = "LOCAL:R2";
if ((dbProp.compare(0, dbServer.size(), dbServer) == 0) ||
(dbProp.compare(0, dbLocal.size(), dbLocal) == 0)
)
{
if (dbProp.compare(0, dbLocalR2.size(), dbLocalR2) != 0)
{
nlstop;
throw ELuaIHMException("setDbProp(): You are not allowed to write on 'SERVER:...' or 'LOCAL:...' database");
}
}
// Write to the DB if found
CInterfaceManager *pIM = CInterfaceManager::getInstance();
CCDBNodeLeaf *node = NLGUI::CDBManager::getInstance()->getDbProp(dbProp, false);
if (node)
node->setValue64(value);
else
debugInfo(toString("setDbProp(): '%s' dbProp Not found", dbProp.c_str()));
}
void CLuaIHMRyzom::delDbProp(const string &dbProp) void CLuaIHMRyzom::delDbProp(const string &dbProp)
{ {
//H_AUTO(Lua_CLuaIHM_setDbProp) //H_AUTO(Lua_CLuaIHM_setDbProp)
@ -3151,7 +3189,7 @@ void CLuaIHMRyzom::browseNpcWebPage(const std::string &htmlId, const std::string
if (groupHtml) if (groupHtml)
{ {
// if true, it means that we want to display a web page that use webig auth // if true, it means that we want to display a web page that use webig auth
bool webig = urlIn.find("http://") == 0; bool webig = urlIn.find("http://") == 0 || urlIn.find("https://") == 0;
string url; string url;
@ -3264,6 +3302,21 @@ std::string CLuaIHMRyzom::getSheetType(const std::string &sheet)
} }
// ***************************************************************************
std::string CLuaIHMRyzom::getSheetFamily(const std::string &sheet)
{
CEntitySheet *pES = SheetMngr.get ( CSheetId(sheet) );
if ((pES != NULL) && (pES->type() == CEntitySheet::ITEM))
{
CItemSheet *pIS = (CItemSheet*)pES;
if (pIS)
return ITEMFAMILY::toString(pIS->Family);
}
return "";
}
// *************************************************************************** // ***************************************************************************
std::string CLuaIHMRyzom::getSheetName(uint32 sheetId) std::string CLuaIHMRyzom::getSheetName(uint32 sheetId)
{ {
@ -3826,3 +3879,144 @@ std::string CLuaIHMRyzom::createGotoFileButtonTag(const char *fileName, uint lin
return ""; return "";
} }
// ***************************************************************************
void CLuaIHMRyzom::setDbRGBA(const std::string &dbProp, const NLMISC::CRGBA &color)
{
//H_AUTO(Lua_CLuaIHM_setDbRGBA)
static const std::string dbServer = "SERVER:";
static const std::string dbLocal = "LOCAL:";
static const std::string dbLocalR2 = "LOCAL:R2";
// do not allow write on SERVER: or LOCAL:
if ((dbProp.compare(0, dbServer.size(), dbServer) == 0) || (dbProp.compare(0, dbLocal.size(), dbLocal) == 0))
{
if (dbProp.compare(0, dbLocalR2.size(), dbLocalR2) != 0)
{
nlstop;
throw ELuaIHMException("setDbRGBA(): You are not allowed to write on 'SERVER:...' or 'LOCAL:...' database");
}
}
// write to the db
CCDBNodeLeaf *node = NLGUI::CDBManager::getInstance()->getDbProp(dbProp, true);
if (node)
node->setValue64(color.R+(color.G<<8)+(color.B<<16)+(color.A<<24));
return;
}
// ***************************************************************************
std::string CLuaIHMRyzom::getDbRGBA(const std::string &dbProp)
{
//H_AUTO(Lua_CLuaIHM_getDbRGBA)
CCDBNodeLeaf *node = NLGUI::CDBManager::getInstance()->getDbProp(dbProp, false);
if (node)
{
CRGBA color = CRGBA::White;
sint64 rgba = (sint64)node->getValue64();
color.R = (sint8)(rgba & 0xff);
color.G = (sint8)((rgba >> 8) & 0xff);
color.B = (sint8)((rgba >> 16) & 0xff);
color.A = (sint8)((rgba >> 24) & 0xff);
return toString("%i %i %i %i", color.R, color.G, color.B, color.A);
}
return "";
}
// ***************************************************************************
int CLuaIHMRyzom::displayChatMessage(CLuaState &ls)
{
//H_AUTO(Lua_CLuaIHM_displayChatMessage)
const char *funcName = "displayChatMessage";
CLuaIHM::checkArgMin(ls, funcName, 2);
CLuaIHM::checkArgType(ls, funcName, 1, LUA_TSTRING);
CInterfaceProperty prop;
CChatStdInput &ci = PeopleInterraction.ChatInput;
std::string msg = ls.toString(1);
const std::string dbPath = "UI:SAVE:CHAT:COLORS";
if (ls.type(2) == LUA_TSTRING)
{
std::string input = toLower(ls.toString(2));
std::unordered_map<std::string, std::string> sParam;
// input should match chat_group_filter sParam
sParam.insert(make_pair(string("around"), string(dbPath+":SAY")));
sParam.insert(make_pair(string("region"), string(dbPath+":REGION")));
sParam.insert(make_pair(string("guild"), string(dbPath+":CLADE")));
sParam.insert(make_pair(string("team"), string(dbPath+":GROUP")));
sParam.insert(make_pair(string("universe"), string(dbPath+":UNIVERSE_NEW")));
for (const auto& db : sParam)
{
if (db.first.c_str() == input)
{
prop.readRGBA(db.second.c_str(), " ");
if (input == "around")
ci.AroundMe.displayMessage(ucstring(msg), prop.getRGBA());
if (input == "region")
ci.Region.displayMessage(ucstring(msg), prop.getRGBA());
if (input == "universe")
ci.Universe.displayMessage(ucstring(msg), prop.getRGBA());
if (input == "guild")
ci.Guild.displayMessage(ucstring(msg), prop.getRGBA());
if (input == "team")
ci.Team.displayMessage(ucstring(msg), prop.getRGBA());
break;
}
}
}
if (ls.type(2) == LUA_TNUMBER)
{
sint64 id = ls.toInteger(2);
prop.readRGBA(toString("%s:DYN:%i", dbPath.c_str(), id).c_str(), " ");
if (id >= 0 && id < CChatGroup::MaxDynChanPerPlayer)
ci.DynamicChat[id].displayMessage(ucstring(msg), prop.getRGBA());
}
return 1;
}
// ***************************************************************************
int CLuaIHMRyzom::scrollElement(CLuaState &ls)
{
const char *funcName = "scrollElement";
// scrollElement(object, vertical, direction, offset_multiplier)
CLuaIHM::checkArgMin(ls, funcName, 3);
CLuaIHM::check(ls, ls.getTop() > 2, funcName);
CLuaIHM::check(ls, CLuaIHM::isUIOnStack(ls, 1), toString("%s requires a UI object in param 1", funcName));
CLuaIHM::check(ls, ls.type(2)==LUA_TBOOLEAN, toString("%s requires a boolean in param 2", funcName));
CLuaIHM::check(ls, ls.isInteger(3), toString("%s requires a number in param 3", funcName));
if (ls.getTop() > 3)
CLuaIHM::check(ls, ls.isInteger(4), toString("%s requires a number in param 4", funcName));
CInterfaceElement *pIE = CLuaIHM::getUIOnStack(ls, 1);
if (pIE)
{
// must be a scroll element
CCtrlScroll *pCS = dynamic_cast<CCtrlScroll*>(pIE);
if (pCS)
{
sint32 direction = 0;
sint32 multiplier = 16;
direction = (ls.toInteger(3) > 0) ? 1 : -1;
if (ls.getTop() > 3)
multiplier = (ls.toInteger(4) > 0) ? ls.toInteger(4) : 1;
const bool vertical = ls.toBoolean(2);
if (vertical)
pCS->moveTrackY(-(direction * multiplier));
else
pCS->moveTrackX(-(direction * multiplier));
return 0;
}
}
ls.pushNil();
return 1;
}

@ -60,6 +60,7 @@ private:
static int getMainPageURL(CLuaState &ls); static int getMainPageURL(CLuaState &ls);
static int getCharSlot(CLuaState &ls); static int getCharSlot(CLuaState &ls);
static int displaySystemInfo(CLuaState &ls); static int displaySystemInfo(CLuaState &ls);
static int displayChatMessage(CLuaState &ls);
static int setWeatherValue(CLuaState &ls); // first value is a boolean to say automatic, second value ranges from of to 1 and gives the weather static int setWeatherValue(CLuaState &ls); // first value is a boolean to say automatic, second value ranges from of to 1 and gives the weather
static int getWeatherValue(CLuaState &ls); // get current real weather value (blend between server driven value & predicted value). Manual weather value is ignored static int getWeatherValue(CLuaState &ls); // get current real weather value (blend between server driven value & predicted value). Manual weather value is ignored
static int disableContextHelpForControl(CLuaState &ls); // params: CCtrlBase*. return: none static int disableContextHelpForControl(CLuaState &ls); // params: CCtrlBase*. return: none
@ -122,8 +123,11 @@ private:
static sint32 getDbProp(const std::string &dbProp); // return 0 if not found. static sint32 getDbProp(const std::string &dbProp); // return 0 if not found.
static sint64 getDbProp64(const std::string &dbProp); // return 0 if not found. static sint64 getDbProp64(const std::string &dbProp); // return 0 if not found.
static void setDbProp(const std::string &dbProp, sint32 value); // Nb: the db prop is not created if not present. static void setDbProp(const std::string &dbProp, sint32 value); // Nb: the db prop is not created if not present.
static void setDbProp64(const std::string &dbProp, sint64 value); // Nb: the db prop is not created if not present.
static void addDbProp(const std::string &dbProp, sint32 value); // Nb: the db prop is created if not present. static void addDbProp(const std::string &dbProp, sint32 value); // Nb: the db prop is created if not present.
static void delDbProp(const std::string &dbProp); static void delDbProp(const std::string &dbProp);
static void setDbRGBA(const std::string &dbProp, const NLMISC::CRGBA &color); // the db prop is created if not present
static std::string getDbRGBA(const std::string &dbProp); // empty string if not found
public: public:
// Print a message in the log. // Print a message in the log.
@ -189,6 +193,7 @@ 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 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);
static std::string getFameName(sint32 fameIndex); static std::string getFameName(sint32 fameIndex);

@ -774,6 +774,10 @@ void CPeopleList::setOnline(uint index, TCharConnectionState online)
CCtrlBase *chatButton = hc->getCtrl("chat_button"); CCtrlBase *chatButton = hc->getCtrl("chat_button");
if (chatButton != NULL) if (chatButton != NULL)
chatButton->setActive(online != ccs_offline); chatButton->setActive(online != ccs_offline);
CCtrlBase *inviteButton = hc->getCtrl("invite_button");
if (inviteButton != NULL)
inviteButton->setActive(online != ccs_offline);
} }
_Peoples[index].Online = online; _Peoples[index].Online = online;

@ -1156,7 +1156,7 @@ void initShardDisplay()
for (uint fff = 0; fff < 20; ++fff) for (uint fff = 0; fff < 20; ++fff)
{ {
CShard s ( toString("%05d",fff), fff%3, fff+32, toString("%s%d","pipo",fff), CShard s ( toString("%05d",fff), fff%3, fff+32, toString("%s%d","pipo",fff),
32*fff%46546, "32.32.32.32", "http://www.ryzomcore.org" ); 32*fff%46546, "32.32.32.32", "http://www.ryzom.com" );
Shards.push_back(s); Shards.push_back(s);
}*/ }*/
@ -1283,7 +1283,7 @@ void onlogin(bool vanishScreen = true)
// for (uint fff = 0; fff < 20; ++fff) // for (uint fff = 0; fff < 20; ++fff)
// { // {
// CShard s ( toString("%05d",fff), fff%3, fff+32, toString("%s%d","pipo",fff), // CShard s ( toString("%05d",fff), fff%3, fff+32, toString("%s%d","pipo",fff),
// 32*fff%46546, "32.32.32.32", "http://www.ryzomcore.org" ); // 32*fff%46546, "32.32.32.32", "http://www.ryzom.com" );
// Shards.push_back(s); // Shards.push_back(s);
// }*/ // }*/
// //

@ -690,7 +690,7 @@ void release()
CStrictTransportSecurity::release(); CStrictTransportSecurity::release();
#if FINAL_VERSION #if FINAL_VERSION
// openURL ("http://www.ryzomcore.org/exit/"); // openURL ("http://ryzom.com/exit/");
#endif #endif
}// release // }// release //

@ -93,6 +93,8 @@ public:
CTypeVersion(std::string type, uint version) {Type=type; Version=version;} CTypeVersion(std::string type, uint version) {Type=type; Version=version;}
}; };
// if you change these values please rebuild the packed_sheets with an updated sheets_packer binary.
// This is the only way to have correct version in both client and packed_sheets
CTypeVersion TypeVersion [] = CTypeVersion TypeVersion [] =
{ {
CTypeVersion("creature", 17), CTypeVersion("creature", 17),

@ -1257,6 +1257,8 @@ void CUserEntity::applyMotion(CEntityCL *target)
mount->_Stages.addStage(NetMngr.getCurrentClientTick()+time, CLFECOMMON::PROPERTY_POSZ, z); mount->_Stages.addStage(NetMngr.getCurrentClientTick()+time, CLFECOMMON::PROPERTY_POSZ, z);
} }
} }
}// applyMotion // }// applyMotion //

@ -1,6 +1,6 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> <html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>Ryzom AI service: Le script d&apos;AI</title> <title>Ryzom AI service: AI Scripting</title>
<link href="doxygen.css" rel="stylesheet" type="text/css"> <link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body> </head><body>
<div class="header"> <div class="header">
@ -19,7 +19,7 @@
</div> </div>
<div class="maindox"> <div class="maindox">
<!-- Generated by Doxygen 1.5.2 --> <!-- Generated by Doxygen 1.5.2 -->
<h1><a class="anchor" name="code">Le script d'AI</a></h1><h2><a class="anchor" name="general"> <h1><a class="anchor" name="code">AI Scripting</a></h1><h2><a class="anchor" name="general">
General information</a></h2> General information</a></h2>
Its a C like code.<p> Its a C like code.<p>
Comments are defined after two slashes like this: <div class="fragment"><pre class="fragment"><span class="comment">// my comment</span> Comments are defined after two slashes like this: <div class="fragment"><pre class="fragment"><span class="comment">// my comment</span>
@ -1464,9 +1464,9 @@ Arguments: f(botIndex) -&gt; s(playerEidAsString) <dl compact><dt><b>Parameters:
()setAggroListTarget(4, $playerId); ()setAggroListTarget(4, $playerId);
</pre></div><h3><a class="anchor" name="getAggroListElement_ff_s"> </pre></div><h3><a class="anchor" name="getAggroListElement_ff_s">
getAggroListElement_ff_s</a></h3> getAggroListElement_ff_s</a></h3>
Get a player entity id (as string) from the aggro list of a bot by it aggro list index.<p> Get a player entity id (as string) from the aggro list of a bot by its aggro list index.<p>
A bot index is used to identify the bot. If there is only one spawned bot in a group then the index value is 0. If we want the bot index of a specific bot the getBotIndexByName function can be used. The function getBotCount can be used to know the number of bot in a group. The function isGroupAlived or isBotAlived can be used to verify if the index is valid. If no bot are identified by the bot index (or bot not spawaned) the function returns an empty string and display a warning message. You can this of using isBotAlived to be sure that the bot index is still a valid value.<p> A bot index is used to identify the bot. If there is only one spawned bot in a group then the index value is 0. If we want the bot index of a specific bot the getBotIndexByName function can be used. The function getBotCount can be used to know the number of bot in a group. The function isGroupAlived or isBotAlived can be used to verify if the index is valid. If no bot are identified by the bot index (or bot not spawned) the function returns an empty string and display a warning message. You can use this with isBotAlived to be sure that the bot index is still a valid value.<p>
A aggro list index is used to identified the player in the aggro list. The size of the aggro list is given by getAggroListSize_f_s )<p> A aggro list index is used to identify the player in the aggro list. The size of the aggro list is given by getAggroListSize_f_s<p>
Arguments: f(botIndex), f(aggroListIndex) -&gt; s(playerEidAsString) <dl compact><dt><b>Parameters:</b></dt><dd> Arguments: f(botIndex), f(aggroListIndex) -&gt; s(playerEidAsString) <dl compact><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0"> <table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>botIndex</em>&nbsp;</td><td>is the index of an bot member of the current group </td></tr> <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>botIndex</em>&nbsp;</td><td>is the index of an bot member of the current group </td></tr>
@ -1474,47 +1474,47 @@ Arguments: f(botIndex), f(aggroListIndex) -&gt; s(playerEidAsString) <dl compact
<tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>playerEidAsString</em>&nbsp;</td><td>is EntityId as string from the player we want infos</td></tr> <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>playerEidAsString</em>&nbsp;</td><td>is EntityId as string from the player we want infos</td></tr>
</table> </table>
</dl> </dl>
<div class="fragment"><pre class="fragment">(aggroSize)getAggorListSize(0); <div class="fragment"><pre class="fragment">(aggroSize)getAggroListSize(0);
<span class="comment">// to much player are attacking the boss</span> <span class="comment">// to much players are attacking the boss</span>
<span class="keywordflow">if</span> (aggoroSize &gt; 10) <span class="keywordflow">if</span> (aggroSize &gt; 10)
{ {
($player1)getAggroListElement(0); &#9;($player1)getAggroListElement(0,0);
($player2)getAggroListElement(1); &#9;($player2)getAggroListElement(1,0);
($player3)getAggroListElement(2); &#9;($player3)getAggroListElement(2,0);
<span class="comment">// so the boss teleport 3 person from its aggro list at the end of the world</span> <span class="comment">&#9;// so the boss teleport 3 players from its aggro list at the end of the world</span>
teleportPlayer($player1, 14233, 123123, 0, 0); &#9;teleportPlayer($player1, 14233, 123123, 0, 0);
teleportPlayer($player2, 14233, 123123, 0, 0); &#9;teleportPlayer($player2, 14233, 123123, 0, 0);
teleportPlayer($player2, 14233, 123123, 0, 0); &#9;teleportPlayer($player2, 14233, 123123, 0, 0);
clearAggroList(); &#9;clearAggroList();
} }
</pre></div><h3><a class="anchor" name="getAggroListSize_f_f"> </pre></div><h3><a class="anchor" name="getAggroListSize_f_f">
getAggroListSize_f_f</a></h3> getAggroListSize_f_f</a></h3>
Get a size of the aggro lsit of a bot (list of aggroable PLAYER)<p> Get a size of the aggro list of a bot (list of aggroable PLAYER)<p>
A bot index is used to identify the bot. If there is only one spawned bot in a group then the index value is 0. If we want the bot index of a specific bot the getBotIndexByName function can be used. The function getBotCount can be used to know the number of bot in a group. The function isGroupAlived or isBotAlived can be used to verify if the index is valid. If no bot are identified by the bot index (or bot not spawaned) the function returns an empty string and display a warning message. You can this of using isBotAlived to be sure that the bot index is still a valid value.<p> A bot index is used to identify the bot. If there is only one spawned bot in a group then the index value is 0. If we want the bot index of a specific bot the getBotIndexByName function can be used. The function getBotCount can be used to know the number of bot in a group. The function isGroupAlived or isBotAlived can be used to verify if the index is valid. If no bot are identified by the bot index (or bot not spawned) the function returns an empty string and display a warning message. You can use this with isBotAlived to be sure that the bot index is still a valid value.<p>
A number is used to indicate the size of the aggro lsit<p> A number is used to indicate the size of the aggro list<p>
Arguments: f(aggroListIndex) -&gt; f(sizeOfAggroList) <dl compact><dt><b>Parameters:</b></dt><dd> Arguments: f(aggroListIndex) -&gt; f(sizeOfAggroList) <dl compact><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0"> <table border="0" cellspacing="2" cellpadding="0">
<tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>botIndex</em>&nbsp;</td><td>is the index of an bot member of the current group. </td></tr> <tr><td valign="top"><tt>[in]</tt>&nbsp;</td><td valign="top"><em>botIndex</em>&nbsp;</td><td>is the index of an bot member of the current group. </td></tr>
<tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>sizeOfAggroList</em>&nbsp;</td><td>The size of the aggro list index.</td></tr> <tr><td valign="top"><tt>[out]</tt>&nbsp;</td><td valign="top"><em>sizeOfAggroList</em>&nbsp;</td><td>The size of the aggro list index.</td></tr>
</table> </table>
</dl> </dl>
<div class="fragment"><pre class="fragment">(aggroSize)getAggorListSize(0); <div class="fragment"><pre class="fragment">(aggroSize)getAggroListSize(0);
<span class="comment">// to much player are attacking the boss</span> <span class="comment">// to much players are attacking the boss</span>
<span class="keywordflow">if</span> (aggoroSize &gt; 10) <span class="keywordflow">if</span> (aggroSize &gt; 10)
{ {
($player1)getAggroListElement(0); &#9;($player1)getAggroListElement(0,0);
($player2)getAggroListElement(1); &#9;($player2)getAggroListElement(1,0);
($player3)getAggroListElement(2); &#9;($player3)getAggroListElement(2,0);
<span class="comment">// so the boss teleport 3 person from its aggro list at the end of the world</span> <span class="comment">&#9;// so the boss teleport 3 players from its aggro list at the end of the world</span>
teleportPlayer($player1, 14233, 123123, 0, 0); &#9;teleportPlayer($player1, 14233, 123123, 0, 0);
teleportPlayer($player2, 14233, 123123, 0, 0); &#9;teleportPlayer($player2, 14233, 123123, 0, 0);
teleportPlayer($player2, 14233, 123123, 0, 0); &#9;teleportPlayer($player2, 14233, 123123, 0, 0);
clearAggroList(); &#9;clearAggroList();
} }
</pre></div><h3><a class="anchor" name="setAggroListTarget_fs_"> </pre></div><h3><a class="anchor" name="setAggroListTarget_fs_">
setAggroListTarget_fs_</a></h3> setAggroListTarget_fs_</a></h3>
Maximize the Aggro of a target from the Aggro list of one bot (this id can be given by getRandomPlayerAggroListTarget)..<p> Maximize the Aggro of a target from the Aggro list of one bot (this id can be given by getRandomPlayerAggroListTarget)..<p>
A bot index is used to identify the bot. If there is only one spawned bot in a group then the index value is 0. If we want the bot index of a specific bot the getBotIndexByName function can be used. The function getBotCount can be used to know the number of bot in a group. The function isGroupAlived or isBotAlived can be used to verify if the index is valid. If no bot are identified by the bot index (or bot not spawaned) the function display a warning message. You can this of using isBotAlived to be sure that the bot index is still a valid value.<p> A bot index is used to identify the bot. If there is only one spawned bot in a group then the index value is 0. If we want the bot index of a specific bot the getBotIndexByName function can be used. The function getBotCount can be used to know the number of bot in a group. The function isGroupAlived or isBotAlived can be used to verify if the index is valid. If no bot are identified by the bot index (or bot not spawned) the function returns an empty string and display a warning message. You can use this with isBotAlived to be sure that the bot index is still a valid value.<p>
A player EntityId is used to identify the player. If the entityId is not from the aggro list then a warning message is shown in the log. If the entityId is a empty string nothing no message are displayed.<p> A player EntityId is used to identify the player. If the entityId is not from the aggro list then a warning message is shown in the log. If the entityId is a empty string nothing no message are displayed.<p>
Arguments: f(botIndex) &gt;s(playerEidAsString) &gt; <dl compact><dt><b>Parameters:</b></dt><dd> Arguments: f(botIndex) &gt;s(playerEidAsString) &gt; <dl compact><dt><b>Parameters:</b></dt><dd>
<table border="0" cellspacing="2" cellpadding="0"> <table border="0" cellspacing="2" cellpadding="0">
@ -1562,7 +1562,6 @@ Arguments:, s(botName) &gt; f(botIndex)<p>
<div class="fragment"><pre class="fragment">(botIndex)getBotIndexByName(<span class="stringliteral">"boss_random_aggro"</span>); <div class="fragment"><pre class="fragment">(botIndex)getBotIndexByName(<span class="stringliteral">"boss_random_aggro"</span>);
($playerId)getRandomPlayerAggroListTarget(botIndex); ($playerId)getRandomPlayerAggroListTarget(botIndex);
()setAggroListTarget(botIndex, $playerId); ()setAggroListTarget(botIndex, $playerId);
}
</pre></div><h3><a class="anchor" name="isGroupAlived__f"> </pre></div><h3><a class="anchor" name="isGroupAlived__f">
isGroupAlived__f</a></h3> isGroupAlived__f</a></h3>
Test if a group is alived (at least one member is alived)<p> Test if a group is alived (at least one member is alived)<p>
@ -1808,7 +1807,7 @@ Arguments: s(botIndex), s(query), c(groupThatWillBeTriggered), f(idOfTheUserEven
</table> </table>
</dl> </dl>
Answer will be given by the getParam<p> Answer will be given by the getParam<p>
<div class="fragment"><pre class="fragment"> <span class="comment">//Sening msg to EGS</span> <div class="fragment"><pre class="fragment"> <span class="comment">//Sending msg to EGS</span>
(@groupToNotify)boss_group.context(); (@groupToNotify)boss_group.context();
()queryEgs(<span class="stringliteral">"Name"</span>, $playerEid, @groupToNotify, 4, <span class="stringliteral">"MSG_NAME"</span>); ()queryEgs(<span class="stringliteral">"Name"</span>, $playerEid, @groupToNotify, 4, <span class="stringliteral">"MSG_NAME"</span>);
()queryEgs(<span class="stringliteral">"Hp"</span>, $playerEid, @groupToNotify, 4, <span class="stringliteral">"msg1"</span>); ()queryEgs(<span class="stringliteral">"Hp"</span>, $playerEid, @groupToNotify, 4, <span class="stringliteral">"msg1"</span>);

@ -17,10 +17,7 @@
#ifndef RYZOM_VERSION_H #ifndef RYZOM_VERSION_H
#define RYZOM_VERSION_H #define RYZOM_VERSION_H
#define RYZOM_VERSION "ryzomcore" \ #define RYZOM_VERSION "3.0.0"
"/" \
"v0.12.0" \
"-dev"
#endif // RYZOM_VERSION_H #endif // RYZOM_VERSION_H

@ -1,4 +1,4 @@
version=4 version=5
[common] [common]
installation_directory= installation_directory=
@ -14,19 +14,21 @@ url_help=http://app.ryzom.com/app_forum/index.php?page=topic/view/22047/1&post14
comments=Science-fantasy MMORPG comments=Science-fantasy MMORPG
[servers] [servers]
size=2 size=3
[server_0] [server_0]
id=ryzom_live id=ryzom_live
name=Atys name=Atys
display_url="http://app.ryzom.com/app_releasenotes/index.php?lang=$LANG" display_url="http://app.ryzom.com/app_releasenotes/index.php?lang=$LANG"
files_list_url="https://sourceforge.net/projects/ryzom/rss?path=/installer" files_list_url="https://sourceforge.net/projects/ryzom/rss?path=/installer&not_used_yet"
data_download_url="http://downloads.sourceforge.net/project/ryzom/installer/ryzom_live_data.7z?r=&ts=$TIMESTAMP" data_download_url="https://download.ryzom.com/ryzom_live_data.7z"
data_download_filename=ryzom_live_data.7z data_download_filename=ryzom_live_data.7z
data_compressed_size=1500000000 data_compressed_size=1500000000
data_uncompressed_size=7000000000 data_uncompressed_size=7000000000
client_download_url="http://downloads.sourceforge.net/project/ryzom/installer/ryzom_live_client_$ARCH.7z?r=&ts=$TIMESTAMP" client_download_url="https://download.ryzom.com/ryzom_live_client_$ARCH.7z"
client_download_filename=ryzom_live_client_$ARCH.7z client_download_filename=ryzom_live_client_$ARCH.7z
cfg_download_url="https://download.ryzom.com/client_atys.cfg"
cfg_download_filename=client_atys.cfg
client_filename_windows=ryzom_client_r.exe client_filename_windows=ryzom_client_r.exe
client_filename_osx=Ryzom.app/Contents/MacOS/Ryzom client_filename_osx=Ryzom.app/Contents/MacOS/Ryzom
client_filename_linux=ryzom_client client_filename_linux=ryzom_client
@ -40,13 +42,15 @@ comments=
id=ryzom_dev id=ryzom_dev
name=Yubo name=Yubo
display_url="http://app.ryzom.com/app_releasenotes/index.php?lang=$LANG" display_url="http://app.ryzom.com/app_releasenotes/index.php?lang=$LANG"
files_list_url="https://sourceforge.net/projects/ryzom/rss?path=/installer" files_list_url="https://sourceforge.net/projects/ryzom/rss?path=/installer&not_used_yet"
data_download_url="http://downloads.sourceforge.net/project/ryzom/installer/ryzom_live_data.7z?r=&ts=$TIMESTAMP" data_download_url="https://download.ryzom.com/ryzom_live_data.7z"
data_download_filename=ryzom_live_data.7z data_download_filename=ryzom_live_data.7z
data_compressed_size=1500000000 data_compressed_size=1500000000
data_uncompressed_size=7000000000 data_uncompressed_size=7000000000
client_download_url="http://downloads.sourceforge.net/project/ryzom/installer/ryzom_live_client_$ARCH.7z?r=&ts=$TIMESTAMP" client_download_url="https://download.ryzom.com/ryzom_live_client_$ARCH.7z"
client_download_filename=ryzom_live_client_$ARCH.7z client_download_filename=ryzom_live_client_$ARCH.7z
cfg_download_url="https://download.ryzom.com/client_yubo.cfg"
cfg_download_filename=client_yubo.cfg
client_filename_windows=ryzom_client_r.exe client_filename_windows=ryzom_client_r.exe
client_filename_osx=Ryzom.app/Contents/MacOS/Ryzom client_filename_osx=Ryzom.app/Contents/MacOS/Ryzom
client_filename_linux=ryzom_client client_filename_linux=ryzom_client
@ -54,7 +58,30 @@ client_filename_old_windows=client_ryzom_rd.exe
configuration_filename_windows=ryzom_configuration_qt_r.exe configuration_filename_windows=ryzom_configuration_qt_r.exe
configuration_filename_osx=Ryzom.app/Contents/MacOS/RyzomConfiguration configuration_filename_osx=Ryzom.app/Contents/MacOS/RyzomConfiguration
configuration_filename_linux=ryzom_configuration_qt configuration_filename_linux=ryzom_configuration_qt
comments=Test server comments=
[server_2]
id=ryzom_test
name=Gingo
display_url="http://app.ryzom.com/app_releasenotes/index.php?lang=$LANG"
files_list_url="https://sourceforge.net/projects/ryzom/rss?path=/installer&not_used_yet"
data_download_url="https://download.ryzom.com/ryzom_live_data.7z"
data_download_filename=ryzom_live_data.7z
data_compressed_size=1500000000
data_uncompressed_size=7000000000
client_download_url="https://download.ryzom.com/ryzom_live_client_$ARCH.7z"
client_download_filename=ryzom_live_client_$ARCH.7z
cfg_download_url="https://download.ryzom.com/client_gingo.cfg"
cfg_download_filename=client_gingo.cfg
client_filename_windows=ryzom_client_r.exe
client_filename_osx=Ryzom.app/Contents/MacOS/Ryzom
client_filename_linux=ryzom_client
client_filename_old_windows=client_ryzom_rd.exe
configuration_filename_windows=ryzom_configuration_qt_r.exe
configuration_filename_osx=Ryzom.app/Contents/MacOS/RyzomConfiguration
configuration_filename_linux=ryzom_configuration_qt
comments=
[profiles] [profiles]
size=0 size=0

@ -877,6 +877,8 @@ bool COperationDialog::createDefaultProfile()
profile.comments = "Default profile created by Ryzom Installer"; profile.comments = "Default profile created by Ryzom Installer";
profile.desktopShortcut = false; profile.desktopShortcut = false;
profile.menuShortcut = false; profile.menuShortcut = false;
// default use locale
profile.language = config->getLanguage();
#ifdef Q_OS_WIN32 #ifdef Q_OS_WIN32
QStringList paths; QStringList paths;

@ -33,6 +33,7 @@ void CProfile::loadFromSettings(const QSettings &settings)
executable = settings.value("executable").toString(); executable = settings.value("executable").toString();
arguments = settings.value("arguments").toString(); arguments = settings.value("arguments").toString();
comments = settings.value("comments").toString(); comments = settings.value("comments").toString();
language = settings.value("language").toString();
desktopShortcut = settings.value("desktop_shortcut").toBool(); desktopShortcut = settings.value("desktop_shortcut").toBool();
menuShortcut = settings.value("menu_shortcut").toBool(); menuShortcut = settings.value("menu_shortcut").toBool();
} }
@ -45,6 +46,7 @@ void CProfile::saveToSettings(QSettings &settings) const
settings.setValue("executable", executable); settings.setValue("executable", executable);
settings.setValue("arguments", arguments); settings.setValue("arguments", arguments);
settings.setValue("comments", comments); settings.setValue("comments", comments);
settings.setValue("language", language);
settings.setValue("desktop_shortcut", desktopShortcut); settings.setValue("desktop_shortcut", desktopShortcut);
settings.setValue("menu_shortcut", menuShortcut); settings.setValue("menu_shortcut", menuShortcut);
} }
@ -175,7 +177,7 @@ bool CProfile::createClientConfig() const
// create the 2 initial lines of client.cfg // create the 2 initial lines of client.cfg
QString rootConfigFilenameLine = QString("RootConfigFilename = \"%1\";").arg(s.getDefaultClientConfigFullPath()); QString rootConfigFilenameLine = QString("RootConfigFilename = \"%1\";").arg(s.getDefaultClientConfigFullPath());
QString languageCodeline = QString("LanguageCode = \"%1\";\n").arg(CConfigFile::getInstance()->getLanguage()); QString languageCodeline = QString("LanguageCode = \"%1\";\n").arg(language);
QString content; QString content;

@ -34,6 +34,7 @@ public:
QString executable; QString executable;
QString arguments; QString arguments;
QString comments; QString comments;
QString language;
bool desktopShortcut; bool desktopShortcut;
bool menuShortcut; bool menuShortcut;

@ -108,6 +108,7 @@ void CProfilesDialog::displayProfile(int index)
serverComboBox->setEnabled(enabled); serverComboBox->setEnabled(enabled);
argumentsEdit->setEnabled(enabled); argumentsEdit->setEnabled(enabled);
commentsEdit->setEnabled(enabled); commentsEdit->setEnabled(enabled);
langComboBox->setEnabled(enabled);
if (index < 0) return; if (index < 0) return;
@ -134,6 +135,7 @@ void CProfilesDialog::displayProfile(int index)
directoryPathLabel->setText(profileDirectory); directoryPathLabel->setText(profileDirectory);
desktopShortcutCheckBox->setChecked(profile.desktopShortcut); desktopShortcutCheckBox->setChecked(profile.desktopShortcut);
menuShortcutCheckBox->setChecked(profile.menuShortcut); menuShortcutCheckBox->setChecked(profile.menuShortcut);
langComboBox->setCurrentIndex(getIndexFromProfileLanguage(profile.language));
// disable click on button if directory doesn't exist // disable click on button if directory doesn't exist
directoryButton->setEnabled(QFile::exists(profileDirectory)); directoryButton->setEnabled(QFile::exists(profileDirectory));
@ -155,6 +157,7 @@ void CProfilesDialog::saveProfile(int index)
profile.comments = commentsEdit->toPlainText(); profile.comments = commentsEdit->toPlainText();
profile.desktopShortcut = desktopShortcutCheckBox->isChecked(); profile.desktopShortcut = desktopShortcutCheckBox->isChecked();
profile.menuShortcut = menuShortcutCheckBox->isChecked(); profile.menuShortcut = menuShortcutCheckBox->isChecked();
profile.language = getProfileLanguageFromIndex(langComboBox->currentIndex());
} }
void CProfilesDialog::deleteProfile(int index) void CProfilesDialog::deleteProfile(int index)
@ -170,7 +173,9 @@ void CProfilesDialog::deleteProfile(int index)
profilesListView->setCurrentIndex(m_model->index(index, 0)); profilesListView->setCurrentIndex(m_model->index(index, 0));
displayProfile(index); displayProfile(index);
// TODO: delete files for delete profile // delete files for delete profile
COperationDialog dialog(this);
dialog.setOperation(OperationUpdateProfiles);
} }
void CProfilesDialog::addProfile() void CProfilesDialog::addProfile()
@ -214,6 +219,7 @@ void CProfilesDialog::addProfile()
// set default parameters // set default parameters
profile.id = QString::number(nextId); profile.id = QString::number(nextId);
profile.server = server.id; profile.server = server.id;
profile.language = config->getLanguage(); // locale
profilesListView->setCurrentIndex(m_model->index(index, 0)); profilesListView->setCurrentIndex(m_model->index(index, 0));
displayProfile(index); displayProfile(index);
@ -310,3 +316,25 @@ void CProfilesDialog::onProfileDirectoryClicked()
QDesktopServices::openUrl(QUrl::fromLocalFile(profileDirectory)); QDesktopServices::openUrl(QUrl::fromLocalFile(profileDirectory));
} }
int CProfilesDialog::getIndexFromProfileLanguage(const QString &lang) const
{
if (lang == "en") return 0;
if (lang == "fr") return 1;
if (lang == "de") return 2;
if (lang == "es") return 3;
if (lang == "ru") return 4;
return -1;
}
QString CProfilesDialog::getProfileLanguageFromIndex(int index) const
{
if (index == 0) return "en";
if (index == 1) return "fr";
if (index == 2) return "de";
if (index == 3) return "es";
if (index == 4) return "ru";
// locale
return CConfigFile::getInstance()->getLanguage();
}

@ -54,6 +54,10 @@ private slots:
void onExecutableDefaultClicked(); void onExecutableDefaultClicked();
void onExecutableBrowseClicked(); void onExecutableBrowseClicked();
int getIndexFromProfileLanguage(const QString &langId) const;
QString getProfileLanguageFromIndex(int index) const;
private: private:
CProfilesModel *m_model; CProfilesModel *m_model;
CServersModel *m_serversModel; CServersModel *m_serversModel;

@ -828,18 +828,23 @@ Drücke Weiter und folge den verschiedenen Schritten bis zum Ende.</translation>
<source>Open</source> <source>Open</source>
<translation>Öffnen</translation> <translation>Öffnen</translation>
</message> </message>
<message>
<location filename="../ui/profilesdialog.ui" line="207"/>
<source>Language:</source>
<translation>Sprache :</translation>
</message>
<message> <message>
<location filename="../ui/profilesdialog.ui" line="207"/> <location filename="../ui/profilesdialog.ui" line="207"/>
<source>Create shortcuts:</source> <source>Create shortcuts:</source>
<translation>Erstelle Verknüpfungen:</translation> <translation>Erstelle Verknüpfungen:</translation>
</message> </message>
<message> <message>
<location filename="../ui/profilesdialog.ui" line="216"/> <location filename="../ui/profilesdialog.ui" line="223"/>
<source>Desktop</source> <source>Desktop</source>
<translation>Desktop</translation> <translation>Desktop</translation>
</message> </message>
<message> <message>
<location filename="../ui/profilesdialog.ui" line="223"/> <location filename="../ui/profilesdialog.ui" line="230"/>
<source>Start Menu</source> <source>Start Menu</source>
<translation>Start-Menü</translation> <translation>Start-Menü</translation>
</message> </message>

@ -635,16 +635,21 @@ Just press Continue button and follow the different steps until everything is do
</message> </message>
<message> <message>
<location filename="../ui/profilesdialog.ui" line="207"/> <location filename="../ui/profilesdialog.ui" line="207"/>
<source>Language:</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/profilesdialog.ui" line="214"/>
<source>Create shortcuts:</source> <source>Create shortcuts:</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/profilesdialog.ui" line="216"/> <location filename="../ui/profilesdialog.ui" line="223"/>
<source>Desktop</source> <source>Desktop</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message> <message>
<location filename="../ui/profilesdialog.ui" line="223"/> <location filename="../ui/profilesdialog.ui" line="230"/>
<source>Start Menu</source> <source>Start Menu</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>

@ -841,16 +841,21 @@ Vous n&apos;avez qu&apos;à cliquer sur Suivant et suivre les différentes étap
</message> </message>
<message> <message>
<location filename="../ui/profilesdialog.ui" line="207"/> <location filename="../ui/profilesdialog.ui" line="207"/>
<source>Language:</source>
<translation>Langage :</translation>
</message>
<message>
<location filename="../ui/profilesdialog.ui" line="214"/>
<source>Create shortcuts:</source> <source>Create shortcuts:</source>
<translation>Créer les raccourcis :</translation> <translation>Créer les raccourcis :</translation>
</message> </message>
<message> <message>
<location filename="../ui/profilesdialog.ui" line="216"/> <location filename="../ui/profilesdialog.ui" line="223"/>
<source>Desktop</source> <source>Desktop</source>
<translation>Bureau</translation> <translation>Bureau</translation>
</message> </message>
<message> <message>
<location filename="../ui/profilesdialog.ui" line="223"/> <location filename="../ui/profilesdialog.ui" line="230"/>
<source>Start Menu</source> <source>Start Menu</source>
<translation>Menu Démarrer</translation> <translation>Menu Démarrer</translation>
</message> </message>

@ -807,16 +807,21 @@ Just press Continue button and follow the different steps until everything is do
</message> </message>
<message> <message>
<location filename="../ui/profilesdialog.ui" line="207"/> <location filename="../ui/profilesdialog.ui" line="207"/>
<source>Language:</source>
<translation>Язык:</translation>
</message>
<message>
<location filename="../ui/profilesdialog.ui" line="214"/>
<source>Create shortcuts:</source> <source>Create shortcuts:</source>
<translation>Создать ярлыки:</translation> <translation>Создать ярлыки:</translation>
</message> </message>
<message> <message>
<location filename="../ui/profilesdialog.ui" line="216"/> <location filename="../ui/profilesdialog.ui" line="223"/>
<source>Desktop</source> <source>Desktop</source>
<translation>Рабочий стол</translation> <translation>Рабочий стол</translation>
</message> </message>
<message> <message>
<location filename="../ui/profilesdialog.ui" line="223"/> <location filename="../ui/profilesdialog.ui" line="230"/>
<source>Start Menu</source> <source>Start Menu</source>
<translation>меню Пуск</translation> <translation>меню Пуск</translation>
</message> </message>

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>583</width> <width>631</width>
<height>329</height> <height>356</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@ -202,13 +202,20 @@
</layout> </layout>
</item> </item>
<item row="7" column="0"> <item row="7" column="0">
<widget class="QLabel" name="langLabel">
<property name="text">
<string>Language:</string>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="shortcutsLabel"> <widget class="QLabel" name="shortcutsLabel">
<property name="text"> <property name="text">
<string>Create shortcuts:</string> <string>Create shortcuts:</string>
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="1"> <item row="8" column="1">
<layout class="QVBoxLayout" name="shortcutsLayout"> <layout class="QVBoxLayout" name="shortcutsLayout">
<item> <item>
<widget class="QCheckBox" name="desktopShortcutCheckBox"> <widget class="QCheckBox" name="desktopShortcutCheckBox">
@ -226,6 +233,35 @@
</item> </item>
</layout> </layout>
</item> </item>
<item row="7" column="1">
<widget class="QComboBox" name="langComboBox">
<item>
<property name="text">
<string>English</string>
</property>
</item>
<item>
<property name="text">
<string>Francais</string>
</property>
</item>
<item>
<property name="text">
<string>Deutsch</string>
</property>
</item>
<item>
<property name="text">
<string>Español</string>
</property>
</item>
<item>
<property name="text">
<string>Russian (РУССКИЙ)</string>
</property>
</item>
</widget>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>
@ -250,10 +286,11 @@
<tabstop>serverComboBox</tabstop> <tabstop>serverComboBox</tabstop>
<tabstop>executableBrowseButton</tabstop> <tabstop>executableBrowseButton</tabstop>
<tabstop>argumentsEdit</tabstop> <tabstop>argumentsEdit</tabstop>
<tabstop>commentsEdit</tabstop>
<tabstop>directoryButton</tabstop> <tabstop>directoryButton</tabstop>
<tabstop>langComboBox</tabstop>
<tabstop>desktopShortcutCheckBox</tabstop> <tabstop>desktopShortcutCheckBox</tabstop>
<tabstop>menuShortcutCheckBox</tabstop> <tabstop>menuShortcutCheckBox</tabstop>
<tabstop>commentsEdit</tabstop>
</tabstops> </tabstops>
<resources/> <resources/>
<connections> <connections>

@ -0,0 +1,6 @@
@echo off
echo Generating words diff...
bin\translation_tools make_words_diff
echo Done.
pause

@ -0,0 +1,6 @@
@echo off
echo Merging words diff...
bin\translation_tools merge_words_diff
echo Done.
pause

@ -0,0 +1,16 @@
@echo off
echo Installing translation file into ryzom...
REM Copy translated files in client directory...
xcopy /Y translated\*.uxt ..\..\client\data\gamedev\language\
xcopy /Y translated\skill_*.txt ..\..\client\data\gamedev\language\
xcopy /Y translated\item_*.txt ..\..\client\data\gamedev\language\
xcopy /Y translated\creature_*.txt ..\..\client\data\gamedev\language\
xcopy /Y translated\sbrick_*.txt ..\..\client\data\gamedev\language\
xcopy /Y translated\sphrase_*.txt ..\..\client\data\gamedev\language\
xcopy /Y translated\place_*.txt ..\..\client\data\gamedev\language\
xcopy /Y translated\faction_*.txt ..\..\client\data\gamedev\language\
xcopy /Y translated\title_*.txt ..\..\client\data\gamedev\language\
xcopy /Y translated\outpost_*.txt ..\..\client\data\gamedev\language\
echo Done.

@ -0,0 +1,6 @@
@echo off
echo Cleaning string diff...
bin\translation_tools clean_string_diff
echo Done.
pause

@ -0,0 +1,6 @@
@echo off
echo Generating string diff...
bin\translation_tools make_string_diff
echo Done.
pause

@ -0,0 +1,6 @@
@echo off
echo Merging string diff...
bin\translation_tools merge_string_diff
echo Done.
pause

@ -0,0 +1,24 @@
Please don't update files in "translated" directly!
First, be sure you put "translation_tools" in "bin" directory.
How to update translations in UXT files :
1. Update original texts in "work/wk.uxt"
2. Launch A_make_string_diff script
3. Open files in "diff" directory
4. Replace original text with translation between [ and ]
5. The 2 last lines : // REMOVE THE FOLOWING LINE WHEN TRANSLATION IS DONE and // DIFF NOT TRANSLATED
6. Save files
7. Launch AA_clean_string_diff to delete translations help (old values)
8. Launch B_merge_string_diff to merge your translations in "translated"
How to update translations in words files :
1. Update original texts in "work" directory
2. Launch 5_make_words_diff script
3. Open files in "diff" directory
4. Replace original text with translation (separators are <tab>)
5. The 2 last lines : REMOVE THE FOLOWING TWO LINE WHEN TRANSLATION IS DONE and DIFF NOT TRANSLATED
6. Save files
7. Launch 6_merge_words_diff to merge your translations in "translated"

@ -0,0 +1,43 @@
*HASH_VALUE bodypartID name pro daa ia da p pia pda description
_ACB9BC721BA65099 HHead Kopf deinen den ein der Köpfe die
_278A7C5D654814CD HChest Oberkörper deinen den ein der Oberkörper die
_A2D940906B29B889 HArms Arme deine die die Arme die
_B1CAFC85DB767C9C HHands Hände deine die die Hände die
_20A8389BAC987C9F HLegs Beine deine die die Beine die
_E18820962C586494 HFeet Füße deine die die Füße die
_ACB9BC7B1B375099 QHead Kopf deinen den ein der Köpfe die
_E80BB4A21A9838B5 QBody Körper deinen den ein der Körper die
_C96F0919D2F8DC71 QFrontPaws Vorderbeine deinen die die Vorderbeine die
_08A1A8FEABC3CD11 QFrontHooves Vorderbeine deine die die Vorderbeine die
_23B95F02A87957B0 QRearPaws Hinterbeine deine die die Hinterbeine die
_D880990C5BE9DCB7 QRearHooves Hinterbeine deine die die Hinterbeine die
_2836645DDE8874AD LKHead Kopf deinen den ein der Köpfe die
_ED86C05FE298A4B9 LKBody Körper deinen den ein der Körper die
_39BFC0EBE486B512 LKFrontPaws1 Vorderbeine deine die die Vorderbeine die
_79BFC0EBE486B512 LKFrontPaws2 Vorderbeine deine die die Vorderbeine die
_D92BB508D8F884A6 LKRearPaws1 Hinterbeine deine die die Hinterbeine die
_D93BB508D8F884A6 LKRearPaws2 Hinterbeine deine die die Hinterbeine die
_283664575C8874AD FKHead Kopf deinen den ein der Köpfe die
_ED86C0596098A4B9 FKBody Körper deinen den ein der Körper die
_DBBA7473640310B0 FKPaws1 Beine deine die die Beine die
_1BBA7473641310B0 FKPaws2 Beine deine die die Beine die
_66B6A47A4A7ADCC2 FKWings1 Flügel deine die die Flügel die
_66B6A47ACA7ADCC2 FKWings2 Flügel deine die die Flügel die
_ACB9BC701B865099 FHead Kopf deinen den ein der Köpfe die
_E80BB4971AE738B5 FBody Körper deinen den ein der Körper die
_C40D15A82A36DF2C FFrontFins1 Vorderflossen deine die die Vorderflossen die
_C41D15A82A36DF2C FFrontFins2 Vorderflossen deine die die Vorderflossen die
_67B624EBAAF630A4 FRearFins1 Hinterflossen deine die die Hinterflossen die
_67B628EBAAF630A4 FRearFins2 Hinterflossen deine die die Hinterflossen die
_ACB9BC6C1B465099 BHead Kopf deinen den ein der Köpfe die
_E80BB4931AA738B5 BBody Körper deinen den ein der Körper die
_25897F8F25594780 BFeet1 Füße deine die die Füße die
_2589838F25594B80 BFeet2 Füße deine die die Füße die
_2C68746BA436D3C2 BWings1 Flügel deine die die Flügel die
_2C68746BA446D7C2 BWings2 Flügel deine die die Flügel die
_8061E6E18C3EA521 PUpperTrunk Stiel deinen den ein die Stiele die
_ECEA3087A666CCC3 Ptrunk Rüssel deinen den ein die Rüssel die
_E7469C4D9B5A0C9D PLeaves1 Blatt dein das ein die Blätter die
_E7469C4DDB5A0C9D PLeaves2 Blatt dein das ein die Blätter die
_C3EE9906771FB524 PLowerTrunk Stamm deinen den ein die Stämme die
_DFA67A5CC7DECDE6 PVisibleRoots Wurzel deine die eine die Wurzeln die

@ -0,0 +1,43 @@
*HASH_VALUE bodypartID name ia da p pia pda description
_ACB9BC721BA65099 HHead head a the heads \d the
_278A7C5D654814CD HChest chest a the chests \d the
_A2D940906B29B889 HArms arms \d the arms \d the
_B1CAFC85DB767C9C HHands hands \d the hands \d the
_20A8389BAC987C9F HLegs legs \d the legs \d the
_E18820962C586494 HFeet feet \d the feet \d the
_ACB9BC7B1B375099 QHead head a the heads \d the
_E80BB4A21A9838B5 QBody body a the bodies \d the
_C96F0919D2F8DC71 QFrontPaws forelegs \d the forelegs \d the
_08A1A8FEABC3CD11 QFrontHooves forelegs \d the forelegs \d the
_23B95F02A87957B0 QRearPaws hind legs \d the hind legs \d the
_D880990C5BE9DCB7 QRearHooves hind legs \d the hind legs \d the
_2836645DDE8874AD LKHead head a the heads \d the
_ED86C05FE298A4B9 LKBody body a the bodies \d the
_39BFC0EBE486B512 LKFrontPaws1 forelegs \d the forelegs \d the
_79BFC0EBE486B512 LKFrontPaws2 forelegs \d the forelegs \d the
_D92BB508D8F884A6 LKRearPaws1 hind legs \d the hind legs \d the
_D93BB508D8F884A6 LKRearPaws2 hind legs \d the hind legs \d the
_283664575C8874AD FKHead head a the heads \d the
_ED86C0596098A4B9 FKBody body a the bodies \d the
_DBBA7473640310B0 FKPaws1 legs \d the legs \d the
_1BBA7473641310B0 FKPaws2 legs \d the legs \d the
_66B6A47A4A7ADCC2 FKWings1 wings \d the wings \d the
_66B6A47ACA7ADCC2 FKWings2 wings \d the wings \d the
_ACB9BC701B865099 FHead head a the heads \d the
_E80BB4971AE738B5 FBody body a the bodies \d the
_C40D15A82A36DF2C FFrontFins1 fore fins \d the fore fins \d the
_C41D15A82A36DF2C FFrontFins2 fore fins \d the fore fins \d the
_67B624EBAAF630A4 FRearFins1 hind fins \d the hind fins \d the
_67B628EBAAF630A4 FRearFins2 hind fins \d the hind fins \d the
_ACB9BC6C1B465099 BHead head a the heads \d the
_E80BB4931AA738B5 BBody body a the bodies \d the
_25897F8F25594780 BFeet1 feet \d the feet \d the
_2589838F25594B80 BFeet2 feet \d the feet \d the
_2C68746BA436D3C2 BWings1 wings \d the wings \d the
_2C68746BA446D7C2 BWings2 wings \d the wings \d the
_8061E6E18C3EA521 PUpperTrunk upper trunk an the upper trunks \d the
_ECEA3087A666CCC3 Ptrunk trunk a the trunks \d the
_E7469C4D9B5A0C9D PLeaves1 leaf a the leaves \d the
_E7469C4DDB5A0C9D PLeaves2 leaf a the leaves \d the
_C3EE9906771FB524 PLowerTrunk lower trunk a the lower trunks \d the
_DFA67A5CC7DECDE6 PVisibleRoots visible root a the visible roots \d the

@ -0,0 +1,43 @@
*HASH_VALUE bodypartID name ia da p pia pda description
_ACB9BC721BA65099 HHead cabeza una la cabezas las
_278A7C5D654814CD HChest torso un el torsos los
_A2D940906B29B889 HArms brazo un el brazos los
_B1CAFC85DB767C9C HHands mano una la manos las
_20A8389BAC987C9F HLegs pierna una la piernas las
_E18820962C586494 HFeet pie un el pies los
_ACB9BC7B1B375099 QHead cabeza una la cabezas las
_E80BB4A21A9838B5 QBody cuerpo un el cuerpos los
_C96F0919D2F8DC71 QFrontPaws pata delantera una la patas delanteras las
_08A1A8FEABC3CD11 QFrontHooves pezuña delantera una la pezuñas delanteras las
_23B95F02A87957B0 QRearPaws pata trasera una la patas traseras las
_D880990C5BE9DCB7 QRearHooves pezuña trasera una la pezuñas traseras las
_2836645DDE8874AD LKHead cabeza una la cabezas las
_ED86C05FE298A4B9 LKBody cuerpo un el cuerpos los
_39BFC0EBE486B512 LKFrontPaws1 pata delantera una la patas delanteras las
_79BFC0EBE486B512 LKFrontPaws2 pata delantera una la pata delanteras las
_D92BB508D8F884A6 LKRearPaws1 pata trasera una la patas traseras las
_D93BB508D8F884A6 LKRearPaws2 pata trasera una la patas traseras las
_283664575C8874AD FKHead cabeza una la cabezas las
_ED86C0596098A4B9 FKBody cuerpo un el cuerpos los
_DBBA7473640310B0 FKPaws1 pierna una la piernas las
_1BBA7473641310B0 FKPaws2 pierna una la piernas las
_66B6A47A4A7ADCC2 FKWings1 ala un el alas las
_66B6A47ACA7ADCC2 FKWings2 ala un el alas las
_ACB9BC701B865099 FHead cabeza una la cabezas las
_E80BB4971AE738B5 FBody cuerpo un el cuerpos los
_C40D15A82A36DF2C FFrontFins1 aleta delantera una la aletas delanteras las
_C41D15A82A36DF2C FFrontFins2 aleta delantera una la aletas delanteras las
_67B624EBAAF630A4 FRearFins1 aleta trasera una la aletas traseras las
_67B628EBAAF630A4 FRearFins2 aleta trasera una la aletas traseras las
_ACB9BC6C1B465099 BHead cabeza una la cabezas las
_E80BB4931AA738B5 BBody cuerpo un el cuerpos los
_25897F8F25594780 BFeet1 pie un el pies los
_2589838F25594B80 BFeet2 pie un el pies los
_2C68746BA436D3C2 BWings1 ala un el alas las
_2C68746BA446D7C2 BWings2 ala un el alas las
_8061E6E18C3EA521 PUpperTrunk tronco superior un el troncos superiores los
_ECEA3087A666CCC3 Ptrunk tronco un el troncos los
_E7469C4D9B5A0C9D PLeaves1 hoja una la hojas las
_E7469C4DDB5A0C9D PLeaves2 hoja una la hojas las
_C3EE9906771FB524 PLowerTrunk tronco inferior un el troncos inferiores los
_DFA67A5CC7DECDE6 PVisibleRoots raíz visible una la raíces visibles las

@ -0,0 +1,43 @@
*HASH_VALUE bodypartID name ia da p pia pda description
_ACB9BC721BA65099 HHead tête une la têtes des les
_278A7C5D654814CD HChest poitrine une la poitrines des les
_A2D940906B29B889 HArms bras un le bras des les
_B1CAFC85DB767C9C HHands main une la mains des les
_20A8389BAC987C9F HLegs jambe une la jambes des les
_E18820962C586494 HFeet pied un le pieds des les
_ACB9BC7B1B375099 QHead tête une la têtes des les
_E80BB4A21A9838B5 QBody corps un le corps des les
_C96F0919D2F8DC71 QFrontPaws patte avant une la pattes avant des les
_08A1A8FEABC3CD11 QFrontHooves sabot avant un le sabots avant des les
_23B95F02A87957B0 QRearPaws patte arrière une la pattes arrière des les
_D880990C5BE9DCB7 QRearHooves sabot arrière un le sabots arrière des les
_2836645DDE8874AD LKHead tête une la têtes des les
_ED86C05FE298A4B9 LKBody corps un le corps des les
_39BFC0EBE486B512 LKFrontPaws1 patte avant une la pattes avant des les
_79BFC0EBE486B512 LKFrontPaws2 patte avant une la pattes avant des les
_D92BB508D8F884A6 LKRearPaws1 patte arrière une la pattes arrière des les
_D93BB508D8F884A6 LKRearPaws2 patte arrière une la pattes arrière des les
_283664575C8874AD FKHead tête une la têtes des les
_ED86C0596098A4B9 FKBody corps un le corps des les
_DBBA7473640310B0 FKPaws1 patte une la pattes des les
_1BBA7473641310B0 FKPaws2 patte une la pattes des les
_66B6A47A4A7ADCC2 FKWings1 aile une l'\d ailes des les
_66B6A47ACA7ADCC2 FKWings2 aile une l'\d ailes des les
_ACB9BC701B865099 FHead tête une la têtes des les
_E80BB4971AE738B5 FBody corps un le corps des les
_C40D15A82A36DF2C FFrontFins1 nageoire avant une la nageoires avant des les
_C41D15A82A36DF2C FFrontFins2 nageoire avant une la nageoires avant des les
_67B624EBAAF630A4 FRearFins1 nageoire arrière une la nageoires arrière des les
_67B628EBAAF630A4 FRearFins2 nageoire arrière une la nageoires arrière des les
_ACB9BC6C1B465099 BHead tête une la têtes des les
_E80BB4931AA738B5 BBody corps un le corps des les
_25897F8F25594780 BFeet1 pied un le pieds des les
_2589838F25594B80 BFeet2 pied un le pieds des les
_2C68746BA436D3C2 BWings1 aile un l'\d ailes des les
_2C68746BA446D7C2 BWings2 aile un l'\d ailes des les
_8061E6E18C3EA521 PUpperTrunk tige supérieure une la tiges supérieures des les
_ECEA3087A666CCC3 Ptrunk tige une la tiges des les
_E7469C4D9B5A0C9D PLeaves1 feuille une la feuilles des les
_E7469C4DDB5A0C9D PLeaves2 feuille une la feuilles des les
_C3EE9906771FB524 PLowerTrunk tige inférieure une la tiges inférieures des les
_DFA67A5CC7DECDE6 PVisibleRoots racine visible une la racines visibles des les

@ -0,0 +1,43 @@
*HASH_VALUE bodypartID name p description prp
_ACB9BC721BA65099 HHead голове головы по
_278A7C5D654814CD HChest грудь груди в
_A2D940906B29B889 HArms предплечью предплечья по
_B1CAFC85DB767C9C HHands руке руки по
_20A8389BAC987C9F HLegs ноге ноги по
_E18820962C586494 HFeet ступне ступни по
_ACB9BC7B1B375099 QHead голове головы по
_E80BB4A21A9838B5 QBody туловище туловища в
_C96F0919D2F8DC71 QFrontPaws передней лапе передние лапы по
_08A1A8FEABC3CD11 QFrontHooves передней ноге передние ноги по
_23B95F02A87957B0 QRearPaws задней лапе задние лапы по
_D880990C5BE9DCB7 QRearHooves задней ноге задние ноги по
_2836645DDE8874AD LKHead голове головы по
_ED86C05FE298A4B9 LKBody туловище туловища по
_39BFC0EBE486B512 LKFrontPaws1 передней лапе передние лапы по
_79BFC0EBE486B512 LKFrontPaws2 передней лапе передние лапы по
_D92BB508D8F884A6 LKRearPaws1 задней лапе задние лапы по
_D93BB508D8F884A6 LKRearPaws2 задняя лапе задние лапы по
_283664575C8874AD FKHead голове головы по
_ED86C0596098A4B9 FKBody туловище туловища в
_DBBA7473640310B0 FKPaws1 лапе лапы по
_1BBA7473641310B0 FKPaws2 ноге ноги по
_66B6A47A4A7ADCC2 FKWings1 крылу крылья по
_66B6A47ACA7ADCC2 FKWings2 крылу крылья по
_ACB9BC701B865099 FHead голове головы по
_E80BB4971AE738B5 FBody туловище туловища в
_C40D15A82A36DF2C FFrontFins1 переднему плавнику передние плавники по
_C41D15A82A36DF2C FFrontFins2 переднему плавнику передние плавники по
_67B624EBAAF630A4 FRearFins1 заднему плавнику задние плавники по
_67B628EBAAF630A4 FRearFins2 заднему плавнику задние плавники по
_ACB9BC6C1B465099 BHead голове головы по
_E80BB4931AA738B5 BBody туловище туловища в
_25897F8F25594780 BFeet1 ноге ноги по
_2589838F25594B80 BFeet2 ноге ноги по
_2C68746BA436D3C2 BWings1 крылу крылья по
_2C68746BA446D7C2 BWings2 крылу крылья по
_8061E6E18C3EA521 PUpperTrunk верху стебля верхние стебли по
_ECEA3087A666CCC3 Ptrunk стеблю стебли по
_E7469C4D9B5A0C9D PLeaves1 листу листья по
_E7469C4DDB5A0C9D PLeaves2 листу листья по
_C3EE9906771FB524 PLowerTrunk низу стебля нижние стебли по
_DFA67A5CC7DECDE6 PVisibleRoots корень корни в

@ -0,0 +1,43 @@
*HASH_VALUE bodypartID name ia da p pia pda description
_ACB9BC721BA65099 HHead head an the heads the
_278A7C5D654814CD HChest chest a the chests the
_A2D940906B29B889 HArms arms the arms the
_B1CAFC85DB767C9C HHands hands the hands the
_20A8389BAC987C9F HLegs legs the legs the
_E18820962C586494 HFeet feet the feet the
_ACB9BC7B1B375099 QHead head an the heads the
_E80BB4A21A9838B5 QBody body a the bodies the
_C96F0919D2F8DC71 QFrontPaws front legs the front legs the
_08A1A8FEABC3CD11 QFrontHooves front legs the front legs the
_23B95F02A87957B0 QRearPaws rear legs the rear legs the
_D880990C5BE9DCB7 QRearHooves rear legs the rear legs the
_2836645DDE8874AD LKHead head an the heads the
_ED86C05FE298A4B9 LKBody body a the bodies the
_39BFC0EBE486B512 LKFrontPaws1 front legs the front legs the
_79BFC0EBE486B512 LKFrontPaws2 front legs the front legs the
_D92BB508D8F884A6 LKRearPaws1 rear legs the rear legs the
_D93BB508D8F884A6 LKRearPaws2 rear legs the rear legs the
_283664575C8874AD FKHead head an the heads the
_ED86C0596098A4B9 FKBody body a the bodies the
_DBBA7473640310B0 FKPaws1 legs the legs the
_1BBA7473641310B0 FKPaws2 legs the legs the
_66B6A47A4A7ADCC2 FKWings1 wings the wings the
_66B6A47ACA7ADCC2 FKWings2 wings the wings the
_ACB9BC701B865099 FHead head an the heads the
_E80BB4971AE738B5 FBody body a the bodies the
_C40D15A82A36DF2C FFrontFins1 front fins the front fins the
_C41D15A82A36DF2C FFrontFins2 front fins the front fins the
_67B624EBAAF630A4 FRearFins1 rear fins the rear fins the
_67B628EBAAF630A4 FRearFins2 rear fins the rear fins the
_ACB9BC6C1B465099 BHead head an the heads the
_E80BB4931AA738B5 BBody body a the bodies the
_25897F8F25594780 BFeet1 feet the feet the
_2589838F25594B80 BFeet2 feet the feet the
_2C68746BA436D3C2 BWings1 wings the wings the
_2C68746BA446D7C2 BWings2 wings the wings the
_CCD189BCC86AD11B PUpperTrunk Upper Trunk an the Upper Trunks the
_F1EA0CAEA90BB4B5 Ptrunk Trunk a the Trunks the
_60C70C89DC1C7CB6 PLeaves1 Leaf a the Leaves the
_60C70C891C1C7CB6 PLeaves2 Leaf a the Leaves the
_0CAF41BCC86AED1A PLowerTrunk Lower Trunk a the Lower Trunks the
_DFA6C25CC7DECDE6 PVisibleRoots Visible Root a the Visible Roots the

@ -0,0 +1,9 @@
*HASH_VALUE career ID name named * noms français ia da p pd pia pda
_1700C956C37FB64F MeleeFighter Nahkämpfer Nahkämpfer Combattant Contact ein der Nahkämpfer die die
_9720B95DC35FBA54 RangeFighter Fernkämpfer Fernkämpfer Combattant Distance ein der Fernkämpfer die die
_D32171700AD23D57 AttackCaster Kampfmagier Kampfmagier Caster Attaque ein der Kampfmagier die die
_9A511D668371AE04 BufferCaster Schutzmagier Schutzmagier Caster Buffer ein der Schutzmagier die die
_1C01F56701816E0A HealerCaster Heiler Heiler Caster Healer ein der Heiler die die
_A6473C7A6A380099 Ranger Ranger Ranger Ranger ein der Ranger die die
_EA665D00EAE788B3 Shopkeeper Händler Händler Marchand ein der Händler die die
_2D28B08D636AEC9E Artisan Handwerker Handwerker Crafter ein der Handwerker die die

@ -0,0 +1,9 @@
*HASH_VALUE career ID name * noms français ia da p pia pda
_1700C956C37FB64F MeleeFighter Melee Fighter Combattant Contact a the Melee Fighters the
_9720B95DC35FBA54 RangeFighter Range Fighter Combattant Distance a the Range Fighters the
_D32171700AD23D57 AttackCaster Attack Caster Caster Attaque an the Attack Casters the
_9A511D668371AE04 BufferCaster Buffer Caster Caster Buffer a the Buffer Casters the
_1C01F56701816E0A HealerCaster Healer Caster Caster Healer a the Healer Casters the
_A6473C7A6A380099 Ranger Ranger Ranger a the Rangers the
_EA665D00EAE788B3 Shopkeeper Merchant Marchand a the Merchants the
_2D28B08D636AEC9E Artisan Crafter Crafter a the Crafters the

@ -0,0 +1,9 @@
*HASH_VALUE career ID name * noms français ia da p pia pda
_1700C956C37FB64F MeleeFighter Luchador Cuerpo a Cuerpo Combattant Contact un el Luchadores Cuerpo a Cuerpo unos los
_9720B95DC35FBA54 RangeFighter Luchador a Distancia Combattant Distance un el Luchadores a Distancia unos los
_D32171700AD23D57 AttackCaster Lanzador de Ataque Caster Attaque un el Lanzadores de Ataque unos los
_9A511D668371AE04 BufferCaster Lanzador de Defensa Caster Buffer un el Lanzadores de Defensa unos los
_1C01F56701816E0A HealerCaster Sanador Caster Healer un el Sanadores unos los
_A6473C7A6A380099 Ranger Ranger un el Rangers unos los
_EA665D00EAE788B3 Shopkeeper Tendero un el Tenderos unos los
_2D28B08D636AEC9E Artisan Artesano un el Artesanos unos los

@ -0,0 +1,9 @@
*HASH_VALUE career ID name * noms français ia da p pia pda
_1700C956C37FB64F MeleeFighter Combattant de mêlée Combattant Contact un le Combattants de mêlée des les
_9720B95DC35FBA54 RangeFighter Combattant à distance Combattant Distance un le Combattants à distance des les
_D32171700AD23D57 AttackCaster Mage offensif Mage Attaque un le Mages offensifs des les
_9A511D668371AE04 BufferCaster Mage protecteur Mage Protection un le Mages protecteurs des les
_1C01F56701816E0A HealerCaster Guérisseur Guérisseur un le Guérisseurs des les
_A6473C7A6A380099 Ranger Récolteur Ranger un le Récolteurs des les
_EA665D00EAE788B3 Shopkeeper Marchand Marchand un le Marchands des les
_2D28B08D636AEC9E Artisan Artisan Artisan un l'\d Artisans des les

@ -0,0 +1,9 @@
*HASH_VALUE career ID name * noms français p
_1700C956C37FB64F MeleeFighter Боец ближнего боя Combattant Contact Бойцы ближнего боя
_9720B95DC35FBA54 RangeFighter Боец дальнего боя Combattant Distance Бойцы дальнего боя
_D32171700AD23D57 AttackCaster Боевой маг Caster Attaque Боевые маги
_9A511D668371AE04 BufferCaster Маг поддержки Caster Buffer Маги поддержки
_1C01F56701816E0A HealerCaster Целитель Caster Healer Целители
_A6473C7A6A380099 Ranger Охотник Ranger Охотники
_EA665D00EAE788B3 Shopkeeper Торговец Marchand Торговцы
_2D28B08D636AEC9E Artisan Ремесленник Crafter Ремесленники

@ -0,0 +1,9 @@
*HASH_VALUE career ID name * noms français ia da p pia pda
_1700C956C37FB64F MeleeFighter Melee Fighter Combattant Contact a the Melee Fighters the
_9720B95DC35FBA54 RangeFighter Range Fighter Combattant Distance a the Range Fighters the
_D32171700AD23D57 AttackCaster Attack Caster Caster Attaque an the Attack Casters the
_9A511D668371AE04 BufferCaster Buffer Caster Caster Buffer a the Buffer Casters the
_1C01F56701816E0A HealerCaster Healer Caster Caster Healer a the Healer Casters the
_A6473C7A6A380099 Ranger Ranger Ranger a the Rangers the
_EA665D00EAE788B3 Shopkeeper Merchant Marchand a the Merchants the
_EC38FC89E25AE8AD Artisan Crafter Crafter a the Crafters the

@ -0,0 +1,9 @@
*HASH_VALUE characteristic_ID name named
_B009C46E316AACBF Constitution Konstitution Konstitution
_661AAC8EE6098C96 Metabolism Metabolismus Metabolismus
_E45ADC6364A9D4A6 Intelligence Intelligenz Intelligenz
_E7DB9090281BA0A8 Wisdom Weisheit Weisheit
_649C448C681C74B8 Strength Stärke Stärke
_6A880849E7D8DC86 WellBalanced Gleichgewicht Gleichgewicht
_ADB8DC9A6C5A10B6 Dexterity Geschicklichkeit Geschicklichkeit
_6C18945C6C1894DC Will Wille Wille

@ -0,0 +1,9 @@
*HASH_VALUE characteristic_ID name
_B009C46E316AACBF Constitution constitution
_661AAC8EE6098C96 Metabolism metabolism
_E45ADC6364A9D4A6 Intelligence intelligence
_E7DB9090281BA0A8 Wisdom wisdom
_649C448C681C74B8 Strength strength
_6A880849E7D8DC86 WellBalanced balance
_ADB8DC9A6C5A10B6 Dexterity dexterity
_6C18945C6C1894DC Will will

@ -0,0 +1,9 @@
*HASH_VALUE characteristic_ID name
_B009C46E316AACBF Constitution Constitución
_661AAC8EE6098C96 Metabolism Metabolismo
_E45ADC6364A9D4A6 Intelligence Inteligencia
_E7DB9090281BA0A8 Wisdom Sabiduría
_649C448C681C74B8 Strength Fuerza
_6A880849E7D8DC86 WellBalanced Equilibrio
_ADB8DC9A6C5A10B6 Dexterity Destreza
_6C18945C6C1894DC Will Voluntad

@ -0,0 +1,9 @@
*HASH_VALUE characteristic_ID name
_B009C46E316AACBF Constitution Constitution
_661AAC8EE6098C96 Metabolism Métabolisme
_E45ADC6364A9D4A6 Intelligence Intelligence
_E7DB9090281BA0A8 Wisdom Sagesse
_649C448C681C74B8 Strength Force
_6A880849E7D8DC86 WellBalanced Équilibre
_ADB8DC9A6C5A10B6 Dexterity Dextérité
_6C18945C6C1894DC Will Volonté

@ -0,0 +1,9 @@
*HASH_VALUE characteristic_ID name
_B009C46E316AACBF Constitution телосложение
_661AAC8EE6098C96 Metabolism метаболизм
_E45ADC6364A9D4A6 Intelligence интеллект
_E7DB9090281BA0A8 Wisdom мудрость
_649C448C681C74B8 Strength сила
_6A880849E7D8DC86 WellBalanced сбалансированность
_ADB8DC9A6C5A10B6 Dexterity ловкость
_6C18945C6C1894DC Will воля

@ -0,0 +1,9 @@
*HASH_VALUE characteristic_ID name
_B009C46E316AACBF Constitution constitution
_661AAC8EE6098C96 Metabolism metabolism
_E45ADC6364A9D4A6 Intelligence intelligence
_E7DB9090281BA0A8 Wisdom wisdom
_649C448C681C74B8 Strength strength
_6A880849E7D8DC86 WellBalanced well balanced
_ADB8DC9A6C5A10B6 Dexterity dexterity
_6C18945C6C1894DC Will will

@ -0,0 +1,21 @@
*HASH_VALUE classification_type name ia da p pia pda description
_3A05A61DFA348A48 TypeHumanoid Humanoider ein der Humanoide die Humanoiden
_45506C09EB15E8F6 TypeHomin Homin ein der Homins die Homins
_8E983B69E6751B5B TypeDegenerated Degenerierter ein der Degenerierte die Degenerierten
_A9DA837C2389848E TypeFauna Tier ein das Tiere die Tiere
_EB29AF7C2428C08C TypeFlora Pflanze eine die Pflanzen die Pflanzen
_418079E7A7FCBDE4 TypeDog Hund ein der Hunde die Hunde
_2ADE76E9CAEF61FD TypeRunner Läufer ein der Läufer die Läufer
_E66DB1300A4F65FE TypeHorse Pferd ein das Pferde die Pferde
_41C17C16195279E3 TypeBird Vogel ein der Vögel die Vögel
_86208D03AB86D000 TypeKitin Kitin ein der Kitins die Kitins
_6BA9A101DCF285C2 TypeLandKitin Kitin ein der Kitins die Kitins
_084D91AFD5E36708 TypeFlyingKitin Flugkitin ein der Flugkitins die Flugkitins
_473159828751A1F6 TypeFish Fisch ein der Fische die Fische
_2117AAF84DF7627F TypeRyzomian Ryzomier ein der Ryzomier die Ryzomier
_367CB4F6AA3221AE TypeGreatRyzomian großer Ryzomier ein der große Ryzomier die großen Ryzomier
_FABC37E2BA5ACB87 TypePachyderm Dickhäuter ein der Dickhäuter die Dickhäuter
_20C7038A1FE556FD TypeShellfish Krebstier ein das Krebstiere die Krebstiere
_15EA8409E9C8749E TypeKami Kami ein der Kami die Kami
_84632E6705B131E4 TypeKaravan Karavan ein der Karavan die Karavan
_66BC409E659A149E TypeAll Alle Alle Alle

@ -0,0 +1,21 @@
*HASH_VALUE classification_type name ia da p pia pda description
_3A05A61DFA348A48 TypeHumanoid humanoid a the humanoids the humanoids
_45506C09EB15E8F6 TypeHomin homin a the homins the homins
_8E983B69E6751B5B TypeDegenerated degenerate homin a the degenerate homins the degenerate homins
_A9DA837C2389848E TypeFauna fauna a the faunas the faunas
_EB29AF7C2428C08C TypeFlora flora a the floras the floras
_418079E7A7FCBDE4 TypeDog canine a the canines the canines
_2ADE76E9CAEF61FD TypeRunner runner a the runners the runners
_E66DB1300A4F65FE TypeHorse equine an the equines the equines
_41C17C16195279E3 TypeBird bird a the birds the birds
_86208D03AB86D000 TypeKitin Kitin a the Kitins the Kitins
_6BA9A101DCF285C2 TypeLandKitin Kitin a the Kitins the Kitins
_084D91AFD5E36708 TypeFlyingKitin flying Kitin a the flying Kitins the flying Kitins
_473159828751A1F6 TypeFish fish a the fish the fish
_2117AAF84DF7627F TypeRyzomian ryzomian a the ryzomians the ryzomians
_367CB4F6AA3221AE TypeGreatRyzomian large ryzomian a the large ryzomians the large ryzomians
_FABC37E2BA5ACB87 TypePachyderm pachyderm a the pachyderms the pachyderms
_20C7038A1FE556FD TypeShellfish crustacian a the crustacians the crustacians
_15EA8409E9C8749E TypeKami Kami a the Kamis the Kamis
_84632E6705B131E4 TypeKaravan Karavan a the Karavans the Karavans
_66BC409E659A149E TypeAll all all all

@ -0,0 +1,21 @@
*HASH_VALUE classification_type name ia da p pia pda description
_3A05A61DFA348A48 TypeHumanoid humanoide un el humanoides unos los humanoides
_45506C09EB15E8F6 TypeHomin homin un el homins unos los homins
_8E983B69E6751B5B TypeDegenerated homin degenerado un el homins degenerados unos los homins degenerados
_A9DA837C2389848E TypeFauna fauna la faunas las faunas
_EB29AF7C2428C08C TypeFlora flora la floras las floras
_418079E7A7FCBDE4 TypeDog cánido un el cánidos unos los cánidos
_2ADE76E9CAEF61FD TypeRunner corredor un el corredores unos los corredores
_E66DB1300A4F65FE TypeHorse équido un el équidos unos los équidos
_41C17C16195279E3 TypeBird ave un el aves unas los aves
_86208D03AB86D000 TypeKitin Kitin un el Kitins unos los Kitins
_6BA9A101DCF285C2 TypeLandKitin Kitin un el Kitins unos los Kitins
_084D91AFD5E36708 TypeFlyingKitin Kitin volador un los Kitins voladores unos los Kitins voladores
_473159828751A1F6 TypeFish pez un el peces unos los peces
_2117AAF84DF7627F TypeRyzomian ryzomiano un el ryzomianos unos los ryzomianos
_367CB4F6AA3221AE TypeGreatRyzomian gran ryzomiano un el grandes ryzomianos unos los ryzomianos
_FABC37E2BA5ACB87 TypePachyderm paquidermo un el paquidermos unos un paquidermos
_20C7038A1FE556FD TypeShellfish crustáceo un el crustáceos unos los crustáceos
_15EA8409E9C8749E TypeKami Kami un el Kamis unos los Kamis
_84632E6705B131E4 TypeKaravan Karavan un el Karavan unos los Karavan
_66BC409E659A149E TypeAll todo un el todos unos los todos

@ -0,0 +1,21 @@
*HASH_VALUE classification_type name ia da p pia pda description
_3A05A61DFA348A48 TypeHumanoid humanoïde un l'\d humanoïdes des les les humanoïdes
_45506C09EB15E8F6 TypeHomin homin un l'\d homins des les les homins
_8E983B69E6751B5B TypeDegenerated homin dégénéré un l'\d homins dégénérés des les les homins dégénérés
_A9DA837C2389848E TypeFauna faune la faune la la faune
_EB29AF7C2428C08C TypeFlora flore la flore la la flore
_418079E7A7FCBDE4 TypeDog canidé un le canidés des les les canidés
_2ADE76E9CAEF61FD TypeRunner capriné un le caprinés des les les caprinés
_E66DB1300A4F65FE TypeHorse équidé un l'\d équidés des les les équidés
_41C17C16195279E3 TypeBird oiseau un l'\d oiseaux des les les oiseaux
_86208D03AB86D000 TypeKitin kitin un le kitins des les les kitins
_6BA9A101DCF285C2 TypeLandKitin kitin terrestre un le kitins terrestres des les les kitins terrestres
_084D91AFD5E36708 TypeFlyingKitin kitin volant un le kitins volants des les les kitins volants
_473159828751A1F6 TypeFish poisson un le poissons des les les poissons
_2117AAF84DF7627F TypeRyzomian ryzomien un le ryzomiens des les les ryzomiens
_367CB4F6AA3221AE TypeGreatRyzomian grand ryzomien un le grands ryzomiens des les les grands ryzomiens
_FABC37E2BA5ACB87 TypePachyderm pachyderme un le pachydermes des les les pachydermes
_20C7038A1FE556FD TypeShellfish crustacé un le crustacés des les les crustacés
_15EA8409E9C8749E TypeKami kami un le kamis des les les kamis
_84632E6705B131E4 TypeKaravan karavan une la karavan des les les karavans
_66BC409E659A149E TypeAll tous tous tous

@ -0,0 +1,21 @@
*HASH_VALUE classification_type name p description
_3A05A61DFA348A48 TypeHumanoid человекообразный человекообразные человекообразные
_45506C09EB15E8F6 TypeHomin хомин хомины хомины
_8E983B69E6751B5B TypeDegenerated вырождающийся хомин вырождающиеся хомины вырождающиеся хомины
_A9DA837C2389848E TypeFauna фауна фауна фауна
_EB29AF7C2428C08C TypeFlora флора флора флора
_418079E7A7FCBDE4 TypeDog псовое псовые псовые
_2ADE76E9CAEF61FD TypeRunner серна серны серны
_E66DB1300A4F65FE TypeHorse копытное копытные копытные
_41C17C16195279E3 TypeBird птица птицы птицы
_86208D03AB86D000 TypeKitin кхитин кхитины кxитины
_6BA9A101DCF285C2 TypeLandKitin кхитин кхитины кхитины
_084D91AFD5E36708 TypeFlyingKitin летучий кхитин летучие кхитины летучие кxитины
_473159828751A1F6 TypeFish рыба рыбы рыбы
_2117AAF84DF7627F TypeRyzomian ризомиан ризомиане ризомиане
_367CB4F6AA3221AE TypeGreatRyzomian большой ризомиан большие ризомиане большие ризомиане
_FABC37E2BA5ACB87 TypePachyderm толстокожее толстокожие толстокожие
_20C7038A1FE556FD TypeShellfish ракообразное ракообразные ракообразные
_15EA8409E9C8749E TypeKami ками ками ками
_84632E6705B131E4 TypeKaravan караван караван караван
_66BC409E659A149E TypeAll все все все

@ -0,0 +1,21 @@
*HASH_VALUE classification_type name ia da p pia pda description
_3A05A61DFA348A48 TypeHumanoid humanoïde un l' humanoïdes les les humanoïdes
_45506C09EB15E8F6 TypeHomin homin un l' homins les les homins
_8E983B69E6751B5B TypeDegenerated homin dégénéré un l' homins dégénérés les les homins dégénérés
_A9DA837C2389848E TypeFauna faune la faune la la faune
_EB29AF7C2428C08C TypeFlora flore la flore la la flore
_418079E7A7FCBDE4 TypeDog canidé un le canidés les les canidés
_2ADE76E9CAEF61FD TypeRunner capriné un le caprinés les les caprinés
_E66DB1300A4F65FE TypeHorse équidé un l' équidés les les équidés
_41C17C16195279E3 TypeBird oiseau un l' oiseaux les les oiseaux
_86208D03AB86D000 TypeKitin kitin un le kitins les les kitins
_6BA9A101DCF285C2 TypeLandKitin kitin terrestre un le kitins terrestres les les kitins terrestres
_084D91AFD5E36708 TypeFlyingKitin kitin volant un le kitins volants les les kitins volants
_473159828751A1F6 TypeFish poisson un le poissons les les poissons
_2117AAF84DF7627F TypeRyzomian ryzomien un le ryzomiens les les ryzomiens
_367CB4F6AA3221AE TypeGreatRyzomian grand ryzomien un le grands ryzomiens les les grands ryzomiens
_FABC37E2BA5ACB87 TypePachyderm pachyderme un le pachydermes les les pachydermes
_20C7038A1FE556FD TypeShellfish crustacé un le crustacés les les crustacés
_15EA8409E9C8749E TypeKami kami un le kamis les les kamis
_84632E6705B131E4 TypeKaravan karavan un karavans les les karavans
_66BC409E659A149E TypeAll tous tous tous

@ -0,0 +1 @@
*HASH_VALUE damageTypeId name named ia da p pd pia pda description

@ -0,0 +1 @@
*HASH_VALUE damageTypeId name ia da p pia pda description

@ -0,0 +1,11 @@
*HASH_VALUE damageTypeId name ia da p pia pda description
_EC0860AC264890AB Slashing Tranchant Tranchants
_2D9830A326487C9B Piercing Perforant Perforants
_6CFA0460721A84D2 Blunt Contondant Contondants
_2EDA18A76F8924A9 Rot Pourriture Pourritures
_64766C6AA518A8A1 Acid Acide Acides
_28B6D46E2AE8E8A6 Cold Froid Froid
_A848B076EBB9ECB0 Fire Feu Feux
_E5B90496AEBAD8C1 Poison Poison Poisons
_6659CC92EA58A491 Electricity Electricité Electricité
_E45A9C6C6E78B4B4 Shock Choc Chocs

@ -0,0 +1 @@
*HASH_VALUE damageTypeId name ia da p pia pda description

@ -0,0 +1,11 @@
*HASH_VALUE damageTypeId name ia da p pia pda description
_EC08606C264890AB Slashing Schneide ein der Schneide die
_2D98306326487C9B Piercing Durchbohrungs ein der Durchbohrungs die
_6CF60460721A84D2 Blunt Zertrümmerungs ein der Zertrümmerungs die
_26D818876787A4A9 Rot Verrottungs ein der Verrottungs die
_6476EC4AA5162881 Acid Säure ein der Säure die
_28B6544E2AE66886 Cold Kälte ein der Kälte die
_A8483056EBB76C90 Fire Feuer ein der Feuer die
_E5B98496A6B8D8A1 Poison Gift ein der Gift die
_5659CC92EA58A491 Electricity Elektrizitäts ein der Elektrizitäts die
_E4569C6C6E78B4B4 Shock Schockwellen ein der Schockwellen die

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save