Files
source/Tactical/Drugs And Alcohol.cpp
T

460 lines
11 KiB
C++

#ifdef PRECOMPILEDHEADERS
#include "Tactical All.h"
#else
#include "sgp.h"
#include "soldier control.h"
#include "soldier profile.h"
#include "drugs and alcohol.h"
#include "items.h"
#include "drugs and alcohol.h"
#include "morale.h"
#include "points.h"
#include "message.h"
#endif
UINT8 ubDrugTravelRate[] = { 4, 2 };
UINT8 ubDrugWearoffRate[] = { 2, 2 };
UINT8 ubDrugEffect[] = { 15, 8 };
UINT8 ubDrugSideEffect[] = { 20, 10 };
UINT8 ubDrugSideEffectRate[] = { 2, 1 };
INT32 giDrunkModifier[] =
{
100, // Sober
75, // Feeling good,
65, // Bporderline
50, // Drunk
100, // HungOver
};
#define HANGOVER_AP_REDUCE 5
#define HANGOVER_BP_REDUCE 200
UINT8 GetDrugType( UINT16 usItem )
{
if ( usItem == ADRENALINE_BOOSTER )
{
return( DRUG_TYPE_ADRENALINE );
}
if ( usItem == REGEN_BOOSTER )
{
return( DRUG_TYPE_REGENERATION );
}
if ( usItem == ALCOHOL || usItem == WINE || usItem == BEER )
{
return( DRUG_TYPE_ALCOHOL );
}
return( NO_DRUG );
}
BOOLEAN ApplyDrugs( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject )
{
UINT8 ubDrugType;
UINT8 ubKitPoints;
INT8 bRegenPointsGained;
UINT16 usItem;
usItem = pObject->usItem;
// If not a syringe, return
ubDrugType = GetDrugType( usItem );
// Determine what type of drug....
if ( ubDrugType == NO_DRUG )
{
return( FALSE );
}
// do switch for Larry!!
if ( pSoldier->ubProfile == LARRY_NORMAL )
{
pSoldier = SwapLarrysProfiles( pSoldier );
}
else if ( pSoldier->ubProfile == LARRY_DRUNK )
{
gMercProfiles[ LARRY_DRUNK ].bNPCData = 0;
}
if ( ubDrugType < NUM_COMPLEX_DRUGS )
{
// Add effects
if ( ( pSoldier->bFutureDrugEffect[ ubDrugType ] + ubDrugEffect[ ubDrugType ] ) < 127 )
{
pSoldier->bFutureDrugEffect[ ubDrugType ] += ubDrugEffect[ ubDrugType ];
}
pSoldier->bDrugEffectRate[ ubDrugType ] = ubDrugTravelRate[ ubDrugType ];
// Increment times used during lifetime...
// CAP!
if ( ubDrugType == DRUG_TYPE_ADRENALINE )
{
if ( gMercProfiles[ pSoldier->ubProfile ].ubNumTimesDrugUseInLifetime != 255 )
{
gMercProfiles[ pSoldier->ubProfile ].ubNumTimesDrugUseInLifetime++;
}
}
// Reset once we sleep...
pSoldier->bTimesDrugUsedSinceSleep[ ubDrugType ]++;
// Increment side effects..
if ( ( pSoldier->bDrugSideEffect[ ubDrugType ] + ubDrugSideEffect[ ubDrugType ] ) < 127 )
{
pSoldier->bDrugSideEffect[ ubDrugType ] += ( ubDrugSideEffect[ ubDrugType ] );
}
// Stop side effects until were done....
pSoldier->bDrugSideEffectRate[ ubDrugType ] = 0;
if ( ubDrugType == DRUG_TYPE_ALCOHOL )
{
// ATE: use kit points...
if ( usItem == ALCOHOL )
{
ubKitPoints = 10;
}
else if ( usItem == WINE )
{
ubKitPoints = 20;
}
else
{
ubKitPoints = 100;
}
UseKitPoints( pObject, ubKitPoints, pSoldier );
}
else
{
// Remove the object....
DeleteObj( pObject );
// ATE: Make guy collapse from heart attack if too much stuff taken....
if ( pSoldier->bDrugSideEffectRate[ ubDrugType ] > ( ubDrugSideEffect[ ubDrugType ] * 3 ) )
{
// Keel over...
DeductPoints( pSoldier, 0, 10000 );
// Permanently lower certain stats...
pSoldier->bWisdom -= 5;
pSoldier->bDexterity -= 5;
pSoldier->bStrength -= 5;
if (pSoldier->bWisdom < 1)
pSoldier->bWisdom = 1;
if (pSoldier->bDexterity < 1)
pSoldier->bDexterity = 1;
if (pSoldier->bStrength < 1)
pSoldier->bStrength = 1;
// export stat changes to profile
gMercProfiles[ pSoldier->ubProfile ].bWisdom = pSoldier->bWisdom;
gMercProfiles[ pSoldier->ubProfile ].bDexterity = pSoldier->bDexterity;
gMercProfiles[ pSoldier->ubProfile ].bStrength = pSoldier->bStrength;
// make those stats RED for a while...
pSoldier->uiChangeWisdomTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( WIS_INCREASE );
pSoldier->uiChangeDexterityTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( DEX_INCREASE );
pSoldier->uiChangeStrengthTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( STRENGTH_INCREASE );
}
}
}
else
{
if ( ubDrugType == DRUG_TYPE_REGENERATION )
{
// each use of a regen booster over 1, each day, reduces the effect
bRegenPointsGained = REGEN_POINTS_PER_BOOSTER * pObject->bStatus[0] / 100;
// are there fractional %s left over?
if ( ( pObject->bStatus[0] % (100 / REGEN_POINTS_PER_BOOSTER ) ) != 0 )
{
// chance of an extra point
if ( PreRandom( 100 / REGEN_POINTS_PER_BOOSTER ) < (UINT32) ( pObject->bStatus[0] % (100 / REGEN_POINTS_PER_BOOSTER ) ) )
{
bRegenPointsGained++;
}
}
bRegenPointsGained -= pSoldier->bRegenBoostersUsedToday;
if (bRegenPointsGained > 0)
{
// can't go above the points you get for a full boost
pSoldier->bRegenerationCounter = __min( pSoldier->bRegenerationCounter + bRegenPointsGained, REGEN_POINTS_PER_BOOSTER );
}
pSoldier->bRegenBoostersUsedToday++;
}
// remove object
DeleteObj( pObject );
}
if ( ubDrugType == DRUG_TYPE_ALCOHOL )
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_DRANK_SOME ], pSoldier->name, ShortItemNames[ usItem ] );
}
else
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_MERC_TOOK_DRUG ], pSoldier->name );
}
// Dirty panel
fInterfacePanelDirty = DIRTYLEVEL2;
return( TRUE );
}
void HandleEndTurnDrugAdjustments( SOLDIERTYPE *pSoldier )
{
INT32 cnt, cnt2;
INT32 iNumLoops;
// INT8 bBandaged;
for ( cnt = 0; cnt < NUM_COMPLEX_DRUGS; cnt++ )
{
// If side effect aret is non-zero....
if ( pSoldier->bDrugSideEffectRate[ cnt ] > 0 )
{
// Subtract some...
pSoldier->bDrugSideEffect[ cnt ] -= pSoldier->bDrugSideEffectRate[ cnt ];
// If we're done, we're done!
if ( pSoldier->bDrugSideEffect[ cnt ] <= 0 )
{
pSoldier->bDrugSideEffect[ cnt ] = 0;
fInterfacePanelDirty = DIRTYLEVEL1;
}
}
// IF drug rate is -ve, it's being worn off...
if ( pSoldier->bDrugEffectRate[ cnt ] < 0 )
{
pSoldier->bDrugEffect[ cnt ] -= ( -1 * pSoldier->bDrugEffectRate[ cnt ] );
// Have we run out?
if ( pSoldier->bDrugEffect[ cnt ] <= 0 )
{
pSoldier->bDrugEffect[ cnt ] = 0;
// Dirty panel
fInterfacePanelDirty = DIRTYLEVEL2;
// Start the bad news!
pSoldier->bDrugSideEffectRate[ cnt ] = ubDrugSideEffectRate[ cnt ];
// The drug rate is 0 now too
pSoldier->bDrugEffectRate[ cnt ] = 0;
// Once for each 'level' of crash....
iNumLoops = ( pSoldier->bDrugSideEffect[ cnt ] / ubDrugSideEffect[ cnt ] ) + 1;
for ( cnt2 = 0; cnt2 < iNumLoops; cnt2++ )
{
// OK, give a much BIGGER morale downer
if ( cnt == DRUG_TYPE_ALCOHOL )
{
HandleMoraleEvent( pSoldier, MORALE_ALCOHOL_CRASH, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ );
}
else
{
HandleMoraleEvent( pSoldier, MORALE_DRUGS_CRASH, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ );
}
}
}
}
// Add increase ineffect....
if ( pSoldier->bDrugEffectRate[ cnt ] > 0 )
{
// Seap some in....
pSoldier->bFutureDrugEffect[ cnt ] -= pSoldier->bDrugEffectRate[ cnt ];
pSoldier->bDrugEffect[ cnt ] += pSoldier->bDrugEffectRate[ cnt ];
// Refresh morale w/ new drug value...
RefreshSoldierMorale( pSoldier );
// Check if we need to stop 'adding'
if ( pSoldier->bFutureDrugEffect[ cnt ] <= 0 )
{
pSoldier->bFutureDrugEffect[ cnt ] = 0;
// Change rate to -ve..
pSoldier->bDrugEffectRate[ cnt ] = -ubDrugWearoffRate[ cnt ];
}
}
}
if ( pSoldier->bRegenerationCounter > 0)
{
// bBandaged = BANDAGED( pSoldier );
// increase life
pSoldier->bLife = __min( pSoldier->bLife + LIFE_GAIN_PER_REGEN_POINT, pSoldier->bLifeMax );
if ( pSoldier->bLife == pSoldier->bLifeMax )
{
pSoldier->bBleeding = 0;
}
else if ( pSoldier->bBleeding + pSoldier->bLife > pSoldier->bLifeMax )
{
// got to reduce amount of bleeding
pSoldier->bBleeding = (pSoldier->bLifeMax - pSoldier->bLife);
}
// decrement counter
pSoldier->bRegenerationCounter--;
}
}
INT8 GetDrugEffect( SOLDIERTYPE *pSoldier, UINT8 ubDrugType )
{
return( pSoldier->bDrugEffect[ ubDrugType ] );
}
INT8 GetDrugSideEffect( SOLDIERTYPE *pSoldier, UINT8 ubDrugType )
{
// If we have a o-positive effect
if ( pSoldier->bDrugEffect[ ubDrugType ] > 0 )
{
return( 0 );
}
else
{
return( pSoldier->bDrugSideEffect[ ubDrugType ] );
}
}
void HandleAPEffectDueToDrugs( SOLDIERTYPE *pSoldier, UINT8 *pubPoints )
{
INT8 bDrunkLevel;
INT16 sPoints = (*pubPoints);
// Are we in a side effect or good effect?
if ( pSoldier->bDrugEffect[ DRUG_TYPE_ADRENALINE ] )
{
// Adjust!
sPoints += pSoldier->bDrugEffect[ DRUG_TYPE_ADRENALINE ];
}
else if ( pSoldier->bDrugSideEffect[ DRUG_TYPE_ADRENALINE ] )
{
// Adjust!
sPoints -= pSoldier->bDrugSideEffect[ DRUG_TYPE_ADRENALINE ];
if ( sPoints < AP_MINIMUM )
{
sPoints = AP_MINIMUM;
}
}
bDrunkLevel = GetDrunkLevel( pSoldier );
if ( bDrunkLevel == HUNGOVER )
{
// Reduce....
sPoints -= HANGOVER_AP_REDUCE;
if ( sPoints < AP_MINIMUM )
{
sPoints = AP_MINIMUM;
}
}
(*pubPoints) = (UINT8)sPoints;
}
void HandleBPEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT16 *psPointReduction )
{
INT8 bDrunkLevel;
// Are we in a side effect or good effect?
if ( pSoldier->bDrugEffect[ DRUG_TYPE_ADRENALINE ] )
{
// Adjust!
(*psPointReduction) -= ( pSoldier->bDrugEffect[ DRUG_TYPE_ADRENALINE ] * BP_RATIO_RED_PTS_TO_NORMAL );
}
else if ( pSoldier->bDrugSideEffect[ DRUG_TYPE_ADRENALINE ] )
{
// Adjust!
(*psPointReduction) += ( pSoldier->bDrugSideEffect[ DRUG_TYPE_ADRENALINE ] * BP_RATIO_RED_PTS_TO_NORMAL );
}
bDrunkLevel = GetDrunkLevel( pSoldier );
if ( bDrunkLevel == HUNGOVER )
{
// Reduce....
(*psPointReduction) += HANGOVER_BP_REDUCE;
}
}
INT8 GetDrunkLevel( SOLDIERTYPE *pSoldier )
{
INT8 bNumDrinks;
// If we have a -ve effect ...
if ( pSoldier->bDrugEffect[ DRUG_TYPE_ALCOHOL ] == 0 && pSoldier->bDrugSideEffect[ DRUG_TYPE_ALCOHOL ] == 0 )
{
return( SOBER );
}
if ( pSoldier->bDrugEffect[ DRUG_TYPE_ALCOHOL ] == 0 && pSoldier->bDrugSideEffect[ DRUG_TYPE_ALCOHOL ] != 0 )
{
return( HUNGOVER );
}
// Calculate how many dinks we have had....
bNumDrinks = ( pSoldier->bDrugEffect[ DRUG_TYPE_ALCOHOL ] / ubDrugEffect[ DRUG_TYPE_ALCOHOL ] );
if ( bNumDrinks <= 3 )
{
return( FEELING_GOOD );
}
else if ( bNumDrinks <= 4 )
{
return( BORDERLINE );
}
else
{
return( DRUNK );
}
}
INT32 EffectStatForBeingDrunk( SOLDIERTYPE *pSoldier, INT32 iStat )
{
return( ( iStat * giDrunkModifier[ GetDrunkLevel( pSoldier ) ] / 100 ) );
}
BOOLEAN MercUnderTheInfluence( SOLDIERTYPE *pSoldier )
{
// Are we in a side effect or good effect?
if ( pSoldier->bDrugEffect[ DRUG_TYPE_ADRENALINE ] )
{
return( TRUE );
}
else if ( pSoldier->bDrugSideEffect[ DRUG_TYPE_ADRENALINE ] )
{
return( TRUE );
}
if ( GetDrunkLevel( pSoldier ) != SOBER )
{
return( TRUE );
}
return( FALSE );
}