/************************************************************************************************ * 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î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é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'é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'é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 ê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 ê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 ê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 être compris entre 0° exclus et 180° 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 être compris entre 0° exclus et 90° 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é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é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é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é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é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é") 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é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é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é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é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é") 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é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é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é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é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é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é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é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é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é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é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é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é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é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é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 à 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é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 à 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é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 à 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é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< 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'é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'é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écifié 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, ç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); }