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);