/*============================================================================= * * Filename: CPAState.cpp * Version: 1.0 * Date: 30/12/96 * Author: Marc Trabucato & V.L. * * Description: implementation of CPA_State class * (this is a derivation of CPA_SaveObject) * *===========================================================================*/ #ifdef ACTIVE_EDITOR #include "stdafx.h" //ACP #include "ACP_Base.h" #include "incITF.h" #include "incDPT.h" #include "TAC.h" #include "TFa.h" #include "TAn.h" // Shaitan Clean Env { //#include "incsrf.h" //End Shaitan Clean Env } #include "x:\cpa\main\inc\_editid.h" #include "ACInterf.hpp" /****************************************************************************** * unexisting engine function ******************************************************************************/ /* static tdxHandleToState fn_hGetProhibitedStateInProhibit( tdxHandleToProhibit _hProhibit ) { return ( _hProhibit ? _hProhibit -> h_ProhibitedState : NULL ); } static void fn_vSetProhibitedStateInProhibit( tdxHandleToProhibit _hProhibit, tdxHandleToState _hState ) { ASSERT( _hProhibit ); _hProhibit -> h_ProhibitedState = _hState; } static tdxHandleToTransition fn_hGetTransitionalWithTargetState( tdxHandleToState _hState, tdxHandleToState _hTargetState ) { ASSERT( _hState ); tdxHandleToTransition hTransition; hTransition = LST2_M_StaticGetFirstElement( & _hState -> hForTransitionArray ); while( hTransition ) { if( fn_hGetTargetStateInTransition( hTransition ) == _hTargetState) { return( hTransition ); } hTransition = LST2_M_StaticGetNextElement( hTransition ); } return(NULL); } */ void del(tdxHandleToState h) { if (M_GetMainApp()->m_bLeavingApplication) return; fn_h_StateFree(h); } /****************************************************************************** * Macros ******************************************************************************/ #define M_AddTransitionalStateToState( p_oState , p_stTransState ) \ p_oState -> m_oListOfTransitionalStates.AddTail (p_stTransState ) #define M_Char(string) ((char*)(LPCTSTR)(string)) #define M_ForEachElement(p_oList,p_oElement,Pos)\ for( p_oElement = (p_oList) -> GetHeadElement( Pos ) ;\ p_oElement ;\ p_oElement = (p_oList) -> GetNextElement( Pos )\ ) #define M_FindStateByEngineHandle( p_oState, hState, p_oOwnerFamily ) ((CPA_State*) p_oState -> GetBaseObjectList() -> fn_p_oFindObjectWithdData( (void*)hState, C_szStateTypeName, p_oOwnerFamily )) DeclareTemplateStatic(tdxHandleToState); /****************************************************************************** * Class ******************************************************************************/ void CPA_State::Init() { CPA_EdMot::Init(fn_h_StateAlloc,NULL,del); } /*----------------------------------------------------------------------------- * Description : *---------------------------------------------------------------------------*/ void CPA_State::fn_vCallBackSave( SCR_tdst_File_Description *_p_stFile, char *_p_szSectionName, void *_p_vData, SCR_tde_Ntfy_Action _eAction) { CPA_State* p_oState = (CPA_State*)_p_vData; char szActionName[SCR_CV_ui_Cfg_MaxLenName]; char szIdName[SCR_CV_ui_Cfg_MaxLenName]; char szSectionName[SCR_CV_ui_Cfg_MaxLenName]; char szValue[10]; int iIndex; tdxHandleToProhibit hProhibit; tdxHandleToTransition hTransition; BOOL bProhibit = p_oState -> mfn_bIsProhibitedByDefault(); CPA_Animation* p_oAnimation; switch ( _eAction ) { case SCR_EA_Ntfy_AddSection: SCR_fn_v_SvL1_ToEndSection( _p_stFile ); case SCR_EA_Ntfy_RebuildSection: // construct section name SCR_fn_v_RdL0_SplitSectionName( _p_szSectionName, NULL, szActionName, szIdName ); SCR_fn_v_RdL0_ComputeSectionName( szSectionName, NULL, szActionName, szIdName ); // save begin section SCR_M_SvL0_SaveBeginSection(_p_stFile, szSectionName, SCR_CC_C_Cfg_EOL ); // save entries // Animation p_oAnimation = p_oState -> mfn_p_oGetAnimation(); if ( p_oAnimation ) { if( p_oAnimation -> GetOwner() == p_oState -> GetOwner() ) { // anim of current family SCR_M_SvL0_SaveEntry(_p_stFile, C_Entry_Animation, SCR_CC_C_Cfg_NoChar ); SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, p_oAnimation -> fn_p_szGetName() ); } else { // anim of other family SCR_M_SvL0_SaveEntry(_p_stFile, "ExternAnimation", SCR_CC_C_Cfg_NoChar ); SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 2, p_oAnimation -> fn_p_szGetName(), p_oAnimation -> GetOwner() -> fn_p_szGetName() ); } } // Repeat SCR_M_SvL0_SaveEntry(_p_stFile, C_Entry_Repeat, SCR_CC_C_Cfg_NoChar ); SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, itoa( p_oState -> mfn_ucGetReplay(), szValue, 10 ) ); // Speed SCR_M_SvL0_SaveEntry(_p_stFile, C_Entry_Speed, SCR_CC_C_Cfg_NoChar ); SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, itoa( p_oState -> mfn_cGetSpeed(), szValue, 10 ) ); // TransitionalState Flag SCR_M_SvL0_SaveEntry(_p_stFile, C_Entry_TransitionStatusFlag, SCR_CC_C_Cfg_NoChar ); SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, p_oState -> mfn_bIsProhibitedByDefault() ? C_Value_TransitionProhibitedbyDefault : C_Value_TransitionAllowedByDefault ); // prohibited states if( ! bProhibit ) { iIndex = 0; LST2_M_StaticForEachElementOf( & p_oState -> GetStruct() -> hForProhibitArray, hProhibit, iIndex) { // get State tdxHandleToState hState = fn_hGetProhibitedStateInProhibit( hProhibit ); CPA_State *p_oProhibitState = M_FindStateByEngineHandle( p_oState, hState, p_oState -> GetOwner() ); ASSERT( p_oProhibitState ); // save entry SCR_M_SvL0_SaveEntry(_p_stFile, C_Entry_ProhibitedTargetState, SCR_CC_C_Cfg_NoChar ); SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, p_oProhibitState -> fn_p_szGetName() ); } } // allowed states iIndex = 0; LST2_M_StaticForEachElementOf( & p_oState -> GetStruct() -> hForTransitionArray, hTransition, iIndex) { tdxHandleToState hTargetState = fn_hGetTargetStateInTransition( hTransition ); tdxHandleToState hStateToGo = fn_hGetStateToGoInTransition( hTransition ); CPA_State *p_oTargetState = M_FindStateByEngineHandle( p_oState, hTargetState, p_oState -> GetOwner() ); CPA_State *p_oStateToGo = M_FindStateByEngineHandle( p_oState, hStateToGo, p_oState -> GetOwner() ); //ANNECY CT 11/02/98{ unsigned char ucLink = fn_ucGetLinkingTypeInTransition(hTransition); if( bProhibit || ( p_oTargetState != p_oStateToGo ) || (ucLink!=C_ucStandardLink)) { char szInt[5]; sprintf(szInt,"%d",ucLink); SCR_M_SvL0_SaveEntry(_p_stFile, C_Entry_AddTargetState, SCR_CC_C_Cfg_NoChar ); if( p_oStateToGo ) SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 3, p_oTargetState -> fn_p_szGetName() , p_oStateToGo -> fn_p_szGetName(),szInt); else SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 3, p_oTargetState -> fn_p_szGetName() , p_oTargetState -> fn_p_szGetName(),szInt); } //ENDANNECY CT} } // Next State SCR_M_SvL0_SaveEntry(_p_stFile, C_Entry_NextState, SCR_CC_C_Cfg_NoChar ); if( p_oState -> mfn_p_oGetNextState() ) SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, p_oState -> mfn_p_oGetNextState() -> fn_p_szGetName() ); else SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, C_szNoState); // Mechanic if( p_oState -> mfn_p_oGetMecaCard() ) { SCR_M_SvL0_SaveEntry(_p_stFile, C_Entry_LinkMechanics, SCR_CC_C_Cfg_NoChar ); SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, M_Char( p_oState -> mfn_p_oGetMecaCard() -> GetReferencedSectionName() ) ); } // Custom bits SCR_M_SvL0_SaveEntry(_p_stFile, C_Entry_CustomBits, SCR_CC_C_Cfg_NoChar ); SCR_fn_v_SvL0_SaveParameters_MP(_p_stFile, SCR_EF_SvL0_Normal, 1, itoa( p_oState -> mfn_ucGetCustomBits(), szValue, 10 ) ); // save end section SCR_M_SvL0_SaveEndSection(_p_stFile, SCR_CC_C_Cfg_EOL ); SCR_M_SvL0_SaveBlankLine( _p_stFile ); // update 'Existing section' bool p_oState -> fn_vSectionSaved(); break; case SCR_EA_Ntfy_DeleteSection: p_oState -> fn_vSectionDeleted(); break; } } /*----------------------------------------------------------------------------- * Constructor : create new engine state or use existing engine state *---------------------------------------------------------------------------*/ CPA_State::CPA_State( CPA_EditorBase *p_oEditor, CPA_BaseObject *_p_oOwnerFamily, tdxHandleToState _hEngineState /*=NULL*/, CPA_Animation *p_oAnimation /*=NULL*/, CString _csStateName /*=""*/ ) :CPA_SaveObject( p_oEditor, C_szStateTypeName, E_ss_Responsible, _p_oOwnerFamily, TRUE, fn_szGetFamiliesDataPath(), CPA_State::fn_vCallBackSave ), CPA_EdMot(_hEngineState) { ASSERT( _p_oOwnerFamily ); // Section & File Name char szFileName[SCR_CV_ui_Cfg_MaxLenName]; char szReferencedSectionName[SCR_CV_ui_Cfg_MaxLenName]; strcpy( szFileName, _p_oOwnerFamily -> fn_p_szGetName() ); strcat( szFileName, "\\" ); strcat( szFileName, _p_oOwnerFamily -> fn_p_szGetName() ); strcat( szFileName, ".sta" ); SCR_fn_v_RdL0_ComputeSectionName( szReferencedSectionName, szFileName, C_szStateSectionName, "" ); SetReferencedSectionName( szReferencedSectionName ); SetSectionData( this ); SetExistingSection( _hEngineState != NULL ); // // Create Engine Data ???? if( GetStruct() == NULL ) SetStruct( fn_h_StateAlloc() ); // // Name if( fn_eRename( _csStateName ) != E_mc_None ) SetDefaultValidName( _csStateName ); fn_vUpdateSectionName(); // // Datas m_p_oNextState = NULL; m_p_oMecaCard = NULL; m_p_oAnimation = NULL; if ( _hEngineState != NULL ) { // use existing engine state mfn_vInitNextState(); // use existing meca mfn_vInitMechanics(); // use existing anim mfn_vInitAnimation(); } else { mfn_vSetReplay(1); mfn_vSetSpeed(1); mfn_vSetAnimation( p_oAnimation ); mfn_vSetProhibitedByDefault( FALSE ); // Allowed by default // about saving fn_vNotifySave(); } // m_bTransitional = FALSE; m_oListOfTransitionStateInfo . RemoveAll(); m_oListOfUsedAsNextState.RemoveAll () ; m_oListOfUsedAsTransitional.RemoveAll () ; m_bMustRecomputeTransitions = FALSE; // CPA_Ed_1 Mihaela Tancu begin m_iNumber=0; // CPA_Ed_1 Mihaela Tancu end } /*----------------------------------------------------------------------------- * Destructor *---------------------------------------------------------------------------*/ CPA_State::~CPA_State(void) { mfn_vResetTransitionStateInfoList(); while ( ! m_oListOfUsedOnZAList . IsEmpty() ) { free( m_oListOfUsedOnZAList . RemoveHead() ); } } // ---------------------------------------------------------------------------- // Description : set engine struct // ---------------------------------------------------------------------------- void CPA_State::SetStruct(tdxHandleToState _hState) { CPA_EdMot::SetStruct( _hState ); } void CPA_State::fn_vNotifyRename(void) { CPA_SaveObject::fn_vNotifyRename(); CPA_Action *p_oAction = (CPA_Action*) mfn_p_oGetAction(); if( this == p_oAction -> mfn_p_oGetDefaultState() ) { // save al IA using this Action CPA_DLLBase *p_oActorDLL = GetMainWorld() -> GetObjectDLLWithName( C_szDLLActorName ); CPA_DLLBase *pclIADLL = GetMainWorld()->GetToolDLLWithName(C_szDLLAIEditorName); CList< CPA_BaseObject *, CPA_BaseObject *> oList; if( p_oActorDLL != NULL ) { p_oActorDLL -> OnQueryAction( GetEditor(), C_uiActor_ActionModif, (LPARAM)p_oAction ); if((pclIADLL != NULL) && ( g_oCoherenceManager . m_fn_iGetFatherList( p_oAction, &oList ) > 0 )) { POSITION xPos = oList . GetHeadPosition(); while( xPos ) { CPA_BaseObject *p_oBsObj = oList . GetNext( xPos ); if( p_oBsObj -> fn_bIsOfType( C_szActorModelTypeName ) ) pclIADLL -> OnQueryAction( GetEditor(), C_uiAI_SaveIA, (LPARAM)p_oBsObj ); } } } } } /****************************************************************************** * Owner functions : ******************************************************************************/ void CPA_State::mfn_vObtainSpaceNumbers(void) { CPA_State* p_oNextState = m_p_oNextState; while (p_oNextState->mfn_bGetTransitional()) { m_iNumber+=4; p_oNextState = p_oNextState->mfn_p_oGetNextState(); } } /*----------------------------------------------------------------------------- * Description : return a copy of current state *---------------------------------------------------------------------------*/ CPA_State * CPA_State::mfn_p_oDuplicateState(void) { CPA_State *p_oNewState = new CPA_State( GetEditor(), GetOwner(), NULL, m_p_oAnimation, "CopyOf" + GetName() ); POSITION xPos; tdstTransitionStateInfo *p_stTSI; // copy action p_oNewState -> mfn_vSetAction( m_p_oAction ); // copy next state p_oNewState -> mfn_vSetNextState( m_p_oNextState == this ? p_oNewState : m_p_oNextState ); // cop mechanic p_oNewState -> mfn_vSetMecaCard( m_p_oMecaCard ); // copy speed p_oNewState -> mfn_vSetSpeed( mfn_cGetSpeed() ); // copy replay p_oNewState -> mfn_vSetReplay( mfn_ucGetReplay() ); // copy list of transitional states M_ForEachElement( & m_oListOfTransitionStateInfo, p_stTSI, xPos ) { p_oNewState -> mfn_vSetTransitionStateInfo( p_stTSI -> p_oAction, p_stTSI-> eState, p_stTSI-> p_oStateToGo ); } // copy flag 'Transitional' p_oNewState -> m_bTransitional = m_bTransitional; return p_oNewState; } /*----------------------------------------------------------------------------- * Description : change Animation of state *---------------------------------------------------------------------------*/ void CPA_State::mfn_vSetAnimation(CPA_Animation *_p_oAnimation) { m_p_oAnimation = _p_oAnimation; if(m_p_oAnimation) fn_vSetAnimInState( GetStruct(), (struct tdstAnim3d_*)_p_oAnimation->GetData() ); else fn_vSetAnimInState( GetStruct(), NULL ); mfn_vSetSpeed( m_p_oAnimation ? m_p_oAnimation -> mfn_ucGetFrameRate() : 0 ); } /*----------------------------------------------------------------------------- * Description : change next state of state *---------------------------------------------------------------------------*/ void CPA_State::mfn_vSetNextState(CPA_State *_p_oNextState, BOOL _bPreviousRemoved /*=FALSE*/) { if(m_p_oNextState) m_p_oNextState -> mfn_vDelAsNextStateOf( this ); // update engine struct if( _p_oNextState == NULL ) { if( _bPreviousRemoved && m_p_oNextState && m_p_oNextState -> mfn_p_oGetNextState() && (m_p_oNextState -> mfn_p_oGetNextState() != m_p_oNextState) ) _p_oNextState = m_p_oNextState -> mfn_p_oGetNextState(); else if( mfn_bGetTransitional() ) _p_oNextState = mfn_p_oGetAction() -> mfn_p_oGetDefaultState(); } fn_vSetNextStateInState( GetStruct(), _p_oNextState ? _p_oNextState->GetStruct() : NULL ); // update coherence if(_p_oNextState) _p_oNextState -> mfn_vAddAsNextStateOf( this ); m_p_oNextState = _p_oNextState; } /*----------------------------------------------------------------------------- * Description : change mechanic of state *---------------------------------------------------------------------------*/ void CPA_State::mfn_vSetMecaCard(CPA_SaveObject *_p_oMeca) { m_p_oMecaCard = _p_oMeca; if(m_p_oMecaCard) fn_vSetStateMechanicsIdCard( GetStruct(), (DNM_tdxHandleToMecIdentityCard)m_p_oMecaCard -> GetData() ); else fn_vSetStateMechanicsIdCard( GetStruct(), NULL ); } /*----------------------------------------------------------------------------- * Description : change replay of state *---------------------------------------------------------------------------*/ void CPA_State::mfn_vSetReplay(unsigned char _ucReplay) { fn_vSetRepeatAnimationInState( GetStruct(), (unsigned char)(_ucReplay-1) ); } /*----------------------------------------------------------------------------- * Description : change speed of state *---------------------------------------------------------------------------*/ void CPA_State::mfn_vSetSpeed(signed char _cSpeed) { fn_vSetSpeedInState( GetStruct(), (signed char)_cSpeed); } /*----------------------------------------------------------------------------- * Description : Set transitional state of current state *---------------------------------------------------------------------------*/ void CPA_State::mfn_vSetTransitional(BOOL _bTransitional, BOOL _bUpdateEngine /*=TRUE*/) { m_bTransitional = _bTransitional; if( m_bTransitional && _bUpdateEngine && mfn_p_oGetAction() && !mfn_p_oGetNextState() ) { mfn_vSetNextState( mfn_p_oGetAction() -> mfn_p_oGetDefaultState() ); } } /*----------------------------------------------------------------------------- * Description : Set Custom bits *---------------------------------------------------------------------------*/ void CPA_State::mfn_vSetCustomBits(unsigned char _ucCustomBits) { fn_vSetStateCustomBits( GetStruct() , _ucCustomBits ); } /*----------------------------------------------------------------------------- * Description : *---------------------------------------------------------------------------*/ unsigned char CPA_State::mfn_ucGetReplay(void) { return (fn_ucGetRepeatAnimationInState( GetStruct() )+1); } /*----------------------------------------------------------------------------- * Description : *---------------------------------------------------------------------------*/ signed char CPA_State::mfn_cGetSpeed(void) { return fn_scGetSpeedInState( GetStruct() ); } // ---------------------------------------------------------------------------- // Description : init editor next state with engine next state // ---------------------------------------------------------------------------- void CPA_State::mfn_vInitNextState(void) { tdxHandleToState hState = fn_hGetNextStateInState( GetStruct() ); if( !m_p_oNextState && hState) { m_p_oNextState = (CPA_State*)GetEditor() -> GetBaseObject( hState, C_szStateTypeName, mfn_p_oGetFamily() ); if( m_p_oNextState ) m_p_oNextState -> mfn_vAddAsNextStateOf( this ); } } // ---------------------------------------------------------------------------- // Description : init editor next state with engine next state // ---------------------------------------------------------------------------- void CPA_State::mfn_vInitMechanics(void) { DNM_tdxHandleToMecIdentityCard hMeca = fn_hGetStateMechanicsIdCard( GetStruct() ); if( !m_p_oMecaCard && hMeca ) m_p_oMecaCard = (CPA_SaveObject*)GetMainWorld() -> fn_p_oFindObjectWithEngine( hMeca, C_szMecaCardTypeName ); } // ---------------------------------------------------------------------------- // Description : init editor animation with engine animation // ---------------------------------------------------------------------------- void CPA_State::mfn_vInitAnimation(void) { struct tdstAnim3d_ *p_stAnim = fn_p_stGetAnimInState( GetStruct() ); if( p_stAnim != NULL ) m_p_oAnimation = (CPA_Animation*) GetEditor() -> GetMainWorld() -> fn_p_oFindObjectWithEngine( p_stAnim, C_szAnimationTypeName); } /*----------------------------------------------------------------------------- * Description : *---------------------------------------------------------------------------*/ void CPA_State::mfn_vAddAsNextStateOf( CPA_State *_p_oState ) { if( fn_bIsValid() ) { POSITION stPos = m_oListOfUsedAsNextState . Find ( _p_oState ) ; if( !stPos ) m_oListOfUsedAsNextState . AddTail ( _p_oState ) ; } } /*----------------------------------------------------------------------------- * Description : *---------------------------------------------------------------------------*/ void CPA_State::mfn_vDelAsNextStateOf( CPA_State *_p_oState ) { if( fn_bIsValid() ) { POSITION stPos = m_oListOfUsedAsNextState . Find ( _p_oState ) ; if( stPos ) m_oListOfUsedAsNextState . RemoveAt ( stPos ) ; } } /*----------------------------------------------------------------------------- * Description : *---------------------------------------------------------------------------*/ void CPA_State::mfn_vAddAsTransitionalStateOf( CPA_State *_p_oState ) { if( fn_bIsValid() ) { POSITION stPos = m_oListOfUsedAsTransitional . Find ( _p_oState ) ; if( !stPos ) m_oListOfUsedAsTransitional . AddTail ( _p_oState ) ; } } /*----------------------------------------------------------------------------- * Description : *---------------------------------------------------------------------------*/ void CPA_State::mfn_vDelAsTransitionalStateOf( CPA_State *_p_oState ) { if( fn_bIsValid() ) { POSITION stPos = m_oListOfUsedAsTransitional . Find ( _p_oState ) ; if( stPos ) m_oListOfUsedAsTransitional . RemoveAt ( stPos ) ; } } /*----------------------------------------------------------------------------- * Description : *---------------------------------------------------------------------------*/ void CPA_State::mfn_vAddOnZAList( CPA_SaveObject *_p_oZAList, CPA_SaveObject *_p_oZA ) { if( fn_bIsValid() ) { POSITION xPos = mfn_xGetPosOfZAListUsing( _p_oZAList ); if ( xPos != NULL ) { // update ZA tdstZAListInfo *p_stZAListInfo = m_oListOfUsedOnZAList . GetAt( xPos ); p_stZAListInfo -> p_oZA = _p_oZA; } else { // add ZAList tdstZAListInfo *p_stZAListInfo = (tdstZAListInfo*) malloc( sizeof tdstZAListInfo ); p_stZAListInfo -> p_oZAList = _p_oZAList; p_stZAListInfo -> p_oZA = _p_oZA; m_oListOfUsedOnZAList . AddTail( p_stZAListInfo ); } } } /*----------------------------------------------------------------------------- * Description : *---------------------------------------------------------------------------*/ void CPA_State::mfn_vDelOnZAList( CPA_SaveObject *_p_oZAList ) { if( fn_bIsValid() ) { POSITION xPos = mfn_xGetPosOfZAListUsing( _p_oZAList ); if ( xPos != NULL ) { // delete tdstZAListInfo *p_stZAListInfo = m_oListOfUsedOnZAList . GetAt( xPos ); m_oListOfUsedOnZAList . RemoveAt( xPos ); free( p_stZAListInfo ); } } } /*----------------------------------------------------------------------------- * Description : *---------------------------------------------------------------------------*/ CPA_SaveObject *CPA_State::mfn_p_oGetZAFromZAList( CPA_SaveObject *_p_oZAList ) { POSITION xPos = mfn_xGetPosOfZAListUsing( _p_oZAList ); if ( xPos != NULL ) { tdstZAListInfo *p_stZAListInfo = m_oListOfUsedOnZAList . GetAt( xPos ); return p_stZAListInfo -> p_oZA; } return NULL; } /*----------------------------------------------------------------------------- * Description : *---------------------------------------------------------------------------*/ POSITION CPA_State::mfn_xGetPosOfZAListUsing( CPA_SaveObject *_p_oZAList ) { POSITION xPos = m_oListOfUsedOnZAList . GetHeadPosition(); while ( xPos ) { tdstZAListInfo *p_stZAListInfo = m_oListOfUsedOnZAList . GetAt( xPos ); if( p_stZAListInfo -> p_oZAList == _p_oZAList ) return xPos; m_oListOfUsedOnZAList . GetNext( xPos ); } return NULL; } /*----------------------------------------------------------------------------- * Description : return TRUE if _p_oState can be used as next state of 'this' state *---------------------------------------------------------------------------*/ BOOL CPA_State::mfn_bCanUseAsNextState(CPA_State *_p_oState) { // no by default BOOL bResult = FALSE; // it is possible only if the target state belongs to the same action, and is valid of course... if( _p_oState && (_p_oState -> mfn_p_oGetAction() == mfn_p_oGetAction()) ) { // if I am a transitional state if( mfn_bGetTransitional() ) { // I cannot use myself as a next state if( _p_oState == this ) { bResult = FALSE; } else if( _p_oState -> mfn_bGetTransitional() ) // if the target is transitional { // I can use it as next state if it doesn't chain to me, directly or indirectly CPA_List oListOfStates; CPA_State *p_oDefaultState = mfn_p_oGetAction() ? mfn_p_oGetAction() -> mfn_p_oGetDefaultState() : NULL; BOOL bContinue = TRUE; CPA_State *p_oState = _p_oState; oListOfStates . AddTail( this ); oListOfStates . AddTail( p_oState ); while( bContinue ) { p_oState = p_oState -> mfn_p_oGetNextState(); POSITION xPos = oListOfStates . Find( p_oState ); if( xPos || ( p_oState && !p_oState -> mfn_bGetTransitional() && (p_oState != p_oDefaultState) ) ) { bContinue = FALSE; bResult = FALSE; } else if( !p_oState || (p_oState == p_oDefaultState) ) { bContinue = FALSE; bResult = TRUE; } else oListOfStates . AddHead( p_oState ); } } else // I am transitional, but the target isn't { // I can use the default state as next state bResult = mfn_p_oGetAction() && ( _p_oState == mfn_p_oGetAction() -> mfn_p_oGetDefaultState() ); // if the target is not the default state, let's see if it does chain to it if ( !bResult ) { CPA_State *p_oDefaultState = mfn_p_oGetAction() ? mfn_p_oGetAction() -> mfn_p_oGetDefaultState() : NULL; // we start with the target CPA_State *p_oState = _p_oState; for ( ;; ) { // if I found the default state in the chain, I can use the target as a next state if ( p_oState == p_oDefaultState ) { bResult = TRUE; break; } // I scanned all possible states: either the target loops to itself, or the chain ends if ( !p_oState ) break; //go to the next in list p_oState = p_oState -> mfn_p_oGetNextState(); // if it loops to itself at some point without using the default state in between // we break the loop, else the loop would be infinite // example of that case: the default state branches to the target, that loops to itself // -> it never encounters the default state in its own chain, but the chain doesn't end either... if ( p_oState == _p_oState ) break; } } } } else // I am not a transitional state { // I can use the target as next state only if it is not transitional bResult = !_p_oState -> mfn_bGetTransitional(); } } return bResult; } ////////////////////////////////////////////////////////////////////////////////////////////////// // new transision state info functions ////////////////////////////////////////////////////////////////////////////////////////////////// // ---------------------------------------------------------------------------- // Author : Marc Trabucato Creation : 17/11/97 // Description : set ucTransitionStatusFlag // ---------------------------------------------------------------------------- void CPA_State::mfn_vSetProhibitedByDefault (BOOL _bProhibit /*=FALSE*/) { fn_vSetTransitionStatusFlagInState( GetStruct(), _bProhibit ? C_ucProhibitedState : C_ucAllowedState ); } // ---------------------------------------------------------------------------- // Author : Marc Trabucato Creation : 17/11/97 // Description : set the transition state of the given action // ---------------------------------------------------------------------------- void CPA_State::mfn_vSetTransitionStateInfo(CPA_Action *_p_oAction, tdeTransitionState _eState, CPA_State *_p_oState /*=NULL*/, BOOL _bOnInit /*=FALSE*/) { ASSERT( _p_oAction ); tdstTransitionStateInfo *p_stTSI = mfn_p_stGetTransitionStateInfo( _p_oAction ); //ANNECY CT 11/02/98{ if( _eState == E_ts_Fluid ) { // take account transition if( p_stTSI == NULL ) { p_stTSI = (tdstTransitionStateInfo*) malloc( sizeof tdstTransitionStateInfo ); p_stTSI -> p_oAction = _p_oAction; p_stTSI -> p_oStateToGo = NULL; p_stTSI -> eState = E_ts_Unknown; m_bMustRecomputeTransitions = !_bOnInit; m_oListOfTransitionStateInfo . AddTail( p_stTSI ); } if( mfn_bIsProhibitedByDefault() || ( ( p_stTSI -> p_oStateToGo != _p_oState ) && ( _p_oState != _p_oAction -> mfn_p_oGetDefaultState() ) ) ) { // if( p_stTSI -> p_oStateToGo ) p_stTSI -> p_oStateToGo -> mfn_vDelAsTransitionalStateOf( this ); p_stTSI -> p_oStateToGo = _p_oState; m_bMustRecomputeTransitions = !_bOnInit; // if( p_stTSI -> p_oStateToGo ) p_stTSI -> p_oStateToGo -> mfn_vAddAsTransitionalStateOf( this ); } // if( mfn_bIsProhibitedByDefault() ) { p_stTSI -> p_oAction -> mfn_vInterruptState( this ); } else { p_stTSI -> p_oAction -> mfn_vDontInterruptState( this ); } } else //ENDANNECY CT} if( _eState == E_ts_Allowed ) { // take account transition if( p_stTSI == NULL ) { p_stTSI = (tdstTransitionStateInfo*) malloc( sizeof tdstTransitionStateInfo ); p_stTSI -> p_oAction = _p_oAction; p_stTSI -> p_oStateToGo = NULL; p_stTSI -> eState = E_ts_Unknown; m_bMustRecomputeTransitions = !_bOnInit; m_oListOfTransitionStateInfo . AddTail( p_stTSI ); } if( mfn_bIsProhibitedByDefault() || ( ( p_stTSI -> p_oStateToGo != _p_oState ) && ( _p_oState != _p_oAction -> mfn_p_oGetDefaultState() ) ) ) { // if( p_stTSI -> p_oStateToGo ) p_stTSI -> p_oStateToGo -> mfn_vDelAsTransitionalStateOf( this ); p_stTSI -> p_oStateToGo = _p_oState; m_bMustRecomputeTransitions = !_bOnInit; // if( p_stTSI -> p_oStateToGo ) p_stTSI -> p_oStateToGo -> mfn_vAddAsTransitionalStateOf( this ); } // if( mfn_bIsProhibitedByDefault() ) { p_stTSI -> p_oAction -> mfn_vInterruptState( this ); } else { p_stTSI -> p_oAction -> mfn_vDontInterruptState( this ); } } else if( _eState == E_ts_Prohibited ) { // take account transition if( p_stTSI == NULL ) { p_stTSI = (tdstTransitionStateInfo*) malloc( sizeof tdstTransitionStateInfo ); p_stTSI -> p_oAction = _p_oAction; p_stTSI -> eState = E_ts_Unknown; p_stTSI -> p_oStateToGo = NULL; m_bMustRecomputeTransitions = !_bOnInit; m_oListOfTransitionStateInfo . AddTail( p_stTSI ); } if( p_stTSI -> p_oStateToGo ) p_stTSI -> p_oStateToGo -> mfn_vDelAsTransitionalStateOf( this ); p_stTSI -> p_oStateToGo = NULL; // if( mfn_bIsProhibitedByDefault() ) { p_stTSI -> p_oAction -> mfn_vDontInterruptState( this ); } else { p_stTSI -> p_oAction -> mfn_vInterruptState( this ); } } else // _eState == E_ts_Unknown { // if( mfn_bIsProhibitedByDefault() && p_stTSI -> p_oAction ) { p_stTSI -> p_oAction -> mfn_vDontInterruptState( this ); } } // update state if( p_stTSI && ( p_stTSI -> eState != _eState ) ) { p_stTSI -> eState = _eState; m_bMustRecomputeTransitions = !_bOnInit; } } // ---------------------------------------------------------------------------- // Author : Marc Trabucato Creation : 17/11/97 // Description : update engine transition list and engine prohibited list // ---------------------------------------------------------------------------- BOOL CPA_State::mfn_bUpdateTransitionStateList( void ) { if( m_bMustRecomputeTransitions ) { tdstTransitionStateInfo* p_stTSI = NULL; POSITION xPos; BOOL bProhibState = mfn_bIsProhibitedByDefault(); // get first engine list element tdxHandleToProhibit hFreeProhibit = LST2_M_StaticGetFirstElement( & GetStruct() -> hForProhibitArray ); tdxHandleToTransition hFreeTransition = LST2_M_StaticGetFirstElement( & GetStruct() -> hForTransitionArray ); // // M_ForEachElement( &m_oListOfTransitionStateInfo, p_stTSI, xPos ) { //ANNECY CT 11/02/98{ unsigned char ucLink = C_ucStandardLink; //ENDANNECY CT} switch( p_stTSI -> eState ) { //ANNECY CT 11/02/98{ case E_ts_Fluid: ucLink = C_ucProportionalLink; //ENDANNECY CT} case E_ts_Allowed: if( p_stTSI && p_stTSI -> p_oAction && p_stTSI -> p_oAction -> mfn_p_oGetDefaultState() ) { CPA_State *p_oTargetState = p_stTSI -> p_oAction -> mfn_p_oGetDefaultState(); // add on transitional states list ? if( bProhibState || // only existing Transition must interrupt state //ANNECY CT 11/02/98{ (ucLink == C_ucProportionalLink) || //ENDANNECY CT} p_stTSI -> p_oStateToGo ) // need Transition to precise state to go { if( hFreeTransition == NULL ) { hFreeTransition = fn_h_TransitionAlloc(); LST2_M_StaticAddTail( & GetStruct() -> hForTransitionArray, hFreeTransition ); fn_vSetTargetStateInTransition( hFreeTransition, p_oTargetState -> GetStruct() ); fn_vSetStateToGoInTransition( hFreeTransition, p_stTSI -> p_oStateToGo ? p_stTSI -> p_oStateToGo -> GetStruct() : p_oTargetState -> GetStruct() ); //ANNECY CT 11/02/98{ fn_vSetLinkingTypeInTransition(hFreeTransition,ucLink); //ENDANNECY CT} hFreeTransition = NULL; } else { fn_vSetTargetStateInTransition( hFreeTransition, p_oTargetState -> GetStruct() ); fn_vSetStateToGoInTransition( hFreeTransition, p_stTSI -> p_oStateToGo ? p_stTSI -> p_oStateToGo -> GetStruct() : p_oTargetState -> GetStruct() ); //ANNECY CT 11/02/98{ fn_vSetLinkingTypeInTransition(hFreeTransition,ucLink); //ENDANNECY CT} hFreeTransition = LST2_M_StaticGetNextElement( hFreeTransition ); } } } break; case E_ts_Prohibited: if( p_stTSI && p_stTSI -> p_oAction && p_stTSI -> p_oAction -> mfn_p_oGetDefaultState() ) { CPA_State *p_oTargetState = p_stTSI -> p_oAction -> mfn_p_oGetDefaultState(); // add on prohibited list ? if( !bProhibState ) // only existing existing prohibited states are prohibited !!! { if( hFreeProhibit == NULL ) { hFreeProhibit = fn_h_ProhibitAlloc(); fn_vSetProhibitedStateInProhibit( hFreeProhibit, p_oTargetState -> GetStruct() ); LST2_M_StaticAddTail( & GetStruct() -> hForProhibitArray, hFreeProhibit ); hFreeProhibit = NULL; } else { fn_vSetProhibitedStateInProhibit( hFreeProhibit, p_oTargetState -> GetStruct() ); hFreeProhibit = LST2_M_StaticGetNextElement( hFreeProhibit ); } } } break; case E_ts_Unknown: // nothing to do break; } } // clear unused hTransition if( hFreeTransition ) { do { tdxHandleToTransition hNextTransition = LST2_M_StaticGetNextElement( hFreeTransition ); LST2_M_StaticIsolate( hFreeTransition ); fn_h_TransitionFree( hFreeTransition ); hFreeTransition = hNextTransition; } while( hFreeTransition ); } // clear unused hProhibit if( hFreeProhibit ) { do { tdxHandleToProhibit hNextProhibit = LST2_M_StaticGetNextElement( hFreeProhibit ); LST2_M_StaticIsolate( hFreeProhibit ); fn_h_ProhibitFree( hFreeProhibit ); hFreeProhibit = hNextProhibit; } while( hFreeProhibit ); } } m_bMustRecomputeTransitions = FALSE; return TRUE; } // ---------------------------------------------------------------------------- // Author : Marc Trabucato Creation : 17/11/97 // Description : fill transitionStateInfo list with engine transition list and engine prohibited list // ---------------------------------------------------------------------------- void CPA_State::mfn_vFillTransitionStateList( void ) { tdxHandleToTransition hTransition; tdxHandleToProhibit hProhibit; int iIndex; // reset list mfn_vResetTransitionStateInfoList(); // add transition list iIndex = 0; LST2_M_StaticForEachElementOf( & GetStruct() -> hForTransitionArray, hTransition, iIndex) { // get Target State and State To Go tdxHandleToState hTargetState = fn_hGetTargetStateInTransition( hTransition ); tdxHandleToState hStateToGo = fn_hGetStateToGoInTransition( hTransition ); CPA_State *p_oTargetState = M_FindStateByEngineHandle( this, hTargetState, GetOwner() ); // Shaitan => state list in the level if (!p_oTargetState) { hTargetState = mfn_p_oGetAction()->mfn_hGetStateFromLinkTable((char *)hTargetState, (char *) (LPCSTR) mfn_p_oGetFamily()->GetName()); fn_vSetTargetStateInTransition(hTransition, hTargetState); p_oTargetState = M_FindStateByEngineHandle( this, hTargetState, GetOwner() ); } // End Shaitan => state list in the level CPA_State *p_oStateToGo = M_FindStateByEngineHandle( this, hStateToGo, GetOwner() ); // Shaitan => state list in the level if (!p_oStateToGo) { hStateToGo = mfn_p_oGetAction()->mfn_hGetStateFromLinkTable((char *)hStateToGo, (char *) (LPCSTR) mfn_p_oGetFamily()->GetName()); if (hStateToGo) { fn_vSetTargetStateInTransition(hTransition, hStateToGo); p_oStateToGo = M_FindStateByEngineHandle( this, hStateToGo, GetOwner() ); } } // End Shaitan => state list in the level ASSERT( p_oTargetState ); CPA_Action *p_oAction = p_oTargetState -> mfn_p_oGetAction(); // //ANNECY CT 11/02/98{ if (fn_ucGetLinkingTypeInTransition(hTransition) == C_ucProportionalLink) mfn_vSetTransitionStateInfo( p_oAction, E_ts_Fluid, p_oStateToGo, TRUE ); else mfn_vSetTransitionStateInfo( p_oAction, E_ts_Allowed, p_oStateToGo, TRUE ); //ENDANNECY CT} } // add prohibited states iIndex = 0; LST2_M_StaticForEachElementOf( & GetStruct() -> hForProhibitArray, hProhibit, iIndex) { // get State tdxHandleToState hState = fn_hGetProhibitedStateInProhibit( hProhibit ); CPA_State *p_oState = M_FindStateByEngineHandle( this, hState, GetOwner() ); // Shaitan => state list in the level if (!p_oState) { hState = mfn_p_oGetAction()->mfn_hGetStateFromLinkTable((char *)hState, (char *) (LPCSTR) mfn_p_oGetFamily()->GetName()); fn_vSetProhibitedStateInProhibit(hProhibit, hState); p_oState = M_FindStateByEngineHandle( this, hState, GetOwner() ); } // End Shaitan => state list in the level ASSERT( p_oState ); CPA_Action *p_oAction = p_oState -> mfn_p_oGetAction(); // mfn_vSetTransitionStateInfo( p_oAction, E_ts_Prohibited, NULL, TRUE ); } } // ---------------------------------------------------------------------------- // Author : Marc Trabucato Creation : 17/11/97 // Description : clear list // ---------------------------------------------------------------------------- void CPA_State::mfn_vResetTransitionStateInfoList( void ) { while( ! m_oListOfTransitionStateInfo . IsEmpty() ) { tdstTransitionStateInfo* p_stTSI = m_oListOfTransitionStateInfo . RemoveHead(); // if( p_stTSI -> p_oAction ) p_stTSI -> p_oAction -> mfn_vDontInterruptState( this ); // if( p_stTSI -> p_oStateToGo ) p_stTSI -> p_oStateToGo -> mfn_vDelAsTransitionalStateOf( this ); // free( p_stTSI ); } } // ---------------------------------------------------------------------------- // Author : Marc Trabucato Creation : 17/11/97 // Description : return tdstTransitionStateInfo struct associated with given // : action or NULL else // ---------------------------------------------------------------------------- tdstTransitionStateInfo* CPA_State::mfn_p_stGetTransitionStateInfo( CPA_Action *_p_oAction ) { tdstTransitionStateInfo* p_stResult = NULL; POSITION xPos; M_ForEachElement( &m_oListOfTransitionStateInfo, p_stResult, xPos ) { if( p_stResult -> p_oAction == _p_oAction ) return p_stResult; } return NULL; } // ---------------------------------------------------------------------------- // Author : Marc Trabucato Creation : 17/11/97 // Description : remove given state from transition list // ---------------------------------------------------------------------------- void CPA_State::mfn_vRemoveStateFromTransition( CPA_State *_p_oState ) { ASSERT( _p_oState ); tdstTransitionStateInfo *p_stTSI = mfn_p_stGetTransitionStateInfo( _p_oState -> mfn_p_oGetAction() ); if( p_stTSI ) { if( _p_oState -> mfn_bGetTransitional() ) { if( ( p_stTSI -> eState == E_ts_Allowed ) && ( p_stTSI -> p_oStateToGo == _p_oState ) ) { mfn_vSetTransitionStateInfo( _p_oState -> mfn_p_oGetAction(), E_ts_Allowed, NULL ); } } } } // ---------------------------------------------------------------------------- // Author : Marc Trabucato Creation : 17/11/97 // Description : remove TSI associated with given action // ---------------------------------------------------------------------------- void CPA_State::mfn_vRemoveActionFromTransition( CPA_Action *_p_oAction ) { ASSERT( _p_oAction ); tdstTransitionStateInfo *p_stTSI = NULL; POSITION xPos = NULL; xPos = m_oListOfTransitionStateInfo . GetHeadPosition(); while ( xPos ) { p_stTSI = m_oListOfTransitionStateInfo . GetAt( xPos ); if( p_stTSI -> p_oAction == _p_oAction ) { m_oListOfTransitionStateInfo . RemoveAt( xPos ); m_bMustRecomputeTransitions = TRUE; xPos = NULL; } else m_oListOfTransitionStateInfo . GetNext( xPos ); } } // ---------------------------------------------------------------------------- // Author : Marc Trabucato Creation : 17/11/97 // Description : TRUE if the given action is allowed fir the current state // ---------------------------------------------------------------------------- BOOL CPA_State::mfn_bIsActionProhibited( CPA_Action *_p_oAction ) { tdeTransitionState eState = mfn_eGetTransitionForAction( _p_oAction ); //ANNECY CT 11/02/98{ //return ( ( mfn_bIsProhibitedByDefault() && ( eState != E_ts_Allowed ) ) || ( eState == E_ts_Prohibited ) ); return ((mfn_bIsProhibitedByDefault() && !((eState == E_ts_Allowed) || (eState == E_ts_Fluid))) || (eState == E_ts_Prohibited )); //ENDANNECY CT} } // ---------------------------------------------------------------------------- // Author : Marc Trabucato Creation : 17/11/97 // Description : return the tdeTransitionState for given action on state // ---------------------------------------------------------------------------- tdeTransitionState CPA_State::mfn_eGetTransitionForAction( CPA_Action *_p_oAction ) { ASSERT( _p_oAction ); tdstTransitionStateInfo *p_stTSI = mfn_p_stGetTransitionStateInfo( _p_oAction ); return ( p_stTSI ? p_stTSI -> eState : E_ts_Unknown ); } #endif // ACTIVE_EDITOR