diff --git a/.hgtags b/.hgtags index 38ed6cd84..5f0958f4c 100644 --- a/.hgtags +++ b/.hgtags @@ -1,27 +1,28 @@ -4eddbaff0c5e5d685db96ee3e8427aa0fd96ac83 v0.8.0 -00d9b6e29e95f56785fbf85abe60afd34674f402 v0.9.0 -79776c337176dd5b02e1a74fe5dfb703b91747aa v0.9.1 -fedf2aa443d09707beed814b0f499c6a5519cc84 v0.10.0 -edaa3624a56420b02ccc64c26059801a389927ee v0.11.0 -e3fe4855f22c3e75722e015dc33c091c340b3ad7 v0.11.1 -9e583b717fd63be0be9fd60b99087abf1691ea49 v0.11.2 -bfe5628e14a024ba7ea32e4b326ae433a07856b9 v0.11.3 -9a6120735daa97c96ac5d85ca35c7f21f607bd87 v0.12.0 -3e92c7104c20d6bc6c2147b4b5fc289e8621d322 v1.0.0 -8eb94c3549be898fdc4a7c6d791d2477bdc11a18 v1.0.1 -3e17907af67e8d66d80e6b714707bbf912607f2a ryzom/3.0.0 -153e0b605c9e0c83ba05b6428c62838b49cc84b2 ryzom/3.0.1 -9d41f2994d44b9aad92b83f945f114e4b6bed44a ryzom/3.0.2 -4300cc14aad098b1f86ea4c55577b7fa4a4cb5d2 ryzom/3.1.0 -d4060f217f4f834cc62a33f2f1ccdf3c28298066 ryzom/3.1.0-hotfix -043aaeb3d8a2a54177581b57bda87a9deaad510e ryzom/3.1.0-april_patch -4036ecf59e83960f03acebc2089eb2ff5eeaed0a ryzom/3.2.0 -18403bb9485da3d9742c6f007a16d5619ebfb196 ryzom/3.2.1 -822ff8f8917ad66e09e2c21c983282f6f693b9f6 ryzom/3.3.0 -00dde390a394fce9da06c2f3264140282158d39f ryzom/3.3.0 -dcd4c4d161ef775136e18c7e8f5072b75dede27e ryzom/3.3.1 -fc4be8ebec5ca754ef4453bc6a9faef90837c674 ryzom/3.4.0 -70eba02e8eab6920586dbabf74e9e8180c729980 ryzom/3.4.0-steam_fix -3941482843f9cd130cfc16634efc08d34a98ed35 ryzom/3.4.0-atysmas -ecae9feb4cceb78103e5d7236caccaf450796cdb ryzom/3.5.0 -95783afa226f241062134eb62f4323295d29ac84 ryzom/3.5.0.9637 +4eddbaff0c5e5d685db96ee3e8427aa0fd96ac83 ryzomcore/v0.8.0 +00d9b6e29e95f56785fbf85abe60afd34674f402 ryzomcore/v0.9.0 +79776c337176dd5b02e1a74fe5dfb703b91747aa ryzomcore/v0.9.1 +fedf2aa443d09707beed814b0f499c6a5519cc84 ryzomcore/v0.10.0 +edaa3624a56420b02ccc64c26059801a389927ee ryzomcore/v0.11.0 +e3fe4855f22c3e75722e015dc33c091c340b3ad7 ryzomcore/v0.11.1 +9e583b717fd63be0be9fd60b99087abf1691ea49 ryzomcore/v0.11.2 +bfe5628e14a024ba7ea32e4b326ae433a07856b9 ryzomcore/v0.11.3 +9a6120735daa97c96ac5d85ca35c7f21f607bd87 ryzomcore/v0.12.0 +3e17907af67e8d66d80e6b714707bbf912607f2a ryzom-patch-3.0.0 +153e0b605c9e0c83ba05b6428c62838b49cc84b2 ryzom-patch-3.0.1 +9d41f2994d44b9aad92b83f945f114e4b6bed44a ryzom-patch-3.0.2 +4300cc14aad098b1f86ea4c55577b7fa4a4cb5d2 ryzom-patch-3.1.0 +d4060f217f4f834cc62a33f2f1ccdf3c28298066 ryzom-patch-3.1.0-hotfix +043aaeb3d8a2a54177581b57bda87a9deaad510e ryzom-patch-3.1.0-april_patch +4036ecf59e83960f03acebc2089eb2ff5eeaed0a ryzom-patch-3.2.0 +18403bb9485da3d9742c6f007a16d5619ebfb196 ryzom-patch-3.2.1 +822ff8f8917ad66e09e2c21c983282f6f693b9f6 ryzom-patch-3.3.0 +00dde390a394fce9da06c2f3264140282158d39f ryzom-patch-3.3.0 +dcd4c4d161ef775136e18c7e8f5072b75dede27e ryzom-patch-3.3.1 +fc4be8ebec5ca754ef4453bc6a9faef90837c674 ryzom-patch-3.4.0 +70eba02e8eab6920586dbabf74e9e8180c729980 ryzom-patch-3.4.0 Steam Fix +3941482843f9cd130cfc16634efc08d34a98ed35 ryzom-patch-3.4.0 Atysmas +ecae9feb4cceb78103e5d7236caccaf450796cdb ryzom-patch-3.5.0 +95783afa226f241062134eb62f4323295d29ac84 ryzom-patch-3.5.0.9637 +2102fb276eb69d49ed4923042215312a63c47c08 Live-746 +8eb94c3549be898fdc4a7c6d791d2477bdc11a18 ryzomcore/v1.0.1 +3e92c7104c20d6bc6c2147b4b5fc289e8621d322 ryzomcore/v1.0.0 diff --git a/code/nel/include/nel/gui/ctrl_scroll.h b/code/nel/include/nel/gui/ctrl_scroll.h index 76827dd29..4052e6cea 100644 --- a/code/nel/include/nel/gui/ctrl_scroll.h +++ b/code/nel/include/nel/gui/ctrl_scroll.h @@ -177,6 +177,7 @@ namespace NLGUI bool _MouseDown : 1; bool _CallingAH : 1; bool _Cancelable : 1; // true if the slider may be cancelled when pressed on the mouse right button + bool _Keyboard : 1; bool _Frozen : 1; bool _Scale : 1; diff --git a/code/nel/include/nel/gui/ctrl_text_button.h b/code/nel/include/nel/gui/ctrl_text_button.h index 25fc9eeac..9bae24ad5 100644 --- a/code/nel/include/nel/gui/ctrl_text_button.h +++ b/code/nel/include/nel/gui/ctrl_text_button.h @@ -127,6 +127,16 @@ namespace NLGUI void setTexturePushed(const std::string &l, const std::string &m, const std::string &r); void setTextureOver(const std::string &l, const std::string &m, const std::string &r); + // lua + void setTextureLua (const std::string &name); + void setTexturePushedLua (const std::string &name); + void setTextureOverLua (const std::string &name); + + // return texture _l.tga + std::string getTexture () const; + std::string getTexturePushed () const; + std::string getTextureOver() const; + int luaGetViewText(CLuaState &ls); REFLECT_EXPORT_START(CCtrlTextButton, CCtrlBaseButton) @@ -137,6 +147,9 @@ namespace NLGUI REFLECT_SINT32("wmin", getWMin, setWMin) REFLECT_SINT32("hmin", getHMin, setHMin) REFLECT_LUA_METHOD("getViewText", luaGetViewText) + REFLECT_STRING("texture", getTexture, setTextureLua); + REFLECT_STRING("texture_pushed", getTexturePushed, setTexturePushedLua); + REFLECT_STRING("texture_over", getTextureOver, setTextureOverLua); REFLECT_EXPORT_END void onRemoved(); diff --git a/code/nel/include/nel/sound/driver/sound_driver.h b/code/nel/include/nel/sound/driver/sound_driver.h index 1fba9c887..9c758487a 100644 --- a/code/nel/include/nel/sound/driver/sound_driver.h +++ b/code/nel/include/nel/sound/driver/sound_driver.h @@ -191,7 +191,7 @@ public: /// Create a native music channel, only supported by the FMod driver. virtual IMusicChannel *createMusicChannel() { return NULL; } /** Get music info. Returns false if the song is not found or the function is not implemented. - * \param filepath path to file, CPath::lookup done by driver + * \param filepath full path to file * \param artist returns the song artist (empty if not available) * \param title returns the title (empty if not available) */ diff --git a/code/nel/src/gui/ctrl_scroll.cpp b/code/nel/src/gui/ctrl_scroll.cpp index 14caa75f4..6b2a5d066 100644 --- a/code/nel/src/gui/ctrl_scroll.cpp +++ b/code/nel/src/gui/ctrl_scroll.cpp @@ -57,6 +57,7 @@ namespace NLGUI _MouseDown = false; _CallingAH = false; _Cancelable = false; + _Keyboard = false; _Target = NULL; _Inverted = false; _IsDBLink = false; @@ -225,6 +226,11 @@ namespace NLGUI return toString( _Cancelable ); } else + if( name == "keyboard" ) + { + return toString( _Keyboard ); + } + else if( name == "frozen" ) { return toString( _Frozen ); @@ -405,6 +411,14 @@ namespace NLGUI return; } else + if( name == "keyboard" ) + { + bool b; + if( fromString( value, b ) ) + _Keyboard = b; + return; + } + else if( name == "frozen" ) { bool b; @@ -474,6 +488,7 @@ namespace NLGUI xmlSetProp( node, BAD_CAST "target_stepy", BAD_CAST toString( _TargetStepY ).c_str() ); xmlSetProp( node, BAD_CAST "step_value", BAD_CAST toString( _StepValue ).c_str() ); xmlSetProp( node, BAD_CAST "cancelable", BAD_CAST toString( _Cancelable ).c_str() ); + xmlSetProp( node, BAD_CAST "keyboard", BAD_CAST toString( _Keyboard ).c_str() ); xmlSetProp( node, BAD_CAST "frozen", BAD_CAST toString( _Frozen ).c_str() ); return node; @@ -589,6 +604,9 @@ namespace NLGUI prop = (char*) xmlGetProp( node, (xmlChar*)"cancelable" ); if (prop) _Cancelable = convertBool(prop); + prop = (char*) xmlGetProp( node, (xmlChar*)"keyboard" ); + if (prop) _Keyboard = convertBool(prop); + prop= (char*) xmlGetProp (node, (xmlChar*)"frozen"); _Frozen = false; if (prop) @@ -854,6 +872,7 @@ namespace NLGUI if (CCtrlBase::handleEvent(event)) return true; if (!_Active || _Frozen) return false; + if (event.getType() == NLGUI::CEventDescriptor::mouse) { const NLGUI::CEventDescriptorMouse &eventDesc = (const NLGUI::CEventDescriptorMouse &)event; @@ -912,6 +931,30 @@ namespace NLGUI return true; } } + else if (event.getType() == NLGUI::CEventDescriptor::key) + { + const NLGUI::CEventDescriptorKey &eventDesc = (const NLGUI::CEventDescriptorKey &)event; + + if (eventDesc.getKeyEventType() == NLGUI::CEventDescriptorKey::keydown) + { + if (_Keyboard) + { + sint32 i = 0; + // direction + if (eventDesc.getKey() == KeyNEXT) i++; + else if (eventDesc.getKey() == KeyPRIOR) i--; + else + return false; + + if (_Vertical) + moveTrackY(-(i * _TargetStepY)); + else + moveTrackX(-(i * _TargetStepX)); + + return true; + } + } + } return false; } @@ -1213,6 +1256,7 @@ namespace NLGUI if(wReal <= maxWReal) return; + // compute the new ofsX. sint32 ofsX= _Target->getOfsX(); ofsX+= dx; diff --git a/code/nel/src/gui/ctrl_text_button.cpp b/code/nel/src/gui/ctrl_text_button.cpp index de01174ed..d7902c166 100644 --- a/code/nel/src/gui/ctrl_text_button.cpp +++ b/code/nel/src/gui/ctrl_text_button.cpp @@ -1077,6 +1077,69 @@ namespace NLGUI // *************************************************************************** + void CCtrlTextButton::setTextureLua(const std::string &name) + { + _TextureIdNormal[0].setTexture(std::string(name + "_l.tga").c_str()); + _TextureIdNormal[1].setTexture(std::string(name + "_m.tga").c_str()); + _TextureIdNormal[2].setTexture(std::string(name + "_r.tga").c_str()); + } + + // *************************************************************************** + + void CCtrlTextButton::setTexturePushedLua(const std::string &name) + { + _TextureIdPushed[0].setTexture(std::string(name + "_l.tga").c_str()); + _TextureIdPushed[1].setTexture(std::string(name + "_m.tga").c_str()); + _TextureIdPushed[2].setTexture(std::string(name + "_r.tga").c_str()); + } + + // *************************************************************************** + + void CCtrlTextButton::setTextureOverLua(const std::string &name) + { + _TextureIdOver[0].setTexture(std::string(name + "_l.tga").c_str()); + _TextureIdOver[1].setTexture(std::string(name + "_m.tga").c_str()); + _TextureIdOver[2].setTexture(std::string(name + "_r.tga").c_str()); + } + + // *************************************************************************** + + std::string CCtrlTextButton::getTexture() const + { + std::string tx = CViewRenderer::getInstance()->getTextureNameFromId(_TextureIdNormal[0]); + std::string::size_type i = tx.rfind("_l.tga"); + if (i != std::string::npos) + tx = tx.substr(0, i); + + return tx; + } + + // *************************************************************************** + + std::string CCtrlTextButton::getTexturePushed() const + { + std::string tx = CViewRenderer::getInstance()->getTextureNameFromId(_TextureIdOver[0]); + std::string::size_type i = tx.rfind("_l.tga"); + if (i != std::string::npos) + tx = tx.substr(0, i); + + return tx; + } + + // *************************************************************************** + + std::string CCtrlTextButton::getTextureOver() const + { + std::string tx = CViewRenderer::getInstance()->getTextureNameFromId(_TextureIdPushed[0]); + std::string::size_type i = tx.rfind("_l.tga"); + if (i != std::string::npos) + tx = tx.substr(0, i); + + return tx; + } + + // *************************************************************************** + int CCtrlTextButton::luaGetViewText(CLuaState &ls) { const char *funcName = "getViewText"; diff --git a/code/nel/src/misc/bitmap.cpp b/code/nel/src/misc/bitmap.cpp index 015a9c4c4..c21b30fb7 100644 --- a/code/nel/src/misc/bitmap.cpp +++ b/code/nel/src/misc/bitmap.cpp @@ -3269,77 +3269,79 @@ CRGBAF CBitmap::getColor (float x, float y) const uint32 i; + bool isValid = true; for (i = 0; i < 4; ++i) { - nlassert (nX[i] >= 0); - nlassert (nY[i] >= 0 ); - nlassert (nX[i] < nWidth); - nlassert (nY[i] < nHeight); + if (nX[i] < 0 || nY[i] < 0 || nX[i] >= nWidth || nY[i] >= nHeight) + isValid = false; } - // Decimal part of (x,y) - x = x - (float)nX[0]; - y = y - (float)nY[0]; - - switch (this->PixelFormat) + if (isValid) { - case RGBA: - case DXTC1: - case DXTC1Alpha: - case DXTC3: - case DXTC5: - { - CRGBAF finalVal; - CRGBA val[4]; + // Decimal part of (x,y) + x = x - (float)nX[0]; + y = y - (float)nY[0]; - if (this->PixelFormat == RGBA) + switch (this->PixelFormat) + { + case RGBA: + case DXTC1: + case DXTC1Alpha: + case DXTC3: + case DXTC5: { - for (i = 0; i < 4; ++i) + CRGBAF finalVal; + CRGBA val[4]; + + if (this->PixelFormat == RGBA) { - val[i] = CRGBA (rBitmap[(nX[i]+nY[i]*nWidth)*4+0], - rBitmap[(nX[i]+nY[i]*nWidth)*4+1], - rBitmap[(nX[i]+nY[i]*nWidth)*4+2], - rBitmap[(nX[i]+nY[i]*nWidth)*4+3]); + for (i = 0; i < 4; ++i) + { + val[i] = CRGBA (rBitmap[(nX[i]+nY[i]*nWidth)*4+0], + rBitmap[(nX[i]+nY[i]*nWidth)*4+1], + rBitmap[(nX[i]+nY[i]*nWidth)*4+2], + rBitmap[(nX[i]+nY[i]*nWidth)*4+3]); + } } - } - else - { - // slower version : get from DXT - for (i = 0; i < 4; ++i) + else { - val[i] = getPixelColor(nX[i], nY[i]); + // slower version : get from DXT + for (i = 0; i < 4; ++i) + { + val[i] = getPixelColor(nX[i], nY[i]); + } } - } - finalVal.R = getColorInterp (x, y, val[0].R, val[1].R, val[2].R, val[3].R); - finalVal.G = getColorInterp (x, y, val[0].G, val[1].G, val[2].G, val[3].G); - finalVal.B = getColorInterp (x, y, val[0].B, val[1].B, val[2].B, val[3].B); - finalVal.A = getColorInterp (x, y, val[0].A, val[1].A, val[2].A, val[3].A); - finalVal /= 255.f; + finalVal.R = getColorInterp (x, y, val[0].R, val[1].R, val[2].R, val[3].R); + finalVal.G = getColorInterp (x, y, val[0].G, val[1].G, val[2].G, val[3].G); + finalVal.B = getColorInterp (x, y, val[0].B, val[1].B, val[2].B, val[3].B); + finalVal.A = getColorInterp (x, y, val[0].A, val[1].A, val[2].A, val[3].A); + finalVal /= 255.f; - return finalVal; - } - break; - case Alpha: - case Luminance: - { + return finalVal; + } + break; + case Alpha: + case Luminance: + { - float finalVal; - float val[4]; + float finalVal; + float val[4]; - for (i = 0; i < 4; ++i) - val[i] = rBitmap[(nX[i]+nY[i]*nWidth)]; + for (i = 0; i < 4; ++i) + val[i] = rBitmap[(nX[i]+nY[i]*nWidth)]; - finalVal = getColorInterp (x, y, val[0], val[1], val[2], val[3]); - finalVal /= 255.f; + finalVal = getColorInterp (x, y, val[0], val[1], val[2], val[3]); + finalVal /= 255.f; - if (this->PixelFormat == Alpha) - return CRGBAF (1.f, 1.f, 1.f, finalVal); - else // Luminance - return CRGBAF (finalVal, finalVal, finalVal, 1.f); + if (this->PixelFormat == Alpha) + return CRGBAF (1.f, 1.f, 1.f, finalVal); + else // Luminance + return CRGBAF (finalVal, finalVal, finalVal, 1.f); + } + break; + default: break; } - break; - default: break; } return CRGBAF (0.0f, 0.0f, 0.0f, 0.0f); @@ -3626,7 +3628,7 @@ void CBitmap::loadSize(NLMISC::IStream &f, uint32 &retWidth, uint32 &retHeight) { uint8 imagePrecision = 0; // sample precision uint32 imageSize = 0; // width and height - f.serial(imagePrecision); + f.serial(imagePrecision); f.serial(imageSize); NLMISC_BSWAP32(imageSize); diff --git a/code/nel/src/sound/audio_decoder.cpp b/code/nel/src/sound/audio_decoder.cpp index ac7745721..1314cd448 100644 --- a/code/nel/src/sound/audio_decoder.cpp +++ b/code/nel/src/sound/audio_decoder.cpp @@ -116,10 +116,9 @@ IAudioDecoder *IAudioDecoder::createAudioDecoder(const std::string &type, NLMISC bool IAudioDecoder::getInfo(const std::string &filepath, std::string &artist, std::string &title, float &length) { - std::string lookup = CPath::lookup(filepath, false); - if (lookup.empty()) + if (filepath.empty() || !CFile::fileExists(filepath)) { - nlwarning("Music file %s does not exist!", filepath.c_str()); + nlwarning("Music file '%s' does not exist!", filepath.c_str()); return false; } @@ -127,7 +126,7 @@ bool IAudioDecoder::getInfo(const std::string &filepath, std::string &artist, st CIFile ifile; ifile.setCacheFileOnOpen(false); ifile.allowBNPCacheFileOnOpen(false); - if (ifile.open(lookup)) + if (ifile.open(filepath)) return CAudioDecoderFfmpeg::getInfo(&ifile, artist, title, length); #else std::string type = CFile::getExtension(filepath); @@ -138,7 +137,7 @@ bool IAudioDecoder::getInfo(const std::string &filepath, std::string &artist, st CIFile ifile; ifile.setCacheFileOnOpen(false); ifile.allowBNPCacheFileOnOpen(false); - if (ifile.open(lookup)) + if (ifile.open(filepath)) return CAudioDecoderVorbis::getInfo(&ifile, artist, title, length); nlwarning("Unable to open: '%s'", filepath.c_str()); @@ -149,7 +148,7 @@ bool IAudioDecoder::getInfo(const std::string &filepath, std::string &artist, st CIFile ifile; ifile.setCacheFileOnOpen(false); ifile.allowBNPCacheFileOnOpen(false); - if (ifile.open(lookup)) + if (ifile.open(filepath)) return CAudioDecoderMP3::getInfo(&ifile, artist, title, length); nlwarning("Unable to open: '%s'", filepath.c_str()); diff --git a/code/nel/src/sound/driver/fmod/sound_driver_fmod.cpp b/code/nel/src/sound/driver/fmod/sound_driver_fmod.cpp index d98aa600f..2b250a1d3 100644 --- a/code/nel/src/sound/driver/fmod/sound_driver_fmod.cpp +++ b/code/nel/src/sound/driver/fmod/sound_driver_fmod.cpp @@ -496,36 +496,20 @@ bool getTag (std::string &result, const char *tag, FSOUND_STREAM *stream) } /** Get music info. Returns false if the song is not found or the function is not implemented. - * \param filepath path to file, CPath::lookup done by driver + * \param filepath full path to file * \param artist returns the song artist (empty if not available) * \param title returns the title (empty if not available) */ bool CSoundDriverFMod::getMusicInfo(const std::string &filepath, std::string &artist, std::string &title, float &length) { - /* Open a stream, get the tag if it exists, close the stream */ - string pathName = CPath::lookup(filepath, false); - uint32 fileOffset = 0, fileSize = 0; - if (pathName.empty()) + if (filepath.empty() || !CFile::fileExists(filepath)) { nlwarning("NLSOUND FMod Driver: Music file %s not found!", filepath.c_str()); return false; } - // if the file is in a bnp - if (pathName.find('@') != string::npos) - { - if (CBigFile::getInstance().getFileInfo(pathName, fileSize, fileOffset)) - { - // set pathname to bnp - pathName = pathName.substr(0, pathName.find('@')); - } - else - { - nlwarning("NLSOUND FMod Driver: BNP BROKEN"); - return false; - } - } - FSOUND_STREAM *stream = FSOUND_Stream_Open((const char *)CPath::lookup(filepath, false).c_str(), FSOUND_2D, (sint)fileOffset, (sint)fileSize); + uint32 fileOffset = 0, fileSize = 0; + FSOUND_STREAM *stream = FSOUND_Stream_Open(filepath.c_str(), FSOUND_2D, (sint)fileOffset, (sint)fileSize); if (stream) { getTag(artist, "ARTIST", stream); diff --git a/code/nel/src/sound/driver/fmod/sound_driver_fmod.h b/code/nel/src/sound/driver/fmod/sound_driver_fmod.h index db82cde6e..73d3b8673 100644 --- a/code/nel/src/sound/driver/fmod/sound_driver_fmod.h +++ b/code/nel/src/sound/driver/fmod/sound_driver_fmod.h @@ -112,7 +112,7 @@ public: virtual IMusicChannel *createMusicChannel(); /** Get music info. Returns false if the song is not found or the function is not implemented. - * \param filepath path to file, CPath::lookup done by driver + * \param filepath full path to file * \param artist returns the song artist (empty if not available) * \param title returns the title (empty if not available) */ diff --git a/code/ryzom/client/src/client_cfg.cpp b/code/ryzom/client/src/client_cfg.cpp index d2e3458fb..df1debee2 100644 --- a/code/ryzom/client/src/client_cfg.cpp +++ b/code/ryzom/client/src/client_cfg.cpp @@ -439,8 +439,8 @@ CClientConfig::CClientConfig() CurlMaxConnections = 5; CurlCABundle.clear(); - RingReleaseNotePath = WebIgMainDomain + "/releasenotes_ring/index.php"; - ReleaseNotePath = WebIgMainDomain + "/releasenotes/index.php"; + RingReleaseNotePath = WebIgMainDomain + "/app_releasenotes/index.php"; + ReleaseNotePath = WebIgMainDomain + "/app_releasenotes/index.php"; /////////////// diff --git a/code/ryzom/client/src/connection.cpp b/code/ryzom/client/src/connection.cpp index 8e301c36f..82564354e 100644 --- a/code/ryzom/client/src/connection.cpp +++ b/code/ryzom/client/src/connection.cpp @@ -33,6 +33,7 @@ #include "nel/misc/time_nl.h" #include "nel/misc/algo.h" #include "nel/misc/system_utils.h" +#include "nel/misc/stream.h" // 3D Interface. #include "nel/3d/u_driver.h" #include "nel/3d/u_text_context.h" @@ -149,6 +150,7 @@ ucstring PlayerSelectedHomeShardName; ucstring PlayerSelectedHomeShardNameWithParenthesis; extern std::string CurrentCookie; + ucstring NewKeysCharNameWanted; // name of the character for which a new keyset must be created ucstring NewKeysCharNameValidated; std::string GameKeySet = "keys.xml"; @@ -157,9 +159,11 @@ std::string RingEditorKeySet = "keys_r2ed.xml"; string ScenarioFileName; sint LoginCharsel = -1; -static const char *KeySetVarName = "BuiltInKeySets"; +std::string ImportCharacter; +static const char *KeySetVarName = "BuiltInKeySets"; +#define GROUP_LIST_CHARACTER "ui:outgame:charsel_import:import_list" #define GROUP_LIST_MAINLAND "ui:outgame:appear_mainland:mainland_list" #define GROUP_LIST_KEYSET "ui:outgame:appear_keyset:keyset_list" vector Mainlands; @@ -2124,7 +2128,7 @@ public: virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */) { - CInterfaceManager *pIM = CInterfaceManager::getInstance(); + //CInterfaceManager *pIM = CInterfaceManager::getInstance(); CInterfaceGroup *pList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_MAINLAND)); if (pList == NULL) @@ -2203,7 +2207,7 @@ public: virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */) { - CInterfaceManager *pIM = CInterfaceManager::getInstance(); + //CInterfaceManager *pIM = CInterfaceManager::getInstance(); CInterfaceGroup *pList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_MAINLAND)); pList->clearGroups(); } @@ -2214,32 +2218,56 @@ REGISTER_ACTION_HANDLER (CAHResetMainlandList, "reset_mainland_list"); // *************************************************************************** class CAHMainlandSelect : public IActionHandler { - virtual void execute (CCtrlBase *pCaller, const string &/* Params */) + virtual void execute (CCtrlBase *pCaller, const std::string &Params) { - nlinfo("CAHMainlandSelect called"); - - CInterfaceManager *pIM = CInterfaceManager::getInstance(); + //nlinfo("CAHMainlandSelect called"); + struct CUnpush : public CInterfaceElementVisitor + { + CCtrlBase *Ref; + virtual void visitCtrl(CCtrlBase *ctrl) + { + if (ctrl == Ref) return; + CCtrlBaseButton *but = dynamic_cast(ctrl); + if (but) + { + but->setPushed(false); + } + } + }; + CInterfaceGroup *list = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_MAINLAND)); + if (!list) + return; - CCtrlButton *pCB = NULL; - // Unselect - if (MainlandSelected.asInt() != 0) + // unselect + if (Params.empty()) { - pCB = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_MAINLAND ":"+toString(MainlandSelected)+":but")); - if (pCB != NULL) - pCB->setPushed(false); + CUnpush unpusher; + unpusher.Ref = pCaller; + list->visit(&unpusher); } - pCB = dynamic_cast(pCaller); - if (pCB != NULL) + // now select + uint32 mainland; + if (Params.empty()) { - string name = pCB->getId(); - name = name.substr(0,name.rfind(':')); - uint32 mainland; - fromString(name.substr(name.rfind(':')+1,name.size()), mainland); - MainlandSelected = (TSessionId)mainland; + CCtrlButton *pCB = dynamic_cast(pCaller); + if (!pCB) + return; + + std::string name = pCB->getId(); + name = name.substr(0, name.rfind(':')); + + if (!fromString(name.substr(name.rfind(':')+1, name.size()), mainland)) + return; pCB->setPushed(true); } + else + if (!fromString(Params, mainland)) + return; + + // and store + MainlandSelected = (TSessionId)mainland; } }; REGISTER_ACTION_HANDLER (CAHMainlandSelect, "mainland_select"); @@ -2444,7 +2472,7 @@ public: virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */) { - CInterfaceManager *pIM = CInterfaceManager::getInstance(); + //CInterfaceManager *pIM = CInterfaceManager::getInstance(); CInterfaceGroup *pList = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_KEYSET)); pList->clearGroups(); } @@ -2455,59 +2483,66 @@ REGISTER_ACTION_HANDLER (CAHResetKeysetList, "reset_keyset_list"); // *************************************************************************** class CAHResetKeysetSelect : public IActionHandler { -public: std::string getIdPostFix(const std::string fullId) { std::string::size_type pos = fullId.find_last_of(":"); if (pos != std::string::npos) - { return fullId.substr(pos + 1); - } + return ""; } - virtual void execute (CCtrlBase *pCaller, const string &/* Params */) + + virtual void execute(CCtrlBase *pCaller, const std::string &Params) { - if (!pCaller) return; // 'unpush' all groups but the caller - // struct CUnpush : public CInterfaceElementVisitor { CCtrlBase *Ref; virtual void visitCtrl(CCtrlBase *ctrl) { if (ctrl == Ref) return; - CCtrlBaseButton *but = dynamic_cast(ctrl); + CCtrlBaseButton *but = dynamic_cast(ctrl); if (but) { but->setPushed(false); } } }; - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - CInterfaceGroup * list = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_KEYSET)); - if (list) - { - CUnpush unpusher; - unpusher.Ref = pCaller; - list->visit(&unpusher); - } - CCtrlBaseButton *but = dynamic_cast(pCaller); + CInterfaceGroup *list = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_KEYSET)); + if (!list) + return; + + // unselect + CUnpush unpusher; + unpusher.Ref = pCaller; + list->visit(&unpusher); + + // now select + CCtrlBaseButton *but = dynamic_cast(pCaller); if (but) - { but->setPushed(true); + + std::string id; + if (Params.empty()) + { + if (!pCaller) return; + if (!pCaller->getParent()) return; + + id = getIdPostFix(pCaller->getParent()->getId()); } - // + else + id = getIdPostFix(Params); + GameKeySet = "keys.xml"; RingEditorKeySet = "keys_r2ed.xml"; - if (!pCaller->getParent()) return; - // compute the 2 filenames from the id - // if id is in the built-in keysets : + + // compute the two filenames from the id + // if id is in the built-in keysets CConfigFile::CVar *keySetVar = ClientCfg.ConfigFile.getVarPtr(KeySetVarName); - if (keySetVar && keySetVar->size() != 0) + if (keySetVar && keySetVar->size() > 0) { for (uint k = 0; k < keySetVar->size(); ++k) { - std::string id = getIdPostFix(pCaller->getParent()->getId()); if (keySetVar->asString(k) == id) { GameKeySet = "keys" + string(id.empty() ? "" : "_") + id + ".xml"; @@ -2516,17 +2551,15 @@ public: } } } - // ... else maybe from a previous character ? - if (CFile::isExists("save/keys_" + getIdPostFix(pCaller->getParent()->getId()) + ".xml") ) - { - GameKeySet = "keys_" + getIdPostFix(pCaller->getParent()->getId()) + ".xml"; - } - if (CFile::isExists("save/keys_r2ed_" + getIdPostFix(pCaller->getParent()->getId()) + ".xml") ) - { - RingEditorKeySet = "keys_r2ed_" + getIdPostFix(pCaller->getParent()->getId()) + ".xml"; - } - // NB : key file will be copied for real when the new 'character summary' is + // else maybe from a previous character? + if (CFile::isExists("save/keys_" + id + ".xml")) + GameKeySet = "keys_" + id + ".xml"; + + if (CFile::isExists("save/keys_r2ed_" + id + ".xml")) + RingEditorKeySet = "keys_r2ed_" + id + ".xml"; + + // NB: key file will be copied for real when the new character summary is } }; REGISTER_ACTION_HANDLER (CAHResetKeysetSelect, "keyset_select"); @@ -3421,3 +3454,239 @@ class CAHOpenRingSessions : public IActionHandler } }; REGISTER_ACTION_HANDLER (CAHOpenRingSessions, "open_ring_sessions"); + +// *************************************************************************** +class CAHInitImportCharacter : public IActionHandler +{ + virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */) + { + CInterfaceGroup *list = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_CHARACTER)); + if (!list) + { + nlwarning("element " GROUP_LIST_CHARACTER " not found probably bad outgame.xml"); + return; + } + + // retrieve saved files + std::vector savedCharacters; + CPath::getPathContent("save/", false, false, true, savedCharacters); + + CInterfaceGroup *newLine; + CInterfaceGroup *prevLine; + + for (uint i = 0; i < savedCharacters.size(); ++i) + { + // search saved characters only + if (testWildCard(CFile::getFilename(savedCharacters[i]), "character_*.save")) + { + const std::string id = CFile::getFilenameWithoutExtension(savedCharacters[i]).substr(strlen("character_")); + if (id.empty()) + continue; + + std::vector> params; + params.clear(); + params.push_back(std::pair("id", id)); + // adjust ref + if (list->getNumGroup() > 0) + params.push_back(std::pair("posref", "BL TL")); + + newLine = CWidgetManager::getInstance()->getParser()->createGroupInstance("t_import", GROUP_LIST_CHARACTER, params); + if (newLine) + { + CViewText *text = dynamic_cast(newLine->getView("name")); + if (text) + text->setText(ucstring(savedCharacters[i])); + + // first button is pushed + CCtrlButton *button = dynamic_cast(newLine->getCtrl("but")); + if (button && list->getNumGroup() == 0) + button->setPushed(true); + + // add to the list now + newLine->setParent(list); + newLine->setParentSize(list); + newLine->setParentPos(prevLine); + + list->addGroup(newLine); + + prevLine = newLine; + } + } + } + // none case + if (list->getNumGroup() == 0) + CLuaManager::getInstance().executeLuaScript("outgame:procCharselNotifaction(3)"); + + list->invalidateCoords(); + } +}; +REGISTER_ACTION_HANDLER( CAHInitImportCharacter, "import_char_init" ); + +// *************************************************************************** +class CAHResetImportCharacter : public IActionHandler +{ + virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */) + { + CInterfaceGroup *list = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_CHARACTER)); + if (list) + list->clearGroups(); + + if (!ImportCharacter.empty()) + ImportCharacter = ""; + } +}; +REGISTER_ACTION_HANDLER( CAHResetImportCharacter, "import_char_reset" ); + +// *************************************************************************** +class CAHSelectImportCharacter : public IActionHandler +{ + virtual void execute (CCtrlBase *pCaller, const std::string &Params) + { + struct CUnpush : public CInterfaceElementVisitor + { + CCtrlBase *Ref; + virtual void visitCtrl(CCtrlBase *ctrl) + { + if (ctrl == Ref) return; + CCtrlBaseButton *but = dynamic_cast(ctrl); + if (but) + { + but->setPushed(false); + } + } + }; + CInterfaceGroup *list = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(GROUP_LIST_CHARACTER)); + if (!list) + return; + + // unselect + if (Params.empty()) + { + CUnpush unpusher; + unpusher.Ref = pCaller; + list->visit(&unpusher); + } + + // now select + std::string name; + if (Params.empty()) + { + CCtrlButton *pCB = dynamic_cast(pCaller); + if (!pCB) + return; + + std::string id = pCB->getId(); + id = id.substr(0, id.rfind(':')); + + if (!fromString(id.substr(id.rfind(':')+1, id.size()), name)) + return; + + pCB->setPushed(true); + } + else + if (!fromString(Params, name)) + return; + + ImportCharacter = ""; + // check filename and store + if (CFile::fileExists(toString("save/character_%s.save", name.c_str()))) + ImportCharacter = name; + } +}; +REGISTER_ACTION_HANDLER( CAHSelectImportCharacter, "import_char_select" ); + +// *************************************************************************** +class CAHImportCharacter : public IActionHandler +{ + virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */) + { + if (ImportCharacter.empty()) + return; + + if (!CFile::fileExists(toString("save/character_%s.save", ImportCharacter.c_str()))) + return; + + bool success = false; + + CIFile fd; + CCharacterSummary CS; + // use temporary file until close() + if (fd.open(toString("save/character_%s.save", ImportCharacter.c_str()))) + { + try + { + CS.serial(fd); + SCharacter3DSetup::setupDBFromCharacterSummary("UI:TEMP:CHAR3D", CS); + + // validate import + CDBManager::getInstance()->getDbProp("UI:TEMP:IMPORT")->setValue32(1); + success = true; + } + catch (const EStream &e) + { + nlwarning(e.what()); + } + fd.close(); + } + else + nlwarning("Failed to open file: save/character_%s.save", ImportCharacter.c_str()); + + // user notification + if (!success) + CLuaManager::getInstance().executeLuaScript("outgame:procCharselNotifaction(2)"); + else + CAHManager::getInstance()->runActionHandler("proc", NULL, "proc_charsel_create_new"); + } +}; +REGISTER_ACTION_HANDLER( CAHImportCharacter, "import_char" ); + +// *************************************************************************** +class CAHExportCharacter : public IActionHandler +{ + virtual void execute (CCtrlBase * /* pCaller */, const std::string &Params) + { + if (Params.empty()) + return; + + sint32 slot = -1; + if (!fromString(getParam(Params, "slot"), slot)) + return; + + if (slot >= CharacterSummaries.size() || slot < 0) + return; + + // retrieve infos + CCharacterSummary &CS = CharacterSummaries[slot]; + if (CS.Name.empty()) + return; + + // extract name + const std::string name = buildPlayerNameForSaveFile(CS.Name.toString()); + + COFile fd; + bool success = false; + // use temporary file until close() + if (fd.open(toString("save/character_%s.save", name.c_str()), false, false, true)) + { + try + { + fd.serial(CS); + fd.flush(); + // validate + success = true; + } + catch (const EStream &e) + { + nlwarning(e.what()); + } + fd.close(); + } + else + nlwarning("Failed to open file: save/character_%s.save", name.c_str()); + + const uint8 val = (success == true) ? 0 : 1; + // user notification + CLuaManager::getInstance().executeLuaScript(toString("outgame:procCharselNotifaction(%i)", val)); + } +}; +REGISTER_ACTION_HANDLER( CAHExportCharacter, "export_char" ); diff --git a/code/ryzom/client/src/game_context_menu.cpp b/code/ryzom/client/src/game_context_menu.cpp index c19ea62ac..78e58c4b5 100644 --- a/code/ryzom/client/src/game_context_menu.cpp +++ b/code/ryzom/client/src/game_context_menu.cpp @@ -451,18 +451,19 @@ void CGameContextMenu::update() else if (continent == "lepaysmalade.continent") fameIndex = CStaticFames::getInstance().getFactionIndex("zorai"); - + if (fameIndex != CStaticFames::INVALID_FACTION_INDEX) { CCDBNodeLeaf *pLeafFame = NLGUI::CDBManager::getInstance()->getDbProp(toString("SERVER:FAME:PLAYER%d:VALUE", fameIndex), false); if (pLeafFame != NULL) fameValue = pLeafFame->getValue8(); } + if (_TextNews) - _TextNews->setActive(selection && !canAttack() && selection->isNPC() && fameValue >= -30); + _TextNews->setActive(!UserEntity->isFighting() && !UserEntity->isRiding() && selection && !canAttack() && selection->isNPC() && fameValue >= -30); if (_TextNewsAgressive) - _TextNewsAgressive->setActive(selection && !canAttack() && selection->isNPC() && fameValue < -30); + _TextNewsAgressive->setActive(!UserEntity->isFighting() && !UserEntity->isRiding() && selection && !canAttack() && selection->isNPC() && fameValue < -30); if (_TextDuel && _TextUnDuel) diff --git a/code/ryzom/client/src/interface_v3/action_handler_game.cpp b/code/ryzom/client/src/interface_v3/action_handler_game.cpp index 58c00421b..3e3ce9b8e 100644 --- a/code/ryzom/client/src/interface_v3/action_handler_game.cpp +++ b/code/ryzom/client/src/interface_v3/action_handler_game.cpp @@ -4655,6 +4655,45 @@ public: }; REGISTER_ACTION_HANDLER( CHandlerSortTribeFame, "sort_tribefame"); +// *************************************************************************** +class CHandlerOutgameNaviGetKeys : public IActionHandler +{ + virtual void execute (CCtrlBase *pCaller, const std::string &Params) + { + if (!pCaller->getParent()) + return; + + if (pCaller->getParent()->getId() != "ui:outgame") + return; + + if (Params.empty()) + { + sint32 event = -1; + + if (Driver->AsyncListener.isKeyPushed(KeyESCAPE)) event = 0; + if (Driver->AsyncListener.isKeyPushed(KeyDELETE)) event = 1; + if (Driver->AsyncListener.isKeyPushed(KeyRETURN)) event = 2; + if (Driver->AsyncListener.isKeyPushed(KeyDOWN)) event = 3; + if (Driver->AsyncListener.isKeyPushed(KeyUP)) event = 4; + if (Driver->AsyncListener.isKeyPushed(KeyI)) event = 5; + if (Driver->AsyncListener.isKeyPushed(KeyP)) event = 6; + if (Driver->AsyncListener.isKeyPushed(KeyE)) event = 7; + if (Driver->AsyncListener.isKeyPushed(KeyLEFT)) event = 8; + if (Driver->AsyncListener.isKeyPushed(KeyRIGHT)) event = 9; + + std::string id = "create"; + if (pCaller->getId() == "ui:outgame:charsel") + id = "sel"; + + if (event != -1) +- CLuaManager::getInstance().executeLuaScript(toString("outgame:eventChar%sKeyGet(%i)", id.c_str(), event)); + } + // reset previous input + Driver->AsyncListener.reset(); + } +}; +REGISTER_ACTION_HANDLER( CHandlerOutgameNaviGetKeys, "navigate_outgame" ); + // *************************************************************************** class CHandlerTriggerIconBuffs : public IActionHandler { diff --git a/code/ryzom/client/src/interface_v3/chat_text_manager.cpp b/code/ryzom/client/src/interface_v3/chat_text_manager.cpp index 3b11d17a5..b3a673ffe 100644 --- a/code/ryzom/client/src/interface_v3/chat_text_manager.cpp +++ b/code/ryzom/client/src/interface_v3/chat_text_manager.cpp @@ -422,6 +422,29 @@ CViewBase *CChatTextManager::createMsgTextComplex(const ucstring &msg, NLMISC::C return para; } + ucstring::size_type pos = 0; + + // Manage Translations + string::size_type startTr = msg.find(ucstring("{:")); + string::size_type endOfOriginal = msg.find(ucstring("}@{")); + + // Original/Translated case, example: {:enHello the world!}@{ Bonjour le monde ! + if (startTr != string::npos && endOfOriginal != string::npos) + { + CViewBase *vt = createMsgTextSimple(msg.substr(0, startTr), col, justified, NULL); + para->addChild(vt); + + string texture = "flag-"+toLower(msg.substr(startTr+2, 2)).toString()+".tga"; + ucstring original = msg.substr(startTr+5, endOfOriginal-startTr-5); + pos = endOfOriginal+3; + CCtrlButton *ctrlButton = new CCtrlButton(CViewBase::TCtorParam()); + ctrlButton->setTexture(texture); + ctrlButton->setTextureOver(texture); + ctrlButton->setTexturePushed(texture); + ctrlButton->setDefaultContextHelp(original); + ctrlButton->setId("tr"); + para->addChild(ctrlButton); + } // quickly check if text has links or not bool hasUrl; @@ -430,8 +453,7 @@ CViewBase *CChatTextManager::createMsgTextComplex(const ucstring &msg, NLMISC::C hasUrl = (s.find(ucstring("http://")) || s.find(ucstring("https://"))); } - ucstring::size_type pos = 0; - for (ucstring::size_type i = 0; i< textSize;) + for (ucstring::size_type i = pos; i< textSize;) { if (hasUrl && isUrlTag(msg, i, textSize)) { diff --git a/code/ryzom/client/src/interface_v3/chat_window.cpp b/code/ryzom/client/src/interface_v3/chat_window.cpp index 1537e7b8b..13f7bc66d 100644 --- a/code/ryzom/client/src/interface_v3/chat_window.cpp +++ b/code/ryzom/client/src/interface_v3/chat_window.cpp @@ -215,29 +215,34 @@ void CChatWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CChatGr CChatTextManager &ctm = getChatTextMngr(); gl = dynamic_cast(_Chat->getGroup("cb:text_list")); - if (gl) gl->addChild(ctm.createMsgText(msg, col)); - // if the group is closed, make it blink - if (!_Chat->isOpen()) + CViewBase *child = ctm.createMsgText(msg, col); + if (child) { - if (numBlinks) _Chat->enableBlink(numBlinks); - } - if (_ParentBlink) - { - CGroupContainer *father = dynamic_cast(_Chat->getParent()); - if (father && !father->isOpen()) + if (gl) gl->addChild(child); + + // if the group is closed, make it blink + if (!_Chat->isOpen()) { - father->enableBlink(numBlinks); + if (numBlinks) _Chat->enableBlink(numBlinks); } + if (_ParentBlink) + { + CGroupContainer *father = dynamic_cast(_Chat->getParent()); + if (father && !father->isOpen()) + { + father->enableBlink(numBlinks); + } + } + if (windowVisible != NULL) + { + *windowVisible = isVisible(); + } + /*for(std::vector::iterator it = _Observers.begin(); it != _Observers.end(); ++it) + { + (*it)->displayMessage(this, msg, col, numBlinks); + }*/ } - if (windowVisible != NULL) - { - *windowVisible = isVisible(); - } - /*for(std::vector::iterator it = _Observers.begin(); it != _Observers.end(); ++it) - { - (*it)->displayMessage(this, msg, col, numBlinks); - }*/ } //================================================================================= @@ -563,12 +568,17 @@ void CChatGroupWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CC ucstring newmsg = msg; ucstring prefix; + CViewBase *child = NULL; if (gl != NULL) { - gl->addChild(ctm.createMsgText(newmsg, col)); - if (!gl->getParent()->getActive()) - if (tab != NULL) - tab->setTextColorNormal(newMsgColor); + child = ctm.createMsgText(newmsg, col); + if (child) + { + gl->addChild(child); + if (!gl->getParent()->getActive()) + if (tab != NULL) + tab->setTextColorNormal(newMsgColor); + } } // *** Display the message in the UserChat (special case) @@ -590,7 +600,7 @@ void CChatGroupWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CC case CChatGroup::guild: if (ci.Guild.isListeningWindow(cw)) gl = gl2; break; case CChatGroup::system: if (ci.SystemInfo.isListeningWindow(cw)) gl = gl2; break; case CChatGroup::universe: if (ci.Universe.isListeningWindow(cw)) gl = gl2; break; - case CChatGroup::dyn_chat: + case CChatGroup::dyn_chat: if (ci.DynamicChat[dynamicChatDbIndex].isListeningWindow(cw)) { gl = gl2; @@ -608,7 +618,7 @@ void CChatGroupWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CC pos = newmsg.find(ucstring("}")); prefix += " "; } - + if (pos == ucstring::npos) newmsg = prefix + newmsg; else @@ -635,31 +645,37 @@ void CChatGroupWindow::displayMessage(const ucstring &msg, NLMISC::CRGBA col, CC if (gl != NULL) { - gl->addChild(ctm.createMsgText(newmsg, col)); - if (!gl->getParent()->getActive()) - if (tab != NULL) - tab->setTextColorNormal(newMsgColor); + child = ctm.createMsgText(newmsg, col); + if (child) + { + gl->addChild(child); + if (!gl->getParent()->getActive()) + if (tab != NULL) + tab->setTextColorNormal(newMsgColor); + } } } - - // *** Blink and visibility event - // if the group is closed, make it blink - if (!_Chat->isOpen()) - { - if (numBlinks) _Chat->enableBlink(numBlinks); - } - if (_ParentBlink) + if (child) { - CGroupContainer *father = dynamic_cast(_Chat->getParent()); - if (father && !father->isOpen()) + // *** Blink and visibility event + // if the group is closed, make it blink + if (!_Chat->isOpen()) { - father->enableBlink(numBlinks); + if (numBlinks) _Chat->enableBlink(numBlinks); + } + if (_ParentBlink) + { + CGroupContainer *father = dynamic_cast(_Chat->getParent()); + if (father && !father->isOpen()) + { + father->enableBlink(numBlinks); + } + } + if (windowVisible != NULL) + { + *windowVisible = isVisible(); } - } - if (windowVisible != NULL) - { - *windowVisible = isVisible(); } } @@ -685,8 +701,9 @@ void CChatGroupWindow::displayTellMessage(const ucstring &msg, NLMISC::CRGBA col nlwarning(" can't get text_list."); return; } - - gl->addChild(getChatTextMngr().createMsgText(msg, col)); + CViewBase *child = getChatTextMngr().createMsgText(msg, col); + if (child) + gl->addChild(child); } //================================================================================= diff --git a/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp b/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp index 3d6c58dcd..56727f6d4 100644 --- a/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp +++ b/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp @@ -567,6 +567,11 @@ CDBCtrlSheet::~CDBCtrlSheet() Driver->deleteTextureFile(_GuildSymb); _GuildSymb = NULL; } + if (_RegenText) + { + delete _RegenText; + _RegenText = NULL; + } // ensure erase static if(this==_CurrMenuSheet) _CurrMenuSheet = NULL; diff --git a/code/ryzom/client/src/interface_v3/group_in_scene_bubble.cpp b/code/ryzom/client/src/interface_v3/group_in_scene_bubble.cpp index d79861b58..460a095fc 100644 --- a/code/ryzom/client/src/interface_v3/group_in_scene_bubble.cpp +++ b/code/ryzom/client/src/interface_v3/group_in_scene_bubble.cpp @@ -843,6 +843,14 @@ void CGroupInSceneBubbleManager::chatOpen (uint32 nUID, const ucstring &ucsText, if (pChar == NULL || nUID==CLFECOMMON::INVALID_CLIENT_DATASET_INDEX) return; if (bubbleTimer == 0) bubbleTimer = CWidgetManager::getInstance()->getSystemOption(CWidgetManager::OptionTimeoutBubbles).getValSInt32(); + + + // Clean bubble from translation system + ucstring::size_type pos = 0; + string::size_type endOfOriginal = ucsText.find(ucstring("}@{")); + if (endOfOriginal != string::npos) + pos = endOfOriginal+4; + // Output the message in a bubble bool show = false; @@ -862,7 +870,7 @@ void CGroupInSceneBubbleManager::chatOpen (uint32 nUID, const ucstring &ucsText, return; // Get a bubble - CGroupInSceneBubble *bubble = newBubble (ucsText); + CGroupInSceneBubble *bubble = newBubble (ucsText.substr(pos)); if (bubble) { // Link the bubble diff --git a/code/ryzom/client/src/interface_v3/interface_manager.cpp b/code/ryzom/client/src/interface_v3/interface_manager.cpp index f8637bff3..e81785ea8 100644 --- a/code/ryzom/client/src/interface_v3/interface_manager.cpp +++ b/code/ryzom/client/src/interface_v3/interface_manager.cpp @@ -1044,6 +1044,10 @@ void CInterfaceManager::initInGame() gc->setTarget(gc->getSavedTarget()); } + // rebuild mp3 player playlist if user reselected a char (songs are already scanned) + CAHManager::getInstance()->runActionHandler("music_player", NULL, "update_playlist"); + CAHManager::getInstance()->runActionHandler("music_player", NULL, "stop"); + CCDBNodeLeaf *node = NLGUI::CDBManager::getInstance()->getDbProp("UI:SAVE:CHATLOG_STATE", false); if (node) { diff --git a/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp b/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp index ac8d7dde8..8aa7af585 100644 --- a/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp +++ b/code/ryzom/client/src/interface_v3/lua_ihm_ryzom.cpp @@ -2298,13 +2298,28 @@ int CLuaIHMRyzom::addShape(CLuaState &ls) if(!instance.empty()) { + + if (texture == "#season#" || texture.empty()) + { + uint8 selectedTextureSet = (uint8)::computeCurrSeason(); + instance.selectTextureSet(selectedTextureSet); + texture = ""; + } + else if (texture[0] == '#') + { + uint8 selectedTextureSet; + fromString(texture.substr(1), selectedTextureSet); + instance.selectTextureSet(selectedTextureSet); + texture = ""; + } + for(uint j=0;j &filenames) // If pause, stop, else play will resume if (_State == Paused || _Songs.empty()) - _State = Stopped; + stop(); // get song title/duration using worker thread MusicPlayerWorker.getSongsInfo(filenames); } // *************************************************************************** -void CMusicPlayer::updatePlaylist(sint prevIndex) +void CMusicPlayer::updatePlaylist(uint index, bool state) { - CInterfaceElement *pIE; - std::string rowId; + if (index >= _Songs.size()) return; + + std::string rowId = toString("%s:s%d:bg", MP3_PLAYER_PLAYLIST_LIST, index); + CInterfaceElement *pIE = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(rowId)); + if (pIE) pIE->setActive(state); +} +void CMusicPlayer::updatePlaylist(sint prevIndex) +{ if (prevIndex >= 0 && prevIndex < _Songs.size()) { - rowId = toString("%s:s%d:bg", MP3_PLAYER_PLAYLIST_LIST, prevIndex); - pIE = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(rowId)); - if (pIE) pIE->setActive(false); + updatePlaylist(prevIndex, false); } - rowId = toString("%s:s%d:bg", MP3_PLAYER_PLAYLIST_LIST, _CurrentSongIndex); - pIE = dynamic_cast(CWidgetManager::getInstance()->getElementFromId(rowId)); - if (pIE) pIE->setActive(true); + updatePlaylist(_CurrentSongIndex, true); } // *************************************************************************** @@ -361,7 +363,7 @@ void CMusicPlayer::play (sint index) if (_Songs.empty()) { - _State = Stopped; + stop(); return; } @@ -432,11 +434,15 @@ void CMusicPlayer::stop () return; // stop the music only if we are really playing (else risk to stop a background music!) - SoundMngr->stopMusic(0); + if (_State != Stopped) + SoundMngr->stopMusic(0); + _State = Stopped; _PlayStart = 0; _PauseTime = 0; + clearPlayingInfo(); + NLGUI::CDBManager::getInstance()->getDbProp("UI:TEMP:MP3_PLAYING")->setValueBool(false); } @@ -472,12 +478,38 @@ void CMusicPlayer::next () } // *************************************************************************** +void CMusicPlayer::updatePlayingInfo(const std::string info) +{ + CViewText *pVT = dynamic_cast(CWidgetManager::getInstance()->getElementFromId("ui:interface:mp3_player:screen:text")); + if (pVT) + { + pVT->setText(ucstring::makeFromUtf8(info)); + } +} +// *************************************************************************** +void CMusicPlayer::clearPlayingInfo() +{ + if (_Songs.empty()) + { + updatePlayingInfo(CI18N::get("uiNoFiles").toUtf8()); + } + else + { + updatePlayingInfo(""); + } +} + +// *************************************************************************** void CMusicPlayer::update () { if(!SoundMngr) { - _State = Stopped; + if (_State != Stopped) + { + _State = Stopped; + clearPlayingInfo(); + } return; } @@ -488,8 +520,6 @@ void CMusicPlayer::update () if (_State == Playing) { - CViewText *pVT = dynamic_cast(CWidgetManager::getInstance()->getElementFromId("ui:interface:mp3_player:screen:text")); - if (pVT) { TTime dur = (CTime::getLocalTime() - _PlayStart) / 1000; uint min = (dur / 60) % 60; @@ -499,7 +529,7 @@ void CMusicPlayer::update () std::string title(toString("%02d:%02d", min, sec)); if (hour > 0) title = toString("%02d:", hour) + title; title += " " + _CurrentSong.Title; - pVT->setText(ucstring::makeFromUtf8(title)); + updatePlayingInfo(title); } if (SoundMngr->isMusicEnded ()) @@ -520,8 +550,13 @@ void CMusicPlayer::update () } else { - SoundMngr->stopMusic(0); - _State = Stopped; + // remove active highlight from playlist + updatePlaylist(_CurrentSongIndex, false); + + stop(); + + // restart from top on next 'play' + _CurrentSongIndex = 0; } } } diff --git a/code/ryzom/client/src/interface_v3/music_player.h b/code/ryzom/client/src/interface_v3/music_player.h index 1932591e3..febfde719 100644 --- a/code/ryzom/client/src/interface_v3/music_player.h +++ b/code/ryzom/client/src/interface_v3/music_player.h @@ -62,6 +62,10 @@ public: void update (); + // update currently playing song info/duration on main gui + void updatePlayingInfo(const std::string info); + void clearPlayingInfo(); + bool isRepeatEnabled() const; bool isShuffleEnabled() const; @@ -71,6 +75,8 @@ public: void shuffleAndRebuildPlaylist(); // Update playlist active row void updatePlaylist(sint prevIndex = -1); + // set/remove playlist highlight + void updatePlaylist(uint index, bool state); // Update single song title/duration on _Songs and on playlist void updateSong(const CSongs &song); diff --git a/code/ryzom/client/src/interface_v3/people_list.cpp b/code/ryzom/client/src/interface_v3/people_list.cpp index 6be310d94..92601ed32 100644 --- a/code/ryzom/client/src/interface_v3/people_list.cpp +++ b/code/ryzom/client/src/interface_v3/people_list.cpp @@ -199,7 +199,7 @@ bool CPeopleList::sortExByName(const CPeople& a, const CPeople& b) { ucstring name_a = toUpper(a.getName()); ucstring name_b = toUpper(b.getName()); - + return (name_a < name_b); } @@ -208,7 +208,7 @@ bool CPeopleList::sortExByOnline(const CPeople& a, const CPeople& b) { ucstring name_a = toUpper(a.getName()); ucstring name_b = toUpper(b.getName()); - + // We want order: online/alpha, offworld/alpha, offline/alpha if (a.Online == b.Online) { @@ -249,7 +249,7 @@ void CPeopleList::sortEx(TSortOrder order) { _BaseContainer->detachContainer(_Peoples[k].Container); } - + switch (order) { default: @@ -480,17 +480,21 @@ void CPeopleList::displayLocalPlayerTell(const ucstring &receiver, uint index, c ucstring s = CI18N::get("youTellPlayer"); strFindReplace(s, "%name", receiver); strFindReplace(finalMsg, CI18N::get("youTell"), s); - gl->addChild(getChatTextMngr().createMsgText(finalMsg, prop.getRGBA())); - CInterfaceManager::getInstance()->log(finalMsg, CChatGroup::groupTypeToString(CChatGroup::tell)); - - // if the group is closed, make it blink - if (!gc->isOpen()) + CViewBase *child = getChatTextMngr().createMsgText(finalMsg, prop.getRGBA()); + if (child) { - if (numBlinks) gc->enableBlink(numBlinks); - } - if (_BaseContainer && !_BaseContainer->isOpen()) - { - _BaseContainer->enableBlink(numBlinks); + gl->addChild(child); + CInterfaceManager::getInstance()->log(finalMsg, CChatGroup::groupTypeToString(CChatGroup::tell)); + + // if the group is closed, make it blink + if (!gc->isOpen()) + { + if (numBlinks) gc->enableBlink(numBlinks); + } + if (_BaseContainer && !_BaseContainer->isOpen()) + { + _BaseContainer->enableBlink(numBlinks); + } } } @@ -539,8 +543,9 @@ void CPeopleList::displayMessage(uint index, const ucstring &msg, NLMISC::CRGBA nlwarning(" can't get text_list."); return; } - - gl->addChild(getChatTextMngr().createMsgText(msg, col)); + CViewBase *child = getChatTextMngr().createMsgText(msg, col); + if (child) + gl->addChild(child); } @@ -777,7 +782,7 @@ void CPeopleList::setOnline(uint index, TCharConnectionState online) CCtrlBase *chatButton = hc->getCtrl("chat_button"); if (chatButton != NULL) chatButton->setActive(online != ccs_offline); - + CCtrlBase *inviteButton = hc->getCtrl("invite_button"); if (inviteButton != NULL) inviteButton->setActive(online != ccs_offline); diff --git a/code/ryzom/client/src/release.cpp b/code/ryzom/client/src/release.cpp index 0477acce9..889bcee11 100644 --- a/code/ryzom/client/src/release.cpp +++ b/code/ryzom/client/src/release.cpp @@ -240,8 +240,8 @@ void releaseMainLoopReselect() // alredy called from farTPMainLoop() // --R2::getEditor().autoConfigRelease(IsInRingSession); - // Pause any user played music - MusicPlayer.pause(); + // stop any user played music + MusicPlayer.stop(); // only really needed at exit // --STRING_MANAGER::CStringManagerClient::instance()->flushStringCache(); @@ -390,8 +390,8 @@ void releaseMainLoop(bool closeConnection) // Release R2 editor if applicable R2::getEditor().autoConfigRelease(IsInRingSession); - // Pause any user played music - MusicPlayer.pause(); + // stop any user played music + MusicPlayer.stop(); // flush the server string cache STRING_MANAGER::CStringManagerClient::instance()->flushStringCache(); diff --git a/code/ryzom/client/src/string_manager_client.cpp b/code/ryzom/client/src/string_manager_client.cpp index 06c3523b4..ddc41d0d1 100644 --- a/code/ryzom/client/src/string_manager_client.cpp +++ b/code/ryzom/client/src/string_manager_client.cpp @@ -390,7 +390,7 @@ restartLoop4: else { result = it->second; - if (result.size() > 9 && result.substr(0, 9) == ucstring(" 9 && result.substr(0, 9) == ucstring("::iterator itds = _DynStrings.find(result.substr(9, result.size()-10)); if (itds != _DynStrings.end()) @@ -747,6 +747,12 @@ restartLoop: str = CEntityCL::removeTitleFromName(str); } + // if the string contains a special rename of creature, remove it + if (str.size() > 2 && str[0] == '<' && str[1] == '#') + { + str = str.substr(2); + } + // append this string temp.append(move, src+param.ReplacementPoint); temp += str; @@ -1625,7 +1631,7 @@ const ucchar *CStringManagerClient::getTitleLocalizedName(const ucstring &titleI _TitleWords.push_back(listInfos[0]); return getLocalizedName(_TitleWords.back()); } - + return getLocalizedName(titleId); }