diff --git a/Tactical/PATHAI.cpp b/Tactical/PATHAI.cpp index 5eb9e6867..af3105554 100644 --- a/Tactical/PATHAI.cpp +++ b/Tactical/PATHAI.cpp @@ -2624,7 +2624,7 @@ if(!GridNoOnVisibleWorldTile(iDestination)) fNonSwimmer = !( IS_MERC_BODY_TYPE( s ) ); if ( fNonSwimmer ) { - if ( Water( sDestination ) ) + if ( Water( sDestination, ubLevel ) ) { return( 0 ); } diff --git a/Tactical/Soldier Add.cpp b/Tactical/Soldier Add.cpp index 0e398f8f1..ca7967225 100644 --- a/Tactical/Soldier Add.cpp +++ b/Tactical/Soldier Add.cpp @@ -1117,7 +1117,7 @@ INT32 FindRandomGridNoBetweenCircles( INT32 sCenterGridNo, UINT8 uInnerRadius, U sGridNo = sCenterGridNo + (WORLD_COLS * sY) + sX; - if ( TileIsOutOfBounds( sGridNo ) || Water( sGridNo ) || !IsLocationSittable( sGridNo, 0 ) || PythSpacesAway( sGridNo, sCenterGridNo ) <= uInnerRadius || PythSpacesAway( sGridNo, sCenterGridNo ) > uOuterRadius ) + if ( TileIsOutOfBounds( sGridNo ) || Water( sGridNo, 0 ) || !IsLocationSittable( sGridNo, 0 ) || PythSpacesAway( sGridNo, sCenterGridNo ) <= uInnerRadius || PythSpacesAway( sGridNo, sCenterGridNo ) > uOuterRadius ) sGridNo = NOWHERE; else fFound = TRUE; diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index 8cb716dc2..1411d2a80 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -16318,7 +16318,7 @@ void SOLDIERTYPE::DropSectorEquipment( ) if ( sPutGridNo == NOWHERE ) sPutGridNo = RandomGridNo( ); - if ( Water( sPutGridNo ) ) + if ( Water( sPutGridNo, this->pathing.bLevel ) ) sPutGridNo = gMapInformation.sCenterGridNo; if ( (this->sSectorX == gWorldSectorX) && (this->sSectorY == gWorldSectorY) && (this->bSectorZ == gbWorldSectorZ) ) diff --git a/Tactical/UI Cursors.cpp b/Tactical/UI Cursors.cpp index aa706a2e7..0427676d8 100644 --- a/Tactical/UI Cursors.cpp +++ b/Tactical/UI Cursors.cpp @@ -2829,7 +2829,7 @@ UINT8 GetActionModeCursor( SOLDIERTYPE *pSoldier ) // WANNE.WATER: Allow shooting if we are on a "water" tile, but on level > 0 // Now check our terrain to see if we cannot do the action now... - if ( WaterTooDeepForAttacks( pSoldier->sGridNo) && pSoldier->pathing.bLevel == 0 ) + if ( WaterTooDeepForAttacks( pSoldier->sGridNo, pSoldier->pathing.bLevel) && pSoldier->pathing.bLevel == 0 ) { ubCursor = INVALIDCURS; } diff --git a/Tactical/opplist.cpp b/Tactical/opplist.cpp index 2846ed380..fa5855c60 100644 --- a/Tactical/opplist.cpp +++ b/Tactical/opplist.cpp @@ -5408,11 +5408,11 @@ UINT8 MovementNoise( SOLDIERTYPE *pSoldier ) } // if sneaker is moving through water - if (Water( pSoldier->sGridNo ) ) + if (Water( pSoldier->sGridNo, pSoldier->pathing.bLevel ) ) { iStealthSkill -= 10; // 10% penalty } - else if (DeepWater( pSoldier->sGridNo ) ) + else if (DeepWater( pSoldier->sGridNo, pSoldier->pathing.bLevel ) ) { iStealthSkill -= 20; // 20% penalty } diff --git a/TacticalAI/AIUtils.cpp b/TacticalAI/AIUtils.cpp index f7c998fd6..9856dc74a 100644 --- a/TacticalAI/AIUtils.cpp +++ b/TacticalAI/AIUtils.cpp @@ -88,7 +88,7 @@ INT8 OKToAttack(SOLDIERTYPE * pSoldier, int target) if (target == pSoldier->sGridNo) return(NOSHOOT_MYSELF); - if (WaterTooDeepForAttacks(pSoldier->sGridNo)) + if (WaterTooDeepForAttacks(pSoldier->sGridNo, pSoldier->pathing.bLevel)) return(NOSHOOT_WATER); // make sure a weapon is in hand (FEB.8 ADDITION: tossable items are also OK) @@ -1688,7 +1688,8 @@ INT16 EstimatePathCostToLocation( SOLDIERTYPE * pSoldier, INT32 sDestGridNo, INT else { sPathCost = PlotPath( pSoldier, sClimbGridNo, FALSE, FALSE, FALSE, WALKING, FALSE, FALSE, 0 ); - if (sPathCost != 0) + // sevenfm: check if we are already standing at climb gridno + if (sPathCost != 0 || pSoldier->sGridNo == sClimbGridNo) { // add in cost of climbing down if (fAddCostAfterClimbingUp) @@ -1731,7 +1732,8 @@ INT16 EstimatePathCostToLocation( SOLDIERTYPE * pSoldier, INT32 sDestGridNo, INT else { sPathCost = PlotPath( pSoldier, sClimbGridNo, FALSE, FALSE, FALSE, WALKING, FALSE, FALSE, 0); - if (sPathCost != 0) + // sevenfm: check if we are already standing at climb gridno + if (sPathCost != 0 || pSoldier->sGridNo == sClimbGridNo) { // add in the cost of climbing up or down if (pSoldier->pathing.bLevel == 0) @@ -1942,7 +1944,7 @@ INT16 DistanceToClosestFriend( SOLDIERTYPE * pSoldier ) BOOLEAN InWaterGasOrSmoke( SOLDIERTYPE *pSoldier, INT32 sGridNo ) { - if (WaterTooDeepForAttacks( sGridNo )) + if (WaterTooDeepForAttacks( sGridNo, pSoldier->pathing.bLevel )) { return(TRUE); } @@ -1968,7 +1970,7 @@ BOOLEAN InGasOrSmoke( SOLDIERTYPE *pSoldier, INT32 sGridNo ) INT16 InWaterOrGas(SOLDIERTYPE *pSoldier, INT32 sGridNo) { - if (WaterTooDeepForAttacks( sGridNo )) + if (WaterTooDeepForAttacks( sGridNo, pSoldier->pathing.bLevel )) { return(TRUE); } diff --git a/TacticalAI/DecideAction.cpp b/TacticalAI/DecideAction.cpp index 8bdc3366b..8aa10fef7 100644 --- a/TacticalAI/DecideAction.cpp +++ b/TacticalAI/DecideAction.cpp @@ -788,7 +788,7 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier) } - bInWater = Water( pSoldier->sGridNo ); + bInWater = Water( pSoldier->sGridNo, pSoldier->pathing.bLevel ); // check if standing in tear gas without a gas mask on, or in smoke bInGas = InGasOrSmoke( pSoldier, pSoldier->sGridNo ); @@ -1825,7 +1825,7 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) iChance = 5 * WhatIKnowThatPublicDont(pSoldier,FALSE); // use 5 * for YELLOW alert // if I actually know something they don't and I ain't swimming (deep water) - if (iChance && !DeepWater( pSoldier->sGridNo )) + if (iChance && !DeepWater( pSoldier->sGridNo, pSoldier->pathing.bLevel )) { // CJC: this addition allows for varying difficulty levels for soldier types @@ -2474,8 +2474,8 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) // determine if we happen to be in water (in which case we're in BIG trouble!) - bInWater = Water( pSoldier->sGridNo ); - bInDeepWater = Water( pSoldier->sGridNo ); + bInWater = Water( pSoldier->sGridNo, pSoldier->pathing.bLevel ); + bInDeepWater = Water( pSoldier->sGridNo, pSoldier->pathing.bLevel ); // check if standing in tear gas without a gas mask on bInGas = InGasOrSmoke( pSoldier, pSoldier->sGridNo ); @@ -3437,7 +3437,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) if( !TileIsOutOfBounds(tempGridNo) && !GuySawEnemyThisTurnOrBefore(pSoldier) && !pSoldier->aiData.bUnderFire && - !Water(pSoldier->sGridNo) && + !Water(pSoldier->sGridNo, pSoldier->pathing.bLevel) && pSoldier->bInitialActionPoints >= APBPConstants[AP_MINIMUM] && ( PythSpacesAway( pSoldier->sGridNo, tempGridNo ) > MIN_FLANK_DIST_RED || !LocationToLocationLineOfSightTest( pSoldier->sGridNo, pSoldier->pathing.bLevel, tempGridNo, pSoldier->pathing.bLevel, TRUE) ) ) @@ -3452,7 +3452,7 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) // sevenfm: avoid going into water, gas or light if( !TileIsOutOfBounds(pSoldier->aiData.usActionData) && - !Water(pSoldier->aiData.usActionData) && + !Water(pSoldier->aiData.usActionData, pSoldier->pathing.bLevel) && !InGas( pSoldier, pSoldier->aiData.usActionData ) && !InLightAtNight( pSoldier->aiData.usActionData, pSoldier->pathing.bLevel ) ) { @@ -4563,8 +4563,8 @@ INT16 ubMinAPCost; else { // determine if we happen to be in water (in which case we're in BIG trouble!) - bInWater = Water( pSoldier->sGridNo ); - bInDeepWater = WaterTooDeepForAttacks( pSoldier->sGridNo ); + bInWater = Water( pSoldier->sGridNo, pSoldier->pathing.bLevel ); + bInDeepWater = WaterTooDeepForAttacks( pSoldier->sGridNo, pSoldier->pathing.bLevel ); // check if standing in tear gas without a gas mask on bInGas = InGasOrSmoke( pSoldier, pSoldier->sGridNo ); @@ -6716,7 +6716,7 @@ INT8 ZombieDecideActionGreen(SOLDIERTYPE *pSoldier) return( AI_ACTION_NONE ); } - bInWater = Water( pSoldier->sGridNo ); + bInWater = Water( pSoldier->sGridNo, pSoldier->pathing.bLevel ); if ( bInWater && PreRandom( 2 ) ) { @@ -7174,7 +7174,7 @@ INT8 ZombieDecideActionYellow(SOLDIERTYPE *pSoldier) iChance = 5 * WhatIKnowThatPublicDont(pSoldier,FALSE); // use 5 * for YELLOW alert // if I actually know something they don't and I ain't swimming (deep water) - if (iChance && !DeepWater( pSoldier->sGridNo )) + if (iChance && !DeepWater( pSoldier->sGridNo, pSoldier->pathing.bLevel )) { // CJC: this addition allows for varying difficulty levels for soldier types iChance += gbDiff[ DIFF_RADIO_RED_ALERT ][ SoldierDifficultyLevel( pSoldier ) ] / 2; @@ -7361,8 +7361,8 @@ INT8 ZombieDecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) // determine if we happen to be in water (in which case we're in BIG trouble!) - bInWater = Water( pSoldier->sGridNo ); - bInDeepWater = Water( pSoldier->sGridNo ); + bInWater = Water( pSoldier->sGridNo, pSoldier->pathing.bLevel ); + bInDeepWater = Water( pSoldier->sGridNo, pSoldier->pathing.bLevel ); DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"decideactionred: crouch and rest if running out of breath"); //////////////////////////////////////////////////////////////////////// @@ -8053,8 +8053,8 @@ INT8 ZombieDecideActionBlack(SOLDIERTYPE *pSoldier) ubCanMove = (pSoldier->bActionPoints >= MinPtsToMove(pSoldier)); // determine if we happen to be in water (in which case we're in BIG trouble!) - bInWater = Water( pSoldier->sGridNo ); - bInDeepWater = WaterTooDeepForAttacks( pSoldier->sGridNo ); + bInWater = Water( pSoldier->sGridNo, pSoldier->pathing.bLevel ); + bInDeepWater = WaterTooDeepForAttacks( pSoldier->sGridNo, pSoldier->pathing.bLevel ); // calculate our morale pSoldier->aiData.bAIMorale = CalcMorale(pSoldier); diff --git a/TacticalAI/FindLocations.cpp b/TacticalAI/FindLocations.cpp index 73c5f9fc6..53542245c 100644 --- a/TacticalAI/FindLocations.cpp +++ b/TacticalAI/FindLocations.cpp @@ -2611,13 +2611,13 @@ INT32 FindFlankingSpot(SOLDIERTYPE *pSoldier, INT32 sPos, INT8 bAction ) } // sevenfm: don't go into deep water for flanking - if( DeepWater( sGridNo ) ) + if( DeepWater( sGridNo, pSoldier->pathing.bLevel ) ) { continue; } // sevenfm: allow water flanking only for CUNNINGSOLO soldiers - if( Water( sGridNo ) && pSoldier->aiData.bAttitude != CUNNINGSOLO ) + if( Water( sGridNo, pSoldier->pathing.bLevel ) && pSoldier->aiData.bAttitude != CUNNINGSOLO ) { continue; } @@ -2696,25 +2696,29 @@ INT32 FindFlankingSpot(SOLDIERTYPE *pSoldier, INT32 sPos, INT8 bAction ) return( sBestSpot ); } +//sevenfm: new calculation using FindHeigherLevel INT32 FindClosestClimbPoint (SOLDIERTYPE *pSoldier, BOOLEAN fClimbUp ) { INT32 sBestSpot = NOWHERE; + // sevenfm: safety check + if(!pSoldier) + { + return NOWHERE; + } + //DebugMsg( TOPIC_JA2AI , DBG_LEVEL_3 , "FindClosestClimbPoint"); - //gubNPCAPBudget = gubNPCAPBudget = __min( gubNPCAPBudget, gubNPCAPBudget - GetAPsToChangeStance( pSoldier, ANIM_STAND ) -1 ); //-1 for turning cost while standing - //NumMessage("Search Range = ",iSearchRange); - //NumMessage("gubNPCAPBudget = ",gubNPCAPBudget); - - // 0verhaul: This function is optimized to take advantage of the new climb point info. - if (fClimbUp) { // For the climb up case, search the nearby limits for a climb up point and take the closest. INT32 sGridNo; static const INT32 iSearchRange = 20; INT16 sMaxLeft, sMaxRight, sMaxUp, sMaxDown, sXOffset, sYOffset; - UINT8 ubTestDir; + //UINT8 ubTestDir; + + INT8 ubClimbDir; + INT32 sClimbSpot; // determine maximum horizontal limits sMaxLeft = min( iSearchRange, (pSoldier->sGridNo % MAXCOL)); @@ -2744,7 +2748,6 @@ INT32 FindClosestClimbPoint (SOLDIERTYPE *pSoldier, BOOLEAN fClimbUp ) continue; } - if ( sGridNo == pSoldier->pathing.sBlackList ) { continue; @@ -2756,24 +2759,32 @@ INT32 FindClosestClimbPoint (SOLDIERTYPE *pSoldier, BOOLEAN fClimbUp ) continue; } - if (gpWorldLevelData[ sGridNo].ubExtFlags[0] & MAPELEMENT_EXT_CLIMBPOINT) + // exclude water tiles + if ( Water( sGridNo, pSoldier->pathing.bLevel ) ) { - // Search for the destination climb point on the roof - for ( ubTestDir = 0; ubTestDir < NUM_WORLD_DIRECTIONS; ubTestDir += 2 ) + continue; + } + + // check that there's noone at sGridNo at level 0 (this soldier is allowed) + if( WhoIsThere2( sGridNo, 0 ) != NOBODY && + WhoIsThere2( sGridNo, 0 ) != pSoldier->ubID ) + { + continue; + } + + if( FindHeigherLevel( pSoldier, sGridNo, pSoldier->ubDirection, &ubClimbDir ) ) + { + // ubClimbDir is new direction + // check that there's noone there + sClimbSpot = NewGridNo( sGridNo, DirectionInc( ubClimbDir)); + if( WhoIsThere2( sClimbSpot, 1 ) == NOBODY ) { - INT32 sTestGridNo = NewGridNo( sGridNo, DirectionInc( ubTestDir)); - // And see if it or the ground location is occupied - if (gpWorldLevelData[ sTestGridNo ].ubExtFlags[1] & MAPELEMENT_EXT_CLIMBPOINT && - (WhoIsThere2( sTestGridNo, 1 ) == NOBODY) && - (WhoIsThere2( sGridNo, 0 ) == NOBODY) ) + // Good climb point. Is it closer than the previous point? + if( TileIsOutOfBounds(sBestSpot) || + GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo , sGridNo ) < GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo , sBestSpot )) { - // Good climb point. Is it closer than the previous point? - if ( GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo , sGridNo ) < - GetRangeInCellCoordsFromGridNoDiff( pSoldier->sGridNo , sBestSpot )) - { - // If not, we have a new winnar! - sBestSpot = sGridNo; - } + // If not, we have a new winnar! + sBestSpot = sGridNo; } } } @@ -2936,47 +2947,47 @@ INT32 FindBestCoverNearTheGridNo(SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubS } +// sevenfm: new calculation using FindHeigherLevel/FindLowerLevel INT8 FindDirectionForClimbing( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel ) { - UINT8 ubClimbDir; + INT8 ubClimbDir; INT32 sClimbSpot; - if (bLevel == 0) + if(!pSoldier) { - if (gpWorldLevelData[ sGridNo].ubExtFlags[0] & MAPELEMENT_EXT_CLIMBPOINT) + return DIRECTION_IRRELEVANT; + } + + if (pSoldier->pathing.bLevel == 0) + { + // check climb up + if( FindHeigherLevel( pSoldier, sGridNo, pSoldier->ubDirection, &ubClimbDir ) ) { - for ( ubClimbDir = 0; ubClimbDir < NUM_WORLD_DIRECTIONS; ubClimbDir += 2 ) + // ubClimbDir is new direction + // check that there's noone there + sClimbSpot = NewGridNo( sGridNo, DirectionInc( ubClimbDir)); + if( WhoIsThere2( sClimbSpot, 1 ) == NOBODY && + !Water(sClimbSpot, 1) ) { - sClimbSpot = NewGridNo( sGridNo, DirectionInc( ubClimbDir)); - if (gpWorldLevelData[ sClimbSpot].ubExtFlags[1] & MAPELEMENT_EXT_CLIMBPOINT && - WhoIsThere2( sClimbSpot, 1 ) == NOBODY ) - { - return ubClimbDir; - } + return ubClimbDir; } } } - else if (bLevel == 1) + else { - //CHRISL: If NewInv and wearing a backpack, don't allow climbing - if (UsingNewInventorySystem() == true && pSoldier->inv[BPACKPOCKPOS].exists() == true - //JMich.BackpackClimb - && ((gGameExternalOptions.sBackpackWeightToClimb == -1) || (INT16)pSoldier->inv[BPACKPOCKPOS].GetWeightOfObjectInStack() + Item[pSoldier->inv[BPACKPOCKPOS].usItem].sBackpackWeightModifier > gGameExternalOptions.sBackpackWeightToClimb) - && ((gGameExternalOptions.fUseGlobalBackpackSettings == TRUE) || (Item[pSoldier->inv[BPACKPOCKPOS].usItem].fAllowClimbing == FALSE))) - return DIRECTION_IRRELEVANT; - if (gpWorldLevelData[ sGridNo].ubExtFlags[1] & MAPELEMENT_EXT_CLIMBPOINT) + // check climb down + if( FindLowerLevel( pSoldier, pSoldier->sGridNo, pSoldier->ubDirection, &ubClimbDir ) ) { - for ( ubClimbDir = 0; ubClimbDir< NUM_WORLD_DIRECTIONS; ubClimbDir += 2 ) + // ubClimbDir is new direction + sClimbSpot = NewGridNo( sGridNo, DirectionInc( ubClimbDir)); + if( WhoIsThere2( sClimbSpot, 0 ) == NOBODY && + !Water(sClimbSpot, 0) ) { - sClimbSpot = NewGridNo( sGridNo, DirectionInc( ubClimbDir)); - if (gpWorldLevelData[ sClimbSpot].ubExtFlags[0] & MAPELEMENT_EXT_CLIMBPOINT && - WhoIsThere2( sClimbSpot, 0 ) == NOBODY ) - { - return ubClimbDir; - } + return ubClimbDir; } } } + return DIRECTION_IRRELEVANT; } diff --git a/TacticalAI/Movement.cpp b/TacticalAI/Movement.cpp index ae94d5bcb..dd29fc8cd 100644 --- a/TacticalAI/Movement.cpp +++ b/TacticalAI/Movement.cpp @@ -82,7 +82,7 @@ int LegalNPCDestination(SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT8 ubPathMode, */ { // if water's a problem, and gridno is in a water tile (bridges are OK) - if (!ubWaterOK && Water(sGridNo)) + if (!ubWaterOK && Water(sGridNo, pSoldier->pathing.bLevel)) return(FALSE); //Madd: added to prevent people from running into gas and fire @@ -510,7 +510,7 @@ INT32 InternalGoAsFarAsPossibleTowards(SOLDIERTYPE *pSoldier, INT32 sDesGrid, IN // don't try to approach go after noises or enemies actually in water // would be too easy to throw rocks in water, etc. & distract the AI - if (Water(sDesGrid)) + if (Water(sDesGrid, pSoldier->pathing.bLevel)) { return(NOWHERE); } diff --git a/TileEngine/Buildings.cpp b/TileEngine/Buildings.cpp index fb91c515d..075f67976 100644 --- a/TileEngine/Buildings.cpp +++ b/TileEngine/Buildings.cpp @@ -663,72 +663,8 @@ INT32 FindClosestClimbPoint( SOLDIERTYPE *pSoldier, INT32 sStartGridNo, INT32 sD { return( NOWHERE ); } - - // WANNE: This code is from Overhauls A* climbing building, but also works here. - /* - INT32 sTestGridNo; - UINT8 ubTestDir; - INT32 sGridNo; - - for (sGridNo = 0; sGridNo < WORLD_MAX; sGridNo++) - { - if (gubBuildingInfo[ sGridNo ] == gubBuildingInfo[ sDesiredGridNo ]) //&& - //gpWorldLevelData[ sGridNo ].ubExtFlags[1] & MAPELEMENT_EXT_CLIMBPOINT) - { - // Found a climb point for this building - if (fClimbUp) - { - for (ubTestDir = 0; ubTestDir < 8; ubTestDir += 2) - { - sTestGridNo = NewGridNo( sGridNo, DirectionInc( ubTestDir)); - //if (gpWorldLevelData[ sTestGridNo ].ubExtFlags[0] & MAPELEMENT_EXT_CLIMBPOINT) - { - // Found a matching climb point - if ( (WhoIsThere2( sTestGridNo, 0 ) == NOBODY || sTestGridNo == pSoldier->sGridNo) - && (WhoIsThere2( sGridNo, 1 ) == NOBODY) && - (!pSoldier || !InGas( pSoldier, sTestGridNo ) ) ) - { - // And it's open - sDistance = PythSpacesAway( sStartGridNo, sTestGridNo ); - if (sDistance < sClosestDistance ) - { - sClosestDistance = sDistance; - sClosestSpot = sTestGridNo; - } - } - } - } - } - else - { - for (ubTestDir = 0; ubTestDir < 8; ubTestDir += 2) - { - sTestGridNo = NewGridNo( sGridNo, DirectionInc( ubTestDir)); - //if (gpWorldLevelData[ sTestGridNo ].ubExtFlags[0] & MAPELEMENT_EXT_CLIMBPOINT) - { - // Found a matching climb point - if ( (WhoIsThere2( sTestGridNo, 0 ) == NOBODY) && - (WhoIsThere2( sGridNo, 1 ) == NOBODY || sGridNo == pSoldier->sGridNo) && - (!pSoldier || !InGas( pSoldier, sTestGridNo ) ) ) - { - // And it's open - sDistance = PythSpacesAway( sStartGridNo, sGridNo ); - if (sDistance < sClosestDistance ) - { - sClosestDistance = sDistance; - sClosestSpot = sGridNo; - } - } - } - } - } - } - } - - return( sClosestSpot ); - */ - - // WANNE: This code is from "vanilla" climbing + + // WANNE: Reworked climbing code from sevenfm UINT8 ubNumClimbSpots; INT32 * psClimbSpots; UINT8 ubLoop; @@ -746,9 +682,12 @@ INT32 FindClosestClimbPoint( SOLDIERTYPE *pSoldier, INT32 sStartGridNo, INT32 sD for ( ubLoop = 0; ubLoop < ubNumClimbSpots; ubLoop++ ) { - if ( (WhoIsThere2( pBuilding->sUpClimbSpots[ ubLoop ], 0 ) == NOBODY) - && (WhoIsThere2( pBuilding->sDownClimbSpots[ ubLoop ], 1 ) == NOBODY) && - (!pSoldier || !InGas( pSoldier, psClimbSpots[ ubLoop] ) ) ) + if( (WhoIsThere2( pBuilding->sUpClimbSpots[ ubLoop ], 0 ) == NOBODY || + WhoIsThere2( pBuilding->sUpClimbSpots[ ubLoop ], 0 ) == pSoldier->ubID ) && + (WhoIsThere2( pBuilding->sDownClimbSpots[ ubLoop ], 1 ) == NOBODY || + WhoIsThere2( pBuilding->sDownClimbSpots[ ubLoop ], 1 ) == pSoldier->ubID) && + !InGas( pSoldier, psClimbSpots[ ubLoop] ) && + !Water( psClimbSpots[ ubLoop], pSoldier->pathing.bLevel) ) { sDistance = PythSpacesAway( sStartGridNo, psClimbSpots[ ubLoop ] ); if (sDistance < sClosestDistance ) diff --git a/TileEngine/worldman.cpp b/TileEngine/worldman.cpp index 371d64ef0..1577287e7 100644 --- a/TileEngine/worldman.cpp +++ b/TileEngine/worldman.cpp @@ -3717,15 +3717,21 @@ UINT8 GetTerrainType( INT32 sGridNo ) */ } -BOOLEAN Water( INT32 sGridNo ) +BOOLEAN Water( INT32 sGridNo, BOOLEAN bLevel ) { MAP_ELEMENT * pMapElement; - + if( TileIsOutOfBounds( sGridNo ) ) { return( FALSE ); } + // sevenfm: check bridge + if( bLevel ) + { + return FALSE; + } + pMapElement = &(gpWorldLevelData[sGridNo]); if ( TERRAIN_IS_WATER( pMapElement->ubTerrainID) ) { @@ -3738,7 +3744,7 @@ BOOLEAN Water( INT32 sGridNo ) } } -BOOLEAN DeepWater( INT32 sGridNo ) +BOOLEAN DeepWater( INT32 sGridNo, BOOLEAN bLevel ) { MAP_ELEMENT * pMapElement; @@ -3747,6 +3753,12 @@ BOOLEAN DeepWater( INT32 sGridNo ) return( FALSE ); } + // sevenfm: check bridge + if( bLevel ) + { + return FALSE; + } + pMapElement = &(gpWorldLevelData[sGridNo]); if (TERRAIN_IS_DEEP_WATER( pMapElement->ubTerrainID) ) @@ -3760,9 +3772,9 @@ BOOLEAN DeepWater( INT32 sGridNo ) } } -BOOLEAN WaterTooDeepForAttacks( INT32 sGridNo ) +BOOLEAN WaterTooDeepForAttacks( INT32 sGridNo, BOOLEAN bLevel ) { - return( DeepWater( sGridNo ) ); + return( DeepWater( sGridNo, bLevel ) ); } void SetStructAframeFlags( INT32 iMapIndex, UINT32 uiFlags ) diff --git a/TileEngine/worldman.h b/TileEngine/worldman.h index d4819b44b..e22202eb7 100644 --- a/TileEngine/worldman.h +++ b/TileEngine/worldman.h @@ -63,9 +63,9 @@ void SetAllLandShadeLevels( INT32 iMapIndex, UINT8 ubShadeLevel ); void AdjustAllLandShadeLevels( INT32 iMapIndex, INT8 bShadeDiff ); void AdjustAllLandDirtyCount( INT32 iMapIndex, INT8 bDirtyDiff ); UINT8 GetTerrainType( INT32 sGridNo ); -BOOLEAN Water( INT32 sGridNo ); -BOOLEAN DeepWater( INT32 sGridNo ); -BOOLEAN WaterTooDeepForAttacks( INT32 sGridNo ); +BOOLEAN Water( INT32 sGridNo, BOOLEAN bLevel ); +BOOLEAN DeepWater( INT32 sGridNo, BOOLEAN bLevel ); +BOOLEAN WaterTooDeepForAttacks( INT32 sGridNo, BOOLEAN bLevel ); // Structure manipulation routines BOOLEAN RemoveStruct( INT32 iMapIndex, UINT16 usIndex );