From cdc605d5ab22223a60e3bae5a0ecb1499d434e5d Mon Sep 17 00:00:00 2001 From: Sevenfm Date: Thu, 21 Apr 2022 13:00:09 +0000 Subject: [PATCH] Press [\] to break window glass with crowbar or any two-handed weapon. Weapon can be damaged in the process. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@9368 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Tactical/Points.cpp | 12 +++++++- Tactical/Points.h | 3 ++ Tactical/Soldier Ani.cpp | 32 ++++++++++++++++++++- Tactical/Soldier Control.cpp | 52 +++++++++++++++++++++++++++++++++++ Tactical/Soldier Control.h | 3 ++ Tactical/Turn Based Input.cpp | 14 ++++++++++ 6 files changed, 114 insertions(+), 2 deletions(-) diff --git a/Tactical/Points.cpp b/Tactical/Points.cpp index 418d307d..a19c7865 100644 --- a/Tactical/Points.cpp +++ b/Tactical/Points.cpp @@ -4656,4 +4656,14 @@ INT32 GetBPCostForRecoilkick( SOLDIERTYPE * pSoldier ) iKickPower = max(0, iKickPower); return ( iKickPower ); -} \ No newline at end of file +} + +INT16 GetAPsToBreakWindow(SOLDIERTYPE *pSoldier, BOOLEAN fStance) +{ + if (fStance) + { + return MinAPsToPunch(pSoldier, pSoldier->sGridNo); + } + + return MinAPsToPunch(pSoldier, NOWHERE); +} diff --git a/Tactical/Points.h b/Tactical/Points.h index b1e49603..f9b6d82c 100644 --- a/Tactical/Points.h +++ b/Tactical/Points.h @@ -387,4 +387,7 @@ INT16 GetBPsToJumpWall( SOLDIERTYPE *pSoldier, BOOLEAN fClimbDown ); INT32 GetBPCostPer10APsForGunHolding( SOLDIERTYPE * pSoldier, BOOLEAN fEstimate = FALSE ); INT32 GetBPCostForRecoilkick( SOLDIERTYPE * pSoldier ); +// sevenfm +INT16 GetAPsToBreakWindow(SOLDIERTYPE *pSoldier, BOOLEAN fStance); + #endif diff --git a/Tactical/Soldier Ani.cpp b/Tactical/Soldier Ani.cpp index 5c5e7387..431f08b9 100644 --- a/Tactical/Soldier Ani.cpp +++ b/Tactical/Soldier Ani.cpp @@ -376,6 +376,36 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier ) case 430: { + // sevenfm: breaking window with crowbar code + if (pSoldier->inv[HANDPOS].exists() && + (Item[pSoldier->inv[HANDPOS].usItem].crowbar && Item[pSoldier->inv[HANDPOS].usItem].usItemClass & (IC_PUNCH) || + Item[pSoldier->inv[HANDPOS].usItem].usItemClass & IC_GUN && Item[pSoldier->inv[HANDPOS].usItem].twohanded && Item[pSoldier->inv[HANDPOS].usItem].metal)) + { + INT32 sWindowGridNo = pSoldier->sTargetGridNo; + if (pSoldier->ubDirection == NORTH || pSoldier->ubDirection == WEST) + sWindowGridNo = NewGridNo(pSoldier->sGridNo, (UINT16)DirectionInc((UINT8)pSoldier->ubDirection)); + + // is there really an intact window that we jump through? + if (IsJumpableWindowPresentAtGridNo(sWindowGridNo, pSoldier->ubDirection, TRUE) && !IsJumpableWindowPresentAtGridNo(sWindowGridNo, pSoldier->ubDirection, FALSE)) + { + STRUCTURE * pStructure = FindStructure(sWindowGridNo, STRUCTURE_WALLNWINDOW); + if (pStructure && !(pStructure->fFlags & STRUCTURE_OPEN)) + { + // intact window found. Smash it! + WindowHit(sWindowGridNo, pStructure->usStructureID, (pSoldier->ubDirection == SOUTH || pSoldier->ubDirection == EAST), TRUE); + // damage weapon + if (Chance(50 - 10 * min(5, Item[pSoldier->inv[HANDPOS].usItem].bReliability))) + { + pSoldier->inv[HANDPOS][0]->data.objectStatus--; + if (Random(100) < Item[pSoldier->inv[HANDPOS].usItem].usDamageChance) + { + pSoldier->inv[HANDPOS][0]->data.sRepairThreshold--; + } + } + } + } + } + DebugMsg(TOPIC_JA2,DBG_LEVEL_3,"AdjustToNextAnimationFrame: case 430"); // SHOOT GUN // MAKE AN EVENT, BUT ONLY DO STUFF IF WE OWN THE GUY! @@ -386,7 +416,7 @@ BOOLEAN AdjustToNextAnimationFrame( SOLDIERTYPE *pSoldier ) SFireWeapon.bTargetCubeLevel= pSoldier->bTargetCubeLevel; if((is_server && pSoldier->ubID<120) || (!is_server && is_client && pSoldier->ubID<20) || (!is_server && !is_client) ) { - //only carry on if own werc + //only carry on if own merc AddGameEvent( S_FIREWEAPON, 0, &SFireWeapon ); //hayden diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index fff1c701..908bcc8c 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -24402,6 +24402,58 @@ void BeginSoldierClimbWallUp( SOLDIERTYPE *pSoldier ) } //------------------------------------------------------------------------------------------ +void SOLDIERTYPE::BreakWindow(void) +{ + if (this->inv[HANDPOS].exists() && + this->inv[HANDPOS][0]->data.objectStatus >= USABLE && + (Item[this->inv[HANDPOS].usItem].crowbar && Item[this->inv[HANDPOS].usItem].usItemClass & (IC_PUNCH) || + Item[this->inv[HANDPOS].usItem].usItemClass & IC_GUN && Item[this->inv[HANDPOS].usItem].twohanded && Item[this->inv[HANDPOS].usItem].metal)) + { + this->usAttackingWeapon = this->inv[HANDPOS].usItem; + this->aiData.bAction = AI_ACTION_KNIFE_STAB; + this->aiData.usActionData = this->sGridNo; + this->aiData.ubPendingAction = NO_PENDING_ACTION; + this->sTargetGridNo = this->sGridNo; + this->bTargetLevel = this->pathing.bLevel; + //this->sLastTarget = sGridNo; //dnl ch73 021013 + this->ubTargetID = NOBODY; //WhoIsThere2(this->sTargetGridNo, this->bTargetLevel); + this->EVENT_InitNewSoldierAnim(CROWBAR_ATTACK, 0, FALSE); + SetUIBusy(this->ubID); + + DeductPoints(this, GetAPsToBreakWindow(this, FALSE), BP_USE_CROWBAR); + } +} + +BOOLEAN SOLDIERTYPE::CanBreakWindow(void) +{ + if (this->stats.bLife >= OKLIFE && + !this->IsUnconscious() && + IS_MERC_BODY_TYPE(this) && + this->inv[HANDPOS].exists() && + this->inv[HANDPOS][0]->data.objectStatus >= USABLE && + (Item[this->inv[HANDPOS].usItem].crowbar && Item[this->inv[HANDPOS].usItem].usItemClass & (IC_PUNCH) || + Item[this->inv[HANDPOS].usItem].usItemClass & IC_GUN && Item[this->inv[HANDPOS].usItem].twohanded && Item[this->inv[HANDPOS].usItem].metal)) + { + //INT32 sWindowGridNo = this->sTargetGridNo; + INT32 sWindowGridNo = this->sGridNo; + if (this->ubDirection == NORTH || this->ubDirection == WEST) + sWindowGridNo = NewGridNo(this->sGridNo, (UINT16)DirectionInc((UINT8)this->ubDirection)); + + // is there really an intact window that we jump through? + if (IsJumpableWindowPresentAtGridNo(sWindowGridNo, this->ubDirection, TRUE) && !IsJumpableWindowPresentAtGridNo(sWindowGridNo, this->ubDirection, FALSE)) + { + STRUCTURE * pStructure = FindStructure(sWindowGridNo, STRUCTURE_WALLNWINDOW); + if (pStructure && !(pStructure->fFlags & STRUCTURE_OPEN)) + { + // intact window found + return TRUE; + } + } + } + + return FALSE; +} + BOOLEAN DoesSoldierWearGasMask( SOLDIERTYPE *pSoldier )//dnl ch40 200909 { INT8 bPosOfMask = FindGasMask( pSoldier ); diff --git a/Tactical/Soldier Control.h b/Tactical/Soldier Control.h index 9d2503f5..4615828c 100644 --- a/Tactical/Soldier Control.h +++ b/Tactical/Soldier Control.h @@ -1789,6 +1789,9 @@ public: void ChangeToFlybackAnimation( UINT8 flyBackDirection ); void ChangeToFallbackAnimation( UINT8 fallBackDirection ); + // sevenfm + void BreakWindow(void); + BOOLEAN CanBreakWindow(void); void UpdateRobotControllerGivenController( void ); void UpdateRobotControllerGivenRobot( void ); diff --git a/Tactical/Turn Based Input.cpp b/Tactical/Turn Based Input.cpp index 8e1dc05b..af0f75aa 100644 --- a/Tactical/Turn Based Input.cpp +++ b/Tactical/Turn Based Input.cpp @@ -2959,6 +2959,20 @@ void GetKeyboardInput( UINT32 *puiNewEvent ) } break; + case '\\': + if (gusSelectedSoldier != NOBODY) + { + SOLDIERTYPE *pSoldier; + if (GetSoldier(&pSoldier, gusSelectedSoldier)) + { + if (pSoldier->CanBreakWindow() && EnoughPoints(pSoldier, GetAPsToBreakWindow(pSoldier, TRUE), BP_USE_CROWBAR, TRUE)) + pSoldier->BreakWindow(); + //else if (pSoldier->CanStartDrag()) + //pSoldier->StartDrag(); + } + } + break; + #if 0//dnl ch75 021113 case '\"': Testing(1);