/* ---------------------------------------- File Name : AIUseCPA.h ---------------------------------------- Required for : ACP basic definitions. ---------------------------------------- */ #include "AIUseCPA.h" #include "TMP.h" /* ---------------------------------------- File Name : AIMacros.h ---------------------------------------- Required for : AI main macros definitions. ---------------------------------------- */ #include "AIMacros.h" /* in order to compile AI in C++ and link with GAM in C*/ #include "AI_Proto.h" #define _WP_D_DEFINE_WAYPOINTS_ #include "WP_Handl.h" /* in order to compile AI in C++ and link with GAM in C*/ #include "WP_Func.h" #undef _WP_D_DEFINE_WAYPOINTS_ #define _WP_D_WPGRAPH_FRIEND_ #include "WPgraphe.h" #undef _WP_D_WPGRAPH_FRIEND_ #include "WPWayPt.h" #define _WP_D_WPARC_FREIND_ #include "WParc.h" #undef _WP_D_WPARC_FREIND_ /*ANNECY Bart 02/02/98 {*/ #ifndef U64 static SCR_tdst_Link_Table gs_stGraphLinkTable; #endif /*U64 AR980313 To be changed into a normal list ?*/ /*ENDANNECY Bart }*/ /*ROMTEAM Networks (Gabriela Dumitrascu 05/03/98)*/ #if !defined(U64) SCR_tdst_Link_Table* WPG_fnp_Graph_GetLinkTable (void) { return &gs_stGraphLinkTable; } #endif /* U64 */ /*ENDROMTEAM Networks (Gabriela Dumitrascu)*/ /*ROMTEAM Networks (Gabriela Dumitrascu 15/03/98)*/ /***************************************************** * Function : WPG_fn_pGetNameOfGraph * Description : retrieve the name of a graph ***************************************************** * Author : Gabriela Dumitrascu * Date : 15/03/98 *****************************************************/ #ifdef GAM_USE_SCRIPT char* WPG_fn_pGetNameOfGraph(WP_tdHandleOfGraph hGraph) { M_AI_DEBUG_ASSERT(hGraph, E_uwAIFatalInvalidParameter); return hGraph->m_szNameOfGraph; } /***************************************************** * Function : WPG_fn_vSetNameOfGraph * Description : change the name of a graph ***************************************************** * Author : Gabriela Dumitrascu * Date : 15/03/98 *****************************************************/ /* script only*/ void WPG_fn_vSetNameOfGraph(WP_tdHandleOfGraph hGraph, const char* _szName) { M_AI_DEBUG_ASSERT(hGraph, E_uwAIFatalInvalidParameter); if (hGraph->m_szNameOfGraph) M_AIFree(hGraph->m_szNameOfGraph); MMG_fn_vAddMemoryInfo (MMG_C_lTypeAI , MMG_C_lSubTypeNameOfGraph , NULL); M_AIAlloc(hGraph->m_szNameOfGraph, char*, strlen(_szName)+1 ) ; strcpy(hGraph->m_szNameOfGraph, _szName); } /***************************************************** * Function : WPG_fn_pGetReferenceSection * Description : retrieve the name of the section registering the graph ***************************************************** * Author : Gabriela Dumitrascu * Date : 15/03/98 *****************************************************/ /* script only*/ char* WPG_fn_pGetReferenceSection(WP_tdHandleOfGraph hGraph) { M_AI_DEBUG_ASSERT(hGraph, E_uwAIFatalInvalidParameter); return hGraph->m_szReferenceSection; } /***************************************************** * Function : WPG_fn_vSetReferenceSection * Description : change the name of the section registering the graph ***************************************************** * Author : Gabriela Dumitrascu * Date : 15/03/98 *****************************************************/ /* script only*/ void WPG_fn_vSetReferenceSection(WP_tdHandleOfGraph hGraph, const char* _szReferenceSection) { M_AI_DEBUG_ASSERT(hGraph, E_uwAIFatalInvalidParameter); if (hGraph->m_szReferenceSection) M_AIFree(hGraph->m_szReferenceSection); MMG_fn_vAddMemoryInfo (MMG_C_lTypeAI , MMG_C_lSubTypeNameOfGraphSection , NULL); M_AIAlloc(hGraph->m_szReferenceSection, char*, strlen(_szReferenceSection)+1 ) ; strcpy(hGraph->m_szReferenceSection, _szReferenceSection); } #endif /***************************************************** * Function : WPG_fn_vCopy * Description : make a copy of a graph ***************************************************** * Author : Gabriela Dumitrascu * Date : 15/03/98 *****************************************************/ #ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */ void WPG_fn_vCopy (WP_tdHandleOfGraph hDst,WP_tdHandleOfGraph hSrc) { int i; WP_tdhGraphNode hNode, hNextNode; M_AI_DEBUG_ASSERT(hDst && hSrc, E_uwAIFatalInvalidParameter); /* Empty the dst graph*/ LST2_M_DynamicForEachMovingElementOf(&hDst->m_hListOfNode, hNode, hNextNode, i) { LST2_M_DynamicIsolate(hNode); WPG_fn_vDestroyNode (hNode); } /* Copy the new name and the reference*/ #ifdef GAM_USE_SCRIPT WPG_fn_vSetNameOfGraph(hDst, hSrc->m_szNameOfGraph); WPG_fn_vSetReferenceSection(hDst, hSrc->m_szReferenceSection); #endif /* Copy all the nodes*/ LST2_M_DynamicForEachElementOf(&hSrc->m_hListOfNode, hNode, i) { WPG_fn_lAddWayPoint (hDst, hNode->m_hWayPoint, hNode->m_lTypeOfWP); /*BART*/ } /* Copy all the arcs*/ LST2_M_DynamicForEachElementOf(&hSrc->m_hListOfNode, hNode, i) { int j; WP_tdHandleOfArc hArc; LST2_M_DynamicForEachElementOf(&hNode->m_hListOfArc->m_hArc, hArc, j) { WPG_fn_lAddArcToWayPoint (hDst, hNode->m_hWayPoint, hArc->m_hNode->m_hWayPoint, WPARC_fn_lGetWeight(hArc), WPARC_fn_ulGetCapability(hArc)); } } } #endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */ /*ENDROMTEAM Networks (Gabriela Dumitrascu)*/ /***************************************************** * Function : WPG_fn_hCreate * Description : create a graph handle ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ WP_tdHandleOfGraph WPG_fn_hCreate (char* _szName, char* _szReference) { WP_tdHandleOfGraph hNewGraph ; MMG_fn_vAddMemoryInfo (MMG_C_lTypeAI , MMG_C_lSubTypeGraph , NULL); #ifdef U64 /* on U64, AI is a block without free, so alloc in TMP*/ hNewGraph = (WP_tdHandleOfGraph) TMP_M_p_Malloc(sizeof(WP_tdstGraph)); #else M_AIAlloc(hNewGraph, WP_tdHandleOfGraph, sizeof(WP_tdstGraph)) ; #endif if (hNewGraph) { #ifdef GAM_USE_SCRIPT MMG_fn_vAddMemoryInfo (MMG_C_lTypeAI , MMG_C_lSubTypeNameOfGraph , NULL); M_AIAlloc(hNewGraph->m_szNameOfGraph, char*, strlen(_szName)+1 ) ; strcpy(hNewGraph->m_szNameOfGraph, _szName); MMG_fn_vAddMemoryInfo (MMG_C_lTypeAI , MMG_C_lSubTypeNameOfGraphSection , NULL); M_AIAlloc(hNewGraph->m_szReferenceSection, char*, strlen(_szReference)+1 ) ; strcpy(hNewGraph->m_szReferenceSection, _szReference); #endif LST2_M_DynamicInitAnchor(&hNewGraph->m_hListOfNode) ; } return (hNewGraph) ; } /* ---------------------------------------------------------------------------------------- Description : WPG_fn_hGetGraph get a graph _szName -> name of the graph Returns (WP_tdHandleOfGraph ) handle to the graph ---------------------------------------------------------------------------------------- Author : Fred 'Bart' Compagnon Date : 02/02/98 ---------------------------------------------------------------------------------------- */ #ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */ WP_tdHandleOfGraph WPG_fn_hGetGraph(char* _szName) { #ifndef U64 char szCompleteName[255]; char szLevelName[255]; char szTmpName[128] ; WP_tdHandleOfGraph hGraph = NULL; SCR_tdst_Link_Value *p_stLinkValue = NULL; strncpy ( szTmpName, _szName, 128 ) ; szTmpName[127] = 0 ; strcpy(szLevelName, fn_p_szGetLevelName()); sprintf(szCompleteName, "%s\\%s\\%s.%s^%s:%s", fn_szGetLevelsDataPath(), szLevelName, szLevelName, C_ScriptWayPointSuffixe, C_SectionWPGraphDescription, szTmpName); p_stLinkValue = SCR_fnp_st_Link_SearchKey(&gs_stGraphLinkTable, szCompleteName); if ( (p_stLinkValue!=NULL) && (SCR_M_e_Link_GetState(p_stLinkValue) != SCR_ELS_Link_NotInitialized) ) { hGraph = (WP_tdHandleOfGraph)(p_stLinkValue->ulValue); } return(hGraph); #endif /*U64 AR980313*/ } #endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */ /***************************************************** * Function : WPG_fn_vDestroy * Description : destroy a graph ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ void WPG_fn_vDestroy (WP_tdHandleOfGraph hGraph) { WP_tdhGraphNode hElement, hNextElement ; int i ; LST2_M_DynamicForEachMovingElementOf(&hGraph->m_hListOfNode, hElement, hNextElement, i) { LST2_M_DynamicIsolate(hElement) ; WPG_fn_vDestroyNode (hElement) ; } #ifdef GAM_USE_SCRIPT M_AIFree(hGraph->m_szNameOfGraph); /* Jean-Marc, Jean-Marc !!! Pfffffff...*/ M_AIFree(hGraph->m_szReferenceSection); /* Jean-Marc, Jean-Marc !!! Pfffffff...*/ #endif #ifdef U64 /* on U64, AI block is replaced by TMP block, so free in TMP*/ TMP_M_Free(hGraph); #else M_AIFree(hGraph) ; #endif hGraph = NULL; /* BART ?*/ } /* ---------------------------------------------------------------------------------------- Description : WPG_fn_vDestroyAllGraph destroy all the graph ---------------------------------------------------------------------------------------- Author : Fred 'Bart' Compagnon Date : 02/02/98 ---------------------------------------------------------------------------------------- */ #ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */ void WPG_fn_vDestroyAllGraph(void) { #ifndef U64 unsigned int uiPos; SCR_tdst_Link_Value *pLinkValue=NULL; /* Get first element of array */ uiPos = 0; SCR_M_DyAr_GetNextElement(SCR_tdst_Link_Value, uiPos, pLinkValue, SCR_M_st_Link_GetDynamicArray(&gs_stGraphLinkTable) ) while (pLinkValue) /* for each graph ...*/ { if (SCR_M_e_Link_GetState (pLinkValue) != SCR_ELS_Link_NotInitialized) { WP_tdHandleOfGraph hGraph = (WP_tdHandleOfGraph) SCR_M_ul_Link_GetValue (pLinkValue); /* ... get it ...*/ WPG_fn_vDestroy (hGraph); /* ... and destroy it !*/ } uiPos++; /* Get next element */ SCR_M_DyAr_GetNextElement(SCR_tdst_Link_Value, uiPos, pLinkValue, SCR_M_st_Link_GetDynamicArray(&gs_stGraphLinkTable) ) } SCR_fn_v_Link_CloseTable(&gs_stGraphLinkTable); /* then destroy LinkTable !*/ #endif /*U64 AR980313 Must be replaced by a normal list*/ } #endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */ /***************************************************** * Function : WPG_fn_lAddWayPoint * Description : add a WP to a graph ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ long WPG_fn_lAddWayPoint (WP_tdHandleOfGraph _hGraph, WP_tdhWayPoint _hWayPoint, long _lTypeOfWP) { WP_tdhGraphNode hNewNode ; if ( _hGraph && _hWayPoint ) { hNewNode = WPG_fn_hCreateNode (_hWayPoint, _lTypeOfWP) ; LST2_M_DynamicAddTail(&_hGraph->m_hListOfNode, hNewNode) ; return (0) ; } return(-1) ; } /***************************************************** * Function : WPG_fn_lAddWayPointIfNotExists * Description : add a WP to a graph if it doesn't * already in the graph ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ #ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */ long WPG_fn_lAddWayPointIfNotExists (WP_tdHandleOfGraph _hGraph, WP_tdhWayPoint _hWayPoint, long _lTypeOfWP) { int i; WP_tdhGraphNode hNode; LST2_M_DynamicForEachElementOf(&_hGraph->m_hListOfNode, hNode, i ) { if ( hNode->m_hWayPoint == _hWayPoint ) return (0); /* already exists !*/ } /* does NOT exists*/ return (WPG_fn_lAddWayPoint (_hGraph, _hWayPoint, _lTypeOfWP)); } #endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */ #ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */ long WPG_fn_lChangeTypeOfWP (WP_tdHandleOfGraph _hGraph, WP_tdhWayPoint _hWayPoint, long _lTypeOfWP) { int i; WP_tdhGraphNode hNode; LST2_M_DynamicForEachElementOf(&_hGraph->m_hListOfNode, hNode, i ) { if ( hNode->m_hWayPoint == _hWayPoint ) { /* ok, exists !*/ hNode->m_lTypeOfWP = _lTypeOfWP; hNode->m_lTypeOfWPInit = _lTypeOfWP; return (0); } } /* does NOT exists*/ return (-1); } #endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */ /***************************************************** * Function : WPG_fn_lRemoveWayPoint * Description : remove a WP from a graph ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ #ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */ long WPG_fn_lRemoveWayPoint (WP_tdHandleOfGraph hGraph, WP_tdhWayPoint hWayPoint) { WP_tdhGraphNode hNode, hNextNode ; int i ; if ( hGraph && hWayPoint ) { LST2_M_DynamicForEachMovingElementOf(&hGraph->m_hListOfNode, hNode, hNextNode, i){ if ( hNode->m_hWayPoint == hWayPoint ) { LST2_M_DynamicIsolate(hNode) ; WPG_fn_vDestroyNode (hNode) ; return (0) ; } } } return (-1) ; } #endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */ /***************************************************** * Function : WPG_fn_lAddArcToWayPoint * Description : add a link between to WP of a graph ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ long WPG_fn_lAddArcToWayPoint (WP_tdHandleOfGraph hGraph, WP_tdhWayPoint hSrcWayPoint, WP_tdhWayPoint hDstWayPoint, long lWeight, unsigned long ulCapability) { int i; WP_tdhGraphNode hSrcNode, hDstNode; if ( hGraph && hSrcWayPoint && hDstWayPoint ) { /* * find the destinationnode from the hDstWayPoint */ LST2_M_DynamicForEachElementOf(&hGraph->m_hListOfNode, hDstNode, i ) { if ( hDstNode->m_hWayPoint == hDstWayPoint ) { break ; } } if ( hDstNode ) { LST2_M_DynamicForEachElementOf(&hGraph->m_hListOfNode, hSrcNode, i ) { if ( hSrcNode->m_hWayPoint == hSrcWayPoint ) { WPG_fn_vAddArc ( hSrcNode, hDstNode, ulCapability, lWeight) ; return (0) ; } } } } return (-1) ; } /***************************************************** * Function : WPG_fn_lRemoveArcFromWayPoint * Description : remove a link between to WP of a graph ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ #ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */ long WPG_fn_lRemoveArcFromWayPoint (WP_tdHandleOfGraph hGraph, WP_tdhWayPoint hSrcWayPoint, WP_tdhWayPoint hDstWayPoint ) { int i; WP_tdhGraphNode hSrcNode, hDstNode; if ( hGraph && hSrcWayPoint && hDstWayPoint ) { /* * find the destinationnode from the hDstWayPoint */ LST2_M_DynamicForEachElementOf(&hGraph->m_hListOfNode, hDstNode, i ) { if ( hDstNode->m_hWayPoint == hDstWayPoint ) { break ; } } if ( hDstNode ) { LST2_M_DynamicForEachElementOf(&hGraph->m_hListOfNode, hSrcNode, i ) { if ( hSrcNode->m_hWayPoint == hSrcWayPoint ) { WPG_fn_vRemoveArc ( hSrcNode, hDstNode ) ; return (0) ; } } } } return (-1) ; } #endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */ /***************************************************** * Function : WPG_fn_lChangeLinkCapabilities * Description : change the capability of a link between * two WP of the graph ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ long WPG_fn_lChangeLinkCapabilities (WP_tdHandleOfGraph hGraph, WP_tdhWayPoint hSrcWayPoint, WP_tdhWayPoint hDstWayPoint, unsigned long ulCapability, long lValue ) { int i; WP_tdhGraphNode hSrcNode, hDstNode; if ( hGraph && hSrcWayPoint && hDstWayPoint ) { /* * find the destinationnode from the hDstWayPoint */ LST2_M_DynamicForEachElementOf(&hGraph->m_hListOfNode, hDstNode, i ) { if ( hDstNode->m_hWayPoint == hDstWayPoint ) { break ; } } if ( hDstNode ) { LST2_M_DynamicForEachElementOf(&hGraph->m_hListOfNode, hSrcNode, i ) { if ( hSrcNode->m_hWayPoint == hSrcWayPoint ) { return (WPG_fn_lChangeArcCapabilities ( hSrcNode, hDstNode, ulCapability, lValue) ) ; } } } } return (-1) ; } /***************************************************** * Function : WPG_fn_lGetLinkCapabilities * Description : get the Capability of a link between * two WP of a graph ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ long WPG_fn_lGetLinkCapabilities (WP_tdHandleOfGraph hGraph, WP_tdhWayPoint hSrcWayPoint, WP_tdhWayPoint hDstWayPoint, unsigned long* p_ulCapability) { int i; WP_tdhGraphNode hSrcNode, hDstNode; if ( hGraph && hSrcWayPoint && hDstWayPoint ) { /* * find the destinationnode from the hDstWayPoint */ LST2_M_DynamicForEachElementOf(&hGraph->m_hListOfNode, hDstNode, i ) { if ( hDstNode->m_hWayPoint == hDstWayPoint ) { break ; } } if ( hDstNode ) { LST2_M_DynamicForEachElementOf(&hGraph->m_hListOfNode, hSrcNode, i ) { if ( hSrcNode->m_hWayPoint == hSrcWayPoint ) { return (WPG_fn_lGetArcCapabilities ( hSrcNode, hDstNode, p_ulCapability) ) ; } } } } return (-1) ; } long WPG_fn_lChangeLinkWeight (WP_tdHandleOfGraph hGraph, WP_tdhWayPoint hSrcWayPoint, WP_tdhWayPoint hDstWayPoint, long lWeight) { int i; WP_tdhGraphNode hSrcNode, hDstNode; if ( hGraph && hSrcWayPoint && hDstWayPoint ) { /* * find the destinationnode from the hDstWayPoint */ LST2_M_DynamicForEachElementOf(&hGraph->m_hListOfNode, hDstNode, i ) { if ( hDstNode->m_hWayPoint == hDstWayPoint ) { break ; } } if ( hDstNode ) { LST2_M_DynamicForEachElementOf(&hGraph->m_hListOfNode, hSrcNode, i ) { if ( hSrcNode->m_hWayPoint == hSrcWayPoint ) { return (WPG_fn_lChangeArcWeight ( hSrcNode, hDstNode, lWeight) ) ; } } } } return (-1) ; } long WPG_fn_lGetLinkWeight (WP_tdHandleOfGraph hGraph, WP_tdhWayPoint hSrcWayPoint, WP_tdhWayPoint hDstWayPoint, long *p_lWeight) { int i; WP_tdhGraphNode hSrcNode, hDstNode; if ( hGraph && hSrcWayPoint && hDstWayPoint ) { /* * find the destinationnode from the hDstWayPoint */ LST2_M_DynamicForEachElementOf(&hGraph->m_hListOfNode, hDstNode, i ) { if ( hDstNode->m_hWayPoint == hDstWayPoint ) { break ; } } if ( hDstNode ) { LST2_M_DynamicForEachElementOf(&hGraph->m_hListOfNode, hSrcNode, i ) { if ( hSrcNode->m_hWayPoint == hSrcWayPoint ) { return (WPG_fn_lGetArcWeight ( hSrcNode, hDstNode, p_lWeight) ) ; } } } } return (-1) ; } void WPG_fn_vReinitGraph (WP_tdHandleOfGraph hGraph) { int i, j; WP_tdhGraphNode hNode; WP_tdHandleOfArc hElement ; if ( hGraph) { LST2_M_DynamicForEachElementOf(&hGraph->m_hListOfNode, hNode, i ) { hNode->m_lTypeOfWP = hNode->m_lTypeOfWPInit; LST2_M_DynamicForEachElementOf(&hNode->m_hListOfArc->m_hArc, hElement, j) { hElement->m_ulCapability = hElement->m_ulCapabilityInit; hElement->m_lWeight = hElement->m_lWeightInit; } } } } /***************************************************** * Function : WPG_fn_lShortestPath * Description : find the shortest path between two WP * of a graph, return a sub-graph if a * path is found, otherwise return NULL ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ WP_tdHandleOfGraph WPG_fn_lShortestPath (WP_tdHandleOfGraph hGraph, WP_tdhWayPoint hSrcWayPoint, WP_tdhWayPoint hDstWayPoint, unsigned long ulCapability) { WP_tdhGraphNode hCurrentNode ; /* the node currently examine */ WP_tdhGraphNode hNeighbor ; /* the neighbor currently examine of the current node */ WP_tdHandleOfArc hArc ; /* the link between the current node an his neighbor */ WP_tdhGraphNode *d_hExplored; /* list of the explored WayPoint, ie : the shortest path to this node have been found */ WP_tdhGraphNode *d_hReached ; /* list of the WayPoint that can be reached from the Explored node */ int *d_iWayOfExplored, *d_iWayOfReached ; /* Array of the previous node in the path (the index of the node in Explored (Reached) )*/ int *d_iValuationOfExplored, *d_iValuationOfReached ; /* Array of the valuation to go to the node */ int iCurrentWayPointInExplored, iNbElementInExplored ; int iCurrentWayPointInReached, iNbElementInReached ; int iNbElementInTheGraph ; int iDone, iIndex, iValuation, i ; WP_tdHandleOfGraph tdhShortestPath ; long lWeight; /* Bart*/ /* * initialise all local variables * for the algorithme */ iNbElementInTheGraph = LST2_M_DynamicGetNumberOfElements(&hGraph->m_hListOfNode) ; d_hExplored = (WP_tdhGraphNode *)TMP_M_p_Malloc(sizeof(WP_tdhGraphNode)*iNbElementInTheGraph); d_hReached = (WP_tdhGraphNode *)TMP_M_p_Malloc(sizeof(WP_tdhGraphNode)*iNbElementInTheGraph); d_iWayOfExplored = (int *)TMP_M_p_Malloc(sizeof(int)*iNbElementInTheGraph); d_iValuationOfExplored = (int *)TMP_M_p_Malloc(sizeof(int)*iNbElementInTheGraph); d_iWayOfReached = (int *)TMP_M_p_Malloc(sizeof(int)*iNbElementInTheGraph); d_iValuationOfReached = (int *)TMP_M_p_Malloc(sizeof(int)*iNbElementInTheGraph); /* M_AI_MemSet(d_hExplored, 0, (sizeof(WP_tdhGraphNode)*iNbElementInTheGraph) ) ; M_AI_MemSet(d_hReached, 0, (sizeof(WP_tdhGraphNode)*iNbElementInTheGraph) ) ; M_AI_MemSet(d_iWayOfExplored, 0, (sizeof(int)*iNbElementInTheGraph) ) ; M_AI_MemSet(d_iValuationOfExplored, 0, (sizeof(int)*iNbElementInTheGraph) ) ; M_AI_MemSet(d_iWayOfReached, 0, (sizeof(int)*iNbElementInTheGraph) ) ; M_AI_MemSet(d_iValuationOfReached, 0, (sizeof(int)*iNbElementInTheGraph) ) ; */ /* AR9904 Already done in the alloc functions */ iCurrentWayPointInExplored = 0 ; iCurrentWayPointInReached = 0 ; iNbElementInExplored = 0 ; iNbElementInReached = 1 ; LST2_M_DynamicForEachElementOf(&hGraph->m_hListOfNode, hCurrentNode, i) { if ( hCurrentNode->m_hWayPoint == hSrcWayPoint ) { d_hReached[0] = hCurrentNode ; d_iWayOfReached[0] = -1 ; /* this is the starting node */ break ; } } if ( d_hReached[0] == NULL ) { tdhShortestPath = NULL ; /* et on libère pas la mémoire des structures allouées ? ? ! ! !*/ /* return (NULL) ; /* starting node is not in the graph ? */ } else { iDone = 0 ; /* * and then come the algorithme */ while ( iNbElementInReached /* while there still node to process */ && !iDone ) { /* and the destination have not been explored */ /* * pick in Reached the Node with the smaller valuation */ iValuation = 0x7FFFFFFF; /* biggest valuation */ for ( iIndex=0 ; iIndex d_iValuationOfReached[iIndex] ) { iValuation = d_iValuationOfReached[iIndex] ; iCurrentWayPointInReached = iIndex ; } } /* * remove the selected Node from Reached * and add it to Explored */ d_hExplored[iNbElementInExplored] = d_hReached[iCurrentWayPointInReached] ; d_iValuationOfExplored[iNbElementInExplored] = d_iValuationOfReached[iCurrentWayPointInReached] ; d_iWayOfExplored[iNbElementInExplored] = d_iWayOfReached[iCurrentWayPointInReached] ; iCurrentWayPointInExplored = iNbElementInExplored ; iNbElementInExplored ++ ; memmove ( d_iValuationOfReached+iCurrentWayPointInReached, d_iValuationOfReached+iCurrentWayPointInReached+1, sizeof(int)*(iNbElementInReached-iCurrentWayPointInReached) ) ; memmove ( d_iWayOfReached+iCurrentWayPointInReached, d_iWayOfReached+iCurrentWayPointInReached+1, sizeof(int)*(iNbElementInReached-iCurrentWayPointInReached) ) ; memmove ( d_hReached+iCurrentWayPointInReached, d_hReached+iCurrentWayPointInReached+1, sizeof(WP_tdhWayPoint *)*(iNbElementInReached-iCurrentWayPointInReached) ) ; iNbElementInReached -- ; /* * Does the destination point have been reached */ hCurrentNode = d_hExplored[iCurrentWayPointInExplored] ; if ( hCurrentNode->m_hWayPoint == hDstWayPoint ) iDone = 1 ; /* * checked all the neighbor of the current Node */ LST2_M_DynamicForEachElementOf(&hCurrentNode->m_hListOfArc->m_hArc, hArc, iIndex) { hNeighbor = hArc->m_hNode ; /* * have we the capability to go through this link * and can we use it */ if ( !(hArc->m_ulCapability & ulCapability) ) continue ; /* * is hNeighbor already in Explored * (ie:the shortest path to this point have already been found) */ for (i=0 ; im_lWeight ; d_iWayOfReached[iNbElementInReached] = iCurrentWayPointInExplored ; iNbElementInReached++ ; } else { /* * already in Reached, update Weight if it is necessary */ if ( d_iValuationOfReached[i] > (d_iValuationOfExplored[iCurrentWayPointInExplored] + hArc->m_lWeight ) ) { d_iValuationOfReached[i] = d_iValuationOfExplored[iCurrentWayPointInExplored] + hArc->m_lWeight ; d_iWayOfReached[i] = iCurrentWayPointInExplored ; } } } } } /* * build the shortest path from the information stored in Explored * if !iDone there is no path between the two WayPoint */ tdhShortestPath = NULL ; if ( iDone ) { tdhShortestPath = WPG_fn_hCreate ( "Generated by ShortestPath", "@") ; i = iCurrentWayPointInExplored ; /* * add the node in the graph */ while ( i != -1 ) { WPG_fn_lAddWayPoint ( tdhShortestPath, d_hExplored[i]->m_hWayPoint , d_hExplored[i]->m_lTypeOfWP); /*BART*/ i = d_iWayOfExplored[i] ; } /* * add the link between the node */ i = iCurrentWayPointInExplored ; while ( i != 0 ) { WPG_fn_lGetLinkCapabilities ( hGraph, d_hExplored[d_iWayOfExplored[i]]->m_hWayPoint, d_hExplored[i]->m_hWayPoint, &ulCapability ) ; WPG_fn_lGetLinkWeight ( hGraph, d_hExplored[d_iWayOfExplored[i]]->m_hWayPoint, d_hExplored[i]->m_hWayPoint, &lWeight ) ; WPG_fn_lAddArcToWayPoint ( tdhShortestPath, d_hExplored[d_iWayOfExplored[i]]->m_hWayPoint, d_hExplored[i]->m_hWayPoint, lWeight, ulCapability) ; i = d_iWayOfExplored[i] ; } } } /* fin du grand else*/ TMP_M_Free(d_hExplored) ; TMP_M_Free(d_hReached) ; TMP_M_Free(d_iWayOfExplored); TMP_M_Free(d_iValuationOfExplored) ; TMP_M_Free(d_iWayOfReached) ; TMP_M_Free(d_iValuationOfReached) ; return (tdhShortestPath) ; } WP_tdHandleOfGraph WPG_fn_lBuildOrderedPath(WP_tdHandleOfGraph hGraph, WP_tdhWayPoint hStartWP) { WP_tdHandleOfGraph tdhNewPath; /*returned value*/ WP_tdhGraphNode hCurrentNode ; /* the node currently examine */ WP_tdhGraphNode* d_hListOfWPNode; /* list of the WayPoints in the graph */ WP_tdhGraphNode hFirstNode; int iNbElementInTheGraph ; int iCount, iStartingIndex, iCurrentIndex; unsigned long ulCapability; long lWeight; long lBestWeight; unsigned long ulCapsOfBestNode = 0; int iIndexOfBestNode; /*WP_tdhGraphNode* d_hListOfDestWP;*/ WP_tdhWayPoint* d_hListOfDestWP; long* d_hListOfTypeOfWP; /* m_lTypeOfWP*/ unsigned long* d_hListOfDestCaps; long* d_hListOfDestWeight; int iIndex; iNbElementInTheGraph = LST2_M_DynamicGetNumberOfElements(&hGraph->m_hListOfNode) ; if (iNbElementInTheGraph == 0) /* Bart : no WP in da graph !*/ { return NULL; } /* allocate structures*/ /* M_AIAlloc(d_hListOfWPNode, WP_tdhGraphNode *, (sizeof(WP_tdhGraphNode)*iNbElementInTheGraph) );*/ d_hListOfWPNode = (WP_tdhGraphNode *)TMP_M_p_Malloc(sizeof(WP_tdhGraphNode)*iNbElementInTheGraph); /* M_AI_MemSet(d_hListOfWPNode, 0, (sizeof(WP_tdhGraphNode)*iNbElementInTheGraph) ) ; AR9904 Already done in the alloc function */ /*d_hListOfDestWP = (WP_tdhGraphNode *)TMP_M_p_Malloc(sizeof(WP_tdhGraphNode)*iNbElementInTheGraph);*/ d_hListOfDestWP = (WP_tdhWayPoint *)TMP_M_p_Malloc(sizeof(WP_tdhWayPoint)*iNbElementInTheGraph); /* M_AI_MemSet(d_hListOfDestWP, 0, (sizeof(WP_tdhWayPoint)*iNbElementInTheGraph) ) ; AR9904 Already done in the alloc function */ d_hListOfTypeOfWP = (long *)TMP_M_p_Malloc(sizeof(long)*iNbElementInTheGraph); /* M_AI_MemSet(d_hListOfTypeOfWP, 0, (sizeof(long)*iNbElementInTheGraph) ) ; AR9904 Already done in the alloc function */ d_hListOfDestCaps = (unsigned long *)TMP_M_p_Malloc(sizeof(unsigned long)*iNbElementInTheGraph); /* M_AI_MemSet(d_hListOfDestCaps, 0, (sizeof(unsigned long)*iNbElementInTheGraph) ) ; AR9904 Already done in the alloc function */ d_hListOfDestWeight = (long *)TMP_M_p_Malloc(sizeof(long)*iNbElementInTheGraph); /* M_AI_MemSet(d_hListOfDestWeight, 0, (sizeof(long)*iNbElementInTheGraph) ) ; AR9904 Already done in the alloc function */ iStartingIndex = -1; /* juste pour faire plaisir à YLG !*/ /* on cherche le WP de départ :*/ LST2_M_DynamicForEachElementOf(&hGraph->m_hListOfNode, hCurrentNode, iCount) { if ( hCurrentNode->m_hWayPoint == hStartWP ) { d_hListOfWPNode[0] = hCurrentNode; iStartingIndex = iCount; break ; } } tdhNewPath = NULL; if (iStartingIndex != -1) /* starting node has been found in the graph !*/ /*if ( d_hListOfWPNode[0] != NULL )*/ { /* build the list d_hListOfWPNode:*/ tdhNewPath = WPG_fn_hCreate ( "Generated by BuildOrderedPath", "@") ; iCount = iStartingIndex+1; while ( iCount != -1 ) { int i; LST2_M_DynamicGetElementNumber(&hGraph->m_hListOfNode, hCurrentNode, (iCount%iNbElementInTheGraph), i) ; d_hListOfWPNode[(iCount-iStartingIndex)%iNbElementInTheGraph] = hCurrentNode; /*++iCount %= iNbElementInTheGraph;*/ if (++iCount%iNbElementInTheGraph == iStartingIndex) iCount = -1; /* this is the end !*/ } /* start of le remplissage :*/ hFirstNode = d_hListOfWPNode[0]; iIndex = 0; d_hListOfDestWP[0] = d_hListOfWPNode[0]->m_hWayPoint; d_hListOfTypeOfWP[0] = d_hListOfWPNode[0]->m_lTypeOfWP; /*BART*/ iCurrentIndex = 0; /* on commence la recherche*/ do { iIndexOfBestNode = -1; lBestWeight = (long) ( ((unsigned long) (1 << 31)) - 1 ); /* max possible Weight*/ for (iCount = 1/*0*/ ; iCountm_hWayPoint; d_hListOfTypeOfWP[iIndex] = d_hListOfWPNode[iIndexOfBestNode]->m_lTypeOfWP; /*BART*/ d_hListOfDestCaps[iIndex] = ulCapsOfBestNode; d_hListOfDestWeight[iIndex] = lBestWeight; d_hListOfWPNode[iCurrentIndex] = NULL; /* on l'éfface de la liste*/ iCurrentIndex = iIndexOfBestNode; } } while(iIndexOfBestNode != -1); /* tant qu'on trouve un nouvel élément*/ d_hListOfDestCaps[0] = (unsigned long)0; /* default*/ d_hListOfDestWeight[0] = (long)0; /* si le dernier et le premier ont un lien, on boucle !*/ if ( (WPG_fn_lGetArcCapabilities(d_hListOfWPNode[iCurrentIndex], hFirstNode, &ulCapability) != -1) && (WPG_fn_lGetArcWeight (d_hListOfWPNode[iCurrentIndex], hFirstNode, &lWeight ) != -1) ) { /* to put ulCapability and Weight*/ d_hListOfDestCaps[0] = ulCapability; d_hListOfDestWeight[0] = lWeight; } /* construit le graph (à l'envers) maintenant*/ WPG_fn_lAddWayPoint(tdhNewPath, d_hListOfDestWP[iIndex], d_hListOfTypeOfWP[iIndex]); /*BART*/ iIndex--; while (iIndex >= 0) { /* add the node in the graph*/ WPG_fn_lAddWayPoint(tdhNewPath, d_hListOfDestWP[iIndex], d_hListOfTypeOfWP[iIndex]); /*BART*/ /* to put ulCapability (and no Weight)*/ WPG_fn_lAddArcToWayPoint ( tdhNewPath, d_hListOfDestWP[iIndex], d_hListOfDestWP[iIndex+1], d_hListOfDestWeight[iIndex+1], d_hListOfDestCaps[iIndex+1] ); iIndex--; } WPG_fn_lAddArcToWayPoint ( tdhNewPath, d_hListOfWPNode[iCurrentIndex]->m_hWayPoint, /* le dernier de la liste ! => donc le premier, vous suivez ? pas moi ! ah, bon !*/ d_hListOfDestWP[0], d_hListOfDestWeight[0], d_hListOfDestCaps[0] ); } /* end of if ( d_hListOfWPNode[0] != NULL )*/ /* freeing the structures :*/ TMP_M_Free(d_hListOfWPNode); /* M_AIFree*/ TMP_M_Free(d_hListOfDestWP); TMP_M_Free(d_hListOfTypeOfWP); /*BART*/ TMP_M_Free(d_hListOfDestCaps); TMP_M_Free(d_hListOfDestWeight); return (tdhNewPath) ; } /***************************************************** * Function : WPG_fn_hGetFirstWaypointOfGraph * Description : ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ #ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */ WP_tdhWayPoint WPG_fn_hGetFirstWaypointOfGraph (WP_tdHandleOfGraph hGraph) { return (hGraph->m_hListOfNode.hFirstElementDyn->m_hWayPoint ) ; } #endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */ /***************************************************** * Function : WPG_fn_hGetLastWaypointOfGraph * Description : ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ #ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */ WP_tdhWayPoint WPG_fn_hGetLastWaypointOfGraph (WP_tdHandleOfGraph hGraph) { return (hGraph->m_hListOfNode.hLastElementDyn->m_hWayPoint ) ; } #endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */ /***************************************************** * Function : WPG_fn_lNumberOfWaypointOfGraph * Description : ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ long WPG_fn_lNumberOfWaypointOfGraph (WP_tdHandleOfGraph hGraph) { return (LST2_M_DynamicGetNumberOfElements(&hGraph->m_hListOfNode)) ; } /***************************************************** * Function : WPG_fn_hGetWaypointOfGraph * Description : ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ WP_tdhWayPoint WPG_fn_hGetWaypointOfGraph (WP_tdHandleOfGraph hGraph, int iIndex, long* _plTypeOfWP) { WP_tdhGraphNode hElement ; int i ; LST2_M_DynamicGetElementNumber(&hGraph->m_hListOfNode, hElement, iIndex, i) ; *_plTypeOfWP = hElement->m_lTypeOfWP; /* BART*/ return (hElement->m_hWayPoint) ; } /* ---------------------------------------------------------------------------------------- Description : WPG_fn_vAddGlobalGraph add a graph in the list of graph (in the link table) hGraph -> handle to the graph to add ---------------------------------------------------------------------------------------- Author : Fred 'Bart' Compagnon Date : 02/02/98 ---------------------------------------------------------------------------------------- */ #ifndef U64 void WPG_fn_vAddGlobalGraph(WP_tdHandleOfGraph hGraph) { char szCompleteName[255]; char szLevelName[255]; SCR_tdst_Link_Value *p_stLinkValue = NULL; strcpy(szLevelName, fn_p_szGetLevelName()); sprintf(szCompleteName, "%s\\%s\\%s.%s^%s:%s", fn_szGetLevelsDataPath(), szLevelName, szLevelName, C_ScriptWayPointSuffixe, C_SectionWPGraphDescription, hGraph->m_szNameOfGraph); /* Yargla !*/ SCR_fn_v_Link_InitTable(&gs_stGraphLinkTable); SCR_fnp_st_Link_SetValue(&gs_stGraphLinkTable, szCompleteName, (unsigned long)hGraph); } #endif /*U64 */ /***************************************************** * Function : WPG_fn_szGetReferenceSection * Description : ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ #ifdef GAM_USE_SCRIPT char *WPG_fn_szGetReferenceSection (WP_tdHandleOfGraph hGraph) { return (hGraph->m_szReferenceSection) ; } #endif /************************************************************************* * Node managment *************************************************************************/ /***************************************************** * Function : WPG_fn_hCreateNode * Description : ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ WP_tdhGraphNode WPG_fn_hCreateNode (WP_tdhWayPoint _hWayPoint, long _lTypeOfWP) { WP_tdhGraphNode hNewNode = NULL ; if ( _hWayPoint ) { MMG_fn_vAddMemoryInfo (MMG_C_lTypeAI , MMG_C_lSubTypeGraphNode , NULL); #ifdef U64 /* on U64, AI is a block without free, so alloc in TMP*/ hNewNode = (WP_tdhGraphNode) TMP_M_p_Malloc(sizeof(WP_tdstGraphNode)); #else M_AIAlloc(hNewNode, WP_tdhGraphNode, sizeof(WP_tdstGraphNode)) ; #endif if ( hNewNode ) { LST2_M_DynamicInitElement(hNewNode) ; hNewNode->m_hWayPoint = _hWayPoint; hNewNode->m_lTypeOfWP = _lTypeOfWP; /* BART*/ hNewNode->m_lTypeOfWPInit = _lTypeOfWP; /* BART*/ hNewNode->m_hListOfArc = WPARCLST_fn_hInit () ; } } return (hNewNode) ; } /***************************************************** * Function : WPG_fn_vDestroyNode * Description : ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ void WPG_fn_vDestroyNode (WP_tdhGraphNode hNode) { if ( hNode ) { WPARCLST_fn_vDestroy (hNode->m_hListOfArc) ; #ifdef U64 /* on U64, AI block is replaced by TMP block, so free in TMP*/ TMP_M_Free(hNode); #else M_AIFree(hNode) ; #endif hNode = NULL; /* BART ?*/ } } /***************************************************** * Function : WPG_fn_vAddArc * Description : ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ void WPG_fn_vAddArc (WP_tdhGraphNode hSrcNode, WP_tdhGraphNode hDstNode, unsigned long ulCapability, long lWeight) { if ( hSrcNode && hDstNode ) WPARCLST_fn_vAdd ( hSrcNode->m_hListOfArc, hDstNode, lWeight, ulCapability ) ; } /***************************************************** * Function : WPG_fn_vRemoveArc * Description : ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ #ifndef _FIRE_DEADCODE_U64_ /* Added by RUC */ void WPG_fn_vRemoveArc (WP_tdhGraphNode hSrcNode, WP_tdhGraphNode hDstNode ) { if ( hSrcNode && hDstNode ) WPARCLST_fn_vRemove ( hSrcNode->m_hListOfArc, hDstNode ) ; } #endif /* _FIRE_DEADCODE_U64_ */ /* Added by RUC */ /***************************************************** * Function : WPG_fn_hGetArcList * Description : ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ WP_tdHandleOfListOfArc WPG_fn_hGetArcList (WP_tdhGraphNode hSrcNode) { if ( hSrcNode ) return (hSrcNode->m_hListOfArc) ; return (NULL) ; } /***************************************************** * Function : WPG_fn_lChangeArcCapabilities * Description : ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ long WPG_fn_lChangeArcCapabilities ( WP_tdhGraphNode hSrcNode, WP_tdhGraphNode hDstNode, unsigned long ulCapability, long lValue) { if ( hSrcNode && hDstNode ) return ( WPARCLST_fn_lChangeCapabilities ( hSrcNode->m_hListOfArc, hDstNode, ulCapability, lValue) ) ; return (-1) ; } /***************************************************** * Function : WPG_fn_lGetArcCapabilities * Description : ***************************************************** * Author : Jean-Marc Drouaud * Date : 13/01/98 *****************************************************/ long WPG_fn_lGetArcCapabilities ( WP_tdhGraphNode hSrcNode, WP_tdhGraphNode hDstNode, unsigned long* p_ulCapability ) { if ( hSrcNode && hDstNode ) return ( WPARCLST_fn_lGetCapabilities ( hSrcNode->m_hListOfArc, hDstNode, p_ulCapability ) ) ; return (-1) ; } long WPG_fn_lChangeArcWeight ( WP_tdhGraphNode hSrcNode, WP_tdhGraphNode hDstNode, long lWeight) { if ( hSrcNode && hDstNode ) return ( WPARCLST_fn_lChangeWeight ( hSrcNode->m_hListOfArc, hDstNode, lWeight) ) ; return (-1) ; } long WPG_fn_lGetArcWeight ( WP_tdhGraphNode hSrcNode, WP_tdhGraphNode hDstNode, long *p_lWeight) { if ( hSrcNode && hDstNode ) return ( WPARCLST_fn_lGetWeight ( hSrcNode->m_hListOfArc, hDstNode, p_lWeight ) ) ; return (-1) ; }