void PossiblyMakeThisEnemyChosenOne( SOLDIERTYPE * pSoldier ) { INT32 iAPCost, iPathCost; //INT8 bOldKeys; INT8 bPanicTrigger; INT16 sPanicTriggerGridNo; UINT32 uiPercentEnemiesKilled; if ( ! (gTacticalStatus.fPanicFlags & PANIC_TRIGGERS_HERE) ) { return; } if ( pSoldier->bLevel != 0 ) { // screw having guys on the roof go for panic triggers! return; } bPanicTrigger = ClosestPanicTrigger( pSoldier ); if (bPanicTrigger == -1) { return; } sPanicTriggerGridNo = gTacticalStatus.sPanicTriggerGridNo[ bPanicTrigger ]; uiPercentEnemiesKilled = (UINT32)( 100 * (UINT32)(gTacticalStatus.ubArmyGuysKilled) / (UINT32)( gTacticalStatus.Team[ ENEMY_TEAM ].bMenInSector + gTacticalStatus.ubArmyGuysKilled ) ); if ( gTacticalStatus.ubPanicTolerance[ bPanicTrigger ] > uiPercentEnemiesKilled ) { // not yet... not yet return; } //bOldKeys = pSoldier->bHasKeys; pSoldier->bHasKeys = (pSoldier->bHasKeys << 1) | 1; // if he can't get to a spot where he could get at the panic trigger iAPCost = AP_PULL_TRIGGER; if (pSoldier->sGridNo != sPanicTriggerGridNo) { iPathCost = PlotPath( pSoldier, sPanicTriggerGridNo, FALSE, FALSE, FALSE, RUNNING, FALSE, FALSE, 0); if (iPathCost == 0) { //pSoldier->bHasKeys = bOldKeys; pSoldier->bHasKeys = (pSoldier->bHasKeys >> 1); return; }
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 ); } }
int LegalNPCDestination(SOLDIERTYPE *pSoldier, INT16 sGridno, UINT8 ubPathMode, UINT8 ubWaterOK, UINT8 fFlags) { BOOLEAN fSkipTilesWithMercs; if ((sGridno < 0) || (sGridno >= GRIDSIZE)) { #ifdef RECORDNET fprintf(NetDebugFile,"LegalNPC->sDestination: ERROR - rcvd invalid gridno %d",gridno); #endif #ifdef BETAVERSION NumMessage("LegalNPC->sDestination: ERROR - rcvd invalid gridno ",gridno); #endif return(FALSE); } // return false if gridno on different level from merc if ( GridNoOnVisibleWorldTile( pSoldier->sGridNo ) && gpWorldLevelData[ pSoldier->sGridNo ].sHeight != gpWorldLevelData[ sGridno ].sHeight ) { return( FALSE ); } // skip mercs if turnbased and adjacent AND not doing an IGNORE_PATH check (which is used almost exclusively by GoAsFarAsPossibleTowards) fSkipTilesWithMercs = (gfTurnBasedAI && ubPathMode != IGNORE_PATH && SpacesAway( pSoldier->sGridNo, sGridno ) == 1 ); // if this gridno is an OK destination // AND the gridno is NOT in a tear-gassed tile when we have no gas mask // AND someone is NOT already standing there // AND we're NOT already standing at that gridno // AND the gridno hasn't been black-listed for us // Nov 28 98: skip people in destination tile if in turnbased if ( ( NewOKDestination(pSoldier, sGridno, fSkipTilesWithMercs, pSoldier->bLevel ) ) && ( !InGas( pSoldier, sGridno ) ) && ( sGridno != pSoldier->sGridNo ) && ( sGridno != pSoldier->sBlackList ) ) /* if ( ( NewOKDestination(pSoldier, sGridno, FALSE, pSoldier->bLevel ) ) && ( !(gpWorldLevelData[ sGridno ].ubExtFlags[0] & (MAPELEMENT_EXT_SMOKE | MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS)) || ( pSoldier->inv[ HEAD1POS ].usItem == GASMASK || pSoldier->inv[ HEAD2POS ].usItem == GASMASK ) ) && ( sGridno != pSoldier->sGridNo ) && ( sGridno != pSoldier->sBlackList ) )*/ /* if ( ( NewOKDestination(pSoldier,sGridno,ALLPEOPLE, pSoldier->bLevel ) ) && ( !(gpWorldLevelData[ sGridno ].ubExtFlags[0] & (MAPELEMENT_EXT_SMOKE | MAPELEMENT_EXT_TEARGAS | MAPELEMENT_EXT_MUSTARDGAS)) || ( pSoldier->inv[ HEAD1POS ].usItem == GASMASK || pSoldier->inv[ HEAD2POS ].usItem == GASMASK ) ) && ( sGridno != pSoldier->sGridNo ) && ( sGridno != pSoldier->sBlackList ) ) */ { // if water's a problem, and gridno is in a water tile (bridges are OK) if (!ubWaterOK && Water(sGridno)) return(FALSE); // passed all checks, now try to make sure we can get there! switch (ubPathMode) { // if finding a path wasn't asked for (could have already been done, // for example), don't bother case IGNORE_PATH : return(TRUE); case ENSURE_PATH : if ( FindBestPath( pSoldier, sGridno, pSoldier->bLevel, WALKING, COPYROUTE, fFlags ) ) { return(TRUE); // legal destination } else // got this far, but found no clear path, { // so test fails return(FALSE); } // *** NOTE: movement mode hardcoded to WALKING !!!!! case ENSURE_PATH_COST: return(PlotPath(pSoldier,sGridno,FALSE,FALSE,FALSE,WALKING,FALSE,FALSE,0)); default : #ifdef BETAVERSION NumMessage("LegalNPC->sDestination: ERROR - illegal pathMode = ",ubPathMode); #endif return(FALSE); } } else // something failed - didn't even have to test path return(FALSE); // illegal destination }
BOOLEAN AddUIPlan( UINT16 sGridNo, UINT8 ubPlanID ) { SOLDIERTYPE *pPlanSoldier; INT16 sXPos, sYPos; INT16 sAPCost = 0; INT8 bDirection; INT32 iLoop; SOLDIERCREATE_STRUCT MercCreateStruct; UINT8 ubNewIndex; // Depeding on stance and direction facing, add guy! // If we have a planned action here, ignore! // If not OK Dest, ignore! if ( !NewOKDestination( gpUIPlannedSoldier, sGridNo, FALSE, (INT8)gsInterfaceLevel ) ) { return( FALSE ); } if ( ubPlanID == UIPLAN_ACTION_MOVETO ) { // Calculate cost to move here sAPCost = PlotPath( gpUIPlannedSoldier, sGridNo, COPYROUTE, NO_PLOT, TEMPORARY, (UINT16) gpUIPlannedSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, gpUIPlannedSoldier->bActionPoints ); // Adjust for running if we are not already running if ( gpUIPlannedSoldier->usUIMovementMode == RUNNING ) { sAPCost += AP_START_RUN_COST; } if ( EnoughPoints( gpUIPlannedSoldier, sAPCost, 0, FALSE ) ) { memset( &MercCreateStruct, 0, sizeof( MercCreateStruct ) ); MercCreateStruct.bTeam = SOLDIER_CREATE_AUTO_TEAM; MercCreateStruct.ubProfile = NO_PROFILE; MercCreateStruct.fPlayerPlan = TRUE; MercCreateStruct.bBodyType = gpUIPlannedSoldier->ubBodyType; MercCreateStruct.sInsertionGridNo = sGridNo; // Get Grid Corrdinates of mouse if ( TacticalCreateSoldier( &MercCreateStruct, &ubNewIndex ) ) { // Get pointer to soldier GetSoldier( &pPlanSoldier, (UINT16)ubNewIndex ); pPlanSoldier->sPlannedTargetX = -1; pPlanSoldier->sPlannedTargetY = -1; // Compare OPPLISTS! // Set ones we don't know about but do now back to old ( ie no new guys ) for (iLoop = 0; iLoop < MAX_NUM_SOLDIERS; iLoop++ ) { if ( gpUIPlannedSoldier->bOppList[ iLoop ] < 0 ) { pPlanSoldier->bOppList[ iLoop ] = gpUIPlannedSoldier->bOppList[ iLoop ]; } } // Get XY from Gridno ConvertGridNoToCenterCellXY( sGridNo, &sXPos, &sYPos ); EVENT_SetSoldierPosition( pPlanSoldier, sXPos, sYPos ); EVENT_SetSoldierDestination( pPlanSoldier, sGridNo ); pPlanSoldier->bVisible = 1; pPlanSoldier->usUIMovementMode = gpUIPlannedSoldier->usUIMovementMode; pPlanSoldier->bActionPoints = gpUIPlannedSoldier->bActionPoints - sAPCost; pPlanSoldier->ubPlannedUIAPCost = (UINT8)pPlanSoldier->bActionPoints; // Get direction bDirection = (INT8)gpUIPlannedSoldier->usPathingData[ gpUIPlannedSoldier->usPathDataSize - 1 ]; // Set direction pPlanSoldier->bDirection = bDirection; pPlanSoldier->bDesiredDirection = bDirection; // Set walking animation ChangeSoldierState( pPlanSoldier, pPlanSoldier->usUIMovementMode, 0, FALSE ); // Change selected soldier gusSelectedSoldier = (UINT16)pPlanSoldier->ubID; // Change global planned mode to this guy! gpUIPlannedSoldier = pPlanSoldier; gubNumUIPlannedMoves++; gfPlotNewMovement = TRUE; ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Adding Merc Move to Plan" ); } } else { ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Merc will not have enough action points" ); } } else if ( ubPlanID == UIPLAN_ACTION_FIRE ) { sAPCost = CalcTotalAPsToAttack( gpUIPlannedSoldier, sGridNo, TRUE, (INT8)(gpUIPlannedSoldier->bShownAimTime /2) ); // Get XY from Gridno ConvertGridNoToCenterCellXY( sGridNo, &sXPos, &sYPos ); // If this is a player guy, show message about no APS if ( EnoughPoints( gpUIPlannedSoldier, sAPCost, 0, FALSE ) ) { // CHECK IF WE ARE A PLANNED SOLDIER OR NOT< IF SO< CREATE! if ( gpUIPlannedSoldier->ubID < MAX_NUM_SOLDIERS ) { memset( &MercCreateStruct, 0, sizeof( MercCreateStruct ) ); MercCreateStruct.bTeam = SOLDIER_CREATE_AUTO_TEAM; MercCreateStruct.ubProfile = NO_PROFILE; MercCreateStruct.fPlayerPlan = TRUE; MercCreateStruct.bBodyType = gpUIPlannedSoldier->ubBodyType; MercCreateStruct.sInsertionGridNo = sGridNo; // Get Grid Corrdinates of mouse if ( TacticalCreateSoldier( &MercCreateStruct, &ubNewIndex ) ) { // Get pointer to soldier GetSoldier( &pPlanSoldier, (UINT16)ubNewIndex ); pPlanSoldier->sPlannedTargetX = -1; pPlanSoldier->sPlannedTargetY = -1; // Compare OPPLISTS! // Set ones we don't know about but do now back to old ( ie no new guys ) for (iLoop = 0; iLoop < MAX_NUM_SOLDIERS; iLoop++ ) { if ( gpUIPlannedSoldier->bOppList[ iLoop ] < 0 ) { pPlanSoldier->bOppList[ iLoop ] = gpUIPlannedSoldier->bOppList[ iLoop ]; } } EVENT_SetSoldierPosition( pPlanSoldier, gpUIPlannedSoldier->dXPos, gpUIPlannedSoldier->dYPos ); EVENT_SetSoldierDestination( pPlanSoldier, gpUIPlannedSoldier->sGridNo ); pPlanSoldier->bVisible = 1; pPlanSoldier->usUIMovementMode = gpUIPlannedSoldier->usUIMovementMode; pPlanSoldier->bActionPoints = gpUIPlannedSoldier->bActionPoints - sAPCost; pPlanSoldier->ubPlannedUIAPCost = (UINT8)pPlanSoldier->bActionPoints; // Get direction bDirection = (INT8)gpUIPlannedSoldier->usPathingData[ gpUIPlannedSoldier->usPathDataSize - 1 ]; // Set direction pPlanSoldier->bDirection = bDirection; pPlanSoldier->bDesiredDirection = bDirection; // Set walking animation ChangeSoldierState( pPlanSoldier, pPlanSoldier->usUIMovementMode, 0, FALSE ); // Change selected soldier gusSelectedSoldier = (UINT16)pPlanSoldier->ubID; // Change global planned mode to this guy! gpUIPlannedSoldier = pPlanSoldier; gubNumUIPlannedMoves++; } } gpUIPlannedSoldier->bActionPoints = gpUIPlannedSoldier->bActionPoints - sAPCost; gpUIPlannedSoldier->ubPlannedUIAPCost = (UINT8)gpUIPlannedSoldier->bActionPoints; // Get direction from gridno bDirection = (INT8)GetDirectionFromGridNo( sGridNo, gpUIPlannedSoldier ); // Set direction gpUIPlannedSoldier->bDirection = bDirection; gpUIPlannedSoldier->bDesiredDirection = bDirection; // Set to shooting animation SelectPausedFireAnimation( gpUIPlannedSoldier ); gpUIPlannedSoldier->sPlannedTargetX = sXPos; gpUIPlannedSoldier->sPlannedTargetY = sYPos; ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Adding Merc Shoot to Plan" ); } else { ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Merc will not have enough action points" ); } } return( TRUE ); }
void MakeClosestEnemyChosenOne() { UINT32 cnt; INT16 sPathCost, sShortestPath = 1000; INT8 bOldKeys = -1; UINT8 ubClosestEnemy = NOBODY; SOLDIERTYPE * pSoldier; INT8 bPanicTrigger; INT16 sPanicTriggerGridNo; if ( ! (gTacticalStatus.fPanicFlags & PANIC_TRIGGERS_HERE) ) { #ifdef BETAVERSION PopMessage("MakeClosestEnemyChosenOne: ERROR - Panic Trigger is NOWHERE"); #endif return; } if (!NeedToRadioAboutPanicTrigger() ) { // no active panic triggers return; } // consider every enemy, looking for the closest capable, unbusy one for (cnt = 0; cnt < guiNumMercSlots; cnt++) { pSoldier = MercSlots[cnt]; if (!pSoldier) // if this merc is inactive, or not here { continue; } // if this merc is unconscious, or dead if (pSoldier->bLife < OKLIFE) { continue; // next soldier } // if this guy's too tired to go if (pSoldier->bBreath < OKBREATH) { continue; // next soldier } if ( gWorldSectorX == TIXA_SECTOR_X && gWorldSectorY == TIXA_SECTOR_Y ) { if ( pSoldier->ubProfile != WARDEN ) { continue; } } else { // only consider for army guys if (pSoldier->bTeam != ENEMY_TEAM ) { continue; } } // if this guy is in battle with opponent(s) if (pSoldier->bOppCnt > 0) { continue; // next soldier } // if this guy is still in serious shock if (pSoldier->bShock > 2) { continue; // next soldier } if ( pSoldier->bLevel != 0 ) { // screw having guys on the roof go for panic triggers! continue; // next soldier } bPanicTrigger = ClosestPanicTrigger( pSoldier ); if (bPanicTrigger == -1) { continue; // next soldier } sPanicTriggerGridNo = gTacticalStatus.sPanicTriggerGridNo[ bPanicTrigger ]; if (sPanicTriggerGridNo == NOWHERE) { // this should never happen! continue; } // remember whether this guy had keys before //bOldKeys = pSoldier->bHasKeys; // give him keys to see if with them he can get to the panic trigger pSoldier->bHasKeys = (pSoldier->bHasKeys << 1) | 1; // we now path directly to the panic trigger // if he can't get to a spot where he could get at the panic trigger /* if ( FindAdjacentGridEx( pSoldier, gTacticalStatus.sPanicTriggerGridno, &ubDirection, &sAdjSpot, FALSE, FALSE ) == -1 ) { pSoldier->bHasKeys = bOldKeys; continue; // next merc } */ // ok, this enemy appears to be eligible // FindAdjacentGrid set HandGrid for us. If we aren't at that spot already if (pSoldier->sGridNo != sPanicTriggerGridNo) { // get the AP cost for this enemy to go to target position sPathCost = PlotPath( pSoldier, sPanicTriggerGridNo, FALSE, FALSE, FALSE, WALKING, FALSE, FALSE, 0); } else { sPathCost = 0; } // set his keys value back to what it was before this hack pSoldier->bHasKeys = (pSoldier->bHasKeys >> 1 ); // if he can get there (or is already there!) if (sPathCost || (pSoldier->sGridNo == sPanicTriggerGridNo)) { if (sPathCost < sShortestPath) { sShortestPath = sPathCost; ubClosestEnemy = pSoldier->ubID; } } //else //NameMessage(pSoldier,"can't get there..."); } // if we found have an eligible enemy, make him our "chosen one" if (ubClosestEnemy < NOBODY) { gTacticalStatus.ubTheChosenOne = ubClosestEnemy; // flag him as the chosen one #ifdef TESTVERSION NumMessage("TEST MSG: The chosen one is ",TheChosenOne); #endif pSoldier = MercPtrs[gTacticalStatus.ubTheChosenOne]; if ( pSoldier->bAlertStatus < STATUS_RED ) { pSoldier->bAlertStatus = STATUS_RED; CheckForChangingOrders( pSoldier ); } SetNewSituation( pSoldier ); // set new situation for the chosen one pSoldier->bHasKeys = (pSoldier->bHasKeys << 1) | 1; // cheat and give him keys to every door //pSoldier->bHasKeys = TRUE; } #ifdef TESTVERSION else PopMessage("TEST MSG: Couldn't find anyone eligible to become TheChosenOne!"); #endif }
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 ); }