From 67a3a5e488b7c68f5a52677b565f099e643fea1c Mon Sep 17 00:00:00 2001 From: Shadooow Date: Fri, 9 Jul 2021 01:13:27 +0000 Subject: [PATCH] allowed to throw grenades from behind corners without need to move into open field git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@9134 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Tactical/Handle Items.cpp | 41 +++++++++++----- TileEngine/physics.cpp | 100 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+), 13 deletions(-) diff --git a/Tactical/Handle Items.cpp b/Tactical/Handle Items.cpp index e4cf834c..d5ca4947 100644 --- a/Tactical/Handle Items.cpp +++ b/Tactical/Handle Items.cpp @@ -2127,10 +2127,15 @@ void HandleSoldierThrowItem( SOLDIERTYPE *pSoldier, INT32 sGridNo ) // Set attacker to NOBODY, since it's not a combat attack pSoldier->ubTargetID = NOBODY; + INT16 sXTest, sYTest; + ConvertGridNoToCenterCellXY(pSoldier->sGridNo, &sXTest, &sYTest); + //shadooow: if the grenade isn't thrown from soldier gridno, it should mean it is thrown using my grenade rolling feature + BOOLEAN gbGrenadeRolling = pSoldier->pThrowParams->dX != sXTest || pSoldier->pThrowParams->dY != sYTest; + // Alrighty, switch based on stance! switch( gAnimControl[ pSoldier->usAnimState ].ubHeight ) { - case ANIM_STAND: + case ANIM_STAND: // CHECK IF WE ARE NOT ON THE SAME GRIDNO if ( sGridNo == pSoldier->sGridNo ) @@ -2147,33 +2152,37 @@ void HandleSoldierThrowItem( SOLDIERTYPE *pSoldier, INT32 sGridNo ) pSoldier->EVENT_SetSoldierDesiredDirection( ubDirection ); pSoldier->flags.fTurningUntilDone = TRUE; + if (gbGrenadeRolling) + { + if ((pSoldier->pThrowParams->ubActionCode == THROW_ARM_ITEM) && + ((pSoldier->ubBodyType == BIGMALE) || (pSoldier->ubBodyType == REGMALE))) + pSoldier->usPendingAnimation = LOB_GRENADE_STANCE; + else + pSoldier->usPendingAnimation = LOB_ITEM; + } // Draw item depending on distance from buddy - if ( GetRangeFromGridNoDiff( sGridNo, pSoldier->sGridNo ) < MIN_LOB_RANGE ) + else if ( GetRangeFromGridNoDiff( sGridNo, pSoldier->sGridNo ) < MIN_LOB_RANGE ) { - //ddd maybe need to add check for throwing item class - grenade if( (pSoldier->pThrowParams->ubActionCode == THROW_ARM_ITEM) && ( (pSoldier->ubBodyType == BIGMALE) || (pSoldier->ubBodyType == REGMALE) ) ) pSoldier->usPendingAnimation = LOB_GRENADE_STANCE; else pSoldier->usPendingAnimation = LOB_ITEM; - } else { - if( (pSoldier->pThrowParams->ubActionCode == THROW_ARM_ITEM) && ( (pSoldier->ubBodyType == BIGMALE) || (pSoldier->ubBodyType == REGMALE) ) ) pSoldier->usPendingAnimation = THROW_GRENADE_STANCE; else pSoldier->usPendingAnimation = THROW_ITEM; } - } break; // crouch throwing - case ANIM_PRONE: + case ANIM_PRONE: if ( sGridNo == pSoldier->sGridNo ) { // OK, JUST DROP ITEM! @@ -2203,20 +2212,26 @@ void HandleSoldierThrowItem( SOLDIERTYPE *pSoldier, INT32 sGridNo ) } else { - // CHANGE DIRECTION AT LEAST + // CHANGE DIRECTION AT LEAST ubDirection = (UINT8)GetDirectionFromGridNo( sGridNo, pSoldier ); - pSoldier->SoldierGotoStationaryStance( ); + pSoldier->SoldierGotoStationaryStance( ); pSoldier->EVENT_SetSoldierDesiredDirection( ubDirection ); - pSoldier->flags.fTurningUntilDone = TRUE; + pSoldier->flags.fTurningUntilDone = TRUE; + if (gbGrenadeRolling) + { pSoldier->usPendingAnimation = THROW_ITEM_CROUCHED; + } + else + { + pSoldier->usPendingAnimation = THROW_ITEM_CROUCHED; + } } - break; -// + break; + // } - } diff --git a/TileEngine/physics.cpp b/TileEngine/physics.cpp index 085f7d1d..a323ea95 100644 --- a/TileEngine/physics.cpp +++ b/TileEngine/physics.cpp @@ -23,6 +23,7 @@ #include "Dialogue Control.h" // added by Flugente #endif #include "connect.h" +#include "PATHAI.H" //forward declarations of common classes to eliminate includes @@ -2096,6 +2097,95 @@ void CalculateLaunchItemBasicParams( SOLDIERTYPE *pSoldier, OBJECTTYPE *pItem, I (*pdDegrees ) = dDegrees; } +BOOLEAN GrenadeRollingPossible(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 *sXPos, INT16 *sYPos) +{ + if (!(pSoldier->bWeaponMode == WM_ATTACHED_GL || pSoldier->bWeaponMode == WM_ATTACHED_GL_BURST || pSoldier->bWeaponMode == WM_ATTACHED_GL_AUTO)) + { + UINT8 ubDirection = GetDirectionFromGridNo(sGridNo, pSoldier); + if (ubDirection % 2 == 1)//diagonal direction is disabled + { + return FALSE; + } + INT32 sTestGridNo = NewGridNo(pSoldier->sGridNo, DirectionInc(ubDirection)); + + if (gubWorldMovementCosts[sTestGridNo][ubDirection][pSoldier->pathing.bLevel] == TRAVELCOST_WALL) + { + BOOLEAN obstacle = FALSE; + INT16 newDir = (ubDirection != 2 && ubDirection != 6) ? EAST : SOUTH; + INT32 newLoc = NewGridNo(pSoldier->sGridNo, DirectionInc(newDir)); + STRUCTURE *pStruct; + pStruct = gpWorldLevelData[newLoc].pStructureHead; + while (pStruct) + { + if ((pStruct->fFlags & STRUCTURE_ANYDOOR) && (pStruct->fFlags & STRUCTURE_OPEN)) + { + if (gubWorldMovementCosts[newLoc][newDir][pSoldier->pathing.bLevel] >= 220)//doors are opened in a way they make an obstacle + return FALSE; + ConvertGridNoToCenterCellXY(newLoc, sXPos, sYPos); + return TRUE; + } + pStruct = pStruct->pNext; + } + newLoc = NewGridNo(sTestGridNo, DirectionInc(newDir)); + pStruct = gpWorldLevelData[newLoc].pStructureHead; + while (pStruct) + { + if ((pStruct->fFlags & STRUCTURE_ANYDOOR) && (pStruct->fFlags & STRUCTURE_OPEN)) + { + ConvertGridNoToCenterCellXY(newLoc, sXPos, sYPos); + return TRUE; + } + else if ((pStruct->fFlags & STRUCTURE_OBSTACLE)) + { + obstacle = TRUE; + } + pStruct = pStruct->pNext; + } + if (!obstacle) + { + ConvertGridNoToCenterCellXY(newLoc, sXPos, sYPos); + return TRUE; + } + obstacle = FALSE; + newDir = (ubDirection != 2 && ubDirection != 6) ? WEST : NORTH; + newLoc = NewGridNo(pSoldier->sGridNo, DirectionInc(newDir)); + pStruct = gpWorldLevelData[newLoc].pStructureHead; + while (pStruct) + { + if ((pStruct->fFlags & STRUCTURE_ANYDOOR) && (pStruct->fFlags & STRUCTURE_OPEN)) + { + if (gubWorldMovementCosts[newLoc][newDir][pSoldier->pathing.bLevel] >= 220)//doors are opened in a way they make an obstacle + return FALSE; + ConvertGridNoToCenterCellXY(newLoc, sXPos, sYPos); + return TRUE; + } + pStruct = pStruct->pNext; + } + newLoc = NewGridNo(sTestGridNo, DirectionInc(newDir)); + pStruct = gpWorldLevelData[newLoc].pStructureHead; + while (pStruct) + { + if ((pStruct->fFlags & STRUCTURE_ANYDOOR) && (pStruct->fFlags & STRUCTURE_OPEN)) + { + ConvertGridNoToCenterCellXY(newLoc, sXPos, sYPos); + return TRUE; + } + else if ((pStruct->fFlags & STRUCTURE_OBSTACLE)) + { + obstacle = TRUE; + } + pStruct = pStruct->pNext; + } + if (!obstacle) + { + ConvertGridNoToCenterCellXY(newLoc, sXPos, sYPos); + return TRUE; + } + } + } + return FALSE; +} + BOOLEAN CalculateLaunchItemChanceToGetThrough( SOLDIERTYPE *pSoldier, OBJECTTYPE *pItem, INT32 sGridNo, UINT8 ubLevel, INT16 sEndZ, INT32 *psFinalGridNo, BOOLEAN fArmed, INT8 *pbLevel, BOOLEAN fFromUI ) { @@ -2117,6 +2207,11 @@ BOOLEAN CalculateLaunchItemChanceToGetThrough( SOLDIERTYPE *pSoldier, OBJECTTYPE ConvertGridNoToCenterCellXY( sGridNo, &sDestX, &sDestY ); ConvertGridNoToCenterCellXY( pSoldier->sGridNo, &sSrcX, &sSrcY ); + if (GrenadeRollingPossible(pSoldier, sGridNo, &sSrcX, &sSrcY)) + { + dForce /= 2; + } + // Set position vPosition.x = sSrcX; vPosition.y = sSrcY; @@ -2267,6 +2362,11 @@ void CalculateLaunchItemParamsForThrow( SOLDIERTYPE *pSoldier, INT32 sGridNo, UI ConvertGridNoToCenterCellXY( sGridNo, &sDestX, &sDestY ); ConvertGridNoToCenterCellXY( pSoldier->sGridNo, &sSrcX, &sSrcY ); + if (GrenadeRollingPossible(pSoldier, sGridNo, &sSrcX, &sSrcY)) + { + dForce /= 2; + } + // OK, get direction normal vDirNormal.x = (float)(sDestX - sSrcX); vDirNormal.y = (float)(sDestY - sSrcY);