BOOLEAN CanSoldierReachGridNoInGivenTileLimit( SOLDIERTYPE *pSoldier, INT16 sGridNo, INT16 sMaxTiles, INT8 bLevel ) { INT32 iNumTiles; INT16 sActionGridNo; UINT8 ubDirection; if ( pSoldier->bLevel != bLevel ) { return( FALSE ); } sActionGridNo = FindAdjacentGridEx( pSoldier, sGridNo, &ubDirection, NULL, FALSE, FALSE ); if ( sActionGridNo == -1 ) { sActionGridNo = sGridNo; } if ( sActionGridNo == pSoldier->sGridNo ) { return( TRUE ); } iNumTiles = FindBestPath( pSoldier, sActionGridNo, pSoldier->bLevel, WALKING, NO_COPYROUTE, PATH_IGNORE_PERSON_AT_DEST ); if ( iNumTiles <= sMaxTiles && iNumTiles != 0 ) { return( TRUE ); } else { return( FALSE ); } }
INT8 FindBestPatient( SOLDIERTYPE * pSoldier, BOOLEAN * pfDoClimb ) { UINT8 cnt, cnt2; INT32 bBestPriority = 0, sBestAdjGridNo = NOWHERE; INT32 sPatientGridNo = NOWHERE, sBestPatientGridNo = NOWHERE; INT16 sShortestPath = 1000, sPathCost, sOtherMedicPathCost; SOLDIERTYPE * pPatient; SOLDIERTYPE * pBestPatient = NULL; SOLDIERTYPE * pOtherMedic; INT8 bPatientPriority; UINT8 ubDirection; INT32 sAdjustedGridNo, sAdjacentGridNo, sOtherAdjacentGridNo; INT32 sClimbGridNo, sBestClimbGridNo = NOWHERE, sShortestClimbPath = 1000; BOOLEAN fClimbingNecessary; gubGlobalPathFlags = PATH_THROUGH_PEOPLE; // search for someone who needs aid cnt = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; for ( pPatient = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; cnt++,pPatient++) { if ( !(pPatient->bActive) || !(pPatient->bInSector) ) { continue; // NEXT!!! } if (pPatient->stats.bLife > 0 && pPatient->bBleeding && pPatient->ubServiceCount == 0) { if (pPatient->stats.bLife < OKLIFE) { bPatientPriority = 3; } else if (pPatient->stats.bLife < OKLIFE * 2) { bPatientPriority = 2; } else { bPatientPriority = 1; } if (bPatientPriority >= bBestPriority) { if ( !ClimbingNecessary( pSoldier, pPatient->sGridNo, pPatient->pathing.bLevel ) ) { sPatientGridNo = pPatient->sGridNo; sAdjacentGridNo = FindAdjacentGridEx( pSoldier, sPatientGridNo, &ubDirection, &sAdjustedGridNo, FALSE, FALSE ); if ( sAdjacentGridNo == -1 && gAnimControl[ pPatient->usAnimState ].ubEndHeight == ANIM_PRONE ) { // prone; could be the base tile is inaccessible but the rest isn't... for ( cnt2 = 0; cnt2 < NUM_WORLD_DIRECTIONS; cnt2++ ) { sPatientGridNo = pPatient->sGridNo + DirectionInc( cnt2 ); if ( WhoIsThere2( sPatientGridNo, pPatient->pathing.bLevel ) == pPatient->ubID ) { // patient is also here, try this location sAdjacentGridNo = FindAdjacentGridEx( pSoldier, sPatientGridNo, &ubDirection, &sAdjustedGridNo, FALSE, FALSE ); if ( sAdjacentGridNo != -1 ) { break; } } } } if (sAdjacentGridNo != -1) { if (sAdjacentGridNo == pSoldier->sGridNo) { sPathCost = 1; } else { sPathCost = PlotPath( pSoldier, sAdjacentGridNo, FALSE, FALSE, FALSE, RUNNING, FALSE, FALSE, 0); } if ( sPathCost != 0 ) { // we can get there... can anyone else? if ( pPatient->ubAutoBandagingMedic != NOBODY && pPatient->ubAutoBandagingMedic != pSoldier->ubID ) { // only switch to this patient if our distance is closer than // the other medic's pOtherMedic = MercPtrs[ pPatient->ubAutoBandagingMedic ]; sOtherAdjacentGridNo = FindAdjacentGridEx( pOtherMedic, sPatientGridNo, &ubDirection, &sAdjustedGridNo, FALSE, FALSE ); if (sOtherAdjacentGridNo != -1) { if (sOtherAdjacentGridNo == pOtherMedic->sGridNo) { sOtherMedicPathCost = 1; } else { sOtherMedicPathCost = PlotPath( pOtherMedic, sOtherAdjacentGridNo, FALSE, FALSE, FALSE, RUNNING, FALSE, FALSE, 0); } if (sPathCost >= sOtherMedicPathCost) { // this patient is best served by the merc moving to them now continue; } } } if (bPatientPriority == bBestPriority) { // compare path distances if ( sPathCost > sShortestPath ) { continue; } } sShortestPath = sPathCost; pBestPatient = pPatient; sBestPatientGridNo = sPatientGridNo; bBestPriority = bPatientPriority; sBestAdjGridNo = sAdjacentGridNo; } } } else { sClimbGridNo = NOWHERE; // see if guy on another building etc and we need to climb somewhere sPathCost = EstimatePathCostToLocation( pSoldier, pPatient->sGridNo, pPatient->pathing.bLevel, FALSE, &fClimbingNecessary, &sClimbGridNo ); // if we can get there if ( sPathCost != 0 && fClimbingNecessary && sPathCost < sShortestClimbPath ) { sBestClimbGridNo = sClimbGridNo; sShortestClimbPath = sPathCost; } } } } } gubGlobalPathFlags = 0; if (pBestPatient) { if (pBestPatient->ubAutoBandagingMedic != NOBODY) { // cancel that medic CancelAIAction( MercPtrs[ pBestPatient->ubAutoBandagingMedic ], TRUE ); } pBestPatient->ubAutoBandagingMedic = pSoldier->ubID; *pfDoClimb = FALSE; if ( CardinalSpacesAway( pSoldier->sGridNo, sBestPatientGridNo ) == 1 ) { pSoldier->aiData.usActionData = sBestPatientGridNo; return( AI_ACTION_GIVE_AID ); } else { pSoldier->aiData.usActionData = sBestAdjGridNo; return( AI_ACTION_GET_CLOSER ); } } else if (!TileIsOutOfBounds(sBestClimbGridNo)) { *pfDoClimb = TRUE; pSoldier->aiData.usActionData = sBestClimbGridNo; return( AI_ACTION_MOVE_TO_CLIMB ); } else { return( AI_ACTION_NONE ); } }