From 7e6ec3659e71efb2e80bfac1a94692674d98fbb7 Mon Sep 17 00:00:00 2001 From: Flugente Date: Sat, 8 Dec 2012 00:34:52 +0000 Subject: [PATCH] New Feature: scuba gear allows to dive, thereby staying invisible to the enemy as long as you are in deep water. If you are spotted however, the enemy remembers that, and can still see you in deep water. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@5718 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Tactical/Interface.cpp | 46 ++++++++++++++++++++++++++++++++++++ Tactical/Item Types.h | 8 +++---- Tactical/Points.cpp | 27 +++++++++++++++++++++ Tactical/Soldier Control.cpp | 16 +++++++++++++ Tactical/Soldier Control.h | 3 +++ Tactical/opplist.cpp | 4 ++++ 6 files changed, 100 insertions(+), 4 deletions(-) diff --git a/Tactical/Interface.cpp b/Tactical/Interface.cpp index bcb2fb1b9..aa3d868fd 100644 --- a/Tactical/Interface.cpp +++ b/Tactical/Interface.cpp @@ -239,6 +239,8 @@ UINT32 guiVEHINV; UINT32 guiBURSTACCUM; UINT32 guiITEMPOINTERHATCHES; +UINT32 guiUNDERWATER; // added by Flugente + // UI Globals MOUSE_REGION gViewportRegion; MOUSE_REGION gRadarRegion; @@ -514,6 +516,12 @@ BOOLEAN InitializeTacticalInterface( ) if( !AddVideoObject( &VObjectDesc, &guiBURSTACCUM ) ) AssertMsg(0, "Missing INTERFACE\\burst1.sti" ); + // Flugente: load fish symbol (signifies that a merc is diving until someone comes up with a proper animation) + VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; + FilenameForBPP("INTERFACE\\fish.sti", VObjectDesc.ImageFile); + if( !AddVideoObject( &VObjectDesc, &guiUNDERWATER ) ) + AssertMsg(0, "Missing INTERFACE\\fish.sti" ); + //CHRISL: Moved to seperate function so we can call seperately InitializeTacticalPortraits(); @@ -1747,7 +1755,45 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID ) } } } + // Flugente: show a small animation hat signifies that a merc is underwater (hopefully temporary until someone comes up with a proper animation) + else if ( pSoldier->UsesScubaGear() ) + { + if ( TIMECOUNTERDONE( pSoldier->timeCounters.BlinkSelCounter, 320 ) ) + { + RESETTIMECOUNTER( pSoldier->timeCounters.BlinkSelCounter, 320 ); + + // Update frame + pSoldier->sLocatorFrame++; + if ( pSoldier->sLocatorFrame == 5 ) + { + // Update time we do this + pSoldier->sLocatorFrame = 0; + } + } + + if ( pSoldier->flags.fFlashLocator == pSoldier->ubNumLocateCycles ) + { + pSoldier->flags.fShowLocator = FALSE; + } + + // Render the beastie + GetSoldierAboveGuyPositions( pSoldier, &sXPos, &sYPos, TRUE ); + + // Adjust for bars! + sXPos += 25; + sYPos += 25; + + // Add bars + iBack = RegisterBackgroundRect( BGND_FLAG_SINGLE, NULL, sXPos, sYPos, (INT16)(sXPos +40 ), (INT16)(sYPos + 40 ) ); + + if ( iBack != -1 ) + { + SetBackgroundRectFilled( iBack ); + } + + BltVideoObjectFromIndex( FRAME_BUFFER, guiUNDERWATER, pSoldier->sLocatorFrame, sXPos, sYPos, VO_BLT_SRCTRANSPARENCY, NULL ); + } if ( !pSoldier->flags.fShowLocator ) { diff --git a/Tactical/Item Types.h b/Tactical/Item Types.h index ee9305147..eab722505 100644 --- a/Tactical/Item Types.h +++ b/Tactical/Item Types.h @@ -753,11 +753,11 @@ extern OBJECTTYPE gTempObject; #define HANDCUFFS 0x00080000 //524288 // item can be used to capture soldiers #define TASER 0x00100000 //1048576 // item is a taser, melee hits with this will drain breath (if batteries are supplied) -/*#define PLAYER_NET_2_LVL_2 0x00200000 //2097152 -#define PLAYER_NET_3_LVL_2 0x00400000 //4194304 -#define PLAYER_NET_4_LVL_2 0x00800000 //8388608 +#define SCUBA_BOTTLE 0x00200000 //2097152 // item is a scuba gear air bottle +#define SCUBA_MASK 0x00400000 //4194304 // item is a scuba gear breathing mask +#define SCUBA_FINS 0x00800000 //8388608 // this item speed up swimming, but slows walking and running -#define PLAYER_NET_1_LVL_3 0x01000000 //16777216 +/*#define PLAYER_NET_1_LVL_3 0x01000000 //16777216 #define PLAYER_NET_2_LVL_3 0x02000000 //33554432 #define PLAYER_NET_3_LVL_3 0x04000000 //67108864 #define PLAYER_NET_4_LVL_3 0x08000000 //134217728 diff --git a/Tactical/Points.cpp b/Tactical/Points.cpp index 514ace6bf..f7a453dbd 100644 --- a/Tactical/Points.cpp +++ b/Tactical/Points.cpp @@ -331,6 +331,19 @@ INT16 TerrainBreathPoints(SOLDIERTYPE * pSoldier, INT32 sGridNo, INT8 bDir, UINT iPoints = max(1, (INT16)((iPoints * (100 - gSkillTraitValues.ubATBPsMovementReduction) / 100) + 0.5)); } + // Flugente: scuba fins reduce movement cost in water, but increase cost on land + if ( pSoldier->inv[LEGPOS].exists() && HasItemFlag( pSoldier->inv[LEGPOS].usItem, SCUBA_FINS ) ) + { + if ( TERRAIN_IS_HIGH_WATER( ubTerrainID) ) + { + iPoints /= 2; + } + else + { + iPoints *= 2; + } + } + // ATE: Adjust these by realtime movement if (!(gTacticalStatus.uiFlags & TURNBASED) || !(gTacticalStatus.uiFlags & INCOMBAT ) ) { @@ -443,6 +456,20 @@ INT16 ActionPointCost( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir, UINT16 u { sPoints = max(1, (INT16)((sPoints * (100 - gSkillTraitValues.ubATAPsMovementReduction) / 100) + 0.5)); } + + // Flugente: scuba fins reduce movement cost in water, but increase cost on land + if ( pSoldier->inv[LEGPOS].exists() && HasItemFlag( pSoldier->inv[LEGPOS].usItem, SCUBA_FINS ) ) + { + if ( TERRAIN_IS_HIGH_WATER( ubTerrainID) ) + { + sPoints /= 2; + } + else + { + sPoints *= 2; + } + } + // Check if doors if not player's merc (they have to open them manually) if ( sSwitchValue == TRAVELCOST_DOOR && pSoldier->bTeam != gbPlayerNum ) { diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index 7fafac120..c847a610d 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -15335,6 +15335,22 @@ UINT32 SOLDIERTYPE::GetSurrenderStrength() return value; } +// Flugente: scuba gear +BOOLEAN SOLDIERTYPE::UsesScubaGear() +{ + if ( !this->MercInHighWater() ) + return FALSE; + + // do we wear a scuba mask? + if ( !( this->inv[ HEAD1POS ].exists() && HasItemFlag(this->inv[ HEAD1POS ].usItem, SCUBA_MASK) ) && !( this->inv[ HEAD2POS ].exists() && HasItemFlag(this->inv[ HEAD2POS ].usItem, SCUBA_MASK) ) ) + return FALSE; + + if ( !this->inv[VESTPOCKPOS].exists() || !HasItemFlag( this->inv[VESTPOCKPOS].usItem, SCUBA_BOTTLE ) ) + return FALSE; + + return TRUE; +} + INT32 CheckBleeding( SOLDIERTYPE *pSoldier ) { INT8 bBandaged; //,savedOurTurn; diff --git a/Tactical/Soldier Control.h b/Tactical/Soldier Control.h index 10377a6fb..b181bbf19 100644 --- a/Tactical/Soldier Control.h +++ b/Tactical/Soldier Control.h @@ -1500,6 +1500,9 @@ public: // Flugente: prisoner system BOOLEAN CanProcessPrisoners(); UINT32 GetSurrenderStrength(); + + // Flugente: scuba gear + BOOLEAN UsesScubaGear(); ////////////////////////////////////////////////////////////////////////////// }; // SOLDIERTYPE; diff --git a/Tactical/opplist.cpp b/Tactical/opplist.cpp index b4c726c0d..f8114d008 100644 --- a/Tactical/opplist.cpp +++ b/Tactical/opplist.cpp @@ -2206,6 +2206,10 @@ void ManSeesMan(SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, INT32 sOppGridNo, return; } + // Flugente: if the other guy is in med or deep water and wearing scua gear, then we cannot see him as he is submerged + if ( pOpponent->UsesScubaGear() ) + return; + // Flugente: update our sight concerning this guy, otherwise we could get way with open attacks because this does not get updated pSoldier->RecognizeAsCombatant(pOpponent->ubID);