From 130b43104357927922f2ca728c67750e5a2e2907 Mon Sep 17 00:00:00 2001 From: kervala Date: Mon, 13 Feb 2012 11:31:28 +0100 Subject: [PATCH 01/16] Fixed: Bad check in emote tokens --- code/ryzom/client/src/interface_v3/interface_manager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/ryzom/client/src/interface_v3/interface_manager.cpp b/code/ryzom/client/src/interface_v3/interface_manager.cpp index 180a25763..27b8f9197 100644 --- a/code/ryzom/client/src/interface_v3/interface_manager.cpp +++ b/code/ryzom/client/src/interface_v3/interface_manager.cpp @@ -6374,7 +6374,7 @@ bool CInterfaceManager::parseTokens(ucstring& ucstr) // Get everything between the two "$" size_t token_start_pos = start_pos + start_token.length(); size_t token_end_pos = end_pos - end_token.length(); - if (token_start_pos < token_end_pos) + if (token_start_pos > token_end_pos) { // Wrong formatting; give up on this one. start_pos = end_pos; From 874b39b05a3f5778709baf9364dd778e0252b3c8 Mon Sep 17 00:00:00 2001 From: kervala Date: Tue, 21 Feb 2012 17:47:16 +0100 Subject: [PATCH 02/16] Changed: Search in default paths if DXSDK_DIR is not defined --- code/CMakeModules/FindDirectXSDK.cmake | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/code/CMakeModules/FindDirectXSDK.cmake b/code/CMakeModules/FindDirectXSDK.cmake index 1f832cf95..9947778db 100644 --- a/code/CMakeModules/FindDirectXSDK.cmake +++ b/code/CMakeModules/FindDirectXSDK.cmake @@ -14,17 +14,22 @@ FIND_PATH(DXSDK_DIR "Include/dxsdkver.h" PATHS "$ENV{DXSDK_DIR}" + "C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)" + "C:/Program Files/Microsoft DirectX SDK (June 2010)" + "C:/Program Files (x86)/Microsoft DirectX SDK (February 2010)" + "C:/Program Files/Microsoft DirectX SDK (February 2010)" + "C:/Program Files (x86)/Microsoft DirectX SDK (November 2007)" + "C:/Program Files/Microsoft DirectX SDK (November 2007)" + "C:/Program Files (x86)/Microsoft DirectX SDK" + "C:/Program Files/Microsoft DirectX SDK" ) MACRO(FIND_DXSDK_LIBRARY MYLIBRARY MYLIBRARYNAME) FIND_LIBRARY(${MYLIBRARY} NAMES ${MYLIBRARYNAME} PATHS - "${DXSDK_LIBRARY_DIR}" - "$ENV{DXSDK_DIR}" - "$ENV{DXSDK_DIR}/Lib" - "$ENV{DXSDK_DIR}/Lib/x86" - ) + "${DXSDK_LIBRARY_DIR}" + ) ENDMACRO(FIND_DXSDK_LIBRARY MYLIBRARY MYLIBRARYNAME) IF(DXSDK_DIR) From 639b7f228568d45b15946962b6034d8cc36b8b85 Mon Sep 17 00:00:00 2001 From: kervala Date: Tue, 21 Feb 2012 21:11:04 +0100 Subject: [PATCH 03/16] Changed: #1219 Bad color when rgba.cpp is compiled with GCC 4.2.4 --- code/nel/src/misc/rgba.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/code/nel/src/misc/rgba.cpp b/code/nel/src/misc/rgba.cpp index 844a100cf..598d8eb53 100644 --- a/code/nel/src/misc/rgba.cpp +++ b/code/nel/src/misc/rgba.cpp @@ -643,6 +643,8 @@ bool CRGBA::convertToHLS(float &h, float &l, float &s) const { h = 2.f + (b - r) / diff; } +#if defined(GCC_VERSION) && (GCC_VERSION == 40204) + // use the fix only if using the specific GCC version else if (maxV == b) { h = 4.f + (r - g) / diff; @@ -652,6 +654,12 @@ bool CRGBA::convertToHLS(float &h, float &l, float &s) const // this case is to fix a compiler bug h = (g - b) / diff; } +#else + else + { + h = 4.f + (r - g) / diff; + } +#endif h *= 60.f; // scale to [0..360] From 48d8e331a65831d92c23abc802410e789d6db3f8 Mon Sep 17 00:00:00 2001 From: kervala Date: Wed, 22 Feb 2012 22:17:09 +0100 Subject: [PATCH 04/16] Changed: Fix again bad MSVC10 CMake generator... --- code/CMakeModules/nel.cmake | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/CMakeModules/nel.cmake b/code/CMakeModules/nel.cmake index 5c5efc4a9..eb2bc24ac 100644 --- a/code/CMakeModules/nel.cmake +++ b/code/CMakeModules/nel.cmake @@ -37,7 +37,9 @@ ENDMACRO(NL_TARGET_DRIVER) # Argument: ### MACRO(NL_DEFAULT_PROPS name label) - SET_TARGET_PROPERTIES(${name} PROPERTIES PROJECT_LABEL ${label}) + IF(NOT MSVC10) + SET_TARGET_PROPERTIES(${name} PROPERTIES PROJECT_LABEL ${label}) + ENDIF(NOT MSVC10) GET_TARGET_PROPERTY(type ${name} TYPE) IF(${type} STREQUAL SHARED_LIBRARY) # Set versions only if target is a shared library From ea55ed6cd0072720f49146ab10233709c70d3a4d Mon Sep 17 00:00:00 2001 From: kervala Date: Mon, 27 Feb 2012 09:59:27 +0100 Subject: [PATCH 05/16] Changed: #1433 Merge changes from patch 1.13 --- code/nel/include/nel/misc/common.h | 2 ++ code/nel/include/nel/misc/eid_translator.h | 2 ++ code/nel/include/nel/net/transport_class.h | 3 ++- code/nel/src/misc/common.cpp | 26 ++++++++++++++++++++++ code/nel/src/misc/eid_translator.cpp | 11 +++++++++ code/nel/src/misc/win_event_emitter.cpp | 7 ++++++ code/nel/src/net/transport_class.cpp | 3 ++- 7 files changed, 52 insertions(+), 2 deletions(-) diff --git a/code/nel/include/nel/misc/common.h b/code/nel/include/nel/misc/common.h index 42bf56d3b..fa9272386 100644 --- a/code/nel/include/nel/misc/common.h +++ b/code/nel/include/nel/misc/common.h @@ -342,6 +342,8 @@ std::string secondsToHumanReadable (uint32 time); /// Get a bytes or time in string format and convert it in seconds or bytes uint32 fromHumanReadable (const std::string &str); +/// Add digit grouping seperator to if value >= 10 000. Assumes input is numerical string. +std::string formatThousands(const std::string& s); /// This function executes a program in the background and returns instantly (used for example to launch services in AES). /// The program will be launched in the current directory diff --git a/code/nel/include/nel/misc/eid_translator.h b/code/nel/include/nel/misc/eid_translator.h index 695f7724e..9937b72fd 100644 --- a/code/nel/include/nel/misc/eid_translator.h +++ b/code/nel/include/nel/misc/eid_translator.h @@ -146,6 +146,8 @@ public: TAdditionalInfoCb EntityInfoCallback; + static void removeShardFromName(ucstring& name); + private: // get all eid for a user using the user name or the user id void getByUser (uint32 uid, std::vector &res); diff --git a/code/nel/include/nel/net/transport_class.h b/code/nel/include/nel/net/transport_class.h index 11161d7cd..2517da64b 100644 --- a/code/nel/include/nel/net/transport_class.h +++ b/code/nel/include/nel/net/transport_class.h @@ -75,7 +75,7 @@ public: enum TProp { PropUInt8, PropUInt16, PropUInt32, PropUInt64, PropSInt8, PropSInt16, PropSInt32, PropSInt64, - PropBool, PropFloat, PropDouble, PropString, PropDataSetRow, PropSheetId, PropUKN }; + PropBool, PropFloat, PropDouble, PropString, PropDataSetRow, PropSheetId, PropUCString, PropUKN }; // PropBool, PropFloat, PropDouble, PropString, PropDataSetRow, PropEntityId, PropSheetId, PropUKN }; @@ -160,6 +160,7 @@ public: case PropString: nlassert(sizeof(T) == sizeof (std::string)); break; // case PropEntityId: nlassert(sizeof(T) == sizeof (NLMISC::CEntityId)); break; case PropSheetId: nlassert(sizeof(T) == sizeof (NLMISC::CSheetId)); break; + case PropUCString: nlassert(sizeof(T) == sizeof (ucstring)); break; default: nlerror ("property %s have unknown type %d", name.c_str(), type); } diff --git a/code/nel/src/misc/common.cpp b/code/nel/src/misc/common.cpp index fb9a9c6f5..19be95367 100644 --- a/code/nel/src/misc/common.cpp +++ b/code/nel/src/misc/common.cpp @@ -30,6 +30,7 @@ #include "nel/misc/command.h" #include "nel/misc/path.h" +#include "nel/misc/i18n.h" using namespace std; @@ -526,6 +527,31 @@ void toUpper(char *str) } } +std::string formatThousands(const std::string& s) +{ + int i, k; + int remaining = s.length() - 1; + static std::string separator = NLMISC::CI18N::get("uiThousandsSeparator").toUtf8(); + + // Don't add separator if the number is < 10k + if (remaining < 4) return s; + + std::string ns; + + do + { + for (i = remaining, k = 0; i >= 0 && k < 3; --i, ++k ) + { + ns = s[i] + ns; // New char is added to front of ns + if ( i > 0 && k == 2) ns = separator + ns; // j > 0 means still more digits + } + + remaining -= 3; + } + while (remaining >= 0); + + return ns; +} // // Exceptions diff --git a/code/nel/src/misc/eid_translator.cpp b/code/nel/src/misc/eid_translator.cpp index 36ea84247..e254831c4 100644 --- a/code/nel/src/misc/eid_translator.cpp +++ b/code/nel/src/misc/eid_translator.cpp @@ -417,6 +417,17 @@ void CEntityIdTranslator::checkEntity (const CEntityId &eid, const ucstring &ent } } +void CEntityIdTranslator::removeShardFromName(ucstring& name) +{ + // The string must contain a '(' and a ')' + ucstring::size_type p0= name.find('('); + ucstring::size_type p1= name.find(')'); + if (p0 == ucstring::npos || p1 == ucstring::npos || p1 <= p0) + return; + + name = name.substr(0, p0) + name.substr(p1 + 1); +} + // this callback is call when the file is changed void cbInvalidEntityNamesFilename(const std::string &invalidEntityNamesFilename) { diff --git a/code/nel/src/misc/win_event_emitter.cpp b/code/nel/src/misc/win_event_emitter.cpp index 2c46a7530..c216e3e1a 100644 --- a/code/nel/src/misc/win_event_emitter.cpp +++ b/code/nel/src/misc/win_event_emitter.cpp @@ -153,6 +153,13 @@ bool CWinEventEmitter::processMessage (HWND hWnd, uint32 msg, WPARAM wParam, LPA if ((int)wParam==VK_SHIFT) _ShiftButton=false; + // As Print Screen button does not trigger a WM_KEYDOWN msg, simulate it here + if ((int)wParam==VK_SNAPSHOT) + { + if (wParam < KeyCount) + server->postEvent (new CEventKeyDown ((NLMISC::TKey)wParam, getKeyButton(_AltButton, _ShiftButton, _CtrlButton), true, this)); + } + // Post the message if (wParam < KeyCount) server->postEvent (new CEventKeyUp ((NLMISC::TKey)wParam, getKeyButton(_AltButton, _ShiftButton, _CtrlButton), this)); diff --git a/code/nel/src/net/transport_class.cpp b/code/nel/src/net/transport_class.cpp index a5f826728..dca866916 100644 --- a/code/nel/src/net/transport_class.cpp +++ b/code/nel/src/net/transport_class.cpp @@ -77,7 +77,7 @@ string typeToString (CTransportClass::TProp type) string conv[] = { "PropUInt8", "PropUInt16", "PropUInt32", "PropUInt64", "PropSInt8", "PropSInt16", "PropSInt32", "PropSInt64", - "PropBool", "PropFloat", "PropDouble", "PropString", "PropDataSetRow", "PropSheetId", "PropUKN" }; + "PropBool", "PropFloat", "PropDouble", "PropString", "PropDataSetRow", "PropSheetId", "PropUCString", "PropUKN" }; // "PropBool", "PropFloat", "PropDouble", "PropString", "PropDataSetRow", "PropEntityId", "PropSheetId", "PropUKN" }; if (type > CTransportClass::PropUKN) @@ -352,6 +352,7 @@ void CTransportClass::init () // nlassert (PropDataSetRow < PropUKN); DummyProp[PropDataSetRow] = new CTransportClass::CRegisteredProp; // nlassert (PropEntityId < PropUKN); DummyProp[PropEntityId] = new CTransportClass::CRegisteredProp; nlassert (PropSheetId < PropUKN); DummyProp[PropSheetId] = new CTransportClass::CRegisteredProp; + nlassert (PropUCString < PropUKN); DummyProp[PropUCString] = new CTransportClass::CRegisteredProp; // we have to know when a service comes, so add callback (put the callback before all other one because we have to send this message first) CUnifiedNetwork::getInstance()->setServiceUpCallback("*", cbTCUpService, NULL, false); From 6865470c035e03f9607185ced79a7f96353a54d5 Mon Sep 17 00:00:00 2001 From: kervala Date: Mon, 27 Feb 2012 10:01:45 +0100 Subject: [PATCH 06/16] Changed: #878 Fix typos in comments/code --- code/nel/include/nel/misc/event_emitter.h | 2 +- code/nel/src/3d/driver/direct3d/driver_direct3d.cpp | 2 +- code/nel/src/3d/driver/opengl/driver_opengl_light.cpp | 2 +- code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp | 2 +- code/nel/src/3d/nelu.cpp | 3 ++- code/nel/src/misc/events.cpp | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/code/nel/include/nel/misc/event_emitter.h b/code/nel/include/nel/misc/event_emitter.h index e678c2674..5c547d07f 100644 --- a/code/nel/include/nel/misc/event_emitter.h +++ b/code/nel/include/nel/misc/event_emitter.h @@ -49,7 +49,7 @@ public: * \param server */ virtual void submitEvents(CEventServer & server, bool allWindows) = 0; - + /** * Instruct the event emitter to send CGDMouseMove instead of CEventMouseMove. * diff --git a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp index 5ac1d2906..bfbd3fdb7 100644 --- a/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp +++ b/code/nel/src/3d/driver/direct3d/driver_direct3d.cpp @@ -1228,7 +1228,7 @@ bool CDriverD3D::init (uint windowIcon, emptyProc exitFunc) ExitFunc = exitFunc; createCursors(); - + // Register a window class WNDCLASSW wc; diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_light.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_light.cpp index e5c3cff6e..2fc25f94a 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_light.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_light.cpp @@ -138,7 +138,7 @@ void CDriverGL::setLightInternal(uint8 num, const CLight& light) } else { - // Deactivate spot properties + // Disable spot properties #ifdef USE_OPENGLES glLightf (lightNum, GL_SPOT_CUTOFF, 180.f); glLightf (lightNum, GL_SPOT_EXPONENT, 0.f); diff --git a/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp b/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp index 502c971f1..7241d499b 100644 --- a/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp +++ b/code/nel/src/3d/driver/opengl/driver_opengl_vertex.cpp @@ -978,7 +978,7 @@ void CDriverGL::setupGlArraysStd(CVertexBufferInfo &vb) // Check type nlassert (vb.Type[CVertexBuffer::Normal]==CVertexBuffer::Float3); _DriverGLStates.enableNormalArray(true); - nglArrayObjectATI(GL_NORMAL_ARRAY, 3, GL_FLOAT, vb.VertexSize, vb.VertexObjectId, (ptrdiff_t) vb.ValuePtr[CVertexBuffer::Normal]); + nglArrayObjectATI(GL_NORMAL_ARRAY, 3, GL_FLOAT, vb.VertexSize, vb.VertexObjectId, (ptrdiff_t) vb.ValuePtr[CVertexBuffer::Normal]); } else { diff --git a/code/nel/src/3d/nelu.cpp b/code/nel/src/3d/nelu.cpp index 80ef89ec4..3d143bce1 100644 --- a/code/nel/src/3d/nelu.cpp +++ b/code/nel/src/3d/nelu.cpp @@ -58,7 +58,7 @@ bool CNELU::initDriver (uint w, uint h, uint bpp, bool windowed, nlWindow syst CNELU::Driver = NULL; // Init driver. -#if defined(NL_OS_WINDOWS) +#ifdef NL_OS_WINDOWS if (direct3d) { CNELU::Driver= CDRU::createD3DDriver(); @@ -75,6 +75,7 @@ bool CNELU::initDriver (uint w, uint h, uint bpp, bool windowed, nlWindow syst nlwarning ("CNELU::initDriver: no driver found"); return false; } + if (!CNELU::Driver->init()) { nlwarning ("CNELU::initDriver: init() failed"); diff --git a/code/nel/src/misc/events.cpp b/code/nel/src/misc/events.cpp index 4d3979416..4d0f996d5 100644 --- a/code/nel/src/misc/events.cpp +++ b/code/nel/src/misc/events.cpp @@ -179,7 +179,7 @@ static const CStringConversion::CPair stringTable [] = { "KeyNONAME", KeyNONAME }, { "KeyPA1", KeyPA1 }, { "KeyOEM_CLEAR", KeyOEM_CLEAR }, -}; +} static CStringConversion KeyConversion(stringTable, sizeof(stringTable) / sizeof(stringTable[0]), KeyCount); From 87e6c19981fb8e65b99ca29ebea4ab73711af558 Mon Sep 17 00:00:00 2001 From: kervala Date: Mon, 27 Feb 2012 15:04:33 +0100 Subject: [PATCH 07/16] Changed: #1433 Merge changes from patch 1.13 --- code/ryzom/common/src/game_share/bot_chat_types.h | 2 ++ code/ryzom/common/src/game_share/entity_types.h | 2 +- code/ryzom/common/src/game_share/item_infos.cpp | 2 ++ code/ryzom/common/src/game_share/item_infos.h | 1 + .../common/src/game_share/persistent_data_template.h | 12 ++++++++---- code/ryzom/common/src/game_share/pvp_mode.cpp | 2 ++ code/ryzom/common/src/game_share/pvp_mode.h | 4 +++- .../common/src/game_share/ryzom_mirror_properties.h | 2 +- code/ryzom/common/src/game_share/send_chat.h | 2 +- 9 files changed, 21 insertions(+), 8 deletions(-) diff --git a/code/ryzom/common/src/game_share/bot_chat_types.h b/code/ryzom/common/src/game_share/bot_chat_types.h index 779bc8ba3..19982f106 100644 --- a/code/ryzom/common/src/game_share/bot_chat_types.h +++ b/code/ryzom/common/src/game_share/bot_chat_types.h @@ -82,6 +82,8 @@ namespace BOTCHATTYPE ResaleKOBroken, // this item can't be sold because its Resold time has expired ResaleKONoTimeLeft, + // this item can't be sold because the owner has locked it (temporary hack to get around modifying database.xml) + ResaleKOLockedByOwner, NumBotChatResaleFlag }; diff --git a/code/ryzom/common/src/game_share/entity_types.h b/code/ryzom/common/src/game_share/entity_types.h index 3841f9a17..68b42e954 100644 --- a/code/ryzom/common/src/game_share/entity_types.h +++ b/code/ryzom/common/src/game_share/entity_types.h @@ -130,7 +130,7 @@ const TCoord THRESHOLD_BEHAVIOUR = 60000; // Name const TPropIndex PROPERTY_NAME_STRING_ID = 6; -const TCoord THRESHOLD_NAME_STRING_ID = 25000; +const TCoord THRESHOLD_NAME_STRING_ID = 100000; // Main target const TPropIndex PROPERTY_TARGET_ID = 7; diff --git a/code/ryzom/common/src/game_share/item_infos.cpp b/code/ryzom/common/src/game_share/item_infos.cpp index a968ff8a4..af84c5d6c 100644 --- a/code/ryzom/common/src/game_share/item_infos.cpp +++ b/code/ryzom/common/src/game_share/item_infos.cpp @@ -73,6 +73,7 @@ CItemInfos::CItemInfos() LacustreMagicResistance = 0; JungleMagicResistance = 0; PrimaryRootMagicResistance = 0; + PetNumber = 0; // 1 based! } void CItemInfos::serial(NLMISC::IStream & s) @@ -130,5 +131,6 @@ void CItemInfos::serial(NLMISC::IStream & s) s.serial( CustomText ); s.serial( R2ItemDescription ); s.serial( R2ItemComment ); + s.serial( PetNumber ); } diff --git a/code/ryzom/common/src/game_share/item_infos.h b/code/ryzom/common/src/game_share/item_infos.h index ff34bfddc..3fd94444e 100644 --- a/code/ryzom/common/src/game_share/item_infos.h +++ b/code/ryzom/common/src/game_share/item_infos.h @@ -139,6 +139,7 @@ public: ucstring CustomText; ucstring R2ItemDescription; ucstring R2ItemComment; + uint8 PetNumber; // 1 based pet index //@} }; diff --git a/code/ryzom/common/src/game_share/persistent_data_template.h b/code/ryzom/common/src/game_share/persistent_data_template.h index ef76101cd..08211687a 100644 --- a/code/ryzom/common/src/game_share/persistent_data_template.h +++ b/code/ryzom/common/src/game_share/persistent_data_template.h @@ -176,16 +176,20 @@ inline uint32 saveGameCycleToSecond(NLMISC::TGameCycle tick) { // Evaluate the UTC of this event (with the current date of save). Suppose that 1 second==10 tick - return sint32(NLMISC::CTime::getSecondsSince1970()) + (sint32(tick) - sint32(CTickEventHandler::getGameCycle()))/10; + if (tick < CTickEventHandler::getGameCycle()) + return NLMISC::CTime::getSecondsSince1970(); + else + return NLMISC::CTime::getSecondsSince1970() + (tick - CTickEventHandler::getGameCycle())/10; // NB: result should be positive since no event should have been launched before 1970! } inline NLMISC::TGameCycle loadSecondToGameCycle(uint32 second) { + if (second < NLMISC::CTime::getSecondsSince1970()) + return 0; + // Convert UTC of the event to game cycle. Suppose that 1 second==10 tick - sint32 newTick= CTickEventHandler::getGameCycle() + (sint32(second) - sint32(NLMISC::CTime::getSecondsSince1970()))*10; - // If game cycle is loaded on a server where current game cycle is too young, we can have here negative values => avoid them - return std::max(newTick, sint32(0)); + return CTickEventHandler::getGameCycle() + (second - NLMISC::CTime::getSecondsSince1970())*10; } #endif diff --git a/code/ryzom/common/src/game_share/pvp_mode.cpp b/code/ryzom/common/src/game_share/pvp_mode.cpp index aa3ac1496..3e13fd428 100644 --- a/code/ryzom/common/src/game_share/pvp_mode.cpp +++ b/code/ryzom/common/src/game_share/pvp_mode.cpp @@ -35,6 +35,8 @@ namespace PVP_MODE NL_STRING_CONVERSION_TABLE_ENTRY(PvpZoneOutpost) NL_STRING_CONVERSION_TABLE_ENTRY(PvpFaction) NL_STRING_CONVERSION_TABLE_ENTRY(PvpFactionFlagged) + NL_STRING_CONVERSION_TABLE_ENTRY(PvpZoneSafe) + NL_STRING_CONVERSION_TABLE_ENTRY(PvpSafe) NL_END_STRING_CONVERSION_TABLE(TPVPMode, PVPModeConversion, Unknown) TPVPMode fromString(const std::string & str) diff --git a/code/ryzom/common/src/game_share/pvp_mode.h b/code/ryzom/common/src/game_share/pvp_mode.h index dd52f1fd6..0e654752f 100644 --- a/code/ryzom/common/src/game_share/pvp_mode.h +++ b/code/ryzom/common/src/game_share/pvp_mode.h @@ -32,10 +32,12 @@ namespace PVP_MODE PvpZoneOutpost = 32, PvpFaction = 64, PvpFactionFlagged = 128, + PvpZoneSafe = 256, + PvpSafe = 512, Unknown, NbModes = Unknown, - NbBits = 8 // number of bits needed to store all valid values + NbBits = 10 // number of bits needed to store all valid values }; diff --git a/code/ryzom/common/src/game_share/ryzom_mirror_properties.h b/code/ryzom/common/src/game_share/ryzom_mirror_properties.h index 0aab0b870..afd0ac892 100644 --- a/code/ryzom/common/src/game_share/ryzom_mirror_properties.h +++ b/code/ryzom/common/src/game_share/ryzom_mirror_properties.h @@ -138,7 +138,7 @@ void initRyzomVisualPropertyIndices( CMirroredDataSet& dataset ); #define TYPE_BOT_TRADE_SELECTOR2 uint64 #define TYPE_EVENT_FACTION_ID uint32 -#define TYPE_PVP_MODE uint8 +#define TYPE_PVP_MODE uint32 #define TYPE_PVP_CLAN uint32 #define TYPE_FUEL bool diff --git a/code/ryzom/common/src/game_share/send_chat.h b/code/ryzom/common/src/game_share/send_chat.h index cefb8bba0..1efa7acee 100644 --- a/code/ryzom/common/src/game_share/send_chat.h +++ b/code/ryzom/common/src/game_share/send_chat.h @@ -115,7 +115,7 @@ inline void npcChatToChannelEx(const TDataSetRow &senderId, CChatGroup::TGroupTy * Chat group can be constructed from CChatGroup class. * sentence is the sentence to be sent. */ -inline void npcChatToChannelSentence(const TDataSetRow &senderId, CChatGroup::TGroupType groupType, std::string& sentence) +inline void npcChatToChannelSentence(const TDataSetRow &senderId, CChatGroup::TGroupType groupType, ucstring& sentence) { NLNET::CMessage msgout("NPC_CHAT_SENTENCE"); msgout.serial(const_cast(senderId)); From 232493249100e7bdd53db6c18c85f1e7007dcae4 Mon Sep 17 00:00:00 2001 From: kervala Date: Mon, 27 Feb 2012 15:19:53 +0100 Subject: [PATCH 08/16] Changed: Support for Debian/Ubuntu multiarch (use -DCMAKE_LIBRARY_ARCHITECTURE=) --- code/CMakeModules/nel.cmake | 98 +++++++++++++++++++++++++++++-------- 1 file changed, 77 insertions(+), 21 deletions(-) diff --git a/code/CMakeModules/nel.cmake b/code/CMakeModules/nel.cmake index eb2bc24ac..9314a7a85 100644 --- a/code/CMakeModules/nel.cmake +++ b/code/CMakeModules/nel.cmake @@ -304,27 +304,66 @@ MACRO(NL_SETUP_BUILD) ENDIF(CMAKE_BUILD_TYPE MATCHES "Release") ENDIF(CMAKE_BUILD_TYPE MATCHES "Debug") + SET(HOST_CPU ${CMAKE_SYSTEM_PROCESSOR}) + # Determine target CPU -# IF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86") - IF(NOT CMAKE_SIZEOF_VOID_P) - INCLUDE (CheckTypeSize) - CHECK_TYPE_SIZE("void*" CMAKE_SIZEOF_VOID_P) - ENDIF(NOT CMAKE_SIZEOF_VOID_P) + IF(NOT TARGET_CPU) + SET(TARGET_CPU $ENV{DEB_HOST_GNU_CPU}) + ENDIF(NOT TARGET_CPU) - # Using 32 or 64 bits libraries + # If not specified, use the same CPU as host + IF(NOT TARGET_CPU) + SET(TARGET_CPU ${CMAKE_SYSTEM_PROCESSOR}) + ENDIF(NOT TARGET_CPU) + + IF(TARGET_CPU MATCHES "amd64") + SET(TARGET_CPU "x86_64") + ELSEIF(TARGET_CPU MATCHES "i.86") + SET(TARGET_CPU "x86") + ENDIF(TARGET_CPU MATCHES "amd64") + + # DEB_HOST_ARCH_ENDIAN is 'little' or 'big' + # DEB_HOST_ARCH_BITS is '32' or '64' + + # If target and host CPU are the same + IF("${HOST_CPU}" STREQUAL "${TARGET_CPU}") + # x86-compatible CPU + IF(HOST_CPU MATCHES "x86") + IF(NOT CMAKE_SIZEOF_VOID_P) + INCLUDE (CheckTypeSize) + CHECK_TYPE_SIZE("void*" CMAKE_SIZEOF_VOID_P) + ENDIF(NOT CMAKE_SIZEOF_VOID_P) + + # Using 32 or 64 bits libraries + IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + SET(TARGET_CPU "x86_64") + ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8) + SET(TARGET_CPU "x86") + ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8) + ENDIF(HOST_CPU MATCHES "x86") + # TODO: add checks for ARM and PPC + ELSE("${HOST_CPU}" STREQUAL "${TARGET_CPU}") + MESSAGE(STATUS "Compiling on ${HOST_CPU} for ${TARGET_CPU}") + ENDIF("${HOST_CPU}" STREQUAL "${TARGET_CPU}") + + IF(TARGET_CPU STREQUAL "x86_64") + SET(TARGET_X64 1) + SET(PLATFORM_CFLAGS "-DHAVE_X86_64") + ELSEIF(TARGET_CPU STREQUAL "x86") SET(TARGET_X86 1) - IF(CMAKE_SIZEOF_VOID_P EQUAL 8) - SET(ARCH "x86_64") - SET(TARGET_X64 1) - ADD_DEFINITIONS(-DHAVE_X86_64) - ELSE(CMAKE_SIZEOF_VOID_P EQUAL 8) - SET(ARCH "x86") - ADD_DEFINITIONS(-DHAVE_X86) - ENDIF(CMAKE_SIZEOF_VOID_P EQUAL 8) -# ADD_DEFINITIONS(-DHAVE_IA64) -# ENDIF(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86") + SET(PLATFORM_CFLAGS "-DHAVE_X86") + ENDIF(TARGET_CPU STREQUAL "x86_64") - IF(WIN32) + # Fix library paths suffixes for Debian MultiArch + IF(NOT CMAKE_LIBRARY_ARCHITECTURE) + SET(CMAKE_LIBRARY_ARCHITECTURE $ENV{DEB_HOST_MULTIARCH}) + ENDIF(NOT CMAKE_LIBRARY_ARCHITECTURE) + + IF(CMAKE_LIBRARY_ARCHITECTURE) + SET(CMAKE_LIBRARY_PATH "/lib/${CMAKE_LIBRARY_ARCHITECTURE};/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE};${CMAKE_LIBRARY_PATH}") + ENDIF(CMAKE_LIBRARY_ARCHITECTURE) + + IF(MSVC) IF(MSVC10) # /Ox is working with VC++ 2010, but custom optimizations don't exist SET(SPEED_OPTIMIZATIONS "/Ox /GF /GS-") @@ -367,7 +406,16 @@ MACRO(NL_SETUP_BUILD) SET(NL_DEBUG_LINKFLAGS "/NODEFAULTLIB:msvcrt /INCREMENTAL:YES") SET(NL_RELEASE_LINKFLAGS "/OPT:REF /OPT:ICF /INCREMENTAL:NO") ELSE(WIN32) - SET(PLATFORM_CFLAGS "-g -pipe -ftemplate-depth-48 -D_REENTRANT -Wall -ansi -W -Wpointer-arith -Wsign-compare -Wno-deprecated-declarations -Wno-multichar -Wno-unused -fno-strict-aliasing") + IF(HOST_CPU STREQUAL "x86_64" AND TARGET_CPU STREQUAL "x86") + SET(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -m32 -march=i686") + ENDIF(HOST_CPU STREQUAL "x86_64" AND TARGET_CPU STREQUAL "x86") + + IF(HOST_CPU STREQUAL "x86" AND TARGET_CPU STREQUAL "x86_64") + SET(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -m64") + ENDIF(HOST_CPU STREQUAL "x86" AND TARGET_CPU STREQUAL "x86_64") + + SET(PLATFORM_CFLAGS "{PLATFORM_CFLAGS} -g -D_REENTRANT -pipe -ftemplate-depth-48 -Wall -ansi -W -Wpointer-arith -Wsign-compare -Wno-deprecated-declarations -Wno-multichar -Wno-unused -fno-strict-aliasing") + IF(WITH_COVERAGE) SET(PLATFORM_CFLAGS "-fprofile-arcs -ftest-coverage ${PLATFORM_CFLAGS}") ENDIF(WITH_COVERAGE) @@ -384,7 +432,7 @@ MACRO(NL_SETUP_BUILD) SET(PLATFORM_CXXFLAGS ${PLATFORM_CFLAGS}) IF(NOT APPLE) - SET(PLATFORM_LINKFLAGS "-Wl,--no-undefined -Wl,--as-needed") + SET(PLATFORM_LINKFLAGS "${PLATFORM_LINKFLAGS} -Wl,--no-undefined -Wl,--as-needed") ENDIF(NOT APPLE) SET(NL_DEBUG_CFLAGS "-DNL_DEBUG -D_DEBUG") @@ -453,7 +501,11 @@ MACRO(NL_SETUP_PREFIX_PATHS) IF(WIN32) SET(NL_LIB_PREFIX "../lib" CACHE PATH "Installation path for libraries.") ELSE(WIN32) - SET(NL_LIB_PREFIX "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation path for libraries.") + IF(CMAKE_LIBRARY_ARCHITECTURE) + SET(NL_LIB_PREFIX "${CMAKE_INSTALL_PREFIX}/lib/${CMAKE_LIBRARY_ARCHITECTURE}" CACHE PATH "Installation path for libraries.") + ELSE(CMAKE_LIBRARY_ARCHITECTURE) + SET(NL_LIB_PREFIX "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation path for libraries.") + ENDIF(CMAKE_LIBRARY_ARCHITECTURE) ENDIF(WIN32) ENDIF(NOT NL_LIB_PREFIX) @@ -462,7 +514,11 @@ MACRO(NL_SETUP_PREFIX_PATHS) IF(WIN32) SET(NL_DRIVER_PREFIX "../lib" CACHE PATH "Installation path for drivers.") ELSE(WIN32) - SET(NL_DRIVER_PREFIX "${CMAKE_INSTALL_PREFIX}/lib/nel" CACHE PATH "Installation path for drivers.") + IF(CMAKE_LIBRARY_ARCHITECTURE) + SET(NL_DRIVER_PREFIX "${CMAKE_INSTALL_PREFIX}/lib/${CMAKE_LIBRARY_ARCHITECTURE}/nel" CACHE PATH "Installation path for drivers.") + ELSE(CMAKE_LIBRARY_ARCHITECTURE) + SET(NL_DRIVER_PREFIX "${CMAKE_INSTALL_PREFIX}/lib/nel" CACHE PATH "Installation path for drivers.") + ENDIF(CMAKE_LIBRARY_ARCHITECTURE) ENDIF(WIN32) ENDIF(NOT NL_DRIVER_PREFIX) From a272d956c242b6b74f645020fbeb5231fccc780f Mon Sep 17 00:00:00 2001 From: kervala Date: Mon, 27 Feb 2012 16:10:47 +0100 Subject: [PATCH 09/16] Changed: #1433 Merge changes from patch 1.13 --- code/ryzom/client/src/character_cl.cpp | 89 ++-- code/ryzom/client/src/character_cl.h | 55 +- code/ryzom/client/src/client.cpp | 15 +- code/ryzom/client/src/client_cfg.cpp | 8 +- code/ryzom/client/src/client_cfg.h | 4 +- code/ryzom/client/src/client_chat_manager.cpp | 59 +-- code/ryzom/client/src/commands.cpp | 39 +- code/ryzom/client/src/connection.cpp | 35 +- code/ryzom/client/src/cursor_functions.cpp | 3 + code/ryzom/client/src/entity_cl.cpp | 76 ++- code/ryzom/client/src/entity_cl.h | 27 +- .../src/interface_v3/action_handler_help.cpp | 49 +- .../src/interface_v3/action_handler_help.h | 9 + .../src/interface_v3/action_handler_item.cpp | 140 ++++- .../src/interface_v3/action_phrase_faber.cpp | 103 +++- .../src/interface_v3/action_phrase_faber.h | 5 +- .../src/interface_v3/bot_chat_page_trade.cpp | 17 +- .../client/src/interface_v3/chat_filter.cpp | 2 +- .../src/interface_v3/chat_text_manager.cpp | 27 +- .../client/src/interface_v3/chat_window.cpp | 26 +- .../src/interface_v3/ctrl_base_button.h | 2 + .../client/src/interface_v3/ctrl_button.cpp | 9 +- .../client/src/interface_v3/dbctrl_sheet.cpp | 171 +++++- .../client/src/interface_v3/dbctrl_sheet.h | 29 +- .../interface_v3/dbgroup_list_sheet_trade.cpp | 25 +- .../client/src/interface_v3/dbview_number.cpp | 28 +- .../client/src/interface_v3/group_html.cpp | 493 ++++++++++++++---- .../client/src/interface_v3/group_html.h | 46 +- .../client/src/interface_v3/group_html_cs.cpp | 14 +- .../client/src/interface_v3/group_html_cs.h | 4 +- .../src/interface_v3/group_html_forum.cpp | 11 +- .../src/interface_v3/group_html_forum.h | 4 +- .../src/interface_v3/group_html_mail.cpp | 11 +- .../client/src/interface_v3/group_html_mail.h | 4 +- .../src/interface_v3/group_html_webig.cpp | 150 +++++- .../src/interface_v3/group_html_webig.h | 30 +- .../interface_v3/group_in_scene_bubble.cpp | 126 +++++ .../src/interface_v3/group_in_scene_bubble.h | 3 + .../interface_v3/group_in_scene_user_info.cpp | 209 ++++---- .../client/src/interface_v3/group_table.cpp | 97 +++- .../client/src/interface_v3/group_table.h | 11 + .../client/src/interface_v3/guild_manager.cpp | 61 ++- .../client/src/interface_v3/interface_group.h | 18 +- .../src/interface_v3/interface_manager.cpp | 41 +- .../src/interface_v3/interface_manager.h | 1 + .../src/interface_v3/interface_parser.cpp | 22 +- .../src/interface_v3/inventory_manager.cpp | 80 ++- .../src/interface_v3/inventory_manager.h | 17 +- .../ryzom/client/src/interface_v3/lua_ihm.cpp | 404 +++++++++++++- code/ryzom/client/src/interface_v3/lua_ihm.h | 53 +- .../src/interface_v3/people_interraction.cpp | 82 ++- .../client/src/interface_v3/people_list.cpp | 28 +- .../client/src/interface_v3/player_trade.cpp | 1 + .../client/src/interface_v3/skill_manager.cpp | 2 +- .../ryzom/client/src/interface_v3/view_base.h | 4 + .../client/src/interface_v3/view_bitmap.h | 2 + .../client/src/interface_v3/view_link.cpp | 18 + .../ryzom/client/src/interface_v3/view_link.h | 3 + .../client/src/interface_v3/view_pointer.cpp | 82 ++- .../client/src/interface_v3/view_pointer.h | 1 + .../client/src/interface_v3/view_renderer.cpp | 9 +- .../client/src/interface_v3/view_renderer.h | 1 + code/ryzom/client/src/libwww.cpp | 6 +- code/ryzom/client/src/libwww.h | 5 +- code/ryzom/client/src/login.cpp | 21 +- code/ryzom/client/src/main_loop.cpp | 3 + code/ryzom/client/src/net_manager.cpp | 14 +- code/ryzom/client/src/player_cl.cpp | 189 +++---- .../client/src/string_manager_client.cpp | 41 +- code/ryzom/client/src/string_manager_client.h | 7 +- code/ryzom/client/src/user_entity.cpp | 47 +- code/ryzom/client/src/user_entity.h | 10 + 72 files changed, 2719 insertions(+), 819 deletions(-) diff --git a/code/ryzom/client/src/character_cl.cpp b/code/ryzom/client/src/character_cl.cpp index 1d7c87c2a..694ed9b16 100644 --- a/code/ryzom/client/src/character_cl.cpp +++ b/code/ryzom/client/src/character_cl.cpp @@ -358,17 +358,8 @@ CCharacterCL::CCharacterCL() _EventFactionId = 0; _PvpMode = PVP_MODE::None; - _PvpClan = PVP_CLAN::None; - - for (uint8 i = 0; i < PVP_CLAN::NbClans; i++) - { - _PvpAllies[i] = false; - _PvpEnemies[i] = false; - } - - _ClanCivMaxFame = PVP_CLAN::None; - _ClanCultMaxFame = PVP_CLAN::None; + _LeagueId = 0; _OutpostId = 0; _OutpostSide = OUTPOSTENUMS::UnknownPVPSide; @@ -1842,9 +1833,30 @@ void CCharacterCL::updateVisualPropertyGuildNameID(const NLMISC::TGameCycle &/* //----------------------------------------------- void CCharacterCL::updateVisualPropertyEventFactionID(const NLMISC::TGameCycle &/* gameCycle */, const sint64 &prop) { - _EventFactionId = uint32(prop); + // ODD Hack by Ulukyn + //_EventFactionId = uint32(prop); + _PvpMode = uint32(prop); + buildInSceneInterface(); + if (isUser()) + { + uint i; + uint numEntity = (uint)EntitiesMngr.entities().size(); + for (i=0; i(entity); + if (character) + { + if( character->getPvpMode() != 0 && !character->isUser()) + character->buildInSceneInterface (); + } + } + } + } } // updateVisualPropertyEventFactionID // //----------------------------------------------- @@ -1853,8 +1865,8 @@ void CCharacterCL::updateVisualPropertyEventFactionID(const NLMISC::TGameCycle & //----------------------------------------------- void CCharacterCL::updateVisualPropertyPvpMode(const NLMISC::TGameCycle &/* gameCycle */, const sint64 &prop) { - _PvpMode = (uint8)prop; - buildInSceneInterface(); + //_PvpMode = uint32(prop); + //buildInSceneInterface(); } // updateVisualPropertyPvpMode // @@ -1864,18 +1876,27 @@ void CCharacterCL::updateVisualPropertyPvpMode(const NLMISC::TGameCycle &/* game //----------------------------------------------- void CCharacterCL::updateVisualPropertyPvpClan(const NLMISC::TGameCycle &/* gameCycle */, const sint64 &prop) { - // get fames signs from prop - for (uint8 fameIdx = 0; fameIdx < 7; fameIdx++) - { - _PvpAllies[fameIdx] = (prop & (SINT64_CONSTANT(1) << (2*fameIdx))) != 0; - _PvpEnemies[fameIdx] = (prop & (SINT64_CONSTANT(1) << (2*fameIdx+1))) != 0; - } - - _ClanCivMaxFame = PVP_CLAN::TPVPClan((prop & (0x03 << 2*7)) >> 2*7); - _ClanCultMaxFame = PVP_CLAN::TPVPClan(4 + ((prop & (0x03 << 2*8)) >> 2*8)); - + _LeagueId = uint32(prop); buildInSceneInterface(); + if (isUser()) + { + uint i; + uint numEntity = (uint)EntitiesMngr.entities().size(); + for (i=0; i(entity); + if (character) + { + if( character->getPvpMode() != 0 && !character->isUser()) + character->buildInSceneInterface (); + } + } + } + } } // updateVisualPropertyPvpClan // //----------------------------------------------- @@ -4522,10 +4543,6 @@ void CCharacterCL::applyBehaviourFlyingHPs(const CBehaviourContext &bc, const MB else deltaHPColor = ClientCfg.SystemInfoParams["dg"].Color; } - else - { - deltaHPColor = CRGBA(127,127,127); - } } else { @@ -10252,7 +10269,7 @@ NLMISC_COMMAND(pvpMode, "modify pvp mode", "[ ]") if( args.size() == 0 ) { - uint8 pvpMode = playerTarget->getPvpMode(); + uint16 pvpMode = playerTarget->getPvpMode(); string str; if( pvpMode&PVP_MODE::PvpDuel ) str+="duel "; @@ -10270,6 +10287,10 @@ NLMISC_COMMAND(pvpMode, "modify pvp mode", "[ ]") str+="faction "; if( pvpMode&PVP_MODE::PvpFactionFlagged) str+="faction_flagged "; + if( pvpMode&PVP_MODE::PvpZoneSafe) + str+="in_safe_zone "; + if( pvpMode&PVP_MODE::PvpSafe) + str+="safe "; IM->displaySystemInfo(ucstring(str)); nlinfo(" %s",str.c_str()); } @@ -10280,14 +10301,14 @@ NLMISC_COMMAND(pvpMode, "modify pvp mode", "[ ]") fromString(args[1], state); if( state ) { - uint8 currentPVPMode = playerTarget->getPvpMode(); + uint16 currentPVPMode = playerTarget->getPvpMode(); currentPVPMode |= pvpMode; playerTarget->setPvpMode(currentPVPMode); IM->displaySystemInfo(toString(" adding pvp mode %s",args[0].c_str())); } else { - uint8 currentPVPMode = playerTarget->getPvpMode(); + uint16 currentPVPMode = playerTarget->getPvpMode(); currentPVPMode &= ~pvpMode; playerTarget->setPvpMode(currentPVPMode); IM->displaySystemInfo(toString(" removing pvp mode %s",args[0].c_str())); @@ -10297,7 +10318,7 @@ NLMISC_COMMAND(pvpMode, "modify pvp mode", "[ ]") return true; } - +/* NLMISC_COMMAND(pvpClan, "modify pvp clan", "") { if (args.size() != 1) return false; @@ -10319,13 +10340,13 @@ NLMISC_COMMAND(pvpClan, "modify pvp clan", "") if (!playerTarget) return false; - PVP_CLAN::TPVPClan clan = PVP_CLAN::fromString(args[0]); - playerTarget->setPvpClan(clan); +// PVP_CLAN::TPVPClan clan = PVP_CLAN::fromString(args[0]); +// playerTarget->setPvpClan(clan); playerTarget->buildInSceneInterface(); return true; } - +*/ #endif // !FINAL_VERSION #include "r2/editor.h" diff --git a/code/ryzom/client/src/character_cl.h b/code/ryzom/client/src/character_cl.h index a5d7ba880..6c87692d3 100644 --- a/code/ryzom/client/src/character_cl.h +++ b/code/ryzom/client/src/character_cl.h @@ -84,7 +84,7 @@ public: enum { MaxNumAura = 2 }; enum TAtkHeight { - AtkUnknownHeight = 0, + AtkUnkownHeight = 0, AtkLow, AtkMiddle, AtkHigh @@ -368,48 +368,10 @@ public: virtual uint64 getGuildSymbol () const { return _GuildSymbol; } virtual uint32 getEventFactionID() const { return _EventFactionId; } - virtual uint8 getPvpMode() const { return _PvpMode; } - void setPvpMode(uint8 mode) { _PvpMode=mode; } - virtual PVP_CLAN::TPVPClan getPvpClan() const { return _PvpClan; } - void setPvpClan(PVP_CLAN::TPVPClan clan) { _PvpClan=clan; } - - virtual PVP_CLAN::TPVPClan getClanCivMaxFame() const { return _ClanCivMaxFame; } - void setClanCivMaxFame(PVP_CLAN::TPVPClan clan) { _ClanCivMaxFame=clan; } - virtual PVP_CLAN::TPVPClan getClanCultMaxFame() const { return _ClanCultMaxFame; } - void setClanCultMaxFame(PVP_CLAN::TPVPClan clan) { _ClanCultMaxFame=clan; } - - virtual bool isPvpAlly(uint8 faction) const { if (faction < PVP_CLAN::NbClans) return _PvpAllies[faction]; else return false; } - virtual bool isPvpEnnemy(uint8 faction) const { if (faction < PVP_CLAN::NbClans) return _PvpEnemies[faction]; else return false; } - - virtual bool isPvpMarauder() const - { - for (uint8 i = 0; i < 4; i++) - if (!_PvpEnemies[i]) - return false; - return true; - } - - virtual bool isPvpTrytonist() const - { - if (_PvpEnemies[4] && _PvpEnemies[6]) - return true; - return false; - } - - virtual bool isPvpPrimas() const - { - if (_PvpAllies[4] && _PvpAllies[6]) - return true; - return false; - } - - virtual bool isPvpRanger() const - { - for (uint8 i = 0; i < 4; i++) - if (!_PvpAllies[i]) - return false; - return true; - } + virtual uint16 getPvpMode() const { return _PvpMode; } + void setPvpMode(uint16 mode) { _PvpMode=mode; } + virtual uint32 getLeagueID() const { return _LeagueId; } + void setLeagueID(uint32 league) { _LeagueId=league; } virtual uint16 getOutpostId() const { return _OutpostId; } virtual OUTPOSTENUMS::TPVPSide getOutpostSide() const { return _OutpostSide; } @@ -727,12 +689,9 @@ protected: uint32 _GuildNameId; uint64 _GuildSymbol; uint32 _EventFactionId; - uint8 _PvpMode; + uint16 _PvpMode; PVP_CLAN::TPVPClan _PvpClan; - PVP_CLAN::TPVPClan _ClanCivMaxFame; - PVP_CLAN::TPVPClan _ClanCultMaxFame; - bool _PvpAllies[PVP_CLAN::NbClans]; - bool _PvpEnemies[PVP_CLAN::NbClans]; + uint32 _LeagueId; uint16 _OutpostId; OUTPOSTENUMS::TPVPSide _OutpostSide; diff --git a/code/ryzom/client/src/client.cpp b/code/ryzom/client/src/client.cpp index 72fe1c0b1..49cc6e328 100644 --- a/code/ryzom/client/src/client.cpp +++ b/code/ryzom/client/src/client.cpp @@ -422,15 +422,12 @@ int main(int argc, char **argv) string sCmdLine = cmdline; #if FINAL_VERSION - if (sCmdLine.find("/multi") == string::npos) // If '/multi' not found - { - HANDLE mutex = CreateMutex (NULL, false, "RyzomClient"); - if (mutex && GetLastError() == ERROR_ALREADY_EXISTS) - { - delete appContext; - return 0; - } - } + //if (sCmdLine.find("/multi") == string::npos) // If '/multi' not found + //{ + // HANDLE mutex = CreateMutex (NULL, false, "RyzomClient"); + // if (mutex && GetLastError() == ERROR_ALREADY_EXISTS) + // exit (0); + //} initCrashReport (); #endif // FINAL_VERSION diff --git a/code/ryzom/client/src/client_cfg.cpp b/code/ryzom/client/src/client_cfg.cpp index ff270ad1a..54a3d9b45 100644 --- a/code/ryzom/client/src/client_cfg.cpp +++ b/code/ryzom/client/src/client_cfg.cpp @@ -424,6 +424,7 @@ CClientConfig::CClientConfig() PatchWanted = false; #endif PatchUrl = ""; + PatchletUrl = ""; PatchVersion = ""; PatchServer = ""; @@ -433,6 +434,7 @@ CClientConfig::CClientConfig() RingReleaseNotePath = "http://"+WebIgMainDomain+"/releasenotes_ring/index.php"; ReleaseNotePath = "http://"+WebIgMainDomain+"/releasenotes/index.php"; + /////////////// // ANIMATION // // With a bigger angle, rotation is animated. @@ -1044,9 +1046,13 @@ void CClientConfig::setValues() READ_STRING_DEV(ReleaseNotePath) READ_STRING_FV(PatchServer) + ///////////////////////// + // NEW PATCHLET SYSTEM // + READ_STRING_FV(PatchletUrl) + //////////////////////// // WEBIG // - READ_STRING_DEV(WebIgMainDomain); + READ_STRING_FV(WebIgMainDomain); READ_STRINGVECTOR_FV(WebIgTrustedDomains); /////////////// diff --git a/code/ryzom/client/src/client_cfg.h b/code/ryzom/client/src/client_cfg.h index 667606814..86e70c1b8 100644 --- a/code/ryzom/client/src/client_cfg.h +++ b/code/ryzom/client/src/client_cfg.h @@ -286,17 +286,17 @@ struct CClientConfig // NEW PATCHING SYSTEM // bool PatchWanted; std::string PatchUrl; + std::string PatchletUrl; std::string PatchVersion; std::string PatchServer; std::string RingReleaseNotePath; std::string ReleaseNotePath; - //////////////////////// - // WEBIG // std::string WebIgMainDomain; std::vector WebIgTrustedDomains; + /////////////// // ANIMATION // // With a bigger angle, rotation is animated. diff --git a/code/ryzom/client/src/client_chat_manager.cpp b/code/ryzom/client/src/client_chat_manager.cpp index fa4159b1f..e7ef54d02 100644 --- a/code/ryzom/client/src/client_chat_manager.cpp +++ b/code/ryzom/client/src/client_chat_manager.cpp @@ -963,16 +963,10 @@ void CClientChatManager::buildTellSentence(const ucstring &sender, const ucstrin else { // Does the char have a CSR title? - if (CHARACTER_TITLE::isCsrTitle(CEntityCL::getTitleFromName(sender))) csr = ucstring("(CSR) "); + csr = CHARACTER_TITLE::isCsrTitle(CEntityCL::getTitleFromName(sender)) ? ucstring("(CSR) ") : ucstring(""); } - ucstring cur_time; - CCDBNodeLeaf *pNL = CInterfaceManager::getInstance()->getDbProp("UI:SAVE:CHAT:SHOW_TIMES_IN_CHAT_CB", false); - if (pNL && pNL->getValueBool()) - { - cur_time = CInterfaceManager::getTimestampHuman(); - } - result = cur_time + csr + name + ucstring(" ") + CI18N::get("tellsYou") + ucstring(": ") + msg; + result = csr + name + ucstring(" ") + CI18N::get("tellsYou") + ucstring(": ") + msg; } } @@ -1002,23 +996,18 @@ void CClientChatManager::buildChatSentence(TDataSetIndex /* compressedSenderInde if (!catStr.empty()) cat = string("&")+catStr+"&"; + if ( ! cat.empty()) + { + result = msg; + return; + } + // Format the sentence with the provided sender name ucstring senderName = CEntityCL::removeTitleAndShardFromName(sender); - // Add time if not a &bbl& - ucstring cur_time; - if (cat.toString() != "&bbl&") - { - CCDBNodeLeaf *pNL = CInterfaceManager::getInstance()->getDbProp("UI:SAVE:CHAT:SHOW_TIMES_IN_CHAT_CB", false); - if (pNL && pNL->getValueBool()) - { - cur_time = CInterfaceManager::getTimestampHuman(); - } - } - ucstring csr; // Does the char have a CSR title? - if (CHARACTER_TITLE::isCsrTitle(CEntityCL::getTitleFromName(sender))) csr = ucstring("(CSR) "); + csr = CHARACTER_TITLE::isCsrTitle(CEntityCL::getTitleFromName(sender)) ? ucstring("(CSR) ") : ucstring(""); if (UserEntity && senderName == UserEntity->getDisplayName()) { @@ -1026,10 +1015,10 @@ void CClientChatManager::buildChatSentence(TDataSetIndex /* compressedSenderInde switch(type) { case CChatGroup::shout: - result = cat + cur_time + csr + CI18N::get("youShout") + ucstring(": ") + finalMsg; + result = cat + csr + CI18N::get("youShout") + ucstring(": ") + finalMsg; break; default: - result = cat + cur_time + csr + CI18N::get("youSay") + ucstring(": ") + finalMsg; + result = cat + csr + CI18N::get("youSay") + ucstring(": ") + finalMsg; break; } } @@ -1048,10 +1037,10 @@ void CClientChatManager::buildChatSentence(TDataSetIndex /* compressedSenderInde switch(type) { case CChatGroup::shout: - result = cat + cur_time + csr + senderName + ucstring(" ") + CI18N::get("heShout") + ucstring(": ") + finalMsg; + result = cat + csr + senderName + ucstring(" ") + CI18N::get("heShout") + ucstring(": ") + finalMsg; break; default: - result = cat + cur_time + csr + senderName + ucstring(" ") + CI18N::get("heSays") + ucstring(": ") + finalMsg; + result = cat + csr + senderName + ucstring(" ") + CI18N::get("heSays") + ucstring(": ") + finalMsg; break; } } @@ -1185,14 +1174,8 @@ class CHandlerTell : public IActionHandler ucstring finalMsg; CChatWindow::encodeColorTag(prop.getRGBA(), finalMsg, false); - ucstring cur_time; - CCDBNodeLeaf *pNL = CInterfaceManager::getInstance()->getDbProp("UI:SAVE:CHAT:SHOW_TIMES_IN_CHAT_CB", false); - if (pNL && pNL->getValueBool()) - cur_time = CInterfaceManager::getTimestampHuman(); - - ucstring csr; - if (CHARACTER_TITLE::isCsrTitle(UserEntity->getTitleRaw())) csr += ucstring("(CSR) "); - finalMsg += cur_time + csr + CI18N::get("youTell") + ": "; + ucstring csr = CHARACTER_TITLE::isCsrTitle(UserEntity->getTitleRaw()) ? "(CSR) " : ""; + finalMsg += csr + CI18N::get("youTell") + ": "; prop.readRGBA("UI:SAVE:CHAT:COLORS:TELL"," "); CChatWindow::encodeColorTag(prop.getRGBA(), finalMsg, true); finalMsg += message; @@ -1351,8 +1334,18 @@ class CHandlerTalk : public IActionHandler { string str = text.toUtf8(); string cmdWithArgs = str.substr(1); - /* In the chat context, only ' ' is a possible separator */ + + // Get the command name from the string, can contain spaces string cmd = cmdWithArgs.substr(0, cmdWithArgs.find(' ')); + if (cmdWithArgs.find('"') == 0) + { + string::size_type pos = cmdWithArgs.find('"', 1); + if (string::npos != pos) + { + cmd = cmdWithArgs.substr(1, pos - 1); + } + } + if ( NLMISC::ICommand::exists( cmd ) ) { NLMISC::ICommand::execute( cmdWithArgs, g_log ); diff --git a/code/ryzom/client/src/commands.cpp b/code/ryzom/client/src/commands.cpp index 877f80429..f62d8f245 100644 --- a/code/ryzom/client/src/commands.cpp +++ b/code/ryzom/client/src/commands.cpp @@ -192,7 +192,7 @@ NLMISC_COMMAND(where, "Ask information on the position", "") return false; } -NLMISC_COMMAND(who, "Display all players currently in game","[]") +NLMISC_COMMAND(who, "Display all players currently in region","[]") { // Check parameters. if(args.size() > 1) @@ -1177,7 +1177,7 @@ NLMISC_COMMAND(db, "Modify Database"," ") if(node) node->setValue64(value); else - pIM->displaySystemInfo(toString("DB %s don't exist.", args[0].c_str())); + pIM->displaySystemInfo(toString("DB '%s' does not exist.", args[0].c_str())); #else pIM->displaySystemInfo(ucstring("Can't write to DB when in Final Version.")); #endif @@ -1193,7 +1193,7 @@ NLMISC_COMMAND(db, "Modify Database"," ") nlinfo("%s", str.c_str()); } else - pIM->displaySystemInfo(toString("DB %s don't exist.", args[0].c_str())); + pIM->displaySystemInfo(toString("DB '%s' does not exist.", args[0].c_str())); return true; } else @@ -1295,6 +1295,24 @@ NLMISC_COMMAND(setItemName, "set name of items, sbrick, etc.."," ") +{ + if (args.size() < 2) return false; + ucstring name; + name.fromUtf8(args[0]); + ucstring text; + text.fromUtf8(args[1]); + + STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance(); + if (pSMC) + pSMC->replaceDynString(name, text); + else + return false; + return true; +} + + + ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// @@ -5243,7 +5261,7 @@ bool CUserCommand::execute(const std::string &/* rawCommandString */, const std: { if ((uint)index >= args.size()) { - // Not enough argument + // Not enough arguments pIM->displaySystemInfo (ucstring(CommandName+" : ")+CI18N::get ("uiCommandWrongArgumentCount")); return false; } @@ -5253,11 +5271,18 @@ bool CUserCommand::execute(const std::string &/* rawCommandString */, const std: finalArgs += /*ucstring(*/args[index++]/*).toUtf8()*/; else { - finalArgs += /*ucstring(*/args[index++]/*).toUtf8()*/; while (index 0) ? " " : ""; + // If arg contains spaces then put it in quotes + if (string::npos != args[index].find(" ")) + { + finalArgs += "\"" + args[index++] + "\""; + } + else + { + finalArgs += args[index++]; + } } } } diff --git a/code/ryzom/client/src/connection.cpp b/code/ryzom/client/src/connection.cpp index 1750d253b..32962cd93 100644 --- a/code/ryzom/client/src/connection.cpp +++ b/code/ryzom/client/src/connection.cpp @@ -244,20 +244,20 @@ class CAHOnReloadTestPage: public IActionHandler REGISTER_ACTION_HANDLER (CAHOnReloadTestPage, "on_reload_test_page"); -//void initWebBrowser() -//{ -// CInterfaceManager *pIM = CInterfaceManager::getInstance(); -// pIM->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_WEBSTART); -// -// // start the browser -// CGroupHTML *pGH = dynamic_cast(pIM->getElementFromId(GROUP_BROWSER)); -// -// if (pGH) -// { -// pGH->setActive(true); -// pGH->browse(MainPageURL.c_str()); -// } -//} +void initWebBrowser() +{ + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + //pIM->getDbProp("UI:VARIABLES:SCREEN")->setValue32(UI_VARIABLES_SCREEN_WEBSTART); + + // start the browser + CGroupHTML *pGH = dynamic_cast(pIM->getElementFromId(GROUP_BROWSER)); + + if (pGH) + { + pGH->setActive(true); + pGH->browse(ClientCfg.PatchletUrl.c_str()); + } +} // ------------------------------------------------------------------------------------------------ @@ -392,9 +392,6 @@ bool connection (const string &cookie, const string &fsaddr) pIM->getDbProp ("UI:CURRENT_SCREEN")->setValue32(ClientCfg.Local ? 6 : -1); // TMP TMP CCDBNodeBranch::flushObserversCalls(); - // Init web box - //initWebBrowser(); - // Active inputs Actions.enable(true); EditActions.enable(true); @@ -422,6 +419,10 @@ bool connection (const string &cookie, const string &fsaddr) nlinfo ("PROFILE: %d seconds for connection", (uint32)(ryzomGetLocalTime ()-connStart)/1000); + // Init web box + nlinfo("ok"); + initWebBrowser(); + // TMP TMP if (ClientCfg.Local) { diff --git a/code/ryzom/client/src/cursor_functions.cpp b/code/ryzom/client/src/cursor_functions.cpp index c212dbb0d..2ced655c9 100644 --- a/code/ryzom/client/src/cursor_functions.cpp +++ b/code/ryzom/client/src/cursor_functions.cpp @@ -484,6 +484,9 @@ void checkUnderCursor() if(ContextCur.context("ATTACK")) return; } + + if(testMissionOption(0)) + return; } // Dead else diff --git a/code/ryzom/client/src/entity_cl.cpp b/code/ryzom/client/src/entity_cl.cpp index fbbe0c041..421faad47 100644 --- a/code/ryzom/client/src/entity_cl.cpp +++ b/code/ryzom/client/src/entity_cl.cpp @@ -115,7 +115,7 @@ NLMISC::CRGBA CEntityCL::_UserPackAnimalColor; NLMISC::CRGBA CEntityCL::_PvpEnemyColor; NLMISC::CRGBA CEntityCL::_PvpNeutralColor; NLMISC::CRGBA CEntityCL::_PvpAllyInTeamColor; -NLMISC::CRGBA CEntityCL::_PvpAllyInGuildColor; +NLMISC::CRGBA CEntityCL::_PvpAllyInLeagueColor; NLMISC::CRGBA CEntityCL::_PvpAllyColor; NLMISC::CRGBA CEntityCL::_GMTitleColor[CHARACTER_TITLE::EndGmTitle - CHARACTER_TITLE::BeginGmTitle + 1]; uint8 CEntityCL::_InvalidGMTitleCode = 0xFF; @@ -2295,6 +2295,7 @@ void CEntityCL::onStringAvailable(uint /* stringId */, const ucstring &value) womenTitle = true; } const ucstring replacement(STRING_MANAGER::CStringManagerClient::getTitleLocalizedName(_TitleRaw,womenTitle)); + _Tags = STRING_MANAGER::CStringManagerClient::getTitleInfos(_TitleRaw,womenTitle); if (!replacement.empty() || !ClientCfg.DebugStringManager) { // build the final name @@ -2436,7 +2437,6 @@ public: CEntityCL::_PvpEnemyColor = pIM->getDbProp("UI:SAVE:ENTITY:COLORS:PVPENEMY")->getValueRGBA(); CEntityCL::_PvpAllyColor = pIM->getDbProp("UI:SAVE:ENTITY:COLORS:PVPALLY")->getValueRGBA(); CEntityCL::_PvpAllyInTeamColor = pIM->getDbProp("UI:SAVE:ENTITY:COLORS:PVPALLYINTEAM")->getValueRGBA(); - CEntityCL::_PvpAllyInGuildColor = pIM->getDbProp("UI:SAVE:ENTITY:COLORS:PVPALLYINGUILD")->getValueRGBA(); CEntityCL::_PvpNeutralColor = pIM->getDbProp("UI:SAVE:ENTITY:COLORS:PVPNEUTRAL")->getValueRGBA(); // don't save these colors in .icfg because players can't change them @@ -2463,7 +2463,7 @@ bool CEntityCL::isTarget () const //----------------------------------------------- -bool CEntityCL::isInGuild () const +bool CEntityCL::isInSameGuild () const { if (Type != Player && Type != User) return false; @@ -2477,6 +2477,33 @@ bool CEntityCL::isInGuild () const //----------------------------------------------- +bool CEntityCL::oneInLeague () const +{ + if (Type != Player && Type != User) + return false; + + const uint32 leagueID = getLeagueID(); + if ((UserEntity && (UserEntity->getLeagueID() != 0)) || leagueID != 0) + return true; + + return false; +} + +//----------------------------------------------- + +bool CEntityCL::isInSameLeague () const +{ + if (Type != Player && Type != User) + return false; + + const uint32 leagueID = getLeagueID(); + if ((leagueID != 0) && UserEntity && (leagueID == UserEntity->getLeagueID())) + return true; + + return false; +} +//----------------------------------------------- + NLMISC::CRGBA CEntityCL::getColor () const { // target @@ -2511,46 +2538,43 @@ NLMISC::CRGBA CEntityCL::getColor () const { if (isEnemy()) { - if (getPvpMode()&PVP_MODE::PvpFactionFlagged || getPvpMode()&PVP_MODE::PvpChallenge) - return _PvpEnemyColor; + if (getPvpMode()&PVP_MODE::PvpFaction) + return CRGBA::CRGBA(min(255, _PvpEnemyColor.R+150), min(255, _PvpEnemyColor.G+150), min(255, _PvpEnemyColor.B+150),_PvpEnemyColor.A); else - return CRGBA(min(255, _PvpEnemyColor.R+150), min(255, _PvpEnemyColor.G+150), min(255, _PvpEnemyColor.B+150),_PvpEnemyColor.A); + return _PvpEnemyColor; } } - // neutral pvp - if (isNeutralPVP()) - { - if (isInTeam()) - return _PvpAllyInTeamColor; - if (isInGuild()) - return _PvpAllyInGuildColor; - return _PvpNeutralColor; - } // ally if (isAlly()) { if (getPvpMode() & PVP_MODE::PvpFactionFlagged) { - if (isInTeam()) - return _PvpAllyInTeamColor; - if(isInGuild()) - return _PvpAllyInGuildColor; - return _PvpAllyColor; + if(isInSameLeague()) + return CRGBA::CRGBA(max(0, _PvpAllyColor.R-100), max(0, _PvpAllyColor.G-100), max(0, _PvpAllyColor.B-100),_PvpAllyColor.A); + return CRGBA::CRGBA(max(0, _PvpAllyInTeamColor.R-100), max(0, _PvpAllyInTeamColor.G-100), max(0, _PvpAllyInTeamColor.B-100),_PvpAllyInTeamColor.A); } else { - if (isInTeam()) - return CRGBA(min(255, _PvpAllyInTeamColor.R+150), min(255, _PvpAllyInTeamColor.G+150), min(255, _PvpAllyInTeamColor.B+150),_PvpAllyInTeamColor.A); - if(isInGuild()) - return CRGBA(min(255, _PvpAllyInGuildColor.R+150), min(255, _PvpAllyInGuildColor.G+150), min(255, _PvpAllyInGuildColor.B+150),_PvpAllyInGuildColor.A); - return CRGBA(min(255, _PvpAllyColor.R+150), min(255, _PvpAllyColor.G+150), min(255, _PvpAllyColor.B+150),_PvpAllyColor.A); + if(isInSameLeague()) + return _PvpAllyColor; + return _PvpAllyInTeamColor; } } + + // neutral pvp + if (isNeutralPVP()) + return _PvpNeutralColor; + // neutral if (isInTeam()) return _GroupColor; - if (isInGuild()) + + // neutral + if (isInSameLeague()) + return CRGBA::CRGBA(min(255, _GroupColor.R+50), min(255, _GroupColor.G+50), min(255, _GroupColor.B+50),_GroupColor.A); + + if (isInSameGuild()) return _GuildColor; } return _EntitiesColor[Type]; diff --git a/code/ryzom/client/src/entity_cl.h b/code/ryzom/client/src/entity_cl.h index 1c79161ea..bb508dd42 100644 --- a/code/ryzom/client/src/entity_cl.h +++ b/code/ryzom/client/src/entity_cl.h @@ -686,7 +686,7 @@ public: virtual bool isNeutralPVP() const { return false; } /// Return true if this player has the viewing properties of a friend (inscene bars...) - virtual bool isViewedAsFriend() const { return isNeutral() || isFriend() || isInTeam() || isInGuild(); } + virtual bool isViewedAsFriend() const { return isNeutral() || isFriend() || isInTeam() || isInSameGuild() || isInSameLeague(); } /// Return the People for the entity (unknown by default) virtual EGSPD::CPeople::TPeople people() const; @@ -733,7 +733,13 @@ public: bool isInTeam () const { return _IsInTeam; } // Return true if this entity is in the user guild - bool isInGuild () const; + bool isInSameGuild () const; + + // Return true if this entity is in the user league + bool isInSameLeague () const; + + // Return true if this entity or the user is in a league + bool oneInLeague () const; // Return true if this entity is a Mount owned by the User bool isUserMount () const {return _IsUserMount;} @@ -746,8 +752,9 @@ public: virtual uint64 getGuildSymbol () const { return 0; } virtual uint32 getEventFactionID() const { return 0; } - virtual uint8 getPvpMode() const { return PVP_MODE::None; } + virtual uint16 getPvpMode() const { return PVP_MODE::None; } virtual PVP_CLAN::TPVPClan getPvpClan() const { return PVP_CLAN::None; } + virtual uint32 getLeagueID() const { return 0; } virtual uint16 getOutpostId() const { return 0; } virtual OUTPOSTENUMS::TPVPSide getOutpostSide() const { return OUTPOSTENUMS::UnknownPVPSide; } @@ -760,6 +767,16 @@ public: return _Title; } + /// Return the entity tags + const ucstring &getTag(uint8 id) const + { + if (_Tags.size() > id) { + return _Tags[id]; + } + static ucstring empty; + return empty; + } + /// Return the raw unparsed entity title const ucstring getTitleRaw() const { @@ -910,6 +927,8 @@ protected: ucstring _EntityName; // Current entity title ucstring _Title; + // Current entity tags + std::vector _Tags; // Current entity title string id std::string _TitleRaw; // Current permanent content symbol for the entity @@ -1006,7 +1025,7 @@ protected: static NLMISC::CRGBA _PvpEnemyColor; static NLMISC::CRGBA _PvpNeutralColor; static NLMISC::CRGBA _PvpAllyInTeamColor; - static NLMISC::CRGBA _PvpAllyInGuildColor; + static NLMISC::CRGBA _PvpAllyInLeagueColor; static NLMISC::CRGBA _PvpAllyColor; // colors for GM players static NLMISC::CRGBA _GMTitleColor[CHARACTER_TITLE::EndGmTitle - CHARACTER_TITLE::BeginGmTitle + 1]; diff --git a/code/ryzom/client/src/interface_v3/action_handler_help.cpp b/code/ryzom/client/src/interface_v3/action_handler_help.cpp index 4c92fe6e0..ddcb324d7 100644 --- a/code/ryzom/client/src/interface_v3/action_handler_help.cpp +++ b/code/ryzom/client/src/interface_v3/action_handler_help.cpp @@ -57,6 +57,9 @@ #include "sbrick_manager.h" #include "sphrase_manager.h" #include "action_handler_help.h" +#include "nel/misc/i18n.h" +#include "nel/misc/algo.h" +#include "nel/net/email.h" #include "game_share/mission_desc.h" #include "game_share/inventories.h" #include "game_share/visual_slot_manager.h" @@ -378,7 +381,7 @@ CInterfaceGroup *CInterfaceHelp::activateNextWindow(CDBCtrlSheet *elt, sint forc setup.setupDefaultIDs(); setup.SrcSheet = elt; setup.HelpWindow = group; - setupCreatorName(setup); + //setupCreatorName(setup); // Hide elements by defaults resetSheetHelp(setup); @@ -2064,6 +2067,12 @@ void getItemText (CDBCtrlSheet *item, ucstring &itemText, const CItemSheet*pIS) strFindReplace(itemText, "%r2_comment_text", toString(itemInfo.R2ItemComment)); } break; + case ITEMFAMILY::PET_ANIMAL_TICKET: + { + string nr = (itemInfo.PetNumber > 0) ? toString(itemInfo.PetNumber) : "(slot)" + toString(item->getIndexInDB()); + strFindReplace(itemText, "%petnumber", nr); + } + break; default: { strFindReplace(itemText, "%no_rent", pIS->IsItemNoRent ? CI18N::get("uihelpItemNoRent") : string("")); @@ -2745,8 +2754,15 @@ void setupCreatorName(CSheetHelpSetup &setup) CViewText *vthd = dynamic_cast(setup.HelpWindow->getView("creator_header")); if (vtid != NULL) { - // if not an item, disable the view - if(!setup.SrcSheet || setup.SrcSheet->getType()!=CCtrlSheetInfo::SheetType_Item ) + bool bIsRM = false; + if (setup.SrcSheet) + { + const CItemSheet *pIS= dynamic_cast(SheetMngr.get(CSheetId(setup.SrcSheet->getSheetId()))); + bIsRM = (pIS && pIS->Family == ITEMFAMILY::RAW_MATERIAL); + } + + // if a RM or not an item, disable the view + if(!setup.SrcSheet || bIsRM || setup.SrcSheet->getType()!=CCtrlSheetInfo::SheetType_Item ) { // important else a brick could display a creator name.... vtid->setActive(false); @@ -3569,6 +3585,31 @@ public: }; REGISTER_ACTION_HANDLER( CHandlerAuraModifierTooltip, "aura_modifier_tooltip"); +// *************************************************************************** +class CHandlerUserPaToolTip : public IActionHandler +{ +public: + virtual void execute(CCtrlBase *pCaller, const string &Params) + { + CInterfaceManager *pIM= CInterfaceManager::getInstance(); + + uint8 index; + fromString(Params, index); + --index; // Param is 1-based so subtract 1 + if (index < 0 || index >= MAX_INVENTORY_ANIMAL) + { + return; + } + + ucstring txt; + CCDBNodeLeaf *node = pIM->getDbProp(toString("SERVER:PACK_ANIMAL:BEAST%d:NAME", index)); + if (node && CStringManagerClient::instance()->getDynString(node->getValue32(), txt)) + { + pIM->setContextHelpText(CEntityCL::removeTitleFromName(txt)); + } + } +}; +REGISTER_ACTION_HANDLER( CHandlerUserPaToolTip, "userpa_name_tooltip"); // *************************************************************************** class CHandlerAnimalDeadPopupTooltip : public IActionHandler @@ -3922,7 +3963,7 @@ public: #ifdef NL_OS_WINDOWS if (Driver) { - HWND wnd = Driver->getDisplay(); + HWND wnd = (HWND) Driver->getDisplay(); ShowWindow(wnd, SW_MINIMIZE); } #endif diff --git a/code/ryzom/client/src/interface_v3/action_handler_help.h b/code/ryzom/client/src/interface_v3/action_handler_help.h index 7430ee8cf..48253ea96 100644 --- a/code/ryzom/client/src/interface_v3/action_handler_help.h +++ b/code/ryzom/client/src/interface_v3/action_handler_help.h @@ -64,6 +64,15 @@ void refreshItemHelp(CSheetHelpSetup &setup); // refresh help for a mission void refreshMissionHelp(CSheetHelpSetup &setup, const CPrerequisitInfos &infos); +class CPetAnimalItemInfoWaiter : public IItemInfoWaiter +{ + void infoReceived() + { + //ItemSheet + //ItemSlotId + CClientItemInfo info = getInventory().getItemInfo(ItemSlotId); + } +}; // *************************************************************************** diff --git a/code/ryzom/client/src/interface_v3/action_handler_item.cpp b/code/ryzom/client/src/interface_v3/action_handler_item.cpp index 819b8c0d4..ce5e49307 100644 --- a/code/ryzom/client/src/interface_v3/action_handler_item.cpp +++ b/code/ryzom/client/src/interface_v3/action_handler_item.cpp @@ -31,9 +31,11 @@ #include "../net_manager.h" #include "group_menu.h" #include "../global.h" +#include "group_html.h" // #include "game_share/inventories.h" +#include "game_share/bot_chat_types.h" #include "macrocmd_manager.h" #include "inventory_manager.h" @@ -43,6 +45,7 @@ #include "view_bitmap.h" extern CSheetManager SheetMngr; +extern NLMISC::CLog g_log; using namespace std; using namespace NLMISC; @@ -80,8 +83,6 @@ void CInterfaceItemEdition::setCurrWindow(CDBCtrlSheet* ctrlSheet, const std::st _CurrWindow.IsInEditionMode = isInEditionMode; _CurrWindow.begin(); } - - } // ******************************************************************************************** @@ -153,13 +154,26 @@ void CInterfaceItemEdition::CItemEditionWindow::infoReceived() if (itemInfo.CustomText.empty()) display->setTextFormatTaged(ucstring(STRING_MANAGER::CStringManagerClient::getItemLocalizedDescription(pIS->Id))); else - display->setTextFormatTaged(itemInfo.CustomText); + { + ucstring text = itemInfo.CustomText; + string::size_type delimiter = text.find(' '); + if(text.size() > 3 && text[0]=='@' && text[1]=='W' && text[2]=='E' && text[3]=='B') + { + CGroupHTML *pGH = dynamic_cast(pIM->getElementFromId("ui:interface:web_transactions:content:html")); + if (pGH) + pGH->browse(ucstring(text.substr(4, delimiter-4)).toString().c_str()); + if (delimiter == string::npos) + group->setActive(false); + else + text = text.substr(delimiter, text.size()-delimiter); + } + + display->setTextFormatTaged(text); + } } - } } } - } @@ -278,7 +292,21 @@ void CInterfaceItemEdition::CItemEditionWindow::begin() if (itemInfo.CustomText.empty()) display->setTextFormatTaged(ucstring(STRING_MANAGER::CStringManagerClient::getItemLocalizedDescription(pIS->Id))); else - display->setTextFormatTaged(itemInfo.CustomText); + { + ucstring text = itemInfo.CustomText; + string::size_type delimiter = text.find(' '); + if(text.size() > 3 && text[0]=='@' && text[1]=='W' && text[2]=='E' && text[3]=='B') + { + CGroupHTML *pGH = dynamic_cast(pIM->getElementFromId("ui:interface:web_transactions:content:html")); + if (pGH) + pGH->browse(ucstring(text.substr(4, delimiter-4)).toString().c_str()); + if (delimiter == string::npos) + group->setActive(false); + else + text = text.substr(delimiter, text.size()-delimiter); + } + display->setTextFormatTaged(text); + } } else { @@ -287,7 +315,6 @@ void CInterfaceItemEdition::CItemEditionWindow::begin() } } } - } } } @@ -366,7 +393,6 @@ void CInterfaceItemEdition::CItemEditionWindow::validate() text = editBoxLarge->getInputString(); } - if (textValid) { CBitMemStream out; @@ -972,6 +998,12 @@ bool checkCanExchangeItem(CDBCtrlSheet *pCSSrc) bDropOrSell = pIS->canExchangeOrGive(PlayerTrade.BotChatGiftContext); } + // Locked by owner; cannot trade + if (pCSSrc->getLockedByOwner()) + { + return false; + } + // Special case if this is an animal ticket if ((pIS != NULL) && (pIS->Family == ITEMFAMILY::PET_ANIMAL_TICKET)) { @@ -1209,6 +1241,13 @@ class CHandlerDestroyItem : public IActionHandler nlwarning(" no caller sheet found"); return; } + + // Don't destroy locked items + if (item->getLockedByOwner()) + { + return; + } + // if the item is currently selected, removes the selection if (item == CDBCtrlSheet::getCurrSelection()) { @@ -1712,11 +1751,15 @@ class CHandlerItemMenuCheck : public IActionHandler CViewTextMenu *pXpCatalyserUse = dynamic_cast(pMenu->getView("xp_catalyser_use")); CViewTextMenu *pDrop = dynamic_cast(pMenu->getView("drop")); CViewTextMenu *pDestroy = dynamic_cast(pMenu->getView("destroy")); + CViewTextMenu *pLockUnlock = dynamic_cast(pMenu->getView("lockunlock")); CViewTextMenu *pMoveSubMenu = dynamic_cast(pMenu->getView("move")); CViewTextMenu *pMoveToBag = dynamic_cast(pMenu->getView("bag")); CViewTextMenu *pMoveToGuild = dynamic_cast(pMenu->getView("guild")); CViewTextMenu *pMoveToRoom = dynamic_cast(pMenu->getView("room")); CViewTextMenu *pMoveToPa[MAX_INVENTORY_ANIMAL]; + + bool bIsLockedByOwner = pCS->getLockedByOwner(); + for(i=0;i(pMenu->getView(toString("pa%d", i))); @@ -1735,24 +1778,27 @@ class CHandlerItemMenuCheck : public IActionHandler if(pXpCatalyserUse) pXpCatalyserUse->setActive(false); if(pItemTextDisplay) pItemTextDisplay->setActive(false); if(pItemTextEdition) pItemTextEdition->setActive(false); + + if(pLockUnlock) pLockUnlock->setActive(true); + const CItemSheet *pIS = pCS->asItemSheet(); if (invId != INVENTORIES::guild) if (pIS != NULL) { - if (pCrisEnchant && pIS->Family == ITEMFAMILY::CRYSTALLIZED_SPELL) + if (pCrisEnchant && pIS->Family == ITEMFAMILY::CRYSTALLIZED_SPELL && !bIsLockedByOwner) pCrisEnchant->setActive(true); - if (pCrisReload && pIS->Family == ITEMFAMILY::ITEM_SAP_RECHARGE) + if (pCrisReload && pIS->Family == ITEMFAMILY::ITEM_SAP_RECHARGE && !bIsLockedByOwner) pCrisReload->setActive(true); // teleport can be used only from bag (NB: should not exist in mektoub....) - if (pTeleportUse && pIS->Family == ITEMFAMILY::TELEPORT && pCS->getInventoryIndex()==INVENTORIES::bag) + if (pTeleportUse && pIS->Family == ITEMFAMILY::TELEPORT && pCS->getInventoryIndex()==INVENTORIES::bag && !bIsLockedByOwner) { pTeleportUse->setActive(true); } - if (pItemConsume && pIS->IsConsumable == true && pCS->getInventoryIndex()==INVENTORIES::bag) + if (pItemConsume && pIS->IsConsumable == true && pCS->getInventoryIndex()==INVENTORIES::bag && !bIsLockedByOwner) { pItemConsume->setActive(true); } - if (pXpCatalyserUse && pIS->Family == ITEMFAMILY::XP_CATALYSER && pCS->getInventoryIndex()==INVENTORIES::bag) + if (pXpCatalyserUse && pIS->Family == ITEMFAMILY::XP_CATALYSER && pCS->getInventoryIndex()==INVENTORIES::bag && !bIsLockedByOwner) { pXpCatalyserUse->setActive(true); } @@ -1815,9 +1861,10 @@ class CHandlerItemMenuCheck : public IActionHandler for(i=0;isetActive(false); - // additionnaly, cannot drop/destroy an animal item. + // additionnaly, cannot drop/destroy/lock an animal item. if(pDrop) pDrop->setActive(false); if(pDestroy) pDestroy->setActive(false); + if(pLockUnlock) pLockUnlock->setActive(false); } else { @@ -1845,6 +1892,7 @@ class CHandlerItemMenuCheck : public IActionHandler // std case: can drop / destroy if(pDrop) pDrop->setActive(invId!=INVENTORIES::guild); if(pDestroy) pDestroy->setActive(invId!=INVENTORIES::guild); + if(pLockUnlock) pLockUnlock->setActive(invId!=INVENTORIES::guild); } // hide the move entry completely? @@ -1899,6 +1947,29 @@ class CHandlerItemMenuCheck : public IActionHandler pItemTextDisplay->setGrayed(pIM->getDbProp("UI:VARIABLES:ISACTIVE:PHRASE_EDIT_CUSTOM")->getValueBool()); } + if (pCS->getGrayed()) + { + if (pEquip) pEquip->setActive(false); + if (pDestroy) pDestroy->setActive(false); + if (pLockUnlock) pLockUnlock->setActive(false); + if (pMoveSubMenu) pMoveSubMenu->setActive(false); + } + + if (bIsLockedByOwner) + { + if (pLockUnlock) pLockUnlock->setHardText("uimUnlockItem"); + // Cannot drop/destroy if locked by owner + if (pDrop) pDrop->setActive(false); + if (pDestroy) pDestroy->setActive(false); + } + else + { + if (pLockUnlock) pLockUnlock->setHardText("uimLockItem"); + } + + // Only show lock menu item if inventory contains the info + if (pLockUnlock) pLockUnlock->setActive(pCS->canOwnerLock()); + // **** Gray Entries // If ourselves are not available, then gray all @@ -1911,6 +1982,7 @@ class CHandlerItemMenuCheck : public IActionHandler if(pXpCatalyserUse) pXpCatalyserUse->setGrayed(true); if(pDrop) pDrop->setGrayed(true); if(pDestroy) pDestroy->setGrayed(true); + if(pLockUnlock) pLockUnlock->setGrayed(true); if(pMoveSubMenu) pMoveSubMenu->setGrayed(true); if(pMoveToBag) pMoveToBag->setGrayed(true); for(i=0;isetGrayed(false); if(pDrop) pDrop->setGrayed(false); if(pDestroy) pDestroy->setGrayed(false); + if(pLockUnlock) pLockUnlock->setGrayed(false); if(pMoveSubMenu) pMoveSubMenu->setGrayed(false); // check each inventory dest if available @@ -1956,6 +2029,45 @@ class CHandlerItemMenuDeactivate : public IActionHandler }; REGISTER_ACTION_HANDLER( CHandlerItemMenuDeactivate, "item_menu_deactivate" ); + +// *************************************************************************** + +class CHandlerItemMenuBaseCheck : public IActionHandler +{ + void execute (CCtrlBase *pCaller, const std::string &/* sParams */) + { + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + + // Get the ctrl sheet that launched this menu + CDBCtrlSheet *pCS = dynamic_cast(pIM->getCtrlLaunchingModal()); + if (pCS == NULL) return; + INVENTORIES::TInventory invId= (INVENTORIES::TInventory)pCS->getInventoryIndex(); + + // Get the menu launched + CInterfaceGroup *pMenu= dynamic_cast(pCaller); + if(!pMenu) return; + + // Get all needed text entries + CViewTextMenu *pDestroy = dynamic_cast(pMenu->getView("destroy")); + CViewTextMenu *pLockUnlock = dynamic_cast(pMenu->getView("lockunlock")); + + if (pCS->getLockedByOwner()) + { + pLockUnlock->setHardText("uimUnlockItem"); + // Cannot destroy if locked by owner + if (pDestroy) pDestroy->setActive(false); + } + else + { + pLockUnlock->setHardText("uimLockItem"); + if (pDestroy) pDestroy->setActive(true); + } + + } +}; +REGISTER_ACTION_HANDLER( CHandlerItemMenuBaseCheck, "item_menu_base_check" ); + + // *************************************************************************** static void sendMsgUseItem(uint16 slot) { diff --git a/code/ryzom/client/src/interface_v3/action_phrase_faber.cpp b/code/ryzom/client/src/interface_v3/action_phrase_faber.cpp index 53a1258bc..097247f6f 100644 --- a/code/ryzom/client/src/interface_v3/action_phrase_faber.cpp +++ b/code/ryzom/client/src/interface_v3/action_phrase_faber.cpp @@ -33,7 +33,7 @@ #include "group_editbox.h" #include "dbview_bar.h" #include "skill_manager.h" - +#include "game_share/bot_chat_types.h" using namespace std; using namespace NLMISC; @@ -69,7 +69,9 @@ const std::string FaberPhraseItemResultGroup= FaberPhraseWindow + ":header_opene // *************************************************************************** CActionPhraseFaber::CActionPhraseFaber() { - _InventoryMirror.resize(INVENTORIES::NUM_INVENTORY * MAX_PLAYER_INV_ENTRIES); + uint size = MAX_PLAYER_INV_ENTRIES + (MAX_ANIMALINV_ENTRIES * MAX_INVENTORY_ANIMAL) + + MAX_GUILDINV_ENTRIES + MAX_ROOMINV_ENTRIES; + _InventoryMirror.resize(size); _InventoryObsSetup= false; _ExecuteFromItemPlanBrick= NULL; } @@ -275,25 +277,64 @@ void CActionPhraseFaber::fillFaberPlanSelection(const std::string &brickDB, ui } // *************************************************************************** -CItemImage *CActionPhraseFaber::getInvMirrorItemImage(uint slotIndex) +CItemImage *CActionPhraseFaber::getInvMirrorItemImage(uint slotIndex, uint& invId, uint& indexInInv) { - uint invId= slotIndex/MAX_PLAYER_INV_ENTRIES; - uint indexInInv= slotIndex%MAX_PLAYER_INV_ENTRIES; + if (slotIndex < MAX_PLAYER_INV_ENTRIES) + { + invId = INVENTORIES::bag; + indexInInv = slotIndex; + return &getInventory().getBagItem(slotIndex); + } + slotIndex -= MAX_PLAYER_INV_ENTRIES; - // get the item image from bag, steed, pack animal... - if(invId==INVENTORIES::bag && indexInInv=INVENTORIES::pet_animal && invIdgetDbBranch(SERVER_INVENTORY ":GUILD:" + toString(slotIndex)); + static CItemImage image; + image.build(itemBranch); + invId = INVENTORIES::guild; + indexInInv = slotIndex; + return ℑ + } + return NULL; + } + slotIndex -= MAX_GUILDINV_ENTRIES; + + if (slotIndex < MAX_ROOMINV_ENTRIES) + { + if (getInventory().isInventoryAvailable(INVENTORIES::player_room)) + { + CInterfaceManager *im = CInterfaceManager::getInstance(); + CCDBNodeBranch *itemBranch = im->getDbBranch(SERVER_INVENTORY ":ROOM:" + toString(slotIndex)); + static CItemImage image; + image.build(itemBranch); + invId = INVENTORIES::player_room; + indexInInv = slotIndex; + return ℑ + } + return NULL; + } return NULL; } // *************************************************************************** -bool CActionPhraseFaber::isMpAvailable(CItemSheet *mpSheet, uint slotIndex) const +bool CActionPhraseFaber::isMpAvailable(CItemSheet *mpSheet, uint invId, uint slotIndex) const { - uint invId= slotIndex / MAX_PLAYER_INV_ENTRIES; return mpSheet && mpSheet->Family==ITEMFAMILY::RAW_MATERIAL && getInventory().isInventoryAvailable((INVENTORIES::TInventory)invId); } @@ -396,14 +437,14 @@ void CActionPhraseFaber::validateFaberPlanSelection(CSBrickSheet *itemPlanBrick _InventoryMirror[i].reset(); } + uint invId = 0; + uint indexInInv = 0; // Run all the inventories. for(i=0;i<_InventoryMirror.size();i++) { - uint invId= i/MAX_PLAYER_INV_ENTRIES; - uint indexInInv= i%MAX_PLAYER_INV_ENTRIES; - CItemImage *itemImage= getInvMirrorItemImage(i); - - // item found? + CItemImage *itemImage= getInvMirrorItemImage(i, invId, indexInInv); + bool bLockedByOwner = itemImage && itemImage->getLockedByOwner(); + // item found and not locked? if(itemImage) { // setup the origin @@ -413,7 +454,7 @@ void CActionPhraseFaber::validateFaberPlanSelection(CSBrickSheet *itemPlanBrick // The item must be a mp CSheetId sheetId= CSheetId(itemImage->getSheetID()); CItemSheet *mpSheet= dynamic_cast(SheetMngr.get(sheetId)); - if( isMpAvailable(mpSheet, i) ) + if( isMpAvailable(mpSheet, invId, i) && !bLockedByOwner) { _InventoryMirror[i].Sheet= sheetId; _InventoryMirror[i].Quality= itemImage->getQuality(); @@ -422,6 +463,7 @@ void CActionPhraseFaber::validateFaberPlanSelection(CSBrickSheet *itemPlanBrick _InventoryMirror[i].Weight= itemImage->getWeight(); // Bkup original quantity from inventory _InventoryMirror[i].OriginalQuantity= _InventoryMirror[i].Quantity; + _InventoryMirror[i].LockedByOwner= bLockedByOwner; } } } @@ -1311,17 +1353,22 @@ void CActionPhraseFaber::onInventoryChange() return; // Run all the Bag + uint invId = 0; + uint indexInInv = 0; for(i=0;i<_InventoryMirror.size();i++) { - CItemImage *itemImage= getInvMirrorItemImage(i); + CItemImage *itemImage= getInvMirrorItemImage(i, invId, indexInInv); + if(itemImage) { CSheetId sheetId= CSheetId(itemImage->getSheetID()); CItemSheet *mpSheet= dynamic_cast(SheetMngr.get(sheetId)); CItem newInvItem; - // The item must be a mp, and the item must be available - if( isMpAvailable(mpSheet, i) ) + bool bLockedByOwner = itemImage->getLockedByOwner(); + + // The item must be a mp, and the item must be available and unlocked + if( isMpAvailable(mpSheet, invId, i) && !bLockedByOwner) { newInvItem.Sheet= sheetId; newInvItem.Quality= itemImage->getQuality(); @@ -1329,12 +1376,13 @@ void CActionPhraseFaber::onInventoryChange() newInvItem.UserColor= itemImage->getUserColor(); newInvItem.Weight= itemImage->getWeight(); newInvItem.OriginalQuantity= newInvItem.Quantity; + newInvItem.LockedByOwner = bLockedByOwner; } - /* There is 4 cases: + /* There is 5 cases: - no changes => no op. - - new Mp on a empty or non Mp slot. Easy, just add. - - old Mp removed (not same sheetId/quality/userColor) + - new/unlocked Mp on a empty or non Mp slot. Easy, just add. + - old Mp removed (not same sheetId/quality/userColor/locked) - old Mp with quantity changed to be greater - old Mp with quantity changed to be smaller */ @@ -1348,8 +1396,8 @@ void CActionPhraseFaber::onInventoryChange() // If the item was not a mp if(_InventoryMirror[i].Sheet==CSheetId::Unknown) { - // if now it is, easy, just add - if(newInvItem.Sheet!=CSheetId::Unknown) + // if now it is, easy, just add if not locked + if(newInvItem.Sheet!=CSheetId::Unknown && !newInvItem.LockedByOwner) curInvItem= newInvItem; } // else must test change or remove @@ -1358,7 +1406,8 @@ void CActionPhraseFaber::onInventoryChange() bool sameMp; sameMp= curInvItem.Sheet == newInvItem.Sheet && curInvItem.Quality == newInvItem.Quality && - curInvItem.UserColor == newInvItem.UserColor ; + curInvItem.UserColor == newInvItem.UserColor && + curInvItem.LockedByOwner == newInvItem.LockedByOwner; // if the Mp was deleted from this slot, delete it from all faber execution if(!sameMp) diff --git a/code/ryzom/client/src/interface_v3/action_phrase_faber.h b/code/ryzom/client/src/interface_v3/action_phrase_faber.h index 8b792089b..517b25210 100644 --- a/code/ryzom/client/src/interface_v3/action_phrase_faber.h +++ b/code/ryzom/client/src/interface_v3/action_phrase_faber.h @@ -92,6 +92,7 @@ private: uint Selected; // This is the original quantity in inventory sint32 OriginalQuantity; + bool LockedByOwner; CItem() : Sheet(0) { @@ -233,8 +234,8 @@ private: void removeMpSlotThatUseInvSlot(uint invSlot, uint quantityToRemove); // from an index in _InventoryMirror, get the ItemImage - CItemImage *getInvMirrorItemImage(uint slotIndex); - bool isMpAvailable(CItemSheet *mpSheet, uint slotIndex) const; + CItemImage *getInvMirrorItemImage(uint slotIndex, uint& invId, uint& indexInInv); + bool isMpAvailable(CItemSheet *mpSheet, uint invId, uint slotIndex) const; void updateItemResult(); }; diff --git a/code/ryzom/client/src/interface_v3/bot_chat_page_trade.cpp b/code/ryzom/client/src/interface_v3/bot_chat_page_trade.cpp index dcebe792d..1cd5644d4 100644 --- a/code/ryzom/client/src/interface_v3/bot_chat_page_trade.cpp +++ b/code/ryzom/client/src/interface_v3/bot_chat_page_trade.cpp @@ -48,6 +48,7 @@ #include "../sheet_manager.h" #include "../user_entity.h" #include "view_bitmap.h" +#include "nel/misc/common.h" using namespace std::rel_ops; @@ -996,7 +997,7 @@ void CBotChatPageTrade::startSellDialog(CDBCtrlSheet *sheet, CCtrlBase * /* pCal CCtrlTextButton *confirmButton = dynamic_cast(ig->getCtrl("ok")); if (confirmButton) { - confirmButton->setActive( true ); + confirmButton->setActive( sheet->getLockedByOwner() ); confirmButton->setText(CI18N::get("uiSellImmediately")); confirmButton->setDefaultContextHelp(CI18N::get("uittDirectSellButton")); } @@ -1538,10 +1539,12 @@ void CBotChatPageTrade::setupResellGroup(bool sellMode, uint defaultQuantity, CI CViewText *vt= dynamic_cast(cantResellGroup->getView("reason")); if(vt) { - if(resaleFlag==BOTCHATTYPE::ResaleKOBroken) + if(resaleFlag == BOTCHATTYPE::ResaleKOBroken) vt->setHardText("uiCantResaleCauseDamaged"); - else + else if (resaleFlag == BOTCHATTYPE::ResaleKONoTimeLeft) vt->setHardText("uiCantResaleCauseTooLate"); + else + vt->setHardText("uiCantResaleLockedByOwner"); } } // else setup "can_resell:choose_resell group" @@ -2575,9 +2578,9 @@ static DECLARE_INTERFACE_USER_FCT(getPriceWithFame) if(value==-1) result.setUCString(CI18N::get("uiBadPrice")); else if(value==valueFame) - result.setUCString(toString(value)); + result.setUCString(NLMISC::formatThousands(toString(value))); else - result.setUCString(toString("%d (%d)", valueFame, value)); + result.setUCString(NLMISC::formatThousands(toString(valueFame)) + " (" + NLMISC::formatThousands(toString(value)) + ")"); return true; } @@ -2592,8 +2595,8 @@ static DECLARE_INTERFACE_USER_FCT(getBonusOnResale) sint valueHigh= (sint)args[0].getInteger(); sint valueLow= (sint)args[1].getInteger(); - sint diff = valueHigh - valueLow; - result.setUCString(toString("+%d", diff)); + sint diff = valueHigh - valueLow; + result.setUCString("+" + NLMISC::formatThousands(toString(diff))); return true; } diff --git a/code/ryzom/client/src/interface_v3/chat_filter.cpp b/code/ryzom/client/src/interface_v3/chat_filter.cpp index fc2e6c9c3..9609fc1af 100644 --- a/code/ryzom/client/src/interface_v3/chat_filter.cpp +++ b/code/ryzom/client/src/interface_v3/chat_filter.cpp @@ -378,7 +378,7 @@ void CChatTargetFilter::setTargetGroup(CChatGroup::TGroupType groupType, uint32 const bool guildActive = pIM->getDbProp("SERVER:GUILD:NAME")->getValueBool(); switch(groupType) { - case CChatGroup::dyn_chat: entry+="DYN"; break; + case CChatGroup::dyn_chat: entry+="DYN:" + NLMISC::toString(dynamicChannelDbIndex); break; case CChatGroup::say: entry+="SAY"; break; case CChatGroup::shout: entry+="SHOUT"; break; case CChatGroup::team: if(!teamActive) return; entry+="GROUP"; break; 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 391898563..d1488b4dd 100644 --- a/code/ryzom/client/src/interface_v3/chat_text_manager.cpp +++ b/code/ryzom/client/src/interface_v3/chat_text_manager.cpp @@ -148,18 +148,43 @@ CViewBase *CChatTextManager::createMsgText(const ucstring &cstMsg, NLMISC::CRGBA vt->setMultiLineSpace(getTextMultiLineSpace()); vt->setModulateGlobalColor(false); + ucstring cur_time = ""; + static CCDBNodeLeaf* node = CInterfaceManager::getInstance()->getDbProp("UI:SAVE:CHAT:SHOW_TIMES_IN_CHAT_CB", false); + if (node) + { + if (node->getValueBool()) + { + cur_time = CInterfaceManager::getTimestampHuman(); + } + } + // if text contain any color code, set the text formated and white, // otherwise, set text normal and apply global color - if (msg.find(ucstring("@{")) != ucstring::npos) + size_t codePos = msg.find(ucstring("@{")); + if (codePos != ucstring::npos) { + // Prepend the current time (do it after the color if the color at first position. + if (codePos == 0) + { + codePos = msg.find(ucstring("}")); + msg = msg.substr(0, codePos + 1) + cur_time + msg.substr(codePos + 1, msg.length() - codePos); + } + else + { + msg = cur_time + msg; + } + + vt->setTextFormatTaged(msg); vt->setColor(NLMISC::CRGBA::White); } else { + msg = cur_time + msg; vt->setText(msg); vt->setColor(col); } + if (!commandGroup) { return vt; diff --git a/code/ryzom/client/src/interface_v3/chat_window.cpp b/code/ryzom/client/src/interface_v3/chat_window.cpp index 6f13b1bed..773992fc3 100644 --- a/code/ryzom/client/src/interface_v3/chat_window.cpp +++ b/code/ryzom/client/src/interface_v3/chat_window.cpp @@ -472,15 +472,9 @@ void CChatWindow::displayLocalPlayerTell(const ucstring &receiver, const ucstrin CInterfaceProperty prop; prop.readRGBA("UI:SAVE:CHAT:COLORS:SPEAKER"," "); encodeColorTag(prop.getRGBA(), finalMsg, false); - ucstring cur_time; - CCDBNodeLeaf *pNL = CInterfaceManager::getInstance()->getDbProp("UI:SAVE:CHAT:SHOW_TIMES_IN_CHAT_CB", false); - if (pNL && pNL->getValueBool()) - { - cur_time = CInterfaceManager::getTimestampHuman(); - } - ucstring csr; - if (CHARACTER_TITLE::isCsrTitle(UserEntity->getTitleRaw())) csr += ucstring("(CSR) "); - finalMsg += cur_time + csr + CI18N::get("youTell") + ": "; + + ucstring csr = CHARACTER_TITLE::isCsrTitle(UserEntity->getTitleRaw()) ? "(CSR) " : ""; + finalMsg += csr + CI18N::get("youTell") + ": "; prop.readRGBA("UI:SAVE:CHAT:COLORS:TELL"," "); encodeColorTag(prop.getRGBA(), finalMsg, true); finalMsg += msg; @@ -1294,8 +1288,18 @@ public: CChatWindow::_ChatWindowLaunchingCommand = chat; string str = text.toUtf8(); string cmdWithArgs = str.substr(1); - /* In the chat context, only ' ' is a possible separator */ + + // Get the command name from the string, can contain spaces string cmd = cmdWithArgs.substr(0, cmdWithArgs.find(' ')); + if (cmdWithArgs.find('"') == 0) + { + string::size_type pos = cmdWithArgs.find('"', 1); + if (string::npos != pos) + { + cmd = cmdWithArgs.substr(1, pos - 1); + } + } + if ( NLMISC::ICommand::exists( cmd ) ) { NLMISC::ICommand::execute( cmdWithArgs, g_log ); @@ -1314,7 +1318,7 @@ public: } } // Clear input string - pEB->setInputString (string("")); + pEB->setInputString (ucstring("")); CGroupContainer *gc = pEB->getEnclosingContainer(); if (gc) { diff --git a/code/ryzom/client/src/interface_v3/ctrl_base_button.h b/code/ryzom/client/src/interface_v3/ctrl_base_button.h index 06a27b276..c33f0c63e 100644 --- a/code/ryzom/client/src/interface_v3/ctrl_base_button.h +++ b/code/ryzom/client/src/interface_v3/ctrl_base_button.h @@ -115,6 +115,7 @@ public: // @{ // Event part void setActionOnLeftClick (const std::string &actionHandlerName) { _AHOnLeftClickString = actionHandlerName; _AHOnLeftClick = getAH(actionHandlerName, _AHLeftClickParams); } + void setActionOnLeftClickParams(const std::string ¶ms) { _AHOnLeftClickStringParams = params; } void setActionOnRightClick (const std::string &actionHandlerName) { _AHOnRightClick = getAH(actionHandlerName, _AHRightClickParams); } void setActionOnClockTick (const std::string &ahName) { _AHOnClockTick = getAH(ahName, _AHClockTickParams); } void setParamsOnLeftClick (const std::string ¶msHandlerName) { _AHLeftClickParams = paramsHandlerName; } @@ -204,6 +205,7 @@ protected: IActionHandler *_AHOnOver; CStringShared _AHOverParams; std::string _AHOnLeftClickString; + std::string _AHOnLeftClickStringParams; IActionHandler *_AHOnLeftClick; CStringShared _AHLeftClickParams; IActionHandler *_AHOnLeftDblClick; diff --git a/code/ryzom/client/src/interface_v3/ctrl_button.cpp b/code/ryzom/client/src/interface_v3/ctrl_button.cpp index fd1ba049b..0f77fc6fe 100644 --- a/code/ryzom/client/src/interface_v3/ctrl_button.cpp +++ b/code/ryzom/client/src/interface_v3/ctrl_button.cpp @@ -338,7 +338,14 @@ bool CCtrlButton::getMouseOverShape(string &texName, uint8 &rot, CRGBA &col) { if (_AHOnLeftClickString == "browse") { - texName = "curs_pick.tga"; + if (!_AHOnLeftClickStringParams.empty()) + { + texName = "@curs_pick.tga@"+_AHOnLeftClickStringParams; + } + else + { + texName = "curs_pick.tga"; + } rot= 0; col = CRGBA::White; return true; diff --git a/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp b/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp index ce551a0b7..c7afcaf92 100644 --- a/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp +++ b/code/ryzom/client/src/interface_v3/dbctrl_sheet.cpp @@ -45,6 +45,7 @@ #include "../client_sheets/sphrase_sheet.h" #include "game_share/xml_auto_ptr.h" #include "lua_ihm.h" +#include "game_share/bot_chat_types.h" #include "../r2/editor.h" @@ -123,6 +124,14 @@ ucstring CControlSheetTooltipInfoWaiter::infoValidated(CDBCtrlSheet* ctrlSheet, return help; } + +// *************************************************************************** +int CDBCtrlSheet::luaGetDraggedSheet(CLuaState &ls) +{ + CLuaIHM::pushUIOnStack(ls, dynamic_cast(_LastDraggedSheet)); + return 1; +} + // *************************************************************************** int CDBCtrlSheet::luaGetHpBuff(CLuaState &ls) { @@ -179,6 +188,62 @@ int CDBCtrlSheet::luaGetName(CLuaState &ls) return 1; } +// ********************************************************************************************************** +class LuaInfoWaiter : public IItemInfoWaiter +{ +public: + volatile bool done; + +public: + virtual void infoReceived(); +}; + + +void LuaInfoWaiter::infoReceived() +{ + getInventory().removeItemInfoWaiter(this); + this->done = true; +} + +static LuaInfoWaiter luaInfoWaiter; + +// *************************************************************************** +int CDBCtrlSheet::luaGetCreatorName(CLuaState &ls) +{ + uint32 itemSlotId = getInventory().getItemSlotId(this); + CClientItemInfo itemInfo = getInventory().getItemInfo(itemSlotId); + ucstring creatorName; + STRING_MANAGER::CStringManagerClient::instance()->getString(itemInfo.CreatorName, creatorName); + CLuaIHM::push(ls, creatorName); + + return 1; +} + +// *************************************************************************** +int CDBCtrlSheet::luaWaitInfo(CLuaState &ls) +{ + static bool sent = false; + CDBCtrlSheet *ctrlSheet = const_cast(this); + uint32 itemSlotId= getInventory().getItemSlotId(ctrlSheet); + CClientItemInfo itemInfo = getInventory().getItemInfo(itemSlotId); + + if (sent || itemInfo.versionInfo != 0) + { + ls.push((bool)(luaInfoWaiter.done)); + if (luaInfoWaiter.done) + sent = false; + return luaInfoWaiter.done ? 1 : 0; + } + else + { + luaInfoWaiter.ItemSlotId = itemSlotId; + luaInfoWaiter.ItemSheet = this->getSheetId(); + luaInfoWaiter.done = false; + getInventory().addItemInfoWaiter(&luaInfoWaiter); + sent = true; + } + return 0; +} // *************************************************************************** int CDBCtrlSheet::luaBuildCrystallizedSpellListBrick(CLuaState &ls) @@ -1797,8 +1862,16 @@ void CDBCtrlSheet::draw() string params = string("src=") + pCSSrc->getId(); if (!_AHCanDropParams.empty()) { - string sTmp = _AHCanDropParams; - params = sTmp + "|" + params; + if (getAHName(_AHOnCanDrop) == "lua") + { + params = _AHCanDropParams; + strFindReplace(params, "%src", pCSSrc->getId()); + } + else + { + string sTmp = _AHCanDropParams; + params = sTmp + "|" + params; + } } pIM->runActionHandler (_AHOnCanDrop, this, params); } @@ -2138,6 +2211,12 @@ void CDBCtrlSheet::drawSheet (sint32 x, sint32 y, bool draging, bool showSelecti // if a raw material for example, must add special icon text. displayCharBitmaps(_RenderLayer+2, x, y, curSheetColor); + + // Add the lock overlay if needed + if (getLockedByOwner()) + { + rVR.draw11RotFlipBitmap (_RenderLayer+1, x - 2, y + 8, 0, false, rVR.getSystemTextureId(CViewRenderer::ItemLockedByOwnerTexture), curSheetColor); + } } break; // Action @@ -2600,8 +2679,16 @@ bool CDBCtrlSheet::handleEvent (const CEventDescriptor &event) string params = string("src=") + _Id; if (!pCSdest->_AHCanDropParams.empty()) { - string sTmp = pCSdest->_AHCanDropParams; - params = sTmp + "|" + params; + if (getAHName(pCSdest->_AHOnCanDrop) == "lua") + { + params = pCSdest->_AHCanDropParams; + strFindReplace(params, "%src", _Id); + } + else + { + string sTmp = pCSdest->_AHCanDropParams; + params = sTmp + "|" + params; + } } pIM->runActionHandler (pCSdest->_AHOnCanDrop, pCSdest, params); @@ -2612,8 +2699,16 @@ bool CDBCtrlSheet::handleEvent (const CEventDescriptor &event) string params = string("src=") + _Id; if (!pCSdest->_AHDropParams.empty()) { - string sTmp = pCSdest->_AHDropParams; - params = sTmp + "|" + params; // must copy 'drop' params at start because it could be the name of a procedure + if (getAHName(pCSdest->_AHOnDrop) == "lua") + { + params = pCSdest->_AHDropParams; + strFindReplace(params, "%src", _Id); + } + else + { + string sTmp = pCSdest->_AHDropParams; + params = sTmp + "|" + params;// must copy 'drop' params at start because it could be the name of a procedure + } } // call action pIM->runActionHandler (pCSdest->_AHOnDrop, pCSdest, params); @@ -2649,8 +2744,16 @@ bool CDBCtrlSheet::handleEvent (const CEventDescriptor &event) string params = string("src=") + _Id; if (!pList->getCtrlSheetInfo()._AHCanDropParams.empty()) { - string sTmp = pList->getCtrlSheetInfo()._AHCanDropParams; - params = sTmp + "|" + params; + if (getAHName(pList->getCtrlSheetInfo()._AHOnCanDrop) == "lua") + { + params = pList->getCtrlSheetInfo()._AHCanDropParams; + strFindReplace(params, "%src", _Id); + } + else + { + string sTmp = pList->getCtrlSheetInfo()._AHCanDropParams; + params = sTmp + "|" + params; + } } pIM->runActionHandler (pList->getCtrlSheetInfo()._AHOnCanDrop, pList, params); @@ -2661,8 +2764,16 @@ bool CDBCtrlSheet::handleEvent (const CEventDescriptor &event) string params = string("src=") + _Id; if (!pList->getCtrlSheetInfo()._AHDropParams.empty()) { - string sTmp = pList->getCtrlSheetInfo()._AHDropParams; - params = sTmp + "|" + params; // must copy 'drop' params at start because it could be the name of a procedure + if (getAHName(pList->getCtrlSheetInfo()._AHOnDrop) == "lua") + { + params = pList->getCtrlSheetInfo()._AHDropParams; + strFindReplace(params, "%src", _Id); + } + else + { + string sTmp = pList->getCtrlSheetInfo()._AHDropParams; + params = sTmp + "|" + params; // must copy 'drop' params at start because it could be the name of a procedure + } } // call action pIM->runActionHandler (pList->getCtrlSheetInfo()._AHOnDrop, pList, params); @@ -2975,9 +3086,32 @@ void CDBCtrlSheet::getContextHelp(ucstring &help) const } else if(getType() == CCtrlSheetInfo::SheetType_Item) { - const CItemSheet *item = asItemSheet(); - if (item) - help = getItemActualName(); + const CItemSheet *item= asItemSheet(); + if(item) + { + if (item->Family == ITEMFAMILY::CRYSTALLIZED_SPELL || item->Family == ITEMFAMILY::JEWELRY || item->Family == ITEMFAMILY::ARMOR) + { + string luaMethodName = ( (item->Family == ITEMFAMILY::CRYSTALLIZED_SPELL) ? "updateCrystallizedSpellTooltip" : "updateBuffItemTooltip"); + CDBCtrlSheet *ctrlSheet = const_cast(this); + 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); + + } + else + help= getItemActualName(); + + } else help= _ContextHelp; } @@ -3936,6 +4070,17 @@ void CDBCtrlSheet::setItemResaleFlag(sint32 rf) node->setValue32(rf); } +// *************************************************************************** +bool CDBCtrlSheet::getLockedByOwner() const +{ + return (getItemResaleFlag() == BOTCHATTYPE::ResaleKOLockedByOwner); +} + +// *************************************************************************** +bool CDBCtrlSheet::canOwnerLock() const +{ + return (NULL != getItemResaleFlagPtr()); +} // *************************************************************************** sint32 CDBCtrlSheet::getItemSellerType() const diff --git a/code/ryzom/client/src/interface_v3/dbctrl_sheet.h b/code/ryzom/client/src/interface_v3/dbctrl_sheet.h index 2cf34e722..6bd7706fb 100644 --- a/code/ryzom/client/src/interface_v3/dbctrl_sheet.h +++ b/code/ryzom/client/src/interface_v3/dbctrl_sheet.h @@ -194,16 +194,20 @@ public: void setActionOnLeftClick (const std::string &ActionHandlerName) { _AHOnLeftClick = getAH(ActionHandlerName, _AHLeftClickParams); } void setActionOnRightClick (const std::string &ActionHandlerName) { _AHOnRightClick = getAH(ActionHandlerName, _AHRightClickParams); } void setActionOnDrop (const std::string &ActionHandlerName) { _AHOnDrop = getAH(ActionHandlerName, _AHDropParams); } + void setActionOnCanDrop (const std::string &ActionHandlerName) { _AHOnCanDrop = getAH(ActionHandlerName, _AHCanDropParams); } void setParamsOnLeftClick (const std::string &ParamsHandlerName) { _AHLeftClickParams = ParamsHandlerName; } void setParamsOnRightClick (const std::string &ParamsHandlerName) { _AHRightClickParams = ParamsHandlerName; } void setParamsOnDrop (const std::string &ParamsHandlerName) { _AHDropParams = ParamsHandlerName; } + void setParamsOnCanDrop (const std::string &ParamsHandlerName) { _AHCanDropParams = ParamsHandlerName; } const std::string &getActionOnLeftClick () const { return getAHName(_AHOnLeftClick); } const std::string &getActionOnRightClick () const { return getAHName(_AHOnRightClick); } const std::string &getActionOnDrop () const { return getAHName(_AHOnDrop); } + const std::string &getActionOnCanDrop () const { return getAHName(_AHOnCanDrop); } const std::string &getParamsOnLeftClick () const { return _AHLeftClickParams; } const std::string &getParamsOnRightClick () const { return _AHRightClickParams; } const std::string &getParamsOnDrop () const { return _AHDropParams; } + const std::string &getParamsOnCanDrop () const { return _AHCanDropParams; } void setListMenuLeft (const std::string &cm) { CCtrlSheetInfo::setListMenuLeft(cm); } void setListMenuRight (const std::string &cm) { CCtrlSheetInfo::setListMenuRight(cm); } @@ -215,6 +219,7 @@ public: void setCanDrop (bool cd) { _CanDrop = cd; } bool getCanDrop () const { return _CanDrop; } bool isDragable() { return _Dragable; } + void setDragable(bool dragable) { _Dragable = dragable; } bool isDraging() { return _Draging; } sint32 getDeltaDragX() {return _DeltaDragX;} sint32 getDeltaDragY() {return _DeltaDragY;} @@ -265,19 +270,35 @@ public: REFLECT_SINT32("back", getGuildBack, setGuildBack); REFLECT_SINT32("symbol", getGuildSymbol, setGuildSymbol); REFLECT_BOOL("invert_symbol", getInvertGuildSymbol, setInvertGuildSymbol); + REFLECT_BOOL("dragable", isDragable, setDragable); + REFLECT_BOOL("can_drop", getCanDrop, setCanDrop); + REFLECT_STRING ("left_click", getActionOnLeftClick, setActionOnLeftClick); + REFLECT_STRING ("right_click", getActionOnRightClick, setActionOnRightClick); + REFLECT_STRING ("left_click_params", getParamsOnLeftClick, setParamsOnLeftClick); + REFLECT_STRING ("right_click_params", getParamsOnRightClick, setParamsOnRightClick); + REFLECT_STRING ("on_drop", getActionOnDrop, setActionOnDrop); + REFLECT_STRING ("on_drop_params", getParamsOnDrop, setParamsOnDrop); + REFLECT_STRING ("on_can_drop", getActionOnCanDrop, setActionOnCanDrop); + REFLECT_STRING ("on_can_drop_params", getParamsOnCanDrop, setParamsOnCanDrop); + REFLECT_LUA_METHOD("getDraggedSheet", luaGetDraggedSheet) REFLECT_LUA_METHOD("getHpBuff", luaGetHpBuff) REFLECT_LUA_METHOD("getSapBuff", luaGetSapBuff) REFLECT_LUA_METHOD("getFocusBuff", luaGetFocusBuff) REFLECT_LUA_METHOD("getStaBuff", luaGetStaBuff) REFLECT_LUA_METHOD("getName", luaGetName) + REFLECT_LUA_METHOD("getCreatorName", luaGetCreatorName) + REFLECT_LUA_METHOD("waitInfo", luaWaitInfo) REFLECT_LUA_METHOD("buildCrystallizedSpellListBrick", luaBuildCrystallizedSpellListBrick) REFLECT_EXPORT_END + int luaGetDraggedSheet(CLuaState &ls); int luaGetHpBuff(CLuaState &ls); int luaGetSapBuff(CLuaState &ls); int luaGetFocusBuff(CLuaState &ls); int luaGetStaBuff(CLuaState &ls); int luaGetName(CLuaState &ls); + int luaGetCreatorName(CLuaState &ls); + int luaWaitInfo(CLuaState &ls); int luaBuildCrystallizedSpellListBrick(CLuaState &ls); // hardcode creation. User must setup other CtrlBase value (parent etc...) @@ -355,9 +376,9 @@ public: /// Special ContextHelp for ctrl sheet. virtual void getContextHelp(ucstring &help) const; - /// Special ContextHelp for ctrl sheet. virtual void getContextHelpToolTip(ucstring &help) const; + /** true if an item of another ctrlSheet can be dropped on this slot. * also return true if src is 0, or if _ItemSlot==UNDEFINED */ @@ -494,6 +515,12 @@ public: // set item RESALE_FLAG void setItemResaleFlag(sint32 rf); + // get item locked by owner + bool getLockedByOwner() const; + + // true if the inventory supports owner locking + bool canOwnerLock() const; + // get item SELLER_TYPE. 0 if no DB sint32 getItemSellerType() const; CCDBNodeLeaf *getItemSellerTypePtr() const; diff --git a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_trade.cpp b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_trade.cpp index 7511ee8ef..bd30d61f6 100644 --- a/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_trade.cpp +++ b/code/ryzom/client/src/interface_v3/dbgroup_list_sheet_trade.cpp @@ -30,6 +30,7 @@ #include "game_share/pvp_clan.h" #include "../string_manager_client.h" #include "../entity_cl.h" +#include "nel/misc/common.h" using namespace NLMISC; @@ -264,7 +265,7 @@ void CDBGroupListSheetTrade::CSheetChildTrade::updateViewText(CDBGroupListSheetT { STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance(); text += string("\n") + pSMC->getOutpostBuildingLocalizedDescription(CSheetId(Ctrl->getSheetId())); - text += "\n" + CI18N::get("uiBotChatPrice") + toString(pOBS->CostDapper); + text += "\n" + CI18N::get("uiBotChatPrice") + NLMISC::formatThousands(toString(pOBS->CostDapper)); text += CI18N::get("uiBotChatTime") + toString(pOBS->CostTime/60) + CI18N::get("uiBotChatTimeMinute"); if ((pOBS->CostTime % 60) != 0) text += toString(pOBS->CostTime%60) + CI18N::get("uiBotChatTimeSecond"); @@ -341,7 +342,7 @@ void CDBGroupListSheetTrade::CSheetChildTrade::updateViewText(CDBGroupListSheetT if (pIS && pIS->Family == ITEMFAMILY::GUILD_OPTION) { text+= "\n" + CI18N::get("uiBotChatSkillPointCost") + toString(pIS->GuildOption.XPCost); - text+= "\n" + CI18N::get("uiBotChatPrice") + toString(pIS->GuildOption.MoneyCost); + text+= "\n" + CI18N::get("uiBotChatPrice") + NLMISC::formatThousands(toString(pIS->GuildOption.MoneyCost)); guildOption= true; } } @@ -376,10 +377,10 @@ void CDBGroupListSheetTrade::CSheetChildTrade::updateViewText(CDBGroupListSheetT if (LastPrice > 0) { if(displayMulPrice) - text+= "\n" + CI18N::get("uiBotChatPrice") + toString(sint32(LastPrice * priceFactor)) + " (" - + toString( sint32(factor) * sint32(LastPrice * priceFactor) ) + ")"; + text+= "\n" + CI18N::get("uiBotChatPrice") + NLMISC::formatThousands(toString(sint32(LastPrice * priceFactor))) + " (" + + NLMISC::formatThousands(toString( sint32(factor) * sint32(LastPrice * priceFactor) )) + ")"; else - text+= "\n" + CI18N::get("uiBotChatPrice") + toString( sint32(factor * LastPrice * priceFactor) ); + text+= "\n" + CI18N::get("uiBotChatPrice") + NLMISC::formatThousands(toString( sint32(factor * LastPrice * priceFactor) )); } if ((LastFactionPointPrice != 0) && (LastFactionType >= PVP_CLAN::BeginClans) && (LastFactionType <= PVP_CLAN::EndClans)) @@ -390,7 +391,7 @@ void CDBGroupListSheetTrade::CSheetChildTrade::updateViewText(CDBGroupListSheetT text+= "\n"; text+= CI18N::get("uiBotChatFactionType") + PVP_CLAN::toString((PVP_CLAN::TPVPClan)LastFactionType) - + CI18N::get("uiBotChatFactionPointPrice") + toString(LastFactionPointPrice); + + CI18N::get("uiBotChatFactionPointPrice") + NLMISC::formatThousands(toString(LastFactionPointPrice)); } // some additional info for resale @@ -402,10 +403,10 @@ void CDBGroupListSheetTrade::CSheetChildTrade::updateViewText(CDBGroupListSheetT { // append price if(pIS && pIS->Stackable>1 && zeFather->getMultiplyPriceByQuantityFlag()) - text+= CI18N::get("uiBotChatRetirePrice") + toString(LastPriceRetire) + " (" - + toString(factor * LastPriceRetire) + ")"; + text+= CI18N::get("uiBotChatRetirePrice") + NLMISC::formatThousands(toString(LastPriceRetire)) + " (" + + NLMISC::formatThousands(toString(factor * LastPriceRetire)) + ")"; else - text+= CI18N::get("uiBotChatRetirePrice") + toString(factor * LastPriceRetire); + text+= CI18N::get("uiBotChatRetirePrice") + NLMISC::formatThousands(toString(factor * LastPriceRetire)); // set resale time left ucstring fmt= CI18N::get("uiBotChatResaleTimeLeft"); strFindReplace(fmt, "%d", toString(LastResaleTimeLeft/RYZOM_DAY_IN_HOUR)); @@ -482,6 +483,12 @@ bool CDBGroupListSheetTrade::CSheetChildTrade::isSheetValid(CDBGroupListSheetTex return false; } + // Locked by owner; cannot trade + if (Ctrl->getLockedByOwner()) + { + return false; + } + // Check seller type? TSellerTypeFilter stf= father->getSellerTypeFilter(); if( stf != None) diff --git a/code/ryzom/client/src/interface_v3/dbview_number.cpp b/code/ryzom/client/src/interface_v3/dbview_number.cpp index 8ca6e7c94..5ac955659 100644 --- a/code/ryzom/client/src/interface_v3/dbview_number.cpp +++ b/code/ryzom/client/src/interface_v3/dbview_number.cpp @@ -21,6 +21,7 @@ #include "dbview_number.h" #include "interface_manager.h" #include "game_share/xml_auto_ptr.h" +#include "nel/misc/common.h" using namespace std; using namespace NL3D; @@ -102,30 +103,6 @@ bool CDBViewNumber::parse (xmlNodePtr cur, CInterfaceGroup * parentGroup) return true; } -// *************************************************************************** -// Helper function -ucstring formatThousands(const ucstring& s, const ucstring& separator) -{ - int j; - int k; - int topI = s.length() - 1; - - if (topI < 4) return s; - - ucstring ns; - do - { - for (j = topI, k = 0; j >= 0 && k < 3; --j, ++k ) - { - ns = s[j] + ns; // new char is added to front of ns - if( j > 0 && k == 2) ns = separator + ns; // j > 0 means still more digits - } - topI -= 3; - - } while(topI >= 0); - return ns; -} - // *************************************************************************** void CDBViewNumber::checkCoords() { @@ -134,8 +111,7 @@ void CDBViewNumber::checkCoords() if (_Cache != val) { _Cache= val; - static ucstring separator = NLMISC::CI18N::get("uiThousandsSeparator"); - ucstring value = _Format ? formatThousands(toString(val), separator) : toString(val); + ucstring value = _Format ? NLMISC::formatThousands(toString(val)) : toString(val); if (_Positive) setText(val >= 0 ? ( ucstring(_Prefix) + value + ucstring(_Suffix) ) : ucstring("?")); else setText( ucstring(_Prefix) + value + ucstring(_Suffix) ); } diff --git a/code/ryzom/client/src/interface_v3/group_html.cpp b/code/ryzom/client/src/interface_v3/group_html.cpp index 8ce18fb77..388064131 100644 --- a/code/ryzom/client/src/interface_v3/group_html.cpp +++ b/code/ryzom/client/src/interface_v3/group_html.cpp @@ -34,6 +34,7 @@ extern "C" #include "view_link.h" #include "ctrl_scroll.h" #include "ctrl_button.h" +#include "dbctrl_sheet.h" #include "ctrl_text_button.h" #include "action_handler.h" #include "group_paragraph.h" @@ -63,13 +64,55 @@ using namespace NLMISC; CGroupHTML *CGroupHTML::_ConnectingLock = NULL; extern CActionsContext ActionsContext; -// Check if domain is on TrustedDomain -bool CGroupHTML::isTrustedDomain(const string &domain) { +// Check if domain is on TrustedDomain +bool CGroupHTML::isTrustedDomain(const string &domain) +{ vector::iterator it; it = find (ClientCfg.WebIgTrustedDomains.begin(), ClientCfg.WebIgTrustedDomains.end(), domain); return it != ClientCfg.WebIgTrustedDomains.end(); } +void CGroupHTML::setImage(CViewBase * view, const string &file) +{ + CCtrlButton *btn = dynamic_cast(view); + if(btn) + { + btn->setTexture (file); + btn->setTexturePushed(file); + btn->invalidateCoords(); + btn->invalidateContent(); + btn->resetInvalidCoords(); + btn->updateCoords(); + paragraphChange(); + } + else + { + CViewBitmap *btm = dynamic_cast(view); + if(btm) + { + btm->setTexture (file); + btm->invalidateCoords(); + btm->invalidateContent(); + btm->resetInvalidCoords(); + btm->updateCoords(); + paragraphChange(); + } + else + { + CGroupCell *btgc = dynamic_cast(view); + if(btgc) + { + btgc->setTexture (file); + btgc->invalidateCoords(); + btgc->invalidateContent(); + btgc->resetInvalidCoords(); + btgc->updateCoords(); + paragraphChange(); + } + } + } +} + // Get an url and return the local filename with the path where the url image should be string CGroupHTML::localImageName(const string &url) { @@ -99,30 +142,38 @@ void CGroupHTML::addImageDownload(const string &url, CViewBase *img) curl_easy_setopt(curl, CURLOPT_NOPROGRESS, true); curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); - string dest = localImageName(url)+".tmp"; + string dest = localImageName(url); + string tmpdest = localImageName(url)+".tmp"; #ifdef LOG_DL nlwarning("add to download '%s' dest '%s' img %p", url.c_str(), dest.c_str(), img); #endif - // create the local file - if (NLMISC::CFile::fileExists(dest)) - { - CFile::setRWAccess(dest); - NLMISC::CFile::deleteFile(dest); - } - FILE *fp = fopen (dest.c_str(), "wb"); - if (fp == NULL) - { - nlwarning("Can't open file '%s' for writing: code=%d '%s'", dest.c_str (), errno, strerror(errno)); - return; - } - curl_easy_setopt(curl, CURLOPT_FILE, fp); - curl_multi_add_handle(MultiCurl, curl); - Curls.push_back(CDataDownload(curl, url, fp, ImgType, img, "", "")); -#ifdef LOG_DL - nlwarning("adding handle %x, %d curls", curl, Curls.size()); -#endif - RunningCurls++; + // erase the tmp file if exists + if (NLMISC::CFile::fileExists(tmpdest)) + NLMISC::CFile::deleteFile(tmpdest); + + if (!NLMISC::CFile::fileExists(dest)) + { + + FILE *fp = fopen (tmpdest.c_str(), "wb"); + if (fp == NULL) + { + nlwarning("Can't open file '%s' for writing: code=%d '%s'", tmpdest.c_str (), errno, strerror(errno)); + return; + } + curl_easy_setopt(curl, CURLOPT_FILE, fp); + + curl_multi_add_handle(MultiCurl, curl); + Curls.push_back(CDataDownload(curl, url, fp, ImgType, img, "", "")); + #ifdef LOG_DL + nlwarning("adding handle %x, %d curls", curl, Curls.size()); + #endif + RunningCurls++; + } + else + { + setImage(img, dest); + } } void CGroupHTML::initImageDownload() @@ -297,41 +348,11 @@ void CGroupHTML::checkDownloads() for(uint i = 0; i < it->imgs.size(); i++) { // don't display image that are not power of 2 - uint32 w, h; - CBitmap::loadSize (file, w, h); - if (w == 0 || h == 0 || ((!NLMISC::isPowerOf2(w) || !NLMISC::isPowerOf2(h)) && !NL3D::CTextureFile::supportNonPowerOfTwoTextures())) - file.clear(); - - CCtrlButton *btn = dynamic_cast(it->imgs[i]); - if(btn) - { - #ifdef LOG_DL - nlwarning("refresh new downloading image %d button %p", i, it->imgs[i]); - #endif - btn->setTexture (file); - btn->setTexturePushed(file); - btn->invalidateCoords(); - btn->invalidateContent(); - btn->resetInvalidCoords(); - btn->updateCoords(); - paragraphChange(); - } - else - { - CViewBitmap *btm = dynamic_cast(it->imgs[i]); - if(btm) - { - #ifdef LOG_DL - nlwarning("refresh new downloading image %d image %p", i, it->imgs[i]); - #endif - btm->setTexture (file); - btm->invalidateCoords(); - btm->invalidateContent(); - btm->resetInvalidCoords(); - btm->updateCoords(); - paragraphChange(); - } - } + //uint32 w, h; + //CBitmap::loadSize (file, w, h); + //if (w == 0 || h == 0 || ((!NLMISC::isPowerOf2(w) || !NLMISC::isPowerOf2(h)) && !NL3D::CTextureFile::supportNonPowerOfTwoTextures())) + // file.clear(); + setImage(it->imgs[i], file); } } } @@ -446,6 +467,28 @@ void CGroupHTML::beginBuild () } +TStyle CGroupHTML::parseStyle (const string &str_styles) +{ + TStyle styles; + vector elements; + NLMISC::splitString(str_styles, ";", elements); + + for(uint i = 0; i < elements.size(); ++i) + { + vector style; + NLMISC::splitString(elements[i], ":", style); + if (style.size() >= 2) + { + string fullstyle = style[1]; + for (uint j=2; j < style.size(); j++) + fullstyle += ":"+style[j]; + styles[trim(style[0])] = fullstyle; + } + } + + return styles; +} + // *************************************************************************** void CGroupHTML::addText (const char * buf, int len) @@ -556,9 +599,31 @@ void CGroupHTML::addLink (uint element_number, uint /* attribute_number */, HTCh _Link.push_back(""); } } + + for(uint8 i = MY_HTML_A_ACCESSKEY; i < MY_HTML_A_Z_ACTION_SHORTCUT; i++) + { + if (present[i] && value[i]) + { + string title = value[i]; + // nlinfo("key %d = %s", i, title.c_str()); + } + } + //nlinfo("key of TITLE is : %d", MY_HTML_A_Z_ACTION_PARAMS); + if (present[MY_HTML_A_Z_ACTION_PARAMS] && value[MY_HTML_A_Z_ACTION_PARAMS]) + { + string title = value[MY_HTML_A_Z_ACTION_PARAMS]; + _LinkTitle.push_back(title); + } + else + _LinkTitle.push_back(""); } else + { _Link.push_back(""); + _LinkTitle.push_back(""); + } + + } } } @@ -626,7 +691,6 @@ static const char *scanColorComponent(const char *src, uint8 &intensity) return src; } - class CNameToCol { public: @@ -831,6 +895,11 @@ void CGroupHTML::beginElement (uint element_number, const BOOL *present, const c _GlobalColor.push_back(LinkColorGlobalColor); _A.push_back(true); + if (present[MY_HTML_A_TITLE] && value[MY_HTML_A_TITLE]) + _LinkTitle.push_back(value[MY_HTML_A_TITLE]); + if (present[MY_HTML_A_CLASS] && value[MY_HTML_A_CLASS]) + _LinkClass.push_back(value[MY_HTML_A_CLASS]); + // Quick help if (_TrustedDomain && present[MY_HTML_A_Z_ACTION_SHORTCUT] && value[MY_HTML_A_Z_ACTION_SHORTCUT]) { @@ -856,15 +925,87 @@ void CGroupHTML::beginElement (uint element_number, const BOOL *present, const c } } } + break; case HTML_DIV: { if (present[MY_HTML_DIV_NAME] && value[MY_HTML_DIV_NAME]) - { _DivName = value[MY_HTML_DIV_NAME]; + + string instClass; + if (present[MY_HTML_DIV_CLASS] && value[MY_HTML_DIV_CLASS]) + instClass = value[MY_HTML_DIV_CLASS]; + + // use generic template system + if (_TrustedDomain && !instClass.empty() && instClass == "ryzom-ui-grouptemplate") + { + string id; + if (present[MY_HTML_DIV_ID] && value[MY_HTML_DIV_ID]) + id = value[MY_HTML_DIV_ID]; + + string style; + if (present[MY_HTML_DIV_STYLE] && value[MY_HTML_DIV_STYLE]) + style = value[MY_HTML_DIV_STYLE]; + + typedef pair TTmplParam; + vector tmplParams; + + string templateName; + if (!style.empty()) + { + TStyle styles = parseStyle(style); + TStyle::iterator it; + for (it=styles.begin(); it != styles.end(); it++) + { + if ((*it).first == "template") + templateName = (*it).second; + else + tmplParams.push_back(TTmplParam((*it).first, (*it).second)); + } + } + + if (!templateName.empty()) + { + string parentId; + bool haveParentDiv = getDiv() != NULL; + if (haveParentDiv) + parentId = getDiv()->getId(); + else + parentId = _Paragraph->getId(); + + CInterfaceManager *im = CInterfaceManager::getInstance(); + CInterfaceGroup *inst = im->createGroupInstance(templateName, parentId+":"+id, tmplParams); + if (inst) + { + inst->setId(parentId+":"+id); + inst->updateCoords(); + if (haveParentDiv) + { + inst->setParent(getDiv()); + inst->setParentSize(getDiv()); + inst->setParentPos(getDiv()); + inst->setPosRef(Hotspot_TL); + inst->setParentPosRef(Hotspot_TL); + getDiv()->addGroup(inst); + } + else + { + if (!_Paragraph) + { + newParagraph (0); + paragraphChange (); + } + + getParagraph()->addChild(inst); + paragraphChange(); + } + _Divs.push_back(inst); + } + } } } break; + case HTML_FONT: { bool found = false; @@ -898,11 +1039,42 @@ void CGroupHTML::beginElement (uint element_number, const BOOL *present, const c addString(ucstring ("\n")); break; case HTML_BODY: - if (present[HTML_BODY_BGCOLOR] && value[HTML_BODY_BGCOLOR]) { - // Get the color - CRGBA bgColor = getColor (value[HTML_BODY_BGCOLOR]); - setBackgroundColor (bgColor); + if (present[HTML_BODY_BGCOLOR] && value[HTML_BODY_BGCOLOR]) + { + CRGBA bgColor = getColor (value[HTML_BODY_BGCOLOR]); + setBackgroundColor (bgColor); + } + + string style; + if (present[HTML_BODY_STYLE] && value[HTML_BODY_STYLE]) + style = value[HTML_BODY_STYLE]; + + + if (!style.empty()) + { + TStyle styles = parseStyle(style); + TStyle::iterator it; + + it = styles.find("background-repeat"); + bool repeat = (it != styles.end() && it->second == "1"); + + // Webig only + it = styles.find("background-scale"); + bool scale = (it != styles.end() && it->second == "1"); + + it = styles.find("background-image"); + if (it != styles.end()) + { + string image = it->second; + string::size_type texExt = strlwr(image).find("url("); + // Url image + if (texExt != string::npos) + // Remove url() + image = image.substr(4, image.size()-5); + setBackground (image, scale, repeat); + } + } } break; case HTML_FORM: @@ -1000,7 +1172,24 @@ void CGroupHTML::beginElement (uint element_number, const BOOL *present, const c } else { - addImage (value[MY_HTML_IMG_SRC], globalColor); + // Get the option to reload (class==reload) + bool reloadImg = false; + + string style; + if (present[MY_HTML_IMG_STYLE] && value[MY_HTML_IMG_STYLE]) + style = value[MY_HTML_IMG_STYLE]; + + if (!style.empty()) + { + TStyle styles = parseStyle(style); + TStyle::iterator it; + + it = styles.find("reload"); + if (it != styles.end() && (*it).second == "1") + reloadImg = true; + } + + addImage (value[MY_HTML_IMG_SRC], globalColor, reloadImg); } } } @@ -1312,8 +1501,43 @@ void CGroupHTML::beginElement (uint element_number, const BOOL *present, const c if (!_Cells.empty()) { _Cells.back() = new CGroupCell(CViewBase::TCtorParam()); + string style; + if (present[MY_HTML_TD_STYLE] && value[MY_HTML_TD_STYLE]) + style = value[MY_HTML_TD_STYLE]; // Set the cell parameters + if (!style.empty()) + { + TStyle styles = parseStyle(style); + TStyle::iterator it; + + it = styles.find("background-repeat"); + _Cells.back()->setTextureTile(it != styles.end()); + + // Webig only + it = styles.find("background-scale"); + _Cells.back()->setTextureScale(it != styles.end()); + + it = styles.find("background-image"); + if (it != styles.end()) + { + nlinfo("found background-image %s", it->second.c_str()); + string image = (*it).second; + string::size_type texExt = strlwr(image).find("url("); + // Url image + if (texExt != string::npos) + { + // Remove url() + image = image.substr(4, image.size()-5); + addImageDownload(image, _Cells.back()); + // Image in BNP + } + else + { + _Cells.back()->setTexture(image); + } + } + } _Cells.back()->BgColor = _CellParams.back().BgColor; _Cells.back()->Align = _CellParams.back().Align; _Cells.back()->VAlign = _CellParams.back().VAlign; @@ -1435,6 +1659,8 @@ void CGroupHTML::endElement (uint element_number) popIfNotEmpty (_GlobalColor); popIfNotEmpty (_A); popIfNotEmpty (_Link); + popIfNotEmpty (_LinkTitle); + popIfNotEmpty (_LinkClass); break; case HTML_H1: case HTML_H2: @@ -1452,6 +1678,7 @@ void CGroupHTML::endElement (uint element_number) break; case HTML_DIV: _DivName = ""; + popIfNotEmpty (_Divs); break; case HTML_TABLE: @@ -1551,7 +1778,7 @@ void CGroupHTML::endElement (uint element_number) if (addBnpDownload(_ObjectData, _ObjectAction, _ObjectScript, _ObjectMD5Sum)) { CInterfaceManager *pIM = CInterfaceManager::getInstance(); - pIM->executeLuaScript(_ObjectScript, true); + pIM->executeLuaScript("\nlocal __ALLREADYDL__=true\n"+_ObjectScript, true); } _ObjectScript = ""; } @@ -1586,6 +1813,7 @@ void CGroupHTML::endUnparsedElement(const char *buffer, int length) _ParsingLua = false; // execute the embeded lua script CInterfaceManager *pIM = CInterfaceManager::getInstance(); + _LuaScript = "\nlocal __CURRENT_WINDOW__=\""+this->_Id+"\" \n"+_LuaScript; pIM->executeLuaScript(_LuaScript, true); } } @@ -2211,40 +2439,77 @@ void CGroupHTML::addString(const ucstring &str) // Not added ? if (!added) { - CViewLink *newLink = new CViewLink(CViewBase::TCtorParam()); - if (getA()) + if (getA() && string(getLinkClass()) == "ryzom-ui-button") { - newLink->Link = getLink(); - if (!newLink->Link.empty()) - { - newLink->setHTMLView (this); - newLink->setUnderlined (true); - } - } - newLink->setText(tmpStr); - newLink->setColor(getTextColor()); - newLink->setFontSize(getFontSize()); - newLink->setMultiLineSpace((uint)((float)getFontSize()*LineSpaceFontFactor)); - newLink->setMultiLine(true); - newLink->setModulateGlobalColor(getGlobalColor()); - // newLink->setLineAtBottom (true); + string buttonTemplate = DefaultButtonGroup; + // Action handler parameters : "name=group_html_id|form=id_of_the_form|submit_button=button_name" + string param = "name=" + this->_Id + "|url=" + getLink(); - if (getA() && !newLink->Link.empty()) - { - getParagraph()->addChildLink(newLink); + CInterfaceManager *im = CInterfaceManager::getInstance(); + typedef pair TTmplParam; + vector tmplParams; + tmplParams.push_back(TTmplParam("id", "")); + tmplParams.push_back(TTmplParam("onclick", "browse")); + tmplParams.push_back(TTmplParam("onclick_param", param)); + tmplParams.push_back(TTmplParam("active", "true")); + CInterfaceGroup *buttonGroup = im->createGroupInstance(buttonTemplate, _Paragraph->getId(), tmplParams); + if (buttonGroup) + { + + // Add the ctrl button + CCtrlTextButton *ctrlButton = dynamic_cast(buttonGroup->getCtrl("button")); + if (!ctrlButton) ctrlButton = dynamic_cast(buttonGroup->getCtrl("b")); + if (ctrlButton) + { + ctrlButton->setModulateGlobalColorAll (false); + + // Translate the tooltip + ctrlButton->setDefaultContextHelp(ucstring::makeFromUtf8(getLinkTitle())); + ctrlButton->setText(tmpStr); + } + getParagraph()->addChild (buttonGroup); + paragraphChange (); + } + } else { - getParagraph()->addChild(newLink); + CViewLink *newLink = new CViewLink(CViewBase::TCtorParam()); + if (getA()) + { + newLink->Link = getLink(); + newLink->LinkTitle = getLinkTitle(); + if (!newLink->Link.empty()) + { + newLink->setHTMLView (this); + newLink->setUnderlined (true); + } + } + newLink->setText(tmpStr); + newLink->setColor(getTextColor()); + newLink->setFontSize(getFontSize()); + newLink->setMultiLineSpace((uint)((float)getFontSize()*LineSpaceFontFactor)); + newLink->setMultiLine(true); + newLink->setModulateGlobalColor(getGlobalColor()); + // newLink->setLineAtBottom (true); + + if (getA() && !newLink->Link.empty()) + { + getParagraph()->addChildLink(newLink); + } + else + { + getParagraph()->addChild(newLink); + } + paragraphChange (); } - paragraphChange (); } } } // *************************************************************************** -void CGroupHTML::addImage(const char *img, bool globalColor) +void CGroupHTML::addImage(const char *img, bool globalColor, bool reloadImg) { // In a paragraph ? if (_Paragraph) @@ -2268,6 +2533,7 @@ void CGroupHTML::addImage(const char *img, bool globalColor) newImage->Link = getLink(); newImage->setHTMLView (this); }*/ + newImage->setRenderLayer(getRenderLayer()+1); newImage->setTexture (finalUrl); newImage->setModulateGlobalColor(globalColor); @@ -2284,7 +2550,7 @@ void CGroupHTML::addImage(const char *img, bool globalColor) // 2/ if it doesn't work, try to load the image in cache // image = localImageName(img); - if (lookupLocalFile (finalUrl, image.c_str(), false)) + if (!reloadImg && lookupLocalFile (finalUrl, image.c_str(), false)) { // No more text in this text view _CurrentViewLink = NULL; @@ -2314,7 +2580,9 @@ void CGroupHTML::addImage(const char *img, bool globalColor) else*/ getParagraph()->addChild(newImage); paragraphChange (); - } else { + } + else + { // // 3/ if it doesn't work, display a placeholder and ask to dl the image into the cache @@ -2527,6 +2795,9 @@ CCtrlButton *CGroupHTML::addButton(CCtrlButton::EType type, const std::string &/ ctrlButton->setInstantContextHelp(true); ctrlButton->setToolTipParent(TTMouse); + ctrlButton->setToolTipParentPosRef(Hotspot_TTAuto); + ctrlButton->setToolTipPosRef(Hotspot_TTAuto); + ctrlButton->setActionOnLeftClickParams(tooltip); } getParagraph()->addChild (ctrlButton); @@ -2556,6 +2827,7 @@ void CGroupHTML::clearContext() _UL.clear(); _A.clear(); _Link.clear(); + _LinkTitle.clear(); _Tables.clear(); _Cells.clear(); _TR.clear(); @@ -2632,6 +2904,9 @@ CInterfaceGroup *CGroupHTML::getCurrentGroup() void CGroupHTML::addGroup (CInterfaceGroup *group, uint beginSpace) { + if (!group) + return; + // Remove previous paragraph if empty if (_Paragraph && (_Paragraph->getNumChildren() == 0)) { @@ -2796,7 +3071,30 @@ void CGroupHTML::setBackgroundColor (const CRGBA &bgcolor) { // Change the background color bitmap->setColor (bgcolor); - bitmap->setModulateGlobalColor(true); + bitmap->setModulateGlobalColor(false); + } + } +} + +// *************************************************************************** + +void CGroupHTML::setBackground (const string &bgtex, bool scale, bool tile) +{ + // Should have a child named bg + CViewBase *view = getView (DefaultBackgroundBitmapView); + if (view) + { + CViewBitmap *bitmap = dynamic_cast (view); + if (bitmap) + { + bitmap->setParentPosRef(Hotspot_TL); + bitmap->setPosRef(Hotspot_TL); + bitmap->setX(0); + bitmap->setY(0); + bitmap->setRenderLayer(-2); + bitmap->setScale(scale); + bitmap->setTile(tile); + addImageDownload(bgtex, view); } } } @@ -2897,9 +3195,6 @@ void CGroupHTML::handle () _Browsing = true; updateRefreshButton(); - // Add custom get params - addHTTPGetParams (finalUrl); - // Save new url _URL = finalUrl; @@ -2910,6 +3205,10 @@ void CGroupHTML::handle () initLibWWW(); _TrustedDomain = isTrustedDomain(setCurrentDomain(finalUrl)); + // Add custom get params + addHTTPGetParams (finalUrl, _TrustedDomain); + + // Get the final URL C3WSmartPtr uri = HTParse(finalUrl.c_str(), NULL, PARSE_ALL); @@ -3030,7 +3329,7 @@ void CGroupHTML::handle () HTParseFormInput(formfields, (_PostFormSubmitButton + "_y=0").c_str()); // Add custom params - addHTTPPostParams (formfields); + addHTTPPostParams(formfields, _TrustedDomain); // Reset the title if(_TitlePrefix.empty()) @@ -3146,13 +3445,13 @@ void CGroupHTML::endBuild () // *************************************************************************** -void CGroupHTML::addHTTPGetParams (string &/* url */) +void CGroupHTML::addHTTPGetParams (string &/* url */, bool /*trustedDomain*/) { } // *************************************************************************** -void CGroupHTML::addHTTPPostParams (HTAssocList * /* formfields */) +void CGroupHTML::addHTTPPostParams (HTAssocList * /* formfields */, bool /*trustedDomain*/) { } @@ -3401,7 +3700,7 @@ int CGroupHTML::luaRefresh(CLuaState &ls) // *************************************************************************** int CGroupHTML::luaRemoveContent(CLuaState &ls) { - const char *funcName = "refresh"; + const char *funcName = "removeContent"; CLuaIHM::checkArgCount(ls, funcName, 0); removeContent(); return 0; diff --git a/code/ryzom/client/src/interface_v3/group_html.h b/code/ryzom/client/src/interface_v3/group_html.h index d155c6d3f..098fbb4ff 100644 --- a/code/ryzom/client/src/interface_v3/group_html.h +++ b/code/ryzom/client/src/interface_v3/group_html.h @@ -30,6 +30,8 @@ #include "ctrl_button.h" #include "group_table.h" +typedef std::map TStyle; + extern "C" { #include "WWWInit.h" @@ -147,6 +149,7 @@ public: std::string DefaultCheckBoxBitmapPushed; std::string DefaultCheckBoxBitmapOver; std::string DefaultBackgroundBitmapView; + std::string CurrentLinkTitle; // Browser home std::string Home; @@ -216,10 +219,10 @@ protected : virtual void endUnparsedElement(const char *buffer, int length); // Add GET params to the url - virtual void addHTTPGetParams (std::string &url); + virtual void addHTTPGetParams (std::string &url, bool trustedDomain); // Add POST params to the libwww list - virtual void addHTTPPostParams (HTAssocList *formfields); + virtual void addHTTPPostParams (HTAssocList *formfields, bool trustedDomain); // the current request is terminated virtual void requestTerminated(HTRequest *request); @@ -227,6 +230,9 @@ protected : // Get Home URL virtual std::string home(); + // Parse style html tag + TStyle parseStyle(const std::string &str_styles); + // Handle some work at each pass virtual void handle (); @@ -251,7 +257,7 @@ protected : void addString(const ucstring &str); // Add an image in the current paragraph - void addImage(const char *image, bool globalColor); + void addImage(const char *image, bool globalColor, bool reloadImg=false); // Add a text area in the current paragraph CInterfaceGroup *addTextArea (const std::string &templateName, const char *name, uint rows, uint cols, bool multiLine, const ucstring &content); @@ -266,6 +272,9 @@ protected : // Set the background color void setBackgroundColor (const NLMISC::CRGBA &bgcolor); + // Set the background + void setBackground (const std::string &bgtex, bool scale, bool tile); + // Force the current string to be in a single string void flushString(); @@ -281,7 +290,7 @@ protected : // Current URL std::string _URL; - // Current DOMAIN + // Current DOMAIN bool _TrustedDomain; // Title prefix @@ -397,6 +406,30 @@ protected : return _Link.back().c_str(); } + std::vector _LinkTitle; + inline const char *getLinkTitle() const + { + if (_LinkTitle.empty()) + return ""; + return _LinkTitle.back().c_str(); + } + std::vector _LinkClass; + inline const char *getLinkClass() const + { + if (_LinkClass.empty()) + return ""; + return _LinkClass.back().c_str(); + } + + // Divs (i.e. interface group) + std::vector _Divs; + inline CInterfaceGroup *getDiv() const + { + if (_Divs.empty()) + return NULL; + return _Divs.back(); + } + // Tables std::vector _Tables; inline CGroupTable *getTable() const @@ -475,6 +508,7 @@ protected : NoWrap = false; } NLMISC::CRGBA BgColor; + std::string Style; CGroupCell::TAlign Align; CGroupCell::TVAlign VAlign; sint32 LeftMargin; @@ -582,9 +616,9 @@ private: void checkImageDownload(); void addImageDownload(const std::string &url, CViewBase *img); std::string localImageName(const std::string &url); + bool isTrustedDomain(const std::string &domain); - - + void setImage(CViewBase *view, const std::string &file); // BnpDownload system void initBnpDownload(); diff --git a/code/ryzom/client/src/interface_v3/group_html_cs.cpp b/code/ryzom/client/src/interface_v3/group_html_cs.cpp index 66d884437..13d7dda24 100644 --- a/code/ryzom/client/src/interface_v3/group_html_cs.cpp +++ b/code/ryzom/client/src/interface_v3/group_html_cs.cpp @@ -24,6 +24,7 @@ #include "group_html_cs.h" #include "game_share/xml_auto_ptr.h" #include "../client_cfg.h" +#include "interface_manager.h" // used for login cookie to be sent to the web server #include "../net_manager.h" @@ -49,7 +50,7 @@ CGroupHTMLCS::~CGroupHTMLCS() // *************************************************************************** -void CGroupHTMLCS::addHTTPGetParams (string &url) +void CGroupHTMLCS::addHTTPGetParams (string &url, bool /*trustedDomain*/) { url += ((url.find('?') != string::npos) ? "&" : "?"); @@ -69,7 +70,7 @@ void CGroupHTMLCS::addHTTPGetParams (string &url) // *************************************************************************** -void CGroupHTMLCS::addHTTPPostParams (HTAssocList *formfields) +void CGroupHTMLCS::addHTTPPostParams (HTAssocList *formfields, bool /*trustedDomain*/) { std::vector parameters; getParameters (parameters, false); @@ -120,6 +121,15 @@ void CGroupHTMLCS::getParameters (std::vector ¶meters, bool enco string s = getDebugInformation(); s += getSystemInformation(); + static bool webIgReady = false; + + if (!webIgReady) // Webig is ready when getParameters of CGroupHTMLCS is called + { + webIgReady = true; + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + pIM->executeLuaScript("game:onWebIgReady()"); + } + // For each line string::size_type startOfLine = 0; string::size_type endOfLine; diff --git a/code/ryzom/client/src/interface_v3/group_html_cs.h b/code/ryzom/client/src/interface_v3/group_html_cs.h index a37b2b50c..e3c8a765e 100644 --- a/code/ryzom/client/src/interface_v3/group_html_cs.h +++ b/code/ryzom/client/src/interface_v3/group_html_cs.h @@ -39,8 +39,8 @@ public: ~CGroupHTMLCS(); // From CGroupHTML - virtual void addHTTPGetParams (std::string &url); - virtual void addHTTPPostParams (HTAssocList *formfields); + virtual void addHTTPGetParams (std::string &url, bool trustedDomain); + virtual void addHTTPPostParams (HTAssocList *formfields, bool trustedDomain); virtual std::string home(); private: diff --git a/code/ryzom/client/src/interface_v3/group_html_forum.cpp b/code/ryzom/client/src/interface_v3/group_html_forum.cpp index b0fd96642..53d1058d9 100644 --- a/code/ryzom/client/src/interface_v3/group_html_forum.cpp +++ b/code/ryzom/client/src/interface_v3/group_html_forum.cpp @@ -51,9 +51,9 @@ CGroupHTMLForum::~CGroupHTMLForum() // *************************************************************************** -void CGroupHTMLForum::addHTTPGetParams (string &url) +void CGroupHTMLForum::addHTTPGetParams (string &url, bool /*trustedDomain*/) { - ucstring user_name = UserEntity->getDisplayName (); + ucstring user_name = UserEntity->getLoginName (); const SGuild &guild = CGuildManager::getInstance()->getGuild(); string gname = guild.Name.toUtf8(); @@ -83,9 +83,9 @@ void CGroupHTMLForum::addHTTPGetParams (string &url) // *************************************************************************** -void CGroupHTMLForum::addHTTPPostParams (HTAssocList *formfields) +void CGroupHTMLForum::addHTTPPostParams (HTAssocList *formfields, bool /*trustedDomain*/) { - ucstring user_name = UserEntity->getDisplayName (); + ucstring user_name = UserEntity->getLoginName (); const SGuild &guild = CGuildManager::getInstance()->getGuild(); string gname = guild.Name.toUtf8(); @@ -115,12 +115,13 @@ string CGroupHTMLForum::home () void CGroupHTMLForum::handle () { - // Do nothing if WebServer is not initialized +/* // Do nothing if WebServer is not initialized if (!WebServer.empty()) { Home = WebServer+"forum.php"; CGroupHTML::handle (); } +*/ } // *************************************************************************** diff --git a/code/ryzom/client/src/interface_v3/group_html_forum.h b/code/ryzom/client/src/interface_v3/group_html_forum.h index 8458609c6..fe233fecc 100644 --- a/code/ryzom/client/src/interface_v3/group_html_forum.h +++ b/code/ryzom/client/src/interface_v3/group_html_forum.h @@ -39,8 +39,8 @@ public: ~CGroupHTMLForum(); // From CGroupHTML - virtual void addHTTPGetParams (std::string &url); - virtual void addHTTPPostParams (HTAssocList *formfields); + virtual void addHTTPGetParams (std::string &url, bool trustedDomain); + virtual void addHTTPPostParams (HTAssocList *formfields, bool trustedDomain); virtual std::string home(); virtual void handle (); diff --git a/code/ryzom/client/src/interface_v3/group_html_mail.cpp b/code/ryzom/client/src/interface_v3/group_html_mail.cpp index 2c0d9d225..9c723d45b 100644 --- a/code/ryzom/client/src/interface_v3/group_html_mail.cpp +++ b/code/ryzom/client/src/interface_v3/group_html_mail.cpp @@ -50,9 +50,9 @@ CGroupHTMLMail::~CGroupHTMLMail() // *************************************************************************** -void CGroupHTMLMail::addHTTPGetParams (string &url) +void CGroupHTMLMail::addHTTPGetParams (string &url, bool /*trustedDomain*/) { - ucstring user_name = UserEntity->getDisplayName (); + ucstring user_name = UserEntity->getLoginName (); url += ((url.find('?') != string::npos) ? "&" : "?") + string("shard=") + toString(CharacterHomeSessionId) + string("&user_login=") + user_name.toString() + @@ -62,9 +62,9 @@ void CGroupHTMLMail::addHTTPGetParams (string &url) // *************************************************************************** -void CGroupHTMLMail::addHTTPPostParams (HTAssocList *formfields) +void CGroupHTMLMail::addHTTPPostParams (HTAssocList *formfields, bool /*trustedDomain*/) { - ucstring user_name = UserEntity->getDisplayName (); + ucstring user_name = UserEntity->getLoginName (); HTParseFormInput(formfields, ("shard="+toString(CharacterHomeSessionId)).c_str()); HTParseFormInput(formfields, ("user_login="+user_name.toString()).c_str()); HTParseFormInput(formfields, ("session_cookie="+NetMngr.getLoginCookie().toString()).c_str()); @@ -85,11 +85,12 @@ string CGroupHTMLMail::home () void CGroupHTMLMail::handle () { // Do nothing if WebServer is not initialized - if (!WebServer.empty()) +/* if (!WebServer.empty()) { Home = WebServer+"mailbox.php"; CGroupHTML::handle (); } +*/ } // *************************************************************************** diff --git a/code/ryzom/client/src/interface_v3/group_html_mail.h b/code/ryzom/client/src/interface_v3/group_html_mail.h index bb72a3b78..51f363c3c 100644 --- a/code/ryzom/client/src/interface_v3/group_html_mail.h +++ b/code/ryzom/client/src/interface_v3/group_html_mail.h @@ -39,8 +39,8 @@ public: ~CGroupHTMLMail(); // From CGroupHTML - virtual void addHTTPGetParams (std::string &url); - virtual void addHTTPPostParams (HTAssocList *formfields); + virtual void addHTTPGetParams (std::string &url, bool trustedDomain); + virtual void addHTTPPostParams (HTAssocList *formfields, bool trustedDomain); virtual std::string home(); virtual void handle (); diff --git a/code/ryzom/client/src/interface_v3/group_html_webig.cpp b/code/ryzom/client/src/interface_v3/group_html_webig.cpp index 4a13d9806..e4a55ab48 100644 --- a/code/ryzom/client/src/interface_v3/group_html_webig.cpp +++ b/code/ryzom/client/src/interface_v3/group_html_webig.cpp @@ -20,6 +20,7 @@ #include "game_share/xml_auto_ptr.h" #include "../client_cfg.h" #include "../user_entity.h" +#include "../entities.h" #include "interface_manager.h" // used for login cookie to be sent to the web server @@ -55,7 +56,7 @@ static string getWebAuthKey() // authkey = uint32 cid = NetMngr.getLoginCookie().getUserId() * 16 + PlayerSelectedSlot; string rawKey = toString(CharacterHomeSessionId) + - UserEntity->getDisplayName().toString() + + UserEntity->getLoginName().toString() + toString(cid) + NetMngr.getLoginCookie().toString(); string key = getMD5((const uint8*)rawKey.c_str(), (uint32)rawKey.size()).toString(); @@ -64,18 +65,72 @@ static string getWebAuthKey() return key; } -void addWebIGParams (string &url) +void addWebIGParams (string &url, bool trustedDomain) { if(!UserEntity || !NetMngr.getLoginCookie().isValid()) return; uint32 cid = NetMngr.getLoginCookie().getUserId() * 16 + PlayerSelectedSlot; url += ((url.find('?') != string::npos) ? "&" : "?") + string("shardid=") + toString(CharacterHomeSessionId) + - string("&name=") + UserEntity->getDisplayName().toUtf8() + - string("&cid=") + toString(cid) + - string("&authkey=") + getWebAuthKey() + - string("&ig=1") + - string("&lang=") + CI18N::getCurrentLanguageCode(); + string("&name=") + UserEntity->getLoginName().toUtf8() + + string("&lang=") + CI18N::getCurrentLanguageCode() + + string("&ig=1"); + if (trustedDomain) + { + url += string("&cid=") + toString(cid) + + string("&authkey=") + getWebAuthKey(); + + if (url.find('$') != string::npos) + { + strFindReplace(url, "$datasetid$", toString(UserEntity->dataSetId())); + strFindReplace(url, "$gender$", GSGENDER::toString(UserEntity->getGender())); + strFindReplace(url, "$displayName$", UserEntity->getDisplayName().toString()); + strFindReplace(url, "$posx$", toString(UserEntity->pos().x)); + strFindReplace(url, "$posy$", toString(UserEntity->pos().y)); + strFindReplace(url, "$posz$", toString(UserEntity->pos().z)); + strFindReplace(url, "$post$", toString(atan2(UserEntity->front().y, UserEntity->front().x))); + + // Target fields + const char *dbPath = "UI:VARIABLES:TARGET:SLOT"; + CInterfaceManager *im = CInterfaceManager::getInstance(); + CCDBNodeLeaf *node = im->getDbProp(dbPath, false); + if (node && (uint8)node->getValue32() != (uint8) CLFECOMMON::INVALID_SLOT) + { + CEntityCL *target = EntitiesMngr.entity((uint) node->getValue32()); + if (target) + { + strFindReplace(url, "$tdatasetid$", toString(target->dataSetId())); + strFindReplace(url, "$tdisplayName$", target->getDisplayName().toString()); + strFindReplace(url, "$tposx$", toString(target->pos().x)); + strFindReplace(url, "$tposy$", toString(target->pos().y)); + strFindReplace(url, "$tposz$", toString(target->pos().z)); + strFindReplace(url, "$tpost$", toString(atan2(target->front().y, target->front().x))); + strFindReplace(url, "$tsheet$", target->sheetId().toString()); + string type; + if (target->isFauna()) + type = "fauna"; + else if (target->isNPC()) + type = "npc"; + else if (target->isPlayer()) + type = "player"; + else if (target->isUser()) + type = "user"; + strFindReplace(url, "$ttype$", target->sheetId().toString()); + } + else + { + strFindReplace(url, "$tdatasetid$", ""); + strFindReplace(url, "$tdisplayName$", ""); + strFindReplace(url, "$tposx$", ""); + strFindReplace(url, "$tposy$", ""); + strFindReplace(url, "$tposz$", ""); + strFindReplace(url, "$tpost$", ""); + strFindReplace(url, "$tsheet$", ""); + strFindReplace(url, "$ttype$", ""); + } + } + } + } } // *************************************************************************** @@ -204,7 +259,7 @@ struct CWebigNotificationThread : public NLMISC::IRunnable while (true) { string url = "http://"+ClientCfg.WebIgMainDomain+"/start/index.php?app=notif&rnd="+randomString(); - addWebIGParams(url); + addWebIGParams(url, true); get(url); nlSleep(10*60*1000); } @@ -230,11 +285,66 @@ void startWebigNotificationThread() // *************************************************************************** +// *************************************************************************** +NLMISC_REGISTER_OBJECT(CViewBase, CGroupHTMLAuth, std::string, "auth_html"); + +CGroupHTMLAuth::CGroupHTMLAuth(const TCtorParam ¶m) +: CGroupHTML(param) +{ +} + +// *************************************************************************** + +CGroupHTMLAuth::~CGroupHTMLAuth() +{ +} + +void CGroupHTMLAuth::addHTTPGetParams (string &url, bool trustedDomain) +{ + addWebIGParams(url, trustedDomain); +} + +// *************************************************************************** + +void CGroupHTMLAuth::addHTTPPostParams (HTAssocList *formfields, bool trustedDomain) +{ + if(!UserEntity) return; + + uint32 cid = NetMngr.getLoginCookie().getUserId() * 16 + PlayerSelectedSlot; + HTParseFormInput(formfields, ("shardid="+toString(CharacterHomeSessionId)).c_str()); + HTParseFormInput(formfields, ("name="+UserEntity->getLoginName().toUtf8()).c_str()); + HTParseFormInput(formfields, ("lang="+CI18N::getCurrentLanguageCode()).c_str()); + HTParseFormInput(formfields, "ig=1"); + if (trustedDomain) + { + HTParseFormInput(formfields, ("cid="+toString(cid)).c_str()); + HTParseFormInput(formfields, ("authkey="+getWebAuthKey()).c_str()); + } +} + +// *************************************************************************** + +string CGroupHTMLAuth::home () +{ + return Home; +} + +// *************************************************************************** + +void CGroupHTMLAuth::handle () +{ + CGroupHTML::handle (); +} + +// *************************************************************************** +// *************************************************************************** + + // *************************************************************************** NLMISC_REGISTER_OBJECT(CViewBase, CGroupHTMLWebIG, std::string, "webig_html"); CGroupHTMLWebIG::CGroupHTMLWebIG(const TCtorParam ¶m) -: CGroupHTML(param) +: CGroupHTMLAuth(param) { startWebigNotificationThread(); } @@ -245,24 +355,18 @@ CGroupHTMLWebIG::~CGroupHTMLWebIG() { } -void CGroupHTMLWebIG::addHTTPGetParams (string &url) +// *************************************************************************** + +void CGroupHTMLWebIG::addHTTPGetParams (string &url, bool trustedDomain) { - addWebIGParams(url); + CGroupHTMLAuth::addHTTPGetParams(url, trustedDomain); } // *************************************************************************** -void CGroupHTMLWebIG::addHTTPPostParams (HTAssocList *formfields) +void CGroupHTMLWebIG::addHTTPPostParams (HTAssocList *formfields, bool trustedDomain) { - if(!UserEntity) return; - - uint32 cid = NetMngr.getLoginCookie().getUserId() * 16 + PlayerSelectedSlot; - HTParseFormInput(formfields, ("shardid="+toString(CharacterHomeSessionId)).c_str()); - HTParseFormInput(formfields, ("name="+UserEntity->getDisplayName().toUtf8()).c_str()); - HTParseFormInput(formfields, ("cid="+toString(cid)).c_str()); - HTParseFormInput(formfields, ("authkey="+getWebAuthKey()).c_str()); - HTParseFormInput(formfields, "ig=1"); - HTParseFormInput(formfields, ("lang="+CI18N::getCurrentLanguageCode()).c_str()); + CGroupHTMLAuth::addHTTPPostParams(formfields, trustedDomain); } // *************************************************************************** @@ -276,8 +380,6 @@ string CGroupHTMLWebIG::home () void CGroupHTMLWebIG::handle () { -// Home = "http://atys.ryzom.com/start/index.php"; - CGroupHTML::handle (); + CGroupHTMLAuth::handle (); } -// *************************************************************************** diff --git a/code/ryzom/client/src/interface_v3/group_html_webig.h b/code/ryzom/client/src/interface_v3/group_html_webig.h index 15485d7dc..5967f671d 100644 --- a/code/ryzom/client/src/interface_v3/group_html_webig.h +++ b/code/ryzom/client/src/interface_v3/group_html_webig.h @@ -20,10 +20,32 @@ #include "nel/misc/types_nl.h" #include "group_html.h" +/** +* Auth HTML group +*/ +class CGroupHTMLAuth : public CGroupHTML +{ +public: + + // Constructor + CGroupHTMLAuth(const TCtorParam ¶m); + ~CGroupHTMLAuth(); + + // From CGroupHTML + virtual void addHTTPGetParams (std::string &url, bool trustedDomain); + virtual void addHTTPPostParams (HTAssocList *formfields, bool trustedDomain); + virtual std::string home(); + virtual void handle (); + +private: + +}; + + /** * WebIG HTML group */ -class CGroupHTMLWebIG : public CGroupHTML +class CGroupHTMLWebIG : public CGroupHTMLAuth { public: @@ -31,9 +53,9 @@ public: CGroupHTMLWebIG(const TCtorParam ¶m); ~CGroupHTMLWebIG(); - // From CGroupHTML - virtual void addHTTPGetParams (std::string &url); - virtual void addHTTPPostParams (HTAssocList *formfields); + /// From CGroupHTMLAuth + virtual void addHTTPGetParams (std::string &url, bool trustedDomain); + virtual void addHTTPPostParams (HTAssocList *formfields, bool trustedDomain); virtual std::string home(); virtual void handle (); 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 85238ad7d..cc0d3e82f 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 @@ -973,6 +973,132 @@ void CGroupInSceneBubbleManager::dynChatOpen (uint32 nBotUID, uint32 nBotName, c UserEntity->interlocutor( pChar->slot() ); } +// *************************************************************************** + +void CGroupInSceneBubbleManager::webIgChatOpen (uint32 nBotUID, string text, const vector &strs, const vector &links) +{ + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + // If the character doesn't exist in view field -> do not display the bubble + + CEntityCL *pEntity = EntitiesMngr.getEntityByCompressedIndex(nBotUID); + CCharacterCL *pChar = dynamic_cast(pEntity); + if (pChar == NULL) + { + nlwarning("character probably too far"); + return; + } + + // Look if we get a bubble with this nBotUID ? + uint32 pos, j; + for (pos = 0; pos < _DynBubbles.size(); ++pos) + { + if (_DynBubbles[pos].BotUID == nBotUID) + break; + } + + // If the bubble doesn't exist -> create + CGroupInSceneBubble *bubble = NULL; + string id; + if (pos == _DynBubbles.size()) + { + uint32 i = 0; + while (getDynBubble(i) != NULL) i++; + id = "in_scene_webig_bubble_" + toString(i); + // Create the instance + std::vector > templateParams; + templateParams.push_back (std::pair("id", id)); + + CInterfaceGroup *group = pIM->createGroupInstance ("webig_3dbulle_L", "ui:interface", templateParams); + if (group == NULL) + { + nlwarning("cannot create webig_3dbulle_L"); + return; + } + // Link to the interface + pIM->addWindowToMasterGroup("ui:interface", group); + CInterfaceGroup *pRoot = dynamic_cast(pIM->getElementFromId("ui:interface")); + group->setParent(pRoot); + if (pRoot) + pRoot->addGroup (group); + group->setActive(false); + + bubble = dynamic_cast(group); + if (bubble == NULL) + { + nlwarning("cannot cast to CGroupInSceneBubble"); + return; + } + CDynBubble dynBubble; + dynBubble.BotName = 0; + dynBubble.BotUID = nBotUID; + dynBubble.Bubble = bubble; + _DynBubbles.push_back(dynBubble); + } + else + { + bubble = _DynBubbles[pos].Bubble; + // Remove from group to delete if in the same frame + for (j=0; j<_GroupToDelete.size(); j++) + if (_GroupToDelete[j] == bubble) + { + _GroupToDelete.erase(_GroupToDelete.begin()+j); + break; + } + } + + // Update the bubble's texts + + ucstring ucText; + ucText.fromUtf8(text); + bubble->setText(ucText); + id = bubble->getId() + ":header_opened:window:"; + CViewText *pVT; + CCtrlLink *pCL; + + _DynBubbles[pos].DescWaiting = 0; + + for (j = 0; j < 8; ++j) + { + pVT = dynamic_cast(bubble->getElement(id+"opt"+toString(j))); + if (pVT != NULL) + { + pVT->setActive(false); + pVT->setText(ucstring("")); + } + pCL = dynamic_cast(bubble->getElement(id+"optb"+toString(j))); + if (pCL != NULL) pCL->setActive(false); + } + + for (j = 0; j < strs.size(); ++j) + { + string fullid = id+"opt"+toString(j); + pVT = dynamic_cast(bubble->getElement(id+"opt"+toString(j))); + if (pVT != NULL) + { + pVT->setActive(true); + ucstring optionText; + optionText.fromUtf8(strs[j]); + pVT->setText(optionText); + pCL = dynamic_cast(bubble->getElement(id+"optb"+toString(j))); + if (pCL != NULL) + { + pCL->setActionOnLeftClick("browse"); + pCL->setParamsOnLeftClick("name=ui:interface:web_transactions:content:html|show=0|url="+links[j]); + //pCL->setActionOnLeftClickParams("name=ui:interface:web_transactions:content:html|url="+links[j]); + pCL->setActive(true); + + } + } + } + + // Link bubble to the character + pChar->setBubble(bubble); + + // Make the npc face the character + UserEntity->interlocutor( pChar->slot() ); +} + + uint32 CGroupInSceneBubbleManager::CDynBubble::getOptionStringId(uint option) { if (!Bubble) return 0; diff --git a/code/ryzom/client/src/interface_v3/group_in_scene_bubble.h b/code/ryzom/client/src/interface_v3/group_in_scene_bubble.h index 5e7cd4546..635e8c47e 100644 --- a/code/ryzom/client/src/interface_v3/group_in_scene_bubble.h +++ b/code/ryzom/client/src/interface_v3/group_in_scene_bubble.h @@ -64,6 +64,9 @@ public: // Open a Dynamic Chat void dynChatOpen (uint32 nBotUID, uint32 nBotName, const std::vector &DynStrs); + // Open a Dynamic Chat from webig + void webIgChatOpen (uint32 nBotUID, std::string sBotName, const std::vector &strs, const std::vector &links); + // Close a Dynamic Chat void dynChatClose (uint32 nBotUID); diff --git a/code/ryzom/client/src/interface_v3/group_in_scene_user_info.cpp b/code/ryzom/client/src/interface_v3/group_in_scene_user_info.cpp index dcc3895f7..d9fa10707 100644 --- a/code/ryzom/client/src/interface_v3/group_in_scene_user_info.cpp +++ b/code/ryzom/client/src/interface_v3/group_in_scene_user_info.cpp @@ -97,7 +97,7 @@ CRGBA CGroupInSceneUserInfo::BarColorHPNegative = CRGBA(127, 32, 0); #define nlfsinfo2 if ( _Entity->isForageSource() ) nlinfo -CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (class CEntityCL *entity) +CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (CEntityCL *entity) { // Get the interface manager CInterfaceManager *pIM = CInterfaceManager::getInstance(); @@ -129,6 +129,7 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (class CEntityCL *entity) bool forageSourceBarDisplayed= false; bool needPvPLogo= false; bool permanentContent = false; + bool rpTags = false; bool displayMissionIcons = pIM->getDbProp("UI:SAVE:INSCENE:FRIEND:MISSION_ICON")->getValueBool(); // Names @@ -136,6 +137,12 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (class CEntityCL *entity) ucstring theTribeName; ucstring entityName = entity->getDisplayName(); ucstring entityTitle = entity->getTitle(); + + ucstring entityTag1 = entity->getTag(1); + ucstring entityTag2 = entity->getTag(2); + ucstring entityTag3 = entity->getTag(3); + ucstring entityTag4 = entity->getTag(4); + string entityPermanentContent = entity->getPermanentStatutIcon(); // Active fields and bars @@ -160,6 +167,8 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (class CEntityCL *entity) } else if(npcFriendAndNeutral) { + string dbEntry; + getBarSettings( pIM, user, entity->isPlayer(), _friend, dbEntry, bars ); // For RoleMasters, merchants etc... must display name and function, and nothing else for(uint i=0;igetDbProp(dbEntry+"RPTAGS")->getValueBool(); } else { @@ -176,6 +186,7 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (class CEntityCL *entity) getBarSettings( pIM, user, entity->isPlayer(), _friend, dbEntry, bars ); name = !entityName.empty() && pIM->getDbProp(dbEntry+"NAME")->getValueBool(); title = !entityTitle.empty() && pIM->getDbProp(dbEntry+"TITLE")->getValueBool(); + rpTags = (!entityTag1.empty() || !entityTag2.empty() || !entityTag3.empty() || !entityTag4.empty() ) && pIM->getDbProp(dbEntry+"RPTAGS")->getValueBool(); // if name is empty but not title, title is displayed as name if (!title && entityName.empty() && !entityTitle.empty() && pIM->getDbProp(dbEntry+"NAME")->getValueBool()) title = true; @@ -369,6 +380,26 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (class CEntityCL *entity) else stringSpace += textH; + if (rpTags) + { + CPlayerCL * pPlayer = dynamic_cast(entity); + CViewBitmap *bitmap; + if (pPlayer == NULL || (pPlayer != NULL && pPlayer->getPvpMode() & PVP_MODE::PvpFaction)) + { + bitmap = dynamic_cast(leftGroup->getView ("rp_logo_1")); + if (bitmap) + bitmap->setTexture(entityTag1.toString()); + bitmap = dynamic_cast(leftGroup->getView ("rp_logo_2")); + if (bitmap) + bitmap->setTexture(entityTag2.toString()); + } + bitmap = dynamic_cast(leftGroup->getView ("rp_logo_3")); + if (bitmap) + bitmap->setTexture(entityTag3.toString()); + bitmap = dynamic_cast(leftGroup->getView ("rp_logo_4")); + if (bitmap) + bitmap->setTexture(entityTag4.toString()); + } // Get the permanent content bitmap if(permanentContent) @@ -539,162 +570,96 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (class CEntityCL *entity) info->_MissionTarget = bitmap; } - CViewBase * pvpCivLogo = info->getView ("pvp_faction_civ_logo"); - CViewBase * pvpCultLogo = info->getView ("pvp_faction_cult_logo"); + CViewBase * pvpFactionLogo = info->getView ("pvp_faction_logo"); + CViewBase * pvpOutpostLogo = info->getView ("pvp_outpost_logo"); + CViewBase * pvpDuelLogo = info->getView ("pvp_duel_logo"); CPlayerCL * pPlayer = dynamic_cast(entity); if (pPlayer == NULL) needPvPLogo = false; - // set or inactive pvp logos - bool needCivPvpLogo = needPvPLogo; - bool needCultPvpLogo = needPvPLogo; - if (pPlayer != NULL && needPvPLogo && pvpCivLogo && pvpCultLogo) + if (pPlayer != NULL && needPvPLogo) { - uint8 civToDisplay = (uint8)(pPlayer->getClanCivMaxFame() & 0xFF); - uint8 cultToDisplay = (uint8)(pPlayer->getClanCultMaxFame() & 0xFF); - - if (!entity->isUser()) + if (pvpFactionLogo) { - bool civEnnemies = false; - for (uint8 i = 0; i < 4; i++) + pvpFactionLogo->setActive(true); + CViewBitmap * pvpFactionBitmap = dynamic_cast(pvpFactionLogo); + if( pvpFactionBitmap ) { - if ( (pPlayer->isPvpAlly(i) && UserEntity->isPvpEnnemy(i)) || - (pPlayer->isPvpEnnemy(i) && UserEntity->isPvpAlly(i)) ) + if (user) { - civEnnemies = true; - if ( civToDisplay == i) - break; - else - civToDisplay = i; - } - - if (!civEnnemies) - { - if ( (pPlayer->isPvpAlly(i) && UserEntity->isPvpAlly(i)) || - (pPlayer->isPvpEnnemy(i) && UserEntity->isPvpEnnemy(i)) ) + if (pPlayer->getPvpMode() & PVP_MODE::PvpChallenge) { - if ( civToDisplay == i) - break; - else - civToDisplay = i; + pvpFactionBitmap->setTexture("ico_curse.tga"); + } + else if (pPlayer->getPvpMode() & PVP_MODE::PvpFaction) + { + if (pPlayer->getPvpMode() & PVP_MODE::PvpZoneSafe) + pvpFactionBitmap->setTexture("pvp_neutral.tga"); + else + pvpFactionBitmap->setTexture("pvp_enemy_tag.tga"); + } + else if (pPlayer->getPvpMode() & PVP_MODE::PvpFactionFlagged) + { + if (pPlayer->getPvpMode() & PVP_MODE::PvpSafe) + pvpFactionBitmap->setTexture("pvp_neutral.tga"); + else + pvpFactionBitmap->setTexture("pvp_enemy_flag.tga"); } - } - } - - - for (uint8 i = 4; i < 7; i++) - { - if ( (pPlayer->isPvpAlly(i) && UserEntity->isPvpEnnemy(i)) || - (pPlayer->isPvpEnnemy(i) && UserEntity->isPvpAlly(i)) ) - { - if ( cultToDisplay == i) - break; else - cultToDisplay = i; - } - - if ( (pPlayer->isPvpAlly(i) && UserEntity->isPvpAlly(i)) || - (pPlayer->isPvpEnnemy(i) && UserEntity->isPvpEnnemy(i)) ) - { - if ( cultToDisplay == i) - break; - else - cultToDisplay = i; - } - } - } - - if ((pPlayer->getPvpMode() & PVP_MODE::PvpFaction) || (pPlayer->getPvpMode() & PVP_MODE::PvpFactionFlagged)) - { - CViewBitmap * pvpCivLogoBmp = dynamic_cast(pvpCivLogo); - if( pvpCivLogoBmp ) - { - if (pPlayer->isPvpAlly(civToDisplay)) - { - if (pPlayer->isPvpRanger()) - pvpCivLogoBmp->setTexture("pvp_ally_ranger.tga"); - else - pvpCivLogoBmp->setTexture("pvp_ally_"+toString(civToDisplay)+".tga"); - } - else if (pPlayer->isPvpEnnemy(civToDisplay)) - { - if (pPlayer->isPvpMarauder()) - pvpCivLogoBmp->setTexture("pvp_enemy_marauder.tga"); - else - pvpCivLogoBmp->setTexture("pvp_enemy_"+toString(civToDisplay)+".tga"); + pvpFactionLogo->setActive(false); } else { - needCivPvpLogo = false; - } - } - - CViewBitmap * pvpCultLogoBmp = dynamic_cast(pvpCultLogo); - if( pvpCultLogoBmp ) - { - if (pPlayer->isPvpAlly(cultToDisplay)) - { - if (pPlayer->isPvpPrimas()) - pvpCultLogoBmp->setTexture("pvp_ally_primas.tga"); + if (pPlayer->getPvpMode() & PVP_MODE::PvpChallenge) + pvpFactionBitmap->setTexture("ico_curse.tga"); + else if (pPlayer->isNeutralPVP()) + pvpFactionBitmap->setTexture("pvp_neutral.tga"); + else if (pPlayer->isAlly() && (pPlayer->getPvpMode() & PVP_MODE::PvpFactionFlagged)) + pvpFactionBitmap->setTexture("pvp_ally_flag.tga"); + else if (pPlayer->isAlly() && (pPlayer->getPvpMode() & PVP_MODE::PvpFaction)) + pvpFactionBitmap->setTexture("pvp_ally_tag.tga"); + else if (pPlayer->isEnemy() && (pPlayer->getPvpMode() & PVP_MODE::PvpFactionFlagged)) + pvpFactionBitmap->setTexture("pvp_enemy_flag.tga"); + else if (pPlayer->isEnemy() && (pPlayer->getPvpMode() & PVP_MODE::PvpFaction)) + pvpFactionBitmap->setTexture("pvp_enemy_tag.tga"); + else if (pPlayer->getPvpMode() & PVP_MODE::PvpFactionFlagged) + pvpFactionBitmap->setTexture("pvp_enemy_flag.tga"); + else if (pPlayer->getPvpMode() & PVP_MODE::PvpFaction) + pvpFactionBitmap->setTexture("pvp_enemy_tag.tga"); else - pvpCultLogoBmp->setTexture("pvp_ally_"+toString(cultToDisplay)+".tga"); - } - else if (pPlayer->isPvpEnnemy(cultToDisplay)) - { - if (pPlayer->isPvpTrytonist()) - pvpCultLogoBmp->setTexture("pvp_enemy_trytonist.tga"); - else - pvpCultLogoBmp->setTexture("pvp_enemy_"+toString(cultToDisplay)+".tga"); - } - else - { - needCultPvpLogo = false; + pvpFactionLogo->setActive(false); } } } - else - { - needCivPvpLogo = false; - needCultPvpLogo = false; - } - - CViewBase * pvpOutpostLogo = info->getView ("pvp_outpost_logo"); + if (pvpOutpostLogo) { - if( pPlayer->getOutpostId() == 0 ) - { + if( pPlayer->getOutpostId() != 0 ) + pvpOutpostLogo->setActive(true); + else pvpOutpostLogo->setActive(false); - } } - - CViewBase * pvpDuelLogo = info->getView ("pvp_duel_logo"); + if (pvpDuelLogo) { - if( !(pPlayer->getPvpMode()&PVP_MODE::PvpDuel || pPlayer->getPvpMode()&PVP_MODE::PvpChallenge) ) - { + if( pPlayer->getPvpMode()&PVP_MODE::PvpDuel ) + pvpDuelLogo->setActive(true); + else pvpDuelLogo->setActive(false); - } } + } else { - CViewBase * pvpOutpostLogo = info->getView ("pvp_outpost_logo"); + if (pvpFactionLogo) + pvpFactionLogo->setActive(false); if (pvpOutpostLogo) pvpOutpostLogo->setActive(false); - - CViewBase * pvpDuelLogo = info->getView ("pvp_duel_logo"); if (pvpDuelLogo) - pvpDuelLogo->setActive(false); + pvpDuelLogo->setActive(false); } - - if (pvpCivLogo) - pvpCivLogo->setActive(needCivPvpLogo); - - if (pvpCultLogo) - pvpCultLogo->setActive(needCultPvpLogo); - } // No bar and no string ? diff --git a/code/ryzom/client/src/interface_v3/group_table.cpp b/code/ryzom/client/src/interface_v3/group_table.cpp index 48ec926a4..890a8b0fe 100644 --- a/code/ryzom/client/src/interface_v3/group_table.cpp +++ b/code/ryzom/client/src/interface_v3/group_table.cpp @@ -55,6 +55,9 @@ CGroupCell::CGroupCell(const TCtorParam ¶m) IgnoreMaxWidth = false; IgnoreMinWidth = false; AddChildW = false; + _UserTexture = false; + _TextureTiled = false; + _TextureScaled = false; setEnclosedGroupDefaultParams(); addGroup (Group); } @@ -200,20 +203,62 @@ void CGroupCell::draw () } // Draw the background - if (BgColor.A != 0) + if (_UserTexture || BgColor.A != 0) { CViewRenderer &rVR = pIM->getViewRenderer(); - CRGBA finalColor; - finalColor.modulateFromColor (BgColor, pIM->getGlobalColor()); - - // Get the parent table - if (getParent ()) + if (_UserTexture) { - CGroupTable *table = static_cast (getParent ()); - finalColor.A = (uint8) (((uint16) table->CurrentAlpha * (uint16) finalColor.A) >> 8); + CRGBA col; + if (BgColor.A == 0 ) + col = CRGBA(255,255,255,255); + else + col = BgColor; + + + if (_TextureScaled && !_TextureTiled) + { + rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, + _WReal, _HReal, + 0, false, + _TextureId, + col ); + } + else + { + if (!_TextureTiled) + { + rVR.draw11RotFlipBitmap (_RenderLayer, _XReal, _YReal, + 0, false, + _TextureId, + col); + } + else + { + rVR.drawRotFlipBitmapTiled(_RenderLayer, _XReal, _YReal, + _WReal, _HReal, + 0, false, + _TextureId, + 0, + col); + } + } + } + else + { + CRGBA finalColor; + finalColor.modulateFromColor (BgColor, pIM->getGlobalColor()); - rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, _WReal, _HReal, 0, false, rVR.getBlankTextureId(), finalColor); + // Get the parent table + if (getParent ()) + { + CGroupTable *table = static_cast (getParent ()); + finalColor.A = (uint8) (((uint16) table->CurrentAlpha * (uint16) finalColor.A) >> 8); + } + + //nlinfo("Blank Texture"); + rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, _WReal, _HReal, 0, false, rVR.getBlankTextureId(), finalColor); + } } CInterfaceGroup::draw (); @@ -231,6 +276,40 @@ sint32 CGroupCell::getMinUsedW() const return Group->getMinUsedW(); } + +// ---------------------------------------------------------------------------- +void CGroupCell::setTexture(const std::string & TxName) +{ + if (TxName.empty() || TxName == "none") + { + _UserTexture = false; + nlinfo("Set no texture"); + } + else + { + nlinfo("Set texture to cell : %s", TxName.c_str()); + _UserTexture = true; + _TextureId.setTexture (TxName.c_str (), 0, 0, -1, -1, false); + } +} + +// ---------------------------------------------------------------------------- +void CGroupCell::setTextureTile(bool tiled) +{ + if (tiled) + nlinfo("Set texture is Tiled"); + _TextureTiled = tiled; +} + +// ---------------------------------------------------------------------------- +void CGroupCell::setTextureScale(bool scaled) +{ + if (scaled) + nlinfo("Set texture is Scaled : %s"); + _TextureScaled = scaled; +} + + // ---------------------------------------------------------------------------- NLMISC_REGISTER_OBJECT(CViewBase, CGroupTable, std::string, "table"); diff --git a/code/ryzom/client/src/interface_v3/group_table.h b/code/ryzom/client/src/interface_v3/group_table.h index 08cdad11e..888d6dbe3 100644 --- a/code/ryzom/client/src/interface_v3/group_table.h +++ b/code/ryzom/client/src/interface_v3/group_table.h @@ -80,6 +80,12 @@ public: // The cell color NLMISC::CRGBA BgColor; + // Texture + CViewRenderer::CTextureId _TextureId; /// Accelerator + bool _UserTexture; + bool _TextureTiled; + bool _TextureScaled; + // Alignment TAlign Align; TVAlign VAlign; @@ -90,6 +96,11 @@ public: // The cell is nowrap bool NoWrap; + + void setTexture(const std::string & TxName); + void setTextureTile(bool tiled); + void setTextureScale(bool scaled); + private: void setEnclosedGroupDefaultParams(); }; diff --git a/code/ryzom/client/src/interface_v3/guild_manager.cpp b/code/ryzom/client/src/interface_v3/guild_manager.cpp index c9bb4ec01..8d0066816 100644 --- a/code/ryzom/client/src/interface_v3/guild_manager.cpp +++ b/code/ryzom/client/src/interface_v3/guild_manager.cpp @@ -358,15 +358,54 @@ void CGuildManager::update() // If all is valid no more need update and if guild is opened update the interface if (bAllValid) { + CCDBNodeLeaf* node = CInterfaceManager::getInstance()->getDbProp("UI:SAVE:CHAT:SHOW_ONLINE_OFFLINE_NOTIFICATIONS_CB", false); + if (node && node->getValueBool()) + { + // See if we need to show any online/offline messages + static vector CachedGuildMembers; + ucstring onlineMessage = CI18N::get("uiPlayerOnline"); + ucstring offlineMessage = CI18N::get("uiPlayerOffline"); + + for (uint i = 0; i < _GuildMembers.size(); ++i) + { + for (uint j = 0; j < CachedGuildMembers.size(); ++j) + { + if ((CachedGuildMembers[j].Name == _GuildMembers[i].Name) && + (CachedGuildMembers[j].Online != _GuildMembers[i].Online)) + { + ucstring msg = (_GuildMembers[i].Online != ccs_offline) ? onlineMessage : offlineMessage; + strFindReplace(msg, "%s", _GuildMembers[i].Name); + string cat = getStringCategory(msg, msg); + map::const_iterator it; + NLMISC::CRGBA col = CRGBA::Yellow; + it = ClientCfg.SystemInfoParams.find(toLower(cat)); + if (it != ClientCfg.SystemInfoParams.end()) + { + col = it->second.Color; + } + bool dummy; + PeopleInterraction.ChatInput.Guild.displayMessage(msg, col, 2, &dummy); + break; + } + } + } + + CachedGuildMembers.clear(); + for (uint i = 0; i < _GuildMembers.size(); ++i) + { + CachedGuildMembers.push_back(_GuildMembers[i]); + } + } + // Search for UserEntity to find our own grade if ((UserEntity != NULL) && (_GuildMembers.size() > 0)) { uint i; _Grade = EGSPD::CGuildGrade::Member; - string sUserName = strlwr(UserEntity->getEntityName().toString()); + ucstring sUserName = toLower(UserEntity->getEntityName()); for (i = 0; i < _GuildMembers.size(); ++i) { - if (strlwr(_GuildMembers[i].Name.toString()) == sUserName) + if (toLower(_GuildMembers[i].Name) == sUserName) { _Grade = _GuildMembers[i].Grade; break; @@ -1048,10 +1087,26 @@ class CAHGuildSheetSetLeader : public IActionHandler { virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */) { - sendMsgSetGrade(EGSPD::CGuildGrade::Leader); + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + + // Ask if they are sure + pIM->validMessageBox(CInterfaceManager::QuestionIconMsg, CI18N::get("uiQSetLeader"), "guild_member_do_change_leader"); } }; REGISTER_ACTION_HANDLER (CAHGuildSheetSetLeader, "guild_member_chg_to_leader"); + +// *************************************************************************** +class CAHGuildSheetSetLeaderConfirm : public IActionHandler +{ + virtual void execute (CCtrlBase * /* pCaller */, const string &/* Params */) + { + // Leadership change confirmed + sendMsgSetGrade(EGSPD::CGuildGrade::Leader); + } +}; +REGISTER_ACTION_HANDLER (CAHGuildSheetSetLeaderConfirm, "guild_member_do_change_leader"); + + // *************************************************************************** class CAHGuildSheetSetHighOfficer : public IActionHandler diff --git a/code/ryzom/client/src/interface_v3/interface_group.h b/code/ryzom/client/src/interface_v3/interface_group.h index 5079c1899..432176704 100644 --- a/code/ryzom/client/src/interface_v3/interface_group.h +++ b/code/ryzom/client/src/interface_v3/interface_group.h @@ -176,13 +176,17 @@ public: void setRightClickHandlerParams(const std::string ¶ms) { _AHOnRightClickParams = params; } void setOnActiveHandler(const std::string &h) { _AHOnActive = getAH(h,_AHOnActiveParams); } void setOnActiveParams(const std::string &p) { _AHOnActiveParams = p; } - std::string getOnActiveParams() const { return _AHOnActiveParams; } void setOnDeactiveHandler(const std::string &h) { _AHOnDeactive = getAH(h,_AHOnDeactiveParams); } void setOnDeactiveParams(const std::string &p) { _AHOnDeactiveParams = p; } - std::string getOnDeactiveParams() const { return _AHOnDeactiveParams; } const std::string &getLeftClickHandler() const { return getAHName(_AHOnLeftClick); } const std::string &getLeftClickHandlerParams() const { return _AHOnLeftClickParams; } + const std::string &getRightClickHandler() const { return getAHName(_AHOnRightClick); } + const std::string &getRightClickHandlerParams() const { return _AHOnRightClickParams; } + const std::string &getOnActiveHandler() const { return getAHName(_AHOnActive); } + const std::string &getOnActiveParams() const { return _AHOnActiveParams; } + const std::string &getOnDeactiveHandler() const { return getAHName(_AHOnDeactive); } + const std::string &getOnDeactiveParams() const { return _AHOnDeactiveParams; } // find a sub view/ctrl/group in this group from its id int luaFind(CLuaState &ls); @@ -205,8 +209,18 @@ public: REFLECT_LUA_METHOD("delGroup", luaDelGroup); REFLECT_LUA_METHOD("getNumGroups", luaGetNumGroups); REFLECT_LUA_METHOD("getGroup", luaGetGroup); + REFLECT_STRING ("left_click", getLeftClickHandler, setLeftClickHandler); + REFLECT_STRING ("right_click", getRightClickHandler, setRightClickHandler); + REFLECT_STRING ("left_click_params", getLeftClickHandlerParams, setLeftClickHandlerParams); + REFLECT_STRING ("right_click_params", getRightClickHandlerParams, setRightClickHandlerParams); + REFLECT_STRING ("on_active", getOnActiveHandler, setOnActiveHandler); REFLECT_STRING ("on_active_params", getOnActiveParams, setOnActiveParams); + REFLECT_STRING ("on_deactive", getOnDeactiveHandler, setOnDeactiveHandler); REFLECT_STRING ("on_deactive_params", getOnDeactiveParams, setOnDeactiveParams); + REFLECT_STRING ("on_enter", getAHOnEnter, setAHOnEnter); + REFLECT_STRING ("on_enter_params", getAHOnEnterParams, setAHOnEnterParams); + REFLECT_STRING ("on_escape", getAHOnEscape, setAHOnEscape); + REFLECT_STRING ("on_escape_params", getAHOnEscapeParams, setAHOnEscapeParams); REFLECT_SINT32 ("ofsx", getOfsX, setOfsX); REFLECT_SINT32 ("ofsy", getOfsY, setOfsY); REFLECT_BOOL("child_resize_w", getResizeFromChildW, setResizeFromChildW); diff --git a/code/ryzom/client/src/interface_v3/interface_manager.cpp b/code/ryzom/client/src/interface_v3/interface_manager.cpp index 27b8f9197..8e0851cf6 100644 --- a/code/ryzom/client/src/interface_v3/interface_manager.cpp +++ b/code/ryzom/client/src/interface_v3/interface_manager.cpp @@ -824,6 +824,21 @@ void CInterfaceManager::initInGame() { gc->setTarget(gc->getSavedTarget()); } + + CCDBNodeLeaf *node = getDbProp("UI:SAVE:CHATLOG_STATE", false); + if (node) + { + _LogState = (node->getValue32() != 0); + } + + if (_LogState) + { + displaySystemInfo(CI18N::get("uiLogTurnedOn")); + } + else + { + displaySystemInfo(CI18N::get("uiLogTurnedOff")); + } } // ------------------------------------------------------------------------------------------------ @@ -2372,7 +2387,8 @@ void CInterfaceManager::drawContextHelp () if(newCtrl) { // get the text - newCtrl->getContextHelpToolTip(_ContextHelpText); + //newCtrl->getContextHelpToolTip(_ContextHelpText); + newCtrl->getContextHelp(_ContextHelpText); // UserDefined context help if( !newCtrl->getContextHelpActionHandler().empty() ) { @@ -3408,6 +3424,13 @@ CCDBNodeLeaf* CInterfaceManager::getDbProp(const std::string & name, bool bCreat return pDBNL; } +// ------------------------------------------------------------------------------------------------ +void CInterfaceManager::delDbProp(const std::string & name) +{ + if (name.empty()) return; + _DbRootNode->removeNode( ICDBNode::CTextId(name) ); +} + // ------------------------------------------------------------------------------------------------ CCDBNodeBranch *CInterfaceManager::getDbBranch(const std::string &name) { @@ -5759,7 +5782,7 @@ bool CInterfaceManager::executeLuaScript(const std::string &luaScript, bool smal std::string msg = e.luaWhat(); char filename[MAX_PATH]; char exceptionName[MAX_PATH]; - int line; + uint32 line; // Hamster: quick fix on AJM code but sscanf is still awfull if (sscanf(msg.c_str(), "%s: %s.lua:%d:",exceptionName, filename, &line) == 3) // NB: test not exact here, but should work in 99,9 % of cases { @@ -5770,6 +5793,20 @@ bool CInterfaceManager::executeLuaScript(const std::string &luaScript, bool smal else // AJM: handle the other 0.1% of cases { // Yoyo: seems that previous test doesn't work.... btw, must still print the message please... + std::vector error; + splitString(msg.c_str(), ":", error); + if (error.size() > 3) + { + std::vector contextList; + explode(luaScript, string("\n"), contextList); + fromString(error[2], line); + if (line >= 3 && contextList.size() >= line) + msg = error[0]+": \n>>> "+contextList[line-3]+"\n>>> "+contextList[line-2]+"\n>>> "+contextList[line-1]+"\nError:"+error[2]+": "+error[3]; + else if (line >= 2 && contextList.size() >= line) + msg = error[0]+": \n>>>"+contextList[line-2]+"\n>>>"+contextList[line-1]+"\nError:"+error[2]+": "+error[3]; + else if (line >= 1 && contextList.size() >= line) + msg = error[0]+": \n>>>"+contextList[line-1]+"\nError:"+error[2]+": "+error[3]; + } nlwarning(formatLuaErrorNlWarn(msg).c_str()); displaySystemInfo(formatLuaErrorSysInfo(msg)); } diff --git a/code/ryzom/client/src/interface_v3/interface_manager.h b/code/ryzom/client/src/interface_v3/interface_manager.h index ced23130f..7ee6d1951 100644 --- a/code/ryzom/client/src/interface_v3/interface_manager.h +++ b/code/ryzom/client/src/interface_v3/interface_manager.h @@ -232,6 +232,7 @@ public: CCDBNodeBranch *getDB() const { return _DbRootNode; } // yoyo: should avoid to try creating DbPropr with this system... very dangerous CCDBNodeLeaf* getDbProp (const std::string & name, bool bCreate=true); + void delDbProp(const std::string & name); // get a Db Branch by its name. NULL if don't exist or not a branch (never try to create it) CCDBNodeBranch *getDbBranch(const std::string &name); // return the DB as an int32. return 0 if the DB does not exist (never create) diff --git a/code/ryzom/client/src/interface_v3/interface_parser.cpp b/code/ryzom/client/src/interface_v3/interface_parser.cpp index 56b95be88..109b3d5cd 100644 --- a/code/ryzom/client/src/interface_v3/interface_parser.cpp +++ b/code/ryzom/client/src/interface_v3/interface_parser.cpp @@ -517,7 +517,7 @@ bool CInterfaceParser::parseInterface (const std::vector & strings, { bool ok; - bool needCheck = checkInData; + bool needCheck = false; #if !FINAL_VERSION needCheck = false; @@ -554,10 +554,12 @@ bool CInterfaceParser::parseInterface (const std::vector & strings, string::size_type pos = filename.find ("@"); if (pos != string::npos) { - std::string bigFilename = CBigFile::getInstance().getBigFileName(filename.substr(0, pos)); - std::string path = "data/"+filename.substr(0, pos); - - isInData = bigFilename.find(path) != std::string::npos; + vector bigFilePaths; + CBigFile::getInstance().getBigFilePaths(bigFilePaths); + if (CBigFile::getInstance().getBigFileName(filename.substr(0, pos)) != "data/"+filename.substr(0, pos)) + isInData = false; + else + isInData = true; } if ((needCheck && !isInData) || !file.open (CPath::lookup(firstFileName))) @@ -4685,7 +4687,7 @@ bool CInterfaceParser::loadLUA(const std::string &fileName, std::string &error) { // get file - bool needCheck = true; + bool needCheck = false; #if !FINAL_VERSION needCheck = false; @@ -4702,10 +4704,10 @@ bool CInterfaceParser::loadLUA(const std::string &fileName, std::string &error) std::string::size_type pos = pathName.find("@"); if (pos != string::npos) { - std::string bigFilename = CBigFile::getInstance().getBigFileName(pathName.substr(0, pos)); - std::string path = "data/"+pathName.substr(0, pos); - - isInData = bigFilename.find(path) != std::string::npos; + if (CBigFile::getInstance().getBigFileName(pathName.substr(0, pos)) != "data/"+pathName.substr(0, pos)) + isInData = false; + else + isInData = true; } if (needCheck && !isInData) diff --git a/code/ryzom/client/src/interface_v3/inventory_manager.cpp b/code/ryzom/client/src/interface_v3/inventory_manager.cpp index 9d20c0661..421076364 100644 --- a/code/ryzom/client/src/interface_v3/inventory_manager.cpp +++ b/code/ryzom/client/src/interface_v3/inventory_manager.cpp @@ -44,12 +44,14 @@ #include "../sheet_manager.h" #include "game_share/slot_equipment.h" #include "game_share/animal_status.h" +#include "game_share/bot_chat_types.h" #include "../client_cfg.h" using namespace std; using namespace NLMISC; +extern NLMISC::CLog g_log; // Context help extern void contextHelp (const std::string &help); @@ -131,6 +133,7 @@ void CItemImage::build(CCDBNodeBranch *branch) Weight = dynamic_cast(branch->getNode(ICDBNode::CTextId("WEIGHT"), false)); NameId = dynamic_cast(branch->getNode(ICDBNode::CTextId("NAMEID"), false)); InfoVersion= dynamic_cast(branch->getNode(ICDBNode::CTextId("INFO_VERSION"), false)); + ResaleFlag = dynamic_cast(branch->getNode(ICDBNode::CTextId("RESALE_FLAG"), false)); // Should always have at least those one:(ie all but Price) nlassert(Sheet && Quality && Quantity && UserColor && Weight && NameId && InfoVersion); @@ -1998,6 +2001,9 @@ bool SBagOptions::parse(xmlNodePtr cur, CInterfaceGroup * /* parentGroup */) prop = xmlGetProp (cur, (xmlChar*)"filter_missmp"); if (prop) DbFilterMissMP = pIM->getDbProp(prop); + prop = xmlGetProp (cur, (xmlChar*)"filter_tp"); + if (prop) DbFilterTP = pIM->getDbProp(prop); + return true; } @@ -2041,6 +2047,13 @@ bool SBagOptions::isSomethingChanged() LastDbFilterMissMP = (DbFilterMissMP->getValue8() != 0); } + if (DbFilterTP != NULL) + if ((DbFilterTP->getValue8() != 0) != LastDbFilterTP) + { + bRet = true; + LastDbFilterTP = (DbFilterTP->getValue8() != 0); + } + return bRet; } @@ -2054,25 +2067,33 @@ bool SBagOptions::canDisplay(CDBCtrlSheet *pCS) const bool bFilterTool = getFilterTool(); bool bFilterMP = getFilterMP(); bool bFilterMissMP = getFilterMissMP(); + bool bFilterTP = getFilterTP(); const CItemSheet *pIS = pCS->asItemSheet(); if (pIS != NULL) { // Armor - if ((pIS->Family == ITEMFAMILY::ARMOR) || (pIS->Family == ITEMFAMILY::JEWELRY)) + if ((pIS->Family == ITEMFAMILY::ARMOR) || + (pIS->Family == ITEMFAMILY::JEWELRY)) if (!bFilterArmor) bDisplay = false; // Weapon - if ((pIS->Family == ITEMFAMILY::SHIELD) || (pIS->Family == ITEMFAMILY::MELEE_WEAPON) || - (pIS->Family == ITEMFAMILY::RANGE_WEAPON) || (pIS->Family == ITEMFAMILY::AMMO) || - (pIS->Family == ITEMFAMILY::CRYSTALLIZED_SPELL) || (pIS->Family == ITEMFAMILY::ITEM_SAP_RECHARGE) || + if ((pIS->Family == ITEMFAMILY::SHIELD) || + (pIS->Family == ITEMFAMILY::MELEE_WEAPON) || + (pIS->Family == ITEMFAMILY::RANGE_WEAPON) || + (pIS->Family == ITEMFAMILY::AMMO) || + (pIS->Family == ITEMFAMILY::CRYSTALLIZED_SPELL) || + (pIS->Family == ITEMFAMILY::ITEM_SAP_RECHARGE) || (pIS->Family == ITEMFAMILY::BRICK) ) if (!bFilterWeapon) bDisplay = false; // Tool - if ((pIS->Family == ITEMFAMILY::CRAFTING_TOOL) || (pIS->Family == ITEMFAMILY::HARVEST_TOOL) || - (pIS->Family == ITEMFAMILY::TAMING_TOOL) || (pIS->Family == ITEMFAMILY::TRAINING_TOOL) || - (pIS->Family == ITEMFAMILY::BAG) || (pIS->Family == ITEMFAMILY::PET_ANIMAL_TICKET) ) + if ((pIS->Family == ITEMFAMILY::CRAFTING_TOOL) || + (pIS->Family == ITEMFAMILY::HARVEST_TOOL) || + (pIS->Family == ITEMFAMILY::TAMING_TOOL) || + (pIS->Family == ITEMFAMILY::TRAINING_TOOL) || + (pIS->Family == ITEMFAMILY::BAG) || + (pIS->Family == ITEMFAMILY::PET_ANIMAL_TICKET) ) if (!bFilterTool) bDisplay = false; // MP @@ -2081,9 +2102,15 @@ bool SBagOptions::canDisplay(CDBCtrlSheet *pCS) const // Mission MP if ((pIS->Family == ITEMFAMILY::MISSION_ITEM) || + (pIS->Family == ITEMFAMILY::XP_CATALYSER) || + (pIS->Family == ITEMFAMILY::CONSUMABLE) || ((pIS->Family == ITEMFAMILY::RAW_MATERIAL) && !pIS->canBuildSomeItemPart())) if (!bFilterMissMP) bDisplay = false; - + + // Teleporter Pacts + if ((pIS->Family == ITEMFAMILY::TELEPORT)) + if (!bFilterTP) bDisplay = false; + // Jobs Items if (pIS->Id.toString().substr(0, 6) == "rpjob_") bDisplay = false; @@ -2776,6 +2803,37 @@ public: REGISTER_ACTION_HANDLER( CHandlerInvAutoEquip, "inv_auto_equip" ); +// ********************************************************************************************************** +class CHandlerLockInvItem : public IActionHandler +{ + void execute (CCtrlBase *pCaller, const std::string &sParams) + { + // get the calling item + CDBCtrlSheet *item = CDBCtrlSheet::getCurrSelSheet(); + if ( ! item) + { + nlwarning(" no caller sheet found"); + return; + } + + string lock = "1"; + if (item->getLockedByOwner()) + { + lock = "0"; + } + + uint32 slot = item->getIndexInDB(); + uint32 inv = item->getInventoryIndex(); + INVENTORIES::TInventory inventory = INVENTORIES::UNDEFINED; + inventory = (INVENTORIES::TInventory)(inv); + if (inventory == INVENTORIES::UNDEFINED) + { + return; + } + NLMISC::ICommand::execute("a lockItem " + INVENTORIES::toString(inventory) + " " + toString(slot) + " " + lock, g_log); + } +}; +REGISTER_ACTION_HANDLER( CHandlerLockInvItem, "lock_inv_item" ); // *************************************************************************** // Inventory Temporary @@ -2844,11 +2902,11 @@ class CHandlerInvTempAll : public IActionHandler nlctassert(MAX_INVENTORY_ANIMAL==4); if (pInv->isInventoryAvailable(INVENTORIES::pet_animal1)) - BagsBulk.push_back(pair (pInv->getBagBulk(2), pInv->getMaxBagBulk(2))); + BagsBulk.push_back(pair (pInv->getBagBulk(1), pInv->getMaxBagBulk(1))); if (pInv->isInventoryAvailable(INVENTORIES::pet_animal2)) - BagsBulk.push_back(pair (pInv->getBagBulk(3), pInv->getMaxBagBulk(3))); + BagsBulk.push_back(pair (pInv->getBagBulk(2), pInv->getMaxBagBulk(2))); if (pInv->isInventoryAvailable(INVENTORIES::pet_animal3)) - BagsBulk.push_back(pair (pInv->getBagBulk(4), pInv->getMaxBagBulk(4))); + BagsBulk.push_back(pair (pInv->getBagBulk(3), pInv->getMaxBagBulk(3))); if (pInv->isInventoryAvailable(INVENTORIES::pet_animal4)) BagsBulk.push_back(pair (pInv->getBagBulk(4), pInv->getMaxBagBulk(4))); diff --git a/code/ryzom/client/src/interface_v3/inventory_manager.h b/code/ryzom/client/src/interface_v3/inventory_manager.h index a5c332ba7..12de9ad98 100644 --- a/code/ryzom/client/src/interface_v3/inventory_manager.h +++ b/code/ryzom/client/src/interface_v3/inventory_manager.h @@ -25,6 +25,7 @@ #include "game_share/item_infos.h" #include "game_share/temp_inventory_mode.h" #include "game_share/inventories.h" +#include "game_share/bot_chat_types.h" class CCDBNodeBranch; class CDBCtrlSheet; @@ -62,6 +63,7 @@ public: CCDBNodeLeaf *Weight; CCDBNodeLeaf *NameId; CCDBNodeLeaf *InfoVersion; + CCDBNodeLeaf *ResaleFlag; public: // ctor @@ -77,6 +79,8 @@ public: uint32 getWeight() const { return (uint32) (Weight ? Weight->getValue32() : 0); } uint32 getNameId() const { return (uint32) (NameId ? NameId->getValue32() : 0); } uint8 getInfoVersion() const { return (uint8) (InfoVersion ? (uint8) InfoVersion->getValue8() : 0); } + uint8 getResaleFlag() const { return (uint8) (ResaleFlag ? (uint8) ResaleFlag->getValue8() : 0); } + bool getLockedByOwner() const { return (bool) (ResaleFlag ? (ResaleFlag->getValue8() == BOTCHATTYPE::ResaleKOLockedByOwner) : false); } // void setSheetID(uint32 si) { if (Sheet) Sheet->setValue32((sint32) si); } void setQuality(uint16 quality) { if (Quality) Quality->setValue16((sint16) quality); } @@ -86,6 +90,7 @@ public: void setWeight(uint32 wgt) { if (Weight) Weight->setValue32((sint32) wgt); } void setNameId(uint32 nid) { if (NameId) NameId->setValue32((sint32) nid); } void setInfoVersion(uint8 iv) { if (InfoVersion) InfoVersion->setValue8((sint8) iv); } + void setResaleFlag(uint8 resale) { if (ResaleFlag) ResaleFlag->setValue8(resale); } }; @@ -504,18 +509,20 @@ struct SBagOptions CCDBNodeLeaf *DbFilterTool; CCDBNodeLeaf *DbFilterMP; CCDBNodeLeaf *DbFilterMissMP; + CCDBNodeLeaf *DbFilterTP; bool LastDbFilterArmor; bool LastDbFilterWeapon; bool LastDbFilterTool; bool LastDbFilterMP; bool LastDbFilterMissMP; + bool LastDbFilterTP; // ----------------------- SBagOptions() { InvType = CInventoryManager::InvUnknown; - DbFilterArmor = DbFilterWeapon = DbFilterTool = DbFilterMP = DbFilterMissMP = NULL; - LastDbFilterArmor = LastDbFilterWeapon = LastDbFilterTool = LastDbFilterMP = LastDbFilterMissMP = false; + DbFilterArmor = DbFilterWeapon = DbFilterTool = DbFilterMP = DbFilterMissMP = DbFilterTP = NULL; + LastDbFilterArmor = LastDbFilterWeapon = LastDbFilterTool = LastDbFilterMP = LastDbFilterMissMP = LastDbFilterTP = false; } bool parse (xmlNodePtr cur, CInterfaceGroup *parentGroup); @@ -552,6 +559,12 @@ struct SBagOptions return (DbFilterMissMP->getValue8()!=0); } + bool getFilterTP() const + { + if (DbFilterTP == NULL) return true; + return (DbFilterTP->getValue8() != 0); + } + // Return true if the sheet can be displayed due to filters bool canDisplay(CDBCtrlSheet *pCS) const; }; diff --git a/code/ryzom/client/src/interface_v3/lua_ihm.cpp b/code/ryzom/client/src/interface_v3/lua_ihm.cpp index 15dd9872a..44e9a3ba7 100644 --- a/code/ryzom/client/src/interface_v3/lua_ihm.cpp +++ b/code/ryzom/client/src/interface_v3/lua_ihm.cpp @@ -143,7 +143,7 @@ extern NLMISC::CLog g_log; extern CContinentManager ContinentMngr; extern uint8 PlayerSelectedSlot; extern CClientChatManager ChatMngr; -extern void addWebIGParams (string &url); +extern void addWebIGParams (string &url, bool trustedDomain); // declare ostream << operator for ucstring -> registration of ucstring iin luabind will build a 'tostring' function from it std::ostream &operator<<(std::ostream &str, const ucstring &value) @@ -1323,6 +1323,7 @@ void CLuaIHM::registerIHM(CLuaState &ls) ls.registerFunc("getIndexInDB", getIndexInDB); ls.registerFunc("getUIId", getUIId); ls.registerFunc("createGroupInstance", createGroupInstance); + ls.registerFunc("createRootGroupInstance", createRootGroupInstance); ls.registerFunc("createUIElement", createUIElement); ls.registerFunc("launchContextMenuInGame", launchContextMenuInGame); ls.registerFunc("parseInterfaceFromString", parseInterfaceFromString); @@ -1356,6 +1357,19 @@ void CLuaIHM::registerIHM(CLuaState &ls) ls.registerFunc("enableModalWindow", enableModalWindow); ls.registerFunc("disableModalWindow", disableModalWindow); ls.registerFunc("getPlayerPos", getPlayerPos); + ls.registerFunc("getPlayerFront", getPlayerFront); + ls.registerFunc("getPlayerDirection", getPlayerDirection); + ls.registerFunc("getPlayerGender", getPlayerGender); + ls.registerFunc("getPlayerName", getPlayerName); + ls.registerFunc("getPlayerTitleRaw", getPlayerTitleRaw); + ls.registerFunc("getPlayerTitle", getPlayerTitle); + ls.registerFunc("getTargetPos", getTargetPos); + ls.registerFunc("getTargetFront", getTargetFront); + ls.registerFunc("getTargetDirection", getTargetDirection); + ls.registerFunc("getTargetGender", getTargetGender); + ls.registerFunc("getTargetName", getTargetName); + ls.registerFunc("getTargetTitleRaw", getTargetTitleRaw); + ls.registerFunc("getTargetTitle", getTargetTitle); ls.registerFunc("addSearchPathUser", addSearchPathUser); ls.registerFunc("displaySystemInfo", displaySystemInfo); ls.registerFunc("disableContextHelpForControl", disableContextHelpForControl); @@ -1363,6 +1377,7 @@ void CLuaIHM::registerIHM(CLuaState &ls) ls.registerFunc("setWeatherValue", setWeatherValue); ls.registerFunc("getWeatherValue", getWeatherValue); ls.registerFunc("getCompleteIslands", getCompleteIslands); + ls.registerFunc("displayBubble", displayBubble); ls.registerFunc("getIslandId", getIslandId); ls.registerFunc("getClientCfgVar", getClientCfgVar); ls.registerFunc("isPlayerFreeTrial", isPlayerFreeTrial); @@ -1370,14 +1385,18 @@ void CLuaIHM::registerIHM(CLuaState &ls) ls.registerFunc("isInRingMode", isInRingMode); ls.registerFunc("getUserRace", getUserRace); ls.registerFunc("getSheet2idx", getSheet2idx); + ls.registerFunc("getTargetSlot", getTargetSlot); + ls.registerFunc("getSlotDataSetId", getSlotDataSetId); // Through LUABind API lua_State *L= ls.getStatePointer(); luabind::module(L) [ + LUABIND_FUNC(addDbProp), LUABIND_FUNC(getDbProp), LUABIND_FUNC(setDbProp), + LUABIND_FUNC(delDbProp), LUABIND_FUNC(debugInfo), LUABIND_FUNC(rawDebugInfo), LUABIND_FUNC(dumpCallStack), @@ -1456,9 +1475,16 @@ void CLuaIHM::registerIHM(CLuaState &ls) luabind::def("shellExecute", CMiscFunctions::shellExecute), LUABIND_FUNC(getPlayerLevel), + LUABIND_FUNC(getPlayerVpa), + LUABIND_FUNC(getPlayerVpb), + LUABIND_FUNC(getPlayerVpc), LUABIND_FUNC(getTargetLevel), LUABIND_FUNC(getTargetForceRegion), LUABIND_FUNC(getTargetLevelForce), + LUABIND_FUNC(getTargetSheet), + LUABIND_FUNC(getTargetVpa), + LUABIND_FUNC(getTargetVpb), + LUABIND_FUNC(getTargetVpc), LUABIND_FUNC(isTargetNPC), LUABIND_FUNC(isTargetPlayer), // return 'true' if the target is an npc LUABIND_FUNC(isTargetUser), @@ -1686,12 +1712,60 @@ void CLuaIHM::setDbProp(const std::string &dbProp, sint32 value) // Write to the DB if found CInterfaceManager *pIM= CInterfaceManager::getInstance(); CCDBNodeLeaf *node= pIM->getDbProp(dbProp, false); + if(node) node->setValue32(value); else debugInfo(toString("setDbProp(): '%s' dbProp Not found", dbProp.c_str())); } +void CLuaIHM::delDbProp(const string &dbProp) +{ + //H_AUTO(Lua_CLuaIHM_setDbProp) + // Do not allow Write on SERVER: or LOCAL: + static const string dbServer= "SERVER:"; + static const string dbLocal= "LOCAL:"; + static const string dbLocalR2= "LOCAL:R2"; + if( (0==dbProp.compare(0, dbServer.size(), dbServer)) || + (0==dbProp.compare(0, dbLocal.size(), dbLocal)) + ) + { + if (0!=dbProp.compare(0, dbLocalR2.size(), dbLocalR2)) + { + 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(); + pIM->delDbProp(dbProp); +} + +void CLuaIHM::addDbProp(const std::string &dbProp, sint32 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( (0==dbProp.compare(0, dbServer.size(), dbServer)) || + (0==dbProp.compare(0, dbLocal.size(), dbLocal)) + ) + { + if (0!=dbProp.compare(0, dbLocalR2.size(), dbLocalR2)) + { + 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= pIM->getDbProp(dbProp, true); + if(node) + node->setValue32(value); +} // *************************************************************************** void CLuaIHM::debugInfo(const std::string &cstDbg) @@ -1865,7 +1939,21 @@ std::string CLuaIHM::getDefine(const std::string &def) // *************************************************************************** -static CEntityCL *getTargetSlot() +static sint32 getTargetSlotNr() +{ + const char *dbPath = "UI:VARIABLES:TARGET:SLOT"; + CInterfaceManager *im = CInterfaceManager::getInstance(); + CCDBNodeLeaf *node = im->getDbProp(dbPath, false); + if (!node) return NULL; + if ((uint8) node->getValue32() == (uint8) CLFECOMMON::INVALID_SLOT) + { + return NULL; + } + return node->getValue32(); +} + +// *************************************************************************** +static CEntityCL *getTargetEntity() { const char *dbPath = "UI:VARIABLES:TARGET:SLOT"; CInterfaceManager *im = CInterfaceManager::getInstance(); @@ -1878,6 +1966,12 @@ static CEntityCL *getTargetSlot() return EntitiesMngr.entity((uint) node->getValue32()); } +// *************************************************************************** +static CEntityCL *getSlotEntity(uint slot) +{ + return EntitiesMngr.entity(slot); +} + // *************************************************************************** sint32 CLuaIHM::getPlayerLevel() { @@ -1890,10 +1984,31 @@ sint32 CLuaIHM::getPlayerLevel() return sint32(maxskill); } +// *************************************************************************** +sint64 CLuaIHM::getPlayerVpa() +{ + sint64 prop = CInterfaceManager::getInstance()->getDbProp("SERVER:Entities:E0:P"+toString("%d", CLFECOMMON::PROPERTY_VPA))->getValue64(); + return prop; +} + +// *************************************************************************** +sint64 CLuaIHM::getPlayerVpb() +{ + sint64 prop = CInterfaceManager::getInstance()->getDbProp("SERVER:Entities:E0:P"+toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64(); + return prop; +} + +// *************************************************************************** +sint64 CLuaIHM::getPlayerVpc() +{ + sint64 prop = CInterfaceManager::getInstance()->getDbProp("SERVER:Entities:E0:P"+toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64(); + return prop; +} + // *************************************************************************** sint32 CLuaIHM::getTargetLevel() { - CEntityCL *target = getTargetSlot(); + CEntityCL *target = getTargetEntity(); if (!target) return -1; if ( target->isPlayer() ) { @@ -1913,10 +2028,52 @@ sint32 CLuaIHM::getTargetLevel() return -1; } +// *************************************************************************** +ucstring CLuaIHM::getTargetSheet() +{ + CEntityCL *target = getTargetEntity(); + if (!target) return ""; + + return target->sheetId().toString(); +} + +// *************************************************************************** +sint64 CLuaIHM::getTargetVpa() +{ + CEntityCL *target = getTargetEntity(); + if (!target) return 0; + + sint64 prop = CInterfaceManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", getTargetSlotNr())+":P"+toString("%d", CLFECOMMON::PROPERTY_VPA))->getValue64(); + + return prop; +} + +// *************************************************************************** +sint64 CLuaIHM::getTargetVpb() +{ + CEntityCL *target = getTargetEntity(); + if (!target) return 0; + + sint64 prop = CInterfaceManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", getTargetSlotNr())+":P"+toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64(); + + return prop; +} + +// *************************************************************************** +sint64 CLuaIHM::getTargetVpc() +{ + CEntityCL *target = getTargetEntity(); + if (!target) return 0; + + sint64 prop = CInterfaceManager::getInstance()->getDbProp("SERVER:Entities:E"+toString("%d", getTargetSlotNr())+":P"+toString("%d", CLFECOMMON::PROPERTY_VPB))->getValue64(); + + return prop; +} + // *************************************************************************** sint32 CLuaIHM::getTargetForceRegion() { - CEntityCL *target = getTargetSlot(); + CEntityCL *target = getTargetEntity(); if (!target) return -1; if ( target->isPlayer() ) { @@ -1944,7 +2101,7 @@ sint32 CLuaIHM::getTargetForceRegion() // *************************************************************************** sint32 CLuaIHM::getTargetLevelForce() { - CEntityCL *target = getTargetSlot(); + CEntityCL *target = getTargetEntity(); if (!target) return -1; if ( target->isPlayer() ) { @@ -1972,7 +2129,7 @@ sint32 CLuaIHM::getTargetLevelForce() // *************************************************************************** bool CLuaIHM::isTargetNPC() { - CEntityCL *target = getTargetSlot(); + CEntityCL *target = getTargetEntity(); if (!target) return false; return target->isNPC(); } @@ -1980,7 +2137,7 @@ bool CLuaIHM::isTargetNPC() // *************************************************************************** bool CLuaIHM::isTargetPlayer() { - CEntityCL *target = getTargetSlot(); + CEntityCL *target = getTargetEntity(); if (!target) return false; return target->isPlayer(); } @@ -1989,7 +2146,7 @@ bool CLuaIHM::isTargetPlayer() // *************************************************************************** bool CLuaIHM::isTargetUser() { - CEntityCL *target = getTargetSlot(); + CEntityCL *target = getTargetEntity(); if (!target) return false; return target->isUser(); } @@ -1998,15 +2155,15 @@ bool CLuaIHM::isTargetUser() bool CLuaIHM::isPlayerInPVPMode() { if (!UserEntity) return false; - return (UserEntity->getPvpMode() & PVP_MODE::PvpFaction || UserEntity->getPvpMode() & PVP_MODE::PvpFactionFlagged || UserEntity->getPvpMode() & PVP_MODE::PvpZoneFaction); + return (UserEntity->getPvpMode() & PVP_MODE::PvpFaction || UserEntity->getPvpMode() & PVP_MODE::PvpFactionFlagged || UserEntity->getPvpMode() & PVP_MODE::PvpZoneFaction) != 0; } // *************************************************************************** bool CLuaIHM::isTargetInPVPMode() { - CEntityCL *target = getTargetSlot(); + CEntityCL *target = getTargetEntity(); if (!target) return false; - return (target->getPvpMode() & PVP_MODE::PvpFaction || target->getPvpMode() & PVP_MODE::PvpFactionFlagged || target->getPvpMode() & PVP_MODE::PvpZoneFaction); + return (target->getPvpMode() & PVP_MODE::PvpFaction || target->getPvpMode() & PVP_MODE::PvpFactionFlagged || target->getPvpMode() & PVP_MODE::PvpZoneFaction) != 0; } // *************************************************************************** @@ -2368,6 +2525,53 @@ int CLuaIHM::createGroupInstance(CLuaState &ls) return 1; } +// *************************************************************************** +int CLuaIHM::createRootGroupInstance(CLuaState &ls) +{ + //H_AUTO(Lua_CLuaIHM_createGroupInstance) + const char *funcName = "createRootGroupInstance"; + CLuaIHM::checkArgCount(ls, funcName, 3); + CLuaIHM::checkArgType(ls, funcName, 1, LUA_TSTRING); + CLuaIHM::checkArgType(ls, funcName, 2, LUA_TSTRING); + CLuaIHM::checkArgType(ls, funcName, 3, LUA_TTABLE); + std::vector > templateParams; + CLuaObject params; + params.pop(ls); + ENUM_LUA_TABLE(params, it) + { + if (!it.nextKey().isString()) + { + nlwarning("%s : bad key encountered with type %s, string expected.", funcName, it.nextKey().getTypename()); + continue; + } + if (!it.nextValue().isString()) + { + nlwarning("%s : bad value encountered with type %s for key %s, string expected.", funcName, it.nextValue().getTypename(), it.nextKey().toString().c_str()); + continue; + } + templateParams.push_back(std::pair(it.nextKey().toString(), it.nextValue().toString())); // strange compilation bug here when I use std::make_pair ... :( + } + CInterfaceManager *im = CInterfaceManager::getInstance(); + CInterfaceGroup *result = im->createGroupInstance(ls.toString(1), "ui:interface:"+string(ls.toString(2)), templateParams); + if (!result) + { + ls.pushNil(); + } + else + { + result->setId("ui:interface:"+string(ls.toString(2))); + result->updateCoords(); + im->addWindowToMasterGroup("ui:interface", result); + CInterfaceGroup *pRoot = dynamic_cast(im->getElementFromId("ui:interface")); + result->setParent(pRoot); + if (pRoot) + pRoot->addGroup(result); + result->setActive(true); + CLuaIHM::pushUIOnStack(ls, result); + } + return 1; +} + // *************************************************************************** int CLuaIHM::createUIElement(CLuaState &ls) { @@ -2407,6 +2611,42 @@ int CLuaIHM::createUIElement(CLuaState &ls) return 1; } + +// *************************************************************************** +int CLuaIHM::displayBubble(CLuaState &ls) +{ + //H_AUTO(Lua_CLuaIHM_createUIElement) + const char *funcName = "displayBubble"; + CLuaIHM::checkArgCount(ls, funcName, 3); + CLuaIHM::checkArgType(ls, funcName, 1, LUA_TNUMBER); + CLuaIHM::checkArgType(ls, funcName, 2, LUA_TSTRING); + CLuaIHM::checkArgType(ls, funcName, 3, LUA_TTABLE); + std::vector strs; + std::vector links; + CLuaObject params; + params.pop(ls); + ENUM_LUA_TABLE(params, it) + { + if (!it.nextKey().isString()) + { + nlwarning("%s : bad key encountered with type %s, string expected.", funcName, it.nextKey().getTypename()); + continue; + } + if (!it.nextValue().isString()) + { + nlwarning("%s : bad value encountered with type %s for key %s, string expected.", funcName, it.nextValue().getTypename(), it.nextKey().toString().c_str()); + continue; + } + links.push_back(it.nextValue().toString()); + strs.push_back(it.nextKey().toString()); + } + + InSceneBubbleManager.webIgChatOpen((uint32)ls.toNumber(1), ls.toString(2), strs, links); + + return 1; +} + + // *************************************************************************** int CLuaIHM::getCompleteIslands(CLuaState &ls) { @@ -3523,7 +3763,7 @@ void CLuaIHM::browseNpcWebPage(const std::string &htmlId, const std::string &url string("&lang=") + ClientCfg.getHtmlLanguageCode() + string("&guild_name=") + guildName; } -/* +/* Already added by GroupHtml if(webig) { // append special webig auth params @@ -4242,6 +4482,126 @@ int CLuaIHM::getPlayerPos(CLuaState &ls) return 3; } +// *************************************************************************** +int CLuaIHM::getPlayerFront(CLuaState &ls) +{ + checkArgCount(ls, "getPlayerFront", 0); + ls.push(atan2(UserEntity->front().y, UserEntity->front().x)); + return 1; +} + +// *************************************************************************** +int CLuaIHM::getPlayerDirection(CLuaState &ls) +{ + checkArgCount(ls, "getPlayerDirection", 0); + ls.push(atan2(UserEntity->dir().y, UserEntity->dir().x)); + return 1; +} + +// *************************************************************************** +int CLuaIHM::getPlayerGender(CLuaState &ls) +{ + checkArgCount(ls, "getPlayerGender", 0); + ls.push((lua_Number)(UserEntity->getGender())); + return 1; +} + +// *************************************************************************** +int CLuaIHM::getPlayerName(CLuaState &ls) +{ + checkArgCount(ls, "getPlayerName", 0); + ls.push(UserEntity->getEntityName().toUtf8()); + return 1; +} + +// *************************************************************************** +int CLuaIHM::getPlayerTitleRaw(CLuaState &ls) +{ + checkArgCount(ls, "getPlayerTitleRaw", 0); + ls.push(UserEntity->getTitleRaw().toUtf8()); + return 1; +} + +// *************************************************************************** +int CLuaIHM::getPlayerTitle(CLuaState &ls) +{ + checkArgCount(ls, "getPlayerTitle", 0); + ls.push(UserEntity->getTitle().toUtf8()); + return 1; +} + +// *************************************************************************** +int CLuaIHM::getTargetPos(CLuaState &ls) +{ + checkArgCount(ls, "getTargetPos", 0); + CEntityCL *target = getTargetEntity(); + if (!target) return 0; + ls.push(target->pos().x); + ls.push(target->pos().y); + ls.push(target->pos().z); + return 3; +} + +// *************************************************************************** +int CLuaIHM::getTargetFront(CLuaState &ls) +{ + checkArgCount(ls, "getTargetFront", 0); + CEntityCL *target = getTargetEntity(); + if (!target) return 0; + ls.push(atan2(target->front().y, target->front().x)); + return 1; +} + +// *************************************************************************** +int CLuaIHM::getTargetDirection(CLuaState &ls) +{ + checkArgCount(ls, "getTargetDirection", 0); + CEntityCL *target = getTargetEntity(); + if (!target) return 0; + ls.push(atan2(target->dir().y, target->dir().x)); + return 1; +} + +// *************************************************************************** +int CLuaIHM::getTargetGender(CLuaState &ls) +{ + checkArgCount(ls, "getTargetGender", 0); + CCharacterCL* target = (CCharacterCL*)getTargetEntity(); + if (!target) return (int)GSGENDER::unknown; + ls.push((lua_Number)(target->getGender())); + return 1; +} + +// *************************************************************************** +int CLuaIHM::getTargetName(CLuaState &ls) +{ + checkArgCount(ls, "getTargetName", 0); + CEntityCL *target = getTargetEntity(); + if (!target) return 0; + ls.push(target->getEntityName().toUtf8()); + return 1; +} + +// *************************************************************************** +int CLuaIHM::getTargetTitleRaw(CLuaState &ls) +{ + checkArgCount(ls, "getTargetTitleRaw", 0); + CEntityCL *target = getTargetEntity(); + if (!target) return 0; + ls.push(target->getTitleRaw().toUtf8()); + return 1; +} + +// *************************************************************************** +int CLuaIHM::getTargetTitle(CLuaState &ls) +{ + checkArgCount(ls, "getTargetTitle", 0); + CEntityCL *target = getTargetEntity(); + if (!target) return 0; + ls.push(target->getTitle().toUtf8()); + return 1; +} + // *************************************************************************** int CLuaIHM::addSearchPathUser(CLuaState &ls) { @@ -4437,3 +4797,23 @@ int CLuaIHM::getSheet2idx(CLuaState &ls) return 1; } +// *************************************************************************** +int CLuaIHM::getTargetSlot(CLuaState &ls) +{ + uint32 slot = (uint32)getTargetSlotNr(); + ls.push((lua_Number)slot); + return 1; +} + +// *************************************************************************** +int CLuaIHM::getSlotDataSetId(CLuaState &ls) +{ + CLuaIHM::checkArgCount(ls, "getSlotDataSetId", 1); + CLuaIHM::checkArgType(ls, "getSlotDataSetId", 1, LUA_TNUMBER); + + uint32 slot = (uint32)ls.toNumber(1); + CEntityCL *e = getSlotEntity(slot); + string id = toString(e->dataSetId()); + ls.push(id); + return 1; +} diff --git a/code/ryzom/client/src/interface_v3/lua_ihm.h b/code/ryzom/client/src/interface_v3/lua_ihm.h index 6a11a5c91..12d8b5459 100644 --- a/code/ryzom/client/src/interface_v3/lua_ihm.h +++ b/code/ryzom/client/src/interface_v3/lua_ihm.h @@ -185,9 +185,16 @@ private: // LUA exported Functions with luabind static sint32 getPlayerLevel(); // get max level among player skills (magi, combat, crafting ,foraging) + static sint64 getPlayerVpa(); + static sint64 getPlayerVpb(); + static sint64 getPlayerVpc(); static sint32 getTargetLevel(); // get current, precise level of the selected target, or -1 if there's no such selected target static sint32 getTargetForceRegion(); // get 'force region' for current target, or -1 if there's no selected target - static sint32 getTargetLevelForce(); // get 'level force' for current target, or -1 if there's no selected target + static sint32 getTargetLevelForce(); // get 'level force' for current target, or -1 if there's no selected target + static ucstring getTargetSheet(); // get the name of the target sheet (like 'zoha2old.creature') + static sint64 getTargetVpa(); + static sint64 getTargetVpb(); + static sint64 getTargetVpc(); static bool isTargetNPC(); // return 'true' if the target is an npc static bool isTargetPlayer(); // return 'true' if the target is a player static bool isTargetUser(); // return 'true' if the target is the user @@ -202,10 +209,12 @@ private: static bool isInGame(); static uint32 getPlayerSelectedSlot(); static bool isPlayerSlotNewbieLand(uint32 slot); // test if one of the player slot is a newbieland one, if not so, client must be patched in order to continue - static uint32 getLocalTime(); + static uint32 getLocalTime(); static double getPreciseLocalTime(); static sint32 getDbProp(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 addDbProp(const std::string &dbProp, sint32 value); // Nb: the db prop is created if not present. + static void delDbProp(const std::string &dbProp); static std::string getDefine(const std::string &def); static void messageBox(const ucstring &text); static void messageBox(const ucstring &text, const std::string &masterGroup); @@ -286,17 +295,24 @@ private: static int getUICaller(CLuaState &ls); // params: none. return: CInterfaceElement* (nil if error) static int getCurrentWindowUnder(CLuaState &ls); // params: none. return: CInterfaceElement* (nil if none) static int getUI(CLuaState &ls); // params: "ui:interface:...". return: CInterfaceElement* (nil if error), an additionnal boolean parameter - // can specify verbose display when the element is note found (default is true) + // can specify verbose display when the element is note found (default is true) static int createGroupInstance(CLuaState &ls); // params : param 1 = template name, - // param 2 = id of parent where the instance will be inserted - // param 3 = table with ("template_param", "template_param_value") key/value pairs + // param 2 = id of parent where the instance will be inserted + // param 3 = table with ("template_param", "template_param_value") key/value pairs // such as { id="foo", x="10" } etc. -> returns a new instance of the template, or nil on fail + static int createRootGroupInstance(CLuaState &ls); // params : param 1 = template name, + // param 2 = id of parent where the instance will be inserted + // param 3 = table with ("template_param", "template_param_value") key/value pairs + // such as { id="foo", x="10" } etc. -> returns a new instance of the template, or nil on fail static int createUIElement(CLuaState &ls); // params : param 1 = template name, - // param 2 = id of parent where the instance will be inserted - // param 3 = table with ("template_param", "template_param_value") key/value pairs + // param 2 = id of parent where the instance will be inserted + // param 3 = table with ("template_param", "template_param_value") key/value pairs // such as { id="foo", x="10" } etc. -> returns a new instance of the template, or nil on fail - + static int displayBubble(CLuaState &ls); // params : param 1 = bot id + // param 2 = text + // param 3 = table with all strings and urls + // {"main text"="http:///", "text option 1"="http:///", "text option 2"="http:///") etc... static int getIndexInDB(CLuaState &ls); // params: CDBCtrlSheet*.... return: index, or 0 if error static int getUIId(CLuaState &ls); // params: CInterfaceElement*. return: ui id (empty if error) static int runAH(CLuaState &ls); // params: CInterfaceElement *, "ah", "params". return: none @@ -334,9 +350,9 @@ private: static int getServerSeason(CLuaState &ls); // get the last season sent by the server // 0->auto, computed locally from the current day (or not received from server yet) // 1->server force spring - // 2->' ' ' summer - // 3->' ' ' autumn - // 4->' ' ' winter + // 2->' ' ' summer + // 3->' ' ' autumn + // 4->' ' ' winter static int computeCurrSeason(CLuaState &ls); // compute current displayed season (1->spring, etc .) static int getAutoSeason(CLuaState &ls); // compute automatic season that would be at this time (1->spring, etc .) @@ -345,6 +361,19 @@ private: static int enableModalWindow(CLuaState &ls); static int disableModalWindow(CLuaState &ls); static int getPlayerPos(CLuaState &ls); + static int getPlayerFront(CLuaState &ls); + static int getPlayerDirection(CLuaState &ls); + static int getPlayerGender(CLuaState &ls); + static int getPlayerName(CLuaState &ls); + static int getPlayerTitleRaw(CLuaState &ls); + static int getPlayerTitle(CLuaState &ls); + static int getTargetPos(CLuaState &ls); + static int getTargetFront(CLuaState &ls); + static int getTargetDirection(CLuaState &ls); + static int getTargetGender(CLuaState &ls); + static int getTargetName(CLuaState &ls); + static int getTargetTitleRaw(CLuaState &ls); + static int getTargetTitle(CLuaState &ls); static int addSearchPathUser(CLuaState &ls); static int getClientCfgVar(CLuaState &ls); static int isPlayerFreeTrial(CLuaState &ls); @@ -352,6 +381,8 @@ private: static int isInRingMode(CLuaState &ls); static int getUserRace(CLuaState &ls); static int getSheet2idx(CLuaState &ls); + static int getTargetSlot(CLuaState &ls); + static int getSlotDataSetId(CLuaState &ls); // LUA functions exported for Dev only (debug) diff --git a/code/ryzom/client/src/interface_v3/people_interraction.cpp b/code/ryzom/client/src/interface_v3/people_interraction.cpp index e98013f9a..a92d73ce3 100644 --- a/code/ryzom/client/src/interface_v3/people_interraction.cpp +++ b/code/ryzom/client/src/interface_v3/people_interraction.cpp @@ -40,6 +40,7 @@ #include "../net_manager.h" #include "../connection.h" #include "group_tab.h" +#include "guild_manager.h" // Game share #include "game_share/entity_types.h" // NeL @@ -1418,7 +1419,47 @@ void CPeopleInterraction::updateContactInList(uint32 contactId, TCharConnectionS { sint index = FriendList.getIndexFromContactId(contactId); if (index != -1) - FriendList.setOnline(index, online); + { + if (FriendList.getOnline(index) != online) + { + // Only do work if online status has changed + FriendList.setOnline(index, online); + + CCDBNodeLeaf* node = CInterfaceManager::getInstance()->getDbProp("UI:SAVE:CHAT:SHOW_ONLINE_OFFLINE_NOTIFICATIONS_CB", false); + if (node && node->getValueBool()) + { + // Only show the message if this player is not in my guild (because then the guild manager will show a message) + std::vector GuildMembers = CGuildManager::getInstance()->getGuildMembers(); + bool bOnlyFriend = true; + ucstring name = toLower(FriendList.getName(index)); + for (uint i = 0; i < GuildMembers.size(); ++i) + { + if (toLower(GuildMembers[i].Name) == name) + { + bOnlyFriend = false; + break; + } + } + + // Player is not in my guild + if (bOnlyFriend) + { + ucstring msg = (online != ccs_offline) ? CI18N::get("uiPlayerOnline") : CI18N::get("uiPlayerOffline"); + strFindReplace(msg, "%s", FriendList.getName(index)); + string cat = getStringCategory(msg, msg); + map::const_iterator it; + NLMISC::CRGBA col = CRGBA::Yellow; + it = ClientCfg.SystemInfoParams.find(toLower(cat)); + if (it != ClientCfg.SystemInfoParams.end()) + { + col = it->second.Color; + } + bool dummy; + PeopleInterraction.ChatInput.AroundMe.displayMessage(msg, col, 2, &dummy); + } + } + } + } } else { @@ -1988,6 +2029,39 @@ public: }; REGISTER_ACTION_HANDLER( CHandlerDismissMember, "dismiss_member"); +//================================================================================================================= +// Set the leader of the team +class CHandlerSetTeamLeader : public IActionHandler +{ +public: + void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */) + { + // retrieve the index of the people + CPeopleList *list; + uint peopleIndex; + if (PeopleInterraction.getPeopleFromCurrentMenu(list, peopleIndex)) + { + if (list == &PeopleInterraction.TeamList) // check for good list + { + /* + const string msgName = "TEAM:SET_LEADER"; + CBitMemStream out; + if(GenericMsgHeaderMngr.pushNameToStream(msgName, out)) + { + uint8 teamMember = (uint8)(peopleIndex); + out.serial(teamMember); + NetMngr.push(out); + //nlinfo("impulseCallBack : %s %d sent", msgName.c_str(), teamMember); + } + else + nlwarning("command 'set_leader': unknown message named '%s'.", msgName.c_str()); + */ + NLMISC::ICommand::execute("a setTeamLeader " + toString(peopleIndex), g_log); + } + } + } +}; +REGISTER_ACTION_HANDLER( CHandlerSetTeamLeader, "set_team_leader"); //================================================================================================================= // Set a successor for the team @@ -3236,6 +3310,12 @@ NLMISC_COMMAND(chatLog, "", "") if (pIM->getLogState()) pIM->displaySystemInfo(CI18N::get("uiLogTurnedOn")); + CCDBNodeLeaf *node = pIM->getDbProp("UI:SAVE:CHATLOG_STATE", false); + if (node) + { + node->setValue32(pIM->getLogState() ? 1 : 0); + } + return true; }; diff --git a/code/ryzom/client/src/interface_v3/people_list.cpp b/code/ryzom/client/src/interface_v3/people_list.cpp index ac4764e15..c9b95a14a 100644 --- a/code/ryzom/client/src/interface_v3/people_list.cpp +++ b/code/ryzom/client/src/interface_v3/people_list.cpp @@ -211,7 +211,8 @@ bool CPeopleList::sortExByOnline(const CPeople& a, const CPeople& b) { return (name_a < name_b); } - else { + else + { // Compare online status switch (a.Online) { @@ -467,14 +468,8 @@ void CPeopleList::displayLocalPlayerTell(const ucstring &receiver, uint index, c return; } - ucstring cur_time; - CCDBNodeLeaf *pNL = CInterfaceManager::getInstance()->getDbProp("UI:SAVE:CHAT:SHOW_TIMES_IN_CHAT_CB", false); - if (pNL && pNL->getValueBool()) - cur_time = CInterfaceManager::getTimestampHuman(); - - ucstring csr; - if (CHARACTER_TITLE::isCsrTitle(UserEntity->getTitleRaw())) csr += ucstring("(CSR) "); - ucstring finalMsg = cur_time + csr + CI18N::get("youTell") + ": " + msg; + ucstring csr = CHARACTER_TITLE::isCsrTitle(UserEntity->getTitleRaw()) ? "(CSR) " : ""; + ucstring finalMsg = csr + CI18N::get("youTell") + ": " + msg; // display msg with good color CInterfaceProperty prop; prop.readRGBA("UI:SAVE:CHAT:COLORS:TELL"," "); @@ -783,10 +778,6 @@ void CPeopleList::setOnline(uint index, TCharConnectionState online) _Peoples[index].Online = online; - // If the people goes offline remove eventually opened chat - if (online == ccs_offline) - openCloseChat(index, false); - updatePeopleMenu(index); } @@ -944,14 +935,8 @@ class CHandlerContactEntry : public IActionHandler ucstring final; CChatWindow::encodeColorTag(prop.getRGBA(), final, false); - ucstring cur_time; - CCDBNodeLeaf *pNL = CInterfaceManager::getInstance()->getDbProp("UI:SAVE:CHAT:SHOW_TIMES_IN_CHAT_CB", false); - if (pNL && pNL->getValueBool()) - cur_time = CInterfaceManager::getTimestampHuman(); - - ucstring csr; - if (CHARACTER_TITLE::isCsrTitle(UserEntity->getTitleRaw())) csr += ucstring("(CSR) "); - final += cur_time + csr + CI18N::get("youTell")+": "; + ucstring csr = CHARACTER_TITLE::isCsrTitle(UserEntity->getTitleRaw()) ? "(CSR) " : ""; + final += csr + CI18N::get("youTell")+": "; prop.readRGBA("UI:SAVE:CHAT:COLORS:TELL"," "); CChatWindow::encodeColorTag(prop.getRGBA(), final, true); final += text; @@ -962,7 +947,6 @@ class CHandlerContactEntry : public IActionHandler strFindReplace(final, CI18N::get("youTell"), s); CInterfaceManager::getInstance()->log(final); } - } } }; diff --git a/code/ryzom/client/src/interface_v3/player_trade.cpp b/code/ryzom/client/src/interface_v3/player_trade.cpp index 7307110d9..ebc618ec7 100644 --- a/code/ryzom/client/src/interface_v3/player_trade.cpp +++ b/code/ryzom/client/src/interface_v3/player_trade.cpp @@ -139,6 +139,7 @@ void CPlayerTrade::restoreItem(CDBCtrlSheet *exchangeSlot) im.getBagItem(emptySlot).setWeight((uint32) exchangeSlot->getItemWeight()); im.getBagItem(emptySlot).setNameId(exchangeSlot->getItemNameId()); im.getBagItem(emptySlot).setInfoVersion(exchangeSlot->getItemInfoVersion()); + im.getBagItem(emptySlot).setResaleFlag(exchangeSlot->getItemResaleFlag()); } diff --git a/code/ryzom/client/src/interface_v3/skill_manager.cpp b/code/ryzom/client/src/interface_v3/skill_manager.cpp index 9d59c5bcb..c5fec7eb8 100644 --- a/code/ryzom/client/src/interface_v3/skill_manager.cpp +++ b/code/ryzom/client/src/interface_v3/skill_manager.cpp @@ -1042,7 +1042,7 @@ void CSkillManager::setPlayerTitle(const std::string &name) // *************************************************************************** // *************************************************************************** -#define GROUP_TITLE_COMBO "ui:interface:info_player_skills:content:basics_skills:title:player_title" +#define GROUP_TITLE_COMBO "ui:interface:info_player_skills:content:webinfos:title:player_title" // *************************************************************************** class CHandlerTitleInit: public IActionHandler diff --git a/code/ryzom/client/src/interface_v3/view_base.h b/code/ryzom/client/src/interface_v3/view_base.h index b568014a6..f4faaa204 100644 --- a/code/ryzom/client/src/interface_v3/view_base.h +++ b/code/ryzom/client/src/interface_v3/view_base.h @@ -70,6 +70,10 @@ public: // from CInterfaceElement virtual void visit(CInterfaceElementVisitor *visitor); + + // special for mouse over : return true and fill the name of the cursor to display + virtual bool getMouseOverShape(std::string &/* texName */, uint8 &/* rot */, NLMISC::CRGBA &/* col */) { return false; } + }; diff --git a/code/ryzom/client/src/interface_v3/view_bitmap.h b/code/ryzom/client/src/interface_v3/view_bitmap.h index 9cfd9de09..670c6fdf7 100644 --- a/code/ryzom/client/src/interface_v3/view_bitmap.h +++ b/code/ryzom/client/src/interface_v3/view_bitmap.h @@ -72,6 +72,8 @@ public: bool getScale() const { return _Scale; } void setScale (bool s) { _Scale = s; } + bool getTile() const { return _Tile; } + void setTile (bool s) { _Tile = s; } void setColor (const NLMISC::CRGBA &r) { _Color = r; } // Reflected diff --git a/code/ryzom/client/src/interface_v3/view_link.cpp b/code/ryzom/client/src/interface_v3/view_link.cpp index 4b0426006..61421133e 100644 --- a/code/ryzom/client/src/interface_v3/view_link.cpp +++ b/code/ryzom/client/src/interface_v3/view_link.cpp @@ -42,5 +42,23 @@ void CViewLink::setHTMLView(CGroupHTML *html) HTML = html; } +// *************************************************************************** +bool CViewLink::getMouseOverShape(string &texName, uint8 &rot, CRGBA &col) +{ + if (HTML != NULL) + { + if (!LinkTitle.empty()) + { + texName = LinkTitle; + rot= 0; + col = CRGBA::White; + return true; + } + } + + return false; +} + + // *************************************************************************** diff --git a/code/ryzom/client/src/interface_v3/view_link.h b/code/ryzom/client/src/interface_v3/view_link.h index 7a77f2b81..ba30fafd2 100644 --- a/code/ryzom/client/src/interface_v3/view_link.h +++ b/code/ryzom/client/src/interface_v3/view_link.h @@ -38,8 +38,11 @@ public: // The URI std::string Link; + std::string LinkTitle; + // Set the main group void setHTMLView(class CGroupHTML *html); + bool getMouseOverShape(std::string &texName, uint8 &rot, NLMISC::CRGBA &col); protected: diff --git a/code/ryzom/client/src/interface_v3/view_pointer.cpp b/code/ryzom/client/src/interface_v3/view_pointer.cpp index e6e6dcaa2..27d3dae86 100644 --- a/code/ryzom/client/src/interface_v3/view_pointer.cpp +++ b/code/ryzom/client/src/interface_v3/view_pointer.cpp @@ -70,6 +70,7 @@ CViewPointer::CViewPointer (const TCtorParam ¶m) _Color = CRGBA(255,255,255,255); _LastHightLight = NULL; _StringMode = false; + _ForceStringMode = false; _StringCursor = NULL; } @@ -255,6 +256,41 @@ void CViewPointer::draw () return; } + const vector &vUP = pIM->getViewsUnderPointer (); + + for(uint i=0;i(vUP[i]); + if (vLink != NULL) + { + string tooltip; + uint8 rot; + + if (vLink->getMouseOverShape(tooltip, rot, col)) + { + setString(ucstring(tooltip)); + sint32 texId = rVR.getTextureIdFromName ("curs_pick.tga"); + + CInterfaceGroup *stringCursor = IsMouseCursorHardware() ? _StringCursorHardware : _StringCursor; + if (stringCursor) + { + stringCursor->setX(_PointerX); + stringCursor->setY(_PointerY); + stringCursor->updateCoords(); + stringCursor->draw(); + // if in hardware mode, force to draw the default cursor no matter what.. + if (IsMouseCursorHardware()) + drawCursor(texId, col, 0); + } + else + { + drawCursor(texId, col, 0); + } + return; + } + } + } + // Draw if capture right pCB = pIM->getCapturePointerRight(); if (pCB != NULL) @@ -521,16 +557,50 @@ bool CViewPointer::drawPan(CCtrlBase* pCB, NLMISC::CRGBA col) // -------------------------------------------------------------------------------------------------------------------- bool CViewPointer::drawCustom(CCtrlBase* pCB) { - std::string texName; + string texName; uint8 rot; NLMISC::CRGBA col; if (pCB->getMouseOverShape(texName, rot, col)) { - CInterfaceManager *pIM = CInterfaceManager::getInstance(); - CViewRenderer &rVR = pIM->getViewRenderer(); - sint32 texId = rVR.getTextureIdFromName (texName); - drawCursor(texId, col, 0); - return true; + if (texName[0] == '@') + { + const string &tooltipInfos = texName.substr(1); + string tooltip; + vector tooltipInfosList; + splitString(tooltipInfos, "@", tooltipInfosList); + texName = tooltipInfosList[0]; + tooltip = tooltipInfosList[1]; + nlinfo(tooltip.c_str()); + setString(ucstring(tooltip)); + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + CViewRenderer &rVR = pIM->getViewRenderer(); + sint32 texId = rVR.getTextureIdFromName (texName); + + CInterfaceGroup *stringCursor = IsMouseCursorHardware() ? _StringCursorHardware : _StringCursor; + if (stringCursor) + { + stringCursor->setX(_PointerX); + stringCursor->setY(_PointerY); + stringCursor->updateCoords(); + stringCursor->draw(); + // if in hardware mode, force to draw the default cursor no matter what.. + if (IsMouseCursorHardware()) + drawCursor(texId, col, 0); + } + else + { + drawCursor(texId, col, 0); + } + return true; + } + else + { + CInterfaceManager *pIM = CInterfaceManager::getInstance(); + CViewRenderer &rVR = pIM->getViewRenderer(); + sint32 texId = rVR.getTextureIdFromName (texName); + drawCursor(texId, col, 0); + return true; + } } return false; } diff --git a/code/ryzom/client/src/interface_v3/view_pointer.h b/code/ryzom/client/src/interface_v3/view_pointer.h index 0ade8b2c7..42a20b0a0 100644 --- a/code/ryzom/client/src/interface_v3/view_pointer.h +++ b/code/ryzom/client/src/interface_v3/view_pointer.h @@ -153,6 +153,7 @@ private: // Cursor mode bool _StringMode; + bool _ForceStringMode; CInterfaceGroup *_StringCursor; CInterfaceGroup *_StringCursorHardware; ucstring _ContextString; diff --git a/code/ryzom/client/src/interface_v3/view_renderer.cpp b/code/ryzom/client/src/interface_v3/view_renderer.cpp index 6a300275e..b3e419e5c 100644 --- a/code/ryzom/client/src/interface_v3/view_renderer.cpp +++ b/code/ryzom/client/src/interface_v3/view_renderer.cpp @@ -743,8 +743,8 @@ void CViewRenderer::loadTextures (const std::string &textureFileName, const std: image.UVMin.V = uvMinV; image.UVMax.U = uvMaxU; image.UVMax.V = uvMaxV; - sTGAname = tgaName; - sTGAname = toLower(sTGAname); + sTGAname = toLower(string(tgaName)); + string::size_type stripPng = sTGAname.find(".png"); if (stripPng != string::npos) { @@ -752,6 +752,7 @@ void CViewRenderer::loadTextures (const std::string &textureFileName, const std: sTGAname[stripPng + 2] = 'g'; sTGAname[stripPng + 3] = 'a'; } + image.Name = sTGAname; image.GlobalTexturePtr = &(_GlobalTextures.back()); if (getTextureIdFromName(sTGAname) != -1) @@ -1029,6 +1030,7 @@ sint32 CViewRenderer::getTextureIdFromName (const string &sName) const // convert to lowCase string nameLwr = toLower(sName); + string::size_type stripPng = nameLwr.find(".png"); if (stripPng != string::npos) { @@ -1036,7 +1038,7 @@ sint32 CViewRenderer::getTextureIdFromName (const string &sName) const nameLwr[stripPng + 2] = 'g'; nameLwr[stripPng + 3] = 'a'; } - + // Search in map TTextureMap::const_iterator it= _TextureMap.find(nameLwr); if( it==_TextureMap.end() ) @@ -1531,6 +1533,7 @@ void CViewRenderer::initSystemTextures() addSystemTexture(RegenTexture, "regen.tga"); addSystemTexture(RegenBackTexture, "regen_back.tga"); addSystemTexture(GlowStarTexture, "glow_star_24.tga"); + addSystemTexture(ItemLockedByOwnerTexture, "r2ed_toolbar_lock_small.tga"); } diff --git a/code/ryzom/client/src/interface_v3/view_renderer.h b/code/ryzom/client/src/interface_v3/view_renderer.h index ea7583dfa..cea807a23 100644 --- a/code/ryzom/client/src/interface_v3/view_renderer.h +++ b/code/ryzom/client/src/interface_v3/view_renderer.h @@ -75,6 +75,7 @@ public: RegenTexture, RegenBackTexture, GlowStarTexture, + ItemLockedByOwnerTexture, NumSystemTextures, }; diff --git a/code/ryzom/client/src/libwww.cpp b/code/ryzom/client/src/libwww.cpp index 966aeffa6..a1c0ce826 100644 --- a/code/ryzom/client/src/libwww.cpp +++ b/code/ryzom/client/src/libwww.cpp @@ -225,7 +225,10 @@ HTAttr p_attr[] = HTAttr div_attr[] = { - HTML_ATTR(DIV,NAME), + HTML_ATTR(DIV,CLASS), + HTML_ATTR(DIV,ID), + HTML_ATTR(DIV,NAME), + HTML_ATTR(DIV,STYLE), { 0 } }; @@ -535,6 +538,7 @@ const std::string &setCurrentDomain(const std::string &url) return HTTPCurrentDomain; } + void initLibWWW() { static bool initialized = false; diff --git a/code/ryzom/client/src/libwww.h b/code/ryzom/client/src/libwww.h index 41db90a6c..2c6ed2ae0 100644 --- a/code/ryzom/client/src/libwww.h +++ b/code/ryzom/client/src/libwww.h @@ -206,7 +206,10 @@ enum enum { - HTML_ATTR(DIV,NAME) = 0, + HTML_ATTR(DIV,CLASS) = 0, + HTML_ATTR(DIV,ID), + HTML_ATTR(DIV,NAME), + HTML_ATTR(DIV,STYLE), }; diff --git a/code/ryzom/client/src/login.cpp b/code/ryzom/client/src/login.cpp index d1dee738d..e43d6c8f5 100644 --- a/code/ryzom/client/src/login.cpp +++ b/code/ryzom/client/src/login.cpp @@ -738,8 +738,10 @@ void initLoginScreen() if(!l.empty()) { CGroupEditBox *pGEB = dynamic_cast(pIM->getElementFromId(CTRL_EDITBOX_LOGIN)); - if (pGEB != NULL) + if (pGEB != NULL && (pGEB->getInputString().empty())) + { pGEB->setInputString(l); + } pIM->runActionHandler("set_keyboard_focus", NULL, "target=" CTRL_EDITBOX_PASSWORD "|select_all=false"); } else @@ -1792,7 +1794,6 @@ class CAHOpenURL : public IActionHandler } else { - DWORD ret = 0; LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | @@ -1922,21 +1923,21 @@ class CAHInitResLod : public IActionHandler // first indicates the preset-able cfg-variable // second indicates if its a double variable (else it's an int) CfgPresetList.clear(); - CfgPresetList.push_back(pair("LandscapeTileNear", true)); - CfgPresetList.push_back(pair("LandscapeThreshold", true)); - CfgPresetList.push_back(pair("Vision", true)); - CfgPresetList.push_back(pair("MicroVeget", false)); - CfgPresetList.push_back(pair("MicroVegetDensity", true)); + CfgPresetList.push_back(pair("LandscapeTileNear", true)); + CfgPresetList.push_back(pair("LandscapeThreshold", true)); + CfgPresetList.push_back(pair("Vision", true)); + CfgPresetList.push_back(pair("MicroVeget", false)); + CfgPresetList.push_back(pair("MicroVegetDensity", true)); CfgPresetList.push_back(pair("FxNbMaxPoly", false)); - CfgPresetList.push_back(pair("Cloud", false)); + CfgPresetList.push_back(pair("Cloud", false)); CfgPresetList.push_back(pair("CloudQuality", true)); CfgPresetList.push_back(pair("CloudUpdate", false)); CfgPresetList.push_back(pair("Shadows", false)); - CfgPresetList.push_back(pair("SkinNbMaxPoly", false)); + CfgPresetList.push_back(pair("SkinNbMaxPoly", false)); CfgPresetList.push_back(pair("NbMaxSkeletonNotCLod", false)); CfgPresetList.push_back(pair("CharacterFarClip", true)); - CfgPresetList.push_back(pair("Bloom", false)); + CfgPresetList.push_back(pair("Bloom", false)); CfgPresetList.push_back(pair("SquareBloom", false)); CfgPresetList.push_back(pair("DensityBloom", true)); diff --git a/code/ryzom/client/src/main_loop.cpp b/code/ryzom/client/src/main_loop.cpp index 81a63ae60..15a525f58 100644 --- a/code/ryzom/client/src/main_loop.cpp +++ b/code/ryzom/client/src/main_loop.cpp @@ -2889,6 +2889,7 @@ bool mainLoop() // This code must remain at the very end of the main loop. if(LoginSM.getCurrentState() == CLoginStateMachine::st_enter_far_tp_main_loop) { + CInterfaceManager::getInstance()->executeLuaScript("game:onFarTpStart()"); // Will loop the network until the end of the relogging process FarTP.farTPmainLoop(); @@ -2965,6 +2966,8 @@ bool mainLoop() // Get the Connection State (must be done after any Far TP to prevent the uiDisconnected box to be displayed) lastConnectionState = CNetworkConnection::Connected; connectionState = NetMngr.getConnectionState(); + + CInterfaceManager::getInstance()->executeLuaScript("game:onFarTpEnd()"); } } // end of main loop diff --git a/code/ryzom/client/src/net_manager.cpp b/code/ryzom/client/src/net_manager.cpp index 568081c81..55df0585d 100644 --- a/code/ryzom/client/src/net_manager.cpp +++ b/code/ryzom/client/src/net_manager.cpp @@ -664,10 +664,12 @@ void CInterfaceChatDisplayer::displayChat(TDataSetIndex compressedSenderIndex, c } // select DB + sint32 dbIndex = ChatMngr.getDynamicChannelDbIndexFromId(dynChatId); + clamp(dbIndex,0 , CChatGroup::MaxDynChanPerPlayer); string entry="UI:SAVE:CHAT:COLORS:"; switch(mode) { - case CChatGroup::dyn_chat: entry+="DYN"; break; + case CChatGroup::dyn_chat: entry+="DYN:" + NLMISC::toString(dbIndex); break; case CChatGroup::say: entry+="SAY"; break; case CChatGroup::shout: entry+="SHOUT"; break; case CChatGroup::team: entry+="GROUP"; break; @@ -697,6 +699,11 @@ void CInterfaceChatDisplayer::displayChat(TDataSetIndex compressedSenderIndex, c } } + if (stringCategory == "emt") + { + bubbleWanted = false; + } + if (mode != CChatGroup::system) { // find the sender/text separator to put color tags @@ -3206,7 +3213,7 @@ void impulseOutpostDeclareWarAck(NLMISC::CBitMemStream &impulse) node->setValue32(timeStartAttack); } -extern void addWebIGParams (string &url); +extern void addWebIGParams(string &url, bool trustedDomain); //----------------------------------------------- //----------------------------------------------- @@ -3290,7 +3297,6 @@ private: string group = titleStr.toString(); // group = group.substr(9, group.size()-10); - nlinfo("group = %s", group.c_str()); groupHtml = dynamic_cast(pIM->getElementFromId("ui:interface:"+group+":content:html")); if (!groupHtml) { @@ -3312,7 +3318,7 @@ private: if (group == "webig") pGC->setActive(true); string url = contentStr.toString(); - addWebIGParams(url); + addWebIGParams(url, true); groupHtml->browse(url.c_str()); pIM->setTopWindow(pGC); } diff --git a/code/ryzom/client/src/player_cl.cpp b/code/ryzom/client/src/player_cl.cpp index 9dfe6e12f..d74cf6ae1 100644 --- a/code/ryzom/client/src/player_cl.cpp +++ b/code/ryzom/client/src/player_cl.cpp @@ -164,7 +164,7 @@ bool CPlayerCL::isNeutral() const //----------------------------------------------- bool CPlayerCL::isFriend () const { - return isNeutral() || isNeutralPVP() || isAlly(); + return isNeutral() || isAlly(); } @@ -174,12 +174,44 @@ bool CPlayerCL::isFriend () const //----------------------------------------------- bool CPlayerCL::isEnemy () const { + // Challenge i.e. SOLO FULL PVP + if( getPvpMode()&PVP_MODE::PvpChallenge || + UserEntity->getPvpMode()&PVP_MODE::PvpChallenge ) + { + return true; + } + + // if one of 2 players is not in pvp they can't be enemies if( UserEntity->getPvpMode() == PVP_MODE::None || getPvpMode() == PVP_MODE::None ) { return false; } + + // if one of 2 players is safe they can't be enemies + if( UserEntity->getPvpMode()&PVP_MODE::PvpSafe || + getPvpMode()&PVP_MODE::PvpSafe ) + { + return false; + } + + // if one of 2 players are in safe zone and not flagged they can't be enemies + if ((UserEntity->getPvpMode()&PVP_MODE::PvpZoneSafe && + ((UserEntity->getPvpMode()&PVP_MODE::PvpFactionFlagged) == 0)) + || + (getPvpMode()&PVP_MODE::PvpZoneSafe && + ((getPvpMode()&PVP_MODE::PvpFactionFlagged) == 0))) + { + return false; + } + + // Duel + if( getPvpMode()&PVP_MODE::PvpDuel && + UserEntity->getPvpMode()&PVP_MODE::PvpDuel ) + { + return true; // TODO + } // Outpost if ( isAnOutpostEnemy() ) @@ -187,19 +219,12 @@ bool CPlayerCL::isEnemy () const return true; } - // Challenge - if( getPvpMode()&PVP_MODE::PvpChallenge && - UserEntity->getPvpMode()&PVP_MODE::PvpChallenge ) - { - if( !isInTeam() ) - return true; - } - // Zone Free if( getPvpMode()&PVP_MODE::PvpZoneFree && UserEntity->getPvpMode()&PVP_MODE::PvpZoneFree ) { - if( !isInTeam() && !isInGuild() ) + // If not in same Team and not in same League => ennemy + if( !isInTeam() && !isInSameLeague() ) return true; } @@ -207,7 +232,11 @@ bool CPlayerCL::isEnemy () const if( getPvpMode()&PVP_MODE::PvpZoneGuild && UserEntity->getPvpMode()&PVP_MODE::PvpZoneGuild ) { - if( !isInTeam() && !isInGuild() ) + // If in same Guild but different Leagues => ennemy + if ( isInSameGuild() && oneInLeague() && !isInSameLeague() ) + return true; + + if( !isInTeam() && !isInSameLeague() ) return true; } @@ -219,29 +248,18 @@ bool CPlayerCL::isEnemy () const return true; } - // Duel - if( getPvpMode()&PVP_MODE::PvpDuel && - UserEntity->getPvpMode()&PVP_MODE::PvpDuel ) - { - return true; // TODO - } - - // Faction + // Free PVP : Ennemis are not in team AND not in league if ((getPvpMode()&PVP_MODE::PvpFaction || getPvpMode()&PVP_MODE::PvpFactionFlagged) && (UserEntity->getPvpMode()&PVP_MODE::PvpFaction || UserEntity->getPvpMode()&PVP_MODE::PvpFactionFlagged)) { - // Check if is not ally - if (!isInTeam() && !isInGuild()) - { - // Check for each Clan if is in opposition - for (uint8 i = 0; i < PVP_CLAN::NbClans; i++) - { - if ((isPvpEnnemy(i) && UserEntity->isPvpAlly(i)) || (isPvpAlly(i) && UserEntity->isPvpEnnemy(i))) - return true; - } - } - + // If in same Guild but different Leagues => ennemy + if ( isInSameGuild() && oneInLeague() && !isInSameLeague() ) + return true; + + if (!isInTeam() && !isInSameLeague()) + return true; } + return false; } // isEnemy // @@ -253,32 +271,38 @@ bool CPlayerCL::isEnemy () const //----------------------------------------------- bool CPlayerCL::isAlly() const { - // if one of 2 players is not in pvp they can't be enemies + + // Challenge i.e. SOLO FULL PVP + if( getPvpMode()&PVP_MODE::PvpChallenge || + UserEntity->getPvpMode()&PVP_MODE::PvpChallenge ) + { + return false; + } + + // if one of 2 players is not in pvp they can't be allies if( UserEntity->getPvpMode() == PVP_MODE::None || getPvpMode() == PVP_MODE::None ) { return false; } + // if one of 2 players is in safe zone and not other they can't be allies + if ((UserEntity->getPvpMode()&PVP_MODE::PvpSafe) != (getPvpMode()&PVP_MODE::PvpSafe)) + { + return false; + } + // Outpost if ( isAnOutpostAlly() ) { return true; } - // Challenge - if( getPvpMode()&PVP_MODE::PvpChallenge && - UserEntity->getPvpMode()&PVP_MODE::PvpChallenge ) - { - if( isInTeam() ) - return true; - } - // Zone Free if( getPvpMode()&PVP_MODE::PvpZoneFree && UserEntity->getPvpMode()&PVP_MODE::PvpZoneFree ) { - if( isInTeam() || isInGuild() ) + if( isInTeam() || isInSameLeague() ) return true; } @@ -286,8 +310,12 @@ bool CPlayerCL::isAlly() const if( getPvpMode()&PVP_MODE::PvpZoneGuild && UserEntity->getPvpMode()&PVP_MODE::PvpZoneGuild ) { - if( isInTeam() || isInGuild() ) + if( isInTeam() || isInSameLeague() ) return true; + + if ( isInSameGuild() && !oneInLeague() ) + return true; + } // Zone Faction @@ -298,26 +326,15 @@ bool CPlayerCL::isAlly() const return true; } - // Faction + // Free PVP : Allies are in team OR in league if ((getPvpMode()&PVP_MODE::PvpFaction || getPvpMode()&PVP_MODE::PvpFactionFlagged) && (UserEntity->getPvpMode()&PVP_MODE::PvpFaction || UserEntity->getPvpMode()&PVP_MODE::PvpFactionFlagged)) { - if (isInTeam() && isInGuild()) + if (isInTeam() || isInSameLeague()) return true; - - // Check for each Clan if is in opposition - for (uint8 i = 0; i < PVP_CLAN::NbClans; i++) - { - if ((isPvpEnnemy(i) && UserEntity->isPvpAlly(i)) || (isPvpAlly(i) && UserEntity->isPvpEnnemy(i))) - return false; - } - // Check for each Clan if is in same clan - for (uint8 i = 0; i < PVP_CLAN::NbClans; i++) - { - if ((isPvpEnnemy(i) && UserEntity->isPvpEnnemy(i)) || (isPvpAlly(i) && UserEntity->isPvpAlly(i))) - return true; - } + if ( isInSameGuild() && !oneInLeague() ) + return true; } return false; @@ -336,66 +353,12 @@ bool CPlayerCL::isNeutralPVP() const return false; } - // Outpost - if ( getOutpostId() != 0 ) + if( UserEntity->getPvpMode() == PVP_MODE::None ) { - if( UserEntity->getOutpostId() != getOutpostId() ) - { - return true; - } + return false; } - // Challenge - if( getPvpMode()&PVP_MODE::PvpChallenge && - !(UserEntity->getPvpMode()&PVP_MODE::PvpChallenge) ) - { - return true; - } - - // Zone Free - if( getPvpMode()&PVP_MODE::PvpZoneFree && - !(UserEntity->getPvpMode()&PVP_MODE::PvpZoneFree) ) - { - return true; - } - - // Zone Guild - if( getPvpMode()&PVP_MODE::PvpZoneGuild && - !(UserEntity->getPvpMode()&PVP_MODE::PvpZoneGuild) ) - { - return true; - } - - // Zone Faction - if( getPvpMode()&PVP_MODE::PvpZoneFaction && - !(UserEntity->getPvpMode()&PVP_MODE::PvpZoneFaction) ) - { - return true; - } - - // Duel - if( getPvpMode()&PVP_MODE::PvpDuel && - !(UserEntity->getPvpMode()&PVP_MODE::PvpDuel) ) - { - return true; - } - - if ((getPvpMode()&PVP_MODE::PvpFaction || getPvpMode()&PVP_MODE::PvpFactionFlagged) && - (UserEntity->getPvpMode()&PVP_MODE::PvpFaction || UserEntity->getPvpMode()&PVP_MODE::PvpFactionFlagged)) - { - // Check for each Clan if is in opposition or same - for (uint8 i = 0; i < PVP_CLAN::NbClans; i++) - { - if ((isPvpEnnemy(i) && UserEntity->isPvpAlly(i)) || - (isPvpAlly(i) && UserEntity->isPvpEnnemy(i)) || - (isPvpEnnemy(i) && UserEntity->isPvpEnnemy(i)) || - (isPvpAlly(i) && UserEntity->isPvpAlly(i))) - return false; - } - return true; - } - - return false; + return (!isEnemy() && !isAlly()); } diff --git a/code/ryzom/client/src/string_manager_client.cpp b/code/ryzom/client/src/string_manager_client.cpp index 40886d518..dd79da45e 100644 --- a/code/ryzom/client/src/string_manager_client.cpp +++ b/code/ryzom/client/src/string_manager_client.cpp @@ -34,6 +34,8 @@ namespace STRING_MANAGER // *************************************************************************** map CStringManagerClient::_SpecItem_TempMap; + map CStringManagerClient::_DynStrings; + vector CStringManagerClient::_TitleWords; bool CStringManagerClient::_SpecItem_MemoryCompressed = false; char *CStringManagerClient::_SpecItem_Labels = NULL; ucchar *CStringManagerClient::_SpecItem_NameDesc = NULL; @@ -381,7 +383,15 @@ restartLoop4: result = ucstring(tmp) + it->second; } else + { result = it->second; + if (result.size() > 9 && result.substr(0, 9) == ucstring("::iterator itds = _DynStrings.find(result.substr(9, result.size()-10)); + if (itds != _DynStrings.end()) + result = itds->second; + } + } } return true; @@ -1595,9 +1605,29 @@ const ucchar *CStringManagerClient::getSPhraseLocalizedDescription(NLMISC::CShee // *************************************************************************** const ucchar *CStringManagerClient::getTitleLocalizedName(const std::string &titleId, bool women) { - return getSpecialWord(titleId,women); + const ucchar * infos = getSpecialWord(titleId, women); + ucstring infosUC(infos); + + vector listInfos; + splitUCString(infosUC, ucstring("#"), listInfos); + if (listInfos.empty()) + return infos; + + _TitleWords.push_back(listInfos[0]); + return _TitleWords.back().c_str(); } +vector CStringManagerClient::getTitleInfos(const std::string &titleId, bool women) +{ + const ucchar * infos = getSpecialWord(titleId, women); + ucstring infosUC(infos); + + vector listInfos; + splitUCString(infosUC, ucstring("#"), listInfos); + return listInfos; +} + + // *************************************************************************** const ucchar *CStringManagerClient::getClassificationTypeLocalizedName(EGSPD::CClassificationType::TClassificationType type) { @@ -1641,7 +1671,14 @@ const ucchar *CStringManagerClient::getSquadLocalizedDescription(NLMISC::CSheetI } // *************************************************************************** -void CStringManagerClient::replaceSBrickName(NLMISC::CSheetId id, const ucstring &name, const ucstring &desc, const ucstring &desc2) +void CStringManagerClient::replaceDynString(const ucstring &name, const ucstring &text) +{ + _DynStrings[name] = text; +} + + +// *************************************************************************** +void CStringManagerClient::replaceSBrickName(NLMISC::CSheetId id, const ucstring &name, const ucstring &desc, const ucstring &desc2) { std::string label= id.toString(); if (label.empty()) diff --git a/code/ryzom/client/src/string_manager_client.h b/code/ryzom/client/src/string_manager_client.h index 511986407..e5842a9f6 100644 --- a/code/ryzom/client/src/string_manager_client.h +++ b/code/ryzom/client/src/string_manager_client.h @@ -77,6 +77,7 @@ public: static void specialWordsMemoryCompress(); // Yoyo: Replace the Brick Name with Filled stats (CSBrickManager work). No-Op if not found static void replaceSBrickName(NLMISC::CSheetId id, const ucstring &name, const ucstring &desc, const ucstring &desc2); + static void replaceDynString(const ucstring &name, const ucstring &text); // Get the Localized Name of the Places. static const ucchar *getPlaceLocalizedName(const std::string &placeNameID); @@ -106,6 +107,7 @@ public: // Get the Localized Title name static const ucchar *getTitleLocalizedName(const std::string &titleId, bool women); + static std::vector CStringManagerClient::getTitleInfos(const std::string &titleId, bool women); // Get the Localized name of a classification type static const ucchar *getClassificationTypeLocalizedName(EGSPD::CClassificationType::TClassificationType type); @@ -215,8 +217,6 @@ private: // Callback for dyn string value from the server TStringCallbacksContainer _DynStringsCallbacks; - - // Return value for waiting string.. static ucstring _WaitString; @@ -273,6 +273,9 @@ private: static bool _SpecItem_MemoryCompressed; static std::map _SpecItem_TempMap; + static std::vector _TitleWords; + static std::map _DynStrings; + static char *_SpecItem_Labels; static ucchar *_SpecItem_NameDesc; diff --git a/code/ryzom/client/src/user_entity.cpp b/code/ryzom/client/src/user_entity.cpp index 64a493d2e..f1e4aeff2 100644 --- a/code/ryzom/client/src/user_entity.cpp +++ b/code/ryzom/client/src/user_entity.cpp @@ -507,7 +507,7 @@ void CUserEntity::updateVisualPropertyName(const NLMISC::TGameCycle &gameCycle, CPlayerCL::updateVisualPropertyName(gameCycle, prop); // Name changed ? - if (oldNameId != _NameId) +/* if (oldNameId != _NameId) { CInterfaceManager *pIM = CInterfaceManager::getInstance(); CInterfaceElement *element = pIM->getElementFromId("ui:interface:mailbox:content:html"); @@ -518,7 +518,7 @@ void CUserEntity::updateVisualPropertyName(const NLMISC::TGameCycle &gameCycle, html->browse("home"); } } - +*/ }// updateVisualPropertyName // //----------------------------------------------- @@ -2657,36 +2657,39 @@ void CUserEntity::selection(const CLFECOMMON::TCLEntityId &slot) // virtual playerGiftNeeded->setValue32(0); } } +/* TODO ULU : Add RP tags */ // update pvp tags - CViewBase * tagView = dynamic_cast(pIM->getElementFromId("ui:interface:target:pvp_tags")); - CViewBase * contentView = dynamic_cast(pIM->getElementFromId("ui:interface:target:content")); - if ((tgtSlot!=CLFECOMMON::INVALID_SLOT) && entity) { CPlayerCL *pPlayer = dynamic_cast(entity); if (pPlayer) { - for (uint8 i = 0; i < 7; i++) + /*// Pvp Mode + CViewBitmap * tagMode = dynamic_cast(pIM->getElementFromId("ui:interface:target:pvp_tags:mode")); + if (tagMode) { - CViewBitmap * tag = dynamic_cast(pIM->getElementFromId("ui:interface:target:pvp_tags:tag_"+toString(i))); - if (tag) - { - if ((pPlayer->getPvpMode()&PVP_MODE::PvpFaction || pPlayer->getPvpMode()&PVP_MODE::PvpFactionFlagged) && pPlayer->isPvpAlly(i)) - { - tag->setTexture("pvp_ally_"+toString(i)+".tga"); - } - else if ((pPlayer->getPvpMode()&PVP_MODE::PvpFaction || pPlayer->getPvpMode()&PVP_MODE::PvpFactionFlagged) && pPlayer->isPvpEnnemy(i)) - { - tag->setTexture("pvp_enemy_"+toString(i)+".tga"); - } - else - { - tag->setTexture("alpha_10.tga"); - } - } + if (pPlayer->getPvpMode()&PVP_MODE::PvpFaction) + tagMode->setTexture("pvp_orange.tga"); + else if (pPlayer->getPvpMode()&PVP_MODE::PvpFactionFlagged) + tagMode->setTexture("pvp_red.tga"); + else + tagMode->setTexture("alpha_10.tga"); } +*/ + /*// Pvp available actions (attack, heal, both) + CViewBitmap * tagMode = dynamic_cast(pIM->getElementFromId("ui:interface:target:pvp_tags:actions")); + if (tagMode) + { + if (pPlayer->getPvpMode()&PVP_MODE::PvpFaction) + tag->setTexture("pvp_orange.tga"); + else if (pPlayer->getPvpMode()&PVP_MODE::PvpFactionFlagged) + tag->setTexture("pvp_red.tga"); + else + tag->setTexture("alpha_10.tga"); + }*/ + } } diff --git a/code/ryzom/client/src/user_entity.h b/code/ryzom/client/src/user_entity.h index 0d39f2967..30c9fed41 100644 --- a/code/ryzom/client/src/user_entity.h +++ b/code/ryzom/client/src/user_entity.h @@ -477,6 +477,14 @@ public: /// true if current behaviour allows to change front bool canChangeFront(); + ucstring getLoginName() + { + if (_LoginName == ucstring("")) + _LoginName = getDisplayName(); + + return _LoginName; + } + protected: class CSpeedFactor : public ICDBNode::IPropertyObserver { @@ -741,6 +749,8 @@ private: /// previous items in hand before they have been changed by an auto-equip due to an action (ex: forage) CItemSnapshot _PreviousRightHandItem; CItemSnapshot _PreviousLeftHandItem; + + ucstring _LoginName; }; /// Out game received position From ad9b680e9182a1d1d14221ae8d452c2e3dcce062 Mon Sep 17 00:00:00 2001 From: kervala Date: Mon, 27 Feb 2012 22:42:30 +0100 Subject: [PATCH 10/16] Changed: #1433 Merge changes from patch 1.13 --- code/ryzom/client/src/cdb_branch.cpp | 2 +- code/ryzom/client/src/cdb_branch.h | 2 +- code/ryzom/client/src/character_cl.cpp | 1 - code/ryzom/client/src/client_chat_manager.cpp | 4 ++-- code/ryzom/client/src/entity_cl.cpp | 8 ++++---- .../client/src/interface_v3/chat_text_manager.cpp | 2 +- code/ryzom/client/src/interface_v3/chat_window.cpp | 2 +- code/ryzom/client/src/interface_v3/group_compas.cpp | 10 ++++++++++ .../client/src/interface_v3/group_html_webig.cpp | 2 +- code/ryzom/client/src/interface_v3/lua_ihm.cpp | 12 ++++++------ code/ryzom/client/src/interface_v3/people_list.cpp | 6 +++--- code/ryzom/client/src/string_manager_client.h | 2 +- 12 files changed, 31 insertions(+), 22 deletions(-) diff --git a/code/ryzom/client/src/cdb_branch.cpp b/code/ryzom/client/src/cdb_branch.cpp index 60c6b63f4..351203493 100644 --- a/code/ryzom/client/src/cdb_branch.cpp +++ b/code/ryzom/client/src/cdb_branch.cpp @@ -628,7 +628,7 @@ void CCDBNodeBranch::display (const std::string &prefix) } } -void CCDBNodeBranch::removeNode (CTextId& id) +void CCDBNodeBranch::removeNode (const CTextId& id) { // Look for the node CCDBNodeBranch *pNode = dynamic_cast(getNode(id,false)); diff --git a/code/ryzom/client/src/cdb_branch.h b/code/ryzom/client/src/cdb_branch.h index 405c7c479..74e085ca4 100644 --- a/code/ryzom/client/src/cdb_branch.h +++ b/code/ryzom/client/src/cdb_branch.h @@ -165,7 +165,7 @@ public: virtual void display (const std::string &prefix); - void removeNode (CTextId& id); + void removeNode (const CTextId& id); /** * add an observer to a property diff --git a/code/ryzom/client/src/character_cl.cpp b/code/ryzom/client/src/character_cl.cpp index 694ed9b16..c0e6d1104 100644 --- a/code/ryzom/client/src/character_cl.cpp +++ b/code/ryzom/client/src/character_cl.cpp @@ -1877,7 +1877,6 @@ void CCharacterCL::updateVisualPropertyPvpMode(const NLMISC::TGameCycle &/* game void CCharacterCL::updateVisualPropertyPvpClan(const NLMISC::TGameCycle &/* gameCycle */, const sint64 &prop) { _LeagueId = uint32(prop); - buildInSceneInterface(); if (isUser()) { diff --git a/code/ryzom/client/src/client_chat_manager.cpp b/code/ryzom/client/src/client_chat_manager.cpp index e7ef54d02..59b72cedb 100644 --- a/code/ryzom/client/src/client_chat_manager.cpp +++ b/code/ryzom/client/src/client_chat_manager.cpp @@ -1174,7 +1174,7 @@ class CHandlerTell : public IActionHandler ucstring finalMsg; CChatWindow::encodeColorTag(prop.getRGBA(), finalMsg, false); - ucstring csr = CHARACTER_TITLE::isCsrTitle(UserEntity->getTitleRaw()) ? "(CSR) " : ""; + ucstring csr(CHARACTER_TITLE::isCsrTitle(UserEntity->getTitleRaw()) ? "(CSR) " : ""); finalMsg += csr + CI18N::get("youTell") + ": "; prop.readRGBA("UI:SAVE:CHAT:COLORS:TELL"," "); CChatWindow::encodeColorTag(prop.getRGBA(), finalMsg, true); @@ -1182,7 +1182,7 @@ class CHandlerTell : public IActionHandler // display msg with good color // TDataSetIndex dsi; // not used .... PeopleInterraction.ChatInput.Tell.displayTellMessage(/*dsi, */finalMsg, receiver, prop.getRGBA()); - + ucstring s = CI18N::get("youTellPlayer"); strFindReplace(s, "%name", receiver); strFindReplace(finalMsg, CI18N::get("youTell"), s); diff --git a/code/ryzom/client/src/entity_cl.cpp b/code/ryzom/client/src/entity_cl.cpp index 421faad47..7cefa69d7 100644 --- a/code/ryzom/client/src/entity_cl.cpp +++ b/code/ryzom/client/src/entity_cl.cpp @@ -2539,7 +2539,7 @@ NLMISC::CRGBA CEntityCL::getColor () const if (isEnemy()) { if (getPvpMode()&PVP_MODE::PvpFaction) - return CRGBA::CRGBA(min(255, _PvpEnemyColor.R+150), min(255, _PvpEnemyColor.G+150), min(255, _PvpEnemyColor.B+150),_PvpEnemyColor.A); + return CRGBA(min(255, _PvpEnemyColor.R+150), min(255, _PvpEnemyColor.G+150), min(255, _PvpEnemyColor.B+150),_PvpEnemyColor.A); else return _PvpEnemyColor; } @@ -2551,8 +2551,8 @@ NLMISC::CRGBA CEntityCL::getColor () const if (getPvpMode() & PVP_MODE::PvpFactionFlagged) { if(isInSameLeague()) - return CRGBA::CRGBA(max(0, _PvpAllyColor.R-100), max(0, _PvpAllyColor.G-100), max(0, _PvpAllyColor.B-100),_PvpAllyColor.A); - return CRGBA::CRGBA(max(0, _PvpAllyInTeamColor.R-100), max(0, _PvpAllyInTeamColor.G-100), max(0, _PvpAllyInTeamColor.B-100),_PvpAllyInTeamColor.A); + return CRGBA(max(0, _PvpAllyColor.R-100), max(0, _PvpAllyColor.G-100), max(0, _PvpAllyColor.B-100),_PvpAllyColor.A); + return CRGBA(max(0, _PvpAllyInTeamColor.R-100), max(0, _PvpAllyInTeamColor.G-100), max(0, _PvpAllyInTeamColor.B-100),_PvpAllyInTeamColor.A); } else { @@ -2572,7 +2572,7 @@ NLMISC::CRGBA CEntityCL::getColor () const // neutral if (isInSameLeague()) - return CRGBA::CRGBA(min(255, _GroupColor.R+50), min(255, _GroupColor.G+50), min(255, _GroupColor.B+50),_GroupColor.A); + return CRGBA(min(255, _GroupColor.R+50), min(255, _GroupColor.G+50), min(255, _GroupColor.B+50),_GroupColor.A); if (isInSameGuild()) return _GuildColor; 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 d1488b4dd..9b5113a55 100644 --- a/code/ryzom/client/src/interface_v3/chat_text_manager.cpp +++ b/code/ryzom/client/src/interface_v3/chat_text_manager.cpp @@ -148,7 +148,7 @@ CViewBase *CChatTextManager::createMsgText(const ucstring &cstMsg, NLMISC::CRGBA vt->setMultiLineSpace(getTextMultiLineSpace()); vt->setModulateGlobalColor(false); - ucstring cur_time = ""; + ucstring cur_time; static CCDBNodeLeaf* node = CInterfaceManager::getInstance()->getDbProp("UI:SAVE:CHAT:SHOW_TIMES_IN_CHAT_CB", false); if (node) { diff --git a/code/ryzom/client/src/interface_v3/chat_window.cpp b/code/ryzom/client/src/interface_v3/chat_window.cpp index 773992fc3..18be552e9 100644 --- a/code/ryzom/client/src/interface_v3/chat_window.cpp +++ b/code/ryzom/client/src/interface_v3/chat_window.cpp @@ -473,7 +473,7 @@ void CChatWindow::displayLocalPlayerTell(const ucstring &receiver, const ucstrin prop.readRGBA("UI:SAVE:CHAT:COLORS:SPEAKER"," "); encodeColorTag(prop.getRGBA(), finalMsg, false); - ucstring csr = CHARACTER_TITLE::isCsrTitle(UserEntity->getTitleRaw()) ? "(CSR) " : ""; + ucstring csr(CHARACTER_TITLE::isCsrTitle(UserEntity->getTitleRaw()) ? "(CSR) " : ""); finalMsg += csr + CI18N::get("youTell") + ": "; prop.readRGBA("UI:SAVE:CHAT:COLORS:TELL"," "); encodeColorTag(prop.getRGBA(), finalMsg, true); diff --git a/code/ryzom/client/src/interface_v3/group_compas.cpp b/code/ryzom/client/src/interface_v3/group_compas.cpp index 0fa2b30e7..fa7655591 100644 --- a/code/ryzom/client/src/interface_v3/group_compas.cpp +++ b/code/ryzom/client/src/interface_v3/group_compas.cpp @@ -587,6 +587,12 @@ bool CGroupCompasMenu::parse(xmlNodePtr cur, CInterfaceGroup *parent /*=NULL*/) return true; } +// Helper for sorting landmarks +static inline bool UserLandMarksSortPredicate(const CUserLandMark& lm1, const CUserLandMark& lm2) +{ + return toLower(lm1.Title) < toLower(lm2.Title); +} + // *************************************************************************** // Called when we activate the compass menu void CGroupCompasMenu::setActive (bool state) @@ -803,6 +809,10 @@ void CGroupCompasMenu::setActive (bool state) } // User landmarks uint nbUserLandMarks = std::min( uint(currCont->UserLandMarks.size()), CContinent::getMaxNbUserLandMarks() ); + + // Sort the landmarks + std::sort(currCont->UserLandMarks.begin(), currCont->UserLandMarks.end(), UserLandMarksSortPredicate); + for(k = 0; k < nbUserLandMarks; ++k) { if (currCont->UserLandMarks[k].Type < CUserLandMark::UserLandMarkTypeCount) diff --git a/code/ryzom/client/src/interface_v3/group_html_webig.cpp b/code/ryzom/client/src/interface_v3/group_html_webig.cpp index e4a55ab48..0e17c47d3 100644 --- a/code/ryzom/client/src/interface_v3/group_html_webig.cpp +++ b/code/ryzom/client/src/interface_v3/group_html_webig.cpp @@ -74,6 +74,7 @@ void addWebIGParams (string &url, bool trustedDomain) string("shardid=") + toString(CharacterHomeSessionId) + string("&name=") + UserEntity->getLoginName().toUtf8() + string("&lang=") + CI18N::getCurrentLanguageCode() + + string("&datasetid=") + toString(UserEntity->dataSetId()) + string("&ig=1"); if (trustedDomain) { @@ -82,7 +83,6 @@ void addWebIGParams (string &url, bool trustedDomain) if (url.find('$') != string::npos) { - strFindReplace(url, "$datasetid$", toString(UserEntity->dataSetId())); strFindReplace(url, "$gender$", GSGENDER::toString(UserEntity->getGender())); strFindReplace(url, "$displayName$", UserEntity->getDisplayName().toString()); strFindReplace(url, "$posx$", toString(UserEntity->pos().x)); diff --git a/code/ryzom/client/src/interface_v3/lua_ihm.cpp b/code/ryzom/client/src/interface_v3/lua_ihm.cpp index 44e9a3ba7..08b128b66 100644 --- a/code/ryzom/client/src/interface_v3/lua_ihm.cpp +++ b/code/ryzom/client/src/interface_v3/lua_ihm.cpp @@ -1944,12 +1944,12 @@ static sint32 getTargetSlotNr() const char *dbPath = "UI:VARIABLES:TARGET:SLOT"; CInterfaceManager *im = CInterfaceManager::getInstance(); CCDBNodeLeaf *node = im->getDbProp(dbPath, false); - if (!node) return NULL; + if (!node) return 0; if ((uint8) node->getValue32() == (uint8) CLFECOMMON::INVALID_SLOT) { - return NULL; + return 0; } - return node->getValue32(); + return node->getValue32(); } // *************************************************************************** @@ -1963,13 +1963,13 @@ static CEntityCL *getTargetEntity() { return NULL; } - return EntitiesMngr.entity((uint) node->getValue32()); + return EntitiesMngr.entity((uint) node->getValue32()); } // *************************************************************************** static CEntityCL *getSlotEntity(uint slot) { - return EntitiesMngr.entity(slot); + return EntitiesMngr.entity(slot); } // *************************************************************************** @@ -2032,7 +2032,7 @@ sint32 CLuaIHM::getTargetLevel() ucstring CLuaIHM::getTargetSheet() { CEntityCL *target = getTargetEntity(); - if (!target) return ""; + if (!target) return ucstring(); return target->sheetId().toString(); } diff --git a/code/ryzom/client/src/interface_v3/people_list.cpp b/code/ryzom/client/src/interface_v3/people_list.cpp index c9b95a14a..395935aab 100644 --- a/code/ryzom/client/src/interface_v3/people_list.cpp +++ b/code/ryzom/client/src/interface_v3/people_list.cpp @@ -468,12 +468,12 @@ void CPeopleList::displayLocalPlayerTell(const ucstring &receiver, uint index, c return; } - ucstring csr = CHARACTER_TITLE::isCsrTitle(UserEntity->getTitleRaw()) ? "(CSR) " : ""; + ucstring csr(CHARACTER_TITLE::isCsrTitle(UserEntity->getTitleRaw()) ? "(CSR) " : ""); ucstring finalMsg = csr + CI18N::get("youTell") + ": " + msg; // display msg with good color CInterfaceProperty prop; prop.readRGBA("UI:SAVE:CHAT:COLORS:TELL"," "); - + ucstring s = CI18N::get("youTellPlayer"); strFindReplace(s, "%name", receiver); strFindReplace(finalMsg, CI18N::get("youTell"), s); @@ -935,7 +935,7 @@ class CHandlerContactEntry : public IActionHandler ucstring final; CChatWindow::encodeColorTag(prop.getRGBA(), final, false); - ucstring csr = CHARACTER_TITLE::isCsrTitle(UserEntity->getTitleRaw()) ? "(CSR) " : ""; + ucstring csr(CHARACTER_TITLE::isCsrTitle(UserEntity->getTitleRaw()) ? "(CSR) " : ""); final += csr + CI18N::get("youTell")+": "; prop.readRGBA("UI:SAVE:CHAT:COLORS:TELL"," "); CChatWindow::encodeColorTag(prop.getRGBA(), final, true); diff --git a/code/ryzom/client/src/string_manager_client.h b/code/ryzom/client/src/string_manager_client.h index e5842a9f6..13f8188bb 100644 --- a/code/ryzom/client/src/string_manager_client.h +++ b/code/ryzom/client/src/string_manager_client.h @@ -107,7 +107,7 @@ public: // Get the Localized Title name static const ucchar *getTitleLocalizedName(const std::string &titleId, bool women); - static std::vector CStringManagerClient::getTitleInfos(const std::string &titleId, bool women); + static std::vector getTitleInfos(const std::string &titleId, bool women); // Get the Localized name of a classification type static const ucchar *getClassificationTypeLocalizedName(EGSPD::CClassificationType::TClassificationType type); From 89e0ca326042348429ff8b30f6cfe9d71000ab3c Mon Sep 17 00:00:00 2001 From: kervala Date: Mon, 27 Feb 2012 23:48:36 +0100 Subject: [PATCH 11/16] Changed: #1433 Merge changes from patch 1.13 --- code/CMakeModules/nel.cmake | 6 +- code/nel/src/misc/events.cpp | 4 +- code/ryzom/client/client_default.cfg | 20 +- code/ryzom/client/client_default.cfg.in | 23 +- .../new_texture_interfaces_dxtc.tga | Bin 4194322 -> 4194322 bytes .../new_texture_interfaces_dxtc.txt | 1282 +++++++++-------- .../data/gamedev/interfaces_v3/commands.xml | 11 +- .../data/gamedev/interfaces_v3/config.xml | 65 +- .../gamedev/interfaces_v3/encyclopedia.xml | 2 +- .../gamedev/interfaces_v3/game_config.xml | 178 ++- .../data/gamedev/interfaces_v3/guild.xml | 53 +- .../gamedev/interfaces_v3/info_player.lua | 134 +- .../gamedev/interfaces_v3/info_player.xml | 278 +++- .../gamedev/interfaces_v3/interaction.xml | 28 +- .../data/gamedev/interfaces_v3/interface.txt | 1 + .../gamedev/interfaces_v3/out_v2_select.xml | 16 +- .../gamedev/interfaces_v3/out_v2_widgets.xml | 2 +- .../data/gamedev/interfaces_v3/player.lua | 41 +- .../data/gamedev/interfaces_v3/player.xml | 14 +- .../gamedev/interfaces_v3/player_trade.xml | 58 +- .../data/gamedev/interfaces_v3/reset.xml | 6 + .../interfaces_v3/texture_interfaces_v3.tga | Bin 2117952 -> 4194322 bytes .../data/gamedev/interfaces_v3/widgets.xml | 129 +- 23 files changed, 1478 insertions(+), 873 deletions(-) diff --git a/code/CMakeModules/nel.cmake b/code/CMakeModules/nel.cmake index 9314a7a85..7dd43e8b4 100644 --- a/code/CMakeModules/nel.cmake +++ b/code/CMakeModules/nel.cmake @@ -405,7 +405,7 @@ MACRO(NL_SETUP_BUILD) SET(NL_RELEASE_CFLAGS "/MD /D NDEBUG ${SPEED_OPTIMIZATIONS}") SET(NL_DEBUG_LINKFLAGS "/NODEFAULTLIB:msvcrt /INCREMENTAL:YES") SET(NL_RELEASE_LINKFLAGS "/OPT:REF /OPT:ICF /INCREMENTAL:NO") - ELSE(WIN32) + ELSE(MSVC) IF(HOST_CPU STREQUAL "x86_64" AND TARGET_CPU STREQUAL "x86") SET(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -m32 -march=i686") ENDIF(HOST_CPU STREQUAL "x86_64" AND TARGET_CPU STREQUAL "x86") @@ -414,7 +414,7 @@ MACRO(NL_SETUP_BUILD) SET(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -m64") ENDIF(HOST_CPU STREQUAL "x86" AND TARGET_CPU STREQUAL "x86_64") - SET(PLATFORM_CFLAGS "{PLATFORM_CFLAGS} -g -D_REENTRANT -pipe -ftemplate-depth-48 -Wall -ansi -W -Wpointer-arith -Wsign-compare -Wno-deprecated-declarations -Wno-multichar -Wno-unused -fno-strict-aliasing") + SET(PLATFORM_CFLAGS "${PLATFORM_CFLAGS} -g -D_REENTRANT -pipe -ftemplate-depth-48 -Wall -ansi -W -Wpointer-arith -Wsign-compare -Wno-deprecated-declarations -Wno-multichar -Wno-unused -fno-strict-aliasing") IF(WITH_COVERAGE) SET(PLATFORM_CFLAGS "-fprofile-arcs -ftest-coverage ${PLATFORM_CFLAGS}") @@ -437,7 +437,7 @@ MACRO(NL_SETUP_BUILD) SET(NL_DEBUG_CFLAGS "-DNL_DEBUG -D_DEBUG") SET(NL_RELEASE_CFLAGS "-DNL_RELEASE -DNDEBUG -O6") - ENDIF(WIN32) + ENDIF(MSVC) ENDMACRO(NL_SETUP_BUILD) MACRO(NL_SETUP_BUILD_FLAGS) diff --git a/code/nel/src/misc/events.cpp b/code/nel/src/misc/events.cpp index 4d0f996d5..7cef02f44 100644 --- a/code/nel/src/misc/events.cpp +++ b/code/nel/src/misc/events.cpp @@ -178,8 +178,8 @@ static const CStringConversion::CPair stringTable [] = { "KeyZOOM", KeyZOOM }, { "KeyNONAME", KeyNONAME }, { "KeyPA1", KeyPA1 }, - { "KeyOEM_CLEAR", KeyOEM_CLEAR }, -} + { "KeyOEM_CLEAR", KeyOEM_CLEAR } +}; static CStringConversion KeyConversion(stringTable, sizeof(stringTable) / sizeof(stringTable[0]), KeyCount); diff --git a/code/ryzom/client/client_default.cfg b/code/ryzom/client/client_default.cfg index 14885fa01..997699ca8 100644 --- a/code/ryzom/client/client_default.cfg +++ b/code/ryzom/client/client_default.cfg @@ -354,8 +354,8 @@ SystemInfoColors = // NEW System Info Categories "SYS", "255 255 255 255 normal", // Default system messages -"BC", "255 255 255 255 center", // Broadcast messages -"TAGBC", "255 255 255 255 center", // Taged broadcast messages : color should remain white as some word are tagged +"BC", "255 255 255 255 centeraround", // Broadcast messages +"TAGBC", "255 255 255 255 centeraround", // Taged broadcast messages : color should remain white as some word are tagged "XP", "255 255 64 255 over", // XP Gain "SP", "255 255 64 255 over", // SP Gain "TTL", "255 255 64 255 over", // Title @@ -443,23 +443,24 @@ R2EDReloadFiles = { XMLInterfaceFiles = { "config.xml", "widgets.xml", + "webig_widgets.xml", "player.xml", "inventory.xml", "interaction.xml", - "phrase.xml", + "phrase.xml", "harvest.xml", "macros.xml", "info_player.xml", "outpost.xml", "guild.xml", "taskbar.xml", - "game_config.xml", + "game_config.xml", "game_context_menu.xml", "player_trade.xml", "bot_chat_v4.xml", "compass.xml", "map.xml", - "hierarchy.xml", + "hierarchy.xml", "reset.xml", "actions.xml", "help.xml", @@ -559,6 +560,15 @@ HelpPages = "de=http://forums.ryzom.com/forum/showthread.php?t=29131" }; +WebIgMainDomain = "atys.ryzom.com"; + +WebIgTrustedDomains = +{ + "atys.ryzom.com" +}; + +PatchletUrl = "http://atys.ryzom.com/start/app_patchlet.php?patch=preload"; + SelectedSlot = 0; BuildName = "RELEASE_HEAD"; diff --git a/code/ryzom/client/client_default.cfg.in b/code/ryzom/client/client_default.cfg.in index 8ae0117a5..41c3dd1de 100644 --- a/code/ryzom/client/client_default.cfg.in +++ b/code/ryzom/client/client_default.cfg.in @@ -80,6 +80,9 @@ XMLOutGameInterfaceFiles = { "out_v2_keys.xml", }; +TexturesInterface = "texture_interfaces_v3"; +TexturesInterfaceDXTC = "texture_interfaces_dxtc"; + // The ligo primitive class file LigoPrimitiveClass = "world_editor_classes.xml"; @@ -352,8 +355,8 @@ SystemInfoColors = // NEW System Info Categories "SYS", "255 255 255 255 normal", // Default system messages -"BC", "255 255 255 255 center", // Broadcast messages -"TAGBC", "255 255 255 255 center", // Taged broadcast messages : color should remain white as some word are tagged +"BC", "255 255 255 255 centeraround", // Broadcast messages +"TAGBC", "255 255 255 255 centeraround", // Taged broadcast messages : color should remain white as some word are tagged "XP", "255 255 64 255 over", // XP Gain "SP", "255 255 64 255 over", // SP Gain "TTL", "255 255 64 255 over", // Title @@ -441,23 +444,24 @@ R2EDReloadFiles = { XMLInterfaceFiles = { "config.xml", "widgets.xml", + "webig_widgets.xml", "player.xml", "inventory.xml", "interaction.xml", - "phrase.xml", + "phrase.xml", "harvest.xml", "macros.xml", "info_player.xml", "outpost.xml", "guild.xml", "taskbar.xml", - "game_config.xml", + "game_config.xml", "game_context_menu.xml", "player_trade.xml", "bot_chat_v4.xml", "compass.xml", "map.xml", - "hierarchy.xml", + "hierarchy.xml", "reset.xml", "actions.xml", "help.xml", @@ -557,6 +561,15 @@ HelpPages = "de=http://forums.ryzom.com/forum/showthread.php?t=29131" }; +WebIgMainDomain = "atys.ryzom.com"; + +WebIgTrustedDomains = +{ + "atys.ryzom.com" +}; + +PatchletUrl = "http://atys.ryzom.com/start/app_patchlet.php?patch=preload"; + SelectedSlot = 0; BuildName = "RELEASE_HEAD"; diff --git a/code/ryzom/client/data/gamedev/adds/interfaces/new_texture_interfaces_dxtc.tga b/code/ryzom/client/data/gamedev/adds/interfaces/new_texture_interfaces_dxtc.tga index bbeeab27b137f23de2ef17354622069d33f7c77c..91e87e2e7ca33bf8fcad0846b7f2d90a0849095f 100644 GIT binary patch delta 75237 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 wOzxN4!CoHX0h+d&k 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
{Fb24wo2>~lVm~rbn zRGcgKe-m%l)rl8itI|(PUe11R%s+Fs>}<;YpcIGe{KSsgotpB8^?%XPV1I9TqRY4M zx3k~5y+v;~a*SwQ#ccCa< zxHKxM#l0>=C%%m8*hkd*IzR88q<%Cg&F{vP42P;k9qm3^)m1hHZEHelPhrxs9<3H` z>m>{Une@;53CfBAg8iO>jLV6yq7Ahn3X0hL;7fbrgYo*j)C7rckCx-N4nh`l;C=GaGb-* zNh#J_R=j039dW1M=I%l}RFyPT;f(U$+&}R!OCXrE+%r(1gV&`TlhEZ4(=ufwb)Xt7 zMsgPSRF_Pf11_UEixmSVCkhTzlZCh$sX``l&z#dn$ehw6umJMpFseC`v zZuNU@9Tvae&arS=C!0PSvV|ltFu)e_tvP}h7M~8EvBf~B2lAF6Z>w49g3atUf(`PvLEiRDvIOU4?FF|L z9R>HLooqbkws&-2-o>HC#%_W=^0qS*X=$xOX21*>UYGxg9X(IH%)??SJ3kK9JakBGD*w>={9lE(>yBi-qq z6bXqHbW<@0{*+Y!EMlnD*RWryQzzjcRi?#)OWyTgc*Qmd;UHLxDS8}m*E5ZVXzPz%ikOxxs-NIE(4L;CTgq!j!gc+>-fe7rGoHFKsN zt)9c77MP&uY1>pe%4tPxY-9G*rn!+p(6S=CHbvW#OYjby6@U|VDfIMGd8lVX73L|xPj<8M_YFe=pz*j%pSb~I;$!xjwy_%bL>hQ`&h0Z}?6qJ-F$`^t?=pJ)xcWITPIC-v#@>z|Z_mlJkJ(F~ zo`_`a17883iY#I4aHzm1lS1)VuGA&NjFL(ErThC5zX=LIxPTt7R=-5kxPn?tep-|O z>-6DxePSwT{r4QtiJZF}xt6cu(se&1#RAWry7gc-9_@v1m%C^Ct4Z`B&+zi&x79K_ zGG}~pi?+#VN8XoN-LRvZUcU3f$-q6^$PP6Ra; zD}zx;wlval1;g3st)P|aKqVk_9HN{%2keX z1%;{Y8O7WTE;$UP7e`5_iPcJMmBJng19Q(&Gtzqm);JDHT65YCUO*aIZ}E&;if_R-PlaX$WCYZDIj5H;NIk zBh~ZGK=U{diX>I}A&|aJ%ZdYopzKZOtO-;}=n1bh?7+Y9jIE%xA8}f-F5}8_x?p=?fMiW)jn(RWjSan^Pjf|E(gEbr7Bk58ZBd9fD9Tn2(t&2ERjt5a zG~HAg7y<@Lx}*vqq#!f075yx zqdsZqAyZG_ES+zk*tLi;9K?!TzibBifrIp-J$k5QCXm~K5!{+f?gg^GM^XN0WE%bg z7n+O&!qZ=YK(60q_H?2L?<9LerWfr!L?uE9&ZsvRWckxTHU24#Hcd&Z!>HArr1sR> zkf15C#q`Br4CLk$&VhwG8+x)K*#+Vc>7$9Nkw8KmBQ%M(Wi4%g8+iovdlk)ZgT-a4v<65X(WtJ7^X?`j(p09hsrpEjV?z6wp{Y%1Bp@TuhOX6V^vLon zy6Ka&Y(Pe^V%m|c^4LGwiI`2A=&j_oHkxmzR%=q&X{I^~&^`b}VA<*4hHj7IfI)Ok zoQB2LGjzxPv<|>ZAf0IJ@9b>K_L%668k?3hpaz%EAE394IROD@k=o9U2QtZMM*V3-vYlfK=v!O^U ze@N&BzU+ulXinTTlg{^CN6&hk#Vkm4`c>1xiUh2{DW&n*8aa*2=c;#@Dj)8K4(F;? zCQCg2HQEDt2D1+58twF#W|S$z0`+Do-Pe%NT}pM6;}%NkAAd#rKrozjD6LH+r+rfG zALgv`3NSs4D^jytZ|!KMRqI~Rn;$n%N^4~?I0y9fV>z}lm-=NAhevWH-Q}jOv!Wo$ z-T`%@mF}&xrBuB-ZV}{LF?qL*czJe*TKn5;MPU|9EKy?Vq^xn`ICrhCwzJjXbP?K6u zl~UuAxEYXp*CI!DsdZ}l?Hp~j)xLnhRe+n<8UkU~@%ULg_f?L?+6GwCm5Z!`2(wa@ zM?4^FKQc?rpu5VLlv)|csBcAn%u7*PF16*AR3(>+2xK?$S<&LXTo8VZWrC0P#Gspl zV*qzt``n7^(gPQ9pfxAWh;i+>;0cQ$*%75}LBFilK7e#Kmv*A-e}G+B{&6{6`g@Bs z-F2J8=34~swB~J+CJu*SdHt_3mh9`fTtQ$FaNOzo28-NeF87yNj_eqsRniMmT@7+C z3S_47rt7T|$MIiM=d;|O%3@#QPy`A^c1&c_Zn}%CVg}CR&}-Zi83k{ex|&P3vPe_7 zhnb*+!@AQo8ZIcO8QYlPi@;dil4`P56c?-rWJZ@`y3F&3;65%GZ5Avd@Daj7hVBo* z9<@kka%m;aI>n@$+Qv3;*m<<7hYmGOchOR;UKZHPtb#Q4gdj!!N^}djnYAaN2M^VC zw4%ma92$lgX3@ACk7jB!EcPKZ9^zvM7D?G?hK_kxmuW@A>H?X+pfSm!@gyD%)nQUB zF70~Nu*W=-qgPk5Z!R3^;JLc@t@h<>do&J$7#)^#3O>-i7dcBf7@=dX!`L3EQp8uv*78H+!wNmQ4Dz*lPnfwB9 z>NeP;j?USl>ug24Dm8t1o@HATM{%_bEu>8&VAa;xOHc`JR@tLVw_ZYwLqq}@s!V%l*hF`t#ev=Go`ctSs@-Qj9u-&A|1 z+h|tHwqh&hjx=X-0>8i>cXyd+CDSmeei+~5iz?ELGIy3kKG3k`8CSASkEp-fR*kiw zn_uev$j6)29<<3iNeKcPT$a@g;>JPDMTuLX83u=Zk15IE4Vt|`av~2-;GwRaUJME6 z=`ak!=|y_iBPkY0LAXPz8A;8N_#&|_jV#gpEupnLG?<1Ku(#9K>(v;k;)t?4y{=7S z#t*@DNhak4YK+p4LRoNhnl0UhR%kE=xP4HAIkibS-lA+G_e*S2C=gJ zRD&_d^>dme-d(P1uTC-LOS-;`C8b~5B^jWKE%I-mT0KgG%zJQE^B#clqUIqUpk?bB zKV8=(V6OI&uM;ipqmH%E&q)da0yg`9G-Vz`bwl*yK%c#Nt*PV6cJz8J7|_)t)om<# z!;^xbmri>8ZqkduvVpz;dU$xej_L97!{ry6bm&b{x8nwPrPn8Oui-Mfe@uEorX^nW z94M2po{>)b0ZsHjax(#gJpVHNWNYfC)IOKcb4Kl3&@49>(use! zM6YkNWE^bPq@I=f8BmJQHXzUa-dH9})OLU-W!}MgHq!`^UfY-CW6CoLn)pyvN!^a? zi=defO?tYMwi}ern3d3|M*`~dDX!ED9}u(bwuM2dnk!{cfbg%SmqFJ=)XnTW@9O zu55;I!CQ==$>X)!97vDk(!(K59{t)H`?(#cbYjp75UhhJv&Xp?+P)B+!UZQMqn6(L ztMy(kI0u6J+;ptwIp~~Xi_k8g>tU2jVlD26)MdN>q9bKE}H?I{x`dZiQkMXqy(>zv{`ZJACcZMqb+%0%o&LQAU8 z*8R?PuJ_k}p^%^0^Eh7Vuy6OvLI8)PCV=c5L$JMnm#-^%8n>3`Pss3ZY-z zhYq=LD%pnC+)cj80Li1FiEsiGADa{@I!-5ycc-Jj!=);;;#pvngjPS{Cj(r`qj$~X z5(A@$I07?ZM7uZ^W=(iKGT&z z(Vu>$*My^>+LVh>)DY>`#7U$oj44KOMQ_t|JfcFkMoJeP(ruLS*FEXUcug3(n%IoA&G@(rX{Dz)^R_L^V`z1I#~L|nEjlkLG}aZdRnlU@EJFUVXH z+gEdn*5;&~w7|l~5p?1ZgA&CLGLcEYr7Omu|94%W`Nn0O$sJ90jMDTaO_NjX=|96$ z_L$Vi`)}Q?L>tbk(|uv{=K0&!6tb95^_XqAXw6U2?(3-k{MF~ok@%WPe+zqBwtidL zk3sCvud}Heec-JB2^qMO#0fYcdu*X*vWyn4G(5K=F2pd85zcVc@4oK0#GTrE*=Eu{yO^=zJQMJp-S$fgsI8S<^@#M1^g2*zpd zbUg*HPWnddKX%q*S-bKKUq$LmCtfljFpRlkU^_Nolg(lK>oFYJHBhgCDYLdJtuw&(B=?rte`Z(eBDI`m&b{<{7b30-r;1a2CS9q6NV zHsvswE8*L-5k}?>DBa>pwOr{TF9Tjl?u+Tq!I4^4t&r0@M&?3HhzgC&-%zUKN-wz5 zOU}%PDZwXGEIG|KvQX_rCoV9u>V)qUf)3-mLWiJR5?bsO#Ed1Ul?%1_t|@o9d>YyW zSMa7Y*BISRxwvu-U#=k!;_L6GG2;QE#n)emSw*z4)YuF8V3T3Hk*&*uoRX^vb8g8r<}HEq;riDqWP3-2GPWVp#8A)bgnrgh(!Y&3w)+!FZZA#OM*?S zano&rnZY1m#O0T8`K3WIT>iAJjs+sfx8(8{NtRb|XD+@Xh*it=L9Ci>G>f0};^JtF zs$jN+_BF}U2X`hnXZs+IlmxLjvV$vp9+bfF%P;74_!IJx!Q;4mr}*Fwq<2Se$X9Ur zgIxY_P%@XVj%V@+5p6&R8(YD0+_$^N7t%+$^tm9`q`oyvUun;z5q-LI>E2Abx4|2q zgJKDw9a<_6Nj!CZC(leNJnBh9+SWoxN&1DxrcBOyvzOIIH2s#*8EORmp zl<|o(eYB9XK-69tJPhSq!=#n?0L9g?1>(L27A)n4zA|#*qbOHePju<5W8kvexol^e zr!)}A8VxK8hZw;3X}K;LV!OFm6&K5&#k7;v{T#)jzLF?`qjJu&*v>4yL9KQr+Krv=Xr z-g>UX5ulyZ6;8zRS&cuR%#myJ!|)x_Ls~5h`2k!{^1WzMUu4K9JEkjIP}LH{N^4qd ztDg&h*sb=L_oJSx!_qNEE5JPXW491%3>Us8wJQu`8NNLYSdU>BE%t%}*%#oSPd&DU zwLuBhAuS-8W4bb7eu?2CDz)KbNa~s7lO0TQAD4{ck{$VXHDp?a;Tm;2XefbXJeNGk zBu{b4j1VVart>a{j6Q03K;6!9$@X0G9Fx4vC3|qm2!2?N^uK6$PTj6^$v#~2I+MK1 zC5LcH^Kwh4TLxIqt(J?9z0+qU0h*E>iwVB$kU*a*+rwlE_8qE0K0wMk;z=7o{JQ4k?CCI8AR+*W>E<5^fTGCUY<>A*WY;|lHnOW`tC=)n~(a)s+$q0fIQ+~o>GLRm$*#a&#> z6-NG-!V|7A5elp~HrDZq_=4+9fsVOySx4~t%B8T&^O4qRUsNyxl$%2^ud=TsJ-B3X zs4K%Wt*XSi1}k7p-(Y4;@=8?8Ma#ITJ55vu`$5XcrOIDP#d4`ii&O-cO5{@Xl~lV3 zG?4YjIYD5hL&_X?It8=1bLN$3PDB^WE2f7dOR` zUUCcj0fdf`dnwhvD)@LYKFBW#X(aMmjI;r%6se3Q{C#ucf0v2>&l1YO zrOc}nQfHwIT*`d1k-8)G6iUHm1Gp>(myz-TLK1b`20rw(I*ff)c9h&Jd5wxcP2CYZ z2~_lE({w{Nj0Q#e4(SR~&HpBtq{cG~se@1h8a1F%P9@4hrQ%I02RW5^GnIbGc0JMsqz6d#NDZ$i&}i^%kJJIFlhEMZ z8L2B$w$K0?4ZgjE2EVShPeXdDpMgd#Xng0NCv5P~7y47TQxP+;ev%P(gIlHcXfW?$ zo!H9?u*x}3rM;O7s~{yvSKtsv;~%6(p4tkHpwS3xG@^1ef<_~((FhuipwS2#jc`h1 z{6J&Vvd=ydwOyi`%O&E=T-|AysQSzGqlE*nCZ%UJN#WXA3qe znsGh206ywtt}cuXt0K%V%pi=32xg*tJN%g?h%kr8 z&yHpmU66A(B*vmAQdcW+>6R7EmqPhuxQKqeg+|z;!G8#t3>C^0!-YJOYU{U!Emzo+ zBTpiJq}L{fT?QZhD?VD9^&)s2EHedsSfk~ZfhD+QJm4Eo#-+WP%Uj^UEMnopEg}&Y zl`L((sY{)u715AH_^1&UX@Es)6eEN(<)}5d+jrlE$V{A-#VG;OdS1%F<{{s<=H-Z1&%Z6D6YWFNZ7?b^WJ}1L#fBBlY{9z5y{*vT(GF~1XUeQ*_MI=7`gD_ub2lz( zzIM&R6g5c%(?&3D0Mi=fD6kz3w!ZY7Yh(u*iCUF1l;*4q`x3)#A5MZ8Fv6U;&QLPQ zVloh@LB(OMiB)6K3#LLfHkk_M;BL#7h>J^?H{ZP%m=(kc!c>fa2m*~D(4ZJ4)TqV? zWvX%b#NlUO57YMjd1Yh@OsCh|k*KYVP$?&5;DpLKp-(M@+6txcTa5>rHg8jmkeLkg z4FWFekVKrhZeH_s^6A5KMfX&xh@dB;4vC6kNF#(sSffEX2870e(0CIedO9L9UB+l( zm2_{)NSd>ob7{@FP|oE5xS(CPkV#3g#CVQZE6m3}Y#?uqVPLbSh@;oz-kpkl(!a0rVaY6%l)C3j? zWq}hdT(TpvL67}be69Th<8p~}>BqTTHDpT2@s26(WXUzdqCAfdAk;}Hg;8qI1F@Lf z*fPeJ-?JMtsJ%FR(eyW7B?-jqy3i3>bw%SAm1Z)^u^{v|j5A(n0GS$)Dbq|cRp0zb ztfz4|1>8xQLUVrMbVhSJ_ZgkS2ZoJ#Fi9>p|^YEW@h%{j4~xi zY?Y4YZDyfhEJlNYiG`@10MitJ$-7`O2}}x2ObQ}{%uG^GrP>lzL&_wY^O)0_#_2rc zp8DHR!iERA@J=Zxu)eSXePN?-4kA#B=Nor*Yubf~?rj7S9h2zKYU}G%#t9<4BL=>M z8uu>fOcH7|Q-m_@R2GHkg`!9er(;WetWsyt97*_58J)a11bgzuwnju4_K^x%VsBiO z2dm`5H>I#j4JvE{s5E-D3EbF5<0@6F6 z^RCdSnJhGbN{x0Z=u8J4HLYF|iKDNF7W{!P|1Z=O3^jf zAm%rCr7QTi$St*c(Iv!Mbd8aUj^6fSc$e;C?2t^+KTpCP#Hxvf3arAYh@jF4Dh;4g zqkB&%)6D=K9lcT#DaUaXP3l~lqXH9ac7>ln9v%1bqANcQQNc!fBMX2AV@V#kJ0~WcyeS{K>nXZgn zzq`pVF1pDr$*Kwcc%yHB#P^{>BU*B!H>$U9UxZo~QP6NuT^r5yggJ*iUrGIO;CPoH%(E*b=j^g}dV zFYhm0@XT;{+$vS}40Zb{>gyA5VSPh_DUtP6I5`fQr(fVRaT2Ma#TnvIyf+ ztDhx&r=Kls2%3Yhwr_<*(%Tm!aiq+lSLz2er#t6zjdSV49n{ZQG6?4A=7-@UdKn5j zmr(p4LE%R>P(aqKyQ@J9W&yqiF{B0*SPZGruqHDZ^_11sX-FogTrpFips?65UtsqN zhq7h;+qW2#yf`Di&>6-|GnmtP!0C+SbVj4TfJzdA#|Vs?7V)9vAdH$Yasri7P$`8a zNoWQS zAHZ-Di;X2@=H!Hp^pR^6)}kF&F|n0g%!i8+F18M0zMcvBY`L&r8HF`yhpkMqluH`8 zWI31o)VPJ*ty7iKrx8&&Nae7XiS6dCrFAF^Ym|!}0HFH3kDPQpD9>a&NiWiwxXVe_ zxQ=o0j$Hf<7e5Q}D5;M(>2yxsf$jD-Wk<2o({{w|2NoVKagBal<0{v<294^zG43Sm zy1X;V+v|fY@}ugY<3v2~q|QPo#C1kAH0$D@K19mU5)-eWRQb@ zG*?>@^&3j9*W-$j|JT-e$7Nl9|Np@d5K%$dGH#GP?g{r~XgM3MG*|8!xkt_vbKwRP z4{qFON=9z2YAZ5ZGGGVMt7|#jc z@eksJN)hkT|A5nEhRhA{UsC)tDQ=SD7KleT^bcimH|k*xwMqla^_QHf>ebB6@G&yY z8JVVSB0JvpiJPf)kAP6>@>*yMSuN-E-$MK?7Vj*@FH7<6QbkXwXx)P?>ctkJ7OzY3 zK`cH%ivJ?The`2wAzpSZ1v&5K$ayc$IX3$r>d!&XcuqK0Cj46_oFo%YLBiCNfj-n` zYAEXd4MSJq=4AK^31)MGSu#O=HMhq3iCmKl64y}b!q7h4PC7~7A?o`W&LF`@oFGpo z2$Bg%CRl|8Q@ny2(krV&arU{BaE>srL7Q28qn3SfyqdqV?NWRP#MkM9V9?G`>~Fvv z9g9EuG;;&pxS{nEStZ&cq_M~}LYD1kiJSR0(`yGp(cqDyrA+Y!SKd*npuH46B^8`W zT$86N5pJEO(EnKIyfnI}H2R_xy39gl!gGKDRVq&aHu{+x>kTRSu9UnZb^nsMxkObT z$M*ip3?RRSiMae|-*uK-&yz&zpIU6OO`IarJeFzxW_#xzyYESyLbNp+&WByee$?9)jXvf;nv!$UbF>aCC#pOj2AF<6n=_@B{THmjq zD9JTMV4UEs+f05NqOd=YtD-V+XI^-?6IJ``%1TsNP9E2R!(izP)UX_fpkA$;eKrtp ztWzVD6{Z@A;EH1S)m~mDpaiElPH|QtgqbX952_HlU zL$>I$L*2aIi!5)kH8$yMuo9WIN3x{3N20c}6O+ek-Yp3SqS~n2U82H@_Hv=dU<`&H z7yAyWk2uj8&oH^Bp`$KG)Z@iglO)=hSkA<8uE~M$*1ARH_YGrR1$MA;Kd-utZihIW z=;!RjQ3dsgo21@cPoYJ8quz+y*fN{1Gw58MY1g8*(8!^29yH*5cnMJ#U16#;*79o$yIiJyf^R9;-2z{BNk!5O9e} zet)QU<6M!1yvL9Sb>`GCX`zG4%2Hk|o5s-q zIjIzD+*JV0)2*`y*UOQ>R z^HG&iaexZ3x>hPAlW6a)sgJWZff~+LxCZBd8j4a%DhFZ>BUBPm$jwQ^hzLf+GGd#8 zFo@PFO+z5!BtoM>v-T0C+a=;-Mrb8s4iYA+R=7_rZR&`N|^A~H2a)No@{ z?CuK*ImnO}b%j&T4W}cMS~96ElTIq6M3LSCA$CP&J4x!O*+Ty%`3K>sh9rH-q)yVD zb8Jq(=pyRVSye*C-5GL0fgl`ZCruC_JtU-`rjS=yLUD>iLcV86e+jwHkkQe&g*^b5 zNs5OtinzLh)j(tfAquhDJL`cO>aoCXJD#2TYpDq_L`9v~vuhbk+T>%pOJ3*T4Z(|GN%r? zOhE>TVt0;-S=t~B$Xscmw;mR5h~7;D^HfE&lNjgkz~$EA3K%CHRQfmS29&fxvw+JF z%mB%3#>_&=R59}tW^Pn%p>5j{c&$3d!7Qv}7CD$$ob;r`Pc#ed%vi}xWab{p)atiW z(2;2At%jDU3Tc~QtkHqpQ-|IEf3QasY@pa}Ndzj2g`(J8crvxZ5i$Nky-xlwh{LfFc{m?4fZ^5o@W~Jp#me3bA+oNbM~IoYOv6 zdSR5=So^*mIG=%4OSzSMr?O+qW%I&gP6Q^3dO-;anWqQkKf@V(m<>Hr$A(q6Mu^KT~dpgs+H6|OwF`Ybxbueb)P~VL=&~zAMI50^HhH_Wol>GsX|f@GqnX% zl`<{oGVK_%itnhs-!fts9cvpg9xhQYyRJbrrG@sg9o_DEv>zEeYG<>9Y$&#!lIRLX zcajF5V}tu~;fB!E&Jp{mvU|iJ_(+91gr;@UUbIttFtxVR2eqGeK0EOGV%tSYy~@=7 zl6sw~qwUlI5r^o)u!w$entIt`522a;wf|#kptv_&yXXb#Xze1g@lNu2)Yg3lj*-9z z44i2Pj*U1+_a;TW4&SNYK^RGVMfb*Nhchrl+@GwSZwL1IP8&qlnc5t&>9K57&ls3p zTcr6329)SB2^CXkMPNs=+Rac4%x0iVvPx9tXlK`1h(@(cJ6~*dS7Z28)rdc$Txp@V z4i;`;m`cpZiwFSB->^GRb(Vh1)eg0z3Z6$r&?_6Xv&Gf`i3(#>p+u<|^$DZmlnvUY z8zZpkSRG@K14pWCo*XBh7HOx|nUz4Vf1(}D_b9x?wpcZ{bu|O`)Y*1~fp`d^M6!&A z&q`EL=x&-PYlZV?+VOS1jK_0YL{P%nd9lqTSsBbKuPrzp)UBnMZy1;)mL8SBHin}m z2-QNBhU66Cc1An;{|q_d#@Zs_E>(44);VccuCAQ)*J5%d=DftbZ8%e+@_k`&%wx{} zqRS83=Ktp?4EmbxhyzSjeHnQjNKraOosFUDjR+T%*HFXx5|tNv_(AGyoMZh}i+C9? z45?M3Y?vCusH#z6gQ#q-f3mpwAoT%mTTR3q0a|~il@B9oUQB~|;@@K23?90#e~d{7 z%e^Q1{HqQ8|E-%Ot($?%6-~yN&(Yzz{vl$$lhNeNTY>GVZ?>VUi%X**T!}KSqbr{V zHKR9k3^>*!sJ;g-#H{)!xFy}riC^aEW^|`=)y&98d zZ@N_wzl53u$EHwBNbG2SXQ4BB_SAWa<$*e^$;f*;sUf-#TzK-*3aZvSRH;~1gj7}d zf~q3JIlC$kTA#@J0_a4sx|8w%?X{x#kElsPY!Zbf#ZF?4Zz@-27sTl}yp0#mETtx~ z#^u|k#$wi(YurjgYuq3n>7>RzFKFCv_=+>b)>6JrhgU!X=;&c}SMG#w?2pf*Cf3+E z3Qmii#`;<-@xwkeW3f&or0H^?N=Q|Q9hqyvnQIAEUN!yu_m_VL4<1Y#j~Qk)9XfPq z&7eVpY6cD*Sc6638b`J2Pa94d=j5aO{T{BlH2syWvs`3NqORAT|*a|u^FuMS8+vbjU zEkx-uBQE|w%9FY9PFY7+4;tH(ZLP68=>t;^apf#+hHah&YjjI!Wte8B8X~D<3#gwns zWOHn%syHaB`Z#toXGDin#d;4hs)!p}@Ge~e6vawK39M+3R8%4rY3mee_#GK{N<3s7 zMtZZN2$8Cx=%8*cEzQs%>;M#*6EHwKsN_f|hVDm>g#RJkT8!p4=&*8X#uTZ_%6iJB zo}*Gvi#k0qwCu349;v=Ejw5}$6ij&o>BBE|b7)=%%`&N?9p~jsdtSuQ(^AD(tYZ0N zO%t)DtwxPPdyRFRlRC~z9i8fQgv-Z3sM!z3Nu=*#*YQ2;=&M0!=usFEJ?xP%i>kg? zv?Pmxmsm@aA9RH%tnRX~da;7*Qo#+Wpua8{~G6$ezKxU zsgi%VN@h6pO=f-nu)bSrKYDf-_vt%7(V^39^sjCUifz6IPi0KfBtq5Hu>NIDOx)C* zOx$f`qbXN4Frnsh6a`A-YM`IRv8(fzYUWUVU0@L1&q+WG@&<965jt1rE82VLBV2^1 zmmX`0z;i2J$eHk#Xdj8rWppz}7bs|sbwvxB=|A8&*ZJ!;+4T3ZAfO8v-7IdiNDb8M z?1j`YM86eilIYcpR!MY(L>DqTkb#MDHl#xYfT#D+P6XrsY z`DT5x3!!IeEPT@R8*8gp$f`ZS{1%em()5E9{Co;Nkk^@iI%OC2eVwDipj0X}i+K(9 z-syxK{LIvL`gj*Ctr6-F5dz>#g65^1Ud5R~Xn|0td)KxXy*}9s}>DY+)dbY(R7GYtXyH z$h(Ytk8#7%4A@BN{+&kXOXNq|RBXMY!R6nodkh{U!DA)(0fVP8_z8oj*}=~k>`T8q zNmziN89dnzmeuAo9blZ{lg2(}X0~L`0yEz)705-5^hgDA5l6^rOmiD)fkaQ@k(i60 z8JUBui>Hh9`|$$DKkP`{wd_bd!@R2vX4Y~LTJStL*0DJdN&Ef!hB#+`P=82j@fSrVZ347dSxdRpa#U(*QKv;m zF<+TRz?Y{MQLiucm^q;IJ7{z115*G-ob3{qz?;KwK#Pwu1nO{FkD=J3FQG*&Z>weJ z@fs^QCl#ER3Ody(SO*`@?C+V~jPm+w@u`E{12tRyy<&e5UG0lYPu(u*ok0Gc?Qe2K zU&s?|Z2a}m!WHyl71yPT8&XC87gP*q6~A&Jh1050T72tJF`QNWs;CH68hOvV`g$(n z*{}F~b1po$S$ggl_&KTjDXW2@kQOf0E|RwA0F8?o zKIG!1D;BC%A4i_X<9eo%;g2AoaIA)o5C>UYjGy z1xyZ(#~?5yUJe4s@-(k9&`{_snuHh%B|Hit=lF#lV{jPYDhZE}@WL11MX3)Mo>y$I z)gp!`#A7gfB`i;f`4)3zTd9&Fe}BUus;zC`__02*3;tUU|msaHtcd1VQB^o1)GGU zY%wX?VprTkDsCw=RQ^JSPN)9G8OpEFW-A^&5zDx*#Yd3;8}T#iGStqn7a?cfFf2xC z4Nf+Tv#0n?9VJ(tB)qePpL+p*DfLO7iZJxoVzvWMe2L+`;^Qgoop?FBQVj25IE3gj z?-=IPPUIABf5{ynx!0fL3jN(w7hL(coA?1W$%@D9a76qFmz0zgI$s`yu$#jT$DM_7 zgkd^14hQpiTfvPnV}EP;I5YOQFzZdGS01E}am+!5{z>XbPCV1ir{KR6d&tWxEQguy z^mt{aE90kLnPMn+64vR4$u2zaR_KR#`@b~XoK}zTy`pPW$*+&j*SGZ~>k@MT0u&ev z>3{Cn5D#8p*z1O+NZlOQoHgreC?hzm6Lkm<^Pr`{VJe}{H5Vadkxx<~J#7>|43m7i z;K#@mye4WJOxAU^v_JitnT6*nL%EwAL1Q&im;G{Np+rUix%z0JSBa{V6CwPRJ6(>B zoQrRPFH(EqsZOTvevXdym>q`WZnP~{xA^7YJrb+~_`vc|1zedLiO)_;2Q0SX+)HG9 zZeF3}-bIJ&WzY6AQ656sVbU#l2{sCslFb+fK57Z<)Q-*i<*ELo%GQx+`Y8wm&Qx!D zOQ> z2-jj9Hw+Kj_pWUOuXJ|!-8_etXlT}Z#<7GViV~0Ra+R(erd#_GB}u~iz>K-Yqp?up zzazadov4n-27xd6S4FL$vlAn8r~)_hsCbHP0=GkG$Yu@6G;^A9JZn&iswZ3tD<{2F zLtL5B!UZ)83ij1Y*u}-uZv&dvoJFAK!c&IPu~)VGx`nmYb&p2qYfnz6_@!A{5A z)eWOoUExdYM?H8;d>-Td5{lULCQTTh&*g&%969C&RJO`Ck}?iL7wiwGDWR60tR|es zt})JHHCSH_OhG1=(@WK$m{b-nrj4v7n$;j|Tx9fGI=hwCged0+ckVz&8r_Odrhdtm z@vI?~Mt^LaZPySdHEe&W2Cc}@S_+_{gf*nvHRxGGS)?2uUTtS_qb;A=X3*7^F*+_P z4|*@%GK|%P(5QpPId(N>sRjXMUQ%8u;*}N_IP^zHSxsxZnparO308w>N&JrTrZcu| zs&IoZ9QvjOVL!fvw?QdkS-V}zX_V5bm%`H!?Z*O-{^&fzyK!B6QKK#l|1NR`|3`X; zZI^A+$$HS=Oj&&_!x0q50q-H<7hei*CA##t%mMrc!-pj7;r;wZ19|hw6>$M0SJ3ib zY`Iji#F9p%Mp_2j>-SfsetAJ&!tcBkK3F>3F_tLsAA)}%IMzoV>Ow?C zp)@Q4ywwi_ebK0KsLOLxG`x)~RYo_@p@s2j1)Od0b~CSm(T|2DnikoiMG_jT$Ifa= z)Dt@Pz#Jyd?XkEaw>m(d-o{sXwv3^rc4#U?Er33AVk19yKy41_ehD?%q1efknQjSQ zhnQHn+!G0F$@5tBb~@j>`2rllOhfjgsPESf)awcg-}Y(wNwfv(?8@L~l;1uuJr7%g z$h=Bap0l{Z&d%T#&y8ePj^k!-mDpRa=+-=!miA1;DvbyA{gJsm%~agQC5h|~#EdJF)o+S~`V+-qiO$0GHcLDjGM< zl+D(%hnB!e08X6}*u!pUY}sY&e>fdAi+L)#P%m)>c{;}w!Zm{@PeiX=kS4pFz6}u` zMDb^f6f3b)c{XmL|D&M z0{kMwF9RNv5?n}|`slUdW`FAwz;7hOQAg3eA&Kb8>>Yr5V9XpeTNH(C2Ah6K+si{y zcN#g;I)pW}Ci>OX+pghV*3i?K;6)qn=-1K*zXW!p*9J%B0w+qx$YObz3dvg^=Rv3{c4)|ci>yp zXis8oCbDHFoYZ@nUo|&z4p*EE9h~-I%s8s37qx{p)lZj7MlG?*jzN|?ie>@$e8!C5 zSfOq1hBY*+eo$vxit>k(wI*Tb$wz&fOXX31Vz%73Tplw9p~ItaBqb;vO(%rLt+V#$ z5~*dblFWv*DZsFq<^~15$zR)tJ{j8WHw&$ZDIcjm&V!VvTN9^qLwRLW%m}K8j@nD5 z@#*L!RrLOD>pKo$ClR?r0)1#_tYH%^jt^=hUBMn}3WE0Q)#Yr1^S(rk&I+g^6&%?j z4qMVu&`~t?b8C<1VV|WIAjjBCF&T(=%dKXdUw%b>yo7JCRkV&ePKON! zU%Jpf9nIitYgY%StB5%xIe|*a9d2t_L<`ynwdbs&-CD(O=d8|HfbF90k8654bfH@m zO0kIM{b+r|LFpk9E~hSqH8FI!yWu0s>uERSy0ryXqX(+zIN`NUCtCQs6`|Zvzyj_0 zD{N2ROZBUlr!vsVVTKVLt)TRQbr{}@9;f~qudpJdpj~vPbBXGq3%yd4in93^Q+yjD zhHi4kGn4Gk`ISui+|}5_u?d+@I7x}%%X88@<*EMSD31NvW)8eW>giE1N?MT z@>Fw_S1!)1HY0K6IuO|}%F~pk0Y)st9}BMqMlmo#0k)(IThia*V0-|&lWx0thZ1aH zKr~Yk)7RaGYb-Ik_c-7cUci_D`ff?bR!*#O7r+_`M))o~I6);T#=+E0=b-OZ=#9Et zKo@2(lN68DCsp@>j2KL_j5?HOePv1R!~ye2sQ6q_fxZ**ii=IgEzpx`*TZj0P)RG} zV6U38*F)u>1Dzt}?jqf6X>2MNXQ=XcI!YUJ?^9-cz&wY9b$wdvrqKN?xSbE$=qAf7 zoi$H)7FWJDbFeIAsjbXXN4u(>U5$7-sk4%sbgKN8nHZ^YS;b%E+(hvZ)R%g7(@myv zZ|i1D<`r|cv$*=BnL}uS*aa_)3{+_pp{>=Y@L0=yirK2$P9wK53lCi+FsmxrQVtfD)3zJ2_;u_Pn-(l@ zTE3TAB}#T9XkSVOoT-Yl>q#Ld%ZHqYm@>xgv*WCm70%*Oy5$gXadh|;+)1zf#wYl6 zk4UB$Ej^B%rfx?a%vQ_{QCg2*TMHsmyHex{T@huS#1T%st>A<3icEd_re!~GmUf7qS zK!@Hn{s!nD3|$|fYfMZ2GUiaXhYsijJ9Ls|1w~eKejkB{_3R)~F_n34Gc3EnGc&K5 zxb@gL5}B@HUZago@vsI0n^T^vX%2OB!U(6{rnF%CWKIUYHROCgL+fGel;ws4o_OXW zR8%fROGE<^o=Yu7;HHTRcN5m`jx|oJMK1KkP`;ZFXjn)0qn#@<&_+Nbrui|=A2gT< z+GiTR>~UR(gr60j3E+hC7gmZR$q3QKq?Yu52Yv?9$FH%nc;Z?cjz*V~&&+ z1McTj{G-K{ofeLx3~sUHwqh>&gjmVdIJgT_*i@Z@45H$_jPxZ>VZouSR5sNJBw7y+ zh@tc; zE`ruDbyOSueCF!J?Xxn5b)fLCu&k9xxsUX9Thm-1JKB*AXhB!g0_xHkNF4u+qJ7^o z64qQ~WH+2l8~3&zwPq3bugIv>cnapKrGSCrWOoyeRUGS=7KbNYzq!I}#jlZ0Arog-~jB8YC6 zRsIPh-`{K60GFxIO32N`j522IvooxHxI0?jrpO zwCJfP?SR*60Ua2y)C-}4&z_QiZzSMb2Ap>Qx?A^<@jLw%ntFi&5#mBG35XNwz6_Yr zy?G3^_&zE~oWCf)hHFfD$_?VfpG|oB^9E4L9!U#w8)n^48Mkv6;dz^q!} zCS<w;rN4^$gOkd2WW$d8$+d|Fp6*!RqBwW}RGOX~lM3 zaW_v!P_RLGJfgC3y06TuH_h`kqoMjd&m`+{>fmRvLJr26W6Jv_8hrU4lQha`fpq zkx^`&;6z>G1G|dbvE~tc*|908n)E>VnZgOAm=}4~Y%+V+Y)flY^J#m$0*#$0x~apf z8cIE(Jh0+iqC!l&Tu{%>=pN80Q9{8e(5TVKrmVu%oYuJ zo^wZ91kR>kB_~Y`y>ETPsU*nTg*IiGF#$&U(dki0Uw8B|LJa&fHO@(RKDL%Si=F>i zRn8*onYA4h`?}D!sb)AgB%2AfLO(ZszcU59+Sc-*9Lt}s#ud_$%2BNdYhc^r$}{)tRphCr*V&_BgC zhyUicImtN%;|+Oa;)d0B11T|_6=v*-S00gxPNWwgQ3(0B;zTHE9=kfV!t$zoF7oPY zHhvu*iB8Ex-^fJYrLRCD75R5n5*3GGBJ}JnEQ-tMo|k*s_yu}zvFV~2N1ZCK$waqg zB6OmIZRk%BH3~7z>F+_t1)?&`_CS%pBjx{)^3_t_m(-`y8<5`wE=LOjIv}Ekjqxi5kwaEs=?48*@d)LfcY->P&e`;H&jM#qv)R-qK4%C`tk|t$J@zxnR&UEh!Tag03_XV4B zwpOyOl&hci?1U71mBn5);q%9E@wK#{ z(LD_@bI)kG3(0RX;_wvAcNxcjBA#8fp_jR6xem!|8A+}p<5tFG zNDfNdPCpJZ?Pkf_S!qAG(!xnGt;B^pmLDMbM@EXPXj7dr0kt+B%q!zf@FF3iYHHd! zR|@WqJK9$sTP{JeCc}(38tP?^f#htKoXwI^;_1S))2{jJuQIfgxY^cv4#sq3aU5xn6TP}+z60_9rR_rVG!;tmD=hxB zYg`hWcC))o(N8L97#S~m56SF}6hEaEp${-^;Vj;}mv+gO9{mvv1;eEHXuEC||k*=M<`yZ#F?Gsdq*q7*+25tK?+c{CfMfjv@L;8>G!(vj*gSr29 zv!#E9R6WE~Vcm~ZN1jV{l2g_8Jzn(RtLc|HX+kSb8sd1`$yfNlo_+|BF`~(7Yat-t zJO{auiN!VvseUW{7gBdMcjCM0!M)S>D@iWNB-hYB<&EBPw=;1hf&Hg||D58)T_oZG z$o0Hk%5yLoBhpv6;E4j^f7iMe>i)>w1=L;~*E4jLx*7pD-=G2xRo) Jr8B}>{6B`FHJ$(f delta 55962 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 diff --git a/code/ryzom/client/data/gamedev/adds/interfaces/new_texture_interfaces_dxtc.txt b/code/ryzom/client/data/gamedev/adds/interfaces/new_texture_interfaces_dxtc.txt index ec1afb449..f35989e33 100644 --- a/code/ryzom/client/data/gamedev/adds/interfaces/new_texture_interfaces_dxtc.txt +++ b/code/ryzom/client/data/gamedev/adds/interfaces/new_texture_interfaces_dxtc.txt @@ -18,305 +18,305 @@ BK_goo.tga 0.156250000000 0.078125000000 0.195312500000 0.117187500000 bk_guild.tga 0.195312500000 0.078125000000 0.234375000000 0.117187500000 bk_horde.tga 0.000000000000 0.117187500000 0.039062500000 0.156250000000 bk_kami.tga 0.039062500000 0.117187500000 0.078125000000 0.156250000000 -bk_karavan.tga 0.078125000000 0.117187500000 0.117187500000 0.156250000000 -BK_matis.tga 0.117187500000 0.117187500000 0.156250000000 0.156250000000 -bk_mission.tga 0.156250000000 0.117187500000 0.195312500000 0.156250000000 -bk_mission2.tga 0.195312500000 0.117187500000 0.234375000000 0.156250000000 -BK_outpost.tga 0.000000000000 0.156250000000 0.039062500000 0.195312500000 -BK_primes.tga 0.039062500000 0.156250000000 0.078125000000 0.195312500000 -bk_service.tga 0.078125000000 0.156250000000 0.117187500000 0.195312500000 -bk_training.tga 0.117187500000 0.156250000000 0.156250000000 0.195312500000 -BK_tryker.tga 0.156250000000 0.156250000000 0.195312500000 0.195312500000 -BK_zorai.tga 0.195312500000 0.156250000000 0.234375000000 0.195312500000 -charge.tga 0.000000000000 0.195312500000 0.039062500000 0.234375000000 -clef.tga 0.039062500000 0.195312500000 0.078125000000 0.234375000000 -conso_branche.tga 0.078125000000 0.195312500000 0.117187500000 0.234375000000 -conso_branche_mask.tga 0.117187500000 0.195312500000 0.156250000000 0.234375000000 -conso_fleur.tga 0.156250000000 0.195312500000 0.195312500000 0.234375000000 -conso_fleur_mask.tga 0.195312500000 0.195312500000 0.234375000000 0.234375000000 -conso_grappe.tga 0.242187500000 0.000000000000 0.281250000000 0.039062500000 -conso_grappe_mask.tga 0.281250000000 0.000000000000 0.320312500000 0.039062500000 -conso_nectar.tga 0.320312500000 0.000000000000 0.359375000000 0.039062500000 -conso_nectar_mask.tga 0.359375000000 0.000000000000 0.398437500000 0.039062500000 -construction.tga 0.398437500000 0.000000000000 0.437500000000 0.039062500000 -cristal_ammo.tga 0.437500000000 0.000000000000 0.476562500000 0.039062500000 -cristal_spell.tga 0.238281250000 0.039062500000 0.277343750000 0.078125000000 -ge_mission_outpost_townhall.tga 0.277343750000 0.039062500000 0.316406250000 0.078125000000 -ico_amande.tga 0.316406250000 0.039062500000 0.355468750000 0.078125000000 -ico_cataliseur_xp.tga 0.355468750000 0.039062500000 0.394531250000 0.078125000000 -ico_consommable_over.tga 0.394531250000 0.039062500000 0.433593750000 0.078125000000 -ico_fleur_carac_1.tga 0.433593750000 0.039062500000 0.472656250000 0.078125000000 -ico_fleur_carac_1_mask.tga 0.234375000000 0.078125000000 0.273437500000 0.117187500000 -ico_fleur_carac_2.tga 0.273437500000 0.078125000000 0.312500000000 0.117187500000 -ico_fleur_carac_2_mask.tga 0.312500000000 0.078125000000 0.351562500000 0.117187500000 -ico_fleur_carac_3.tga 0.351562500000 0.078125000000 0.390625000000 0.117187500000 -ico_fleur_carac_3_mask.tga 0.390625000000 0.078125000000 0.429687500000 0.117187500000 -ico_foreuse.tga 0.429687500000 0.078125000000 0.468750000000 0.117187500000 -ico_haircolor.tga 0.234375000000 0.117187500000 0.273437500000 0.156250000000 -ico_haircut.tga 0.273437500000 0.117187500000 0.312500000000 0.156250000000 -ico_mission_art_fyros.tga 0.312500000000 0.117187500000 0.351562500000 0.156250000000 -ico_mission_art_matis.tga 0.351562500000 0.117187500000 0.390625000000 0.156250000000 -ico_mission_art_tryker.tga 0.390625000000 0.117187500000 0.429687500000 0.156250000000 -ico_mission_art_zorai.tga 0.429687500000 0.117187500000 0.468750000000 0.156250000000 -ico_mission_barrel.tga 0.234375000000 0.156250000000 0.273437500000 0.195312500000 -ico_mission_bottle.tga 0.273437500000 0.156250000000 0.312500000000 0.195312500000 -ico_mission_casket.tga 0.312500000000 0.156250000000 0.351562500000 0.195312500000 -ico_mission_medicine.tga 0.351562500000 0.156250000000 0.390625000000 0.195312500000 -ico_mission_message.tga 0.390625000000 0.156250000000 0.429687500000 0.195312500000 -ico_mission_package.tga 0.429687500000 0.156250000000 0.468750000000 0.195312500000 -ico_mission_pot.tga 0.234375000000 0.195312500000 0.273437500000 0.234375000000 -ico_mission_purse.tga 0.273437500000 0.195312500000 0.312500000000 0.234375000000 -ico_noix.tga 0.312500000000 0.195312500000 0.351562500000 0.234375000000 -ico_racine.tga 0.351562500000 0.195312500000 0.390625000000 0.234375000000 -ico_spores.tga 0.390625000000 0.195312500000 0.429687500000 0.234375000000 -ico_task_craft.tga 0.429687500000 0.195312500000 0.468750000000 0.234375000000 -ico_task_done.tga 0.000000000000 0.234375000000 0.039062500000 0.273437500000 -ico_task_failed.tga 0.039062500000 0.234375000000 0.078125000000 0.273437500000 -ico_task_fight.tga 0.078125000000 0.234375000000 0.117187500000 0.273437500000 -ico_task_forage.tga 0.117187500000 0.234375000000 0.156250000000 0.273437500000 -ico_task_generic.tga 0.156250000000 0.234375000000 0.195312500000 0.273437500000 -ico_task_generic_quart.tga 0.195312500000 0.234375000000 0.234375000000 0.273437500000 -ico_task_guild.tga 0.234375000000 0.234375000000 0.273437500000 0.273437500000 -ico_task_rite.tga 0.273437500000 0.234375000000 0.312500000000 0.273437500000 -ico_task_travel.tga 0.312500000000 0.234375000000 0.351562500000 0.273437500000 -ico_tatoo.tga 0.351562500000 0.234375000000 0.390625000000 0.273437500000 -ico_tourbe.tga 0.390625000000 0.234375000000 0.429687500000 0.273437500000 -improved_tool.tga 0.429687500000 0.234375000000 0.468750000000 0.273437500000 -item_default.tga 0.000000000000 0.273437500000 0.039062500000 0.312500000000 -item_plan_over.tga 0.039062500000 0.273437500000 0.078125000000 0.312500000000 -lucky_flower.tga 0.078125000000 0.273437500000 0.117187500000 0.312500000000 -mektoub_pack.tga 0.117187500000 0.273437500000 0.156250000000 0.312500000000 -mektoub_steed.tga 0.156250000000 0.273437500000 0.195312500000 0.312500000000 -mg_glove.tga 0.195312500000 0.273437500000 0.234375000000 0.312500000000 -mission_icon_0.tga 0.234375000000 0.273437500000 0.273437500000 0.312500000000 -mission_icon_1.tga 0.273437500000 0.273437500000 0.312500000000 0.312500000000 -mission_icon_2.tga 0.312500000000 0.273437500000 0.351562500000 0.312500000000 -mission_icon_3.tga 0.351562500000 0.273437500000 0.390625000000 0.312500000000 -mp_amber.tga 0.390625000000 0.273437500000 0.429687500000 0.312500000000 -mp_bark.tga 0.429687500000 0.273437500000 0.468750000000 0.312500000000 -mp_batiment_brique.tga 0.000000000000 0.312500000000 0.039062500000 0.351562500000 -mp_batiment_colonne.tga 0.039062500000 0.312500000000 0.078125000000 0.351562500000 -mp_batiment_colonne_justice.tga 0.078125000000 0.312500000000 0.117187500000 0.351562500000 -mp_batiment_comble.tga 0.117187500000 0.312500000000 0.156250000000 0.351562500000 -mp_batiment_noyau_maduk.tga 0.156250000000 0.312500000000 0.195312500000 0.351562500000 -mp_batiment_ornement.tga 0.195312500000 0.312500000000 0.234375000000 0.351562500000 -mp_batiment_revetement.tga 0.234375000000 0.312500000000 0.273437500000 0.351562500000 -mp_batiment_socle.tga 0.273437500000 0.312500000000 0.312500000000 0.351562500000 -mp_batiment_statue.tga 0.312500000000 0.312500000000 0.351562500000 0.351562500000 -mp_beak.tga 0.351562500000 0.312500000000 0.390625000000 0.351562500000 -mp_blood.tga 0.390625000000 0.312500000000 0.429687500000 0.351562500000 -mp_bone.tga 0.429687500000 0.312500000000 0.468750000000 0.351562500000 -mp_bud.tga 0.000000000000 0.351562500000 0.039062500000 0.390625000000 -mp_buterfly_blue.tga 0.039062500000 0.351562500000 0.078125000000 0.390625000000 -mp_buterfly_cocoon.tga 0.078125000000 0.351562500000 0.117187500000 0.390625000000 -mp_cereal.tga 0.117187500000 0.351562500000 0.156250000000 0.390625000000 -mp_claw.tga 0.156250000000 0.351562500000 0.195312500000 0.390625000000 -mp_dandelion.tga 0.195312500000 0.351562500000 0.234375000000 0.390625000000 -mp_dust.tga 0.234375000000 0.351562500000 0.273437500000 0.390625000000 -mp_egg.tga 0.273437500000 0.351562500000 0.312500000000 0.390625000000 -mp_eyes.tga 0.312500000000 0.351562500000 0.351562500000 0.390625000000 -mp_fang.tga 0.351562500000 0.351562500000 0.390625000000 0.390625000000 -mp_fiber.tga 0.390625000000 0.351562500000 0.429687500000 0.390625000000 -mp_filament.tga 0.429687500000 0.351562500000 0.468750000000 0.390625000000 -mp_firefly_abdomen.tga 0.000000000000 0.390625000000 0.039062500000 0.429687500000 -mp_fish_scale.tga 0.039062500000 0.390625000000 0.078125000000 0.429687500000 -mp_flowers.tga 0.078125000000 0.390625000000 0.117187500000 0.429687500000 -mp_fresh_loose_soil.tga 0.117187500000 0.390625000000 0.156250000000 0.429687500000 -mp_fruit.tga 0.156250000000 0.390625000000 0.195312500000 0.429687500000 -mp_generic.tga 0.195312500000 0.390625000000 0.234375000000 0.429687500000 -mp_generic_colorize.tga 0.234375000000 0.390625000000 0.273437500000 0.429687500000 -mp_gomme.tga 0.273437500000 0.390625000000 0.312500000000 0.429687500000 -mp_goo_residue.tga 0.312500000000 0.390625000000 0.351562500000 0.429687500000 -mp_hairs.tga 0.351562500000 0.390625000000 0.390625000000 0.429687500000 -mp_hoof.tga 0.390625000000 0.390625000000 0.429687500000 0.429687500000 -mp_horn.tga 0.429687500000 0.390625000000 0.468750000000 0.429687500000 -mp_horney.tga 0.000000000000 0.429687500000 0.039062500000 0.468750000000 -mp_insect_fossil.tga 0.039062500000 0.429687500000 0.078125000000 0.468750000000 -mp_kitinshell.tga 0.078125000000 0.429687500000 0.117187500000 0.468750000000 -mp_kitin_flesh.tga 0.117187500000 0.429687500000 0.156250000000 0.468750000000 -mp_kitin_secretion.tga 0.156250000000 0.429687500000 0.195312500000 0.468750000000 -mp_larva.tga 0.195312500000 0.429687500000 0.234375000000 0.468750000000 -mp_leaf.tga 0.234375000000 0.429687500000 0.273437500000 0.468750000000 -mp_leather.tga 0.273437500000 0.429687500000 0.312500000000 0.468750000000 -mp_liane.tga 0.312500000000 0.429687500000 0.351562500000 0.468750000000 -mp_lichen.tga 0.351562500000 0.429687500000 0.390625000000 0.468750000000 -mp_ligament.tga 0.390625000000 0.429687500000 0.429687500000 0.468750000000 -mp_mandible.tga 0.429687500000 0.429687500000 0.468750000000 0.468750000000 -mp_meat.tga 0.476562500000 0.000000000000 0.515625000000 0.039062500000 -mp_moss.tga 0.515625000000 0.000000000000 0.554687500000 0.039062500000 -mp_mushroom.tga 0.554687500000 0.000000000000 0.593750000000 0.039062500000 -mp_nail.tga 0.593750000000 0.000000000000 0.632812500000 0.039062500000 -mp_oil.tga 0.632812500000 0.000000000000 0.671875000000 0.039062500000 -mp_parasite.tga 0.671875000000 0.000000000000 0.710937500000 0.039062500000 -mp_pearl.tga 0.710937500000 0.000000000000 0.750000000000 0.039062500000 -mp_pelvis.tga 0.750000000000 0.000000000000 0.789062500000 0.039062500000 -mp_pigment.tga 0.789062500000 0.000000000000 0.828125000000 0.039062500000 -mp_pistil.tga 0.828125000000 0.000000000000 0.867187500000 0.039062500000 -mp_plant_fossil.tga 0.867187500000 0.000000000000 0.906250000000 0.039062500000 -mp_pollen.tga 0.906250000000 0.000000000000 0.945312500000 0.039062500000 -mp_resin.tga 0.945312500000 0.000000000000 0.984375000000 0.039062500000 -mp_ronce.tga 0.472656250000 0.039062500000 0.511718750000 0.078125000000 -mp_rostrum.tga 0.511718750000 0.039062500000 0.550781250000 0.078125000000 -mp_sap.tga 0.550781250000 0.039062500000 0.589843750000 0.078125000000 -mp_sawdust.tga 0.589843750000 0.039062500000 0.628906250000 0.078125000000 -mp_seed.tga 0.628906250000 0.039062500000 0.667968750000 0.078125000000 -mp_shell.tga 0.667968750000 0.039062500000 0.707031250000 0.078125000000 -mp_silk_worm.tga 0.707031250000 0.039062500000 0.746093750000 0.078125000000 -mp_skin.tga 0.746093750000 0.039062500000 0.785156250000 0.078125000000 -mp_skull.tga 0.785156250000 0.039062500000 0.824218750000 0.078125000000 -mp_spiders_web.tga 0.824218750000 0.039062500000 0.863281250000 0.078125000000 -mp_spine.tga 0.863281250000 0.039062500000 0.902343750000 0.078125000000 -mp_stem.tga 0.902343750000 0.039062500000 0.941406250000 0.078125000000 -mp_sting.tga 0.941406250000 0.039062500000 0.980468750000 0.078125000000 -mp_straw.tga 0.468750000000 0.078125000000 0.507812500000 0.117187500000 -mp_suc.tga 0.507812500000 0.078125000000 0.546875000000 0.117187500000 -mp_tail.tga 0.546875000000 0.078125000000 0.585937500000 0.117187500000 -mp_tooth.tga 0.585937500000 0.078125000000 0.625000000000 0.117187500000 -mp_trunk.tga 0.625000000000 0.078125000000 0.664062500000 0.117187500000 -mp_whiskers.tga 0.664062500000 0.078125000000 0.703125000000 0.117187500000 -mp_wing.tga 0.703125000000 0.078125000000 0.742187500000 0.117187500000 -mp_wood.tga 0.742187500000 0.078125000000 0.781250000000 0.117187500000 -mp_wood_node.tga 0.781250000000 0.078125000000 0.820312500000 0.117187500000 -MW_2h_axe.tga 0.820312500000 0.078125000000 0.859375000000 0.117187500000 -MW_2h_lance.tga 0.859375000000 0.078125000000 0.898437500000 0.117187500000 -MW_2h_mace.tga 0.898437500000 0.078125000000 0.937500000000 0.117187500000 -MW_2h_sword.tga 0.937500000000 0.078125000000 0.976562500000 0.117187500000 -MW_axe.tga 0.468750000000 0.117187500000 0.507812500000 0.156250000000 -MW_dagger.tga 0.507812500000 0.117187500000 0.546875000000 0.156250000000 -MW_lance.tga 0.546875000000 0.117187500000 0.585937500000 0.156250000000 -MW_mace.tga 0.585937500000 0.117187500000 0.625000000000 0.156250000000 -MW_staff.tga 0.625000000000 0.117187500000 0.664062500000 0.156250000000 -MW_sword.tga 0.664062500000 0.117187500000 0.703125000000 0.156250000000 -PA_anklet.tga 0.703125000000 0.117187500000 0.742187500000 0.156250000000 -PA_bracelet.tga 0.742187500000 0.117187500000 0.781250000000 0.156250000000 -PA_diadem.tga 0.781250000000 0.117187500000 0.820312500000 0.156250000000 -PA_earring.tga 0.820312500000 0.117187500000 0.859375000000 0.156250000000 -PA_pendant.tga 0.859375000000 0.117187500000 0.898437500000 0.156250000000 -PA_ring.tga 0.898437500000 0.117187500000 0.937500000000 0.156250000000 -protect_amber.tga 0.937500000000 0.117187500000 0.976562500000 0.156250000000 -pvp_aura.tga 0.468750000000 0.156250000000 0.507812500000 0.195312500000 -pvp_aura_mask.tga 0.507812500000 0.156250000000 0.546875000000 0.195312500000 -pvp_boost.tga 0.546875000000 0.156250000000 0.585937500000 0.195312500000 -pvp_boost_mask.tga 0.585937500000 0.156250000000 0.625000000000 0.195312500000 -pw_4.tga 0.625000000000 0.156250000000 0.664062500000 0.195312500000 -pw_5.tga 0.664062500000 0.156250000000 0.703125000000 0.195312500000 -pw_6.tga 0.703125000000 0.156250000000 0.742187500000 0.195312500000 -pw_7.tga 0.742187500000 0.156250000000 0.781250000000 0.195312500000 -PW_heavy.tga 0.781250000000 0.156250000000 0.820312500000 0.195312500000 -PW_light.tga 0.820312500000 0.156250000000 0.859375000000 0.195312500000 -PW_medium.tga 0.859375000000 0.156250000000 0.898437500000 0.195312500000 -quest_coeur.tga 0.898437500000 0.156250000000 0.937500000000 0.195312500000 -quest_foie.tga 0.937500000000 0.156250000000 0.976562500000 0.195312500000 -quest_jeton.tga 0.468750000000 0.195312500000 0.507812500000 0.234375000000 -quest_langue.tga 0.507812500000 0.195312500000 0.546875000000 0.234375000000 -quest_louche.tga 0.546875000000 0.195312500000 0.585937500000 0.234375000000 -quest_oreille.tga 0.585937500000 0.195312500000 0.625000000000 0.234375000000 -quest_patte.tga 0.625000000000 0.195312500000 0.664062500000 0.234375000000 -quest_poils.tga 0.664062500000 0.195312500000 0.703125000000 0.234375000000 -quest_queue.tga 0.703125000000 0.195312500000 0.742187500000 0.234375000000 -quest_ticket.tga 0.742187500000 0.195312500000 0.781250000000 0.234375000000 -AM_logo.tga 0.781250000000 0.195312500000 0.820312500000 0.234375000000 -AR_armpad.tga 0.820312500000 0.195312500000 0.859375000000 0.234375000000 -ar_armpad_mask.tga 0.859375000000 0.195312500000 0.898437500000 0.234375000000 -requirement.tga 0.898437500000 0.195312500000 0.937500000000 0.234375000000 -rm_f.tga 0.937500000000 0.195312500000 0.976562500000 0.234375000000 -rm_f_upgrade.tga 0.468750000000 0.234375000000 0.507812500000 0.273437500000 -rm_h.tga 0.507812500000 0.234375000000 0.546875000000 0.273437500000 -rm_h_upgrade.tga 0.546875000000 0.234375000000 0.585937500000 0.273437500000 -rm_m.tga 0.585937500000 0.234375000000 0.625000000000 0.273437500000 -rm_m_upgrade.tga 0.625000000000 0.234375000000 0.664062500000 0.273437500000 -rm_r.tga 0.664062500000 0.234375000000 0.703125000000 0.273437500000 -rm_r_upgrade.tga 0.703125000000 0.234375000000 0.742187500000 0.273437500000 -rpjobitem_200_a.tga 0.742187500000 0.234375000000 0.781250000000 0.273437500000 -rpjobitem_200_b.tga 0.781250000000 0.234375000000 0.820312500000 0.273437500000 -rpjobitem_200_c.tga 0.820312500000 0.234375000000 0.859375000000 0.273437500000 -rpjobitem_201_a.tga 0.859375000000 0.234375000000 0.898437500000 0.273437500000 -rpjobitem_201_b.tga 0.898437500000 0.234375000000 0.937500000000 0.273437500000 -rpjobitem_201_c.tga 0.937500000000 0.234375000000 0.976562500000 0.273437500000 -rpjobitem_202_a.tga 0.468750000000 0.273437500000 0.507812500000 0.312500000000 -rpjobitem_202_b.tga 0.507812500000 0.273437500000 0.546875000000 0.312500000000 -rpjobitem_202_c.tga 0.546875000000 0.273437500000 0.585937500000 0.312500000000 -rpjobitem_203_a.tga 0.585937500000 0.273437500000 0.625000000000 0.312500000000 -rpjobitem_203_b.tga 0.625000000000 0.273437500000 0.664062500000 0.312500000000 -rpjobitem_203_c.tga 0.664062500000 0.273437500000 0.703125000000 0.312500000000 -rpjobitem_204_a.tga 0.703125000000 0.273437500000 0.742187500000 0.312500000000 -rpjobitem_204_b.tga 0.742187500000 0.273437500000 0.781250000000 0.312500000000 -rpjobitem_204_c.tga 0.781250000000 0.273437500000 0.820312500000 0.312500000000 -rpjobitem_205_a.tga 0.820312500000 0.273437500000 0.859375000000 0.312500000000 -rpjobitem_205_b.tga 0.859375000000 0.273437500000 0.898437500000 0.312500000000 -rpjobitem_205_c.tga 0.898437500000 0.273437500000 0.937500000000 0.312500000000 -rpjobitem_206_a.tga 0.937500000000 0.273437500000 0.976562500000 0.312500000000 -rpjobitem_206_b.tga 0.468750000000 0.312500000000 0.507812500000 0.351562500000 -rpjobitem_206_c.tga 0.507812500000 0.312500000000 0.546875000000 0.351562500000 -rpjobitem_207_a.tga 0.546875000000 0.312500000000 0.585937500000 0.351562500000 -rpjobitem_207_b.tga 0.585937500000 0.312500000000 0.625000000000 0.351562500000 -rpjobitem_207_c.tga 0.625000000000 0.312500000000 0.664062500000 0.351562500000 -rpjobitem_certifications.tga 0.664062500000 0.312500000000 0.703125000000 0.351562500000 -rpjob_200.tga 0.703125000000 0.312500000000 0.742187500000 0.351562500000 -rpjob_201.tga 0.742187500000 0.312500000000 0.781250000000 0.351562500000 -rpjob_202.tga 0.781250000000 0.312500000000 0.820312500000 0.351562500000 -rpjob_203.tga 0.820312500000 0.312500000000 0.859375000000 0.351562500000 -rpjob_204.tga 0.859375000000 0.312500000000 0.898437500000 0.351562500000 -rpjob_205.tga 0.898437500000 0.312500000000 0.937500000000 0.351562500000 -rpjob_206.tga 0.937500000000 0.312500000000 0.976562500000 0.351562500000 -rpjob_207.tga 0.468750000000 0.351562500000 0.507812500000 0.390625000000 -rpjob_advanced.tga 0.507812500000 0.351562500000 0.546875000000 0.390625000000 -rpjob_elementary.tga 0.546875000000 0.351562500000 0.585937500000 0.390625000000 -rpjob_roleplay.tga 0.585937500000 0.351562500000 0.625000000000 0.390625000000 -rpjob_task.tga 0.625000000000 0.351562500000 0.664062500000 0.390625000000 -rpjob_task_certificats.tga 0.664062500000 0.351562500000 0.703125000000 0.390625000000 -rpjob_task_convert.tga 0.703125000000 0.351562500000 0.742187500000 0.390625000000 -rpjob_task_elementary.tga 0.742187500000 0.351562500000 0.781250000000 0.390625000000 -rpjob_task_generic.tga 0.781250000000 0.351562500000 0.820312500000 0.390625000000 -rpjob_task_upgrade.tga 0.820312500000 0.351562500000 0.859375000000 0.390625000000 -RW_autolaunch.tga 0.859375000000 0.351562500000 0.898437500000 0.390625000000 -RW_bowgun.tga 0.898437500000 0.351562500000 0.937500000000 0.390625000000 -RW_grenade.tga 0.937500000000 0.351562500000 0.976562500000 0.390625000000 -RW_harpoongun.tga 0.468750000000 0.390625000000 0.507812500000 0.429687500000 -RW_launcher.tga 0.507812500000 0.390625000000 0.546875000000 0.429687500000 -RW_pistol.tga 0.546875000000 0.390625000000 0.585937500000 0.429687500000 -RW_pistolarc.tga 0.585937500000 0.390625000000 0.625000000000 0.429687500000 -RW_rifle.tga 0.625000000000 0.390625000000 0.664062500000 0.429687500000 -SH_buckler.tga 0.664062500000 0.390625000000 0.703125000000 0.429687500000 -SH_large_shield.tga 0.703125000000 0.390625000000 0.742187500000 0.429687500000 -spe_beast.tga 0.742187500000 0.390625000000 0.781250000000 0.429687500000 -spe_com.tga 0.781250000000 0.390625000000 0.820312500000 0.429687500000 -spe_inventory.tga 0.820312500000 0.390625000000 0.859375000000 0.429687500000 -spe_labs.tga 0.859375000000 0.390625000000 0.898437500000 0.429687500000 -spe_memory.tga 0.898437500000 0.390625000000 0.937500000000 0.429687500000 -spe_options.tga 0.937500000000 0.390625000000 0.976562500000 0.429687500000 -spe_status.tga 0.468750000000 0.429687500000 0.507812500000 0.468750000000 -stimulating_water.tga 0.507812500000 0.429687500000 0.546875000000 0.468750000000 -tetekitin.tga 0.546875000000 0.429687500000 0.585937500000 0.468750000000 -to_ammo.tga 0.585937500000 0.429687500000 0.625000000000 0.468750000000 -to_armor.tga 0.625000000000 0.429687500000 0.664062500000 0.468750000000 -to_cooking_pot.tga 0.664062500000 0.429687500000 0.703125000000 0.468750000000 -to_fishing_rod.tga 0.703125000000 0.429687500000 0.742187500000 0.468750000000 -to_forage.tga 0.742187500000 0.429687500000 0.781250000000 0.468750000000 -to_hammer.tga 0.781250000000 0.429687500000 0.820312500000 0.468750000000 -to_jewelry_hammer.tga 0.820312500000 0.429687500000 0.859375000000 0.468750000000 -to_jewels.tga 0.859375000000 0.429687500000 0.898437500000 0.468750000000 -to_leathercutter.tga 0.898437500000 0.429687500000 0.937500000000 0.468750000000 -to_melee.tga 0.937500000000 0.429687500000 0.976562500000 0.468750000000 -to_needle.tga 0.000000000000 0.468750000000 0.039062500000 0.507812500000 -to_pestle.tga 0.039062500000 0.468750000000 0.078125000000 0.507812500000 -to_range.tga 0.078125000000 0.468750000000 0.117187500000 0.507812500000 -to_searake.tga 0.117187500000 0.468750000000 0.156250000000 0.507812500000 -to_spade.tga 0.156250000000 0.468750000000 0.195312500000 0.507812500000 -to_stick.tga 0.195312500000 0.468750000000 0.234375000000 0.507812500000 -to_tunneling_knife.tga 0.234375000000 0.468750000000 0.273437500000 0.507812500000 -to_whip.tga 0.273437500000 0.468750000000 0.312500000000 0.507812500000 -to_wrench.tga 0.312500000000 0.468750000000 0.351562500000 0.507812500000 -TP_caravane.tga 0.351562500000 0.468750000000 0.390625000000 0.507812500000 -TP_kami.tga 0.390625000000 0.468750000000 0.429687500000 0.507812500000 -W_AM_logo.tga 0.429687500000 0.468750000000 0.468750000000 0.507812500000 -w_pa_anklet.tga 0.468750000000 0.468750000000 0.507812500000 0.507812500000 -w_pa_bracelet.tga 0.507812500000 0.468750000000 0.546875000000 0.507812500000 -w_pa_diadem.tga 0.546875000000 0.468750000000 0.585937500000 0.507812500000 -w_pa_earring.tga 0.585937500000 0.468750000000 0.625000000000 0.507812500000 -w_pa_pendant.tga 0.625000000000 0.468750000000 0.664062500000 0.507812500000 -w_pa_ring.tga 0.664062500000 0.468750000000 0.703125000000 0.507812500000 -xp_cat_green.tga 0.703125000000 0.468750000000 0.742187500000 0.507812500000 +BK_matis.tga 0.078125000000 0.117187500000 0.117187500000 0.156250000000 +bk_mission.tga 0.117187500000 0.117187500000 0.156250000000 0.156250000000 +bk_mission2.tga 0.156250000000 0.117187500000 0.195312500000 0.156250000000 +BK_outpost.tga 0.195312500000 0.117187500000 0.234375000000 0.156250000000 +BK_primes.tga 0.000000000000 0.156250000000 0.039062500000 0.195312500000 +bk_service.tga 0.039062500000 0.156250000000 0.078125000000 0.195312500000 +bk_training.tga 0.078125000000 0.156250000000 0.117187500000 0.195312500000 +BK_tryker.tga 0.117187500000 0.156250000000 0.156250000000 0.195312500000 +BK_zorai.tga 0.156250000000 0.156250000000 0.195312500000 0.195312500000 +charge.tga 0.195312500000 0.156250000000 0.234375000000 0.195312500000 +clef.tga 0.000000000000 0.195312500000 0.039062500000 0.234375000000 +conso_branche.tga 0.039062500000 0.195312500000 0.078125000000 0.234375000000 +conso_branche_mask.tga 0.078125000000 0.195312500000 0.117187500000 0.234375000000 +conso_fleur.tga 0.117187500000 0.195312500000 0.156250000000 0.234375000000 +conso_fleur_mask.tga 0.156250000000 0.195312500000 0.195312500000 0.234375000000 +conso_grappe.tga 0.195312500000 0.195312500000 0.234375000000 0.234375000000 +conso_nectar.tga 0.242187500000 0.000000000000 0.281250000000 0.039062500000 +conso_nectar_mask.tga 0.281250000000 0.000000000000 0.320312500000 0.039062500000 +construction.tga 0.320312500000 0.000000000000 0.359375000000 0.039062500000 +cristal_ammo.tga 0.359375000000 0.000000000000 0.398437500000 0.039062500000 +cristal_spell.tga 0.398437500000 0.000000000000 0.437500000000 0.039062500000 +ico_haircolor.tga 0.437500000000 0.000000000000 0.476562500000 0.039062500000 +ico_haircut.tga 0.238281250000 0.039062500000 0.277343750000 0.078125000000 +bk_karavan.tga 0.277343750000 0.039062500000 0.316406250000 0.078125000000 +conso_grappe_mask.tga 0.316406250000 0.039062500000 0.355468750000 0.078125000000 +ico_foreuse.tga 0.355468750000 0.039062500000 0.394531250000 0.078125000000 +ico_noix.tga 0.394531250000 0.039062500000 0.433593750000 0.078125000000 +ico_spores.tga 0.433593750000 0.039062500000 0.472656250000 0.078125000000 +mektoub_pack.tga 0.234375000000 0.078125000000 0.273437500000 0.117187500000 +mp_beak.tga 0.273437500000 0.078125000000 0.312500000000 0.117187500000 +mp_fresh_loose_soil.tga 0.312500000000 0.078125000000 0.351562500000 0.117187500000 +mp_lichen.tga 0.351562500000 0.078125000000 0.390625000000 0.117187500000 +mp_sawdust.tga 0.390625000000 0.078125000000 0.429687500000 0.117187500000 +MW_2h_axe.tga 0.429687500000 0.078125000000 0.468750000000 0.117187500000 +PA_bracelet.tga 0.234375000000 0.117187500000 0.273437500000 0.156250000000 +pvp_aura_mask.tga 0.273437500000 0.117187500000 0.312500000000 0.156250000000 +quest_queue.tga 0.312500000000 0.117187500000 0.351562500000 0.156250000000 +rpjobitem_201_b.tga 0.351562500000 0.117187500000 0.390625000000 0.156250000000 +rpjobitem_207_a.tga 0.390625000000 0.117187500000 0.429687500000 0.156250000000 +rpjob_task_elementary.tga 0.429687500000 0.117187500000 0.468750000000 0.156250000000 +spe_options.tga 0.234375000000 0.156250000000 0.273437500000 0.195312500000 +to_range.tga 0.273437500000 0.156250000000 0.312500000000 0.195312500000 +w_pa_anklet.tga 0.312500000000 0.156250000000 0.351562500000 0.195312500000 +ico_task_craft.tga 0.351562500000 0.156250000000 0.390625000000 0.195312500000 +ico_task_done.tga 0.390625000000 0.156250000000 0.429687500000 0.195312500000 +ico_task_failed.tga 0.429687500000 0.156250000000 0.468750000000 0.195312500000 +ico_task_fight.tga 0.234375000000 0.195312500000 0.273437500000 0.234375000000 +ico_task_forage.tga 0.273437500000 0.195312500000 0.312500000000 0.234375000000 +ico_task_generic.tga 0.312500000000 0.195312500000 0.351562500000 0.234375000000 +ico_task_generic_quart.tga 0.351562500000 0.195312500000 0.390625000000 0.234375000000 +ico_task_guild.tga 0.390625000000 0.195312500000 0.429687500000 0.234375000000 +ico_task_rite.tga 0.429687500000 0.195312500000 0.468750000000 0.234375000000 +ico_task_travel.tga 0.000000000000 0.234375000000 0.039062500000 0.273437500000 +ico_tatoo.tga 0.039062500000 0.234375000000 0.078125000000 0.273437500000 +mektoub_steed.tga 0.078125000000 0.234375000000 0.117187500000 0.273437500000 +mg_glove.tga 0.117187500000 0.234375000000 0.156250000000 0.273437500000 +mission_icon_0.tga 0.156250000000 0.234375000000 0.195312500000 0.273437500000 +mission_icon_1.tga 0.195312500000 0.234375000000 0.234375000000 0.273437500000 +mission_icon_2.tga 0.234375000000 0.234375000000 0.273437500000 0.273437500000 +mission_icon_3.tga 0.273437500000 0.234375000000 0.312500000000 0.273437500000 +mp_amber.tga 0.312500000000 0.234375000000 0.351562500000 0.273437500000 +mp_bark.tga 0.351562500000 0.234375000000 0.390625000000 0.273437500000 +mp_batiment_brique.tga 0.390625000000 0.234375000000 0.429687500000 0.273437500000 +mp_batiment_colonne.tga 0.429687500000 0.234375000000 0.468750000000 0.273437500000 +mp_batiment_colonne_justice.tga 0.000000000000 0.273437500000 0.039062500000 0.312500000000 +mp_batiment_comble.tga 0.039062500000 0.273437500000 0.078125000000 0.312500000000 +mp_batiment_noyau_maduk.tga 0.078125000000 0.273437500000 0.117187500000 0.312500000000 +mp_batiment_ornement.tga 0.117187500000 0.273437500000 0.156250000000 0.312500000000 +mp_batiment_revetement.tga 0.156250000000 0.273437500000 0.195312500000 0.312500000000 +mp_batiment_socle.tga 0.195312500000 0.273437500000 0.234375000000 0.312500000000 +mp_batiment_statue.tga 0.234375000000 0.273437500000 0.273437500000 0.312500000000 +mp_blood.tga 0.273437500000 0.273437500000 0.312500000000 0.312500000000 +mp_bone.tga 0.312500000000 0.273437500000 0.351562500000 0.312500000000 +mp_bud.tga 0.351562500000 0.273437500000 0.390625000000 0.312500000000 +mp_buterfly_blue.tga 0.390625000000 0.273437500000 0.429687500000 0.312500000000 +mp_buterfly_cocoon.tga 0.429687500000 0.273437500000 0.468750000000 0.312500000000 +mp_cereal.tga 0.000000000000 0.312500000000 0.039062500000 0.351562500000 +mp_claw.tga 0.039062500000 0.312500000000 0.078125000000 0.351562500000 +mp_dandelion.tga 0.078125000000 0.312500000000 0.117187500000 0.351562500000 +mp_dust.tga 0.117187500000 0.312500000000 0.156250000000 0.351562500000 +mp_egg.tga 0.156250000000 0.312500000000 0.195312500000 0.351562500000 +mp_eyes.tga 0.195312500000 0.312500000000 0.234375000000 0.351562500000 +mp_fang.tga 0.234375000000 0.312500000000 0.273437500000 0.351562500000 +mp_fiber.tga 0.273437500000 0.312500000000 0.312500000000 0.351562500000 +mp_filament.tga 0.312500000000 0.312500000000 0.351562500000 0.351562500000 +mp_firefly_abdomen.tga 0.351562500000 0.312500000000 0.390625000000 0.351562500000 +mp_fish_scale.tga 0.390625000000 0.312500000000 0.429687500000 0.351562500000 +mp_flowers.tga 0.429687500000 0.312500000000 0.468750000000 0.351562500000 +mp_fruit.tga 0.000000000000 0.351562500000 0.039062500000 0.390625000000 +mp_generic.tga 0.039062500000 0.351562500000 0.078125000000 0.390625000000 +mp_generic_colorize.tga 0.078125000000 0.351562500000 0.117187500000 0.390625000000 +mp_gomme.tga 0.117187500000 0.351562500000 0.156250000000 0.390625000000 +mp_goo_residue.tga 0.156250000000 0.351562500000 0.195312500000 0.390625000000 +mp_hairs.tga 0.195312500000 0.351562500000 0.234375000000 0.390625000000 +mp_hoof.tga 0.234375000000 0.351562500000 0.273437500000 0.390625000000 +mp_horn.tga 0.273437500000 0.351562500000 0.312500000000 0.390625000000 +mp_horney.tga 0.312500000000 0.351562500000 0.351562500000 0.390625000000 +mp_insect_fossil.tga 0.351562500000 0.351562500000 0.390625000000 0.390625000000 +mp_kitinshell.tga 0.390625000000 0.351562500000 0.429687500000 0.390625000000 +mp_kitin_flesh.tga 0.429687500000 0.351562500000 0.468750000000 0.390625000000 +mp_kitin_secretion.tga 0.000000000000 0.390625000000 0.039062500000 0.429687500000 +mp_larva.tga 0.039062500000 0.390625000000 0.078125000000 0.429687500000 +mp_leaf.tga 0.078125000000 0.390625000000 0.117187500000 0.429687500000 +mp_leather.tga 0.117187500000 0.390625000000 0.156250000000 0.429687500000 +mp_liane.tga 0.156250000000 0.390625000000 0.195312500000 0.429687500000 +mp_ligament.tga 0.195312500000 0.390625000000 0.234375000000 0.429687500000 +mp_mandible.tga 0.234375000000 0.390625000000 0.273437500000 0.429687500000 +mp_meat.tga 0.273437500000 0.390625000000 0.312500000000 0.429687500000 +mp_moss.tga 0.312500000000 0.390625000000 0.351562500000 0.429687500000 +mp_mushroom.tga 0.351562500000 0.390625000000 0.390625000000 0.429687500000 +mp_nail.tga 0.390625000000 0.390625000000 0.429687500000 0.429687500000 +mp_oil.tga 0.429687500000 0.390625000000 0.468750000000 0.429687500000 +mp_parasite.tga 0.000000000000 0.429687500000 0.039062500000 0.468750000000 +mp_pearl.tga 0.039062500000 0.429687500000 0.078125000000 0.468750000000 +mp_pelvis.tga 0.078125000000 0.429687500000 0.117187500000 0.468750000000 +mp_pigment.tga 0.117187500000 0.429687500000 0.156250000000 0.468750000000 +mp_pistil.tga 0.156250000000 0.429687500000 0.195312500000 0.468750000000 +mp_plant_fossil.tga 0.195312500000 0.429687500000 0.234375000000 0.468750000000 +mp_pollen.tga 0.234375000000 0.429687500000 0.273437500000 0.468750000000 +mp_resin.tga 0.273437500000 0.429687500000 0.312500000000 0.468750000000 +mp_ronce.tga 0.312500000000 0.429687500000 0.351562500000 0.468750000000 +mp_rostrum.tga 0.351562500000 0.429687500000 0.390625000000 0.468750000000 +mp_sap.tga 0.390625000000 0.429687500000 0.429687500000 0.468750000000 +mp_seed.tga 0.429687500000 0.429687500000 0.468750000000 0.468750000000 +mp_shell.tga 0.476562500000 0.000000000000 0.515625000000 0.039062500000 +mp_silk_worm.tga 0.515625000000 0.000000000000 0.554687500000 0.039062500000 +mp_skin.tga 0.554687500000 0.000000000000 0.593750000000 0.039062500000 +mp_skull.tga 0.593750000000 0.000000000000 0.632812500000 0.039062500000 +mp_spiders_web.tga 0.632812500000 0.000000000000 0.671875000000 0.039062500000 +mp_spine.tga 0.671875000000 0.000000000000 0.710937500000 0.039062500000 +mp_stem.tga 0.710937500000 0.000000000000 0.750000000000 0.039062500000 +mp_sting.tga 0.750000000000 0.000000000000 0.789062500000 0.039062500000 +mp_straw.tga 0.789062500000 0.000000000000 0.828125000000 0.039062500000 +mp_suc.tga 0.828125000000 0.000000000000 0.867187500000 0.039062500000 +mp_tail.tga 0.867187500000 0.000000000000 0.906250000000 0.039062500000 +mp_tooth.tga 0.906250000000 0.000000000000 0.945312500000 0.039062500000 +mp_trunk.tga 0.945312500000 0.000000000000 0.984375000000 0.039062500000 +mp_whiskers.tga 0.472656250000 0.039062500000 0.511718750000 0.078125000000 +mp_wing.tga 0.511718750000 0.039062500000 0.550781250000 0.078125000000 +mp_wood.tga 0.550781250000 0.039062500000 0.589843750000 0.078125000000 +mp_wood_node.tga 0.589843750000 0.039062500000 0.628906250000 0.078125000000 +MW_2h_lance.tga 0.628906250000 0.039062500000 0.667968750000 0.078125000000 +MW_2h_mace.tga 0.667968750000 0.039062500000 0.707031250000 0.078125000000 +MW_2h_sword.tga 0.707031250000 0.039062500000 0.746093750000 0.078125000000 +MW_axe.tga 0.746093750000 0.039062500000 0.785156250000 0.078125000000 +MW_dagger.tga 0.785156250000 0.039062500000 0.824218750000 0.078125000000 +MW_lance.tga 0.824218750000 0.039062500000 0.863281250000 0.078125000000 +MW_mace.tga 0.863281250000 0.039062500000 0.902343750000 0.078125000000 +MW_staff.tga 0.902343750000 0.039062500000 0.941406250000 0.078125000000 +MW_sword.tga 0.941406250000 0.039062500000 0.980468750000 0.078125000000 +PA_anklet.tga 0.468750000000 0.078125000000 0.507812500000 0.117187500000 +pvp_boost.tga 0.507812500000 0.078125000000 0.546875000000 0.117187500000 +pvp_boost_mask.tga 0.546875000000 0.078125000000 0.585937500000 0.117187500000 +pw_4.tga 0.585937500000 0.078125000000 0.625000000000 0.117187500000 +pw_5.tga 0.625000000000 0.078125000000 0.664062500000 0.117187500000 +pw_6.tga 0.664062500000 0.078125000000 0.703125000000 0.117187500000 +pw_7.tga 0.703125000000 0.078125000000 0.742187500000 0.117187500000 +PW_heavy.tga 0.742187500000 0.078125000000 0.781250000000 0.117187500000 +PW_light.tga 0.781250000000 0.078125000000 0.820312500000 0.117187500000 +PW_medium.tga 0.820312500000 0.078125000000 0.859375000000 0.117187500000 +quest_coeur.tga 0.859375000000 0.078125000000 0.898437500000 0.117187500000 +quest_foie.tga 0.898437500000 0.078125000000 0.937500000000 0.117187500000 +quest_jeton.tga 0.937500000000 0.078125000000 0.976562500000 0.117187500000 +quest_langue.tga 0.468750000000 0.117187500000 0.507812500000 0.156250000000 +quest_louche.tga 0.507812500000 0.117187500000 0.546875000000 0.156250000000 +quest_oreille.tga 0.546875000000 0.117187500000 0.585937500000 0.156250000000 +quest_patte.tga 0.585937500000 0.117187500000 0.625000000000 0.156250000000 +quest_poils.tga 0.625000000000 0.117187500000 0.664062500000 0.156250000000 +quest_ticket.tga 0.664062500000 0.117187500000 0.703125000000 0.156250000000 +AM_logo.tga 0.703125000000 0.117187500000 0.742187500000 0.156250000000 +AR_armpad.tga 0.742187500000 0.117187500000 0.781250000000 0.156250000000 +ar_armpad_mask.tga 0.781250000000 0.117187500000 0.820312500000 0.156250000000 +requirement.tga 0.820312500000 0.117187500000 0.859375000000 0.156250000000 +rm_f.tga 0.859375000000 0.117187500000 0.898437500000 0.156250000000 +rm_f_upgrade.tga 0.898437500000 0.117187500000 0.937500000000 0.156250000000 +rm_h.tga 0.937500000000 0.117187500000 0.976562500000 0.156250000000 +rm_h_upgrade.tga 0.468750000000 0.156250000000 0.507812500000 0.195312500000 +rm_m.tga 0.507812500000 0.156250000000 0.546875000000 0.195312500000 +rm_m_upgrade.tga 0.546875000000 0.156250000000 0.585937500000 0.195312500000 +rm_r.tga 0.585937500000 0.156250000000 0.625000000000 0.195312500000 +rm_r_upgrade.tga 0.625000000000 0.156250000000 0.664062500000 0.195312500000 +rpjobitem_200_a.tga 0.664062500000 0.156250000000 0.703125000000 0.195312500000 +rpjobitem_200_b.tga 0.703125000000 0.156250000000 0.742187500000 0.195312500000 +rpjobitem_200_c.tga 0.742187500000 0.156250000000 0.781250000000 0.195312500000 +rpjobitem_201_a.tga 0.781250000000 0.156250000000 0.820312500000 0.195312500000 +rpjobitem_201_c.tga 0.820312500000 0.156250000000 0.859375000000 0.195312500000 +rpjobitem_202_a.tga 0.859375000000 0.156250000000 0.898437500000 0.195312500000 +rpjobitem_202_b.tga 0.898437500000 0.156250000000 0.937500000000 0.195312500000 +rpjobitem_202_c.tga 0.937500000000 0.156250000000 0.976562500000 0.195312500000 +rpjobitem_203_a.tga 0.468750000000 0.195312500000 0.507812500000 0.234375000000 +rpjobitem_203_b.tga 0.507812500000 0.195312500000 0.546875000000 0.234375000000 +rpjobitem_203_c.tga 0.546875000000 0.195312500000 0.585937500000 0.234375000000 +rpjobitem_204_a.tga 0.585937500000 0.195312500000 0.625000000000 0.234375000000 +rpjobitem_204_b.tga 0.625000000000 0.195312500000 0.664062500000 0.234375000000 +rpjobitem_204_c.tga 0.664062500000 0.195312500000 0.703125000000 0.234375000000 +rpjobitem_205_a.tga 0.703125000000 0.195312500000 0.742187500000 0.234375000000 +rpjobitem_205_b.tga 0.742187500000 0.195312500000 0.781250000000 0.234375000000 +rpjobitem_205_c.tga 0.781250000000 0.195312500000 0.820312500000 0.234375000000 +rpjobitem_206_a.tga 0.820312500000 0.195312500000 0.859375000000 0.234375000000 +rpjobitem_206_b.tga 0.859375000000 0.195312500000 0.898437500000 0.234375000000 +rpjobitem_206_c.tga 0.898437500000 0.195312500000 0.937500000000 0.234375000000 +rpjobitem_207_b.tga 0.937500000000 0.195312500000 0.976562500000 0.234375000000 +rpjobitem_207_c.tga 0.468750000000 0.234375000000 0.507812500000 0.273437500000 +rpjobitem_certifications.tga 0.507812500000 0.234375000000 0.546875000000 0.273437500000 +rpjob_200.tga 0.546875000000 0.234375000000 0.585937500000 0.273437500000 +rpjob_201.tga 0.585937500000 0.234375000000 0.625000000000 0.273437500000 +rpjob_202.tga 0.625000000000 0.234375000000 0.664062500000 0.273437500000 +rpjob_203.tga 0.664062500000 0.234375000000 0.703125000000 0.273437500000 +rpjob_204.tga 0.703125000000 0.234375000000 0.742187500000 0.273437500000 +rpjob_205.tga 0.742187500000 0.234375000000 0.781250000000 0.273437500000 +rpjob_206.tga 0.781250000000 0.234375000000 0.820312500000 0.273437500000 +rpjob_207.tga 0.820312500000 0.234375000000 0.859375000000 0.273437500000 +rpjob_advanced.tga 0.859375000000 0.234375000000 0.898437500000 0.273437500000 +rpjob_elementary.tga 0.898437500000 0.234375000000 0.937500000000 0.273437500000 +rpjob_roleplay.tga 0.937500000000 0.234375000000 0.976562500000 0.273437500000 +rpjob_task.tga 0.468750000000 0.273437500000 0.507812500000 0.312500000000 +rpjob_task_certificats.tga 0.507812500000 0.273437500000 0.546875000000 0.312500000000 +rpjob_task_convert.tga 0.546875000000 0.273437500000 0.585937500000 0.312500000000 +rpjob_task_generic.tga 0.585937500000 0.273437500000 0.625000000000 0.312500000000 +rpjob_task_upgrade.tga 0.625000000000 0.273437500000 0.664062500000 0.312500000000 +RW_autolaunch.tga 0.664062500000 0.273437500000 0.703125000000 0.312500000000 +RW_bowgun.tga 0.703125000000 0.273437500000 0.742187500000 0.312500000000 +RW_grenade.tga 0.742187500000 0.273437500000 0.781250000000 0.312500000000 +RW_harpoongun.tga 0.781250000000 0.273437500000 0.820312500000 0.312500000000 +RW_launcher.tga 0.820312500000 0.273437500000 0.859375000000 0.312500000000 +RW_pistol.tga 0.859375000000 0.273437500000 0.898437500000 0.312500000000 +RW_pistolarc.tga 0.898437500000 0.273437500000 0.937500000000 0.312500000000 +RW_rifle.tga 0.937500000000 0.273437500000 0.976562500000 0.312500000000 +SH_buckler.tga 0.468750000000 0.312500000000 0.507812500000 0.351562500000 +SH_large_shield.tga 0.507812500000 0.312500000000 0.546875000000 0.351562500000 +spe_beast.tga 0.546875000000 0.312500000000 0.585937500000 0.351562500000 +spe_com.tga 0.585937500000 0.312500000000 0.625000000000 0.351562500000 +spe_inventory.tga 0.625000000000 0.312500000000 0.664062500000 0.351562500000 +spe_labs.tga 0.664062500000 0.312500000000 0.703125000000 0.351562500000 +spe_memory.tga 0.703125000000 0.312500000000 0.742187500000 0.351562500000 +spe_status.tga 0.742187500000 0.312500000000 0.781250000000 0.351562500000 +stimulating_water.tga 0.781250000000 0.312500000000 0.820312500000 0.351562500000 +ico_cataliseur_xp.tga 0.820312500000 0.312500000000 0.859375000000 0.351562500000 +ico_consommable_over.tga 0.859375000000 0.312500000000 0.898437500000 0.351562500000 +ico_fleur_carac_1.tga 0.898437500000 0.312500000000 0.937500000000 0.351562500000 +ico_fleur_carac_1_mask.tga 0.937500000000 0.312500000000 0.976562500000 0.351562500000 +ico_fleur_carac_2.tga 0.468750000000 0.351562500000 0.507812500000 0.390625000000 +ico_fleur_carac_2_mask.tga 0.507812500000 0.351562500000 0.546875000000 0.390625000000 +ico_fleur_carac_3.tga 0.546875000000 0.351562500000 0.585937500000 0.390625000000 +ico_fleur_carac_3_mask.tga 0.585937500000 0.351562500000 0.625000000000 0.390625000000 +ico_mission_art_fyros.tga 0.625000000000 0.351562500000 0.664062500000 0.390625000000 +ico_mission_art_matis.tga 0.664062500000 0.351562500000 0.703125000000 0.390625000000 +ico_mission_art_tryker.tga 0.703125000000 0.351562500000 0.742187500000 0.390625000000 +ico_mission_art_zorai.tga 0.742187500000 0.351562500000 0.781250000000 0.390625000000 +ico_mission_barrel.tga 0.781250000000 0.351562500000 0.820312500000 0.390625000000 +ico_mission_bottle.tga 0.820312500000 0.351562500000 0.859375000000 0.390625000000 +ico_mission_casket.tga 0.859375000000 0.351562500000 0.898437500000 0.390625000000 +ico_mission_medicine.tga 0.898437500000 0.351562500000 0.937500000000 0.390625000000 +ico_mission_message.tga 0.937500000000 0.351562500000 0.976562500000 0.390625000000 +ico_mission_package.tga 0.468750000000 0.390625000000 0.507812500000 0.429687500000 +ico_mission_pot.tga 0.507812500000 0.390625000000 0.546875000000 0.429687500000 +ico_mission_purse.tga 0.546875000000 0.390625000000 0.585937500000 0.429687500000 +ico_racine.tga 0.585937500000 0.390625000000 0.625000000000 0.429687500000 +ge_mission_outpost_townhall.tga 0.625000000000 0.390625000000 0.664062500000 0.429687500000 +ico_amande.tga 0.664062500000 0.390625000000 0.703125000000 0.429687500000 +to_searake.tga 0.703125000000 0.390625000000 0.742187500000 0.429687500000 +to_spade.tga 0.742187500000 0.390625000000 0.781250000000 0.429687500000 +to_stick.tga 0.781250000000 0.390625000000 0.820312500000 0.429687500000 +to_tunneling_knife.tga 0.820312500000 0.390625000000 0.859375000000 0.429687500000 +to_whip.tga 0.859375000000 0.390625000000 0.898437500000 0.429687500000 +to_wrench.tga 0.898437500000 0.390625000000 0.937500000000 0.429687500000 +TP_caravane.tga 0.937500000000 0.390625000000 0.976562500000 0.429687500000 +TP_kami.tga 0.468750000000 0.429687500000 0.507812500000 0.468750000000 +tetekitin.tga 0.507812500000 0.429687500000 0.546875000000 0.468750000000 +to_ammo.tga 0.546875000000 0.429687500000 0.585937500000 0.468750000000 +to_armor.tga 0.585937500000 0.429687500000 0.625000000000 0.468750000000 +to_cooking_pot.tga 0.625000000000 0.429687500000 0.664062500000 0.468750000000 +to_fishing_rod.tga 0.664062500000 0.429687500000 0.703125000000 0.468750000000 +to_forage.tga 0.703125000000 0.429687500000 0.742187500000 0.468750000000 +to_hammer.tga 0.742187500000 0.429687500000 0.781250000000 0.468750000000 +to_jewelry_hammer.tga 0.781250000000 0.429687500000 0.820312500000 0.468750000000 +to_jewels.tga 0.820312500000 0.429687500000 0.859375000000 0.468750000000 +to_leathercutter.tga 0.859375000000 0.429687500000 0.898437500000 0.468750000000 +to_melee.tga 0.898437500000 0.429687500000 0.937500000000 0.468750000000 +to_needle.tga 0.937500000000 0.429687500000 0.976562500000 0.468750000000 +to_pestle.tga 0.000000000000 0.468750000000 0.039062500000 0.507812500000 +ico_tourbe.tga 0.039062500000 0.468750000000 0.078125000000 0.507812500000 +improved_tool.tga 0.078125000000 0.468750000000 0.117187500000 0.507812500000 +item_default.tga 0.117187500000 0.468750000000 0.156250000000 0.507812500000 +item_plan_over.tga 0.156250000000 0.468750000000 0.195312500000 0.507812500000 +lucky_flower.tga 0.195312500000 0.468750000000 0.234375000000 0.507812500000 +W_AM_logo.tga 0.234375000000 0.468750000000 0.273437500000 0.507812500000 +w_pa_bracelet.tga 0.273437500000 0.468750000000 0.312500000000 0.507812500000 +w_pa_diadem.tga 0.312500000000 0.468750000000 0.351562500000 0.507812500000 +w_pa_earring.tga 0.351562500000 0.468750000000 0.390625000000 0.507812500000 +w_pa_pendant.tga 0.390625000000 0.468750000000 0.429687500000 0.507812500000 +w_pa_ring.tga 0.429687500000 0.468750000000 0.468750000000 0.507812500000 +xp_cat_green.tga 0.468750000000 0.468750000000 0.507812500000 0.507812500000 +PA_diadem.tga 0.507812500000 0.468750000000 0.546875000000 0.507812500000 +PA_earring.tga 0.546875000000 0.468750000000 0.585937500000 0.507812500000 +PA_pendant.tga 0.585937500000 0.468750000000 0.625000000000 0.507812500000 +PA_ring.tga 0.625000000000 0.468750000000 0.664062500000 0.507812500000 +protect_amber.tga 0.664062500000 0.468750000000 0.703125000000 0.507812500000 +pvp_aura.tga 0.703125000000 0.468750000000 0.742187500000 0.507812500000 asc_exit.tga 0.742187500000 0.468750000000 0.773437500000 0.500000000000 asc_rolemastercraft.tga 0.773437500000 0.468750000000 0.804687500000 0.500000000000 asc_rolemasterfight.tga 0.804687500000 0.468750000000 0.835937500000 0.500000000000 @@ -324,340 +324,350 @@ asc_rolemasterharvest.tga 0.835937500000 0.468750000000 0.867187500000 0.5000000 asc_rolemastermagic.tga 0.867187500000 0.468750000000 0.898437500000 0.500000000000 asc_unknown.tga 0.898437500000 0.468750000000 0.929687500000 0.500000000000 mail.tga 0.929687500000 0.468750000000 0.960937500000 0.492187500000 -mp_back_curative.tga 0.976562500000 0.078125000000 1.000000000000 0.101562500000 -mp_back_offensive.tga 0.976562500000 0.101562500000 1.000000000000 0.125000000000 -mp_back_selfonly.tga 0.976562500000 0.125000000000 1.000000000000 0.148437500000 -building_state_24x24.tga 0.976562500000 0.148437500000 1.000000000000 0.171875000000 -ico_ammo_bullet.tga 0.976562500000 0.171875000000 1.000000000000 0.195312500000 -ico_ammo_jacket.tga 0.976562500000 0.195312500000 1.000000000000 0.218750000000 -ico_angle.tga 0.976562500000 0.218750000000 1.000000000000 0.242187500000 -ico_anti_magic_shield.tga 0.976562500000 0.242187500000 1.000000000000 0.265625000000 -ico_armor.tga 0.976562500000 0.265625000000 1.000000000000 0.289062500000 -ico_armor_clip.tga 0.976562500000 0.289062500000 1.000000000000 0.312500000000 -ico_armor_heavy.tga 0.976562500000 0.312500000000 1.000000000000 0.335937500000 -ico_armor_kitin.tga 0.976562500000 0.335937500000 1.000000000000 0.359375000000 -ico_armor_light.tga 0.976562500000 0.359375000000 1.000000000000 0.382812500000 -ico_armor_medium.tga 0.976562500000 0.382812500000 1.000000000000 0.406250000000 -ico_armor_penalty.tga 0.976562500000 0.406250000000 1.000000000000 0.429687500000 -ico_armor_shell.tga 0.976562500000 0.429687500000 1.000000000000 0.453125000000 -ico_atys.tga 0.976562500000 0.453125000000 1.000000000000 0.476562500000 -ico_atysian.tga 0.960937500000 0.476562500000 0.984375000000 0.500000000000 -ico_balance_hp.tga 0.929687500000 0.492187500000 0.953125000000 0.515625000000 -ico_barrel.tga 0.742187500000 0.500000000000 0.765625000000 0.523437500000 -ico_bash.tga 0.765625000000 0.500000000000 0.789062500000 0.523437500000 -ico_berserk.tga 0.789062500000 0.500000000000 0.812500000000 0.523437500000 -ico_blade.tga 0.812500000000 0.500000000000 0.835937500000 0.523437500000 -ico_bleeding.tga 0.835937500000 0.500000000000 0.859375000000 0.523437500000 -ico_blind.tga 0.859375000000 0.500000000000 0.882812500000 0.523437500000 -ico_blunt.tga 0.882812500000 0.500000000000 0.906250000000 0.523437500000 -ico_bomb.tga 0.906250000000 0.500000000000 0.929687500000 0.523437500000 -cb_main_nue.tga 0.953125000000 0.500000000000 0.976562500000 0.523437500000 -ico_celestial.tga 0.976562500000 0.500000000000 1.000000000000 0.523437500000 -ico_circular_attack.tga 0.000000000000 0.507812500000 0.023437500000 0.531250000000 -ico_clothes.tga 0.023437500000 0.507812500000 0.046875000000 0.531250000000 -ico_cold.tga 0.046875000000 0.507812500000 0.070312500000 0.531250000000 -ico_concentration.tga 0.070312500000 0.507812500000 0.093750000000 0.531250000000 -BK_matis_brick.tga 0.093750000000 0.507812500000 0.117187500000 0.531250000000 -ico_constitution.tga 0.117187500000 0.507812500000 0.140625000000 0.531250000000 -ico_counterweight.tga 0.140625000000 0.507812500000 0.164062500000 0.531250000000 -ico_craft_buff.tga 0.164062500000 0.507812500000 0.187500000000 0.531250000000 -ico_create_sapload.tga 0.187500000000 0.507812500000 0.210937500000 0.531250000000 -ico_curse.tga 0.210937500000 0.507812500000 0.234375000000 0.531250000000 -ico_debuff.tga 0.234375000000 0.507812500000 0.257812500000 0.531250000000 -ico_debuff_resist.tga 0.257812500000 0.507812500000 0.281250000000 0.531250000000 -ico_debuff_skill.tga 0.281250000000 0.507812500000 0.304687500000 0.531250000000 -ico_desert.tga 0.304687500000 0.507812500000 0.328125000000 0.531250000000 -ico_dexterity.tga 0.328125000000 0.507812500000 0.351562500000 0.531250000000 -ico_disarm.tga 0.351562500000 0.507812500000 0.375000000000 0.531250000000 -ico_dodge.tga 0.375000000000 0.507812500000 0.398437500000 0.531250000000 -ico_dot.tga 0.398437500000 0.507812500000 0.421875000000 0.531250000000 -ico_durability.tga 0.421875000000 0.507812500000 0.445312500000 0.531250000000 -ico_electric.tga 0.445312500000 0.507812500000 0.468750000000 0.531250000000 -ico_explosif.tga 0.468750000000 0.507812500000 0.492187500000 0.531250000000 -ico_extracting.tga 0.492187500000 0.507812500000 0.515625000000 0.531250000000 -ico_fear.tga 0.515625000000 0.507812500000 0.539062500000 0.531250000000 -ico_feint.tga 0.539062500000 0.507812500000 0.562500000000 0.531250000000 -ico_fire.tga 0.562500000000 0.507812500000 0.585937500000 0.531250000000 -ico_firing_pin.tga 0.585937500000 0.507812500000 0.609375000000 0.531250000000 -ch_back.tga 0.609375000000 0.507812500000 0.632812500000 0.531250000000 -BK_generic_brick.tga 0.632812500000 0.507812500000 0.656250000000 0.531250000000 -mp_over_link.tga 0.656250000000 0.507812500000 0.679687500000 0.531250000000 -bk_aura.tga 0.679687500000 0.507812500000 0.703125000000 0.531250000000 -bk_conso.tga 0.703125000000 0.507812500000 0.726562500000 0.531250000000 -bk_outpost_brick.tga 0.929687500000 0.515625000000 0.953125000000 0.539062500000 -bk_power.tga 0.726562500000 0.523437500000 0.750000000000 0.546875000000 -ico_focus.tga 0.750000000000 0.523437500000 0.773437500000 0.546875000000 -ico_forage_buff.tga 0.773437500000 0.523437500000 0.796875000000 0.546875000000 -ico_forbid_item.tga 0.796875000000 0.523437500000 0.820312500000 0.546875000000 -ico_forest.tga 0.820312500000 0.523437500000 0.843750000000 0.546875000000 -2h_over.tga 0.843750000000 0.523437500000 0.867187500000 0.546875000000 -ico_gardening.tga 0.867187500000 0.523437500000 0.890625000000 0.546875000000 -ico_gentle.tga 0.890625000000 0.523437500000 0.914062500000 0.546875000000 -ico_goo.tga 0.953125000000 0.523437500000 0.976562500000 0.546875000000 -ico_gripp.tga 0.976562500000 0.523437500000 1.000000000000 0.546875000000 -1h_over.tga 0.000000000000 0.531250000000 0.023437500000 0.554687500000 -BK_fyros_brick.tga 0.023437500000 0.531250000000 0.046875000000 0.554687500000 -ico_hammer.tga 0.046875000000 0.531250000000 0.070312500000 0.554687500000 -ico_harmful.tga 0.070312500000 0.531250000000 0.093750000000 0.554687500000 -ico_hatred.tga 0.093750000000 0.531250000000 0.117187500000 0.554687500000 -ico_heal.tga 0.117187500000 0.531250000000 0.140625000000 0.554687500000 -ico_hit_rate.tga 0.140625000000 0.531250000000 0.164062500000 0.554687500000 -ico_incapacity.tga 0.164062500000 0.531250000000 0.187500000000 0.554687500000 -ico_intelligence.tga 0.187500000000 0.531250000000 0.210937500000 0.554687500000 -ico_interrupt.tga 0.210937500000 0.531250000000 0.234375000000 0.554687500000 -ico_invulnerability.tga 0.234375000000 0.531250000000 0.257812500000 0.554687500000 -ico_jewel_stone.tga 0.257812500000 0.531250000000 0.281250000000 0.554687500000 -ico_jewel_stone_support.tga 0.281250000000 0.531250000000 0.304687500000 0.554687500000 -ico_jungle.tga 0.304687500000 0.531250000000 0.328125000000 0.554687500000 -ico_lacustre.tga 0.328125000000 0.531250000000 0.351562500000 0.554687500000 -ico_landmark_bonus.tga 0.351562500000 0.531250000000 0.375000000000 0.554687500000 -ico_level.tga 0.375000000000 0.531250000000 0.398437500000 0.554687500000 -ico_lining.tga 0.398437500000 0.531250000000 0.421875000000 0.554687500000 -ico_location.tga 0.421875000000 0.531250000000 0.445312500000 0.554687500000 -ico_madness.tga 0.445312500000 0.531250000000 0.468750000000 0.554687500000 -ico_magic.tga 0.468750000000 0.531250000000 0.492187500000 0.554687500000 -ico_magic_action_buff.tga 0.492187500000 0.531250000000 0.515625000000 0.554687500000 -ico_magic_focus.tga 0.515625000000 0.531250000000 0.539062500000 0.554687500000 -ico_magic_target_buff.tga 0.539062500000 0.531250000000 0.562500000000 0.554687500000 -ico_melee_action_buff.tga 0.562500000000 0.531250000000 0.585937500000 0.554687500000 -ico_melee_target_buff.tga 0.585937500000 0.531250000000 0.609375000000 0.554687500000 -ico_mental.tga 0.609375000000 0.531250000000 0.632812500000 0.554687500000 -no_action.tga 0.632812500000 0.531250000000 0.656250000000 0.554687500000 -op_back.tga 0.656250000000 0.531250000000 0.679687500000 0.554687500000 -op_over_break.tga 0.679687500000 0.531250000000 0.703125000000 0.554687500000 -op_over_less.tga 0.703125000000 0.531250000000 0.726562500000 0.554687500000 -op_over_more.tga 0.914062500000 0.539062500000 0.937500000000 0.562500000000 -ico_metabolism.tga 0.726562500000 0.546875000000 0.750000000000 0.570312500000 -pa_back.tga 0.750000000000 0.546875000000 0.773437500000 0.570312500000 -ico_mezz.tga 0.773437500000 0.546875000000 0.796875000000 0.570312500000 -ico_misfortune.tga 0.796875000000 0.546875000000 0.820312500000 0.570312500000 -BK_magie_noire_brick.tga 0.820312500000 0.546875000000 0.843750000000 0.570312500000 -pa_over_break.tga 0.843750000000 0.546875000000 0.867187500000 0.570312500000 -pa_over_less.tga 0.867187500000 0.546875000000 0.890625000000 0.570312500000 -pa_over_more.tga 0.890625000000 0.546875000000 0.914062500000 0.570312500000 -BK_tryker_brick.tga 0.937500000000 0.546875000000 0.960937500000 0.570312500000 -cp_back.tga 0.960937500000 0.546875000000 0.984375000000 0.570312500000 -cp_over_break.tga 0.000000000000 0.554687500000 0.023437500000 0.578125000000 -pvp_ally_0.tga 0.023437500000 0.554687500000 0.046875000000 0.578125000000 -pvp_ally_1.tga 0.046875000000 0.554687500000 0.070312500000 0.578125000000 -pvp_ally_2.tga 0.070312500000 0.554687500000 0.093750000000 0.578125000000 -pvp_ally_3.tga 0.093750000000 0.554687500000 0.117187500000 0.578125000000 -pvp_ally_4.tga 0.117187500000 0.554687500000 0.140625000000 0.578125000000 -pvp_ally_6.tga 0.140625000000 0.554687500000 0.164062500000 0.578125000000 -pvp_ally_primas.tga 0.164062500000 0.554687500000 0.187500000000 0.578125000000 -pvp_ally_ranger.tga 0.187500000000 0.554687500000 0.210937500000 0.578125000000 -cp_over_less.tga 0.210937500000 0.554687500000 0.234375000000 0.578125000000 -cp_over_more.tga 0.234375000000 0.554687500000 0.257812500000 0.578125000000 -cp_over_opening.tga 0.257812500000 0.554687500000 0.281250000000 0.578125000000 -cp_over_opening_2.tga 0.281250000000 0.554687500000 0.304687500000 0.578125000000 -pvp_enemy_0.tga 0.304687500000 0.554687500000 0.328125000000 0.578125000000 -pvp_enemy_1.tga 0.328125000000 0.554687500000 0.351562500000 0.578125000000 -pvp_enemy_2.tga 0.351562500000 0.554687500000 0.375000000000 0.578125000000 -pvp_enemy_3.tga 0.375000000000 0.554687500000 0.398437500000 0.578125000000 -pvp_enemy_4.tga 0.398437500000 0.554687500000 0.421875000000 0.578125000000 -pvp_enemy_6.tga 0.421875000000 0.554687500000 0.445312500000 0.578125000000 -pvp_enemy_marauder.tga 0.445312500000 0.554687500000 0.468750000000 0.578125000000 -pvp_enemy_trytonist.tga 0.468750000000 0.554687500000 0.492187500000 0.578125000000 -bg_downloader.tga 0.492187500000 0.554687500000 0.515625000000 0.578125000000 -BK_zorai_brick.tga 0.515625000000 0.554687500000 0.539062500000 0.578125000000 -ef_back.tga 0.539062500000 0.554687500000 0.562500000000 0.578125000000 -ef_over_break.tga 0.562500000000 0.554687500000 0.585937500000 0.578125000000 -ico_move.tga 0.585937500000 0.554687500000 0.609375000000 0.578125000000 -ico_multiple_spots.tga 0.609375000000 0.554687500000 0.632812500000 0.578125000000 -ico_multi_fight.tga 0.632812500000 0.554687500000 0.656250000000 0.578125000000 -ef_over_less.tga 0.656250000000 0.554687500000 0.679687500000 0.578125000000 -ico_opening_hit.tga 0.679687500000 0.554687500000 0.703125000000 0.578125000000 -ico_over_autumn.tga 0.703125000000 0.554687500000 0.726562500000 0.578125000000 -ico_over_degenerated.tga 0.914062500000 0.562500000000 0.937500000000 0.585937500000 -ico_over_fauna.tga 0.726562500000 0.570312500000 0.750000000000 0.593750000000 -ico_over_flora.tga 0.750000000000 0.570312500000 0.773437500000 0.593750000000 -ico_over_hit_arms.tga 0.773437500000 0.570312500000 0.796875000000 0.593750000000 -ico_over_hit_chest.tga 0.796875000000 0.570312500000 0.820312500000 0.593750000000 -ico_over_hit_feet.tga 0.820312500000 0.570312500000 0.843750000000 0.593750000000 -ico_over_hit_feet_hands.tga 0.843750000000 0.570312500000 0.867187500000 0.593750000000 -ico_over_hit_feet_head.tga 0.867187500000 0.570312500000 0.890625000000 0.593750000000 -ico_over_hit_feet_x2.tga 0.890625000000 0.570312500000 0.914062500000 0.593750000000 -ico_over_hit_feint_x3.tga 0.937500000000 0.570312500000 0.960937500000 0.593750000000 -ico_over_hit_hands.tga 0.960937500000 0.570312500000 0.984375000000 0.593750000000 -ico_over_hit_hands_chest.tga 0.000000000000 0.578125000000 0.023437500000 0.601562500000 -ico_over_hit_hands_head.tga 0.023437500000 0.578125000000 0.046875000000 0.601562500000 -ico_over_hit_head.tga 0.046875000000 0.578125000000 0.070312500000 0.601562500000 -ico_over_hit_head_x3.tga 0.070312500000 0.578125000000 0.093750000000 0.601562500000 -ico_over_hit_legs.tga 0.093750000000 0.578125000000 0.117187500000 0.601562500000 -ico_over_homin.tga 0.117187500000 0.578125000000 0.140625000000 0.601562500000 -ico_over_kitin.tga 0.140625000000 0.578125000000 0.164062500000 0.601562500000 -ico_over_magic.tga 0.164062500000 0.578125000000 0.187500000000 0.601562500000 -ico_over_melee.tga 0.187500000000 0.578125000000 0.210937500000 0.601562500000 -ico_over_racial.tga 0.210937500000 0.578125000000 0.234375000000 0.601562500000 -ico_over_range.tga 0.234375000000 0.578125000000 0.257812500000 0.601562500000 -ico_over_special.tga 0.257812500000 0.578125000000 0.281250000000 0.601562500000 -ico_over_spring.tga 0.281250000000 0.578125000000 0.304687500000 0.601562500000 -ico_over_summer.tga 0.304687500000 0.578125000000 0.328125000000 0.601562500000 -ico_over_winter.tga 0.328125000000 0.578125000000 0.351562500000 0.601562500000 -ico_parry.tga 0.351562500000 0.578125000000 0.375000000000 0.601562500000 -ico_piercing.tga 0.375000000000 0.578125000000 0.398437500000 0.601562500000 -ico_pointe.tga 0.398437500000 0.578125000000 0.421875000000 0.601562500000 -ico_poison.tga 0.421875000000 0.578125000000 0.445312500000 0.601562500000 -ico_power.tga 0.445312500000 0.578125000000 0.468750000000 0.601562500000 -ico_preservation.tga 0.468750000000 0.578125000000 0.492187500000 0.601562500000 -ico_primal.tga 0.492187500000 0.578125000000 0.515625000000 0.601562500000 -ico_prime_roots.tga 0.515625000000 0.578125000000 0.539062500000 0.601562500000 -ico_private.tga 0.539062500000 0.578125000000 0.562500000000 0.601562500000 -ico_prospecting.tga 0.562500000000 0.578125000000 0.585937500000 0.601562500000 -ico_quality.tga 0.585937500000 0.578125000000 0.609375000000 0.601562500000 -ef_over_more.tga 0.609375000000 0.578125000000 0.632812500000 0.601562500000 -ico_range.tga 0.632812500000 0.578125000000 0.656250000000 0.601562500000 -ico_range_action_buff.tga 0.656250000000 0.578125000000 0.679687500000 0.601562500000 -ico_range_target_buff.tga 0.679687500000 0.578125000000 0.703125000000 0.601562500000 -ico_ricochet.tga 0.703125000000 0.578125000000 0.726562500000 0.601562500000 -ico_root.tga 0.914062500000 0.585937500000 0.937500000000 0.609375000000 -ico_rot.tga 0.726562500000 0.593750000000 0.750000000000 0.617187500000 -ico_safe.tga 0.750000000000 0.593750000000 0.773437500000 0.617187500000 -ico_sap.tga 0.773437500000 0.593750000000 0.796875000000 0.617187500000 -ico_self_damage.tga 0.796875000000 0.593750000000 0.820312500000 0.617187500000 -ico_shaft.tga 0.820312500000 0.593750000000 0.843750000000 0.617187500000 -ico_shielding.tga 0.843750000000 0.593750000000 0.867187500000 0.617187500000 -ico_shield_buff.tga 0.867187500000 0.593750000000 0.890625000000 0.617187500000 -ico_shield_up.tga 0.890625000000 0.593750000000 0.914062500000 0.617187500000 -ico_shockwave.tga 0.937500000000 0.593750000000 0.960937500000 0.617187500000 -ico_sickness.tga 0.960937500000 0.593750000000 0.984375000000 0.617187500000 -ico_slashing.tga 0.000000000000 0.601562500000 0.023437500000 0.625000000000 -ico_slow.tga 0.023437500000 0.601562500000 0.046875000000 0.625000000000 -ico_soft_spot.tga 0.046875000000 0.601562500000 0.070312500000 0.625000000000 -ico_source_time.tga 0.070312500000 0.601562500000 0.093750000000 0.625000000000 -ico_speed.tga 0.093750000000 0.601562500000 0.117187500000 0.625000000000 -ico_speeding_up.tga 0.117187500000 0.601562500000 0.140625000000 0.625000000000 -ico_spell_break.tga 0.140625000000 0.601562500000 0.164062500000 0.625000000000 -fo_back.tga 0.164062500000 0.601562500000 0.187500000000 0.625000000000 -ico_spray.tga 0.187500000000 0.601562500000 0.210937500000 0.625000000000 -ico_spying.tga 0.210937500000 0.601562500000 0.234375000000 0.625000000000 -ico_stamina.tga 0.234375000000 0.601562500000 0.257812500000 0.625000000000 -ico_strength.tga 0.257812500000 0.601562500000 0.281250000000 0.625000000000 -ico_stuffing.tga 0.281250000000 0.601562500000 0.304687500000 0.625000000000 -ico_stunn.tga 0.304687500000 0.601562500000 0.328125000000 0.625000000000 -fo_over.tga 0.328125000000 0.601562500000 0.351562500000 0.625000000000 -fp_ammo.tga 0.351562500000 0.601562500000 0.375000000000 0.625000000000 -fp_armor.tga 0.375000000000 0.601562500000 0.398437500000 0.625000000000 -fp_building.tga 0.398437500000 0.601562500000 0.421875000000 0.625000000000 -fp_jewel.tga 0.421875000000 0.601562500000 0.445312500000 0.625000000000 -fp_melee.tga 0.445312500000 0.601562500000 0.468750000000 0.625000000000 -fp_over.tga 0.468750000000 0.601562500000 0.492187500000 0.625000000000 -fp_range.tga 0.492187500000 0.601562500000 0.515625000000 0.625000000000 -fp_shield.tga 0.515625000000 0.601562500000 0.539062500000 0.625000000000 -fp_tools.tga 0.539062500000 0.601562500000 0.562500000000 0.625000000000 -brick_default.tga 0.562500000000 0.601562500000 0.585937500000 0.625000000000 -ico_taunt.tga 0.585937500000 0.601562500000 0.609375000000 0.625000000000 -tb_action_attack.tga 0.609375000000 0.601562500000 0.632812500000 0.625000000000 -tb_action_config.tga 0.632812500000 0.601562500000 0.656250000000 0.625000000000 -tb_action_disband.tga 0.656250000000 0.601562500000 0.679687500000 0.625000000000 -tb_action_disengage.tga 0.679687500000 0.601562500000 0.703125000000 0.625000000000 -tb_action_extract.tga 0.703125000000 0.601562500000 0.726562500000 0.625000000000 -tb_action_invite.tga 0.914062500000 0.609375000000 0.937500000000 0.632812500000 -tb_action_kick.tga 0.726562500000 0.617187500000 0.750000000000 0.640625000000 -tb_action_move.tga 0.750000000000 0.617187500000 0.773437500000 0.640625000000 -tb_action_run.tga 0.773437500000 0.617187500000 0.796875000000 0.640625000000 -tb_action_sit.tga 0.796875000000 0.617187500000 0.820312500000 0.640625000000 -tb_action_stand.tga 0.820312500000 0.617187500000 0.843750000000 0.640625000000 -tb_action_stop.tga 0.843750000000 0.617187500000 0.867187500000 0.640625000000 -tb_action_talk.tga 0.867187500000 0.617187500000 0.890625000000 0.640625000000 -tb_action_walk.tga 0.890625000000 0.617187500000 0.914062500000 0.640625000000 -tb_animals.tga 0.937500000000 0.617187500000 0.960937500000 0.640625000000 -tb_config.tga 0.960937500000 0.617187500000 0.984375000000 0.640625000000 -tb_connection.tga 0.000000000000 0.625000000000 0.023437500000 0.648437500000 -tb_contacts.tga 0.023437500000 0.625000000000 0.046875000000 0.648437500000 -tb_desk_1.tga 0.046875000000 0.625000000000 0.070312500000 0.648437500000 -tb_desk_2.tga 0.070312500000 0.625000000000 0.093750000000 0.648437500000 -tb_desk_3.tga 0.093750000000 0.625000000000 0.117187500000 0.648437500000 -tb_desk_4.tga 0.117187500000 0.625000000000 0.140625000000 0.648437500000 -tb_faction.tga 0.140625000000 0.625000000000 0.164062500000 0.648437500000 -tb_forum.tga 0.164062500000 0.625000000000 0.187500000000 0.648437500000 -tb_guild.tga 0.187500000000 0.625000000000 0.210937500000 0.648437500000 -TB_help2.tga 0.210937500000 0.625000000000 0.234375000000 0.648437500000 -tb_keys.tga 0.234375000000 0.625000000000 0.257812500000 0.648437500000 -tb_macros.tga 0.257812500000 0.625000000000 0.281250000000 0.648437500000 -tb_mail.tga 0.281250000000 0.625000000000 0.304687500000 0.648437500000 -tb_mode_dodge.tga 0.304687500000 0.625000000000 0.328125000000 0.648437500000 -tb_mode_parry.tga 0.328125000000 0.625000000000 0.351562500000 0.648437500000 -tb_over.tga 0.351562500000 0.625000000000 0.375000000000 0.648437500000 -tb_support.tga 0.375000000000 0.625000000000 0.398437500000 0.648437500000 -tb_team.tga 0.398437500000 0.625000000000 0.421875000000 0.648437500000 -tb_windows.tga 0.421875000000 0.625000000000 0.445312500000 0.648437500000 -ico_time.tga 0.445312500000 0.625000000000 0.468750000000 0.648437500000 -ico_time_bonus.tga 0.468750000000 0.625000000000 0.492187500000 0.648437500000 -ico_absorb_damage.tga 0.492187500000 0.625000000000 0.515625000000 0.648437500000 -ico_trigger.tga 0.515625000000 0.625000000000 0.539062500000 0.648437500000 -ico_umbrella.tga 0.539062500000 0.625000000000 0.562500000000 0.648437500000 -ico_use_enchantement.tga 0.562500000000 0.625000000000 0.585937500000 0.648437500000 -ico_vampire.tga 0.585937500000 0.625000000000 0.609375000000 0.648437500000 -ico_visibility.tga 0.609375000000 0.625000000000 0.632812500000 0.648437500000 -ico_war_cry.tga 0.632812500000 0.625000000000 0.656250000000 0.648437500000 -ico_weight.tga 0.656250000000 0.625000000000 0.679687500000 0.648437500000 -ico_wellbalanced.tga 0.679687500000 0.625000000000 0.703125000000 0.648437500000 -ico_will.tga 0.703125000000 0.625000000000 0.726562500000 0.648437500000 -ico_windding.tga 0.914062500000 0.632812500000 0.937500000000 0.656250000000 -ico_wisdom.tga 0.726562500000 0.640625000000 0.750000000000 0.664062500000 -ico_accurate.tga 0.750000000000 0.640625000000 0.773437500000 0.664062500000 -ico_acid.tga 0.773437500000 0.640625000000 0.796875000000 0.664062500000 -ico_aim.tga 0.796875000000 0.640625000000 0.820312500000 0.664062500000 -ico_aim_bird_wings.tga 0.820312500000 0.640625000000 0.843750000000 0.664062500000 -ico_aim_flying_kitin_abdomen.tga 0.843750000000 0.640625000000 0.867187500000 0.664062500000 -ico_aim_homin_arms.tga 0.867187500000 0.640625000000 0.890625000000 0.664062500000 -ico_aim_homin_chest.tga 0.890625000000 0.640625000000 0.914062500000 0.664062500000 -mf_back.tga 0.937500000000 0.640625000000 0.960937500000 0.664062500000 -us_back_0.tga 0.960937500000 0.640625000000 0.984375000000 0.664062500000 -us_back_1.tga 0.000000000000 0.648437500000 0.023437500000 0.671875000000 -us_back_2.tga 0.023437500000 0.648437500000 0.046875000000 0.671875000000 -us_back_3.tga 0.046875000000 0.648437500000 0.070312500000 0.671875000000 -us_back_4.tga 0.070312500000 0.648437500000 0.093750000000 0.671875000000 -us_back_5.tga 0.093750000000 0.648437500000 0.117187500000 0.671875000000 -us_back_6.tga 0.117187500000 0.648437500000 0.140625000000 0.671875000000 -us_back_7.tga 0.140625000000 0.648437500000 0.164062500000 0.671875000000 -us_back_8.tga 0.164062500000 0.648437500000 0.187500000000 0.671875000000 -us_back_9.tga 0.187500000000 0.648437500000 0.210937500000 0.671875000000 -us_ico_0.tga 0.210937500000 0.648437500000 0.234375000000 0.671875000000 -us_ico_1.tga 0.234375000000 0.648437500000 0.257812500000 0.671875000000 -us_ico_2.tga 0.257812500000 0.648437500000 0.281250000000 0.671875000000 -us_ico_3.tga 0.281250000000 0.648437500000 0.304687500000 0.671875000000 -us_ico_4.tga 0.304687500000 0.648437500000 0.328125000000 0.671875000000 -us_ico_5.tga 0.328125000000 0.648437500000 0.351562500000 0.671875000000 -us_ico_6.tga 0.351562500000 0.648437500000 0.375000000000 0.671875000000 -us_ico_7.tga 0.375000000000 0.648437500000 0.398437500000 0.671875000000 -us_ico_8.tga 0.398437500000 0.648437500000 0.421875000000 0.671875000000 -us_ico_9.tga 0.421875000000 0.648437500000 0.445312500000 0.671875000000 -us_over_0.tga 0.445312500000 0.648437500000 0.468750000000 0.671875000000 -us_over_1.tga 0.468750000000 0.648437500000 0.492187500000 0.671875000000 -us_over_2.tga 0.492187500000 0.648437500000 0.515625000000 0.671875000000 -us_over_3.tga 0.515625000000 0.648437500000 0.539062500000 0.671875000000 -us_over_4.tga 0.539062500000 0.648437500000 0.562500000000 0.671875000000 -mf_over.tga 0.562500000000 0.648437500000 0.585937500000 0.671875000000 -ico_aim_homin_feet.tga 0.585937500000 0.648437500000 0.609375000000 0.671875000000 -ico_aim_homin_feint.tga 0.609375000000 0.648437500000 0.632812500000 0.671875000000 -ico_aim_homin_hands.tga 0.632812500000 0.648437500000 0.656250000000 0.671875000000 -ico_aim_homin_head.tga 0.656250000000 0.648437500000 0.679687500000 0.671875000000 -ico_aim_homin_legs.tga 0.679687500000 0.648437500000 0.703125000000 0.671875000000 -mp3.tga 0.703125000000 0.648437500000 0.726562500000 0.671875000000 -W_slot_shortcut_id0.tga 0.914062500000 0.656250000000 0.937500000000 0.679687500000 -W_slot_shortcut_id1.tga 0.726562500000 0.664062500000 0.750000000000 0.687500000000 -W_slot_shortcut_id2.tga 0.750000000000 0.664062500000 0.773437500000 0.687500000000 -W_slot_shortcut_id3.tga 0.773437500000 0.664062500000 0.796875000000 0.687500000000 -W_slot_shortcut_id4.tga 0.796875000000 0.664062500000 0.820312500000 0.687500000000 -W_slot_shortcut_id5.tga 0.820312500000 0.664062500000 0.843750000000 0.687500000000 -W_slot_shortcut_id6.tga 0.843750000000 0.664062500000 0.867187500000 0.687500000000 -W_slot_shortcut_id7.tga 0.867187500000 0.664062500000 0.890625000000 0.687500000000 -W_slot_shortcut_id8.tga 0.890625000000 0.664062500000 0.914062500000 0.687500000000 -W_slot_shortcut_id9.tga 0.937500000000 0.664062500000 0.960937500000 0.687500000000 -w_slot_shortcut_shift_id0.tga 0.960937500000 0.664062500000 0.984375000000 0.687500000000 -w_slot_shortcut_shift_id1.tga 0.000000000000 0.671875000000 0.023437500000 0.695312500000 -w_slot_shortcut_shift_id2.tga 0.023437500000 0.671875000000 0.046875000000 0.695312500000 -w_slot_shortcut_shift_id3.tga 0.046875000000 0.671875000000 0.070312500000 0.695312500000 -w_slot_shortcut_shift_id4.tga 0.070312500000 0.671875000000 0.093750000000 0.695312500000 -w_slot_shortcut_shift_id5.tga 0.093750000000 0.671875000000 0.117187500000 0.695312500000 -w_slot_shortcut_shift_id6.tga 0.117187500000 0.671875000000 0.140625000000 0.695312500000 -w_slot_shortcut_shift_id7.tga 0.140625000000 0.671875000000 0.164062500000 0.695312500000 -w_slot_shortcut_shift_id8.tga 0.164062500000 0.671875000000 0.187500000000 0.695312500000 -w_slot_shortcut_shift_id9.tga 0.187500000000 0.671875000000 0.210937500000 0.695312500000 -ico_aim_kitin_head.tga 0.210937500000 0.671875000000 0.234375000000 0.695312500000 -ico_source_knowledge.tga 0.234375000000 0.671875000000 0.255859375000 0.695312500000 +ico_taunt.tga 0.976562500000 0.078125000000 1.000000000000 0.101562500000 +BK_generic_brick.tga 0.976562500000 0.101562500000 1.000000000000 0.125000000000 +bk_aura.tga 0.976562500000 0.125000000000 1.000000000000 0.148437500000 +bk_outpost_brick.tga 0.976562500000 0.148437500000 1.000000000000 0.171875000000 +bk_power.tga 0.976562500000 0.171875000000 1.000000000000 0.195312500000 +no_action.tga 0.976562500000 0.195312500000 1.000000000000 0.218750000000 +no_pvp.tga 0.976562500000 0.218750000000 1.000000000000 0.242187500000 +op_back.tga 0.976562500000 0.242187500000 1.000000000000 0.265625000000 +op_over_break.tga 0.976562500000 0.265625000000 1.000000000000 0.289062500000 +op_over_less.tga 0.976562500000 0.289062500000 1.000000000000 0.312500000000 +op_over_more.tga 0.976562500000 0.312500000000 1.000000000000 0.335937500000 +bk_conso.tga 0.976562500000 0.335937500000 1.000000000000 0.359375000000 +pa_back.tga 0.976562500000 0.359375000000 1.000000000000 0.382812500000 +2h_over.tga 0.976562500000 0.382812500000 1.000000000000 0.406250000000 +1h_over.tga 0.976562500000 0.406250000000 1.000000000000 0.429687500000 +pvp_duel.tga 0.976562500000 0.429687500000 1.000000000000 0.453125000000 +pvp_enemy_0.tga 0.976562500000 0.453125000000 1.000000000000 0.476562500000 +pvp_enemy_1.tga 0.960937500000 0.476562500000 0.984375000000 0.500000000000 +pvp_enemy_2.tga 0.929687500000 0.492187500000 0.953125000000 0.515625000000 +pvp_enemy_3.tga 0.742187500000 0.500000000000 0.765625000000 0.523437500000 +pvp_enemy_4.tga 0.765625000000 0.500000000000 0.789062500000 0.523437500000 +pvp_enemy_6.tga 0.789062500000 0.500000000000 0.812500000000 0.523437500000 +pvp_enemy_flag.tga 0.812500000000 0.500000000000 0.835937500000 0.523437500000 +pvp_enemy_marauder.tga 0.835937500000 0.500000000000 0.859375000000 0.523437500000 +pvp_enemy_tag.tga 0.859375000000 0.500000000000 0.882812500000 0.523437500000 +tb_action_attack.tga 0.882812500000 0.500000000000 0.906250000000 0.523437500000 +tb_action_config.tga 0.906250000000 0.500000000000 0.929687500000 0.523437500000 +tb_action_disband.tga 0.953125000000 0.500000000000 0.976562500000 0.523437500000 +tb_action_disengage.tga 0.976562500000 0.500000000000 1.000000000000 0.523437500000 +tb_action_extract.tga 0.000000000000 0.507812500000 0.023437500000 0.531250000000 +tb_action_invite.tga 0.023437500000 0.507812500000 0.046875000000 0.531250000000 +tb_action_kick.tga 0.046875000000 0.507812500000 0.070312500000 0.531250000000 +tb_action_move.tga 0.070312500000 0.507812500000 0.093750000000 0.531250000000 +tb_action_run.tga 0.093750000000 0.507812500000 0.117187500000 0.531250000000 +tb_action_sit.tga 0.117187500000 0.507812500000 0.140625000000 0.531250000000 +tb_action_stand.tga 0.140625000000 0.507812500000 0.164062500000 0.531250000000 +tb_action_stop.tga 0.164062500000 0.507812500000 0.187500000000 0.531250000000 +tb_action_talk.tga 0.187500000000 0.507812500000 0.210937500000 0.531250000000 +tb_action_walk.tga 0.210937500000 0.507812500000 0.234375000000 0.531250000000 +ico_armor_penalty.tga 0.234375000000 0.507812500000 0.257812500000 0.531250000000 +ico_armor_shell.tga 0.257812500000 0.507812500000 0.281250000000 0.531250000000 +ico_atys.tga 0.281250000000 0.507812500000 0.304687500000 0.531250000000 +ico_atysian.tga 0.304687500000 0.507812500000 0.328125000000 0.531250000000 +ico_balance_hp.tga 0.328125000000 0.507812500000 0.351562500000 0.531250000000 +ico_barrel.tga 0.351562500000 0.507812500000 0.375000000000 0.531250000000 +ico_bash.tga 0.375000000000 0.507812500000 0.398437500000 0.531250000000 +ico_berserk.tga 0.398437500000 0.507812500000 0.421875000000 0.531250000000 +ico_blade.tga 0.421875000000 0.507812500000 0.445312500000 0.531250000000 +ico_bleeding.tga 0.445312500000 0.507812500000 0.468750000000 0.531250000000 +ico_blind.tga 0.468750000000 0.507812500000 0.492187500000 0.531250000000 +ico_blunt.tga 0.492187500000 0.507812500000 0.515625000000 0.531250000000 +ico_bomb.tga 0.515625000000 0.507812500000 0.539062500000 0.531250000000 +pvp_enemy_trytonist.tga 0.539062500000 0.507812500000 0.562500000000 0.531250000000 +ico_celestial.tga 0.562500000000 0.507812500000 0.585937500000 0.531250000000 +ico_circular_attack.tga 0.585937500000 0.507812500000 0.609375000000 0.531250000000 +ico_cold.tga 0.609375000000 0.507812500000 0.632812500000 0.531250000000 +ico_concentration.tga 0.632812500000 0.507812500000 0.656250000000 0.531250000000 +pvp_flag.tga 0.656250000000 0.507812500000 0.679687500000 0.531250000000 +ico_constitution.tga 0.679687500000 0.507812500000 0.703125000000 0.531250000000 +ico_counterweight.tga 0.703125000000 0.507812500000 0.726562500000 0.531250000000 +ico_craft_buff.tga 0.929687500000 0.515625000000 0.953125000000 0.539062500000 +ico_create_sapload.tga 0.726562500000 0.523437500000 0.750000000000 0.546875000000 +ico_curse.tga 0.750000000000 0.523437500000 0.773437500000 0.546875000000 +ico_debuff.tga 0.773437500000 0.523437500000 0.796875000000 0.546875000000 +ico_debuff_resist.tga 0.796875000000 0.523437500000 0.820312500000 0.546875000000 +ico_debuff_skill.tga 0.820312500000 0.523437500000 0.843750000000 0.546875000000 +ico_desert.tga 0.843750000000 0.523437500000 0.867187500000 0.546875000000 +ico_dexterity.tga 0.867187500000 0.523437500000 0.890625000000 0.546875000000 +ico_disarm.tga 0.890625000000 0.523437500000 0.914062500000 0.546875000000 +ico_dodge.tga 0.953125000000 0.523437500000 0.976562500000 0.546875000000 +ico_dot.tga 0.976562500000 0.523437500000 1.000000000000 0.546875000000 +ico_electric.tga 0.000000000000 0.531250000000 0.023437500000 0.554687500000 +ico_explosif.tga 0.023437500000 0.531250000000 0.046875000000 0.554687500000 +ico_extracting.tga 0.046875000000 0.531250000000 0.070312500000 0.554687500000 +ico_fear.tga 0.070312500000 0.531250000000 0.093750000000 0.554687500000 +ico_feint.tga 0.093750000000 0.531250000000 0.117187500000 0.554687500000 +ico_fire.tga 0.117187500000 0.531250000000 0.140625000000 0.554687500000 +ico_firing_pin.tga 0.140625000000 0.531250000000 0.164062500000 0.554687500000 +pvp_neutral.tga 0.164062500000 0.531250000000 0.187500000000 0.554687500000 +pvp_tag.tga 0.187500000000 0.531250000000 0.210937500000 0.554687500000 +BK_magie_noire_brick.tga 0.210937500000 0.531250000000 0.234375000000 0.554687500000 +cp_back.tga 0.234375000000 0.531250000000 0.257812500000 0.554687500000 +cp_over_break.tga 0.257812500000 0.531250000000 0.281250000000 0.554687500000 +cp_over_less.tga 0.281250000000 0.531250000000 0.304687500000 0.554687500000 +ico_focus.tga 0.304687500000 0.531250000000 0.328125000000 0.554687500000 +ico_forage_buff.tga 0.328125000000 0.531250000000 0.351562500000 0.554687500000 +ico_forbid_item.tga 0.351562500000 0.531250000000 0.375000000000 0.554687500000 +ico_forest.tga 0.375000000000 0.531250000000 0.398437500000 0.554687500000 +ico_jungle.tga 0.398437500000 0.531250000000 0.421875000000 0.554687500000 +ico_lacustre.tga 0.421875000000 0.531250000000 0.445312500000 0.554687500000 +ico_landmark_bonus.tga 0.445312500000 0.531250000000 0.468750000000 0.554687500000 +ico_level.tga 0.468750000000 0.531250000000 0.492187500000 0.554687500000 +ico_lining.tga 0.492187500000 0.531250000000 0.515625000000 0.554687500000 +ico_location.tga 0.515625000000 0.531250000000 0.539062500000 0.554687500000 +ico_madness.tga 0.539062500000 0.531250000000 0.562500000000 0.554687500000 +ico_magic.tga 0.562500000000 0.531250000000 0.585937500000 0.554687500000 +ico_magic_action_buff.tga 0.585937500000 0.531250000000 0.609375000000 0.554687500000 +ico_magic_focus.tga 0.609375000000 0.531250000000 0.632812500000 0.554687500000 +ico_magic_target_buff.tga 0.632812500000 0.531250000000 0.656250000000 0.554687500000 +ico_melee_action_buff.tga 0.656250000000 0.531250000000 0.679687500000 0.554687500000 +ico_melee_target_buff.tga 0.679687500000 0.531250000000 0.703125000000 0.554687500000 +ico_mental.tga 0.703125000000 0.531250000000 0.726562500000 0.554687500000 +ico_metabolism.tga 0.914062500000 0.539062500000 0.937500000000 0.562500000000 +ico_mezz.tga 0.726562500000 0.546875000000 0.750000000000 0.570312500000 +cp_over_more.tga 0.750000000000 0.546875000000 0.773437500000 0.570312500000 +cp_over_opening.tga 0.773437500000 0.546875000000 0.796875000000 0.570312500000 +tb_animals.tga 0.796875000000 0.546875000000 0.820312500000 0.570312500000 +cp_over_opening_2.tga 0.820312500000 0.546875000000 0.843750000000 0.570312500000 +us_back_9.tga 0.843750000000 0.546875000000 0.867187500000 0.570312500000 +BK_tryker_brick.tga 0.867187500000 0.546875000000 0.890625000000 0.570312500000 +ico_spray.tga 0.890625000000 0.546875000000 0.914062500000 0.570312500000 +ico_spying.tga 0.937500000000 0.546875000000 0.960937500000 0.570312500000 +ico_stamina.tga 0.960937500000 0.546875000000 0.984375000000 0.570312500000 +ico_strength.tga 0.000000000000 0.554687500000 0.023437500000 0.578125000000 +ico_stuffing.tga 0.023437500000 0.554687500000 0.046875000000 0.578125000000 +ico_stunn.tga 0.046875000000 0.554687500000 0.070312500000 0.578125000000 +ico_move.tga 0.070312500000 0.554687500000 0.093750000000 0.578125000000 +ico_multiple_spots.tga 0.093750000000 0.554687500000 0.117187500000 0.578125000000 +ico_multi_fight.tga 0.117187500000 0.554687500000 0.140625000000 0.578125000000 +ico_opening_hit.tga 0.140625000000 0.554687500000 0.164062500000 0.578125000000 +ico_over_autumn.tga 0.164062500000 0.554687500000 0.187500000000 0.578125000000 +ico_over_degenerated.tga 0.187500000000 0.554687500000 0.210937500000 0.578125000000 +ico_over_fauna.tga 0.210937500000 0.554687500000 0.234375000000 0.578125000000 +ico_over_flora.tga 0.234375000000 0.554687500000 0.257812500000 0.578125000000 +ico_over_hit_arms.tga 0.257812500000 0.554687500000 0.281250000000 0.578125000000 +ico_over_hit_chest.tga 0.281250000000 0.554687500000 0.304687500000 0.578125000000 +ico_over_hit_feet.tga 0.304687500000 0.554687500000 0.328125000000 0.578125000000 +ico_over_hit_feet_hands.tga 0.328125000000 0.554687500000 0.351562500000 0.578125000000 +ico_over_hit_feet_head.tga 0.351562500000 0.554687500000 0.375000000000 0.578125000000 +ico_over_hit_feet_x2.tga 0.375000000000 0.554687500000 0.398437500000 0.578125000000 +ico_over_hit_feint_x3.tga 0.398437500000 0.554687500000 0.421875000000 0.578125000000 +ico_over_hit_hands.tga 0.421875000000 0.554687500000 0.445312500000 0.578125000000 +ico_over_hit_hands_chest.tga 0.445312500000 0.554687500000 0.468750000000 0.578125000000 +ico_over_hit_hands_head.tga 0.468750000000 0.554687500000 0.492187500000 0.578125000000 +ico_over_hit_head.tga 0.492187500000 0.554687500000 0.515625000000 0.578125000000 +ico_over_hit_legs.tga 0.515625000000 0.554687500000 0.539062500000 0.578125000000 +ico_over_homin.tga 0.539062500000 0.554687500000 0.562500000000 0.578125000000 +ico_over_kitin.tga 0.562500000000 0.554687500000 0.585937500000 0.578125000000 +ico_over_magic.tga 0.585937500000 0.554687500000 0.609375000000 0.578125000000 +ico_over_melee.tga 0.609375000000 0.554687500000 0.632812500000 0.578125000000 +ico_over_racial.tga 0.632812500000 0.554687500000 0.656250000000 0.578125000000 +ico_over_range.tga 0.656250000000 0.554687500000 0.679687500000 0.578125000000 +ico_over_special.tga 0.679687500000 0.554687500000 0.703125000000 0.578125000000 +ico_over_spring.tga 0.703125000000 0.554687500000 0.726562500000 0.578125000000 +ico_over_summer.tga 0.914062500000 0.562500000000 0.937500000000 0.585937500000 +ico_over_winter.tga 0.726562500000 0.570312500000 0.750000000000 0.593750000000 +ico_parry.tga 0.750000000000 0.570312500000 0.773437500000 0.593750000000 +ico_piercing.tga 0.773437500000 0.570312500000 0.796875000000 0.593750000000 +ico_pointe.tga 0.796875000000 0.570312500000 0.820312500000 0.593750000000 +ico_poison.tga 0.820312500000 0.570312500000 0.843750000000 0.593750000000 +ico_power.tga 0.843750000000 0.570312500000 0.867187500000 0.593750000000 +ico_preservation.tga 0.867187500000 0.570312500000 0.890625000000 0.593750000000 +ico_prime_roots.tga 0.890625000000 0.570312500000 0.914062500000 0.593750000000 +ico_private.tga 0.937500000000 0.570312500000 0.960937500000 0.593750000000 +ico_prospecting.tga 0.960937500000 0.570312500000 0.984375000000 0.593750000000 +ico_quality.tga 0.000000000000 0.578125000000 0.023437500000 0.601562500000 +BK_fyros_brick.tga 0.023437500000 0.578125000000 0.046875000000 0.601562500000 +ico_range.tga 0.046875000000 0.578125000000 0.070312500000 0.601562500000 +ico_range_action_buff.tga 0.070312500000 0.578125000000 0.093750000000 0.601562500000 +ico_range_target_buff.tga 0.093750000000 0.578125000000 0.117187500000 0.601562500000 +ico_ricochet.tga 0.117187500000 0.578125000000 0.140625000000 0.601562500000 +ico_root.tga 0.140625000000 0.578125000000 0.164062500000 0.601562500000 +ico_rot.tga 0.164062500000 0.578125000000 0.187500000000 0.601562500000 +ico_safe.tga 0.187500000000 0.578125000000 0.210937500000 0.601562500000 +ico_sap.tga 0.210937500000 0.578125000000 0.234375000000 0.601562500000 +ico_self_damage.tga 0.234375000000 0.578125000000 0.257812500000 0.601562500000 +ico_shaft.tga 0.257812500000 0.578125000000 0.281250000000 0.601562500000 +ico_shielding.tga 0.281250000000 0.578125000000 0.304687500000 0.601562500000 +ico_shield_buff.tga 0.304687500000 0.578125000000 0.328125000000 0.601562500000 +ico_shield_up.tga 0.328125000000 0.578125000000 0.351562500000 0.601562500000 +ico_shockwave.tga 0.351562500000 0.578125000000 0.375000000000 0.601562500000 +ico_sickness.tga 0.375000000000 0.578125000000 0.398437500000 0.601562500000 +ico_slashing.tga 0.398437500000 0.578125000000 0.421875000000 0.601562500000 +ico_slow.tga 0.421875000000 0.578125000000 0.445312500000 0.601562500000 +ico_soft_spot.tga 0.445312500000 0.578125000000 0.468750000000 0.601562500000 +ico_source_time.tga 0.468750000000 0.578125000000 0.492187500000 0.601562500000 +ico_speed.tga 0.492187500000 0.578125000000 0.515625000000 0.601562500000 +ico_speeding_up.tga 0.515625000000 0.578125000000 0.539062500000 0.601562500000 +ico_spell_break.tga 0.539062500000 0.578125000000 0.562500000000 0.601562500000 +fp_armor.tga 0.562500000000 0.578125000000 0.585937500000 0.601562500000 +fp_building.tga 0.585937500000 0.578125000000 0.609375000000 0.601562500000 +fp_jewel.tga 0.609375000000 0.578125000000 0.632812500000 0.601562500000 +fp_melee.tga 0.632812500000 0.578125000000 0.656250000000 0.601562500000 +fp_over.tga 0.656250000000 0.578125000000 0.679687500000 0.601562500000 +fp_range.tga 0.679687500000 0.578125000000 0.703125000000 0.601562500000 +fp_shield.tga 0.703125000000 0.578125000000 0.726562500000 0.601562500000 +fp_tools.tga 0.914062500000 0.585937500000 0.937500000000 0.609375000000 +ef_back.tga 0.726562500000 0.593750000000 0.750000000000 0.617187500000 +ico_absorb_damage.tga 0.750000000000 0.593750000000 0.773437500000 0.617187500000 +ico_accurate.tga 0.773437500000 0.593750000000 0.796875000000 0.617187500000 +ico_acid.tga 0.796875000000 0.593750000000 0.820312500000 0.617187500000 +ico_aim.tga 0.820312500000 0.593750000000 0.843750000000 0.617187500000 +ico_aim_bird_wings.tga 0.843750000000 0.593750000000 0.867187500000 0.617187500000 +ico_aim_flying_kitin_abdomen.tga 0.867187500000 0.593750000000 0.890625000000 0.617187500000 +ico_aim_homin_arms.tga 0.890625000000 0.593750000000 0.914062500000 0.617187500000 +ico_aim_homin_chest.tga 0.937500000000 0.593750000000 0.960937500000 0.617187500000 +ico_aim_homin_feet.tga 0.960937500000 0.593750000000 0.984375000000 0.617187500000 +ico_aim_homin_feint.tga 0.000000000000 0.601562500000 0.023437500000 0.625000000000 +ico_aim_homin_hands.tga 0.023437500000 0.601562500000 0.046875000000 0.625000000000 +ico_aim_homin_head.tga 0.046875000000 0.601562500000 0.070312500000 0.625000000000 +ico_aim_homin_legs.tga 0.070312500000 0.601562500000 0.093750000000 0.625000000000 +ico_aim_kitin_head.tga 0.093750000000 0.601562500000 0.117187500000 0.625000000000 +ef_over_break.tga 0.117187500000 0.601562500000 0.140625000000 0.625000000000 +ico_ammo_bullet.tga 0.140625000000 0.601562500000 0.164062500000 0.625000000000 +ico_ammo_jacket.tga 0.164062500000 0.601562500000 0.187500000000 0.625000000000 +ico_angle.tga 0.187500000000 0.601562500000 0.210937500000 0.625000000000 +ico_anti_magic_shield.tga 0.210937500000 0.601562500000 0.234375000000 0.625000000000 +ico_armor.tga 0.234375000000 0.601562500000 0.257812500000 0.625000000000 +ico_armor_clip.tga 0.257812500000 0.601562500000 0.281250000000 0.625000000000 +ico_armor_heavy.tga 0.281250000000 0.601562500000 0.304687500000 0.625000000000 +ico_armor_kitin.tga 0.304687500000 0.601562500000 0.328125000000 0.625000000000 +ico_armor_light.tga 0.328125000000 0.601562500000 0.351562500000 0.625000000000 +ef_over_less.tga 0.351562500000 0.601562500000 0.375000000000 0.625000000000 +ef_over_more.tga 0.375000000000 0.601562500000 0.398437500000 0.625000000000 +fo_back.tga 0.398437500000 0.601562500000 0.421875000000 0.625000000000 +fo_over.tga 0.421875000000 0.601562500000 0.445312500000 0.625000000000 +ico_gardening.tga 0.445312500000 0.601562500000 0.468750000000 0.625000000000 +ico_gentle.tga 0.468750000000 0.601562500000 0.492187500000 0.625000000000 +mp_over_link.tga 0.492187500000 0.601562500000 0.515625000000 0.625000000000 +ico_goo.tga 0.515625000000 0.601562500000 0.539062500000 0.625000000000 +us_back_0.tga 0.539062500000 0.601562500000 0.562500000000 0.625000000000 +us_back_1.tga 0.562500000000 0.601562500000 0.585937500000 0.625000000000 +us_back_2.tga 0.585937500000 0.601562500000 0.609375000000 0.625000000000 +us_back_3.tga 0.609375000000 0.601562500000 0.632812500000 0.625000000000 +us_back_4.tga 0.632812500000 0.601562500000 0.656250000000 0.625000000000 +us_back_5.tga 0.656250000000 0.601562500000 0.679687500000 0.625000000000 +us_back_6.tga 0.679687500000 0.601562500000 0.703125000000 0.625000000000 +us_back_7.tga 0.703125000000 0.601562500000 0.726562500000 0.625000000000 +us_back_8.tga 0.914062500000 0.609375000000 0.937500000000 0.632812500000 +tb_config.tga 0.726562500000 0.617187500000 0.750000000000 0.640625000000 +tb_connection.tga 0.750000000000 0.617187500000 0.773437500000 0.640625000000 +tb_contacts.tga 0.773437500000 0.617187500000 0.796875000000 0.640625000000 +tb_desk_1.tga 0.796875000000 0.617187500000 0.820312500000 0.640625000000 +tb_desk_2.tga 0.820312500000 0.617187500000 0.843750000000 0.640625000000 +tb_desk_3.tga 0.843750000000 0.617187500000 0.867187500000 0.640625000000 +tb_desk_4.tga 0.867187500000 0.617187500000 0.890625000000 0.640625000000 +tb_faction.tga 0.890625000000 0.617187500000 0.914062500000 0.640625000000 +tb_forum.tga 0.937500000000 0.617187500000 0.960937500000 0.640625000000 +tb_guild.tga 0.960937500000 0.617187500000 0.984375000000 0.640625000000 +TB_help2.tga 0.000000000000 0.625000000000 0.023437500000 0.648437500000 +tb_keys.tga 0.023437500000 0.625000000000 0.046875000000 0.648437500000 +tb_macros.tga 0.046875000000 0.625000000000 0.070312500000 0.648437500000 +tb_mail.tga 0.070312500000 0.625000000000 0.093750000000 0.648437500000 +tb_mode_dodge.tga 0.093750000000 0.625000000000 0.117187500000 0.648437500000 +tb_mode_parry.tga 0.117187500000 0.625000000000 0.140625000000 0.648437500000 +tb_over.tga 0.140625000000 0.625000000000 0.164062500000 0.648437500000 +tb_support.tga 0.164062500000 0.625000000000 0.187500000000 0.648437500000 +tb_team.tga 0.187500000000 0.625000000000 0.210937500000 0.648437500000 +tb_windows.tga 0.210937500000 0.625000000000 0.234375000000 0.648437500000 +ico_gripp.tga 0.234375000000 0.625000000000 0.257812500000 0.648437500000 +BK_zorai_brick.tga 0.257812500000 0.625000000000 0.281250000000 0.648437500000 +mf_back.tga 0.281250000000 0.625000000000 0.304687500000 0.648437500000 +mf_over.tga 0.304687500000 0.625000000000 0.328125000000 0.648437500000 +brick_default.tga 0.328125000000 0.625000000000 0.351562500000 0.648437500000 +ico_hammer.tga 0.351562500000 0.625000000000 0.375000000000 0.648437500000 +ico_harmful.tga 0.375000000000 0.625000000000 0.398437500000 0.648437500000 +ico_hatred.tga 0.398437500000 0.625000000000 0.421875000000 0.648437500000 +ico_heal.tga 0.421875000000 0.625000000000 0.445312500000 0.648437500000 +mp3.tga 0.445312500000 0.625000000000 0.468750000000 0.648437500000 +ico_hit_rate.tga 0.468750000000 0.625000000000 0.492187500000 0.648437500000 +mp_back_curative.tga 0.492187500000 0.625000000000 0.515625000000 0.648437500000 +mp_back_offensive.tga 0.515625000000 0.625000000000 0.539062500000 0.648437500000 +ico_time.tga 0.539062500000 0.625000000000 0.562500000000 0.648437500000 +ico_time_bonus.tga 0.562500000000 0.625000000000 0.585937500000 0.648437500000 +mp_back_selfonly.tga 0.585937500000 0.625000000000 0.609375000000 0.648437500000 +ico_trigger.tga 0.609375000000 0.625000000000 0.632812500000 0.648437500000 +ico_umbrella.tga 0.632812500000 0.625000000000 0.656250000000 0.648437500000 +ico_use_enchantement.tga 0.656250000000 0.625000000000 0.679687500000 0.648437500000 +ico_vampire.tga 0.679687500000 0.625000000000 0.703125000000 0.648437500000 +ico_visibility.tga 0.703125000000 0.625000000000 0.726562500000 0.648437500000 +ico_war_cry.tga 0.914062500000 0.632812500000 0.937500000000 0.656250000000 +ico_weight.tga 0.726562500000 0.640625000000 0.750000000000 0.664062500000 +ico_wellbalanced.tga 0.750000000000 0.640625000000 0.773437500000 0.664062500000 +ico_will.tga 0.773437500000 0.640625000000 0.796875000000 0.664062500000 +ico_windding.tga 0.796875000000 0.640625000000 0.820312500000 0.664062500000 +ico_wisdom.tga 0.820312500000 0.640625000000 0.843750000000 0.664062500000 +ico_incapacity.tga 0.843750000000 0.640625000000 0.867187500000 0.664062500000 +ico_intelligence.tga 0.867187500000 0.640625000000 0.890625000000 0.664062500000 +ico_interrupt.tga 0.890625000000 0.640625000000 0.914062500000 0.664062500000 +ico_invulnerability.tga 0.937500000000 0.640625000000 0.960937500000 0.664062500000 +ico_jewel_stone.tga 0.960937500000 0.640625000000 0.984375000000 0.664062500000 +us_ico_0.tga 0.000000000000 0.648437500000 0.023437500000 0.671875000000 +us_ico_1.tga 0.023437500000 0.648437500000 0.046875000000 0.671875000000 +us_ico_2.tga 0.046875000000 0.648437500000 0.070312500000 0.671875000000 +us_ico_3.tga 0.070312500000 0.648437500000 0.093750000000 0.671875000000 +us_ico_4.tga 0.093750000000 0.648437500000 0.117187500000 0.671875000000 +us_ico_5.tga 0.117187500000 0.648437500000 0.140625000000 0.671875000000 +us_ico_6.tga 0.140625000000 0.648437500000 0.164062500000 0.671875000000 +us_ico_7.tga 0.164062500000 0.648437500000 0.187500000000 0.671875000000 +us_ico_8.tga 0.187500000000 0.648437500000 0.210937500000 0.671875000000 +us_ico_9.tga 0.210937500000 0.648437500000 0.234375000000 0.671875000000 +us_over_0.tga 0.234375000000 0.648437500000 0.257812500000 0.671875000000 +us_over_1.tga 0.257812500000 0.648437500000 0.281250000000 0.671875000000 +us_over_2.tga 0.281250000000 0.648437500000 0.304687500000 0.671875000000 +us_over_3.tga 0.304687500000 0.648437500000 0.328125000000 0.671875000000 +us_over_4.tga 0.328125000000 0.648437500000 0.351562500000 0.671875000000 +building_state_24x24.tga 0.351562500000 0.648437500000 0.375000000000 0.671875000000 +cb_main_nue.tga 0.375000000000 0.648437500000 0.398437500000 0.671875000000 +fp_ammo.tga 0.398437500000 0.648437500000 0.421875000000 0.671875000000 +ico_armor_medium.tga 0.421875000000 0.648437500000 0.445312500000 0.671875000000 +ico_clothes.tga 0.445312500000 0.648437500000 0.468750000000 0.671875000000 +ico_durability.tga 0.468750000000 0.648437500000 0.492187500000 0.671875000000 +W_slot_shortcut_id0.tga 0.492187500000 0.648437500000 0.515625000000 0.671875000000 +W_slot_shortcut_id1.tga 0.515625000000 0.648437500000 0.539062500000 0.671875000000 +W_slot_shortcut_id2.tga 0.539062500000 0.648437500000 0.562500000000 0.671875000000 +W_slot_shortcut_id3.tga 0.562500000000 0.648437500000 0.585937500000 0.671875000000 +W_slot_shortcut_id4.tga 0.585937500000 0.648437500000 0.609375000000 0.671875000000 +W_slot_shortcut_id5.tga 0.609375000000 0.648437500000 0.632812500000 0.671875000000 +W_slot_shortcut_id6.tga 0.632812500000 0.648437500000 0.656250000000 0.671875000000 +W_slot_shortcut_id7.tga 0.656250000000 0.648437500000 0.679687500000 0.671875000000 +W_slot_shortcut_id8.tga 0.679687500000 0.648437500000 0.703125000000 0.671875000000 +W_slot_shortcut_id9.tga 0.703125000000 0.648437500000 0.726562500000 0.671875000000 +w_slot_shortcut_shift_id0.tga 0.914062500000 0.656250000000 0.937500000000 0.679687500000 +w_slot_shortcut_shift_id1.tga 0.726562500000 0.664062500000 0.750000000000 0.687500000000 +w_slot_shortcut_shift_id2.tga 0.750000000000 0.664062500000 0.773437500000 0.687500000000 +w_slot_shortcut_shift_id3.tga 0.773437500000 0.664062500000 0.796875000000 0.687500000000 +w_slot_shortcut_shift_id4.tga 0.796875000000 0.664062500000 0.820312500000 0.687500000000 +w_slot_shortcut_shift_id5.tga 0.820312500000 0.664062500000 0.843750000000 0.687500000000 +w_slot_shortcut_shift_id6.tga 0.843750000000 0.664062500000 0.867187500000 0.687500000000 +w_slot_shortcut_shift_id7.tga 0.867187500000 0.664062500000 0.890625000000 0.687500000000 +w_slot_shortcut_shift_id8.tga 0.890625000000 0.664062500000 0.914062500000 0.687500000000 +w_slot_shortcut_shift_id9.tga 0.937500000000 0.664062500000 0.960937500000 0.687500000000 +BK_matis_brick.tga 0.960937500000 0.664062500000 0.984375000000 0.687500000000 +ico_jewel_stone_support.tga 0.000000000000 0.671875000000 0.023437500000 0.695312500000 +ico_misfortune.tga 0.023437500000 0.671875000000 0.046875000000 0.695312500000 +pa_over_break.tga 0.046875000000 0.671875000000 0.070312500000 0.695312500000 +pa_over_less.tga 0.070312500000 0.671875000000 0.093750000000 0.695312500000 +pa_over_more.tga 0.093750000000 0.671875000000 0.117187500000 0.695312500000 +ch_back.tga 0.117187500000 0.671875000000 0.140625000000 0.695312500000 +ico_over_hit_head_x3.tga 0.140625000000 0.671875000000 0.164062500000 0.695312500000 +ico_primal.tga 0.164062500000 0.671875000000 0.187500000000 0.695312500000 +pvp_ally_0.tga 0.187500000000 0.671875000000 0.210937500000 0.695312500000 +pvp_ally_1.tga 0.210937500000 0.671875000000 0.234375000000 0.695312500000 +pvp_ally_2.tga 0.234375000000 0.671875000000 0.257812500000 0.695312500000 +pvp_ally_3.tga 0.257812500000 0.671875000000 0.281250000000 0.695312500000 +pvp_ally_4.tga 0.281250000000 0.671875000000 0.304687500000 0.695312500000 +pvp_ally_6.tga 0.304687500000 0.671875000000 0.328125000000 0.695312500000 +pvp_ally_flag.tga 0.328125000000 0.671875000000 0.351562500000 0.695312500000 +pvp_ally_primas.tga 0.351562500000 0.671875000000 0.375000000000 0.695312500000 +pvp_ally_ranger.tga 0.375000000000 0.671875000000 0.398437500000 0.695312500000 +pvp_ally_tag.tga 0.398437500000 0.671875000000 0.421875000000 0.695312500000 +bg_downloader.tga 0.421875000000 0.671875000000 0.445312500000 0.695312500000 +ico_source_knowledge.tga 0.445312500000 0.671875000000 0.466796875000 0.695312500000 +filter_tp.tga 0.468750000000 0.671875000000 0.492187500000 0.687500000000 small_task_done.tga 0.984375000000 0.000000000000 1.000000000000 0.015625000000 small_task_failed.tga 0.984375000000 0.015625000000 1.000000000000 0.031250000000 small_task_fight.tga 0.984375000000 0.031250000000 1.000000000000 0.046875000000 @@ -669,6 +679,6 @@ small_task_travel.tga 0.914062500000 0.523437500000 0.929687500000 0.53906250000 small_task_craft.tga 0.984375000000 0.546875000000 1.000000000000 0.562500000000 num_slash.tga 0.984375000000 0.562500000000 0.996093750000 0.576171875000 W_leader.tga 0.984375000000 0.578125000000 0.997070312500 0.589843750000 -tb_mode.tga 0.984375000000 0.589843750000 0.996093750000 0.601562500000 -profile.tga 0.984375000000 0.601562500000 0.996093750000 0.613281250000 -w_major.tga 0.984375000000 0.613281250000 0.996093750000 0.625000000000 +w_major.tga 0.984375000000 0.589843750000 0.996093750000 0.601562500000 +tb_mode.tga 0.984375000000 0.601562500000 0.996093750000 0.613281250000 +profile.tga 0.984375000000 0.613281250000 0.996093750000 0.625000000000 diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/commands.xml b/code/ryzom/client/data/gamedev/interfaces_v3/commands.xml index ca013f242..f0455028a 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/commands.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/commands.xml @@ -78,9 +78,18 @@ - + + + + + + + + + + diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/config.xml b/code/ryzom/client/data/gamedev/interfaces_v3/config.xml index 1d593ef06..9fb0dd958 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/config.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/config.xml @@ -258,6 +258,9 @@ + @@ -291,6 +294,9 @@ + @@ -327,6 +333,9 @@ + @@ -2797,6 +2806,9 @@ This MUST follow the Enum MISSION_DESC::TIconId + - + + + + + + + + @@ -3045,6 +3081,9 @@ This MUST follow the Enum MISSION_DESC::TIconId + @@ -3066,6 +3105,9 @@ This MUST follow the Enum MISSION_DESC::TIconId + @@ -3087,6 +3129,9 @@ This MUST follow the Enum MISSION_DESC::TIconId + @@ -3108,6 +3153,9 @@ This MUST follow the Enum MISSION_DESC::TIconId + @@ -3129,6 +3177,9 @@ This MUST follow the Enum MISSION_DESC::TIconId + @@ -3151,6 +3202,9 @@ This MUST follow the Enum MISSION_DESC::TIconId + @@ -3173,6 +3227,9 @@ This MUST follow the Enum MISSION_DESC::TIconId + + + diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/encyclopedia.xml b/code/ryzom/client/data/gamedev/interfaces_v3/encyclopedia.xml index b2db7ab26..30f2c34a0 100644 --- a/code/ryzom/client/data/gamedev/interfaces_v3/encyclopedia.xml +++ b/code/ryzom/client/data/gamedev/interfaces_v3/encyclopedia.xml @@ -11,7 +11,7 @@ -