Files
source/Tactical/Drugs And Alcohol.cpp
T
Wanne 91087ca8c0 ************************************************************
* Merged Source Code from Development Trunk: Revision 4063 *
************************************************************
- Source Code is merged from: https://81.169.133.124/source/ja2/branches/Wanne/JA2%201.13%20MP
- This will be the Source for the Beta 2011 Test

git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@4064 3b4a5df2-a311-0410-b5c6-a8a6f20db521
2011-01-18 09:11:09 +00:00

530 lines
15 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"
#include "GameSettings.h" // SANDRO - had to add this, dammit!
#include "Random.h"
#include "Text.h"
#include "Interface.h"
#endif
//forward declarations of common classes to eliminate includes
class OBJECTTYPE;
class SOLDIERTYPE;
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->drugs.bFutureDrugEffect[ ubDrugType ] + ubDrugEffect[ ubDrugType ] ) < 127 )
{
pSoldier->drugs.bFutureDrugEffect[ ubDrugType ] += ubDrugEffect[ ubDrugType ];
}
pSoldier->drugs.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->drugs.bTimesDrugUsedSinceSleep[ ubDrugType ]++;
// Increment side effects..
if ( ( pSoldier->drugs.bDrugSideEffect[ ubDrugType ] + ubDrugSideEffect[ ubDrugType ] ) < 127 )
{
pSoldier->drugs.bDrugSideEffect[ ubDrugType ] += ( ubDrugSideEffect[ ubDrugType ] );
}
// Stop side effects until were done....
pSoldier->drugs.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....
pObject->RemoveObjectsFromStack(1);
// ATE: Make guy collapse from heart attack if too much stuff taken....
if ( pSoldier->drugs.bDrugSideEffectRate[ ubDrugType ] > ( ubDrugSideEffect[ ubDrugType ] * 3 ) )
{
// Keel over...
DeductPoints( pSoldier, 0, 10000 );
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - if our stat is damaged through facility event, make it healable
// Permanently lower certain stats...
if ( gGameOptions.fNewTraitSystem )
{
// WISDOM decrease
if ( pSoldier->stats.bWisdom > 5 )
{
pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_WISDOM ] += 5;
pSoldier->stats.bWisdom -= 5;
}
else
{
pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_WISDOM ] += (pSoldier->stats.bWisdom - 1);
pSoldier->stats.bWisdom = 1;
}
// DEXTERITY decrease
if ( pSoldier->stats.bDexterity > 5 )
{
pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_DEXTERITY ] += 5;
pSoldier->stats.bDexterity -= 5;
}
else
{
pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_DEXTERITY ] += (pSoldier->stats.bDexterity - 1);
pSoldier->stats.bDexterity = 1;
}
// STRENGTH decrease
if ( pSoldier->stats.bStrength > 5 )
{
pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_STRENGTH ] += 5;
pSoldier->stats.bStrength -= 5;
}
else
{
pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_STRENGTH ] += (pSoldier->stats.bStrength - 1);
pSoldier->stats.bStrength = 1;
}
// AGILITY decrease
if ( pSoldier->stats.bAgility > 5 )
{
pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_AGILITY ] += 5;
pSoldier->stats.bAgility -= 5;
}
else
{
pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_AGILITY ] += (pSoldier->stats.bAgility - 1);
pSoldier->stats.bAgility = 1;
}
}
else // old system
{
pSoldier->stats.bAgility = __max(1, pSoldier->stats.bWisdom-5);
pSoldier->stats.bDexterity = __max(1, pSoldier->stats.bDexterity-5);
pSoldier->stats.bStrength = __max(1, pSoldier->stats.bStrength-5);
pSoldier->stats.bAgility = __max(1, pSoldier->stats.bAgility-5);
// make those stats RED for a while...
// SANDRO - we don't need to do this with new system, as we simply show all damaged stats in red until healed
pSoldier->timeChanges.uiChangeWisdomTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( WIS_INCREASE );
pSoldier->timeChanges.uiChangeDexterityTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( DEX_INCREASE );
pSoldier->timeChanges.uiChangeStrengthTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( STRENGTH_INCREASE );
pSoldier->timeChanges.uiChangeAgilityTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( AGIL_INCREASE );
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// export stat changes to profile
gMercProfiles[ pSoldier->ubProfile ].bWisdom = pSoldier->stats.bWisdom;
gMercProfiles[ pSoldier->ubProfile ].bDexterity = pSoldier->stats.bDexterity;
gMercProfiles[ pSoldier->ubProfile ].bStrength = pSoldier->stats.bStrength;
gMercProfiles[ pSoldier->ubProfile ].bAgility = pSoldier->stats.bAgility;
// SANDRO - merc records - stat damaged
gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++;
}
}
}
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)[0]->data.objectStatus / 100;
// are there fractional %s left over?
if ( ( (*pObject)[0]->data.objectStatus % (100 / REGEN_POINTS_PER_BOOSTER ) ) != 0 )
{
// chance of an extra point
if ( PreRandom( 100 / REGEN_POINTS_PER_BOOSTER ) < (UINT32) ( (*pObject)[0]->data.objectStatus % (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
pObject->RemoveObjectsFromStack(1);
}
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->drugs.bDrugSideEffectRate[ cnt ] > 0 )
{
// Subtract some...
pSoldier->drugs.bDrugSideEffect[ cnt ] -= pSoldier->drugs.bDrugSideEffectRate[ cnt ];
// If we're done, we're done!
if ( pSoldier->drugs.bDrugSideEffect[ cnt ] <= 0 )
{
pSoldier->drugs.bDrugSideEffect[ cnt ] = 0;
fInterfacePanelDirty = DIRTYLEVEL1;
}
}
// IF drug rate is -ve, it's being worn off...
if ( pSoldier->drugs.bDrugEffectRate[ cnt ] < 0 )
{
pSoldier->drugs.bDrugEffect[ cnt ] -= ( -1 * pSoldier->drugs.bDrugEffectRate[ cnt ] );
// Have we run out?
if ( pSoldier->drugs.bDrugEffect[ cnt ] <= 0 )
{
pSoldier->drugs.bDrugEffect[ cnt ] = 0;
// Dirty panel
fInterfacePanelDirty = DIRTYLEVEL2;
// Start the bad news!
pSoldier->drugs.bDrugSideEffectRate[ cnt ] = ubDrugSideEffectRate[ cnt ];
// The drug rate is 0 now too
pSoldier->drugs.bDrugEffectRate[ cnt ] = 0;
// Once for each 'level' of crash....
iNumLoops = ( pSoldier->drugs.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->drugs.bDrugEffectRate[ cnt ] > 0 )
{
// Seap some in....
pSoldier->drugs.bFutureDrugEffect[ cnt ] -= pSoldier->drugs.bDrugEffectRate[ cnt ];
pSoldier->drugs.bDrugEffect[ cnt ] += pSoldier->drugs.bDrugEffectRate[ cnt ];
// Refresh morale w/ new drug value...
RefreshSoldierMorale( pSoldier );
// Check if we need to stop 'adding'
if ( pSoldier->drugs.bFutureDrugEffect[ cnt ] <= 0 )
{
pSoldier->drugs.bFutureDrugEffect[ cnt ] = 0;
// Change rate to -ve..
pSoldier->drugs.bDrugEffectRate[ cnt ] = -ubDrugWearoffRate[ cnt ];
}
}
}
if ( pSoldier->bRegenerationCounter > 0)
{
// bBandaged = BANDAGED( pSoldier );
// increase life
pSoldier->stats.bLife = __min( pSoldier->stats.bLife + LIFE_GAIN_PER_REGEN_POINT, pSoldier->stats.bLifeMax );
//SANDRO - Insta-healable injury reduction
if( pSoldier->iHealableInjury > 0 )
{
pSoldier->iHealableInjury = max(0, (pSoldier->iHealableInjury - (100 * LIFE_GAIN_PER_REGEN_POINT)));
}
if ( pSoldier->stats.bLife == pSoldier->stats.bLifeMax )
{
pSoldier->bBleeding = 0;
pSoldier->iHealableInjury = 0;
}
else if ( pSoldier->bBleeding + pSoldier->stats.bLife > pSoldier->stats.bLifeMax )
{
// got to reduce amount of bleeding
pSoldier->bBleeding = (pSoldier->stats.bLifeMax - pSoldier->stats.bLife);
}
// decrement counter
pSoldier->bRegenerationCounter--;
}
}
INT8 GetDrugEffect( SOLDIERTYPE *pSoldier, UINT8 ubDrugType )
{
return( pSoldier->drugs.bDrugEffect[ ubDrugType ] );
}
INT8 GetDrugSideEffect( SOLDIERTYPE *pSoldier, UINT8 ubDrugType )
{
// If we have a o-positive effect
if ( pSoldier->drugs.bDrugEffect[ ubDrugType ] > 0 )
{
return( 0 );
}
else
{
return( pSoldier->drugs.bDrugSideEffect[ ubDrugType ] );
}
}
void HandleAPEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT16 *pubPoints )
{
INT8 bDrunkLevel;
INT16 sPoints = (*pubPoints);
// Are we in a side effect or good effect?
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ADRENALINE ] )
{
// Adjust!
sPoints += pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ADRENALINE ];
}
else if ( pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_ADRENALINE ] )
{
// Adjust!
sPoints -= pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_ADRENALINE ];
if ( sPoints < APBPConstants[APBPConstants[APBPConstants[AP_MINIMUM]]] )
{
sPoints = APBPConstants[APBPConstants[APBPConstants[AP_MINIMUM]]];
}
}
bDrunkLevel = GetDrunkLevel( pSoldier );
if ( bDrunkLevel == HUNGOVER )
{
// Reduce....
sPoints -= HANGOVER_AP_REDUCE;
if ( sPoints < APBPConstants[APBPConstants[APBPConstants[AP_MINIMUM]]] )
{
sPoints = APBPConstants[APBPConstants[APBPConstants[AP_MINIMUM]]];
}
}
(*pubPoints) = sPoints;
}
void HandleBPEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT16 *psPointReduction )
{
INT8 bDrunkLevel;
// Are we in a side effect or good effect?
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ADRENALINE ] )
{
// Adjust!
(*psPointReduction) -= ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ADRENALINE ] * APBPConstants[BP_RATIO_RED_PTS_TO_NORMAL] );
}
else if ( pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_ADRENALINE ] )
{
// Adjust!
(*psPointReduction) += ( pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_ADRENALINE ] * APBPConstants[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->drugs.bDrugEffect[ DRUG_TYPE_ALCOHOL ] == 0 && pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_ALCOHOL ] == 0 )
{
return( SOBER );
}
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ALCOHOL ] == 0 && pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_ALCOHOL ] != 0 )
{
return( HUNGOVER );
}
// Calculate how many dinks we have had....
bNumDrinks = ( pSoldier->drugs.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->drugs.bDrugEffect[ DRUG_TYPE_ADRENALINE ] )
{
return( TRUE );
}
else if ( pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_ADRENALINE ] )
{
return( TRUE );
}
if ( GetDrunkLevel( pSoldier ) != SOBER )
{
return( TRUE );
}
return( FALSE );
}