reman3/Rayman_X/cpa/tempgrp/TAc/src/CPAState.cpp

1201 lines
45 KiB
C++

/*=============================================================================
*
* 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<tdxHandleToState>::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<tdxHandleToState>(_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<tdxHandleToState>::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<CPA_State> 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