reman3/Rayman_X/cpa/tempgrp/AI/AIGame/FuncRay2.cxx

2881 lines
99 KiB
C++
Raw Blame History

/************************************************************************************************
* Name: FuncRay2.c *
* Use : Functions for AI of Rayman II *
* Author: Christophe Giraud *
* (c) UBI Simulations Annecy *
************************************************************************************************/
/*#include "safe.h" //BART*/
/*ANNECY CG {*/
#define ONLY4DEBUG
#include "PO.h"
#include "DataRay2.h"
#ifdef __cplusplus
extern "C"{
#endif
#define TEXT_MAX_PARAMETERS 10
extern int TEXT_gai_IntParameters[TEXT_MAX_PARAMETERS];
extern float TEXT_gaf_FloatParameters[TEXT_MAX_PARAMETERS];
extern char TEXT_gc_ViewportFixed;
#ifdef __cplusplus
}
#endif
/**********************************************************************************************************
* Function: TEXT_Affiche *
* *
* Use : Event := TEXT_Affiche( DSG_VAR_PersoGenerated, Always, vecteur(X,Y,Z), String, DSG_VAR_DELAY) *
* *
* Author : Christophe Giraud *
* Date of last modification: 15/10/98 *
* *
**********************************************************************************************************/
tdstNodeInterpret *fn_p_stCode4TextAffiche(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam * p_stValue )
{
tdstGetSetParam stParam ;
long ulEvent = 0 ;
tdstEngineObject *p_stEngineObject = NULL ;
HIE_tdxHandleToSuperObject p_SuperObjPersoGenerated = NULL ,
p_SuperObjPersoTreated = NULL;
MS_tdxHandleToDynam h_Dynam = NULL ;
POS_tdstCompletePosition *hPersoGlobalMatrix = NULL ;
tdstTfmtStatus stStatus ;
MTH3D_tdstVector stVertex , stTextPosition ;
MTH_tdxReal xPosX = MTH_C_ZERO , xPosY = MTH_C_ZERO , xPosZ = MTH_C_ZERO ;
long lPosX = 0 , lPosY = 0 , lPosZ = 0 , lStart = 0 , lEnd = -1 ;
MTH_tdxReal xxPosX , xxPosY , xxPosZ ;
unsigned long ulTimer = 0 , ulDeltaTimer = 0 ;
unsigned long ulDelay ;
char *p_szString = NULL , szCopy[600] ;
unsigned char ucPersoId , ucNumberOfCurrentTextAffiche = 0 , ucDelayId ;
short wPositionInString = 0 ;
ACP_tdxBool bFirstTime = TRUE ;
/* Get Perso parameter and his Id for acces to its DsgVar*/
#if defined(__DEBUG_AI__)
fn_vSetDontCheckNULLFlag(1);
#endif /* __DEBUG_AI__ */
ucPersoId = (unsigned char) M_ucVarIdInterpret(p_stTree);
M_EvalNextParameter(&stParam);
p_SuperObjPersoTreated = M_GetSetParam_p_stEngineObjValue(&stParam) ? M_GetSetParam_p_stSupObjValue(&stParam) : NULL;
#if defined(__DEBUG_AI__)
fn_vSetDontCheckNULLFlag(-1);
#endif /*__DEBUG_AI__ */
/* Get always model parameter*/
M_EvalNextParameter(&stParam);
#if defined(__DEBUG_AI__)
M_VerifyTypeOfParamAction(&stParam, E_vt_Perso);
#endif
p_stEngineObject = M_GetSetParam_p_stEngineObjValue(&stParam);
/* Get Coordinates parameters*/
M_EvalNextParameter(&stParam);
stTextPosition = M_GetSetParam_stVectorValue(&stParam);
MTH3D_M_vGetVectorElements( &lPosX, &lPosY, &lPosZ, &stTextPosition);
MTH3D_M_vGetVectorElements( &xxPosX, &xxPosY, &xxPosZ, &stTextPosition);
/* Get String parameter or string from Game.txt*/
M_EvalNextParameter(&stParam);
p_szString = fn_szGetStringFromTextOrStringParam(&stParam);
if (p_szString == NULL)
p_szString = "No Text";
#ifdef U64
if (((unsigned long)p_szString == 0xcccccccc)||(((unsigned long)p_szString & 0x80000000) != 0x80000000))
p_szString = "No Text";
#endif
/* process specials string /-?*/
if ( *p_szString == '/' && *(p_szString+1) == '-' )
{
char *szCur ;
long i ;
i = 0 ;
szCur = p_szString + 2 ;
switch ( *szCur )
{
case 'W' :
case 'w' :
TFMT_vUpdateSpacingTable(szCur+1);
break ;
case 'Z' :
case 'z' :
TFMT_vUpdateScaleTable(szCur+1);
break ;
}
/*remove un-interpreted parameters !!*/
M_Full_GetSetParam_Integer(p_stValue, ulEvent );
return fn_p_stSkipThisArgument(p_stTree) ;
}
SAF_M_AssertWithMsg(strlen(p_szString) < sizeof(szCopy), "Erreur Interne: la fonction ne peut traiter une cha<68>ne aussi longue");
strcpy(szCopy, p_szString);
/* Take care of /%Xnnn */
{
char *psz_Temp, *psz_Copy;
char asz_Num[20];
int i_Num;
psz_Copy = szCopy;
psz_Temp = p_szString;
while(*psz_Temp)
{
if(psz_Temp[0] == '/')
{
if(psz_Temp[1] == '%')
{
switch(psz_Temp[2])
{
/* Int */
case 'i':
case 'I':
i_Num = atoi(psz_Temp + 3);
itoa(TEXT_gai_IntParameters[i_Num], asz_Num, 10);
strcpy(psz_Copy, asz_Num);
psz_Copy += strlen(asz_Num);
while(*psz_Temp != ':')
psz_Temp++;
psz_Temp++;
continue;
break;
/* Float */
case 'f':
case 'F':
i_Num = atoi(psz_Temp + 3);
sprintf(asz_Num, "%.3f", TEXT_gaf_FloatParameters[i_Num]);
strcpy(psz_Copy, asz_Num);
psz_Copy += strlen(asz_Num);
while(*psz_Temp != ':')
psz_Temp++;
psz_Temp++;
continue;
break;
}
}
}
*psz_Copy++ = *psz_Temp++;
}
*psz_Copy = 0;
p_szString = szCopy ;
}
/* Get delay parameter*/
ucDelayId = (unsigned char) M_ucVarIdInterpret(p_stTree);
M_EvalNextParameter(&stParam);
ulDelay = M_GetSetParam_ulValue(&stParam);
if ( p_SuperObjPersoTreated != NULL )
{
/* Get the number of the current TEXT_Affiche function*/
ucNumberOfCurrentTextAffiche = TFMT_ucNumberOfCurrentTextAffiche( p_SuperObjPersoTreated );
/* Get the position of the current char to display*/
wPositionInString = g_stInfoTextAffiche[ ucNumberOfCurrentTextAffiche ].wCurrentLetterInString;
bFirstTime = g_stInfoTextAffiche[ ucNumberOfCurrentTextAffiche ].bFirstInit;
ulEvent = g_stInfoTextAffiche[ ucNumberOfCurrentTextAffiche ].ulEvent;
/* Exit if string is always fully displayed*/
if ( wPositionInString >= (short)strlen(p_szString) )
{
/* Inform the motor of the type and the value of the variable*/
M_Full_GetSetParam_Integer(p_stValue, ulEvent );
return(p_stTree);
}
}
/*------ GENERATION DE L'ALWAYS ------{*/
/********************************************
* Object is create only for the first time *
********************************************/
if (p_SuperObjPersoTreated==NULL)
{
MTH3D_M_vFillVector( &stVertex, MTH_C_ONE );
/* Generated the Always*/
if (p_stEngineObject!= NULL)
{
if (fn_ucIsAnAlwaysModel(p_stEngineObject))
{
POS_tdstCompletePosition stMatrix;
//HP 080499
#ifndef U64
tdObjectType otObjectModelType = M_ObjectGetModelType(p_stEngineObject);
#else
tdObjectType otObjectPersonalType = M_ObjectGetPersonalType(p_stEngineObject);
#endif
POS_fn_vSetIdentityMatrix(&stMatrix);
POS_fn_vSetTranslationVector(&stMatrix, &stVertex);
/* Create the always*/
#ifndef U64
p_SuperObjPersoGenerated = fn_p_stAllocateAlways(otObjectModelType, gp_stDynamicWorld, p_SuperObjPerso, 0, &stMatrix);
#else
p_SuperObjPersoGenerated = fn_p_stAllocateAlways(otObjectPersonalType, gp_stDynamicWorld, p_SuperObjPerso, 0, &stMatrix);
#endif
if ( p_SuperObjPersoGenerated != NULL )
{
register unsigned long ulTmpDelay = ulDelay;
/* to be sure that the anim player will not be called, clear the current state of the actor. */
fn_v3dDataSetFlagEndState(M_GetMSHandle(p_SuperObjPersoGenerated,3dData),TRUE);
/* Set a number for this new TEXT_Affiche function*/
ucNumberOfCurrentTextAffiche = TFMT_ucSetNumber4CurrentTextAffiche();
/* Get the Timer*/
ulTimer = g_stEngineStructure.stEngineTimer.ulCurrentTimerCount;
g_stInfoTextAffiche[ ucNumberOfCurrentTextAffiche ].ulTimer = ulTimer;
/* Store Delay*/
g_stInfoTextAffiche[ ucNumberOfCurrentTextAffiche ].ulCurrentDelay = ulDelay;
/* Store the new TEXT_Affiche always*/
gp_SuperObjPersoGenerated[ ucNumberOfCurrentTextAffiche ] = p_SuperObjPersoGenerated;
/* Restore the DsgVar for the Perso*/
M_Full_GetSetParam_Perso(&stParam, p_SuperObjPersoGenerated);
ucPersoId = fn_ucSetDsgVar(ucPersoId, 0, AI_M_stGetMindOfSuperObj(p_SuperObjPerso), &stParam);
/* ANNECY MT - 18/09/98 { next call is now useless*/
/*fn_vForceActiveAnObject(M_GetEngineObject( p_SuperObjPersoGenerated ) );*/
/* END ANNECY MT }*/
/*------ GENERATION DU TEXTE A LA CREATION DE L'ALWAYS ------{ */
if ( !ulDelay )
{
wPositionInString = -1;
ulEvent = TFMT_wPositionModulesAccordingToText2(&stStatus, p_SuperObjPersoGenerated, p_szString, lStart, lEnd, &bFirstTime, &wPositionInString, &ulDelay);
wPositionInString = strlen(p_szString);
}
else
{
ulEvent = TFMT_wPositionModulesAccordingToText2(&stStatus, p_SuperObjPersoGenerated, p_szString, lStart, lEnd, &bFirstTime, &wPositionInString, &ulDelay);
}
/*}------ GENERATION DU TEXTE A LA CREATION DE L'ALWAYS ------ */
if( ulDelay != ulTmpDelay )
{
if((int) ulDelay < 0)
ulDelay = -((int)ulDelay);
else
g_stInfoTextAffiche[ ucNumberOfCurrentTextAffiche ].ulCurrentDelay = ulDelay; /* It's a new delay*/
}
/*------ AFFICHAGE DANS LE SECOND VIEWPORT -----{*/
/* Initialize all the stuff*/
TEXT_vComputeLengthOgString(p_szString,&stStatus);
h_Dynam = M_GetMSHandle(p_SuperObjPersoGenerated,Dynam);
/* Get the global matrix of the actor's superobject*/
hPersoGlobalMatrix = HIE_fn_hGetSuperObjectGlobalMatrix(p_SuperObjPersoGenerated);
if(TEXT_gc_ViewportFixed)
{
HIE_fn_SO_vSetSuperimposedFlag(p_SuperObjPersoGenerated);
xPosY = MTH_M_xDiv( MTH_M_xLongToReal(lPosY), 1000.0 ) ;
xPosZ = MTH_M_xDiv( MTH_M_xLongToReal(lPosZ), 1000.0 );
if ( stStatus.cJustificationMode == 'c' )
{
xPosX = MTH_M_xDiv( 500.0, 1000.0 );
GLI_vGet3DVertexFromScreenPos( &g_stEngineStructure.stFixViewportAttr, &stVertex, xPosX, xPosY, xPosZ);
/* stVertex.xX -= MTH_M_xDiv( (stStatus.xScreenWidth - stStatus.xBaseToAddX), MTH_C_2 ); //total string width - space after the last char*/
stVertex.xX -= MTH_M_xDiv( stStatus.xScreenWidth, MTH_C_2 );
}
else
{
xPosX = MTH_M_xDiv( MTH_M_xLongToReal(lPosX), 1000.0 ) ;
GLI_vGet3DVertexFromScreenPos( &g_stEngineStructure.stFixViewportAttr, &stVertex, xPosX, xPosY, xPosZ);
}
#ifndef U64
hPersoGlobalMatrix->ulType = POS_C_ulCompleteMatrixFlag;
hPersoGlobalMatrix->stTransformMatrix.stCol_2.xZ = hPersoGlobalMatrix->stTransformMatrix.stCol_0.xX = g_stEngineStructure.stFixViewportAttr.dwWidth / 640.0f;
#endif /* U64 */
}
else
{
HIE_fn_SO_vClearSuperimposedFlag(p_SuperObjPersoGenerated);
stVertex.xX = xxPosX;
stVertex.xY = xxPosY;
stVertex.xZ = xxPosZ;
}
POS_fn_vSetTranslationVector(hPersoGlobalMatrix,&stVertex);
if ( h_Dynam )
{
DNM_tdstDynamics *p_stDynamics = fn_p_stDynamGetDynamics(h_Dynam);
MEC_vInitTranslation( p_stDynamics, p_SuperObjPersoGenerated, &stVertex );
}
HIE_fn_vComputeNewRelativeMatrix(p_SuperObjPersoGenerated);
/* update global matrix of all child*/
PLA_fn_vRefreshGlobalMatrixUnderCharacter(p_SuperObjPersoGenerated);
/*}------ AFFICHAGE DANS LE SECOND VIEWPORT ------ */
} /*** Mettre une sortie de secours si le perso n'est pas cr<63>er !!!!! ***/
}
}
}
else
{
/*------ GENERATION DU TEXTE ------{*/
/*if (!bFirstTime)*/
{
/* Compute delay*/
ulTimer = g_stInfoTextAffiche[ ucNumberOfCurrentTextAffiche ].ulTimer;
ulDeltaTimer = g_stEngineStructure.stEngineTimer.ulCurrentTimerCount-ulTimer;
p_SuperObjPersoGenerated = p_SuperObjPersoTreated;
bFirstTime = g_stInfoTextAffiche[ ucNumberOfCurrentTextAffiche ].bFirstInit;
if ( ulDeltaTimer>=ulDelay)
{
unsigned long ulTmpDelay = g_stInfoTextAffiche[ ucNumberOfCurrentTextAffiche ].ulCurrentDelay;
ulDelay = ulTmpDelay;
if (!ulDelay) /* No delay*/
{
while( (wPositionInString<(short)strlen(p_szString)) && (!ulDelay) )
{
ulEvent = TFMT_wPositionModulesAccordingToText2(&stStatus, p_SuperObjPersoGenerated, p_szString, lStart, lEnd, &bFirstTime, &wPositionInString, &ulDelay);
}
}
else
{
ulEvent = TFMT_wPositionModulesAccordingToText2(&stStatus, p_SuperObjPersoGenerated, p_szString, lStart, lEnd, &bFirstTime, &wPositionInString, &ulDelay);
}
g_stInfoTextAffiche[ ucNumberOfCurrentTextAffiche ].ulTimer = g_stEngineStructure.stEngineTimer.ulCurrentTimerCount;
/* Management of the next delay*/
if( ulDelay != ulTmpDelay )
{
if((int) ulDelay < 0)
ulDelay = -((int)ulDelay);
else
g_stInfoTextAffiche[ ucNumberOfCurrentTextAffiche ].ulCurrentDelay = ulDelay; /* It's a new delay*/
}
g_stInfoTextAffiche[ ucNumberOfCurrentTextAffiche ].ulTimer = g_stEngineStructure.stEngineTimer.ulCurrentTimerCount;
}
else
{
if (ulEvent)
{
register unsigned long ulTmpDelay = g_stInfoTextAffiche[ ucNumberOfCurrentTextAffiche ].ulCurrentDelay;
unsigned long ulCptDelay = ulTmpDelay;
ulEvent = TFMT_wPositionModulesAccordingToText2(&stStatus, p_SuperObjPersoGenerated, p_szString, lStart, lEnd, &bFirstTime, &wPositionInString, &ulCptDelay);
if( ulCptDelay != ulTmpDelay )
{
if((int) ulCptDelay < 0)
ulCptDelay = -((int)ulCptDelay);
else
g_stInfoTextAffiche[ ucNumberOfCurrentTextAffiche ].ulCurrentDelay = ulCptDelay; /* It's a new delay*/
ulDelay = ulCptDelay;
}
}
}
} /*}------ GENERATION DU TEXTE ------ */
} /*}------ GENERATION DE L'ALWAYS ------ */
/* Restore all datas of the current TEXT_Affiche function*/
g_stInfoTextAffiche[ ucNumberOfCurrentTextAffiche ].bFirstInit = bFirstTime;
g_stInfoTextAffiche[ ucNumberOfCurrentTextAffiche ].ulEvent = ulEvent;
g_stInfoTextAffiche[ ucNumberOfCurrentTextAffiche ].wCurrentLetterInString = wPositionInString;
/* Restore the DsgVar for the Delay*/
M_Full_GetSetParam_Integer( &stParam, ulDelay );
ucDelayId = fn_ucSetDsgVar(ucDelayId, 0, AI_M_stGetMindOfSuperObj(p_SuperObjPerso), &stParam);
/* Inform the motor of the type and the value of the variable*/
M_Full_GetSetParam_Integer(p_stValue, ulEvent);
return(p_stTree);
}
/******************************************************************************************
* Function: Code4PointsDair *
* Use : LitPointsDair( ) *
* : Return the Air point of Rayman *
* Use : LitPointsDairMax( ) *
* : Return the Air point Max of Rayman *
* Use : AjouteEtLitPointsDair( Entier Number_Of_Air_Points ) *
* : Add Number_Of_Air_Points and return the Air point of Rayman *
* Use : AjouteEtLitPointsDairMax( Entier Number_Of_Air_Points ) *
* : Add Number_Of_Air_Points to Air points max and return the Air point Max *
* Use : EnleveEtLitPointsDair( Entier Number_Of_Air_Points ) *
* : Sub Number_Of_Air_Points and return the Air point of Rayman *
* Use : EnleveEtLitPointsDairMax( Entier Number_Of_Air_Points ) *
* : Sub Number_Of_Air_Points to Air points max and return the Air point Max *
* Author : Christophe Giraud *
* Date of last modification: 24/02/98 *
******************************************************************************************/
tdstNodeInterpret *fn_p_stCode4PointsDair(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
MTH_tdxReal xValue = MTH_C_ZERO; /* Variable to stock the return value*/
MTH_tdxReal xNumberOfAirPoints; /* variable to store the eventual parameter*/
MTH_tdxReal xSign = MTH_C_ONE;
tdstGetSetParam stParam; /* Structure d'<27>change*/
enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1);
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
switch(eFuncId)
{
case eFunc_LitPointsDair:
/* Get Air points of Ray*/
xValue = stExtendDatas4Ray.xAirPoints4Ray;
break;
case eFunc_LitPointsDairMax:
/* Get Air points Max of Ray*/
xValue = stExtendDatas4Ray.xAirPointsMax4Ray;
break;
case eFunc_EnleveEtLitPointsDair:
xSign = MTH_C_MinusONE;
/* No break : enleve = ajoute du n<>gatif*/
#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/
case eFunc_AjouteEtLitPointsDair:
#endif /* _AI_EXCLUDE_NEVER_USED_ }*/
{
/* Get number of Air points to add*/
M_EvalNextParameter( &stParam );
SAF_M_AssertWithMsg(MTH_M_bGreaterEqual(M_ReturnParam_xValue( &stParam ), MTH_C_ZERO), "On ne peut manipuler que des points d'air positifs!");
xNumberOfAirPoints = MTH_M_xMul(xSign, M_ReturnParam_xValue( &stParam ));
/* Add "xNumberOfAirPoints"*/
xValue = MTH_M_xAdd(stExtendDatas4Ray.xAirPoints4Ray, xNumberOfAirPoints);
/* Test if Number of Air points > Number of Air points max*/
if ( MTH_M_bGreater(xValue, stExtendDatas4Ray.xAirPointsMax4Ray) )
xValue = stExtendDatas4Ray.xAirPointsMax4Ray;
else if ( MTH_M_bLessZero(xValue) )
xValue = MTH_C_ZERO;
/* Return number of Air points*/
stExtendDatas4Ray.xAirPoints4Ray = xValue;
}
break;
#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/
case eFunc_EnleveEtLitPointsDairMax:
xSign = MTH_C_MinusONE;
/* No break : enleve = ajoute du neg*/
case eFunc_AjouteEtLitPointsDairMax:
{
/* Get number of Air points to add*/
M_EvalNextParameter( &stParam );
SAF_M_AssertWithMsg(MTH_M_bGreaterEqual(M_ReturnParam_xValue( &stParam ), MTH_C_ZERO), "On ne peut manipuler que des points d'air positifs!");
xNumberOfAirPoints = MTH_M_xMul(xSign, M_ReturnParam_xValue( &stParam ));
/* Add "xNumberOfAirPoints"*/
xValue = MTH_M_xAdd(stExtendDatas4Ray.xAirPointsMax4Ray, xNumberOfAirPoints);
/* Test if Number of Air points > MAXAirPOINTS*/
if ( MTH_M_bLessZero(xValue) )
xValue = MTH_C_ZERO;
if ( MTH_M_bLess(xValue, stExtendDatas4Ray.xAirPoints4Ray) )
stExtendDatas4Ray.xAirPoints4Ray = xValue;
/* Return number of Air points Max*/
stExtendDatas4Ray.xAirPointsMax4Ray = xValue;
}
break;
#endif /* _AI_EXCLUDE_NEVER_USED_ }*/
default:
#if defined(__DEBUG_AI__) || (defined(U64) && defined(D_CHECK_AI_FPCO))
M_AIFatalError(E_uwAIFatalNotValidFunction);
#endif
return(p_stTree);
break;
}
M_Full_GetSetParam_Float(p_stValue, xValue );
return(p_stTree);
}
/******************************************************************************************
* Function: Code4PointsDeMagie *
* Use : LitPointsDeMagie( ) *
* : Return the magic point of Rayman *
* Use : LitPointsDeMagieMax( ) *
* : Return the magic point Max of Rayman *
* Use : AjouteEtLitPointsDeMagie( Entier Number_Of_Magic_Points ) *
* : Add Number_Of_Magic_Points and return the magic point of Rayman *
* Use : AjouteEtLitPointsDeMagieMax( Entier Number_Of_Magic_Points ) *
* : Add Number_Of_Magic_Points to Magic points max and return the magic point Max *
* Use : EnleveEtLitPointsDeMagie( Entier Number_Of_Magic_Points ) *
* : Sub Number_Of_Magic_Points and return the magic point of Rayman *
* Use : EnleveEtLitPointsDeMagieMax( Entier Number_Of_Magic_Points ) *
* : Sub Number_Of_Magic_Points to Magic points max and return the magic point Max *
* Author : Christophe Giraud *
* Date of last modification: 30/10/97 *
******************************************************************************************/
#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/
tdstNodeInterpret *fn_p_stCode4PointsDeMagie(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
long lValue=0, /* Variable to stock the return value*/
lNumberOfMagicPoints;
tdstGetSetParam stParam ; /* Structure d'<27>change*/
enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1);
switch(eFuncId)
{
case eFunc_LitPointsDeMagie:
/* Get magic points of Ray*/
lValue = stExtendDatas4Ray.iMagicPoints4Ray;
break;
case eFunc_LitPointsDeMagieMax:
/* Get magic points Max of Ray*/
lValue = stExtendDatas4Ray.iMagicPointsMax4Ray;
break;
case eFunc_AjouteEtLitPointsDeMagie:
{
/* Evaluation of next parameter*/
M_EvalNextParameter( &stParam );
/* Get number of magic points to add*/
lNumberOfMagicPoints = M_ReturnParam_lValue( &stParam );
SAF_M_AssertWithMsg(lNumberOfMagicPoints >= 0, "On ne peut manipuler que des points de magie positifs!");
/* Add "lNumberOfMagicPoints"*/
stExtendDatas4Ray.iMagicPoints4Ray += lNumberOfMagicPoints;
/* Test if Number of magic points > Number of magic points max*/
if ( stExtendDatas4Ray.iMagicPoints4Ray > stExtendDatas4Ray.iMagicPointsMax4Ray )
stExtendDatas4Ray.iMagicPoints4Ray = stExtendDatas4Ray.iMagicPointsMax4Ray;
/* Return number of magic points*/
lValue = stExtendDatas4Ray.iMagicPoints4Ray;
}
break;
case eFunc_AjouteEtLitPointsDeMagieMax:
{
/* Evaluation of next parameter*/
M_EvalNextParameter( &stParam );
/* Get number of magic points to add*/
lNumberOfMagicPoints = M_ReturnParam_lValue( &stParam );
SAF_M_AssertWithMsg(lNumberOfMagicPoints >= 0, "On ne peut manipuler que des points de magie positifs!");
/* Add "lNumberOfMagicPoints"*/
stExtendDatas4Ray.iMagicPointsMax4Ray += lNumberOfMagicPoints;
/* Return number of magic points Max*/
lValue = stExtendDatas4Ray.iMagicPointsMax4Ray;
}
break;
case eFunc_EnleveEtLitPointsDeMagie:
{
/* Evaluation of next parameter*/
M_EvalNextParameter( &stParam );
/* Get number of magic points to sub*/
lNumberOfMagicPoints = M_ReturnParam_lValue( &stParam );
SAF_M_AssertWithMsg(lNumberOfMagicPoints >= 0, "On ne peut manipuler que des points de magie positifs!");
/* Sub "lNumberOfMagicPoints"*/
stExtendDatas4Ray.iMagicPoints4Ray -= lNumberOfMagicPoints;
/* Test if Number of magic points < 0*/
if ( stExtendDatas4Ray.iMagicPoints4Ray < 0 )
stExtendDatas4Ray.iMagicPoints4Ray = 0;
/* Return number of magic points*/
lValue = stExtendDatas4Ray.iMagicPoints4Ray;
}
break;
case eFunc_EnleveEtLitPointsDeMagieMax:
{
/* Evaluation of next parameter*/
M_EvalNextParameter( &stParam );
/* Get number of magic points to sub*/
lNumberOfMagicPoints = M_ReturnParam_lValue( &stParam );
SAF_M_AssertWithMsg(lNumberOfMagicPoints >= 0, "On ne peut manipuler que des points de magie positifs!");
/* Sub "lNumberOfMagicPoints"*/
stExtendDatas4Ray.iMagicPointsMax4Ray -= lNumberOfMagicPoints;
/* Test if Number of magic points Max < 0*/
if ( stExtendDatas4Ray.iMagicPointsMax4Ray < 0 )
stExtendDatas4Ray.iMagicPointsMax4Ray = 0;
/* Return number of magic points Max*/
lValue = stExtendDatas4Ray.iMagicPointsMax4Ray;
}
break;
default:
#if defined(__DEBUG_AI__) || (defined(U64) && defined(D_CHECK_AI_FPCO))
M_AIFatalError(E_uwAIFatalNotValidFunction);
#endif
return(p_stTree);
break;
}
/* Inform the motor of the type and the value of the variable*/
M_Full_GetSetParam_Integer(p_stValue, lValue );
return(p_stTree);
}
#endif /* _AI_EXCLUDE_NEVER_USED_ }*/
/**********************************************************************
**********************************************************************/
static ACP_tdxBool fn_vGetZoneCenter(ACP_tdxHandleOfObject _hGeoObj, MTH3D_tdstVector *_hZoneCenter)
{
ACP_tdxBool bZoneIsValid;
/* deal with type of GEO OBJ*/
switch ( *_hGeoObj->d_xListOfElementsTypes )
{
/* Get center of a sphere*/
case GEO_C_xElementSpheres :
{
ACP_tdxIndex xCenter;
/* get Center of the spehere*/
xCenter = GEO_xGetCenterPointOfIndexedSphere(_hGeoObj,0,0);
GEO_vGetPointOfObject(_hGeoObj,_hZoneCenter,xCenter);
/*we found one, dont bother with module zones*/
bZoneIsValid = 1;
}
break;
/* Get center of a box*/
case GEO_C_xElementAlignedBoxes :
{
ACP_tdxIndex xMin,xMax;
MTH3D_tdstVector stMin,stMax;
/* get Min & Max of the box*/
GEO_vGetMinMaxPointOfIndexedAlignedBox(_hGeoObj,0,0,&xMin,&xMax);
GEO_vGetPointOfObject(_hGeoObj,&stMin,xMin);
GEO_vGetPointOfObject(_hGeoObj,&stMax,xMax);
/* Compute Center*/
MTH3D_M_vAddVector(_hZoneCenter,&stMin,&stMax);
MTH3D_M_vMulScalarVector(_hZoneCenter,MTH_C_Inv2,_hZoneCenter);
/*we found one, dont bother with module zones*/
bZoneIsValid = 1;
}
break;
default:
bZoneIsValid = 0;
break;
}
return bZoneIsValid;
}
static void fn_vInternGetZDxCenter(
HIE_tdxHandleToSuperObject _hCharacter,
GMT_tdxMask _xMask,
unsigned char _ucZoneType,
ACP_tdxBool _bInGlobalCoordinates,
MTH3D_tdstVector *_p_stReturnVector
)
{
long lI, lMax;
ACP_tdxHandleOfObject hGeoObj;
ACP_tdxBool bFoundOne = 0;
/* found the good Zone in the list*/
lMax = fn_lGetZdxListNumberOfElements(_ucZoneType, _hCharacter);
for ( lI = 0; lI < lMax; lI ++ )
{
hGeoObj = fn_hGetGeometricZdxOfTypeAtIndex(_ucZoneType, (unsigned short)lI, _hCharacter);
if ( hGeoObj && fn_hIsTypeExistsInGeoObj(hGeoObj, _xMask) && fn_hIsThisZoneActive(_hCharacter, _ucZoneType, (unsigned char) lI) )
{
if ( (bFoundOne = fn_vGetZoneCenter(hGeoObj, _p_stReturnVector)) != 0 ) /*VOLUNTARY ASSIGNMENT!*/
{
if ( _bInGlobalCoordinates )
{
POS_fn_vMulMatrixVertex(_p_stReturnVector,HIE_fn_hGetSuperObjectGlobalMatrix(_hCharacter),_p_stReturnVector);
}
else
{
MTH3D_tdstMatrix stScaleMatrix;
POS_tdstCompletePosition *hGlobalMatrix = HIE_fn_hGetSuperObjectGlobalMatrix(_hCharacter);
/*dont forget to apply the actor's scale to the relative position if necessary*/
if ( !POS_fn_ulIsNotScaledMatrix(hGlobalMatrix) )
{
POS_fn_vGetScaleMatrix(
hGlobalMatrix,
&stScaleMatrix.stCol_0,
&stScaleMatrix.stCol_1,
&stScaleMatrix.stCol_2
);
MTH3D_M_vMulMatrixVector(_p_stReturnVector, &stScaleMatrix, _p_stReturnVector);
}
}
break;
}
}
}
/*we found no zones, check module zones to see if we get what we want there*/
if ( !bFoundOne )
{
PCS_tdxHandleToPhysicalCollSet hPhysicalCollideSet;
CHN_tdxHandleToChannel hChannel;
/*ACP_tdxIndex xIndex;*/
HIE_tdxHandleToSuperObject hModule;
hChannel = fn_h3dDataGetFirstActiveChannel(M_GetMSHandle(_hCharacter,3dData));
while (hChannel)
{
hModule = hChannel->hSupObject;
if
(
hModule
&& ( (HIE_fn_ulGetSuperObjectType(hModule) & (HIE_C_ulPO | HIE_C_ulPO_Mirror)) )
/* beware, the flag name is improper: it is true when the object is visible */
&& ( ! ( HIE_M_xGetSuperObjectMember(hModule, ulFlags) & HIE_C_Flag_ulHidden ) ) /* don't use a zone when its channel is deactivated */
)
{
hPhysicalCollideSet = PO_fn_hGetCollideSet( (PO_tdxHandleToPhysicalObject)HIE_fn_hGetSuperObjectObject(hModule) );
switch ( _ucZoneType )
{
case C_ucTypeZde:
hGeoObj = PCS_fn_hGetZdeGeoObjOfPhysicalCollSet(hPhysicalCollideSet);
break;
#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/
case C_ucTypeZdd:
hGeoObj = PCS_fn_hGetZddGeoObjOfPhysicalCollSet(hPhysicalCollideSet);
break;
case C_ucTypeZdr:
hGeoObj = PCS_fn_hGetZdrGeoObjOfPhysicalCollSet(hPhysicalCollideSet);
break;
case C_ucTypeZdm:
hGeoObj = PCS_fn_hGetZdmGeoObjOfPhysicalCollSet(hPhysicalCollideSet);
break;
#endif /* _AI_EXCLUDE_NEVER_USED_ }*/
default:
hGeoObj = NULL;
break;
}
if ( hGeoObj && fn_hIsTypeExistsInGeoObj(hGeoObj, _xMask) && ( (bFoundOne = fn_vGetZoneCenter(hGeoObj, _p_stReturnVector)) != 0) ) /*VOLUNTARY ASSIGNMENT!*/
{
POS_tdstCompletePosition stGlobToPerso;
#ifdef ACTIVE_EDITOR
fn_vCheckModuleAccess(_hCharacter, FALSE, &hModule);
#endif
/*express the center in perso coordinates (it is in module's coordinates)*/
/* passing by global coordinates due to possible hierarchy*/
POS_fn_vMulMatrixVertex(_p_stReturnVector,HIE_fn_hGetSuperObjectGlobalMatrix(hModule),_p_stReturnVector);
if ( !_bInGlobalCoordinates )
{
POS_fn_vInvertMatrix(&stGlobToPerso,HIE_fn_hGetSuperObjectGlobalMatrix(_hCharacter));
POS_fn_vMulMatrixVertex(_p_stReturnVector,&stGlobToPerso,_p_stReturnVector);
}
/*and stop now, because we got what we want*/
break;
}
}
hChannel = hChannel->p_stNextActiveChannel;
}
}
}
/**********************************************************************
* Function: PersoLePlusProche *
* Function: CibleLaPlusProche *
* Use : Perso = PersoLePlusProche() *
* Return NULL is there is no perso (enemy) *
* !! A enemy is a character with Good Custom Bit *
* Use : Perso = CibleLaPlusProche() *
* Return NULL is there is no perso (enemy) *
* !! A enemy is a character with Good Custom Bit *
* *
* Author : Christophe Giraud *
* Date of last modification: 24/11/97 *
* Modif : 15/07/98 Add CibleLaPlusProche - Carlos Torres *
* Modif : 17/07/98 Add PersoLePlusProcheDansChampsDeVision - jt *
* Modif : 20/08/98 Add Search direction in CibleLaPlusProche - CT *
**********************************************************************/
HIE_tdxHandleToSuperObject fn_hGetClosestPersoInSector(
HIE_tdxHandleToSuperObject _hCloserSO, /*the closest perso I found so far*/
MTH_tdxReal *_p_xBestDist, /* the distance at which I found the closest until now*/
MTH_tdxReal *_p_xPrevWeight, /*its associated weight*/
HIE_tdxHandleToSuperObject _hMe, /*identify myself so that I cant be the closet actor to myself...*/
MTH3D_tdstVector *_p_stMyVector, /*where I am*/
MTH3D_tdstVector *_p_stActorSighting, /*where I look*/
POS_tdstCompletePosition *_p_stGlobToPerso, /*matrix to convert positions into my local coordinates*/
HIE_tdxHandleToSuperObject _hSector, /*sector to search*/
unsigned long _ulFilterCustomBits, /*custombits to accept*/
MTH_tdxReal _xXWeight,
MTH_tdxReal _x2DWeight,
MTH_tdxReal _x3DWeight,
GMT_tdxMask _xMask, /*if the test has to be done against a ZDE center, the mask will be non null...*/
MTH_tdxReal _xCosXoY, /* angle of the the cone in degree*/
MTH_tdxReal _xSinYoZ, /* angle of the the cone in degree*/
enum tdeFuncId_ _eFuncId /*what is to be done*/
)
{
SECT_tdxHandleOfElementLstCharacter hCharacterElement;
HIE_tdxHandleToSuperObject hCharacterSO;
int j;
MTH_tdxReal xTmp;
MTH3D_tdstVector stVector;
MS_tdxHandleToStandardGame hStdGame;
#ifdef ONLY4DEBUG
char *cName,*cCloserName;
MS_tdxHandleToBrain hBrain;
#endif
/* Find all characters in the current sector of the list*/
SECT_M_ForEachCharListInSector(_hSector, hCharacterElement, j)
{
hCharacterSO = SECT_GetCharacterInList( hCharacterElement );
if ( hCharacterSO != _hMe )
{
#ifdef ONLY4DEBUG
hBrain = M_GetMSHandle(hCharacterSO,Brain);
if (hBrain)
cName = AI_M_szGetPersoName(AI_M_stGetMindOfSuperObj(hCharacterSO));
#endif
/* Do this only if CustomBits are set*/
/* if ( (fn_ulStandardGameGetCustomBits(M_GetMSHandle(hCharacterSO,StandardGame)) & _ulFilterCustomBits) == _ulFilterCustomBits ) */
hStdGame = M_GetMSHandle(hCharacterSO,StandardGame);
if( hStdGame && /* always not destroyed */
!fn_bf1StandardGameGetIsDesactivateAtAll(hStdGame) && /* actor not definitively dead */
( (fn_ulStandardGameGetCustomBits(hStdGame) & _ulFilterCustomBits) == _ulFilterCustomBits ) ) /* wanted custombits */
{
/* by default use the coordinates of the character*/
POS_fn_vGetTranslationVector( HIE_fn_hGetSuperObjectGlobalMatrix( hCharacterSO ), &stVector );
if ( _xMask ) /*if we want to test a ZDE position, get it now*/
fn_vInternGetZDxCenter(hCharacterSO, _xMask, C_ucTypeZde, TRUE, &stVector);
#if !defined(_AI_EXCLUDE_NEVER_USED_) /*{*/
/* PERSO LE PLUS PROCHE*/
if ( _eFuncId == eFunc_PersoLePlusProche )
{
/* Distance between My character and other one*/
xTmp = MTH3D_M_xVectorGap(&stVector, _p_stMyVector);
if ( MTH_M_bLess(xTmp, *_p_xBestDist) )
{
*_p_xBestDist = xTmp;
_hCloserSO = hCharacterSO;
#ifdef ONLY4DEBUG
hBrain = M_GetMSHandle(hCharacterSO,Brain);
if (hBrain)
cCloserName = AI_M_szGetPersoName(AI_M_stGetMindOfSuperObj(hCharacterSO));
#endif
}
}
/* PERSO LE PLUS PROCHE DANS LE CHAMPS DE VISION*/
else if ( _eFuncId == eFunc_NearerActorInFieldOfVision )
{
MTH3D_M_vSubVector ( &stVector, _p_stMyVector, &stVector );
MTH3D_M_vNormalizeVector ( &stVector, &stVector );
xTmp = MTH3D_M_xDotProductVector ( _p_stActorSighting, &stVector );
if ( MTH_M_bGreater(xTmp, MTH_M_xDoubleToReal(0.5)) )
{
xTmp = MTH3D_M_xVectorGap(&stVector, _p_stMyVector);
if ( MTH_M_bLess(xTmp,*_p_xBestDist) )
{
*_p_xBestDist = xTmp;
_hCloserSO = hCharacterSO;
#ifdef ONLY4DEBUG
hBrain = M_GetMSHandle(hCharacterSO,Brain);
if (hBrain)
cCloserName = AI_M_szGetPersoName(AI_M_stGetMindOfSuperObj(hCharacterSO));
#endif
}
}
}
else
#endif /* !defined(_AI_EXCLUDE_NEVER_USED_) */ /*}*/
/* CIBLE LA PLUS PROCHE*/
{
MTH3D_tdstVector stTargetPosition;
MTH_tdxReal xNorm ,xX, xY, xZ, xWeight = MTH_C_ZERO;
MTH_tdxReal xNormXoY, xAngleYoZ ;
/* get target position in perso coordinates*/
POS_fn_vMulMatrixVertex(&stTargetPosition,_p_stGlobToPerso,&stVector);
MTH3D_M_vGetVectorElements(&xX,&xY,&xZ,&stTargetPosition);
stTargetPosition.xZ = MTH_C_ZERO;
xNormXoY = MTH3D_M_xNormVector(&stTargetPosition);
stTargetPosition.xZ = xZ;
if ( xNormXoY )
xAngleYoZ = MTH_M_xATan ( MTH_M_xDiv ( xZ , xNormXoY ) ) ;
else
xAngleYoZ = MTH_C_PiBy2 ;
/* compute weight if target is in both detection sectors */
if
(
MTH_M_bGreater ( MTH_M_xNeg ( xY ) , MTH_M_xMul ( _xCosXoY , xNormXoY ) )
&& MTH_M_bLess ( MTH_M_xSin ( xAngleYoZ ), _xSinYoZ )
)
{
/* if the target is in the back of the fighter, consider the angle only! */
if ( MTH_M_bGreaterEqualZero ( xY ) )
{
if ( MTH_M_bEqualZero(xX) )
{
/* the target is straight in the back of the fighter: no way we select it! */
xWeight = MTH_C_InfinitMinus ;
}
else
{
/* we use a negative weight to continue favorizing the target in front of the fighter */
/* but the target with the smaller angle is preferred, ie the less in the back */
xWeight = MTH_M_xNeg ( MTH_M_xAbs ( MTH_M_xDiv ( xY , xX ) ) ) ;
}
}
else
{
/* compute Weight N1/|X| + N2/|XY| + N3/|XYZ|*/
if ( MTH_M_bEqualZero(xX) )
{
xWeight = MTH_C_InfinitPlus;
}
else
{
xX = MTH_M_xAbs(xX);
xNorm = MTH3D_M_xNormVector(&stTargetPosition);
xWeight = MTH_M_xDiv(_xXWeight, xX);
xWeight = MTH_M_xAdd(xWeight, MTH_M_xDiv(_x2DWeight, MTH_M_xSqrt(MTH_M_xAdd(MTH_M_xSqr(xX),MTH_M_xSqr(xY)))));
xWeight = MTH_M_xAdd(xWeight, MTH_M_xDiv(_x3DWeight, xNorm));
}
}
/* better target*/
if ( MTH_M_bGreater(xWeight,*_p_xPrevWeight) )
{
*_p_xPrevWeight = xWeight;
_hCloserSO = hCharacterSO;
#ifdef ONLY4DEBUG
hBrain = M_GetMSHandle(hCharacterSO,Brain);
if (hBrain)
cCloserName = AI_M_szGetPersoName(AI_M_stGetMindOfSuperObj(hCharacterSO));
#endif
}
}
}
}
}
}
return _hCloserSO ;
}
tdstNodeInterpret *fn_p_stCode4PersoLePlusProche(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
tdstGetSetParam stParam;
HIE_tdxHandleToSuperObject hCurrentSectorPerso,hGraphicSectorSO,/*hCharacterSO,*/hCloserSO = NULL;
SECT_tdxHandleOfElementLstGraphicInteraction hGraphicElement;
/*SECT_tdxHandleOfElementLstCharacter hCharacterElement;*/
MTH3D_tdstVector stMyVector/*, stVector*/;
struct POS_stCompletePosition stGlobToPerso;
MTH_tdxReal /*xTmp,*/xBestDist = MTH_C_InfinitPlus;
unsigned long ulCustomBitValue;
MTH_tdxReal xXWeight = MTH_C_ZERO, x2DWeight = MTH_C_ZERO, x3DWeight = MTH_C_ZERO;
MTH_tdxReal xPrevWeight = MTH_M_xDiv ( MTH_C_InfinitMinus , MTH_C_2 ) ;
MTH3D_tdstVector *p_stTmpVector1, *p_stTmpVector2, *p_stActorSighting,stDirection;
GMT_tdxMask xMask = (GMT_tdxMask) 0;
/*MTH_tdxReal xDotProd;*/
MTH_tdxReal xCosXoY = MTH_M_xFloatToReal(0.8944f), xSinYoZ = MTH_M_xFloatToReal(0.4473f); /* default angle 26.56deg*/
enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1);
/*XB980429*/
/* long lValue=0;*/
/*End XB*/
int i/*, j*/;
/*unsigned long ulCurrentBits;*/
/*#ifdef ONLY4DEBUG
char *cName,*cCloserName;
MS_tdxHandleToBrain hBrain;
#endif*/
/********************************************************************************/
/* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */
/********************************************************************************/
HIE_tdxHandleToSuperObject hNewSuperObjPerso;
fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId), p_SuperObjPerso, &hNewSuperObjPerso);
/********************************************************************************/
/* Evaluation of next parameter*/
M_EvalNextParameter( &stParam );
/* Get number the custom bit value*/
ulCustomBitValue = M_ReturnParam_lValue(&stParam);
switch(eFuncId)
{
case eFunc_CibleLaPlusProcheAvecAngles:
case eFunc_CibleLaPlusProche:
/* Get weight for x distance*/
M_EvalNextParameter( &stParam );
xXWeight = M_ReturnParam_xValue(&stParam);
SAF_M_AssertWithMsg(MTH_M_bGreaterEqual(xXWeight, MTH_C_ZERO), "Les poids doivent <20>tre positifs ou nuls!");
/* Get weight for distance in plan XY*/
M_EvalNextParameter( &stParam );
x2DWeight = M_ReturnParam_xValue(&stParam);
SAF_M_AssertWithMsg(MTH_M_bGreaterEqual(x2DWeight, MTH_C_ZERO), "Les poids doivent <20>tre positifs ou nuls!");
/* Get weight for global distance*/
M_EvalNextParameter( &stParam );
x3DWeight = M_ReturnParam_xValue(&stParam);
SAF_M_AssertWithMsg(MTH_M_bGreaterEqual(x3DWeight, MTH_C_ZERO), "Les poids doivent <20>tre positifs ou nuls!");
/* Get Search direction (absolute coordinates)*/
M_EvalNextParameter( &stParam );
stDirection=M_GetSetParam_stVectorValue(&stParam);
xMask = (GMT_tdxMask) 0x0001; /* type JaiMalType*/
/* get angle and compute Cosinus*/
if (eFunc_CibleLaPlusProcheAvecAngles == eFuncId)
{
M_EvalNextParameter( &stParam );
xCosXoY = M_ReturnParam_xValue(&stParam);
SAF_M_AssertWithMsg(
MTH_M_bGreaterZero(xCosXoY) && MTH_M_bLessEqual(xCosXoY, MTH_M_xFloatToReal(180.0f)),
"L'angle horizontal doit <20>tre compris entre 0<> exclus et 180<38> inclus !"
);
xCosXoY = MTH_M_xCos(MTH_M_xDegToRad(xCosXoY));
M_EvalNextParameter( &stParam );
xSinYoZ = M_ReturnParam_xValue(&stParam);
SAF_M_AssertWithMsg(
MTH_M_bGreaterZero(xSinYoZ) && MTH_M_bLessEqual(xSinYoZ, MTH_M_xFloatToReal(90.0f)),
"L'angle vertical doit <20>tre compris entre 0<> exclus et 90<39> inclus !"
);
xSinYoZ = MTH_M_xSin(MTH_M_xDegToRad(xSinYoZ));
}
#if !defined(_AI_EXCLUDE_NEVER_USED_) /*{*/
case eFunc_PersoLePlusProche:
case eFunc_NearerActorInFieldOfVision:
#endif /*!defined(_AI_EXCLUDE_NEVER_USED_)*/ /*}*/
{
/* Point to the current sector where the character is*/
hCurrentSectorPerso = fn_h_SectInfoGetCurrentSector( M_GetMSHandle( hNewSuperObjPerso, SectInfo ) );
#if !defined(_AI_EXCLUDE_NEVER_USED_) /*{*/
/* PERSO LE PLUS PROCHE*/
if (eFuncId == eFunc_PersoLePlusProche)
{
/* Coordinates of my character*/
POS_fn_vGetTranslationVector( HIE_fn_hGetSuperObjectGlobalMatrix( hNewSuperObjPerso), &stMyVector );
}
/* PERSO LE PLUS PROCHE DANS CHAMPS DE VISION*/
else if ( eFuncId == eFunc_NearerActorInFieldOfVision )
{
POS_tdxHandleToPosition hActorMatrix = HIE_fn_hGetSuperObjectGlobalMatrix( hNewSuperObjPerso);
POS_fn_vGetTranslationVector( hActorMatrix, &stMyVector );
POS_fn_vGetRotationVector ( hActorMatrix, &p_stTmpVector1, &p_stActorSighting, &p_stTmpVector2 );
}
else
#endif /*!defined(_AI_EXCLUDE_NEVER_USED_)*/ /*}*/
/* CIBLE LA PLUS PROCHE*/
{
MTH3D_tdstVector vI,vJ,vK;
struct POS_stCompletePosition stGlobPerso;
/* get Glob Matrix & current rotation of perso*/
POS_fn_vCopyMatrix(&stGlobPerso,HIE_fn_hGetSuperObjectGlobalMatrix(hNewSuperObjPerso));
if (!MTH3D_M_bIsNullVector(&stDirection)) {
POS_fn_vGetRotationMatrix(&stGlobPerso,&vI,&vJ,&vK);
/* Compute new rotation with the direction*/
/* compute J*/
MTH3D_M_vNegVector(&stDirection,&stDirection);
MTH3D_M_vNormalizeVector(&vJ,&stDirection);
/* compute K before I, if J&K are colinear*/
if (MTH_M_bEqualWithEpsilon(MTH3D_M_xDotProductVector(&vJ,&vK),MTH_C_ONE,MTH_M_xFloatToReal(0.002)) ) {
/* compute K*/
MTH3D_M_vCrossProductVectorWithoutBuffer(&vK,&vI,&vJ);
/* compute I*/
MTH3D_M_vCrossProductVectorWithoutBuffer(&vI,&vJ,&vK);
}
/* compute I before K*/
else {
/* compute I*/
MTH3D_M_vCrossProductVectorWithoutBuffer(&vI,&vJ,&vK);
/* compute K*/
MTH3D_M_vCrossProductVectorWithoutBuffer(&vK,&vI,&vJ);
}
/* change rotation*/
POS_fn_vSetRotationMatrix(&stGlobPerso,&vI,&vJ,&vK);
}
/* build matrix to transform glob coordinates in perso coordinates*/
POS_fn_vInvertIsoMatrix(&stGlobToPerso,&stGlobPerso);
}
hCloserSO = fn_hGetClosestPersoInSector(
hCloserSO, /*the closest perso I found so far*/
&xBestDist, /* the distance at which I found it*/
&xPrevWeight, /*its associated weight*/
hNewSuperObjPerso, /*identify myself so that I cant be the closet actor to myself...*/
&stMyVector, /*where I am*/
p_stActorSighting, /*where I look*/
&stGlobToPerso, /*matrix to convert positions into my local coordinates*/
hCurrentSectorPerso, /*sector to search*/
ulCustomBitValue, /*custombits to accept*/
xXWeight,
x2DWeight,
x3DWeight,
xMask,
xCosXoY,
xSinYoZ,
eFuncId /*what is to be done*/
);
/* Cover the list of visible sectors*/
SECT_M_ForEachGraphicNodeInGraphicInteractionList(hCurrentSectorPerso, hGraphicElement, i)
{
hGraphicSectorSO = SECT_GetSectorInGraphicList( hGraphicElement );
hCloserSO = fn_hGetClosestPersoInSector(
hCloserSO, /*the closest perso I found so far*/
&xBestDist, /* the distance at which I found it*/
&xPrevWeight, /*its associated weight*/
hNewSuperObjPerso, /*identify myself so that I cant be the closet actor to myself...*/
&stMyVector, /*where I am*/
p_stActorSighting, /*where I look*/
&stGlobToPerso, /*matrix to convert positions into my local coordinates*/
hGraphicSectorSO, /*sector to search*/
ulCustomBitValue, /*custombits to accept*/
xXWeight,
x2DWeight,
x3DWeight,
xMask,
xCosXoY,
xSinYoZ,
eFuncId /*what is to be done*/
);
}
}
/* On informe le moteur sur le type et la valeur calcul<75>e.*/
M_Full_GetSetParam_Perso(p_stValue, hCloserSO);
return(p_stTree);
break;
default:
break;
}
/* La fonction n'existe pas !!*/
M_AIFatalError(E_uwAIFatalNotValidFunction);
/* On informe le moteur sur l'avancement dans l'interpr<70>tation*/
return p_stTree;
}
/*ANNECY JMD & BART {*/
tdstNodeInterpret *fn_p_stGraphFunction(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1);
WP_tdHandleOfGraph hGraph ;
long lValue, lWeight;
unsigned long ulNewCaps;
/* struct tdstEngineObject_ * hEngineObj; // there's no "tdhEngineObject" ? ? ? ? ? ? ! ! !*/
/* Oliv' - Portage v14*/
/* char bIsCircular=0;*/
/* EndOfOliv'*/
WP_tdhWayPoint hWayPoint1, hWayPoint2 ;
/********************************************************************************/
/* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */
/********************************************************************************/
/* HIE_tdxHandleToSuperObject hNewSuperObjPerso;*/
/* fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hNewSuperObjPerso);*/
/* Evaluation of parameters*/
M_EvalNextParameter( p_stValue );
#if defined(__DEBUG_AI__)
M_VerifyTypeOfParamAction(p_stValue, E_vt_Graph);
#endif /* __DEBUG_AI__*/
hGraph = M_GetSetParam_GraphValue(p_stValue) ;
M_EvalNextParameter( p_stValue );
hWayPoint1 = M_GetSetParam_WayPointValue(p_stValue) ;
M_EvalNextParameter( p_stValue );
hWayPoint2 = M_GetSetParam_WayPointValue(p_stValue) ;
if (hGraph == NULL)
{
if (eFuncId == eFunc_ReseauLitCapaciteLiaisonDansGraph)
{
M_Full_GetSetParam_Caps(p_stValue, (unsigned long)0);
}
else
{
M_Full_GetSetParam_Integer(p_stValue, -1);
}
return(p_stTree);
}
switch(eFuncId)
{
case eFunc_ReseauLitCapaciteLiaisonDansGraph :
{
if(WPG_fn_lGetLinkCapabilities (hGraph, hWayPoint1, hWayPoint2, &ulNewCaps ) == -1) { /*-1 if failed !*/
M_Full_GetSetParam_Caps(p_stValue, (unsigned long)0);
} else {
M_Full_GetSetParam_Caps(p_stValue, ulNewCaps);
}
return(p_stTree);
break;
}
case eFunc_ReseauChangeCapaciteLiaisonDansGraph :
{
M_EvalNextParameter( p_stValue );
ulNewCaps = M_GetSetParam_CapsValue( p_stValue);
M_EvalNextParameter( p_stValue );
lValue = M_GetSetParam_lValue(p_stValue) ;
lValue = WPG_fn_lChangeLinkCapabilities (hGraph, hWayPoint1, hWayPoint2, ulNewCaps, lValue ) ;
/* On informe le moteur sur le type et la valeur calcul<75>e.*/
M_Full_GetSetParam_Integer(p_stValue, lValue);
return(p_stTree);
break;
}
#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/
case eFunc_ReseauLitPoidsLiaisonDansGraph :
{
if(WPG_fn_lGetLinkWeight(hGraph, hWayPoint1, hWayPoint2, &lWeight ) == -1) { /*-1 if failed !*/
M_Full_GetSetParam_Integer(p_stValue, -1);
} else {
M_Full_GetSetParam_Integer(p_stValue, lWeight);
}
return(p_stTree);
break;
}
case eFunc_ReseauChangePoidsLiaisonDansGraph :
{
M_EvalNextParameter( p_stValue );
lWeight = M_GetSetParam_lValue(p_stValue) ;
lValue = WPG_fn_lChangeLinkWeight(hGraph, hWayPoint1, hWayPoint2, lWeight) ;
/* On informe le moteur sur le type et la valeur calcul<75>e.*/
M_Full_GetSetParam_Integer(p_stValue, lValue);
return(p_stTree);
break;
}
#endif /* _AI_EXCLUDE_NEVER_USED_ }*/
default:
break;
}
/* La fonction n'existe pas !!*/
M_AIFatalError(E_uwAIFatalNotValidFunction);
/* On informe le moteur sur l'avancement dans l'interpr<70>tation*/
return(p_stTree);
}
tdstNodeInterpret *fn_p_stGraphToWayFunction(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
enum tdeFuncId_ eFuncId;
MS_tdxHandleToMSWay h_MSWay;
WP_tdHandleOfGraph hGraph ;
long lValue ;
struct tdstEngineObject_ * hEngineObj; /* there's no "tdhEngineObject" ? ? ? ? ? ? ! ! !*/
char bIsCircular;
WP_tdHandleOfGraph hPath ;
WP_tdhWayPoint hWayPoint1, hWayPoint2 ;
WP_tdhGraphNode hCurrentNode ; /*Bart*/
unsigned long ulPersoCapability ;
int i;
/********************************************************************************/
/* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */
/********************************************************************************/
HIE_tdxHandleToSuperObject hNewSuperObjPerso;
eFuncId=M_eFuncIdInterpret(p_stTree-1);
fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hNewSuperObjPerso);
h_MSWay = M_GetMSHandle(hNewSuperObjPerso, MSWay);
SAF_M_AssertWithMsg((h_MSWay != NULL),"MsWay non allou<6F>")
M_EvalNextParameter( p_stValue );
#if defined(__DEBUG_AI__)
M_VerifyTypeOfParamAction(p_stValue, E_vt_Graph);
#endif /* __DEBUG_AI__*/
hGraph = M_GetSetParam_GraphValue(p_stValue) ;
/* 0 is the default (error) return value !*/
lValue = 0;
/* The way is not circular by default !*/
bIsCircular=0;
switch(eFuncId)
{
case eFunc_ReseauCheminLePlusCourt :
{
/* Evaluation of parameters*/
M_EvalNextParameter( p_stValue );
hWayPoint1 = M_GetSetParam_WayPointValue(p_stValue) ;
M_EvalNextParameter( p_stValue );
hWayPoint2 = M_GetSetParam_WayPointValue(p_stValue) ;
if ( ( h_MSWay == NULL) || (hGraph == NULL) )
{
M_Full_GetSetParam_Integer(p_stValue, 0L);
return(p_stTree);
break;
}
/* get perso capability */
hEngineObj = M_GetEngineObject(hNewSuperObjPerso);
ulPersoCapability = fn_ulGetCapabilities(hEngineObj);
hPath = WPG_fn_lShortestPath (hGraph, hWayPoint1, hWayPoint2, ulPersoCapability ) ;
if ( hPath ) {
MSWay_fn_vSetPath(h_MSWay, hPath, 0); /* bIsCircular=0;*/
lValue = WPG_fn_lNumberOfWaypointOfGraph (hPath) ;
}
else {
MSWay_fn_vDesinitPath(h_MSWay) ;
lValue = 0 ;
}
/* On informe le moteur sur le type et la valeur calcul<75>e.*/
M_Full_GetSetParam_Integer(p_stValue, lValue );
return(p_stTree);
break;
}
case eFunc_NetworkBuildOrderedPathCircular:
bIsCircular = 1;
case eFunc_NetworkBuildOrderedPath :
{
/* Evaluation of parameters*/
M_EvalNextParameter( p_stValue );
hWayPoint1 = M_GetSetParam_WayPointValue(p_stValue);
if ( ( h_MSWay == NULL) || (hGraph == NULL) )
{
M_Full_GetSetParam_Integer(p_stValue, 0L);
return(p_stTree);
break;
}
hPath = WPG_fn_lBuildOrderedPath(hGraph, hWayPoint1 );
if ( hPath ) {
MSWay_fn_vSetPath(h_MSWay, hPath, bIsCircular);
lValue = WPG_fn_lNumberOfWaypointOfGraph (hPath);
}
else {
MSWay_fn_vDesinitPath(h_MSWay) ;
lValue = 0 ;
}
/* On informe le moteur sur le type et la valeur calcul<75>e.*/
M_Full_GetSetParam_Integer(p_stValue, lValue );
return(p_stTree);
break;
}
#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/
case eFunc_NetworkAllocateGraphToMSWayCircular:
bIsCircular = 1;
#endif /* _AI_EXCLUDE_NEVER_USED_ }*/
case eFunc_NetworkAllocateGraphToMSWay:
{
/*SAF_M_AssertWithMsg(FALSE,"Ne plus utiliser \"Reseau_AffecteGraphAChemin\" SVP !")*/
/* No more parameter*/
if ( ( h_MSWay == NULL) || (hGraph == NULL) )
{
M_Full_GetSetParam_Integer(p_stValue, 0);
return(p_stTree);
break;
}
#if defined(OLD_CODE)
MSWay_fn_vSetPath(h_MSWay, hGraph, bIsCircular);
lValue = WPG_fn_lNumberOfWaypointOfGraph (hGraph) ;
#else /*OLD_CODE*/
LST2_M_DynamicGetElementNumber(&hGraph->m_hListOfNode, hCurrentNode, 0, i); /* first WP*/
hPath = WPG_fn_lBuildOrderedPath(hGraph, hCurrentNode->m_hWayPoint );
if ( hPath ) {
MSWay_fn_vSetPath(h_MSWay, hPath, bIsCircular);
lValue = WPG_fn_lNumberOfWaypointOfGraph (hPath);
}
else {
MSWay_fn_vDesinitPath(h_MSWay) ;
lValue = 0 ;
}
#endif /*defined(OLD_CODE)*/
/* On informe le moteur sur le type et la valeur calcul<75>e.*/
M_Full_GetSetParam_Integer(p_stValue, lValue );
return(p_stTree);
break;
}
default:
break;
}
/* La fonction n'existe pas !!*/
M_AIFatalError(E_uwAIFatalNotValidFunction);
/* On informe le moteur sur l'avancement dans l'interpr<70>tation*/
return(p_stTree);
}
tdstNodeInterpret *fn_p_stWayFunction(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1);
MS_tdxHandleToMSWay h_MSWay;
long lValue, lIndex, lWeight ;
unsigned long ulNewCaps;
/* struct tdstEngineObject_ * hEngineObj; // there's no "tdhEngineObject" ? ? ? ? ? ? ! ! !*/
/* Oliv' - Portage v15 - remove unused local variable and 1 warning*/
/* char bIsCircular=0;*/
/* EndOfOliv'*/
/********************************************************************************/
/* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */
/********************************************************************************/
HIE_tdxHandleToSuperObject hNewSuperObjPerso;
fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hNewSuperObjPerso);
h_MSWay = M_GetMSHandle(hNewSuperObjPerso, MSWay);
SAF_M_AssertWithMsg((h_MSWay != NULL),"MsWay non allou<6F>")
if ( h_MSWay == NULL) {
//XB 14/099
#if defined(U64)
M_PrintfStopErrorN64(("MsWay not allocated SPO=0x%x",hNewSuperObjPerso));
return NULL;
#endif /* defined(U64) && !defined(FINAL_VERSION) */
//End XB 14/099
switch(eFuncId)
{
case eFunc_ReseauLitWPAIndex :
M_Full_GetSetParam_WayPoint(p_stValue, NULL );
break;
case eFunc_ReseauLitCapaciteLiaisonAIndex :
M_Full_GetSetParam_Caps(p_stValue, (unsigned long)0);
/* Oliv' - Portage v14*/
default : break;
/* EndOfOliv'*/
}
M_Full_GetSetParam_Integer(p_stValue, -1 );
return(p_stTree);
}
switch(eFuncId)
{
case eFunc_ReseauLitIndexCourant:
{
lValue = MSWay_fn_lGetCurrentIndexInPath (h_MSWay) ;
/* On informe le moteur sur le type et la valeur calcul<75>e.*/
M_Full_GetSetParam_Integer(p_stValue, lValue );
return(p_stTree);
break;
}
case eFunc_ReseauForceIndexCourant:
{
M_EvalNextParameter( p_stValue );
lValue = MSWay_fn_lSetCurrentIndexInPath(h_MSWay, M_GetSetParam_lValue(p_stValue) );
/* On informe le moteur sur le type et la valeur calcul<75>e.*/
M_Full_GetSetParam_Integer(p_stValue, lValue );
return(p_stTree);
break;
}
case eFunc_ReseauLitPremierIndex:
{
lValue = MSWay_fn_lGetFirstIndexInPath ( h_MSWay ) ;
/* On informe le moteur sur le type et la valeur calcul<75>e.*/
M_Full_GetSetParam_Integer(p_stValue, lValue );
return(p_stTree);
break;
}
case eFunc_ReseauLitDernierIndex:
{
lValue = MSWay_fn_lGetLastIndexInPath ( h_MSWay ) ;
/* On informe le moteur sur le type et la valeur calcul<75>e.*/
M_Full_GetSetParam_Integer(p_stValue, lValue );
return(p_stTree);
break;
}
case eFunc_ReseauIncrementIndex :
{
/* Evaluation of next parameter*/
M_EvalNextParameter( p_stValue );
lValue=MSWay_fn_lIncrementCurrentIndexInPath(h_MSWay, M_GetSetParam_lValue(p_stValue) );
/* On informe le moteur sur le type et la valeur calcul<75>e.*/
M_Full_GetSetParam_Integer(p_stValue, lValue );
return(p_stTree);
break;
}
case eFunc_ReseauDecrementIndex :
{
/* Evaluation of next parameter*/
M_EvalNextParameter( p_stValue );
lValue=MSWay_fn_lIncrementCurrentIndexInPath(h_MSWay, -(M_GetSetParam_lValue(p_stValue)) );
/* On informe le moteur sur le type et la valeur calcul<75>e.*/
M_Full_GetSetParam_Integer(p_stValue, lValue );
return(p_stTree);
break;
}
case eFunc_ReseauLitWPAIndex :
{
WP_tdhWayPoint hWayPoint ;
/* Evaluation of next parameter*/
M_EvalNextParameter( p_stValue );
hWayPoint=MSWay_fn_hGetWayPointOfPath(h_MSWay, M_GetSetParam_lValue(p_stValue) );
/* On informe le moteur sur le type et la valeur calcul<75>e.*/
M_Full_GetSetParam_WayPoint(p_stValue, hWayPoint );
return(p_stTree);
break;
}
case eFunc_ReseauLitCapaciteLiaisonAIndex :
{
/* Evaluation of parameters*/
M_EvalNextParameter( p_stValue );
lIndex = M_GetSetParam_lValue(p_stValue) ;
ulNewCaps = MSWay_fn_ulGetCapsForNextWayPointOfPath (h_MSWay, lIndex) ;
/* On informe le moteur sur le type et la valeur calcul<75>e.*/
M_Full_GetSetParam_Caps(p_stValue, ulNewCaps);
return(p_stTree);
break;
}
#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/
case eFunc_ReseauChangeCapaciteLiaisonAIndex :
{
/* Evaluation of parameters*/
M_EvalNextParameter( p_stValue );
lIndex = M_GetSetParam_lValue(p_stValue) ;
M_EvalNextParameter( p_stValue );
ulNewCaps = M_GetSetParam_CapsValue( p_stValue);
M_EvalNextParameter( p_stValue );
lValue = M_GetSetParam_lValue(p_stValue) ;
lValue = MSWay_fn_lChangeCapsForNextWayPointOfPath (h_MSWay, lIndex, ulNewCaps, lValue) ;
/* On informe le moteur sur le type et la valeur calcul<75>e.*/
M_Full_GetSetParam_Integer(p_stValue, lValue);
return(p_stTree);
break;
}
case eFunc_ReseauLitPoidsLiaisonAIndex :
{
/* Evaluation of parameters*/
M_EvalNextParameter( p_stValue );
lIndex = M_GetSetParam_lValue(p_stValue) ;
lWeight = MSWay_fn_lGetWeightForNextWayPointOfPath (h_MSWay, lIndex) ;
/* On informe le moteur sur le type et la valeur calcul<75>e.*/
M_Full_GetSetParam_Integer(p_stValue, lWeight);
return(p_stTree);
break;
}
case eFunc_ReseauChangePoidsLiaisonAIndex :
{
/* Evaluation of parameters*/
M_EvalNextParameter( p_stValue );
lIndex = M_GetSetParam_lValue(p_stValue) ;
M_EvalNextParameter( p_stValue );
lWeight = M_GetSetParam_lValue(p_stValue) ;
lValue = MSWay_fn_lChangeWeightForNextWayPointOfPath (h_MSWay, lIndex, lWeight) ;
/* On informe le moteur sur le type et la valeur calcul<75>e.*/
M_Full_GetSetParam_Integer(p_stValue, lValue);
return(p_stTree);
break;
}
#endif /* _AI_EXCLUDE_NEVER_USED_ }*/
/* To search for a WP in the way, and get its index (-1 if error)*/
case eFunc_NetworkGetIndexOfWPInMSWay:
{
/* Evaluation of parameters*/
WP_tdhWayPoint hWayPoint;
M_EvalNextParameter( p_stValue );
hWayPoint = M_GetSetParam_WayPointValue(p_stValue);
lValue = MSWay_fn_lLookForWPInMSWay(h_MSWay, hWayPoint); /* might be -1 if not found*/
/* On informe le moteur sur le type et la valeur calcul<75>e.*/
M_Full_GetSetParam_Integer(p_stValue, lValue );
return(p_stTree);
break;
}
/* To force a WP to be the current WP in a way. Returns the index of the WP in the way(-1 if error)*/
case eFunc_NetworkForceWPToCurrent:
{
long lIndex;
/* Evaluation of parameters*/
WP_tdhWayPoint hWayPoint;
M_EvalNextParameter( p_stValue );
hWayPoint = M_GetSetParam_WayPointValue(p_stValue) ;
lIndex = MSWay_fn_lLookForWPInMSWay(h_MSWay, hWayPoint); /* might be -1 if not found*/
if (lIndex != -1)
lValue = MSWay_fn_lSetCurrentIndexInPath(h_MSWay, lIndex );
else
lValue = -1; /* not found !*/
/* On informe le moteur sur le type et la valeur calcul<75>e.*/
M_Full_GetSetParam_Integer(p_stValue, lValue );
return(p_stTree);
break;
}
default:
break;
}
/* La fonction n'existe pas !!*/
M_AIFatalError(E_uwAIFatalNotValidFunction);
/* On informe le moteur sur l'avancement dans l'interpr<70>tation*/
return(p_stTree);
}
tdstNodeInterpret *fn_p_stCloserWPInGraph(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1);
long lValue, lIndex, lNbWPInGraph, lTypeOfWPToTest = 0, lTypeOfWP;
WP_tdHandleOfGraph hGraph;
WP_tdhWayPoint hBestWP = (WP_tdhWayPoint)NULL;
WP_tdhWayPoint hWayPoint = NULL, hWayPoint1 = NULL, hWayPoint2 = NULL;
MTH_tdxReal xBestDist = MTH_C_MinusONE;
MTH_tdxReal xTmp;
MTH3D_tdstVector stCurrentWPVector, stPosPerso, stTempVector;
HIE_tdxHandleToSuperObject hCurrentSectorPerso;
/********************************************************************************/
/* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */
/********************************************************************************/
HIE_tdxHandleToSuperObject hNewSuperObjPerso;
fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hNewSuperObjPerso);
/********************************************************************************/
/* Evaluation of parameters*/
/*ANNECY Bart 10/02/98 {*/
M_EvalNextParameter(p_stValue);
#if defined(__DEBUG_AI__)
M_VerifyTypeOfParamAction(p_stValue, E_vt_Graph);
#endif /* __DEBUG_AI__*/
hGraph = M_GetSetParam_GraphValue(p_stValue) ;
M_EvalNextParameter( p_stValue );
lValue = M_GetSetParam_lValue(p_stValue) ;
/*ENDANNECY Bart }*/
switch(eFuncId)
{
case eFunc_NetworkCloserWPOfType:
M_EvalNextParameter( p_stValue );
lTypeOfWPToTest = (long)M_GetSetParam_CapsValue(p_stValue);
#if defined(__DEBUG_AI__)
fn_vSetDontCheckNULLFlag(1); /* BART : we allow to have WayPoints to NoWhere !*/
#endif /*__DEBUG_AI__ */
M_EvalNextParameter( p_stValue );
hWayPoint1 = M_GetSetParam_WayPointValue(p_stValue) ;
M_EvalNextParameter( p_stValue );
hWayPoint2 = M_GetSetParam_WayPointValue(p_stValue) ;
#if defined(__DEBUG_AI__)
fn_vSetDontCheckNULLFlag(-1);
#endif /* __DEBUG_AI__ */
/* then as in Func_ReseauWPLePlusProche :*/
case eFunc_ReseauWPLePlusProche:
{
if (hGraph == NULL)
{
M_Full_GetSetParam_WayPoint(p_stValue, (WP_tdhWayPoint)NULL); /* return NULL as WayPoint ! !*/
return(p_stTree);
break;
}
POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(hNewSuperObjPerso),&stPosPerso);
/* sorti de la boucle car inutile de le refaire <20> chaque fois...*/
hCurrentSectorPerso = fn_h_SectInfoGetCurrentSector(M_GetMSHandle(hNewSuperObjPerso, SectInfo));
lNbWPInGraph = WPG_fn_lNumberOfWaypointOfGraph (hGraph) ;
for ( lIndex = 0; lIndex < lNbWPInGraph; lIndex ++ )
{
hWayPoint = WPG_fn_hGetWaypointOfGraph(hGraph, lIndex, &lTypeOfWP); /* Bart*/
if
(
(eFuncId != eFunc_NetworkCloserWPOfType)
||
(
(hWayPoint != hWayPoint1)
&& (hWayPoint != hWayPoint2)
&& ((lTypeOfWPToTest & lTypeOfWP) == lTypeOfWPToTest)
)
)
{
/* dans le if() car inutile de le faire en dehors -> on peut gagner du temps*/
WP_fnv_WayPoint_ComputeLocation( hWayPoint, &stCurrentWPVector);
MTH3D_M_vSubVector(&stTempVector, &stCurrentWPVector, &stPosPerso);
xTmp = MTH3D_M_xNormVector(&stTempVector);
if
(
(MTH_M_bEqual(xBestDist, (MTH_tdxReal) -1))
||
(MTH_M_bLess(xTmp, xBestDist))
)
{
if ( lValue )
{
/* chech way validity*/
if
(
!HIE_bDetectIntersectSegmentWithSuperObject(
&stPosPerso,
/* &stCurrentWPVector,*/
&stTempVector,
hCurrentSectorPerso
)
)
{
xBestDist = MTH3D_M_xNormVector(&stTempVector);
hBestWP = hWayPoint;
}
}
else
{
xBestDist = MTH3D_M_xNormVector(&stTempVector);
hBestWP = hWayPoint;
}
}
}
}
M_Full_GetSetParam_WayPoint(p_stValue, hBestWP);
return(p_stTree);
}
break;
/* ANNECY CG CLOSER WAYPOINT WITH AXE 19/06/98 {*/
#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/
case eFunc_ReseauWPLePlusDansLAxe2:
M_EvalNextParameter( p_stValue );
lTypeOfWPToTest = (long)M_GetSetParam_CapsValue(p_stValue);
#if defined(__DEBUG_AI__)
fn_vSetDontCheckNULLFlag(1); /* BART : we allow to have WayPoints to NoWhere !*/
#endif /* __DEBUG_AI__ */
M_EvalNextParameter( p_stValue );
hWayPoint1 = M_GetSetParam_WayPointValue(p_stValue) ;
M_EvalNextParameter( p_stValue );
hWayPoint2 = M_GetSetParam_WayPointValue(p_stValue) ;
#if defined(__DEBUG_AI__)
fn_vSetDontCheckNULLFlag(-1);
#endif /* __DEBUG_AI__ */
/* then as in Func_ReseauWPLePlusDansLAxe :*/
case eFunc_ReseauWPLePlusDansLAxe:
{
/*
-->
Axe
Perso ----------------->
\ |
\ |
\ | --> ------->
\ | distance Axe/Waypoint = // Axe x PersoWP //
\ | -----------------
\ | -->
\ | // Axe //
\ |
\|
Waypoint
*/
MTH3D_tdstVector stAxisVector,
stPersoWaypointVector;
/*stTmpVector;*/
tdstGetSetParam stParam;
/* Get the axis vector*/
M_EvalNextParameter(&stParam);
stAxisVector = M_GetSetParam_stVectorValue(&stParam);
if (hGraph == NULL)
{
M_Full_GetSetParam_WayPoint(p_stValue, (WP_tdhWayPoint)NULL); /* return NULL as WayPoint ! !*/
return(p_stTree);
break;
}
/* Get the position of the perso*/
POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectGlobalMatrix(hNewSuperObjPerso),&stPosPerso);
/* Get the current sector of the perso*/
hCurrentSectorPerso = fn_h_SectInfoGetCurrentSector(M_GetMSHandle(hNewSuperObjPerso, SectInfo));
lNbWPInGraph = WPG_fn_lNumberOfWaypointOfGraph (hGraph) ;
hBestWP = NULL;
for ( lIndex = 0; lIndex < lNbWPInGraph; lIndex ++ )
{
hWayPoint = WPG_fn_hGetWaypointOfGraph(hGraph, lIndex, &lTypeOfWP);
if (
(eFuncId != eFunc_ReseauWPLePlusDansLAxe2) ||
( (hWayPoint != hWayPoint1) && (hWayPoint != hWayPoint2) &&
((lTypeOfWPToTest & lTypeOfWP) == lTypeOfWPToTest) )
)
{
/* Compute Position of the Waypoint*/
WP_fnv_WayPoint_ComputeLocation( hWayPoint, &stCurrentWPVector);
/* Compute Vector PersoWaypoint*/
MTH3D_M_vSubVector( &stPersoWaypointVector, &stCurrentWPVector, &stPosPerso );
/*
Compute --> ------->
// Axe x PersoWP //
-------------------
-->
// Axe //
*/
/*MTH3D_M_vCrossProductVector( &stTmpVector, &stAxisVector, &stPersoWaypointVector );*/
/*xTmp = MTH3D_M_xNormVector(&stTmpVector)/MTH3D_M_xNormVector(&stAxisVector);*/
/* in fact, it is better to test the cosinus :*/
xTmp = MTH3D_M_xDotProductVector(&stAxisVector, &stPersoWaypointVector )/MTH3D_M_xNormVector(&stPersoWaypointVector );
/*if ( (MTH_M_bEqual(xBestDist, (MTH_tdxReal) -1)) || (MTH_M_bLess(xTmp, xBestDist)) )*/
if ( (MTH_M_bEqual(xBestDist, (MTH_tdxReal) -1)) || (MTH_M_bGreater(xTmp, xBestDist)) )
{
if (lValue)
{
/* chech way validity*/
if (
!HIE_bDetectIntersectSegmentWithSuperObject( &stPosPerso,
/* &stCurrentWPVector,*/
&stPersoWaypointVector,
hCurrentSectorPerso )
)
{
xBestDist = xTmp;
hBestWP = hWayPoint;
}
}
else
{
xBestDist = xTmp;
hBestWP = hWayPoint;
}
}
}
}
M_Full_GetSetParam_WayPoint(p_stValue, hBestWP);
return(p_stTree);
}
break;
/* } ENDANNECY CG CLOSERWAYPOINT WITH AXE 19/06/98*/
#endif /* _AI_EXCLUDE_NEVER_USED_ }*/
default:
break;
}
/* La fonction n'existe pas !!*/
M_AIFatalError(E_uwAIFatalNotValidFunction);
/* On informe le moteur sur l'avancement dans l'interpr<70>tation*/
return(p_stTree);
}
tdstNodeInterpret *fn_p_stTravelOnAGraph(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1);
long lIndex, lTypeOfWP;
unsigned long ulCapaToTest;
WP_tdHandleOfGraph hGraph;
WP_tdhWayPoint hWayPoint, hWayPoint2;
WP_tdhGraphNode hCurrentNode; /* the node currently examine*/
WP_tdHandleOfListOfArc hListOfArc = NULL;
long lValue = 0;
/* Evaluation of parameters*/
M_EvalNextParameter(p_stValue);
#if defined(__DEBUG_AI__)
M_VerifyTypeOfParamAction(p_stValue, E_vt_Graph);
#endif /* __DEBUG_AI__*/
hGraph = M_GetSetParam_GraphValue(p_stValue) ;
lTypeOfWP = 0L;
#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/
if ( (eFuncId == eFunc_NetworkAffectTypeOfConnectedWP) || (eFuncId == eFunc_NetworkAffectTypeOfConnectedWPWithCapa) ) {
/*get the TypeOfWP to affect to the WP*/
M_EvalNextParameter( p_stValue );
lTypeOfWP = (long)M_GetSetParam_CapsValue(p_stValue);
}
#endif /* _AI_EXCLUDE_NEVER_USED_ }*/
/*get the waypoint from which we want to search*/
M_EvalNextParameter( p_stValue );
hWayPoint = M_GetSetParam_WayPointValue(p_stValue) ;
ulCapaToTest = (unsigned long)0;
//#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/
if(
(eFuncId == eFunc_NetworkNextWPWithCapa)
//XB
#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/
||
(eFuncId == eFunc_NetworkAffectTypeOfConnectedWPWithCapa)
#endif /* _AI_EXCLUDE_NEVER_USED_ }*/
//End XB
)
{
/*get the capability to match*/
M_EvalNextParameter( p_stValue );
ulCapaToTest = (unsigned long)M_GetSetParam_CapsValue(p_stValue);
}
//#endif /* _AI_EXCLUDE_NEVER_USED_ }*/
#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/
if ( (eFuncId == eFunc_NetworkAffectTypeOfConnectedWP) || (eFuncId == eFunc_NetworkAffectTypeOfConnectedWPWithCapa) ) {
M_EvalNextParameter(p_stValue);
#if defined(__DEBUG_AI__)
M_VerifyTypeOfParamAction(p_stValue, E_vt_Integer);
#endif /* __DEBUG_AI__*/
lValue = (unsigned char) M_GetSetParam_lValue(p_stValue);
}
#endif /* _AI_EXCLUDE_NEVER_USED_ }*/
/* now scan the list of connections from the current waypoint*/
lIndex = -1; /* juste pour faire plaisir <20> YLG !*/
hWayPoint2 = (WP_tdhWayPoint)NULL;
/* looking for the starting WP :*/
LST2_M_DynamicForEachElementOf(&hGraph->m_hListOfNode, hCurrentNode, lIndex) {
if ( hCurrentNode->m_hWayPoint == hWayPoint ) {
hWayPoint2 = hWayPoint;
break ;
}
}
/* we found the waypoint in the graph -> get its connections*/
if ( hWayPoint2 ) {
hListOfArc = WPG_fn_hGetArcList(hCurrentNode);
}
switch(eFuncId)
{
case eFunc_NetworkNextWPWithCapa: /* find next waypoint from the specified one that we can get from the current one*/
{
hWayPoint2 = (WP_tdhWayPoint) NULL; /*re-nullify because Nowhere is the default return value*/
if ( hListOfArc ) {
/*scan each arc of the node to see if its capability matches ours*/
long lBestWeight = (long) ( ((unsigned long) (1 << 31)) - 1 ); /* max possible Weight*/
WP_tdHandleOfArc hElement;
LST2_M_DynamicForEachElementOf(&hListOfArc->m_hArc, hElement, lIndex) { /* if already exists !*/
hWayPoint = hElement->m_hNode->m_hWayPoint;
/* if the capabilities match and the arc has a higher weight, proceed*/
if ( (hElement->m_ulCapability & ulCapaToTest) && (hElement->m_lWeight < lBestWeight) ) {
lBestWeight = hElement->m_lWeight;
hWayPoint2 = hWayPoint;
}
}
}
M_Full_GetSetParam_WayPoint(p_stValue, hWayPoint2); /* return NULL as WayPoint ! !*/
}
break;
#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/
case eFunc_NetworkAffectTypeOfConnectedWP:
case eFunc_NetworkAffectTypeOfConnectedWPWithCapa:
{
long lNbOfConnectedWP = 0;
/* first, erase this type in the types Field of all the nodes of the graph*/
if (lValue == 2)
{
LST2_M_DynamicForEachElementOf(&hGraph->m_hListOfNode, hCurrentNode, lIndex) {
hCurrentNode->m_lTypeOfWP &= ~lTypeOfWP;
}
}
if (lValue == 3)
{
LST2_M_DynamicForEachElementOf(&hGraph->m_hListOfNode, hCurrentNode, lIndex) {
hCurrentNode->m_lTypeOfWP = 0;
}
}
if ( hListOfArc ) {
/*scan each arc of the node to see if its capability matches ours*/
WP_tdHandleOfArc hElement;
LST2_M_DynamicForEachElementOf(&hListOfArc->m_hArc, hElement, lIndex) { /* if already exists !*/
if ( (eFuncId != eFunc_NetworkAffectTypeOfConnectedWPWithCapa)
|| (hElement->m_ulCapability & ulCapaToTest) ) {
lNbOfConnectedWP++;
/*hElement->m_hNode->m_lTypeOfWP |= lTypeOfWP;*/
switch (lValue)
{
case 0:
case 2:
hElement->m_hNode->m_lTypeOfWP |= lTypeOfWP; /* add the type*/
break;
case 1:
case 3:
hElement->m_hNode->m_lTypeOfWP = lTypeOfWP; /* change all the types field*/
break;
case 4:
hElement->m_hNode->m_lTypeOfWP &= ~lTypeOfWP;; /* sub the type*/
break;
case 5:
hElement->m_hNode->m_lTypeOfWP = 0; /* erase all the types field*/
break;
}
}
}
}
M_Full_GetSetParam_Integer(p_stValue, lNbOfConnectedWP ); /* 0 if no connected WP*/
}
break;
#endif /* _AI_EXCLUDE_NEVER_USED_ }*/
default:
/* La fonction n'existe pas !!*/
M_AIFatalError(E_uwAIFatalNotValidFunction);
break;
}
/* On informe le moteur sur l'avancement dans l'interpr<70>tation*/
return(p_stTree);
}
tdstNodeInterpret *fn_p_stMiscFuncOnTypeOfWP(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
long lTypeOfWP, lIndex;
WP_tdHandleOfGraph hGraph;
WP_tdhWayPoint hWayPoint;
WP_tdhGraphNode hCurrentNode, hTheNode; /* the node currently examine*/
/* Evaluation of parameters*/
M_EvalNextParameter(p_stValue);
#if defined(__DEBUG_AI__)
M_VerifyTypeOfParamAction(p_stValue, E_vt_Graph);
#endif /* __DEBUG_AI__*/
hGraph = M_GetSetParam_GraphValue(p_stValue) ;
/*get the waypoint to search*/
M_EvalNextParameter( p_stValue );
hWayPoint = M_GetSetParam_WayPointValue(p_stValue) ;
/* now scan the list of connections from the current waypoint*/
lIndex = -1; /* juste pour faire plaisir <20> YLG !*/
hTheNode = (WP_tdhGraphNode)NULL;
/* looking for the starting WP :*/
LST2_M_DynamicForEachElementOf(&hGraph->m_hListOfNode, hCurrentNode, lIndex) {
if ( hCurrentNode->m_hWayPoint == hWayPoint ) {
hTheNode = hCurrentNode;
break ;
}
}
lTypeOfWP = 0L;
/* we found the waypoint in the graph -> get its type*/
if ( hTheNode )
lTypeOfWP = hTheNode->m_lTypeOfWP;
M_Full_GetSetParam_Caps(p_stValue, lTypeOfWP);
/* On informe le moteur sur l'avancement dans l'interpr<70>tation*/
return(p_stTree);
}
/*ENDANNECY JMD & BART }*/
/**********************************************************************
* Function: RESEAU_ExtremiteDeRail *
* Use : CONSTANT = RESEAU_ExtremiteDeRail(Dist) *
* Return : *
* -1 -> No Rail *
* 0 -> Is not on the first or the last wp *
* 1 -> is on the first Wp *
* 2 -> Is on the last Wp *
* Author : Yann Le Guyader *
* Date of last modification: 26/11/97 *
**********************************************************************/
#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/
tdstNodeInterpret *fn_p_stGetSituationOnRail(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1);
HIE_tdxHandleToSuperObject hNewPerso;
tdstGetSetParam stParam;
MTH_tdxReal xDist;
MS_tdxHandleToMSWay h_MSWay;
long lCurrentIndex;
long lNbWp;
WP_tdhWayPoint hWayPoint;
long lValue=0;
MTH3D_tdstVector stWpPosition;
MTH3D_tdstVector stPersoPosition;
/********************************************************************************/
/* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */
/********************************************************************************/
fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hNewPerso);
/********************************************************************************/
M_EvalNextParameter(&stParam);
xDist = M_GetSetParam_xValue(&stParam);
h_MSWay = M_GetMSHandle(hNewPerso, MSWay);
if ( h_MSWay == NULL)
{
M_Full_GetSetParam_Integer(p_stValue, -1 );
return (p_stTree);
}
/* Number of Wp */
lNbWp = MSWay_fn_lGetNumberWayPointInPath(h_MSWay);
/* Get the current Wp */
lCurrentIndex = MSWay_fn_lGetCurrentIndexInPath(h_MSWay);
if (lCurrentIndex == 1)
{
lValue = 1;
/*Test if perso is on the first Wp*/
hWayPoint = MSWay_fn_hGetWayPointOfPath (h_MSWay,0);
}
else
{
if (lCurrentIndex == (lNbWp -1))
{
lValue = 2;
/*Test if perso is on the first Wp*/
hWayPoint = MSWay_fn_hGetWayPointOfPath (h_MSWay,lCurrentIndex);
}
else
{
M_Full_GetSetParam_Integer(p_stValue, 0 );
return (p_stTree);
}
}
if (MTH_M_bEqualZero(xDist))
xDist = WP_fnx_WayPoint_GetRadius(hWayPoint);
/*
* Get perso position
*/
POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectMatrix(hNewPerso), &stPersoPosition);
/* Position of the Wp */
WP_fnv_WayPoint_GetVertex(hWayPoint, &stWpPosition);
if (
(!MTH3D_M_bEqualVector(&stWpPosition, &stPersoPosition))
&&
MTH_M_bLess(MTH3D_M_xVectorGap(&stWpPosition, &stPersoPosition), xDist)
)
{
M_Full_GetSetParam_Integer(p_stValue, lValue);
}
else
{
M_Full_GetSetParam_Integer(p_stValue, 0 );
}
return(p_stTree);
}
#endif /* _AI_EXCLUDE_NEVER_USED_ }*/
/* Capability functions*/
#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/
tdstNodeInterpret *fn_p_stPersoCapabilityFunction(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1);
unsigned long ubf32Capabilities = 0;
struct tdstEngineObject_ * hEngineObj; /* there's no "tdhEngineObject" ? ? ? ? ? ? ! ! !*/
/********************************************************************************/
/* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */
/********************************************************************************/
HIE_tdxHandleToSuperObject hNewSuperObjPerso;
fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hNewSuperObjPerso);
/********************************************************************************/
hEngineObj = M_GetEngineObject(hNewSuperObjPerso);
#if defined(__DEBUG_AI__) || (defined(U64) && defined(D_CHECK_AI_FPCO))
if (eFuncId != eFunc_GetCapabilities) {
M_AIFatalError(E_uwAIFatalNotValidFunction);
return(p_stTree);
}
#endif
ubf32Capabilities = fn_ulGetCapabilities(hEngineObj);
M_Full_GetSetParam_Caps(p_stValue, ubf32Capabilities);
return(p_stTree);
}
#endif /* _AI_EXCLUDE_NEVER_USED_ }*/
#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT 08/06/99 { */
tdstNodeInterpret *fn_p_stCapabilityFunction(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
unsigned char ucBitNumber;
unsigned long ubf32Capabilities;
ubf32Capabilities = 0;
M_EvalNextParameter( p_stValue );
ucBitNumber = (unsigned char) M_GetSetParam_lValue(p_stValue);
if (ucBitNumber >= 32)
{
ubf32Capabilities = 0;
}
ubf32Capabilities = 1<<ucBitNumber;
M_Full_GetSetParam_Caps(p_stValue, ubf32Capabilities);
return(p_stTree);
}
#endif /* _AI_EXCLUDE_NEVER_USED_ } */
/*ANNECY CT 02/02/98{*/
/**********************************************************************
* Function: MAT_ScrollingVitesse *
* Use : Vecteur = MAT_ScrollingVitesse(GMT,SurfaceType) *
* Surface Type Value : *
* 0 -> Ground *
* 1 -> Wall *
* 2 -> Ceiling *
* *
* Author : Carlos Torres *
* Date of last modification: 24/11/97 *
**********************************************************************/
tdstNodeInterpret *fn_p_stGetScrollSpeed(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1);
tdstGetSetParam stParam ; /* Structure d'<27>change*/
if (eFuncId==eFunc_GetScrollSpeed)
{
MTH3D_tdstVector stVector; /* Reaction Vector*/
unsigned long ulObstacleType; /* first param : collided obstacle type*/
/* get the type of obstacle (ground, wall or ceiling)*/
M_EvalNextParameter(&stParam);
ulObstacleType = M_GetSetParam_ulValue(&stParam);
/*switch(M_GetSetParam_ucValue(&stParam)) {
case 0 : ulObstacleType=C_WOT_ulGround;
break;
case 1 : ulObstacleType=C_WOT_ulWall;
break;
case 2 : ulObstacleType=C_WOT_ulCeiling;
break;
default : ulObstacleType=C_WOT_ulGround;
}*/
fn_vGetScrollSpeedMatCollided(p_SuperObjPerso,&stVector,ulObstacleType);
/* return the Reaction vector*/
M_Full_GetSetParam_p_stVertex(p_stValue,&stVector);
return (p_stTree);
}
M_AIFatalError(E_uwAIFatalNotValidFunction);
return(p_stTree);
}
/*ENDANNECY CT}*/
/*ANNECY CT 17/02/98{*/
/**********************************************************************
* Function: ANI_LitNbFrame *
* Use : Integer = Perso.ANI_LitNbFrame() *
* *
* Author : Carlos Torres *
* Date of last modification: 17/02/98 *
**********************************************************************/
tdstNodeInterpret *fn_p_stGetNbFrame(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1);
/********************************************************************************/
/* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */
/********************************************************************************/
HIE_tdxHandleToSuperObject hNewSuperObjPerso;
fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hNewSuperObjPerso);
/********************************************************************************/
switch(eFuncId)
{
case eFunc_GetNbFrame:
{
M_Full_GetSetParam_Integer(p_stValue,PLA_fn_uwGetNbFrameInCurrAnim(hNewSuperObjPerso));
return (p_stTree);
}
return p_stTree;
break;
/*case eFunc_GetCurrentFrame:
{
M_Full_GetSetParam_Integer(p_stValue,PLA_fn_uwGetCurrFrameOfAnim(hNewSuperObjPerso));
return (p_stTree);
}
return (p_stTree);
break;*/
default:
break;
}
M_AIFatalError(E_uwAIFatalNotValidFunction);
return(p_stTree);
}
/*ENDANNECY CT}*/
/*ANNECY CT 18/02/98{*/
/**********************************************************************
* Function: VEC_ProduitVectoriel *
* VEC_Normer *
* Use : Vector = VEC_ProduitVectoriel(Vector,Vector) *
* Vector = VEC_Normer(Vector) *
* *
* Author : Carlos Torres *
* Date of last modification: 18/02/98 *
**********************************************************************/
tdstNodeInterpret *fn_p_stVectorOperations(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1);
MTH3D_tdstVector *p_stV = &M_GetSetParam_stVertexValue(p_stValue); /* Param Vector*/
/* get the first vector*/
M_EvalNextParameter(p_stValue);
/*stV1=M_GetSetParam_stVectorValue(&stParam);*/
switch ( eFuncId )
{
/* CROSS PRODUCT*/
case eFunc_CrossProduct:
{
MTH3D_tdstVector stV1 = *p_stV, stV2;
/* get the second vector*/
M_EvalNextParameter(p_stValue);
stV2 = M_GetSetParam_stVectorValue(p_stValue);
MTH3D_M_vCrossProductVectorWithoutBuffer(p_stV,&stV1,&stV2);
/* return cross product*/
/*M_Full_GetSetParam_p_stVertex(p_stValue,&stV1xV2);*/
}
return p_stTree;
break;
/* NORMALIZE*/
case eFunc_Normalize:
if ( !( MTH_M_bEqualWithEpsilon ( MTH3D_M_xGetXofVector(p_stV), MTH_C_ZERO, MTH_M_xDoubleToReal(1e-9) )
&& MTH_M_bEqualWithEpsilon ( MTH3D_M_xGetYofVector(p_stV), MTH_C_ZERO, MTH_M_xDoubleToReal(1e-9) )
&& MTH_M_bEqualWithEpsilon ( MTH3D_M_xGetZofVector(p_stV), MTH_C_ZERO, MTH_M_xDoubleToReal(1e-9) )
)
) /*AR9902 Avoid too small values for N64*/
{
/*SAF_M_AssertWithMsg((! MTH3D_M_bIsNullVector(&stV1)),"Normalisation d'un vecteur nul")*/
MTH3D_M_vNormalizeVector(p_stV, p_stV);
/* return cross product*/
/*M_Full_GetSetParam_p_stVertex(p_stValue,&stVNorm);*/
}
return (p_stTree);
break;
default:
break;
}
M_AIFatalError(E_uwAIFatalNotValidFunction);
return p_stTree;
}
/*ENDANNECY CT}*/
/*ANNECY CT 26/02/98{*/
/**********************************************************************
* Function: SPO_LitCoordonnees *
* Use : Vector = SPO_LitCoordonnees(SPO) *
* *
* Author : Carlos Torres *
* Date of last modification: 26/02/98 *
**********************************************************************/
#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/
tdstNodeInterpret *fn_p_stGetSPOCoordinates(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1);
tdstGetSetParam stParam ; /* Structure d'<27>change*/
HIE_tdxHandleToSuperObject hSpo;
/* get the first vector*/
M_EvalNextParameter(&stParam);
hSpo=M_GetSetParam_SuperObjectValue(&stParam);
if (eFuncId == eFunc_GetSPOCoordinates) {
MTH3D_tdstVector stCoordinates;
if (HIE_fn_bIsSuperObjectValid(hSpo))
POS_fn_vGetTranslationVector(HIE_fn_hGetSuperObjectMatrix(hSpo),&stCoordinates);
else
MTH3D_M_vNullVector(&stCoordinates);
/* return Position*/
M_Full_GetSetParam_p_stVertex(p_stValue,&stCoordinates);
return (p_stTree);
}
M_AIFatalError(E_uwAIFatalNotValidFunction);
return(p_stTree);
}
#endif /* _AI_EXCLUDE_NEVER_USED_ }*/
/*ENDANNECY CT}*/
/*ANNECY CT 02/03/98{*/
/**********************************************************************
* Function: ACT_LitNbPersoActifs *
* Use : Entier = ACT_LitNbPersoActifs() *
* *
* Author : Carlos Torres *
* Date of last modification: 02/03/98 *
**********************************************************************/
#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/
tdstNodeInterpret *fn_p_stGetNbActivePerso(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1);
if (eFuncId == eFunc_GetNbActivePerso) {
/* return Nb Active Perso*/
M_Full_GetSetParam_Integer(p_stValue,GAM_fn_lGetNbPersoActive());
return (p_stTree);
}
M_AIFatalError(E_uwAIFatalNotValidFunction);
return(p_stTree);
}
#endif /* _AI_EXCLUDE_NEVER_USED_ }*/
/*ENDANNECY CT}*/
/*
----------------------------------------------------------------------------------------
Description : *fn_p_stTractionFactorFunction
----------------------------------------------------------------------------------------
Author : Fred 'Bart#02' Compagnon
Date : 11/03/98
----------------------------------------------------------------------------------------
*/
tdstNodeInterpret *fn_p_stTractionFactorFunction(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1);
unsigned char ucTractionFactor = 0;
struct tdstEngineObject_ * hEngineObj; /* there's no "tdhEngineObject" ? ? ? ? ? ? ! ! !*/
/********************************************************************************/
/* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */
/********************************************************************************/
HIE_tdxHandleToSuperObject hNewSuperObjPerso;
fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hNewSuperObjPerso);
/********************************************************************************/
hEngineObj = M_GetEngineObject(hNewSuperObjPerso);
switch(eFuncId)
{
case eFunc_GetTractionFactor :
ucTractionFactor = fn_ucStandardGameGetTractionFactor(hEngineObj->h_StandardGame);
break;
default:
#if defined(__DEBUG_AI__) || (defined(U64) && defined(D_CHECK_AI_FPCO))
M_AIFatalError(E_uwAIFatalNotValidFunction);
#endif
break;
}
/*M_Full_GetSetParam_Integer(p_stValue, ucTractionFactor);*/
M_GetSetParam_ucValue(p_stValue) = ucTractionFactor;
M_GetSetParam_Type(p_stValue) = E_vt_0To255;
return(p_stTree);
}
/**********************************************************************
* Function: ZON_LitCentreZDEType *
* Use : Vecteur = ZON_LitCentreZDEType(Perso,CMT) *
* Function: ZON_LitCentreZDMType *
* Use : Vecteur = ZON_LitCentreZDMType(Perso,CMT) *
* Function: ZON_LitCentreZDRType *
* Use : Vecteur = ZON_LitCentreZDRType(Perso,CMT) *
* Function: ZON_LitCentreZDDType *
* Use : Vecteur = ZON_LitCentreZDDType(Perso,CMT) *
* *
* Author : Carlos Torres 28/04/98 *
* Modif : 18/05/98 check if zone is active Carlos Torres
**********************************************************************/
/* Modif 21/08/98 : take care of hierarchy for Module ZDE - Carlos Torres*/
tdstNodeInterpret *fn_p_stGetZDxCenter(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1);
HIE_tdxHandleToSuperObject hCharacter;
GMT_tdxMask xMask;
MTH3D_tdstVector *p_stCenter = &M_GetSetParam_stVertexValue(p_stValue);
unsigned char ucZoneType;
/* XB 05/05/99 */
/* ACP_tdxBool bFoundOne = 0; */
/* End XB */
/* 1 - get the perso*/
M_EvalNextParameter(p_stValue);
hCharacter=M_GetSetParam_p_stSupObjValue(p_stValue);
SAF_M_AssertWithMsg(hCharacter, "le perso sp<73>cifi<66> est invalide!");
/* 2 - get the CMT*/
M_EvalNextParameter(p_stValue);
xMask=(GMT_tdxMask) M_GetSetParam_xMaskValue(p_stValue);
/* Set default return value*/
MTH3D_M_vNullVector(p_stCenter);
/* get type of zone*/
switch(eFuncId)
{
case eFunc_GetCenterZDEType :
ucZoneType = C_ucTypeZde;
break;
#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/
case eFunc_GetCenterZDMType :
ucZoneType = C_ucTypeZdm;
break;
case eFunc_GetCenterZDRType :
ucZoneType = C_ucTypeZdr;
break;
case eFunc_GetCenterZDDType :
ucZoneType = C_ucTypeZdd;
break;
#endif /* _AI_EXCLUDE_NEVER_USED_ }*/
default :
ucZoneType = 0xff; /*prevent a compilation warning*/
#if defined(__DEBUG_AI__) || (defined(U64) && defined(D_CHECK_AI_FPCO))
M_AIFatalError(E_uwAIFatalNotValidFunction);
#endif
break;
}
/* return center in perso coordinates*/
M_GetSetParam_Type(p_stValue) = E_vt_Vector;
fn_vInternGetZDxCenter(hCharacter, xMask, ucZoneType, FALSE, p_stCenter);
/*M_Full_GetSetParam_p_stVertex(p_stValue,&stCenter);*/
return(p_stTree);
}
/**********************************************************************
* Function: fn_hGetNearestActorInSectorWithAnyCustombit *
* Author : Yann Le Tensorer *
* Date of last modification: 21/08/98 *
**********************************************************************/
#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/
/**********************************************************************
* Function: fn_hGetNearestActorInSectorWithAnyCustombit *
* Author : Yann Le Tensorer *
* Date of last modification: 21/08/98 *
**********************************************************************/
HIE_tdxHandleToSuperObject fn_hGetNearestActorInSectorWithAnyCustombit(
HIE_tdxHandleToSuperObject _hMe, /*identify myself so that I cant be the closet actor to myself...*/
HIE_tdxHandleToSuperObject _hSector, /*sector to search*/
unsigned long _ulFilterCustomBits /*custombits to accept*/
)
{
SECT_tdxHandleOfElementLstCharacter hCharacterElement; /* current list of character*/
HIE_tdxHandleToSuperObject hCharacterSO=NULL; /* current actor tested*/
HIE_tdxHandleToSuperObject hCloserSO=NULL; /* current actor tested*/
MTH_tdxReal xBestDist= MTH_C_InfinitPlus;
int i;
MTH_tdxReal xTmp;
MTH3D_tdstVector stMyPosition,stActorsPosition;
/* Get The Position of my character*/
POS_fn_vGetTranslationVector( HIE_fn_hGetSuperObjectGlobalMatrix( _hMe), &stMyPosition );
/* Find all characters in the current sector of the list*/
SECT_M_ForEachCharListInSector(_hSector, hCharacterElement, i)
{
hCharacterSO = SECT_GetCharacterInList( hCharacterElement );
if ( hCharacterSO != _hMe )
{
/* Do this only if any of the CustomBits is set*/
if ( (fn_ulStandardGameGetCustomBits(M_GetMSHandle(hCharacterSO,StandardGame)) & _ulFilterCustomBits) != 0 )
{
/* Coordinates of the character*/
POS_fn_vGetTranslationVector( HIE_fn_hGetSuperObjectGlobalMatrix( hCharacterSO ), &stActorsPosition );
/* Square of Distance between My character and other one*/
xTmp = MTH3D_M_xVectorGapSqr(&stActorsPosition, &stMyPosition);
if ( MTH_M_bLess(xTmp, xBestDist) )
{
xBestDist = xTmp;
hCloserSO = hCharacterSO;
}
}
}
}
return hCloserSO;
}
tdstNodeInterpret *fn_p_stGetNearestActorInCurrentSector(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
tdstGetSetParam stParam;
HIE_tdxHandleToSuperObject hCurrentSectorPerso,hCloserSO = NULL;
unsigned long ulCustomBitValue;
enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1);
/********************************************************************************/
/* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */
/********************************************************************************/
HIE_tdxHandleToSuperObject hNewSuperObjPerso;
fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId), p_SuperObjPerso, &hNewSuperObjPerso);
/********************************************************************************/
/* Evaluation of next parameter*/
M_EvalNextParameter( &stParam );
/* Get number the custom bit value*/
ulCustomBitValue = M_ReturnParam_lValue(&stParam);
/* Point to the current sector where the character is*/
hCurrentSectorPerso = fn_h_SectInfoGetCurrentSector( M_GetMSHandle( hNewSuperObjPerso, SectInfo ) );
hCloserSO = fn_hGetNearestActorInSectorWithAnyCustombit(
hNewSuperObjPerso, /*identify myself so that I cant be the closet actor to myself...*/
hCurrentSectorPerso, /*sector to search*/
ulCustomBitValue /*custombits to accept*/
);
/* give the engine the closest actor*/
M_Full_GetSetParam_Perso(p_stValue, hCloserSO);
return(p_stTree);
}
#endif /* _AI_EXCLUDE_NEVER_USED_ }*/
/**********************************************************************
* Function: fn_hGetNearestActorInSectorWithAnyCustombit *
* Author : Yann Le Tensorer *
* Date of last modification: 26/08/98 *
**********************************************************************/
/* merci de ne pas mettre cette fonction avec d'autres dans un case, <20>a ralentit le code...*/
tdstNodeInterpret *fn_p_stDotProduct(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
/* XB 05/05/99 */
/* enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1); */
/* End XB */
MTH3D_tdstVector stV1, *p_stV2; /* first and second vectors*/
MTH_tdxReal xReturnValue; /* dot product*/
p_stV2 = &M_GetSetParam_stVectorValue(p_stValue);
/* get the first vector*/
M_EvalNextParameter(p_stValue);
stV1 = *p_stV2;
/* get the second vector*/
M_EvalNextParameter(p_stValue);
xReturnValue = MTH3D_M_xDotProductVector (&stV1,p_stV2);
/* return dot product*/
M_Full_GetSetParam_Float(p_stValue, xReturnValue );
return p_stTree;
}
/**********************************************************************
* Function: fn_p_stGetCPUCounter *
* Author : Marc Trabucato *
* Date of last modification: 24/10/98 *
**********************************************************************/
#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/
tdstNodeInterpret *fn_p_stGetCPUCounter(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
/* XB 05/05/99 */
/* enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1); */
/* End XB */
unsigned long ulValue;
ulValue = TMR_fn_ulFastGetInternalCounter();
/* return cross product*/
M_Full_GetSetParam_Integer(p_stValue, ulValue);
return(p_stTree);
}
#endif /* _AI_EXCLUDE_NEVER_USED_ }*/
tdstNodeInterpret *fn_GetCheatFlags(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
// Dummy for editor
M_Full_GetSetParam_Integer(p_stValue, 0);
return (p_stTree);
}
tdstNodeInterpret *fn_GetBacklight(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
// Dummy for editor
M_Full_GetSetParam_Integer(p_stValue, 0);
return (p_stTree);
}
extern unsigned char g_ucCalibrationDone;
tdstNodeInterpret *fn_DoneAnalogCalibration(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue)
{
// Dummy for editor
M_Full_GetSetParam_Integer(p_stValue, 0);
return (p_stTree);
}