BOOLEAN FindAutobandageClimbPoint( INT32 sDesiredGridNo, BOOLEAN fClimbUp ) { // checks for existance of location to climb up to building, not occupied by a medic BUILDING * pBuilding; UINT8 ubNumClimbSpots; UINT8 ubLoop; UINT8 ubWhoIsThere; pBuilding = FindBuilding( sDesiredGridNo ); if (!pBuilding) { return( FALSE ); } ubNumClimbSpots = pBuilding->ubNumClimbSpots; for ( ubLoop = 0; ubLoop < ubNumClimbSpots; ubLoop++ ) { ubWhoIsThere = WhoIsThere2( pBuilding->sUpClimbSpots[ ubLoop ], 1 ); if ( ubWhoIsThere != NOBODY && !CanCharacterAutoBandageTeammate( MercPtrs[ ubWhoIsThere ] ) ) { continue; } ubWhoIsThere = WhoIsThere2( pBuilding->sDownClimbSpots[ ubLoop ], 0 ); if ( ubWhoIsThere != NOBODY && !CanCharacterAutoBandageTeammate( MercPtrs[ ubWhoIsThere ] ) ) { continue; } return( TRUE ); } return( FALSE ); }
BOOLEAN CheckOnBoxers( void ) { UINT32 uiLoop; UINT8 ubID; // repick boxer IDs every time if ( gubBoxerID[0] == NOBODY ) { // get boxer soldier IDs! for( uiLoop = 0; uiLoop < NUM_BOXERS; uiLoop++ ) { ubID = WhoIsThere2( gsBoxerGridNo[ uiLoop ], 0 ); // WANNE: Safty check! if (ubID < TOTAL_SOLDIERS) { if ( FindObjClass( MercPtrs[ ubID ], IC_WEAPON ) == NO_SLOT && IS_MERC_BODY_TYPE( MercPtrs[ ubID ] ) ) { // no weapon and not a civilian so this guy is a boxer gubBoxerID[ uiLoop ] = ubID; } } } } if ( gubBoxerID[ 0 ] == NOBODY && gubBoxerID[ 1 ] == NOBODY && gubBoxerID[ 2 ] == NOBODY ) { return( FALSE ); } return( TRUE ); }
BOOLEAN IsRepairableStructAtGridNo( INT16 sGridNo, UINT8 *pubID ) { UINT8 ubMerc; // OK, first look for a vehicle.... ubMerc = WhoIsThere2( sGridNo, 0 ); if ( pubID != NULL ) { (*pubID) = ubMerc; } if ( ubMerc != NOBODY ) { if ( MercPtrs[ ubMerc ]->uiStatusFlags & SOLDIER_VEHICLE ) { return( 2 ); } } // Then for over a robot.... // then for SAM site.... if ( DoesSAMExistHere( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, sGridNo ) ) { return( 3 ); } return( FALSE ); }
void SearchForOtherMembersWithinPitRadiusAndMakeThemFall( INT16 sGridNo, INT16 sRadius ) { INT16 x, y, sNewGridNo; UINT8 ubID; SOLDIERTYPE *pSoldier; PlayJA2Sample( CAVE_COLLAPSE, RATE_11025, SoundVolume( HIGHVOLUME, sGridNo ), 1, SoundDir( sGridNo ) ); for( y = -sRadius; y <= sRadius; y++ ) for( x = -sRadius; x <= sRadius; x++ ) { sNewGridNo = sGridNo + y * WORLD_COLS + x; //Validate gridno location, and check if there are any mercs here. If there are //any mercs, we want them to fall below. The exitgrid already exists at this location if( GridNoOnVisibleWorldTile( sNewGridNo ) ) { // Check if buddy exists here..... ubID = WhoIsThere2( sNewGridNo, 0 ); if ( ubID != NOBODY ) { // OK, make guy fall... // Set data to look for exit grid.... pSoldier = MercPtrs[ ubID ]; pSoldier->uiPendingActionData4 = sNewGridNo; EVENT_InitNewSoldierAnim( pSoldier, FALL_INTO_PIT, 0 , FALSE ); } } } }
void OutputDebugInfoForTurnBasedNextTileWaiting( SOLDIERTYPE * pSoldier ) { if ( (gTacticalStatus.uiFlags & INCOMBAT) && (pSoldier->usPathDataSize > 0) ) { UINT32 uiLoop; UINT16 usTemp; UINT16 usNewGridNo; usNewGridNo = NewGridNo( pSoldier->sGridNo, DirectionInc( (UINT8)pSoldier->usPathingData[ pSoldier->usPathIndex ] ) ); // provide more info!! DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String(" Soldier path size %d, index %d", pSoldier->usPathDataSize, pSoldier->usPathIndex ) ); DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String(" Who is at blocked gridno: %d", WhoIsThere2( usNewGridNo, pSoldier->bLevel ) ) ); for ( uiLoop = 0; uiLoop < pSoldier->usPathDataSize; uiLoop++ ) { if ( uiLoop > pSoldier->usPathIndex ) { usTemp = NewGridNo( usTemp, DirectionInc( (UINT8)pSoldier->usPathingData[ uiLoop ] ) ); DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String(" Soldier path[%d]: %d == gridno %d", uiLoop, pSoldier->usPathingData[uiLoop], usTemp ) ); } else if ( uiLoop == pSoldier->usPathIndex ) { usTemp = usNewGridNo; DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String(" Soldier path[%d]: %d == gridno %d", uiLoop, pSoldier->usPathingData[uiLoop], usTemp ) ); } else { DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String(" Soldier path[%d]: %d", uiLoop, pSoldier->usPathingData[uiLoop] ) ); } } } }
void SetDelayedTileWaiting( SOLDIERTYPE *pSoldier, INT16 sCauseGridNo, INT8 bValue ) { UINT8 ubPerson; // Cancel AI Action // CancelAIAction( pSoldier, TRUE ); pSoldier->fDelayedMovement = bValue; pSoldier->sDelayedMovementCauseGridNo = sCauseGridNo; RESETTIMECOUNTER( pSoldier->NextTileCounter, NEXT_TILE_CHECK_DELAY ); // ATE: Now update realtime movement speed.... // check if guy exists here... ubPerson = WhoIsThere2( sCauseGridNo, pSoldier->bLevel ); // There may not be anybody there, but it's reserved by them! if ( ( gpWorldLevelData[ sCauseGridNo ].uiFlags & MAPELEMENT_MOVEMENT_RESERVED ) ) { ubPerson = gpWorldLevelData[ sCauseGridNo ].ubReservedSoldierID; } if ( ubPerson != NOBODY ) { // if they are our own team members ( both ) if ( MercPtrs[ ubPerson ]->bTeam == gbPlayerNum && pSoldier->bTeam == gbPlayerNum ) { // Here we have another guy.... save his stats so we can use them for // speed determinations.... pSoldier->bOverrideMoveSpeed = ubPerson; pSoldier->fUseMoverrideMoveSpeed = TRUE; } } }
INT16 FindClosestClimbPoint( INT16 sStartGridNo, INT16 sDesiredGridNo, BOOLEAN fClimbUp ) { BUILDING * pBuilding; UINT8 ubNumClimbSpots; INT16 * psClimbSpots; UINT8 ubLoop; INT16 sDistance, sClosestDistance = 1000, sClosestSpot= NOWHERE; pBuilding = FindBuilding( sDesiredGridNo ); if (!pBuilding) { return( NOWHERE ); } ubNumClimbSpots = pBuilding->ubNumClimbSpots; if (fClimbUp) { psClimbSpots = pBuilding->sUpClimbSpots; } else { psClimbSpots = pBuilding->sDownClimbSpots; } for ( ubLoop = 0; ubLoop < ubNumClimbSpots; ubLoop++ ) { if ( (WhoIsThere2( pBuilding->sUpClimbSpots[ ubLoop ], 0 ) == NOBODY) && (WhoIsThere2( pBuilding->sDownClimbSpots[ ubLoop ], 1 ) == NOBODY) ) { sDistance = PythSpacesAway( sStartGridNo, psClimbSpots[ ubLoop ] ); if (sDistance < sClosestDistance ) { sClosestDistance = sDistance; sClosestSpot = psClimbSpots[ ubLoop ]; } } } return( sClosestSpot ); }
BOOLEAN BoxerExists( void ) { UINT32 uiLoop; for( uiLoop = 0; uiLoop < NUM_BOXERS; ++uiLoop ) { if ( WhoIsThere2( gsBoxerGridNo[ uiLoop ], 0 ) != NOBODY ) { return( TRUE ); } } return( FALSE ); }
void SkillSelection::Functions( UINT32 aVal ) { Cancel(); SOLDIERTYPE * pSoldier = NULL; GetSoldier( &pSoldier, gusSelectedSoldier ); if ( pSoldier == NULL ) return; UINT8 ubID = WhoIsThere2(sTraitsMenuTargetGridNo, 0 ); pSoldier->UseSkill(aVal, sTraitsMenuTargetGridNo, ubID); Cancel(); gTraitSelection.Cancel(); }
BOOLEAN IsRefuelableStructAtGridNo( INT16 sGridNo, UINT8 *pubID ) { UINT8 ubMerc; // OK, first look for a vehicle.... ubMerc = WhoIsThere2( sGridNo, 0 ); if ( pubID != NULL ) { (*pubID) = ubMerc; } if ( ubMerc != NOBODY ) { if ( MercPtrs[ ubMerc ]->uiStatusFlags & SOLDIER_VEHICLE ) { return( TRUE ); } } 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 ); } }
BOOLEAN HandleNextTileWaiting( SOLDIERTYPE *pSoldier ) { // Buddy is waiting to continue his path INT8 bBlocked, bPathBlocked; INT16 sCost; INT16 sNewGridNo, sCheckGridNo; UINT8 ubDirection, bCauseDirection; UINT8 ubPerson; UINT8 fFlags = 0; if ( pSoldier->fDelayedMovement ) { if ( TIMECOUNTERDONE( pSoldier->NextTileCounter, NEXT_TILE_CHECK_DELAY ) ) { RESETTIMECOUNTER( pSoldier->NextTileCounter, NEXT_TILE_CHECK_DELAY ); // Get direction from gridno... bCauseDirection = (INT8)GetDirectionToGridNoFromGridNo( pSoldier->sGridNo, pSoldier->sDelayedMovementCauseGridNo ); bBlocked = TileIsClear( pSoldier, bCauseDirection, pSoldier->sDelayedMovementCauseGridNo, pSoldier->bLevel ); // If we are waiting for a temp blockage.... continue to wait if ( pSoldier->fDelayedMovement >= 100 && bBlocked == MOVE_TILE_TEMP_BLOCKED ) { // ATE: Increment 1 pSoldier->fDelayedMovement++; // Are we close enough to give up? ( and are a pc ) if ( pSoldier->fDelayedMovement > 120 ) { // Quit... SetFinalTile( pSoldier, pSoldier->sGridNo, TRUE ); pSoldier->fDelayedMovement = FALSE; } return( TRUE ); } // Try new path if anything but temp blockage! if ( bBlocked != MOVE_TILE_TEMP_BLOCKED ) { // Set to normal delay if ( pSoldier->fDelayedMovement >= 100 && pSoldier->fDelayedMovement != 150 ) { pSoldier->fDelayedMovement = 1; } // Default to pathing through people fFlags = PATH_THROUGH_PEOPLE; // Now, if we are in the state where we are desparently trying to get out... // Use other flag // CJC: path-through-people includes ignoring person at dest /* if ( pSoldier->fDelayedMovement >= 150 ) { fFlags = PATH_IGNORE_PERSON_AT_DEST; } */ // Check destination first! if ( pSoldier->sAbsoluteFinalDestination == pSoldier->sFinalDestination ) { // on last lap of scripted move, make sure we get to final dest sCheckGridNo = pSoldier->sAbsoluteFinalDestination; } else if (!NewOKDestination( pSoldier, pSoldier->sFinalDestination, TRUE, pSoldier->bLevel )) { if ( pSoldier->fDelayedMovement >= 150 ) { // OK, look around dest for the first one! sCheckGridNo = FindGridNoFromSweetSpot( pSoldier, pSoldier->sFinalDestination, 6, &ubDirection ); if ( sCheckGridNo == NOWHERE ) { // If this is nowhere, try harder! sCheckGridNo = FindGridNoFromSweetSpot( pSoldier, pSoldier->sFinalDestination, 16, &ubDirection ); } } else { // OK, look around dest for the first one! sCheckGridNo = FindGridNoFromSweetSpotThroughPeople( pSoldier, pSoldier->sFinalDestination, 6, &ubDirection ); if ( sCheckGridNo == NOWHERE ) { // If this is nowhere, try harder! sCheckGridNo = FindGridNoFromSweetSpotThroughPeople( pSoldier, pSoldier->sFinalDestination, 16, &ubDirection ); } } } else { sCheckGridNo = pSoldier->sFinalDestination; } // Try another path to destination // ATE: Allow path to exit grid! if ( pSoldier->ubWaitActionToDo == 1 && gubWaitingForAllMercsToExitCode == WAIT_FOR_MERCS_TO_WALK_TO_GRIDNO ) { gfPlotPathToExitGrid = TRUE; } sCost = (INT16) FindBestPath( pSoldier, sCheckGridNo, pSoldier->bLevel, pSoldier->usUIMovementMode, NO_COPYROUTE, fFlags ); gfPlotPathToExitGrid = FALSE; // Can we get there if ( sCost > 0 ) { // Is the next tile blocked too? sNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, DirectionInc( (UINT8)guiPathingData[ 0 ] ) ); bPathBlocked = TileIsClear( pSoldier, (UINT8)guiPathingData[ 0 ], sNewGridNo, pSoldier->bLevel ); if ( bPathBlocked == MOVE_TILE_STATIONARY_BLOCKED ) { // Try to path around everyone except dest person if ( pSoldier->ubWaitActionToDo == 1 && gubWaitingForAllMercsToExitCode == WAIT_FOR_MERCS_TO_WALK_TO_GRIDNO ) { gfPlotPathToExitGrid = TRUE; } sCost = (INT16) FindBestPath( pSoldier, sCheckGridNo, pSoldier->bLevel, pSoldier->usUIMovementMode, NO_COPYROUTE, PATH_IGNORE_PERSON_AT_DEST ); gfPlotPathToExitGrid = FALSE; // Is the next tile in this new path blocked too? sNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, DirectionInc( (UINT8)guiPathingData[ 0 ] ) ); bPathBlocked = TileIsClear( pSoldier, (UINT8)guiPathingData[ 0 ], sNewGridNo, pSoldier->bLevel ); // now working with a path which does not go through people pSoldier->ubDelayedMovementFlags &= (~DELAYED_MOVEMENT_FLAG_PATH_THROUGH_PEOPLE); } else { // path through people worked fine if ( pSoldier->fDelayedMovement < 150 ) { pSoldier->ubDelayedMovementFlags |= DELAYED_MOVEMENT_FLAG_PATH_THROUGH_PEOPLE; } } // Are we clear? if ( bPathBlocked == MOVE_TILE_CLEAR ) { // Go for it path! if ( pSoldier->ubWaitActionToDo == 1 && gubWaitingForAllMercsToExitCode == WAIT_FOR_MERCS_TO_WALK_TO_GRIDNO ) { gfPlotPathToExitGrid = TRUE; } //pSoldier->fDelayedMovement = FALSE; // ATE: THis will get set in EENT_GetNewSoldierPath.... pSoldier->usActionData = sCheckGridNo; pSoldier->bPathStored = FALSE; EVENT_GetNewSoldierPath( pSoldier, sCheckGridNo, pSoldier->usUIMovementMode ); gfPlotPathToExitGrid = FALSE; return( TRUE ); } } pSoldier->fDelayedMovement++; if ( pSoldier->fDelayedMovement == 99 ) { // Cap at 99 pSoldier->fDelayedMovement = 99; } // Do we want to force a swap? if (pSoldier->fDelayedMovement == 3 && (pSoldier->sAbsoluteFinalDestination != NOWHERE || gTacticalStatus.fAutoBandageMode) ) { // with person who is in the way? ubPerson = WhoIsThere2( pSoldier->sDelayedMovementCauseGridNo, pSoldier->bLevel ); // if either on a mission from god, or two AI guys not on stationary... if ( ubPerson != NOBODY && ( pSoldier->ubQuoteRecord != 0 || ( pSoldier->bTeam != gbPlayerNum && pSoldier->bOrders != STATIONARY && MercPtrs[ ubPerson ]->bTeam != gbPlayerNum && MercPtrs[ ubPerson ]->bOrders != STATIONARY ) || (pSoldier->bTeam == gbPlayerNum && gTacticalStatus.fAutoBandageMode && !(MercPtrs[ ubPerson ]->bTeam == CIV_TEAM && MercPtrs[ ubPerson ]->bOrders == STATIONARY ) ) ) ) { // Swap now! //MercPtrs[ ubPerson ]->fBlockedByAnotherMerc = FALSE; // Restore final dest.... //MercPtrs[ ubPerson ]->sFinalDestination = sTempDestGridNo; // Swap merc positions..... SwapMercPositions( pSoldier, MercPtrs[ ubPerson ] ); // With these two guys swapped, we should try to continue on our way.... pSoldier->fDelayedMovement = FALSE; // We must calculate the path here so that we can give it the "through people" parameter if ( gTacticalStatus.fAutoBandageMode && pSoldier->sAbsoluteFinalDestination == NOWHERE ) { FindBestPath( pSoldier, pSoldier->sFinalDestination, pSoldier->bLevel, pSoldier->usUIMovementMode, COPYROUTE, PATH_THROUGH_PEOPLE ); } else if ( pSoldier->sAbsoluteFinalDestination != NOWHERE && !FindBestPath( pSoldier, pSoldier->sAbsoluteFinalDestination, pSoldier->bLevel, pSoldier->usUIMovementMode, COPYROUTE, PATH_THROUGH_PEOPLE ) ) { // check to see if we're there now! if ( pSoldier->sGridNo == pSoldier->sAbsoluteFinalDestination ) { NPCReachedDestination( pSoldier, FALSE ); pSoldier->bNextAction = AI_ACTION_WAIT; pSoldier->usNextActionData = 500; return( TRUE ); } } pSoldier->bPathStored = TRUE; EVENT_GetNewSoldierPath( pSoldier, pSoldier->sAbsoluteFinalDestination, pSoldier->usUIMovementMode ); //EVENT_GetNewSoldierPath( MercPtrs[ ubPerson ], MercPtrs[ ubPerson ]->sFinalDestination, MercPtrs[ ubPerson ]->usUIMovementMode ); } } // Are we close enough to give up? ( and are a pc ) if ( pSoldier->fDelayedMovement > 20 && pSoldier->fDelayedMovement != 150) { if ( PythSpacesAway( pSoldier->sGridNo, pSoldier->sFinalDestination ) < 5 && pSoldier->bTeam == gbPlayerNum ) { // Quit... SetFinalTile( pSoldier, pSoldier->sGridNo, FALSE ); pSoldier->fDelayedMovement = FALSE; } } // Are we close enough to give up? ( and are a pc ) if ( pSoldier->fDelayedMovement > 170 ) { if ( PythSpacesAway( pSoldier->sGridNo, pSoldier->sFinalDestination ) < 5 && pSoldier->bTeam == gbPlayerNum ) { // Quit... SetFinalTile( pSoldier, pSoldier->sGridNo, FALSE ); pSoldier->fDelayedMovement = FALSE; } } } } } return( TRUE ); }
INT8 TileIsClear( SOLDIERTYPE *pSoldier, INT8 bDirection, INT16 sGridNo, INT8 bLevel ) { UINT8 ubPerson; INT16 sTempDestGridNo; INT16 sNewGridNo; BOOLEAN fSwapInDoor = FALSE; if ( sGridNo == NOWHERE ) { return( MOVE_TILE_CLEAR ); } ubPerson = WhoIsThere2( sGridNo, bLevel ); if ( ubPerson != NO_SOLDIER ) { // If this us? if ( ubPerson != pSoldier->ubID ) { // OK, set flag indicating we are blocked by a merc.... if ( pSoldier->bTeam != gbPlayerNum ) // CJC: shouldn't this be in all cases??? //if ( 0 ) { pSoldier->fBlockedByAnotherMerc = TRUE; // Set direction we were trying to goto pSoldier->bBlockedByAnotherMercDirection = bDirection; // Are we only temporarily blocked? // Check if our final destination is = our gridno if ( ( MercPtrs[ ubPerson ]->sFinalDestination == MercPtrs[ ubPerson ]->sGridNo ) ) { return( MOVE_TILE_STATIONARY_BLOCKED ); } else { // OK, if buddy who is blocking us is trying to move too... // And we are in opposite directions... if ( MercPtrs[ ubPerson ]->fBlockedByAnotherMerc && MercPtrs[ ubPerson ]->bBlockedByAnotherMercDirection == gOppositeDirection[ bDirection ] ) { // OK, try and get a path around buddy.... // We have to temporarily make buddy stopped... sTempDestGridNo = MercPtrs[ ubPerson ]->sFinalDestination; MercPtrs[ ubPerson ]->sFinalDestination = MercPtrs[ ubPerson ]->sGridNo; if ( PlotPath( pSoldier, pSoldier->sFinalDestination, NO_COPYROUTE, NO_PLOT, TEMPORARY, pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints ) ) { pSoldier->bPathStored = FALSE; // OK, make guy go here... EVENT_GetNewSoldierPath( pSoldier, pSoldier->sFinalDestination, pSoldier->usUIMovementMode ); // Restore final dest.... MercPtrs[ ubPerson ]->sFinalDestination = sTempDestGridNo; pSoldier->fBlockedByAnotherMerc = FALSE; // Is the next tile blocked too? sNewGridNo = NewGridNo( (UINT16)pSoldier->sGridNo, DirectionInc( (UINT8)guiPathingData[ 0 ] ) ); return( TileIsClear( pSoldier, (UINT8)guiPathingData[ 0 ], sNewGridNo, pSoldier->bLevel ) ); } else { // Not for multi-tiled things... if ( !( pSoldier->uiStatusFlags & SOLDIER_MULTITILE ) ) { // Is the next movement cost for a door? if ( DoorTravelCost( pSoldier, sGridNo, gubWorldMovementCosts[ sGridNo ][ bDirection ][ pSoldier->bLevel ], (BOOLEAN)( pSoldier->bTeam == gbPlayerNum ), NULL ) == TRAVELCOST_DOOR ) { fSwapInDoor = TRUE; } // If we are to swap and we're near a door, open door first and then close it...? // Swap now! MercPtrs[ ubPerson ]->fBlockedByAnotherMerc = FALSE; // Restore final dest.... MercPtrs[ ubPerson ]->sFinalDestination = sTempDestGridNo; // Swap merc positions..... SwapMercPositions( pSoldier, MercPtrs[ ubPerson ] ); // With these two guys swapped, they should try and continue on their way.... // Start them both again along their way... EVENT_GetNewSoldierPath( pSoldier, pSoldier->sFinalDestination, pSoldier->usUIMovementMode ); EVENT_GetNewSoldierPath( MercPtrs[ ubPerson ], MercPtrs[ ubPerson ]->sFinalDestination, MercPtrs[ ubPerson ]->usUIMovementMode ); } } } return( MOVE_TILE_TEMP_BLOCKED ); } } else { //return( MOVE_TILE_STATIONARY_BLOCKED ); // ATE: OK, put some smartshere... // If we are waiting for more than a few times, change to stationary... if ( MercPtrs[ ubPerson ]->fDelayedMovement >= 105 ) { // Set to special 'I want to walk through people' value pSoldier->fDelayedMovement = 150; return( MOVE_TILE_STATIONARY_BLOCKED ); } if ( MercPtrs[ ubPerson ]->sGridNo == MercPtrs[ ubPerson ]->sFinalDestination ) { return( MOVE_TILE_STATIONARY_BLOCKED ); } return( MOVE_TILE_TEMP_BLOCKED ); } } } if ( ( gpWorldLevelData[ sGridNo ].uiFlags & MAPELEMENT_MOVEMENT_RESERVED ) ) { if ( gpWorldLevelData[ sGridNo ].ubReservedSoldierID != pSoldier->ubID ) { return( MOVE_TILE_TEMP_BLOCKED ); } } // Are we clear of structs? if ( !NewOKDestination( pSoldier, sGridNo, FALSE, pSoldier->bLevel ) ) { // ATE: Fence cost is an exclusiuon here.... if ( gubWorldMovementCosts[ sGridNo ][ bDirection ][ pSoldier->bLevel ] != TRAVELCOST_FENCE ) { // ATE: HIdden structs - we do something here... reveal it! if ( gubWorldMovementCosts[ sGridNo ][ bDirection ][ pSoldier->bLevel ] == TRAVELCOST_HIDDENOBSTACLE ) { gpWorldLevelData[ sGridNo ].uiFlags|=MAPELEMENT_REVEALED; gpWorldLevelData[ sGridNo ].uiFlags|=MAPELEMENT_REDRAW; SetRenderFlags(RENDER_FLAG_MARKED); RecompileLocalMovementCosts( (UINT16)sGridNo ); } // Unset flag for blocked by soldier... pSoldier->fBlockedByAnotherMerc = FALSE; return( MOVE_TILE_STATIONARY_BLOCKED ); } else { #if 0 // Check if there is a reserved marker here at least.... sNewGridNo = NewGridNo( sGridNo, DirectionInc( bDirection ) ); if ( ( gpWorldLevelData[ sNewGridNo ].uiFlags & MAPELEMENT_MOVEMENT_RESERVED ) ) { if ( gpWorldLevelData[ sNewGridNo ].ubReservedSoldierID != pSoldier->ubID ) { return( MOVE_TILE_TEMP_BLOCKED ); } } #endif } } // Unset flag for blocked by soldier... pSoldier->fBlockedByAnotherMerc = FALSE; return( MOVE_TILE_CLEAR ); }