2010-05-06 00:08:41 +00:00
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
# include "stdpch.h"
# include <algorithm>
# include "lua_helper.h"
// Warning: cannot use namespace std, when using luabind
# ifdef NL_OS_WINDOWS
# ifndef NL_EXTENDED_FOR_SCOPE
# undef for
# endif
# endif
# include <luabind/luabind.hpp>
# if LUABIND_MAX_ARITY == 10
# define LUABIND_VERSION 07
# elif LUABIND_MAX_ARITY == 5
# define LUABIND_VERSION 06
# else
# pragma error("luabind version not recognized")
# endif
# if LUABIND_VERSION == 07
# include <luabind / operator.hpp>
# endif
# include "lua_ihm.h"
# include "reflect.h"
# include "action_handler.h"
# include "action_handler_tools.h"
# include "interface_manager.h"
# include "interface_group.h"
# include "view_text.h"
# include "game_share/people_pd.h"
# include "group_tree.h"
# include "interface_link.h"
# include "interface_expr.h"
# include "people_interraction.h"
# include "nel/misc/algo.h"
# include "nel/misc/file.h"
# include "nel/misc/i18n.h"
# include "nel/misc/time_nl.h"
# include "skill_manager.h"
# include "group_html.h"
# include "../net_manager.h"
# include "../user_entity.h"
# include "sphrase_manager.h"
# include "guild_manager.h"
# include "../client_cfg.h"
# include "../sheet_manager.h"
# include "lua_object.h"
# include "game_share/emote_list_parser.h"
# include "game_share/pvp_clan.h"
# include "../weather.h"
# include "../continent_manager.h"
# include "../zone_util.h"
# include "../motion/user_controls.h"
# include "group_html_cs.h"
# include "bonus_malus.h"
# include "group_editbox.h"
# include "../entities.h"
# include "../sheet_manager.h" // for emotes
# include "../global.h" // for emotes
# include "../entity_animation_manager.h" // for emotes
# include "../net_manager.h" // for emotes
# include "../client_chat_manager.h" // for emotes
# include "../login.h"
# include "lua_object.h"
# include "../actions.h"
# include "../bg_downloader_access.h"
# include "../connection.h"
# include "../login_patch.h"
# include "bot_chat_page_all.h"
# include "bot_chat_page_ring_sessions.h"
# include "nel/georges/u_form_loader.h"
# include "nel/georges/u_form.h"
# include "nel/georges/u_form_elm.h"
# include "nel/misc/polygon.h"
# include "game_share/scenario_entry_points.h"
# include "game_share/bg_downloader_msg.h"
# include "game_share/constants.h"
# ifdef LUA_NEVRAX_VERSION
# include "lua_ide_dll_nevrax/include/lua_ide_dll/ide_interface.h" // external debugger
# endif
# ifdef LUA_NEVRAX_VERSION
extern ILuaIDEInterface * LuaDebuggerIDE ;
# endif
// ***************************************************************************
/*
IMPORTANT NOTE : we do this heavy double registration in this file because we DON ' T want
to include luabind . hpp in every file .
Compilation is VERY SLOW
*/
// ***************************************************************************
using namespace NLMISC ;
using namespace NLGEORGES ;
using namespace R2 ;
extern NLMISC : : CLog g_log ;
extern CContinentManager ContinentMngr ;
extern uint8 PlayerSelectedSlot ;
extern CClientChatManager ChatMngr ;
extern void addWebIGParams ( string & url ) ;
// declare ostream << operator for ucstring -> registration of ucstring iin luabind will build a 'tostring' function from it
std : : ostream & operator < < ( std : : ostream & str , const ucstring & value )
{
return str < < value . toString ( ) ;
}
2010-05-10 18:37:23 +00:00
struct CMiscFunctions
{
static std : : string fileLookup ( const std : : string & fileName )
{
return NLMISC : : CPath : : lookup ( fileName , false ) ;
}
static void shellExecute ( const char * operation , const char * fileName , const char * parameters )
{
# if !FINAL_VERSION
# ifdef NL_OS_WINDOWS
ShellExecute ( NULL , operation , fileName , parameters , NULL , SW_SHOWDEFAULT ) ;
# endif
# endif
}
} ;
2010-05-06 00:08:41 +00:00
/**
* Data structure pushed in lua ( a userdata ) to access CReflectableRefPtrTarget derived objects
* These includes element of the GUI .
* if holds a pointer to the reflectable object , and
* a cache to its CClassInfo for fast access to exported properties
* \ see reflect . h
*/
//
class CReflectableLuaRef
{
public :
CReflectableLuaRef ( CReflectableRefPtrTarget * ptr = NULL ) : Ptr ( ptr ) , _ClassInfo ( NULL ) { }
NLMISC : : CRefPtr < CReflectableRefPtrTarget > Ptr ;
const CClassInfo & getClassInfo ( ) const ;
// IMPORTANT : luaStringPtr should have been obtained from lua, see remark in CClassInfo
const CReflectedProperty * getProp ( const char * luaStringPtr ) const ;
private :
// cache to class definition of the pointee object (once a CReflectableLuaRef created in lua, it remains a *const* pointer)
mutable const CClassInfo * _ClassInfo ;
} ;
inline const CClassInfo & CReflectableLuaRef : : getClassInfo ( ) const
{
nlassert ( Ptr ) ; // class info should not be accessed for a null ptr
if ( _ClassInfo ) return * _ClassInfo ;
_ClassInfo = Ptr - > getClassInfo ( ) ;
return * _ClassInfo ;
}
const CReflectedProperty * CReflectableLuaRef : : getProp ( const char * luaStringPtr ) const
{
const CClassInfo & ci = getClassInfo ( ) ;
CClassInfo : : TLuaStrToPropMap : : const_iterator it = ci . LuaStrToProp . find ( luaStringPtr ) ;
if ( it ! = ci . LuaStrToProp . end ( ) )
{
return it - > second . Prop ;
}
// slowly retrieve property, and store in cache
// NB nico : this could also be done at startup...
const CReflectedProperty * prop = CReflectSystem : : getProperty ( ci . ClassName , luaStringPtr , false ) ;
if ( ! prop ) return NULL ;
CLuaIndexedProperty lip ;
lip . Id = CLuaString ( luaStringPtr ) ; // keep a ref on the lua string to ensure that its pointer always remains valid
lip . Prop = prop ;
ci . LuaStrToProp [ luaStringPtr ] = lip ;
return prop ;
}
// ***************************************************************************
bool CLuaIHM : : pop ( CLuaState & ls , NLMISC : : CRGBA & dest )
{
//H_AUTO(Lua_CLuaIHM_pop)
try
{
if ( ls . isNil ( - 1 ) ) return false ;
# if LUABIND_VERSION == 07
luabind : : object obj ( luabind : : from_stack ( ls . getStatePointer ( ) , - 1 ) ) ;
2010-05-10 18:37:23 +00:00
ls . pop ( ) ;
2010-05-06 00:08:41 +00:00
# else
luabind : : object obj ( ls . getStatePointer ( ) ) ;
obj . set ( ) ;
# endif
dest = luabind : : object_cast < NLMISC : : CRGBA > ( obj ) ;
}
catch ( luabind : : cast_failed & )
{
return false ;
}
return true ;
}
// ***************************************************************************
bool CLuaIHM : : pop ( CLuaState & ls , NLMISC : : CVector2f & dest )
{
//H_AUTO(Lua_CLuaIHM_pop)
try
{
if ( ls . isNil ( - 1 ) ) return false ;
# if LUABIND_VERSION == 07
luabind : : object obj ( luabind : : from_stack ( ls . getStatePointer ( ) , - 1 ) ) ;
2010-05-10 18:37:23 +00:00
ls . pop ( ) ;
2010-05-06 00:08:41 +00:00
# else
luabind : : object obj ( ls . getStatePointer ( ) ) ;
obj . set ( ) ;
# endif
dest = luabind : : object_cast < NLMISC : : CVector2f > ( obj ) ;
}
catch ( luabind : : cast_failed & )
{
return false ;
}
return true ;
}
// ***************************************************************************
bool CLuaIHM : : pop ( CLuaState & ls , ucstring & dest )
{
//H_AUTO(Lua_CLuaIHM_pop)
try
{
if ( ls . isNil ( - 1 ) ) return false ;
# if LUABIND_VERSION == 07
luabind : : object obj ( luabind : : from_stack ( ls . getStatePointer ( ) , - 1 ) ) ;
2010-05-10 18:37:23 +00:00
ls . pop ( ) ;
2010-05-06 00:08:41 +00:00
# else
luabind : : object obj ( ls . getStatePointer ( ) ) ;
obj . set ( ) ;
# endif
dest = luabind : : object_cast < ucstring > ( obj ) ;
}
catch ( luabind : : cast_failed & )
{
return false ;
}
return true ;
}
// ***************************************************************************
bool CLuaIHM : : isUCStringOnStack ( CLuaState & ls , sint index )
{
//H_AUTO(Lua_CLuaIHM_isUCStringOnStack)
ls . pushValue ( index ) ;
ucstring dummy ;
return pop ( ls , dummy ) ;
}
// ***************************************************************************
bool CLuaIHM : : getUCStringOnStack ( CLuaState & ls , sint index , ucstring & dest )
{
//H_AUTO(Lua_CLuaIHM_getUCStringOnStack)
ls . pushValue ( index ) ;
return pop ( ls , dest ) ;
}
// ***************************************************************************
void CLuaIHM : : push ( CLuaState & ls , const ucstring & value )
{
//H_AUTO(Lua_CLuaIHM_push)
luabind : : object obj ( ls . getStatePointer ( ) , value ) ;
# if LUABIND_VERSION != 07
obj . pushvalue ( ) ;
# endif
}
// ***************************************************************************
// ***************************************************************************
// Special Action Handlers for Lua
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
class CHandlerLUA : public IActionHandler
{
public :
void execute ( CCtrlBase * pCaller , const std : : string & sParams )
{
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
// For getUI() LUA function, push the UI caller
if ( pCaller )
_UICallerStack . push_back ( pCaller ) ;
// execute a small script. NB: use a small script here because
// most often action handlers are called from xml files => lot of redundant script
pIM - > executeLuaScript ( sParams , true ) ;
// pop UI caller
if ( pCaller )
_UICallerStack . pop_back ( ) ;
}
// get the top of stack Caller to this LUA script
static CCtrlBase * getUICaller ( ) ;
private :
static std : : deque < CRefPtr < CCtrlBase > > _UICallerStack ;
} ;
REGISTER_ACTION_HANDLER ( CHandlerLUA , " lua " ) ;
std : : deque < CRefPtr < CCtrlBase > > CHandlerLUA : : _UICallerStack ;
CCtrlBase * CHandlerLUA : : getUICaller ( )
{
if ( _UICallerStack . empty ( ) )
return NULL ;
else
return _UICallerStack . back ( ) ;
}
// ***************************************************************************
// Allow also to call script from expression
static DECLARE_INTERFACE_USER_FCT ( lua )
{
if ( args . size ( ) ! = 1 | | ! args [ 0 ] . toString ( ) )
{
nlwarning ( " <lua> requires 1 arg (string=script) " ) ;
return false ;
}
// Retrieve lua state
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
CLuaState * state = pIM - > getLuaState ( ) ;
if ( ! state )
return false ;
CLuaState & ls = * state ;
// *** clear return value
const std : : string retId = " __ui_internal_ret_ " ;
CLuaStackChecker lsc ( & ls ) ;
ls . push ( retId ) ;
ls . pushNil ( ) ;
ls . setTable ( LUA_GLOBALSINDEX ) ;
// *** execute script
std : : string script = args [ 0 ] . getString ( ) ;
// assign return value in retId.
script = retId + " = " + script ;
// execute a small script here, because most often exprs are called from xml files => lot of redundant script
pIM - > executeLuaScript ( script , true ) ;
// *** retrieve and convert return value
ls . push ( retId ) ;
ls . getTable ( LUA_GLOBALSINDEX ) ;
bool ok = false ;
sint type = ls . type ( ) ;
if ( type = = LUA_TBOOLEAN )
{
// get and pop
bool val = ls . toBoolean ( ) ;
ls . pop ( ) ;
// set result
result . setBool ( val ) ;
ok = true ;
}
else if ( type = = LUA_TNUMBER )
{
// get and pop
double val = ls . toNumber ( ) ;
ls . pop ( ) ;
// set double or integer?
if ( val = = floor ( val ) )
result . setInteger ( sint64 ( floor ( val ) ) ) ;
else
result . setDouble ( val ) ;
ok = true ;
}
else if ( type = = LUA_TSTRING )
{
// get and pop
std : : string val ;
ls . toString ( - 1 , val ) ;
ls . pop ( ) ;
// set result
result . setString ( val ) ;
ok = true ;
}
else if ( type = = LUA_TUSERDATA )
{
// NB: the value is poped in obj.set() (no need to do ls.pop());
// try with ucstring
ucstring ucstrVal ;
if ( CLuaIHM : : pop ( ls , ucstrVal ) )
{
result . setUCString ( ucstrVal ) ;
ok = true ;
}
// try with RGBA
if ( ! ok )
{
NLMISC : : CRGBA rgbaVal ;
if ( CLuaIHM : : pop ( ls , rgbaVal ) )
{
result . setRGBA ( rgbaVal ) ;
ok = true ;
}
}
}
else
{
// error (nil for instance)
ls . pop ( ) ;
}
return ok ;
}
REGISTER_INTERFACE_USER_FCT ( " lua " , lua )
// ***************************************************************************
// ***************************************************************************
// CInterface To LUA Registry
// ***************************************************************************
// ***************************************************************************
CLuaState * ELuaIHMException : : getLuaState ( )
{
CInterfaceManager * im = CInterfaceManager : : getInstance ( ) ;
return im - > getLuaState ( ) ;
}
// ***************************************************************************
# define LUA_REGISTER_BASIC(_type_) \
2010-05-10 18:37:23 +00:00
luabind : : detail : : yes_t is_user_defined ( luabind : : detail : : by_value < _type_ > ) ; \
_type_ convert_lua_to_cpp ( lua_State * L , luabind : : detail : : by_value < _type_ > , int index ) \
2010-05-06 00:08:41 +00:00
{ \
return ( _type_ ) lua_tonumber ( L , index ) ; \
} \
2010-05-10 18:37:23 +00:00
int match_lua_to_cpp ( lua_State * L , luabind : : detail : : by_value < _type_ > , int index ) \
2010-05-06 00:08:41 +00:00
{ \
if ( lua_isnumber ( L , index ) ) return 0 ; else return - 1 ; \
} \
void convert_cpp_to_lua ( lua_State * L , const _type_ & v ) \
{ \
lua_pushnumber ( L , ( double ) v ) ; \
}
// Basic LUA types
namespace luabind
{
namespace converters
{
LUA_REGISTER_BASIC ( sint8 )
LUA_REGISTER_BASIC ( uint8 )
LUA_REGISTER_BASIC ( sint16 )
LUA_REGISTER_BASIC ( uint16 )
LUA_REGISTER_BASIC ( sint32 )
LUA_REGISTER_BASIC ( uint32 )
// LUA_REGISTER_BASIC(sint)
// LUA_REGISTER_BASIC(uint)
}
}
// ***************************************************************************
void CLuaIHM : : registerBasics ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_registerBasics)
using namespace luabind ;
lua_State * L = ls . getStatePointer ( ) ;
// RGBA
module ( L )
[
class_ < NLMISC : : CRGBA > ( " CRGBA " )
. def ( constructor < > ( ) )
. def ( constructor < const NLMISC : : CRGBA & > ( ) )
. def ( constructor < uint8 , uint8 , uint8 > ( ) )
. def ( constructor < uint8 , uint8 , uint8 , uint8 > ( ) )
. def_readwrite ( " R " , & NLMISC : : CRGBA : : R )
. def_readwrite ( " G " , & NLMISC : : CRGBA : : G )
. def_readwrite ( " B " , & NLMISC : : CRGBA : : B )
. def_readwrite ( " A " , & NLMISC : : CRGBA : : A )
] ;
// ucstring
module ( L )
[
class_ < ucstring > ( " ucstring " )
. def ( constructor < > ( ) )
. def ( constructor < const ucstring & > ( ) )
. def ( constructor < const std : : string & > ( ) )
. def ( const_self + other < const std : : string > ( ) )
. def ( other < const std : : string > ( ) + const_self )
// NB nico : luabind crash not solved here -> use concatUCString as a replacement
// .def(const_self + other<const ucstring &>())
. def ( const_self < other < const ucstring & > ( ) )
. def ( const_self = = other < const ucstring & > ( ) )
. def ( " toUtf8 " , & ucstring : : toUtf8 )
. def ( " fromUtf8 " , & ucstring : : fromUtf8 )
. def ( " substr " , & ucstring : : luabind_substr )
. def ( luabind : : tostring ( const_self ) ) // __string metamethod
. def ( " toString " , ( std : : string ( ucstring : : * ) ( ) const ) & ucstring : : toString )
//.def(self + other<ucstring>())
] ;
// CVector2f
module ( L )
[
class_ < NLMISC : : CVector2f > ( " CVector2f " )
. def ( constructor < float , float > ( ) )
. def_readwrite ( " x " , & NLMISC : : CVector2f : : x )
. def_readwrite ( " y " , & NLMISC : : CVector2f : : y )
] ;
// MISC ui ctors
struct CUICtor
{
// CGroupTree::SNode
static int SNode ( CLuaState & ls )
{
CLuaIHM : : checkArgCount ( ls , " SNode " , 0 ) ;
CLuaIHM : : pushReflectableOnStack ( ls , new CGroupTree : : SNode ) ;
return 1 ;
}
} ;
ls . registerFunc ( " SNode " , CUICtor : : SNode ) ;
}
// ***************************************************************************
CInterfaceElement * CLuaIHM : : getUIRelative ( CInterfaceElement * pIE , const std : : string & propName )
{
//H_AUTO(Lua_CLuaIHM_getUIRelative)
if ( pIE = = NULL ) return NULL ;
// If the prop is "parent", then return the parent of the ui
if ( propName = = " parent " )
{
return pIE - > getParent ( ) ;
}
// else try to get a child (if group/exist)
else
{
CInterfaceGroup * group = dynamic_cast < CInterfaceGroup * > ( pIE ) ;
if ( group )
{
return group - > getElement ( group - > getId ( ) + " : " + propName ) ;
}
}
return NULL ;
}
// ***************************************************************************
int CLuaIHM : : luaMethodCall ( lua_State * ls )
{
//H_AUTO(Lua_CLuaIHM_luaMethodCall)
nlassert ( ls ) ;
const CReflectedProperty * prop = ( const CReflectedProperty * ) lua_touserdata ( ls , lua_upvalueindex ( 1 ) ) ;
CLuaState * state = ( CLuaState * ) lua_touserdata ( ls , lua_upvalueindex ( 2 ) ) ;
nlassert ( prop ) ;
nlassert ( prop - > Type = = CReflectedProperty : : LuaMethod ) ;
nlassert ( state ) ;
if ( state - > empty ( ) )
{
state - > push ( NLMISC : : toString ( " Error while calling lua method %s:%s : no 'self' reference provided, did you you function call '.' instead of method call ':' ? " ,
prop - > ParentClass - > ClassName . c_str ( ) , prop - > Name . c_str ( ) )
) ;
lua_error ( ls ) ;
}
// because this is a method, first parameter is the 'this'
CReflectableRefPtrTarget * pRPT = getReflectableOnStack ( * state , 1 ) ;
if ( pRPT = = NULL )
{
state - > push ( NLMISC : : toString ( " Error while calling lua method %s:%s : 'self' pointer is nil or of bad type, can't make the call. " ,
prop - > ParentClass - > ClassName . c_str ( ) , prop - > Name . c_str ( ) )
) ;
lua_error ( ls ) ;
}
//
state - > remove ( 1 ) ; // remove 'self' reference from parameters stack
//
int numResults ;
int initialStackSize = state - > getTop ( ) ;
try
{
// call the actual method
numResults = ( pRPT - > * ( prop - > GetMethod . GetLuaMethod ) ) ( * state ) ;
}
catch ( const std : : exception & e )
{
// restore stack to its initial size
state - > setTop ( initialStackSize ) ;
lua_pushstring ( ls , e . what ( ) ) ;
// TODO : see if this is safe to call lua error there" ... (it does a long jump)
lua_error ( ls ) ;
}
return numResults ;
}
// ***************************************************************************
void CLuaIHM : : luaValueFromReflectedProperty ( CLuaState & ls , CReflectable & reflectedObject , const CReflectedProperty & property )
{
//H_AUTO(Lua_CLuaIHM_luaValueFromReflectedProperty)
switch ( property . Type )
{
case CReflectedProperty : : Boolean :
ls . push ( ( reflectedObject . * ( property . GetMethod . GetBool ) ) ( ) ) ;
break ;
case CReflectedProperty : : SInt32 :
ls . push ( ( lua_Number ) ( reflectedObject . * ( property . GetMethod . GetSInt32 ) ) ( ) ) ;
break ;
case CReflectedProperty : : Float :
ls . push ( ( lua_Number ) ( reflectedObject . * ( property . GetMethod . GetFloat ) ) ( ) ) ;
break ;
case CReflectedProperty : : String :
ls . push ( ( reflectedObject . * ( property . GetMethod . GetString ) ) ( ) ) ;
break ;
case CReflectedProperty : : UCString :
{
luabind : : object obj ( ls . getStatePointer ( ) , ( reflectedObject . * ( property . GetMethod . GetUCString ) ) ( ) ) ;
# if LUABIND_VERSION != 07
obj . pushvalue ( ) ;
# endif
}
break ;
case CReflectedProperty : : RGBA :
{
luabind : : object obj ( ls . getStatePointer ( ) , ( reflectedObject . * ( property . GetMethod . GetRGBA ) ) ( ) ) ;
# if LUABIND_VERSION != 07
obj . pushvalue ( ) ;
# endif
}
break ;
case CReflectedProperty : : LuaMethod :
{
// must create a closure that will forward the call to the real method
if ( ! property . LuaMethodRef . isValid ( ) )
{
ls . pushLightUserData ( ( void * ) & property ) ;
ls . pushLightUserData ( ( void * ) & ls ) ;
ls . pushCClosure ( luaMethodCall , 2 ) ;
property . LuaMethodRef . pop ( ls ) ;
}
nlassert ( property . LuaMethodRef . getLuaState ( ) = = & ls ) ; // only one single lua state supported for now
property . LuaMethodRef . push ( ) ;
}
break ;
default :
nlstop ;
break ;
}
}
static CLuaString lstr_Env ( " Env " ) ;
static CLuaString lstr_isNil ( " isNil " ) ;
// ***************************************************************************
int CLuaIHM : : luaUIIndex ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_luaUIIndex)
nlassert ( ls . getTop ( ) = = 2 ) ;
// get the userdata and key
CReflectableLuaRef * pRefElm = ( CReflectableLuaRef * ) ls . toUserData ( 1 ) ;
const char * propName = ls . toString ( 2 ) ;
CReflectableRefPtrTarget * pRPT = ( CReflectableRefPtrTarget * ) ( pRefElm - > Ptr ) ;
// ** try to get the Env Table (interface group only)
if ( propName = = lstr_isNil )
{
ls . push ( pRPT = = NULL ) ;
return 1 ;
}
// Check the object is not NULL or freed
if ( pRPT = = NULL )
{
return 0 ;
}
// ** try to get the Env Table (interface group only)
if ( propName = = lstr_Env )
{
// Env can be bound to a CInterfaceGroup only
CInterfaceGroup * group = dynamic_cast < CInterfaceGroup * > ( pRPT ) ;
if ( group = = NULL )
{
ls . pushNil ( ) ;
return 1 ;
}
else
{
group - > pushLUAEnvTable ( ) ;
return 1 ;
}
}
// ** try to get the property
const CReflectedProperty * prop = pRefElm - > getProp ( propName ) ;
if ( prop )
{
luaValueFromReflectedProperty ( ls , * pRPT , * prop ) ;
return 1 ;
}
// ** try to get a UI relative
CInterfaceElement * uiRelative = getUIRelative ( dynamic_cast < CInterfaceElement * > ( pRPT ) , propName ) ;
if ( uiRelative )
{
// push the UI onto the stack
CLuaIHM : : pushUIOnStack ( ls , uiRelative ) ;
return 1 ;
}
// Fail to find any Attributes or elements
// Yoyo: don't write any message or warning because this may be a feature (if user want to test that something exit in the ui)
ls . pushNil ( ) ;
return 1 ;
}
// ***************************************************************************
void CLuaIHM : : luaValueToReflectedProperty ( CLuaState & ls , int stackIndex , CReflectable & target , const CReflectedProperty & property ) throw ( ELuaIHMException )
{
//H_AUTO(Lua_property_throw)
if ( ls . isNil ( stackIndex ) )
throw ELuaIHMException ( " Trying to set nil to UI property '%s' " , property . Name . c_str ( ) ) ;
switch ( property . Type )
{
case CReflectedProperty : : Boolean :
{
bool val = ls . toBoolean ( stackIndex ) ;
( target . * ( property . SetMethod . SetBool ) ) ( val ) ;
return ;
}
case CReflectedProperty : : SInt32 :
{
sint32 val = ( sint32 ) ls . toNumber ( stackIndex ) ;
( target . * ( property . SetMethod . SetSInt32 ) ) ( val ) ;
return ;
}
case CReflectedProperty : : UInt32 :
{
uint32 val = ( uint32 ) ls . toNumber ( stackIndex ) ;
( target . * ( property . SetMethod . SetUInt32 ) ) ( val ) ;
return ;
}
case CReflectedProperty : : Float :
{
float val = ( float ) ls . toNumber ( stackIndex ) ;
( target . * ( property . SetMethod . SetFloat ) ) ( val ) ;
return ;
}
case CReflectedProperty : : String :
{
std : : string val ;
ls . toString ( stackIndex , val ) ;
( target . * ( property . SetMethod . SetString ) ) ( val ) ;
return ;
}
case CReflectedProperty : : UCString :
{
ucstring val ;
// Additionaly return of CInterfaceExpr may be std::string... test std string too
if ( ls . isString ( ) | | ls . isNumber ( ) )
{
std : : string str ;
ls . toString ( stackIndex , str ) ;
val = str ;
}
else
{
// else this should be a ucstring
if ( ! pop ( ls , val ) )
{
throw ELuaIHMException ( " You must set a string, number or ucstring to UI property '%s' " , property . Name . c_str ( ) ) ;
}
}
( target . * ( property . SetMethod . SetUCString ) ) ( val ) ;
return ;
}
case CReflectedProperty : : RGBA :
{
CRGBA color ;
if ( pop ( ls , color ) )
{
( target . * ( property . SetMethod . SetRGBA ) ) ( color ) ;
}
else
{
throw ELuaIHMException ( " You must set a CRGBA to UI property '%s' " , property . Name . c_str ( ) ) ;
}
return ;
}
default :
nlstop ;
}
}
// ***************************************************************************
int CLuaIHM : : luaUINewIndex ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_luaUINewIndex)
nlassert ( ls . getTop ( ) = = 3 ) ;
// get the userdata and key
CReflectableLuaRef * pRefElm = ( CReflectableLuaRef * ) ls . toUserData ( 1 ) ;
nlassert ( pRefElm ) ;
CReflectableRefPtrTarget * pRPT = ( CReflectableRefPtrTarget * ) ( pRefElm - > Ptr ) ;
// Check the UI is not NULL or freed
if ( pRPT = = NULL )
{
return 0 ;
}
const char * propName = ls . toString ( 2 ) ;
// ** try to set the Env Table (interface group only)
if ( propName = = lstr_Env )
{
CInterfaceElement * pIE = dynamic_cast < CInterfaceElement * > ( pRPT ) ;
std : : string name ;
if ( pIE )
{
name = pIE - > getId ( ) ;
}
else
{
name = " <reflectable element> " ;
}
// Exception!!! not allowed
throw ELuaIHMException ( " You cannot change the Env Table of '%s' " , name . c_str ( ) ) ;
}
// ** try to set the property
const CReflectedProperty * prop = pRefElm - > getProp ( propName ) ;
if ( prop )
{
luaValueToReflectedProperty ( ls , 3 , * pRPT , * prop ) ;
return 0 ;
}
CInterfaceElement * pIE = dynamic_cast < CInterfaceElement * > ( pRPT ) ;
// ** try to get an other UI (child or parent)
CInterfaceElement * uiRelative = getUIRelative ( pIE , propName ) ;
if ( uiRelative )
{
// Exception!!! not allowed
throw ELuaIHMException ( " You cannot write into the UI '%s' of '%s' " , propName , pIE - > getId ( ) . c_str ( ) ) ;
}
// ** Prop Not Found
throw ELuaIHMException ( " Property '%s' not found in '%s' of type %s " , propName , pIE ? pIE - > getId ( ) . c_str ( ) : " <reflectable element> " , typeid ( * pRPT ) . name ( ) ) ;
// Fail to find any Attributes or elements
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : luaUIEq ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_luaUIEq)
nlassert ( ls . getTop ( ) = = 2 ) ;
// read lhs & rhs
// get the userdata and key
CReflectableLuaRef * lhs = ( CReflectableLuaRef * ) ls . toUserData ( 1 ) ;
CReflectableLuaRef * rhs = ( CReflectableLuaRef * ) ls . toUserData ( 2 ) ;
nlassert ( lhs ) ;
nlassert ( rhs ) ;
ls . push ( lhs - > Ptr = = rhs - > Ptr ) ;
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : luaUIDtor ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_luaUIDtor)
nlassert ( ls . getTop ( ) = = 1 ) ;
// get the userdata
CReflectableLuaRef * pRefElm = ( CReflectableLuaRef * ) ls . toUserData ( 1 ) ;
nlassert ( pRefElm ) ;
// call dtor
pRefElm - > ~ CReflectableLuaRef ( ) ;
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : luaUINext ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_luaUINext)
// Code below allow enumeration of properties of a reflectable object
// From lua standpoint, the object is seen as a table with (key, value) pairs
// If object is a CInterfaceGroup, iteration is also done on sons (groups, controls & view).
if ( ls . getTop ( ) ! = 2 )
{
CLuaIHM : : fails ( ls , " __next metamethod require 2 arguments (table & key) " ) ;
}
CLuaIHM : : check ( ls , isReflectableOnStack ( ls , 1 ) , " __next : require ui element as first arg " ) ;
CReflectableRefPtrTarget * reflectedObject = getReflectableOnStack ( ls , 1 ) ;
// To traverse all properties / field of the object, we must be able to determine the next key from a previous key
// (keys are ordered)
// We use the 'TValueType' enum to know which kind of property we are traversing, and an index in this group of properties
// The key which uniquely identify an element / property in the reflectable object
struct CKey
{
enum TValueType
{
VTGroup = 0 , // children groups (If the object is a CInterfaceGroup)
VTView , // children views (If the object is a CInterfaceView)
VTCtrl , // children controls (If the object is a CInterfaceCtrl)
VTProp // List of exported proeprties (For all relfectable objects)
} ;
TValueType ValueType ;
sint Index ;
const CClassInfo * ClassInfo ; // if ValueType is "VTProp" -> give the class for which property are currently enumerated
//
static int tostring ( CLuaState & ls ) // '__print' metamathod
{
CLuaIHM : : checkArgCount ( ls , " reflected object metatable:__print " , 1 ) ;
CKey key ;
key . pop ( ls ) ;
switch ( key . ValueType )
{
case VTGroup : ls . push ( toString ( " _Group %d " , key . Index ) ) ; break ;
case VTView : ls . push ( toString ( " _View %d " , key . Index ) ) ; break ;
case VTCtrl : ls . push ( toString ( " _Ctrl %d " , key . Index ) ) ; break ;
case VTProp : ls . push ( key . ClassInfo - > Properties [ key . Index ] . Name ) ; break ;
}
return 1 ;
}
// push the key on the lua stack
void push ( CLuaState & ls )
{
void * ud = ls . newUserData ( sizeof ( * this ) ) ;
* ( CKey * ) ud = * this ;
getMetaTable ( ls ) . push ( ) ;
ls . setMetaTable ( - 2 ) ;
}
// pop the key from the lua stack
void pop ( CLuaState & ls )
{
CLuaStackChecker lsc ( & ls , - 1 ) ;
if ( ! ls . isUserData ( - 1 ) )
{
CLuaIHM : : fails ( ls , " Can't pop object, not a user data " ) ;
}
// check that metatable is good (it is share between all keys)
ls . getMetaTable ( - 1 ) ;
getMetaTable ( ls ) . push ( ) ;
if ( ! ls . rawEqual ( - 1 , - 2 ) )
{
CLuaIHM : : fails ( ls , " Bad metatable for reflectable object key " ) ;
}
ls . pop ( 2 ) ;
// retrieve key
* this = * ( CKey * ) ls . toUserData ( - 1 ) ;
ls . pop ( ) ;
}
// get the metatable for a CKey
CLuaObject & getMetaTable ( CLuaState & ls )
{
static CLuaObject metatable ;
if ( ! metatable . isValid ( ) )
{
// first build
CLuaStackChecker lsc ( & ls ) ;
ls . newTable ( ) ;
ls . push ( " __tostring " ) ;
ls . push ( CKey : : tostring ) ;
ls . setTable ( - 3 ) ;
metatable . pop ( ls ) ;
}
return metatable ;
}
} ;
// Pop the current key to continue enumeration
CKey key ;
if ( ls . isNil ( 2 ) )
{
// no key -> start of table
key . ValueType = CKey : : VTGroup ;
key . Index = - 1 ;
}
else
{
key . pop ( ls ) ;
}
//
CInterfaceGroup * group = dynamic_cast < CInterfaceGroup * > ( reflectedObject ) ;
bool enumerate = true ;
while ( enumerate )
{
switch ( key . ValueType )
{
case CKey : : VTGroup :
if ( ! group | | ( key . Index + 1 ) = = ( sint ) group - > getGroups ( ) . size ( ) )
{
key . Index = - 1 ;
key . ValueType = CKey : : VTView ; // continue enumeration with views
}
else
{
+ + key . Index ;
key . push ( ls ) ;
CLuaIHM : : pushUIOnStack ( ls , group - > getGroups ( ) [ key . Index ] ) ;
return 2 ;
}
break ;
case CKey : : VTView :
if ( ! group | | ( key . Index + 1 ) = = ( sint ) group - > getViews ( ) . size ( ) )
{
key . Index = - 1 ;
key . ValueType = CKey : : VTCtrl ; // continue enumeration with controls
}
else
{
+ + key . Index ;
key . push ( ls ) ;
CLuaIHM : : pushUIOnStack ( ls , group - > getViews ( ) [ key . Index ] ) ;
return 2 ;
}
break ;
case CKey : : VTCtrl :
if ( ! group | | ( key . Index + 1 ) = = ( sint ) group - > getControls ( ) . size ( ) )
{
key . Index = - 1 ;
key . ValueType = CKey : : VTProp ; // continue enumeration with properties
key . ClassInfo = reflectedObject - > getClassInfo ( ) ;
}
else
{
+ + key . Index ;
key . push ( ls ) ;
CLuaIHM : : pushUIOnStack ( ls , group - > getControls ( ) [ key . Index ] ) ;
return 2 ;
}
break ;
case CKey : : VTProp :
if ( ! key . ClassInfo )
{
enumerate = false ;
break ;
}
if ( ( sint ) key . ClassInfo - > Properties . size ( ) = = ( key . Index + 1 ) )
{
key . ClassInfo = key . ClassInfo - > ParentClass ; // continue enumeration in parent class
key . Index = - 1 ;
}
else
{
+ + key . Index ;
key . push ( ls ) ;
luaValueFromReflectedProperty ( ls , * reflectedObject , key . ClassInfo - > Properties [ key . Index ] ) ;
return 2 ;
}
break ;
default :
nlassert ( 0 ) ;
break ;
}
}
ls . pushNil ( ) ;
return 0 ;
}
int CLuaIHM : : getClientCfgVar ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_getClientCfgVar)
const char * funcName = " getClientCfgVar " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TSTRING ) ;
std : : string varName = ls . toString ( 1 ) ;
CConfigFile : : CVar * v = ClientCfg . ConfigFile . getVarPtr ( varName ) ;
if ( ! v ) return 0 ;
if ( v - > size ( ) = = 1 )
{
switch ( v - > Type )
{
case CConfigFile : : CVar : : T_REAL :
ls . push ( ( double ) v - > asDouble ( ) ) ;
return 1 ;
break ;
case CConfigFile : : CVar : : T_STRING :
ls . push ( v - > asString ( ) ) ;
return 1 ;
break ;
default : // handle both T_INT && T_BOOL
case CConfigFile : : CVar : : T_INT :
ls . push ( ( double ) v - > asInt ( ) ) ;
return 1 ;
break ;
}
}
else
{
ls . newTable ( ) ;
CLuaObject result ( ls ) ;
uint count = 0 ;
for ( uint i = 0 ; ( sint ) i < v - > StrValues . size ( ) ; i + + )
{
result . setValue ( toString ( count ) . c_str ( ) , v - > StrValues [ i ] ) ;
count + + ;
}
for ( uint i = 0 ; ( sint ) i < v - > IntValues . size ( ) ; i + + )
{
result . setValue ( toString ( count ) . c_str ( ) , ( double ) v - > IntValues [ i ] ) ;
count + + ;
}
for ( uint i = 0 ; ( sint ) i < v - > RealValues . size ( ) ; i + + )
{
result . setValue ( toString ( count ) . c_str ( ) , ( double ) v - > RealValues [ i ] ) ;
count + + ;
}
result . push ( ) ;
return 1 ;
}
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : luaClientCfgIndex ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_luaClientCfgIndex)
CConfigFile : : CVar * v = ClientCfg . ConfigFile . getVarPtr ( ls . toString ( 2 ) ) ;
if ( ! v ) return 0 ;
if ( v - > size ( ) ! = 1 )
{
// arrays not implemented (would require a second metatable)....
throw ELuaWrappedFunctionException ( & ls , " Access to array inside client.cfg not supported. " ) ;
}
switch ( v - > Type )
{
case CConfigFile : : CVar : : T_REAL :
ls . push ( ( double ) v - > asDouble ( ) ) ;
return 1 ;
break ;
case CConfigFile : : CVar : : T_STRING :
ls . push ( v - > asString ( ) ) ;
return 1 ;
break ;
default : // handle both T_INT && T_BOOL
case CConfigFile : : CVar : : T_INT :
ls . push ( ( double ) v - > asInt ( ) ) ;
return 1 ;
break ;
}
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : luaClientCfgNewIndex ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_luaClientCfgNewIndex)
throw ELuaWrappedFunctionException ( & ls , " Can't write into config file from lua. " ) ;
}
// ***************************************************************************
void CLuaIHM : : createLuaEnumTable ( CLuaState & ls , const std : : string & str )
{
//H_AUTO(Lua_CLuaIHM_createLuaEnumTable)
std : : string path = " " , script , p ;
CSString s = str ;
// Create table recursively (ex: 'game.TPVPClan' will check/create the table 'game' and 'game.TPVPClan')
p = s . splitTo ( ' . ' , true ) ;
while ( p . size ( ) > 0 )
{
if ( path = = " " )
path = p ;
else
path + = " . " + p ;
script = " if ( " + path + " == nil) then " + path + " = {}; end " ;
ls . executeScript ( script ) ;
p = s . splitTo ( ' . ' , true ) ;
}
}
# define LUABIND_ENUM(__enum__, __name__, __num__, __toStringFunc__) \
createLuaEnumTable ( ls , __name__ ) ; \
for ( uint e = 0 ; e < __num__ ; e + + ) \
{ \
std : : string str = __toStringFunc__ ( ( __enum__ ) e ) ; \
std : : string temp = __name__ + toString ( " . " ) + __toStringFunc__ ( ( __enum__ ) e ) + " = " + toString ( " %d; " , e ) ; \
ls . executeScript ( temp ) ; \
} \
// ***************************************************************************
2010-05-10 18:37:23 +00:00
# define LUABIND_FUNC(__func__) luabind::def(#__func__, &__func__)
2010-05-06 00:08:41 +00:00
void CLuaIHM : : registerIHM ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_registerIHM)
CLuaStackChecker lsc ( & ls ) ;
// *** Register the metatable for access to client.cfg (nb nico this may be more general later -> access to any config file ...)
{
ls . pushValue ( LUA_GLOBALSINDEX ) ;
CLuaObject globals ( ls ) ;
CLuaObject clientCfg = globals . newTable ( " config " ) ;
CLuaObject mt = globals . newTable ( " __cfmt " ) ;
nlverify ( clientCfg . setMetaTable ( mt ) ) ;
mt . setValue ( " __index " , luaClientCfgIndex ) ;
mt . setValue ( " __newindex " , luaClientCfgNewIndex ) ;
globals . setNil ( " __cfmt " ) ; // remove temp metatable
}
// *** Register the MetaTable for UI userdata
ls . push ( IHM_LUA_METATABLE ) ; // "__ui_metatable"
ls . newTable ( ) ; // "__ui_metatable" {}
// set the '__index' method
ls . push ( " __index " ) ;
ls . push ( luaUIIndex ) ;
nlassert ( ls . isCFunction ( ) ) ;
ls . setTable ( - 3 ) ; // "__ui_metatable" {"__index"= CFunc_luaUIIndex}
// set the '__newindex' method
ls . push ( " __newindex " ) ;
ls . push ( luaUINewIndex ) ;
nlassert ( ls . isCFunction ( ) ) ;
ls . setTable ( - 3 ) ;
// set the '__newindex' method
ls . push ( " __gc " ) ;
ls . push ( luaUIDtor ) ;
nlassert ( ls . isCFunction ( ) ) ;
ls . setTable ( - 3 ) ;
// set the '__eq' method
ls . push ( " __eq " ) ;
ls . push ( luaUIEq ) ;
nlassert ( ls . isCFunction ( ) ) ;
ls . setTable ( - 3 ) ;
// set the custom '__next' method
ls . push ( " __next " ) ;
ls . push ( luaUINext ) ;
nlassert ( ls . isCFunction ( ) ) ;
ls . setTable ( - 3 ) ;
// set registry
ls . setTable ( LUA_REGISTRYINDEX ) ;
// *** Register a Table for ui env.
ls . push ( IHM_LUA_ENVTABLE ) ; // "__ui_envtable"
ls . newTable ( ) ; // "__ui_envtable" {}
ls . setTable ( LUA_REGISTRYINDEX ) ;
// *** Register Functions
// Through std LUA API
ls . registerFunc ( " setOnDraw " , setOnDraw ) ;
ls . registerFunc ( " setCaptureKeyboard " , setCaptureKeyboard ) ;
ls . registerFunc ( " resetCaptureKeyboard " , resetCaptureKeyboard ) ;
ls . registerFunc ( " validMessageBox " , validMessageBox ) ;
ls . registerFunc ( " setTopWindow " , setTopWindow ) ;
ls . registerFunc ( " concatUCString " , concatUCString ) ;
ls . registerFunc ( " concatString " , concatString ) ;
ls . registerFunc ( " tableToString " , tableToString ) ;
ls . registerFunc ( " addOnDbChange " , addOnDbChange ) ;
ls . registerFunc ( " removeOnDbChange " , removeOnDbChange ) ;
ls . registerFunc ( " getUICaller " , getUICaller ) ;
ls . registerFunc ( " getCurrentWindowUnder " , getCurrentWindowUnder ) ;
ls . registerFunc ( " getUI " , getUI ) ;
ls . registerFunc ( " getIndexInDB " , getIndexInDB ) ;
ls . registerFunc ( " getUIId " , getUIId ) ;
ls . registerFunc ( " createGroupInstance " , createGroupInstance ) ;
ls . registerFunc ( " createUIElement " , createUIElement ) ;
ls . registerFunc ( " launchContextMenuInGame " , launchContextMenuInGame ) ;
ls . registerFunc ( " parseInterfaceFromString " , parseInterfaceFromString ) ;
ls . registerFunc ( " updateAllLocalisedElements " , updateAllLocalisedElements ) ;
ls . registerFunc ( " runAH " , runAH ) ;
ls . registerFunc ( " runExpr " , runExpr ) ;
ls . registerFunc ( " runFct " , runFct ) ;
ls . registerFunc ( " runCommand " , runCommand ) ;
ls . registerFunc ( " formatUI " , formatUI ) ;
ls . registerFunc ( " formatDB " , formatDB ) ;
ls . registerFunc ( " deleteUI " , deleteUI ) ;
ls . registerFunc ( " deleteReflectable " , deleteReflectable ) ;
ls . registerFunc ( " dumpUI " , dumpUI ) ;
ls . registerFunc ( " setKeyboardContext " , setKeyboardContext ) ;
ls . registerFunc ( " breakPoint " , breakPoint ) ;
ls . registerFunc ( " getWindowSize " , getWindowSize ) ;
ls . registerFunc ( " setTextFormatTaged " , setTextFormatTaged ) ;
ls . registerFunc ( " initEmotesMenu " , initEmotesMenu ) ;
ls . registerFunc ( " isUCString " , isUCString ) ;
ls . registerFunc ( " hideAllWindows " , hideAllWindows ) ;
ls . registerFunc ( " hideAllNonSavableWindows " , hideAllNonSavableWindows ) ;
ls . registerFunc ( " getDesktopIndex " , getDesktopIndex ) ;
ls . registerFunc ( " setLuaBreakPoint " , setLuaBreakPoint ) ;
ls . registerFunc ( " getMainPageURL " , getMainPageURL ) ;
ls . registerFunc ( " getCharSlot " , getCharSlot ) ;
ls . registerFunc ( " getPathContent " , getPathContent ) ;
ls . registerFunc ( " getServerSeason " , getServerSeason ) ;
ls . registerFunc ( " computeCurrSeason " , computeCurrSeason ) ;
ls . registerFunc ( " getAutoSeason " , getAutoSeason ) ;
ls . registerFunc ( " getTextureSize " , getTextureSize ) ;
ls . registerFunc ( " enableModalWindow " , enableModalWindow ) ;
ls . registerFunc ( " disableModalWindow " , disableModalWindow ) ;
ls . registerFunc ( " getPlayerPos " , getPlayerPos ) ;
ls . registerFunc ( " displaySystemInfo " , displaySystemInfo ) ;
ls . registerFunc ( " disableContextHelpForControl " , disableContextHelpForControl ) ;
ls . registerFunc ( " disableContextHelp " , disableContextHelp ) ;
ls . registerFunc ( " setWeatherValue " , setWeatherValue ) ;
ls . registerFunc ( " getWeatherValue " , getWeatherValue ) ;
ls . registerFunc ( " getCompleteIslands " , getCompleteIslands ) ;
ls . registerFunc ( " getIslandId " , getIslandId ) ;
ls . registerFunc ( " getClientCfgVar " , getClientCfgVar ) ;
ls . registerFunc ( " isPlayerFreeTrial " , isPlayerFreeTrial ) ;
ls . registerFunc ( " isPlayerNewbie " , isPlayerNewbie ) ;
ls . registerFunc ( " isInRingMode " , isInRingMode ) ;
ls . registerFunc ( " getUserRace " , getUserRace ) ;
// Through LUABind API
lua_State * L = ls . getStatePointer ( ) ;
2010-05-10 18:37:23 +00:00
luabind : : module ( L )
[
LUABIND_FUNC ( getDbProp ) ,
LUABIND_FUNC ( setDbProp ) ,
LUABIND_FUNC ( debugInfo ) ,
LUABIND_FUNC ( rawDebugInfo ) ,
LUABIND_FUNC ( dumpCallStack ) ,
LUABIND_FUNC ( getDefine ) ,
LUABIND_FUNC ( setContextHelpText ) ,
luabind : : def ( " messageBox " , ( void ( * ) ( const ucstring & ) ) & messageBox ) ,
luabind : : def ( " messageBox " , ( void ( * ) ( const ucstring & , const std : : string & ) ) & messageBox ) ,
luabind : : def ( " messageBox " , ( void ( * ) ( const ucstring & , const std : : string & , int caseMode ) ) & messageBox ) ,
luabind : : def ( " messageBox " , ( void ( * ) ( const std : : string & ) ) & messageBox ) ,
luabind : : def ( " messageBoxWithHelp " , ( void ( * ) ( const ucstring & ) ) & messageBoxWithHelp ) ,
luabind : : def ( " messageBoxWithHelp " , ( void ( * ) ( const ucstring & , const std : : string & ) ) & messageBoxWithHelp ) ,
luabind : : def ( " messageBoxWithHelp " , ( void ( * ) ( const ucstring & , const std : : string & , int caseMode ) ) & messageBoxWithHelp ) ,
luabind : : def ( " messageBoxWithHelp " , ( void ( * ) ( const std : : string & ) ) & messageBoxWithHelp ) ,
luabind : : def ( " findReplaceAll " , ( std : : string ( * ) ( const std : : string & , const std : : string & , const std : : string & ) ) & findReplaceAll ) ,
luabind : : def ( " findReplaceAll " , ( ucstring ( * ) ( const ucstring & , const ucstring & , const ucstring & ) ) & findReplaceAll ) ,
luabind : : def ( " findReplaceAll " , ( ucstring ( * ) ( const ucstring & , const std : : string & , const std : : string & ) ) & findReplaceAll ) ,
luabind : : def ( " findReplaceAll " , ( ucstring ( * ) ( const ucstring & , const ucstring & , const std : : string & ) ) & findReplaceAll ) ,
luabind : : def ( " findReplaceAll " , ( ucstring ( * ) ( const ucstring & , const std : : string & , const ucstring & ) ) & findReplaceAll ) ,
LUABIND_FUNC ( getPlayerSelectedSlot ) ,
LUABIND_FUNC ( isInGame ) ,
LUABIND_FUNC ( pauseBGDownloader ) ,
LUABIND_FUNC ( unpauseBGDownloader ) ,
LUABIND_FUNC ( requestBGDownloaderPriority ) ,
LUABIND_FUNC ( getBGDownloaderPriority ) ,
LUABIND_FUNC ( getPatchLastErrorMessage ) ,
LUABIND_FUNC ( isPlayerSlotNewbieLand ) ,
LUABIND_FUNC ( getSkillIdFromName ) ,
LUABIND_FUNC ( getSkillLocalizedName ) ,
LUABIND_FUNC ( getMaxSkillValue ) ,
LUABIND_FUNC ( getBaseSkillValueMaxChildren ) ,
LUABIND_FUNC ( getMagicResistChance ) ,
LUABIND_FUNC ( getDodgeParryChance ) ,
LUABIND_FUNC ( browseNpcWebPage ) ,
LUABIND_FUNC ( clearHtmlUndoRedo ) ,
LUABIND_FUNC ( getDynString ) ,
LUABIND_FUNC ( isDynStringAvailable ) ,
LUABIND_FUNC ( isFullyPatched ) ,
LUABIND_FUNC ( getSheetType ) ,
LUABIND_FUNC ( getSheetName ) ,
LUABIND_FUNC ( getFameIndex ) ,
LUABIND_FUNC ( getFameName ) ,
LUABIND_FUNC ( getFameDBIndex ) ,
LUABIND_FUNC ( getFirstTribeFameIndex ) ,
LUABIND_FUNC ( getNbTribeFameIndex ) ,
LUABIND_FUNC ( getClientCfg ) ,
LUABIND_FUNC ( fileExists ) ,
LUABIND_FUNC ( sendMsgToServer ) ,
LUABIND_FUNC ( sendMsgToServerPvpTag ) ,
LUABIND_FUNC ( isGuildQuitAvailable ) ,
LUABIND_FUNC ( sortGuildMembers ) ,
LUABIND_FUNC ( getNbGuildMembers ) ,
LUABIND_FUNC ( getGuildMemberName ) ,
LUABIND_FUNC ( getGuildMemberGrade ) ,
LUABIND_FUNC ( isR2Player ) ,
LUABIND_FUNC ( getR2PlayerRace ) ,
LUABIND_FUNC ( isR2PlayerMale ) ,
LUABIND_FUNC ( getCharacterSheetSkel ) ,
LUABIND_FUNC ( getSheetId ) ,
LUABIND_FUNC ( getCharacterSheetRegionForce ) ,
LUABIND_FUNC ( getCharacterSheetRegionLevel ) ,
LUABIND_FUNC ( replacePvpEffectParam ) ,
LUABIND_FUNC ( getRegionByAlias ) ,
LUABIND_FUNC ( tell ) ,
LUABIND_FUNC ( isRingAccessPointInReach ) ,
LUABIND_FUNC ( updateTooltipCoords ) ,
LUABIND_FUNC ( secondsSince1970ToHour ) ,
LUABIND_FUNC ( isCtrlKeyDown ) ,
LUABIND_FUNC ( encodeURLUnicodeParam ) ,
# if !FINAL_VERSION
LUABIND_FUNC ( openDoc ) ,
LUABIND_FUNC ( launchProgram ) ,
# endif
luabind : : def ( " fileLookup " , CMiscFunctions : : fileLookup ) ,
luabind : : def ( " shellExecute " , CMiscFunctions : : shellExecute ) ,
LUABIND_FUNC ( getPlayerLevel ) ,
LUABIND_FUNC ( getTargetLevel ) ,
LUABIND_FUNC ( getTargetForceRegion ) ,
LUABIND_FUNC ( getTargetLevelForce ) ,
LUABIND_FUNC ( isTargetNPC ) ,
LUABIND_FUNC ( isTargetPlayer ) , // return 'true' if the target is an npc
LUABIND_FUNC ( isTargetUser ) ,
LUABIND_FUNC ( isPlayerInPVPMode ) ,
LUABIND_FUNC ( isTargetInPVPMode )
] ;
LUABIND_ENUM ( PVP_CLAN : : TPVPClan , " game.TPVPClan " , PVP_CLAN : : NbClans , PVP_CLAN : : toString ) ;
LUABIND_ENUM ( BONUS_MALUS : : TBonusMalusSpecialTT , " game.TBonusMalusSpecialTT " , BONUS_MALUS : : NbSpecialTT , BONUS_MALUS : : toString ) ;
2010-05-06 00:08:41 +00:00
// inside i18n table
luabind : : module ( L , " i18n " )
[
luabind : : def ( " get " , & CI18N : : get ) ,
luabind : : def ( " hasTranslation " , & CI18N : : hasTranslation )
] ;
// inside 'nlfile' table
luabind : : module ( L , " nlfile " )
[
luabind : : def ( " getFilename " , NLMISC : : CFile : : getFilename ) ,
luabind : : def ( " getExtension " , NLMISC : : CFile : : getExtension ) ,
luabind : : def ( " getFilenameWithoutExtension " , NLMISC : : CFile : : getFilenameWithoutExtension )
] ;
// inside 'nltime' table
luabind : : module ( L , " nltime " )
[
luabind : : def ( " getPreciseLocalTime " , getPreciseLocalTime ) ,
luabind : : def ( " getSecondsSince1970 " , NLMISC : : CTime : : getSecondsSince1970 ) ,
luabind : : def ( " getLocalTime " , getLocalTime ) // NB : use CLuaIHM::getLocalTime instead of NLMISC::CTime::getLocalTime, because the NLMISC
// version returns a uint64, which can't be casted into lua numbers (doubles ...)
] ;
}
// ***************************************************************************
double CLuaIHM : : getPreciseLocalTime ( )
{
//H_AUTO(Lua_CLuaIHM_getPreciseLocalTime)
// don't export these 2 function to lua directly here, because all uint64 can't be represented with lua 'numbers'
return NLMISC : : CTime : : ticksToSecond ( NLMISC : : CTime : : getPerformanceTime ( ) ) ;
}
// ***************************************************************************
void CLuaIHM : : registerAll ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_registerAll)
registerBasics ( ls ) ;
registerIHM ( ls ) ;
}
//#define CHECK_REFLECTABLE_MT
// ***************************************************************************
void CLuaIHM : : pushReflectableOnStack ( CLuaState & ls , class CReflectableRefPtrTarget * pRPT )
{
//H_AUTO(Lua_CLuaIHM_pushReflectableOnStack)
nlassert ( pRPT ) ;
CLuaStackChecker lsc ( & ls , 1 ) ;
if ( ! pRPT )
{
ls . pushNil ( ) ;
return ;
}
//ls.dumpStack();
/** if there's already a ref ptr for this object in the registry, then use it,
* else create a new one to avoid costly allocations
*/
ls . pushLightUserData ( pRPT ) ;
ls . getTable ( LUA_REGISTRYINDEX ) ;
//ls.dumpStack();
if ( ls . isNil ( ) )
{
ls . pop ( 1 ) ;
//ls.dumpStack();
// allocate the user data where to put the ref ptr
void * ptr = ls . newUserData ( sizeof ( CReflectableLuaRef ) ) ;
nlassert ( ptr ) ;
//ls.dumpStack();
// initialize it, and copy the given element
new ( ptr ) CReflectableLuaRef ( pRPT ) ;
// Assign to this user data the __ui_metatable
//ls.dumpStack();
ls . push ( IHM_LUA_METATABLE ) ; // userdata "__ui_metatable"
//ls.dumpStack();
ls . getTable ( LUA_REGISTRYINDEX ) ; // userdata __ui_metatable
//ls.dumpStack();
nlverify ( ls . setMetaTable ( - 2 ) ) ; // userdata
//ls.dumpStack();
// cache in registry
ls . pushLightUserData ( pRPT ) ;
ls . pushValue ( - 2 ) ; // copy for table insertion
//ls.dumpStack();
ls . setTable ( LUA_REGISTRYINDEX ) ;
//ls.dumpStack();
}
// Check that the metatable is correct
# ifdef CHECK_REFLECTABLE_MT
nlverify ( ls . getMetaTable ( - 1 ) ) ; // userdata __ui_metatable
ls . push ( " __index " ) ;
ls . getTable ( - 2 ) ;
ls . push ( " __newindex " ) ;
ls . getTable ( - 3 ) ;
ls . push ( " __gc " ) ;
ls . getTable ( - 4 ) ;
nlassert ( ls . isCFunction ( - 1 ) ) ;
nlassert ( ls . isCFunction ( - 2 ) ) ;
nlassert ( ls . isCFunction ( - 3 ) ) ;
ls . pop ( 4 ) ;
# endif
//ls.dumpStack();
}
// ***************************************************************************
bool CLuaIHM : : isReflectableOnStack ( CLuaState & ls , sint index )
{
//H_AUTO(Lua_CLuaIHM_isReflectableOnStack)
CLuaStackChecker lsc ( & ls ) ;
if ( ! ls . isUserData ( index ) )
return false ;
// verify that it is a UI with its metatable
if ( ! ls . getMetaTable ( index ) ) // ??? object_metatable
return false ;
ls . push ( IHM_LUA_METATABLE ) ; // ??? object_metatable "__ui_metatable"
ls . getTable ( LUA_REGISTRYINDEX ) ; // ??? object_metatable __ui_metatable
// equal test
bool ok = ls . rawEqual ( - 2 , - 1 ) ;
// Also must not be nil (maybe nil in case of LuaIHM still not registered)
ok = ok & & ! ls . isNil ( - 1 ) ;
ls . pop ( ) ;
ls . pop ( ) ;
return ok ;
}
// ***************************************************************************
CReflectableRefPtrTarget * CLuaIHM : : getReflectableOnStack ( CLuaState & ls , sint index )
{
//H_AUTO(Lua_CLuaIHM_getReflectableOnStack)
if ( ! isReflectableOnStack ( ls , index ) )
return NULL ;
CReflectableLuaRef * p = ( CReflectableLuaRef * ) ls . toUserData ( index ) ;
nlassert ( p - > Ptr ) ;
return p - > Ptr ;
}
// ***************************************************************************
void CLuaIHM : : pushUIOnStack ( CLuaState & ls , class CInterfaceElement * pIE )
{
//H_AUTO(Lua_CLuaIHM_pushUIOnStack)
pushReflectableOnStack ( ls , pIE ) ;
}
// ***************************************************************************
bool CLuaIHM : : isUIOnStack ( CLuaState & ls , sint index )
{
//H_AUTO(Lua_CLuaIHM_isUIOnStack)
return getUIOnStack ( ls , index ) ! = NULL ;
}
// ***************************************************************************
CInterfaceElement * CLuaIHM : : getUIOnStack ( CLuaState & ls , sint index )
{
//H_AUTO(Lua_CLuaIHM_getUIOnStack)
return dynamic_cast < CInterfaceElement * > ( getReflectableOnStack ( ls , index ) ) ;
}
// ***************************************************************************
// ***************************************************************************
// LUA IHM Functions
// ***************************************************************************
// ***************************************************************************
// ***************************************************************************
uint32 CLuaIHM : : getLocalTime ( )
{
//H_AUTO(Lua_CLuaIHM_getLocalTime)
return ( uint32 ) NLMISC : : CTime : : getLocalTime ( ) ;
}
// ***************************************************************************
sint32 CLuaIHM : : getDbProp ( const std : : string & dbProp )
{
//H_AUTO(Lua_CLuaIHM_getDbProp)
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
CCDBNodeLeaf * node = pIM - > getDbProp ( dbProp , false ) ;
if ( node )
return node - > getValue32 ( ) ;
else
{
debugInfo ( toString ( " getDbProp(): '%s' dbProp Not found " , dbProp . c_str ( ) ) ) ;
return 0 ;
}
}
void CLuaIHM : : setDbProp ( const std : : string & dbProp , sint32 value )
{
//H_AUTO(Lua_CLuaIHM_setDbProp)
// Do not allow Write on SERVER: or LOCAL:
static const std : : string dbServer = " SERVER: " ;
static const std : : string dbLocal = " LOCAL: " ;
static const std : : string dbLocalR2 = " LOCAL:R2 " ;
if ( ( 0 = = dbProp . compare ( 0 , dbServer . size ( ) , dbServer ) ) | |
( 0 = = dbProp . compare ( 0 , dbLocal . size ( ) , dbLocal ) )
)
{
if ( 0 ! = dbProp . compare ( 0 , dbLocalR2 . size ( ) , dbLocalR2 ) )
{
nlstop ;
throw ELuaIHMException ( " setDbProp() : You are not allowed to write on ' SERVER : . . . ' or ' LOCAL : . . . ' database " ) ;
}
}
// Write to the DB if found
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
CCDBNodeLeaf * node = pIM - > getDbProp ( dbProp , false ) ;
if ( node )
node - > setValue32 ( value ) ;
else
debugInfo ( toString ( " setDbProp(): '%s' dbProp Not found " , dbProp . c_str ( ) ) ) ;
}
// ***************************************************************************
void CLuaIHM : : debugInfo ( const std : : string & cstDbg )
{
//H_AUTO(Lua_CLuaIHM_debugInfo)
if ( ClientCfg . DisplayLuaDebugInfo )
{
std : : string dbg = cstDbg ;
if ( ClientCfg . LuaDebugInfoGotoButtonEnabled )
{
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
lua_State * ls = pIM - > getLuaState ( ) - > getStatePointer ( ) ;
lua_Debug luaDbg ;
if ( lua_getstack ( ls , 1 , & luaDbg ) )
{
if ( lua_getinfo ( ls , " lS " , & luaDbg ) )
{
// add a command button to jump to the wanted file
dbg = createGotoFileButtonTag ( luaDbg . short_src , luaDbg . currentline ) + dbg ;
}
}
}
rawDebugInfo ( dbg ) ;
}
}
// ***************************************************************************
void CLuaIHM : : rawDebugInfo ( const std : : string & dbg )
{
//H_AUTO(Lua_CLuaIHM_rawDebugInfo)
if ( ClientCfg . DisplayLuaDebugInfo )
{
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
if ( ! dbg . empty ( ) & & dbg [ 0 ] = = ' @ ' )
{
// if color is already given use the message as it
NLMISC : : InfoLog - > displayRawNL ( dbg . c_str ( ) ) ;
}
else
{
NLMISC : : InfoLog - > displayRawNL ( pIM - > formatLuaErrorSysInfo ( dbg ) . c_str ( ) ) ;
}
# ifdef LUA_NEVRAX_VERSION
if ( LuaDebuggerIDE )
{
LuaDebuggerIDE - > debugInfo ( dbg . c_str ( ) ) ;
}
# endif
pIM - > displaySystemInfo ( pIM - > formatLuaErrorSysInfo ( dbg ) ) ;
}
}
// ***************************************************************************
int CLuaIHM : : displaySystemInfo ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_displaySystemInfo)
const char * funcName = " displaySystemInfo " ;
checkArgCount ( ls , funcName , 2 ) ;
checkArgTypeUCString ( ls , funcName , 1 ) ;
checkArgType ( ls , funcName , 2 , LUA_TSTRING ) ;
ucstring msg ;
nlverify ( getUCStringOnStack ( ls , 1 , msg ) ) ;
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
pIM - > displaySystemInfo ( msg , ls . toString ( 2 ) ) ;
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : setWeatherValue ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_setWeatherValue)
const char * funcName = " setWeatherValue " ;
checkArgMin ( ls , funcName , 1 ) ;
checkArgMax ( ls , funcName , 2 ) ;
checkArgType ( ls , funcName , 1 , LUA_TBOOLEAN ) ;
// bool autoWeather = ls.toBoolean(1);
ClientCfg . ManualWeatherSetup = ! ls . toBoolean ( 1 ) ;
if ( ls . getTop ( ) = = 2 )
{
checkArgType ( ls , funcName , 2 , LUA_TNUMBER ) ;
ManualWeatherValue = ( float ) ls . toNumber ( 2 ) ;
}
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : getWeatherValue ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_getWeatherValue)
const char * funcName = " getWeatherValue " ;
checkArgCount ( ls , funcName , 0 ) ;
uint64 currDay = RT . getRyzomDay ( ) ;
float currHour = ( float ) RT . getRyzomTime ( ) ;
ls . push ( : : getBlendedWeather ( currDay , currHour , * WeatherFunctionParams , ContinentMngr . cur ( ) - > WeatherFunction ) ) ;
return 1 ;
}
void CLuaIHM : : dumpCallStack ( int startStackLevel )
{
//H_AUTO(Lua_CLuaIHM_dumpCallStack)
if ( ClientCfg . DisplayLuaDebugInfo )
{
lua_Debug dbg ;
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
lua_State * ls = pIM - > getLuaState ( ) - > getStatePointer ( ) ;
int stackLevel = startStackLevel ;
rawDebugInfo ( " Call stack : " ) ;
rawDebugInfo ( " ------------- " ) ;
while ( lua_getstack ( ls , stackLevel , & dbg ) )
{
if ( lua_getinfo ( ls , " lS " , & dbg ) )
{
std : : string result = createGotoFileButtonTag ( dbg . short_src , dbg . currentline ) + NLMISC : : toString ( " %s:%d: " , dbg . short_src , dbg . currentline ) ;
rawDebugInfo ( result ) ;
}
+ + stackLevel ;
}
}
}
// ***************************************************************************
void CLuaIHM : : getCallStackAsString ( int startStackLevel /*=0*/ , std : : string & result )
{
//H_AUTO(Lua_CLuaIHM_getCallStackAsString)
result . clear ( ) ;
lua_Debug dbg ;
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
lua_State * ls = pIM - > getLuaState ( ) - > getStatePointer ( ) ;
int stackLevel = startStackLevel ;
result + = " Call stack : \n " ;
result + = " ------------- " ;
while ( lua_getstack ( ls , stackLevel , & dbg ) )
{
if ( lua_getinfo ( ls , " lS " , & dbg ) )
{
result + = NLMISC : : toString ( " %s:%d: " , dbg . short_src , dbg . currentline ) ;
}
+ + stackLevel ;
}
}
// ***************************************************************************
std : : string CLuaIHM : : createGotoFileButtonTag ( const char * fileName , uint line )
{
//H_AUTO(Lua_CLuaIHM_createGotoFileButtonTag)
if ( ClientCfg . LuaDebugInfoGotoButtonEnabled )
{
// TODO nico : put this in the interface
// add a command button to jump to the wanted file
return toString ( " /$$%s|%s|lua|%s('%s', %d)$$/ " ,
ClientCfg . LuaDebugInfoGotoButtonTemplate . c_str ( ) ,
ClientCfg . LuaDebugInfoGotoButtonCaption . c_str ( ) ,
ClientCfg . LuaDebugInfoGotoButtonFunction . c_str ( ) ,
fileName ,
line
) ;
}
return " " ;
}
// ***************************************************************************
std : : string CLuaIHM : : getDefine ( const std : : string & def )
{
//H_AUTO(Lua_CLuaIHM_getDefine)
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
if ( ClientCfg . DisplayLuaDebugInfo & & ! pIM - > isDefineExist ( def ) )
debugInfo ( toString ( " getDefine(): '%s' not found " , def . c_str ( ) ) ) ;
return pIM - > getDefine ( def ) ;
}
// ***************************************************************************
static CEntityCL * getTargetSlot ( )
{
const char * dbPath = " UI:VARIABLES:TARGET:SLOT " ;
CInterfaceManager * im = CInterfaceManager : : getInstance ( ) ;
CCDBNodeLeaf * node = im - > getDbProp ( dbPath , false ) ;
if ( ! node ) return NULL ;
if ( ( uint8 ) node - > getValue32 ( ) = = ( uint8 ) CLFECOMMON : : INVALID_SLOT )
{
return NULL ;
}
return EntitiesMngr . entity ( ( uint ) node - > getValue32 ( ) ) ;
}
// ***************************************************************************
sint32 CLuaIHM : : getPlayerLevel ( )
{
if ( ! UserEntity ) return - 1 ;
CSkillManager * pSM = CSkillManager : : getInstance ( ) ;
uint32 maxskill = pSM - > getBestSkillValue ( SKILLS : : SC ) ;
maxskill = std : : max ( maxskill , pSM - > getBestSkillValue ( SKILLS : : SF ) ) ;
maxskill = std : : max ( maxskill , pSM - > getBestSkillValue ( SKILLS : : SH ) ) ;
maxskill = std : : max ( maxskill , pSM - > getBestSkillValue ( SKILLS : : SM ) ) ;
return sint32 ( maxskill ) ;
}
// ***************************************************************************
sint32 CLuaIHM : : getTargetLevel ( )
{
CEntityCL * target = getTargetSlot ( ) ;
if ( ! target ) return - 1 ;
if ( target - > isPlayer ( ) )
{
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
CCDBNodeLeaf * pDbPlayerLevel = pIM - > getDbProp ( pIM - > getDefine ( " target_player_level " ) ) ;
return pDbPlayerLevel ? pDbPlayerLevel - > getValue32 ( ) : - 1 ;
}
else
{
CCharacterSheet * pCS = dynamic_cast < CCharacterSheet * > ( SheetMngr . get ( target - > sheetId ( ) ) ) ;
if ( ! pCS ) return - 1 ;
// only display the consider if the target is attackable #523
if ( ! pCS - > Attackable ) return - 1 ;
if ( ! target - > properties ( ) . attackable ( ) ) return - 1 ;
return sint32 ( pCS - > Level ) ;
}
return - 1 ;
}
// ***************************************************************************
sint32 CLuaIHM : : getTargetForceRegion ( )
{
CEntityCL * target = getTargetSlot ( ) ;
if ( ! target ) return - 1 ;
if ( target - > isPlayer ( ) )
{
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
CCDBNodeLeaf * pDbPlayerLevel = pIM - > getDbProp ( pIM - > getDefine ( " target_player_level " ) ) ;
if ( ! pDbPlayerLevel ) return - 1 ;
sint nLevel = pDbPlayerLevel - > getValue32 ( ) ;
if ( nLevel < 250 )
{
return ( sint32 ) ( ( nLevel < 20 ) ? 1 : ( nLevel / 50 ) + 2 ) ;
}
else
{
return 8 ;
}
}
else
{
CCharacterSheet * pCS = dynamic_cast < CCharacterSheet * > ( SheetMngr . get ( target - > sheetId ( ) ) ) ;
return pCS ? ( sint32 ) pCS - > RegionForce : - 1 ;
}
return 0 ;
}
// ***************************************************************************
sint32 CLuaIHM : : getTargetLevelForce ( )
{
CEntityCL * target = getTargetSlot ( ) ;
if ( ! target ) return - 1 ;
if ( target - > isPlayer ( ) )
{
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
CCDBNodeLeaf * pDbPlayerLevel = pIM - > getDbProp ( pIM - > getDefine ( " target_player_level " ) ) ;
if ( ! pDbPlayerLevel ) return - 1 ;
sint nLevel = pDbPlayerLevel - > getValue32 ( ) ;
if ( nLevel < 250 )
{
return ( sint32 ) ( ( ( nLevel % 50 ) * 5 / 50 ) + 1 ) ;
}
else
{
return 6 ;
}
}
else
{
CCharacterSheet * pCS = dynamic_cast < CCharacterSheet * > ( SheetMngr . get ( target - > sheetId ( ) ) ) ;
return pCS ? ( sint32 ) pCS - > ForceLevel : - 1 ;
}
return 0 ;
}
// ***************************************************************************
bool CLuaIHM : : isTargetNPC ( )
{
CEntityCL * target = getTargetSlot ( ) ;
if ( ! target ) return false ;
return target - > isNPC ( ) ;
}
// ***************************************************************************
bool CLuaIHM : : isTargetPlayer ( )
{
CEntityCL * target = getTargetSlot ( ) ;
if ( ! target ) return false ;
return target - > isPlayer ( ) ;
}
// ***************************************************************************
bool CLuaIHM : : isTargetUser ( )
{
CEntityCL * target = getTargetSlot ( ) ;
if ( ! target ) return false ;
return target - > isUser ( ) ;
}
// ***************************************************************************
bool CLuaIHM : : isPlayerInPVPMode ( )
{
if ( ! UserEntity ) return false ;
return ( UserEntity - > getPvpMode ( ) & PVP_MODE : : PvpZoneFaction ) ! = 0 ;
}
// ***************************************************************************
bool CLuaIHM : : isTargetInPVPMode ( )
{
CEntityCL * target = getTargetSlot ( ) ;
if ( ! target ) return false ;
return ( target - > getPvpMode ( ) & PVP_MODE : : PvpZoneFaction ) ! = 0 ;
}
// ***************************************************************************
void CLuaIHM : : pauseBGDownloader ( )
{
: : pauseBGDownloader ( ) ;
}
// ***************************************************************************
void CLuaIHM : : unpauseBGDownloader ( )
{
: : unpauseBGDownloader ( ) ;
}
// ***************************************************************************
void CLuaIHM : : requestBGDownloaderPriority ( uint priority )
{
if ( priority < 0 | | priority > = BGDownloader : : ThreadPriority_Count )
{
throw NLMISC : : Exception ( " requestBGDownloaderPriority() : invalid priority " ) ;
}
CBGDownloaderAccess : : getInstance ( ) . requestDownloadThreadPriority ( ( BGDownloader : : TThreadPriority ) priority , false ) ;
}
// ***************************************************************************
sint CLuaIHM : : getBGDownloaderPriority ( )
{
return CBGDownloaderAccess : : getInstance ( ) . getDownloadThreadPriority ( ) ;
}
// ***************************************************************************
ucstring CLuaIHM : : getPatchLastErrorMessage ( )
{
if ( isBGDownloadEnabled ( ) )
{
return CBGDownloaderAccess : : getInstance ( ) . getLastErrorMessage ( ) ;
}
else
{
CPatchManager * pPM = CPatchManager : : getInstance ( ) ;
return pPM - > getLastErrorMessage ( ) ;
}
}
// ***************************************************************************
bool CLuaIHM : : isInGame ( )
{
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
return pIM - > isInGame ( ) ;
}
// ***************************************************************************
uint32 CLuaIHM : : getPlayerSelectedSlot ( )
{
return ( uint32 ) PlayerSelectedSlot ;
}
// ***************************************************************************
bool CLuaIHM : : isPlayerSlotNewbieLand ( uint32 slot )
{
if ( slot > CharacterSummaries . size ( ) )
{
throw ELuaIHMException ( " isPlayerSlotNewbieLand() : Invalid slot % d " , (int) slot) ;
}
return CharacterSummaries [ slot ] . InNewbieland ;
}
// ***************************************************************************
void CLuaIHM : : messageBox ( const ucstring & text )
{
//H_AUTO(Lua_CLuaIHM_messageBox)
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
pIM - > messageBox ( text ) ;
}
// ***************************************************************************
void CLuaIHM : : messageBox ( const ucstring & text , const std : : string & masterGroup )
{
//H_AUTO(Lua_CLuaIHM_messageBox)
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
pIM - > messageBox ( text , masterGroup ) ;
}
// ***************************************************************************
void CLuaIHM : : messageBox ( const ucstring & text , const std : : string & masterGroup , int caseMode )
{
if ( caseMode < 0 | | caseMode > = CaseCount )
{
throw ELuaIHMException ( " messageBox: case mode value is invalid. " ) ;
}
//H_AUTO(Lua_CLuaIHM_messageBox)
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
pIM - > messageBox ( text , masterGroup , ( TCaseMode ) caseMode ) ;
}
// ***************************************************************************
void CLuaIHM : : messageBox ( const std : : string & text )
{
//H_AUTO(Lua_CLuaIHM_messageBox)
static volatile bool dumpCallStack = false ;
if ( dumpCallStack )
{
CLuaIHM : : dumpCallStack ( 0 ) ;
}
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
pIM - > messageBox ( text ) ;
}
// ***************************************************************************
void CLuaIHM : : messageBoxWithHelp ( const ucstring & text )
{
//H_AUTO(Lua_CLuaIHM_messageBox)
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
pIM - > messageBoxWithHelp ( text ) ;
}
// ***************************************************************************
void CLuaIHM : : messageBoxWithHelp ( const ucstring & text , const std : : string & masterGroup )
{
//H_AUTO(Lua_CLuaIHM_messageBox)
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
pIM - > messageBoxWithHelp ( text , masterGroup ) ;
}
// ***************************************************************************
void CLuaIHM : : messageBoxWithHelp ( const ucstring & text , const std : : string & masterGroup , int caseMode )
{
if ( caseMode < 0 | | caseMode > = CaseCount )
{
throw ELuaIHMException ( " messageBoxWithHelp: case mode value is invalid. " ) ;
}
//H_AUTO(Lua_CLuaIHM_messageBox)
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
pIM - > messageBoxWithHelp ( text , masterGroup , " " , " " , ( TCaseMode ) caseMode ) ;
}
// ***************************************************************************
void CLuaIHM : : messageBoxWithHelp ( const std : : string & text )
{
//H_AUTO(Lua_CLuaIHM_messageBox)
static volatile bool dumpCallStack = false ;
if ( dumpCallStack )
{
CLuaIHM : : dumpCallStack ( 0 ) ;
}
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
pIM - > messageBoxWithHelp ( text ) ;
}
// ***************************************************************************
void CLuaIHM : : setContextHelpText ( const ucstring & text )
{
//H_AUTO(Lua_CLuaIHM_setContextHelpText)
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
pIM - > setContextHelpText ( text ) ;
}
// ***************************************************************************
std : : string CLuaIHM : : findReplaceAll ( const std : : string & str , const std : : string & search , const std : : string & replace )
{
//H_AUTO(Lua_CLuaIHM_findReplaceAll)
std : : string ret = str ;
while ( strFindReplace ( ret , search , replace ) ) ;
return ret ;
}
// ***************************************************************************
ucstring CLuaIHM : : findReplaceAll ( const ucstring & str , const ucstring & search , const ucstring & replace )
{
//H_AUTO(Lua_CLuaIHM_findReplaceAll)
ucstring ret = str ;
while ( strFindReplace ( ret , search , replace ) ) ;
return ret ;
}
// ***************************************************************************
ucstring CLuaIHM : : findReplaceAll ( const ucstring & str , const std : : string & search , const std : : string & replace )
{
//H_AUTO(Lua_CLuaIHM_findReplaceAll)
return findReplaceAll ( str , ucstring ( search ) , ucstring ( replace ) ) ;
}
// ***************************************************************************
ucstring CLuaIHM : : findReplaceAll ( const ucstring & str , const std : : string & search , const ucstring & replace )
{
//H_AUTO(Lua_CLuaIHM_findReplaceAll)
return findReplaceAll ( str , ucstring ( search ) , ucstring ( replace ) ) ;
}
// ***************************************************************************
ucstring CLuaIHM : : findReplaceAll ( const ucstring & str , const ucstring & search , const std : : string & replace )
{
//H_AUTO(Lua_CLuaIHM_findReplaceAll)
return findReplaceAll ( str , ucstring ( search ) , ucstring ( replace ) ) ;
}
// ***************************************************************************
int CLuaIHM : : getUICaller ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_getUICaller)
CLuaStackChecker lsc ( & ls , 1 ) ;
// params: none.
// return: CInterfaceElement* (nil if error)
CInterfaceElement * pIE = CHandlerLUA : : getUICaller ( ) ;
if ( ! pIE )
{
ls . pushNil ( ) ;
debugInfo ( toString ( " getUICaller(): No UICaller found. return Nil " ) ) ;
}
else
{
pushUIOnStack ( ls , pIE ) ;
}
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : getCurrentWindowUnder ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_getCurrentWindowUnder)
CLuaStackChecker lsc ( & ls , 1 ) ;
CInterfaceManager * im = CInterfaceManager : : getInstance ( ) ;
CInterfaceElement * pIE = im - > getCurrentWindowUnder ( ) ;
if ( ! pIE )
{
ls . pushNil ( ) ;
debugInfo ( toString ( " getCurrentWindowUnder(): No UICaller found. return Nil " ) ) ;
}
else
{
pushUIOnStack ( ls , pIE ) ;
}
return 1 ;
}
int CLuaIHM : : getUI ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_getUI)
// params: "ui:interface:...".
// return: CInterfaceElement* (nil if error)
const char * funcName = " getUI " ;
check ( ls , ls . getTop ( ) = = 1 | | ls . getTop ( ) = = 2 , funcName ) ;
checkArgType ( ls , funcName , 1 , LUA_TSTRING ) ;
bool verbose = true ;
if ( ls . getTop ( ) > 1 )
{
checkArgType ( ls , funcName , 2 , LUA_TBOOLEAN ) ;
verbose = ls . toBoolean ( 2 ) ;
}
// get the string
std : : string eltStr ;
ls . toString ( 1 , eltStr ) ;
// return the element
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
CInterfaceElement * pIE = pIM - > getElementFromId ( eltStr ) ;
if ( ! pIE )
{
ls . pushNil ( ) ;
if ( verbose )
{
std : : string stackContext ;
ls . getStackContext ( stackContext , 1 ) ;
debugInfo ( toString ( " %s : getUI(): '%s' not found " , stackContext . c_str ( ) , eltStr . c_str ( ) ) ) ;
}
}
else
{
pushUIOnStack ( ls , pIE ) ;
}
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : getUIId ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_getUIId)
CLuaStackChecker lsc ( & ls , 1 ) ;
// params: CInterfaceElement*
// return: "ui:interface:...". (empty if error)
checkArgCount ( ls , " getUIId " , 1 ) ;
check ( ls , isUIOnStack ( ls , 1 ) , " getUIId() requires a UI object in param 1 " ) ;
// retrieve args
CInterfaceElement * pIE = getUIOnStack ( ls , 1 ) ;
// convert to id
if ( pIE )
ls . push ( pIE - > getId ( ) ) ;
else
ls . push ( " " ) ;
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : getIndexInDB ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_getIndexInDB)
CLuaStackChecker lsc ( & ls , 1 ) ;
// params: CDBCtrlSheet*
// return: index in DB of a dbctrlsheet (empty if error)
checkArgCount ( ls , " getIndexInDB " , 1 ) ;
check ( ls , isUIOnStack ( ls , 1 ) , " getIndexInDB() requires a UI object in param 1 " ) ;
// retrieve args
CInterfaceElement * pIE = getUIOnStack ( ls , 1 ) ;
CDBCtrlSheet * pCS = dynamic_cast < CDBCtrlSheet * > ( pIE ) ;
// get the index in db
if ( pCS )
ls . push ( ( double ) pCS - > getIndexInDB ( ) ) ;
else
ls . push ( 0.0 ) ;
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : createGroupInstance ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_createGroupInstance)
const char * funcName = " createGroupInstance " ;
CLuaIHM : : checkArgCount ( ls , funcName , 3 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TSTRING ) ;
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TSTRING ) ;
CLuaIHM : : checkArgType ( ls , funcName , 3 , LUA_TTABLE ) ;
std : : vector < std : : pair < std : : string , std : : string > > templateParams ;
CLuaObject params ;
params . pop ( ls ) ;
ENUM_LUA_TABLE ( params , it )
{
if ( ! it . nextKey ( ) . isString ( ) )
{
nlwarning ( " %s : bad key encountered with type %s, string expected. " , funcName , it . nextKey ( ) . getTypename ( ) ) ;
continue ;
}
if ( ! it . nextValue ( ) . isString ( ) )
{
nlwarning ( " %s : bad value encountered with type %s for key %s, string expected. " , funcName , it . nextValue ( ) . getTypename ( ) , it . nextKey ( ) . toString ( ) . c_str ( ) ) ;
continue ;
}
templateParams . push_back ( std : : pair < std : : string , std : : string > ( it . nextKey ( ) . toString ( ) , it . nextValue ( ) . toString ( ) ) ) ; // strange compilation bug here when I use std::make_pair ... :(
}
CInterfaceManager * im = CInterfaceManager : : getInstance ( ) ;
CInterfaceGroup * result = im - > createGroupInstance ( ls . toString ( 1 ) , ls . toString ( 2 ) , templateParams ) ;
if ( ! result )
{
ls . pushNil ( ) ;
}
else
{
CLuaIHM : : pushUIOnStack ( ls , result ) ;
}
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : createUIElement ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_createUIElement)
const char * funcName = " addUIElement " ;
CLuaIHM : : checkArgCount ( ls , funcName , 3 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TSTRING ) ;
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TSTRING ) ;
CLuaIHM : : checkArgType ( ls , funcName , 3 , LUA_TTABLE ) ;
std : : vector < std : : pair < std : : string , std : : string > > templateParams ;
CLuaObject params ;
params . pop ( ls ) ;
ENUM_LUA_TABLE ( params , it )
{
if ( ! it . nextKey ( ) . isString ( ) )
{
nlwarning ( " %s : bad key encountered with type %s, string expected. " , funcName , it . nextKey ( ) . getTypename ( ) ) ;
continue ;
}
if ( ! it . nextValue ( ) . isString ( ) )
{
nlwarning ( " %s : bad value encountered with type %s for key %s, string expected. " , funcName , it . nextValue ( ) . getTypename ( ) , it . nextKey ( ) . toString ( ) . c_str ( ) ) ;
continue ;
}
templateParams . push_back ( std : : pair < std : : string , std : : string > ( it . nextKey ( ) . toString ( ) , it . nextValue ( ) . toString ( ) ) ) ; // strange compilation bug here when I use std::make_pair ... :(
}
CInterfaceManager * im = CInterfaceManager : : getInstance ( ) ;
CInterfaceElement * result = im - > createUIElement ( ls . toString ( 1 ) , ls . toString ( 2 ) , templateParams ) ;
if ( ! result )
{
ls . pushNil ( ) ;
}
else
{
CLuaIHM : : pushUIOnStack ( ls , result ) ;
}
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : getCompleteIslands ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_getCompleteIslands)
const char * funcName = " getCompleteIslands " ;
CLuaIHM : : checkArgCount ( ls , funcName , 0 ) ;
ls . newTable ( ) ;
CLuaObject result ( ls ) ;
// load entryPoints
CScenarioEntryPoints scenarioEntryPoints = CScenarioEntryPoints : : getInstance ( ) ;
const CScenarioEntryPoints : : TCompleteIslands & islands = scenarioEntryPoints . getCompleteIslands ( ) ;
CScenarioEntryPoints : : TCompleteIslands : : const_iterator island ( islands . begin ( ) ) , lastIsland ( islands . end ( ) ) ;
for ( ; island ! = lastIsland ; + + island )
{
ls . newTable ( ) ;
CLuaObject islandTable ( ls ) ;
islandTable . setValue ( " continent " , island - > Continent ) ;
islandTable . setValue ( " xmin " , ( double ) island - > XMin ) ;
islandTable . setValue ( " ymin " , ( double ) island - > YMin ) ;
islandTable . setValue ( " xmax " , ( double ) island - > XMax ) ;
islandTable . setValue ( " ymax " , ( double ) island - > YMax ) ;
ls . newTable ( ) ;
CLuaObject entrypointsTable ( ls ) ;
for ( uint e = 0 ; e < island - > EntryPoints . size ( ) ; e + + )
{
const CScenarioEntryPoints : : CShortEntryPoint & entryPoint = island - > EntryPoints [ e ] ;
ls . newTable ( ) ;
CLuaObject entrypointTable ( ls ) ;
entrypointTable . setValue ( " x " , ( double ) entryPoint . X ) ;
entrypointTable . setValue ( " y " , ( double ) entryPoint . Y ) ;
entrypointsTable . setValue ( entryPoint . Location , entrypointTable ) ;
}
islandTable . setValue ( " entrypoints " , entrypointsTable ) ;
result . setValue ( island - > Island , islandTable ) ;
}
result . push ( ) ;
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : getIslandId ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_getIslandId)
const char * funcName = " getIslandId " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ;
check ( ls , ls . isString ( 1 ) , " getIslandId() requires a string in param 1 " ) ;
CScenarioEntryPoints scenarioEntryPoints = CScenarioEntryPoints : : getInstance ( ) ;
uint32 id = scenarioEntryPoints . getIslandId ( ls . toString ( 1 ) ) ;
ls . push ( ( double ) id ) ;
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : launchContextMenuInGame ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_launchContextMenuInGame)
CLuaStackChecker lsc ( & ls ) ;
checkArgCount ( ls , " launchContextMenuInGame " , 1 ) ;
check ( ls , ls . isString ( 1 ) , " launchContextMenuInGame() requires a string in param 1 " ) ;
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
pIM - > launchContextMenuInGame ( ls . toString ( 1 ) ) ;
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : parseInterfaceFromString ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_parseInterfaceFromString)
CLuaStackChecker lsc ( & ls , 1 ) ;
checkArgCount ( ls , " parseInterfaceFromString " , 1 ) ;
check ( ls , ls . isString ( 1 ) , " parseInterfaceFromString() requires a string in param 1 " ) ;
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
std : : vector < std : : string > script ( 1 ) ;
script [ 0 ] = ls . toString ( 1 ) ;
ls . push ( pIM - > parseInterface ( script , true , false ) ) ;
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : updateAllLocalisedElements ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_updateAllLocalisedElements)
TTime startTime = CTime : : getLocalTime ( ) ;
//
CLuaStackChecker lsc ( & ls ) ;
checkArgCount ( ls , " updateAllLocalisedElements " , 0 ) ;
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
pIM - > updateAllLocalisedElements ( ) ;
//
TTime endTime = CTime : : getLocalTime ( ) ;
if ( ClientCfg . R2EDVerboseParseTime )
{
nlinfo ( " %.2f seconds for 'updateAllLocalisedElements' " , ( endTime - startTime ) / 1000.f ) ;
}
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : setCaptureKeyboard ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_setCaptureKeyboard)
const char * funcName = " setCaptureKeyboard " ;
checkArgCount ( ls , funcName , 1 ) ;
checkArgTypeUIElement ( ls , funcName , 1 ) ;
CCtrlBase * ctrl = dynamic_cast < CCtrlBase * > ( getUIOnStack ( ls , 1 ) ) ;
if ( ! ctrl )
{
fails ( ls , " %s waits a ui control as arg 1 " , funcName ) ;
}
CInterfaceManager * im = CInterfaceManager : : getInstance ( ) ;
im - > setCaptureKeyboard ( ctrl ) ;
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : resetCaptureKeyboard ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_resetCaptureKeyboard)
const char * funcName = " resetCaptureKeyboard " ;
checkArgCount ( ls , funcName , 0 ) ;
CInterfaceManager * im = CInterfaceManager : : getInstance ( ) ;
im - > resetCaptureKeyboard ( ) ;
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : setOnDraw ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_setOnDraw)
CLuaStackChecker lsc ( & ls , 0 ) ;
// params: CInterfaceGroup*, "script".
// return: none
checkArgCount ( ls , " setOnDraw " , 2 ) ;
check ( ls , isUIOnStack ( ls , 1 ) , " setOnDraw() requires a UI object in param 1 " ) ;
check ( ls , ls . isString ( 2 ) , " setOnDraw() requires a string in param 2 " ) ;
// retrieve args
CInterfaceElement * pIE = getUIOnStack ( ls , 1 ) ;
std : : string script ;
ls . toString ( 2 , script ) ;
// must be a group
CInterfaceGroup * group = dynamic_cast < CInterfaceGroup * > ( pIE ) ;
if ( ! group )
throw ELuaIHMException ( " setOnDraw() : ' % s ' is not a group " , pIE->getId().c_str()) ;
// Set the script to be executed at each draw
group - > setLuaScriptOnDraw ( script ) ;
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : addOnDbChange ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_addOnDbChange)
CLuaStackChecker lsc ( & ls , 0 ) ;
// params: CInterfaceGroup*, "dblist", "script".
// return: none
checkArgCount ( ls , " addOnDbChange " , 3 ) ;
check ( ls , isUIOnStack ( ls , 1 ) , " addOnDbChange() requires a UI object in param 1 " ) ;
check ( ls , ls . isString ( 2 ) , " addOnDbChange() requires a string in param 2 " ) ;
check ( ls , ls . isString ( 3 ) , " addOnDbChange() requires a string in param 3 " ) ;
// retrieve args
CInterfaceElement * pIE = getUIOnStack ( ls , 1 ) ;
std : : string dbList , script ;
ls . toString ( 2 , dbList ) ;
ls . toString ( 3 , script ) ;
// must be a group
CInterfaceGroup * group = dynamic_cast < CInterfaceGroup * > ( pIE ) ;
if ( ! group )
throw ELuaIHMException ( " addOnDbChange() : ' % s ' is not a group " , pIE->getId().c_str()) ;
// Set the script to be executed when the given DB change
group - > addLuaScriptOnDBChange ( dbList , script ) ;
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : removeOnDbChange ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_removeOnDbChange)
CLuaStackChecker lsc ( & ls , 0 ) ;
// params: CInterfaceGroup*, "dbList"
// return: none
checkArgCount ( ls , " removeOnDbChange " , 2 ) ;
check ( ls , isUIOnStack ( ls , 1 ) , " removeOnDbChange() requires a UI object in param 1 " ) ;
check ( ls , ls . isString ( 2 ) , " removeOnDbChange() requires a string in param 2 " ) ;
// retrieve args
CInterfaceElement * pIE = getUIOnStack ( ls , 1 ) ;
std : : string dbList ;
ls . toString ( 2 , dbList ) ;
// must be a group
CInterfaceGroup * group = dynamic_cast < CInterfaceGroup * > ( pIE ) ;
if ( ! group )
throw ELuaIHMException ( " removeOnDbChange() : ' % s ' is not a group " , pIE->getId().c_str()) ;
// Remove the script to be executed when the given DB change
group - > removeLuaScriptOnDBChange ( dbList ) ;
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : runAH ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_runAH)
CLuaStackChecker lsc ( & ls , 0 ) ;
// params: CInterfaceElement *, "ah", "params".
// return: none
checkArgCount ( ls , " runAH " , 3 ) ;
check ( ls , isUIOnStack ( ls , 1 ) | | ls . isNil ( 1 ) , " runAH() requires a UI object in param 1 (or Nil) " ) ;
check ( ls , ls . isString ( 2 ) , " runAH() requires a string in param 2 " ) ;
check ( ls , ls . isString ( 3 ) , " runAH() requires a string in param 3 " ) ;
// retrieve args
CInterfaceElement * pIE = getUIOnStack ( ls , 1 ) ;
std : : string ah , params ;
ls . toString ( 2 , ah ) ;
ls . toString ( 3 , params ) ;
// run AH
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
// The element must be ctrl (or NULL)
CCtrlBase * ctrl = NULL ;
if ( pIE )
{
ctrl = dynamic_cast < CCtrlBase * > ( pIE ) ;
if ( ! ctrl )
throw ELuaIHMException ( " runAH() : ' % s ' is not a ctrl " , pIE->getId().c_str()) ;
}
pIM - > runActionHandler ( ah , ctrl , params ) ;
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : runExprAndPushResult ( CLuaState & ls , const std : : string & expr )
{
//H_AUTO(Lua_CLuaIHM_runExprAndPushResult)
// Execute expression
CInterfaceExprValue value ;
if ( CInterfaceExpr : : eval ( expr , value , NULL ) )
{
switch ( value . getType ( ) )
{
case CInterfaceExprValue : : Boolean :
ls . push ( value . getBool ( ) ) ;
break ;
case CInterfaceExprValue : : Integer :
ls . push ( ( double ) value . getInteger ( ) ) ;
break ;
case CInterfaceExprValue : : Double :
ls . push ( value . getDouble ( ) ) ;
break ;
case CInterfaceExprValue : : String :
{
ucstring ucstr = value . getUCString ( ) ;
// Yoyo: dynamically decide wether must return a string or a ucstring
bool mustUseUCString = false ;
for ( uint i = 0 ; i < ucstr . size ( ) ; i + + )
{
if ( ucstr [ i ] > 255 )
{
mustUseUCString = true ;
break ;
}
}
// push a ucstring?
if ( mustUseUCString )
{
luabind : : object obj ( ls . getStatePointer ( ) , ucstr ) ;
# if LUABIND_VERSION != 07
obj . pushvalue ( ) ;
# endif
}
else
{
ls . push ( ucstr . toString ( ) ) ;
}
break ;
}
case CInterfaceExprValue : : RGBA :
{
luabind : : object obj ( ls . getStatePointer ( ) , value . getRGBA ( ) ) ;
# if LUABIND_VERSION == 07
obj . push ( ls . getStatePointer ( ) ) ;
# else
obj . pushvalue ( ) ;
# endif
break ;
}
break ;
case CInterfaceExprValue : : UserType : // Yoyo: don't care UserType...
default :
ls . pushNil ( ) ;
break ;
}
}
else
ls . pushNil ( ) ;
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : runExpr ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_runExpr)
CLuaStackChecker lsc ( & ls , 1 ) ;
// params: "expr".
// return: any of: nil, bool, string, number, RGBA, UCString
checkArgCount ( ls , " runExpr " , 1 ) ;
check ( ls , ls . isString ( 1 ) , " runExpr() requires a string in param 1 " ) ;
// retrieve args
std : : string expr ;
ls . toString ( 1 , expr ) ;
// run expression and push result
return runExprAndPushResult ( ls , expr ) ;
}
// ***************************************************************************
int CLuaIHM : : runFct ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_runFct)
CLuaStackChecker lsc ( & ls , 1 ) ;
// params: "expr", param1, param2...
// return: any of: nil, bool, string, number, RGBA, UCString
checkArgMin ( ls , " runFct " , 1 ) ;
check ( ls , ls . isString ( 1 ) , " runExpr() requires a string in param 1 " ) ;
// retrieve fct
std : : string expr ;
ls . toString ( 1 , expr ) ;
expr + = " ( " ;
// retrieve params
uint top = ls . getTop ( ) ;
for ( uint i = 2 ; i < = top ; i + + )
{
if ( i > 2 )
expr + = " , " ;
// If it is a number
if ( ls . type ( i ) = = LUA_TNUMBER )
{
std : : string paramValue ;
ls . toString ( i , paramValue ) ; // nb: transformed to a string in the stack
expr + = paramValue ;
}
// else suppose a string
else
{
// must enclose with "'"
std : : string paramValue ;
ls . toString ( i , paramValue ) ;
expr + = std : : string ( " ' " ) + paramValue + std : : string ( " ' " ) ;
}
}
// end fct call
expr + = " ) " ;
// run expression and push result
return runExprAndPushResult ( ls , expr ) ;
}
// ***************************************************************************
int CLuaIHM : : runCommand ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_runCommand)
CLuaStackChecker lsc ( & ls , 1 ) ;
if ( ls . empty ( ) )
{
nlwarning ( " 'runCommand' : Command name expected " ) ;
ls . push ( false ) ;
return 1 ;
}
const char * commandName = ls . toString ( 1 ) ;
if ( ! commandName )
{
nlwarning ( " 'runCommand' : Bad command name " ) ;
ls . push ( false ) ;
return 1 ;
}
if ( ! NLMISC : : ICommand : : LocalCommands | | ! NLMISC : : ICommand : : LocalCommands - > count ( ls . toString ( 1 ) ) )
{
nlwarning ( " 'runCommand' : Command %s not found " , ls . toString ( 1 ) ) ;
ls . push ( false ) ;
return 1 ;
}
std : : string rawCommandString = ls . toString ( 1 ) ;
NLMISC : : ICommand * command = ( * NLMISC : : ICommand : : LocalCommands ) [ ls . toString ( 1 ) ] ;
nlassert ( command ) ;
std : : vector < std : : string > args ( ls . getTop ( ) - 1 ) ;
for ( uint k = 2 ; k < = ( uint ) ls . getTop ( ) ; + + k )
{
if ( ls . toString ( k ) )
{
args [ k - 2 ] = ls . toString ( k ) ;
rawCommandString + = " " + std : : string ( ls . toString ( k ) ) ;
}
}
ls . push ( command - > execute ( rawCommandString , args , g_log , false , true ) ) ;
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : formatUI ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_formatUI)
CLuaStackChecker lsc ( & ls , 1 ) ;
// params: "expr", param1, param2....
// return: string with # and % parsed
checkArgMin ( ls , " formatUI " , 1 ) ;
check ( ls , ls . isString ( 1 ) , " formatUI() require a string in param1 " ) ;
// get the string to format
std : : string propVal ;
ls . toString ( 1 , propVal ) ;
// *** format with %
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
std : : string newPropVal , defError ;
if ( ! pIM - > solveDefine ( propVal , newPropVal , defError ) )
{
throw ELuaIHMException ( " formatUI() : Can ' t find define : ' % s ' " , defError.c_str()) ;
}
// *** format with any additional parameter and #1, #2, #3 etc...
// search backward, starting from bigger param to replace (thus avoid to replace #1 before #13 for instance...)
sint stackIndex = ls . getTop ( ) ;
while ( stackIndex > 1 )
{
std : : string paramValue ;
ls . toString ( stackIndex , paramValue ) ;
// For stack param 4, the param index is 3 (because stack param 2 is the param No 1)
sint paramIndex = stackIndex - 1 ;
while ( NLMISC : : strFindReplace ( newPropVal , toString ( " #%d " , paramIndex ) , paramValue ) ) ;
// next
stackIndex - - ;
}
// return result
ls . push ( newPropVal ) ;
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : formatDB ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_formatDB)
CLuaStackChecker lsc ( & ls , 1 ) ;
// params: param1, param2....
// return: string with @ and , added
checkArgMin ( ls , " formatDB " , 1 ) ;
uint top = ls . getTop ( ) ;
std : : string dbRes ;
for ( uint i = 1 ; i < = top ; i + + )
{
if ( i = = 1 )
dbRes = " @ " ;
else
dbRes + = " , @ " ;
std : : string paramValue ;
ls . toString ( i , paramValue ) ;
dbRes + = paramValue ;
}
// return result
ls . push ( dbRes ) ;
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : deleteUI ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_deleteUI)
CLuaStackChecker lsc ( & ls , 0 ) ;
// params: CInterfaceElement *
// return: none
checkArgCount ( ls , " deleteUI " , 1 ) ;
check ( ls , isUIOnStack ( ls , 1 ) , " deleteUI() requires a UI object in param 1 " ) ;
// retrieve args
CInterfaceElement * pIE = getUIOnStack ( ls , 1 ) ;
if ( ! pIE )
return 0 ;
// has a parent?
CInterfaceGroup * parent = pIE - > getParent ( ) ;
if ( parent )
{
// correctly remove from parent
parent - > delElement ( pIE ) ;
}
else
{
// just delete
delete pIE ;
}
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : deleteReflectable ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_deleteReflectable)
CLuaStackChecker lsc ( & ls , 0 ) ;
// params: CInterfaceElement *
// return: none
checkArgCount ( ls , " deleteReflectable " , 1 ) ;
check ( ls , isReflectableOnStack ( ls , 1 ) , " deleteReflectable() requires a reflectable C++ object in param 1 " ) ;
// retrieve args
CReflectableRefPtrTarget * pRPT = getReflectableOnStack ( ls , 1 ) ;
if ( ! pRPT )
return 0 ;
CInterfaceElement * pIE = dynamic_cast < CInterfaceElement * > ( pRPT ) ;
if ( pIE )
{
// has a parent?
CInterfaceGroup * parent = pIE - > getParent ( ) ;
if ( parent )
{
// correctly remove from parent
parent - > delElement ( pIE ) ;
}
}
// just delete
delete pIE ;
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : dumpUI ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_dumpUI)
CLuaStackChecker lsc ( & ls , 0 ) ;
// params: CInterfaceElement *
// return: none
checkArgCount ( ls , " dumpUI " , 1 ) ;
check ( ls , isUIOnStack ( ls , 1 ) , " dumpUI() requires a UI object in param 1 " ) ;
// retrieve args
CInterfaceElement * pIE = getUIOnStack ( ls , 1 ) ;
if ( ! pIE )
debugInfo ( " UI: NULL " ) ;
else
{
// Display also Information on RefPtr (warning: don't modify pinfo!!!)
nlassert ( pIE - > pinfo ) ;
debugInfo ( NLMISC : : toString ( " UI: %x. %s. RefPtrCount: %d " , pIE , pIE - > getId ( ) . c_str ( ) ,
pIE - > pinfo - > IsNullPtrInfo ? 0 : pIE - > pinfo - > RefCount ) ) ;
}
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : setKeyboardContext ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_setKeyboardContext)
const char * funcName = " setKeyboardContext " ;
checkArgMin ( ls , funcName , 1 ) ;
checkArgType ( ls , funcName , 1 , LUA_TSTRING ) ;
ActionsContext . setContext ( ls . toString ( 1 ) ) ;
return 0 ;
}
// ***************************************************************************
void CLuaIHM : : fails ( CLuaState & ls , const char * format , . . . )
{
//H_AUTO(Lua_CLuaIHM_fails)
std : : string reason ;
NLMISC_CONVERT_VARGS ( reason , format , NLMISC : : MaxCStringSize ) ;
std : : string stack ;
ls . getStackAsString ( stack ) ;
// use a std::exception, to avoid Nel Exception warning
throw ELuaIHMException ( " %s. Lua stack = \n %s " , reason . c_str ( ) , stack . c_str ( ) ) ;
}
// ***************************************************************************
void CLuaIHM : : fails ( CLuaState & ls , const std : : string & format , . . . )
{
//H_AUTO(Lua_CLuaIHM_fails)
std : : string reason ;
const char * formatPtr = format . c_str ( ) ;
NLMISC_CONVERT_VARGS ( reason , formatPtr , NLMISC : : MaxCStringSize ) ;
fails ( ls , reason . c_str ( ) ) ;
}
// ***************************************************************************
void CLuaIHM : : checkArgCount ( CLuaState & ls , const char * funcName , uint nArgs )
{
//H_AUTO(Lua_CLuaIHM_checkArgCount)
if ( ls . getTop ( ) ! = ( sint ) nArgs )
{
fails ( ls , " %s() need exactly %d arguments (tips : check between method & function call) " , funcName , nArgs ) ;
}
}
// ***************************************************************************
void CLuaIHM : : checkArgMin ( CLuaState & ls , const char * funcName , uint nArgs )
{
//H_AUTO(Lua_CLuaIHM_checkArgMin)
if ( ls . getTop ( ) < ( sint ) nArgs )
{
fails ( ls , " %s() need at least %d arguments (tips : check between method & function call) " , funcName , nArgs ) ;
}
}
// ***************************************************************************
void CLuaIHM : : checkArgMax ( CLuaState & ls , const char * funcName , uint nArgs )
{
//H_AUTO(Lua_CLuaIHM_checkArgMax)
if ( ls . getTop ( ) > ( sint ) nArgs )
{
fails ( ls , " %s() need at most %d arguments. " , funcName , nArgs ) ;
}
}
// ***************************************************************************
void CLuaIHM : : check ( CLuaState & ls , bool ok , const std : : string & failReason )
{
//H_AUTO(Lua_CLuaIHM_check)
if ( ! ok )
{
fails ( ls , failReason ) ;
}
}
// ***************************************************************************
void CLuaIHM : : checkArgType ( CLuaState & ls , const char * funcName , uint index , int argType )
{
//H_AUTO(Lua_CLuaIHM_checkArgType)
nlassert ( index > 0 ) ;
if ( ls . getTop ( ) < ( int ) index )
{
fails ( ls , toString ( " %s : argument %d of expected type %s was not defined " , funcName , index , ls . getTypename ( argType ) ) ) ;
}
if ( ls . type ( index ) ! = argType )
{
fails ( ls , toString ( " %s : argument %d of expected type %s has bad type : %s " , funcName , index , ls . getTypename ( argType ) , ls . getTypename ( ls . type ( index ) ) , ls . type ( index ) ) ) ;
}
}
// ***************************************************************************
void CLuaIHM : : checkArgTypeRGBA ( CLuaState & ls , const char * funcName , uint index )
{
//H_AUTO(Lua_CLuaIHM_checkArgTypeRGBA)
nlassert ( index > 0 ) ;
if ( ls . getTop ( ) < ( int ) index )
{
fails ( ls , toString ( " %s : argument %d of expected type RGBA was not defined " , funcName , index ) ) ;
}
ls . pushValue ( index ) ;
CRGBA dummy ;
if ( ! pop ( ls , dummy ) )
{
fails ( ls , toString ( " %s : argument %d of expected type RGBA has bad type : %s " , funcName , index , ls . getTypename ( ls . type ( index ) ) , ls . type ( index ) ) ) ;
}
}
// ***************************************************************************
void CLuaIHM : : checkArgTypeUIElement ( CLuaState & ls , const char * funcName , uint index )
{
//H_AUTO(Lua_CLuaIHM_checkArgTypeUIElement)
nlassert ( index > 0 ) ;
if ( ls . getTop ( ) < ( int ) index )
{
fails ( ls , toString ( " %s : argument %d of expected type ui element was not defined " , funcName , index ) ) ;
}
if ( ! isUIOnStack ( ls , index ) )
{
fails ( ls , toString ( " %s : argument %d of expected type ui element has bad type : %s " , funcName , index , ls . getTypename ( ls . type ( index ) ) , ls . type ( index ) ) ) ;
}
}
// ***************************************************************************
void CLuaIHM : : checkArgTypeUCString ( CLuaState & ls , const char * funcName , uint index )
{
//H_AUTO(Lua_CLuaIHM_checkArgTypeUCString)
nlassert ( index > 0 ) ;
if ( ls . getTop ( ) < ( int ) index )
{
fails ( ls , toString ( " %s : argument %d of expected type ucstring was not defined " , funcName , index ) ) ;
}
ls . pushValue ( index ) ;
ucstring dummy ;
if ( ! pop ( ls , dummy ) )
{
fails ( ls , toString ( " %s : argument %d of expected type ucstring has bad type : %s " , funcName , index , ls . getTypename ( ls . type ( index ) ) , ls . type ( index ) ) ) ;
}
}
// ***************************************************************************
int CLuaIHM : : validMessageBox ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_validMessageBox)
const char * funcName = " validMessageBox " ;
checkArgCount ( ls , funcName , 6 ) ;
ucstring msg ;
ls . pushValue ( 1 ) ; // copy ucstring at the end of stack to pop it
check ( ls , pop ( ls , msg ) , " validMessageBox : ucstring wanted as first parameter " ) ;
checkArgType ( ls , funcName , 2 , LUA_TSTRING ) ;
checkArgType ( ls , funcName , 3 , LUA_TSTRING ) ;
checkArgType ( ls , funcName , 4 , LUA_TSTRING ) ;
checkArgType ( ls , funcName , 5 , LUA_TSTRING ) ;
checkArgType ( ls , funcName , 6 , LUA_TSTRING ) ;
CInterfaceManager * im = CInterfaceManager : : getInstance ( ) ;
im - > validMessageBox ( CInterfaceManager : : QuestionIconMsg , msg , ls . toString ( 2 ) , ls . toString ( 3 ) , ls . toString ( 4 ) , ls . toString ( 5 ) , ls . toString ( 6 ) ) ;
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : setTopWindow ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_setTopWindow)
const char * funcName = " setTopWindow " ;
checkArgCount ( ls , funcName , 1 ) ;
CInterfaceGroup * wnd = dynamic_cast < CInterfaceGroup * > ( getUIOnStack ( ls , 1 ) ) ;
if ( ! wnd )
{
fails ( ls , " %s : interface group expected as arg 1 " , funcName ) ;
}
CInterfaceManager * im = CInterfaceManager : : getInstance ( ) ;
im - > setTopWindow ( wnd ) ;
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : concatUCString ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_concatUCString)
const char * funcName = " concatUCString " ;
ucstring result ;
for ( uint k = 1 ; k < = ( uint ) ls . getTop ( ) ; + + k )
{
//nlwarning("arg %d = %s", k, ls.getTypename(ls.type(k)));
ucstring part ;
if ( ls . isString ( k ) )
{
part . fromUtf8 ( ls . toString ( k ) ) ;
}
else
{
CLuaIHM : : checkArgTypeUCString ( ls , funcName , k ) ;
nlverify ( getUCStringOnStack ( ls , k , part ) ) ;
}
result + = part ;
}
push ( ls , result ) ;
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : concatString ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_concatUCString)
const char * funcName = " concatString " ;
std : : string result ;
uint stackSize = ls . getTop ( ) ;
for ( uint k = 1 ; k < = stackSize ; + + k )
{
CLuaIHM : : checkArgType ( ls , funcName , k , LUA_TSTRING ) ;
result + = ls . toString ( k ) ;
}
ls . push ( result ) ;
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : tableToString ( CLuaState & ls )
{
const char * funcName = " tableToString " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TTABLE ) ;
uint length = 0 ;
// compute size
ls . pushNil ( ) ;
while ( ls . next ( - 2 ) )
{
ls . toString ( - 1 ) ;
length + = ls . strlen ( - 1 ) ;
ls . pop ( 2 ) ;
}
std : : string result ;
result . resize ( length ) ;
char * dest = & result [ 0 ] ;
// concatenate
ls . pushNil ( ) ;
while ( ls . next ( - 2 ) )
{
uint length = ls . strlen ( - 1 ) ;
if ( length )
{
memcpy ( dest , ls . toString ( - 1 ) , length ) ;
}
dest + = length ;
ls . pop ( 2 ) ;
}
ls . push ( result ) ;
return 1 ;
}
// ***************************************************************************
sint32 CLuaIHM : : getSkillIdFromName ( const std : : string & def )
{
//H_AUTO(Lua_CLuaIHM_getSkillIdFromName)
SKILLS : : ESkills e = SKILLS : : toSkill ( def ) ;
// Avoid any bug, return SF if not found
if ( e > = SKILLS : : unknown )
e = SKILLS : : SF ;
return e ;
}
// ***************************************************************************
ucstring CLuaIHM : : getSkillLocalizedName ( sint32 skillId )
{
//H_AUTO(Lua_CLuaIHM_getSkillLocalizedName)
return ucstring ( STRING_MANAGER : : CStringManagerClient : : getSkillLocalizedName ( ( SKILLS : : ESkills ) skillId ) ) ;
}
// ***************************************************************************
sint32 CLuaIHM : : getMaxSkillValue ( sint32 skillId )
{
//H_AUTO(Lua_CLuaIHM_getMaxSkillValue)
CSkillManager * pSM = CSkillManager : : getInstance ( ) ;
return pSM - > getMaxSkillValue ( ( SKILLS : : ESkills ) skillId ) ;
}
// ***************************************************************************
sint32 CLuaIHM : : getBaseSkillValueMaxChildren ( sint32 skillId )
{
//H_AUTO(Lua_CLuaIHM_getBaseSkillValueMaxChildren)
CSkillManager * pSM = CSkillManager : : getInstance ( ) ;
return pSM - > getBaseSkillValueMaxChildren ( ( SKILLS : : ESkills ) skillId ) ;
}
// ***************************************************************************
bool CLuaIHM : : executeFunctionOnStack ( CLuaState & ls , int numArgs , int numRet )
{
//H_AUTO(Lua_CLuaIHM_executeFunctionOnStack)
static volatile bool dumpFunction = false ;
if ( dumpFunction )
{
CLuaStackRestorer lsr ( & ls , ls . getTop ( ) ) ;
lua_Debug ar ;
ls . pushValue ( - 1 - numArgs ) ;
lua_getinfo ( ls . getStatePointer ( ) , " >lS " , & ar ) ;
nlwarning ( ( std : : string ( ar . what ) + " , at line " + toString ( ar . linedefined ) + " in " + std : : string ( ar . source ) ) . c_str ( ) ) ;
}
int result = ls . pcall ( numArgs , numRet ) ;
switch ( result )
{
case LUA_ERRRUN :
case LUA_ERRMEM :
case LUA_ERRERR :
{
CLuaIHM : : debugInfo ( ls . toString ( - 1 ) ) ;
ls . pop ( ) ;
return false ;
}
break ;
case 0 :
return true ;
break ;
default :
nlassert ( 0 ) ;
break ;
}
return false ;
}
// ***************************************************************************
int CLuaIHM : : breakPoint ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_breakPoint)
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
std : : string reason ;
ls . getStackContext ( reason , 1 ) ; // 1 because 0 is the current C function => return 1 for script called
pIM - > formatLuaStackContext ( reason ) ;
NLMISC : : InfoLog - > displayRawNL ( reason . c_str ( ) ) ;
static volatile bool doAssert = true ;
if ( doAssert ) // breakPoint can be discarded in case of looping assert
{
NLMISC_BREAKPOINT ;
}
return 0 ;
}
// ***************************************************************************
bool CLuaIHM : : popString ( CLuaState & ls , std : : string & dest )
{
//H_AUTO(Lua_CLuaIHM_popString)
try
{
# if LUABIND_VERSION == 07
luabind : : object obj ( luabind : : from_stack ( ls . getStatePointer ( ) , - 1 ) ) ;
2010-05-10 18:37:23 +00:00
ls . pop ( ) ;
2010-05-06 00:08:41 +00:00
# else
luabind : : object obj ( ls . getStatePointer ( ) ) ;
obj . set ( ) ;
# endif
dest = luabind : : object_cast < std : : string > ( obj ) ;
}
catch ( luabind : : cast_failed & )
{
return false ;
}
return true ;
}
// ***************************************************************************
bool CLuaIHM : : popSINT32 ( CLuaState & ls , sint32 & dest )
{
//H_AUTO(Lua_CLuaIHM_popSINT32)
try
{
# if LUABIND_VERSION == 07
luabind : : object obj ( luabind : : from_stack ( ls . getStatePointer ( ) , - 1 ) ) ;
2010-05-10 18:37:23 +00:00
ls . pop ( ) ;
2010-05-06 00:08:41 +00:00
# else
luabind : : object obj ( ls . getStatePointer ( ) ) ;
obj . set ( ) ;
# endif
dest = luabind : : object_cast < sint32 > ( obj ) ;
}
catch ( luabind : : cast_failed & )
{
return false ;
}
return true ;
}
// ***************************************************************************
int CLuaIHM : : getWindowSize ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_getWindowSize)
checkArgCount ( ls , " getWindowSize " , 0 ) ;
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
uint32 w , h ;
pIM - > getViewRenderer ( ) . getScreenSize ( w , h ) ;
ls . push ( ( double ) w ) ;
ls . push ( ( double ) h ) ;
return 2 ;
}
// ***************************************************************************
int CLuaIHM : : setTextFormatTaged ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_setTextFormatTaged)
// params: CViewText*, "text" (or ucstring)
// return: none
checkArgCount ( ls , " setTextFormatTaged " , 2 ) ;
// *** check and retrieve param 1
check ( ls , isUIOnStack ( ls , 1 ) , " setTextFormatTaged() requires a UI object in param 1 " ) ;
CInterfaceElement * pIE = getUIOnStack ( ls , 1 ) ;
// *** check and retrieve param 2. must be a string or a ucstring
ucstring text ;
if ( ls . isString ( 2 ) )
{
std : : string str ;
ls . toString ( 2 , str ) ;
text = str ;
}
else
{
// try to pop a ucstring from the stack
// fail?
if ( ! pop ( ls , text ) )
{
check ( ls , false , " setTextFormatTaged() requires a string or a ucstring in param 2 " ) ;
}
}
// must be a view text
CViewText * vt = dynamic_cast < CViewText * > ( pIE ) ;
if ( ! vt )
throw ELuaIHMException ( " setTextFormatTaged() : ' % s ' is not a CViewText " , pIE->getId().c_str()) ;
// Set the text as format
vt - > setTextFormatTaged ( text ) ;
return 0 ;
}
// ***************************************************************************
sint32 CLuaIHM : : getMagicResistChance ( bool elementalSpell , sint32 casterSpellLvl , sint32 victimResistLvl )
{
//H_AUTO(Lua_CLuaIHM_getMagicResistChance)
CSPhraseManager * pPM = CSPhraseManager : : getInstance ( ) ;
casterSpellLvl = std : : max ( casterSpellLvl , sint32 ( 0 ) ) ;
victimResistLvl = std : : max ( victimResistLvl , sint32 ( 0 ) ) ;
/* The success rate in the table is actually the "Casting Success Chance".
Thus , the relativeLevel is casterSpellLvl - victimResistLvl
Moreover , must take the " PartialSuccessMaxDraw " line because the spell is not resisted if success > 0
*/
sint32 chanceToHit = pPM - > getSuccessRate ( elementalSpell ? CSPhraseManager : : STResistMagic : CSPhraseManager : : STResistMagicLink ,
casterSpellLvl - victimResistLvl , true ) ;
clamp ( chanceToHit , 0 , 100 ) ;
// Thus, the resist chance is 100 - hit chance.
return 100 - chanceToHit ;
}
// ***************************************************************************
sint32 CLuaIHM : : getDodgeParryChance ( sint32 attLvl , sint32 defLvl )
{
//H_AUTO(Lua_CLuaIHM_getDodgeParryChance)
CSPhraseManager * pPM = CSPhraseManager : : getInstance ( ) ;
attLvl = std : : max ( attLvl , sint32 ( 0 ) ) ;
defLvl = std : : max ( defLvl , sint32 ( 0 ) ) ;
sint32 chance = pPM - > getSuccessRate ( CSPhraseManager : : STDodgeParry , defLvl - attLvl , false ) ;
clamp ( chance , 0 , 100 ) ;
return chance ;
}
// ***************************************************************************
void CLuaIHM : : browseNpcWebPage ( const std : : string & htmlId , const std : : string & urlIn , bool addParameters , double timeout )
{
//H_AUTO(Lua_CLuaIHM_browseNpcWebPage)
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
CGroupHTML * groupHtml = dynamic_cast < CGroupHTML * > ( pIM - > getElementFromId ( htmlId ) ) ;
if ( groupHtml )
{
// if true, it means that we want to display a web page that use webig auth
bool webig = urlIn . find ( " http:// " ) = = 0 ;
string url ;
// append the WebServer to the url
if ( urlIn . find ( " ring_access_point=1 " ) ! = std : : string : : npos )
{
url = RingMainURL + " ? " + urlIn ;
}
else if ( webig )
{
url = urlIn ;
}
else
{
url = WebServer + urlIn ;
}
if ( addParameters & & ! webig )
{
// append shardid, playername and language code
string userName ;
string guildName ;
if ( UserEntity )
{
userName = UserEntity - > getDisplayName ( ) . toString ( ) ;
STRING_MANAGER : : CStringManagerClient * pSMC = STRING_MANAGER : : CStringManagerClient : : instance ( ) ;
ucstring ucsTmp ;
pSMC - > getString ( UserEntity - > getGuildNameID ( ) , ucsTmp ) ;
guildName = ucsTmp . toString ( ) ;
while ( guildName . find ( ' ' ) ! = string : : npos )
{
guildName [ guildName . find ( ' ' ) ] = ' _ ' ;
}
}
url + = ( ( url . find ( ' ? ' ) ! = string : : npos ) ? " & " : " ? " ) +
string ( " shard= " ) + toString ( ShardId ) +
string ( " &user_login= " ) + userName +
string ( " &lang= " ) + ClientCfg . getHtmlLanguageCode ( ) +
string ( " &guild_name= " ) + guildName ;
}
/*
if ( webig )
{
// append special webig auth params
addWebIGParams ( url ) ;
}
*/
// set the wanted timeout
groupHtml - > setTimeout ( ( float ) std : : max ( 0.0 , timeout ) ) ;
// Browse the url
groupHtml - > clean ( ) ;
groupHtml - > browse ( url . c_str ( ) ) ;
// Set top of the page
CCtrlScroll * pScroll = groupHtml - > getScrollBar ( ) ;
if ( pScroll ! = NULL )
pScroll - > moveTrackY ( 10000 ) ;
}
}
// ***************************************************************************
void CLuaIHM : : clearHtmlUndoRedo ( const std : : string & htmlId )
{
//H_AUTO(Lua_CLuaIHM_clearHtmlUndoRedo)
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
CGroupHTML * groupHtml = dynamic_cast < CGroupHTML * > ( pIM - > getElementFromId ( htmlId ) ) ;
if ( groupHtml )
groupHtml - > clearUndoRedo ( ) ;
}
// ***************************************************************************
ucstring CLuaIHM : : getDynString ( sint32 dynStringId )
{
//H_AUTO(Lua_CLuaIHM_getDynString)
ucstring result ;
STRING_MANAGER : : CStringManagerClient : : instance ( ) - > getDynString ( dynStringId , result ) ;
return result ;
}
// ***************************************************************************
bool CLuaIHM : : isDynStringAvailable ( sint32 dynStringId )
{
//H_AUTO(Lua_CLuaIHM_isDynStringAvailable)
ucstring result ;
bool res = STRING_MANAGER : : CStringManagerClient : : instance ( ) - > getDynString ( dynStringId , result ) ;
return res ;
}
// ***************************************************************************
bool CLuaIHM : : isFullyPatched ( )
{
return AvailablePatchs = = 0 ;
}
// ***************************************************************************
std : : string CLuaIHM : : getSheetType ( const std : : string & sheet )
{
//H_AUTO(Lua_CLuaIHM_getSheetType)
const CEntitySheet * sheetPtr = SheetMngr . get ( CSheetId ( sheet ) ) ;
if ( ! sheetPtr ) return " " ;
return CEntitySheet : : typeToString ( sheetPtr - > Type ) ;
}
// ***************************************************************************
std : : string CLuaIHM : : getSheetName ( uint32 sheetId )
{
return CSheetId ( sheetId ) . toString ( ) ;
}
// ***************************************************************************
sint32 CLuaIHM : : getFameIndex ( const std : : string & factionName )
{
//H_AUTO(Lua_CLuaIHM_getFameIndex)
return CStaticFames : : getInstance ( ) . getFactionIndex ( factionName ) ;
}
// ***************************************************************************
std : : string CLuaIHM : : getFameName ( sint32 fameIndex )
{
//H_AUTO(Lua_CLuaIHM_getFameName)
return CStaticFames : : getInstance ( ) . getFactionName ( fameIndex ) ;
}
// ***************************************************************************
sint32 CLuaIHM : : getFameDBIndex ( sint32 fameIndex )
{
//H_AUTO(Lua_CLuaIHM_getFameDBIndex)
// Yoyo: avoid crash if fames not initialized
if ( CStaticFames : : getInstance ( ) . getNbFame ( ) = = 0 )
return 0 ;
else
return CStaticFames : : getInstance ( ) . getDatabaseIndex ( fameIndex ) ;
}
// ***************************************************************************
sint32 CLuaIHM : : getFirstTribeFameIndex ( )
{
//H_AUTO(Lua_CLuaIHM_getFirstTribeFameIndex)
return CStaticFames : : getInstance ( ) . getFirstTribeFameIndex ( ) ;
}
// ***************************************************************************
sint32 CLuaIHM : : getNbTribeFameIndex ( )
{
//H_AUTO(Lua_CLuaIHM_getNbTribeFameIndex)
// Yoyo: avoid crash if fames not initialized. at leasst one tribe
return std : : max ( 1U , CStaticFames : : getInstance ( ) . getNbTribeFameIndex ( ) ) ;
}
// ***************************************************************************
bool CLuaIHM : : fileExists ( const string & fileName )
{
//H_AUTO(Lua_CLuaIHM_fileExists)
return CPath : : exists ( fileName ) ;
}
// ***************************************************************************
string CLuaIHM : : getClientCfg ( const string & varName )
{
//H_AUTO(Lua_CLuaIHM_getClientCfg)
return ClientCfg . readString ( varName ) ;
}
// ***************************************************************************
void CLuaIHM : : sendMsgToServer ( const std : : string & sMsg )
{
//H_AUTO(Lua_CLuaIHM_sendMsgToServer)
: : sendMsgToServer ( sMsg ) ;
}
// ***************************************************************************
void CLuaIHM : : sendMsgToServerPvpTag ( bool pvpTag )
{
//H_AUTO(Lua_CLuaIHM_sendMsgToServerPvpTag)
uint8 tag = ( uint8 ) pvpTag ;
: : sendMsgToServer ( " PVP:PVP_TAG " , tag ) ;
}
// ***************************************************************************
bool CLuaIHM : : isGuildQuitAvailable ( )
{
//H_AUTO(Lua_CLuaIHM_isGuildQuitAvailable)
return CGuildManager : : getInstance ( ) - > getGuild ( ) . QuitGuildAvailable ;
}
// ***************************************************************************
void CLuaIHM : : sortGuildMembers ( )
{
//H_AUTO(Lua_CLuaIHM_sortGuildMembers)
CGuildManager : : getInstance ( ) - > sortGuildMembers ( ) ;
}
// ***************************************************************************
sint32 CLuaIHM : : getNbGuildMembers ( )
{
//H_AUTO(Lua_CLuaIHM_getNbGuildMembers)
return CGuildManager : : getInstance ( ) - > getGuildMembers ( ) . size ( ) ;
}
// ***************************************************************************
string CLuaIHM : : getGuildMemberName ( sint32 nMemberId )
{
//H_AUTO(Lua_CLuaIHM_getGuildMemberName)
if ( ( nMemberId < 0 ) | | ( nMemberId > = getNbGuildMembers ( ) ) )
return " " ;
return CGuildManager : : getInstance ( ) - > getGuildMembers ( ) [ nMemberId ] . Name . toString ( ) ;
}
// ***************************************************************************
string CLuaIHM : : getGuildMemberGrade ( sint32 nMemberId )
{
//H_AUTO(Lua_CLuaIHM_getGuildMemberGrade)
if ( ( nMemberId < 0 ) | | ( nMemberId > = getNbGuildMembers ( ) ) )
return " " ;
return EGSPD : : CGuildGrade : : toString ( CGuildManager : : getInstance ( ) - > getGuildMembers ( ) [ nMemberId ] . Grade ) ;
}
// ***************************************************************************
bool CLuaIHM : : isR2Player ( const std : : string & sheet )
{
//H_AUTO(Lua_CLuaIHM_isR2Player)
const CEntitySheet * entitySheet = SheetMngr . get ( CSheetId ( sheet ) ) ;
if ( ! entitySheet ) return false ;
const CCharacterSheet * chSheet = dynamic_cast < const CCharacterSheet * > ( entitySheet ) ;
if ( ! chSheet ) return false ;
return chSheet - > R2Npc ;
}
// ***************************************************************************
std : : string CLuaIHM : : getR2PlayerRace ( const std : : string & sheet )
{
//H_AUTO(Lua_CLuaIHM_getR2PlayerRace)
const CEntitySheet * entitySheet = SheetMngr . get ( CSheetId ( sheet ) ) ;
if ( ! entitySheet ) return " " ;
const CCharacterSheet * chSheet = dynamic_cast < const CCharacterSheet * > ( entitySheet ) ;
if ( ! chSheet ) return " " ;
return EGSPD : : CPeople : : toString ( chSheet - > Race ) ;
}
// ***************************************************************************
bool CLuaIHM : : isR2PlayerMale ( const std : : string & sheet )
{
//H_AUTO(Lua_CLuaIHM_isR2PlayerMale)
const CEntitySheet * entitySheet = SheetMngr . get ( CSheetId ( sheet ) ) ;
if ( ! entitySheet ) return true ;
const CCharacterSheet * chSheet = dynamic_cast < const CCharacterSheet * > ( entitySheet ) ;
if ( ! chSheet ) return true ;
return ( chSheet - > Gender = = GSGENDER : : male ) ;
}
// ***************************************************************************
std : : string CLuaIHM : : getCharacterSheetSkel ( const std : : string & sheet , bool isMale )
{
//H_AUTO(Lua_CLuaIHM_getCharacterSheetSkel)
const CEntitySheet * sheetPtr = SheetMngr . get ( CSheetId ( sheet ) ) ;
const CCharacterSheet * charSheet = dynamic_cast < const CCharacterSheet * > ( sheetPtr ) ;
if ( charSheet ) return charSheet - > getSkelFilename ( ) ;
const CRaceStatsSheet * raceStatSheet = dynamic_cast < const CRaceStatsSheet * > ( sheetPtr ) ;
if ( raceStatSheet ) return raceStatSheet - > GenderInfos [ isMale ? 0 : 1 ] . Skelfilename ;
return " " ;
}
// ***************************************************************************
sint32 CLuaIHM : : getSheetId ( const std : : string & itemName )
{
//H_AUTO(Lua_CLuaIHM_getSheetId)
return ( sint32 ) CSheetId ( itemName ) . asInt ( ) ;
}
// ***************************************************************************
sint CLuaIHM : : getCharacterSheetRegionForce ( const std : : string & sheet )
{
//H_AUTO(Lua_CLuaIHM_getCharacterSheetRegionForce)
const CCharacterSheet * charSheet = dynamic_cast < const CCharacterSheet * > ( SheetMngr . get ( CSheetId ( sheet ) ) ) ;
if ( ! charSheet ) return 0 ;
return charSheet - > RegionForce ;
}
// ***************************************************************************
sint CLuaIHM : : getCharacterSheetRegionLevel ( const std : : string & sheet )
{
//H_AUTO(Lua_CLuaIHM_getCharacterSheetRegionLevel)
const CCharacterSheet * charSheet = dynamic_cast < const CCharacterSheet * > ( SheetMngr . get ( CSheetId ( sheet ) ) ) ;
if ( ! charSheet ) return 0 ;
return charSheet - > RegionForce ;
}
// ***************************************************************************
bool CLuaIHM : : isCtrlKeyDown ( )
{
//H_AUTO(Lua_CLuaIHM_isCtrlKeyDown)
bool ctrlDown = Driver - > AsyncListener . isKeyDown ( KeyLCONTROL ) | |
Driver - > AsyncListener . isKeyDown ( KeyRCONTROL ) ;
if ( ctrlDown ) nlwarning ( " ctrl down " ) ;
else nlwarning ( " ctrl up " ) ;
return ctrlDown ;
}
// ***************************************************************************
std : : string CLuaIHM : : encodeURLUnicodeParam ( const ucstring & text )
{
//H_AUTO(Lua_CLuaIHM_encodeURLUnicodeParam)
return convertToHTML ( text . toUtf8 ( ) ) ;
}
// ***************************************************************************
ucstring CLuaIHM : : replacePvpEffectParam ( const ucstring & str , sint32 parameter )
{
//H_AUTO(Lua_CLuaIHM_replacePvpEffectParam)
ucstring result = str ;
CSString s = str . toString ( ) ;
std : : string p , paramString ;
// Locate parameter and store it
p = s . splitTo ( ' % ' , true ) ;
while ( p . size ( ) > 0 & & s . size ( ) > 0 )
{
if ( s [ 0 ] = = ' p ' | | s [ 0 ] = = ' n ' | | s [ 0 ] = = ' r ' )
{
paramString = " % " ;
paramString + = s [ 0 ] ;
break ;
}
p = s . splitTo ( ' % ' , true ) ;
}
// Return original string if param isn't found
if ( paramString . size ( ) < 2 )
return str ;
// Replace parameter based on its type
switch ( paramString [ 1 ] )
{
case ' p ' :
p = toString ( " %.1f %% " , parameter / 100.0 ) ;
break ;
case ' n ' :
p = toString ( parameter ) ;
break ;
case ' r ' :
p = toString ( " %.1f " , parameter / 100.0 ) ;
break ;
default :
debugInfo ( " Bad arguments in " + str . toString ( ) + " : " + paramString ) ;
}
strFindReplace ( result , paramString . c_str ( ) , p ) ;
return result ;
}
// ***************************************************************************
string CLuaIHM : : getRegionByAlias ( uint32 alias )
{
//H_AUTO(Lua_CLuaIHM_getRegionByAlias)
return ContinentMngr . getRegionNameByAlias ( alias ) ;
}
struct CEmoteStruct
{
string EmoteId ;
string Path ;
string Anim ;
bool UsableFromClientUI ;
bool operator < ( const CEmoteStruct & entry ) const
{
string path1 = Path ;
string path2 = entry . Path ;
for ( ; ; )
{
string : : size_type pos1 = path1 . find ( ' | ' ) ;
string : : size_type pos2 = path2 . find ( ' | ' ) ;
ucstring s1 = toUpper ( CI18N : : get ( path1 . substr ( 0 , pos1 ) ) ) ;
ucstring s2 = toUpper ( CI18N : : get ( path2 . substr ( 0 , pos2 ) ) ) ;
sint result = s1 . compare ( s2 ) ;
if ( result ! = 0 )
return ( result < 0 ) ;
if ( pos1 = = string : : npos )
return ( pos2 ! = string : : npos ) ;
if ( pos2 = = string : : npos )
return false ;
path1 = path1 . substr ( pos1 + 1 ) ;
path2 = path2 . substr ( pos2 + 1 ) ;
}
return false ;
}
} ;
// ***************************************************************************
int CLuaIHM : : initEmotesMenu ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_initEmotesMenu)
CLuaIHM : : checkArgCount ( ls , " initEmotesMenu " , 2 ) ;
CLuaIHM : : checkArgType ( ls , " initEmotesMenu " , 2 , LUA_TSTRING ) ;
const std : : string & emoteMenu = ls . toString ( 1 ) ;
const std : : string & luaParams = ls . toString ( 2 ) ;
ls . newTable ( ) ;
CLuaObject result ( ls ) ;
std : : map < std : : string , std : : string > emoteList ;
uint maxVisibleLine = 10 ;
CTextEmotListSheet * pTELS = dynamic_cast < CTextEmotListSheet * > ( SheetMngr . get ( CSheetId ( " list.text_emotes " ) ) ) ;
if ( pTELS = = NULL )
return 0 ;
std : : list < CEmoteStruct > entries ;
if ( entries . empty ( ) )
{
for ( uint i = 0 ; i < pTELS - > TextEmotList . size ( ) ; i + + )
{
CEmoteStruct entry ;
entry . EmoteId = pTELS - > TextEmotList [ i ] . EmoteId ;
entry . Path = pTELS - > TextEmotList [ i ] . Path ;
entry . Anim = pTELS - > TextEmotList [ i ] . Anim ;
entry . UsableFromClientUI = pTELS - > TextEmotList [ i ] . UsableFromClientUI ;
entries . push_back ( entry ) ;
}
entries . sort ( ) ;
}
// The list of behaviour missnames emotList
CEmotListSheet * pEmotList = dynamic_cast < CEmotListSheet * > ( SheetMngr . get ( CSheetId ( " list.emot " ) ) ) ;
nlassert ( pEmotList ! = NULL ) ;
nlassert ( pEmotList - > Emots . size ( ) < = 255 ) ;
// Get the focus beta tester flag
bool betaTester = false ;
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
CSkillManager * pSM = CSkillManager : : getInstance ( ) ;
betaTester = pSM - > isTitleUnblocked ( CHARACTER_TITLE : : FBT ) ;
CGroupMenu * pInitRootMenu = dynamic_cast < CGroupMenu * > ( pIM - > getElementFromId ( emoteMenu ) ) ;
pInitRootMenu - > reset ( ) ;
for ( std : : list < CEmoteStruct > : : const_iterator it = entries . begin ( ) ; it ! = entries . end ( ) ; it + + )
{
std : : string sEmoteId = ( * it ) . EmoteId ;
std : : string sState = ( * it ) . Anim ;
std : : string sName = ( * it ) . Path ;
// Check that the emote can be added to UI
// ---------------------------------------
if ( ( * it ) . UsableFromClientUI = = false )
{
continue ;
}
// Check the emote reserved for FBT (hardcoded)
// --------------------------------------------
if ( sState = = " FBT " & & ! betaTester )
continue ;
uint32 i , j ;
// Add to the game context menu
// ----------------------------
uint32 nbToken = 1 ;
for ( i = 0 ; i < sName . size ( ) ; + + i )
if ( sName [ i ] = = ' | ' )
nbToken + + ;
CGroupMenu * pRootMenu = dynamic_cast < CGroupMenu * > ( pIM - > getElementFromId ( emoteMenu ) ) ;
CGroupSubMenu * pMenu = pRootMenu - > getRootMenu ( ) ;
for ( i = 0 ; i < nbToken ; + + i )
{
if ( i = = 0 )
{
sName = sName . substr ( sName . find ( ' | ' ) + 1 , sName . size ( ) ) ;
}
else
{
string sTmp ;
if ( i ! = ( nbToken - 1 ) )
sTmp = sName . substr ( 0 , sName . find ( ' | ' ) ) ;
else
sTmp = sName ;
// Look if this part of the path is already present
bool bFound = false ;
for ( j = 0 ; j < pMenu - > getNumLine ( ) ; + + j )
{
if ( sTmp = = pMenu - > getLineId ( j ) )
{
bFound = true ;
break ;
}
}
if ( ! bFound ) // Create it
{
if ( i ! = ( nbToken - 1 ) )
{
pMenu - > addLine ( CI18N : : get ( sTmp ) , " " , " " , sTmp ) ;
// Create a sub menu
CGroupSubMenu * pNewSubMenu = new CGroupSubMenu ( CViewBase : : TCtorParam ( ) ) ;
pMenu - > setSubMenu ( j , pNewSubMenu ) ;
}
else
{
// Create a line
pMenu - > addLine ( CI18N : : get ( sTmp ) , " lua " ,
luaParams + " (' " + sEmoteId + " ', ' " + toString ( CI18N : : get ( sTmp ) ) + " ') " , sTmp ) ;
emoteList [ sEmoteId ] = ( toLower ( CI18N : : get ( sTmp ) ) ) . toUtf8 ( ) ;
}
}
// Jump to sub menu
if ( i ! = ( nbToken - 1 ) )
{
pMenu = pMenu - > getSubMenu ( j ) ;
sName = sName . substr ( sName . find ( ' | ' ) + 1 , sName . size ( ) ) ;
}
}
}
pMenu - > setMaxVisibleLine ( maxVisibleLine ) ;
}
pInitRootMenu - > setMaxVisibleLine ( maxVisibleLine ) ;
std : : map < std : : string , std : : string > : : iterator it ;
for ( it = emoteList . begin ( ) ; it ! = emoteList . end ( ) ; it + + )
{
result . setValue ( it - > first , it - > second ) ;
}
result . push ( ) ;
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : isUCString ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_isUCString)
const char * funcName = " isUCString " ;
checkArgCount ( ls , funcName , 1 ) ;
ls . push ( isUCStringOnStack ( ls , 1 ) ) ;
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : hideAllWindows ( CLuaState & /* ls */ )
{
//H_AUTO(Lua_CLuaIHM_hideAllWindows)
CInterfaceManager : : getInstance ( ) - > hideAllWindows ( ) ;
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : hideAllNonSavableWindows ( CLuaState & /* ls */ )
{
//H_AUTO(Lua_CLuaIHM_hideAllNonSavableWindows)
CInterfaceManager : : getInstance ( ) - > hideAllNonSavableWindows ( ) ;
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : getDesktopIndex ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_getDesktopIndex)
ls . push ( ( double ) CInterfaceManager : : getInstance ( ) - > getMode ( ) ) ;
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : setLuaBreakPoint ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_setLuaBreakPoint)
const char * funcName = " setLuaBreakPoint " ;
CLuaIHM : : checkArgCount ( ls , funcName , 2 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TSTRING ) ;
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TNUMBER ) ;
# ifdef LUA_NEVRAX_VERSION
if ( LuaDebuggerIDE )
{
LuaDebuggerIDE - > setBreakPoint ( ls . toString ( 1 ) , ( int ) ls . toNumber ( 2 ) ) ;
}
# endif
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : getMainPageURL ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_getMainPageURL)
const char * funcName = " getMainPageURL " ;
CLuaIHM : : checkArgCount ( ls , funcName , 0 ) ;
ls . push ( RingMainURL ) ;
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : getCharSlot ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_getCharSlot)
const char * funcName = " getCharSlot " ;
CLuaIHM : : checkArgCount ( ls , funcName , 0 ) ;
ls . push ( double ( PlayerSelectedSlot ) ) ;
return 1 ;
}
// ***************************************************************************
sint32 CLuaIHM : : secondsSince1970ToHour ( sint32 seconds )
{
//H_AUTO(Lua_CLuaIHM_secondsSince1970ToHour)
// convert to readable form
struct tm * tstruct ;
time_t tval = seconds ;
tstruct = gmtime ( & tval ) ;
if ( ! tstruct )
{
debugInfo ( toString ( " Bad Date Received: %d " , seconds ) ) ;
return 0 ;
}
return tstruct - > tm_hour ; // 0-23
}
int CLuaIHM : : getPathContent ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_getPathContent)
const char * funcName = " getPathContent " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TSTRING ) ;
std : : vector < std : : string > files ;
NLMISC : : CPath : : getPathContent ( ls . toString ( 1 ) , false , false , true , files ) ;
ls . newTable ( ) ;
for ( uint k = 0 ; k < files . size ( ) ; + + k )
{
ls . push ( ( double ) k ) ;
ls . push ( files [ k ] ) ;
ls . setTable ( - 3 ) ;
}
return 1 ;
}
int CLuaIHM : : getServerSeason ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_getServerSeason)
const char * funcName = " getServerSeason " ;
CLuaIHM : : checkArgCount ( ls , funcName , 0 ) ;
extern uint8 ServerSeasonValue ;
ls . push ( ( double ) ServerSeasonValue ) ;
return 1 ;
}
int CLuaIHM : : computeCurrSeason ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_computeCurrSeason)
const char * funcName = " computeCurrSeason " ;
CLuaIHM : : checkArgCount ( ls , funcName , 0 ) ;
ls . push ( ( double ) ( : : computeCurrSeason ( ) + 1 ) ) ;
return 1 ;
}
int CLuaIHM : : getAutoSeason ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_getAutoSeason)
const char * funcName = " getAutoSeason " ;
CLuaIHM : : checkArgCount ( ls , funcName , 0 ) ;
ls . push ( ( double ) ( StartupSeason + 1 ) ) ;
return 1 ;
}
int CLuaIHM : : getTextureSize ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_getTextureSize)
const char * funcName = " getTextureSize " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TSTRING ) ;
std : : string textureName = ls . toString ( 1 ) ;
CBitmap bitmap ;
CIFile fs ( CPath : : lookup ( textureName ) . c_str ( ) ) ;
bitmap . load ( fs ) ;
ls . push ( ( double ) bitmap . getWidth ( ) ) ;
ls . push ( ( double ) bitmap . getHeight ( ) ) ;
return 2 ;
}
int CLuaIHM : : enableModalWindow ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_enableModalWindow)
const char * funcName = " enableModalWindow " ;
CLuaIHM : : checkArgCount ( ls , funcName , 2 ) ;
check ( ls , isUIOnStack ( ls , 1 ) , " enableModalWindow() requires a UI object in param 1 " ) ;
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TSTRING ) ;
CInterfaceElement * pIE = getUIOnStack ( ls , 1 ) ;
std : : string modalId = ls . toString ( 2 ) ;
// convert to id
if ( pIE )
{
CCtrlBase * ctrl = dynamic_cast < CCtrlBase * > ( pIE ) ;
if ( ctrl )
{
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
CInterfaceGroup * group = dynamic_cast < CInterfaceGroup * > ( pIM - > getElementFromId ( modalId ) ) ;
if ( group )
{
UserControls . stopFreeLook ( ) ;
// enable the modal
pIM - > enableModalWindow ( ctrl , group ) ;
}
else
{
nlwarning ( " <CLuaIHM::enableModalWindow> Couldn't find group %s " , modalId . c_str ( ) ) ;
}
}
}
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : disableModalWindow ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_disableModalWindow)
checkArgCount ( ls , " disableModalWindow " , 0 ) ;
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
pIM - > disableModalWindow ( ) ;
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : getPlayerPos ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_getPlayerPos)
checkArgCount ( ls , " getPlayerPos " , 0 ) ;
ls . push ( UserEntity - > pos ( ) . x ) ;
ls . push ( UserEntity - > pos ( ) . y ) ;
ls . push ( UserEntity - > pos ( ) . z ) ;
return 3 ;
}
// ***************************************************************************
int CLuaIHM : : isPlayerFreeTrial ( CLuaState & ls )
{
checkArgCount ( ls , " isPlayerFreeTrial " , 0 ) ;
ls . push ( FreeTrial ) ;
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : disableContextHelp ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_disableContextHelp)
CLuaStackChecker lsc ( & ls , 0 ) ;
checkArgCount ( ls , " disableContextHelp " , 0 ) ;
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
pIM - > disableContextHelp ( ) ;
return 0 ;
}
// ***************************************************************************
int CLuaIHM : : disableContextHelpForControl ( CLuaState & ls )
{
//H_AUTO(Lua_CLuaIHM_disableContextHelpForControl)
CLuaStackChecker lsc ( & ls , 0 ) ;
// params: CCtrlBase*
// return: none
checkArgCount ( ls , " disableContextHelpForControl " , 1 ) ;
check ( ls , isUIOnStack ( ls , 1 ) , " disableContextHelpForControl() requires a UI object in param 1 " ) ;
// retrieve args
CInterfaceElement * pIE = getUIOnStack ( ls , 1 ) ;
// go
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
pIM - > disableContextHelpForControl ( dynamic_cast < CCtrlBase * > ( pIE ) ) ;
return 0 ;
}
// ***************************************************************************
void CLuaIHM : : tell ( const ucstring & player , const ucstring & msg )
{
//H_AUTO(Lua_CLuaIHM_tell)
// display a /tell command in the main chat
if ( ! player . empty ( ) )
{
if ( ! msg . empty ( ) )
{
ChatMngr . tell ( player . toUtf8 ( ) , msg ) ;
}
else
{
CChatWindow * w = PeopleInterraction . ChatGroup . Window ;
if ( w )
{
CInterfaceManager * im = CInterfaceManager : : getInstance ( ) ;
w - > setKeyboardFocus ( ) ;
w - > enableBlink ( 1 ) ;
w - > setCommand ( ucstring ( " tell " ) + CEntityCL : : removeTitleFromName ( player ) + ucstring ( " " ) , false ) ;
CGroupEditBox * eb = w - > getEditBox ( ) ;
if ( eb ! = NULL )
{
eb - > bypassNextKey ( ) ;
}
if ( w - > getContainer ( ) )
{
w - > getContainer ( ) - > setActive ( true ) ;
im - > setTopWindow ( w - > getContainer ( ) ) ;
}
}
}
}
}
// ***************************************************************************
bool CLuaIHM : : isRingAccessPointInReach ( )
{
//H_AUTO(Lua_CLuaIHM_isRingAccessPointInReach)
if ( BotChatPageAll - > RingSessions - > RingAccessPointPos = = CVector : : Null ) return false ;
const CVectorD & vect1 = BotChatPageAll - > RingSessions - > RingAccessPointPos ;
CVectorD vect2 = UserEntity - > pos ( ) ;
double distanceSquare = pow ( vect1 . x - vect2 . x , 2 ) + pow ( vect1 . y - vect2 . y , 2 ) ;
return distanceSquare < = MaxTalkingDistSquare ;
}
// ***************************************************************************
void CLuaIHM : : updateTooltipCoords ( )
{
CInterfaceManager : : getInstance ( ) - > updateTooltipCoords ( ) ;
}
// ***************************************************************************
void CLuaIHM : : getPoly2DOnStack ( CLuaState & ls , sint index , NLMISC : : CPolygon2D & dest )
{
//H_AUTO(Lua_CLuaIHM_getPoly2DOnStack)
ls . pushValue ( index ) ;
CLuaObject poly ;
poly . pop ( ls ) ;
dest . Vertices . clear ( ) ;
ENUM_LUA_TABLE ( poly , it )
{
it . nextValue ( ) . push ( ) ;
NLMISC : : CVector2f pos ;
if ( ! CLuaIHM : : pop ( ls , pos ) )
{
CLuaIHM : : fails ( ls , " 2D polygon expects CVector2f for poly coordinates " ) ;
}
dest . Vertices . push_back ( pos ) ;
}
}
// ***************************************************************************
int CLuaIHM : : isPlayerNewbie ( CLuaState & ls )
{
checkArgCount ( ls , " isPlayerNewbie " , 0 ) ;
CInterfaceManager * im = CInterfaceManager : : getInstance ( ) ;
ls . push ( im - > getDbProp ( " SERVER:USER:IS_NEWBIE " ) - > getValueBool ( ) ) ;
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : isInRingMode ( CLuaState & ls )
{
checkArgCount ( ls , " isInRingMode " , 0 ) ;
extern bool IsInRingMode ( ) ;
ls . push ( IsInRingMode ( ) ) ;
return 1 ;
}
// ***************************************************************************
int CLuaIHM : : getUserRace ( CLuaState & ls )
{
checkArgCount ( ls , " getUserRace " , 0 ) ;
if ( ! UserEntity | | ! UserEntity - > playerSheet ( ) )
{
ls . push ( " Unknwown " ) ;
}
else
{
ls . push ( EGSPD : : CPeople : : toString ( UserEntity - > playerSheet ( ) - > People ) ) ;
}
return 1 ;
}