/************************************************************************************************ * Name: Functio1.c * * Use : Function for AI of Rayman II and Egypte * * Authors: Yann Le Tensorer, Christophe Giraud, Jacques Thenoz, Benoit Germain, * * (c) UBI Simulations Annecy * ************************************************************************************************/ /*XB*/ #include "GAM\GamOpt.h" /*End XB*/ #if (defined(ACTIVE_EXEC_CHECKING) && defined(ACTIVE_EDITOR)) || defined(ACTIVE_AIDEBUG) extern AI_tdstMind *p_stCurrentMind; /*declared in Intell.c*/ #endif /*#define AI_RAY2EGYPTE_COLLIDE_RANGE (MTH_tdxReal)10 // Range of collide function (meter)*/ /* CT - 8/12/1997*/ #define C_ucPlanxOy 0 #define C_ucPlanyOz 1 #define C_ucPlanzOx 2 /*VLTEMPORARY*/ /* Oliv' - Portage v14*/ #ifndef U64 #include "x:\cpa\tempgrp\gliglou\multidrv\inc\dispmode.h" #endif /* U64 */ /* EndOfOliv'*/ /*EVL*/ /* For resolution switching...*/ #ifdef U64 #include "u_boot.h" #include "u_cfb.h" #include "U_zbuf.h" #include "GLD/Specif/u_vpt.h" extern short g_wWhichFrameBuffer; #endif /*U64*/ /****************************** Private Data ***************************************************/ MTH3D_tdstVector g_stCollideParameterPoint; MTH3D_tdstVector g_stCollideParameterVector; MTH3D_tdstVector g_stCollideResultPoint; MTH3D_tdstVector g_stCollideResultVector; HIE_tdxHandleToSuperObject g_hSuperObjectHit; unsigned long g_ulMode=0xFFFFFFFF; unsigned long g_ulCollideTimeCounter=0; /* it is possible to override the no raytrace flag once if desired thanks to this variable:*/ unsigned long g_ulOverRideRayTraceSpoMask = HIE_C_Flag_ulNotHitByRayTrace; #ifdef __cplusplus extern "C" { #endif extern unsigned long g_ulSpoMask; #if !defined(U64) && defined(_DEBUG) /* for drawing the raytrace segments in engine mode*/ extern unsigned char g_ucDisplayRayTraceSegments; extern MTH3D_tdstVector g_stRayTraceSegmentOrigin[30]; extern MTH3D_tdstVector g_stRayTraceSegmentEnd[30]; extern short g_wRayTraceSegmentLife[30]; #endif /* !U64 && _DEBUG */ #ifdef __cplusplus } #endif #ifndef U64 /*********** FabPerez ****************/ #include #include #include #ifdef __cplusplus extern "C" { #endif extern long fn_lGetNbAvailableSlotsPc(); extern char * fn_bGetStringSlotDate(unsigned long _ulSlotId); extern long fn_bRecupSlotNum(long lSlotPosId); extern char * fn_cRecupSlotName(long lSlotPosId); extern char g_a_szSlotNames[4]; extern StructRecupPosSlot * g_p_LastStructRecupPosSlot; extern BOOL fn_bEraseGameInSlotList( long lSlotId); extern unsigned char g_ucNbSaveGameSlots; extern BOOL g_bIsGameAlreadyExist; extern int fn_iVersionN64_PC(void); #ifdef __cplusplus } #endif /*************Fin Fab Perez *************/ #endif // !U64 /****************************** Private Function ***********************************************/ void fn_vComputeCollideResult (HIE_tdxHandleToSuperObject hSender) { /* Oliv' - Portage v14*/ /* HIE_tdxHandleToSuperObject hHiearchyRoot = NULL;*/ /* EndOfOliv'*/ HIE_tdxHandleToSuperObject hSuperObjectHit,hSaveSO; HIE_tdxHandleToSuperObject hCurrentPerso; SECT_tdxHandleOfElementLstCharacter hCharacterList; MTH3D_tdstVector stCollidepoint; MTH3D_tdstVector stCollideVector; HIE_tdxHandleToSuperObject hSector1,hSector/*,hSector2*/; SECT_tdxHandleOfElementLstGraphicInteraction hList; SECT_tdxHandleOfElementLstActivityInteraction hInterList; long i,j; BOOL bDynamCollide = FALSE; MTH3D_M_vNullVector (&stCollideVector); MTH3D_M_vNullVector (&g_stCollideResultPoint); MTH3D_M_vNullVector (&g_stCollideResultVector); g_hSuperObjectHit = NULL; hSaveSO = NULL; hSuperObjectHit = NULL; #if !defined(U64) && defined(_DEBUG) if ( g_ucDisplayRayTraceSegments ) { int i; for ( i = 0; i < 30; i ++ ) if ( g_wRayTraceSegmentLife[i] <= 0 ) { g_stRayTraceSegmentOrigin[i] = g_stCollideParameterPoint; MTH3D_M_vAddVector(&g_stRayTraceSegmentEnd[i], &g_stCollideParameterPoint, &g_stCollideParameterVector); g_wRayTraceSegmentLife[i] = 100; break; } } #endif /* !U64 && _DEBUG */ /* find the starting sector*/ hSector1 = SECT_fn_hResearchInWhatSectorIAm(SECT_hFatherSector,&g_stCollideParameterPoint); MTH3D_M_vNullVector (&stCollidepoint); /* g_stCollideParameterPoint contains the starting point*/ /* g_stCollideParameterVector contains the vector for detection*/ if (g_ulMode != 1) { /* if there is a static detection*/ /* test on a sector, so set global mask to check SPO shadow flag :*/ g_ulSpoMask = g_ulOverRideRayTraceSpoMask; if (hSector1==NULL) { /* the starting point is not in a sector... collision on the hole static world ! */ HIE_bIntersectSegmentWithFirstSuperObject(&g_stCollideParameterPoint,&g_stCollideParameterVector,SECT_hFatherSector, &g_stCollideResultPoint, &g_stCollideResultVector, &g_hSuperObjectHit); } else { /* detection on 1st sector...*/ HIE_bIntersectSegmentWithFirstSuperObject(&g_stCollideParameterPoint,&g_stCollideParameterVector, hSector1, &g_stCollideResultPoint, &g_stCollideResultVector, &g_hSuperObjectHit); /* FBF correction pb detection*/ /* if(HIE_bIntersectSegmentWithFirstSuperObject(&g_stCollideParameterPoint,&g_stCollideParameterVector, hSector1, &g_stCollideResultPoint, &g_stCollideResultVector, &g_hSuperObjectHit)) { // collision detected in first sector if (g_ulMode == 0) { // no dynamic detection asked --> return return; } else { // static collision in sector 1 & dynamic collision asked --> seek dynamic collision only in sector 1 ! // look in the list of the sector // test on an actor, so set global mask not to check SPO shadow flag : g_ulSpoMask = 0; SECT_M_ForEachCharListInSector(hSector1,hCharacterList,i) { hCurrentPerso = SECT_GetCharacterInList(hCharacterList); if (hCurrentPerso != hSender) { if ( (fn_ulStandardGameGetCustomBitsSO(hCurrentPerso) & GAM_C_CustBitRayHit) && // hit by ray tracing (fn_bf1StandardGameGetIsActive(M_GetMSHandle(hCurrentPerso,StandardGame))) ) // active { if (HIE_bIntersectSegmentWithFirstSuperObject (&g_stCollideParameterPoint, &g_stCollideParameterVector,hCurrentPerso,&g_stCollideResultPoint, &g_stCollideResultVector, &hSuperObjectHit)) { // dynamic collision detected --> return the actor ! while (HIE_fn_bIsSuperObjectValid (hSuperObjectHit) && HIE_fn_ulGetSuperObjectType(hSuperObjectHit)!=HIE_C_ulActor) { // while superobjecthit is not an actor, seek hSuperObjectHit = HIE_fn_hGetSuperObjectFather(hSuperObjectHit); } // if we arrived to an actor --> return it ! if (HIE_fn_bIsSuperObjectValid (hSuperObjectHit)) g_hSuperObjectHit = hSuperObjectHit; } } } } // and return result ! return; } }*/ /* detection on all others sectors*/ SECT_M_ForEachGraphicNodeInGraphicInteractionList(hSector1, hList, i) { /* if the sector is a mode look only, stop searching !*/ if (SCT_fn_wGetModeInGraphicList(hList) == C_SECT_ModeLookOnly) break; hSector = SECT_GetSectorInGraphicList(hList); /* if the sector is virtual, forget about it !*/ if (!SECT_fn_bIsThisSectorVirtual(hSector)) { HIE_bIntersectSegmentWithFirstSuperObject(&g_stCollideParameterPoint,&g_stCollideParameterVector, hSector, &g_stCollideResultPoint, &g_stCollideResultVector, &g_hSuperObjectHit); } } } /* if no dynamic detection asked --> return*/ if (g_ulMode == 0) { return; } } /* now, dynamic world...*/ /* test on an actor, so set global mask not to check SPO shadow flag :*/ g_ulSpoMask = 0; /* look in current sector first !*/ SECT_M_ForEachCharListInSector(hSector1,hCharacterList,i) { hCurrentPerso = SECT_GetCharacterInList(hCharacterList); /* if perso to detect is the perso that asked detection, don't detect*/ if (hCurrentPerso != hSender) { if ( (fn_ulStandardGameGetCustomBitsSO(hCurrentPerso) & GAM_C_CustBitRayHit) && /* hit by ray tracing*/ (fn_bf1StandardGameGetIsActive(M_GetMSHandle(hCurrentPerso,StandardGame))) ) /* active*/ { if (HIE_bIntersectSegmentWithFirstSuperObject (&g_stCollideParameterPoint, &g_stCollideParameterVector,hCurrentPerso,&g_stCollideResultPoint, &g_stCollideResultVector, &hSuperObjectHit)) { bDynamCollide = TRUE; /* dynamic collision detected --> return the actor !*/ while (HIE_fn_bIsSuperObjectValid (hSuperObjectHit) && HIE_fn_ulGetSuperObjectType(hSuperObjectHit)!=HIE_C_ulActor) { /* while superobjecthit is not an actor, seek */ hSuperObjectHit = HIE_fn_hGetSuperObjectFather(hSuperObjectHit); } /* if we arrived to an actor --> return it !*/ if (HIE_fn_bIsSuperObjectValid (hSuperObjectHit)) g_hSuperObjectHit = hSuperObjectHit; } } } } /* if dynam collision in first sector --> stop*/ /* FBF correction pb detection*/ /* if (bDynamCollide) return; */ /* look in every active sector...*/ SECT_M_ForEachActivityNodeInActivityInteractionList(hSector1,hInterList,i) { MTH3D_tdstVector stMin, stMax; SECT_tdxHandleOfSectorObject hSectorObject; hSector = SECT_GetSectorInActivityList(hInterList); hSectorObject = (SECT_tdxHandleOfSectorObject) HIE_fn_hGetSuperObjectObject(hSector); /* if the sector border is not in intersection with the segment, don't scan its characters*/ /* get the border box of the sector*/ SECT_fn_vGetMinPointInBorder(hSectorObject, &stMin); SECT_fn_vGetMaxPointInBorder(hSectorObject, &stMax); if (INT_fn_bDetectIntersectSegmentWithBox ( &g_stCollideParameterPoint,&g_stCollideParameterVector,&stMin,&stMax,NULL)) { /* ok, intersection between sector border and segment, so scan characters*/ SECT_M_ForEachCharListInSector(hSector,hCharacterList,j) { hCurrentPerso = SECT_GetCharacterInList(hCharacterList); if (hCurrentPerso != hSender) { if ( (fn_ulStandardGameGetCustomBitsSO(hCurrentPerso) & GAM_C_CustBitRayHit) && /* hit by ray tracing*/ (fn_bf1StandardGameGetIsActive(M_GetMSHandle(hCurrentPerso,StandardGame))) ) /* active*/ { if (HIE_bIntersectSegmentWithFirstSuperObject (&g_stCollideParameterPoint, &g_stCollideParameterVector,hCurrentPerso,&g_stCollideResultPoint, &g_stCollideResultVector, &hSuperObjectHit)) { /* dynamic collision detected --> return the actor !*/ while (HIE_fn_bIsSuperObjectValid (hSuperObjectHit) && HIE_fn_ulGetSuperObjectType(hSuperObjectHit)!=HIE_C_ulActor) { /* while superobjecthit is not an actor, seek */ hSuperObjectHit = HIE_fn_hGetSuperObjectFather(hSuperObjectHit); } /* if we arrived to an actor --> return it !*/ if (HIE_fn_bIsSuperObjectValid (hSuperObjectHit)) g_hSuperObjectHit = hSuperObjectHit; } } } } } } } /*ANNECY CG {*/ /*************************************************************************** * Function : PAD_VitessePadAnalogique * * Use : Entier Angle = FUN_VitessePadAnalogique( Entier X, Entier Y ) * * Author : Christophe Giraud * * Date of last modification: 20/02/98 * ***************************************************************************/ #if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/ tdstNodeInterpret *fn_p_stCode4VitessePadAnalogique(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1); switch(eFuncId) { case eFunc_VitessePadAnalogique: { long lSpeedFromIA; MTH_tdxReal xXvalue, xYvalue, xSpeedX, xSpeedY; MTH3D_tdstVector stSpeedVector; /* Get X Value*/ M_EvalNextParameter(p_stValue); xYvalue = MTH_M_xNeg( M_ReturnParam_xValue(p_stValue) ); /* Get Y Value*/ M_EvalNextParameter(p_stValue); xXvalue = MTH_M_xNeg( M_ReturnParam_xValue(p_stValue) ); /* Get Speed for x or z value (ex: VitesseMarcheVarappe)*/ M_EvalNextParameter(p_stValue); lSpeedFromIA = M_ReturnParam_lValue(p_stValue); /* Compute Speed X*/ xSpeedX = MTH_M_xMul( lSpeedFromIA, MTH_M_xDiv( xXvalue, 100 ) ); /* Compute Speed Y*/ xSpeedY = MTH_M_xMul( lSpeedFromIA, MTH_M_xDiv( xYvalue, 100 ) ); /* Compute Speed Vector*/ MTH3D_M_vNullVector( &stSpeedVector ); MTH3D_M_vSetXofVector( &stSpeedVector, xSpeedX ); MTH3D_M_vSetZofVector( &stSpeedVector, xSpeedY ); MTH3D_M_vNormalizeVector( &stSpeedVector, &stSpeedVector ) MTH3D_M_vMulScalarVector( &stSpeedVector, lSpeedFromIA, &stSpeedVector ); /*MTH3D_M_xNormVector( &stSpeedVector );*/ M_Full_GetSetParam_p_stVertex( p_stValue, &stSpeedVector ); } return p_stTree; break; default: break; } #if defined(__DEBUG_AI__) || (defined(U64) && defined(D_CHECK_AI_FPCO)) M_AIFatalError(E_uwAIFatalNotValidFunction); #endif return(p_stTree); } #endif /* _AI_EXCLUDE_NEVER_USED_ }*/ /*********************************************************************** * Function : Vecteur = ZON_LitCentreZDM * * Use : Vecteur = ZON_LitCentreZDM( ZDM ) * * Function : Vecteur = ZON_LitCentreZDE * * Use : Vecteur = ZON_LitCentreZDE( ZDE ) * * Function : Vecteur = ZON_LitCentreZDD * * Use : Vecteur = ZON_LitCentreZDD( ZDD ) * * Author : Christophe Giraud * * Date of last modification: 21/01/98 * ***********************************************************************/ tdstNodeInterpret *fn_p_stCode4LitCentreZDx(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { tdstGetSetParam stParam; /* exchange structure*/ HIE_tdxHandleToSuperObject hPerso; /* Handle of the character*/ ACP_tdxHandleOfObject hGeoObj; /* Handle of the geometric object*/ long lZoneNumber; /* Number of the zone*/ MTH3D_tdstVector stVectorMin, stVectorMax; ACP_tdxIndex xMaxPoint, xMinPoint; enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1); /********************************************************************************/ /* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */ /********************************************************************************/ fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hPerso); /* Get second parameter that is a ZDM*/ M_EvalNextParameter( &stParam ); lZoneNumber = (long) M_GetSetParam_lZDMIdValue( &stParam ); switch( eFuncId ) { #if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/ case eFunc_LitCentreZDM: /* Get handle about geometric object of the ZDM*/ hGeoObj = fn_hGetGeometricZdxOfTypeAtIndex( C_ucTypeZdm, (unsigned short)(lZoneNumber-1), hPerso ); break; case eFunc_LitCentreZDE: /* Get handle about geometric object of the ZDE*/ hGeoObj = fn_hGetGeometricZdxOfTypeAtIndex( C_ucTypeZde, (unsigned short)(lZoneNumber-1), hPerso ); break; #endif /* _AI_EXCLUDE_NEVER_USED_ }*/ case eFunc_LitCentreZDD: /* Get handle about geometric object of the ZDD*/ hGeoObj = fn_hGetGeometricZdxOfTypeAtIndex( C_ucTypeZdd, (unsigned short)(lZoneNumber-1), hPerso ); break; default: /* Function does not existe*/ M_AIFatalError(E_uwAIFatalNotValidFunction); return(p_stTree); break; } if( hGeoObj ) { switch( *hGeoObj->d_xListOfElementsTypes ) { case GEO_C_xElementPoints: /* It's a point:*/ case GEO_C_xElementSpheres: /* It's a sphere:*/ { /* Return the center*/ M_Full_GetSetParam_p_stVertex( p_stValue, &hGeoObj->d_stListOfPoints[0] ); } break; case GEO_C_xElementAlignedBoxes: /* It's a box.*/ { /* Get MinPoint and MaxPoint of the box*/ GEO_vGetMinMaxPointOfIndexedAlignedBox( hGeoObj, 0, 0, &xMinPoint, &xMaxPoint ); /* Get MinVector and MaxVector of the box*/ GEO_vGetPointOfObject( hGeoObj, &stVectorMin, xMinPoint ); GEO_vGetPointOfObject( hGeoObj, &stVectorMax, xMaxPoint ); /* Compute center*/ MTH3D_M_vMiddleVector( &stVectorMin, &stVectorMin, &stVectorMax ); /* Return vector*/ M_Full_GetSetParam_p_stVertex( p_stValue, &stVectorMin ); } break; default: { /* Return a null vector*/ MTH3D_M_vNullVector( &stVectorMin ); M_Full_GetSetParam_p_stVertex( p_stValue, &stVectorMin ); } break; } } else { /* Return a null vector*/ MTH3D_M_vNullVector( &stVectorMin ); M_Full_GetSetParam_p_stVertex( p_stValue, &stVectorMin ); } return(p_stTree); } /************************************************************************** * Function : Vecteur = ZON_LitDimensionZDM * * Use : Vecteur = ZON_LitDimensionZDM( ZDM ) * * Function : Vecteur = ZON_LitDimensionZDE * * Use : Vecteur = ZON_LitDimensionZDE( ZDE ) * * Function : Vecteur = ZON_LitDimensionZDD * * Use : Vecteur = ZON_LitDimensionZDD( ZDD ) * * Author : Yann Le Guyader * * Date of last modification: 09/03/98 * ***************************************************************************/ tdstNodeInterpret *fn_p_stCode4LitDimensionZDx(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { tdstGetSetParam stParam; /* exchange structure*/ HIE_tdxHandleToSuperObject hPerso; /* Handle of the character*/ ACP_tdxHandleOfObject hGeoObj; /* Handle of the geometric object*/ long lZoneNumber; /* Number of the zone*/ MTH3D_tdstVector stVectorMin, stVectorMax; ACP_tdxIndex xMaxPoint, xMinPoint; enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1); /********************************************************************************/ /* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */ /********************************************************************************/ fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hPerso); /* Get First parameter that is a ZDM*/ M_EvalNextParameter( &stParam ); lZoneNumber = (long) M_GetSetParam_lZDMIdValue( &stParam ); switch( eFuncId ) { case eFunc_LitDimensionZDM: /* Get handle about geometric object of the ZDM*/ hGeoObj = fn_hGetGeometricZdxOfTypeAtIndex( C_ucTypeZdm, (unsigned short)(lZoneNumber-1), hPerso ); break; #if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/ case eFunc_LitDimensionZDE: /* Get handle about geometric object of the ZDE*/ hGeoObj = fn_hGetGeometricZdxOfTypeAtIndex( C_ucTypeZde, (unsigned short)(lZoneNumber-1), hPerso ); break; #endif /* _AI_EXCLUDE_NEVER_USED_ }*/ case eFunc_LitDimensionZDD: /* Get handle about geometric object of the ZDD*/ hGeoObj = fn_hGetGeometricZdxOfTypeAtIndex( C_ucTypeZdd, (unsigned short)(lZoneNumber-1), hPerso ); break; default: { /* Function does not existe*/ M_AIFatalError(E_uwAIFatalNotValidFunction); return(p_stTree); break; } } if( hGeoObj ) { switch( *hGeoObj->d_xListOfElementsTypes ) { case GEO_C_xElementSpheres: /* It's a sphere:*/ { MTH_tdxReal xRadius; xRadius = GEO_xGetRadiusOfIndexedSphere(hGeoObj, 0, 0); MTH3D_M_vSetVectorElements(&stVectorMin, xRadius, xRadius, xRadius); } break; case GEO_C_xElementAlignedBoxes: /* It's a box.*/ { /* Get MinPoint and MaxPoint of the box*/ GEO_vGetMinMaxPointOfIndexedAlignedBox( hGeoObj, 0, 0, &xMinPoint, &xMaxPoint ); /* Get MinVector and MaxVector of the box*/ GEO_vGetPointOfObject( hGeoObj, &stVectorMin, xMinPoint ); GEO_vGetPointOfObject( hGeoObj, &stVectorMax, xMaxPoint ); MTH3D_M_vSetVectorElements(&stVectorMin, MTH_M_xAbs(MTH_M_xSub(stVectorMin.xX,stVectorMax.xX)), MTH_M_xAbs(MTH_M_xSub(stVectorMin.xY,stVectorMax.xY)), MTH_M_xAbs(MTH_M_xSub(stVectorMin.xZ,stVectorMax.xZ))); } break; default: { /* Return a null vector*/ MTH3D_M_vNullVector( &stVectorMin ); } break; } } else { MTH3D_M_vNullVector( &stVectorMin ); } /* Return a null vector*/ M_Full_GetSetParam_p_stVertex( p_stValue, &stVectorMin ); return(p_stTree); } /*********************************************************************** * Function : Vecteur = ZON_LitAxeZDM * * Use : Vecteur = ZON_LitAxeZDM( Perso, ZDM ) * * Function : Vecteur = ZON_LitAxeZDE * * Use : Vecteur = ZON_LitAxeZDE( Perso, ZDE ) * * Function : Vecteur = ZON_LitAxeZDD * * Use : Vecteur = ZON_LitAxeZDD( Perso, ZDD ) * * Author : Christophe Giraud * * Date of last modification: 23/01/98 * ***********************************************************************/ #if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/ tdstNodeInterpret *fn_p_stCode4LitAxeZDx(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { tdstGetSetParam stParam; /* exchange structure*/ HIE_tdxHandleToSuperObject hPerso; /* Handle of the character*/ ACP_tdxHandleOfObject hGeoObj; /* Handle of the geometric object*/ long lZoneNumber, /* Number of the zone*/ lLocalGlobal; MTH_tdxReal fMinX, fMinY, fMinZ, fMaxX, fMaxY, fMaxZ; MTH3D_tdstVector stVectorMin, stVectorMax, stAxisVector; ACP_tdxIndex xMaxPoint, xMinPoint; enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1); /********************************************************************************/ /* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */ /********************************************************************************/ fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hPerso); /* Get second parameter that is a ZDM*/ M_EvalNextParameter( &stParam ); lZoneNumber = (long) M_GetSetParam_lZDMIdValue( &stParam ); /* Get third parameter that is a Boolean*/ M_EvalNextParameter(p_stValue); lLocalGlobal = M_GetSetParam_lValue(p_stValue); switch( eFuncId ) { case eFunc_LitAxeZDM: /* Get handle about geometric object of the ZDM*/ hGeoObj = fn_hGetGeometricZdxOfTypeAtIndex( C_ucTypeZdm, (unsigned short)(lZoneNumber-1), hPerso ); break; case eFunc_LitAxeZDE: /* Get handle about geometric object of the ZDE*/ hGeoObj = fn_hGetGeometricZdxOfTypeAtIndex( C_ucTypeZde, (unsigned short)(lZoneNumber-1), hPerso ); break; case eFunc_LitAxeZDD: /* Get handle about geometric object of the ZDD*/ hGeoObj = fn_hGetGeometricZdxOfTypeAtIndex( C_ucTypeZdd, (unsigned short)(lZoneNumber-1), hPerso ); break; default: { /* Function does not existe*/ M_AIFatalError(E_uwAIFatalNotValidFunction); return(p_stTree); break; } } /* Initialize to 0, 0, 0*/ MTH3D_M_vNullVector( &stAxisVector ); if( hGeoObj ) { switch( *hGeoObj->d_xListOfElementsTypes ) { case GEO_C_xElementAlignedBoxes: /* It's a box.*/ { /* Get MinPoint and MaxPoint of the box*/ GEO_vGetMinMaxPointOfIndexedAlignedBox( hGeoObj, 0, 0, &xMinPoint, &xMaxPoint ); /* Get MinVector and MaxVector of the box*/ GEO_vGetPointOfObject( hGeoObj, &stVectorMin, xMinPoint ); GEO_vGetPointOfObject( hGeoObj, &stVectorMax, xMaxPoint ); /* Get all points of MinVector and MaxVector*/ MTH3D_M_vGetVectorElements(&fMinX,&fMinY,&fMinZ,&stVectorMin); MTH3D_M_vGetVectorElements(&fMaxX,&fMaxY,&fMaxZ,&stVectorMax); /* Get lenght for X, Y, Z*/ fMaxX -= fMinX; fMaxY -= fMinY; fMaxZ -= fMinZ; /* Set normed Axis of the box*/ if ( fMaxX>fMaxY && fMaxX>fMaxZ ) { MTH3D_M_vSetXofVector( &stAxisVector, 1.0f ); } if ( fMaxY>fMaxX && fMaxY>fMaxZ ) { MTH3D_M_vSetYofVector( &stAxisVector, 1.0f ); } if ( fMaxZ>fMaxX && fMaxZ>fMaxY ) { MTH3D_M_vSetZofVector( &stAxisVector, 1.0f ); } } break; default: { /* Return a null vector*/ MTH3D_M_vNullVector( &stVectorMin ); } break; } } else { /* Return a null vector*/ MTH3D_M_vNullVector( &stVectorMin ); } if ( lLocalGlobal == TRUE ) { GEO_tdxHandleToMatrix hMatrix; /* get character local matrix */ hMatrix = HIE_fn_hGetSuperObjectGlobalMatrix(p_SuperObjPerso); /* compute the global vector */ POS_fn_vRotateVector(&stAxisVector,hMatrix, &stAxisVector); } /* Return vector*/ M_Full_GetSetParam_p_stVertex( p_stValue, &stAxisVector ); return(p_stTree); } #endif /* _AI_EXCLUDE_NEVER_USED_ }*/ /******************************************************************** * Function : Vecteur = Func_VecteurPointAxe() * * Function : Vecteur = Func_VecteurPointSegment(point, debut, dir) * * Use : Vecteur = Func_VecteurPointAxe( point, SegDebut, SegFin) * * Date of last modification: 10/02/98 * ********************************************************************/ tdstNodeInterpret *fn_p_stCode4VecteurPointAxe(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { tdstGetSetParam stParam1, stParam2, stParam3; /* exchange structure*/ MTH3D_tdstVector stvVector, stdVector, stOMVector, *p_stMVector, *p_stOVector, *p_stuVector; enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1); /* -> -> u v O --------->-------> P \ Q| \ | \ | -> \ | d \ | \ | \ | \ | \| M */ /* Get first parameter : Point M*/ M_EvalNextParameter( &stParam1 ); p_stMVector = &M_GetSetParam_stVectorValue( &stParam1 ); /* Get second parameter : First extremity of segment O*/ M_EvalNextParameter( &stParam2 ); p_stOVector = &M_GetSetParam_stVectorValue( &stParam2 ); /* Get second parameter : second extremity of segment P / direction vector*/ M_EvalNextParameter( &stParam3 ); p_stuVector = &M_GetSetParam_stVectorValue( &stParam3 ); switch( eFuncId ) { case eFunc_VecteurPointSegment: { MTH_tdxReal xNormOP, xNormV; MTH3D_tdstVector stPVector = *p_stuVector; /*save the position of the far extremity, in case we need it*/ /* Compute Vector OM*/ MTH3D_M_vSubVector( &stOMVector, p_stMVector, p_stOVector ); /*transform into vector from O to P (normalized)*/ MTH3D_M_vSubVector(p_stuVector, p_stuVector, p_stOVector); if ( MTH_M_bIsNullWithEpsilon(MTH3D_M_xGetXofVector(p_stuVector), MTH_M_xDoubleToReal(1.0e-4)) && MTH_M_bIsNullWithEpsilon(MTH3D_M_xGetYofVector(p_stuVector), MTH_M_xDoubleToReal(1.0e-4)) && MTH_M_bIsNullWithEpsilon(MTH3D_M_xGetZofVector(p_stuVector), MTH_M_xDoubleToReal(1.0e-4)) ) { /*segment is of null length: return the vector from our position to either point*/ MTH3D_M_vNegVector(&stdVector, &stOMVector); } else { /* remember the segment length*/ xNormOP = MTH3D_M_xNormVector(p_stuVector); MTH3D_M_vNormalizeVector(p_stuVector, p_stuVector); /* See if OQ and OP look the same way*/ xNormV = MTH3D_M_xDotProductVector(&stOMVector, p_stuVector); /* |OM|.cos (because |OP| = |u| = 1)*/ /* Compute d = MQ*/ if ( MTH_M_bLessZero(xNormV) ) /* closest point on the line is beyond the first extremity of the segment*/ { /* vector goes from M to O*/ MTH3D_M_vNegVector(&stdVector, &stOMVector); } else { /*compute v = OQ*/ MTH3D_M_vMulScalarVector(&stvVector, xNormV, p_stuVector); /* v = |OM|.cos = OQ*/ /* get the length of the segment from O to the closest point*/ if ( MTH_M_bGreater(xNormV, xNormOP)) /* closest point on the line is beyond the second extremity of the segment*/ { /*vector goes from M to P*/ MTH3D_M_vSubVector( &stdVector, &stPVector, p_stMVector); } else /* closest point is really on the segment*/ { /* vector goes from M to Q : d = OQ - OM = MQ*/ MTH3D_M_vSubVector( &stdVector, &stvVector, &stOMVector); } } } } break; //#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/ case eFunc_VecteurPointAxe: { /* Compute Vector OM*/ MTH3D_M_vSubVector( &stOMVector, p_stMVector, p_stOVector ); /* Compute v*/ if ( MTH_M_bIsNullWithEpsilon(MTH3D_M_xGetXofVector(p_stuVector), MTH_M_xDoubleToReal(1.0e-4)) && MTH_M_bIsNullWithEpsilon(MTH3D_M_xGetYofVector(p_stuVector), MTH_M_xDoubleToReal(1.0e-4)) && MTH_M_bIsNullWithEpsilon(MTH3D_M_xGetZofVector(p_stuVector), MTH_M_xDoubleToReal(1.0e-4)) ) { /*if the axis direction is not valid, return NULL*/ MTH3D_M_vNullVector(&stdVector); } else { MTH_tdxReal xTmp; MTH3D_M_vNormalizeVector(p_stuVector, p_stuVector); /* normalize axis direction*/ xTmp = MTH3D_M_xDotProductVector(&stOMVector, p_stuVector); MTH3D_M_vMulScalarVector(&stvVector, xTmp, p_stuVector); /* Compute d, du point vers le segment*/ MTH3D_M_vSubVector( &stdVector, &stvVector, &stOMVector); } } break; //#endif /* _AI_EXCLUDE_NEVER_USED_ }*/ default: { /* Function does not existe*/ M_AIFatalError(E_uwAIFatalNotValidFunction); return(p_stTree); break; } } /* Return vector*/ M_Full_GetSetParam_p_stVertex( p_stValue, &stdVector ); return(p_stTree); } /******************************************************************* * Function : LitPositionZDM * * Use : LitPositionZDM( Perso, ZDM ) * * Function : LitPositionZDE * * Use : LitPositionZDE( Perso, ZDE ) * * Function : LitPositionZDD * * Use : LitPositionZDD( Perso, ZDD ) * * Author : Christophe Giraud * * Date of last modification: 06/03/98 * *******************************************************************/ tdstNodeInterpret *fn_p_stCode4LitPositionZDx(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { tdstGetSetParam stParam; /* exchange structure*/ HIE_tdxHandleToSuperObject hPerso; /* Handle of the character*/ ACP_tdxHandleOfObject hGeoObj; /* Handle of the geometric object*/ long lZoneNumber; /* Number of the zone*/ MTH3D_tdstVector stVectorMin; ACP_tdxIndex xMaxPoint, xMinPoint; enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1); /********************************************************************************/ /* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */ /********************************************************************************/ fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hPerso); /* Get second parameter that is a ZDM*/ M_EvalNextParameter( &stParam ); lZoneNumber = (long) M_GetSetParam_lZDMIdValue( &stParam ); switch( eFuncId ) { case eFunc_LitPositionZDM: /* Get handle about goemetric object of the ZDM*/ hGeoObj = fn_hGetGeometricZdxOfTypeAtIndex( C_ucTypeZdm, (unsigned short)(lZoneNumber-1), hPerso ); break; case eFunc_LitPositionZDE: /* Get handle about goemetric object of the ZDE*/ hGeoObj = fn_hGetGeometricZdxOfTypeAtIndex( C_ucTypeZde, (unsigned short)(lZoneNumber-1), hPerso ); break; #if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/ case eFunc_LitPositionZDD: /* Get handle about goemetric object of the ZDD*/ hGeoObj = fn_hGetGeometricZdxOfTypeAtIndex( C_ucTypeZdd, (unsigned short)(lZoneNumber-1), hPerso ); break; #endif /* _AI_EXCLUDE_NEVER_USED_ }*/ default: { /* Function does not existe*/ M_AIFatalError(E_uwAIFatalNotValidFunction); return(p_stTree); break; } } /* if( hGeoObj ) { // Return position of the zone M_Full_GetSetParam_p_stVertex( p_stValue, &hGeoObj->d_stListOfPoints[0] ); return(p_stTree); } */ /* Move geometric object*/ if( hGeoObj ) { switch( *hGeoObj->d_xListOfElementsTypes ) { case GEO_C_xElementPoints: /* It's a point:*/ case GEO_C_xElementSpheres: /* It's a sphere:*/ M_Full_GetSetParam_p_stVertex( p_stValue, &hGeoObj->d_stListOfPoints[0] ); return(p_stTree); break; case GEO_C_xElementAlignedBoxes: /* It's a box.*/ case GEO_C_xElementCones: /* It's a cone:*/ /* Get MinPoint and MaxPoint of the box*/ GEO_vGetMinMaxPointOfIndexedAlignedBox ( hGeoObj, 0, 0, &xMinPoint, &xMaxPoint ); /* Get MinVector and MaxVector of the box*/ GEO_vGetPointOfObject( hGeoObj, &stVectorMin, xMinPoint ); M_Full_GetSetParam_p_stVertex( p_stValue, &stVectorMin ); return(p_stTree); break; } } return(p_stTree); } /******************************************************************* * Function: VitesseHorizontaleDuPerso * * Use : "perso".VitesseHorizontaleDuPerso( Number of frames ) * * Function: VitesseVerticaleDuPerso * * Use : "perso".VitesseVerticaleDuPerso( Number of frames ) * * Use for : Return the value of the global speed for N frames * * Author : Christophe Giraud * * Date of last modification: 17/10/97 * *******************************************************************/ #if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/ tdstNodeInterpret *fn_p_stCode4VitesseHorizontaleDuPerso(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { DNM_tdstReport *p_stDynamReport; /* MTH3D_tdstVector stSpeed; // Vector for average speed*/ MTH_tdxReal xValue = 0; /* Variable to stock the return value of the function*/ /* xNumberOfFrames; // Number of frames wanted to compute global speed*/ /* tdstGetSetParam stParam ; // Structure d'échange*/ 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); if ( (p_stDynamReport = fn_pstGetDNMReport(hNewSuperObjPerso)) == NULL ) { return p_stTree; } switch(eFuncId) { case eFunc_VitesseHorizontaleDuPerso: { /* ANNECY MT - 25/08/98 { // Evaluation of next parameter M_EvalNextParameter( &stParam ); // Get number of frames xNumberOfFrames = (MTH_tdxReal) (M_ReturnParam_lValue( &stParam )<<4); // Use AverageSpeed and norm vector without Z fn_vAverageSpeed( p_SuperObjPerso, xNumberOfFrames, &stSpeed ); xValue = MTH_M_xSqrt( MTH_M_xAdd( MTH_M_xSqr(stSpeed.xX), MTH_M_xSqr(stSpeed.xY) )); END ANNECY MT } */ /* On informe le moteur sur le type et la valeur calculée.*/ M_Full_GetSetParam_Float(p_stValue, xValue ); return(p_stTree); break; } case eFunc_VitesseVerticaleDuPerso: { /* ANNECY MT - 25/08/98 { // Evaluation of next parameter M_EvalNextParameter( &stParam ); // Get number of frames xNumberOfFrames = (MTH_tdxReal) (M_ReturnParam_lValue( &stParam )<<4); // Use AverageSpeed and norm vector without Z fn_vAverageSpeed( p_SuperObjPerso, xNumberOfFrames, &stSpeed ); xValue = stSpeed.xZ; END ANNECY MT } */ /* On informe le moteur sur le type et la valeur calculée.*/ M_Full_GetSetParam_Float(p_stValue, xValue ); 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); } #endif /* _AI_EXCLUDE_NEVER_USED_ }*/ #include "FuncRay2.cxx" /*ENDANNECY CG }*/ /****************************************************************** * Function: GetDTFunction * * Use : LitDT () * * Author : Jacques Thénoz * * optimised by ylt september 18,1998 * Date of last modification: 21/10/97 * ******************************************************************/ tdstNodeInterpret *fn_p_stGetDTFunction(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { M_Full_GetSetParam_Float(p_stValue, MTH_M_xLongToReal(g_stEngineStructure.stEngineTimer.ulUsefulDeltaTime)); #if 0 #ifdef ACTIVE_EDITOR /*after a 10s stabilisation delay, warn if the useful deltaT is not a frame multiple (a tolerance is accepted)*/ if ( g_stEngineStructure.stEngineTimer.ulCurrentTimerCount > 10000 ) { /* compute the exact frame change form the delta time*/ MTH_tdxReal xFrames = MTH_M_xMul(MTH_M_xLongToReal(g_stEngineStructure.stEngineTimer.ulUsefulDeltaTime), MTH_M_xFloatToReal(0.06f)); /* check this against the closest full frames number*/ MTH_tdxReal xRounded = MTH_M_xSub(MTH_M_xLongToReal(MTH_M_xRealToLong(MTH_M_xAdd(xFrames, MTH_C_Inv2))), xFrames); /* we accept a 10% fluctuation!*/ if ( MTH_M_bGreater(MTH_M_xAbs(xRounded), MTH_M_xDoubleToReal(0.1)) ) { char szMsg[200]; sprintf(szMsg, "Erreur interne du moteur: le DeltaT (%d) n'est pas un multiple de la trame (16.66ms)!", g_stEngineStructure.stEngineTimer.ulUsefulDeltaTime); SAF_M_AssertWithMsg(FALSE, szMsg); } } #endif /* ACTIVE_EDITOR */ #endif return (p_stTree); } /****************************************************************** * Function: GetNormalCollideVector * * Use : v := VecteurNormalCollision () * * Author : J Thenoz * * Date of last modification: 20/11/97 * ******************************************************************/ tdstNodeInterpret *fn_p_stGetNormalCollideVector(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1); MTH3D_tdstVector stNormalVector; DNM_tdstReport *p_stDynamReport; DNM_tdstObstacle* p_stObstacle = NULL; /********************************************************************************/ /* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */ /********************************************************************************/ HIE_tdxHandleToSuperObject hNewSuperObjPerso; fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hNewSuperObjPerso); /********************************************************************************/ MTH3D_M_vNullVector(&stNormalVector); SAF_M_AssertWithMsg(DNM_M_bDynamicsIsCollisionReport(fn_p_stDynamGetDynamics(M_GetMSHandle(hNewSuperObjPerso,Dynam))), "la mécanique a besoin du rapport de collisions pour cet appel"); p_stDynamReport = fn_pstGetDNMReport(hNewSuperObjPerso); switch ( eFuncId ) { case eFunc_GetNormalCollideVector2: { long lWhichObstacle; M_EvalNextParameter(p_stValue); lWhichObstacle = M_GetSetParam_lValue(p_stValue); switch ( lWhichObstacle ) { default: SAF_M_AssertWithMsg(FALSE, "l'obstacle spécifié n'est pas valide"); M_Full_GetSetParam_p_stVertex(p_stValue, &stNormalVector); return p_stTree; break; case 0: /*get the last obstacle (equivalent to original version of the function)*/ p_stObstacle = DNM_M_p_stReportGetObstacle(p_stDynamReport); break; case 1: /*get the last ground*/ p_stObstacle = DNM_M_p_stReportGetGround(p_stDynamReport); break; case 2: /*get the last wall*/ p_stObstacle = DNM_M_p_stReportGetWall(p_stDynamReport); break; case 3: /*get the last character*/ p_stObstacle = DNM_M_p_stReportGetCharacter(p_stDynamReport); break; case 4: /*get the last uncollidable/water plane*/ p_stObstacle = DNM_M_p_stReportGetWater(p_stDynamReport); break; case 5: /* get the last ceiling*/ p_stObstacle = DNM_M_p_stReportGetCeil(p_stDynamReport); break; } M_Full_GetSetParam_p_stVertex(p_stValue, DNM_M_p_stObstacleGetNorm(p_stObstacle)); } return p_stTree; break; case eFunc_GetNormalCollideVector: { unsigned long ulSurfState = DNM_M_ulReportGetSurfaceState(p_stDynamReport); if ( (ulSurfState & C_WOT_ulMobile) == C_WOT_ulMobile ) { p_stObstacle = DNM_M_p_stReportGetCharacter(p_stDynamReport); MTH3D_M_vAddVector(&stNormalVector, &stNormalVector, DNM_M_p_stObstacleGetNorm(p_stObstacle)); } if ( (ulSurfState & C_WOT_ulGround) == C_WOT_ulGround ) { p_stObstacle = DNM_M_p_stReportGetGround(p_stDynamReport); MTH3D_M_vAddVector(&stNormalVector, &stNormalVector, DNM_M_p_stObstacleGetNorm(p_stObstacle)); } if ( (ulSurfState & C_WOT_ulWall) == C_WOT_ulWall ) { p_stObstacle = DNM_M_p_stReportGetWall(p_stDynamReport); MTH3D_M_vAddVector(&stNormalVector, &stNormalVector, DNM_M_p_stObstacleGetNorm(p_stObstacle)); } if ( (ulSurfState & C_WOT_ulWater) == C_WOT_ulWater ) { p_stObstacle = DNM_M_p_stReportGetWater(p_stDynamReport); MTH3D_M_vAddVector(&stNormalVector, &stNormalVector, DNM_M_p_stObstacleGetNorm(p_stObstacle)); } if ( (ulSurfState & C_WOT_ulCeiling) == C_WOT_ulCeiling ) { p_stObstacle = DNM_M_p_stReportGetCeil(p_stDynamReport); MTH3D_M_vAddVector(&stNormalVector, &stNormalVector, DNM_M_p_stObstacleGetNorm(p_stObstacle)); } if ( ulSurfState == C_WOT_ulNoObstacle ) { p_stObstacle = DNM_M_p_stReportGetObstacle(p_stDynamReport); MTH3D_M_vAddVector(&stNormalVector, &stNormalVector, DNM_M_p_stObstacleGetNorm(p_stObstacle)); } if ( !MTH3D_M_bIsNullVector(&stNormalVector) ) { MTH3D_M_vNormalizeVector(&stNormalVector, &stNormalVector); } M_Full_GetSetParam_p_stVertex(p_stValue,&stNormalVector); } return p_stTree; break; default: break; } M_AIFatalError(E_uwAIFatalNotValidFunction); return(p_stTree); } /*************************************************************************** * Function : VecteurNormalSol * Use : v := VecteurNormalSol () * Author : Jean-Marc Drouaud * Date : 11/12/97 ****************************************************************************/ /* tdstNodeInterpret *fn_p_stGetNormalGroundVector(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1); if (eFuncId==eFunc_GetNormalGroundVector) { MTH3D_tdstVector stNormalVector; DNM_tdstReport *p_stDynamReport; DNM_tdstObstacle *p_stGround; MTH3D_M_vNullVector ( &stNormalVector ); if ( (p_stDynamReport = fn_pstGetDNMReport(p_SuperObjPerso))!=NULL ) { p_stGround = DNM_M_p_stReportGetGround(p_stDynamReport); if (p_stGround) MTH3D_M_vCopyVector ( &stNormalVector, DNM_M_p_stObstacleGetNorm (p_stGround) ); } M_Full_GetSetParam_p_stVertex(p_stValue,&stNormalVector); return (p_stTree); } M_AIFatalError(E_uwAIFatalNotValidFunction); return(p_stTree); } */ /****************************************************************** * Function: CollideCommunicationFunc * * Use : entier := COL_LitTypeDeCollisionneur() * * Use : v := COL_LitVecteurDeCollisionneur(index) * * Use : reel := COL_LitReelDeCollisionneur(index) * * Author : B. Germain * * Date of last modification: 20/11/97 * ******************************************************************/ tdstNodeInterpret *fn_p_stCollideCommunicationFunc(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1); short wIndex = 0; MS_tdxHandleToCollSet _hCollSet; HIE_tdxHandleToSuperObject hNewSuperObjPerso; fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hNewSuperObjPerso); _hCollSet = M_GetMSHandle(hNewSuperObjPerso,CollSet); switch ( eFuncId ) { case eFunc_GetColliderType: if ( _hCollSet ) wIndex = fn_ucCollSetGetColliderType(_hCollSet); M_Full_GetSetParam_Integer(p_stValue, wIndex); break; case eFunc_GetColliderVector: { /*point directly in the return value's vector field*/ MTH3D_tdstVector *p_stDstVect = &M_GetSetParam_stVertexValue(p_stValue); M_EvalNextParameter(p_stValue); wIndex = M_GetSetParam_wValue(p_stValue); SAF_M_AssertWithMsg((wIndex >= 0) && (wIndex < C_wCollsetNbCollisionVectors), "L'index du vecteur spécifié n'existe pas!"); if ( _hCollSet ) *p_stDstVect = fn_stCollSetGetColliderVector(_hCollSet, wIndex); else MTH3D_M_vNullVector(p_stDstVect); M_GetSetParam_Type(p_stValue) = E_vt_Vector; } break; case eFunc_GetColliderReal: { M_EvalNextParameter(p_stValue); wIndex = M_GetSetParam_wValue(p_stValue); SAF_M_AssertWithMsg((wIndex >= 0) && (wIndex < C_wCollsetNbCollisionReals), "L'index du réel spécifié n'existe pas!"); M_Full_GetSetParam_Float(p_stValue, _hCollSet ? fn_xCollSetGetColliderReal(_hCollSet, wIndex) : MTH_C_ZERO ); } break; default: break; } return p_stTree; } /* ============================================================ function: GetPersoSighting Use : v := ULTRA.ViseePerso() author: Yann Le tensorer sept 16, 1998 ==============================================================*/ tdstNodeInterpret *fn_p_stGetPersoSighting(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1); MTH3D_tdstVector *p_stTmpV0,*p_stTmpV1,*p_stTmpV2; /* temporary vector pointers*/ MTH3D_tdstVector *p_stResultVector = &M_GetSetParam_stVertexValue(p_stValue); HIE_tdxHandleToSuperObject hNewSuperObjPerso; fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hNewSuperObjPerso); /*=========== we get the sight vector of the character*/ /* GetRotationVector doesn't make any copy so it is fast...*/ POS_fn_vGetRotationVector(HIE_fn_hGetSuperObjectGlobalMatrix(hNewSuperObjPerso),&p_stTmpV0,&p_stTmpV1,&p_stTmpV2); MTH3D_M_vNegVector(p_stResultVector,p_stTmpV1); /* objects watch in -Y, so we negate the vector*/ /* the exchange struture already contains the result vector, only the type remains to be properly set.*/ M_GetSetParam_Type(p_stValue) = E_vt_Vector; return p_stTree; } /****************************************************************** * Function: 3DFunc * * Use : v := ULTRA.PositionRelativeModule("canal") * * Use : v := ULTRA.PositionAbsolueModule("canal") * * Use : v := ULTRA.DeformationModule("canal") * * Use : v := ULTRA.ViseePerso() * * Use : v := ULTRA.AssiettePerso() * * Use : v := ULTRA.HorizonPerso() * * Use : v := ULTRA.ViseeModule("canal", BOOL) * * Author : B. Germain * * Date of last modification: 20/11/97 * ******************************************************************/ tdstNodeInterpret *fn_p_st3DFunc(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1); unsigned char ucChannel; long lGlobalAxis = 1; MTH3D_tdstVector stDstVector; POS_tdstCompletePosition *hObjectMatrix; /********************************************************************************/ /* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */ /********************************************************************************/ HIE_tdxHandleToSuperObject hNewSuperObjPerso; fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hNewSuperObjPerso); MTH3D_M_vNullVector(&stDstVector); switch ( eFuncId ) { case eFunc_GetPersoZoomFactor: /*we want to read the position or zoom factor in the local matrix*/ lGlobalAxis = 0; break; case eFunc_GetModuleRelativePosition: #if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/ case eFunc_GetModuleZoomFactor: #endif /* _AI_EXCLUDE_NEVER_USED_ }*/ /*we want to read the position or zoom factor in the local matrix*/ lGlobalAxis = 0; /*fall through*/ case eFunc_GetModuleAbsolutePosition: case eFunc_GetModuleSighting: { HIE_tdxHandleToSuperObject hChannelSuperObject; /*read the args (use the output exchange structure to spare the stack)*/ M_EvalNextParameter(p_stValue); ucChannel = M_GetSetParam_lValue(p_stValue); /*if we dont know the module, return a null vector*/ if ( ucChannel == C_ucUnknownChannel ) { M_Full_GetSetParam_p_stVertex(p_stValue,&stDstVector); return fn_p_stSwapNextParameter(p_stTree); break; } /* read the module superobject*/ hChannelSuperObject = fn_hGetSuperObjectInChannel(fn_h3dDataGetChannelSOList(M_GetMSHandle(hNewSuperObjPerso,3dData)), ucChannel); /* if we got one, use it*/ if ( hChannelSuperObject ) { /* FBF blindage acces modules {*/ #ifdef ACTIVE_EDITOR fn_vCheckModuleAccess(hNewSuperObjPerso, TRUE, &ucChannel); #endif /* } fin blindage acces modules*/ hNewSuperObjPerso = hChannelSuperObject; } /*else use the actor instead (will yield strange results, but won't crash...)*/ if ( eFuncId == eFunc_GetModuleSighting ) { M_EvalNextParameter(p_stValue); lGlobalAxis = M_GetSetParam_lValue(p_stValue); } /*else //we want to read the position in the global matrix lGlobalAxis = 1;*/ } /*fall through*/ case eFunc_GetPersoBanking: case eFunc_GetPersoHorizon: /*do nothing special (we will read the rotation vector in the global matrix)*/ break; default: M_AIFatalError(E_uwAIFatalNotValidFunction); return p_stTree; break; } /*get the matrix that corresponds to the coordinates system in which we want the results*/ hObjectMatrix = lGlobalAxis ? HIE_fn_hGetSuperObjectGlobalMatrix(hNewSuperObjPerso) : HIE_fn_hGetSuperObjectMatrix(hNewSuperObjPerso); /*now do the deed*/ switch ( eFuncId ) { case eFunc_GetPersoBanking: { MTH3D_tdstVector stV1, stV2; /* ANNECY AV {*/ struct DNM_stDynamics * p_stDynamic; MS_tdxHandleToDynam h_Dynam; /* If the actor has tilt, we return a vertical vector*/ /* Oliv' - Portage v14 - to reduce number of warnings*/ if( (h_Dynam = M_GetMSHandle (hNewSuperObjPerso,Dynam)) != 0 ) /* = is not an error*/ { /* Oliv' - Portage v14 - to reduce number of warnings*/ if( ((p_stDynamic = fn_p_stDynamGetDynamics (h_Dynam))!=0) && DNM_M_bDynamicsIsTilt (p_stDynamic)) /* = is not an error*/ { MTH3D_M_vSetVectorElements (& stDstVector , MTH_C_ZERO , MTH_C_ZERO , MTH_C_ONE); break; } } /* END ANNECY AV }*/ /*get the vertical axis*/ POS_fn_vGetRotationMatrix(hObjectMatrix, &stV1, &stV2, &stDstVector); } break; case eFunc_GetPersoHorizon: { MTH3D_tdstVector stV2, stV3; /*get the transversal axis (means that X.z is positive when perso banks to the right)*/ POS_fn_vGetRotationMatrix(hObjectMatrix, &stDstVector, &stV2, &stV3); } break; case eFunc_GetModuleSighting: { MTH3D_tdstVector stV1, stV3; POS_fn_vGetRotationMatrix(hObjectMatrix, &stV1, &stDstVector, &stV3); /*objects are suposed to watch in -Y, so negate the vector to make it point where the object is watching*/ MTH3D_M_vNegVector(&stDstVector, &stDstVector); /* // ANNECY AV { // If the actor has tilt, we return a horizontal vector (if the vector is already horizontal, we don't need to test the tilt if (eFuncId == eFunc_GetPersoSighting && ! MTH_M_bIsNullWithEpsilon (MTH3D_M_xGetZofVector (& stDstVector) , MTH_M_xFloatToReal (0.001))) { struct DNM_stDynamics * p_stDynamic; MS_tdxHandleToDynam h_Dynam; if (h_Dynam = M_GetMSHandle (hNewSuperObjPerso,Dynam)) // = is not an error { if ((p_stDynamic = fn_p_stDynamGetDynamics (h_Dynam)) && DNM_M_bDynamicsIsTilt (p_stDynamic)) // = is not an error { // We project the vector onto the horizontal plane MTH3D_M_vSetZofVector (& stDstVector , MTH_C_ZERO); // But we can do that only if the previous vector is not vertical if (MTH_M_bIsNullWithEpsilon (MTH3D_M_xGetXofVector (& stDstVector) , MTH_M_xFloatToReal (0.001)) == FALSE || MTH_M_bIsNullWithEpsilon (MTH3D_M_xGetYofVector (& stDstVector) , MTH_M_xFloatToReal (0.001)) == FALSE) { MTH3D_M_vNormalizeVector (& stDstVector , & stDstVector); } // If it was vertical, we return a predefined vector else MTH3D_M_vSetVectorElements (& stDstVector , MTH_C_ZERO , MTH_C_MinusONE , MTH_C_ZERO); } } } // END ANNECY AV } */ } break; #if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/ case eFunc_GetModuleZoomFactor: #endif /* _AI_EXCLUDE_NEVER_USED_ }*/ case eFunc_GetPersoZoomFactor: { MTH3D_tdstVector stV1, stV2, stV3; /*get the scale matrix*/ POS_fn_vGetScaleMatrix(hObjectMatrix, &stV1, &stV2, &stV3); /*and extract the norms of the transform matrix vectors*/ MTH3D_M_vSetVectorElements(&stDstVector, MTH3D_M_xNormVector(&stV1), MTH3D_M_xNormVector(&stV2), MTH3D_M_xNormVector(&stV3)); } break; case eFunc_GetModuleRelativePosition: case eFunc_GetModuleAbsolutePosition: /*extract the translation vector from the selected matrix*/ POS_fn_vGetTranslationVector(hObjectMatrix, &stDstVector); break; default: break; } M_Full_GetSetParam_p_stVertex(p_stValue, &stDstVector); return p_stTree; } /************************************************************************** * Function: NameFunc * * Use : text := TEXT_LitNomDuJoueur() * * Use : int := TEXT_LettreDuTexteALaPosition("texte", pos) * * Use : int = TEXT_LitInfoSurTexteFormate("text", array, array, array) * * * * Author : B. Germain * * Date of last modification: 13/03/98 * **************************************************************************/ // FB 100899 char g_szDummy[5]; tdstNodeInterpret *fn_p_stNamesFunc(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1); switch ( eFuncId ) { #if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/ case eFunc_GetInputEntryName: { IPT_tdxHandleToEntryElement IPT_xHandle; M_EvalNextParameter(p_stValue); IPT_xHandle = (IPT_tdxHandleToEntryElement) M_GetSetParam_lValue(p_stValue); SAF_M_AssertWithMsg(IPT_fn_szGetEntryActionName(IPT_xHandle), "Input handle n'a pas de nom"); M_Full_GetSetParam_String(p_stValue, IPT_fn_szGetEntryActionName(IPT_xHandle)); } return p_stTree; break; /*anti-bug GCC N64*/ case eFunc_GetFormattedTextInfo: { unsigned char ucArrayStartCharId, ucArrayEndCharId, ucArrayPosVectorId, ucMaxNbLines, ucCurrentLine; tdstTfmtStatus stStatus; tdstTfmtLineResults *d_stLineResults; MTH_tdxReal xScreenWidth; char *pszString; /*get all the parameters*/ M_EvalNextParameter(p_stValue); pszString = (char *)fn_szGetStringFromTextOrStringParam(p_stValue); M_EvalNextParameter(p_stValue); xScreenWidth = M_ReturnParam_xValue(p_stValue); ucArrayStartCharId = (unsigned char) M_ucVarIdInterpret(p_stTree); p_stTree ++; ucArrayEndCharId = (unsigned char) M_ucVarIdInterpret(p_stTree); p_stTree ++; ucArrayPosVectorId = (unsigned char) M_ucVarIdInterpret(p_stTree); p_stTree ++; M_EvalNextParameter(p_stValue); ucMaxNbLines = M_ReturnParam_lValue(p_stValue); /*now lets fill the arrays properly*/ #ifndef CODEWARRIOR d_stLineResults = (tdstTfmtLineResults *) alloca(sizeof(tdstTfmtLineResults) * ucMaxNbLines); #else d_stLineResults = (tdstTfmtLineResults *) __alloca(sizeof(tdstTfmtLineResults) * ucMaxNbLines); #endif /*start by getting all the info in our own structures. the function returns the number of exceeding lines*/ ucMaxNbLines = ucCurrentLine = TFMT_wPositionModulesAccordingToText(&stStatus, p_SuperObjPerso, pszString, 0, -1, xScreenWidth, d_stLineResults, ucMaxNbLines); /*and fill the arrays with them*/ while ( ucCurrentLine -- ) { M_Full_GetSetParam_Integer(p_stValue, d_stLineResults[ucCurrentLine].wStartChar); if ( fn_ucSetDsgVar(ucArrayStartCharId, ucCurrentLine, AI_M_stGetMindOfSuperObj(p_SuperObjPerso), p_stValue) == C_INVALID_SET ) break; M_Full_GetSetParam_Integer(p_stValue, d_stLineResults[ucCurrentLine].wEndChar); if ( fn_ucSetDsgVar(ucArrayEndCharId, ucCurrentLine, AI_M_stGetMindOfSuperObj(p_SuperObjPerso), p_stValue) == C_INVALID_SET ) break; M_Full_GetSetParam_p_stVertex(p_stValue, &d_stLineResults[ucCurrentLine].stLineOrigin); if ( fn_ucSetDsgVar(ucArrayPosVectorId, ucCurrentLine, AI_M_stGetMindOfSuperObj(p_SuperObjPerso), p_stValue) == C_INVALID_SET ) break; } /* return the number of entries that got filled in the arrays (one for each line)*/ M_Full_GetSetParam_Integer(p_stValue, ucMaxNbLines); } return p_stTree; break; /*anti-bug GCC N64*/ #endif /* _AI_EXCLUDE_NEVER_USED_ }*/ case eFunc_GetSlotName: { long lSlotId; int Version = 0; M_EvalNextParameter(p_stValue); lSlotId = M_ReturnParam_lValue(p_stValue); #ifdef U64 SAF_M_AssertWithMsg((lSlotId >= 1 && lSlotId <= C_ucNbSaveGameSlots),"Slot de sauvegarde inexistant"); strncpy(g_szDummy,g_stGameOptions.a_szSlotNames[lSlotId-1],3); g_szDummy[3] ='\0'; #else /* PC */ #ifdef ACTIVE_EDITOR Version = fn_iVersionN64_PC(); if ( Version == 1 /* U64 */) { SAF_M_AssertWithMsg((lSlotId >= 1 && lSlotId <= C_ucNbSaveGameSlots),"Slot de sauvegarde inexistant"); strncpy(g_szDummy,g_stGameOptions.a_szSlotNames[lSlotId-1],3); g_szDummy[3] ='\0'; } else if( Version == 2 /* PC */) { SAF_M_AssertWithMsg((lSlotId >= 1 && lSlotId <= (long) fn_lGetNbAvailableSlotsPc()),"Slot de sauvegarde inexistant"); strncpy(g_szDummy, fn_cRecupSlotName(lSlotId), 3); g_szDummy[3] ='\0'; } #else // PC sans editeur SAF_M_AssertWithMsg((lSlotId >= 1 && lSlotId <= (long) fn_lGetNbAvailableSlotsPc()),"Slot de sauvegarde inexistant"); strncpy(g_szDummy, fn_cRecupSlotName(lSlotId), 3); g_szDummy[3] ='\0'; #endif // ACTIVE_EDITOR #endif // U64 M_Full_GetSetParam_String(p_stValue, g_szDummy/*g_stGameOptions.a_szSlotNames[lSlotId-1]*/); } return p_stTree; break; /*anti-bug GCC N64*/ case eFunc_GetSlotScore: { long lSlotId; int Version =0; M_EvalNextParameter(p_stValue); lSlotId = M_ReturnParam_lValue(p_stValue); #ifdef U64 SAF_M_AssertWithMsg((lSlotId >= 1 && lSlotId <= C_ucNbSaveGameSlots),"Slot de sauvegarde inexistant") strcpy(g_szDummy, &g_stGameOptions.a_szSlotNames[lSlotId-1][4] ); g_szDummy[4] = '\0'; #else /* PC */ #ifdef ACTIVE_EDITOR Version = fn_iVersionN64_PC(); if ( Version == 1 /* U64 */) { SAF_M_AssertWithMsg((lSlotId >= 1 && lSlotId <= C_ucNbSaveGameSlots),"Slot de sauvegarde inexistant") strcpy(g_szDummy, &g_stGameOptions.a_szSlotNames[lSlotId-1][4] ); g_szDummy[4] = '\0'; } else if( Version == 2 /* PC */) { SAF_M_AssertWithMsg((lSlotId >= 1 && lSlotId <= (long) fn_lGetNbAvailableSlotsPc()),"Slot de sauvegarde inexistant") strcpy(g_szDummy, fn_cRecupSlotName(lSlotId)+3); } #else // Pc sans editeur SAF_M_AssertWithMsg((lSlotId >= 1 && lSlotId <= (long) fn_lGetNbAvailableSlotsPc()),"Slot de sauvegarde inexistant") strcpy(g_szDummy, fn_cRecupSlotName(lSlotId)+3); #endif // ACTIVE_EDITOR #endif // U64 M_Full_GetSetParam_String(p_stValue, g_szDummy/*g_stGameOptions.a_szSlotNames[lSlotId-1]*/); } return p_stTree; break; /*anti-bug GCC N64*/ case eFunc_GetSlotDate: { long lSlotId; char g_szDummyDate[12]; int Version = 0; M_EvalNextParameter(p_stValue); lSlotId = M_ReturnParam_lValue(p_stValue); #ifndef U64 #ifdef ACTIVE_EDITOR Version = fn_iVersionN64_PC(); if( Version == 2 /* PC */) // pas implementé pour N64 { SAF_M_AssertWithMsg((lSlotId >= 1 && lSlotId <= (long) fn_lGetNbAvailableSlotsPc()),"Slot de sauvegarde inexistant") strncpy(g_szDummyDate, fn_bGetStringSlotDate( fn_bRecupSlotNum( lSlotId) ), 10); g_szDummyDate[10] = '\0'; M_Full_GetSetParam_String(p_stValue, g_szDummyDate); } #else // Pc sans editeur SAF_M_AssertWithMsg((lSlotId >= 1 && lSlotId <= (long) fn_lGetNbAvailableSlotsPc()),"Slot de sauvegarde inexistant") strncpy(g_szDummyDate, fn_bGetStringSlotDate( fn_bRecupSlotNum( lSlotId) ), 10); g_szDummyDate[10] = '\0'; M_Full_GetSetParam_String(p_stValue, g_szDummyDate); #endif // ACTIVE_EDITOR #endif // !U64 } return p_stTree; break; // anti-bug GCC N64 case eFunc_GetStringCharAt: { register short wCpt = 0; short wIndexInString = 0; char *pszString = NULL; /*get the string*/ M_EvalNextParameter(p_stValue); pszString = (char *)fn_szGetStringFromTextOrStringParam(p_stValue); /*get the index in the string*/ M_EvalNextParameter(p_stValue); wIndexInString = M_GetSetParam_lValue(p_stValue); /* Search the beginning of the string*/ while( pszString[wCpt++] == '/') { while( pszString[wCpt++] != ':' ); } wIndexInString += wCpt-1; /*return the ASCII code of the letter found there, or 0 if the index is oustide the string*/ if ( (wIndexInString>= 0) && (wIndexInString < (short) strlen(pszString)) ) { M_Full_GetSetParam_Integer(p_stValue, pszString[wIndexInString]); } else { M_Full_GetSetParam_Integer(p_stValue, 0); } } return p_stTree; break; /*anti-bug GCC N64*/ default: #if defined(__DEBUG_AI__) || (defined(U64) && defined(D_CHECK_AI_FPCO)) M_AIFatalError(E_uwAIFatalNotValidFunction); #endif return p_stTree; break; /*anti-bug GCC N64*/ } } /****************************************************************** * Function: GetCollidePoint * * Use : v := LitPointCollision () * * Use : v := LitTauxDePenetrationCollision () * * Author : Y Le Tensorer * * Date of last modification: 27/11/97 * ******************************************************************/ GMT_tdxMask fn_xMaskOfObstacle(DNM_tdstObstacle *_p_stObstacle) { if ( _p_stObstacle ) { GMT_tdxHandleToGameMaterial hGameMaterial = DNM_M_hObstacleGetCollidedMaterial(_p_stObstacle); if ( GMT_fn_b_ulIsValid(hGameMaterial) ) { GMT_tdxHandleToCollideMaterial hMaterialCollide = GMT_fn_hGetCollideMaterial(hGameMaterial); if (hMaterialCollide && ( hMaterialCollide != GMT_C_InvalidCollideMaterial )) return GMT_fn_hGetCollideMaterialIdentifier(hMaterialCollide); } } return (GMT_tdxMask) 0; } tdstNodeInterpret *fn_p_stGetCollidePoint(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1); DNM_tdstReport *p_stDynamReport = NULL; DNM_tdstObstacle *p_stObstacle = NULL; GMT_tdxMask xMask = (GMT_tdxMask) 0; /********************************************************************************/ /* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */ /********************************************************************************/ HIE_tdxHandleToSuperObject hNewSuperObjPerso; fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hNewSuperObjPerso); /********************************************************************************/ SAF_M_AssertWithMsg(DNM_M_bDynamicsIsCollisionReport(fn_p_stDynamGetDynamics(M_GetMSHandle(hNewSuperObjPerso,Dynam))), "la mécanique a besoin du rapport de collisions pour cet appel"); p_stDynamReport = fn_pstGetDNMReport(hNewSuperObjPerso); switch ( eFuncId ) { case eFunc_GetCollideMaterialType: { unsigned long ulSurfState = DNM_M_ulReportGetSurfaceState(p_stDynamReport); if ( (ulSurfState & C_WOT_ulMobile) == C_WOT_ulMobile ) { p_stObstacle = DNM_M_p_stReportGetCharacter(p_stDynamReport); xMask |= fn_xMaskOfObstacle(p_stObstacle); } if ( (ulSurfState & C_WOT_ulGround) == C_WOT_ulGround ) { p_stObstacle = DNM_M_p_stReportGetGround(p_stDynamReport); xMask |= fn_xMaskOfObstacle(p_stObstacle); } if ( (ulSurfState & C_WOT_ulWall) == C_WOT_ulWall ) { p_stObstacle = DNM_M_p_stReportGetWall(p_stDynamReport); xMask |= fn_xMaskOfObstacle(p_stObstacle); } if ( (ulSurfState & C_WOT_ulWater) == C_WOT_ulWater ) { p_stObstacle = DNM_M_p_stReportGetWater(p_stDynamReport); xMask |= fn_xMaskOfObstacle(p_stObstacle); } if ( (ulSurfState & C_WOT_ulCeiling) == C_WOT_ulCeiling ) { p_stObstacle = DNM_M_p_stReportGetCeil(p_stDynamReport); xMask |= fn_xMaskOfObstacle(p_stObstacle); } if ( ulSurfState == C_WOT_ulNoObstacle ) { p_stObstacle = DNM_M_p_stReportGetObstacle(p_stDynamReport); xMask |= fn_xMaskOfObstacle(p_stObstacle); } } M_Full_GetSetParam_Mask(p_stValue, xMask); return p_stTree; break; case eFunc_GetCollideMaterialType2: { long lWhichObstacle; M_EvalNextParameter(p_stValue); lWhichObstacle = M_GetSetParam_lValue(p_stValue); switch ( lWhichObstacle ) { default: SAF_M_AssertWithMsg(FALSE, "l'obstacle spécifié n'est pas valide"); M_Full_GetSetParam_Mask(p_stValue, (GMT_tdxMask) 0); return p_stTree; break; case 0: /*get the last obstacle (equivalent to original version of the function)*/ p_stObstacle = DNM_M_p_stReportGetObstacle(p_stDynamReport); break; case 1: /*get the last ground*/ p_stObstacle = DNM_M_p_stReportGetGround(p_stDynamReport); break; case 2: /*get the last wall*/ p_stObstacle = DNM_M_p_stReportGetWall(p_stDynamReport); break; case 3: /*get the last character*/ p_stObstacle = DNM_M_p_stReportGetCharacter(p_stDynamReport); break; case 4: /*get the last uncollidable/water plane*/ p_stObstacle = DNM_M_p_stReportGetWater(p_stDynamReport); break; case 5: /* get the last ceiling*/ p_stObstacle = DNM_M_p_stReportGetCeil(p_stDynamReport); break; } M_Full_GetSetParam_Mask(p_stValue, fn_xMaskOfObstacle(p_stObstacle)); } return p_stTree; break; case eFunc_GetCollidePoint2: { MTH3D_tdstVector stNullVector = { MTH_C_ZERO, MTH_C_ZERO, MTH_C_ZERO }; long lWhichObstacle; M_EvalNextParameter(p_stValue); lWhichObstacle = M_GetSetParam_lValue(p_stValue); switch ( lWhichObstacle ) { default: SAF_M_AssertWithMsg(FALSE, "l'obstacle spécifié n'est pas valide"); M_Full_GetSetParam_p_stVertex(p_stValue, &stNullVector); return p_stTree; break; case 0: /*get the last obstacle (equivalent to original version of the function)*/ p_stObstacle = DNM_M_p_stReportGetObstacle(p_stDynamReport); break; case 1: /*get the last ground*/ p_stObstacle = DNM_M_p_stReportGetGround(p_stDynamReport); break; case 2: /*get the last wall*/ p_stObstacle = DNM_M_p_stReportGetWall(p_stDynamReport); break; case 3: /*get the last character*/ p_stObstacle = DNM_M_p_stReportGetCharacter(p_stDynamReport); break; case 4: /*get the last uncollidable/water plane*/ p_stObstacle = DNM_M_p_stReportGetWater(p_stDynamReport); break; case 5: /* get the last ceiling*/ p_stObstacle = DNM_M_p_stReportGetCeil(p_stDynamReport); break; } M_Full_GetSetParam_p_stVertex(p_stValue, DNM_M_p_stObstacleGetContact(p_stObstacle)); } return p_stTree; break; case eFunc_GetHandsCollidePoint: { MTH3D_tdstVector *p_stCollidePoint = &M_GetSetParam_stVertexValue(p_stValue); DNM_tdstObstacle *p_stObstacle = DNM_M_p_stReportGetGround(p_stDynamReport); M_GetSetParam_Type(p_stValue) = E_vt_Vector; /* if it has the hang CMT bit, it was necessarily touched by a ZDM with the hands CMT bit */ if ( GMT_fn_xTestCollideIdentifierTypeOfGameMaterial(DNM_M_hObstacleGetCollidedMaterial(p_stObstacle),0x0002) ) { *p_stCollidePoint = *DNM_M_p_stObstacleGetContact(p_stObstacle); } else /* else it was touched by a normal ZDM, hence not by hands*/ { MTH3D_M_vNullVector(p_stCollidePoint); } } return (p_stTree); break; case eFunc_GetCollidePoint: { DNM_tdstObstacle *p_stObstacle = DNM_M_p_stReportGetObstacle(p_stDynamReport); M_Full_GetSetParam_p_stVertex(p_stValue, DNM_M_p_stObstacleGetContact(p_stObstacle)); } return (p_stTree); break; #if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/ case eFunc_GetCollideRate2: { long lWhichObstacle; M_EvalNextParameter(p_stValue); lWhichObstacle = M_GetSetParam_lValue(p_stValue); switch ( lWhichObstacle ) { default: SAF_M_AssertWithMsg(FALSE, "l'obstacle spécifié n'est pas valide"); M_Full_GetSetParam_Float(p_stValue, MTH_C_ZERO); return p_stTree; break; case 0: /*get the last obstacle (equivalent to original version of the function)*/ p_stObstacle = DNM_M_p_stReportGetObstacle(p_stDynamReport); break; case 1: /*get the last ground*/ p_stObstacle = DNM_M_p_stReportGetGround(p_stDynamReport); break; case 2: /*get the last wall*/ p_stObstacle = DNM_M_p_stReportGetWall(p_stDynamReport); break; case 3: /*get the last character*/ p_stObstacle = DNM_M_p_stReportGetCharacter(p_stDynamReport); break; case 4: /*get the last uncollidable/water plane*/ p_stObstacle = DNM_M_p_stReportGetWater(p_stDynamReport); break; case 5: /* get the last ceiling*/ p_stObstacle = DNM_M_p_stReportGetCeil(p_stDynamReport); break; } M_Full_GetSetParam_Float(p_stValue,DNM_M_xObstacleGetRate(p_stObstacle)); } return p_stTree; break; case eFunc_GetCollideRate: { DNM_tdstObstacle *p_stObstacle = DNM_M_p_stReportGetObstacle(p_stDynamReport); M_Full_GetSetParam_Float(p_stValue, MTH_C_ONE); M_Full_GetSetParam_Float(p_stValue,DNM_M_xObstacleGetRate(p_stObstacle)); } return (p_stTree); break; #endif /* _AI_EXCLUDE_NEVER_USED_ }*/ default: break; } M_AIFatalError(E_uwAIFatalNotValidFunction); return(p_stTree); } /****************************************************************** * Function: GetLastCollisionActor * * Use : Actor := GetLastCollisionActor(character) * * Author : Carlos Torres * * Date of last modification: 18/02/98 del chack always * ******************************************************************/ tdstNodeInterpret *fn_p_stGetLastCollisionActor(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1); HIE_tdxHandleToSuperObject p_SuperObjPersoTreated = NULL; HIE_tdxHandleToSuperObject p_SuperObjCollidedActor = NULL; tdstGetSetParam stParam ; /* Structure d'échange*/ if (eFuncId==eFunc_GetLastCollisionActor) { /* get the perso for which we search the last collided actor*/ M_EvalNextParameter(&stParam); p_SuperObjPersoTreated=M_GetSetParam_p_stSupObjValue(&stParam); SAF_M_AssertWithMsg(p_SuperObjPersoTreated, "l'acteur spécifié est nul"); /* get the last collided actor*/ p_SuperObjCollidedActor = fn_hSuperObjectGetLastCollidedCharacter(p_SuperObjPersoTreated); /* return last collided actor*/ M_Full_GetSetParam_Perso(p_stValue,p_SuperObjCollidedActor); return (p_stTree); } M_AIFatalError(E_uwAIFatalNotValidFunction); return(p_stTree); } /****************************************************************** * Function: GetCollide * * Use : p := PointCollision ( point, vector, mode ) * * v := VecteurNormalCollision ( point, vecteur, mode) * * h := PointCollision ( point, vector ) * * * Return point and normal vector of collide between ray * * ( point, vector ) and : * * - static hierarchy if mode=0 * * - dynamic hierarchy if mode=1 * * - dynamic+static if mode=2 * * This function is optimized to call collision function one time * * per tram. * * * * Author : J Thenoz * * Date of last modification: 13/03/98 (YLG) * ******************************************************************/ tdstNodeInterpret *fn_p_stGetCollision(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1); MTH3D_tdstVector *p_stPoint; MTH3D_tdstVector *p_stVector,stVectorSave; unsigned long ulMode; BOOL bCompute = FALSE; /* read point */ M_EvalNextParameter(p_stValue); p_stPoint=&M_GetSetParam_stVectorValue(p_stValue); if (!MTH3D_M_bEqualVector (&g_stCollideParameterPoint,p_stPoint)) { MTH3D_M_vCopyVector (&g_stCollideParameterPoint,p_stPoint); bCompute = TRUE; } /* read vector */ M_EvalNextParameter(p_stValue); p_stVector=&M_GetSetParam_stVectorValue(p_stValue); if (!MTH3D_M_bEqualVector (&g_stCollideParameterVector,p_stVector)) { MTH3D_M_vCopyVector (&g_stCollideParameterVector,p_stVector); bCompute = TRUE; } /* read mode */ M_EvalNextParameter(p_stValue); ulMode=M_GetSetParam_ulValue (p_stValue); /* store data must be updated ?*/ if (bCompute || g_ulCollideTimeCounter != g_stEngineStructure.stEngineTimer.ulCurrentTimerCount || g_ulMode != ulMode ) { MTH3D_M_vCopyVector (&stVectorSave,&g_stCollideParameterVector); g_ulCollideTimeCounter = g_stEngineStructure.stEngineTimer.ulCurrentTimerCount; g_hSuperObjectHit = NULL; g_ulMode = ulMode; g_xMask = 0; fn_vComputeCollideResult (p_SuperObjPerso); MTH3D_M_vCopyVector (&g_stCollideParameterVector,&stVectorSave); } switch (eFuncId) { case eFunc_GetCollisionPoint: M_Full_GetSetParam_p_stVertex(p_stValue,&g_stCollideResultPoint); break; case eFunc_GetCollisionVector: M_Full_GetSetParam_p_stVertex(p_stValue,&g_stCollideResultVector); SAF_M_AssertWithMsg( MTH3D_M_bIsNullVector(&g_stCollideResultVector) || MTH_M_bEqualWithEpsilon(MTH3D_M_xNormVector(&g_stCollideResultVector), MTH_C_ONE, MTH_M_xFloatToReal(0.01f)), "erreur interne du moteur: la normale calculée n'est pas normée!" ); break; //#if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/ case eFunc_GetCollisionPerso: M_Full_GetSetParam_Perso(p_stValue,g_hSuperObjectHit); break; //#endif /* _AI_EXCLUDE_NEVER_USED_ }*/ default: break; } /*restore the default value (no raytrace flag is taken into account)*/ g_ulOverRideRayTraceSpoMask = HIE_C_Flag_ulNotHitByRayTrace; return(p_stTree); } /****************************************************************** * Function: GetCollideWithCollideMaterial * * Use : p := PointCollisionAvecMateriau( point, vector, mode)* * * * Return point and normal vector of collide between ray * * ( point, vector ) and : * * - static hierarchy if mode=0 * * - dynamic hierarchy if mode=1 * * - dynamic+static if mode=2 * * This function is optimized to call collision function one time * * per tram. * * * * Author : J Thenoz * * Date of last modification: 13/03/98 (YLG) * ******************************************************************/ tdstNodeInterpret *fn_p_stGetCollisionWithCollideMaterial(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { MTH3D_tdstVector *p_stPoint; MTH3D_tdstVector *p_stVector,stVectorSave; unsigned long ulMode; unsigned long xTestedMask; BOOL bCompute = FALSE; /* read point */ M_EvalNextParameter(p_stValue); p_stPoint=&M_GetSetParam_stVectorValue(p_stValue); if (!MTH3D_M_bEqualVector (&g_stCollideParameterPoint,p_stPoint)) { MTH3D_M_vCopyVector (&g_stCollideParameterPoint,p_stPoint); bCompute = TRUE; } /* read vector */ M_EvalNextParameter(p_stValue); p_stVector=&M_GetSetParam_stVectorValue(p_stValue); if (!MTH3D_M_bEqualVector (&g_stCollideParameterVector,p_stVector)) { MTH3D_M_vCopyVector (&g_stCollideParameterVector,p_stVector); bCompute = TRUE; } /* read mode */ M_EvalNextParameter(p_stValue); ulMode=M_GetSetParam_ulValue (p_stValue); /*read the tested CMT*/ M_EvalNextParameter(p_stValue); xTestedMask = (unsigned long) M_GetSetParam_xMaskValue(p_stValue); /* store data must be updated ?*/ if (bCompute || g_ulCollideTimeCounter != g_stEngineStructure.stEngineTimer.ulCurrentTimerCount || g_ulMode != ulMode ) { MTH3D_M_vCopyVector (&stVectorSave,&g_stCollideParameterVector); g_xMask = xTestedMask; g_ulCollideTimeCounter = g_stEngineStructure.stEngineTimer.ulCurrentTimerCount; g_hSuperObjectHit = NULL; g_ulMode = ulMode; fn_vComputeCollideResult (p_SuperObjPerso); MTH3D_M_vCopyVector (&g_stCollideParameterVector,&stVectorSave); g_xMask = 0; } /*restore the default value (no raytrace flag is taken into account)*/ g_ulOverRideRayTraceSpoMask = HIE_C_Flag_ulNotHitByRayTrace; M_Full_GetSetParam_p_stVertex(p_stValue,&g_stCollideResultPoint); return(p_stTree); } /****************************************************************** * Function: ComputeRebondVector * * Use : Rv := ComputeRebondVector(V,N,absorption) * * Rv <- absorbtion*(-2*(V.N)*N + V) * * Author : Carlos Torres * * Date of last modification: 04/12/97 * ******************************************************************/ tdstNodeInterpret *fn_p_stComputeRebondVector(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { #if defined(__DEBUG_AI__) || (defined(U64) && defined(D_CHECK_AI_FPCO)) enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1); if ( eFuncId == eFunc_ComputeRebondVector ) { #endif /* __DEBUG_AI__ */ MTH3D_tdstVector stNormalVector; /* normal to collided surface*/ MTH3D_tdstVector stInitVector; /* Vector before rebond*/ MTH_tdxReal xCoefAbsorption; /* coef absorption of the face*/ MTH_tdxReal xReactionNorm; /* Norm of the normal reaction vector*/ MTH3D_tdstVector stReactionVector; /* Reaction Vector*/ /* get the intial vector*/ M_EvalNextParameter(p_stValue); stInitVector = M_GetSetParam_stVectorValue(p_stValue); /* get the face normal vector*/ M_EvalNextParameter(p_stValue); stNormalVector = M_GetSetParam_stVectorValue(p_stValue); SAF_M_AssertWithMsg(MTH_M_bEqualWithEpsilon(MTH3D_M_xNormVector(&stNormalVector), MTH_C_ONE, MTH_M_xFloatToReal(0.01f)), "la normale n'est pas normée!"); /* get the alpha value*/ M_EvalNextParameter(p_stValue); xCoefAbsorption = M_ReturnParam_xValue(p_stValue); /* -2*(V.N)*/ xReactionNorm = MTH_M_xMul(MTH_M_xFloatToReal(-2.0f),MTH3D_M_xDotProductVector(&stInitVector,&stNormalVector)); /* -2*(V.N)*N*/ MTH3D_M_vMulScalarVector(&stReactionVector,xReactionNorm,&stNormalVector); /* -2*(V.N)*N + V*/ MTH3D_M_vAddVector(&stReactionVector,&stReactionVector,&stInitVector); /* absorbtion*(-2*(V.N)*N + V)*/ MTH3D_M_vMulScalarVector(&stReactionVector,xCoefAbsorption,&stReactionVector); /* return the Reaction vector*/ M_Full_GetSetParam_p_stVertex(p_stValue,&stReactionVector); return (p_stTree); #if defined(__DEBUG_AI__) || (defined(U64) && defined(D_CHECK_AI_FPCO)) } M_AIFatalError(E_uwAIFatalNotValidFunction); return(p_stTree); #endif /* __DEBUG_AI__ */ } /****************************************************************** * Function: VectorAndAngle * * Use : alpha := VecteurAngle(U,V,Plan) * * cos := VecteurCos(U,V) * * sin := VecteurSin(U,V,Plan) * * Plan xOy -> 0 * * Plan yOz -> 1 * * Plan zOx -> 2 * * Author : Carlos Torres , * * Date of last modification: 08/12/97 * * optimized by Yann le Tensorer sept 16,1998 * * re-optimized by Benoit Germain Jan 29,1999 * ******************************************************************/ tdstNodeInterpret *fn_p_stVectorAndAngle(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1); unsigned char ucPlan; /* projection plan to eval angle sign*/ ACP_tdxBool bASourceVectorIsNull = FALSE; MTH3D_tdstVector stVectorU, stVectorV; /* First and second vectors*/ MTH3D_tdstVector stOrthVector; /* Orthogonal vector to U and V*/ MTH_tdxReal xSin,xCos,xAngle,xTmp; #define VectorNul(v) ( MTH_M_bIsNullWithEpsilon(MTH3D_M_xGetXofVector(&v), MTH_M_xDoubleToReal(1.0e-5)) && MTH_M_bIsNullWithEpsilon(MTH3D_M_xGetYofVector(&v), MTH_M_xDoubleToReal(1.0e-5)) && MTH_M_bIsNullWithEpsilon(MTH3D_M_xGetZofVector(&v), MTH_M_xDoubleToReal(1.0e-5)) ) /* get the first vector*/ M_EvalNextParameter(p_stValue); stVectorU = M_GetSetParam_stVectorValue(p_stValue); /* get the second vector*/ M_EvalNextParameter(p_stValue); stVectorV = M_GetSetParam_stVectorValue(p_stValue); /* we normalize the two vectors */ /* QuickNormalizeVector uses a table of 1/squareroots*/ if ( !VectorNul(stVectorU) ) { MTH3D_M_vQuickNormalizeVector(&stVectorU,&stVectorU); } else bASourceVectorIsNull = TRUE; if ( !VectorNul(stVectorV) ) { MTH3D_M_vQuickNormalizeVector(&stVectorV,&stVectorV); } else bASourceVectorIsNull = TRUE; switch (eFuncId) { case eFunc_VectorAngle : if ( bASourceVectorIsNull ) { /* skip the projection plane argument*/ p_stTree = fn_p_stSkipThisArgument(p_stTree); /* assume the angle is null!*/ xAngle = MTH_C_ZERO; } else { /* get the projection plan*/ M_EvalNextParameter(p_stValue); ucPlan = M_GetSetParam_ucValue(p_stValue); /*=========== we calculate the cos between the first vector and the second vector (the two vectors are normalized)*/ xCos = MTH3D_M_xDotProductVector(&stVectorU,&stVectorV); if ( MTH_M_bGreater(xCos,MTH_C_ONE) ) xCos = MTH_C_ONE; /* sometimes, the inprecision makes this happen...*/ else if ( MTH_M_bLess(xCos,MTH_C_MinusONE) ) xCos = MTH_C_MinusONE; /* Acos takes 250 cycles (on PII processor), we should perhaps make a table... (sept 21, 1998)*/ /* i tried with atan (faster than acos), but the whole is slower*/ xAngle = MTH_M_xACos(xCos); /* Eval sign with determinant in projection plan (no need of cross product)*/ switch ( ucPlan ) { case C_ucPlanxOy : { xTmp = MTH_M_xSub(MTH_M_xMul(stVectorU.xX,stVectorV.xY), MTH_M_xMul(stVectorU.xY,stVectorV.xX)); /* we calculate the determinant (in the z=0 plane)*/ if ( MTH_M_bLessZero(xTmp) ) xAngle = MTH_M_xNeg(xAngle); /* if determinant is negative, the angle is negative */ } break; case C_ucPlanyOz : { xTmp = MTH_M_xSub(MTH_M_xMul(stVectorU.xY,stVectorV.xZ), MTH_M_xMul(stVectorU.xZ,stVectorV.xY)) ; /* we calculate the determinant */ if ( MTH_M_bLessZero(xTmp) ) xAngle = MTH_M_xNeg(xAngle); /* if determinant is negative, the angle is negative */ } break; case C_ucPlanzOx : { xTmp = MTH_M_xSub(MTH_M_xMul(stVectorU.xZ,stVectorV.xX), MTH_M_xMul(stVectorU.xX,stVectorV.xZ)) ; /* we calculate the determinant */ if ( MTH_M_bLessZero(xTmp) ) xAngle = MTH_M_xNeg(xAngle); /* if determinant is negative, the angle is negative */ } } xAngle = MTH_M_xRadToDeg(xAngle); } M_Full_GetSetParam_Float(p_stValue, xAngle); break; case eFunc_VectorCos : if ( bASourceVectorIsNull ) { /* the answer is equivalent to a null angle!*/ xCos = MTH_C_ONE; } else { /*The cosinus is the result of the dot product*/ xCos = MTH3D_M_xDotProductVector(&stVectorU,&stVectorV); /* sometimes, the inprecision makes this happen...*/ if ( MTH_M_bGreater(xCos,MTH_C_ONE) ) xCos = MTH_C_ONE; else if ( MTH_M_bLess(xCos,MTH_C_MinusONE) ) xCos = MTH_C_MinusONE; } M_Full_GetSetParam_Float(p_stValue,xCos); break; #if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT 08/06/99 { */ case eFunc_VectorSin : if ( bASourceVectorIsNull ) { /* skip the projection plane argument*/ p_stTree = fn_p_stSkipThisArgument(p_stTree); /* the answer is equivalent to a null angle!*/ xSin = MTH_C_ZERO; } else { /* get the projection plan*/ M_EvalNextParameter(p_stValue); ucPlan = M_GetSetParam_ucValue(p_stValue); /*the sinus is the norm of the cross product*/ MTH3D_M_vCrossProductVectorWithoutBuffer(&stOrthVector,&stVectorU,&stVectorV); xSin = MTH3D_M_xQuickNormVector(&stOrthVector); /* Eval sign with projection plan*/ switch (ucPlan) { case C_ucPlanxOy : if ( MTH_M_bLessZero(MTH3D_M_xGetZofVector(&stOrthVector)) ) xSin = MTH_M_xNeg(xSin); break; case C_ucPlanyOz : if ( MTH_M_bLessZero(MTH3D_M_xGetXofVector(&stOrthVector)) ) xSin = MTH_M_xNeg(xSin); break; case C_ucPlanzOx : if ( MTH_M_bLessZero(MTH3D_M_xGetYofVector(&stOrthVector)) ) xSin = MTH_M_xNeg(xSin); default : break; } /* sometimes, the inprecision makes this happen...*/ if ( MTH_M_bGreater(xSin,MTH_C_ONE) ) xSin = MTH_C_ONE; else if ( MTH_M_bLess(xSin,MTH_C_MinusONE) ) xSin = MTH_C_MinusONE; } M_Full_GetSetParam_Float(p_stValue,xSin); #endif /* _AI_EXCLUDE_NEVER_USED_ } */ default : break; } return p_stTree; #undef VectorNul } /****************************************************************** * Function: GetMechanicParameter * * Use : value := LitTruc () * * Author : Jacques Thénoz * * Date of last modification: 16/12/97 * ******************************************************************/ tdstNodeInterpret *fn_p_GetMechanicParameter(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { struct DNM_stDynamics* pstDynamic; MS_tdxHandleToDynam h_Dynam; HIE_tdxHandleToSuperObject hNewSuperObjPerso; enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1); MTH_tdxReal xNulValue = MTH_C_ZERO; /********************************************************************************/ /* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */ /********************************************************************************/ fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hNewSuperObjPerso); /********************************************************************************/ /* Get Dynamics structure*/ h_Dynam = M_GetMSHandle(hNewSuperObjPerso,Dynam); if (!h_Dynam) { #if (defined(ACTIVE_EXEC_CHECKING) && defined(ACTIVE_EDITOR)) || defined(ACTIVE_AIDEBUG) #if !defined(U64_AIDEBUG) /* Oliv' - 23/11/1998*/ Erm_M_UpdateLastError(AI, C_ucErmDefaultChannel, E_uwAIWarningScriptError , C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucNeverStopForDebug, "You must allocate Dynamics."); Erm_fn_iMessageBox ("You must allocate Dynamics.","STOP",MB_OK|MB_ICONERROR); Erm_M_ClearLastError(C_ucErmDefaultChannel); fn_vSetStopAIEngineFlag(); #endif /* !defined(U64_AIDEBUG) */ #endif /* (defined(ACTIVE_EXEC_CHECKING) && defined(ACTIVE_EDITOR)) || defined(ACTIVE_AIDEBUG) */ M_Full_GetSetParam_Float ( p_stValue, xNulValue ); return (p_stTree); } pstDynamic = fn_p_stDynamGetDynamics(h_Dynam); switch (eFuncId) { case eFunc_GetMechanicGravityFactor : { MTH_tdxReal xGravity = DNM_M_xDynamicsGetGravityFactor (pstDynamic); M_Full_GetSetParam_Float ( p_stValue, xGravity ); } return (p_stTree); break; #if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/ case eFunc_GetMechanicSlide : { MTH_tdxReal xSlide = DNM_M_xDynamicsGetSlide (pstDynamic); M_Full_GetSetParam_Float ( p_stValue, xSlide ); } return (p_stTree); break; case eFunc_GetMechanicRebound : { MTH_tdxReal xRebound = DNM_M_xDynamicsGetRebound (pstDynamic); M_Full_GetSetParam_Float ( p_stValue, xRebound ); } return (p_stTree); break; case eFunc_GetMechanicSlopeLimit : { MTH_tdxReal xSlopeLimit = MTH_M_xTan (MTH_M_xDegToRad (DNM_M_xDynamicsGetSlopeLimit (pstDynamic))); M_Full_GetSetParam_Float ( p_stValue, xSlopeLimit ); } return (p_stTree); break; case eFunc_GetMechanicInertiaX : { MTH_tdxReal xInertiaX = DNM_M_xDynamicsGetInertiaFactorX (pstDynamic); M_Full_GetSetParam_Float ( p_stValue, xInertiaX ); } return (p_stTree); break; case eFunc_GetMechanicInertiaY : { MTH_tdxReal xInertiaY = DNM_M_xDynamicsGetInertiaFactorY (pstDynamic); M_Full_GetSetParam_Float ( p_stValue, xInertiaY ); } return (p_stTree); break; case eFunc_GetMechanicInertiaZ : { MTH_tdxReal xInertiaZ = DNM_M_xDynamicsGetInertiaFactorZ (pstDynamic); M_Full_GetSetParam_Float ( p_stValue, xInertiaZ ); } return (p_stTree); break; case eFunc_GetMechanicTiltIntensity : { MTH_tdxReal xTiltIntensity = DNM_M_xDynamicsGetTiltIntensity (pstDynamic); M_Full_GetSetParam_Float ( p_stValue, xTiltIntensity ); } return (p_stTree); break; case eFunc_GetMechanicTiltInertia : { MTH_tdxReal xTiltInertia = DNM_M_xDynamicsGetTiltInertia (pstDynamic); M_Full_GetSetParam_Float ( p_stValue, xTiltInertia ); } return (p_stTree); break; case eFunc_GetMechanicTiltOrigin : { MTH_tdxReal xTiltOrigin = DNM_M_xDynamicsGetTiltOrigin (pstDynamic); M_Full_GetSetParam_Float ( p_stValue, xTiltOrigin ); } return (p_stTree); break; case eFunc_GetMechanicMaxSpeed : { MTH3D_tdstVector stSpeedLimit; MTH3D_M_vCopyVector ( &stSpeedLimit, DNM_M_pDynamicsGetMaxSpeed (pstDynamic) ); M_Full_GetSetParam_p_stVertex (p_stValue,&stSpeedLimit); } return (p_stTree); break; case eFunc_GetMechanicStreamPriority : { MTH_tdxReal xStreamPriority = DNM_M_xDynamicsGetStreamPriority (pstDynamic); M_Full_GetSetParam_Float ( p_stValue, xStreamPriority ); } return (p_stTree); break; case eFunc_GetMechanicStreamSpeed : { MTH3D_tdstVector stStreamSpeed; MTH3D_M_vCopyVector ( &stStreamSpeed, DNM_M_pDynamicsGetStreamSpeed (pstDynamic) ); M_Full_GetSetParam_p_stVertex (p_stValue,&stStreamSpeed); } return (p_stTree); break; case eFunc_GetMechanicStreamFactor : { MTH_tdxReal xStreamFactor = DNM_M_xDynamicsGetStreamFactor (pstDynamic); M_Full_GetSetParam_Float ( p_stValue, xStreamFactor ); } return (p_stTree); break; case eFunc_GetSlideFactorX : { MTH_tdxReal xSlideFactorX = DNM_M_xDynamicsGetSlideFactorX (pstDynamic); M_Full_GetSetParam_Float ( p_stValue, xSlideFactorX ); } return (p_stTree); break; case eFunc_GetSlideFactorY : { MTH_tdxReal xSlideFactorY = DNM_M_xDynamicsGetSlideFactorY (pstDynamic); M_Full_GetSetParam_Float ( p_stValue, xSlideFactorY ); } return (p_stTree); break; case eFunc_GetSlideFactorZ : { MTH_tdxReal xSlideFactorZ = DNM_M_xDynamicsGetSlideFactorZ (pstDynamic); M_Full_GetSetParam_Float ( p_stValue, xSlideFactorZ ); } return (p_stTree); break; #endif /* _AI_EXCLUDE_NEVER_USED_ }*/ case eFunc_GetSpeedAnim : M_Full_GetSetParam_p_stVertex (p_stValue,DNM_M_p_stDynamicsGetSpeedAnim (pstDynamic)); return (p_stTree); break; default: break; } M_AIFatalError(E_uwAIFatalNotValidFunction); return(p_stTree); } /****************************************************************** * Function: GetHierarchyLink * * Author : Jacques Thénoz * * Date of last modification: 10/02/98 * ******************************************************************/ tdstNodeInterpret *fn_p_GetHierarchyLink(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { struct DNM_stDynamics* pstDynamic; MS_tdxHandleToDynam h_Dynam; HIE_tdxHandleToSuperObject hNewSuperObjPerso; HIE_tdxHandleToSuperObject hFather; enum tdeFuncId_ eFuncId=M_eFuncIdInterpret(p_stTree-1); /********************************************************************************/ /* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */ /********************************************************************************/ fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hNewSuperObjPerso); /********************************************************************************/ /* Get Dynamics structure*/ h_Dynam = M_GetMSHandle(hNewSuperObjPerso,Dynam); if (!h_Dynam) { #if (defined(ACTIVE_EXEC_CHECKING) && defined(ACTIVE_EDITOR)) || defined(ACTIVE_AIDEBUG) #if !defined(U64_AIDEBUG) /* Oliv' - 23/11/1998*/ Erm_M_UpdateLastError(AI, C_ucErmDefaultChannel, E_uwAIWarningScriptError , C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucNeverStopForDebug, "You must allocate Dynamics."); Erm_fn_iMessageBox ("You must allocate Dynamics.","STOP",MB_OK|MB_ICONERROR); Erm_M_ClearLastError(C_ucErmDefaultChannel); fn_vSetStopAIEngineFlag(); #endif /* !defined(U64_AIDEBUG) */ #endif return (p_stTree); } pstDynamic = fn_p_stDynamGetDynamics(h_Dynam); switch (eFuncId) { case eFunc_HierGetFather : /*hFather = p_SuperObjPerso;*/ hFather = hNewSuperObjPerso; do { hFather = HIE_fn_hGetSuperObjectFather (hFather); } while (HIE_fn_bIsSuperObjectValid (hFather) && HIE_fn_ulGetSuperObjectType(hFather)!=HIE_C_ulActor); M_Full_GetSetParam_Perso(p_stValue,hFather); return (p_stTree); break; default: break; } M_AIFatalError(E_uwAIFatalNotValidFunction); return(p_stTree); } /******************************************************************* * Function : ZON_LitActivationZDD * * Use : ZON_LitActivationZDD( ZDD ) * * Function : ZON_LitActivationZDM * * Use : ZON_LitActivationZDM( ZDM ) * * Function : ZON_LitActivationZDE * * Use : ZON_LitActivationZDE( ZDE ) * * Function : ZON_LitActivationZDR * * Use : ZON_LitActivationZDR( ZDR ) * * * * Author : Marc Trabucato * * Date of last modification: 12/03/98 * *******************************************************************/ #if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/ tdstNodeInterpret *fn_p_GetPriviligedActivationZdx(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { tdstGetSetParam stParam; /* exchange structure*/ HIE_tdxHandleToSuperObject hPerso; /* Handle of the character*/ long lZoneNumber; /* Number of the zone*/ tdeCollSetPrivilegedActivation ePrivilege; enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1); MS_tdxHandleToCollSet hCollSet; /********************************************************************************/ /* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */ /********************************************************************************/ fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hPerso); hCollSet = M_GetMSHandle(hPerso,CollSet); /* Get first parameter that is a ZDx*/ M_EvalNextParameter( &stParam ); lZoneNumber = (long) M_GetSetParam_lZDMIdValue( &stParam ); lZoneNumber--; switch( eFuncId ) { case eFunc_GetActivationZDD: ePrivilege = CS_fn_eGetPrivilegedActivationZone( C_ucTypeZdd, hCollSet, (unsigned short)lZoneNumber ); M_Full_GetSetParam_Integer(p_stValue, (unsigned short)ePrivilege); break; case eFunc_GetActivationZDM: ePrivilege = CS_fn_eGetPrivilegedActivationZone( C_ucTypeZdm, hCollSet, (unsigned short)lZoneNumber ); M_Full_GetSetParam_Integer(p_stValue, (unsigned short)ePrivilege); break; case eFunc_GetActivationZDE: ePrivilege = CS_fn_eGetPrivilegedActivationZone( C_ucTypeZde, hCollSet, (unsigned short)lZoneNumber ); M_Full_GetSetParam_Integer(p_stValue, (unsigned short)ePrivilege); break; case eFunc_GetActivationZDR: ePrivilege = CS_fn_eGetPrivilegedActivationZone( C_ucTypeZdr, hCollSet, (unsigned short)lZoneNumber ); M_Full_GetSetParam_Integer(p_stValue, (unsigned short)ePrivilege); break; default: /* Function does not existe*/ M_AIFatalError(E_uwAIFatalNotValidFunction); return(p_stTree); break; } return(p_stTree); } #endif /* _AI_EXCLUDE_NEVER_USED_ }*/ /******************************************************************** * Functions : ACT_LitFrequenceCalculCollisions * * : ACT_LitFrequenceCalculIA * * : ACT_LitFrequenceCalculLumières * * Use : ACT_LitFrequenceCalculCollisions() * * : ACT_LitFrequenceCalculIA() * * : ACT_LitFrequenceCalculLumières() * * * * Author : Marc Trabucato * * Date of last modification: 12/06/98 * ********************************************************************/ tdstNodeInterpret *fn_p_GetComputationFrequency(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { HIE_tdxHandleToSuperObject hPerso; /* Handle of the character*/ unsigned char ucFrequency; enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1); /********************************************************************************/ /* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */ /********************************************************************************/ fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hPerso); switch( eFuncId ) { case eFunc_GetBrainFrequency: ucFrequency = fn_uc3dDataGetBrainComputationFrequency( M_GetMSHandle(hPerso,3dData) ); M_GetSetParam_ucValue(p_stValue) = ucFrequency; M_GetSetParam_Type (p_stValue) = E_vt_0To255; break; #if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT {*/ case eFunc_GetCollisionFrequency: ucFrequency = fn_ucCollSetGetCollComputeFrequency( M_GetMSHandle(hPerso,CollSet) ); M_GetSetParam_ucValue(p_stValue) = ucFrequency; M_GetSetParam_Type (p_stValue) = E_vt_0To255; break; case eFunc_GetLightFrequency: #if defined(U64) ucFrequency = 1; #else ucFrequency = fn_uc3dDataGetLightComputationFrequency( M_GetMSHandle(hPerso,3dData) ); #endif M_GetSetParam_ucValue(p_stValue) = ucFrequency; M_GetSetParam_Type (p_stValue) = E_vt_0To255; break; #endif /* _AI_EXCLUDE_NEVER_USED_ }*/ default: /* Function does not existe*/ M_AIFatalError(E_uwAIFatalNotValidFunction); return(p_stTree); break; } return(p_stTree); } /*********************************************************************** * Function : MEC_ImpulsionSaut ( point A, point B, Zmax ) * * Use : Impulsion := MEC_ImpulsionSaut ( point A, point B, Zmax ) * * * * Author : Jacques Thénoz * * Date of last modification: 20/03/98 * ************************************************************************/ tdstNodeInterpret *fn_p_ComputeJumpImpulsion (HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { tdstGetSetParam stParam; HIE_tdxHandleToSuperObject hPerso; enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1); MTH3D_tdstVector stStartPosition; MTH3D_tdstVector stEndPosition; MTH3D_tdstVector stImpulsion; MTH3D_tdstVector stNullVector; MTH_tdxReal xDeltaZ; MTH_tdxReal xZmax; MTH_tdxReal xG; MTH_tdxReal xDelta; MTH_tdxReal xt; MTH_tdxReal xa, xb, xc; struct DNM_stDynamics *p_stDynamic; MS_tdxHandleToDynam h_Dynam; /********************************************************************************/ /* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */ /********************************************************************************/ fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hPerso); /* init the null vector*/ MTH3D_M_vNullVector(&stNullVector); /* parameters */ M_EvalNextParameter(&stParam); stStartPosition=M_GetSetParam_stVectorValue(&stParam); M_EvalNextParameter(&stParam); stEndPosition=M_GetSetParam_stVectorValue(&stParam); M_EvalNextParameter(&stParam); xDeltaZ = M_ReturnParam_xValue(&stParam); if (MTH_M_bLess ( xDeltaZ, MTH_C_ZERO )) { M_Full_GetSetParam_p_stVertex(p_stValue,&stNullVector); return(p_stTree); } /* xZMax */ xZmax = MTH_M_xAdd ( xDeltaZ, MTH3D_M_xGetZofVector(&stEndPosition) ); if (MTH_M_bLess(xZmax,MTH3D_M_xGetZofVector(&stStartPosition))) xZmax = MTH_M_xAdd ( xDeltaZ, MTH3D_M_xGetZofVector(&stStartPosition) ); /* return */ MTH3D_M_vNullVector (&stImpulsion); MTH3D_M_vNullVector (&stNullVector); M_Full_GetSetParam_p_stVertex(p_stValue,&stImpulsion); /* Get Dynamics structure */ h_Dynam = M_GetMSHandle(hPerso,Dynam); if (!h_Dynam) { #if (defined(ACTIVE_EXEC_CHECKING) && defined(ACTIVE_EDITOR)) || defined(ACTIVE_AIDEBUG) #if !defined(U64_AIDEBUG) /* Oliv' - 23/11/1998*/ Erm_M_UpdateLastError(AI, C_ucErmDefaultChannel, E_uwAIWarningScriptError , C_lErmNoDebugData, C_ucErmOpenInfoWindow, C_ucNeverStopForDebug, "You must allocate Dynamics."); Erm_fn_iMessageBox ("You must allocate Dynamics.","STOP",MB_OK|MB_ICONERROR); Erm_M_ClearLastError(C_ucErmDefaultChannel); fn_vSetStopAIEngineFlag(); #endif /* !defined(U64_AIDEBUG) */ #endif M_Full_GetSetParam_p_stVertex(p_stValue,&stNullVector); return(p_stTree); } p_stDynamic = fn_p_stDynamGetDynamics(h_Dynam); if (!p_stDynamic) { M_Full_GetSetParam_p_stVertex(p_stValue,&stNullVector); return (p_stTree); } xG = DNM_M_xDynamicsGetGravityFactor (p_stDynamic); if (MTH_M_bIsNull(xG)) { M_Full_GetSetParam_p_stVertex(p_stValue,&stNullVector); return (p_stTree); /* pour le moment*/ } /* impulsion.z */ MTH3D_M_vSetZofVector (&stImpulsion,MTH_M_xSqrt(MTH_M_xMul(MTH_M_xMul(MTH_M_xSub(xZmax,MTH3D_M_xGetZofVector(&stStartPosition)),MTH_C_2),xG))); /* find t */ xa = MTH_M_xMul (xG,MTH_C_MinusInv2); xb = MTH3D_M_xGetZofVector(&stImpulsion); xc = MTH_M_xSub ( MTH3D_M_xGetZofVector(&stStartPosition), MTH3D_M_xGetZofVector(&stEndPosition) ); xDelta = MTH_M_xTrinomeDelta( xa, xb, xc); if (MTH_M_bLess(xDelta,MTH_C_ZERO)) { M_Full_GetSetParam_p_stVertex(p_stValue,&stNullVector); return(p_stTree); } xt = MTH_M_xDiv ( MTH_M_xSub(MTH_M_xNeg(xb),MTH_M_xSqrt(xDelta)), MTH_M_xMul(MTH_C_2,xa) ); /* impulsion.x */ MTH3D_M_vSetXofVector ( &stImpulsion, MTH_M_xDiv(MTH_M_xSub(MTH3D_M_xGetXofVector(&stEndPosition),MTH3D_M_xGetXofVector(&stStartPosition)),xt) ); /* impulsion.y */ MTH3D_M_vSetYofVector ( &stImpulsion, MTH_M_xDiv(MTH_M_xSub(MTH3D_M_xGetYofVector(&stEndPosition),MTH3D_M_xGetYofVector(&stStartPosition)),xt) ); M_Full_GetSetParam_p_stVertex(p_stValue,&stImpulsion); return(p_stTree); } tdstNodeInterpret *fn_p_GetBooleanInArray(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1); AI_tdstMind * p_stMind; /* Mind of perso (used to return paramaters to dsgVars)*/ unsigned char ucArrayId; unsigned long ulFirstIndex; unsigned long ulIndexFirstLong; unsigned long ulIndexFirstBit; #ifdef _DEBUG /* {*/ tdeDsgVarTypeId eDsgVarType; tdstArray *p_stArray; unsigned long ulMyVarSize; #endif /* }*/ /* get array index*/ M_vEvalNextVarId(p_stMind, ucArrayId); #ifdef _DEBUG /* {*/ /* ucArrayId is an array*/ eDsgVarType = M_GetDsgVarType(p_stMind,ucArrayId); SAF_M_AssertWithMsg((fn_GetDsgVarType(eDsgVarType)==E_vt_Array), "La variable designer n'est pas un tableau") /* verify array size*/ p_stArray = (tdstArray*)M_GetDsgVarAddr(p_stMind,ucArrayId); ulMyVarSize = M_ARRAY_SIZE(p_stArray); #endif /* }*/ /* get index (or min index)*/ M_EvalNextParameter(p_stValue); ulFirstIndex = M_GetSetParam_lValue(p_stValue); SAF_M_AssertWithMsg(ulFirstIndex, "L'index doit être > 0") ulFirstIndex--; ulIndexFirstLong = (ulFirstIndex >> 5); ulIndexFirstBit = (ulFirstIndex & 31); #ifdef _DEBUG /* {*/ SAF_M_AssertWithMsg((ulMyVarSize>ulIndexFirstLong), "Le tableau n'est pas assez grand") #endif /* }*/ /* default*/ M_Full_GetSetParam_Integer(p_stValue , 0); switch(eFuncId) { case eFunc_GetBooleanInArray: { if (fn_ucGetDsgVar(ucArrayId , (unsigned char) ulIndexFirstLong , p_stMind , p_stValue) == C_VALID_GET) { unsigned long ulValue = M_GetSetParam_lValue(p_stValue); M_Full_GetSetParam_Integer(p_stValue , (ulValue & (1 << ulIndexFirstBit)) ? TRUE : FALSE); } break; } case eFunc_GetNumberOfBooleanInArray: { unsigned long ulLastIndex; unsigned long ulIndexLastLong; unsigned long ulIndexLastBit; unsigned long ulNumberOfBits; unsigned long ulIndexLong; /* get max index*/ M_EvalNextParameter(p_stValue); ulLastIndex = M_GetSetParam_lValue(p_stValue); SAF_M_AssertWithMsg((ulLastIndex >= ulFirstIndex), "Le second index doit être > au premier") ulLastIndex--; ulIndexLastLong = (ulLastIndex >> 5); ulIndexLastBit = (ulLastIndex & 31); #ifdef _DEBUG /* {*/ SAF_M_AssertWithMsg((ulMyVarSize>ulIndexLastLong), "Le tableau n'est pas assez grand") #endif /* }*/ /**/ ulNumberOfBits = 0; for (ulIndexLong = ulIndexFirstLong ; ulIndexLong <= ulIndexLastLong ; ulIndexLong++) { if (fn_ucGetDsgVar(ucArrayId , (unsigned char) ulIndexLong , p_stMind , p_stValue) == C_VALID_GET) { unsigned long ulValue = M_GetSetParam_lValue(p_stValue); unsigned long ulFirstBit = (ulIndexLong == ulIndexFirstLong ? ulIndexFirstBit : 0); unsigned long ulLastBit = (ulIndexLong == ulIndexLastLong ? ulIndexLastBit : 31); unsigned long ulIndexBit; for (ulIndexBit = ulFirstBit ; ulIndexBit <= ulLastBit ; ulIndexBit++) { if (ulValue & (1<4*1024*1024 ? 2 : 1)); /*AR9811*/ #endif return(p_stTree); } /*********************************************************************** * Functions : VID_GetCurrentResolution() * return entier ************************************************************************/ #ifdef U64 extern char g_bMustSwitchResolution; #endif tdstNodeInterpret *fn_p_stGetCurrentResolution(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { /* LOL*/ #ifndef U64 M_Full_GetSetParam_Integer (p_stValue, (long)GLI_fn_lGetCurrentDisplayMode() ); #else if (g_bMustSwitchResolution==0) { M_Full_GetSetParam_Integer (p_stValue, (SCREEN_WD==MIN_SCREEN_WD ? 0 : 1)); } else { M_Full_GetSetParam_Integer (p_stValue, (g_bMustSwitchResolution-1)); } #endif return(p_stTree); } /*********************************************************************** * Functions : VID_GetResolutionName(Long) * return entier ************************************************************************/ #if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT 08/06/99 { */ tdstNodeInterpret *fn_p_stGetNameResolution(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { long lValue; static char szName[60]; M_EvalNextParameter(p_stValue); lValue = M_GetSetParam_lValue(p_stValue); /* LOL*/ #ifndef U64 GLI_fn_lGetDisplayModeDescription( lValue, szName ); #else if(lValue==0) strcpy( szName,"LOW" ); else strcpy( szName,"HIGH" ); #endif /* if (lValue == 0) strcpy(szName,"800x600"); else if (lValue == 1) strcpy(szName,"640x480"); */ M_Full_GetSetParam_String(p_stValue,szName); return(p_stTree); } #endif /* _AI_EXCLUDE_NEVER_USED_ } */ /*********************************************************************** * Functions : VID_GetBrightness() * return entier ************************************************************************/ tdstNodeInterpret *fn_p_stGetBrightness(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { /* A REMPLIR*/ #ifndef U64 M_Full_GetSetParam_Integer (p_stValue, GLI_fn_lGetBrightness()); #else /* U64 */ M_Full_GetSetParam_Integer (p_stValue, 1); #endif /* U64 */ return(p_stTree); } #ifdef U64 extern long fn_lGetNbAvailableSlots(); #endif /*********************************************************************** * Functions : OPTION_GetNbSlotsAvailable Parametre: taille d'une sauvegarde * return nombre de slots possible ************************************************************************/ tdstNodeInterpret *fn_p_stGetNbSlotsAvailable(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { long lValue; M_EvalNextParameter(p_stValue); lValue = M_GetSetParam_lValue(p_stValue); #ifdef U64 M_Full_GetSetParam_Integer (p_stValue, (long)fn_lGetNbAvailableSlots()); // Fonction Version 64 #else M_Full_GetSetParam_Integer (p_stValue, (long)fn_lGetNbAvailableSlotsPc() ); // Fonction Diff pour PC (dans GamOpt.c) #endif // U64 return(p_stTree); } /*********************************************************************** * Functions : VID_GetTextureFiltering VID_GetAntiAliasing * return: 0: OFF 1: ON ************************************************************************/ #if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT 08/06/99 { */ tdstNodeInterpret *fn_p_stGetVideoOptions(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1); #ifndef U64 M_Full_GetSetParam_Integer (p_stValue, (long)1); #else /* PARTIE A REMPLIR PAR L EQUIPE U64*/ switch (eFuncId) { case eFunc_GetTextureFiltering: break; case eFunc_GetAntiAliasing: break; /* XB 05/05/99 */ default: break; /* End XB */ } #endif return(p_stTree); } #endif /* _AI_EXCLUDE_NEVER_USED_ } */ /*********************************************************************** * Functions : ACT_GetSaturationDistance ACT_GetBackGroundDistance * return: ************************************************************************/ #if !defined(_AI_EXCLUDE_NEVER_USED_) /* MT 08/06/99 { */ tdstNodeInterpret *fn_p_stGetMSSoundValues(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { HIE_tdxHandleToSuperObject hPerso; /* Handle of the character*/ enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1); MS_tdxHandleToMSSound hMSSound; unsigned long ulValue = 0; SndReal xSndValue; /********************************************************************************/ /* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */ /********************************************************************************/ fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hPerso); hMSSound = M_GetMSHandle(hPerso,MSSound); if(hMSSound) { switch (eFuncId) { case eFunc_GetSaturationDistance: xSndValue = fn_xMSSoundGetSaturationDistance(hMSSound); ulValue = M_RealToIntSnd(xSndValue); break; case eFunc_GetBackgroundDistance: xSndValue = fn_xMSSoundGetBackGroundDistance(hMSSound); ulValue = M_RealToIntSnd(xSndValue); break; default: M_AIFatalError(E_uwAIFatalNotValidFunction); break; } } else { SAF_M_AssertWithMsg((hMSSound!=NULL), "La MSSound de l'acteur n'est pas allouée") } M_Full_GetSetParam_Integer(p_stValue,ulValue); return(p_stTree); } #endif /* _AI_EXCLUDE_NEVER_USED_ } */ /*********************************************************************** * Functions : ACT_LitLimiteEloignement ACT_LitZoneMinTransparence ACT_LitZoneMaxTransparence * return: ************************************************************************/ tdstNodeInterpret *fn_p_stGetStdGameLimit(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { HIE_tdxHandleToSuperObject hPerso; /* Handle of the character*/ enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1); MS_tdxHandleToStandardGame hStdGame; unsigned long ulValue = 0; /********************************************************************************/ /* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */ /********************************************************************************/ fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hPerso); hStdGame = M_GetMSHandle(hPerso,StandardGame); if(hStdGame) { switch (eFuncId) { case eFunc_GetTooFarLimit: ulValue = fn_ucStandardGameGetTooFarLimit(hStdGame); break; case eFunc_GetTransparencyZoneMin: ulValue = fn_ucStandardGameGetTransparencyZoneMin(hStdGame); break; case eFunc_GetTransparencyZoneMax: ulValue = fn_ucStandardGameGetTransparencyZoneMax(hStdGame); break; default: M_AIFatalError(E_uwAIFatalNotValidFunction); break; } } M_Full_GetSetParam_Integer(p_stValue,ulValue); return(p_stTree); } /* ANNECY MT - 30/03/99 { PC Protection Code*/ #if !defined(U64) /* { */ /* Lettre du CDROM */ #if defined(__cplusplus) extern "C" { #endif extern char g_cCDROM; #if defined(__cplusplus) } #endif /* ANNECY OA - 04/08/99 { */ typedef long (*ptrFunction)(char *_szFileName, tdstLoaderHandler *stHandler); void fn_vInitLoaderHandler(tdstLoaderHandler *stLoader); tdstNodeInterpret *fn_p_ExecuteVariable(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1); AI_tdstMind *p_stMind; /* Mind of perso (used to return paramaters to dsgVars)*/ long lResult = 0; if (eFuncId==eFunc_ExecuteVariable) { tdstLoaderHandler stLoader; long lCodePos, lParamPos; char *pcCode, *pcParameter; /* Recherche des positions du code et du parametre */ M_vEvalNextVarId(p_stMind, lCodePos); /* Recherche des pointeurs sur le code et le parametre */ pcCode = (char *)((tdstArray *)(M_GetDsgVarAddr(p_stMind, lCodePos)))->d_ArrayElement; if (*pcCode != 0) { M_vEvalNextVarId(p_stMind, lParamPos); pcParameter = (char *)((tdstArray *)(M_GetDsgVarAddr(p_stMind, lParamPos)))->d_ArrayElement; /* Initialisation du handler */ fn_vInitLoaderHandler(&stLoader); /* lecteur du CDROM en parametre ? */ M_EvalNextParameter(p_stValue); if (M_ReturnParam_lValue(p_stValue)) { *pcParameter = g_cCDROM; } /* Execution du code */ lResult = ((ptrFunction)pcCode)(pcParameter, &stLoader); } else { p_stTree = fn_p_stSkipThisArgument(p_stTree); p_stTree = fn_p_stSkipThisArgument(p_stTree); } } M_Full_GetSetParam_Integer(p_stValue, lResult); return(p_stTree); } /* END ANNECY OA } */ /*********************************************************************** * Functions : ACT_CalculeClefProtection * return: * Author: MT ************************************************************************/ tdstNodeInterpret *fn_p_stComputeProtectKey(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { tdstGetSetParam stParam; /* exchange structure*/ HIE_tdxHandleToSuperObject hPerso; /* Handle of the character*/ enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1); unsigned long ulValue = 0; DWORD dwInitKey; /********************************************************************************/ /* BEWARE THE ULTRA OPERATOR : Must be at the beginning and respect this syntax */ /********************************************************************************/ fn_vGetUltraOperatorPerso(fn_ucGetFunctionUltraOperator(eFuncId),p_SuperObjPerso,&hPerso); M_EvalNextParameter( &stParam ); dwInitKey = (long) M_GetSetParam_ulValue( &stParam ); switch (eFuncId) { case eFunc_ComputeProtectKey: ulValue = (unsigned long)SNA_fn_dwGetProtectionKey(dwInitKey); break; } M_Full_GetSetParam_Integer(p_stValue,ulValue); return(p_stTree); } /*********************************************************************** * Functions : MATH_Xor * return: * Author: MT ************************************************************************/ tdstNodeInterpret *fn_p_stComputeXor(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { tdstGetSetParam stParam1,stParam2; /* exchange structure*/ enum tdeFuncId_ eFuncId = M_eFuncIdInterpret(p_stTree-1); unsigned long ulValue = 0; unsigned long ulParam1 , ulParam2; DWORD dwOffset = (DWORD)PTC_GetModuleHandle(NULL); M_EvalNextParameter( &stParam1 ); ulParam1 = M_GetSetParam_ulValue( &stParam1 ); if (eFuncId == eFunc_GetMemoryValue) { ulValue = *(DWORD*)(ulParam1 + dwOffset); } else { M_EvalNextParameter( &stParam2 ); ulParam2 = M_GetSetParam_ulValue( &stParam2 ); switch (eFuncId) { case eFunc_Xor: ulValue = (unsigned long)(ulParam1 ^ ulParam2); break; /* ANNECY OA - 26/08/99 { */ case eFunc_And: ulValue = (unsigned long)(ulParam1 & ulParam2); break; case eFunc_Or: ulValue = (unsigned long)(ulParam1 | ulParam2); break; /* END ANNECY OA } */ case eFunc_DivUnsigned: ulValue = (unsigned long)(ulParam1 / ulParam2); break; case eFunc_MulUnsigned: ulValue = (unsigned long)(ulParam1 * ulParam2); break; case eFunc_AddUnsigned: ulValue = (unsigned long)(ulParam1 + ulParam2); break; case eFunc_SubUnsigned: ulValue = (unsigned long)(ulParam1 - ulParam2); break; } } M_GetSetParam_ulValue(p_stValue) = ulValue; M_GetSetParam_Type(p_stValue) = E_vt_PositiveInteger; return(p_stTree); } /* ANNECY OA - 26/08/99 { */ tdstNodeInterpret *fn_p_stComputeNot(HIE_tdxHandleToSuperObject p_SuperObjPerso, tdstNodeInterpret *p_stTree, tdstGetSetParam *p_stValue) { tdstGetSetParam stParam1; /* exchange structure*/ unsigned long ulValue = 0; unsigned long ulParam1; DWORD dwOffset = (DWORD)PTC_GetModuleHandle(NULL); M_EvalNextParameter( &stParam1 ); ulParam1 = M_GetSetParam_ulValue( &stParam1 ); ulValue = (unsigned long)(~ulParam1); M_GetSetParam_ulValue(p_stValue) = ulValue; M_GetSetParam_Type(p_stValue) = E_vt_PositiveInteger; return(p_stTree); } /* END ANNECY OA } */ #endif /* U64 } */ /* END ANNECY MT } */