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 <sstream>
# include "nel/misc/path.h"
# include "nel/misc/i18n.h"
# include "nel/misc/sheet_id.h"
# include "nel/misc/polygon.h"
# include "nel/misc/time_nl.h"
//
# include "nel/3d/u_driver.h"
# include "nel/3d/u_text_context.h"
//
# include "nel/ligo/ligo_config.h"
# include "nel/net/unified_network.h"
# include "nel/net/module_manager.h"
# include "nel/pacs/u_global_retriever.h"
//
# include "r2_lua.h"
# include "game_share/r2_share_itf.h"
# include "game_share/r2_messages.h"
# include "game_share/scenario_entry_points.h"
//
# include "dmc/dmc.h" // client interface to the dynamic scenario service
# include "dmc/client_edition_module.h"
# include "dmc/property_accessor.h"
# include "dmc/com_lua_module.h"
# include "game_share/dms.h"
//
# include "../client_sheets/item_sheet.h"
# include "editor.h"
//
# include "../interface_v3/lua_helper.h"
# include "../interface_v3/group_tree.h"
# include "../interface_v3/interface_manager.h"
# include "../contextual_cursor.h"
# include "../cursor_functions.h"
# include "../entities.h"
# include "../events_listener.h"
# include "../interface_v3/group_list.h"
# include "../interface_v3/event_descriptor.h"
# include "../interface_v3/group_tree.h"
# include "../client_cfg.h"
# include "../interface_v3/lua_ihm.h"
# include "../interface_v3/lua_object.h"
# include "../global.h"
# include "../connection.h"
# include "../main_loop.h"
# include "../interface_v3/people_interraction.h"
# include "../time_client.h"
# include "../pacs_client.h"
# include "../interface_v3/lua_ihm.h"
# include "../actions.h"
# include "../actions_client.h"
# include "object_factory_client.h"
# include "../weather.h"
# include "../light_cycle_manager.h"
# include "../dummy_progress.h"
# include "../continent_manager.h"
# include "../world_database_manager.h"
# include "../init_main_loop.h"
# include "../net_manager.h"
# include "../interface_v3/input_handler_manager.h"
# include "../connection.h"
# include "../init_main_loop.h"
# include "../interface_v3/group_editbox.h"
# include "../landscape_poly_drawer.h"
# include "../input.h"
# include "../motion/user_controls.h"
# include "../game_context_menu.h"
# include "../interface_v3/macrocmd_manager.h"
//
# include "../player_r2_cl.h"
# include "palette_node.h"
# include "tool_create_entity.h"
# include "tool_select_move.h"
# include "tool_new_vertex.h"
# include "displayer_visual_entity.h"
# include "displayer_visual_group.h"
# include "displayer_visual_shape.h"
# include "displayer_visual_activity_sequence.h"
# include "displayer_lua.h"
# include "verbose_clock.h"
# include "r2_config.h"
# include "entity_sorter.h"
//
# include "tool_draw_prim.h"
# include "tool_select_move.h"
# include "tool_select_rotate.h"
# include "tool_choose_pos_lua.h"
//
# include "../sheet_manager.h"
# include "../session_browser_impl.h"
# include "../far_tp.h"
using namespace NLMISC ;
using namespace NLNET ;
using namespace NL3D ;
extern CEventsListener EventsListener ;
extern CLog g_log ;
extern CGameContextMenu GameContextMenu ;
extern void badXMLParseMessageBox ( ) ;
R2 : : TUserRole UserRoleInSession ;
# define OPERATOR_EQUAL(X,Y) X==Y
//#define OPERATOR_EQUAL(X, Y) ::operator==(X,Y)
namespace R2
{
class CEditorCheck
{
public :
CEditorCheck ( ) { check ( ) ; }
~ CEditorCheck ( ) { check ( ) ; }
void check ( )
{
if ( ! EditorCreated ) return ; // avoid infinite loop
if ( getEditor ( ) . getMode ( ) ! = CEditor : : NotInitialized )
{
nlassert ( getEditor ( ) . getEnv ( ) . isValid ( ) ) ;
}
}
static bool EditorCreated ;
} ;
bool CEditorCheck : : EditorCreated = false ;
# ifdef NL_DEBUG
# define CHECK_EDITOR CEditorCheck __ec;
# else
# define CHECK_EDITOR (void) 0;
# endif
const char * DEFAULT_CURSOR = " curs_default.tga " ;
bool ResetWanted = false ;
bool ReloadUIFlag = true ; // by default, CEditor loads its own UI
bool ResetScenarioWanted = false ;
bool ReloadScenarioWanted = false ;
bool ConnectionWanted = false ;
std : : string CEditor : : _ScenarioToLoadWhenEntreringIntoAnimation = " " ;
bool CEditor : : _IsStartingScenario = false ;
// *********************************************************************************************************
/** this class forward modification events from the network so that the editor can
* update its state to match the current state of the map
*/
class CDynamicMapClientEventForwarder : public CDynamicMapClient
{
public :
CDynamicMapClientEventForwarder ( const std : : string & eid , NLNET : : IModuleSocket * clientGateway , lua_State * luaState ) ;
virtual void nodeErased ( const std : : string & instanceId , const std : : string & attrName , sint32 position ) ;
virtual void nodeSet ( const std : : string & instanceId , const std : : string & attrName , CObject * value ) ;
virtual void nodeInserted ( const std : : string & instanceId , const std : : string & attrName , sint32 position ,
const std : : string & key , CObject * value ) ;
virtual void nodeMoved ( const std : : string & instanceId , const std : : string & attrName , sint32 position ,
const std : : string & destInstanceId , const std : : string & destAttrName , sint32 destPosition ) ;
virtual void scenarioUpdated ( CObject * highLevel , bool willTP , uint32 initialActIndex ) ;
virtual void onAnimationModeConnected ( const CClientMessageAdventureUserConnection & connected ) ;
virtual void onEditionModeConnected ( uint32 userSlotId , uint32 adventureId , CObject * highLevel , const std : : string & versionName , bool willTP , uint32 initialActIndex ) ;
virtual void onEditionModeDisconnected ( ) ;
virtual void onResetEditionMode ( ) ;
virtual void onTestModeConnected ( ) ;
virtual void onTestModeDisconnected ( TSessionId sessionId , uint32 lasAct , TScenarioSessionType sessionType ) ;
} ;
CDynamicMapClientEventForwarder : : CDynamicMapClientEventForwarder ( const std : : string & eid , NLNET : : IModuleSocket * clientGateway , lua_State * luaState ) :
CDynamicMapClient ( eid , clientGateway , luaState )
{
}
void CDynamicMapClientEventForwarder : : nodeErased ( const std : : string & instanceId , const std : : string & attrName , sint32 position )
{
//H_AUTO(R2_CDynamicMapClientEventForwarder_nodeErased)
if ( ! getEditor ( ) . getMode ( ) = = CEditor : : EditionMode ) return ;
getEditor ( ) . nodeErased ( instanceId , attrName , position ) ;
}
void CDynamicMapClientEventForwarder : : nodeSet ( const std : : string & instanceId , const std : : string & attrName , CObject * value )
{
//H_AUTO(R2_CDynamicMapClientEventForwarder_nodeSet)
if ( ! getEditor ( ) . getMode ( ) = = CEditor : : EditionMode ) return ;
getEditor ( ) . nodeSet ( instanceId , attrName , value ) ;
}
void CDynamicMapClientEventForwarder : : nodeInserted ( const std : : string & instanceId , const std : : string & attrName , sint32 position ,
const std : : string & key , CObject * value )
{
//H_AUTO(R2_CDynamicMapClientEventForwarder_nodeInserted)
if ( ! getEditor ( ) . getMode ( ) = = CEditor : : EditionMode ) return ;
getEditor ( ) . nodeInserted ( instanceId , attrName , position , key , value ) ;
}
void CDynamicMapClientEventForwarder : : nodeMoved (
const std : : string & instanceId , const std : : string & attrName , sint32 position ,
const std : : string & destInstanceId , const std : : string & destAttrName , sint32 destPosition )
{
//H_AUTO(R2_CDynamicMapClientEventForwarder_nodeMoved)
if ( ! getEditor ( ) . getMode ( ) = = CEditor : : EditionMode ) return ;
getEditor ( ) . nodeMoved ( instanceId , attrName , position , destInstanceId , destAttrName , destPosition ) ;
}
void CDynamicMapClientEventForwarder : : scenarioUpdated ( CObject * highLevel , bool willTP , uint32 initialActIndex )
{
//H_AUTO(R2_CDynamicMapClientEventForwarder_scenarioUpdated)
if ( ! getEditor ( ) . getMode ( ) = = CEditor : : EditionMode ) return ;
getEditor ( ) . scenarioUpdated ( highLevel , willTP , initialActIndex ) ;
}
void CDynamicMapClientEventForwarder : : onEditionModeConnected ( uint32 userSlotId , uint32 adventureId , CObject * highLevel , const std : : string & versionName , bool willTP , uint32 initialActIndex )
{
//H_AUTO(R2_CDynamicMapClientEventForwarder_onEditionModeConnected)
getEditor ( ) . onEditionModeConnected ( userSlotId , adventureId , highLevel , versionName , willTP , initialActIndex ) ;
}
void CDynamicMapClientEventForwarder : : onEditionModeDisconnected ( )
{
//H_AUTO(R2_CDynamicMapClientEventForwarder_onEditionModeDisconnected)
getEditor ( ) . onEditionModeDisconnected ( ) ;
}
void CDynamicMapClientEventForwarder : : onResetEditionMode ( )
{
//H_AUTO(R2_CDynamicMapClientEventForwarder_onResetEditionMode)
getEditor ( ) . onResetEditionMode ( ) ;
}
void CDynamicMapClientEventForwarder : : onTestModeConnected ( )
{
//H_AUTO(R2_CDynamicMapClientEventForwarder_onTestModeConnected)
getEditor ( ) . onTestModeConnected ( ) ;
}
void CDynamicMapClientEventForwarder : : onTestModeDisconnected ( TSessionId sessionId , uint32 lastAct , TScenarioSessionType sessionType )
{
//H_AUTO(R2_CDynamicMapClientEventForwarder_onTestModeDisconnected)
getEditor ( ) . onTestModeDisconnected ( sessionId , lastAct , sessionType ) ;
}
void CDynamicMapClientEventForwarder : : onAnimationModeConnected ( const CClientMessageAdventureUserConnection & connected )
{
//H_AUTO(R2_CDynamicMapClientEventForwarder_onAnimationModeConnected)
getEditor ( ) . onAnimationModeConnected ( connected ) ;
}
// *********************************************************************************************************
CEditor : : CEditor ( )
{
//H_AUTO(R2_CEditor_CEditor)
_SelectedInstance = NULL ;
_FocusedInstance = NULL ;
_Scenario = NULL ;
_EnteredInSetSelectedInstance = false ;
_DecalRefTime = 0 ;
_Initialized = false ;
//vianney?? _LastUIModificationDate = 0;
_InstanceObserverHandleCounter = 0 ;
// module are initialized one time and never reconnected
_DMC = NULL ;
_DMS = NULL ;
_Mode = NotInitialized ;
_AccessMode = AccessModeUnknown ;
_SerializeUIConfig = true ;
_LastAutoSaveTime = NLMISC : : CTime : : getLocalTime ( ) ; // wait ClientCfg.R2EDAutoSaveWait
setForceDesktopReset ( false ) ;
CEditorCheck : : EditorCreated = true ;
_ClearingContent = false ;
_Season = UnknownSeason ;
_IsWaitingTPForSeasonChange = true ;
_UpdatingScenario = false ;
_WillTP = false ;
_FixedLighting = false ;
//
_ScenarioReceivedFlag = false ;
_TPReceivedFlag = false ;
_WaitScenarioScreenWanted = false ;
_WaitScenarioScreenActive = false ;
_NewScenario = NULL ;
_NewScenarioInitialAct = 0 ;
_EditionModeDisconnectedFlag = true ;
_PostponeScenarioUpdated = false ;
_EntitySorter = NULL ;
_MaxVisibleEntityExceededFlag = false ;
}
// *********************************************************************************************************
void CEditor : : setForceDesktopReset ( bool force )
{
//H_AUTO(R2_CEditor_setForceDesktopReset)
CHECK_EDITOR
std : : fill ( _ForceDesktopReset , _ForceDesktopReset + sizeofarray ( _ForceDesktopReset ) , force ) ;
}
// *********************************************************************************************************
void CEditor : : autoConfigInit ( bool serverIsRingSession )
{
//H_AUTO(R2_CEditor_autoConfigInit)
// R2ED enabled ?
if ( ClientCfg . R2EDEnabled )
{
// Editor and Animator (DM) modes
initModules ( true ) ;
TMode initialMode ;
TAccessMode initialAccessMode ;
switch ( UserRoleInSession . getValue ( ) )
{
case R2 : : TUserRole : : ur_editor :
initialMode = R2 : : CEditor : : EditionMode ;
initialAccessMode = R2 : : CEditor : : AccessEditor ;
break ;
case R2 : : TUserRole : : ur_animator :
initialMode = R2 : : CEditor : : AnimationModeDm ;
initialAccessMode = R2 : : CEditor : : AccessDM ;
break ;
case R2 : : TUserRole : : ur_outland_owner :
initialMode = R2 : : CEditor : : AnimationModeDm ;
initialAccessMode = R2 : : CEditor : : AccessOutlandOwner ;
break ;
case R2 : : TUserRole : : ur_player :
initialMode = R2 : : CEditor : : AnimationModePlay ;
// NOTE: I'm not sure if 'editor' is the right mode here - but I can't find anything better for now
// If I try 'AccessModeUnknown' the code asserts later on.
initialAccessMode = R2 : : CEditor : : AccessEditor ;
break ;
default :
nlwarning ( " Unexpected user role %u while editor enabled " , ( uint ) ( UserRoleInSession . getValue ( ) ) ) ;
initialMode = R2 : : CEditor : : EditionMode ;
initialAccessMode = R2 : : CEditor : : AccessEditor ;
}
init ( initialMode , initialAccessMode ) ;
}
else
{
// Normal player and Ring player modes
ActionsContext . setContext ( " game " ) ;
if ( serverIsRingSession )
initModules ( false ) ;
if ( UserRoleInSession . getValue ( ) ! = R2 : : TUserRole : : ur_player )
nlwarning ( " Unexpected user role %u while editor disabled " , ( uint ) ( UserRoleInSession . getValue ( ) ) ) ;
}
}
// *********************************************************************************************************
void CEditor : : autoConfigRelease ( bool serverIsRingSession )
{
//H_AUTO(R2_CEditor_autoConfigRelease)
if ( ClientCfg . R2EDEnabled )
{
R2 : : getEditor ( ) . release ( ) ;
R2 : : getEditor ( ) . releaseModules ( ) ;
}
else if ( serverIsRingSession )
R2 : : getEditor ( ) . releaseModules ( ) ;
}
// *********************************************************************************************************
void CEditor : : initModules ( bool connectDMC )
{
//H_AUTO(R2_CEditor_initModules)
CHECK_EDITOR
IModuleManager & mm = IModuleManager : : getInstance ( ) ;
IModule * gateway = mm . createModule ( " StandardGateway " , " clientGw " , " " ) ;
nlassert ( gateway ! = NULL ) ;
NLNET : : IModuleSocket * socketClientGw = mm . getModuleSocket ( " clientGw " ) ;
nlassert ( socketClientGw ! = NULL ) ;
// connect the client gateway to the server
CCommandRegistry : : getInstance ( ) . execute ( " clientGw.transportAdd FEClient fec " , * InfoLog ) ;
if ( ! ClientCfg . Local )
{
CCommandRegistry : : getInstance ( ) . execute ( " clientGw.transportCmd fec(open) " , * InfoLog ) ;
}
if ( ClientCfg . Local )
{
_DMS = new CDynamicMapService ( ClientCfg . ConfigFile , socketClientGw ) ;
_DMS - > init ( ) ;
}
else
{
_DMS = 0 ;
}
if ( connectDMC )
_DMC = new CDynamicMapClientEventForwarder ( " Client0 " , socketClientGw , getLua ( ) . getStatePointer ( ) ) ;
else
_DMC = new CDynamicMapClient ( " Client0 " , socketClientGw , getLua ( ) . getStatePointer ( ) ) ;
_DMC - > setInstantFeedBackFlag ( true ) ;
}
// *********************************************************************************************************
void CEditor : : releaseModules ( )
{
//H_AUTO(R2_CEditor_releaseModules)
CHECK_EDITOR
delete _DMC ; // must have a virtual destructor
if ( ClientCfg . Local )
delete _DMS ;
_DMC = NULL ;
_DMS = NULL ;
IModuleManager & mm = IModuleManager : : getInstance ( ) ;
NLNET : : IModule * clientGw = mm . getLocalModule ( " clientGw " ) ;
if ( clientGw )
{
mm . deleteModule ( clientGw ) ;
}
_Initialized = false ;
}
// *********************************************************************************************************
void CEditor : : inGameSelection ( const CLFECOMMON : : TCLEntityId & /* slot */ )
{
//H_AUTO(R2_CEditor_inGameSelection)
switch ( _Mode )
{
case DMMode :
case AnimationModeDm :
// reset current selection options
getEditor ( ) . callEnvMethod ( " updateAnimBarActions " , 0 ) ;
getLua ( ) . push ( " " ) ;
getEditor ( ) . callEnvMethod ( " dssTarget " , 1 ) ;
break ;
default :
// no-op
break ;
}
}
// *********************************************************************************************************
CEditor : : ~ CEditor ( )
{
release ( ) ;
}
// ***************************************************************
void CEditor : : requestSetLocalNode ( const std : : string & instanceId , const std : : string & attrName , const CObject * value )
{
//H_AUTO(R2_CEditor_requestSetLocalNode)
CHECK_EDITOR
CObject * obj = NULL ;
{
CObject * src = _DMC - > find ( instanceId ) ;
if ( ! src )
{
nlwarning ( " Can't find object with id %s " , instanceId . c_str ( ) ) ;
return ;
}
if ( ! attrName . empty ( ) )
{
CObject * subObj = src - > getAttr ( attrName ) ;
if ( ! subObj )
{
CObject * valueBase = ( CObject * ) getObject ( src , attrName ) ; // from Base
if ( ! valueBase )
{
nlwarning ( " Can't find attribute %s inside object (or is base) with InstanceId = %s " , attrName . c_str ( ) , instanceId . c_str ( ) ) ;
return ;
}
CObject * valueClone = valueBase - > clone ( ) ;
valueClone - > setParent ( 0 ) ;
src - > setObject ( attrName , valueClone ) ;
subObj = src - > getAttr ( attrName ) ;
}
if ( ! subObj )
{
nlwarning ( " Can't find attribute %s inside object with InstanceId = %s " , attrName . c_str ( ) , instanceId . c_str ( ) ) ;
return ;
}
obj = subObj ;
}
}
getDMC ( ) . getPropertyAccessor ( ) . shadowValue ( obj , value - > clone ( ) ) ;
// trigger handlers
onAttrModified ( obj ) ;
}
// *****************************************
void CEditor : : requestCommitLocalNode ( const std : : string & instanceId , const std : : string & attrName )
{
//H_AUTO(R2_CEditor_requestCommitLocalNode)
CHECK_EDITOR
CObject * obj = _DMC - > find ( instanceId , attrName ) ;
if ( ! obj )
{
nlwarning ( " (while calling requestSetLocalNode " ) ;
return ;
}
//nlwarning("**** current unshadowed value");
//obj->dump();
/*
// when requestSetNode is called, the old value can't be retrieved because it will
// be erased by 'commitValue', so backup old value
CObject * oldValueBackup = obj - > clone ( ) ;
// send net request
getDMC ( ) . getPropertyAccessor ( ) . commitValue ( obj ) ;
getDMC ( ) . requestSetNode ( instanceId , attrName , obj ) ;
*/
CObject * localValue = getDMC ( ) . getPropertyAccessor ( ) . getShadowingValue ( obj ) ;
if ( ! localValue )
{
nlwarning ( " value is not shadowed : " ) ;
obj - > dump ( ) ;
return ;
}
CObject * localValueBackup = localValue - > clone ( ) ;
getDMC ( ) . getPropertyAccessor ( ) . rollbackValue ( obj ) ;
getDMC ( ) . requestSetNode ( instanceId , attrName , localValueBackup ) ;
}
// ***************************************************************
void CEditor : : requestRollbackLocalNode ( const std : : string & instanceId , const std : : string & attrName )
{
//H_AUTO(R2_CEditor_requestRollbackLocalNode)
CHECK_EDITOR
CObject * obj = _DMC - > find ( instanceId , attrName ) ;
if ( ! obj )
{
nlwarning ( " (while calling requestSetLocalNode " ) ;
return ;
}
getDMC ( ) . getPropertyAccessor ( ) . rollbackValue ( obj ) ;
// force the displayer to update their state from the shadowed value in place of the local value
onAttrModified ( obj ) ;
}
// ***************************************************************
CInterfaceManager & CEditor : : getUI ( )
{
//H_AUTO(R2_CEditor_getUI)
CHECK_EDITOR
CInterfaceManager * im = CInterfaceManager : : getInstance ( ) ;
nlassert ( im ) ;
return * im ;
}
// *********************************************************************************************************
CLuaState & CEditor : : getLua ( )
{
//H_AUTO(R2_CEditor_getLua)
CHECK_EDITOR
CLuaState * ls = getUI ( ) . getLuaState ( ) ;
nlassert ( ls ) ;
return * ls ;
}
// *********************************************************************************************************
CLuaObject & CEditor : : getEnv ( )
{
//H_AUTO(R2_CEditor_getEnv)
nlassert ( _Env . isValid ( ) ) ;
return _Env ;
}
// *********************************************************************************************************
CLuaObject CEditor : : getConfig ( )
{
//H_AUTO(R2_CEditor_getConfig)
CHECK_EDITOR
return getEnv ( ) [ " Config " ] ;
}
// *********************************************************************************************************
void CEditor : : clearDebugWindow ( )
{
//H_AUTO(R2_CEditor_clearDebugWindow)
CHECK_EDITOR
getUI ( ) . flushDebugWindow ( ) ;
CGroupList * gl = dynamic_cast < CGroupList * > ( getUI ( ) . getElementFromId ( " ui:interface:debug_info:content:cb:text_list " ) ) ;
if ( gl )
{
gl - > deleteAllChildren ( ) ;
}
}
// *********************************************************************************************************
// callback to reload the editor when one of the config files changed
void CEditor : : reloadEditorCallback ( const std : : string & filename )
{
//H_AUTO(R2_CEditor_reloadEditorCallback)
CHECK_EDITOR
ResetWanted = true ;
if ( nlstricmp ( CFile : : getExtension ( filename ) , " xml " ) = = 0 | |
nlstricmp ( CFile : : getExtension ( filename ) , " uxt " ) = = 0 )
{
ReloadUIFlag = true ;
}
}
// *********************************************************************************************************
void CEditor : : setFixedLighting ( bool enabled )
{
//H_AUTO(R2_CEditor_setFixedLighting)
if ( _FixedLighting = = enabled ) return ;
_FixedLighting = enabled ;
LightCycleManager . touch ( ) ;
}
// *********************************************************************************************************
int CEditor : : luaGetSelectedInstanceId ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaGetSelectedInstanceId)
CHECK_EDITOR
if ( ! getEditor ( ) . getSelectedInstance ( ) )
{
ls . pushNil ( ) ;
}
else
{
ls . push ( toString ( getEditor ( ) . getSelectedInstance ( ) - > getId ( ) ) ) ;
}
return 1 ;
}
void CEditor : : setStartingAnimationFilename ( const std : : string & filename )
{
//H_AUTO(R2_CEditor_setStartingAnimationFilename)
_ScenarioToLoadWhenEntreringIntoAnimation = filename ;
}
// *********************************************************************************************************
int CEditor : : luaGetStartingAnimationFilename ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaGetStartingAnimationFilename)
ls . push ( _ScenarioToLoadWhenEntreringIntoAnimation ) ;
return 1 ;
}
// *********************************************************************************************************
int CEditor : : luaSetSelectedInstanceId ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaSetSelectedInstanceId)
CHECK_EDITOR
CLuaIHM : : checkArgCount ( ls , " setSelectedInstance (method) " , 2 ) ;
CLuaIHM : : checkArgType ( ls , " setSelectedInstance " , 2 , LUA_TSTRING ) ;
if ( strcmp ( ls . toString ( 2 ) , " " ) = = 0 )
{
getEditor ( ) . setSelectedInstance ( NULL ) ;
return 0 ;
}
CInstance * inst = getEditor ( ) . getInstanceFromId ( ls . toString ( 2 ) ) ;
if ( ! inst )
{
nlwarning ( " setSelectedInstance : Instance with Id %s not found " , ls . toString ( 2 ) ) ;
return 0 ;
}
if ( ! inst - > getSelectableFromRoot ( ) )
{
nlwarning ( " Instance with id %s or one of its ancestor is not selectable " , ls . toString ( 2 ) ) ;
return 0 ;
}
getEditor ( ) . setSelectedInstance ( inst ) ;
return 0 ;
}
// *********************************************************************************************************
int CEditor : : luaSetCurrentTool ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaSetCurrentTool)
CHECK_EDITOR
CLuaIHM : : check ( ls , ls . getTop ( ) = = 2 | | ls . getTop ( ) = = 3 , " luaSetCurrentTool (method) " ) ;
CLuaIHM : : checkArgType ( ls , " setCurrentTool " , 2 , LUA_TSTRING ) ;
if ( ls . strlen ( 2 ) = = 0 )
{
getEditor ( ) . setCurrentTool ( NULL ) ;
}
else
{
CTool * tool = createObjectFromClassName < CTool > ( ls . toString ( 2 ) ) ;
if ( tool )
{
if ( ls . getTop ( ) = = 3 )
{
CLuaObject initParams ( ls ) ;
tool - > init ( initParams ) ;
}
getEditor ( ) . setCurrentTool ( tool ) ;
}
}
return 0 ;
}
// *********************************************************************************************************
int CEditor : : luaGetCurrentTool ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaGetCurrentTool)
CHECK_EDITOR
CLuaIHM : : checkArgCount ( ls , " getCurrentTool " , 1 ) ; // 1 because of the method call
CLuaIHM : : pushReflectableOnStack ( ls , getEditor ( ) . getCurrentTool ( ) ) ;
return 1 ;
}
// *********************************************************************************************************
int CEditor : : luaGetSelectedInstance ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaGetSelectedInstance)
CHECK_EDITOR
if ( ! getEditor ( ) . getSelectedInstance ( ) )
{
ls . pushNil ( ) ;
}
else
{
getEditor ( ) . projectInLua ( getEditor ( ) . getSelectedInstance ( ) - > getObjectTable ( ) ) ;
}
return 1 ;
}
// *********************************************************************************************************
int CEditor : : luaGetInstanceFromId ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaGetInstanceFromId)
CHECK_EDITOR
const char * funcName = " getInstanceFromId " ;
CLuaIHM : : checkArgCount ( ls , funcName , 2 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TSTRING ) ;
CInstance * inst = getEditor ( ) . getInstanceFromId ( ls . toString ( 2 ) ) ;
if ( inst = = NULL )
{
ls . pushNil ( ) ;
return 1 ;
}
else
{
getEditor ( ) . projectInLua ( inst - > getObjectTable ( ) ) ;
return 1 ;
}
return 0 ;
}
// ********************************************************************************************************
int CEditor : : luaGetVisualPropertiesFromInstanceId ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaGetVisualPropertiesFromInstanceId)
const char * funcName = " getVisualPropertiesFromInstanceId " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TSTRING ) ; // instance sheetClient
CInstance * inst = getEditor ( ) . getInstanceFromId ( ls . toString ( 1 ) ) ;
if ( ! inst ) { return 0 ; }
CObject * object = inst - > getObjectTable ( ) ;
if ( ! object ) { return 0 ; }
SPropVisualA vA ;
SPropVisualB vB ;
SPropVisualC vC ;
bool ok = getEditor ( ) . getVisualPropertiesFromObject ( object , vA , vB , vC ) ;
if ( ! ok )
{
return 0 ; //no param
}
uint64 uVPA = vA . get ( ) ;
uint64 uVPB = vB . get ( ) ;
uint64 uVPC = vC . get ( ) ;
std : : string strVPABC = NLMISC : : toString ( " VPA:%016.16 " NL_I64 " x \n VPB:%016.16 " NL_I64 " x \n VPC:%016.16 " NL_I64 " x " , uVPA , uVPB , uVPC ) ;
ls . push ( strVPABC ) ;
return 1 ; //3 string
}
// *********************************************************************************************************
int CEditor : : luaDisplayContextMenu ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaDisplayContextMenu)
CHECK_EDITOR
CLuaIHM : : checkArgCount ( ls , " displayContextMenu " , 1 ) ; // this is a method
getEditor ( ) . displayContextMenu ( ) ;
return 0 ;
}
// *********************************************************************************************************
int CEditor : : luaConnectAsCreator ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaConnectAsCreator)
CHECK_EDITOR
CLuaIHM : : checkArgCount ( ls , " connectAsCreator " , 1 ) ; // this is a method
//getEditor().connectAsCreator();
return 0 ;
}
// *********************************************************************************************************
int CEditor : : luaDofile ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaDofile)
CHECK_EDITOR
CLuaIHM : : checkArgCount ( ls , " doFile " , 1 ) ;
CLuaIHM : : checkArgType ( ls , " doFile " , 1 , LUA_TSTRING ) ;
getEditor ( ) . doLuaScript ( ls . toString ( - 1 ) , ls . toString ( - 1 ) ) ;
return 0 ;
}
// *********************************************************************************************************
int CEditor : : luaTryFile ( CLuaState & /* ls */ )
{
//H_AUTO(R2_CEditor_luaTryFile)
/* CHECK_EDITOR
CLuaIHM : : checkArgCount ( ls , " doFile " , 1 ) ;
CLuaIHM : : checkArgType ( ls , " doFile " , 1 , LUA_TSTRING ) ;
getEditor ( ) . doLuaScript ( ls . toString ( - 1 ) , ls . toString ( - 1 ) ) ; */
return 0 ;
}
// *********************************************************************************************************
int CEditor : : luaSetEntityCustomSelectBox ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaSetEntityCustomSelectBox)
CHECK_EDITOR
CLuaIHM : : checkArgCount ( ls , " setEntityCustomSelectBox " , 3 ) ; // 3 because of method call
CLuaIHM : : checkArgType ( ls , " setEntityCustomSelectBox " , 2 , LUA_TSTRING ) ;
CLuaIHM : : checkArgType ( ls , " setEntityCustomSelectBox " , 3 , LUA_TTABLE ) ;
std : : string sheetName = ls . toString ( 2 ) ;
CEntityCustomSelectBox selectBox ;
CLuaObject obj ( ls ) ;
selectBox . fromTable ( obj ) ;
TEntityCustomSelectBoxMap & boxMap = getEditor ( ) . getEntityCustomSelectBoxMap ( ) ;
boxMap [ sheetName ] = selectBox ;
/*
static volatile bool dumpMap = false ;
if ( dumpMap )
{
for ( TEntityCustomSelectBoxMap : : const_iterator watchIt = boxMap . begin ( ) ; watchIt ! = boxMap . end ( ) ; + + watchIt )
{
nlwarning ( watchIt - > first . c_str ( ) ) ;
}
}
*/
return 0 ;
}
// *********************************************************************************************************
int CEditor : : luaGetEntityCustomSelectBox ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaGetEntityCustomSelectBox)
CHECK_EDITOR
CLuaIHM : : checkArgCount ( ls , " getEntityCustomSelectBox " , 2 ) ; // 3 because of method call
CLuaIHM : : checkArgType ( ls , " getEntityCustomSelectBox " , 2 , LUA_TSTRING ) ;
std : : string sheetName = ls . toString ( 2 ) ;
TEntityCustomSelectBoxMap boxMap = getEditor ( ) . getEntityCustomSelectBoxMap ( ) ;
if ( boxMap . count ( sheetName ) )
{
ls . newTable ( ) ;
CLuaObject result ( ls ) ;
boxMap [ sheetName ] . toTable ( result ) ;
result . push ( ) ;
}
else
{
ls . pushNil ( ) ;
}
return 1 ;
}
// *********************************************************************************************************
int CEditor : : luaChoosePos ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaChoosePos)
CHECK_EDITOR
const char * funcName = " choosePos " ;
CLuaIHM : : checkArgMin ( ls , funcName , 5 ) ;
CLuaIHM : : checkArgMax ( ls , funcName , 10 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TSTRING ) ;
CLuaIHM : : checkArgType ( ls , funcName , 5 , LUA_TSTRING ) ;
std : : string toolName = ls . toString ( 5 ) ;
std : : string cursValid = " curs_create.tga " ;
std : : string cursInvalid = " curs_stop.tga " ;
if ( ls . getTop ( ) > = 6 )
{
CLuaIHM : : checkArgType ( ls , funcName , 6 , LUA_TSTRING ) ;
cursValid = ls . toString ( 6 ) ;
}
if ( ls . getTop ( ) > = 7 )
{
CLuaIHM : : checkArgType ( ls , funcName , 7 , LUA_TSTRING ) ;
cursInvalid = ls . toString ( 7 ) ;
}
// method param 1 -> sheet id
// method param 2 -> ok function
// method param 3 -> cancel function
ls . pushValue ( 3 ) ;
CLuaObject validFunc ( ls ) ; // pop valid function
ls . pushValue ( 4 ) ;
CLuaObject cancelFunc ( ls ) ; // pop cancel function
//
sint ghostSlot ;
if ( ls . strlen ( 2 ) ! = 0 )
{
CSheetId sheetId ( ls . toString ( 2 ) ) ;
if ( sheetId = = CSheetId : : Unknown )
{
nlwarning ( " Can't get sheet %s " , ls . toString ( 2 ) ) ;
return 0 ;
}
ghostSlot = 1 ; // TMP TMP
if ( ! createEntity ( ghostSlot , sheetId , CVector : : Null , 0.f ) )
{
nlwarning ( " Cannot create entity for sheet %s " , ls . toString ( 2 ) ) ;
return 0 ;
}
}
else
{
ghostSlot = - 1 ; // no representation in scene
}
// additionnal polys displayed by the choose pos
std : : vector < NLMISC : : CPolygon2D > polys ;
CPrimLook validLook ;
CPrimLook invalidLook ;
if ( ls . getTop ( ) > = 8 )
{
CLuaStackRestorer lsr ( & ls , ls . getTop ( ) ) ;
CLuaIHM : : checkArgType ( ls , funcName , 8 , LUA_TTABLE ) ;
ls . pushValue ( 8 ) ;
CLuaObject poly ;
poly . pop ( ls ) ;
ENUM_LUA_TABLE ( poly , it )
{
NLMISC : : CPolygon2D newPoly ;
it . nextValue ( ) . push ( ) ;
CLuaIHM : : getPoly2DOnStack ( ls , - 1 , newPoly ) ;
ls . pop ( ) ;
polys . push_back ( newPoly ) ;
}
}
if ( ls . getTop ( ) > = 9 )
{
ls . pushValue ( 9 ) ;
CLuaObject look ;
look . pop ( ls ) ;
validLook . init ( look ) ;
}
if ( ls . getTop ( ) > = 10 )
{
ls . pushValue ( 10 ) ;
CLuaObject look ;
look . pop ( ls ) ;
invalidLook . init ( look ) ;
}
//
getEditor ( ) . setCurrentTool ( new CToolChoosePosLua ( ghostSlot , validFunc , cancelFunc , toolName , cursValid , cursInvalid , polys , validLook , invalidLook ) ) ;
return 0 ;
}
// *********************************************************************************************************
int CEditor : : luaSnapPosToGround ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaSnapPosToGround)
CHECK_EDITOR
const char * funcName = " snapPosToGround " ;
CLuaIHM : : checkArgCount ( ls , funcName , 3 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TNUMBER ) ;
CLuaIHM : : checkArgType ( ls , funcName , 3 , LUA_TNUMBER ) ;
//
/*NLPACS::UGlobalPosition gpos = GR->retrievePosition(CVector((float) ls.toNumber(2), (float) ls.toNumber(3), 2000.f));
if ( gpos . InstanceId ! = - 1 )
{
CVector snappedPos = GR - > getGlobalPosition ( gpos ) ;
ls . push ( ( double ) snappedPos . x ) ;
ls . push ( ( double ) snappedPos . y ) ;
ls . push ( ( double ) snappedPos . z ) ;
return 3 ;
}
else
{
// default z to 0
ls . push ( 0.f ) ;
return 3 ;
} */
// new algo : to avoid to snapping to a cliff, start from the approximate (valid) height found in the height map
CVector inter ;
if ( CTool : : computeWorldMapIntersection ( ( float ) ls . toNumber ( 2 ) , ( float ) ls . toNumber ( 3 ) , inter ) ! = CTool : : NoIntersection )
{
ls . push ( ( double ) inter . x ) ;
ls . push ( ( double ) inter . y ) ;
ls . push ( ( double ) inter . z ) ;
return 3 ;
}
else
{
// default z to 0
ls . push ( 0.f ) ;
return 3 ;
}
}
// *********************************************************************************************************
int CEditor : : luaGetUserEntityPosition ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaGetUserEntityPosition)
CHECK_EDITOR
const char * funcName = " getUserEntityPosition " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ;
ls . push ( ( double ) UserEntity - > pos ( ) . x ) ;
ls . push ( ( double ) UserEntity - > pos ( ) . y ) ;
ls . push ( ( double ) UserEntity - > pos ( ) . z ) ;
return 3 ;
}
// *********************************************************************************************************
int CEditor : : luaGetUserEntityFront ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaGetUserEntityFront)
CHECK_EDITOR
const char * funcName = " getUserEntityPosition " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ;
ls . push ( ( double ) UserEntity - > front ( ) . x ) ;
ls . push ( ( double ) UserEntity - > front ( ) . y ) ;
return 2 ;
}
// *********************************************************************************************************
int CEditor : : luaRequestSetLocalNode ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaRequestSetLocalNode)
CHECK_EDITOR
const char * funcName = " requestSetLocalNode " ;
CLuaIHM : : checkArgCount ( ls , funcName , 3 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TSTRING ) ;
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TSTRING ) ;
CObject * object = CComLuaModule : : getObjectFromLua ( ls . getStatePointer ( ) ) ;
if ( ! object )
{
CLuaIHM : : fails ( ls , " %s : can't read object from parameter 3 " , funcName ) ;
}
getEditor ( ) . requestSetLocalNode ( ls . toString ( 1 ) , ls . toString ( 2 ) , object ) ;
delete object ;
return 0 ;
}
// *********************************************************************************************************
int CEditor : : luaRequestCommitLocalNode ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaRequestCommitLocalNode)
CHECK_EDITOR
const char * funcName = " requestCommitLocalNode " ;
CLuaIHM : : checkArgCount ( ls , funcName , 2 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TSTRING ) ;
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TSTRING ) ;
getEditor ( ) . requestCommitLocalNode ( ls . toString ( 1 ) , ls . toString ( 2 ) ) ;
return 0 ;
}
// *********************************************************************************************************
int CEditor : : luaRequestRollbackLocalNode ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaRequestRollbackLocalNode)
CHECK_EDITOR
const char * funcName = " requestRollbackLocalNode " ;
CLuaIHM : : checkArgCount ( ls , funcName , 2 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TSTRING ) ;
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TSTRING ) ;
getEditor ( ) . requestRollbackLocalNode ( ls . toString ( 1 ) , ls . toString ( 2 ) ) ;
return 0 ;
}
// *********************************************************************************************************
int CEditor : : luaSetCurrentActFromId ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaSetCurrentActFromId)
CHECK_EDITOR
const char * funcName = " setCurrentActFromId " ;
CLuaIHM : : checkArgCount ( ls , funcName , 2 ) ; // this is a method
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TSTRING ) ;
CInstance * act = getEditor ( ) . getInstanceFromId ( ls . toString ( 2 ) ) ;
if ( getEditor ( ) . _ClearingContent ) { return 0 ; }
if ( ! act )
{
nlwarning ( " %s : act with id %s not found " , funcName , ls . toString ( 1 ) ) ;
return 0 ;
}
if ( ! act - > isKindOf ( " Act " ) )
{
nlwarning ( " %s : instance with id %s is not an act " , funcName , ls . toString ( 1 ) ) ;
return 0 ;
}
getEditor ( ) . setCurrentAct ( act ) ;
return 0 ;
}
// *********************************************************************************************************
int CEditor : : luaGetCurrentAct ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaGetCurrentAct)
CHECK_EDITOR
const char * funcName = " getCurrentAct " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ; // this is a method
if ( getEditor ( ) . getCurrentAct ( ) )
{
getEditor ( ) . projectInLua ( getEditor ( ) . getCurrentAct ( ) - > getObjectTable ( ) ) ;
}
else
{
ls . pushNil ( ) ;
}
return 1 ;
}
// *********************************************************************************************************
int CEditor : : luaGenInstanceName ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaGenInstanceName)
CHECK_EDITOR
const char * funcName = " genInstanceName " ;
CLuaIHM : : checkArgCount ( ls , funcName , 2 ) ; // this is a method
CLuaIHM : : checkArgTypeUCString ( ls , funcName , 2 ) ; // name
ucstring baseName ;
nlverify ( CLuaIHM : : getUCStringOnStack ( ls , 2 , baseName ) ) ;
CLuaIHM : : push ( ls , getEditor ( ) . genInstanceName ( baseName ) ) ;
return 1 ;
}
// *********************************************************************************************************
int CEditor : : luaIsPostFixedByNumber ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaIsPostFixedByNumber)
CHECK_EDITOR
const char * funcName = " isPostFixedByNumber " ;
CLuaIHM : : checkArgCount ( ls , funcName , 2 ) ; // this is a method
CLuaIHM : : checkArgTypeUCString ( ls , funcName , 2 ) ; // name
ucstring baseName ;
nlverify ( CLuaIHM : : getUCStringOnStack ( ls , 2 , baseName ) ) ;
ls . push ( getEditor ( ) . isPostFixedByNumber ( baseName ) ) ;
return 1 ;
}
// *********************************************************************************************************
int CEditor : : luaIsClearingContent ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaIsPostFixedByNumber)
CHECK_EDITOR
const char * funcName = " isClearingContent " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ; // this is a method
ls . push ( getEditor ( ) . isClearingContent ( ) ) ;
return 1 ;
}
// *********************************************************************************************************
int CEditor : : luaSetCookie ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaSetCookie)
CHECK_EDITOR
const char * funcName = " setCookie " ;
CLuaIHM : : checkArgCount ( ls , funcName , 4 ) ; // this is a method (self + 3 params)
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TSTRING ) ; // instance id
CLuaIHM : : checkArgType ( ls , funcName , 3 , LUA_TSTRING ) ; // key
// last parameters may have any type
CLuaObject value ( ls ) ; // pop it
getEditor ( ) . setCookie ( ls . toString ( 2 ) , ls . toString ( 3 ) , value ) ;
return 0 ;
}
// *********************************************************************************************************
int CEditor : : luaIsCreature ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaIsCreature)
CHECK_EDITOR
const char * funcName = " isCreature " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TSTRING ) ; // instance sheetClient
CInstance * inst = getEditor ( ) . getInstanceFromId ( ls . toString ( 1 ) ) ;
if ( ! inst ) return 0 ;
const CCharacterSheet * sheet = dynamic_cast < const CCharacterSheet * > ( SheetMngr . get ( NLMISC : : CSheetId ( inst - > getSheet ( ) ) ) ) ;
if ( ! sheet ) return 0 ;
bool isNPC = sheet - > Race < EGSPD : : CPeople : : Creature ;
// neither NPC, not Kami, nor Karavan
bool creature = ! ( isNPC | | ( ! isNPC & & ( sheet - > Race = = EGSPD : : CPeople : : Kami | | sheet - > Race = = EGSPD : : CPeople : : Karavan ) ) ) ;
ls . push ( creature ) ;
return 1 ;
}
// *********************************************************************************************************
int CEditor : : luaSetEditorSeason ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaSetEditorSeason)
CHECK_EDITOR
const char * funcName = " setEditorSeason " ;
if ( getEditor ( ) . getMode ( ) ! = CEditor : : EditionMode
& & getEditor ( ) . getMode ( ) ! = CEditor : : AnimationModeLoading )
{
CLuaIHM : : fails ( ls , " %s : cannot set weather value outside of edit mode " , funcName ) ;
}
CLuaIHM : : checkArgCount ( ls , funcName , 2 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TSTRING ) ; // this is a method (self + 1 param)
if ( strcmp ( ls . toString ( 2 ) , " Automatic " ) = = 0 ) getEditor ( ) . _Season = Automatic ;
else if ( strcmp ( ls . toString ( 2 ) , " Spring " ) = = 0 ) getEditor ( ) . _Season = Spring ;
else if ( strcmp ( ls . toString ( 2 ) , " Summer " ) = = 0 ) getEditor ( ) . _Season = Summer ;
else if ( strcmp ( ls . toString ( 2 ) , " Autumn " ) = = 0 ) getEditor ( ) . _Season = Autumn ;
else if ( strcmp ( ls . toString ( 2 ) , " Winter " ) = = 0 ) getEditor ( ) . _Season = Winter ;
else CLuaIHM : : fails ( ls , " %s, invalid season name : %s " , ls . toString ( 2 ) ) ;
// If season is changed while scenario is being received, we do not have received the tp command yet,
// so signal the weather system that the season should not be changed for now
if ( ( getEditor ( ) . _UpdatingScenario & & getEditor ( ) . _WillTP )
| | getEditor ( ) . getMode ( ) ! = CEditor : : AnimationModeLoading )
{
getEditor ( ) . _IsWaitingTPForSeasonChange = true ;
}
else
{
getEditor ( ) . _IsWaitingTPForSeasonChange = false ;
}
return 0 ;
}
// *********************************************************************************************************
int CEditor : : luaSetFixedLighting ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaSetFixedLighting)
const char * funcName = " setEditorSeason " ;
CLuaIHM : : checkArgCount ( ls , funcName , 2 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TBOOLEAN ) ; // this is a method (self + 1 param)
getEditor ( ) . setFixedLighting ( ls . toBoolean ( 2 ) ) ;
return 0 ;
}
// *********************************************************************************************************
int CEditor : : luaGetFixedLighting ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaGetFixedLighting)
const char * funcName = " getEditorSeason " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ; // this is a method
ls . push ( getEditor ( ) . getFixedLighting ( ) ) ;
return 1 ;
}
// *********************************************************************************************************
int CEditor : : luaSetPlotItemInfos ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaSetPlotItemInfos)
const char * funcName = " setPlotItemInfos " ;
CLuaIHM : : checkArgCount ( ls , funcName , 5 ) ; // a method with 4 args
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TNUMBER ) ;
CLuaIHM : : checkArgTypeUCString ( ls , funcName , 3 ) ;
CLuaIHM : : checkArgTypeUCString ( ls , funcName , 4 ) ;
CLuaIHM : : checkArgTypeUCString ( ls , funcName , 5 ) ;
CItemSheet * item = dynamic_cast < CItemSheet * > ( SheetMngr . get ( CSheetId ( ( uint32 ) ls . toNumber ( 2 ) ) ) ) ;
if ( ! item | | item - > Family ! = ITEMFAMILY : : SCROLL_R2 )
{
CLuaIHM : : fails ( ls , " %s : bad sheet, r2 plot item required " , funcName ) ;
}
R2 : : TMissionItem mi ;
mi . SheetId = ( uint32 ) ls . toNumber ( 2 ) ;
CLuaIHM : : getUCStringOnStack ( ls , 3 , mi . Name ) ;
CLuaIHM : : getUCStringOnStack ( ls , 4 , mi . Description ) ;
CLuaIHM : : getUCStringOnStack ( ls , 5 , mi . Comment ) ;
getEditor ( ) . setPlotItemInfos ( mi ) ;
return 0 ;
}
// *********************************************************************************************************
int CEditor : : luaIsCurrentSelectionPlayer ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaIsCurrentSelectionPlayer)
const char * funcName = " isCurrentSelectionPlayer " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ; // method with 0 args
CPlayerCL * player = dynamic_cast < CPlayerCL * > ( EntitiesMngr . entity ( UserEntity - > getTargetSlotNoLag ( ) ) ) ;
ls . push ( player ! = NULL ) ;
return 1 ;
}
// *********************************************************************************************************
int CEditor : : luaFindEmptyPlace ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaFindEmptyPlace)
const char * funcName = " findEmptyPlace " ;
CLuaIHM : : checkArgCount ( ls , funcName , 3 ) ; // method with 2 args
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TNUMBER ) ;
CLuaIHM : : checkArgType ( ls , funcName , 3 , LUA_TNUMBER ) ;
CVector result ;
if ( getEditor ( ) . getIslandCollision ( ) . findEmptyPlace ( CVector2f ( ( float ) ls . toNumber ( 2 ) , ( float ) ls . toNumber ( 3 ) ) , result ) )
{
ls . push ( result . x ) ;
ls . push ( result . y ) ;
ls . push ( result . z ) ;
return 3 ;
}
return 0 ;
}
// *********************************************************************************************************
int CEditor : : luaIsInIslandRect ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaIsInIslandRect)
const char * funcName = " isInIslandRect " ;
CLuaIHM : : checkArgCount ( ls , funcName , 3 ) ; // method with 2 args
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TNUMBER ) ;
CLuaIHM : : checkArgType ( ls , funcName , 3 , LUA_TNUMBER ) ;
const R2 : : CScenarioEntryPoints : : CCompleteIsland * island = getEditor ( ) . getIslandCollision ( ) . getCurrIslandDesc ( ) ;
if ( ! island )
{
ls . push ( true ) ;
return 1 ;
}
float x = ( float ) ls . toNumber ( 2 ) ;
float y = ( float ) ls . toNumber ( 3 ) ;
ls . push ( x > = island - > XMin & & y > = island - > YMin & &
x < = island - > XMax & & y < = island - > YMax ) ;
return 1 ;
}
// *********************************************************************************************************
int CEditor : : luaGetCurrentIslandName ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaGetCurrentIslandName)
const char * funcName = " getCurrentIslandName " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ; // method with no args
R2 : : CScenarioEntryPoints : : CCompleteIsland * ci = getEditor ( ) . getIslandCollision ( ) . getCurrIslandDesc ( ) ;
ls . push ( ci ? ci - > Island . c_str ( ) : " " ) ;
return 1 ;
}
// *********************************************************************************************************
int CEditor : : luaKickCharacter ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaKickCharacter)
const char * funcName = " kickCharacter " ;
CLuaIHM : : checkArgCount ( ls , funcName , 2 ) ; // this is a method (self + 1 params)
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TNUMBER ) ;
CSessionBrowserImpl & sb = CSessionBrowserImpl : : getInstance ( ) ;
sb . kickCharacter ( sb . getCharId ( ) , R2 : : getEditor ( ) . getDMC ( ) . getEditionModule ( ) . getCurrentAdventureId ( ) ,
( uint32 ) ls . toNumber ( 2 ) ) ;
if ( ! sb . waitOneMessage ( sb . getMessageName ( " on_invokeResult " ) ) )
nlwarning ( " kickCharacter callback return false " ) ;
return 0 ;
}
// *********************************************************************************************************
int CEditor : : luaUnkickCharacter ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaUnkickCharacter)
const char * funcName = " unkickCharacter " ;
CLuaIHM : : checkArgCount ( ls , funcName , 2 ) ; // this is a method (self + 1 params)
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TNUMBER ) ;
CSessionBrowserImpl & sb = CSessionBrowserImpl : : getInstance ( ) ;
sb . unkickCharacter ( sb . getCharId ( ) , R2 : : getEditor ( ) . getDMC ( ) . getEditionModule ( ) . getCurrentAdventureId ( ) ,
( uint32 ) ls . toNumber ( 2 ) ) ;
if ( ! sb . waitOneMessage ( sb . getMessageName ( " on_invokeResult " ) ) )
nlwarning ( " unkickCharacter callback return false " ) ;
return 0 ;
}
// *********************************************************************************************************
int CEditor : : luaTeleportToCharacter ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaTeleportToCharacter)
const char * funcName = " teleportToCharacter " ;
CLuaIHM : : checkArgCount ( ls , funcName , 2 ) ; // this is a method (self + 1 params)
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TNUMBER ) ;
CClientEditionModule & cem = R2 : : getEditor ( ) . getDMC ( ) . getEditionModule ( ) ;
cem . requestTeleportOneCharacterToAnother ( cem . getCurrentAdventureId ( ) , CSessionBrowserImpl : : getInstance ( ) . getCharId ( ) ,
( uint32 ) ls . toNumber ( 2 ) ) ;
return 0 ;
}
// *********************************************************************************************************
int CEditor : : luaWaitScenarioScreen ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaWaitScenarioScreen)
const char * funcName = " waitScenarioScreen " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ; // method with no args
if ( ! ClientCfg . Local )
{
getEditor ( ) . _WaitScenarioScreenWanted = true ;
}
return 0 ;
}
// *********************************************************************************************************
int CEditor : : luaIsScenarioUpdating ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaIsScenarioUpdating)
const char * funcName = " isScenarioUpdating " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ; // method with no args
ls . push ( ( double ) getEditor ( ) . _UpdatingScenario ) ;
return 1 ;
}
/*
// *********************************************************************************************************
int CEditor : : luaIsValidPoly ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaIsValidPoly)
const char * funcName = " isValidPoly " ;
CLuaIHM : : checkArgCount ( ls , funcName , 2 ) ; // method with no args
CLuaIHM : : checkArgType ( ls , funcName , 3 , LUA_TTABLE ) ; // method with no args
ls . pushValue ( 3 ) ;
CLuaObject poly ;
NLMISC : : CPolygon2D poly2D ;
poly . pop ( luaState ) ;
ENUM_LUA_TABLE ( table , it )
{
NLMISC : : CVector2f pos ;
if ( ! CLuaIHM : : pop ( ls , pos ) )
{
CLuaIHM : : fails ( ls , " %s expects CVector2f for poly coordinates);
}
poly2D . Vertices . push_back ( pos ) ;
}
ls . push ( getEditor ( ) . getIslandCollision ( ) . isValidPoly ( poly2D ) ;
return 1 ;
}
// *********************************************************************************************************
int CEditor : : luaIsValidPosition ( CLuaState & ls )
{
CHECK_EDITOR
const char * funcName = " snapPosToGround " ;
CLuaIHM : : checkArgCount ( ls , funcName , 3 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TNUMBER ) ;
CLuaIHM : : checkArgType ( ls , funcName , 3 , LUA_TNUMBER ) ;
//
/*NLPACS::UGlobalPosition gpos = GR->retrievePosition(CVector((float) ls.toNumber(2), (float) ls.toNumber(3), 2000.f));
if ( gpos . InstanceId ! = - 1 )
{
CVector snappedPos = GR - > getGlobalPosition ( gpos ) ;
ls . push ( ( double ) snappedPos . x ) ;
ls . push ( ( double ) snappedPos . y ) ;
ls . push ( ( double ) snappedPos . z ) ;
return 3 ;
}
else
{
// default z to 0
ls . push ( 0.f ) ;
return 3 ;
}
// new algo : to avoid to snapping to a cliff, start from the approximate (valid) height found in the height map
CVector inter ;
if ( CTool : : computeWorldMapIntersection ( ( float ) ls . toNumber ( 2 ) , ( float ) ls . toNumber ( 3 ) , inter ) ! = CTool : : NoIntersection )
{
ls . push ( ( double ) inter . x ) ;
ls . push ( ( double ) inter . y ) ;
ls . push ( ( double ) inter . z ) ;
}
*/
// *********************************************************************************************************
int CEditor : : luaCanUndo ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaCanUndo)
const char * funcName = " canUndo " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ; // method with no args
ls . push ( getEditor ( ) . getDMC ( ) . getActionHistoric ( ) . canUndo ( ) ) ;
return 1 ;
}
// *********************************************************************************************************
int CEditor : : luaCanRedo ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaCanRedo)
const char * funcName = " canRedo " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ; // method with no args
ls . push ( getEditor ( ) . getDMC ( ) . getActionHistoric ( ) . canRedo ( ) ) ;
return 1 ;
}
// *********************************************************************************************************
int CEditor : : luaGetUserEntityName ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaGetUserEntityName)
const char * funcName = " getUserEntityName " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ; // this is a method
if ( UserEntity )
{
ucstring name = UserEntity - > getEntityName ( ) + PlayerSelectedHomeShardNameWithParenthesis ;
ls . push ( std : : string ( name . toUtf8 ( ) ) ) ;
}
else
{
ls . push ( std : : string ( " " ) ) ;
}
return 1 ;
}
static CLuaString lstr_Next ( " next " ) ;
// *********************************************************************************************************
int CEditor : : luaEnumInstances ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaEnumInstances)
CLuaStackChecker lsc ( & ls , 1 ) ;
// return an enumerator that allows to iterate over instance, by kind
const char * funcName = " enumInstances " ;
CLuaIHM : : checkArgCount ( ls , funcName , 2 ) ; // method with no args
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TSTRING ) ;
struct CInstanceEnumerator
{
CSortedInstances * InstMap ;
TInstanceByName : : iterator Current ;
static int next ( CLuaState & ls )
{
const char * funcName = " InstanceEnumerator:next " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TUSERDATA ) ;
CInstanceEnumerator * ie = ( CInstanceEnumerator * ) ls . toUserData ( 1 ) ;
CEditor & ed = getEditor ( ) ;
while ( ie - > Current ! = ie - > InstMap - > end ( ) )
{
CInstance * inst = ie - > Current - > second ;
if ( ! inst - > getGhost ( ) )
{
// object must be in current act or base act
CInstance * parentAct = inst - > getParentAct ( ) ;
if ( ! parentAct | | parentAct = = ed . getCurrentAct ( ) | | parentAct = = ed . getBaseAct ( ) )
{
inst - > getLuaProjection ( ) . push ( ) ;
+ + ie - > Current ;
return 1 ;
}
}
+ + ie - > Current ;
}
return 0 ;
}
//
static int gc ( CLuaState & ls )
{
const char * funcName = " InstanceEnumerator:next " ;
CLuaIHM : : checkArgCount ( ls , funcName , 1 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TUSERDATA ) ;
CInstanceEnumerator * ie = ( CInstanceEnumerator * ) ls . toUserData ( 1 ) ;
ie - > ~ CInstanceEnumerator ( ) ; // no real effect for now...
return 0 ;
}
static int index ( CLuaState & ls )
{
const char * funcName = " InstanceEnumerator.__index " ;
CLuaIHM : : checkArgCount ( ls , funcName , 2 ) ;
CLuaIHM : : checkArgType ( ls , funcName , 1 , LUA_TUSERDATA ) ;
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TSTRING ) ;
if ( ls . toString ( 2 ) = = lstr_Next )
{
ls . push ( CInstanceEnumerator : : next ) ;
return 1 ;
}
return 0 ;
}
} ;
sint classIndex = getEditor ( ) . classToIndex ( ls . toString ( 2 ) ) ;
if ( classIndex < 0 )
{
CLuaIHM : : fails ( ls , " Trying to iterate over unknown class : %s " , ls . toString ( 2 ) ) ;
}
ls . newTable ( ) ;
CLuaObject mt ;
mt . pop ( ls ) ;
ls . push ( CInstanceEnumerator : : index ) ;
mt . setValue ( " __index " , CLuaObject ( ls ) ) ;
ls . push ( CInstanceEnumerator : : gc ) ;
mt . setValue ( " __gc " , CLuaObject ( ls ) ) ;
//
void * newIter = ls . newUserData ( sizeof ( CInstanceEnumerator ) ) ;
CInstanceEnumerator * ie = new ( newIter ) CInstanceEnumerator ;
ie - > InstMap = & getEditor ( ) . _InstancesByDispName [ classIndex ] ;
ie - > Current = ie - > InstMap - > begin ( ) ;
mt . push ( ) ;
ls . setMetaTable ( - 2 ) ;
//
return 1 ;
}
// *********************************************************************************************************
void CEditor : : waitScenarioScreen ( )
{
//H_AUTO(R2_CEditor_waitScenarioScreen)
if ( ClientCfg . Local ) return ;
if ( _Mode = = EditionMode )
{
setMode ( GoingToEditionMode ) ;
}
getUI ( ) . hideAllWindows ( ) ;
CInterfaceGroup * waitScreen = dynamic_cast < CInterfaceGroup * > ( getUI ( ) . getElementFromId ( " ui:interface:r2ed_connecting " ) ) ;
if ( waitScreen )
{
waitScreen - > setActive ( true ) ;
getUI ( ) . setTopWindow ( waitScreen ) ;
}
//
enum TState { WaitingScenario , WaitingTP , DoExit } ;
TState state = WaitingScenario ;
//
getEditor ( ) . _ScenarioReceivedFlag = false ;
getEditor ( ) . _TPReceivedFlag = false ;
bool firewallTimeout = false ;
//
ActionsContext . setContext ( " waiting_network " ) ;
TGameCycle serverTick = NetMngr . getCurrentServerTick ( ) ;
getUI ( ) . setCaptureKeyboard ( NULL ) ;
getUI ( ) . setDefaultCaptureKeyboard ( NULL ) ;
loadBackgroundBitmap ( StartBackground ) ;
// patch for the 'sys info that pop' prb (cause unknown for now ...)
CInterfaceElement * sysInfo = getUI ( ) . getElementFromId ( " ui:interface:system_info " ) ;
bool sysInfoActive = false ;
if ( sysInfo ) sysInfoActive = sysInfo - > getActive ( ) ;
for ( ; ; )
{
switch ( state )
{
case WaitingScenario :
if ( getEditor ( ) . _ScenarioReceivedFlag )
{
if ( getEditor ( ) . _WillTP )
{
state = WaitingTP ;
}
else
{
state = DoExit ;
}
}
break ;
case WaitingTP :
// no-op
break ;
default :
nlassert ( 0 ) ;
break ;
}
if ( state = = DoExit )
{
break ;
}
// Update network.
try
{
if ( ! firewallTimeout )
NetMngr . update ( ) ;
}
catch ( EBlockedByFirewall & )
{
if ( NetMngr . getConnectionState ( ) = = CNetManager : : Disconnect )
{
firewallTimeout = true ;
}
else
{
// Display the firewall alert string
CViewText * pVT = dynamic_cast < CViewText * > ( getUI ( ) . getElementFromId ( " ui:interface:r2ed_connecting:title " ) ) ;
if ( pVT ! = NULL )
pVT - > setText ( CI18N : : get ( " uiFirewallAlert " ) + ucstring ( " ... " ) ) ;
// The mouse and fullscreen mode should be unlocked for the user to set the firewall permission
nlSleep ( 30 ) ; // 'nice' the client, and prevent to make too many send attempts
}
}
CCDBNodeBranch : : flushObserversCalls ( ) ;
// check if we can send another dated block
if ( NetMngr . getCurrentServerTick ( ) ! = serverTick )
{
//
serverTick = NetMngr . getCurrentServerTick ( ) ;
NetMngr . send ( serverTick ) ;
}
else
{
// Send dummy info
NetMngr . send ( ) ;
}
// update module manager
NLNET : : IModuleManager : : getInstance ( ) . updateModules ( ) ;
// Update the DT T0 and T1 global variables
updateClientTime ( ) ;
CInputHandlerManager : : getInstance ( ) - > pumpEvents ( ) ;
Driver - > clearBuffers ( CRGBA : : Black ) ;
Driver - > setMatrixMode2D11 ( ) ;
drawLoadingBitmap ( 1 ) ;
if ( state = = WaitingTP & & getEditor ( ) . _TPReceivedFlag )
{
break ; // don't want an additionnal swap buffer here, so exit now (the loading bitmap is good,
// has just been reloaded by the tp screen...
}
// Interface handling & displaying (processes clicks...)
getUI ( ) . updateFrameEvents ( ) ;
if ( waitScreen )
{
getUI ( ) . setTopWindow ( waitScreen ) ;
}
if ( sysInfo ) sysInfo - > setActive ( false ) ;
getUI ( ) . updateFrameViews ( NULL ) ;
CCDBNodeBranch : : flushObserversCalls ( ) ;
// Movie shooter
globalMenuMovieShooter ( ) ;
// Force the client to sleep a bit.
if ( ClientCfg . Sleep > = 0 )
{
nlSleep ( ClientCfg . Sleep ) ;
}
//
if ( ! waitScreen )
{
TextContext - > setShaded ( true ) ;
TextContext - > setFontSize ( 40 ) ;
TextContext - > setColor ( CRGBA : : White ) ;
// TOP LEFT //
//----------//
TextContext - > setHotSpot ( NL3D : : UTextContext : : MiddleMiddle ) ;
TextContext - > printfAt ( 0.5f , 0.5f , " (UI NOT FOUND) Waiting scenario from server. " ) ;
}
// Display
Driver - > swapBuffers ( ) ;
//
if ( NetMngr . getConnectionState ( ) = = CNetManager : : Disconnect )
{
if ( firewallTimeout )
{
// Display the firewall error string instead of the normal failure string
CViewText * pVT = dynamic_cast < CViewText * > ( getUI ( ) . getElementFromId ( " ui:interface:r2ed_connecting:title " ) ) ;
if ( pVT ! = NULL )
{
pVT - > setMultiLine ( true ) ;
pVT - > setText ( CI18N : : get ( " uiFirewallFail " ) + ucstring ( " . \n " ) +
CI18N : : get ( " uiFirewallAlert " ) + ucstring ( " . " ) ) ;
}
}
}
}
if ( sysInfo ) sysInfo - > setActive ( sysInfoActive ) ;
destroyLoadingBitmap ( ) ;
if ( _Mode = = GoingToEditionMode )
{
setMode ( EditionMode ) ;
}
return ;
}
// *********************************************************************************************************
// lua instance observer
class CInstanceObserverLua : public CEditor : : IInstanceObserver
{
public :
CInstanceObserverLua ( CLuaObject & receiver ) ;
~ CInstanceObserverLua ( ) ;
CLuaObject & getReceiver ( ) { return _Receiver ; }
// from IInstanceObserver
virtual void onInstanceCreated ( CInstance & instance ) ;
virtual void onInstanceErased ( CInstance & instance ) ;
virtual void onInstancePreHrcMove ( CInstance & instance ) ;
virtual void onInstancePostHrcMove ( CInstance & instance ) ;
virtual void onPreHrcMove ( CInstance & instance ) ;
virtual void onPostHrcMove ( CInstance & instance ) ;
virtual void onAttrModified ( CInstance & instance , const std : : string & attrName , sint32 attrIndex ) ;
private :
CLuaObject _Receiver ; // table that will receive the notifications
static uint _Count ;
} ;
uint CInstanceObserverLua : : _Count = 0 ;
CInstanceObserverLua : : CInstanceObserverLua ( CLuaObject & receiver ) : _Receiver ( receiver )
{
+ + _Count ;
}
CInstanceObserverLua : : ~ CInstanceObserverLua ( )
{
# ifdef NL_DEBUG
nlassert ( ! getEditor ( ) . isInstanceObserver ( this ) ) ;
# endif
nlassert ( _Count > = 0 ) ;
- - _Count ;
}
void CInstanceObserverLua : : onInstanceCreated ( CInstance & instance )
{
//H_AUTO(R2_CInstanceObserverLua_onInstanceCreated)
nlassert ( _Receiver . isValid ( ) ) ;
if ( _Receiver [ " onInstanceCreated " ] . isNil ( ) ) return ; // no-op if not handled
getEditor ( ) . projectInLua ( instance . getObjectTable ( ) ) ;
_Receiver . callMethodByNameNoThrow ( " onInstanceCreated " , 1 , 0 ) ;
}
void CInstanceObserverLua : : onInstanceErased ( CInstance & instance )
{
//H_AUTO(R2_CInstanceObserverLua_onInstanceErased)
nlassert ( _Receiver . isValid ( ) ) ;
if ( _Receiver [ " onInstanceErased " ] . isNil ( ) ) return ; // no-op if not handled
getEditor ( ) . projectInLua ( instance . getObjectTable ( ) ) ;
_Receiver . callMethodByNameNoThrow ( " onInstanceErased " , 1 , 0 ) ;
}
void CInstanceObserverLua : : onInstancePreHrcMove ( CInstance & instance )
{
//H_AUTO(R2_CInstanceObserverLua_onInstancePreHrcMove)
nlassert ( _Receiver . isValid ( ) ) ;
if ( _Receiver [ " onInstanceCreated " ] . isNil ( ) ) return ; // no-op if not handled
getEditor ( ) . projectInLua ( instance . getObjectTable ( ) ) ;
_Receiver . callMethodByNameNoThrow ( " onInstancePreHrcMove " , 1 , 0 ) ;
}
void CInstanceObserverLua : : onInstancePostHrcMove ( CInstance & instance )
{
//H_AUTO(R2_CInstanceObserverLua_onInstancePostHrcMove)
nlassert ( _Receiver . isValid ( ) ) ;
if ( _Receiver [ " onInstanceCreated " ] . isNil ( ) ) return ; // no-op if not handled
getEditor ( ) . projectInLua ( instance . getObjectTable ( ) ) ;
_Receiver . callMethodByNameNoThrow ( " onInstancePostHrcMove " , 1 , 0 ) ;
}
void CInstanceObserverLua : : onPreHrcMove ( CInstance & instance )
{
//H_AUTO(R2_CInstanceObserverLua_onPreHrcMove)
nlassert ( _Receiver . isValid ( ) ) ;
if ( _Receiver [ " onPreHrcMove " ] . isNil ( ) ) return ; // no-op if not handled
getEditor ( ) . projectInLua ( instance . getObjectTable ( ) ) ;
_Receiver . callMethodByNameNoThrow ( " onPreHrcMove " , 1 , 0 ) ;
}
void CInstanceObserverLua : : onPostHrcMove ( CInstance & instance )
{
//H_AUTO(R2_CInstanceObserverLua_onPostHrcMove)
nlassert ( _Receiver . isValid ( ) ) ;
if ( _Receiver [ " onPostHrcMove " ] . isNil ( ) ) return ; // no-op if not handled
getEditor ( ) . projectInLua ( instance . getObjectTable ( ) ) ;
_Receiver . callMethodByNameNoThrow ( " onPostHrcMove " , 1 , 0 ) ;
}
void CInstanceObserverLua : : onAttrModified ( CInstance & instance , const std : : string & attrName , sint32 attrIndex )
{
//H_AUTO(R2_CInstanceObserverLua_onAttrModified)
nlassert ( _Receiver . isValid ( ) ) ;
if ( _Receiver [ " onAttrModified " ] . isNil ( ) ) return ; // no-op if not handled
getEditor ( ) . projectInLua ( instance . getObjectTable ( ) ) ;
getEditor ( ) . getLua ( ) . push ( attrName ) ;
getEditor ( ) . getLua ( ) . push ( ( double ) attrIndex ) ;
_Receiver . callMethodByNameNoThrow ( " onAttrModified " , 3 , 0 ) ;
}
// *********************************************************************************************************
int CEditor : : luaAddInstanceObserver ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaAddInstanceObserver)
CHECK_EDITOR
const char * funcName = " addInstanceObserver " ;
CLuaIHM : : checkArgCount ( ls , funcName , 3 ) ; // this is a method (self + 2 params)
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TSTRING ) ; // instance id
CLuaIHM : : checkArgType ( ls , funcName , 3 , LUA_TTABLE ) ; // receiver
CLuaObject receiver ( ls ) ; // pop the receiver
ls . push ( ( double ) getEditor ( ) . addInstanceObserver ( ls . toString ( 2 ) , new CInstanceObserverLua ( receiver ) ) ) ;
return 1 ;
}
// *********************************************************************************************************
int CEditor : : luaRemoveInstanceObserver ( CLuaState & ls )
{
//H_AUTO(R2_CEditor_luaRemoveInstanceObserver)
CHECK_EDITOR
const char * funcName = " removeInstanceObserver " ;
CLuaIHM : : checkArgCount ( ls , funcName , 2 ) ; // this is a method (self + 1 params)
CLuaIHM : : checkArgType ( ls , funcName , 2 , LUA_TNUMBER ) ; // instance id
IInstanceObserver * observer = getEditor ( ) . getInstanceObserver ( ( TInstanceObserverHandle ) ls . toNumber ( 2 ) ) ;
if ( observer = = NULL )
{
CLuaIHM : : fails ( ls , " Instance observer not found for handle = %d " , ( int ) ls . toNumber ( 2 ) ) ;
}
CInstanceObserverLua * luaObserver = dynamic_cast < CInstanceObserverLua * > ( observer ) ;
if ( luaObserver = = NULL )
{
CLuaIHM : : fails ( ls , " Instance observer found for handle %d, but has bad type, it wasn't registered from lua. " , ( int ) ls . toNumber ( 2 ) ) ;
}
getEditor ( ) . removeInstanceObserver ( ( TInstanceObserverHandle ) ls . toNumber ( 2 ) ) ;
CLuaObject receiver = luaObserver - > getReceiver ( ) ;
delete luaObserver ;
receiver . push ( ) ;
return 1 ;
}
// *********************************************************************************************************
bool CEditor : : isInstanceObserver ( IInstanceObserver * observer ) const
{
//H_AUTO(R2_CEditor_isInstanceObserver)
for ( TInstanceObserverMap : : const_iterator it = _InstanceObservers . begin ( ) ; it ! = _InstanceObservers . end ( ) ; + + it )
{
if ( it - > second = = observer ) return true ;
}
return false ;
}
// *********************************************************************************************************
const CObjectTable * CEditor : : getObjectTableFromId ( const TInstanceId & id ) const
{
//H_AUTO(R2_CEditor_getObjectTableFromId)
CHECK_EDITOR
nlassert ( _DMC ) ;
const CObject * obj = _DMC - > find ( id ) ;
if ( ! obj ) return NULL ;
nlassert ( obj - > isTable ( ) ) ;
return ( CObjectTable * ) obj ;
}
// *********************************************************************************************************
CInstance * CEditor : : getInstanceFromObject ( const CObject * obj ) const
{
//H_AUTO(R2_CEditor_getInstanceFromObject)
CHECK_EDITOR
if ( ! obj - > isTable ( ) ) return NULL ;
TInstanceMap : : const_iterator it = _Instances . find ( ( CObjectTable * ) obj ) ;
if ( it ! = _Instances . end ( ) )
{
return it - > second ;
}
return NULL ;
}
// *********************************************************************************************************
void CEditor : : registerEnvMethod ( const char * name , TLuaWrappedFunction func )
{
//H_AUTO(R2_CEditor_registerEnvMethod)
CHECK_EDITOR
nlassert ( name ) ;
getEnv ( ) . setValue ( name , func ) ;
}
// *********************************************************************************************************
void CEditor : : registerEnvFunction ( const char * name , TLuaWrappedFunction func )
{
//H_AUTO(R2_CEditor_registerEnvFunction)
CHECK_EDITOR
nlassert ( name ) ;
getEnv ( ) . setValue ( name , func ) ;
}
// *********************************************************************************************************
void CEditor : : registerLuaFunc ( )
{
//H_AUTO(R2_CEditor_registerLuaFunc)
CHECK_EDITOR
registerEnvMethod ( " getSelectedInstanceId " , luaGetSelectedInstanceId ) ;
registerEnvMethod ( " setSelectedInstanceId " , luaSetSelectedInstanceId ) ;
registerEnvMethod ( " setCurrentTool " , luaSetCurrentTool ) ;
registerEnvMethod ( " getCurrentTool " , luaGetCurrentTool ) ;
registerEnvMethod ( " getVisualPropertiesFromInstanceId " , luaGetVisualPropertiesFromInstanceId ) ;
registerEnvMethod ( " getInstanceFromId " , luaGetInstanceFromId ) ;
registerEnvMethod ( " displayContextMenu " , luaDisplayContextMenu ) ;
registerEnvMethod ( " getSelectedInstance " , luaGetSelectedInstance ) ;
registerEnvMethod ( " connectAsCreator " , luaConnectAsCreator ) ;
registerEnvMethod ( " doFile " , luaDofile ) ;
registerEnvMethod ( " tryFile " , luaTryFile ) ;
registerEnvMethod ( " setEntityCustomSelectBox " , luaSetEntityCustomSelectBox ) ;
registerEnvMethod ( " getEntityCustomSelectBox " , luaGetEntityCustomSelectBox ) ;
registerEnvMethod ( " choosePos " , luaChoosePos ) ;
registerEnvMethod ( " snapPosToGround " , luaSnapPosToGround ) ;
registerEnvMethod ( " getUserEntityPosition " , luaGetUserEntityPosition ) ;
registerEnvMethod ( " getUserEntityFront " , luaGetUserEntityFront ) ;
registerEnvMethod ( " setCurrentActFromId " , luaSetCurrentActFromId ) ;
registerEnvMethod ( " getCurrentAct " , luaGetCurrentAct ) ;
registerEnvMethod ( " genInstanceName " , luaGenInstanceName ) ;
registerEnvMethod ( " isPostFixedByNumber " , luaIsPostFixedByNumber ) ;
registerEnvMethod ( " setCookie " , luaSetCookie ) ;
registerEnvMethod ( " addInstanceObserver " , luaAddInstanceObserver ) ;
registerEnvMethod ( " removeInstanceObserver " , luaRemoveInstanceObserver ) ;
registerEnvFunction ( " requestSetLocalNode " , luaRequestSetLocalNode ) ;
registerEnvFunction ( " requestCommitLocalNode " , luaRequestCommitLocalNode ) ;
registerEnvFunction ( " requestRollbackLocalNode " , luaRequestRollbackLocalNode ) ;
registerEnvMethod ( " isCreature " , luaIsCreature ) ;
registerEnvMethod ( " setEditorSeason " , luaSetEditorSeason ) ;
registerEnvMethod ( " setFixedLighting " , luaSetFixedLighting ) ;
registerEnvMethod ( " getFixedLighting " , luaGetFixedLighting ) ;
registerEnvMethod ( " setPlotItemInfos " , luaSetPlotItemInfos ) ;
registerEnvMethod ( " isCurrentSelectionPlayer " , luaIsCurrentSelectionPlayer ) ;
registerEnvMethod ( " findEmptyPlace " , luaFindEmptyPlace ) ;
registerEnvMethod ( " isInIslandRect " , luaIsInIslandRect ) ;
registerEnvMethod ( " getCurrentIslandName " , luaGetCurrentIslandName ) ;
registerEnvMethod ( " waitScenarioScreen " , luaWaitScenarioScreen ) ;
registerEnvMethod ( " isScenarioUpdating " , luaIsScenarioUpdating ) ;
registerEnvMethod ( " canUndo " , luaCanUndo ) ;
registerEnvMethod ( " canRedo " , luaCanRedo ) ;
registerEnvMethod ( " getUserEntityName " , luaGetUserEntityName ) ;
registerEnvMethod ( " getStartingAnimationFilename " , luaGetStartingAnimationFilename ) ;
registerEnvMethod ( " kickCharacter " , luaKickCharacter ) ;
registerEnvMethod ( " unkickCharacter " , luaUnkickCharacter ) ;
registerEnvMethod ( " teleportToCharacter " , luaTeleportToCharacter ) ;
registerEnvMethod ( " enumInstances " , luaEnumInstances ) ;
registerEnvMethod ( " isClearingContent " , luaIsClearingContent ) ;
}
/*
static void polyUnitTest ( )
{
CPolygon2D poly ;
poly . Vertices . push_back ( CVector2f ( 0.f , 0.f ) ) ;
poly . Vertices . push_back ( CVector2f ( 1.f , 0.f ) ) ;
poly . Vertices . push_back ( CVector2f ( 1.f , 1.f ) ) ;
poly . Vertices . push_back ( CVector2f ( 0.f , 1.f ) ) ;
nlassert ( poly . contains ( CVector2f ( 0.f , 0.f ) , false ) ) ;
nlassert ( poly . contains ( CVector2f ( 1.f , 0.f ) , false ) ) ;
nlassert ( poly . contains ( CVector2f ( 1.f , 1.f ) , false ) ) ;
nlassert ( poly . contains ( CVector2f ( 0.f , 1.f ) , false ) ) ;
nlassert ( poly . contains ( CVector2f ( 0.5f , 0.f ) , false ) )
nlassert ( poly . contains ( CVector2f ( 1.f , 0.5f ) , false ) ) ;
nlassert ( poly . contains ( CVector2f ( 0.5f , 1.f ) , false ) ) ;
nlassert ( poly . contains ( CVector2f ( 0.f , 0.5f ) , false ) ) ;
nlassert ( poly . contains ( CVector2f ( 0.5f , 0.5f ) , false ) ) ;
//
nlassert ( ! poly . contains ( CVector2f ( - 0.5f , 0.5f ) , false ) ) ;
nlassert ( ! poly . contains ( CVector2f ( 1.5f , 0.5f ) , false ) ) ;
nlassert ( ! poly . contains ( CVector2f ( 0.5f , - 0.5f ) , false ) ) ;
nlassert ( ! poly . contains ( CVector2f ( 0.5f , 1.5f ) , false ) ) ;
}
*/
// *********************************************************************************************************
void CEditor : : loadLanguageFile ( )
{
//H_AUTO(R2_CEditor_loadLanguageFile)
CHECK_EDITOR
static bool reload = false ;
CI18N : : ILoadProxy * oldLoadProxy = CI18N : : getLoadProxy ( ) ;
CI18N : : setLoadProxy ( NULL ) ;
string lc = ClientCfg . LanguageCode ;
nlinfo ( " Reloading the r2_%s.uxt " , lc . c_str ( ) ) ;
CI18N : : loadFromFilename ( " r2_ " + lc + " .uxt " , reload ) ;
CI18N : : setLoadProxy ( oldLoadProxy ) ;
reload = true ;
}
// *********************************************************************************************************
void CEditor : : loadKeySet ( const std : : string & keySet )
{
//H_AUTO(R2_CEditor_loadKeySet)
CHECK_EDITOR
if ( keySet . empty ( ) ) return ;
CVerboseClock clock ( " Parsing of keyset " + keySet ) ;
// remove all existing keys
ActionsContext . removeAllCombos ( ) ;
CMacroCmdManager : : getInstance ( ) - > removeAllMacros ( ) ;
// parse keys that are specific to r2ed
std : : vector < string > xmlFilesToParse ;
// Does the r2ed keys file exist ?
std : : string userKeyFileName = " save/ " + keySet + " _ " + PlayerSelectedFileName + " .xml " ;
if ( CFile : : fileExists ( userKeyFileName ) & & CFile : : getFileSize ( userKeyFileName ) > 0 )
{
// Load the user key file
xmlFilesToParse . push_back ( userKeyFileName ) ;
}
// Load the default key (but don't replace existings bounds, see keys.xml "key_def_no_replace")
xmlFilesToParse . push_back ( keySet + " .xml " ) ;
if ( ! CInterfaceManager : : getInstance ( ) - > parseInterface ( xmlFilesToParse , true ) )
{
badXMLParseMessageBox ( ) ;
}
CActionsManager * actionManager = ActionsContext . getActionsManager ( ) ;
if ( actionManager )
{
// if some mode are unavailable, forbid the associated shortcuts
/*if (!_ModeEnabled[EditionMode])
{
actionManager - > removeBaseAction ( " r2ed_stop_test " ) ;
}
if ( ! _ModeEnabled [ TestMode ] | | ! _ModeEnabled [ DMMode ] )
{
actionManager - > removeBaseAction ( " r2ed_try_go_test " ) ;
} */
}
}
// *********************************************************************************************************
void CEditor : : saveCurrentKeySet ( )
{
//H_AUTO(R2_CEditor_saveCurrentKeySet)
CHECK_EDITOR
std : : string prefix = getKeySetPrefix ( getMode ( ) ) ;
if ( prefix . empty ( ) ) return ;
getUI ( ) . saveKeys ( " save/ " + prefix + " _ " + PlayerSelectedFileName + " .xml " ) ;
}
// *********************************************************************************************************
std : : string CEditor : : getKeySetPrefix ( TMode mode )
{
//H_AUTO(R2_CEditor_getKeySetPrefix)
CHECK_EDITOR
switch ( mode )
{
case EditionMode : return " keys_r2ed " ;
case GoingToDMMode :
case GoingToEditionMode :
case AnimationModeLoading :
case AnimationModeWaitingForLoading :
case AnimationModeGoingToDm :
case AnimationModeGoingToPlay :
return " " ;
case AnimationModePlay :
return " keys " ;
default :
return " keys " ;
}
return std : : string ( ) ;
}
// *********************************************************************************************************
void CEditor : : setUIMode ( uint8 mode )
{
//H_AUTO(R2_CEditor_setUIMode)
CHECK_EDITOR
getUI ( ) . setMode ( mode ) ;
if ( _ForceDesktopReset [ mode ] )
{
// force to call reset when reloading the ui
getLua ( ) . push ( ( double ) mode ) ;
callEnvMethod ( " resetDesktop " , 1 , 0 ) ;
_ForceDesktopReset [ mode ] = false ;
}
getLua ( ) . push ( ( double ) mode ) ;
callEnvMethod ( " onChangeDesktop " , 1 , 0 ) ;
}
// *********************************************************************************************************
void CEditor : : loadStandardUI ( )
{
//H_AUTO(R2_CEditor_loadStandardUI)
getUI ( ) . setMode ( 0 ) ;
// force to reload the standard interface
ClientCfg . R2EDEnabled = false ;
loadUIConfig ( " " ) ;
ClientCfg . R2EDEnabled = true ;
getUI ( ) . updateAllLocalisedElements ( ) ;
}
// *********************************************************************************************************
bool CEditor : : isDMing ( ) const
{
//H_AUTO(R2_CEditor_isDMing)
if ( getMode ( ) = = AnimationModePlay ) return false ; // masterless mode -> not a dm
return getMode ( ) = = DMMode | |
getMode ( ) = = AnimationModeDm | |
(
getMode ( ) ! = NotInitialized & &
getAccessMode ( ) = = AccessDM
) ;
}
// *********************************************************************************************************
void CEditor : : setMode ( TMode mode )
{
switch ( mode )
{
case NotInitialized : nlwarning ( " *R2* Setting mode to NotInitialized " ) ; break ;
case EditionMode : nlwarning ( " *R2* Setting mode to EditionMode " ) ; break ;
case GoingToDMMode : nlwarning ( " *R2* Setting mode to GoingToDMMode " ) ; break ;
case GoingToEditionMode : nlwarning ( " *R2* Setting mode to GoingToEditionMode " ) ; break ;
case TestMode : nlwarning ( " *R2* Setting mode to TestMode " ) ; break ;
case DMMode : nlwarning ( " *R2* Setting mode to DMMode " ) ; break ;
case AnimationModeLoading : nlwarning ( " *R2* Setting mode to AnimationModeLoading " ) ; break ;
case AnimationModeWaitingForLoading : nlwarning ( " *R2* Setting mode to AnimationModeWaitingForLoading " ) ; break ;
case AnimationModeDm : nlwarning ( " *R2* Setting mode to AnimationModeDm " ) ; break ;
case AnimationModePlay : nlwarning ( " *R2* Setting mode to AnimationModePlay " ) ; break ;
case AnimationModeGoingToDm : nlwarning ( " *R2* Setting mode to AnimationModeGoingToDm " ) ; break ;
case AnimationModeGoingToPlay : nlwarning ( " *R2* Setting mode to AnimationModeGoingToPlay " ) ; break ;
default :
nlwarning ( " Setting mode to 'unknown' " ) ;
break ;
}
if ( mode ! = EditionMode )
{
delete _EntitySorter ;
_EntitySorter = NULL ;
}
//H_AUTO(R2_CEditor_setMode)
CHECK_EDITOR
//nlassert(_ModeEnabled[mode]);
if ( mode = = _Mode & & ! _ForceDesktopReset [ mode ] ) return ;
if ( mode ! = _Mode )
{
if ( ( _Mode = = AnimationModeDm | | _Mode = = AnimationModePlay )
& & ! ( ( mode = = AnimationModeDm | | mode = = AnimationModePlay ) ) )
{
// remove the chat windows when leaving animation mode
PeopleInterraction . removeAllFreeTellers ( ) ;
}
CVerboseClock clock ( " Saving windows & key at a mode change ... " ) ;
if ( _Mode ! = NotInitialized )
{
saveCurrentKeySet ( ) ;
}
//if (_Mode != NotInitialized) saveUIConfig();
if ( _Mode = = EditionMode | | _Mode = = AnimationModeLoading )
{
getDMC ( ) . getActionHistoric ( ) . clear ( ) ; // no backup of undo/redo for now
clearContent ( ) ; // when leaving edition, remove content from tree
}
else if ( mode = = EditionMode | | mode = = GoingToEditionMode )
{
removeAllEntitySlots ( ) ; // when leaving test or dm, remove the entities slots
}
if ( mode = = DMMode | | mode = = AnimationModeDm )
{
getEditor ( ) . getDMC ( ) . getEditionModule ( ) . askUpdateCharMode ( TCharMode : : Dm ) ;
}
else if ( mode = = EditionMode )
{
getEditor ( ) . getDMC ( ) . getEditionModule ( ) . askUpdateCharMode ( TCharMode : : Editer ) ;
}
else if ( mode = = AnimationModePlay )
{
if ( _Mode ! = NotInitialized )
{
if ( _SerializeUIConfig )
{
saveUIConfig ( ) ;
}
}
getEditor ( ) . getDMC ( ) . getEditionModule ( ) . askUpdateCharMode ( TCharMode : : Player ) ;
// if access mode is DM, then load the whole ui
if ( _AccessMode = = AccessDM )
{
loadStandardUI ( ) ;
}
}
else if ( mode = = TestMode )
{
getEditor ( ) . getDMC ( ) . getEditionModule ( ) . askUpdateCharMode ( TCharMode : : Tester ) ;
}
else // Other like going to dm ...
{
}
}
// reset any selection
if ( ( ! IngameDbMngr . initInProgress ( ) ) & & UserEntity ) // prevent from calling selection() if coming from a FarTP, otherwise the server will mess up the action counter because it can't know our datasetrow so early (initInProgress(): heuristic to ensure the setTarget() will work on the EGS)
{
UserEntity - > selection ( CLFECOMMON : : INVALID_SLOT ) ;
}
//
ContextCur . release ( ) ;
_Mode = mode ;
loadKeySet ( getKeySetPrefix ( _Mode ) ) ;
getUI ( ) . disableModalWindow ( ) ;
getUI ( ) . setCapturePointerLeft ( NULL ) ;
getUI ( ) . setCapturePointerRight ( NULL ) ;
getUI ( ) . setCaptureKeyboard ( NULL ) ;
// Season is now unknown, until server force it (in test mode), or first set act set it (in edit mode)
_Season = UnknownSeason ;
//
switch ( _Mode )
{
case EditionMode :
if ( ! _EntitySorter )
{
_EntitySorter = new CEntitySorter ;
}
ActionsContext . setContext ( " r2ed " ) ;
// set new mode in lua
_Env . setValue ( " Mode " , " Edit " ) ;
setUIMode ( 0 ) ;
: : IgnoreEntityDbUpdates = true ;
: : SlotUnderCursor = CLFECOMMON : : INVALID_SLOT ;
/**
* nb we manage mouse bitmap ourselves , so there ' s only one cursor context here , and it never changes :
* its sole purpose is to route messages to the current tool
*/
ContextCur . add ( false , " STAND BY " , DEFAULT_CURSOR , 0.0f , CEditor : : checkCursor , CEditor : : mouseClick ) ;
forceSetSelectedInstance ( NULL ) ;
initReferencePlotItems ( ) ;
// force speed to "run" ("walk" not available in edition)
if ( ! UserEntity - > running ( ) )
{
UserEntity - > switchVelocity ( ) ;
}
break ;
case TestMode :
ActionsContext . setContext ( " r2ed_anim_test " ) ;
// set new mode in lua
_Env . setValue ( " Mode " , " Test " ) ;
setUIMode ( 1 ) ;
: : IgnoreEntityDbUpdates = false ;
: : initContextualCursor ( ) ;
nlassert ( CDisplayerBase : : ObjCount = = 0 ) ;
resetPlotItems ( ) ;
break ;
case DMMode :
ActionsContext . setContext ( " r2ed_anim_dm " ) ;
// set new mode in lua
_Env . setValue ( " Mode " , " DM " ) ;
setUIMode ( 2 ) ;
: : IgnoreEntityDbUpdates = false ;
: : initContextualCursor ( ) ;
nlassert ( CDisplayerBase : : ObjCount = = 0 ) ;
// when in local mode, init fake plot item to test the 'dm gift' interface
initDummyPlotItems ( ) ;
break ;
case GoingToDMMode :
ActionsContext . setContext ( " waiting_network " ) ;
// set new mode in lua
_Env . setValue ( " Mode " , " GoingToDM " ) ;
setUIMode ( 3 ) ;
connexionMsg ( _ConnexionMsg ) ; // update connexion window
: : IgnoreEntityDbUpdates = false ;
: : initContextualCursor ( ) ;
nlassert ( CDisplayerBase : : ObjCount = = 0 ) ;
resetPlotItems ( ) ;
break ;
case GoingToEditionMode :
nlassert ( CDisplayerBase : : ObjCount = = 0 ) ;
ActionsContext . setContext ( " waiting_network " ) ;
// set new mode in lua
_Env . setValue ( " Mode " , " BackToEditing " ) ;
setUIMode ( 3 ) ;
connexionMsg ( _ConnexionMsg ) ; // update connexion window
: : IgnoreEntityDbUpdates = true ;
: : initContextualCursor ( ) ;
resetPlotItems ( ) ;
break ;
case AnimationModeLoading :
nlassert ( CDisplayerBase : : ObjCount = = 0 ) ;
ActionsContext . setContext ( " waiting_network " ) ;
// set new mode in lua
_Env . setValue ( " Mode " , " AnimationModeLoading " ) ;
setUIMode ( 3 ) ;
connexionMsg ( _ConnexionMsg ) ; // update connexion window
// ::IgnoreEntityDbUpdates = true;
: : initContextualCursor ( ) ;
resetPlotItems ( ) ;
break ;
case AnimationModeWaitingForLoading :
nlassert ( CDisplayerBase : : ObjCount = = 0 ) ;
ActionsContext . setContext ( " waiting_network " ) ;
// set new mode in lua
_Env . setValue ( " Mode " , " AnimationModeWaitingForLoading " ) ;
setUIMode ( 3 ) ;
connexionMsg ( _ConnexionMsg ) ; // update connexion window
// ::IgnoreEntityDbUpdates = true;
: : initContextualCursor ( ) ;
resetPlotItems ( ) ;
break ;
case AnimationModeDm :
PeopleInterraction . updateAllFreeTellerHeaders ( ) ; // if invitation were received during loading, add 'invite' button to the new windows
nlassert ( CDisplayerBase : : ObjCount = = 0 ) ;
ActionsContext . setContext ( " r2ed_anim_dm " ) ;
// set new mode in lua
_Env . setValue ( " Mode " , " AnimationModeDm " ) ;
setUIMode ( 2 ) ;
: : IgnoreEntityDbUpdates = false ;
: : initContextualCursor ( ) ;
resetPlotItems ( ) ;
break ;
case AnimationModePlay :
{
// animation mode play is still visible in masterless mode
nlassert ( CDisplayerBase : : ObjCount = = 0 ) ;
// no op here, just a player
ActionsContext . setContext ( " game " ) ;
//ActionsContext.setContext("r2ed_anim_test");
// set new mode in lua
_Env . setValue ( " Mode " , " r2ed_anim_test " ) ;
// hide all ring windows that may remain
hideRingWindows ( ) ;
// setUIMode(1); // don't change desktop here, because virtual desktops are allowed in this mode
getUI ( ) . setMode ( 0 ) ; // default to desktop 0 as with standard game
: : IgnoreEntityDbUpdates = false ;
: : initContextualCursor ( ) ;
resetPlotItems ( ) ;
if ( getDMC ( ) . getEditionModule ( ) . isSessionOwner ( ) )
{
// if we are not a player, pop the ui to pop control player window & to quit
callEnvMethod ( " popDMToolbarWindow " , 0 , 0 ) ;
}
else
{
callEnvMethod ( " playerModeUIFix " , 0 , 0 ) ;
}
}
break ;
case AnimationModeGoingToDm :
nlassert ( CDisplayerBase : : ObjCount = = 0 ) ;
ActionsContext . setContext ( " waiting_network " ) ;
//set new mode in lua
_Env . setValue ( " Mode " , " AnimationModeGoingToDM " ) ;
setUIMode ( 3 ) ;
connexionMsg ( _ConnexionMsg ) ; // update connexion window
: : IgnoreEntityDbUpdates = false ;
: : initContextualCursor ( ) ;
resetPlotItems ( ) ;
break ;
default :
nlassert ( 0 ) ;
break ;
}
ClientCfg . ManualWeatherSetup = false ;
ContextCur . context ( " STAND BY " ) ;
_Mode = mode ;
// warn lua that mode has changed
callEnvMethod ( " onModeChanged " , 0 , 0 ) ;
//
setCurrentTool ( NULL ) ;
// display the bars over the player (not available during edition, but available at test time)
UserEntity - > buildInSceneInterface ( ) ;
if ( _Mode = = EditionMode )
{
// special context menu for edition
GameContextMenu . init ( " game_context_menu_edition " ) ;
}
else
{
GameContextMenu . init ( " " ) ;
}
}
// *********************************************************************************************************
void CEditor : : hideRingWindows ( )
{
//H_AUTO(R2_CEditor_hideRingWindows)
static const char * ringWindows [ ] =
{
" r2ed_palette " ,
" r2ed_connect " ,
" r2ed_property_sheet_no_selection " ,
" r2ed_property_sheet_no_properties " ,
" r2ed_bbox_edit " ,
" r2ed_toolbar " ,
" r2ed_windows_dm_bar " ,
" r2ed_toolbar_window " ,
" r2ed_windows_bar " ,
" r2ed_main_bl " ,
" r2ed_animation_loading " ,
" r2ed_animation_waiting " ,
" dm_controlled_entities " ,
" r2ed_current_session " ,
" r2ed_toolbar_admin " ,
" lua_inspector " ,
" r2ed_npc " ,
" r2ed_select_bar " ,
" r2ed_main_menu_button " ,
" r2ed_contextual_toolbar_new " ,
" feature_help " ,
" r2ed_logic_entities " ,
" r2ed_events " ,
" r2ed_activities " ,
" r2ed_edit_activity_sequence " ,
" r2ed_dialogs " ,
" r2ed_edit_chat_sequence " ,
" r2ed_mini_activity_view " ,
" r2ed_acts " ,
" r2ed_connecting " ,
" r2ed_scenario " ,
" r2ed_dm_gift " ,
" r2ed_scenario_filter " ,
" r2ed_testbar "
} ;
for ( uint k = 0 ; k < sizeofarray ( ringWindows ) ; + + k )
{
std : : string id = " ui:interface: " + std : : string ( ringWindows [ k ] ) ;
CInterfaceElement * grp = getUI ( ) . getElementFromId ( id ) ;
if ( grp )
{
grp - > setActive ( false ) ;
}
else
{
nlwarning ( " Can't find group with id : %s " , id . c_str ( ) ) ;
}
}
}
// *********************************************************************************************************
void CEditor : : init ( TMode initialMode , TAccessMode accessMode )
{
nlwarning ( " *R2* init " ) ;
_EntitySorter = NULL ;
//H_AUTO(R2_CEditor_init)
CNiceInputAuto niceInputs ;
nlassert ( ( uint ) initialMode < ModeCount ) ;
nlassert ( ( uint ) accessMode < AccessModeCount ) ;
//nlassert(_ModeEnabled[initialMode]; // mode not enabled ...
CHECK_EDITOR
CVerboseClock clock ( " Init of editor " ) ;
_Initialized = true ;
_AccessMode = accessMode ;
// add a list of files for which modifications will trigger R2ED reset
for ( uint k = 0 ; k < ClientCfg . R2EDReloadFiles . size ( ) ; + + k )
{
CFile : : removeFileChangeCallback ( ClientCfg . R2EDReloadFiles [ k ] ) ; // avoid to add twice when a reset ...
CFile : : addFileChangeCallback ( ClientCfg . R2EDReloadFiles [ k ] , reloadEditorCallback ) ;
}
//
CLuaStackChecker lsc ( & getLua ( ) ) ;
getLua ( ) . pushValue ( LUA_GLOBALSINDEX ) ;
_Globals . pop ( getLua ( ) ) ;
getLua ( ) . pushValue ( LUA_REGISTRYINDEX ) ;
_Registry . pop ( getLua ( ) ) ;
// create R2 environment, and keep a reference on it
_Env = _Globals . newTable ( R2_LUA_PATH ) ;
_Config = _Env . newTable ( " Config " ) ;
//
_Env . setValue ( " InClient " , true ) ; // TMP : signal to the script that it is initialised by the client
//
switch ( accessMode )
{
case AccessEditor : _Env . setValue ( " AccessMode " , " Editor " ) ; break ;
case AccessDM : _Env . setValue ( " AccessMode " , " DM " ) ; break ;
case AccessOutlandOwner : _Env . setValue ( " AccessMode " , " OutlandOwner " ) ; break ;
default :
nlassert ( 0 ) ;
break ;
}
// Load the UI files
if ( ReloadUIFlag )
{
loadLanguageFile ( ) ;
reloadUI ( ) ;
// setForceDesktopReset is done below
ReloadUIFlag = false ;
}
//
registerDisplayers ( ) ;
registerTools ( ) ;
//
std : : vector < std : : string > emptyArgsList ;
// Calling window init proc
registerLuaFunc ( ) ;
//
_DMC - > init ( getLua ( ) . getStatePointer ( ) ) ;
//
initObjectProjectionMetatable ( ) ; // init system to access to scenary objects from lua
// init client/server stuffs
CConfigVarBase : : getConfigFileTimeStamp ( ) + + ; // invalidate all var taken from the config file
// load r2 features & components
{
CVerboseClock clock ( " Execution of r2_core.lua " ) ;
doLuaScript ( " r2_core.lua " , " r2ed common functions and definitions " ) ;
}
initClassInheritanceTable ( ) ;
//
{
CLuaStackChecker lsc4 ( & getLua ( ) ) ;
setCurrentTool ( NULL ) ; // force the default tool (select / move)
}
initDecals ( ) ;
// TMP nico : unit test for newpoly stuff
//polyUnitTest();
_Initialized = true ;
_LuaUIMainLoop = _Env [ " UIMainLoop " ] ;
if ( _SerializeUIConfig )
{
// load virtual desktops configs
bool configLoaded = false ;
{
CVerboseClock clock ( " Load of ui config from disk " ) ;
// if access mode is DM, then load the whole ui (else it has been previuously loaded)
if ( initialMode = = AnimationModePlay )
{
loadStandardUI ( ) ;
}
else
{
configLoaded = loadUIConfig ( getUIPrefix ( initialMode ) ) ;
}
}
// if not found then reset all virtual desktops (one for each mode of the editor)
if ( ! configLoaded )
{
nlwarning ( " No interface config found, resetting editor windows to their default " ) ;
setForceDesktopReset ( true ) ;
}
}
setMode ( initialMode ) ;
{
CVerboseClock clock ( " Update of localized elements " ) ;
getUI ( ) . updateAllLocalisedElements ( ) ;
}
}
// *********************************************************************************************************
std : : string CEditor : : getUIPrefix ( TMode mode ) const
{
//H_AUTO(R2_CEditor_getUIPrefix)
switch ( mode )
{
case AnimationModePlay :
return " " ;
break ;
default :
return " r2ed_interface_ " ;
break ;
}
}
// *********************************************************************************************************
uint CEditor : : getMaxNumPlotItems ( )
{
//H_AUTO(R2_CEditor_getMaxNumPlotItems)
uint ret ;
fromString ( getUI ( ) . getDefine ( " r2ed_max_num_plot_item_sheets " ) , ret ) ;
return ret ;
}
// *********************************************************************************************************
CCDBNodeLeaf * CEditor : : getRefPlotItemSheetDBLeaf ( uint index )
{
//H_AUTO(R2_CEditor_getRefPlotItemSheetDBLeaf)
return getUI ( ) . getDbProp ( toString ( " LOCAL:R2:REFERENCE_PLOT_ITEMS:%d:SHEET " , ( int ) index ) , false ) ;
}
// *********************************************************************************************************
CCDBNodeLeaf * CEditor : : getPlotItemSheetDBLeaf ( uint index )
{
//H_AUTO(R2_CEditor_getPlotItemSheetDBLeaf)
return getUI ( ) . getDbProp ( toString ( " LOCAL:R2:PLOT_ITEMS:%d:SHEET " , ( int ) index ) , false ) ;
}
// *********************************************************************************************************
void CEditor : : setReferencePlotItemSheet ( uint index , uint32 sheetId )
{
//H_AUTO(R2_CEditor_setReferencePlotItemSheet)
CCDBNodeLeaf * leaf = getRefPlotItemSheetDBLeaf ( index ) ;
if ( leaf )
{
leaf - > setValue32 ( sheetId ) ;
}
leaf = getUI ( ) . getDbProp ( toString ( " LOCAL:R2:AVAILABLE_PLOT_ITEMS:%d:SHEET " , ( int ) index ) , false ) ;
if ( leaf )
{
leaf - > setValue32 ( sheetId ) ;
}
}
// *********************************************************************************************************
void CEditor : : initDummyPlotItems ( )
{
//H_AUTO(R2_CEditor_initDummyPlotItems)
uint maxNumPlotItems = getMaxNumPlotItems ( ) ;
uint numItems = std : : min ( 10u , maxNumPlotItems ) ;
uint k ;
for ( k = 0 ; k < numItems ; + + k )
{
CCDBNodeLeaf * destLeaf = getPlotItemSheetDBLeaf ( k ) ;
if ( ! destLeaf ) continue ;
CCDBNodeLeaf * srcLeaf = getRefPlotItemSheetDBLeaf ( k ) ;
destLeaf - > setValue32 ( srcLeaf ? srcLeaf - > getValue32 ( ) : 0u ) ;
}
for ( ; k < maxNumPlotItems ; + + k )
{
CCDBNodeLeaf * destLeaf = getPlotItemSheetDBLeaf ( k ) ;
if ( ! destLeaf ) continue ;
destLeaf - > setValue32 ( 0 ) ;
}
}
// *********************************************************************************************************
void CEditor : : resetPlotItems ( )
{
//H_AUTO(R2_CEditor_resetPlotItems)
uint maxNumPlotItems = getMaxNumPlotItems ( ) ;
// uint numItems = std::min(10u, maxNumPlotItems);
for ( uint k = 0 ; k < maxNumPlotItems ; + + k )
{
CCDBNodeLeaf * destLeaf = getPlotItemSheetDBLeaf ( k ) ;
if ( ! destLeaf ) continue ;
destLeaf - > setValue32 ( 0 ) ;
}
_PlotItemInfos . clear ( ) ;
}
// *********************************************************************************************************
void CEditor : : initReferencePlotItems ( )
{
//H_AUTO(R2_CEditor_initReferencePlotItems)
{
CVerboseClock clock ( " InitReferencePlotItems " ) ;
uint maxNumPlotItems = getMaxNumPlotItems ( ) ;
clamp ( maxNumPlotItems , 0u , 1024u ) ;
uint currIndex = 0 ;
// look for plot item sheets
const CSheetManager : : TEntitySheetMap & sheets = SheetMngr . getSheets ( ) ;
for ( CSheetManager : : TEntitySheetMap : : const_iterator it = sheets . begin ( ) ; it ! = sheets . end ( ) ; + + it )
{
if ( it - > second . EntitySheet & & it - > second . EntitySheet - > Type = = CEntitySheet : : ITEM )
{
std : : string name = it - > second . EntitySheet - > Id . toString ( ) ;
if ( strstr ( name . c_str ( ) , " r2_plot_item " ) )
{
uint32 sheetId = it - > second . EntitySheet - > Id . asInt ( ) ;
setReferencePlotItemSheet ( currIndex , sheetId ) ;
+ + currIndex ;
}
}
}
for ( ; currIndex < maxNumPlotItems ; + + currIndex )
{
setReferencePlotItemSheet ( currIndex , 0 ) ;
}
resetPlotItems ( ) ;
}
}
// *********************************************************************************************************
bool CEditor : : loadUIConfig ( const std : : string & prefix )
{
//H_AUTO(R2_CEditor_loadUIConfig)
CHECK_EDITOR
return getUI ( ) . loadConfig ( " save/ " + prefix + PlayerSelectedFileName + " .icfg " ) ;
}
// *********************************************************************************************************
void CEditor : : saveUIConfig ( )
{
//H_AUTO(R2_CEditor_saveUIConfig)
CHECK_EDITOR
// if there are dirt desktop, update all of them
if ( _Mode ! = AnimationModePlay )
{
bool restoreMode = false ;
uint8 oldMode = getUI ( ) . getMode ( ) ;
for ( uint k = 0 ; k < 4 ; + + k )
{
if ( _ForceDesktopReset [ k ] )
{
setUIMode ( k ) ;
restoreMode = true ;
_ForceDesktopReset [ k ] = false ;
}
if ( restoreMode )
{
setUIMode ( oldMode ) ;
}
}
}
getUI ( ) . saveConfig ( " save/ " + getUIPrefix ( _Mode ) + PlayerSelectedFileName + " .icfg " ) ;
}
// *********************************************************************************************************
void CEditor : : initDecals ( )
{
//H_AUTO(R2_CEditor_initDecals)
CHECK_EDITOR
// highlight
CLuaObject config = getEnv ( ) [ " Config " ] ;
CLuaObject objHighlight = config [ " HightlightDecalLook " ] ;
CLuaObject objSelect = config [ " SelectDecalLook " ] ;
CLuaObject objSelecting = config [ " SelectingDecalLook " ] ;
CLuaObject objPioneer = config [ " PionneerDecalLook " ] ;
_HighlightDecalAnim . buildFromLuaTable ( objHighlight ) ;
_SelectDecalAnim . buildFromLuaTable ( objSelect ) ;
_SelectingDecalAnim . buildFromLuaTable ( objSelecting ) ;
_PionneerDecalAnim . buildFromLuaTable ( objPioneer ) ;
_HighlightDecal . setClipDownFacing ( true ) ;
_SelectDecal . setClipDownFacing ( true ) ;
_PionneerDecal . setClipDownFacing ( true ) ;
//
CPrimLook boxLook ;
boxLook . init ( getEnv ( ) [ " PrimRender " ] [ " SelectBoxLook " ] ) ;
_SelectBox . setLook ( boxLook ) ;
boxLook . init ( getEnv ( ) [ " PrimRender " ] [ " HighlightBoxLook " ] ) ;
_HighlightBox . setLook ( boxLook ) ;
}
// *********************************************************************************************************
void CEditor : : showPrimRender ( CPrimRender & dest , const NLMISC : : CAABBox & localBox , const NLMISC : : CMatrix & worldMat , const CDecalAnim & refDecalAnim )
{
//H_AUTO(R2_CEditor_showPrimRender)
CHECK_EDITOR
static NLMISC : : CPolygon2D poly2D ;
poly2D . Vertices . resize ( 4 ) ;
CVector pmin = localBox . getMin ( ) ;
CVector pmax = localBox . getMax ( ) ;
poly2D . Vertices [ 0 ] = worldMat * CVector ( pmin . x , pmin . y , pmin . z ) ;
poly2D . Vertices [ 1 ] = worldMat * CVector ( pmax . x , pmin . y , pmin . z ) ;
poly2D . Vertices [ 2 ] = worldMat * CVector ( pmax . x , pmax . y , pmin . z ) ;
poly2D . Vertices [ 3 ] = worldMat * CVector ( pmin . x , pmax . y , pmin . z ) ;
NLMISC : : CAABBox bbox ;
CLandscapePolyDrawer : : computeBBoxFromPolygon ( poly2D , bbox ) ;
dest . setVertices ( poly2D . Vertices ) ;
//dest.setWorldMapPolyColor(polyColor);
float animRatio = refDecalAnim . DurationInMs = = 0 ? 0.f : ( T1 % refDecalAnim . DurationInMs ) / ( float ) refDecalAnim . DurationInMs ;
animRatio = 0.5f * cosf ( 2.f * ( float ) Pi * animRatio ) + 0.5f ;
CRGBA color = blend ( refDecalAnim . StartDiffuse , refDecalAnim . EndDiffuse , animRatio ) ;
CPrimLook pl = dest . getLook ( ) ;
pl . EdgeLook . DecalColor = pl . VertexLook . DecalColor = pl . FirstVertexLook . DecalColor = color ;
dest . setLook ( pl ) ;
dest . addDecalsToRenderList ( ) ;
static volatile bool showPoly = true ;
if ( showPoly )
{
CLandscapePolyDrawer : : getInstance ( ) . addPoly ( poly2D , dest . getLook ( ) . EdgeLook . WorldMapColor , bbox ) ;
}
}
// *********************************************************************************************************
void CEditor : : showSelectBox ( const NLMISC : : CAABBox & localBox , const NLMISC : : CMatrix & worldMat )
{
//H_AUTO(R2_CEditor_showSelectBox)
CHECK_EDITOR
showPrimRender ( _SelectBox , localBox , worldMat , _SelectDecalAnim ) ;
}
// *********************************************************************************************************
void CEditor : : showHighlightBox ( const NLMISC : : CAABBox & localBox , const NLMISC : : CMatrix & worldMat )
{
//H_AUTO(R2_CEditor_showHighlightBox)
CHECK_EDITOR
showPrimRender ( _HighlightBox , localBox , worldMat , _HighlightDecalAnim ) ;
}
// *********************************************************************************************************
void CEditor : : showSelectDecal ( const NLMISC : : CVector & pos , float scale )
{
//H_AUTO(R2_CEditor_showSelectDecal)
CHECK_EDITOR
updateDecalBlendRegion ( _SelectDecal , pos ) ;
showDecal ( pos , scale , _SelectDecal , _SelectDecalAnim ) ;
}
// *********************************************************************************************************
void CEditor : : showHighlightDecal ( const NLMISC : : CVector & pos , float scale )
{
//H_AUTO(R2_CEditor_showHighlightDecal)
CHECK_EDITOR
updateDecalBlendRegion ( _HighlightDecal , pos ) ;
showDecal ( pos , scale , _HighlightDecal , _HighlightDecalAnim ) ;
}
// *********************************************************************************************************
void CEditor : : showDecal ( const NLMISC : : CVector2f & pos , float scale , CDecal & decal , const CDecalAnim & decalAnim )
{
//H_AUTO(R2_CEditor_showDecal)
CHECK_EDITOR
float animRatio = decalAnim . DurationInMs = = 0 ? 0.f : ( ( T1 - _DecalRefTime ) % decalAnim . DurationInMs ) / ( float ) decalAnim . DurationInMs ;
animRatio = 0.5f * cosf ( 2.f * ( float ) Pi * animRatio ) + 0.5f ;
decalAnim . updateDecal ( pos , animRatio , decal , scale ) ;
decal . addToRenderList ( ) ;
}
// *********************************************************************************************************
void CEditor : : addSelectingDecal ( const NLMISC : : CVector & pos , float scale )
{
//H_AUTO(R2_CEditor_addSelectingDecal)
CHECK_EDITOR
CSelectingDecal * decal = NULL ;
// see if there's an unused decal in the list
for ( uint k = 0 ; k < _SelectingDecals . size ( ) ; + + k )
{
if ( _SelectingDecals [ k ] - > EndDate < T1 )
{
decal = _SelectingDecals [ k ] ;
break ;
}
}
if ( decal = = NULL )
{
_SelectingDecals . push_back ( new CSelectingDecal ) ;
decal = _SelectingDecals . back ( ) ;
}
decal - > EndDate = T1 + _SelectingDecalAnim . DurationInMs ;
decal - > Pos = pos ;
decal - > Scale = scale ;
//
updateDecalBlendRegion ( decal - > Decal , pos ) ;
_DecalRefTime = T1 ;
}
// *********************************************************************************************************
void CEditor : : updateSelectingDecals ( )
{
//H_AUTO(R2_CEditor_updateSelectingDecals)
CHECK_EDITOR
if ( _SelectingDecalAnim . DurationInMs = = 0 ) return ;
for ( uint k = 0 ; k < _SelectingDecals . size ( ) ; + + k )
{
CSelectingDecal * decal = _SelectingDecals [ k ] ;
if ( decal )
{
if ( decal - > EndDate > T1 )
{
float animRatio = ( float ) ( T1 - ( decal - > EndDate - _SelectingDecalAnim . DurationInMs ) ) / ( float ) _SelectingDecalAnim . DurationInMs ;
_SelectingDecalAnim . updateDecal ( decal - > Pos , animRatio , decal - > Decal , decal - > Scale ) ;
decal - > Decal . addToRenderList ( ) ;
}
}
}
}
// *******************************************************************************************************
void CEditor : : reset ( )
{
//H_AUTO(R2_CEditor_reset)
2010-05-22 12:15:29 +00:00
if ( ClientCfg . R2EDExtendedDebug )
Driver - > setWindowTitle ( ucstring ( " Resetting R2ED editor ... " ) ) ;
2010-05-06 00:08:41 +00:00
CHECK_EDITOR
_SerializeUIConfig = false ; // prevent reloading of ui for speed
_WantedActOnInit . clear ( ) ;
if ( getCurrentAct ( ) )
{
R2 : : CObjectTable * act = getCurrentAct ( ) - > getObjectTable ( ) ;
if ( act - > isString ( " Name " ) )
{
_WantedActOnInit = act - > toString ( " Name " ) ;
}
else
{
_WantedActOnInit = act - > toString ( " Title " ) ; //obsolete
}
}
CVerboseClock clock ( " Reset of editor " ) ;
TMode oldMode = _Mode ;
TAccessMode oldAccessMode = _AccessMode ;
if ( _Mode = = EditionMode )
{
R2 : : getEditor ( ) . getLua ( ) . executeScriptNoThrow ( " r2.Version.save( \" data/r2_buffer.dat \" ) " ) ;
}
release ( ) ;
clearDebugWindow ( ) ;
if ( ReloadUIFlag )
{
loadLanguageFile ( ) ;
reloadUI ( ) ;
setForceDesktopReset ( true ) ; // next changes of desktop should force a reset, since ui has been reloaded
ReloadUIFlag = false ;
}
init ( oldMode , oldAccessMode ) ;
if ( oldMode = = EditionMode )
{
CVerboseClock clock ( " Request reconnection " ) ;
getLua ( ) . executeScriptNoThrow ( " r2.requestReconnection() " ) ;
}
// try to return to the act with the same title
_SerializeUIConfig = true ;
2010-05-22 12:15:29 +00:00
if ( ClientCfg . R2EDExtendedDebug )
{
Driver - > setWindowTitle ( CI18N : : get ( " TheSagaOfRyzom " ) ) ;
Driver - > showWindow ( ) ;
// TODO: check
// Get the window
// Show the window
// ShowWindow (hWnd, SW_SHOW);
// SetForegroundWindow(hWnd);
}
2010-05-06 00:08:41 +00:00
getUI ( ) . displaySystemInfo ( CI18N : : get ( " uiR2EDEditorReseted " ) , " BC " ) ;
}
// *********************************************************************************************************
void CEditor : : reloadUI ( )
{
//H_AUTO(R2_CEditor_reloadUI)
CHECK_EDITOR
CVerboseClock clock ( " Reload ui " ) ;
// reload same list than at startup (given in client.cfg)
for ( uint k = 0 ; k < ClientCfg . XMLR2EDInterfaceFiles . size ( ) ; + + k )
{
reloadUI ( ClientCfg . XMLR2EDInterfaceFiles [ k ] . c_str ( ) ) ;
}
}
// *********************************************************************************************************
void CEditor : : reloadUI ( const char * filename )
{
//H_AUTO(R2_CEditor_reloadUI)
CHECK_EDITOR
CVerboseClock clock ( " Loading ui " + std : : string ( filename ) ) ;
CLuaStackChecker ls ( & getLua ( ) ) ;
std : : string path = CPath : : lookup ( filename , false ) ;
if ( path . empty ( ) )
{
nlwarning ( " File %s not found, r2 ui not (re)loaded. " , filename ) ;
return ;
}
uint32 fileDate = CFile : : getFileModificationDate ( path ) ;
if ( _LastUIModificationDate . count ( filename ) = = 0 )
{
_LastUIModificationDate [ filename ] = 0 ;
}
uint32 & lastUIModificationDate = _LastUIModificationDate [ filename ] ;
if ( fileDate > lastUIModificationDate | | ! ClientCfg . R2EDDontReparseUnchangedUIFiles ) // TMP (init not complete else ...)
{
// reload the ui files
NLMISC : : ICommand : : execute ( toString ( " loadui %s " , filename ) . c_str ( ) , g_log ) ;
lastUIModificationDate = fileDate ;
}
else
{
if ( ! ClientCfg . R2EDDontReparseUnchangedUIFiles )
{
nlwarning ( " ui file %s date unchanged, not reloading. " , filename ) ;
}
}
}
// *********************************************************************************************************
void CEditor : : connectAsCreator ( )
{
//H_AUTO(R2_CEditor_connectAsCreator)
CHECK_EDITOR
nlassert ( _DMC ) ;
{
CLuaStackChecker lsc2 ( & getLua ( ) ) ;
_DMC - > testConnectionAsCreator ( ) ;
}
}
// string cached into lua for fast comparison
static CLuaString lstr_isNil ( " isNil " ) ;
static CLuaString lstr_Parent ( " Parent " ) ;
static CLuaString lstr_ParentInstance ( " ParentInstance " ) ;
static CLuaString lstr_IndexInParent ( " IndexInParent " ) ;
static CLuaString lstr_User ( " User " ) ;
static CLuaString lstr_Size ( " Size " ) ;
static CLuaString lstr_DisplayerUI ( " DisplayerUI " ) ;
static CLuaString lstr_DisplayerVisual ( " DisplayerVisual " ) ;
static CLuaString lstr_DisplayerProperties ( " DisplayerProperties " ) ;
// *********************************************************************************************************
void CEditor : : initObjectProjectionMetatable ( )
{
//H_AUTO(R2_CEditor_initObjectProjectionMetatable)
CHECK_EDITOR
_ObjectProjectionMetatable = getEnv ( ) . newTable ( " _instance_projection_metatable " ) ;
// projection functions
struct CProjector
{
static bool checkTag ( CLuaState & ls )
{
CLuaStackChecker lsc ( & ls ) ;
ls . getMetaTable ( 1 ) ;
ls . push ( " tag " ) ;
ls . getTable ( - 2 ) ;
bool ok = false ;
if ( ls . isString ( - 1 ) )
{
if ( strcmp ( ls . toString ( - 1 ) , " CObjectTable " ) = = 0 )
{
ok = true ;
}
}
ls . pop ( 2 ) ;
if ( ! ok )
{
nlwarning ( " metatable error : Editor object expected " ) ;
}
return ok ;
}
static int index ( CLuaState & ls )
{
nlassert ( ls . getTop ( ) = = 2 ) ;
# ifdef NL_DEBUG
if ( ! checkTag ( ls ) ) return false ;
# endif
CObjectTable : : TRefPtrConst & obj = * ( CObjectTable : : TRefPtrConst * ) ls . toUserData ( 1 ) ;
if ( OPERATOR_EQUAL ( obj , NULL ) )
//NLMISC::operator==(obj, NULL))
{
std : : string index = ls . toString ( 2 ) ;
// special members
if ( index = = " isNil " )
//if (std::operator==(index "isNil")
{
ls . push ( true ) ;
return 1 ;
}
CLuaIHM : : dumpCallStack ( ) ;
// object has been deleted but the script maintains a reference on it
throw ELuaWrappedFunctionException ( & ls , " Attempt to access an erased object " ) ;
}
if ( ls . isNumber ( 2 ) )
{
// index is a number
const CObject * other = obj - > getValue ( ( uint32 ) ls . toNumber ( 2 ) ) ;
if ( other )
{
pushValue ( ls , other ) ;
return 1 ;
}
else
{
// 'bad index' message already printed by CObject::getValue
CLuaIHM : : dumpCallStack ( ) ;
}
}
if ( ! ls . isString ( 2 ) )
{
nlwarning ( " String expected when accessing an object property, %s found instead " , ls . getTypename ( 2 ) ) ;
CLuaIHM : : dumpCallStack ( 0 ) ;
return 0 ;
}
const char * strId = ls . toString ( 2 ) ; // strings are shared in lua, so a pointer comparison is sufficient
// special members
// NB nico : this was added before the R2::CInstance class derived from CReflectable,
// -> see if some of the following properties may better fit into R2::CInstance exported properties
if ( OPERATOR_EQUAL ( lstr_isNil , strId ) )
{
ls . push ( false ) ;
return 1 ;
}
else
if ( OPERATOR_EQUAL ( strId , lstr_Parent ) )
{
if ( ! obj - > getParent ( ) )
{
ls . pushNil ( ) ;
return 1 ;
}
nlassert ( obj - > getParent ( ) - > isTable ( ) ) ;
getEditor ( ) . projectInLua ( ( CObjectTable * ) obj - > getParent ( ) ) ;
return 1 ;
}
else if ( OPERATOR_EQUAL ( strId , lstr_ParentInstance ) )
{
// look for parent instance (that is, not the
CObject * parent = obj - > getParent ( ) ;
while ( parent )
{
if ( parent - > findAttr ( " InstanceId " ) )
{
getEditor ( ) . projectInLua ( ( CObjectTable * ) parent ) ;
return 1 ;
}
parent = parent - > getParent ( ) ;
}
ls . pushNil ( ) ;
return 1 ;
}
if ( OPERATOR_EQUAL ( strId , lstr_IndexInParent ) )
{
if ( ! obj - > getParent ( ) )
{
ls . pushNil ( ) ;
return 1 ;
}
sint32 index = obj - > getParent ( ) - > findIndex ( obj ) ;
if ( obj - > getParent ( ) - > getKey ( index ) . empty ( ) )
{
ls . push ( ( double ) index ) ;
}
else
{
ls . push ( ( double ) - 1 ) ;
}
return 1 ;
}
else if ( OPERATOR_EQUAL ( strId , lstr_User ) )
{
// push user table on stack
CEditor : : getLuaUserTableFromObject ( ls , * obj ) ;
return 1 ;
}
else if ( OPERATOR_EQUAL ( strId , lstr_Size ) )
{
if ( obj - > isTable ( ) )
{
ls . push ( ( double ) obj - > getSize ( ) ) ;
}
else
{
ls . pushNil ( ) ;
}
return 1 ;
}
else
if ( OPERATOR_EQUAL ( strId , lstr_DisplayerUI ) )
{
CInstance * instance = getEditor ( ) . getInstanceFromObject ( obj ) ;
if ( ! instance )
{
ls . pushNil ( ) ;
return 1 ;
}
else
{
if ( instance - > getDisplayerUI ( ) )
{
instance - > getDisplayerUI ( ) - > pushLuaAccess ( ls ) ;
}
else
{
ls . pushNil ( ) ;
}
return 1 ;
}
}
else
if ( OPERATOR_EQUAL ( strId , lstr_DisplayerVisual ) )
{
CInstance * instance = getEditor ( ) . getInstanceFromObject ( obj ) ;
if ( ! instance )
{
ls . pushNil ( ) ;
return 1 ;
}
else
{
if ( instance - > getDisplayerVisual ( ) )
{
instance - > getDisplayerVisual ( ) - > pushLuaAccess ( ls ) ;
}
else
{
ls . pushNil ( ) ;
}
return 1 ;
}
}
else
if ( OPERATOR_EQUAL ( strId , lstr_DisplayerProperties ) )
{
CInstance * instance = getEditor ( ) . getInstanceFromObject ( obj ) ;
if ( ! instance )
{
ls . pushNil ( ) ;
return 1 ;
}
else
{
if ( instance - > getDisplayerProperties ( ) )
{
instance - > getDisplayerProperties ( ) - > pushLuaAccess ( ls ) ;
}
else
{
ls . pushNil ( ) ;
}
return 1 ;
}
}
// else tries with a string
std : : string index = ls . toString ( 2 ) ;
const CObject * other = getObject ( obj , index ) ;
if ( other )
{
pushValue ( ls , other ) ;
return 1 ;
}
// this is not an attribute of the class
// -> maybe this is a method ?
// look in the parent class is there is a function with the wanted name
// NOTE : calling a method on an editor object in the script can be done by doing
// r2:getClass(instance).methodName(instance, parameters ...)
// with this trick, one can do instance:methodName(parameters ...)
CObject * className = obj - > findAttr ( " Class " ) ;
if ( className )
{
CLuaObject method = getEditor ( ) . getClasses ( ) [ className - > toString ( ) ] [ index ] ;
if ( method . isFunction ( ) )
{
method . push ( ) ;
return 1 ;
}
}
// Try with a property exported from CInstance
// Is is ok to test thos properties after those defined in lua classes definition
// because the init check that no "native" property is declared by the user
CInstance * instance = getEditor ( ) . getInstanceFromObject ( obj ) ;
if ( instance )
{
const CReflectedProperty * prop = instance - > getReflectedProperty ( index , false ) ;
if ( prop )
{
CLuaIHM : : luaValueFromReflectedProperty ( ls , * instance , * prop ) ;
return 1 ;
}
}
// unknown attribute
ls . pushNil ( ) ;
return 1 ;
}
static int newIndex ( CLuaState & ls )
{
nlassert ( ls . getTop ( ) = = 3 ) ;
# ifdef NL_DEBUG
if ( ! checkTag ( ls ) ) return false ;
# endif
CObjectTable : : TRefPtrConst & obj = * ( CObjectTable : : TRefPtrConst * ) ls . toUserData ( 1 ) ;
if ( obj = = NULL )
{
throw ELuaWrappedFunctionException ( & ls , " Trying to set a property in an erased object, returning nil " ) ;
}
# ifdef NL_DEBUG
if ( ! checkTag ( ls ) ) return false ;
# endif
// try with a native (local ..) property exported from CInstance
CInstance * instance = getEditor ( ) . getInstanceFromObject ( obj ) ;
if ( instance )
{
const CReflectedProperty * prop = instance - > getReflectedProperty ( ls . toString ( 2 ) ) ;
if ( prop )
{
CLuaIHM : : luaValueToReflectedProperty ( ls , 3 , * instance , * prop ) ;
return 1 ;
}
}
// other instances properties are read only !!
throw ELuaWrappedFunctionException ( & ls , " Property %s of editor object is read-only. You must use 'r2.requestSetNode' function to change it " , ls . toString ( 2 ) ) ;
}
static int gc ( CLuaState & ls )
{
# ifdef NL_DEBUG
if ( ! checkTag ( ls ) ) return false ;
# endif
// TODO : maybe not useful ...
CObjectTable : : TRefPtrConst & obj = * ( CObjectTable : : TRefPtrConst * ) ls . toUserData ( 1 ) ;
typedef CObjectTable : : TRefPtrConst TRefPtrConst ;
obj . ~ TRefPtrConst ( ) ;
return 0 ;
}
// tool function used by 'next'
// TODO : put this code in a better place ...
static void pushValue ( CLuaState & ls , const CObject * obj )
{
if ( ! obj )
{
ls . pushNil ( ) ;
return ;
}
if ( obj - > isString ( ) )
{
ls . push ( obj - > toString ( ) ) ;
}
else if ( obj - > isNumber ( ) )
{
ls . push ( obj - > toNumber ( ) ) ;
}
else if ( obj - > isTable ( ) )
{
getEditor ( ) . projectInLua ( ( CObjectTable * ) obj ) ;
}
else
{
nlassert ( 0 ) ; // type not supported ...
}
}
// helper function used by 'next' : push a key
static void pushKey ( CLuaState & ls , const CObject * obj , sint32 index )
{
if ( ! obj )
{
ls . pushNil ( ) ;
return ;
}
if ( obj - > getKey ( index ) . empty ( ) )
{
ls . push ( ( double ) index ) ;
}
else
{
ls . push ( obj - > getKey ( index ) ) ;
}
}
// special : we redefine the 'next' global function found in the standard
// lua library in order to allow fields traversal for the projected object.
// This is done in lua in the 'r2_core.lua' script
// The new 'next' function will look into the object metatable
// If a __next function is found, then it will be called for traversal
// otherwise, the standard 'next' function is called instead.
// This allow to have a traversal for objects that are not tables
static int next ( CLuaState & ls )
{
if ( ls . getTop ( ) ! = 2 )
{
CLuaIHM : : fails ( ls , " __next metamethod require 2 arguments (table & key) " ) ;
}
# ifdef NL_DEBUG
if ( ! checkTag ( ls ) ) return false ;
# endif
CObjectTable : : TRefPtrConst & obj = * ( CObjectTable : : TRefPtrConst * ) ls . toUserData ( 1 ) ;
if ( obj = = NULL )
{
throw ELuaWrappedFunctionException ( & ls , " editor object '__next' metatmethod : Attempt to access an erased object " ) ;
}
if ( ls . isNil ( 2 ) )
{
// key is nil -> start of traversal
if ( obj - > getSize ( ) = = 0 )
{
ls . remove ( - 2 ) ;
ls . pushNil ( ) ;
return 2 ; // let (nil, nil) on the stack
}
else
{
// look for duplicated keys (ignoring empty keys, because in this case th index is the key)
std : : set < std : : string > keys ;
for ( uint k = 0 ; k < obj - > getSize ( ) ; + + k )
{
std : : string key = obj - > getKey ( ( sint32 ) k ) ;
if ( ! key . empty ( ) )
{
if ( keys . count ( key ) )
{
nlwarning ( " Duplicated key of type string found while attempting to enumerate an instance content. " ) ;
nlwarning ( " key is %s " , key . c_str ( ) ) ;
CLuaIHM : : dumpCallStack ( 1 ) ;
CLuaIHM : : fails ( ls , " Aborting to avoid infinite loop. " ) ;
}
keys . insert ( key ) ;
}
}
ls . pop ( 2 ) ;
pushKey ( ls , obj , 0 ) ;
pushValue ( ls , obj - > getValue ( 0 ) ) ;
return 2 ;
}
}
else
{
// continuation of traversal
// -> retrieve index from the key
sint32 index ;
if ( ls . isNumber ( 2 ) )
{
index = ( uint32 ) ls . toNumber ( 2 ) ;
}
else
{
if ( ! ls . isString ( 2 ) )
{
nlwarning ( " __next metamethod : string expected " ) ;
ls . pop ( ) ;
ls . pushNil ( ) ;
return 2 ;
}
else
{
index = obj - > findIndex ( ls . toString ( 2 ) ) ;
}
}
if ( index = = - 1 )
{
nlwarning ( " __next metamethod : key not found " ) ;
ls . pop ( 2 ) ;
ls . pushNil ( ) ;
ls . pushNil ( ) ;
return 2 ;
}
// retrieve next key
sint32 newIndex = ( uint32 ) ( index + 1 ) ;
if ( newIndex = = ( sint32 ) obj - > getSize ( ) )
{
// this was the last element, returns nil
ls . pop ( 2 ) ;
ls . pushNil ( ) ;
ls . pushNil ( ) ;
return 2 ;
}
else
{
ls . pop ( 2 ) ;
pushKey ( ls , obj , newIndex ) ;
pushValue ( ls , obj - > getValue ( newIndex ) ) ;
return 2 ;
}
}
return 0 ;
}
static int equal ( CLuaState & ls )
{
// TMP TMP TMP
static volatile bool from = false ;
if ( from )
{
CLuaIHM : : dumpCallStack ( 0 ) ;
}
nlassert ( ls . getTop ( ) = = 2 ) ;
if ( ! checkTag ( ls ) ) return false ;
CObjectTable : : TRefPtrConst & lhs = * ( CObjectTable : : TRefPtrConst * ) ls . toUserData ( 1 ) ;
CObjectTable : : TRefPtrConst & rhs = * ( CObjectTable : : TRefPtrConst * ) ls . toUserData ( 2 ) ;
ls . push ( OPERATOR_EQUAL ( lhs , rhs ) ) ;
return 1 ;
}
} ;
// affect functions to the metatable
getLua ( ) . push ( CProjector : : index ) ;
_ObjectProjectionMetatable . setValue ( " __index " , CLuaObject ( getLua ( ) ) ) ;
getLua ( ) . push ( CProjector : : newIndex ) ;
_ObjectProjectionMetatable . setValue ( " __newindex " , CLuaObject ( getLua ( ) ) ) ;
getLua ( ) . push ( CProjector : : gc ) ;
_ObjectProjectionMetatable . setValue ( " __gc " , CLuaObject ( getLua ( ) ) ) ;
getLua ( ) . push ( CProjector : : next ) ;
_ObjectProjectionMetatable . setValue ( " __next " , CLuaObject ( getLua ( ) ) ) ;
getLua ( ) . push ( CProjector : : equal ) ;
_ObjectProjectionMetatable . setValue ( " __eq " , CLuaObject ( getLua ( ) ) ) ;
// tag to mark that the user data is a CObjectTable ref ptr
_ObjectProjectionMetatable . setValue ( " tag " , std : : string ( " CObjectTable " ) ) ;
}
// *********************************************************************************************************
void CEditor : : getLuaUserTableFromObject ( CLuaState & ls , const CObjectTable & table )
{
//H_AUTO(R2_CEditor_getLuaUserTableFromObject)
CHECK_EDITOR
CLuaStackChecker lsc ( & ls , 1 ) ;
// read write environement accessible from lua
ls . pushLightUserData ( ( void * ) & table ) ;
ls . getTable ( LUA_REGISTRYINDEX ) ;
if ( ls . isNil ( ) )
{
ls . pop ( ) ;
// no user table created yet ?... create it
ls . pushLightUserData ( ( void * ) & table ) ;
ls . newTable ( ) ;
ls . pushValue ( - 1 ) ; // saves the table
ls . insert ( - 3 ) ;
ls . setTable ( LUA_REGISTRYINDEX ) ;
// table remains on the stack
}
}
// *********************************************************************************************************
void CEditor : : setCurrentAct ( CInstance * act )
{
//H_AUTO(R2_CEditor_setCurrentAct)
CHECK_EDITOR
if ( ! _ScenarioInstance ) return ;
if ( _ClearingContent ) return ;
bool currentActSelected = _SelectedInstance & & ( _SelectedInstance = = _CurrentAct ) ;
CInstance * previousAct = _CurrentAct ;
_CurrentAct = act ? act : getBaseAct ( ) ;
//
struct CPreActChangedVisitor : public IInstanceVisitor
{
virtual void visit ( CInstance & inst )
{
inst . onPreActChanged ( ) ;
}
} ;
CPreActChangedVisitor preActChangedVisitor ;
_ScenarioInstance - > visit ( preActChangedVisitor ) ;
struct CActChangedVisitor : public IInstanceVisitor
{
virtual void visit ( CInstance & inst )
{
inst . onActChanged ( ) ;
}
} ;
CActChangedVisitor actChangedVisitor ;
_ScenarioInstance - > visit ( actChangedVisitor ) ;
//TP if necesary
// warn lua that current act has changed
if ( ! previousAct )
{
getLua ( ) . pushNil ( ) ;
}
else
{
previousAct - > getLuaProjection ( ) . push ( ) ;
}
if ( ! _CurrentAct )
{
getLua ( ) . pushNil ( ) ;
}
else
{
_CurrentAct - > getLuaProjection ( ) . push ( ) ;
}
callEnvMethod ( " onActChanged " , 2 , 0 ) ;
setSelectedInstance ( currentActSelected ? _CurrentAct : NULL ) ;
setCurrentTool ( NULL ) ;
}
// *********************************************************************************************************
void CEditor : : setCurrentActFromTitle ( const std : : string & wantedTitle )
{
//H_AUTO(R2_CEditor_setCurrentActFromTitle)
CHECK_EDITOR
if ( ! _Scenario )
{
nlwarning ( " Scenario initialisation failed, can't set current act " ) ;
return ;
}
CObject * actTable = _Scenario - > getAttr ( " Acts " ) ;
if ( actTable - > isTable ( ) )
{
for ( uint k = 0 ; k < actTable - > getSize ( ) ; + + k )
{
R2 : : CObject * act = actTable - > getValue ( k ) ;
nlassert ( act ) ;
std : : string actTitle ;
if ( act - > isString ( " Name " ) )
{
actTitle = act - > toString ( " Name " ) ;
}
else
{
actTitle = act - > toString ( " Title " ) ; //obsolete
}
if ( actTitle = = wantedTitle )
{
setCurrentAct ( getInstanceFromObject ( act ) ) ;
break ;
}
}
}
else
{
nlwarning ( " 'Acts' field in scenario should be a table " ) ;
}
}
// *********************************************************************************************************
void CEditor : : projectInLua ( const CObjectTable * table )
{
//H_AUTO(R2_CEditor_projectInLua)
CHECK_EDITOR
nlassert ( table ) ;
const CObjectTableClient * otc = NLMISC : : safe_cast < const CObjectTableClient * > ( table ) ;
otc - > pushOnLuaStack ( getLua ( ) , _ObjectProjectionMetatable ) ;
}
// *********************************************************************************************************
void CEditor : : backupRequestCommands ( )
{
//H_AUTO(R2_CEditor_backupRequestCommands)
nlassert ( ! _OldLuaRequestInsertNode . isValid ( ) ) ; // restoreRequestCommands not called ?
nlassert ( ! _OldLuaRequestInsertGhostNode . isValid ( ) ) ;
nlassert ( ! _OldLuaRequestSetNode . isValid ( ) ) ;
nlassert ( ! _OldLuaRequestEraseNode . isValid ( ) ) ;
nlassert ( ! _OldLuaRequestMoveNode . isValid ( ) ) ;
_OldLuaRequestInsertNode = getEnv ( ) [ " requestInsertNode " ] ;
_OldLuaRequestInsertGhostNode = getEnv ( ) [ " requestInsertGhostNode " ] ;
_OldLuaRequestSetNode = getEnv ( ) [ " requestSetNode " ] ;
_OldLuaRequestEraseNode = getEnv ( ) [ " requestEraseNode " ] ;
_OldLuaRequestMoveNode = getEnv ( ) [ " requestMoveNode " ] ;
struct CIgnoreRequestCall
{
static int requestSomething ( CLuaState & )
{
nlwarning ( " PAS BIEN C MAL !!! " ) ;
/*
CLuaIHM : : debugInfo ( " Can't call a 'r2.request' command while object are erased in displayers, or are just being created (in this case, use onPostCreate instead) ! " ) ;
CLuaIHM : : debugInfo ( " Callstack is : " ) ;
CLuaIHM : : dumpCallStack ( 1 ) ; */
return 0 ;
}
} ;
// While we delete the object tree, displayers will be triggered
// Make sure that they don't call any r2.requestSomething commands, end if so,
// print an error message
getEnv ( ) . setValue ( " requestInsertNode " , CIgnoreRequestCall : : requestSomething ) ;
getEnv ( ) . setValue ( " requestInsertGhostNode " , CIgnoreRequestCall : : requestSomething ) ;
getEnv ( ) . setValue ( " requestSetNode " , CIgnoreRequestCall : : requestSomething ) ;
getEnv ( ) . setValue ( " requestEraseNode " , CIgnoreRequestCall : : requestSomething ) ;
getEnv ( ) . setValue ( " requestMoveNode " , CIgnoreRequestCall : : requestSomething ) ;
}
// *********************************************************************************************************
void CEditor : : restoreRequestCommands ( )
{
//H_AUTO(R2_CEditor_restoreRequestCommands)
nlassert ( _OldLuaRequestInsertNode . isValid ( ) ) ; // backupRequestCommands not called ?
nlassert ( _OldLuaRequestInsertGhostNode . isValid ( ) ) ;
nlassert ( _OldLuaRequestSetNode . isValid ( ) ) ;
nlassert ( _OldLuaRequestEraseNode . isValid ( ) ) ;
nlassert ( _OldLuaRequestMoveNode . isValid ( ) ) ;
// restore old functions
getEnv ( ) . setValue ( " requestInsertNode " , _OldLuaRequestInsertNode ) ;
getEnv ( ) . setValue ( " requestInsertGhostNode " , _OldLuaRequestInsertGhostNode ) ;
getEnv ( ) . setValue ( " requestSetNode " , _OldLuaRequestSetNode ) ;
getEnv ( ) . setValue ( " requestEraseNode " , _OldLuaRequestEraseNode ) ;
getEnv ( ) . setValue ( " requestMoveNode " , _OldLuaRequestMoveNode ) ;
//
_OldLuaRequestInsertNode . release ( ) ;
_OldLuaRequestInsertGhostNode . release ( ) ;
_OldLuaRequestSetNode . release ( ) ;
_OldLuaRequestEraseNode . release ( ) ;
_OldLuaRequestMoveNode . release ( ) ;
}
// *********************************************************************************************************
void CEditor : : clearContent ( )
{
nlwarning ( " *R2* clear content " ) ;
setMaxVisibleEntityExceededFlag ( false ) ;
//H_AUTO(R2_CEditor_clearContent)
if ( _Mode ! = EditionMode & & _Mode ! = AnimationModeLoading ) return ;
_ClearingContent = true ;
CHECK_EDITOR
setSelectedInstance ( NULL ) ;
setFocusedInstance ( NULL ) ;
// backup all "requestCommand"
if ( _CurrentTool ) _CurrentTool - > cancel ( ) ;
CTool : : releaseMouse ( ) ;
delete _NewScenario ; // will be not NULL only if quit is called during the scenario connection screen
_NewScenario = NULL ;
eraseScenario ( ) ;
_InstancesByDispName . clear ( ) ;
_InstancesByDispName . resize ( _ClassNameToIndex . size ( ) ) ;
_InstanceObservers . clear ( ) ;
_InstanceObserverHandles . clear ( ) ;
_Cookies . clear ( ) ;
_LocalGeneratedNames . clear ( ) ;
_Instances . clear ( ) ;
_BaseAct = NULL ;
_CurrentAct = NULL ;
_SelectedInstance = NULL ;
_FocusedInstance = NULL ;
_ScenarioInstance = NULL ;
_Scenario = NULL ;
_SelectingDecals . clear ( ) ;
_InstanceObservers . clear ( ) ;
_InstanceObserverHandles . clear ( ) ;
_LastInstanceUnderPos = NULL ;
_CurrentTool = NULL ;
removeAllEntitySlots ( ) ; // for safety...
_DMC - > CDynamicMapClient : : scenarioUpdated ( NULL , false , 1 ) ; // clear scenario for real
_ClearingContent = false ;
_PlotItemInfos . clear ( ) ;
PeopleInterraction . removeAllFreeTellers ( ) ;
}
// *********************************************************************************************************
void CEditor : : setPlotItemInfos ( const TMissionItem & infos )
{
//H_AUTO(R2_CEditor_setPlotItemInfos)
_PlotItemInfos [ infos . SheetId . asInt ( ) ] = infos ;
}
// *********************************************************************************************************
const TMissionItem * CEditor : : getPlotItemInfos ( uint32 sheetId ) const
{
//H_AUTO(R2_CEditor_getPlotItemInfos)
std : : map < uint32 , TMissionItem > : : const_iterator it = _PlotItemInfos . find ( sheetId ) ;
if ( it = = _PlotItemInfos . end ( ) ) return NULL ;
return & it - > second ;
}
// *********************************************************************************************************
void CEditor : : release ( )
{
nlwarning ( " *R2* release " ) ;
//H_AUTO(R2_CEditor_release)
GameContextMenu . init ( " " ) ;
setFixedLighting ( false ) ;
CHECK_EDITOR
if ( _Mode = = NotInitialized )
{
// nothing more to do there
return ;
}
// warn lua of final release
callEnvMethod ( " onFinalRelease " , 0 , 0 ) ;
if ( _SerializeUIConfig )
{
// serialization disabled when resetting the editor (for speed)
saveCurrentKeySet ( ) ;
saveUIConfig ( ) ;
}
getUI ( ) . hideAllWindows ( ) ; // make sure all action handlers are called while the r2 lua environment is still active
clearContent ( ) ;
_EntityCustomSelectBoxMap . clear ( ) ;
// must do this after clearContent, which sets the default tool
if ( _CurrentTool )
{
_CurrentTool - > cancel ( ) ;
_CurrentTool = NULL ;
}
// clear the environment
if ( getUI ( ) . getLuaState ( ) )
{
getLua ( ) . push ( R2_LUA_PATH ) ;
getLua ( ) . pushNil ( ) ;
getLua ( ) . setTable ( LUA_GLOBALSINDEX ) ;
_Globals . release ( ) ;
_Registry . release ( ) ;
_ObjectProjectionMetatable . release ( ) ; // AJM
_Env . release ( ) ;
_Config . release ( ) ;
CEditorCheck : : EditorCreated = false ;
// force a garbage collection to free the mem for real
getLua ( ) . setGCThreshold ( 0 ) ;
}
// stop at login
if ( _DMC )
{
_DMC - > release ( ) ;
}
//
nlassert ( CDisplayerBase : : ObjCount = = 0 ) ;
_Initialized = false ;
CEditorCheck : : EditorCreated = false ; // AJM
_Mode = NotInitialized ;
_AccessMode = AccessModeUnknown ;
: : IgnoreEntityDbUpdates = false ;
//
_IslandCollision . release ( ) ;
//
_LastUIModificationDate . clear ( ) ;
_InstancesByDispName . clear ( ) ;
//
delete _EntitySorter ;
_EntitySorter = NULL ;
}
// *********************************************************************************************************
void CEditor : : removeAllEntitySlots ( )
{
//H_AUTO(R2_CEditor_removeAllEntitySlots)
CHECK_EDITOR
for ( uint k = 1 ; k < 255 ; + + k )
{
if ( EntitiesMngr . entity ( k ) ! = NULL )
{
EntitiesMngr . remove ( k , false ) ;
}
}
}
// *********************************************************************************************************
void CEditor : : registerDisplayers ( )
{
//H_AUTO(R2_CEditor_registerDisplayers)
CHECK_EDITOR
static bool registered = false ;
if ( registered ) return ;
NLMISC_REGISTER_CLASS ( R2 : : CDisplayerVisualActivitySequence ) ;
NLMISC_REGISTER_CLASS ( R2 : : CDisplayerVisualEntity ) ;
NLMISC_REGISTER_CLASS ( R2 : : CDisplayerVisualGroup )
NLMISC_REGISTER_CLASS ( R2 : : CDisplayerVisualShape )
NLMISC_REGISTER_CLASS ( R2 : : CDisplayerLua )
registered = true ;
}
// *********************************************************************************************************
void CEditor : : registerTools ( )
{
//H_AUTO(R2_CEditor_registerTools)
CHECK_EDITOR
static bool registered = false ;
if ( registered ) return ;
NLMISC_REGISTER_CLASS ( R2 : : CToolDrawPrim ) ;
NLMISC_REGISTER_CLASS ( R2 : : CToolSelectMove ) ;
NLMISC_REGISTER_CLASS ( R2 : : CToolSelectRotate ) ;
NLMISC_REGISTER_CLASS ( R2 : : CToolNewVertex ) ;
registered = true ;
}
// *********************************************************************************************************
void CEditor : : setSelectedInstance ( CInstance * inst )
{
//H_AUTO(R2_CEditor_setSelectedInstance)
CHECK_EDITOR
if ( inst = = _SelectedInstance ) return ;
forceSetSelectedInstance ( inst ) ;
}
// *********************************************************************************************************
void CEditor : : forceSetSelectedInstance ( CInstance * inst )
{
//H_AUTO(R2_CEditor_forceSetSelectedInstance)
CHECK_EDITOR
if ( _EnteredInSetSelectedInstance ) return ; // prevent recursive call (may happen because selection highlight an item in a menu, which trigger selection in turn)
if ( inst )
{
nlassert ( inst - > getSelectableFromRoot ( ) ) ;
}
_EnteredInSetSelectedInstance = true ;
if ( inst )
{
nlassert ( hasInstance ( inst ) ) ; // must have been added in the editor !
}
if ( _SelectedInstance )
{
_SelectedInstance - > onSelect ( false ) ;
}
_SelectedInstance = inst ;
if ( _SelectedInstance )
{
_SelectedInstance - > onSelect ( true ) ;
}
// call r2 method 'onSelectInstance'
if ( ! _SelectedInstance )
{
getLua ( ) . pushNil ( ) ;
}
else
{
_SelectedInstance - > getLuaProjection ( ) . push ( ) ;
}
callEnvMethod ( " onSelectInstance " , 1 , 0 ) ;
_EnteredInSetSelectedInstance = false ;
}
// *********************************************************************************************************
CInstance * CEditor : : getSelectedInstance ( ) const
{
//H_AUTO(R2_CEditor_getSelectedInstance)
CHECK_EDITOR
return _SelectedInstance ;
}
// *********************************************************************************************************
void CEditor : : setFocusedInstance ( CInstance * inst )
{
//H_AUTO(R2_CEditor_setFocusedInstance)
CHECK_EDITOR
if ( inst = = _FocusedInstance ) return ;
if ( inst )
{
nlassert ( hasInstance ( inst ) ) ; // must have been added in the editor !
}
if ( _FocusedInstance )
{
_FocusedInstance - > onFocus ( false ) ;
}
_FocusedInstance = inst ;
if ( _FocusedInstance )
{
_FocusedInstance - > onFocus ( true ) ;
}
}
// *********************************************************************************************************
CInstance * CEditor : : getFocusedInstance ( ) const
{
//H_AUTO(R2_CEditor_getFocusedInstance)
CHECK_EDITOR
return _FocusedInstance ;
}
// *********************************************************************************************************
bool CEditor : : hasInstance ( const CInstance * instance ) const
{
//H_AUTO(R2_CEditor_hasInstance)
CHECK_EDITOR
// TMP : slow test for debug
for ( TInstanceMap : : const_iterator it = _Instances . begin ( ) ; it ! = _Instances . end ( ) ; + + it )
{
if ( it - > second = = instance ) return true ;
}
return false ;
}
// *********************************************************************************************************
bool CEditor : : hasInstanceWithId ( const TInstanceId & id ) const
{
//H_AUTO(R2_CEditor_hasInstanceWithId)
CHECK_EDITOR
return getInstanceFromId ( id ) ! = NULL ;
}
// *********************************************************************************************************
CInstance * CEditor : : getInstanceFromId ( const TInstanceId & id ) const
{
//H_AUTO(R2_CEditor_getInstanceFromId)
CHECK_EDITOR
const CObjectTable * objTable = getObjectTableFromId ( id ) ;
if ( ! objTable ) return NULL ;
return getInstanceFromObject ( objTable ) ;
}
// *********************************************************************************************************
sint CEditor : : getGeneratedNameIndex ( const std : : string & nameUtf8 , const std : : string & baseNameUtf8 )
{
//H_AUTO(R2_CEditor_getGeneratedNameIndex)
CHECK_EDITOR
if ( nameUtf8 . size ( ) > = baseNameUtf8 . size ( ) + 2 )
{
if ( nameUtf8 . substr ( 0 , baseNameUtf8 . size ( ) ) = = baseNameUtf8 )
{
std : : string : : const_iterator strIt = nameUtf8 . begin ( ) + baseNameUtf8 . size ( ) ;
std : : string : : const_iterator endStrIt = nameUtf8 . end ( ) ;
if ( * strIt = = ' ' )
{
+ + strIt ;
const char * numberStart = & * strIt ;
for ( ; strIt ! = endStrIt & & isdigit ( * strIt ) ; + + strIt ) { }
if ( strIt = = endStrIt )
{
sint ret ;
fromString ( numberStart , ret ) ;
return ret ;
}
}
}
}
return - 1 ;
}
// *********************************************************************************************************
bool CEditor : : isPostFixedByNumber ( const ucstring & baseName )
{
//H_AUTO(R2_CEditor_isPostFixedByNumber)
// strip number & spaces at the end of the name
2010-05-13 20:45:24 +00:00
sint lastIndex = ( sint ) baseName . length ( ) - 1 ;
2010-05-06 00:08:41 +00:00
while ( lastIndex > 0 )
{
int currChar = ( int ) baseName [ lastIndex ] ;
if ( ! isdigit ( currChar ) & &
currChar ! = ' ' & &
currChar ! = ' \t ' )
{
break ;
}
- - lastIndex ;
}
return lastIndex ! = ( sint ) baseName . length ( ) - 1 ;
}
// *********************************************************************************************************
ucstring CEditor : : genInstanceName ( const ucstring & baseName )
{
//H_AUTO(R2_CEditor_genInstanceName)
CHECK_EDITOR
uint maxIndex = 0 ;
// strip number & spaces at the end of the name
ucstring strippedName = baseName ;
2010-05-13 20:45:24 +00:00
sint lastIndex = ( sint ) strippedName . length ( ) - 1 ;
2010-05-06 00:08:41 +00:00
while ( lastIndex > 0 )
{
int currChar = ( int ) strippedName [ lastIndex ] ;
if ( ! isdigit ( currChar ) & &
currChar ! = ' ' & &
currChar ! = ' \t ' )
{
break ;
}
- - lastIndex ;
}
strippedName = strippedName . substr ( 0 , lastIndex + 1 ) ;
std : : string baseNameUtf8 = strippedName . toUtf8 ( ) ;
//
for ( TInstanceMap : : const_iterator it = _Instances . begin ( ) ; it ! = _Instances . end ( ) ; + + it )
{
maxIndex = ( uint ) std : : max ( ( sint ) maxIndex , getGeneratedNameIndex ( it - > second - > getName ( ) , baseNameUtf8 ) ) ;
}
nlinfo ( " CEditor::genInstanceName newVersion " ) ;
// Old part : used when there was a delay between net command and effect
// did not work in some parts if genInstance is not followed by creation of an instance with that name
// cf RT 11560
/*
// now, look in local generated names (instance that have not been already added to the scene)
TGeneratedNameMap : : iterator nameSetIt = _LocalGeneratedNames . find ( baseNameUtf8 ) ;
if ( nameSetIt ! = _LocalGeneratedNames . end ( ) )
{
if ( ! nameSetIt - > second . empty ( ) )
{
maxIndex = std : : max ( maxIndex , * ( nameSetIt - > second . rbegin ( ) ) ) ; // take bigger element of the set (the last element)
}
}
// add max index in the map (will be removed when object is truly created)
_LocalGeneratedNames [ baseNameUtf8 ] . insert ( maxIndex + 1 ) ;
*/
return strippedName + " " + toString ( maxIndex + 1 ) ;
}
// *********************************************************************************************************
void CEditor : : setCookie ( const TInstanceId & instanceId , const std : : string & key , CLuaObject & value )
{
//H_AUTO(R2_CEditor_setCookie)
CHECK_EDITOR
TCookieList & cl = _Cookies [ instanceId ] ;
cl . push_front ( CCookie ( ) ) ;
CCookie & cookie = cl . front ( ) ; // don't build struct and push to avoid costly copy of a CLuaObject
cookie . Key = key ;
cookie . Value = value ;
}
// *********************************************************************************************************
void CEditor : : setCookie ( const TInstanceId & instanceId , const std : : string & key , bool value )
{
//H_AUTO(R2_CEditor_setCookie)
CHECK_EDITOR
getLua ( ) . push ( value ) ;
CLuaObject obj ( getLua ( ) ) ;
setCookie ( instanceId , key , obj ) ;
}
// *********************************************************************************************************
void CEditor : : setCurrentTool ( CTool * tool )
{
//H_AUTO(R2_CEditor_setCurrentTool)
CHECK_EDITOR
if ( _CurrentTool )
{
_CurrentTool - > cancel ( ) ;
}
else
{
if ( tool )
{
// setting a tool in non R2 mode force to change the contextual cursor
ContextCur . release ( ) ;
ContextCur . add ( false , " STAND BY " , DEFAULT_CURSOR , 0.0f , CEditor : : checkCursor , CEditor : : mouseClick ) ;
ContextCur . context ( " STAND BY " ) ;
}
}
CTool : : setContextHelp ( ucstring ( " " ) ) ;
if ( tool = = NULL )
{
if ( _Mode = = EditionMode )
{
_CurrentTool = new CToolSelectMove ;
}
else
{
_CurrentTool = NULL ;
ContextCur . release ( ) ;
: : initContextualCursor ( ) ;
ContextCur . context ( " STAND BY " ) ;
CTool : : setMouseCursor ( DEFAULT_CURSOR ) ;
}
}
else
{
_CurrentTool = tool ;
}
if ( _CurrentTool )
{
_CurrentTool - > onActivate ( ) ;
}
{
CLuaStackChecker lsc ( & getLua ( ) ) ;
// activate tool in the ui
getLua ( ) . push ( _CurrentTool ? _CurrentTool - > getToolUIName ( ) : " " ) ;
getEnv ( ) [ " ToolUI " ] . callMethodByNameNoThrow ( " setActiveToolUIByName " , 1 , 0 ) ;
}
}
// *********************************************************************************************************
CLuaObject CEditor : : getClasses ( ) throw ( ELuaError )
{
//H_AUTO(R2_getClasses_throw)
CHECK_EDITOR
return getEnv ( ) . at ( " Classes " ) ;
}
// *********************************************************************************************************
bool CEditor : : callEnvFunc ( const char * funcName , int numArgs , int numRet /*=0*/ )
{
//H_AUTO(R2_CEditor_callEnvFunc)
CHECK_EDITOR
static volatile bool dumpStackWanted = false ;
if ( dumpStackWanted ) getLua ( ) . dumpStack ( ) ;
nlassert ( funcName ) ;
nlassert ( getLua ( ) . getTop ( ) > = numArgs ) ;
int initialStackSize = getLua ( ) . getTop ( ) ;
getEnv ( ) . push ( ) ;
if ( dumpStackWanted ) getLua ( ) . dumpStack ( ) ;
getLua ( ) . insert ( - 1 - numArgs ) ; // put the table before the args
if ( dumpStackWanted ) getLua ( ) . dumpStack ( ) ;
int result = getLua ( ) . pcallByName ( funcName , numArgs , numRet , - 1 - numArgs ) ;
if ( dumpStackWanted ) getLua ( ) . dumpStack ( ) ;
if ( result ! = 0 )
{
nlwarning ( " Error while calling function %s : %s " , funcName , getLua ( ) . toString ( ) ) ;
getLua ( ) . setTop ( initialStackSize - numArgs + numRet ) ; // clean the stack
return false ;
}
// remove the R2 table from the stack
int newSize = getLua ( ) . getTop ( ) ;
if ( dumpStackWanted ) getLua ( ) . dumpStack ( ) ;
nlassert ( newSize = = initialStackSize + 1 - numArgs + numRet ) ; // -1 is because of the r2 table
if ( dumpStackWanted ) getLua ( ) . dumpStack ( ) ;
getLua ( ) . remove ( - numRet - 1 ) ; // remove the 'R2' table
if ( dumpStackWanted ) getLua ( ) . dumpStack ( ) ;
return true ; // results remains on the stack
}
// *********************************************************************************************************
bool CEditor : : callEnvMethod ( const char * funcName , int numArgs , int numRet /*= 0*/ )
{
//H_AUTO(R2_CEditor_callEnvMethod)
CHECK_EDITOR
nlassert ( funcName ) ;
nlassert ( getLua ( ) . getTop ( ) > = numArgs ) ;
getEnv ( ) . push ( ) ;
getLua ( ) . insert ( - 1 - numArgs ) ; // put the table before the args (self parameter)
return callEnvFunc ( funcName , numArgs + 1 , numRet ) ;
}
// *********************************************************************************************************
bool CEditor : : doLuaScript ( const char * filename , const char * fileDescText )
{
//H_AUTO(R2_CEditor_doLuaScript)
CHECK_EDITOR
CVerboseClock clock ( " parsing of " + std : : string ( filename ) ) ;
// load the classes definition file
std : : string filePath = NLMISC : : CPath : : lookup ( filename , false , true ) ;
if ( filePath . empty ( ) )
{
nlwarning ( " Can't find %s : %s " , fileDescText , filename ) ;
return false ;
}
if ( 0 & & FINAL_VERSION = = 1 ) // deactivated for the moment because there are lua file that must be loaded from example
{
const static std : : string path = " data_common.bnp@ " ;
const static std : : string : : size_type len = path . size ( ) ;
if ( filePath . size ( ) < len | | filePath . substr ( 0 , len ) ! = path )
{
nlwarning ( " Can't find %s : %s in ('%s') " , fileDescText , filename , path . c_str ( ) ) ;
return false ;
}
}
try
{
if ( ! getLua ( ) . executeFile ( filePath ) )
{
nlwarning ( " Couldn't open file %s : %s for R2 is not loaded " , filename , fileDescText ) ;
}
CLuaStackChecker ls ( & getLua ( ) ) ;
return true ;
}
catch ( NLMISC : : EStream & e )
{
nlwarning ( " Error while loading R2 %s (file = %s) : %s " , fileDescText , filename , e . what ( ) ) ;
}
catch ( ELuaError & e )
{
//char filename[MAX_PATH];
std : : string msg = e . what ( ) ;
if ( testWildCard ( msg , " *.lua:*:* " ) ) // TODO nico : more accurate testing for filename format
{
std : : string : : size_type extPos = msg . find ( " .lua " ) ;
nlassert ( extPos ! = std : : string : : npos ) ;
std : : string filename = msg . substr ( 0 , extPos + 4 ) ; // extract filename including extension
int line ;
fromString ( & * ( msg . begin ( ) + extPos + 5 ) , line ) ; // line number follows
nlwarning ( ( CLuaIHM : : createGotoFileButtonTag ( filename . c_str ( ) , line ) + e . what ( ) ) . c_str ( ) ) ;
}
else
{
// no filename / line in the result, so maybe the parse error was in an 'inline' script
nlwarning ( " Error in R2 %s (file = %s) : %s " , fileDescText , filename , e . what ( ) ) ;
}
}
return false ;
}
///////////////////////
// CONTEXTUAL CURSOR //
///////////////////////
// *********************************************************************************************************
void CEditor : : checkCursor ( )
{
//H_AUTO(R2_CEditor_checkCursor)
CHECK_EDITOR
// no-op there : we delegate management of mouse to the CTool derived classes
}
// *********************************************************************************************************
void CEditor : : mouseClick ( bool rightButton , bool /* dblClick */ )
{
//H_AUTO(R2_CEditor_mouseClick)
CHECK_EDITOR
CTool * currentTool = getEditor ( ) . getCurrentTool ( ) ;
if ( ! currentTool ) return ;
if ( ! rightButton )
{
// nb : result not handled there (no defaut action for left click)
currentTool - > onMouseLeftButtonClicked ( ) ;
}
else
{
bool handled = currentTool - > onMouseRightButtonClicked ( ) ;
if ( ! handled )
{
getEditor ( ) . displayContextMenu ( ) ;
}
}
}
// *********************************************************************************************************
void CEditor : : updatePreCamera ( )
{
//H_AUTO(R2_CEditor_updatePreCamera)
/*
# ifdef NL_DEBUG
# ifdef NL_OS_WINDOWS
_CrtCheckMemory ( ) ;
# endif
# endif
*/
if ( _Mode = = EditionMode )
{
static uint32 loop = 0 ;
+ + loop ;
if ( loop % 200 = = 0 ) // minimal wait between to save = 20 seconds
{
if ( ( CTime : : getLocalTime ( ) - _LastAutoSaveTime ) / 1000 > ClientCfg . R2EDAutoSaveWait ) // 5 minutes if not change in Confile
{
autoSave ( ) ;
}
loop = 0 ;
}
// if there's no pending action, then start a new one at each frame
if ( ! _DMC - > getActionHistoric ( ) . isPendingActionInProgress ( ) )
{
_DMC - > newAction ( CI18N : : get ( " uiR2EDUnamedAction " ) ) ;
}
else
{
_DMC - > getActionHistoric ( ) . flushPendingAction ( ) ;
}
}
}
// *********************************************************************************************************
void CEditor : : updatePrimitiveContextualVisibility ( )
{
//H_AUTO(R2_CEditor_updatePrimitiveContextualVisibility)
if ( ! _SelectedInstance ) return ;
// if selected instance remains in last contextual prim list, then they may remain visible
bool ok = false ;
for ( uint k = 0 ; k < _LastContextualPrims . size ( ) ; + + k )
{
if ( _LastContextualPrims [ k ] = = _SelectedInstance | |
_SelectedInstance - > isSonOf ( _LastContextualPrims [ k ] )
)
{
ok = true ;
break ;
}
}
_LastContextualPrims . clear ( ) ;
bool isLogicEntity = _SelectedInstance - > isKindOf ( " LogicEntity " ) ;
if ( ! ok & & ! isLogicEntity ) return ;
if ( isLogicEntity )
{
_LastContextualLogicEntity = _SelectedInstance ;
}
if ( ! _LastContextualLogicEntity ) return ;
//
CObject * seq = _LastContextualLogicEntity - > getGroupSelectedSequence ( ) ;
if ( ! seq ) return ;
if ( seq )
{
CObjectTable * activities = seq - > toTable ( " Components " ) ;
if ( activities )
{
// get first world object parent to get start position
for ( uint k = 0 ; k < activities - > getSize ( ) ; + + k )
{
// search next zone of activity
CObjectTable * activity = activities - > getValue ( k ) - > toTable ( ) ;
if ( ! activity ) continue ;
std : : string zoneId = getString ( activity , " ActivityZoneId " ) ;
CInstance * primitive = getInstanceFromId ( zoneId ) ;
if ( primitive )
{
CDisplayerVisualGroup * primDisp = dynamic_cast < CDisplayerVisualGroup * > ( primitive - > getDisplayerVisual ( ) ) ;
if ( primDisp )
{
_LastContextualPrims . push_back ( primitive ) ;
primDisp - > setContextualVisibilityDate ( T1 ) ;
}
}
}
}
}
}
// *********************************************************************************************************
CEntitySorter * CEditor : : getEntitySorter ( ) const
{
return _EntitySorter ;
}
// *********************************************************************************************************
void CEditor : : updateBeforeRender ( )
{
//H_AUTO(R2_CEditor_updateBeforeRender)
CHECK_EDITOR
//
_IslandCollision . updateCurrPackedIsland ( ) ;
// update contextual visibility of primitive from current selection
updatePrimitiveContextualVisibility ( ) ;
//
if ( ConnectionWanted ) return ; // TMP special case for connection
if ( _CurrentTool )
{
_CurrentTool - > updateBeforeRender ( ) ;
}
for ( TInstanceMap : : iterator it = _Instances . begin ( ) ; it ! = _Instances . end ( ) ; + + it )
{
if ( it - > second - > getDisplayerVisual ( ) )
{
it - > second - > getDisplayerVisual ( ) - > onPreRender ( ) ;
}
}
updateSelectingDecals ( ) ;
// hide or show user depending on the mode
if ( UserEntity )
{
if ( _Mode = = EditionMode | | isDMing ( ) )
{
updateDecalBlendRegion ( _PionneerDecal , UserEntity - > pos ( ) ) ;
showDecal ( CVector2f ( ( float ) UserEntity - > pos ( ) . x , ( float ) UserEntity - > pos ( ) . y ) , 1.f , _PionneerDecal , _PionneerDecalAnim ) ;
}
}
if ( ( _SelectedInstance & & _SelectedInstance - > maxVisibleEntityExceeded ( ) ) | |
( _FocusedInstance & & _FocusedInstance - > maxVisibleEntityExceeded ( ) ) )
{
setMaxVisibleEntityExceededFlag ( true ) ;
}
else
{
setMaxVisibleEntityExceededFlag ( false ) ;
}
}
// *********************************************************************************************************
void CEditor : : updateDecalBlendRegion ( CDecal & decal , const NLMISC : : CVector & pos )
{
//H_AUTO(R2_CEditor_updateDecalBlendRegion)
float topBlendDist = CV_DecalTopBlendStartDist . get ( ) ;
float bottomBlendDist = CV_DecalBottomBlendStartDist . get ( ) ;
float blendLength = CV_DecalBlendLength . get ( ) ;
decal . setBottomBlend ( pos . z - bottomBlendDist - blendLength ,
pos . z - bottomBlendDist ) ;
decal . setTopBlend ( pos . z + topBlendDist ,
pos . z + topBlendDist + blendLength ) ;
}
// *********************************************************************************************************
void CEditor : : updateBeforeSwapBuffer ( )
{
//H_AUTO(R2_CEditor_updateBeforeSwapBuffer)
CHECK_EDITOR
if ( _WaitScenarioScreenWanted )
{
waitScenario ( ) ;
_WaitScenarioScreenWanted = false ;
}
}
// *********************************************************************************************************
void CEditor : : waitScenario ( )
{
//H_AUTO(R2_CEditor_waitScenario)
_EditionModeDisconnectedFlag = false ;
_WaitScenarioScreenActive = true ;
waitScenarioScreen ( ) ;
_WaitScenarioScreenActive = false ;
if ( _PostponeScenarioUpdated )
{
scenarioUpdated ( _NewScenario , false , _NewScenarioInitialAct ) ;
_PostponeScenarioUpdated = false ;
_NewScenario = NULL ;
}
}
// *********************************************************************************************************
void CEditor : : updateAfterRender ( )
{
if ( _EntitySorter ) _EntitySorter - > clipEntitiesByDist ( ) ;
//H_AUTO(R2_CEditor_updateAfterRender)
_IslandCollision . updateCurrPackedIsland ( ) ;
CHECK_EDITOR
if ( ConnectionWanted )
{
connect ( ) ;
return ;
}
//
if ( _CurrentTool )
{
_CurrentTool - > updateAfterRender ( ) ;
}
if ( ! _LuaUIMainLoop . isNil ( ) )
{
_LuaUIMainLoop . callMethodByNameNoThrow ( " onPostSceneRender " , 0 , 0 ) ;
}
//
for ( TInstanceMap : : iterator it = _Instances . begin ( ) ; it ! = _Instances . end ( ) ; + + it )
{
if ( it - > second - > getDisplayerVisual ( ) )
{
it - > second - > getDisplayerVisual ( ) - > onPostRender ( ) ;
}
}
}
// *********************************************************************************************************
void CEditor : : autoSave ( )
{
//H_AUTO(R2_CEditor_autoSave)
_LastAutoSaveTime = NLMISC : : CTime : : getLocalTime ( ) ;
uint32 maxAutoSave = ClientCfg . R2EDAutoSaveSlot ;
std : : string lastFile = toString ( " autosave_%u " , maxAutoSave ) ;
uint32 i = maxAutoSave - 1 ;
for ( ; i ! = 0 ; - - i )
{
std : : string current = NLMISC : : toString ( " autosave_%02u.r2 " , i ) ;
std : : string next = NLMISC : : toString ( " autosave_%02u.r2 " , i + 1 ) ;
if ( CFile : : fileExists ( current ) )
{
if ( CFile : : fileExists ( next ) ) // true only for i = maxAutoSave -1
{
CFile : : deleteFile ( next ) ;
}
CFile : : moveFile ( next . c_str ( ) , current . c_str ( ) ) ;
}
}
if ( CFile : : fileExists ( " data/r2_buffer.dat " ) )
{
CFile : : copyFile ( " autosave_01.r2 " , " data/r2_buffer.dat " ) ;
}
R2 : : getEditor ( ) . getLua ( ) . executeScriptNoThrow ( " r2.Version.save( \" data/r2_buffer.dat \" ) " ) ;
}
// *********************************************************************************************************
bool CEditor : : handleEvent ( const CEventDescriptor & eventDesc )
{
//H_AUTO(R2_CEditor_handleEvent )
CHECK_EDITOR
if ( ConnectionWanted | | ! _CurrentTool ) return false ; // TMP special case for connection
if ( eventDesc . getType ( ) = = CEventDescriptor : : system )
{
const CEventDescriptorSystem & eds = ( const CEventDescriptorSystem & ) eventDesc ;
if ( eds . getEventTypeExtended ( ) = = CEventDescriptorSystem : : setfocus )
{
const CEventDescriptorSetFocus & edsf = ( const CEventDescriptorSetFocus & ) eds ;
if ( edsf . hasFocus ( ) = = false )
{
// cancel current tool
setCurrentTool ( NULL ) ;
return true ;
}
}
}
if ( _CurrentTool )
{
return _CurrentTool - > handleEvent ( eventDesc ) ;
}
return false ;
}
// *********************************************************************************************************
void CEditor : : copy ( )
{
//H_AUTO(R2_CEditor_copy)
// forward to lua
callEnvMethod ( " copy " , 0 ) ;
}
// *********************************************************************************************************
void CEditor : : paste ( )
{
//H_AUTO(R2_CEditor_paste)
// forward to lua
callEnvMethod ( " paste " , 0 ) ;
}
// *********************************************************************************************************
/*
void CEditor : : updateEvents ( )
{
if ( ! _CurrentTool ) return ;
//
if ( EventsListener . isMouseButtonPushed ( leftButton ) )
{
nlwarning ( " onMouseLeftButtonDown " ) ;
_CurrentTool - > onMouseLeftButtonDown ( ) ;
}
if ( EventsListener . isMouseButtonReleased ( leftButton ) )
{
nlwarning ( " isMouseButtonReleased " ) ;
_CurrentTool - > onMouseLeftButtonUp ( ) ;
}
if ( EventsListener . isMouseButtonPushed ( rightButton ) )
{
nlwarning ( " isMouseButtonPushed " ) ;
_CurrentTool - > onMouseRightButtonDown ( ) ;
}
if ( EventsListener . isMouseButtonReleased ( rightButton ) )
{
nlwarning ( " onMouseRightButtonUp " ) ;
_CurrentTool - > onMouseRightButtonUp ( ) ;
}
} */
// *********************************************************************************************************
CEntityCL * CEditor : : createEntity ( uint slot , const NLMISC : : CSheetId & sheetId , const NLMISC : : CVector & pos , float heading , const std : : string & permanentStatutIcon )
{
//H_AUTO(R2_CEditor_createEntity)
CHECK_EDITOR
if ( sheetId = = NLMISC : : CSheetId : : Unknown ) return NULL ;
CInterfaceManager * im = CInterfaceManager : : getInstance ( ) ;
if ( EntitiesMngr . entity ( slot ) )
{
EntitiesMngr . remove ( slot , false ) ;
}
// Create the temporary entity in the entity manager
TNewEntityInfo emptyEntityInfo ;
emptyEntityInfo . reset ( ) ;
CEntityCL * entity = EntitiesMngr . create ( slot , sheetId . asInt ( ) , emptyEntityInfo ) ;
if ( ! entity )
{
nlwarning ( " Can't create entity " ) ;
return NULL ;
}
// Set the permanent statut icon
entity - > setPermanentStatutIcon ( permanentStatutIcon ) ;
// TMP TMP : code taken from /entity command
sint64 * prop = 0 ;
CCDBNodeLeaf * node = 0 ;
// Set The property 'CLFECOMMON::PROPERTY_POSITION'.
node = im - > getDbProp ( " SERVER:Entities:E " + NLMISC : : toString ( " %d " , slot ) + " :P " + NLMISC : : toString ( " %d " , CLFECOMMON : : PROPERTY_POSX ) , false ) ;
if ( node )
{
sint64 x = ( sint64 ) ( pos . x * 1000.0 ) ;
sint64 y = ( sint64 ) ( pos . y * 1000.0 ) ;
sint64 z = ( sint64 ) ( pos . z * 1000.0 ) ;
node - > setValue64 ( x ) ;
node = im - > getDbProp ( " SERVER:Entities:E " + toString ( " %d " , slot ) + " :P " + toString ( " %d " , CLFECOMMON : : PROPERTY_POSY ) , false ) ;
if ( node )
{
node - > setValue64 ( y ) ;
node = im - > getDbProp ( " SERVER:Entities:E " + toString ( " %d " , slot ) + " :P " + toString ( " %d " , CLFECOMMON : : PROPERTY_POSZ ) , false ) ;
if ( node )
node - > setValue64 ( z ) ;
}
}
// Set The property 'PROPERTY_ORIENTATION'.
node = im - > getDbProp ( " SERVER:Entities:E " + toString ( " %d " , slot ) + " :P " + toString ( " %d " , CLFECOMMON : : PROPERTY_ORIENTATION ) , false ) ;
if ( node )
{
union
{
uint64 heading64 ;
float headingFloat ;
} ;
headingFloat = heading ;
node - > setValue64 ( heading64 ) ;
}
// Set Mode
node = im - > getDbProp ( " SERVER:Entities:E " + toString ( " %d " , slot ) + " :P " + toString ( " %d " , CLFECOMMON : : PROPERTY_MODE ) , false ) ;
if ( node )
{
MBEHAV : : EMode m = MBEHAV : : NORMAL ;
prop = ( sint64 * ) & m ;
node - > setValue64 ( * prop ) ;
EntitiesMngr . updateVisualProperty ( 0 , slot , CLFECOMMON : : PROPERTY_MODE ) ;
}
// Set Visual Properties
SPropVisualA visualA ;
//visualA.PropertySubData.LTrail = 1;
// Set alternate look
SAltLookProp altLookProp ;
// fill infos for look
prop = ( sint64 * ) & visualA ;
if ( dynamic_cast < CPlayerCL * > ( entity ) )
{
// visual property A depends on the type of the entity
visualA . PropertySubData . Sex = ClientCfg . Sex ;
}
else if ( dynamic_cast < CPlayerR2CL * > ( entity ) = = NULL )
{
// Get the database entry.
// Get the old value (not useful since we change the whole property).
altLookProp . Summary = 0 ;
altLookProp . Element . ColorTop = 0 ;
altLookProp . Element . ColorBot = 2 ;
altLookProp . Element . WeaponRightHand = 0 ;
altLookProp . Element . WeaponLeftHand = 0 ;
altLookProp . Element . Seed = 100 ;
altLookProp . Element . ColorHair = 4 ;
altLookProp . Element . Hat = 0 ;
// old colors
altLookProp . Element . ColorGlove = altLookProp . Element . ColorTop ;
altLookProp . Element . ColorArm = altLookProp . Element . ColorTop ;
altLookProp . Element . ColorBoot = altLookProp . Element . ColorBot ;
// fill alt infos for look
prop = ( sint64 * ) & altLookProp . Summary ;
}
// Set the database.
im - > getDbProp ( " SERVER:Entities:E " + toString ( " %d " , slot ) + " :P " + toString ( " %d " , CLFECOMMON : : PROPERTY_VPA ) ) - > setValue64 ( * prop ) ;
// Set Visual Properties
SPropVisualB visualB ;
visualB . PropertySubData . LTrail = 1 ;
// fill infos for look
sint64 * propB = 0 ;
propB = ( sint64 * ) & visualB ;
// Set the database.
im - > getDbProp ( " SERVER:Entities:E " + toString ( " %d " , slot ) + " :P " + toString ( " %d " , CLFECOMMON : : PROPERTY_VPB ) ) - > setValue64 ( * propB ) ;
// Apply Changes.
EntitiesMngr . updateVisualProperty ( 0 , slot , CLFECOMMON : : PROPERTY_VPA ) ;
EntitiesMngr . updateVisualProperty ( 0 , slot , CLFECOMMON : : PROPERTY_VPB ) ;
return entity ;
}
// *********************************************************************************************************
CInstance * CEditor : : getInstanceFromEntity ( CEntityCL * entity ) const
{
//H_AUTO(R2_CEditor_getInstanceFromEntity)
CHECK_EDITOR
for ( TInstanceMap : : const_iterator it = _Instances . begin ( ) ; it ! = _Instances . end ( ) ; + + it )
{
if ( it - > second - > getEntity ( ) = = entity ) return it - > second ;
}
return NULL ;
}
// *********************************************************************************************************
void CEditor : : displayContextMenu ( )
{
//H_AUTO(R2_CEditor_displayContextMenu)
CHECK_EDITOR
if ( ! _SelectedInstance )
{
// launch standard context menu (for free look & move options)
getUI ( ) . launchContextMenuInGame ( " ui:interface:game_context_menu_edition " ) ;
return ;
}
if ( getCurrentTool ( ) & & getCurrentTool ( ) - > isCreationTool ( ) )
{
setCurrentTool ( NULL ) ;
}
// retrieve the context menu depending on the type of the entity
CLuaObject classDesc = _SelectedInstance - > getClass ( ) ;
if ( classDesc . isNil ( ) )
{
nlwarning ( " Can't retrieve object class " ) ;
return ;
}
std : : string menu = classDesc [ " Menu " ] ;
if ( menu . empty ( ) ) return ; // no menu for that instance ?
//
CLuaObject menuSetupFunction = classDesc [ " onSetupMenu " ] ;
if ( menuSetupFunction . isFunction ( ) )
{
_SelectedInstance - > getLuaProjection ( ) . push ( ) ;
menuSetupFunction . callNoThrow ( 1 , 0 ) ;
}
//
getUI ( ) . launchContextMenuInGame ( menu ) ;
}
// *********************************************************************************************************
void CEditor : : triggerInstanceObserver ( const TInstanceId & id , IObserverAction & action )
{
//H_AUTO(R2_CEditor_triggerInstanceObserver)
TInstanceObserverMap : : iterator lb = _InstanceObservers . lower_bound ( id ) ;
TInstanceObserverMap : : iterator ub = _InstanceObservers . upper_bound ( id ) ;
if ( lb = = ub ) return ;
// must do a copy, because an observer may erase himself from the list when it is triggered
static std : : vector < IInstanceObserver : : TRefPtr > dest ;
dest . clear ( ) ;
for ( TInstanceObserverMap : : iterator it = lb ; it ! = ub ; + + it )
{
dest . push_back ( it - > second ) ;
}
for ( std : : vector < IInstanceObserver : : TRefPtr > : : iterator it = dest . begin ( ) ; it ! = dest . end ( ) ; + + it )
{
if ( * it ) action . doAction ( * * it ) ;
}
}
// *********************************************************************************************************
void CEditor : : onErase ( CObject * object )
{
//H_AUTO(R2_CEditor_onErase)
bool dummyFoundInBase ;
std : : string dummyNameInParent ;
onErase ( object , dummyFoundInBase , dummyNameInParent ) ;
}
// *********************************************************************************************************
void CEditor : : onErase ( CObject * root , bool & foundInBase , std : : string & nameInParent )
{
//H_AUTO(R2_CEditor_onErase)
foundInBase = false ;
CHECK_EDITOR
if ( ! root ) return ;
CInstance * inst = getInstanceFromObject ( root ) ;
// sons
if ( root - > isTable ( ) )
{
for ( uint k = 0 ; k < root - > getSize ( ) ; + + k )
{
CObject * obj = root - > getValue ( k ) ;
if ( obj - > isTable ( ) )
{
onErase ( obj ) ;
}
}
}
//
CObject * parent = NULL ;
//
if ( inst )
{
// Add an 'Erased' flag to the object so that
// any pending property in the property sheet
// won't send a 'requestSetNode' when it is closed
try
{
( * inst ) . getLuaProjection ( ) [ " User " ] . setValue ( " Erased " , true ) ;
}
catch ( ELuaNotATable & e )
{
nlwarning ( e . what ( ) ) ;
}
// if object is selected or focused, then clear these flags
if ( inst = = getSelectedInstance ( ) )
{
setSelectedInstance ( NULL ) ;
}
if ( inst = = getFocusedInstance ( ) )
{
setFocusedInstance ( NULL ) ;
}
}
// if object can be found in its base, then not really a deletion, but
// rather a change of attribute to the "default value' (may happen in an undo operation)
parent = root - > getParent ( ) ;
if ( parent )
{
sint32 sonIndex = parent - > findIndex ( root ) ;
if ( sonIndex ! = - 1 )
{
nameInParent = parent - > getKey ( sonIndex ) ;
if ( ! nameInParent . empty ( ) & & getDMC ( ) . getPropertyAccessor ( ) . hasValueInBase ( parent , nameInParent ) )
{
foundInBase = true ;
}
}
}
if ( inst & & ! foundInBase )
{
// send event to instance & displayers
inst - > onErase ( ) ;
// trigger observers
class CEraseNotification : public IObserverAction
{
public :
CEraseNotification ( CInstance & instance ) : Instance ( instance ) { }
virtual void doAction ( IInstanceObserver & obs )
{
obs . onInstanceErased ( Instance ) ;
}
CInstance & Instance ;
} ;
CEraseNotification eraseNotification ( * inst ) ;
triggerInstanceObserver ( inst - > getId ( ) , eraseNotification ) ;
}
// if object has a user environment attached to it, remove it from lua
if ( inst )
{
CLuaStackChecker lsc ( & getLua ( ) ) ;
getLua ( ) . pushLightUserData ( ( void * ) root ) ;
getLua ( ) . getTable ( LUA_REGISTRYINDEX ) ;
if ( ! getLua ( ) . isNil ( ) )
{
getLua ( ) . pushLightUserData ( ( void * ) root ) ; // key
getLua ( ) . pushNil ( ) ; // value
getLua ( ) . setTable ( LUA_REGISTRYINDEX ) ; // erase
}
getLua ( ) . pop ( ) ;
}
if ( root - > isTable ( ) )
{
// special patch: ref ids under this object should not be triggered any more for that object
CObjectTable * rootTable = root - > toTable ( ) ;
for ( uint32 k = 0 ; k < rootTable - > getSize ( ) ; + + k )
{
CObject * obj = rootTable - > getValue ( k ) ;
CObjectRefIdClient * objRefId = dynamic_cast < CObjectRefIdClient * > ( obj ) ;
if ( objRefId )
{
objRefId - > enable ( false ) ; // don't observe anything
}
}
}
if ( ! _ClearingContent )
{
if ( inst )
{
nlassert ( _Instances . count ( ( const CObjectTable * ) root ) = = 1 ) ;
//nlwarning("Instance with id %s deleted, but not inserted", inst->getId().c_str());
}
}
// really remove object
//nlwarning("Removing instance with id %s (table = 0x%s)", inst->getId().c_str(), (int) root);
if ( inst )
{
_Instances . erase ( ( const CObjectTable * ) root ) ;
}
}
// *********************************************************************************************************
void CEditor : : nodeErased ( const std : : string & instanceId , const std : : string & attrName , sint32 position )
{
//H_AUTO(R2_CEditor_nodeErased)
CHECK_EDITOR
CObject * obj = _DMC - > find ( instanceId , attrName , position ) ;
if ( ! obj ) return ;
bool foundInBase ;
std : : string nameInParent ;
onErase ( obj , foundInBase , nameInParent ) ;
CObject * parent = obj - > getParent ( ) ;
_DMC - > CDynamicMapClient : : nodeErased ( instanceId , attrName , position ) ;
if ( foundInBase )
{
nlassert ( parent ) ;
// erased, but reading in the base will give a new value, so the real
// action from observers standpoint is 'modified'
CInstance * parentInstance = getInstanceFromObject ( parent ) ;
if ( parentInstance )
{
onAttrModified ( * parentInstance , nameInParent ) ;
}
else
{
nlwarning ( " Can't found instance in which %s was modified " , nameInParent . c_str ( ) ) ;
}
}
// warn the parent that it has been modified
onAttrModified ( parent ) ;
// NB : msg for deleted attribute does not exist yet, so the parent is warned that it is modified, but
// 'onTableModified' is not called (because key doesn't exist any more)
}
void CEditor : : onResetEditionMode ( )
{
//H_AUTO(R2_CEditor_onResetEditionMode)
CHECK_EDITOR
// called when a scenario just before a scenario is created
// no-op, to clean
}
void CEditor : : onEditionModeConnected ( uint32 userSlotId , uint32 adventureId , CObject * highLevel , const std : : string & versionName , bool willTP , uint32 initialActIndex )
{
//H_AUTO(R2_CEditor_onEditionModeConnected)
CHECK_EDITOR
if ( ! _WaitScenarioScreenActive )
{
setMode ( EditionMode ) ;
}
CInterfaceGroup * currentSessionGroup = dynamic_cast < CInterfaceGroup * > ( getUI ( ) . getElementFromId ( " ui:interface:r2ed_current_session " ) ) ;
if ( currentSessionGroup )
{
CViewText * text = dynamic_cast < CViewText * > ( currentSessionGroup - > getView ( " current_session " ) ) ;
if ( text )
{
text - > setText ( toString ( " Edition Session = %d (%s) " , adventureId , versionName . c_str ( ) ) ) ;
}
}
setDefaultChatWindow ( PeopleInterraction . ChatGroup . Window ) ;
_DMC - > CDynamicMapClient : : onEditionModeConnected ( userSlotId , adventureId , highLevel , versionName , willTP , initialActIndex ) ;
}
void CEditor : : setAccessMode ( TAccessMode mode )
{
//H_AUTO(R2_CEditor_setAccessMode)
_AccessMode = mode ;
switch ( mode )
{
case AccessEditor : _Env . setValue ( " AccessMode " , " Editor " ) ; break ;
case AccessDM :
_Env . setValue ( " AccessMode " , " DM " ) ;
if ( _Mode = = AnimationModePlay )
{
loadStandardUI ( ) ;
}
break ;
case AccessOutlandOwner : _Env . setValue ( " AccessMode " , " OutlandOwner " ) ; break ;
default :
nlassert ( 0 ) ;
break ;
}
}
void CEditor : : onAnimationModeConnected ( const CClientMessageAdventureUserConnection & connected )
{
//H_AUTO(R2_CEditor_onAnimationModeConnected)
_ScenarioReceivedFlag = true ; // end wait screen
// TMP PATCH
// _WillTP = true;
CHECK_EDITOR
switch ( connected . Mode )
{
case 0 : setMode ( AnimationModeLoading ) ; break ;
case 1 : setMode ( AnimationModeWaitingForLoading ) ; break ;
case 2 : setMode ( AnimationModeDm ) ; break ;
case 3 : setMode ( AnimationModePlay ) ; break ;
default : nlwarning ( " Unhandled %u in Animation Session " , connected . Mode ) ;
}
CInterfaceGroup * currentSessionGroup = dynamic_cast < CInterfaceGroup * > ( getUI ( ) . getElementFromId ( " ui:interface:r2ed_current_session " ) ) ;
if ( currentSessionGroup )
{
CViewText * text = dynamic_cast < CViewText * > ( currentSessionGroup - > getView ( " current_session " ) ) ;
if ( text )
{
text - > setText ( toString ( " Animation Session = %d (%s) " , connected . SessionId . asInt ( ) , connected . VersionName . c_str ( ) ) ) ;
}
}
setDefaultChatWindow ( PeopleInterraction . ChatGroup . Window ) ;
_DMC - > CDynamicMapClient : : onAnimationModeConnected ( connected ) ;
}
void CEditor : : onEditionModeDisconnected ( )
{
//H_AUTO(R2_CEditor_onEditionModeDisconnected)
_EditionModeDisconnectedFlag = true ;
delete _NewScenario ;
_NewScenario = NULL ;
CHECK_EDITOR
// Usefull only for the pionner that does not do requestTranslateFeatures()
// Because avec using the button the currentScenario = 0
try
{
R2 : : getEditor ( ) . getLua ( ) . executeScript ( " r2.Version.save( \" data/r2_buffer.dat \" ) " ) ;
}
catch ( const std : : exception & e )
{
nlwarning ( " Can't start Edition Mode " , e . what ( ) ) ;
}
_DMC - > CDynamicMapClient : : onEditionModeDisconnected ( ) ;
}
void CEditor : : onTestModeConnected ( )
{
//H_AUTO(R2_CEditor_onTestModeConnected)
CHECK_EDITOR
// TODO nico : change the name of the function : should rather be 'onAnimationModeConnected'
// start as a GM
getUI ( ) . runActionHandler ( " r2ed_anim_dm_mode " , NULL , " " ) ;
_DMC - > CDynamicMapClient : : onTestModeConnected ( ) ;
}
void CEditor : : onTestModeDisconnected ( TSessionId sessionId , uint32 lastAct , TScenarioSessionType sessionType )
{
//H_AUTO(R2_CEditor_onTestModeDisconnected)
CHECK_EDITOR
_DMC - > CDynamicMapClient : : onTestModeDisconnected ( sessionId , lastAct , sessionType ) ;
}
// *********************************************************************************************************
void CEditor : : nodeInserted ( const std : : string & instanceId , const std : : string & attrName , sint32 position , const std : : string & key , CObject * value )
{
//H_AUTO(R2_CEditor_nodeInserted)
CHECK_EDITOR
_DMC - > CDynamicMapClient : : nodeInserted ( instanceId , attrName , position , key , value ) ;
if ( value - > isTable ( ) )
{
std : : string id = getString ( value , " InstanceId " ) ;
if ( ! id . empty ( ) )
{
const CObject * clonedValue = _DMC - > find ( id ) ;
// bad insert
if ( clonedValue )
{
createNewInstanceForObjectTable ( clonedValue ) ;
onAttrModified ( clonedValue - > getParent ( ) ) ; // parent table is modified
// so -> only parent of parent table will be notified of change
// maybe we need another msg "onInsert" that is sent
// to the parent table.
}
}
}
}
// *********************************************************************************************************
void CEditor : : createNewInstanceForObjectTable ( const CObject * obj )
{
//H_AUTO(R2_CEditor_createNewInstanceForObjectTable)
CHECK_EDITOR
createNewInstanceForObjectTableInternal ( obj ) ;
onPostCreate ( obj ) ;
}
// *********************************************************************************************************
void CEditor : : notifyInstanceObserversOfCreation ( CInstance & inst )
{
//H_AUTO(R2_CEditor_notifyInstanceObserversOfCreation)
CHECK_EDITOR
// if there are observers watching this instance, warn them
const std : : string & id = inst . getId ( ) ;
// trigger observers
class CCreationNotification : public IObserverAction
{
public :
CCreationNotification ( CInstance & instance ) : Instance ( instance ) { }
virtual void doAction ( IInstanceObserver & obs )
{
obs . onInstanceCreated ( Instance ) ;
}
CInstance & Instance ;
} ;
CCreationNotification creationNotification ( inst ) ;
triggerInstanceObserver ( id , creationNotification ) ;
}
// *********************************************************************************************************
void CEditor : : onPostCreate ( const CObject * obj )
{
//H_AUTO(R2_CEditor_onPostCreate)
CHECK_EDITOR
struct CPostCreateVisitor : public IObjectVisitor
{
virtual void visit ( CObjectTable & obj )
{
// if table has a "InstanceId" field there is a matching editor object
CInstance * inst = getEditor ( ) . getInstanceFromObject ( & obj ) ;
if ( inst )
{
inst - > onPostCreate ( ) ;
getEditor ( ) . notifyInstanceObserversOfCreation ( * inst ) ;
}
}
} ;
if ( obj )
{
CPostCreateVisitor postCreateVisitor ;
const_cast < CObject * > ( obj ) - > visit ( postCreateVisitor ) ;
}
}
// *********************************************************************************************************
sint CEditor : : getLeftQuota ( )
{
//H_AUTO(R2_CEditor_getLeftQuota)
CLuaState & ls = getLua ( ) ;
CLuaStackChecker lsc ( & ls ) ;
callEnvMethod ( " getLeftQuota " , 0 , 1 ) ;
if ( ! ls . isNumber ( - 1 ) )
{
ls . pop ( 1 ) ;
return 0 ;
}
sint result = ( sint ) ls . toNumber ( - 1 ) ;
ls . pop ( 1 ) ;
return result ;
}
// *********************************************************************************************************
bool CEditor : : checkRoomLeft ( )
{
//H_AUTO(R2_CEditor_checkRoomLeft)
return getLeftQuota ( ) > 0 ;
}
// *********************************************************************************************************
void CEditor : : makeRoomMsg ( )
{
//H_AUTO(R2_CEditor_makeRoomMsg)
// delegate ui display to lua
callEnvMethod ( " makeRoomMsg " , 0 , 0 ) ;
}
// *********************************************************************************************************
bool CEditor : : verifyRoomLeft ( uint aiCost , uint staticCost )
{
//H_AUTO(R2_CEditor_verifyRoomLeft)
CLuaState & ls = getLua ( ) ;
if ( aiCost )
{
CLuaStackChecker lsc ( & ls ) ;
getEditor ( ) . getLua ( ) . push ( ( lua_Number ) aiCost ) ;
callEnvMethod ( " checkAiQuota " , 1 , 1 ) ;
if ( ! ls . isBoolean ( - 1 ) )
{
ls . pop ( 1 ) ;
return false ;
}
sint result = ( sint ) ls . toBoolean ( - 1 ) ;
ls . pop ( 1 ) ;
return result ! = 0 ;
}
if ( staticCost )
{
CLuaStackChecker lsc ( & ls ) ;
getEditor ( ) . getLua ( ) . push ( ( lua_Number ) staticCost ) ;
callEnvMethod ( " checkStaticQuota " , 1 , 1 ) ;
if ( ! ls . isBoolean ( - 1 ) )
{
ls . pop ( 1 ) ;
return false ;
}
sint result = ( sint ) ls . toBoolean ( - 1 ) ;
ls . pop ( 1 ) ;
return result ! = 0 ;
}
return true ;
}
// *********************************************************************************************************
void CEditor : : createNewInstanceForObjectTableInternal ( const CObject * obj )
{
//H_AUTO(R2_CEditor_createNewInstanceForObjectTableInternal)
CHECK_EDITOR
if ( ! obj ) return ;
if ( ! obj - > isTable ( ) ) return ; // not a table ...
const CObjectTable * table = ( const CObjectTable * ) obj ;
std : : string id = getString ( obj , " InstanceId " ) ;
if ( ! id . empty ( ) )
{
// CInstance is created only for objects with an instance id
CInstance * inst = new CInstance ( table , getLua ( ) ) ;
nlassert ( _Instances . count ( table ) = = 0 ) ;
_Instances [ table ] = inst ;
// if a cookie was created, add in in the instance lua 'User' table
TCookieMap : : iterator cookieList = _Cookies . find ( id ) ;
if ( cookieList ! = _Cookies . end ( ) )
{
if ( obj - > isTable ( ) )
{
CLuaState & ls = getLua ( ) ;
getLuaUserTableFromObject ( ls , * ( CObjectTable * ) obj ) ;
CLuaObject userTable ( ls ) ; // pop the table into a CLuaObject for convenience
for ( TCookieList : : iterator it = cookieList - > second . begin ( ) ; it ! = cookieList - > second . end ( ) ; + + it )
{
userTable . setValue ( it - > Key , it - > Value ) ;
}
}
_Cookies . erase ( cookieList ) ;
}
// create displayers
CLuaObject classDesc = inst - > getClass ( ) ;
if ( ! classDesc . isNil ( ) )
{
CLuaStackChecker lsc ( & getLua ( ) ) ;
CDisplayerVisual * dispViz = createObjectFromClassName < CDisplayerVisual > ( classDesc [ " DisplayerVisual " ] . toString ( ) ) ;
if ( dispViz )
{
bool ok = dispViz - > init ( classDesc [ " DisplayerVisualParams " ] ) ;
if ( ! ok )
{
nlwarning ( " Error when calling init on visual displayer of class %s " , classDesc [ " Name " ] . toString ( ) . c_str ( ) ) ;
}
}
inst - > setDisplayerVisual ( dispViz ) ;
//
CDisplayerBase * dispUI = createObjectFromClassName < CDisplayerBase > ( classDesc [ " DisplayerUI " ] . toString ( ) ) ;
if ( dispUI )
{
bool ok = dispUI - > init ( classDesc [ " DisplayerUIParams " ] ) ;
if ( ! ok )
{
nlwarning ( " Error when calling init on ui displayer of class %s " , classDesc [ " Name " ] . toString ( ) . c_str ( ) ) ;
}
}
inst - > setDisplayerUI ( dispUI ) ;
//
CDisplayerBase * dispProp = createObjectFromClassName < CDisplayerBase > ( classDesc [ " DisplayerProperties " ] . toString ( ) ) ;
if ( dispProp )
{
bool ok = dispProp - > init ( classDesc [ " DisplayerPropertiesParams " ] ) ;
if ( ! ok )
{
nlwarning ( " Error when calling init on property displayer of class %s " , classDesc [ " Name " ] . toString ( ) . c_str ( ) ) ;
}
}
inst - > setDisplayerProperties ( dispProp ) ;
}
// prevent completion of the tree while an instance is being created
//backupRequestCommands();
inst - > onCreate ( ) ;
//restoreRequestCommands();
//
// if a name was generated locally, erase from the local name map.
std : : string className = getString ( obj , " Class " ) ;
std : : string name = getString ( obj , " Name " ) ;
if ( ! className . empty ( ) & & ! name . empty ( ) )
{
for ( TGeneratedNameMap : : iterator it = _LocalGeneratedNames . begin ( ) ; it ! = _LocalGeneratedNames . end ( ) ; + + it )
{
sint index = getGeneratedNameIndex ( name , it - > first ) ;
if ( index ! = - 1 )
{
it - > second . erase ( index ) ;
break ;
}
}
}
}
// do the same on sons
for ( uint k = 0 ; k < table - > getSize ( ) ; + + k )
{
createNewInstanceForObjectTableInternal ( table - > getValue ( k ) ) ;
}
}
// *********************************************************************************************************
void CEditor : : onAttrModified ( CInstance & parentInstance , const std : : string & attrName , sint32 indexInArray )
{
//H_AUTO(R2_CEditor_onAttrModified)
parentInstance . onAttrModified ( attrName , indexInArray ) ;
class CAttrModifiedNotification : public IObserverAction
{
public :
CAttrModifiedNotification ( CInstance & instance , const std : : string & key , sint32 indexInArray )
: Instance ( instance ) , Key ( key ) , IndexInArray ( indexInArray ) { }
virtual void doAction ( IInstanceObserver & obs )
{
obs . onAttrModified ( Instance , Key , IndexInArray ) ;
}
CInstance & Instance ;
const std : : string & Key ;
sint32 IndexInArray ;
} ;
CAttrModifiedNotification attrModifiedNotification ( parentInstance , attrName , indexInArray ) ;
triggerInstanceObserver ( parentInstance . getId ( ) , attrModifiedNotification ) ;
}
// *********************************************************************************************************
void CEditor : : onAttrModified ( const CObject * value )
{
//H_AUTO(R2_CEditor_onAttrModified)
CHECK_EDITOR
if ( ! value ) return ;
const CObject * son = value ;
const CObject * parent = value - > getParent ( ) ;
sint32 indexInArray = - 1 ;
while ( parent )
{
CInstance * parentInstance = getInstanceFromObject ( parent ) ;
sint32 indexInParent = parent - > findIndex ( son ) ;
2010-05-13 17:02:00 +00:00
nlassert ( indexInParent ! = - 1 ) ;
2010-05-06 00:08:41 +00:00
if ( parentInstance )
{
// we are in an instance (a CObjectTable with an instance id)
// TODO nico : a cache for the 'name' in the parent like with CObjectRefId ...
std : : string key = parent - > getKey ( indexInParent ) ;
onAttrModified ( * parentInstance , key , indexInArray ) ;
indexInArray = - 1 ;
}
else
{
// we are in an array in an instance -> memorize index in that array for next call to "onAttrModified"...
indexInArray = indexInParent ;
}
son = parent ;
parent = parent - > getParent ( ) ;
}
}
// *********************************************************************************************************
void CEditor : : nodeSet ( const std : : string & instanceId , const std : : string & attrName , CObject * value )
{
//H_AUTO(R2_CEditor_nodeSet)
CHECK_EDITOR
CObject * obj = _DMC - > find ( instanceId ) ;
if ( ! obj ) return ;
// erase previous object
nlassert ( obj - > isTable ( ) ) ;
//
if ( ! attrName . empty ( ) )
{
obj = obj - > findAttr ( attrName ) ;
}
if ( obj )
{
onErase ( obj ) ;
}
// change the actual value
_DMC - > CDynamicMapClient : : nodeSet ( instanceId , attrName , value ) ;
//
nlassert ( ! getInstanceFromObject ( value ) ) ; // this must be a new object...
//
if ( value - > isTable ( ) )
{
std : : string id = getString ( value , " InstanceId " ) ;
if ( ! id . empty ( ) )
{
const CObject * clonedValue = _DMC - > find ( id ) ;
if ( clonedValue )
{
createNewInstanceForObjectTable ( clonedValue ) ; // if the created object is a table, warn him that he has been created
onAttrModified ( clonedValue ) ;
return ;
}
}
}
// no instance id for object, retrieve object pointer from parent
const CObject * parent = _DMC - > find ( instanceId ) ;
if ( ! parent ) return ;
onAttrModified ( parent - > getAttr ( attrName ) ) ;
}
// *********************************************************************************************************
void CEditor : : eraseScenario ( )
{
//H_AUTO(R2_CEditor_eraseScenario)
if ( _Scenario )
{
backupRequestCommands ( ) ;
onErase ( _Scenario ) ;
restoreRequestCommands ( ) ;
_Scenario = NULL ;
}
}
// *********************************************************************************************************
void CEditor : : scenarioUpdated ( CObject * highLevel , bool willTP , uint32 initialActIndex )
{
//H_AUTO(R2_CEditor_scenarioUpdated)
CHECK_EDITOR
_ScenarioReceivedFlag = true ;
if ( _WaitScenarioScreenActive )
{
// defer scenario update to the end of the wait screen
_NewScenario = highLevel ? highLevel - > clone ( ) : NULL ;
_NewScenarioInitialAct = initialActIndex ;
_PostponeScenarioUpdated = true ;
return ;
}
if ( ! highLevel )
{
_IsStartingScenario = false ;
_WillTP = false ;
callEnvFunc ( " onEmptyScenarioUpdated " , 0 ) ;
return ;
}
// _WillTP = willTP;
_WillTP = false ; // TMP TMP
_UpdatingScenario = true ;
_BaseAct = NULL ;
_CurrentAct = NULL ;
CLuaStackRestorer lsc ( & getLua ( ) , getLua ( ) . getTop ( ) ) ;
//nlwarning("Scenario updated, start highlevel = ");
//highLevel->dump();
eraseScenario ( ) ;
_IsStartingScenario = false ;
if ( _DMC - > getEditionModule ( ) . getMustStartScenario ( ) )
{
_IsStartingScenario = true ;
}
nlassert ( _Instances . empty ( ) ) ;
nlassert ( CDisplayerBase : : ObjCount = = 0 ) ;
//
_DMC - > CDynamicMapClient : : scenarioUpdated ( highLevel , willTP , initialActIndex ) ;
//nlwarning("Scenario updated, content is = ");
/*
if ( _DMC - > getHighLevel ( ) )
{
_DMC - > getHighLevel ( ) - > dump ( ) ;
}
else
{
nlwarning ( " NULL " ) ;
}
*/
createNewInstanceForObjectTableInternal ( _DMC - > getHighLevel ( ) ) ;
nlassert ( highLevel - > isTable ( ) ) ;
_Scenario = ( CObjectTable * ) _DMC - > getHighLevel ( ) ;
if ( _Scenario - > getAttr ( " InstanceId " ) )
{
_ScenarioInstance = getInstanceFromId ( _Scenario - > getAttr ( " InstanceId " ) - > toString ( ) ) ;
}
else
{
_ScenarioInstance = NULL ;
nlwarning ( " Can't retrieve scenario (no instance id) " ) ;
_Scenario - > dump ( ) ;
}
static volatile bool forceDump = false ;
if ( forceDump )
{
_Scenario - > dump ( ) ;
}
//
projectInLua ( _Scenario ) ; // push on the lua stack
getLua ( ) . push ( float ( initialActIndex ) ) ; // example reconnect after test in act4
// update value in the framework
callEnvFunc ( " onScenarioUpdated " , 2 ) ;
//nlwarning("Instance list now is :");
//dumpInstances();
CObject * acts = _Scenario - > getAttr ( " Acts " ) ;
if ( acts )
{
CObject * baseAct = acts - > getValue ( 0 ) ;
if ( baseAct )
{
_BaseAct = getInstanceFromId ( baseAct - > toString ( " InstanceId " ) ) ;
}
}
if ( ! _BaseAct )
{
nlwarning ( " Base act not found at scenario update " ) ;
}
if ( _WantedActOnInit . empty ( ) )
{
if ( ! _CurrentAct ) // if act not currently setted at scenario creation ...
{
setCurrentAct ( _BaseAct ) ; // ...then default to the base act
}
}
else
{
setCurrentActFromTitle ( _WantedActOnInit ) ;
_WantedActOnInit . clear ( ) ;
}
_DMC - > getActionHistoric ( ) . clear ( highLevel ) ; // reinit the undo / redo stack
onPostCreate ( _Scenario ) ; // post creation require that current act has been set
//TP is done via the onTpPositionSimulated message
/*
// teleport in good island
if ( ClientCfg . Local )
{
sint locationId = ( uint ) _ScenarioInstance - > getLuaProjection ( ) [ " Description " ] [ " LocationId " ] . toNumber ( ) ;
CScenarioEntryPoints & sep = CScenarioEntryPoints : : getInstance ( ) ;
_IslandCollision . loadEntryPoints ( ) ;
if ( sep . getCompleteIslands ( ) . empty ( ) )
{
nlwarning ( " Entry points not loaded, teleport not done (local mode) " ) ;
}
else if ( locationId > = ( sint ) sep . getCompleteIslands ( ) . size ( ) )
{
nlwarning ( " Bad location id %d " , locationId ) ;
}
else
{
// check if already in this entry point (no tp if so)
const CScenarioEntryPoints : : CCompleteIsland & ci = sep . getCompleteIslands ( ) [ locationId ] ;
CVectorD playerPos = UserEntity - > pos ( ) ;
//
if ( playerPos . x < = ci . XMin | |
playerPos . x > = ci . XMax | |
playerPos . y < = ci . YMin | |
playerPos . y > = ci . YMax )
{
if ( ci . EntryPoints . size ( ) > 0 )
{
const CScenarioEntryPoints : : CShortEntryPoint & shortEntryPoint = ci . EntryPoints [ 0 ] ;
CVector dest ( ( float ) shortEntryPoint . X , ( float ) shortEntryPoint . Y , 0.f ) ;
UserEntity - > pos ( dest ) ; // change position in pacs
// Select the closest continent from the new position.
beginLoading ( LoadingBackground ) ;
# define BAR_STEP_TP 2 // fixme : this define is duplicated....
ProgressBar . reset ( BAR_STEP_TP ) ;
ucstring nmsg ( " Loading... " ) ;
ProgressBar . newMessage ( ClientCfg . buildLoadingString ( nmsg ) ) ;
ProgressBar . progress ( 0 ) ;
ContinentMngr . select ( dest , ProgressBar ) ;
endLoading ( ) ;
// Teleport the User.
UserEntity - > tp ( dest ) ;
}
}
}
}
*/
_UpdatingScenario = false ;
if ( _DMC - > getEditionModule ( ) . getMustStartScenario ( )
& & _DMC - > getEditionModule ( ) . getScenarioUpToDate ( ) )
{
_DMC - > getEditionModule ( ) . setMustStartScenario ( false ) ;
if ( _DMC - > getCurrentScenario ( ) - > getHighLevel ( ) )
{
bool result = true ;
if ( ClientCfg . R2EDMustVerifyRingAccessWhileLoadingAnimation )
{
CLuaState & ls = getLua ( ) ;
CLuaStackChecker lsc ( & ls ) ;
callEnvFunc ( " verifyScenario " , 0 , 1 ) ;
if ( ! ls . isBoolean ( - 1 ) )
{
nlassert ( 0 & & " verifyScenario return wrong type " ) ;
}
result = ls . toBoolean ( - 1 ) ;
ls . pop ( ) ;
}
if ( result ) //Start scenario only if allowed
{
ConnectionWanted = true ; // ugly
}
}
}
}
// *********************************************************************************************************
CInstance * CEditor : : getDefaultFeature ( CInstance * act )
{
//H_AUTO(R2_CEditor_getDefaultFeature)
CHECK_EDITOR
if ( ! act ) return NULL ;
CObject * defaultFeature = act - > getObjectTable ( ) - > getAttr ( " Features " ) ;
if ( ! defaultFeature ) return NULL ;
defaultFeature = defaultFeature - > getValue ( 0 ) ;
if ( ! defaultFeature ) return NULL ; // 0 should be the default feature
CInstance * result = getInstanceFromId ( defaultFeature - > toString ( " InstanceId " ) ) ;
if ( ! result ) return NULL ;
if ( ! result - > isKindOf ( " DefaultFeature " ) )
{
nlwarning ( " Can't retrieve default feature. " ) ;
}
return result ;
}
// *********************************************************************************************************
CInstance * CEditor : : getDefaultFeature ( )
{
//H_AUTO(R2_CEditor_getDefaultFeature)
CHECK_EDITOR
return getDefaultFeature ( getCurrentAct ( ) ) ;
}
// *********************************************************************************************************
void CEditor : : nodeMoved ( const std : : string & instanceId , const std : : string & attrName , sint32 position , const std : : string & destInstanceId , const std : : string & destAttrName , sint32 destPosition )
{
//H_AUTO(R2_CEditor_nodeMoved)
CHECK_EDITOR
const CObject * src = _DMC - > find ( instanceId , attrName , position ) ;
if ( ! src ) return ;
//
CObject * oldParent = src - > getParent ( ) ;
//
CInstance * inst = getInstanceFromObject ( src ) ;
// tells object that he is about to move
if ( inst )
{
inst - > onPreHrcMove ( ) ;
// notify possible observers that this instance will move
class CPreHrcMoveNotification : public IObserverAction
{
public :
CPreHrcMoveNotification ( CInstance & instance ) : Instance ( instance ) { }
virtual void doAction ( IInstanceObserver & obs )
{
obs . onPreHrcMove ( Instance ) ;
}
CInstance & Instance ;
} ;
CPreHrcMoveNotification preHrcMoveNotification ( * inst ) ;
triggerInstanceObserver ( inst - > getId ( ) , preHrcMoveNotification ) ;
}
// do the move
_DMC - > CDynamicMapClient : : nodeMoved ( instanceId , attrName , position , destInstanceId , destAttrName , destPosition ) ;
// warn the previous parent that it has been modified
if ( src - > getParent ( ) ! = oldParent )
{
onAttrModified ( oldParent ) ; // the old parent is modified so send appropriate msg
}
// else ... if new parent is the same then send message only at the end (else object believe it has been modified twice in a row)
// tells object that he has moved
if ( inst )
{
inst - > onPostHrcMove ( ) ;
// notify possible observers that this instance has moved
class CPostHrcMoveNotification : public IObserverAction
{
public :
CPostHrcMoveNotification ( CInstance & instance ) : Instance ( instance ) { }
virtual void doAction ( IInstanceObserver & obs )
{
obs . onPostHrcMove ( Instance ) ;
}
CInstance & Instance ;
} ;
CPostHrcMoveNotification postHrcMoveNotification ( * inst ) ;
triggerInstanceObserver ( inst - > getId ( ) , postHrcMoveNotification ) ;
}
onAttrModified ( src ) ; // the new parent is modified so send appropriate msg
}
// *********************************************************************************************************
void CEditor : : dumpInstances ( )
{
//H_AUTO(R2_CEditor_dumpInstances)
CHECK_EDITOR
for ( TInstanceMap : : iterator it = _Instances . begin ( ) ; it ! = _Instances . end ( ) ; + + it )
{
nlwarning ( " Obj = %p, id = %s, instance = %p " , it - > first , it - > second - > getId ( ) . c_str ( ) , & ( * it - > second ) ) ;
}
}
// ***************************************************************
struct CSortSelectableObject
{
ISelectableObject * Object ;
float Depth ;
CVector RayStart , RayStartClipped , RayEndClipped ;
NLMISC : : CAABBox SelectBox ;
bool SelectBoxInWorld ;
bool operator < ( const CSortSelectableObject & o ) const
{
return Depth < o . Depth ;
}
} ;
// special selectable object to detect that mouse is over user
class CSelectableUser : public ISelectableObject
{
public :
virtual bool isSelectable ( ) const { return true ; }
virtual bool getLastClip ( ) const { return UserEntity - > getLastClip ( ) ; }
virtual NLMISC : : CAABBox getSelectBox ( ) const
{
return UserEntity - > localSelectBox ( ) ;
}
virtual const NLMISC : : CMatrix & getInvertedMatrix ( ) const
{
static CMatrix invertedMatrix ;
invertedMatrix = UserEntity - > dirMatrix ( ) ;
invertedMatrix . setPos ( UserEntity - > pos ( ) ) ;
invertedMatrix . invert ( ) ;
return invertedMatrix ;
}
virtual float preciseIntersectionTest ( const NLMISC : : CVector & worldRayStart , const NLMISC : : CVector & worldRayDir ) const
{
if ( ! UserEntity ) return FLT_MAX ;
return CEditor : : preciseEntityIntersectionTest ( * UserEntity , worldRayStart , worldRayDir ) ;
}
virtual CInstance * getInstanceInEditor ( ) const { return NULL ; }
} ;
// ***************************************************************
static CSelectableUser SelectableUser ;
//
CInstance * CEditor : : getInstanceUnderPos ( float x , float y , float distSelection , bool & isPlayerUnderCursor )
{
static volatile bool ignore = false ;
if ( ignore )
{
return NULL ;
}
//H_AUTO(R2_CEditor_getInstanceUnderPos)
CHECK_EDITOR
// TODO nico: this code was copied from CEntityManager::getEntityUnderPos
// then modified, so some factoring could be made ...
uint i ;
// valid only if bbox still intersect
CInstance * precInstanceUnderPos = _LastInstanceUnderPos ;
bool precInstanceUnderPosValid = false ;
// reset result
isPlayerUnderCursor = false ;
_LastInstanceUnderPos = NULL ;
// build the ray
CMatrix camMatrix = MainCam . getMatrix ( ) ;
NL3D : : CFrustum camFrust = MainCam . getFrustum ( ) ;
NL3D : : CViewport viewport = Driver - > getViewport ( ) ;
// Get the Ray made by the mouse.
CTool : : CWorldViewRay worldViewRay ;
worldViewRay . OnMiniMap = false ;
worldViewRay . Valid = true ;
//
viewport . getRayWithPoint ( x , y , worldViewRay . Origin , worldViewRay . Dir , camMatrix , camFrust ) ;
worldViewRay . Dir . normalize ( ) ;
worldViewRay . Right = camMatrix . getI ( ) . normed ( ) ;
worldViewRay . Up = camMatrix . getK ( ) . normed ( ) ;
// **** Get entities with box intersecting the ray.
static std : : vector < ISelectableObject * > validObjects ;
validObjects . clear ( ) ;
static std : : vector < CSortSelectableObject > intersectedObjects ;
intersectedObjects . clear ( ) ;
ISelectableObject * precSelectableObject = NULL ;
validObjects . push_back ( & SelectableUser ) ; // add fake object for test with user entity
for ( TInstanceMap : : iterator it = _Instances . begin ( ) ; it ! = _Instances . end ( ) ; + + it )
{
CInstance * instance = it - > second ;
CDisplayerVisual * vd = instance - > getDisplayerVisual ( ) ;
if ( ! vd ) continue ;
if ( ! vd - > isSelectable ( ) ) continue ;
if ( instance = = getEditor ( ) . getSelectedInstance ( ) )
{
precSelectableObject = vd ;
}
validObjects . push_back ( vd ) ;
}
// compute intersection of mouse with landscape / batiments for test with projected object like region & decals
CVector sceneInter ;
CTool : : TRayIntersectionType rayInterType = CTool : : computeLandscapeRayIntersection ( worldViewRay , sceneInter ) ;
CSortSelectableObject selectObj ;
ISelectableObject * borderSelected = NULL ;
for ( uint k = 0 ; k < validObjects . size ( ) ; + + k )
{
ISelectableObject * object = validObjects [ k ] ;
// if entity not visible, skip
if ( object - > getLastClip ( ) )
continue ;
float depth = FLT_MAX ;
ISelectableObject : : TSelectionType selectionType = object - > getSelectionType ( ) ;
bool borderSelection = false ;
switch ( selectionType )
{
case ISelectableObject : : GroundProjected :
if ( rayInterType ! = CTool : : NoIntersection )
{
CVector2f testPos ( sceneInter . x , sceneInter . y ) ;
borderSelection = object - > isInProjectionBorder ( testPos ) ;
if ( borderSelection | | object - > isInProjection ( testPos ) )
{
depth = ( worldViewRay . Origin - sceneInter ) . norm ( ) ;
}
}
break ;
case ISelectableObject : : LocalSelectBox :
case ISelectableObject : : WorldSelectBox :
{
const CMatrix & rayMatrix = ( selectionType = = ISelectableObject : : LocalSelectBox ) ? object - > getInvertedMatrix ( )
: CMatrix : : Identity ;
selectObj . RayStart = rayMatrix * worldViewRay . Origin ;
selectObj . RayStartClipped = selectObj . RayStart ;
selectObj . RayEndClipped = rayMatrix * ( worldViewRay . Origin + worldViewRay . Dir * distSelection ) ;
// if intersect the bbox
selectObj . SelectBox = object - > getSelectBox ( ) ;
selectObj . SelectBoxInWorld = false ;
if ( selectObj . SelectBox . clipSegment ( selectObj . RayStartClipped , selectObj . RayEndClipped ) )
{
depth = ( selectObj . RayStartClipped - selectObj . RayStart ) . norm ( ) ;
// is it the last entity under pos?
if ( object - > getInstanceInEditor ( ) = = precInstanceUnderPos )
precInstanceUnderPosValid = true ;
}
}
break ;
default :
nlassert ( 0 ) ;
break ;
}
if ( depth ! = FLT_MAX )
{
selectObj . Object = object ;
selectObj . Depth = depth ;
if ( borderSelection )
{
borderSelected = object ;
}
// add this entity to the list of possible entities
intersectedObjects . push_back ( selectObj ) ;
}
}
// if no intersected entities, quit
if ( intersectedObjects . empty ( ) )
return NULL ;
// Compute startDistBox: nearest entity distance, but the user
float startDistBox ;
if ( intersectedObjects [ 0 ] . Object = = & SelectableUser )
{
// if the nearest entity is the user, set res
isPlayerUnderCursor = true ;
// if only player intersected, return NULL!
if ( intersectedObjects . size ( ) = = 1 )
return NULL ;
// so take the second for startDistBox
startDistBox = intersectedObjects [ 1 ] . Depth ;
}
else
{
// ok, take it.
startDistBox = intersectedObjects [ 0 ] . Depth ;
}
/*static std::vector<ISelectableObject *> projectedObjects;
projectedObjects . clear ( ) ; */
// **** get best entity according to distance face-camera or box-ray if no face intersection
ISelectableObject * objectSelected = NULL ;
float bestDistBox = FLT_MAX ;
float bestDistZ = FLT_MAX ;
for ( i = 0 ; i < intersectedObjects . size ( ) ; i + + )
{
ISelectableObject * object = intersectedObjects [ i ] . Object ;
// If this entity is the UserEntity, skip!!
if ( object = = & SelectableUser )
continue ;
float distZ = 0.f ;
bool preciseInterFound = false ;
ISelectableObject : : TSelectionType selectionType = object - > getSelectionType ( ) ;
switch ( selectionType )
{
case ISelectableObject : : GroundProjected :
{
// if current selection remains selected, keep it
bool keepSelection = objectSelected & &
objectSelected - > getSelectionType ( ) = = ISelectableObject : : GroundProjected & &
objectSelected = = precSelectableObject ;
if ( ! keepSelection )
{
preciseInterFound = true ;
distZ = intersectedObjects [ i ] . Depth ;
}
}
break ;
case ISelectableObject : : LocalSelectBox :
case ISelectableObject : : WorldSelectBox :
// if (!object->intersectionTest(bbox, pos, dir, dist2D, distZ, distSelection)) continue;
distZ = object - > preciseIntersectionTest ( worldViewRay . Origin , worldViewRay . Dir ) ;
if ( distZ ! = FLT_MAX )
{
preciseInterFound = true ;
}
break ;
default :
nlassert ( 0 ) ;
break ;
}
// *** if intersect face, then take the best face-intersection, else use box-ray cost
// true face-col found?
if ( preciseInterFound )
{
// yes, get the nearest
if ( distZ < = bestDistZ )
{
bestDistBox = 0 ;
bestDistZ = distZ ;
objectSelected = object ;
/*if (selectionType == ISelectableObject::GroundProjected)
{
projectedObjects . push_back ( object ) ;
} */
}
}
// else
else
{
// if a true face-intersection has not been found for others entities
if ( bestDistZ = = FLT_MAX )
{
// get the "distance to camera" contribution.
// NB: ray & select box are in the same space (local or world)
CVector c = selectObj . SelectBox . getCenter ( ) ;
float distCamCost = intersectedObjects [ i ] . Depth ;
// get relative to the nearest intersected entity
distCamCost - = startDistBox ;
// take the middle of the clipped segment. suppose that this middle is the "nearest ray point to center"
// This is false, but gives better results.
CVector m = ( selectObj . RayStartClipped + selectObj . RayEndClipped ) / 2 ;
// get the distance to center. NB: small entities are preferred since smaller mean lower cost
float outBBoxCost = ( m - c ) . norm ( ) ;
// the final cost is a weighted sum of the both. NB: distCamCost is in meter,
// and outBBBoxCost is meters. Hence ClientCfg.SelectionOutBBoxWeight is a factor
float boxCost = distCamCost + outBBoxCost * ClientCfg . SelectionOutBBoxWeight ;
// take the lowest cost
if ( boxCost < bestDistBox )
{
objectSelected = object ;
bestDistBox = boxCost ;
}
}
}
}
// If precise intersection not found
if ( bestDistZ = = FLT_MAX )
{
// if the last entity under pos is valid, prefer it among all other approximate ones
if ( precInstanceUnderPos & & precInstanceUnderPosValid )
objectSelected = precInstanceUnderPos - > getDisplayerVisual ( ) ;
}
if ( objectSelected - > getSelectionType ( ) = = ISelectableObject : : GroundProjected )
{
if ( borderSelected & & borderSelected ! = objectSelected )
{
if ( ! objectSelected | | ! objectSelected - > isInProjectionBorder ( CVector2f ( sceneInter . x , sceneInter . y ) ) )
{
// when mouse over zone border, preffered over other zones
objectSelected = borderSelected ;
}
}
// TODO nico: list not really needed here (comes from old code)
/*uint k;
for ( k = 0 ; k < projectedObjects . size ( ) ; + + k )
{
if ( projectedObjects [ k ] = = objectSelected ) break ;
}
objectSelected = projectedObjects [ ( k + 1 ) % projectedObjects . size ( ) ] ;
*/
}
// return the best entity
_LastInstanceUnderPos = objectSelected ? objectSelected - > getInstanceInEditor ( ) : NULL ;
return _LastInstanceUnderPos ;
} // getEntityUnderPos //
// *********************************************************************************************************
float CEditor : : preciseEntityIntersectionTest ( CEntityCL & entity , const NLMISC : : CVector & worldRayStart , const NLMISC : : CVector & worldRayDir )
{
//H_AUTO(R2_CEditor_preciseEntityIntersectionTest)
CHECK_EDITOR
// if entity skeleton model was clipped, skip
NL3D : : USkeleton * skeleton = entity . skeleton ( ) ;
if ( ! ClientCfg . Light & & skeleton & & ! skeleton - > getLastClippedState ( ) )
return FLT_MAX ;
H_AUTO ( RZ_Client_GEUP_face_intersect )
// *** Try get face-intersection, result in distZ
// if the entity support fast and precise intersection (and if it succeeds)
// bool trueIntersectComputed= false;
float dist2D , distZ ;
if ( ! ClientCfg . Light )
{
if ( skeleton )
{
if ( skeleton - > supportFastIntersect ( ) & & skeleton - > fastIntersect ( worldRayStart , worldRayDir , dist2D , distZ , false ) )
{
if ( dist2D = = 0.f )
{
return distZ ;
}
}
}
// get the intersection with the instance (bot object)
else if ( ! entity . instances ( ) . empty ( ) & & ! entity . instances ( ) [ 0 ] . Current . empty ( ) )
{
NL3D : : UInstance inst = entity . instances ( ) [ 0 ] . Current ;
if ( inst . supportFastIntersect ( ) )
{
if ( inst . fastIntersect ( worldRayStart , worldRayDir , dist2D , distZ , false ) )
{
if ( dist2D = = 0.f )
{
return distZ ;
}
}
}
else
{
// TMP
// precise test was asked, but there's no better test than bbox, so return the dist for bbox middle
return ( entity . pos ( ) . asVector ( ) + entity . localSelectBox ( ) . getCenter ( ) - worldRayStart ) . norm ( ) ;
}
}
}
return FLT_MAX ;
}
// *********************************************************************************************************
const NLMISC : : CAABBox & CEditor : : getLocalSelectBox ( CEntityCL & entity ) const
{
//H_AUTO(R2_CEditor_getLocalSelectBox)
CHECK_EDITOR
const TEntityCustomSelectBoxMap & boxMap = getEditor ( ) . getEntityCustomSelectBoxMap ( ) ;
TEntityCustomSelectBoxMap : : const_iterator it = boxMap . find ( CSheetId ( entity . sheetId ( ) ) . toString ( ) ) ;
if ( it ! = boxMap . end ( ) )
{
if ( it - > second . Enabled )
{
return it - > second . Box ;
}
}
return entity . localSelectBox ( ) ;
}
// *********************************************************************************************************
NLMISC : : CAABBox CEditor : : getSelectBox ( CEntityCL & entity ) const
{
//H_AUTO(R2_CEditor_getSelectBox)
CHECK_EDITOR
const TEntityCustomSelectBoxMap & boxMap = getEditor ( ) . getEntityCustomSelectBoxMap ( ) ;
TEntityCustomSelectBoxMap : : const_iterator it = boxMap . find ( CSheetId ( entity . sheetId ( ) ) . toString ( ) ) ;
if ( it ! = boxMap . end ( ) )
{
if ( it - > second . Enabled )
{
// box is local, transform in world
CMatrix modelMatrix ;
modelMatrix = entity . dirMatrix ( ) ;
modelMatrix . setPos ( entity . pos ( ) . asVector ( ) ) ;
return CAABBox : : transformAABBox ( modelMatrix , it - > second . Box ) ;
}
}
return entity . selectBox ( ) ;
}
// *********************************************************************************************************
void CEditor : : connexionMsg ( const std : : string & stringId )
{
//H_AUTO(R2_CEditor_connexionMsg)
CHECK_EDITOR
getEditor ( ) . _ConnexionMsg = stringId ;
// ignore if current ui desktop is not the third
if ( getUI ( ) . getMode ( ) ! = 3 ) return ;
// show the connection window
CInterfaceGroup * r2ConnectWindow = dynamic_cast < CInterfaceGroup * > ( getUI ( ) . getElementFromId ( " ui:interface:r2ed_connect " ) ) ;
if ( ! r2ConnectWindow ) return ;
if ( stringId . empty ( ) )
{
r2ConnectWindow - > setActive ( false ) ;
return ;
}
else
{
if ( ! r2ConnectWindow - > getActive ( ) )
{
// center for the first display
r2ConnectWindow - > setActive ( true ) ;
r2ConnectWindow - > center ( ) ;
}
CViewText * vt = dynamic_cast < CViewText * > ( r2ConnectWindow - > getView ( " connexionMsg " ) ) ;
if ( vt )
{
vt - > setText ( CI18N : : get ( stringId ) ) ;
}
}
}
// *********************************************************************************************************
void CEditor : : connect ( )
{
//H_AUTO(R2_CEditor_connect)
CHECK_EDITOR
if ( _Mode = = EditionMode | | _Mode = = AnimationModeLoading )
{
bool ok = false ;
if ( _ScenarioInstance )
{
try
{
if ( _ScenarioInstance - > getLuaProjection ( ) . callMethodByNameNoThrow ( " validateForTesting " , 0 , 1 ) )
{
if ( getLua ( ) . toBoolean ( - 1 ) = = true )
{
R2 : : getEditor ( ) . getDMC ( ) . getEditionModule ( ) . requestStartScenario ( ) ;
ok = true ;
}
}
}
catch ( const std : : exception & )
{
// 'ok' still == false ...
}
}
if ( ! ok )
{
nlwarning ( " Can't go live " ) ;
}
}
else if ( _Mode = = TestMode | | _Mode = = DMMode )
{
try
{
R2 : : getEditor ( ) . getLua ( ) . executeScript ( " r2.requestStopLive() " ) ;
if ( ClientCfg . Local )
{
R2 : : getEditor ( ) . setMode ( CEditor : : EditionMode ) ;
getLua ( ) . executeScriptNoThrow ( " r2.requestReconnection() " ) ;
}
else
{
R2 : : getEditor ( ) . setMode ( CEditor : : GoingToEditionMode ) ;
}
CEditor : : connexionMsg ( " uimR2EDGoToEditingMode " ) ;
}
catch ( const std : : exception & e )
{
nlwarning ( " Can't go live: %s " , e . what ( ) ) ;
}
}
// TODO Nico : reset the good capture keyboard
setDefaultChatWindow ( PeopleInterraction . ChatGroup . Window ) ;
ConnectionWanted = false ;
return ;
}
// *********************************************************************************************************
CEditor : : TInstanceObserverHandle CEditor : : addInstanceObserver ( const TInstanceId & instanceId , IInstanceObserver * observer )
{
//H_AUTO(R2_CEditor_addInstanceObserver)
CHECK_EDITOR
//nlwarning("#adding instance observer 0x%x", (int) observer);
nlassert ( _InstanceObservers . size ( ) = = _InstanceObserverHandles . size ( ) ) ;
const TInstanceObserverMap : : const_iterator lb = _InstanceObservers . lower_bound ( instanceId ) ;
const TInstanceObserverMap : : const_iterator ub = _InstanceObservers . upper_bound ( instanceId ) ;
// NB nico : removed the inserted twice stuff below because observer pointers are not used as keys,
// so sharing is possible
// see if not inserted twice
/*
for ( TInstanceObserverMap : : const_iterator it = lb ; it ! = ub ; + + it )
{
if ( it - > second = = observer )
{
nlwarning ( " addInstanceObserver : Instance observer inserted twice " ) ;
return BadInstanceObserverHandle ;
}
}
*/
// insert the handle
TInstanceObserverHandle handle = _InstanceObserverHandleCounter + + ;
if ( _InstanceObserverHandleCounter = = BadInstanceObserverHandle )
{
+ + _InstanceObserverHandleCounter ; // avoid bad handle
}
_InstanceObserverHandles [ handle ] = _InstanceObservers . insert ( TInstanceObserverMap : : value_type ( instanceId , observer ) ) ;
nlassert ( _InstanceObservers . size ( ) = = _InstanceObserverHandles . size ( ) ) ;
return handle ;
}
// *********************************************************************************************************
CEditor : : IInstanceObserver * CEditor : : removeInstanceObserver ( TInstanceObserverHandle handle )
{
//H_AUTO(R2_CEditor_removeInstanceObserver)
CHECK_EDITOR
nlassert ( _InstanceObservers . size ( ) = = _InstanceObserverHandles . size ( ) ) ;
TInstanceObserverHandleMap : : iterator it = _InstanceObserverHandles . find ( handle ) ;
if ( it = = _InstanceObserverHandles . end ( ) )
{
nlwarning ( " removeInstanceObserver : Instance observer handle not found : %d " , ( int ) handle ) ;
return NULL ;
}
IInstanceObserver * observer = it - > second - > second ;
//nlwarning("#removing instance observer 0x%x", (int) observer);
_InstanceObservers . erase ( it - > second ) ; // remove from observer map
_InstanceObserverHandles . erase ( it ) ;
nlassert ( _InstanceObservers . size ( ) = = _InstanceObserverHandles . size ( ) ) ;
return observer ;
}
// *********************************************************************************************************
CEditor : : IInstanceObserver * CEditor : : getInstanceObserver ( TInstanceObserverHandle handle )
{
//H_AUTO(R2_CEditor_getInstanceObserver)
CHECK_EDITOR
nlassert ( _InstanceObservers . size ( ) = = _InstanceObserverHandles . size ( ) ) ;
TInstanceObserverHandleMap : : iterator it = _InstanceObserverHandles . find ( handle ) ;
if ( it = = _InstanceObserverHandles . end ( ) )
{
return NULL ;
}
return it - > second - > second ;
}
// *********************************************************************************************************
CEditor : : TSeason CEditor : : getSeason ( ) const
{
//H_AUTO(R2_CEditor_getSeason)
if ( _IsWaitingTPForSeasonChange ) return UnknownSeason ; // as long at the teleport message hasn't been received, don't change
// the season for nothing -> pretend that we don't know the season so that it remains unchnged
return _Season ;
}
// *********************************************************************************************************
void CEditor : : tpReceived ( )
{
//H_AUTO(R2_CEditor_tpReceived)
_IsWaitingTPForSeasonChange = false ; // season can be changed now
_TPReceivedFlag = true ;
}
// *********************************************************************************************************
void CEditor : : checkMissingCollisions ( )
{
//H_AUTO(R2_CEditor_checkMissingCollisions)
CScenarioEntryPoints & sep = CScenarioEntryPoints : : getInstance ( ) ;
sep . loadCompleteIslands ( ) ;
const CScenarioEntryPoints : : TCompleteIslands & islands = sep . getCompleteIslands ( ) ;
for ( uint k = 0 ; k < islands . size ( ) ; + + k )
{
bool found = ! ( CPath : : lookup ( islands [ k ] . Island + " .packed_island " , false , false ) . empty ( ) ) ;
if ( ! found )
{
nlwarning ( " ISLAND COLLISION MISSING FOR : %s " , islands [ k ] . Island . c_str ( ) ) ;
}
found = ! ( CPath : : lookup ( islands [ k ] . Island + " .island_hm " , false , false ) . empty ( ) ) ;
if ( ! found )
{
nlwarning ( " ISLAND HEIGHTMAP MISSING FOR : %s " , islands [ k ] . Island . c_str ( ) ) ;
}
}
}
// *********************************************************************************************************
// move
class CAHEdContextMenu : public IActionHandler
{
virtual void execute ( CCtrlBase * /* pCaller */ , const std : : string & /* sParams */ )
{
getEditor ( ) . displayContextMenu ( ) ;
}
} ;
REGISTER_ACTION_HANDLER ( CAHEdContextMenu , " r2ed_context_menu " ) ;
// *********************************************************************************************************
NLMISC : : CVector getVector ( const CObject * obj )
{
return getVectorD ( obj ) . asVector ( ) ;
}
// *********************************************************************************************************
NLMISC : : CVectorD getVectorD ( const CObject * obj )
{
return CVectorD ( getNumber ( obj , " x " ) , getNumber ( obj , " y " ) , getNumber ( obj , " z " ) ) ;
}
// *********************************************************************************************************
CObject * buildVector ( const NLMISC : : CVectorD & vector , const std : : string & instanceId /*= ""*/ )
{
CObject * table ;
if ( instanceId = = " " )
{
table = getEditor ( ) . getDMC ( ) . newComponent ( " Position " ) ;
table - > set ( " x " , vector . x ) ;
table - > set ( " y " , vector . y ) ;
table - > set ( " z " , vector . z ) ;
}
else
{
table = new CObjectTableClient ;
table - > insert ( " InstanceId " , new CObjectString ( instanceId ) ) ;
table - > insert ( " Class " , new CObjectString ( " Position " ) ) ;
table - > insert ( " x " , new CObjectNumber ( vector . x ) ) ;
table - > insert ( " y " , new CObjectNumber ( vector . y ) ) ;
table - > insert ( " z " , new CObjectNumber ( vector . z ) ) ;
}
return table ;
}
// *********************************************************************************************************
const CObject * getObject ( const CObject * obj , const std : : string & attrName )
{
if ( ! obj ) return NULL ;
return getEditor ( ) . getDMC ( ) . getPropertyAccessor ( ) . getPropertyValue ( obj , attrName ) ;
}
// *********************************************************************************************************
std : : string getString ( const CObject * obj , const std : : string & attrName )
{
obj = getObject ( obj , attrName ) ;
if ( ! obj ) return " " ;
return obj - > isString ( ) ? obj - > toString ( ) : " " ;
}
// *********************************************************************************************************
double getNumber ( const CObject * obj , const std : : string & attrName )
{
obj = getObject ( obj , attrName ) ;
if ( ! obj ) return 0 ;
return obj - > isNumber ( ) ? obj - > toNumber ( ) : 0 ;
}
bool isEditionCurrent ( )
{
CEditor & ed = getEditor ( ) ;
return ClientCfg . R2EDEnabled & & ed . getMode ( ) = = CEditor : : EditionMode ;
}
// *********************************************************************************************************
void CEditor : : onContinentChanged ( )
{
//H_AUTO(R2_CEditor_onContinentChanged)
if ( _Mode ! = EditionMode ) return ;
// refresh all collisions
if ( _ScenarioInstance )
{
struct CContinentChangedVisitor : public IInstanceVisitor
{
virtual void visit ( CInstance & inst )
{
inst . onContinentChanged ( ) ;
}
} ;
CContinentChangedVisitor continentChangedVisitor ;
_ScenarioInstance - > visit ( continentChangedVisitor ) ;
}
}
//-----------------------------
bool CEditor : : getVisualPropertiesFromObject ( CObject * object , SPropVisualA & vA , SPropVisualB & vB , SPropVisualC & vC )
{
//H_AUTO(R2_CEditor_getVisualPropertiesFromObject)
std : : string sheetClient = getString ( object , " SheetClient " ) ;
const CEntitySheet * entitySheet = SheetMngr . get ( CSheetId ( sheetClient ) ) ;
if ( ! entitySheet )
{
nlwarning ( " Can't find client sheet %s " , sheetClient . c_str ( ) ) ;
return false ;
}
CSheetId sheetId ( sheetClient ) ;
if ( sheetId = = CSheetId : : Unknown )
{
nlwarning ( " Can't get sheet " ) ;
return false ;
}
//-------------------------random init npc visual properties
std : : map < std : : string , double > visualProps ;
static const char * keys [ ] = { " GabaritHeight " , " GabaritTorsoWidth " , " GabaritArmsWidth " , " GabaritLegsWidth " , " GabaritBreastSize "
, " HairType " , " HairColor " , " Tattoo " , " EyesColor "
, " MorphTarget1 " , " MorphTarget2 " , " MorphTarget3 " , " MorphTarget4 "
, " MorphTarget5 " , " MorphTarget6 " , " MorphTarget7 " , " MorphTarget8 "
, " JacketModel " , " TrouserModel " , " FeetModel " , " HandsModel "
, " ArmModel " , " WeaponRightHand " , " WeaponLeftHand "
, " JacketColor " , " ArmColor " , " HandsColor "
, " TrouserColor " , " FeetColor " } ;
unsigned int first = 0 ;
unsigned int last = sizeof ( keys ) / sizeof ( keys [ 0 ] ) ;
for ( ; first ! = last ; + + first )
{
visualProps [ keys [ first ] ] = getNumber ( object , keys [ first ] ) ;
}
//vA.PropertySubData.Sex = (uint) visualProps["Sex"];
if ( entitySheet )
{
const CCharacterSheet * chSheet = dynamic_cast < const CCharacterSheet * > ( entitySheet ) ;
if ( chSheet )
{
vA . PropertySubData . Sex = ( chSheet - > Gender = = GSGENDER : : female ) ;
}
}
vC . PropertySubData . CharacterHeight = ( uint ) visualProps [ " GabaritHeight " ] ;
vC . PropertySubData . ArmsWidth = ( uint ) visualProps [ " GabaritArmsWidth " ] ;
vC . PropertySubData . TorsoWidth = ( uint ) visualProps [ " GabaritTorsoWidth " ] ;
vC . PropertySubData . LegsWidth = ( uint ) visualProps [ " GabaritLegsWidth " ] ;
vC . PropertySubData . BreastSize = ( uint ) visualProps [ " GabaritBreastSize " ] ;
int itemNb = ( int ) visualProps [ " HairType " ] ;
std : : string itemFileName ;
if ( itemNb > 0 )
{
itemFileName = CSheetId ( itemNb ) . toString ( ) ;
vA . PropertySubData . HatModel = ( uint ) SheetMngr . getVSIndex ( itemFileName , SLOTTYPE : : HEAD_SLOT ) ;
}
else
{
vA . PropertySubData . HatModel = 0 ;
}
vA . PropertySubData . HatColor = ( uint ) visualProps [ " HairColor " ] ;
vC . PropertySubData . Tattoo = ( uint ) visualProps [ " Tattoo " ] ;
vC . PropertySubData . EyesColor = ( uint ) visualProps [ " EyesColor " ] ;
vC . PropertySubData . MorphTarget1 = ( uint ) visualProps [ " MorphTarget1 " ] ;
vC . PropertySubData . MorphTarget2 = ( uint ) visualProps [ " MorphTarget2 " ] ;
vC . PropertySubData . MorphTarget3 = ( uint ) visualProps [ " MorphTarget3 " ] ;
vC . PropertySubData . MorphTarget4 = ( uint ) visualProps [ " MorphTarget4 " ] ;
vC . PropertySubData . MorphTarget5 = ( uint ) visualProps [ " MorphTarget5 " ] ;
vC . PropertySubData . MorphTarget6 = ( uint ) visualProps [ " MorphTarget6 " ] ;
vC . PropertySubData . MorphTarget7 = ( uint ) visualProps [ " MorphTarget7 " ] ;
vC . PropertySubData . MorphTarget8 = ( uint ) visualProps [ " MorphTarget8 " ] ;
itemNb = ( int ) visualProps [ " JacketModel " ] ;
if ( itemNb > 0 )
{
itemFileName = CSheetId ( itemNb ) . toString ( ) ;
vA . PropertySubData . JacketModel = ( uint ) SheetMngr . getVSIndex ( itemFileName , SLOTTYPE : : CHEST_SLOT ) ;
}
else
{
vA . PropertySubData . JacketModel = 0 ;
}
itemNb = ( int ) visualProps [ " TrouserModel " ] ;
if ( itemNb > 0 )
{
itemFileName = CSheetId ( itemNb ) . toString ( ) ;
vA . PropertySubData . TrouserModel = ( uint ) SheetMngr . getVSIndex ( itemFileName , SLOTTYPE : : LEGS_SLOT ) ;
}
else
{
vA . PropertySubData . TrouserModel = 0 ;
}
itemNb = ( int ) visualProps [ " FeetModel " ] ;
if ( itemNb > 0 )
{
itemFileName = CSheetId ( itemNb ) . toString ( ) ;
vB . PropertySubData . FeetModel = ( uint ) SheetMngr . getVSIndex ( itemFileName , SLOTTYPE : : FEET_SLOT ) ;
}
else
{
vB . PropertySubData . FeetModel = 0 ;
}
itemNb = ( int ) visualProps [ " HandsModel " ] ;
if ( itemNb > 0 )
{
itemFileName = CSheetId ( itemNb ) . toString ( ) ;
vB . PropertySubData . HandsModel = ( uint ) SheetMngr . getVSIndex ( itemFileName , SLOTTYPE : : HANDS_SLOT ) ;
}
else
{
vB . PropertySubData . HandsModel = 0 ;
}
itemNb = ( int ) visualProps [ " ArmModel " ] ;
if ( itemNb > 0 )
{
itemFileName = CSheetId ( itemNb ) . toString ( ) ;
vA . PropertySubData . ArmModel = ( uint ) SheetMngr . getVSIndex ( itemFileName , SLOTTYPE : : ARMS_SLOT ) ;
}
else
{
vA . PropertySubData . ArmModel = 0 ;
}
vA . PropertySubData . JacketColor = ( uint ) visualProps [ " JacketColor " ] ;
vA . PropertySubData . TrouserColor = ( uint ) visualProps [ " TrouserColor " ] ;
vB . PropertySubData . FeetColor = ( uint ) visualProps [ " FeetColor " ] ;
vB . PropertySubData . HandsColor = ( uint ) visualProps [ " HandsColor " ] ;
vA . PropertySubData . ArmColor = ( uint ) visualProps [ " ArmColor " ] ;
itemNb = ( int ) visualProps [ " WeaponRightHand " ] ;
if ( itemNb > 0 )
{
itemFileName = CSheetId ( itemNb ) . toString ( ) ;
vA . PropertySubData . WeaponRightHand = ( uint ) SheetMngr . getVSIndex ( itemFileName , SLOTTYPE : : RIGHT_HAND_SLOT ) ;
}
else
{
vA . PropertySubData . WeaponRightHand = 0 ;
}
itemNb = ( int ) visualProps [ " WeaponLeftHand " ] ;
if ( itemNb > 0 )
{
itemFileName = CSheetId ( itemNb ) . toString ( ) ;
vA . PropertySubData . WeaponLeftHand = ( uint ) SheetMngr . getVSIndex ( itemFileName , SLOTTYPE : : LEFT_HAND_SLOT ) ;
}
else
{
vA . PropertySubData . WeaponLeftHand = 0 ;
}
return true ;
}
// *********************************************************************************************************
bool CEditor : : CSortedInstances : : contains ( CInstance * inst ) const
{
TInstanceToIter : : const_iterator it = _InstanceToIter . find ( inst ) ;
# ifdef NL_DEBUG
if ( it = = _InstanceToIter . end ( ) )
{
for ( TInstanceByName : : const_iterator it = _ByName . begin ( ) ; it ! = _ByName . end ( ) ; + + it )
{
nlassert ( it - > second ! = inst ) ; // should be empty
}
}
# endif
return it ! = _InstanceToIter . end ( ) ;
}
// *********************************************************************************************************
void CEditor : : CSortedInstances : : insert ( const ucstring & name , CInstance * inst )
{
nlassert ( inst ) ;
# ifdef NL_DEBUG
static volatile bool doTest = true ;
if ( doTest )
{
nlassert ( ! contains ( inst ) ) ; // inserted twice !!
}
# endif
_InstanceToIter [ inst ] = _ByName . insert ( std : : make_pair ( name , inst ) ) ;
}
// *********************************************************************************************************
void CEditor : : CSortedInstances : : remove ( CInstance * inst )
{
nlassert ( inst ) ;
TInstanceToIter : : iterator it = _InstanceToIter . find ( inst ) ;
nlassert ( it ! = _InstanceToIter . end ( ) ) ;
_ByName . erase ( it - > second ) ;
_InstanceToIter . erase ( it ) ;
# ifdef NL_DEBUG
nlassert ( ! contains ( inst ) ) ;
# endif
}
// *********************************************************************************************************
bool CEditor : : isRegisteredByDispName ( CInstance * inst ) const
{
nlassert ( inst ) ;
for ( uint k = 0 ; k < _InstancesByDispName . size ( ) ; + + k )
{
if ( _InstancesByDispName [ k ] . contains ( inst ) ) return true ; // registered twice !!
}
return false ;
}
// *********************************************************************************************************
void CEditor : : registerInstanceDispName ( const ucstring & displayName , CInstance * inst )
{
nlassert ( inst ) ;
sint currClass = inst - > getClassIndex ( ) ;
if ( currClass < 0 )
{
nlwarning ( " Classindex not found for class %s " , inst - > getClassName ( ) . c_str ( ) ) ;
return ;
}
# ifdef NL_DEBUG
nlassert ( ! isRegisteredByDispName ( inst ) ) ;
# endif
// for each class & subclass of the object, insert in the matching list
while ( currClass > = 0 )
{
nlassert ( currClass < ( sint ) _InstancesByDispName . size ( ) ) ;
_InstancesByDispName [ currClass ] . insert ( displayName , inst ) ;
currClass = getBaseClass ( currClass ) ;
}
//
# ifdef NL_DEBUG
nlassert ( isRegisteredByDispName ( inst ) ) ;
# endif
}
// *********************************************************************************************************
void CEditor : : unregisterInstanceDispName ( CInstance * inst )
{
nlassert ( inst ) ;
sint currClass = inst - > getClassIndex ( ) ;
if ( currClass < 0 )
{
nlwarning ( " Classindex not found for class %s " , inst - > getClassName ( ) . c_str ( ) ) ;
return ;
}
# ifdef NL_DEBUG
nlassert ( isRegisteredByDispName ( inst ) ) ;
# endif
while ( currClass > = 0 )
{
nlassert ( currClass < ( sint ) _InstancesByDispName . size ( ) ) ;
_InstancesByDispName [ currClass ] . remove ( inst ) ;
currClass = getBaseClass ( currClass ) ;
}
# ifdef NL_DEBUG
nlassert ( ! isRegisteredByDispName ( inst ) ) ;
# endif
}
// *********************************************************************************************************
//
// Creation of a new entity in scene
//
class CAHCreateEntity : public IActionHandler
{
virtual void execute ( CCtrlBase * /* pCaller */ , const std : : string & sParams )
{
CHECK_EDITOR
if ( getEditor ( ) . getMode ( ) ! = CEditor : : EditionMode )
{
nlwarning ( " Can't modify scenario while testing " ) ;
return ;
}
CInterfaceManager * im = CInterfaceManager : : getInstance ( ) ;
// Retrieve sheet for entity that is to be created.
std : : string paletteId = getParam ( sParams , " PaletteId " ) ;
CObject * paletteNode = getEditor ( ) . getDMC ( ) . getPaletteElement ( paletteId ) ;
if ( ! paletteNode )
{
nlwarning ( " Can't retrieve palette node for id %s " , paletteId . c_str ( ) ) ;
return ;
}
if ( ! paletteNode - > isTable ( ) )
{
nlwarning ( " Bad type for palette node %s (should be a table) " , paletteId . c_str ( ) ) ;
return ;
}
std : : string sheetClient = getString ( paletteNode , " SheetClient " ) ;
const CEntitySheet * entitySheet = SheetMngr . get ( CSheetId ( sheetClient ) ) ;
if ( ! entitySheet )
{
nlwarning ( " Can't find client sheet %s " , sheetClient . c_str ( ) ) ;
return ;
}
const CCharacterSheet * chSheet = dynamic_cast < const CCharacterSheet * > ( entitySheet ) ;
if ( chSheet - > R2Npc )
{
getEditor ( ) . getLua ( ) . push ( sheetClient ) ;
if ( getEditor ( ) . getEnv ( ) . callMethodByNameNoThrow ( " randomNPCSex " , 1 , 1 ) )
{
CLuaObject result ( getEditor ( ) . getLua ( ) ) ;
sheetClient = result . toString ( ) ;
}
}
CSheetId sheetId ( sheetClient ) ;
if ( sheetId = = CSheetId : : Unknown )
{
nlwarning ( " Can't get sheet " ) ;
return ;
}
getEditor ( ) . setCurrentTool ( NULL ) ; // remove current to avoid to have ghost removed by that tool if it was a "CToolCreateEntity" too.
uint ghostSlot = 1 ; // TMP TMP
CEntityCL * entity = NULL ;
if ( ! ( entity = CEditor : : createEntity ( ghostSlot , sheetId , CVector : : Null , 0.f ) ) )
{
return ;
}
//-------------------------random init npc visual properties
if ( dynamic_cast < CPlayerR2CL * > ( entity ) )
{
// push equipment id
getEditor ( ) . getLua ( ) . push ( getString ( paletteNode , " Equipment " ) ) ;
// push race
std : : string race ;
switch ( entity - > people ( ) )
{
case EGSPD : : CPeople : : Fyros :
race = " Fyros " ;
break ;
case EGSPD : : CPeople : : Matis :
race = " Matis " ;
break ;
case EGSPD : : CPeople : : Tryker :
race = " Tryker " ;
break ;
case EGSPD : : CPeople : : Zorai :
race = " Zorai " ;
break ;
default :
nlwarning ( " CAHCreateEntity::execute unknown people " ) ;
}
getEditor ( ) . getLua ( ) . push ( race ) ;
if ( getEditor ( ) . getEnv ( ) . callMethodByNameNoThrow ( " randomNPCProperties " , 2 , 1 ) )
{
CLuaObject result ( getEditor ( ) . getLua ( ) ) ;
std : : map < std : : string , double > visualProps ;
ENUM_LUA_TABLE ( result , it )
{
visualProps [ it . nextKey ( ) . toString ( ) ] = it . nextValue ( ) . toNumber ( ) ;
}
// visual property A depends on the type of the entity
SPropVisualA vA ;
SPropVisualB vB ;
SPropVisualC vC ;
sint64 * prop = 0 ;
//vA.PropertySubData.Sex = (uint) visualProps["Sex"];
const CEntitySheet * entitySheet = SheetMngr . get ( ( CSheetId ) sheetId . asInt ( ) ) ;
if ( entitySheet )
{
const CCharacterSheet * chSheet = dynamic_cast < const CCharacterSheet * > ( entitySheet ) ;
if ( chSheet )
{
vA . PropertySubData . Sex = ( chSheet - > Gender = = GSGENDER : : female ) ;
}
}
vC . PropertySubData . CharacterHeight = ( uint ) visualProps [ " GabaritHeight " ] ;
vC . PropertySubData . ArmsWidth = ( uint ) visualProps [ " GabaritArmsWidth " ] ;
vC . PropertySubData . TorsoWidth = ( uint ) visualProps [ " GabaritTorsoWidth " ] ;
vC . PropertySubData . LegsWidth = ( uint ) visualProps [ " GabaritLegsWidth " ] ;
vC . PropertySubData . BreastSize = ( uint ) visualProps [ " GabaritBreastSize " ] ;
int itemNb = ( int ) visualProps [ " HairType " ] ;
std : : string itemFileName ;
if ( itemNb > 0 )
{
itemFileName = CSheetId ( itemNb ) . toString ( ) ;
vA . PropertySubData . HatModel = ( uint ) SheetMngr . getVSIndex ( itemFileName , SLOTTYPE : : HEAD_SLOT ) ;
}
else
{
vA . PropertySubData . HatModel = 0 ;
}
vA . PropertySubData . HatColor = ( uint ) visualProps [ " HairColor " ] ;
vC . PropertySubData . Tattoo = ( uint ) visualProps [ " Tattoo " ] ;
vC . PropertySubData . EyesColor = ( uint ) visualProps [ " EyesColor " ] ;
vC . PropertySubData . MorphTarget1 = ( uint ) visualProps [ " MorphTarget1 " ] ;
vC . PropertySubData . MorphTarget2 = ( uint ) visualProps [ " MorphTarget2 " ] ;
vC . PropertySubData . MorphTarget3 = ( uint ) visualProps [ " MorphTarget3 " ] ;
vC . PropertySubData . MorphTarget4 = ( uint ) visualProps [ " MorphTarget4 " ] ;
vC . PropertySubData . MorphTarget5 = ( uint ) visualProps [ " MorphTarget5 " ] ;
vC . PropertySubData . MorphTarget6 = ( uint ) visualProps [ " MorphTarget6 " ] ;
vC . PropertySubData . MorphTarget7 = ( uint ) visualProps [ " MorphTarget7 " ] ;
vC . PropertySubData . MorphTarget8 = ( uint ) visualProps [ " MorphTarget8 " ] ;
itemNb = ( int ) visualProps [ " JacketModel " ] ;
if ( itemNb > 0 )
{
itemFileName = CSheetId ( itemNb ) . toString ( ) ;
vA . PropertySubData . JacketModel = ( uint ) SheetMngr . getVSIndex ( itemFileName , SLOTTYPE : : CHEST_SLOT ) ;
}
else
{
vA . PropertySubData . JacketModel = 0 ;
}
itemNb = ( int ) visualProps [ " TrouserModel " ] ;
if ( itemNb > 0 )
{
itemFileName = CSheetId ( itemNb ) . toString ( ) ;
vA . PropertySubData . TrouserModel = ( uint ) SheetMngr . getVSIndex ( itemFileName , SLOTTYPE : : LEGS_SLOT ) ;
}
else
{
vA . PropertySubData . TrouserModel = 0 ;
}
itemNb = ( int ) visualProps [ " FeetModel " ] ;
if ( itemNb > 0 )
{
itemFileName = CSheetId ( itemNb ) . toString ( ) ;
vB . PropertySubData . FeetModel = ( uint ) SheetMngr . getVSIndex ( itemFileName , SLOTTYPE : : FEET_SLOT ) ;
}
else
{
vB . PropertySubData . FeetModel = 0 ;
}
itemNb = ( int ) visualProps [ " HandsModel " ] ;
if ( itemNb > 0 )
{
itemFileName = CSheetId ( itemNb ) . toString ( ) ;
vB . PropertySubData . HandsModel = ( uint ) SheetMngr . getVSIndex ( itemFileName , SLOTTYPE : : HANDS_SLOT ) ;
}
else
{
vB . PropertySubData . HandsModel = 0 ;
}
itemNb = ( int ) visualProps [ " ArmModel " ] ;
if ( itemNb > 0 )
{
itemFileName = CSheetId ( itemNb ) . toString ( ) ;
vA . PropertySubData . ArmModel = ( uint ) SheetMngr . getVSIndex ( itemFileName , SLOTTYPE : : ARMS_SLOT ) ;
}
else
{
vA . PropertySubData . ArmModel = 0 ;
}
vA . PropertySubData . JacketColor = ( uint ) visualProps [ " JacketColor " ] ;
vA . PropertySubData . TrouserColor = ( uint ) visualProps [ " TrouserColor " ] ;
vB . PropertySubData . FeetColor = ( uint ) visualProps [ " FeetColor " ] ;
vB . PropertySubData . HandsColor = ( uint ) visualProps [ " HandsColor " ] ;
vA . PropertySubData . ArmColor = ( uint ) visualProps [ " ArmColor " ] ;
itemNb = ( int ) visualProps [ " WeaponRightHand " ] ;
if ( itemNb > 0 )
{
itemFileName = CSheetId ( itemNb ) . toString ( ) ;
vA . PropertySubData . WeaponRightHand = ( uint ) SheetMngr . getVSIndex ( itemFileName , SLOTTYPE : : RIGHT_HAND_SLOT ) ;
}
else
{
vA . PropertySubData . WeaponRightHand = 0 ;
}
itemNb = ( int ) visualProps [ " WeaponLeftHand " ] ;
if ( itemNb > 0 )
{
itemFileName = CSheetId ( itemNb ) . toString ( ) ;
vA . PropertySubData . WeaponLeftHand = ( uint ) SheetMngr . getVSIndex ( itemFileName , SLOTTYPE : : LEFT_HAND_SLOT ) ;
}
else
{
vA . PropertySubData . WeaponLeftHand = 0 ;
}
prop = ( sint64 * ) & vA ;
im - > getDbProp ( " SERVER:Entities:E " + toString ( " %d " , entity - > slot ( ) ) + " :P " + toString ( " %d " , CLFECOMMON : : PROPERTY_VPA ) ) - > setValue64 ( * prop ) ;
prop = ( sint64 * ) & vB ;
im - > getDbProp ( " SERVER:Entities:E " + toString ( " %d " , entity - > slot ( ) ) + " :P " + toString ( " %d " , CLFECOMMON : : PROPERTY_VPB ) ) - > setValue64 ( * prop ) ;
prop = ( sint64 * ) & vC ;
im - > getDbProp ( " SERVER:Entities:E " + toString ( " %d " , entity - > slot ( ) ) + " :P " + toString ( " %d " , CLFECOMMON : : PROPERTY_VPC ) ) - > setValue64 ( * prop ) ;
EntitiesMngr . updateVisualProperty ( 0 , entity - > slot ( ) , CLFECOMMON : : PROPERTY_VPA ) ;
EntitiesMngr . updateVisualProperty ( 0 , entity - > slot ( ) , CLFECOMMON : : PROPERTY_VPB ) ;
EntitiesMngr . updateVisualProperty ( 0 , entity - > slot ( ) , CLFECOMMON : : PROPERTY_VPC ) ;
}
}
getEditor ( ) . setCurrentTool ( new CToolCreateEntity ( ghostSlot , paletteId , im - > getDbProp ( " UI:TEMP:R2_DRAW_ARRAY " ) - > getValueBool ( ) ) ) ;
}
} ;
REGISTER_ACTION_HANDLER ( CAHCreateEntity , " r2ed_create_entity " ) ;
// *********************************************************************************************************
sint CEditor : : classToIndex ( const std : : string & className ) const
{
CHashMap < std : : string , uint > : : const_iterator it = _ClassNameToIndex . find ( className ) ;
if ( it = = _ClassNameToIndex . end ( ) ) return - 1 ;
return it - > second ;
}
// *********************************************************************************************************
bool CEditor : : isKindOf ( sint testedClassIndex , sint kindClassIndex ) const
{
if ( testedClassIndex < 0 | | kindClassIndex < 0 ) return false ;
return _KindOfTable ( testedClassIndex , kindClassIndex ) ! = 0 ;
}
// *********************************************************************************************************
void CEditor : : initClassInheritanceTable ( )
{
std : : vector < std : : string > classes ;
std : : map < std : : string , std : : string > baseClasses ;
ENUM_LUA_TABLE ( getClasses ( ) , it )
{
CLuaObject name = it . nextValue ( ) [ " Name " ] ;
CLuaObject base = it . nextValue ( ) [ " BaseClass " ] ;
std : : string baseName ;
if ( base . isString ( ) )
{
baseName = base . toString ( ) ;
}
if ( name . isString ( ) )
{
2010-05-13 20:45:24 +00:00
_ClassNameToIndex [ name . toString ( ) ] = ( uint ) classes . size ( ) ;
2010-05-06 00:08:41 +00:00
classes . push_back ( name . toString ( ) ) ;
baseClasses [ name . toString ( ) ] = baseName ;
}
}
2010-05-13 20:45:24 +00:00
_KindOfTable . init ( ( uint ) classes . size ( ) , ( uint ) classes . size ( ) , 0 ) ;
2010-05-06 00:08:41 +00:00
_BaseClassIndices . resize ( classes . size ( ) ) ;
for ( uint k = 0 ; k < classes . size ( ) ; + + k )
{
//nlwarning("Class %d = %s", (int) k, classes[k].c_str());
_BaseClassIndices [ k ] = classToIndex ( baseClasses [ classes [ k ] ] ) ;
for ( uint l = 0 ; l < classes . size ( ) ; + + l )
{
std : : string currClass = classes [ k ] ;
while ( ! currClass . empty ( ) )
{
if ( currClass = = classes [ l ] )
{
_KindOfTable ( k , l ) = 1 ;
break ;
}
currClass = baseClasses [ currClass ] ;
}
}
}
_InstancesByDispName . clear ( ) ;
_InstancesByDispName . resize ( classes . size ( ) ) ;
}
// *********************************************************************************************************
sint CEditor : : getBaseClass ( sint derivedClass ) const
{
if ( derivedClass < 0 | | derivedClass > = ( sint ) _BaseClassIndices . size ( ) ) return - 1 ;
return _BaseClassIndices [ derivedClass ] ;
}
// *********************************************************************************************************
void CEditor : : setMaxVisibleEntityExceededFlag ( bool on )
{
if ( on = = _MaxVisibleEntityExceededFlag ) return ;
_MaxVisibleEntityExceededFlag = on ;
// lua ui update
CLuaStackChecker lsc ( & getLua ( ) , 0 ) ;
getLua ( ) . push ( on ) ;
callEnvMethod ( " setMaxVisibleEntityExceededFlag " , 1 , 0 ) ;
}
// *********************************************************************************************************
class CAHGoTest : public IActionHandler
{
virtual void execute ( CCtrlBase * /* pCaller */ , const std : : string & /* sParams */ )
{
CHECK_EDITOR
ConnectionWanted = true ;
}
} ;
REGISTER_ACTION_HANDLER ( CAHGoTest , " r2ed_go_test " ) ;
// *********************************************************************************************************
class CAHStopTest : public IActionHandler
{
virtual void execute ( CCtrlBase * /* pCaller */ , const std : : string & /* sParams */ )
{
CHECK_EDITOR
if ( getEditor ( ) . getAccessMode ( ) ! = CEditor : : AccessEditor ) return ;
ConnectionWanted = true ;
}
} ;
REGISTER_ACTION_HANDLER ( CAHStopTest , " r2ed_stop_test " ) ;
// *********************************************************************************************************
class CAHOpenScenarioControl : public IActionHandler
{
virtual void execute ( CCtrlBase * /* pCaller */ , const std : : string & sParams )
{
CHECK_EDITOR
bool openUI = true ;
bool showHide = ( getParam ( sParams , " showHide " ) = = " 1 " ) ;
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
CInterfaceGroup * wnd = NULL ;
if ( ! R2 : : getEditor ( ) . isInitialized ( ) )
wnd = dynamic_cast < CInterfaceGroup * > ( pIM - > getElementFromId ( " ui:interface:ring_scenario_loading_window " ) ) ;
else
wnd = dynamic_cast < CInterfaceGroup * > ( pIM - > getElementFromId ( " ui:interface:r2ed_scenario_control " ) ) ;
if ( wnd )
{
if ( showHide )
openUI = ! wnd - > getActive ( ) ;
wnd - > setActive ( openUI ) ;
}
//}
}
} ;
REGISTER_ACTION_HANDLER ( CAHOpenScenarioControl , " open_scenario_control " ) ;
// *********************************************************************************************************
class CAHR2StopLive : public IActionHandler
{
virtual void execute ( CCtrlBase * /* pCaller */ , const std : : string & sParams )
{
CHECK_EDITOR
bool confirmStopLive = getParam ( sParams , " confirmStopLive " ) = = " 1 " ;
if ( ! confirmStopLive )
{
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
pIM - > validMessageBox ( CInterfaceManager : : QuestionIconMsg , CI18N : : get ( " uiR2EDconfirmStopLive " ) , " r2_stop_live " , " confirmStopLive=1 " , " " , " " , " ui:interface " ) ;
}
else
{
CSessionBrowserImpl & sb = CSessionBrowserImpl : : getInstance ( ) ;
sb . closeSession ( sb . getCharId ( ) , R2 : : getEditor ( ) . getDMC ( ) . getEditionModule ( ) . getCurrentAdventureId ( ) ) ;
if ( sb . waitOneMessage ( sb . getMessageName ( " on_invokeResult " ) ) )
{
if ( R2 : : getEditor ( ) . getDMC ( ) . getEditionModule ( ) . getEditSessionLink ( ) ! = 0 )
{
// Now we expect to receive an impulsion FAR_TP to mainland, triggered
// by the DSS. We'll disobey it by FarTPing to the Edition session instead!
nldebug ( " Will return to editing session %u " , R2 : : getEditor ( ) . getDMC ( ) . getEditionModule ( ) . getEditSessionLink ( ) ) ;
FarTP . hookNextFarTPForEditor ( ) ;
}
// otherwise, let accomplish the FAR_TP to mainland (returnToPreviousSession)
// triggered by the DSS.
}
else
{
nlwarning ( " closeSession callback return false " ) ;
}
}
}
} ;
REGISTER_ACTION_HANDLER ( CAHR2StopLive , " r2_stop_live " ) ;
// *********************************************************************************************************
class CAHInviteCharacter : public IActionHandler
{
virtual void execute ( CCtrlBase * pCaller , const std : : string & /* sParams */ )
{
CHECK_EDITOR
CInterfaceManager * pIM = CInterfaceManager : : getInstance ( ) ;
pIM - > runActionHandler ( " leave_modal " , pCaller , " " ) ;
if ( pCaller )
{
CInterfaceGroup * fatherGC = pCaller - > getParent ( ) ;
if ( fatherGC )
{
// Look for the root parent
for ( ; ; )
{
CInterfaceGroup * parent = fatherGC - > getParent ( ) ;
if ( ! parent | | ( parent - > getId ( ) = = " ui:interface " ) )
break ;
fatherGC = parent ;
}
// Get the modal edit box
CGroupEditBox * geb = dynamic_cast < CGroupEditBox * > ( fatherGC - > getGroup ( " add_contact_eb:eb " ) ) ;
if ( geb & & ! geb - > getInputString ( ) . empty ( ) )
{
string charName = geb - > getInputString ( ) . toString ( ) ;
CSessionBrowserImpl & sessionBrowser = CSessionBrowserImpl : : getInstance ( ) ;
sessionBrowser . inviteCharacterByName ( sessionBrowser . getCharId ( ) , charName ) ;
if ( ! sessionBrowser . waitOneMessage ( sessionBrowser . getMessageName ( " on_invokeResult " ) ) )
{
nlwarning ( " inviteCharacterByName callback return false " ) ;
}
if ( sessionBrowser . _LastInvokeResult = = 14 )
{
CViewText * pVT = dynamic_cast < CViewText * > ( pIM - > getElementFromId ( " ui:interface:warning_free_trial:text " ) ) ;
if ( pVT ! = NULL )
pVT - > setText ( CI18N : : get ( " uiRingWarningInviteFreeTrial " ) ) ;
pIM - > runActionHandler ( " enter_modal " , pCaller , " group=ui:interface:warning_free_trial " ) ;
}
else if ( sessionBrowser . _LastInvokeResult = = 12 )
{
pIM - > runActionHandler ( " enter_modal " , pCaller , " group=ui:interface:warning_newcomer " ) ;
}
geb - > setInputString ( ucstring ( " " ) ) ;
}
}
}
}
} ;
REGISTER_ACTION_HANDLER ( CAHInviteCharacter , " r2ed_invite_character " ) ;
// *********************************************************************************************************
class CAHTryGoTest : public IActionHandler
{
virtual void execute ( CCtrlBase * /* pCaller */ , const std : : string & /* sParams */ )
{
CHECK_EDITOR
getEditor ( ) . callEnvMethod ( " tryGoTest " , 0 , 0 ) ;
}
} ;
REGISTER_ACTION_HANDLER ( CAHTryGoTest , " r2ed_try_go_test " ) ;
// *********************************************************************************************************
class CAHCancelTool : public IActionHandler
{
virtual void execute ( CCtrlBase * /* pCaller */ , const std : : string & /* sParams */ )
{
if ( ! ClientCfg . R2EDEnabled | | ! getEditor ( ) . isInitialized ( ) ) return ;
CHECK_EDITOR
getEditor ( ) . setCurrentTool ( NULL ) ;
}
} ;
REGISTER_ACTION_HANDLER ( CAHCancelTool , " r2ed_cancel_tool " ) ;
//////////////////////////////////////////
// SWITCH DM / TESTER AT ANIMATION TIME //
//////////////////////////////////////////
// *********************************************************************************************************
class CAHAnimTestMode : public IActionHandler
{
virtual void execute ( CCtrlBase * /* pCaller */ , const std : : string & /* sParams */ )
{
CHECK_EDITOR
if ( getEditor ( ) . getAccessMode ( ) = = CEditor : : AccessDM ) return ;
getEditor ( ) . setMode ( CEditor : : TestMode ) ;
}
} ;
REGISTER_ACTION_HANDLER ( CAHAnimTestMode , " r2ed_anim_test_mode " ) ;
// *********************************************************************************************************
class CAHAnimDMMode : public IActionHandler
{
virtual void execute ( CCtrlBase * /* pCaller */ , const std : : string & /* sParams */ )
{
CHECK_EDITOR
getEditor ( ) . setMode ( CEditor : : DMMode ) ;
}
} ;
REGISTER_ACTION_HANDLER ( CAHAnimDMMode , " r2ed_anim_dm_mode " ) ;
// *********************************************************************************************************
class CAHR2ContextCommand : public IActionHandler
{
virtual void execute ( CCtrlBase * /* pCaller */ , const std : : string & sParams )
{
CHECK_EDITOR
// forward the call to lua
// first param is the id of the command
std : : string commandId = getParam ( sParams , " commandId " ) ;
// if there's a current active tool, then see if it wants to handle it first
if ( commandId = = " delete " )
{
if ( getEditor ( ) . getCurrentTool ( ) & & getEditor ( ) . getCurrentTool ( ) - > onDeleteCmd ( ) )
return ;
}
getEditor ( ) . getLua ( ) . push ( commandId ) ;
getEditor ( ) . callEnvMethod ( " execContextCommand " , 1 , 0 ) ;
}
} ;
REGISTER_ACTION_HANDLER ( CAHR2ContextCommand , " r2ed_context_command " ) ;
// *********************************************************************************************************
class CAHR2Teleport : public IActionHandler
{
virtual void execute ( CCtrlBase * /* pCaller */ , const std : : string & /* sParams */ )
{
if ( ! ClientCfg . R2EDEnabled ) return ;
if ( R2 : : getEditor ( ) . getMode ( ) ! = CEditor : : EditionMode & &
R2 : : getEditor ( ) . getMode ( ) ! = CEditor : : DMMode & &
R2 : : getEditor ( ) . getMode ( ) ! = CEditor : : AnimationModeDm ) return ;
CHECK_EDITOR
// just forward to lua
getEditor ( ) . callEnvMethod ( " activeTeleportTool " , 0 , 0 ) ;
}
} ;
REGISTER_ACTION_HANDLER ( CAHR2Teleport , " r2ed_teleport " ) ;
// *********************************************************************************************************
class CAHR2Undo : public IActionHandler
{
virtual void execute ( CCtrlBase * /* pCaller */ , const std : : string & /* sParams */ )
{
// if an edit box currently has focus, then try undo on it first
CGroupEditBox * eb = dynamic_cast < CGroupEditBox * > ( getEditor ( ) . getUI ( ) . getCaptureKeyboard ( ) ) ;
if ( eb & & eb - > undo ( ) )
{
return ;
}
CActionHistoric & historic = getEditor ( ) . getDMC ( ) . getActionHistoric ( ) ;
if ( historic . canUndo ( ) )
{
getEditor ( ) . setCurrentTool ( NULL ) ;
const ucstring * actionName = historic . getPreviousActionName ( ) ;
nlassert ( actionName ) ;
CLuaIHM : : push ( getEditor ( ) . getLua ( ) , * actionName ) ;
historic . undo ( ) ;
getEditor ( ) . callEnvMethod ( " onUndo " , 1 , 0 ) ;
}
else
{
getEditor ( ) . callEnvMethod ( " onCantUndo " , 0 , 0 ) ;
}
}
} ;
REGISTER_ACTION_HANDLER ( CAHR2Undo , " r2ed_undo " ) ;
// *********************************************************************************************************
class CAHR2Redo : public IActionHandler
{
virtual void execute ( CCtrlBase * /* pCaller */ , const std : : string & /* sParams */ )
{
// if an edit box currently has focus, then try redo on it first
CGroupEditBox * eb = dynamic_cast < CGroupEditBox * > ( getEditor ( ) . getUI ( ) . getCaptureKeyboard ( ) ) ;
if ( eb & & eb - > redo ( ) )
{
return ;
}
CActionHistoric & historic = getEditor ( ) . getDMC ( ) . getActionHistoric ( ) ;
if ( historic . canRedo ( ) )
{
getEditor ( ) . setCurrentTool ( NULL ) ;
const ucstring * actionName = historic . getNextActionName ( ) ;
nlassert ( actionName ) ;
CLuaIHM : : push ( getEditor ( ) . getLua ( ) , * actionName ) ;
historic . redo ( ) ;
getEditor ( ) . callEnvMethod ( " onRedo " , 1 , 0 ) ;
}
else
{
getEditor ( ) . callEnvMethod ( " onCantRedo " , 0 , 0 ) ;
}
}
} ;
REGISTER_ACTION_HANDLER ( CAHR2Redo , " r2ed_redo " ) ;
// *********************************************************************************************************
// signal the server that a dm gift has begun, so that the server can take note of the target entity (the current target)
class CAHR2DMGiftBegin : public IActionHandler
{
virtual void execute ( CCtrlBase * /* pCaller */ , const std : : string & /* sParams */ )
{
CBitMemStream out ;
if ( GenericMsgHeaderMngr . pushNameToStream ( " DM_GIFT:BEGIN " , out ) )
{
NetMngr . push ( out ) ;
}
else
nlwarning ( " <CHandlerInvalidateExchange::execute> unknown message name 'DM_GIFT:BEGIN " ) ;
}
} ;
REGISTER_ACTION_HANDLER ( CAHR2DMGiftBegin , " r2ed_dm_gift_begin " ) ;
// *********************************************************************************************************
// signal the server that a dm gift has begun, so that the server can take note of the target entity (the current target)
class CAHR2DMGiftValidate : public IActionHandler
{
virtual void execute ( CCtrlBase * /* pCaller */ , const std : : string & /* sParams */ )
{
CInterfaceManager * im = CInterfaceManager : : getInstance ( ) ;
CBitMemStream out ;
if ( GenericMsgHeaderMngr . pushNameToStream ( " DM_GIFT:VALIDATE " , out ) )
{
for ( uint k = 0 ; k < 8 ; + + k )
{
uint32 sheetId = 0 ;
uint8 quantity = 0 ;
CCDBNodeLeaf * sheetLeaf = im - > getDbProp ( toString ( " LOCAL:R2:DM_GIFT:%d:SHEET " , ( int ) k ) ) ;
if ( sheetLeaf ) sheetId = ( uint32 ) sheetLeaf - > getValue32 ( ) ;
CCDBNodeLeaf * quantityLeaf = im - > getDbProp ( toString ( " LOCAL:R2:DM_GIFT:%d:QUANTITY " , ( int ) k ) ) ;
if ( quantityLeaf ) quantity = ( uint8 ) quantityLeaf - > getValue8 ( ) ;
out . serial ( sheetId ) ;
out . serial ( quantity ) ;
}
NetMngr . push ( out ) ;
}
else
nlwarning ( " <CHandlerInvalidateExchange::execute> unknown message name 'DM_GIFT:VALIDATE " ) ;
}
} ;
REGISTER_ACTION_HANDLER ( CAHR2DMGiftValidate , " r2ed_dm_gift_validate " ) ;
// *********************************************************************************************************
// freeze / unfreeze bot objects
class CAHR2FreezeUnfreezeBotObjects : public IActionHandler
{
virtual void execute ( CCtrlBase * /* pCaller */ , const std : : string & /* sParams */ )
{
CInterfaceManager * im = CInterfaceManager : : getInstance ( ) ;
im - > executeLuaScript ( " r2:freezeUnfreezeBotObjects() " ) ;
}
} ;
REGISTER_ACTION_HANDLER ( CAHR2FreezeUnfreezeBotObjects , " r2ed_freeze_unfreeze_botobjects " ) ;
} // R2
// *********************************************************************************************************
// COMMAND TO REINITIALIZE THE EDITOR : useful to check scripts error
NLMISC_COMMAND ( resetEditor , " reset R2 editor, reload all scripts (except ui xmls) " , " " )
{
if ( ! args . empty ( ) ) return false ;
R2 : : ResetWanted = true ;
R2 : : ReloadUIFlag = false ;
return true ;
}
// *********************************************************************************************************
// COMMAND TO REINITIALIZE THE EDITOR : useful to check scripts error
NLMISC_COMMAND ( resetEditorAndReloadUI , " reset R2 editor, reload all scripts & xml (possibly preserving scenario) " , " " )
{
if ( ! args . empty ( ) ) return false ;
R2 : : ResetWanted = true ;
R2 : : ReloadUIFlag = true ;
return true ;
}
// *********************************************************************************************************
// write scenario rtdata to a file for debugging or stress testing by simulator_service
NLMISC_COMMAND ( saveScenarioRtData , " save scenario RtData to file " , " <filename> " )
{
const R2 : : CObject * scenario = R2 : : getEditor ( ) . getDMC ( ) . getHighLevel ( ) ;
if ( ! scenario )
{
nlinfo ( " No current scenario -- can't save rtdata " ) ;
return false ;
}
std : : string fileName = " outpout " ;
if ( args . empty ( ) )
{
// try to name file from title, then area+instance
R2 : : CObject * description = scenario - > findAttr ( " Description " ) ;
if ( description )
{
R2 : : CObject * name = description - > findAttr ( " Name " ) ;
R2 : : CObject * title = 0 ;
if ( name )
{
title = name ;
}
else
{
title = description - > findAttr ( " Title " ) ; //obsolete
}
R2 : : CObject * locationId = description - > findAttr ( " LocationId " ) ;
R2 : : CObject * instanceId = description - > findAttr ( " InstanceId " ) ;
if ( title )
{
string sTitle = title - > toString ( ) ;
if ( ! sTitle . empty ( ) )
fileName = sTitle ;
}
else if ( locationId & & instanceId )
fileName = " area " + locationId - > toString ( ) + " _ " + instanceId - > toString ( ) ;
}
}
else // filename given
{
fileName = args [ 0 ] ;
}
nlinfo ( " translating current scenario " ) ;
R2 : : CObject * pHighLevel = scenario - > clone ( ) ;
nlassert ( pHighLevel ) ;
R2 : : CObject * pRtData = R2 : : getEditor ( ) . getDMC ( ) . translateScenario ( pHighLevel ) ;
delete pHighLevel ;
if ( ! pRtData )
{
nlwarning ( " Failed to translate high-level scenario into rtdata " ) ;
return false ;
}
// binary
string fullFileName = fileName ;
fullFileName + = " .rt.bin " ;
nlinfo ( " writing rtdata to %s " , fullFileName . c_str ( ) ) ;
COFile output ;
output . open ( fullFileName ) ;
R2 : : CObjectSerializerClient serializer ( pRtData ) ;
serializer . serial ( output ) ;
output . flush ( ) ;
output . close ( ) ;
if ( true ) // debug
{
// text
fullFileName = fileName ;
fullFileName + = " .rt.txt " ;
COFile output ;
//std::stringstream ss;
std : : string ss ;
output . open ( fullFileName ) ;
pRtData - > serialize ( ss ) ;
//std::string str = ss.str();
output . serial ( ss ) ;
output . flush ( ) ;
output . close ( ) ;
}
return true ;
}
NLMISC_COMMAND ( dumpValidPositions , " dump valid position to create objects from the current camera viewpoint " , " <filename> " )
{
if ( args . size ( ) ! = 1 ) return false ;
try
{
COFile output ( args [ 0 ] ) ;
CBitmap result ;
Driver - > getBuffer ( result ) ;
if ( result . getWidth ( ) = = 0 | | result . getHeight ( ) = = 0 ) return false ;
CMatrix camMatrix = MainCam . getMatrix ( ) ;
NL3D : : CFrustum fru = MainCam . getFrustum ( ) ;
R2 : : CTool : : CWorldViewRay wvr ;
wvr . Right = camMatrix . getI ( ) . normed ( ) ;
wvr . Up = camMatrix . getK ( ) . normed ( ) ;
wvr . OnMiniMap = false ;
wvr . Origin = camMatrix . getPos ( ) ;
wvr . Valid = true ;
for ( uint x = 0 ; x < result . getWidth ( ) ; + + x )
{
for ( uint y = 0 ; y < result . getHeight ( ) ; + + y )
{
CVector ray ( fru . Left + ( fru . Right - fru . Left ) * ( x / ( float ) result . getWidth ( ) ) , fru . Near ,
fru . Top + ( fru . Bottom - fru . Top ) * ( y / ( float ) result . getHeight ( ) ) ) ;
ray . normalize ( ) ;
ray = camMatrix . mulVector ( ray ) ;
CVector inter ;
wvr . Dir = ray ;
R2 : : CTool : : TRayIntersectionType rit = R2 : : CTool : : computeLandscapeRayIntersection ( wvr , inter ) ;
CRGBA resultCol ;
switch ( rit )
{
case R2 : : CTool : : NoIntersection : resultCol = CRGBA ( 0 , 0 , 0 , 0 ) ; break ;
case R2 : : CTool : : ValidPacsPos : resultCol = CRGBA ( 0 , 0 , 255 , 100 ) ; break ;
default : resultCol = CRGBA ( 255 , 0 , 0 , 100 ) ; break ;
}
CRGBA * dest = ( ( CRGBA * ) & result . getPixels ( 0 ) [ 0 ] ) + x + y * result . getWidth ( ) ;
dest - > blendFromui ( * dest , resultCol , resultCol . A ) ;
}
}
result . writeTGA ( output , 32 , false ) ;
}
catch ( . . . )
{
}
return true ;
}
/*
// *********************************************************************************************************
NLMISC_COMMAND ( resetScenario , " reset R2 editor, reload all scripts & xml " , " " )
{
if ( ! args . empty ( ) ) return false ;
R2 : : ResetScenarioWanted = true ;
return true ;
}
// *********************************************************************************************************
NLMISC_COMMAND ( reloadScenario , " reset R2 editor, reload all scripts & xml (possibly preserving scenario) " , " " )
{
if ( ! args . empty ( ) ) return false ;
//
R2 : : ReloadScenarioWanted = true ;
return true ;
}
*/
bool IsInRingMode ( )
{
return R2 : : getEditor ( ) . getMode ( ) ! = R2 : : CEditor : : NotInitialized ;
}