This commit is contained in:
rti 2010-10-18 22:34:09 +02:00
commit 254fb2ce97
151 changed files with 3585 additions and 1116 deletions

View file

@ -260,14 +260,14 @@ IF(WIN32)
ENDIF(NOT CMAKE_BUILD_TYPE STREQUAL "Release")
# Install CEGUI and its dependencies.
IF(WITH_CEGUI)
IF(WITH_NEL_CEGUI)
INSTALL(FILES "${CEGUI_LIB_DIR}/CEGUIBase.dll" DESTINATION bin)
INSTALL(FILES "${CEGUI_LIB_DIR}/CEGUIDevilImageCodec.dll" DESTINATION bin)
INSTALL(FILES "${CEGUI_LIB_DIR}/CEGUIExpatParser.dll" DESTINATION bin)
INSTALL(FILES "${CEGUI_LIB_DIR}/CEGUIFalagardWRBase.dll" DESTINATION bin)
INSTALL(FILES "${CEGUI_LIB_DIR}/Devil.dll" DESTINATION bin)
INSTALL(FILES "${CEGUI_LIB_DIR}/ILU.dll" DESTINATION bin)
ENDIF(WITH_CEGUI)
ENDIF(WITH_NEL_CEGUI)
# Only the tools require MFC.
IF(WITH_TOOLS)

View file

@ -42,6 +42,7 @@ MACRO(NL_DEFAULT_PROPS name label)
# Set versions only if target is a shared library
SET_TARGET_PROPERTIES(${name} PROPERTIES
VERSION ${NL_VERSION} SOVERSION ${NL_VERSION_MAJOR}
INSTALL_NAME_DIR ${NL_LIB_PREFIX}
PROJECT_LABEL ${label})
ELSE(${type} STREQUAL SHARED_LIBRARY)
SET_TARGET_PROPERTIES(${name} PROPERTIES
@ -288,7 +289,7 @@ MACRO(NL_SETUP_BUILD)
# without inlining it's unusable, use custom optimizations again
SET(MIN_OPTIMIZATIONS "/Ob1")
SET(PLATFORM_CFLAGS "/D_CRT_SECURE_NO_WARNINGS /DWIN32 /D_WINDOWS /W3 /Zi")
SET(PLATFORM_CFLAGS "/D_CRT_SECURE_NO_WARNINGS /DWIN32 /D_WINDOWS /W3 /Zi /Zm1000")
IF(WITH_STLPORT)
# deactivate all global include paths

View file

@ -32,9 +32,9 @@ IF(WITH_3D)
ENDIF(NOT WIN32)
ENDIF(WITH_DRIVER_OPENGL)
IF(WITH_CEGUI)
IF(WITH_NEL_CEGUI)
FIND_PACKAGE(CEGUI)
ENDIF(WITH_CEGUI)
ENDIF(WITH_NEL_CEGUI)
ENDIF(WITH_3D)

View file

@ -558,6 +558,12 @@ public:
/// Swap the back and front buffers.
virtual bool swapBuffers(void)=0;
/// Copy a string to system clipboard.
virtual bool copyTextToClipboard(const ucstring &text) =0;
/// Paste a string from system clipboard.
virtual bool pasteTextFromClipboard(ucstring &text) =0;
/** set the number of VBL wait when a swapBuffers() is issued. 0 means no synchronisation to the VBL
* Default is 1. Values >1 may be clamped to 1 by the driver.
*/

View file

@ -535,6 +535,11 @@ public:
virtual void deleteWaterEnvMap(UWaterEnvMap *map);
// @}
// Copy a string to system clipboard.
virtual bool copyTextToClipboard(const ucstring &text);
// Paste a string from system clipboard.
virtual bool pasteTextFromClipboard(ucstring &text);
virtual uint64 getSwapBufferCounter();

View file

@ -816,6 +816,15 @@ public:
virtual uint64 getSwapBufferCounter() = 0;
/// \name Clipboard management
// @{
// Copy a string to system clipboard.
virtual bool copyTextToClipboard(const ucstring &text) =0;
// Paste a string from system clipboard.
virtual bool pasteTextFromClipboard(ucstring &text) =0;
// @}
public:
/**

View file

@ -28,6 +28,6 @@ IF(WITH_PACS)
SUBDIRS(pacs)
ENDIF(WITH_PACS)
IF(WITH_CEGUI)
IF(WITH_NEL_CEGUI)
SUBDIRS(cegui)
ENDIF(WITH_CEGUI)
ENDIF(WITH_NEL_CEGUI)

View file

@ -1,3 +1,19 @@
// NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef __INELLIBRARY_H__
#define __INELLIBRARY_H__

View file

@ -58,7 +58,10 @@ public:
void remove (const std::string &sBigFileName);
// true if a bigFile is added
bool isBigFileAdded(const std::string &sBigFileName);
bool isBigFileAdded(const std::string &sBigFileName) const;
// return name of Big File
std::string getBigFileName(const std::string &sBigFileName) const;
// List all files in a bigfile
void list (const std::string &sBigFileName, std::vector<std::string> &vAllFiles);

View file

@ -41,7 +41,7 @@ public:
: EntityNameStringId(0),
EntitySlot(-1),
ShardId(0),
UId(~0),
UId(std::numeric_limits<uint32>::max()),
Online(false)
{ }

View file

@ -48,6 +48,10 @@ public:
/// From IEventEmitter. This call submitEvents on all the emitters
virtual void submitEvents(CEventServer &server, bool allWindows);
virtual void emulateMouseRawMode(bool enable);
virtual bool copyTextToClipboard(const ucstring &text);
virtual bool pasteTextFromClipboard(ucstring &text);
private:
typedef std::vector<std::pair<IEventEmitter *, bool> > TEmitterCont;
TEmitterCont _Emitters;

View file

@ -19,6 +19,7 @@
#include "types_nl.h"
#include "class_id.h"
#include "ucstring.h"
#include <map>
#include <list>
@ -58,6 +59,7 @@ protected:
const CClassId EventKeyDownId (0x3c2643da, 0x43f802a1);
const CClassId EventKeyUpId (0x1e62e85, 0x68a35d46);
const CClassId EventCharId (0x552255fe, 0x75a2373f);
const CClassId EventStringId (0x49b5af8f, 0x7f52cd26);
// Window events
const CClassId EventActivateId (0x7da66b0a, 0x1ef74519);
@ -327,6 +329,20 @@ private:
};
/**
* CEventString
*/
class CEventString : public CEventKey
{
public:
CEventString (const ucstring &str, IEventEmitter* emitter) : CEventKey (noKeyButton, emitter, EventStringId)
{
String = str;
}
ucstring String;
virtual CEvent *clone() const {return new CEventString(*this);}
};
/**
* CEventMouse.

View file

@ -241,6 +241,9 @@ private:
private:
/// Init _LanguageCodes and _LanguageNames
static void initLanguages();
static bool loadFileIntoMap(const std::string &filename, StrMapContainer &dest);
/// The internal read function, it does the real job of readTextFile

View file

@ -224,6 +224,16 @@ public:
*/
std::string getWindowsDirectory();
/** Get application directory.
* \return directory where applications should write files.
*/
std::string getApplicationDirectory(const std::string &appName = "");
/** Get a temporary directory.
* \return temporary directory where applications should write files.
*/
std::string getTemporaryDirectory();
private:
// All path in this vector must have a terminated '/'
@ -506,6 +516,16 @@ public:
*/
static std::string getWindowsDirectory();
/** Get application directory.
* \return directory where applications should write files.
*/
static std::string getApplicationDirectory(const std::string &appName = "");
/** Get a temporary directory.
* \return temporary directory where applications should write files.
*/
static std::string getTemporaryDirectory();
// release singleton
static void releaseInstance();
@ -700,11 +720,6 @@ struct CFile
* Call this method to get a temporary output filename. If you have successfully saved your data, delete the old filename and move the new one.
*/
static void getTemporaryOutputFilename (const std::string &originalFilename, std::string &tempFilename);
/** Get application directory.
* \return directory where applications should write files.
*/
static std::string getApplicationDirectory(const std::string &appName = "");
};
} // NLMISC

View file

@ -184,6 +184,11 @@ public:
return res;
}
ucstring substr(size_type pos = 0, size_type n = npos) const
{
return ucstringbase::substr(pos, n);
}
// for luabind (can't bind to 'substr' else ...)
ucstring luabind_substr(size_type pos = 0, size_type n = npos) const
{

View file

@ -54,7 +54,7 @@ public:
/** Return the number of markers in this track
*/
virtual uint32 countMarkers() { return (uint32)_Markers.size(); }
virtual uint32 countMarkers() const { return (uint32)_Markers.size(); }
/** Return a marker of this track given its index */
virtual CSoundAnimMarker* getMarker(uint32 i) { return _Markers[i]; }

View file

@ -2,9 +2,9 @@ ADD_SUBDIRECTORY(font)
ADD_SUBDIRECTORY(cluster_viewer)
ADD_SUBDIRECTORY(shape_viewer)
IF(WITH_CEGUI)
IF(WITH_NEL_CEGUI)
ADD_SUBDIRECTORY(cegui)
ENDIF(WITH_CEGUI)
ENDIF(WITH_NEL_CEGUI)
#IF(WITH_QT)
# ADD_SUBDIRECTORY(qtnel)

View file

@ -56,7 +56,8 @@ NLMISC_COMMAND(square,"display the square of the parameter","<value>")
// check args, if there is not the right number of parameters, return bad status.
if (args.size() != 1) return false;
uint32 val = atoi(args[0].c_str());
uint32 val;
NLMISC::fromString(args[0], val);
// display the result.
log.displayNL("The square of %d is %d", val, val*val);

View file

@ -215,8 +215,9 @@ void cbInfo (CMessage &msgin, TSockId from, CCallbackNetBase &netbase)
string token = "MeanPongTime ";
string::size_type pos=line.find (token);
string::size_type pos2=line.find (" ", pos+token.size());
uint32 val = atoi(line.substr (pos+token.size(), pos2-pos-token.size()).c_str());
LagGraph.addOneValue ((float)val);
float val;
NLMISC::fromString(line.substr (pos+token.size(), pos2-pos-token.size()), val);
LagGraph.addOneValue (val);
#endif
}

View file

@ -33,7 +33,7 @@ namespace NL3D
{
// ***************************************************************************
const uint32 IDriver::InterfaceVersion = 0x68; // added setWindowIcon
const uint32 IDriver::InterfaceVersion = 0x69; // added clipboard methods
// ***************************************************************************
IDriver::IDriver() : _SyncTexDrvInfos( "IDriver::_SyncTexDrvInfos" )

View file

@ -3831,5 +3831,13 @@ void CDriverD3D::findNearestFullscreenVideoMode()
}
}
}
bool CDriverD3D::copyTextToClipboard(const ucstring &text)
{
return _EventEmitter.copyTextToClipboard(text);
}
bool CDriverD3D::pasteTextFromClipboard(ucstring &text)
{
return _EventEmitter.pasteTextFromClipboard(text);
}
} // NL3D

View file

@ -2392,6 +2392,10 @@ public:
void deleteIndexBuffer(CIBDrvInfosD3D *ib);
// Build 16 bit index buffer for quad
bool buildQuadIndexBuffer();
virtual bool copyTextToClipboard(const ucstring &text);
virtual bool pasteTextFromClipboard(ucstring &text);
public:
#ifdef NL_DEBUG
std::set<CVBDrvInfosD3D *> _LockedBuffers;

View file

@ -341,7 +341,7 @@ CDriverGL::~CDriverGL()
{
H_AUTO_OGL(CDriverGL_CDriverGLDtor)
release();
#if defined(NL_OS_MAC)
[_autoreleasePool release];
#endif
@ -362,8 +362,8 @@ bool CDriverGL::setupDisplay()
nlinfo("3D: %s", lines[i].c_str());
#ifdef NL_OS_WINDOWS
NL3D::registerWGlExtensions (_Extensions, _hDC);
#endif // ifdef NL_OS_WINDOWS
NL3D::registerWGlExtensions(_Extensions, _hDC);
#endif // NL_OS_WINDOWS
// Check required extensions!!
// ARBMultiTexture is a OpenGL 1.2 required extension.
@ -851,7 +851,6 @@ bool CDriverGL::swapBuffers()
}
}
#ifdef NL_OS_WINDOWS
if (_EventEmitter.getNumEmitters() > 1) // is direct input running ?
{

View file

@ -328,6 +328,9 @@ public:
return _win;
}
virtual bool copyTextToClipboard(const ucstring &text);
virtual bool pasteTextFromClipboard(ucstring &text);
virtual uint32 getAvailableVertexAGPMemory ();
virtual uint32 getAvailableVertexVRAMMemory ();

View file

@ -135,7 +135,7 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM l
case SC_MONITORPOWER:
// Prevent From Happening
return 0;
return 0;
default:
break;
@ -2948,4 +2948,14 @@ void CDriverGL::setupApplicationMenu()
}
#endif
bool CDriverGL::copyTextToClipboard(const ucstring &text)
{
return _EventEmitter.copyTextToClipboard(text);
}
bool CDriverGL::pasteTextFromClipboard(ucstring &text)
{
return _EventEmitter.pasteTextFromClipboard(text);
}
} // NL3D

View file

@ -147,6 +147,16 @@ static NLMISC::TKey virtualKeycodeToNelKey(unsigned short keycode)
return NLMISC::KeyNOKEY;
}
bool CCocoaEventEmitter::pasteTextFromClipboard(ucstring &text)
{
return false;
}
bool CCocoaEventEmitter::copyTextToClipboard(const ucstring &text)
{
return false;
}
/// convert modifier key state to nel internal modifier key state
static NLMISC::TKeyButton modifierFlagsToNelKeyButton(unsigned int modifierFlags)
{

View file

@ -50,8 +50,9 @@ public:
bool processMessage(NSEvent* event, CEventServer* server = NULL);
virtual void submitEvents(CEventServer& server, bool allWindows);
virtual void emulateMouseRawMode(bool enable);
};
virtual bool copyTextToClipboard(const ucstring &text);
virtual bool pasteTextFromClipboard(ucstring &text);};
}
#endif

View file

@ -19,6 +19,8 @@
#if defined(NL_OS_UNIX) && !defined(NL_OS_MAC)
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/keysym.h>
#include <GL/gl.h>
#include <GL/glx.h>
@ -27,12 +29,18 @@
typedef bool (*x11Proc)(NL3D::IDriver *drv, XEvent *e);
static Atom XA_CLIPBOARD = 0;
static Atom XA_UTF8_STRING = 0;
static Atom XA_TARGETS = 0;
static Atom XA_NEL_SEL = 0;
namespace NLMISC {
CUnixEventEmitter::CUnixEventEmitter ():_dpy(NULL), _win(0), _emulateRawMode(false), _driver(NULL)
{
_im = 0;
_ic = 0;
_SelectionOwned=false;
}
CUnixEventEmitter::~CUnixEventEmitter()
@ -47,12 +55,18 @@ void CUnixEventEmitter::init(Display *dpy, Window win, NL3D::IDriver *driver)
_win = win;
_driver = driver;
XSelectInput (_dpy, _win, KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask|StructureNotifyMask);
XSelectInput (_dpy, _win, KeyPressMask|KeyReleaseMask|ButtonPressMask|ButtonReleaseMask|PointerMotionMask|StructureNotifyMask|ExposureMask);
// define Atoms used by clipboard
XA_CLIPBOARD = XInternAtom(dpy, "CLIPBOARD", False);
XA_UTF8_STRING = XInternAtom(dpy, "UTF8_STRING", False);
XA_TARGETS = XInternAtom(dpy, "TARGETS", False);
XA_NEL_SEL = XInternAtom(dpy, "NeL_SEL", False);
/*
TODO: implements all useful events processing
EnterWindowMask|LeaveWindowMask|ButtonMotionMask|Button1MotionMask|Button2MotionMask|
Button3MotionMask|Button4MotionMask|Button5MotionMask|KeymapStateMask|ExposureMask|
Button3MotionMask|Button4MotionMask|Button5MotionMask|KeymapStateMask|
SubstructureNotifyMask|VisibilityChangeMask|FocusChangeMask|PropertyChangeMask|
ColormapChangeMask|OwnerGrabButtonMask
*/
@ -553,10 +567,23 @@ bool CUnixEventEmitter::processMessage (XEvent &event, CEventServer *server)
#ifdef X_HAVE_UTF8_STRING
ucstring ucstr;
ucstr.fromUtf8(Text);
server->postEvent (new CEventChar (ucstr[0], noKeyButton, this));
CEventChar *charEvent = new CEventChar (ucstr[0], noKeyButton, this);
// raw if not processed by IME
charEvent->setRaw(keyCode != 0);
server->postEvent (charEvent);
#else
for (int i = 0; i < c; i++)
server->postEvent (new CEventChar ((ucchar)(unsigned char)Text[i], noKeyButton, this));
{
CEventChar *charEvent = new CEventChar ((ucchar)(unsigned char)Text[i], noKeyButton, this);
// raw if not processed by IME
charEvent->setRaw(keyCode != 0);
server->postEvent (charEvent);
}
#endif
}
break;
@ -578,12 +605,164 @@ bool CUnixEventEmitter::processMessage (XEvent &event, CEventServer *server)
}
break;
}
case SelectionRequest:
{
XEvent respond;
XSelectionRequestEvent req = event.xselectionrequest;
respond.xselection.type= SelectionNotify;
respond.xselection.display= req.display;
respond.xselection.requestor= req.requestor;
respond.xselection.selection=req.selection;
respond.xselection.target= req.target;
respond.xselection.time = req.time;
respond.xselection.property = req.property;
if (req.property == None)
{
respond.xselection.property = req.target;
}
if (req.target == XA_TARGETS)
{
Atom targets[] =
{
XA_TARGETS,
XA_STRING,
XA_UTF8_STRING
};
respond.xselection.property = req.property;
XChangeProperty(req.display, req.requestor, req.property, XA_ATOM, 32, PropModeReplace, (unsigned char *)targets, 3 /* number of element */);
}
else if (req.target == XA_STRING)
{
respond.xselection.property = req.property;
std::string str = _CopiedString.toString();
XChangeProperty(req.display, req.requestor, req.property, XA_STRING, 8, PropModeReplace, (const unsigned char*)str.c_str(), str.length());
}
else if (req.target == XA_UTF8_STRING)
{
respond.xselection.property = req.property;
std::string str = _CopiedString.toUtf8();
XChangeProperty(req.display, req.requestor, respond.xselection.property, XA_UTF8_STRING, 8, PropModeReplace, (const unsigned char*)str.c_str(), str.length());
}
else
{
// Note: Calling XGetAtomName with arbitrary value crash the client, maybe req.target have been sanitized by X11 server
respond.xselection.property = None;
}
XSendEvent (_dpy, req.requestor, 0, 0, &respond);
break;
}
case SelectionClear:
_SelectionOwned = false;
_CopiedString = "";
break;
case SelectionNotify:
{
Atom target = event.xselection.target;
Atom actualType = 0;
int actualFormat = 0;
unsigned long nitems = 0, bytesLeft = 0;
// some applications are sending ATOM and other TARGETS
if (target == XA_TARGETS || target == XA_ATOM)
{
Atom *supportedTargets = NULL;
// list NeL selection properties
if (XGetWindowProperty(_dpy, _win, XA_NEL_SEL, 0, XMaxRequestSize(_dpy), False, AnyPropertyType, &actualType, &actualFormat, &nitems, &bytesLeft, (unsigned char**)&supportedTargets) != Success)
return false;
if (bytesLeft > 0)
{
nlwarning("Paste: Supported TARGETS list too long.");
}
Atom bestTarget = 0;
sint bestTargetElect = 0;
// Elect best type
for (uint i=0; i < nitems; i++)
{
// nlwarning(" - Type=%s (%u)", XGetAtomName(_dpy, supportedTargets[i]), (uint)supportedTargets[i]);
if (supportedTargets[i] == XA_UTF8_STRING )
{
if (bestTargetElect < 2)
{
bestTarget = XA_UTF8_STRING;
bestTargetElect = 2;
}
}
else if (supportedTargets[i] == XA_STRING )
{
if (bestTargetElect < 1)
{
bestTarget = XA_STRING;
bestTargetElect = 1;
}
}
}
XFree(supportedTargets);
if (!bestTargetElect)
{
nlwarning("Paste buffer is not a text buffer.");
return false;
}
// request string conversion
XConvertSelection(_dpy, XA_CLIPBOARD, bestTarget, XA_NEL_SEL, _win, CurrentTime);
}
else if (target == XA_UTF8_STRING || target == XA_STRING)
{
uint8 *data = NULL;
// get selection
if (XGetWindowProperty(_dpy, _win, XA_NEL_SEL, 0, XMaxRequestSize(_dpy), False, AnyPropertyType, &actualType, &actualFormat, &nitems, &bytesLeft, (unsigned char**)&data) != Success)
return false;
ucstring text;
std::string tmpData = (const char*)data;
XFree(data);
// convert buffer to ucstring
if (target == XA_UTF8_STRING)
{
text = ucstring::makeFromUtf8(tmpData);
}
else if (target == XA_STRING)
{
text = tmpData;
}
else
{
nlwarning("Unknow format %u", (uint)target);
}
// sent string event to event server
server->postEvent (new CEventString (text, this));
}
else
{
nlwarning("Unknow target %u", (uint)target);
}
break;
}
case FocusIn:
// keyboard focus
// server->postEvent (new CEventSetFocus (true, this));
if (_ic) XSetICFocus(_ic);
break;
case FocusOut:
// keyboard focus
// server->postEvent (new CEventSetFocus (false, this));
if (_ic) XUnsetICFocus(_ic);
break;
case KeymapNotify:
@ -596,6 +775,12 @@ bool CUnixEventEmitter::processMessage (XEvent &event, CEventServer *server)
// XIM server has crashed
createIM();
break;
case ClientMessage:
// if ((xevent.xclient.format == 32) && (xevent.xclient.data.l[0] == videodata->WM_DELETE_WINDOW))
// {
// server->postEvent (new CEventDestroyWindow (this));
// }
break;
default:
// nlinfo("UnknownEvent");
// XtDispatchEvent(&event);
@ -605,6 +790,45 @@ bool CUnixEventEmitter::processMessage (XEvent &event, CEventServer *server)
return true;
}
bool CUnixEventEmitter::copyTextToClipboard(const ucstring &text)
{
_CopiedString = text;
// NeL window is the owner of clipboard
XSetSelectionOwner(_dpy, XA_CLIPBOARD, _win, CurrentTime);
// check we are owning the clipboard
if (XGetSelectionOwner(_dpy, XA_CLIPBOARD) != _win)
{
nlwarning("Can't aquire selection");
return false;
}
_SelectionOwned = true;
return true;
}
bool CUnixEventEmitter::pasteTextFromClipboard(ucstring &text)
{
// check if we own the selection
if (_SelectionOwned)
{
text = _CopiedString;
return true;
}
// check if there is a data in clipboard
if (XGetSelectionOwner(_dpy, XA_CLIPBOARD) == None)
return false;
// request supported methods
XConvertSelection(_dpy, XA_CLIPBOARD, XA_TARGETS, XA_NEL_SEL, _win, CurrentTime);
// don't return result now
return false;
}
} // NLMISC
#endif // defined(NL_OS_UNIX) && !defined(NL_OS_MAC)

View file

@ -65,6 +65,16 @@ public:
*/
bool processMessage(XEvent &event, CEventServer *server = NULL);
/**
* Copy a string to system clipboard.
*/
virtual bool copyTextToClipboard(const ucstring &text);
/*
* Paste a string from system clipboard.
*/
virtual bool pasteTextFromClipboard(ucstring &text);
private:
// Private internal server message
@ -97,6 +107,8 @@ private:
bool _emulateRawMode;
NL3D::IDriver* _driver;
CUnixEventServer _InternalServer;
ucstring _CopiedString;
bool _SelectionOwned;
};

View file

@ -1938,5 +1938,14 @@ bool CDriverUser::setRenderTarget(class UTexture & uTex, uint32 x, uint32 y, uin
return result;
}
bool CDriverUser::copyTextToClipboard(const ucstring &text)
{
return _Driver->copyTextToClipboard(text);
}
bool CDriverUser::pasteTextFromClipboard(ucstring &text)
{
return _Driver->pasteTextFromClipboard(text);
}
} // NL3D

View file

@ -24,9 +24,9 @@ IF(WITH_SOUND)
ADD_SUBDIRECTORY(sound)
ENDIF(WITH_SOUND)
IF(WITH_CEGUI)
IF(WITH_NEL_CEGUI)
ADD_SUBDIRECTORY(cegui)
ENDIF(WITH_CEGUI)
ENDIF(WITH_NEL_CEGUI)
IF(WITH_PACS)
ADD_SUBDIRECTORY(pacs)

View file

@ -17,7 +17,7 @@
#include "stdligo.h"
#include "zone_bank.h"
#include "nel/ligo/zone_bank.h"
#ifdef NL_OS_WINDOWS

View file

@ -381,7 +381,7 @@ void CLogicCounter::read (xmlNodePtr node)
_Name = getXMLProp (node, "Name");
_Value = atoiInt64 (getXMLProp (node, "Value").c_str());
_Verbose = atoi(getXMLProp (node, "Verbose").c_str()) == 1;
NLMISC::fromString(getXMLProp (node, "Verbose"), _Verbose);
Period.setValue(atoiInt64(getXMLProp (node, "Period").c_str()));
Phase.setValue(atoiInt64(getXMLProp (node, "Phase").c_str()));
Step.setValue(atoiInt64(getXMLProp (node, "Step").c_str()));

View file

@ -295,13 +295,25 @@ void CBigFile::remove (const std::string &sBigFileName)
}
// ***************************************************************************
bool CBigFile::isBigFileAdded(const std::string &sBigFileName)
bool CBigFile::isBigFileAdded(const std::string &sBigFileName) const
{
// Is already the same bigfile name ?
string bigfilenamealone = CFile::getFilename (sBigFileName);
return _BNPs.find(bigfilenamealone) != _BNPs.end();
}
// ***************************************************************************
std::string CBigFile::getBigFileName(const std::string &sBigFileName) const
{
string bigfilenamealone = CFile::getFilename (sBigFileName);
map<string, BNP>::const_iterator it = _BNPs.find(bigfilenamealone);
if (it != _BNPs.end())
return it->second.BigFileName;
else
return "";
}
// ***************************************************************************
void CBigFile::list (const std::string &sBigFileName, std::vector<std::string> &vAllFiles)
{
@ -403,9 +415,10 @@ FILE* CBigFile::getFile (const std::string &sFileName, uint32 &rFileSize,
{
handle.File = fopen (bnp->BigFileName.c_str(), "rb");
if (handle.File == NULL)
nlwarning ("bnp: can't fopen big file '%s' error %d '%s'", bnp->BigFileName.c_str(), errno, strerror(errno));
if (handle.File == NULL)
{
nlwarning ("bnp: can't fopen big file '%s' error %d '%s'", bnp->BigFileName.c_str(), errno, strerror(errno));
return NULL;
}
}
rCacheFileOnOpen = bnp->CacheFileOnOpen;

View file

@ -56,8 +56,12 @@ int CConfigFile::CVar::asInt (int index) const
switch (Type)
{
case T_STRING:
{
if (index >= (int)StrValues.size () || index < 0) throw EBadSize (Name, (int)StrValues.size (), index);
return atoi(StrValues[index].c_str());
int ret = 0;
NLMISC::fromString(StrValues[index], ret);
return ret;
}
case T_REAL:
if (index >= (int)RealValues.size () || index < 0) throw EBadSize (Name, (int)RealValues.size (), index);
return (int)RealValues[index];

View file

@ -574,7 +574,7 @@ void CEntityIdTranslator::getEntityIdInfo (const CEntityId &eid, ucstring &entit
nlwarning ("EIT: %s is not registered in CEntityIdTranslator", reid.toString().c_str());
entityName = "";
entitySlot = -1;
uid = ~0;
uid = std::numeric_limits<uint32>::max();
userName = "";
online = false;
}

View file

@ -16,7 +16,7 @@
#include "stdmisc.h"
#include "nel/misc/event_emitter_multi.h"
#include "nel/misc/system_utils.h"
namespace NLMISC
{
@ -99,7 +99,17 @@ const IEventEmitter *CEventEmitterMulti::getEmitter(uint index) const
return _Emitters[index].first;
}
bool CEventEmitterMulti::copyTextToClipboard(const ucstring &text)
{
// Naush: wrapped to old API to avoid duplicate code
return CSystemUtils::copyTextToClipboard(text);
}
bool CEventEmitterMulti::pasteTextFromClipboard(ucstring &text)
{
// Naush: wrapped to old API to avoid duplicate code
return CSystemUtils::pasteTextFromClipboard(text);
}
} // NLMISC

View file

@ -39,40 +39,34 @@ void CI18N::setLoadProxy(ILoadProxy *loadProxy)
_LoadProxy = loadProxy;
}
void CI18N::initLanguages()
{
if (!_LanguagesNamesLoaded)
{
_LanguageCodes.push_back("en");
_LanguageCodes.push_back("fr");
_LanguageCodes.push_back("de");
_LanguageCodes.push_back("ru");
_LanguageNames.push_back(ucstring("English"));
_LanguageNames.push_back(ucstring("French"));
_LanguageNames.push_back(ucstring("German"));
_LanguageNames.push_back(ucstring("Russian"));
_LanguagesNamesLoaded = true;
}
}
const std::vector<ucstring> &CI18N::getLanguageNames()
{
initLanguages();
return _LanguageNames;
}
const std::vector<std::string> &CI18N::getLanguageCodes()
{
if (!_LanguagesNamesLoaded)
{
std::vector<std::string> files;
// search all .uxt files
CPath::getFileList("uxt", files);
// if not uxt found, use default languages
if (files.empty())
{
_LanguageCodes.clear();
_LanguageCodes.push_back("en");
_LanguageCodes.push_back("fr");
_LanguageCodes.push_back("de");
_LanguageCodes.push_back("ru");
}
else
{
// add all languages found
for(uint i = 0; i < files.size(); ++i)
{
_LanguageCodes.push_back(toLower(CFile::getFilenameWithoutExtension(files[i])));
}
_LanguagesNamesLoaded = true;
}
}
initLanguages();
return _LanguageCodes;
}

View file

@ -1083,7 +1083,7 @@ int CIXml::getIntProperty(xmlNodePtr node, const char *property, int defaultValu
return defaultValue;
s=s.strip();
int val=s.atoi();
sint val=s.atoi();
if (val==0 && s!="0")
{
nlwarning("bad integer value: %s",s.c_str());

View file

@ -1686,6 +1686,66 @@ std::string CFileContainer::getWindowsDirectory()
#endif
}
std::string CPath::getApplicationDirectory(const std::string &appName)
{
return getInstance()->_FileContainer.getApplicationDirectory(appName);
}
std::string CFileContainer::getApplicationDirectory(const std::string &appName)
{
static std::string appPath;
if (appPath.empty())
{
#ifdef NL_OS_WINDOWS
wchar_t buffer[MAX_PATH];
SHGetSpecialFolderPathW(NULL, buffer, CSIDL_APPDATA, TRUE);
appPath = CPath::standardizePath(ucstring((ucchar*)buffer).toUtf8());
#else
appPath = CPath::standardizePath(getenv("HOME"));
#endif
}
std::string path = appPath;
#ifdef NL_OS_WINDOWS
if (!appName.empty())
path = CPath::standardizePath(path + appName);
#else
if (!appName.empty())
path = CPath::standardizePath(path + "." + toLower(appName));
#endif
return path;
}
std::string CPath::getTemporaryDirectory()
{
return getInstance()->_FileContainer.getTemporaryDirectory();
}
std::string CFileContainer::getTemporaryDirectory()
{
static std::string path;
if (path.empty())
{
char *tempDir = getenv("TEMP");
if (tempDir == NULL)
tempDir = getenv("TMP");
#ifdef NL_OS_UNIX
if (tempDir == NULL)
tempDir = "/tmp";
#else
if (tempDir == NULL)
tempDir = ".";
#endif
path = CPath::standardizePath(tempDir);
}
return path;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////
@ -2470,30 +2530,4 @@ void CFile::getTemporaryOutputFilename (const std::string &originalFilename, std
while (CFile::isExists(tempFilename));
}
std::string CFile::getApplicationDirectory(const std::string &appName)
{
static std::string appPath;
if (appPath.empty())
{
#ifdef NL_OS_WINDOWS
wchar_t buffer[MAX_PATH];
SHGetSpecialFolderPathW(NULL, buffer, CSIDL_APPDATA, TRUE);
appPath = CPath::standardizePath(ucstring((ucchar*)buffer).toUtf8());
#else
appPath = CPath::standardizePath(getenv("HOME"));
#endif
}
std::string path = appPath;
#ifdef NL_OS_WINDOWS
if (!appName.empty())
path = CPath::standardizePath(path + appName);
#else
if (!appName.empty())
path = CPath::standardizePath(path + "." + toLower(appName));
#endif
return path;
}
} // NLMISC

View file

@ -85,13 +85,6 @@ typedef struct SHA1Context
int Corrupted; /* Is the message digest corrupted? */
} SHA1Context;
// Because the code does some tricky stuff, VC>6 would cry at runtime
#ifdef _MFC_VER
#pragma runtime_checks( "", off )
#endif
//
// Function Prototypes
//
@ -194,10 +187,6 @@ CHashKey getSHA1(const string &filename, bool forcePath)
return hk;
}
#ifdef _MFC_VER
#pragma runtime_checks( "", off )
#endif
/*
* Define the SHA1 circular left shift macro
*/
@ -554,7 +543,3 @@ void SHA1PadMessage(SHA1Context *context)
SHA1ProcessMessageBlock(context);
}
#ifdef _MFC_VER
#pragma runtime_checks( "", restore )
#endif

View file

@ -14,6 +14,9 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef NL_STDMISC_H
#define NL_STDMISC_H
#include "nel/misc/types_nl.h"
#include <algorithm>
@ -54,3 +57,5 @@
#define NOMINMAX
#include <windows.h>
#endif
#endif // NL_STDMISC_H

View file

@ -128,11 +128,11 @@ bool CWinEventEmitter::processMessage (HWND hWnd, uint32 msg, WPARAM wParam, LPA
if (_KeyboardEventsEnabled)
{
// Ctrl, shit or alt ?
if ((int)wParam==VK_MENU)
if ((sint)wParam==VK_MENU)
_AltButton=true;
if ((int)wParam==VK_CONTROL)
if ((sint)wParam==VK_CONTROL)
_CtrlButton=true;
if ((int)wParam==VK_SHIFT)
if ((sint)wParam==VK_SHIFT)
_ShiftButton=true;
// Post the message

View file

@ -1638,7 +1638,7 @@ float NLPACS::CLocalRetriever::getInteriorHeightAround(const ULocalPosition &pos
// ***************************************************************************
#ifdef NL_OS_WINDOWS
#pragma optimize( "", off )
//#pragma optimize( "", off )
#endif // NL_OS_WINDOWS
void NLPACS::CLocalRetriever::findPath(const NLPACS::CLocalRetriever::CLocalPosition &A,
@ -1853,7 +1853,7 @@ void NLPACS::CLocalRetriever::findPath(const NLPACS::CLocalRetriever::CLocalPosi
path.push_back(CVector2s(B.Estimation));
}
#ifdef NL_OS_WINDOWS
#pragma optimize( "", on )
//#pragma optimize( "", on )
#endif // NL_OS_WINDOWS
// ***************************************************************************

View file

@ -314,9 +314,9 @@ int main(int argc, char *argv[])
sint percentageFace= 100;
sint maxFace= INT_MAX;
if(argc>=4)
percentageFace= atoi(argv[3]);
NLMISC::fromString(argv[3], percentageFace);
if(argc>=5)
maxFace= atoi(argv[4]);
NLMISC::fromString(argv[4], maxFace);
// **** Load the Mesh In.
IShape *pResult = NULL;

View file

@ -31,7 +31,7 @@
#include "nel/misc/i_xml.h"
#include "nel/misc/app_context.h"
#include "nel/../../src/ligo/zone_region.h"
#include "nel/ligo/zone_region.h"
#include "nel/3d/scene_group.h"

View file

@ -52,13 +52,17 @@ void CEditEx::OnSetFocus(CWnd* pOldWnd)
sint CEditEx::getSInt() const
{
nlassert(_Type == SIntType);
return (sint) ::atoi(getString().c_str());
sint ret = 0;
NLMISC::fromString(getString(), ret);
return ret;
}
uint CEditEx::getUInt() const
{
nlassert(_Type == UIntType);
return (uint) ::atoi(getString().c_str());
uint ret = 0;
NLMISC::fromString(getString(), ret);
return ret;
}
float CEditEx::getFloat() const
{

View file

@ -880,7 +880,8 @@ bool ShapesExporter::createThumbnail(const string &filename, const string &path)
if (!fgets(str, 100, fp))
strcpy(str, "0");
fclose(fp);
selectedFrame = atoi(str)/2;
NLMISC::fromString(std::string(str), selectedFrame);
selectedFrame /= 2;
}
}

View file

@ -116,7 +116,8 @@ bool getZoneCoordByName(const char * name, uint16& x, uint16& y)
return false;
}
}
y = atoi(ystr.c_str());
NLMISC::fromString(ystr, y);
// x
x = 0;

View file

@ -962,7 +962,7 @@ int main(int /* argc */, char ** /* argv */)
NLMISC::CApplicationContext myApplicationContext;
#ifdef NL_OS_UNIX
NLMISC::CPath::addSearchPath(NLMISC::CFile::getApplicationDirectory("NeL"));
NLMISC::CPath::addSearchPath(NLMISC::CPath::getApplicationDirectory("NeL"));
#endif // NL_OS_UNIX
NLMISC::CPath::addSearchPath(NL_ZVIEWER_CFG);

View file

@ -59,7 +59,7 @@ afx_msg void CLAEdit::OnKeyDown( UINT nChar, UINT nRepCnt, UINT nFlags )
int start, end;
GetSel( start, end );
str = str.Mid( start, end-start );
int lineNum = atoi( str );
int lineNum = atoi(str);
if ( ! ((lineNum != 0) || (str == "0")) )
break;

View file

@ -424,7 +424,7 @@ int main( int argc, char ** argv )
NLMISC::CApplicationContext appContext;
#ifdef NL_OS_UNIX
NLMISC::CPath::addSearchPath(NLMISC::CFile::getApplicationDirectory("NeL"));
NLMISC::CPath::addSearchPath(NLMISC::CPath::getApplicationDirectory("NeL"));
#endif // NL_OS_UNIX
NLMISC::CPath::addSearchPath(NL_MK_SH_ID_CFG);

View file

@ -86,7 +86,7 @@ void init()
try
{
#ifdef NL_OS_UNIX
NLMISC::CPath::addSearchPath(NLMISC::CFile::getApplicationDirectory("NeL"));
NLMISC::CPath::addSearchPath(NLMISC::CPath::getApplicationDirectory("NeL"));
#endif // NL_OS_UNIX
NLMISC::CPath::addSearchPath(NL_BIB_CFG);

View file

@ -122,7 +122,7 @@ void initConfig()
try
{
#ifdef NL_OS_UNIX
NLMISC::CPath::addSearchPath(NLMISC::CFile::getApplicationDirectory("NeL"));
NLMISC::CPath::addSearchPath(NLMISC::CPath::getApplicationDirectory("NeL"));
#endif // NL_OS_UNIX
NLMISC::CPath::addSearchPath(NL_BIRB_CFG);

View file

@ -223,23 +223,3 @@ void CAttackListManager::buildLinkFXs()
{
_Links.init("links.id_to_string_array", _AnimationSet, false /* must not delete animset, owned by this object */);
}

View file

@ -486,7 +486,7 @@ void CBGDownloaderAccess::CDownloadCoTask::restartDownloader()
uint tryCounter = 1;
for (;;)
{
nlwarning("Launching downloader: try number %d", (int) tryCounter++);
nlwarning("Launching downloader: try number %u", tryCounter++);
// now we can create the message queue because we are sure that it will reach the good app
Parent->_DownloaderMsgQueue.init(HInstance, BGDownloader::ClientWndID, BGDownloader::DownloaderWndID);
sleep(200);

View file

@ -19,6 +19,11 @@
#ifndef CDB_H
#define CDB_H
// misc
#include "nel/misc/types_nl.h"
#include "nel/misc/smart_ptr.h"
#include "nel/misc/string_mapper.h"
#include <libxml/parser.h>
namespace NLMISC

View file

@ -359,6 +359,13 @@ 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;
}
_OutpostId = 0;
_OutpostSide = OUTPOSTENUMS::UnknownPVPSide;
@ -1853,12 +1860,16 @@ void CCharacterCL::updateVisualPropertyPvpMode(const NLMISC::TGameCycle &/* game
//-----------------------------------------------
void CCharacterCL::updateVisualPropertyPvpClan(const NLMISC::TGameCycle &/* gameCycle */, const sint64 &prop)
{
_PvpClan = PVP_CLAN::TPVPClan(prop);
if (_PvpClan >= PVP_CLAN::NbClans)
// get fames signs from prop
for (uint8 fameIdx = 0; fameIdx < 7; fameIdx++)
{
//nlwarning("updateVisualPropertyPvpClan: received invalid PvP clan: %"NL_I64"u", prop);
_PvpClan = PVP_CLAN::None;
_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));
buildInSceneInterface();
} // updateVisualPropertyPvpClan //

View file

@ -372,6 +372,44 @@ public:
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 getOutpostId() const { return _OutpostId; }
virtual OUTPOSTENUMS::TPVPSide getOutpostSide() const { return _OutpostSide; }
@ -690,6 +728,10 @@ protected:
uint32 _EventFactionId;
uint8 _PvpMode;
PVP_CLAN::TPVPClan _PvpClan;
PVP_CLAN::TPVPClan _ClanCivMaxFame;
PVP_CLAN::TPVPClan _ClanCultMaxFame;
bool _PvpAllies[PVP_CLAN::NbClans];
bool _PvpEnemies[PVP_CLAN::NbClans];
uint16 _OutpostId;
OUTPOSTENUMS::TPVPSide _OutpostSide;

View file

@ -361,7 +361,7 @@ int main(int argc, char **argv)
// if client_default.cfg is not in current directory, use application default directory
if (!CFile::isExists("client_default.cfg"))
{
std::string currentPath = CFile::getApplicationDirectory("Ryzom");
std::string currentPath = CPath::getApplicationDirectory("Ryzom");
if (!CFile::isExists(currentPath)) CFile::createDirectory(currentPath);

View file

@ -24,6 +24,7 @@
// Misc.
#include "nel/misc/config_file.h"
#include "nel/misc/bit_mem_stream.h"
#include "nel/misc/i18n.h"
// Client.
#include "client_cfg.h"
#include "entities.h"
@ -44,6 +45,8 @@
# include "config.h"
#endif // HAVE_CONFIG_H
#include <locale.h>
///////////
// MACRO //
///////////
@ -1895,15 +1898,34 @@ void CClientConfig::init(const string &configFileName)
{
// create the basic .cfg that link the default one
FILE *fp = fopen(configFileName.c_str(), "w");
if (fp == NULL)
if (fp == NULL)
{
nlerror("CFG::init: Can't create config file '%s'", configFileName.c_str());
}
else
{
nlwarning("CFG::init: creating '%s' with default values", configFileName.c_str ());
}
fprintf(fp, "RootConfigFilename = \"%s\";\n", defaultConfigFileName.c_str());
// get current locale
std::string lang = toLower(std::string(setlocale(LC_CTYPE, "")));
lang = lang.substr(0, 2);
const std::vector<std::string> &languages = CI18N::getLanguageCodes();
// search if current locale is defined in language codes
for(uint i = 0; i < languages.size(); ++i)
{
nlerror ("CFG::init: Can't create config file '%s'", configFileName.c_str());
if (lang == languages[i])
{
fprintf(fp, "LanguageCode = \"%s\";\n", lang.c_str());
break;
}
}
else
{
nlwarning("CFG::init: creating '%s' with default values", configFileName.c_str ());
}
fprintf(fp, "RootConfigFilename = \"%s\";\n", defaultConfigFileName.c_str());
fclose(fp);
}
else

View file

@ -66,8 +66,8 @@ struct CClientConfig
bool SaveConfig;
/// Window position in windowed mode
sint32 PositionX;
sint32 PositionY;
sint32 PositionX;
sint32 PositionY;
/// Window frequency
uint Frequency;

View file

@ -40,6 +40,7 @@
#include "game_share/generic_xml_msg_mngr.h"
#include "game_share/msg_client_server.h"
#include "game_share/chat_group.h"
#include "interface_v3/skill_manager.h"
using namespace std;
using namespace NLMISC;
@ -948,19 +949,29 @@ void CClientChatManager::buildTellSentence(const ucstring &sender, const ucstrin
else
{
ucstring name = CEntityCL::removeTitleAndShardFromName(sender);
ucstring csr;
// special case where there is only a title, very rare case for some NPC
if (name.empty())
{
// we need the gender to display the correct title
CCharacterCL *entity = dynamic_cast<CCharacterCL*>(EntitiesMngr.getEntityByName(sender, true, true));
bool bWoman = entity && entity->getGender() == GSGENDER::female;
name = STRING_MANAGER::CStringManagerClient::getTitleLocalizedName(CEntityCL::getTitleFromName(sender), bWoman);
}
else
{
// Does the char have a CSR title?
csr = CHARACTER_TITLE::isCsrTitle(CEntityCL::getTitleFromName(sender)) ? ucstring("(CSR) ") : ucstring("");
}
result = name + ucstring(" ") + CI18N::get("tellsYou") + ucstring(": ") + msg;
ucstring cur_time;
if (CInterfaceManager::getInstance()->getDbProp("UI:SAVE:CHAT:SHOW_TIMES_IN_CHAT_CB", false)->getValueBool())
{
cur_time = CInterfaceManager::getTimestampHuman();
}
result = cur_time + csr + name + ucstring(" ") + CI18N::get("tellsYou") + ucstring(": ") + msg;
}
}
@ -992,27 +1003,41 @@ void CClientChatManager::buildChatSentence(TDataSetIndex /* compressedSenderInde
// 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&")
{
if (CInterfaceManager::getInstance()->getDbProp("UI:SAVE:CHAT:SHOW_TIMES_IN_CHAT_CB", false)->getValueBool())
{
cur_time = CInterfaceManager::getTimestampHuman();
}
}
ucstring csr;
// Does the char have a CSR title?
csr = CHARACTER_TITLE::isCsrTitle(CEntityCL::getTitleFromName(sender)) ? ucstring("(CSR) ") : ucstring("");
if (UserEntity && senderName == UserEntity->getDisplayName())
{
// the player talks
// The player talks
switch(type)
{
case CChatGroup::shout:
result = cat + CI18N::get("youShout") + ucstring(" : ") + finalMsg;
result = cat + cur_time + csr + CI18N::get("youShout") + ucstring(": ") + finalMsg;
break;
default:
result = cat + CI18N::get("youSay") + ucstring(" : ") + finalMsg;
result = cat + cur_time + csr + CI18N::get("youSay") + ucstring(": ") + finalMsg;
break;
}
}
else
{
// special case where there is only a title, very rare case for some NPC
// Special case where there is only a title, very rare case for some NPC
if (senderName.empty())
{
// we need the gender to display the correct title
CCharacterCL *entity = dynamic_cast<CCharacterCL*>(EntitiesMngr.getEntityByName(sender, true, true));
// We need the gender to display the correct title
bool bWoman = entity && entity->getGender() == GSGENDER::female;
senderName = STRING_MANAGER::CStringManagerClient::getTitleLocalizedName(CEntityCL::getTitleFromName(sender), bWoman);
@ -1021,10 +1046,10 @@ void CClientChatManager::buildChatSentence(TDataSetIndex /* compressedSenderInde
switch(type)
{
case CChatGroup::shout:
result = cat + senderName + ucstring(" ") + CI18N::get("heShout") + ucstring(" : ") + finalMsg;
result = cat + cur_time + csr + senderName + ucstring(" ") + CI18N::get("heShout") + ucstring(": ") + finalMsg;
break;
default:
result = cat + senderName + ucstring(" ") + CI18N::get("heSays") + ucstring(" : ") + finalMsg;
result = cat + cur_time + csr + senderName + ucstring(" ") + CI18N::get("heSays") + ucstring(": ") + finalMsg;
break;
}
}
@ -1157,7 +1182,13 @@ class CHandlerTell : public IActionHandler
prop.readRGBA("UI:SAVE:CHAT:COLORS:SPEAKER"," ");
ucstring finalMsg;
CChatWindow::encodeColorTag(prop.getRGBA(), finalMsg, false);
finalMsg += CI18N::get("youTell") + ": ";
ucstring cur_time;
if (CInterfaceManager::getInstance()->getDbProp("UI:SAVE:CHAT:SHOW_TIMES_IN_CHAT_CB", false)->getValueBool())
{
cur_time = CInterfaceManager::getTimestampHuman();
}
ucstring csr = CHARACTER_TITLE::isCsrTitle(UserEntity->getTitleRaw()) ? "(CSR) " : "";
finalMsg += cur_time + csr + CI18N::get("youTell") + ": ";
prop.readRGBA("UI:SAVE:CHAT:COLORS:TELL"," ");
CChatWindow::encodeColorTag(prop.getRGBA(), finalMsg, true);
finalMsg += message;
@ -1238,6 +1269,14 @@ void CClientChatManager::updateChatModeAndButton(uint mode)
case CChatGroup::universe: pUserBut->setHardText("uiFilterUniverse"); break;
case CChatGroup::team: if (teamActive) pUserBut->setHardText("uiFilterTeam"); break;
case CChatGroup::guild: if (guildActive) pUserBut->setHardText("uiFilterGuild"); break;
case CChatGroup::dyn_chat:
uint32 index = PeopleInterraction.TheUserChat.Filter.getTargetDynamicChannelDbIndex();
uint32 textId = pIM->getDbProp("SERVER:DYN_CHAT:CHANNEL"+toString(index)+":NAME")->getValue32();
ucstring title;
STRING_MANAGER::CStringManagerClient::instance()->getDynString(textId, title);
pUserBut->setHardText(title.toUtf8());
break;
// NB: user chat cannot have yubo_chat target
}
pUserBut->setActive(true);
@ -1276,6 +1315,12 @@ class CHandlerTalk : public IActionHandler
text.fromUtf8 (getParam (sParams, "text"));
// text = getParam (sParams, "text");
// Parse any tokens in the text
if ( ! CInterfaceManager::parseTokens(text))
{
return;
}
// Find the base group
if ((mode<CChatGroup::nbChatMode) && !text.empty())
{
@ -1292,7 +1337,7 @@ class CHandlerTalk : public IActionHandler
else
{
CInterfaceManager *im = CInterfaceManager::getInstance();
im->displaySystemInfo (ucstring(cmd+" : ")+CI18N::get ("uiCommandNotExists"));
im->displaySystemInfo (ucstring(cmd+": ")+CI18N::get ("uiCommandNotExists"));
}
}
else

View file

@ -134,7 +134,7 @@ uint CColorSlotManager::addSlot(const TStringVect &slotDescs)
_Slots.push_back(slotDescs);
for(uint k = 0; k < slotDescs.size(); ++k)
{
NLMISC::strupr(_Slots.back()[k]);
_Slots.back()[k] = NLMISC::toUpper(_Slots.back()[k]);
}
return (uint)_Slots.size() - 1;
}
@ -327,10 +327,9 @@ bool CColorSlotManager::addSlotsFromConfigFile(NLMISC::CConfigFile &cf, uint &st
{
return false;
}
uint startSlot = (uint)_Slots.size();
_Slots.resize(_Slots.size() + mask_extensions->size());
/// For each kind of mask, build a slot
for (uint k = 0; k < (uint) mask_extensions->size(); ++k)

View file

@ -125,7 +125,7 @@ extern CClientChatManager ChatMngr;
extern ULandscape *Landscape;
extern UScene *Scene;
extern CLog g_log;
extern CEntityManager EntitiesMngr;
///////////////
// Variables //
@ -342,6 +342,317 @@ NLMISC_COMMAND(random, "Roll a dice and say the result around","[<min>] <max>")
return true;
}
//-----------------------------------------------
// 'dumpShapePos' : Dump Last Added Shape Pos
//-----------------------------------------------
NLMISC_COMMAND(dumpShapePos, "Dump Last Added Shape Pos.", "")
{
#if FINAL_VERSION
if (!hasPrivilegeDEV() &&
!hasPrivilegeSGM() &&
!hasPrivilegeGM() &&
!hasPrivilegeVG() &&
!hasPrivilegeSG() &&
!hasPrivilegeG() &&
!hasPrivilegeEM() &&
!hasPrivilegeEG())
return true;
#endif // FINAL_VERSION
if (ShapeAddedByCommand.empty())
{
nlwarning("No shape created yet");
return false;
}
CInterfaceManager *IM = CInterfaceManager::getInstance();
CVector pos = ShapeAddedByCommand.back().getPos();
IM->displaySystemInfo(ucstring(toString("Shape Pos = %f, %f, %f", pos.x, pos.y, pos.z)));
return true;
}
//-----------------------------------------------
// 'clearShape' : Remove all shapes added with the 'shape' command
//-----------------------------------------------
NLMISC_COMMAND(clearShape, "Remove all shapes added with the 'shape' command.", "")
{
#if FINAL_VERSION
if (!hasPrivilegeDEV() &&
!hasPrivilegeSGM() &&
!hasPrivilegeGM() &&
!hasPrivilegeVG() &&
!hasPrivilegeSG() &&
!hasPrivilegeG() &&
!hasPrivilegeEM() &&
!hasPrivilegeEG())
return true;
#endif // FINAL_VERSION
if (ShapeAddedByCommand.empty())
{
nlwarning("No shape created yet");
return false;
}
if (!Scene) return false;
for(uint k = 0; k < ShapeAddedByCommand.size(); ++k)
{
Scene->deleteInstance(ShapeAddedByCommand[k]);
}
ShapeAddedByCommand.clear();
return true;
}
//-----------------------------------------------------
// 'setShapeX' : Set X position for last created shape
//-----------------------------------------------------
NLMISC_COMMAND(setShapeX, "Set X position for last created shape.", "<x coordinate>")
{
#if FINAL_VERSION
if (!hasPrivilegeDEV() &&
!hasPrivilegeSGM() &&
!hasPrivilegeGM() &&
!hasPrivilegeVG() &&
!hasPrivilegeSG() &&
!hasPrivilegeG() &&
!hasPrivilegeEM() &&
!hasPrivilegeEG())
return true;
#endif // FINAL_VERSION
if (args.size() != 1) return false;
if (ShapeAddedByCommand.empty())
{
nlwarning("No shape created yet");
return false;
}
float coord;
bool valid_coord;
if (args[0][0] == '+')
valid_coord = fromString(args[0].substr(1), coord);
else
valid_coord = fromString(args[0], coord);
if (!valid_coord)
{
nlwarning("Can't get position");
return false;
}
CVector pos = ShapeAddedByCommand.back().getPos();
if (args[0][0] == '+')
pos.x += coord;
else
pos.x = coord;
ShapeAddedByCommand.back().setPos(pos);
return true;
}
//-----------------------------------------------------
// 'setShapeY' : Set Y position for last created shape
//-----------------------------------------------------
NLMISC_COMMAND(setShapeY, "Set Y position for last created shape.", "<y coordinate>")
{
#if FINAL_VERSION
if (!hasPrivilegeDEV() &&
!hasPrivilegeSGM() &&
!hasPrivilegeGM() &&
!hasPrivilegeVG() &&
!hasPrivilegeSG() &&
!hasPrivilegeG() &&
!hasPrivilegeEM() &&
!hasPrivilegeEG())
return true;
#endif // FINAL_VERSION
if (args.size() != 1) return false;
if (ShapeAddedByCommand.empty())
{
nlwarning("No shape created yet");
return false;
}
float coord;
bool valid_coord;
if (args[0][0] == '+')
valid_coord = fromString(args[0].substr(1), coord);
else
valid_coord = fromString(args[0], coord);
if (!valid_coord)
{
nlwarning("Can't get position");
return false;
}
CVector pos = ShapeAddedByCommand.back().getPos();
if (args[0][0] == '+')
pos.y += coord;
else
pos.y = coord;
ShapeAddedByCommand.back().setPos(pos);
return true;
}
//-----------------------------------------------------
// 'setShapeZ' : Set Z position for last created shape
//-----------------------------------------------------
NLMISC_COMMAND(setShapeZ, "Set Z position for last created shape.", "<z coordinate>")
{
#if FINAL_VERSION
if (!hasPrivilegeDEV() &&
!hasPrivilegeSGM() &&
!hasPrivilegeGM() &&
!hasPrivilegeVG() &&
!hasPrivilegeSG() &&
!hasPrivilegeG() &&
!hasPrivilegeEM() &&
!hasPrivilegeEG())
return true;
#endif // FINAL_VERSION
if (args.size() != 1) return false;
if (ShapeAddedByCommand.empty())
{
nlwarning("No shape created yet");
return false;
}
float coord;
bool valid_coord;
if (args[0][0] == '+')
valid_coord = fromString(args[0].substr(1), coord);
else
valid_coord = fromString(args[0], coord);
if (!valid_coord)
{
nlwarning("Can't get position");
return false;
}
CVector pos = ShapeAddedByCommand.back().getPos();
if (args[0][0] == '+')
pos.z += coord;
else
pos.z = coord;
ShapeAddedByCommand.back().setPos(pos);
return true;
}
//-----------------------------------------------------
// 'setShapeDir' : Set direction angle for last created shape
//-----------------------------------------------------
NLMISC_COMMAND(setShapeDir, "Set direction angle for last created shape.", "<angle>")
{
#if FINAL_VERSION
if (!hasPrivilegeDEV() &&
!hasPrivilegeSGM() &&
!hasPrivilegeGM() &&
!hasPrivilegeVG() &&
!hasPrivilegeSG() &&
!hasPrivilegeG() &&
!hasPrivilegeEM() &&
!hasPrivilegeEG())
return true;
#endif // FINAL_VERSION
if (args.size() != 1) return false;
if (ShapeAddedByCommand.empty())
{
nlwarning("No shape created yet");
return false;
}
float angle;
if (!fromString(args[0], angle))
{
nlwarning("Can't get angle");
return false;
}
CMatrix dir;
dir.identity();
CVector vangle = CVector(sin(angle), cos(angle), 0.f);
CVector vi = vangle^CVector(0.f, 0.f, 1.f);
CVector vk = vi^vangle;
dir.setRot(vi, vangle, vk, true);
// Set Orientation : User Direction should be normalized.
ShapeAddedByCommand.back().setRotQuat(dir.getRot());
return true;
}
//-----------------------------------------------
// 'shape' : Add a shape in the scene.
//-----------------------------------------------
NLMISC_COMMAND(shape, "Add a shape in the scene.", "<shape file>")
{
#if FINAL_VERSION
if (!hasPrivilegeDEV() &&
!hasPrivilegeSGM() &&
!hasPrivilegeGM() &&
!hasPrivilegeVG() &&
!hasPrivilegeSG() &&
!hasPrivilegeG() &&
!hasPrivilegeEM() &&
!hasPrivilegeEG())
return true;
#endif // FINAL_VERSION
if(args.size() < 1)
{
nlwarning("Command 'shape': need at least 1 parameter, try '/help shape' for more details.");
return false;
}
if (!Scene)
{
nlwarning("No scene available");
return false;
}
UInstance instance = Scene->createInstance(args[0]);
if(!instance.empty())
{
ShapeAddedByCommand.push_back(instance);
// Set the position
instance.setPos(UserEntity->pos());
instance.setClusterSystem(UserEntity->getClusterSystem()); // for simplicity, assume it is in the same
// cluster system than the user
// Compute the direction Matrix
CMatrix dir;
dir.identity();
CVector vi = UserEntity->dir()^CVector(0.f, 0.f, 1.f);
CVector vk = vi^UserEntity->dir();
dir.setRot(vi, UserEntity->dir(), vk, true);
// Set Orientation : User Direction should be normalized.
instance.setRotQuat(dir.getRot());
// if the shape is a particle system, additionnal parameters are user params
UParticleSystemInstance psi;
psi.cast (instance);
if (!psi.empty())
{
// set each user param that is present
for(uint k = 0; k < 4; ++k)
{
if (args.size() >= (k + 2))
{
float uparam;
if (fromString(args[k + 1], uparam))
{
psi.setUserParam(k, uparam);
}
else
{
nlwarning("Cant read param %d", k);
}
}
}
}
}
else
{
nlwarning("Command 'shape': cannot find the shape %s.", args[0].c_str());
}
// Command Well Done
return true;
}
NLMISC_COMMAND(bugReport, "Call the bug report tool with dump", "<AddScreenshot>")
{
const char *brname[] = { "bug_report.exe", "bug_report_r.exe", "bug_report_rd.exe", "bug_report_df.exe", "bug_report_d.exe" };
@ -908,6 +1219,10 @@ static bool talkInChan(uint32 nb,std::vector<std::string>args)
PeopleInterraction.talkInDynamicChannel(nb,ucstring(tmp));
return true;
}
else
{
ChatMngr.updateChatModeAndButton(CChatGroup::dyn_chat);
}
return false;
}
@ -3467,156 +3782,6 @@ NLMISC_COMMAND(dist2side, "Change the distance to the side for a given sheet.",
//-----------------------------------------------
// 'clearShape' : Remove all shapes added with the 'shape' command
//-----------------------------------------------
NLMISC_COMMAND(clearShape, "Remove all shapes added with the 'shape' command.", "")
{
if (!Scene) return false;
for(uint k = 0; k < ShapeAddedByCommand.size(); ++k)
{
Scene->deleteInstance(ShapeAddedByCommand[k]);
}
ShapeAddedByCommand.clear();
return true;
}
//-----------------------------------------------------
// 'setShapeX' : Set X position for last created shape
//-----------------------------------------------------
NLMISC_COMMAND(setShapeX, "Set X position for last created shape.", "<x coordinate>")
{
if (args.size() != 1) return false;
if (ShapeAddedByCommand.empty())
{
nlwarning("No shape created yet");
return false;
}
float coord;
if (!fromString(args[0], coord))
{
nlwarning("Can't get position");
return false;
}
CVector pos = ShapeAddedByCommand.back().getPos();
pos.x = coord;
ShapeAddedByCommand.back().setPos(pos);
return true;
}
//-----------------------------------------------------
// 'setShapeY' : Set Y position for last created shape
//-----------------------------------------------------
NLMISC_COMMAND(setShapeY, "Set Y position for last created shape.", "<y coordinate>")
{
if (args.size() != 1) return false;
if (ShapeAddedByCommand.empty())
{
nlwarning("No shape created yet");
return false;
}
float coord;
if (!fromString(args[0], coord))
{
nlwarning("Can't get position");
return false;
}
CVector pos = ShapeAddedByCommand.back().getPos();
pos.y = coord;
ShapeAddedByCommand.back().setPos(pos);
return true;
}
//-----------------------------------------------------
// 'setShapeZ' : Set Z position for last created shape
//-----------------------------------------------------
NLMISC_COMMAND(setShapeZ, "Set Z position for last created shape.", "<z coordinate>")
{
if (args.size() != 1) return false;
if (ShapeAddedByCommand.empty())
{
nlwarning("No shape created yet");
return false;
}
float coord;
if (!fromString(args[0], coord))
{
nlwarning("Can't get position");
return false;
}
CVector pos = ShapeAddedByCommand.back().getPos();
pos.z = coord;
ShapeAddedByCommand.back().setPos(pos);
return true;
}
//-----------------------------------------------
// 'shape' : Add a shape in the scene.
//-----------------------------------------------
NLMISC_COMMAND(shape, "Add a shape in the scene.", "<shape file>")
{
if(args.size() < 1)
{
nlwarning("Command 'shape': need at least 1 parameter, try '/help shape' for more details.");
return false;
}
if (!Scene)
{
nlwarning("No scene available");
return false;
}
UInstance instance = Scene->createInstance(args[0]);
if(!instance.empty())
{
ShapeAddedByCommand.push_back(instance);
// Set the position
instance.setPos(UserEntity->pos());
instance.setClusterSystem(UserEntity->getClusterSystem()); // for simplicity, assume it is in the same
// cluster system than the user
// Compute the direction Matrix
CMatrix dir;
dir.identity();
CVector vi = UserEntity->dir()^CVector(0.f, 0.f, 1.f);
CVector vk = vi^UserEntity->dir();
dir.setRot(vi, UserEntity->dir(), vk, true);
// Set Orientation : User Direction should be normalized.
instance.setRotQuat(dir.getRot());
// if the shape is a particle system, additionnal parameters are user params
UParticleSystemInstance psi;
psi.cast (instance);
if (!psi.empty())
{
// set each user param that is present
for(uint k = 0; k < 4; ++k)
{
if (args.size() >= (k + 2))
{
float uparam;
if (fromString(args[k + 1], uparam))
{
psi.setUserParam(k, uparam);
}
else
{
nlwarning("Cant read param %d", k);
}
}
}
}
}
else
nlwarning("Command 'shape': cannot find the shape %s.", args[0].c_str());
// Command Well Done
return true;
}
// Change the parent of an entity. 'parent slot' not defined remove the current parent.
NLMISC_COMMAND(parent, "Change the parent of an entity.", "<slot> [<parent slot>]")
{

View file

@ -27,9 +27,12 @@
#include "entities.h"
#include "net_manager.h"
#include "interface_v3/interface_manager.h"
#include "interface_v3/interface_3d_scene.h"
#include "interface_v3/group_container.h"
#include "sheet_manager.h"
#include "interface_v3/inventory_manager.h"
#include "interface_v3/guild_manager.h"
#include "nel/3d/u_instance.h"
#include "main_loop.h"
// GAME SHARE
#include "game_share/bot_chat_types.h"
@ -41,6 +44,7 @@
// USING //
///////////
using namespace NLMISC;
using namespace NL3D;
////////////
@ -51,6 +55,9 @@ CContextualCursor ContextCur;
CLFECOMMON::TCLEntityId SlotUnderCursor;
uint32 MissionId = 0;
uint32 MissionRingId = 0;
UInstance selectedInstance;
const UInstance noSelectedInstance;
string selectedInstanceURL;
///////////////
@ -76,6 +83,7 @@ void contextTalk (bool rightClick, bool dblClick);
void contextExtractRM (bool rightClick, bool dblClick);
void contextMission (bool rightClick, bool dblClick);
void contextWebPage (bool rightClick, bool dblClick);
void contextWebIG (bool rightClick, bool dblClick);
void contextRingMission (bool rightClick, bool dblClick);
void contextOutpost (bool rightClick, bool dblClick);
void contextBuildTotem (bool rightClick, bool dblClick);
@ -113,6 +121,7 @@ void initContextualCursor()
ContextCur.add(true, "EXTRACT_RM", string("uimGcmExtractRM"), 0.0f, checkUnderCursor, contextExtractRM);
ContextCur.add(true, "MISSION", string(""), 0.0f, checkUnderCursor, contextMission);
ContextCur.add(true, "WEB PAGE", string(""), 0.0f, checkUnderCursor, contextWebPage);
ContextCur.add(true, "WEBIG", string(""), 0.0f, checkUnderCursor, contextWebIG);
ContextCur.add(true, "OUTPOST", string(""), 0.0f, checkUnderCursor, contextOutpost);
ContextCur.add(true, "RING MISSION", string(""), 0.0f, checkUnderCursor, contextRingMission);
ContextCur.add(true, "BUILD_TOTEM", string("uimGcmChooseBuilding"), 0.0f, checkUnderCursor, contextBuildTotem);
@ -510,9 +519,52 @@ void checkUnderCursor()
}
}
}
else
{
CShapeInstanceReference instref = EntitiesMngr.getShapeInstanceUnderPos(cursX, cursY);
UInstance instance = instref.Instance;
if (!instance.empty())
{
if (instance.getObjectPtr() != selectedInstance.getObjectPtr())
{
for(uint j=0;j<selectedInstance.getNumMaterials();j++)
{
// unhighlight
selectedInstance.getMaterial(j).setEmissive(CRGBA(255,255,255,255));
selectedInstance.getMaterial(j).setShininess( 10.0f );
}
selectedInstance = instance;
// For all materials
for(uint j=0;j<selectedInstance.getNumMaterials();j++)
{
// highlight
selectedInstance.getMaterial(j).setEmissive(CRGBA(255,0,0,255));
selectedInstance.getMaterial(j).setShininess( 1000.0f );
}
}
if (!instref.ContextText.empty())
{
selectedInstanceURL = instref.ContextURL;
if(ContextCur.context("WEBIG", 0.f, ucstring(instref.ContextText)))
return;
}
}
else
{
if (!selectedInstance.empty())
{
for(uint j=0;j<selectedInstance.getNumMaterials();j++)
{
//unhighlight
selectedInstance.getMaterial(j).setEmissive(CRGBA(255,255,255,255));
selectedInstance.getMaterial(j).setShininess( 10.0f );
}
selectedInstance = noSelectedInstance;
selectedInstanceURL = string("");
}
}
SlotUnderCursor = CLFECOMMON::INVALID_SLOT;
}
}
else
{
@ -778,7 +830,7 @@ void contextExtractRM(bool rightClick, bool dblClick)
return;
if( ClientCfg.DblClickMode && !dblClick)
return;
UserEntity->moveToExtractionPhrase(SlotUnderCursor, MaxExtractionDistance, ~0, ~0, true );
UserEntity->moveToExtractionPhrase(SlotUnderCursor, MaxExtractionDistance, std::numeric_limits<uint>::max(), std::numeric_limits<uint>::max(), true );
}
//-----------------------------------------------
@ -806,6 +858,29 @@ void contextWebPage(bool rightClick, bool dblClick)
UserEntity->moveTo(SlotUnderCursor, 3.0, CUserEntity::WebPage);
}// contextWebPage //
//-----------------------------------------------
// contextWebIG :
//-----------------------------------------------
void contextWebIG(bool rightClick, bool dblClick)
{
CInterfaceManager *IM = CInterfaceManager::getInstance();
CInterfaceElement *pGC = IM->getElementFromId("ui:interface:bot_chat_object");
CInterface3DShape *el= dynamic_cast<CInterface3DShape*>(IM->getElementFromId("ui:interface:bot_chat_object:scene3d:object"));
if (el != NULL)
el->setName(selectedInstance.getShapeName());
if (selectedInstanceURL.empty())
{
if (pGC != NULL)
pGC->setActive(true);
}
else
{
if (pGC != NULL)
pGC->setActive(false);
IM->runActionHandler("browse", NULL, "name=ui:interface:webig:content:html|url="+selectedInstanceURL);
}
}// contextWebIG //
//-----------------------------------------------
// contextOutpost
//-----------------------------------------------
@ -839,5 +914,5 @@ void contextBuildTotem(bool rightClick, bool dblClick)
return;
if( ClientCfg.DblClickMode && !dblClick)
return;
UserEntity->moveToTotemBuildingPhrase(SlotUnderCursor,MaxExtractionDistance, ~0, ~0, true );
UserEntity->moveToTotemBuildingPhrase(SlotUnderCursor,MaxExtractionDistance, std::numeric_limits<uint>::max(), std::numeric_limits<uint>::max(), true );
}// contextBuildTotem //

View file

@ -22,14 +22,6 @@
/////////////
#include "stdpch.h" // First include for pre-compiled headers.
#include <limits>
// OS.
#ifdef NL_OS_WINDOWS
# define NOMINMAX
# include <windows.h>
#endif
// Misc
#include "nel/misc/file.h"
#include "nel/misc/async_file_manager.h"
@ -689,6 +681,3 @@ bool verboseVPAdvanceTest(CEntityCL *en, uint32 form)
return false;
}
}

View file

@ -494,6 +494,90 @@ void CEntityManager::reinit()
initialize(_NbMaxEntity);
}
CShapeInstanceReference CEntityManager::createInstance(const string& shape, const CVector &pos, const string& text, const string& url, bool bbox_active)
{
CShapeInstanceReference nullinstref(UInstance(), string(""), string(""));
if (!Scene) return nullinstref;
UInstance instance = Scene->createInstance(shape);
if (text.empty())
bbox_active = false;
CShapeInstanceReference instref = CShapeInstanceReference(instance, text, url, bbox_active);
if(!instance.empty())
{
_ShapeInstances.push_back(instref);
}
return instref;
}
bool CEntityManager::removeInstances()
{
if (!Scene) return false;
// Remove all instances.
for(uint i=0; i<_ShapeInstances.size(); ++i)
{
if (!_ShapeInstances[i].Instance.empty())
Scene->deleteInstance(_ShapeInstances[i].Instance);
}
_ShapeInstances.clear();
return true;
}
CShapeInstanceReference CEntityManager::getShapeInstanceUnderPos(float x, float y)
{
CShapeInstanceReference selectedInstance(UInstance(), string(""), string(""));
_LastInstanceUnderPos= NULL;
// If not initialised, return
if (_ShapeInstances.empty())
return selectedInstance;
// build the ray
CMatrix camMatrix = MainCam.getMatrix();
CFrustum camFrust = MainCam.getFrustum();
CViewport viewport = Driver->getViewport();
// Get the Ray made by the mouse.
CVector pos, dir;
viewport.getRayWithPoint(x, y, pos, dir, camMatrix, camFrust);
// Normalize the direction.
dir.normalize();
// **** Get instances with box intersecting the ray.
float bestDist = 255;
for(uint i=0; i<_ShapeInstances.size(); i++)
{
if (_ShapeInstances[i].BboxActive)
{
H_AUTO(RZ_Client_GEUP_box_intersect)
// if intersect the bbox
NLMISC::CAABBox bbox;
//= _ShapeInstances[i].SelectionBox;
_ShapeInstances[i].Instance.getShapeAABBox(bbox);
if (bbox.getCenter() == CVector::Null)
{
bbox.setMinMax(CVector(-0.3f, -0.3f, -0.3f)+_ShapeInstances[i].Instance.getPos(), CVector(0.3f, 0.3f, 0.3f)+_ShapeInstances[i].Instance.getPos());
}
else
{
bbox.setMinMax((bbox.getMin()*_ShapeInstances[i].Instance.getScale().x)+_ShapeInstances[i].Instance.getPos(), (bbox.getMax()*_ShapeInstances[i].Instance.getScale().x)+_ShapeInstances[i].Instance.getPos());
}
if(bbox.intersect(pos, pos+dir*15.0f))
{
float dist = (bbox.getCenter()-pos).norm();
if (dist < bestDist)
{
selectedInstance = _ShapeInstances[i];
bestDist = dist;
}
}
}
}
return selectedInstance;
}
//-----------------------------------------------
// Create an entity according to the slot and the form.
// \param uint slot : slot for the entity.

View file

@ -35,6 +35,9 @@
#include "nel/misc/time_nl.h"
#include "nel/misc/vector.h"
#include "nel/misc/file.h"
#include "nel/misc/aabbox.h"
// 3D
#include "nel/3d/u_instance.h"
// Std.
#include <vector>
@ -82,8 +85,28 @@ public:
uint Slot;
};
/*
* Class to make cache shape instances
*/
class CShapeInstanceReference
{
public:
CShapeInstanceReference (NL3D::UInstance instance, const string &text, const string &url, bool bbox_active=true)
{
Instance = instance;
ContextText = text;
ContextURL = url;
BboxActive = bbox_active;
}
NL3D::UInstance Instance;
string ContextText;
string ContextURL;
bool BboxActive;
};
/**
* Class to manage entities.
* Class to manage entities and shapes instances.
* \author Guillaume PUZIN
* \author Nevrax France
* \date 2001
@ -103,6 +126,9 @@ private:
std::vector<CEntityReference> _ActiveEntities;
std::vector<CEntityReference> _VisibleEntities;
/// Shapes Instances caches
std::vector<CShapeInstanceReference> _ShapeInstances;
typedef struct
{
NLMISC::TGameCycle GC;
@ -120,6 +146,8 @@ private:
// For selection. NB: the pointer is just a cache. Must not be accessed
CEntityCL *_LastEntityUnderPos;
NL3D::UInstance _LastInstanceUnderPos;
//////////////
//// DEBUG ///
uint _NbUser;
@ -171,6 +199,11 @@ public:
/// Release + initialize
void reinit();
CShapeInstanceReference createInstance(const string& shape, const CVector &pos, const string &text, const string &url, bool active=true);
bool removeInstances();
CShapeInstanceReference getShapeInstanceUnderPos(float x, float y);
/**
* Create an entity according to the slot and the form.
* \param uint slot : slot for the entity.

View file

@ -2511,12 +2511,20 @@ NLMISC::CRGBA CEntityCL::getColor () const
{
if (isEnemy())
{
return _PvpEnemyColor;
if (getPvpMode()&PVP_MODE::PvpFactionFlagged || getPvpMode()&PVP_MODE::PvpChallenge)
return _PvpEnemyColor;
else
return CRGBA(min(255, _PvpEnemyColor.R+150), min(255, _PvpEnemyColor.G+150), min(255, _PvpEnemyColor.B+150),_PvpEnemyColor.A);
}
}
// neutral pvp
if (isNeutralPVP())
{
if (isInTeam())
return _PvpAllyInTeamColor;
if (isInGuild())
return _PvpAllyInGuildColor;
return _PvpNeutralColor;
}
// ally
@ -2526,7 +2534,11 @@ NLMISC::CRGBA CEntityCL::getColor () const
return _PvpAllyInTeamColor;
if(isInGuild())
return _PvpAllyInGuildColor;
return _PvpAllyColor;
if (getPvpMode()&PVP_MODE::PvpFactionFlagged)
return _PvpAllyColor;
else
return CRGBA(min(255, _PvpAllyColor.R+150), min(255, _PvpAllyColor.G+150), min(255, _PvpAllyColor.B+150),_PvpAllyColor.A);
}
// neutral
if (isInTeam())
@ -2795,9 +2807,11 @@ void CEntityCL::updateIsInTeam ()
presentProp && presentProp->getValueBool() )
{
_IsInTeam= true;
buildInSceneInterface();
return;
}
}
buildInSceneInterface();
}
//-----------------------------------------------
@ -3051,13 +3065,15 @@ void CEntityCL::updateVisiblePostPos(const NLMISC::TTime &/* currentTimeInMs */,
position = pos().asVector();
position.z= _SelectBox.getMin().z;
mat.setPos(position);
mat.setRot(dirMatrix());
_StateFX.setTransformMode(NL3D::UTransformable::DirectMatrix);
_StateFX.setMatrix(mat);
if (skeleton())
_StateFX.setClusterSystem(skeleton()->getClusterSystem());
}
else if (!_SelectionFX.empty() || !_MouseOverFX.empty())
if (!_SelectionFX.empty() || !_MouseOverFX.empty())
{
// Build a matrix for the fx
NLMISC::CMatrix mat;

View file

@ -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(); }
virtual bool isViewedAsFriend() const { return isNeutral() || isFriend() || isInTeam() || isInGuild(); }
/// Return the People for the entity (unknown by default)
virtual EGSPD::CPeople::TPeople people() const;
@ -760,6 +760,12 @@ public:
return _Title;
}
/// Return the raw unparsed entity title
const ucstring getTitleRaw() const
{
return ucstring(_TitleRaw);
}
/// Return true if this entity has a reserved title
bool hasReservedTitle() const { return _HasReservedTitle; }
@ -910,6 +916,7 @@ protected:
std::string _PermanentStatutIcon;
// Has reserved title?
bool _HasReservedTitle;
// Extended Name
ucstring _NameEx;
// String ID

View file

@ -965,7 +965,7 @@ void CFarTP::requestReturnToPreviousSession(TSessionId rejectedSessionId)
void CFarTP::requestReconnection()
{
_ReselectingChar = true;
requestFarTPToSession(TSessionId(~0u), ~0, CFarTP::JoinMainland, false);
requestFarTPToSession(TSessionId(std::numeric_limits<uint16>::max()), std::numeric_limits<uint8>::max(), CFarTP::JoinMainland, false);
}
@ -1060,9 +1060,10 @@ void CFarTP::disconnectFromPreviousShard()
// Play music and fade out the Game Sound
if (SoundMngr)
{
SoundMngr->playEventMusic(ClientCfg.SoundOutGameMusic, CSoundManager::LoadingMusicXFade, true); // Loading Music Loop.ogg
SoundMngr->fadeOutGameSound(ClientCfg.SoundTPFade);
// Loading Music Loop.ogg
LoadingMusic = ClientCfg.SoundOutGameMusic;
SoundMngr->playEventMusic(LoadingMusic, CSoundManager::LoadingMusicXFade, true);
SoundMngr->fadeOutGameSound(ClientCfg.SoundTPFade);
}
// Change the tips

View file

@ -142,7 +142,7 @@ void CFXManager::update()
while (!_DeferredFXByDate.empty())
{
if (T1 < (sint64)_DeferredFXByDate.begin()->first) break;
if (T1 < (uint)_DeferredFXByDate.begin()->first) break;
const CDeferredFX &fx = _DeferredFXByDate.begin()->second;
NL3D::UParticleSystemInstance fxInstance = instantFX(fx.FXName, fx.TimeOut);
if (!fxInstance.empty())
@ -231,7 +231,7 @@ void CFXManager::deferFX(const std::string &fxName, const NLMISC::CMatrix &matri
fx.FXName = fxName;
fx.Matrix = matrix;
fx.TimeOut = timeOut;
_DeferredFXByDate.insert(std::make_pair(T1 + sint64(1000.f * delayInSeconds), fx));
_DeferredFXByDate.insert(std::make_pair(T1 + uint64(1000.f * delayInSeconds), fx));
}

View file

@ -847,7 +847,7 @@ void CGameContextMenu::updateContextMenuTalkEntries(uint options)
{
if (ClientCfg.Local)
{
options = ~0; // in local mode, force all options to be shown (for debug)
options = std::numeric_limits<uint>::max(); // in local mode, force all options to be shown (for debug)
}
// news
_OkTextNews= ((options & (1 << BOTCHATTYPE::NewsFlag)));

View file

@ -1364,6 +1364,10 @@ void loadBackgroundBitmap (TBackground background)
string ext = CFile::getExtension (ClientCfg.Launch_BG);
string filename;
if (frand(2.0) < 1)
filename = name+"_0."+ext;
else
filename = name+"_1."+ext;
switch (background)
{
case ElevatorBackground:
@ -1397,13 +1401,6 @@ void loadBackgroundBitmap (TBackground background)
filename = ClientCfg.Loading_BG;
break;
default:
/*
if (frand(2.0) < 1)
filename = name+"_0."+ext;
else
filename = name+"_1."+ext;
*/
filename = name+"."+ext;
break;
}

View file

@ -445,7 +445,6 @@ void HandleSystemCursorCapture(const CEvent &event)
}
}
// *********************************************************************************
bool IsSystemCursorInClientArea()
{
@ -506,8 +505,6 @@ bool IsSystemCursorInClientArea()
return true;
}
sint CNiceInputAuto::_Count = 0;

View file

@ -2440,6 +2440,174 @@ class CAHTarget : public IActionHandler
};
REGISTER_ACTION_HANDLER (CAHTarget, "target");
class CAHAddShape : public IActionHandler
{
virtual void execute (CCtrlBase * /* pCaller */, const string &Params)
{
string sShape = getParam(Params, "shape");
if(sShape.empty())
{
nlwarning("Command 'add_shape': need at least the parameter shape.");
return;
}
if (!Scene)
{
nlwarning("No scene available");
return;
}
double x = UserEntity->pos().x;
double y = UserEntity->pos().y;
double z = UserEntity->pos().z;
CVector userDir = UserEntity->dir();
float s = 1.0f;
string skeleton = getParam(Params, "skeleton");
string c = getParam(Params, "text");
string u = getParam(Params, "url");
string texture_name = getParam(Params, "texture");
string highlight = getParam(Params, "texture");
string transparency = getParam(Params, "transparency");
if (!getParam(Params, "x").empty())
fromString(getParam(Params, "x"), x);
if (!getParam(Params, "y").empty())
fromString(getParam(Params, "y"), y);
if (!getParam(Params, "z").empty())
fromString(getParam(Params, "z"), z);
if (!getParam(Params, "scale").empty())
fromString(getParam(Params, "scale"), s);
if (!getParam(Params, "angle").empty())
{
float a;
fromString(getParam(Params, "angle"), a);
userDir = CVector(sin(a), cos(a), 0.f);
}
bool have_shapes = true;
bool first_shape = true;
while(have_shapes)
{
string shape;
string::size_type index = sShape.find(string(" "));
// multiple shapes/fx
if (index != string::npos)
{
shape = sShape.substr(0, index);
sShape = sShape.substr(index+1);
} else {
shape = sShape;
have_shapes = false;
}
CShapeInstanceReference instref = EntitiesMngr.createInstance(shape, CVector((float)x, (float)y, (float)z), c, u, first_shape);
UInstance instance = instref.Instance;
if(!instance.empty())
{
for(uint j=0;j<instance.getNumMaterials();j++)
{
if (highlight.empty())
{
instance.getMaterial(j).setAmbient(CRGBA(0,0,0,255));
instance.getMaterial(j).setShininess( 10.0f );
instance.getMaterial(j).setEmissive(CRGBA(255,255,255,255));
}
else
{
instance.getMaterial(j).setAmbient(CRGBA(0,0,0,255));
instance.getMaterial(j).setEmissive(CRGBA(255,0,0,255));
instance.getMaterial(j).setShininess( 1000.0f );
}
if (!texture_name.empty() && first_shape)
{
sint numStages = instance.getMaterial(j).getLastTextureStage() + 1;
for(sint l = 0; l < numStages; l++)
{
if (instance.getMaterial(j).isTextureFile((uint) l))
{
instance.getMaterial(j).setTextureFileName(texture_name, (uint) l);
}
}
}
}
first_shape = false;
if (transparency.empty())
::makeInstanceTransparent(instance, 255, false);
else
::makeInstanceTransparent(instance, 100, true);
instance.setClusterSystem(UserEntity->getClusterSystem()); // for simplicity, assume it is in the same
// cluster system than the user
// Compute the direction Matrix
CMatrix dir;
dir.identity();
CVector vi = userDir^CVector(0.f, 0.f, 1.f);
CVector vk = vi^userDir;
dir.setRot(vi, userDir, vk, true);
// Set Orientation : User Direction should be normalized.
if (!skeleton.empty())
{
USkeleton skel = Scene->createSkeleton(skeleton);
if (!skel.empty())
{
skel.bindSkin(instance);
skel.setClusterSystem(UserEntity->getClusterSystem());
skel.setScale(skel.getScale()*s);
skel.setPos(CVector((float)x, (float)y, (float)z));
skel.setRotQuat(dir.getRot());
}
} else {
instance.setScale(instance.getScale()*s);
instance.setPos(CVector((float)x, (float)y, (float)z));
instance.setRotQuat(dir.getRot());
}
// if the shape is a particle system, additionnal parameters are user params
UParticleSystemInstance psi;
psi.cast (instance);
/*if (!psi.empty())
{
// set each user param that is present
for(uint k = 0; k < 4; ++k)
{
if (args.size() >= (k + 2))
{
float uparam;
if (fromString(args[k + 1], uparam))
{
psi.setUserParam(k, uparam);
}
else
{
nlwarning("Cant read param %d", k);
}
}
}
}*/
}
else
nlwarning("Command 'add_shape': cannot find the shape %s.", sShape.c_str());
}
return;
}
};
REGISTER_ACTION_HANDLER (CAHAddShape, "add_shape");
class CAHRemoveShapes : public IActionHandler
{
virtual void execute (CCtrlBase * /* pCaller */, const string &Params)
{
EntitiesMngr.removeInstances();
}
};
REGISTER_ACTION_HANDLER (CAHRemoveShapes, "remove_shapes");
// ***************************************************************************
// See also CHandlerTeamTarget
class CAHTargetTeammateShortcut : public IActionHandler

View file

@ -104,7 +104,9 @@ static void setupMissionHelp(CSheetHelpSetup &setup);
#define INFO_LIST_BRICK_REQUIREMENT "list_brick_requirement"
#define INFO_GROUP_MP_STAT "mp_stats"
#define INFO_GROUP_CHAR_3D "char3d"
#define INFO_ITEM_PREVIEW "item_preview"
#define INFO_ITEM_PREVIEW_SCENE_3D "scene_item_preview"
#define ITEM_PREVIEW_WIDTH 200
// ***************************************************************************
std::deque<uint> CInterfaceHelp::_ActiveWindows;
@ -2178,6 +2180,14 @@ void resetSheetHelp(CSheetHelpSetup &setup)
{
listItem->setActive(false);
}
// Hide the item preview by default
CInterfaceElement *elt= group->getElement(group->getId()+setup.PrefixForExtra+INFO_ITEM_PREVIEW);
if(elt)
{
elt->setActive(false);
}
// Hide the list of brick by default
IListSheetBase *listBrick= dynamic_cast<IListSheetBase*>(group->getElement(group->getId()+setup.PrefixForExtra+INFO_LIST_BRICK));
if(listBrick)
@ -2268,6 +2278,151 @@ void setupCosmetic(CSheetHelpSetup &setup, CItemSheet *pIS)
}
}
// ***************************************************************************
void setupItemPreview(CSheetHelpSetup &setup, CItemSheet *pIS)
{
nlassert(pIS);
CInterfaceManager *pIM = CInterfaceManager::getInstance();
CCDBNodeBranch *dbBranch = pIM->getDbBranch( setup.SrcSheet->getSheet() );
CInterfaceElement *elt = setup.HelpWindow->getElement(setup.HelpWindow->getId()+setup.PrefixForExtra+INFO_ITEM_PREVIEW);
if (elt == NULL)
return;
CInterfaceGroup *ig = dynamic_cast<CInterfaceGroup*>(elt);
if ( ! ig)
{
return;
}
static sint32 helpWidth = setup.HelpWindow->getW();
bool scene_inactive = ! pIM->getDbProp("UI:SAVE:SHOW_3D_ITEM_PREVIEW")->getValueBool();
if (scene_inactive ||
(pIS->Family != ITEMFAMILY::ARMOR &&
pIS->Family != ITEMFAMILY::MELEE_WEAPON &&
pIS->Family != ITEMFAMILY::RANGE_WEAPON &&
pIS->Family != ITEMFAMILY::SHIELD))
{
setup.HelpWindow->setW(helpWidth);
ig->setActive(false);
return;
}
else
{
setup.HelpWindow->setW(helpWidth + ITEM_PREVIEW_WIDTH);
ig->setActive(true);
}
CInterface3DScene *sceneI = dynamic_cast<CInterface3DScene *>(ig->getGroup("scene_item_preview"));
if (!sceneI)
{
nlwarning("Can't retrieve character 3d view, or bad type");
ig->setActive(false);
return;
}
CInterface3DCharacter *char3DI = NULL;
if (sceneI->getCharacter3DCount() != 0)
char3DI = sceneI->getCharacter3D(0);
if (char3DI == NULL)
{
nlwarning("Can't retrieve char 3D Interface");
ig->setActive(false);
return;
}
CInterface3DCamera *camera = sceneI->getCamera(0);
if (camera == NULL)
{
nlwarning("Can't retrieve camera");
ig->setActive(false);
return;
}
SCharacter3DSetup c3Ds;
CCharacterSummary cs;
SCharacter3DSetup::setupCharacterSummaryFromSERVERDB( cs );
float camHeight = -0.85f;
if (pIS->Family == ITEMFAMILY::ARMOR)
{
if (pIS->ItemType == ITEM_TYPE::LIGHT_BOOTS || pIS->ItemType == ITEM_TYPE::MEDIUM_BOOTS || pIS->ItemType == ITEM_TYPE::HEAVY_BOOTS)
{
CCDBNodeLeaf *color = dbBranch->getLeaf( setup.SrcSheet->getSheet()+":USER_COLOR", false );
cs.VisualPropB.PropertySubData.FeetModel = CVisualSlotManager::getInstance()->sheet2Index( CSheetId(setup.SrcSheet->getSheetId()), SLOTTYPE::FEET_SLOT );
cs.VisualPropB.PropertySubData.FeetColor = color->getValue32();
SCharacter3DSetup::setupDBFromCharacterSummary("UI:TEMP:CHAR3D", cs);
camHeight = -1.15f;
}
else if (pIS->ItemType == ITEM_TYPE::LIGHT_GLOVES || pIS->ItemType == ITEM_TYPE::MEDIUM_GLOVES || pIS->ItemType == ITEM_TYPE::HEAVY_GLOVES)
{
CCDBNodeLeaf *color = dbBranch->getLeaf( setup.SrcSheet->getSheet()+":USER_COLOR", false );
cs.VisualPropB.PropertySubData.HandsModel = CVisualSlotManager::getInstance()->sheet2Index( CSheetId(setup.SrcSheet->getSheetId()), SLOTTYPE::HANDS_SLOT );
cs.VisualPropB.PropertySubData.HandsColor = color->getValue32();
SCharacter3DSetup::setupDBFromCharacterSummary("UI:TEMP:CHAR3D", cs);
//cs.VisualPropB.PropertySubData.HandsColor = pIS->Color;
}
else if (pIS->ItemType == ITEM_TYPE::LIGHT_SLEEVES || pIS->ItemType == ITEM_TYPE::MEDIUM_SLEEVES || pIS->ItemType == ITEM_TYPE::HEAVY_SLEEVES)
{
CCDBNodeLeaf *color = dbBranch->getLeaf( setup.SrcSheet->getSheet()+":USER_COLOR", false );
cs.VisualPropA.PropertySubData.ArmModel = CVisualSlotManager::getInstance()->sheet2Index( CSheetId(setup.SrcSheet->getSheetId()), SLOTTYPE::ARMS_SLOT );
SCharacter3DSetup::setupDBFromCharacterSummary("UI:TEMP:CHAR3D", cs);
SCharacter3DSetup::setDB("UI:TEMP:CHAR3D:VPA:ARMCOLOR", pIS->Color);
//cs.VisualPropA.PropertySubData.ArmColor = pIS->Color;
camHeight = -0.55f;
}
else if (pIS->ItemType == ITEM_TYPE::LIGHT_PANTS || pIS->ItemType == ITEM_TYPE::MEDIUM_PANTS || pIS->ItemType == ITEM_TYPE::HEAVY_PANTS)
{
CCDBNodeLeaf *color = dbBranch->getLeaf( setup.SrcSheet->getSheet()+":USER_COLOR", false );
cs.VisualPropA.PropertySubData.TrouserModel = CVisualSlotManager::getInstance()->sheet2Index( CSheetId(setup.SrcSheet->getSheetId()), SLOTTYPE::LEGS_SLOT );
cs.VisualPropA.PropertySubData.TrouserColor = color->getValue32();
SCharacter3DSetup::setupDBFromCharacterSummary("UI:TEMP:CHAR3D", cs);
camHeight = -1.00f;
}
else if (pIS->ItemType == ITEM_TYPE::LIGHT_VEST || pIS->ItemType == ITEM_TYPE::MEDIUM_VEST || pIS->ItemType == ITEM_TYPE::HEAVY_VEST)
{
CCDBNodeLeaf *color = dbBranch->getLeaf( setup.SrcSheet->getSheet()+":USER_COLOR", false );
cs.VisualPropA.PropertySubData.JacketModel = CVisualSlotManager::getInstance()->sheet2Index( CSheetId(setup.SrcSheet->getSheetId()), SLOTTYPE::CHEST_SLOT );
cs.VisualPropA.PropertySubData.JacketColor = color->getValue32();
SCharacter3DSetup::setupDBFromCharacterSummary("UI:TEMP:CHAR3D", cs);
camHeight = -0.55f;
}
else if (pIS->ItemType == ITEM_TYPE::HEAVY_HELMET)
{
CCDBNodeLeaf *color = dbBranch->getLeaf( setup.SrcSheet->getSheet()+":USER_COLOR", false );
cs.VisualPropA.PropertySubData.HatModel = CVisualSlotManager::getInstance()->sheet2Index( CSheetId(setup.SrcSheet->getSheetId()), SLOTTYPE::HEAD_SLOT );
cs.VisualPropA.PropertySubData.HatColor = color->getValue32();
SCharacter3DSetup::setupDBFromCharacterSummary("UI:TEMP:CHAR3D", cs);
camHeight = -0.35f;
}
}
else if (pIS->Family == ITEMFAMILY::SHIELD)
{
cs.VisualPropA.PropertySubData.WeaponLeftHand = CVisualSlotManager::getInstance()->sheet2Index( CSheetId(setup.SrcSheet->getSheetId()), SLOTTYPE::LEFT_HAND_SLOT );
SCharacter3DSetup::setupDBFromCharacterSummary("UI:TEMP:CHAR3D", cs);
}
else if (pIS->Family == ITEMFAMILY::MELEE_WEAPON || pIS->Family == ITEMFAMILY::RANGE_WEAPON)
{
cs.VisualPropA.PropertySubData.WeaponRightHand = CVisualSlotManager::getInstance()->sheet2Index( CSheetId(setup.SrcSheet->getSheetId()), SLOTTYPE::RIGHT_HAND_SLOT );
SCharacter3DSetup::setupDBFromCharacterSummary("UI:TEMP:CHAR3D", cs);
}
else
nlwarning("<setupItemPreview> Invalid armour or weapon item type '%s'", ITEM_TYPE::toString( pIS->ItemType ).c_str() );
if (camera == NULL)
return;
camera->setTgtZ(camHeight);
char3DI->setAnim(CAnimationStateSheet::Idle);
}
// ***************************************************************************
void refreshItemHelp(CSheetHelpSetup &setup)
{
@ -2291,6 +2446,9 @@ void refreshItemHelp(CSheetHelpSetup &setup)
// ---- Cosmetic only
setupCosmetic (setup, pIS);
// ---- item preview
setupItemPreview(setup, pIS);
}
// if this is a R2 plot item, Add comment and description

View file

@ -327,10 +327,10 @@ uint32 CBotChatPageTrade::getCurrItemQuantity() const
// TODO: edit box in faction points?
CGroupEditBox *ed = dynamic_cast<CGroupEditBox *>(ig->getGroup("header_opened:standard_price:quantity:edit:eb"));
if (!ed) return ~0;
int intQuantity;
uint32 intQuantity;
if (fromString(ed->getInputString().toString(), intQuantity))
{
return (uint32) intQuantity;
return intQuantity;
}
else
{
@ -375,7 +375,7 @@ uint32 CBotChatPageTrade::getCurrItemPriceResale() const
// ***************************************************************************************
uint64 CBotChatPageTrade::getCurrItemPrice(bool mulByFame) const
{
if (!_CurrItemSheet) return ~0;
if (!_CurrItemSheet) return std::numeric_limits<uint64>::max();
if (_BuyDlgOn && (_BuyMean == MoneyGuildXP || _BuyMean == GuildMoneyGuildXP || _BuyMean == GuildMoney) )
{
if (_BuyMean == MoneyGuildXP)
@ -419,7 +419,7 @@ uint64 CBotChatPageTrade::getCurrItemPrice(bool mulByFame) const
}
}
}
return ~0;
return std::numeric_limits<uint64>::max();
}
// ***************************************************************************************
@ -440,7 +440,7 @@ uint64 CBotChatPageTrade::getCurrItemXP() const
return 0; // By now no need for XP even if xp guild required
}
return ~0;
return std::numeric_limits<uint64>::max();
}
@ -809,11 +809,11 @@ void CBotChatPageTrade::updateTradeModal()
if (cantTradeButton) cantTradeButton->setText(CI18N::get("uiWontBuyThis"));
if (cantTradeButton) cantTradeButton->setDefaultContextHelp(CI18N::get("uittWontBuyThis"));
}
else if (_SellDlgOn && priceWithoutFame == ~0)
else if (_SellDlgOn && priceWithoutFame == std::numeric_limits<uint64>::max())
{
if (cantTradeButton) cantTradeButton->setText(CI18N::get("uiPriceNotReceived"));
}
else if (quantity == 0 || quantity == ~0)
else if (quantity == 0 || quantity == std::numeric_limits<uint32>::max())
{
if (cantTradeButton) cantTradeButton->setText(CI18N::get("uiBadQuantity"));
if (cantTradeButton) cantTradeButton->setDefaultContextHelp(CI18N::get("uittBadQuantity"));
@ -1100,7 +1100,7 @@ bool CBotChatPageTrade::isTradeValid( bool enableResale ) const
getCurrItemFactionTypePoints(fpType, fpCost);
// if price/quantity is valid
bool validSetup= priceWithoutFame != ~0 && quantity != ~0 && quantity != 0;
bool validSetup= priceWithoutFame != std::numeric_limits<uint64>::max() && quantity != std::numeric_limits<uint32>::max() && quantity != 0;
if(validSetup && _BuyMean==MoneyFactionPoints)
{
// valid if at least one price type is not 0
@ -1179,7 +1179,7 @@ void CBotChatPageTrade::confirmTrade( bool enableResale )
{
uint32 quantity = getCurrItemQuantity();
sint32 resalePrice = resaleEnabled ? getCurrItemPriceResale() : 0; // getCurrItemPriceResale() returns 0 is !_ResaleEdit
if (quantity != ~0)
if (quantity != std::numeric_limits<uint32>::max())
{
uint16 u16Quantity = (uint16) quantity;
// The Item bought is a SPhrase ?
@ -2120,7 +2120,7 @@ void CBotChatPageTrade::startDestroyItemDialog()
// setup the quantity to destroy (if edited correctly)
uint32 quantity= getCurrItemQuantity();
if(quantity==0 || quantity==~0)
if(quantity==0 || quantity==std::numeric_limits<uint32>::max())
return;
// if quantity check, maximize with it (if user entered to big value...)
if(_QuantityCheck)
@ -2144,7 +2144,7 @@ void CBotChatPageTrade::confirmDestroyItemDialog()
// get the quantity destroyed
uint32 quantity= getCurrItemQuantity();
// if correct quantity
if(quantity!=0 && quantity!=~0)
if(quantity!=0 && quantity!=std::numeric_limits<uint32>::max())
{
// if quantity check, maximize with it (if user entered too big value...)
if(_QuantityCheck)
@ -2190,7 +2190,7 @@ void CBotChatPageTrade::confirmDestroyItemDialog()
pIM->disableModalWindow();
// if the quantity entered was correct
if(quantity!=0 && quantity!=~0)
if(quantity!=0 && quantity!=std::numeric_limits<uint32>::max())
{
// close also the container modal
endTradeModal();

View file

@ -312,8 +312,7 @@ void CChatTargetFilter::msgEntered(const ucstring &msg, CChatWindow *chatWindow)
else if (!_TargetPlayer.empty())
{
// the target must be a player, make a tell on him
// TODO: adapt this to unicode when this is OK on server side
ChatMngr.tell(_TargetPlayer.toString(), msg.toString());
ChatMngr.tell(_TargetPlayer.toString(), msg);
// direct output in the chat
chatWindow->displayLocalPlayerTell(msg);
}

View file

@ -472,7 +472,14 @@ void CChatWindow::displayLocalPlayerTell(const ucstring &msg, uint numBlinks /*=
CInterfaceProperty prop;
prop.readRGBA("UI:SAVE:CHAT:COLORS:SPEAKER"," ");
encodeColorTag(prop.getRGBA(), finalMsg, false);
finalMsg += CI18N::get("youTell") + ": ";
ucstring cur_time;
if (CInterfaceManager::getInstance()->getDbProp("UI:SAVE:CHAT:SHOW_TIMES_IN_CHAT_CB", false)->getValueBool())
{
cur_time = CInterfaceManager::getTimestampHuman();
}
ucstring csr;
if (CHARACTER_TITLE::isCsrTitle(UserEntity->getTitleRaw())) csr += ucstring("(CSR) ");
finalMsg += cur_time + csr + CI18N::get("youTell") + ": ";
prop.readRGBA("UI:SAVE:CHAT:COLORS:TELL"," ");
encodeColorTag(prop.getRGBA(), finalMsg, true);
finalMsg += msg;
@ -1241,6 +1248,13 @@ public:
return;
}
// Parse any tokens in the text
if ( ! CInterfaceManager::parseTokens(text))
{
pEB->setInputString (string(""));
return;
}
// if, it s a command, execute it and don't send the command to the server
if(text[0] == '/')
{
@ -1256,7 +1270,7 @@ public:
else
{
CInterfaceManager *im = CInterfaceManager::getInstance();
im->displaySystemInfo (ucstring(cmd+" : ")+CI18N::get ("uiCommandNotExists"));
im->displaySystemInfo (ucstring(cmd+": ")+CI18N::get ("uiCommandNotExists"));
}
}
else

View file

@ -40,6 +40,11 @@ void CEventDescriptorKey::init(const NLMISC::CEventKey &ev)
_KeyEvent = keydown;
_Key = ((const NLMISC::CEventKeyDown &) ev).Key;
}
else if (ev == NLMISC::EventStringId)
{
_KeyEvent = keystring;
_String = ((const NLMISC::CEventString &) ev).String;
}
else
{
_KeyEvent = unknown;

View file

@ -54,6 +54,7 @@ public:
keydown = 0, // a key has been press down. The key value is stored as a TKey
keyup, // a key has been released. The key value is stored as a TKey
keychar, // a key has been stroke. The key is a ucchar
keystring, // a string has been sent. The string is a ucstring
unknown, // uninitialized event
};
CEventDescriptorKey() : _KeyEvent(unknown)
@ -80,6 +81,12 @@ public:
nlassert(_KeyEvent == keychar);
return _Char;
}
// return the string that has been sent. The key event type MUST be 'keystring', else => assert
ucstring getString() const
{
nlassert(_KeyEvent == keystring);
return _String;
}
bool getKeyCtrl() const // is CTRL pressed ?
{
return _CtrlState;
@ -102,9 +109,10 @@ private:
bool _AltState;
union
{
NLMISC::TKey _Key;
ucchar _Char;
NLMISC::TKey _Key;
ucchar _Char;
};
ucstring _String;
};
// ----------------------------------------------------------------------------

View file

@ -332,7 +332,7 @@ void CGroupEditBox::copy()
stopParentBlink();
// get the selection and copy it
if (CSystemUtils::copyTextToClipboard(getSelection()))
if (Driver->copyTextToClipboard(getSelection()))
nlinfo ("Chat input was copied in the clipboard");
}
@ -347,155 +347,163 @@ void CGroupEditBox::paste()
}
cutSelection();
}
stopParentBlink();
makeTopWindow();
ucstring sString;
if (CSystemUtils::pasteTextFromClipboard(sString))
if (Driver->pasteTextFromClipboard(sString))
{
sint length = (sint)sString.length();
ucstring toAppend;
// filter character depending on the netry type
switch (_EntryType)
{
case Text:
case Password:
{
if (_NegativeFilter.empty())
{
toAppend = sString;
}
else
{
for (sint k = 0; k < length; ++k)
{
if (!isFiltered(sString[k]))
{
toAppend += sString[k];
}
}
}
// remove '\r' characters
toAppend.erase(std::remove(toAppend.begin(), toAppend.end(), (ucchar) '\r'), toAppend.end());
}
break;
case PositiveInteger:
case PositiveFloat:
{
for (sint k = 0; k < length; ++k)
{
if (isdigit(sString[k]) || sString[k]== ' ' ||
(_EntryType==PositiveFloat && sString[k]=='.') )
{
if (!isFiltered(sString[k]))
{
toAppend += sString[k];
}
}
}
}
break;
case Integer:
case Float:
{
for (sint k = 0; k < length; ++k)
{
if (isdigit(sString[k]) || sString[k]== ' ' || sString[k]== '-' ||
(_EntryType==Float && sString[k]=='.') )
{
if (!isFiltered(sString[k]))
{
toAppend += sString[k];
}
}
}
}
break;
case AlphaNumSpace:
{
for (sint k = 0; k < length; ++k)
{
if (isValidAlphaNumSpace(sString[k]))
{
if (!isFiltered(sString[k]))
{
toAppend += sString[k];
}
}
}
}
break;
case AlphaNum:
{
for (sint k = 0; k < length; ++k)
{
if (isValidAlphaNum(sString[k]))
{
if (!isFiltered(sString[k]))
{
toAppend += sString[k];
}
}
}
}
break;
case Alpha:
{
for (sint k = 0; k < length; ++k)
{
if (isValidAlpha(sString[k]))
{
if (!isFiltered(sString[k]))
{
toAppend += sString[k];
}
}
}
}
break;
case Filename:
{
for (sint k = 0; k < length; ++k)
{
if (isValidFilenameChar(sString[k]))
{
if (!isFiltered(sString[k]))
{
toAppend += sString[k];
}
}
}
}
break;
case PlayerName:
{
for (sint k = 0; k < length; ++k)
{
if (isValidPlayerNameChar(sString[k]))
{
if (!isFiltered(sString[k]))
{
toAppend += sString[k];
}
}
}
}
}
length = (sint)toAppend.size();
if ((uint) (_InputString.length() + length) > _MaxNumChar)
{
length = _MaxNumChar - (sint)_InputString.length();
}
ucstring toAdd = toAppend.substr(0, length);
_InputString = _InputString.substr(0, _CursorPos) + toAdd + _InputString.substr(_CursorPos);
_CursorPos += (sint32)toAdd.length();
nlinfo ("Chat input was pasted from the clipboard");
triggerOnChangeAH();
// append string now
appendString(sString);
}
}
// ----------------------------------------------------------------------------
void CGroupEditBox::appendString(const ucstring &str)
{
stopParentBlink();
makeTopWindow();
sint length = (sint)str.length();
ucstring toAppend;
// filter character depending on the entry type
switch (_EntryType)
{
case Text:
case Password:
{
if (_NegativeFilter.empty())
{
toAppend = str;
}
else
{
for (sint k = 0; k < length; ++k)
{
if (!isFiltered(str[k]))
{
toAppend += str[k];
}
}
}
// remove '\r' characters
toAppend.erase(std::remove(toAppend.begin(), toAppend.end(), (ucchar) '\r'), toAppend.end());
}
break;
case PositiveInteger:
case PositiveFloat:
{
for (sint k = 0; k < length; ++k)
{
if (isdigit(str[k]) || str[k]== ' ' ||
(_EntryType==PositiveFloat && str[k]=='.') )
{
if (!isFiltered(str[k]))
{
toAppend += str[k];
}
}
}
}
break;
case Integer:
case Float:
{
for (sint k = 0; k < length; ++k)
{
if (isdigit(str[k]) || str[k]== ' ' || str[k]== '-' ||
(_EntryType==Float && str[k]=='.') )
{
if (!isFiltered(str[k]))
{
toAppend += str[k];
}
}
}
}
break;
case AlphaNumSpace:
{
for (sint k = 0; k < length; ++k)
{
if (isValidAlphaNumSpace(str[k]))
{
if (!isFiltered(str[k]))
{
toAppend += str[k];
}
}
}
}
break;
case AlphaNum:
{
for (sint k = 0; k < length; ++k)
{
if (isValidAlphaNum(str[k]))
{
if (!isFiltered(str[k]))
{
toAppend += str[k];
}
}
}
}
break;
case Alpha:
{
for (sint k = 0; k < length; ++k)
{
if (isValidAlpha(str[k]))
{
if (!isFiltered(str[k]))
{
toAppend += str[k];
}
}
}
}
break;
case Filename:
{
for (sint k = 0; k < length; ++k)
{
if (isValidFilenameChar(str[k]))
{
if (!isFiltered(str[k]))
{
toAppend += str[k];
}
}
}
}
break;
case PlayerName:
{
for (sint k = 0; k < length; ++k)
{
if (isValidPlayerNameChar(str[k]))
{
if (!isFiltered(str[k]))
{
toAppend += str[k];
}
}
}
}
}
length = (sint)toAppend.size();
if ((uint) (_InputString.length() + length) > _MaxNumChar)
{
length = _MaxNumChar - (sint)_InputString.length();
}
ucstring toAdd = toAppend.substr(0, length);
_InputString = _InputString.substr(0, _CursorPos) + toAdd + _InputString.substr(_CursorPos);
_CursorPos += (sint32)toAdd.length();
nlinfo ("Chat input was pasted from the clipboard");
triggerOnChangeAH();
_CursorAtPreviousLineEnd = false;
}
@ -610,6 +618,8 @@ void CGroupEditBox::handleEventChar(const CEventDescriptorKey &rEDK)
if (!isValidPlayerNameChar(c))
return;
break;
default:
break;
}
// verify integer bounds
if(_EntryType==Integer && (_IntegerMinValue!=INT_MIN || _IntegerMaxValue!=INT_MAX))
@ -658,6 +668,11 @@ void CGroupEditBox::handleEventChar(const CEventDescriptorKey &rEDK)
}
}
// ----------------------------------------------------------------------------
void CGroupEditBox::handleEventString(const CEventDescriptorKey &rEDK)
{
appendString(rEDK.getString());
}
// ----------------------------------------------------------------------------
bool CGroupEditBox::undo()
@ -720,7 +735,7 @@ bool CGroupEditBox::expand()
if (_InputString[0] == '/')
{
makeTopWindow();
// for french or deutch, be aware of unicode
// for french, deutsch and russian, be aware of unicode
std::string command = ucstring(_InputString.substr(1)).toUtf8();
ICommand::expand(command);
// then back to ucstring
@ -788,12 +803,14 @@ bool CGroupEditBox::handleEvent (const CEventDescriptor& event)
switch(rEDK.getKeyEventType())
{
case CEventDescriptorKey::keychar: handleEventChar(rEDK); break;
case CEventDescriptorKey::keystring: handleEventString(rEDK); break;
default: break;
}
// update the text
setInputString(_InputString);
// if event of type char, consider handle all of them
if( rEDK.getKeyEventType()==CEventDescriptorKey::keychar )
// if event of type char or string, consider handle all of them
if( rEDK.getKeyEventType()==CEventDescriptorKey::keychar || rEDK.getKeyEventType()==CEventDescriptorKey::keystring )
return true;
// Else filter the EventKeyDown AND EventKeyUp.
else
@ -1089,16 +1106,16 @@ void CGroupEditBox::setInputStringAsInt(sint32 val)
// ***************************************************************************
sint64 CGroupEditBox::getInputStringAsInt64() const
{
sint32 value;
{
sint64 value;
fromString(_InputString.toString(), value);
return value;
}
// ***************************************************************************
void CGroupEditBox::setInputStringAsInt64(sint64 val)
{
setInputString(NLMISC::toString(val));
{
setInputString(NLMISC::toString(val));
}
// ***************************************************************************

View file

@ -20,6 +20,7 @@
#define RZ_CTRL_EDITBOX_H
#include "interface_group.h"
#include "nel/3d/u_texture.h"
class CEventDescriptor;
@ -288,8 +289,10 @@ private:
void setupDisplayText();
void makeTopWindow();
void handleEventChar(const CEventDescriptorKey &event);
void handleEventString(const CEventDescriptorKey &event);
void setup();
void triggerOnChangeAH();
void appendString(const ucstring &str);
ucstring getSelection();

View file

@ -45,6 +45,10 @@ extern "C"
#include "lua_ihm.h"
#include "../time_client.h"
#include "nel/misc/i18n.h"
#include "nel/misc/md5.h"
#include "nel/3d/texture_file.h"
#include "nel/misc/big_file.h"
using namespace std;
using namespace NLMISC;
@ -107,15 +111,106 @@ void CGroupHTML::addImageDownload(const string &url, CViewBase *img)
curl_easy_setopt(curl, CURLOPT_FILE, fp);
curl_multi_add_handle(MultiCurl, curl);
Curls.push_back(CImageDownload(curl, url, fp, img));
Curls.push_back(CDataDownload(curl, url, fp, ImgType, img));
#ifdef LOG_DL
nlwarning("adding handle %x, %d curls", curl, Curls.size());
#endif
RunningCurls++;
}
// Call this evenly to check if an image in downloaded and then display it
void CGroupHTML::checkImageDownload()
void CGroupHTML::initImageDownload()
{
#ifdef LOG_DL
nlwarning("Init Image Download");
#endif
/*
// Get current flag
int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
// Turn on leak-checking bit
tmpFlag |= _CRTDBG_CHECK_ALWAYS_DF;
// Set flag to the new value
_CrtSetDbgFlag( tmpFlag );
*/
string pathName = "cache";
if ( ! CFile::isExists( pathName ) )
CFile::createDirectory( pathName );
}
// Get an url and return the local filename with the path where the bnp should be
string CGroupHTML::localBnpName(const string &url)
{
size_t lastIndex = url.find_last_of("/");
string dest = "user/"+url.substr(lastIndex+1);
return dest;
}
// Add a bnp download request in the multi_curl
void CGroupHTML::addBnpDownload(const string &url, const string &action)
{
// Search if we are not already downloading this url.
for(uint i = 0; i < Curls.size(); i++)
{
if(Curls[i].url == url)
{
#ifdef LOG_DL
nlwarning("already downloading '%s'", url.c_str());
#endif
return;
}
}
CURL *curl = curl_easy_init();
if (!MultiCurl || !curl)
return;
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, true);
curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
string dest = localBnpName(url);
#ifdef LOG_DL
nlwarning("add to download '%s' dest '%s'", url.c_str(), dest.c_str());
#endif
// create the local file
if (NLMISC::CFile::fileExists(dest))
{
if (action == "override" || action == "delete")
{
CFile::setRWAccess(dest);
NLMISC::CFile::deleteFile(dest.c_str());
}
}
if (action != "delete")
{
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, BnpType, NULL));
#ifdef LOG_DL
nlwarning("adding handle %x, %d curls", curl, Curls.size());
#endif
RunningCurls++;
}
}
void CGroupHTML::initBnpDownload()
{
#ifdef LOG_DL
nlwarning("Init Bnp Download");
#endif
string pathName = "user";
if ( ! CFile::isExists( pathName ) )
CFile::createDirectory( pathName );
}
// Call this evenly to check if an element is downloaded and then manage it
void CGroupHTML::checkDownloads()
{
//nlassert(_CrtCheckMemory());
@ -142,7 +237,7 @@ void CGroupHTML::checkImageDownload()
{
if (msg->msg == CURLMSG_DONE)
{
for (vector<CImageDownload>::iterator it=Curls.begin(); it<Curls.end(); it++)
for (vector<CDataDownload>::iterator it=Curls.begin(); it<Curls.end(); it++)
{
if(msg->easy_handle == it->curl)
{
@ -156,58 +251,87 @@ void CGroupHTML::checkImageDownload()
#endif
curl_easy_cleanup(it->curl);
string image = localImageName(it->url);
string file;
if(CURLE_OK != res || r < 200 || r >= 300)
if (it->type == ImgType)
file = localImageName(it->url)+".tmp";
else
file = localBnpName(it->url);
if(res != CURLE_OK || r < 200 || r >= 300)
{
NLMISC::CFile::deleteFile((image+".tmp").c_str());
NLMISC::CFile::deleteFile(file.c_str());
}
else
{
string finalUrl;
CFile::moveFile(image.c_str(), (image+".tmp").c_str());
if (lookupLocalFile (finalUrl, image.c_str(), false))
if (it->type == ImgType)
{
for(uint i = 0; i < it->imgs.size(); i++)
string image = localImageName(it->url);
CFile::moveFile(image.c_str(), (image+".tmp").c_str());
if (lookupLocalFile (finalUrl, image.c_str(), false))
{
// don't display image that are not power of 2
uint32 w, h;
CBitmap::loadSize (image, w, h);
if (w == 0 || h == 0 || ((!NLMISC::isPowerOf2(w) || !NLMISC::isPowerOf2(h)) && !NL3D::CTextureFile::supportNonPowerOfTwoTextures()))
image.clear();
for(uint i = 0; i < it->imgs.size(); i++)
{
// don't display image that are not power of 2
uint32 w, h;
CBitmap::loadSize (image, w, h);
if (w == 0 || h == 0 || ((!NLMISC::isPowerOf2(w) || !NLMISC::isPowerOf2(h)) && !NL3D::CTextureFile::supportNonPowerOfTwoTextures()))
image.clear();
CCtrlButton *btn = dynamic_cast<CCtrlButton*>(it->imgs[i]);
if(btn)
{
#ifdef LOG_DL
nlwarning("refresh new downloading image %d button %p", i, it->imgs[i]);
#endif
btn->setTexture (image);
btn->setTexturePushed(image);
btn->invalidateCoords();
btn->invalidateContent();
btn->resetInvalidCoords();
btn->updateCoords();
paragraphChange();
}
else
{
CViewBitmap *btm = dynamic_cast<CViewBitmap*>(it->imgs[i]);
if(btm)
CCtrlButton *btn = dynamic_cast<CCtrlButton*>(it->imgs[i]);
if(btn)
{
#ifdef LOG_DL
nlwarning("refresh new downloading image %d image %p", i, it->imgs[i]);
#endif
btm->setTexture (image);
btm->invalidateCoords();
btm->invalidateContent();
btm->resetInvalidCoords();
btm->updateCoords();
#ifdef LOG_DL
nlwarning("refresh new downloading image %d button %p", i, it->imgs[i]);
#endif
btn->setTexture (image);
btn->setTexturePushed(image);
btn->invalidateCoords();
btn->invalidateContent();
btn->resetInvalidCoords();
btn->updateCoords();
paragraphChange();
}
else
{
CViewBitmap *btm = dynamic_cast<CViewBitmap*>(it->imgs[i]);
if(btm)
{
#ifdef LOG_DL
nlwarning("refresh new downloading image %d image %p", i, it->imgs[i]);
#endif
btm->setTexture (image);
btm->invalidateCoords();
btm->invalidateContent();
btm->resetInvalidCoords();
btm->updateCoords();
paragraphChange();
}
}
}
}
}
else
{
if (lookupLocalFile (finalUrl, file.c_str(), false))
{
nlinfo("BNPCHECK : downloaded");
bool memoryCompressed = CPath::isMemoryCompressed();
if (memoryCompressed)
{
CPath::memoryUncompress();
}
CPath::addSearchPath("user/", true, false, NULL);
if (memoryCompressed)
{
CPath::memoryCompress();
}
CInterfaceManager *pIM = CInterfaceManager::getInstance();
pIM->executeLuaScript("game:onBnpDownloadFinish()", true);
}
}
}
Curls.erase(it);
@ -220,32 +344,11 @@ void CGroupHTML::checkImageDownload()
RunningCurls = NewRunningCurls;
}
void CGroupHTML::initImageDownload()
void CGroupHTML::releaseDownloads()
{
#ifdef LOG_DL
nlwarning("Init Image Download");
#endif
MultiCurl = curl_multi_init();
RunningCurls = 0;
/*
// Get current flag
int tmpFlag = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
// Turn on leak-checking bit
tmpFlag |= _CRTDBG_CHECK_ALWAYS_DF;
// Set flag to the new value
_CrtSetDbgFlag( tmpFlag );
*/
string pathName = "cache";
if ( ! CFile::isExists( pathName ) )
CFile::createDirectory( pathName );
}
void CGroupHTML::releaseImageDownload()
{
#ifdef LOG_DL
nlwarning("Release Image Download");
nlwarning("Release Downloads");
#endif
if(MultiCurl)
curl_multi_cleanup(MultiCurl);
@ -1251,6 +1354,21 @@ void CGroupHTML::beginElement (uint element_number, const BOOL *present, const c
endParagraph();
_UL.push_back(true);
break;
case HTML_OBJECT:
_ObjectType = "";
_ObjectData = "";
_ObjectMD5Sum = "";
_ObjectAction = "";
if (present[HTML_OBJECT_TYPE] && value[HTML_OBJECT_TYPE])
_ObjectType = value[HTML_OBJECT_TYPE];
if (present[HTML_OBJECT_DATA] && value[HTML_OBJECT_DATA])
_ObjectData = value[HTML_OBJECT_DATA];
if (present[HTML_OBJECT_ID] && value[HTML_OBJECT_ID])
_ObjectMD5Sum = value[HTML_OBJECT_ID];
if (present[HTML_OBJECT_STANDBY] && value[HTML_OBJECT_STANDBY])
_ObjectAction = value[HTML_OBJECT_STANDBY];
break;
}
}
}
@ -1371,6 +1489,14 @@ void CGroupHTML::endElement (uint element_number)
popIfNotEmpty (_UL);
}
break;
case HTML_OBJECT:
if (_ObjectType=="application/ryzom-data")
{
if (!_ObjectData.empty())
{
addBnpDownload(_ObjectData, _ObjectAction);
}
}
}
}
}
@ -1483,7 +1609,11 @@ CGroupHTML::CGroupHTML(const TCtorParam &param)
DefaultBackgroundBitmapView = "bg";
clearContext();
MultiCurl = curl_multi_init();
RunningCurls = 0;
initImageDownload();
initBnpDownload();
}
// ***************************************************************************
@ -2313,9 +2443,14 @@ CCtrlButton *CGroupHTML::addButton(CCtrlButton::EType type, const std::string &/
ctrlButton->setActionOnLeftClick (actionHandler);
ctrlButton->setParamsOnLeftClick (actionHandlerParams);
// Translate the tooltip
// Translate the tooltip or display raw text (tooltip from webig)
if (tooltip)
ctrlButton->setDefaultContextHelp (CI18N::get (tooltip));
{
if (CI18N::hasTranslation(tooltip))
ctrlButton->setDefaultContextHelp (CI18N::get(tooltip));
else
ctrlButton->setDefaultContextHelp (ucstring(tooltip));
}
getParagraph()->addChild (ctrlButton);
paragraphChange ();
@ -2913,7 +3048,7 @@ void CGroupHTML::handle ()
void CGroupHTML::draw ()
{
checkImageDownload();
checkDownloads();
CGroupScrollText::draw ();
}

View file

@ -293,6 +293,8 @@ protected :
// the script to execute
std::string _LuaScript;
bool _ParsingBnpUrl;
std::string _BnpUrl;
// Someone is conecting. We got problem with libwww : 2 connection requests can deadlock the client.
static CGroupHTML *_ConnectingLock;
@ -481,6 +483,12 @@ protected :
bool _SelectOption;
ucstring _SelectOptionStr;
// Current node is a object
std::string _ObjectType;
std::string _ObjectData;
std::string _ObjectMD5Sum;
std::string _ObjectAction;
// Get last char
ucchar getLastChar() const;
@ -527,25 +535,38 @@ private:
static ucstring decodeHTMLEntities(const ucstring &str);
// ImageDownload system
enum TDataType {ImgType= 0, BnpType};
struct CImageDownload
struct CDataDownload
{
CImageDownload(CURL *c, const std::string &u, FILE *f, CViewBase *i) : curl(c), url(u), fp(f) { imgs.push_back(i); }
CDataDownload(CURL *c, const std::string &u, FILE *f, TDataType t, CViewBase *i) : curl(c), url(u), fp(f), type(t) { imgs.push_back(i); }
CURL *curl;
std::string url;
TDataType type;
FILE *fp;
std::vector<CViewBase *> imgs;
};
std::vector<CImageDownload> Curls;
std::vector<CDataDownload> Curls;
CURLM *MultiCurl;
int RunningCurls;
void initImageDownload();
void releaseImageDownload();
void checkImageDownload();
void addImageDownload(const std::string &url, CViewBase *img);
std::string localImageName(const std::string &url);
// BnpDownload system
void initBnpDownload();
void checkBnpDownload();
void addBnpDownload(const std::string &url, const std::string &action);
std::string localBnpName(const std::string &url);
void releaseDownloads();
void checkDownloads();
};
// adapter group that store y offset for inputs inside an html form

View file

@ -514,6 +514,13 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (class CEntityCL *entity)
if (!isForageSource)
{
CViewBase * invisibleLogo = info->getView("invisible_logo");
if (entity->isUser() && invisibleLogo)
{
bool invisible = pIM->getDbProp("SERVER:USER:IS_INVISIBLE")->getValueBool();
invisibleLogo->setActive(invisible);
}
// Get the target bitmap
CViewBase *target = leftGroup->getView ("target");
if (target)
@ -532,25 +539,91 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (class CEntityCL *entity)
info->_MissionTarget = bitmap;
}
// set or inactive pvp logos
CViewBase * pvpCivLogo = info->getView ("pvp_faction_civ_logo");
CViewBase * pvpCultLogo = info->getView ("pvp_faction_cult_logo");
CPlayerCL * pPlayer = dynamic_cast<CPlayerCL*>(entity);
if (pPlayer != NULL && needPvPLogo)
if (pPlayer == NULL)
needPvPLogo = false;
// set or inactive pvp logos
bool needCivPvpLogo = needPvPLogo;
bool needCultPvpLogo = needPvPLogo;
if (pPlayer != NULL && needPvPLogo && pvpCivLogo && pvpCultLogo)
{
CViewBase * pvpFactionLogo = info->getView ("pvp_faction_logo");
if (pvpFactionLogo)
uint8 civToDisplay = (uint8)(pPlayer->getClanCivMaxFame() & 0xFF);
uint8 cultToDisplay = (uint8)(pPlayer->getClanCultMaxFame() & 0xFF);
if (!entity->isUser())
{
if( pPlayer->getPvpMode()&PVP_MODE::PvpFaction || pPlayer->getPvpMode()&PVP_MODE::PvpFactionFlagged)
{
CViewBitmap * pvpFactionLogoBmp = dynamic_cast<CViewBitmap *>(pvpFactionLogo);
if( pvpFactionLogoBmp )
pvpFactionLogoBmp->setTexture( pIM->getDefine(PVP_CLAN::toIconDefineString(pPlayer->getPvpClan())) );
}
else
{
pvpFactionLogo->setActive(false);
}
// Check if are Civ Allies
for (uint8 i = 0; i < 4; i++)
if ( (pPlayer->isPvpAlly(i) && UserEntity->isPvpAlly(i)) ||
(pPlayer->isPvpEnnemy(i) && UserEntity->isPvpEnnemy(i)) )
civToDisplay = i;
// Check if are Civ Ennemies
for (uint8 i = 0; i < 4; i++)
if ( (pPlayer->isPvpAlly(i) && UserEntity->isPvpEnnemy(i)) ||
(pPlayer->isPvpEnnemy(i) && UserEntity->isPvpAlly(i)) )
civToDisplay = i;
// Check if are Cult Allies
for (uint8 i = 4; i < 7; i++)
if ( (pPlayer->isPvpAlly(i) && UserEntity->isPvpAlly(i)) ||
(pPlayer->isPvpEnnemy(i) && UserEntity->isPvpEnnemy(i)) )
cultToDisplay = i;
// Check if are Cult Ennemies
for (uint8 i = 4; i < 7; i++)
if ( (pPlayer->isPvpAlly(i) && UserEntity->isPvpEnnemy(i)) ||
(pPlayer->isPvpEnnemy(i) && UserEntity->isPvpAlly(i)) )
cultToDisplay = i;
}
if ((pPlayer->getPvpMode() & PVP_MODE::PvpFaction) || (pPlayer->getPvpMode() & PVP_MODE::PvpFactionFlagged))
{
CViewBitmap * pvpCivLogoBmp = dynamic_cast<CViewBitmap *>(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");
else
needCivPvpLogo = false;
}
CViewBitmap * pvpCultLogoBmp = dynamic_cast<CViewBitmap *>(pvpCultLogo);
if( pvpCultLogoBmp )
{
if (pPlayer->isPvpAlly(cultToDisplay))
if (pPlayer->isPvpPrimas())
pvpCultLogoBmp->setTexture("pvp_ally_primas.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;
}
}
else
{
needCivPvpLogo = false;
needCultPvpLogo = false;
}
CViewBase * pvpOutpostLogo = info->getView ("pvp_outpost_logo");
if (pvpOutpostLogo)
{
@ -563,7 +636,7 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (class CEntityCL *entity)
CViewBase * pvpDuelLogo = info->getView ("pvp_duel_logo");
if (pvpDuelLogo)
{
if( !(pPlayer->getPvpMode()&PVP_MODE::PvpDuel) )
if( !(pPlayer->getPvpMode()&PVP_MODE::PvpDuel || pPlayer->getPvpMode()&PVP_MODE::PvpChallenge) )
{
pvpDuelLogo->setActive(false);
}
@ -571,11 +644,6 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (class CEntityCL *entity)
}
else
{
// unactive pvp logos
CViewBase * pvpFactionLogo = info->getView ("pvp_faction_logo");
if (pvpFactionLogo)
pvpFactionLogo->setActive(false);
CViewBase * pvpOutpostLogo = info->getView ("pvp_outpost_logo");
if (pvpOutpostLogo)
pvpOutpostLogo->setActive(false);
@ -584,6 +652,13 @@ CGroupInSceneUserInfo *CGroupInSceneUserInfo::build (class CEntityCL *entity)
if (pvpDuelLogo)
pvpDuelLogo->setActive(false);
}
if (pvpCivLogo)
pvpCivLogo->setActive(needCivPvpLogo);
if (pvpCultLogo)
pvpCultLogo->setActive(needCultPvpLogo);
}
// No bar and no string ?

View file

@ -41,10 +41,13 @@
#include "game_share/lift_icons.h"
#include "../r2/editor.h"
#include "chat_window.h"
#include "people_interraction.h"
using namespace std;
using namespace NLMISC;
extern CPeopleInterraction PeopleInterraction;
NLMISC_REGISTER_OBJECT(CViewBase, CDBGroupListAscensor, std::string, "list_sheet_guild");
@ -52,26 +55,27 @@ NLMISC_REGISTER_OBJECT(CViewBase, CDBGroupListAscensor, std::string, "list_sheet
// Interface part
// ***************************************************************************
#define WIN_GUILD "ui:interface:guild"
#define WIN_GUILD_CHAT "ui:interface:guild_chat"
#define WIN_GUILD_FORUM "ui:interface:guild_forum"
#define VIEW_TEXT_GUILD_QUIT "ui:interface:guild:content:tab_guild:quit_guild"
#define CTRL_SHEET_GUILD_BLASON "ui:interface:guild:content:tab_guild:blason"
#define VIEW_TEXT_GUILD_MEMBER_COUNT "ui:interface:guild:content:tab_guild:member_count"
#define WIN_GUILD "ui:interface:guild"
#define WIN_GUILD_CHAT "ui:interface:guild_chat"
#define WIN_GUILD_FORUM "ui:interface:guild_forum"
#define VIEW_TEXT_GUILD_QUIT "ui:interface:guild:content:tab_guild:quit_guild"
#define CTRL_SHEET_GUILD_BLASON "ui:interface:guild:content:tab_guild:blason"
#define VIEW_TEXT_GUILD_MEMBER_COUNT "ui:interface:guild:content:tab_guild:member_count"
#define LIST_GUILD_MEMBERS "ui:interface:guild:content:tab_guild:list_member:guild_members"
#define CTRL_QUIT_GUILD "ui:interface:guild:content:tab_guild:quit_guild"
#define TEMPLATE_GUILD_MEMBER "member_template"
#define TEMPLATE_GUILD_MEMBER_NAME "name"
#define TEMPLATE_GUILD_MEMBER_GRADE "grade"
#define TEMPLATE_GUILD_MEMBER_SCORE "score"
#define MENU_GUILD_MEMBER "ui:interface:menu_member"
#define LIST_GUILD_MEMBERS "ui:interface:guild:content:tab_guild:list_member:guild_members"
#define CTRL_QUIT_GUILD "ui:interface:guild:content:tab_guild:quit_guild"
#define TEMPLATE_GUILD_MEMBER "member_template"
#define TEMPLATE_GUILD_MEMBER_NAME "name"
#define TEMPLATE_GUILD_MEMBER_GRADE "grade"
#define TEMPLATE_GUILD_MEMBER_SCORE "score"
#define TEMPLATE_GUILD_MEMBER_ENTER_DATE "enter_date"
#define MENU_GUILD_MEMBER "ui:interface:menu_member"
#define WIN_ASCENSOR "ui:interface:ascensor_teleport_list"
#define WIN_ASCENSOR "ui:interface:ascensor_teleport_list"
#define WIN_JOIN_PROPOSAL "ui:interface:join_guild_proposal"
#define VIEW_JOIN_PROPOSAL_PHRASE "ui:interface:join_guild_proposal:content:inside:phrase"
#define WIN_JOIN_PROPOSAL "ui:interface:join_guild_proposal"
#define VIEW_JOIN_PROPOSAL_PHRASE "ui:interface:join_guild_proposal:content:inside:phrase"
CGuildManager* CGuildManager::_Instance = NULL;
@ -107,16 +111,53 @@ static inline bool lt_member_grade(const SGuildMember &m1, const SGuildMember &m
return m1.Grade < m2.Grade;
}
static inline bool lt_member_online(const SGuildMember &m1, const SGuildMember &m2)
{
if (m1.Online == m2.Online)
{
return lt_member_grade(m1, m2);
}
// Compare online status
switch (m1.Online)
{
case ccs_online:
// m1 is < if m1 is online
return true;
break;
case ccs_online_abroad:
// m1 is < if m2 is offline
return (m2.Online == ccs_offline);
break;
case ccs_offline:
default:
// m2 is always < if m1 is offline
return false;
break;
}
}
// ***************************************************************************
void CGuildManager::sortGuildMembers()
void CGuildManager::sortGuildMembers(TSortOrder order)
{
if (_GuildMembers.size() < 2) return;
// First sort by name
sort(_GuildMembers.begin(), _GuildMembers.end(), lt_member_name);
// Second sort by grade
stable_sort(_GuildMembers.begin(), _GuildMembers.end(), lt_member_grade);
switch (order)
{
default:
case sort_grade:
sort(_GuildMembers.begin(), _GuildMembers.end(), lt_member_name);
stable_sort(_GuildMembers.begin(), _GuildMembers.end(), lt_member_grade);
break;
case sort_name:
sort(_GuildMembers.begin(), _GuildMembers.end(), lt_member_name);
break;
case sort_online:
sort(_GuildMembers.begin(), _GuildMembers.end(), lt_member_name);
stable_sort(_GuildMembers.begin(), _GuildMembers.end(), lt_member_online);
break;
}
}
bool CGuildManager::isProxy()
@ -713,8 +754,9 @@ class CAHGuildSheetOpen : public IActionHandler
// *** Update Members, if necessary
if(updateMembers)
{
CGuildManager::TSortOrder order = (CGuildManager::TSortOrder)(pIM->getDbProp("UI:SAVE:GUILD_LIST:SORT_ORDER")->getValue32());
// Sort the members in Guild Manager
pGM->sortGuildMembers();
pGM->sortGuildMembers(order);
// update member count view
const vector<SGuildMember> &rGuildMembers = pGM->getGuildMembers();
@ -782,6 +824,21 @@ class CAHGuildSheetOpen : public IActionHandler
}
}
// Enter Date
CViewText *pViewEnterDate = dynamic_cast<CViewText*>(pLine->getView(TEMPLATE_GUILD_MEMBER_ENTER_DATE));
if (pViewEnterDate != NULL)
{
CRyzomTime rt;
rt.updateRyzomClock(rGuildMembers[i].EnterDate);
ucstring str = toString("%04d", rt.getRyzomYear()) + " ";
str += CI18N::get("uiJenaYear") + " : ";
str += CI18N::get("uiAtysianCycle") + " ";
str += toString("%01d", rt.getRyzomCycle()+1) +", ";
str += CI18N::get("ui"+MONTH::toString( (MONTH::EMonth)rt.getRyzomMonthInCurrentCycle() )) + ", ";
str += toString("%02d", rt.getRyzomDayOfMonth()+1);
pViewEnterDate->setText(str);
}
// Add to the list
pLine->setParent (pParent);
pParent->addChild (pLine);
@ -850,15 +907,7 @@ class CAHGuildSheetMenuOpen : public IActionHandler
return;
}
// *** Check with the grade of the local player wich types of actions we can do on the player selected
// Grade less or equal cant do anything
if (pGM->getGrade() >= rGuildMembers[nLineNb].Grade)
{
// Close
pIM->disableModalWindow();
return;
}
// enable or disable menu entries
if (pGM->isProxy())
@ -869,7 +918,11 @@ class CAHGuildSheetMenuOpen : public IActionHandler
else
{
// Depending on the grade we can do things or other
if (pGM->getGrade() == EGSPD::CGuildGrade::Leader)
// Grade less or equal can't do anything
if (pGM->getGrade() >= rGuildMembers[nLineNb].Grade)
setRights(false, false, false, false, false, false, false);
else if (pGM->getGrade() == EGSPD::CGuildGrade::Leader)
setRights(true, true, true, true, true, true, true);
else if (pGM->getGrade() == EGSPD::CGuildGrade::HighOfficer)
setRights(false, false, true, true, true, true, true);
@ -926,6 +979,70 @@ static void sendMsgSetGrade(EGSPD::CGuildGrade::TGuildGrade Grade)
}
}
// ***************************************************************************
// Sort the guild member list
class CAHGuildSheetSortGuildList : public IActionHandler
{
public:
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
{
CInterfaceManager* pIM= CInterfaceManager::getInstance();
CGuildManager::TSortOrder order = (CGuildManager::TSortOrder)(pIM->getDbProp("UI:SAVE:GUILD_LIST:SORT_ORDER")->getValue32());
order = (CGuildManager::TSortOrder)(order + 1);
if (order == CGuildManager::END_SORT_ORDER)
{
order = CGuildManager::START_SORT_ORDER;
}
pIM->getDbProp("UI:SAVE:GUILD_LIST:SORT_ORDER")->setValue32((sint32)order);
pIM->runActionHandler("guild_sheet_open", NULL, toString("update_members=1"));
}
};
REGISTER_ACTION_HANDLER(CAHGuildSheetSortGuildList, "sort_guild_list");
// ***************************************************************************
// Invoke the 'tell' command on a contact from its menu
// The tell command is displayed in the 'around me' window
class CAHGuildSheetTellMember : public IActionHandler
{
public:
void execute (CCtrlBase * pCaller, const std::string &/* sParams */)
{
CInterfaceManager *pIM = CInterfaceManager::getInstance();
CGuildManager *pGM = CGuildManager::getInstance();
const vector<SGuildMember> &rGuildMembers = pGM->getGuildMembers();
// *** Check and retrieve the current member index (index in the member list)
CCtrlBase *ctrlLaunchingModal= pIM->getCtrlLaunchingModal();
if (pCaller == NULL)
{
// Error -> Close
return;
}
string sId = pCaller->getId();
sId = sId.substr(sId.rfind('m')+1,sId.size());
sint32 nLineNb;
fromString(sId, nLineNb);
if ((nLineNb < 0) || (nLineNb >= (sint32)rGuildMembers.size()))
{
// Error -> Close
return;
}
MemberIndexSelected= nLineNb;
MemberNameSelected = rGuildMembers[nLineNb].Name;
CPeopleInterraction::displayTellInMainChat(MemberNameSelected);
}
// Current selection
static sint32 MemberIndexSelected; // Index of the member selected when left clicked
static ucstring MemberNameSelected; // Name of the member selected when lef clicked
};
REGISTER_ACTION_HANDLER(CAHGuildSheetTellMember, "guild_tell_member");
sint32 CAHGuildSheetTellMember::MemberIndexSelected= -1;
ucstring CAHGuildSheetTellMember::MemberNameSelected;
// ***************************************************************************
class CAHGuildSheetSetLeader : public IActionHandler
{

View file

@ -98,7 +98,16 @@ public:
const SGuild &getGuild() { return _Guild; }
const std::vector<SGuildMember> &getGuildMembers() { return _GuildMembers; }
void sortGuildMembers();
enum TSortOrder
{
sort_grade,
START_SORT_ORDER = sort_grade,
sort_name,
sort_online,
END_SORT_ORDER
};
void sortGuildMembers(TSortOrder order = sort_grade);
/// Check if the guild is a proxified guild (not managed on the actual shard)
bool isProxy();

View file

@ -104,6 +104,7 @@ void CInputHandlerManager::addToServer(NLMISC::CEventServer * server)
server->addListener(EventMouseDblClkId, this);
// Keyboard
server->addListener(EventStringId, this);
server->addListener(EventCharId, this);
server->addListener(EventKeyDownId, this);
server->addListener(EventKeyUpId, this);
@ -127,6 +128,7 @@ void CInputHandlerManager::release()
_EventServer->removeListener(EventMouseDblClkId, this);
// Keyboard
_EventServer->removeListener(EventStringId, this);
_EventServer->removeListener(EventCharId, this);
_EventServer->removeListener(EventKeyDownId, this);
_EventServer->removeListener(EventKeyUpId, this);
@ -230,7 +232,8 @@ void CInputHandlerManager::operator ()(const NLMISC::CEvent &event)
// **** Event Keyboard
if( event == EventKeyDownId ||
event == EventKeyUpId ||
event == EventCharId)
event == EventCharId ||
event == EventStringId)
{
// if not handled, post to Action Manager
if( !pIM->handleEvent( CEventDescriptorKey((const CEventKey &) event) ) )

View file

@ -506,7 +506,10 @@ void CInterface3DScene::draw ()
for (i = 0; i < _Characters.size(); ++i)
_Characters[i]->setClusterSystem ((UInstanceGroup*)-1);
for (i = 0; i < _Shapes.size(); ++i)
_Shapes[i]->getShape().setClusterSystem ((UInstanceGroup*)-1);
{
if (!_Shapes[i]->getShape().empty())
_Shapes[i]->getShape().setClusterSystem ((UInstanceGroup*)-1);
}
for (i = 0; i < _FXs.size(); ++i)
if (!_FXs[i]->getPS().empty())
_FXs[i]->getPS().setClusterSystem ((UInstanceGroup*)-1);
@ -1344,7 +1347,20 @@ std::string CInterface3DShape::getName() const
// ----------------------------------------------------------------------------
void CInterface3DShape::setName (const std::string &ht)
{
string lwrname = strlwr(ht);
if (ht.empty())
{
CInterface3DScene *pI3DS = dynamic_cast<CInterface3DScene*>(_Parent);
nlassert(pI3DS != NULL);
if (!_Instance.empty())
{
pI3DS->getScene()->deleteInstance(_Instance);
}
return;
_Name.clear();
}
string lwrname = toLower(ht);
if (lwrname != _Name)
{
CInterface3DScene *pI3DS = dynamic_cast<CInterface3DScene*>(_Parent);

View file

@ -101,6 +101,7 @@
#include "../entity_animation_manager.h" // for emotes
#include "../net_manager.h" // for emotes
#include "../client_chat_manager.h" // for emotes
#include "../entities.h"
#include "chat_text_manager.h"
#include "../npc_icon.h"
@ -459,7 +460,7 @@ void CInterfaceManager::initLogin()
}
nldebug("Textures Login Interface");
for (vector<string>::iterator it = ClientCfg.TexturesLoginInterface.begin(), end = ClientCfg.TexturesLoginInterface.end(); it != end; ++it)
{
nldebug("Textures Login Interface: %s", (*it).c_str());
@ -549,13 +550,13 @@ void CInterfaceManager::initOutGame()
}
nldebug("Textures OutGame Interface");
for (vector<string>::iterator it = ClientCfg.TexturesOutGameInterface.begin(), end = ClientCfg.TexturesOutGameInterface.end(); it != end; ++it)
{
nldebug("Textures OutGame Interface: %s", (*it).c_str());
loadTextures(*it + ".tga", *it + ".txt", false);
}
for (vector<string>::iterator it = ClientCfg.TexturesOutGameInterfaceDXTC.begin(), end = ClientCfg.TexturesOutGameInterfaceDXTC.end(); it != end; ++it)
{
nldebug("Textures OutGame Interface DXTC: %s", (*it).c_str());
@ -1288,6 +1289,18 @@ void CInterfaceManager::updateFrameEvents()
pVT = dynamic_cast<CViewText*>(getElementFromId("ui:interface:map:content:map_content:time"));
if (pVT != NULL)
pVT->setText(str);
str.clear();
// Update the clock in the compass if enabled.
pVT = dynamic_cast<CViewText*>(getElementFromId("ui:interface:compass:clock:time"));
if (pVT != NULL)
{
if (pVT->getActive())
{
str = getTimestampHuman("%H:%M");
pVT->setText(str);
}
}
}
}
@ -1667,7 +1680,7 @@ bool CInterfaceManager::loadConfig (const string &filename)
// *** Apply the NPC icon display mode
CNPCIconCache::getInstance().init(!ClientCfg.R2EDEnabled && getDbProp("UI:SAVE:INSCENE:FRIEND:MISSION_ICON")->getValueBool());
return true;
}
@ -2189,7 +2202,7 @@ CInterfaceGroup *CInterfaceManager::getWindowForActiveMasterGroup(const std::str
// ----------------------------------------------------------------------------
void CInterfaceManager::updateTooltipCoords()
{
updateTooltipCoords(_CurCtrlContextHelp);
updateTooltipCoords(_CurCtrlContextHelp);
}
// ----------------------------------------------------------------------------
@ -2239,7 +2252,7 @@ void CInterfaceManager::updateTooltipCoords(CCtrlBase *newCtrl)
yParent = newCtrl->getYReal();
wParent = newCtrl->getWReal();
hParent = newCtrl->getHReal();
// Additionaly, must clip this ctrl with its parent
// Additionaly, must clip this ctrl with its parent
// (else animals are buggy for instance)
CInterfaceGroup *parent= newCtrl->getParent();
if(parent)
@ -2258,7 +2271,7 @@ void CInterfaceManager::updateTooltipCoords(CCtrlBase *newCtrl)
}
// **** resolve auto posref
// **** resolve auto posref
uint clampCount = adjustTooltipPosition(newCtrl, win, newCtrl->getToolTipParentPosRef(), newCtrl->getToolTipPosRef(), xParent, yParent, wParent, hParent);
if (clampCount != 0)
{
@ -2270,7 +2283,7 @@ void CInterfaceManager::updateTooltipCoords(CCtrlBase *newCtrl)
adjustTooltipPosition(newCtrl, win, newCtrl->getToolTipParentPosRef(), newCtrl->getToolTipPosRef(), xParent, yParent, wParent, hParent);
}
}
}
}
}
}
@ -2364,7 +2377,7 @@ void CInterfaceManager::drawContextHelp ()
{
// enable
_CurCtrlContextHelp = newCtrl->getId();
newCtrl->invalidateCoords();
newCtrl->invalidateCoords();
}
}
}
@ -2376,7 +2389,7 @@ void CInterfaceManager::drawContextHelp ()
// **** display
// ***************
if(_CurCtrlContextHelp)
{
{
CInterfaceGroup *groupContextHelp = getWindowForActiveMasterGroup(_CurCtrlContextHelp->getContextHelpWindowName());
if(groupContextHelp)
{
@ -2384,12 +2397,12 @@ void CInterfaceManager::drawContextHelp ()
* If this is the case, we just disable it, unless the tooltip was generated by the current modal window
*/
if (!_ModalStack.empty())
{
{
CInterfaceGroup *mw = _ModalStack.back().ModalWindow;
if (mw && mw->isIn(*groupContextHelp))
{
{
if (_CurCtrlContextHelp->isSonOf(mw))
{
{
groupContextHelp->executeLuaScriptOnDraw();
groupContextHelp->draw ();
// flush layers
@ -2397,7 +2410,7 @@ void CInterfaceManager::drawContextHelp ()
}
}
else
{
{
groupContextHelp->executeLuaScriptOnDraw();
groupContextHelp->draw ();
// flush layers
@ -2405,7 +2418,7 @@ void CInterfaceManager::drawContextHelp ()
}
}
else
{
{
groupContextHelp->executeLuaScriptOnDraw();
groupContextHelp->draw ();
// flush layers
@ -2420,11 +2433,11 @@ void CInterfaceManager::drawContextHelp ()
}
void CInterfaceManager::setContextHelpActive(bool active)
{
{
if (!active)
{
disableContextHelp();
}
disableContextHelp();
}
_ContextHelpActive = active;
}
@ -2675,7 +2688,7 @@ bool CInterfaceManager::handleEvent (const CEventDescriptor& event)
CInterfaceGroup *tw= getTopWindow();
if(tw && !tw->getAHOnEnter().empty())
{
// if the captured keypborad is in this Modal window, then must handle him in priority
// if the captured keyboard is in this Modal window, then must handle him in priority
if(_CaptureKeyboard && _CaptureKeyboard->getRootWindow()==tw)
{
bool result = _CaptureKeyboard->handleEvent(event);
@ -5494,8 +5507,6 @@ class CHandlerEmote : public IActionHandler
public:
void execute (CCtrlBase * /* pCaller */, const std::string &sParams)
{
// An emote is 2 things : a phrase and an animation
// Phrase is the phrase that server returns in chat system
// Behav is the animation played
@ -5524,7 +5535,7 @@ public:
behavToSend = MBEHAV::IDLE;
}
/* Emotes forbidden when dead, emotes with behav forbidden when
/* Emotes forbidden when dead, emotes with behav forbidden when
* stunned or swimming */
if ( ( behavToSend != MBEHAV::IDLE && (isSwimming() || isStunned() || isDead() ) ) )
{
@ -6276,3 +6287,300 @@ void CInterfaceManager::CServerToLocalAutoCopy::onLocalChange(ICDBNode *localNod
}
}
// ------------------------------------------------------------------------------------------------
char* CInterfaceManager::getTimestampHuman(const char* format /* "[%H:%M:%S] " */)
{
static char cstime[25];
time_t date;
time (&date);
struct tm *tms = localtime(&date);
if (tms)
{
strftime(cstime, 25, format, tms);
}
else
{
strcpy(cstime, "");
}
return cstime;
}
/*
* Parse tokens in a chatmessage or emote
*
* Valid subjects:
* $me$
* $t$
* $tt$
* $tm1$..$tm8$
*
* Valid parameters:
* $<subject>.name$
* $<subject>.title$
* $<subject>.race$
* $<subject>.guild$
* $<subject>.gs(m/f/n)$
*
* Default parameter if parameter result is empty:
* $<subject>.<parameter>/<default>$
*
* All \d's in default parameter remove a following character.
*/
bool CInterfaceManager::parseTokens(ucstring& ucstr)
{
ucstring str = ucstr;
ucstring start_token("$");
ucstring end_token("$");
size_t start_pos = 0;
size_t end_pos = 1;
sint endless_loop_protector = 0;
while ((start_pos < str.length() - 1) &&
((start_pos = str.find(start_token, start_pos)) != string::npos))
{
endless_loop_protector++;
if (endless_loop_protector > 100)
{
break;
}
// Get the whole token substring first
end_pos = str.find(end_token, start_pos + 1);
if ((start_pos == string::npos) ||
(end_pos == string::npos) ||
(end_pos <= start_pos + 1))
{
// Wrong formatting; give up on this one.
start_pos = max(start_pos, end_pos);
continue;
}
// 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) < 0)
{
// Wrong formatting; give up on this one.
start_pos = end_pos;
continue;
}
ucstring token_whole = str.luabind_substr(start_pos, end_pos - start_pos + 1);
ucstring token_string = token_whole.luabind_substr(1, token_whole.length() - 2);
ucstring token_replacement = token_whole;
ucstring token_default = token_whole;
ucstring token_subject;
ucstring token_param;
// Does the token have a parameter?
// If not it is 'name' by default
vector<ucstring> token_vector;
vector<ucstring> param_vector;
splitUCString(token_string, ucstring("."), token_vector);
token_subject = token_vector[0];
if (token_vector.size() == 1)
{
splitUCString(token_subject, ucstring("/"), param_vector);
token_subject = param_vector[0];
token_param = ucstring("name");
}
else
{
token_param = token_vector[1];
if (token_param.luabind_substr(0, 3) != ucstring("gs("))
{
splitUCString(token_vector[1], ucstring("/"), param_vector);
token_param = param_vector[0];
}
}
// Get any default value, if not gs
sint extra_replacement = 0;
if (token_param.luabind_substr(0, 3) != ucstring("gs("))
{
if (param_vector.size() == 2)
{
// Set default value
token_replacement = param_vector[1];
// Delete following chars for every '\d' in default
string::size_type token_replacement_pos;
while ((token_replacement_pos = token_replacement.find(ucstring("\\d"))) != string::npos)
{
token_replacement.replace(token_replacement_pos, 2, ucstring(""));
extra_replacement++;
}
token_default = token_replacement;
}
}
CEntityCL *pTokenSubjectEntity = NULL;
if (token_subject == ucstring("me"))
{
pTokenSubjectEntity = static_cast<CEntityCL*>(UserEntity);
}
else if (token_subject == ucstring("t"))
{
// Target
uint targetSlot = UserEntity->targetSlot();
pTokenSubjectEntity = EntitiesMngr.entity(targetSlot);
}
else if (token_subject == ucstring("tt"))
{
// Target's target
uint targetSlot = UserEntity->targetSlot();
CEntityCL *target = EntitiesMngr.entity(targetSlot);
if (target)
{
// Check the new slot.
CLFECOMMON::TCLEntityId newSlot = target->targetSlot();
CEntityCL* pE = EntitiesMngr.entity(newSlot);
if (pE)
{
pTokenSubjectEntity = pE;
}
}
}
else if ((token_subject.length() == 3) &&
(token_subject.luabind_substr(0, 2) == ucstring("tm")))
{
// Teammate
uint indexInTeam = 0;
fromString(token_subject.luabind_substr(2, 1).toString(), indexInTeam);
// Make 0-based
--indexInTeam;
if (indexInTeam < PeopleInterraction.TeamList.getNumPeople() )
{
// Index is the database index (serverIndex() not used for team list)
CCDBNodeLeaf *pNL = CInterfaceManager::getInstance()->getDbProp( NLMISC::toString(TEAM_DB_PATH ":%hu:NAME", indexInTeam ), false);
if (pNL && pNL->getValueBool() )
{
// There is a character corresponding to this index
pNL = CInterfaceManager::getInstance()->getDbProp( NLMISC::toString( TEAM_DB_PATH ":%hu:UID", indexInTeam ), false );
if (pNL)
{
CLFECOMMON::TClientDataSetIndex compressedIndex = pNL->getValue32();
// Search entity in vision
CEntityCL *entity = EntitiesMngr.getEntityByCompressedIndex( compressedIndex );
if (entity)
{
pTokenSubjectEntity = entity;
}
}
}
}
}
else
{
// Unknown token subject, skip it
start_pos = end_pos;
continue;
}
if (pTokenSubjectEntity != NULL)
{
// Parse the parameter
if (token_param == ucstring("name"))
{
ucstring name = pTokenSubjectEntity->getDisplayName();
// special case where there is only a title, very rare case for some NPC
if (name.empty())
{
name = pTokenSubjectEntity->getTitle();
}
token_replacement = name.empty() ? token_replacement : name;
}
else if (token_param == ucstring("title"))
{
ucstring title = pTokenSubjectEntity->getTitle();
token_replacement = title.empty() ? token_replacement : title;
}
else if (token_param == ucstring("race"))
{
CCharacterCL *pC = (CCharacterCL*)(pTokenSubjectEntity);
if (pC)
{
EGSPD::CPeople::TPeople race = pC->people();
if (race >= EGSPD::CPeople::Playable && race <= EGSPD::CPeople::EndPlayable)
{
ucstring srace = NLMISC::CI18N::get("io" + EGSPD::CPeople::toString(race));
token_replacement = srace.empty() ? token_replacement : srace;
}
}
}
else if (token_param == ucstring("guild"))
{
STRING_MANAGER::CStringManagerClient *pSMC = STRING_MANAGER::CStringManagerClient::instance();
ucstring ucGuildName;
if (pSMC->getString(pTokenSubjectEntity->getGuildNameID(), ucGuildName))
{
token_replacement = ucGuildName.empty() ? token_replacement : ucGuildName;
}
}
else if (token_param.luabind_substr(0, 3) == ucstring("gs(") &&
token_param.luabind_substr(token_param.length() - 1 , 1) == ucstring(")"))
{
// Gender string
vector<ucstring> strList;
ucstring gender_string = token_param.luabind_substr(3, token_param.length() - 4);
splitUCString(gender_string, ucstring("/"), strList);
if (strList.size() <= 1)
{
start_pos = end_pos;
continue;
}
// Only care about gender if it's a humanoid.
GSGENDER::EGender gender = GSGENDER::neutral;
if (pTokenSubjectEntity->isUser() || pTokenSubjectEntity->isPlayer() || pTokenSubjectEntity->isNPC())
{
CCharacterCL *pC = (CCharacterCL*)(pTokenSubjectEntity);
if (pC)
{
gender = pC->getGender();
}
}
// Neuter part is optional.
// Fallback to male if something is wrong.
GSGENDER::EGender g = ((uint)gender >= strList.size()) ? GSGENDER::male : gender;
token_replacement = strList[g];
}
}
if (token_whole == token_replacement)
{
// Nothing to replace; show message and exit
CInterfaceManager *im = CInterfaceManager::getInstance();
ucstring message = ucstring(CI18N::get("uiUntranslatedToken"));
message.replace(message.find(ucstring("%s")), 2, token_whole);
im->displaySystemInfo(message);
return false;
}
// Replace all occurances of token with the replacement
size_t token_whole_pos = str.find(token_whole);
start_pos = 0;
// Only do extra replacement if using default
extra_replacement = (token_replacement == token_default) ? extra_replacement : 0;
while (str.find(token_whole, start_pos) != string::npos)
{
str = str.replace(token_whole_pos, token_whole.length() + extra_replacement, token_replacement);
start_pos = token_whole_pos + token_replacement.length();
token_whole_pos = str.find(token_whole, start_pos);
}
}
ucstr = str;
return true;;
}

View file

@ -712,6 +712,14 @@ public:
void updateTooltipCoords();
/** Returns a human readable timestamp with the given format.
*/
static char* getTimestampHuman(const char* format = "[%H:%M:%S] ");
/** Parses any tokens in the ucstring like $t$ or $g()$
*/
static bool parseTokens(ucstring& ucstr);
// ------------------------------------------------------------------------------------------------
private:

View file

@ -25,6 +25,7 @@
#include "nel/misc/algo.h"
#include "nel/misc/mem_stream.h"
#include "nel/misc/factory.h"
#include "nel/misc/big_file.h"
#include "game_share/xml_auto_ptr.h"
@ -106,6 +107,7 @@
#include "../commands.h"
#include "lua_helper.h"
#include "lua_ihm.h"
#include "../r2/editor.h"
#ifdef LUA_NEVRAX_VERSION
#include "lua_ide_dll_nevrax/include/lua_ide_dll/ide_interface.h" // external debugger
@ -114,6 +116,23 @@ const uint32 UI_CACHE_SERIAL_CHECK = (uint32) 'IUG_';
using namespace NLMISC;
void badLuaParseMessageBox()
{
NL3D::UDriver::TMessageBoxId ret = Driver->systemMessageBox( "LUA files reading failed!\n"
"Some LUA files are corrupted, moved or may have been removed.\n"
"Ryzom may need to be restarted to run properly.\n"
"Would you like to quit now?",
"LUA reading failed!",
NL3D::UDriver::yesNoType,
NL3D::UDriver::exclamationIcon);
if (ret == NL3D::UDriver::yesId)
{
extern void quitCrashReport ();
quitCrashReport ();
exit (EXIT_FAILURE);
}
}
void saveXMLTree(COFile &f, xmlNodePtr node)
{
// save node name
@ -494,10 +513,16 @@ static void interfaceScriptAsMemStream(const std::string &script, CMemStream &de
}
// ----------------------------------------------------------------------------
bool CInterfaceParser::parseInterface (const std::vector<std::string> & strings, bool reload, bool isFilename)
bool CInterfaceParser::parseInterface (const std::vector<std::string> & strings, bool reload, bool isFilename, bool checkInData)
{
bool ok;
bool needCheck = checkInData;
#if !FINAL_VERSION
needCheck = false;
#endif
// TestYoyo. UnHide For Parsing Profile
/*
NLMISC::CHTimer::startBench();
@ -524,7 +549,19 @@ bool CInterfaceParser::parseInterface (const std::vector<std::string> & strings,
{
//get the first file document pointer
firstFileName = *it;
if (!file.open (CPath::lookup(firstFileName)))
string filename = CPath::lookup(firstFileName);
bool isInData = false;
if (filename.find ("@") != string::npos)
{
vector<string> bigFilePaths;
CBigFile::getInstance().getBigFilePaths(bigFilePaths);
if (CBigFile::getInstance().getBigFileName(filename.substr(0, filename.find ("@"))) != "data/"+filename.substr(0, filename.find ("@")))
isInData = false;
else
isInData = true;
}
if ((needCheck && !isInData) || !file.open (CPath::lookup(firstFileName)))
{
// todo hulud interface syntax error
nlwarning ("could not open file %s, skipping xml parsing",firstFileName.c_str());
@ -929,7 +966,10 @@ bool CInterfaceParser::parseXMLDocument(xmlNodePtr root, bool reload)
else if ( !strcmp((char*)root->name,"lua") )
{
if(!parseLUAScript(root))
{
badLuaParseMessageBox();
nlwarning ("could not parse 'lua'");
}
}
root = root->next;
@ -4648,6 +4688,13 @@ void CInterfaceParser::uninitLUA()
bool CInterfaceParser::loadLUA(const std::string &fileName, std::string &error)
{
// get file
bool needCheck = true;
#if !FINAL_VERSION
needCheck = false;
#endif
string pathName= CPath::lookup(fileName, false);
if(pathName.empty())
{
@ -4655,6 +4702,20 @@ bool CInterfaceParser::loadLUA(const std::string &fileName, std::string &error)
return false;
}
bool isInData = false;
if (pathName.find ("@") != string::npos)
{
if (CBigFile::getInstance().getBigFileName(pathName.substr(0, pathName.find ("@"))) != "data/"+pathName.substr(0, pathName.find ("@")))
isInData = false;
else
isInData = true;
}
if (needCheck && !isInData)
{
return false;
}
// Parse script
nlassert(_LuaState);
try

View file

@ -103,7 +103,7 @@ public:
* \param isFilename true if xmlFileNames array contains the names of the xml file, false, if each
* array is a script itself
*/
bool parseInterface (const std::vector<std::string> &xmlFileNames, bool reload, bool isFilename = true);
bool parseInterface (const std::vector<std::string> &xmlFileNames, bool reload, bool isFilename = true, bool checkInData = false);
bool parseXMLDocument (xmlNodePtr root, bool reload);

View file

@ -4287,7 +4287,14 @@ void CLuaIHM::tell(const ucstring &player, const ucstring &msg)
{
if (!msg.empty())
{
ChatMngr.tell(player.toUtf8(), msg);
// Parse any tokens in the message.
ucstring msg_modified = msg;
// Parse any tokens in the text
if ( ! CInterfaceManager::parseTokens(msg_modified))
{
return;
}
ChatMngr.tell(player.toUtf8(), msg_modified);
}
else
{

View file

@ -18,6 +18,7 @@
#include "stdpch.h"
// client
#include "../string_manager_client.h"
#include "people_interraction.h"
#include "interface_expr.h"
#include "interface_manager.h"
@ -756,6 +757,7 @@ void CPeopleInterraction::createGuildChat()
chatDesc.Title = "uiGuildChat";
chatDesc.Listener = &GuildChatEntryHandler;
chatDesc.Localize = true;
chatDesc.Savable = true;
chatDesc.Id = "guild_chat";
chatDesc.AHOnCloseButton = "proc";
chatDesc.AHOnCloseButtonParams = "guild_chat_proc_close";
@ -774,6 +776,7 @@ void CPeopleInterraction::createYuboChat()
chatDesc.Title = "uiYuboChat";
chatDesc.Listener = &YuboChatEntryHandler;
chatDesc.Localize = true;
chatDesc.Savable = true;
chatDesc.Id = "yubo_chat";
chatDesc.AHOnCloseButton = "proc";
chatDesc.AHOnCloseButtonParams = "yubo_chat_proc_close";
@ -781,6 +784,7 @@ void CPeopleInterraction::createYuboChat()
YuboChat = getChatWndMgr().createChatWindow(chatDesc);
if (!YuboChat) return;
YuboChat->setMenu(STD_CHAT_SOURCE_MENU);
}
@ -795,6 +799,7 @@ void CPeopleInterraction::createDynamicChats()
DynamicChatEntryHandler[i].DbIndex= i;
chatDesc.Listener = &DynamicChatEntryHandler[i];
chatDesc.Localize = false;
chatDesc.Savable = true;
chatDesc.ChatTemplate ="dynamic_chat_id";
chatDesc.ChatTemplateParams.push_back(make_pair(string("dyn_chat_nb"),toString(i)));
chatDesc.Id = string("dynamic_chat") + toString(i);
@ -804,6 +809,8 @@ void CPeopleInterraction::createDynamicChats()
chatDesc.HeaderColor = "UI:SAVE:WIN:COLORS:MEM";
DynamicChat[i] = getChatWndMgr().createChatWindow(chatDesc);
if (!DynamicChat[i]) continue;
DynamicChat[i]->setMenu(STD_CHAT_SOURCE_MENU);
}
}
@ -956,7 +963,23 @@ class CHandlerChatGroupFilter : public IActionHandler
case CChatGroup::team: pUserBut->setHardText("uiFilterTeam"); break;
case CChatGroup::guild: pUserBut->setHardText("uiFilterGuild"); break;
case CChatGroup::universe: pUserBut->setHardText("uiFilterUniverse"); break;
// NB: user chat cannot have yubo_chat or dyn_chat target
case CChatGroup::dyn_chat:
uint32 index = PeopleInterraction.TheUserChat.Filter.getTargetDynamicChannelDbIndex();
uint32 textId = pIM->getDbProp("SERVER:DYN_CHAT:CHANNEL"+toString(index)+":NAME")->getValue32();
ucstring title;
STRING_MANAGER::CStringManagerClient::instance()->getDynString(textId, title);
if (title.empty())
{
// Dyn channel not available yet, so set to around
PeopleInterraction.TheUserChat.Filter.setTargetGroup(CChatGroup::arround);
pUserBut->setHardText("uiFilterAround");
}
else
{
pUserBut->setHardText(title.toUtf8());
}
break;
// NB: user chat cannot have yubo_chat target
}
pUserBut->setActive(true);
@ -1276,6 +1299,10 @@ void CPeopleInterraction::initContactLists( const std::vector<uint32> &vFriendLi
for (uint i = 0; i < vIgnoreListName.size(); ++i)
addContactInList(contactIdPool++, vIgnoreListName[i], ccs_offline, 1);
updateAllFreeTellerHeaders();
CInterfaceManager* pIM= CInterfaceManager::getInstance();
CPeopleList::TSortOrder order = (CPeopleList::TSortOrder)(pIM->getDbProp("UI:SAVE:CONTACT_LIST:SORT_ORDER")->getValue32());
FriendList.sortEx(order);
}
//=================================================================================================================
@ -1758,6 +1785,20 @@ void CPeopleInterraction::talkInDynamicChannel(uint32 channelNb,ucstring sentenc
}
}
//=================================================================================================================
void CPeopleInterraction::displayTellInMainChat(const ucstring &playerName)
{
//CChatWindow *chat = PeopleInterraction.MainChat.Window;
CChatWindow *chat = PeopleInterraction.ChatGroup.Window;
if (!chat) return;
chat->getContainer()->setActive (true);
// make the container blink
chat->getContainer()->enableBlink(2);
// TODO : center the view on the newly created container ?
// display a new command '/name' in the chat. The player must enter a new unique name for the party chat.
chat->setCommand("tell " + playerName + " ", false);
chat->setKeyboardFocus();
}
/////////////////////////////////////
// ACTION HANDLERS FOR PEOPLE LIST //
@ -1945,22 +1986,6 @@ public:
};
REGISTER_ACTION_HANDLER( CHandlerRemoveContact, "remove_contact");
//=================================================================================================================
static void displayTellInMainChat(const ucstring &playerName)
{
//CChatWindow *chat = PeopleInterraction.MainChat.Window;
CChatWindow *chat = PeopleInterraction.ChatGroup.Window;
if (!chat) return;
chat->getContainer()->setActive (true);
// make the container blink
chat->getContainer()->enableBlink(2);
// TODO : center the view on the newly created container ?
// display a new command '/name' in the chat. The player must enter a new unique name for the party chat.
chat->setCommand("tell " + playerName + " ", false);
chat->setKeyboardFocus();
}
//=================================================================================================================
// Invoke the 'tell' command on a contact from its menu
// The tell command is displayed in the 'around me' window
@ -1974,7 +1999,7 @@ public:
uint peopleIndex;
if (PeopleInterraction.getPeopleFromCurrentMenu(list, peopleIndex))
{
displayTellInMainChat(list->getName(peopleIndex));
CPeopleInterraction::displayTellInMainChat(list->getName(peopleIndex));
}
}
};
@ -1996,7 +2021,7 @@ class CHandlerTellContact : public IActionHandler
uint peopleIndex;
if (PeopleInterraction.getPeopleFromContainerID(gc->getId(), list, peopleIndex))
{
displayTellInMainChat(list->getName(peopleIndex));
CPeopleInterraction::displayTellInMainChat(list->getName(peopleIndex));
}
}
@ -2150,9 +2175,20 @@ class CHandlerSortContacts : public IActionHandler
public:
void execute (CCtrlBase * /* pCaller */, const std::string &/* sParams */)
{
CInterfaceManager* pIM= CInterfaceManager::getInstance();
nlinfo("Load Order : %d", pIM->getDbProp("UI:SAVE:CONTACT_LIST:SORT_ORDER")->getValue32());
CPeopleList::TSortOrder order = (CPeopleList::TSortOrder)(pIM->getDbProp("UI:SAVE:CONTACT_LIST:SORT_ORDER")->getValue32());
order = (CPeopleList::TSortOrder)(order + 1);
if (order == CPeopleList::END_SORT_ORDER) {
order = CPeopleList::START_SORT_ORDER;
}
nlinfo("Save Order : %d", order);
pIM->getDbProp("UI:SAVE:CONTACT_LIST:SORT_ORDER")->setValue32((sint32)order);
CPeopleList *pl = PeopleInterraction.getPeopleListFromCurrentMenu();
if (pl)
pl->sort();
pl->sortEx(order);
}
};
REGISTER_ACTION_HANDLER( CHandlerSortContacts, "sort_contacts");
@ -2441,6 +2477,30 @@ public:
if (pMenuUniverse) pMenuUniverse->setGrayed (false);
if (pMenuTeam) pMenuTeam->setGrayed (!teamActive);
if (pMenuGuild) pMenuGuild->setGrayed (!guildActive);
// Remove existing dynamic chats
while (pMenu->getNumLine() > 5)
pMenu->deleteLine(pMenu->getNumLine()-1);
// Add dynamic chats
uint insertion_index = 0;
for (uint i = 0; i < CChatGroup::MaxDynChanPerPlayer; i++)
{
string s = toString(i);
uint32 textId = im->getDbProp("SERVER:DYN_CHAT:CHANNEL"+s+":NAME")->getValue32();
bool active = (textId != 0);
if (active)
{
uint32 canWrite = im->getDbProp("SERVER:DYN_CHAT:CHANNEL"+s+":WRITE_RIGHT")->getValue32();
if (canWrite != 0)
{
ucstring title;
STRING_MANAGER::CStringManagerClient::instance()->getDynString(textId, title);
pMenu->addLineAtIndex(5 + insertion_index, title+" @{T8}/"+s, "chat_target_selected", "dyn"+s, "dyn"+s);
insertion_index++;
}
}
}
}
// activate the menu
@ -2465,28 +2525,42 @@ class CHandlerChatTargetSelected : public IActionHandler
CChatTargetFilter &cf = fc->Filter;
// Team
if (nlstricmp(sParams, "team") == 0)
{
cf.setTargetGroup(CChatGroup::team);
}
// Guild
if (nlstricmp(sParams, "guild") == 0)
else if (nlstricmp(sParams, "guild") == 0)
{
cf.setTargetGroup(CChatGroup::guild);
}
// Say
if (nlstricmp(sParams, "say") == 0)
else if (nlstricmp(sParams, "say") == 0)
{
cf.setTargetGroup(CChatGroup::say);
}
// Shout
if (nlstricmp(sParams, "shout") == 0)
else if (nlstricmp(sParams, "shout") == 0)
{
cf.setTargetGroup(CChatGroup::shout);
}
// Region
if (nlstricmp(sParams, "region") == 0)
else if (nlstricmp(sParams, "region") == 0)
{
cf.setTargetGroup(CChatGroup::region);
}
// Universe
if (nlstricmp(sParams, "universe") == 0)
else if (nlstricmp(sParams, "universe") == 0)
{
cf.setTargetGroup(CChatGroup::universe);
}
else
{
for (uint i = 0; i < CChatGroup::MaxDynChanPerPlayer; i++) {
if (nlstricmp(sParams, "dyn"+toString("%d", i)) == 0) {
cf.setTargetGroup(CChatGroup::dyn_chat, i);
}
}
}
// Case of user chat in grouped chat window
if (cw == PeopleInterraction.ChatGroup.Window)
@ -2593,6 +2667,25 @@ class CHandlerSelectChatSource : public IActionHandler
// select main chat menu
menu = dynamic_cast<CGroupMenu *>(im->getElementFromId(MAIN_CHAT_SOURCE_MENU));
// Remove all unused dynamic channels and set the names
for (uint i = 0; i < CChatGroup::MaxDynChanPerPlayer; i++)
{
string s = toString(i);
CViewTextMenu *pVTM = dynamic_cast<CViewTextMenu *>(im->getElementFromId(MAIN_CHAT_SOURCE_MENU+":tab:dyn"+s));
if (pVTM)
{
uint32 textId = im->getDbProp("SERVER:DYN_CHAT:CHANNEL"+s+":NAME")->getValue32();
bool active = (textId != 0);
pVTM->setActive(active);
if (active)
{
ucstring title;
STRING_MANAGER::CStringManagerClient::instance()->getDynString(textId, title);
pVTM->setText("["+s+"] " + title);
}
}
}
// Menu with Filters
CChatGroupWindow *pWin = pi.getChatGroupWindow();
if (pWin->getTabIndex() == 5) // (5 == user) -> complete menu

View file

@ -256,6 +256,8 @@ public:
void updateAllFreeTellerHeaders();
void removeAllFreeTellers();
static void displayTellInMainChat(const ucstring &playerName);
private:
// create various chat & people lists
void createTeamChat();

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