New feature: new drug system (by Flugente)

- added many new drug effects. A drug can now have several effects, these can be set via the <DrugType>-tag in Items.xml. 
- Control effect magnitude in Drugs.xml. Added new drugs in Items.xml.
- gave Buns drugs in Kit 5 "Druggist" for demonstration reasons, added drugs to Howard's inventory.
- see also first post in http://www.ja-galaxy-forum.com/board/ubbthreads.php?ubb=showflat&Number=303950#Post303950

WARNING! This will break savegame compatibility!


git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@5225 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
Wanne
2012-04-27 13:22:35 +00:00
parent 4f120f152f
commit fc88abaa5b
24 changed files with 908 additions and 426 deletions
+4
View File
@@ -376,6 +376,10 @@ BOOLEAN LoadExternalGameplayData(STR directoryName)
strcat(fileName, EXPLOSIVESFILENAME);
SGP_THROW_IFFALSE(ReadInExplosiveStats(fileName),EXPLOSIVESFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, DRUGSFILENAME);
SGP_THROW_IFFALSE(ReadInDrugsStats(fileName),DRUGSFILENAME);
strcpy(fileName, directoryName);
strcat(fileName, ARMOURSFILENAME);
SGP_THROW_IFFALSE(ReadInArmourStats(fileName),ARMOURSFILENAME);
+6 -6
View File
@@ -1793,25 +1793,25 @@ void HandleRisksForSoldierFacilityAssignment( SOLDIERTYPE *pSoldier, UINT8 ubFac
}
// Add effects
if ( ( pSoldier->drugs.bFutureDrugEffect[ DRUG_TYPE_ALCOHOL ] + ubDrugEffect[ DRUG_TYPE_ALCOHOL ] ) < 127 )
if ( ( pSoldier->drugs.bFutureDrugEffect[ DRUG_TYPE_ALCOHOL ] + Drug[DRUG_TYPE_ALCOHOL].ubDrugEffect ) < 127 )
{
pSoldier->drugs.bFutureDrugEffect[ DRUG_TYPE_ALCOHOL ] += ubDrugEffect[ DRUG_TYPE_ALCOHOL ];
pSoldier->drugs.bFutureDrugEffect[ DRUG_TYPE_ALCOHOL ] += Drug[DRUG_TYPE_ALCOHOL].ubDrugEffect;
}
pSoldier->drugs.bDrugEffectRate[ DRUG_TYPE_ALCOHOL ] = ubDrugTravelRate[ DRUG_TYPE_ALCOHOL ];
pSoldier->drugs.bDrugEffectRate[ DRUG_TYPE_ALCOHOL ] = Drug[DRUG_TYPE_ALCOHOL].ubDrugTravelRate;
// Reset once we sleep...
pSoldier->drugs.bTimesDrugUsedSinceSleep[ DRUG_TYPE_ALCOHOL ]++;
// Increment side effects..
if ( ( pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_ALCOHOL ] + ubDrugSideEffect[ DRUG_TYPE_ALCOHOL ] ) < 127 )
if ( ( pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_ALCOHOL ] + Drug[DRUG_TYPE_ALCOHOL].ubDrugSideEffect ) < 127 )
{
pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_ALCOHOL ] += ( ubDrugSideEffect[ DRUG_TYPE_ALCOHOL ] );
pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_ALCOHOL ] += ( Drug[DRUG_TYPE_ALCOHOL].ubDrugSideEffect );
}
// Stop side effects until were done....
pSoldier->drugs.bDrugSideEffectRate[ DRUG_TYPE_ALCOHOL ] = 0;
// ATE: Make guy collapse from heart attack if too much stuff taken....
if ( pSoldier->drugs.bDrugSideEffectRate[ DRUG_TYPE_ALCOHOL ] > ( ubDrugSideEffect[ DRUG_TYPE_ALCOHOL ] * 3 ) )
if ( pSoldier->drugs.bDrugSideEffectRate[ DRUG_TYPE_ALCOHOL ] > ( Drug[DRUG_TYPE_ALCOHOL].ubDrugSideEffect * 3 ) )
{
if ( pSoldier->ubProfile == LARRY_NORMAL )
{
+252 -132
View File
@@ -2,11 +2,10 @@
#include "Tactical All.h"
#else
#include "sgp.h"
//#include "soldier control.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"
@@ -21,11 +20,11 @@ class OBJECTTYPE;
class SOLDIERTYPE;
UINT8 ubDrugTravelRate[] = { 4, 2 };
/*UINT8 ubDrugTravelRate[] = { 4, 2 };
UINT8 ubDrugWearoffRate[] = { 2, 2 };
UINT8 ubDrugEffect[] = { 15, 8 };
UINT8 ubDrugEffect[] = { 15, 8 };
UINT8 ubDrugSideEffect[] = { 20, 10 };
UINT8 ubDrugSideEffectRate[] = { 2, 1 };
UINT8 ubDrugSideEffectRate[] = { 2, 1 };*/
INT32 giDrunkModifier[] =
{
@@ -40,43 +39,19 @@ INT32 giDrunkModifier[] =
#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;
UINT32 ubDrugType;
INT8 bRegenPointsGained;
UINT16 usItem;
usItem = pObject->usItem;
// If not a syringe, return
ubDrugType = GetDrugType( usItem );
// Determine what type of drug....
if ( ubDrugType == NO_DRUG )
ubDrugType = Item[usItem].drugtype;
// If not a drug, return
if ( ubDrugType == 0 )
{
return( FALSE );
}
@@ -91,63 +66,37 @@ BOOLEAN ApplyDrugs( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject )
gMercProfiles[ LARRY_DRUNK ].bNPCData = 0;
}
if ( ubDrugType < NUM_COMPLEX_DRUGS )
// Flugente: we have to check for every single type of drug ( a drug applied may consist of several 'pure' drug types)
for (UINT8 i = DRUG_TYPE_ADRENALINE; i < DRUG_TYPE_MAX; ++i)
{
UINT32 drugtestflag = (1 << i); // comparing with this flag will determine the drug
// Add effects
if ( ( pSoldier->drugs.bFutureDrugEffect[ ubDrugType ] + ubDrugEffect[ ubDrugType ] ) < 127 )
// we do not actually test for DRUG_REGENERATION, because that is checked afterwards separately
if ( (drugtestflag & DRUG_REGENERATION ) != 0 )
continue;
if ( (ubDrugType & drugtestflag) != 0 )
{
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 )
// Add effects
if ( ( pSoldier->drugs.bFutureDrugEffect[ i ] + Drug[i].ubDrugEffect ) < 127 )
{
gMercProfiles[ pSoldier->ubProfile ].ubNumTimesDrugUseInLifetime++;
pSoldier->drugs.bFutureDrugEffect[ i ] += Drug[i].ubDrugEffect;
}
}
pSoldier->drugs.bDrugEffectRate[ i ] = Drug[i].ubDrugTravelRate;
// Reset once we sleep...
pSoldier->drugs.bTimesDrugUsedSinceSleep[ ubDrugType ]++;
// Reset once we sleep...
pSoldier->drugs.bTimesDrugUsedSinceSleep[ i ]++;
// 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 )
// Increment side effects..
if ( ( pSoldier->drugs.bDrugSideEffect[ i ] + Drug[i].ubDrugSideEffect ) < 127 )
{
ubKitPoints = 10;
pSoldier->drugs.bDrugSideEffect[ i ] += ( Drug[i].ubDrugSideEffect );
}
else if ( usItem == WINE )
{
ubKitPoints = 20;
}
else
{
ubKitPoints = 100;
}
UseKitPoints( pObject, ubKitPoints, pSoldier );
}
else
{
// Remove the object....
pObject->RemoveObjectsFromStack(1);
// Stop side effects until were done....
pSoldier->drugs.bDrugSideEffectRate[ i ] = 0;
// ATE: Make guy collapse from heart attack if too much stuff taken....
if ( pSoldier->drugs.bDrugSideEffectRate[ ubDrugType ] > ( ubDrugSideEffect[ ubDrugType ] * 3 ) )
if ( pSoldier->drugs.bDrugSideEffectRate[ i ] > ( Drug[i].ubDrugSideEffect * 3 ) )
{
// Keel over...
DeductPoints( pSoldier, 0, 10000 );
@@ -208,7 +157,7 @@ BOOLEAN ApplyDrugs( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject )
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();
@@ -233,36 +182,49 @@ BOOLEAN ApplyDrugs( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject )
}
}
}
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)
if ( (ubDrugType & DRUG_REGENERATION) != 0 )
{
// 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 ) ) )
{
// can't go above the points you get for a full boost
pSoldier->bRegenerationCounter = __min( pSoldier->bRegenerationCounter + bRegenPointsGained, REGEN_POINTS_PER_BOOSTER );
bRegenPointsGained++;
}
pSoldier->bRegenBoostersUsedToday++;
}
// remove object
pObject->RemoveObjectsFromStack(1);
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++;
}
if ( ubDrugType == DRUG_TYPE_ALCOHOL )
// ATE: use kit points...
if ( usItem == ALCOHOL )
UseKitPoints( pObject, 10, pSoldier );
else if ( usItem == WINE )
UseKitPoints( pObject, 20, pSoldier );
else if ( usItem == BEER )
UseKitPoints( pObject, 100, pSoldier );
else
{
// remove object
pObject->RemoveObjectsFromStack(1);
if ( gMercProfiles[ pSoldier->ubProfile ].ubNumTimesDrugUseInLifetime != 255 )
{
gMercProfiles[ pSoldier->ubProfile ].ubNumTimesDrugUseInLifetime++;
}
}
if ( (ubDrugType & DRUG_TYPE_ALCOHOL) != 0 )
{
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_DRANK_SOME ], pSoldier->name, ShortItemNames[ usItem ] );
}
@@ -281,10 +243,16 @@ void HandleEndTurnDrugAdjustments( SOLDIERTYPE *pSoldier )
{
INT32 cnt, cnt2;
INT32 iNumLoops;
// INT8 bBandaged;
for ( cnt = 0; cnt < NUM_COMPLEX_DRUGS; cnt++ )
// We test for every 'pure' drug separately
for (cnt = DRUG_TYPE_ADRENALINE; cnt < DRUG_TYPE_MAX; ++cnt)
{
UINT32 drugtestflag = (1 << cnt); // comparing with this flag will determine the drug
// we do not actually test for DRUG_REGENERATION, because that is checked afterwards separately
if ( (drugtestflag & DRUG_REGENERATION ) != 0 )
continue;
// If side effect aret is non-zero....
if ( pSoldier->drugs.bDrugSideEffectRate[ cnt ] > 0 )
{
@@ -295,6 +263,7 @@ void HandleEndTurnDrugAdjustments( SOLDIERTYPE *pSoldier )
if ( pSoldier->drugs.bDrugSideEffect[ cnt ] <= 0 )
{
pSoldier->drugs.bDrugSideEffect[ cnt ] = 0;
pSoldier->drugs.bDrugSideEffectRate[ cnt ] = 0;
fInterfacePanelDirty = DIRTYLEVEL1;
}
}
@@ -309,28 +278,32 @@ void HandleEndTurnDrugAdjustments( SOLDIERTYPE *pSoldier )
{
pSoldier->drugs.bDrugEffect[ cnt ] = 0;
// Dirty panel
fInterfacePanelDirty = DIRTYLEVEL2;
// Dirty panel
fInterfacePanelDirty = DIRTYLEVEL2;
// Start the bad news!
pSoldier->drugs.bDrugSideEffectRate[ cnt ] = ubDrugSideEffectRate[ cnt ];
pSoldier->drugs.bDrugSideEffectRate[ cnt ] = Drug[cnt].ubDrugSideEffectRate;
// 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++ )
// morla downer only if side effect exists and this effect is allowed for a drug
if ( Drug[cnt].ubDrugSideEffect > 0 && Drug[cnt].ubMoralBacklash > 0 )
{
// OK, give a much BIGGER morale downer
if ( cnt == DRUG_TYPE_ALCOHOL )
// Once for each 'level' of crash....
iNumLoops = ( pSoldier->drugs.bDrugSideEffect[ cnt ] / Drug[cnt].ubDrugSideEffect ) + 1;
for ( cnt2 = 0; cnt2 < iNumLoops; ++cnt2 )
{
HandleMoraleEvent( pSoldier, MORALE_ALCOHOL_CRASH, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ );
}
else
{
HandleMoraleEvent( pSoldier, MORALE_DRUGS_CRASH, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ );
// 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 );
}
}
}
}
@@ -341,7 +314,7 @@ void HandleEndTurnDrugAdjustments( SOLDIERTYPE *pSoldier )
{
// Seap some in....
pSoldier->drugs.bFutureDrugEffect[ cnt ] -= pSoldier->drugs.bDrugEffectRate[ cnt ];
pSoldier->drugs.bDrugEffect[ cnt ] += pSoldier->drugs.bDrugEffectRate[ cnt ];
pSoldier->drugs.bDrugEffect[ cnt ] += pSoldier->drugs.bDrugEffectRate[ cnt ];
// Refresh morale w/ new drug value...
RefreshSoldierMorale( pSoldier );
@@ -351,7 +324,7 @@ void HandleEndTurnDrugAdjustments( SOLDIERTYPE *pSoldier )
{
pSoldier->drugs.bFutureDrugEffect[ cnt ] = 0;
// Change rate to -ve..
pSoldier->drugs.bDrugEffectRate[ cnt ] = -ubDrugWearoffRate[ cnt ];
pSoldier->drugs.bDrugEffectRate[ cnt ] = -Drug[cnt].ubDrugWearoffRate;
}
}
}
@@ -383,6 +356,121 @@ void HandleEndTurnDrugAdjustments( SOLDIERTYPE *pSoldier )
// decrement counter
pSoldier->bRegenerationCounter--;
}
// Flugente: always do the following checks. Thereby, if the effect runs out, our stats will be back to normal
//////////////// STRENGTH ////////////////
// strength we would normally have right now
INT8 strength = gMercProfiles[ pSoldier->ubProfile ].bStrength - pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_STRENGTH ];
INT8 strengthmodifier = pSoldier->drugs.bDrugEffect[ DRUG_TYPE_STRENGTH ] - pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_STRENGTH ];
// cap modifier at 25, as currently stats cant go above 127 (INT8)
strengthmodifier = min(25, strengthmodifier);
UINT32 newstrength = max(1, strength + strengthmodifier);
newstrength = min(126, newstrength);
pSoldier->stats.bStrength = (INT8)newstrength;
if ( strengthmodifier > 0 )
{
pSoldier->timeChanges.uiChangeStrengthTime = GetJA2Clock();
pSoldier->usValueGoneUp |= ( STRENGTH_INCREASE );
}
else if ( strengthmodifier < 0 )
{
pSoldier->timeChanges.uiChangeStrengthTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( STRENGTH_INCREASE );
}
//////////////// DEXTERITY ////////////////
// dexterity we would normally have right now
INT8 dexterity = gMercProfiles[ pSoldier->ubProfile ].bDexterity - pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_DEXTERITY ];
INT8 dexteritymodifier = pSoldier->drugs.bDrugEffect[ DRUG_TYPE_DEXTERITY ] - pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_DEXTERITY ];
// cap modifier at 25, as currently stats cant go above 127 (INT8)
dexteritymodifier = min(25, dexteritymodifier);
UINT32 newdexterity = max(1, dexterity + dexteritymodifier);
newdexterity = min(126, newdexterity);
pSoldier->stats.bDexterity = newdexterity;
if ( dexteritymodifier > 0 )
{
pSoldier->timeChanges.uiChangeDexterityTime = GetJA2Clock();
pSoldier->usValueGoneUp |= ( DEX_INCREASE );
}
else if ( dexteritymodifier < 0 )
{
pSoldier->timeChanges.uiChangeDexterityTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( DEX_INCREASE );
}
//////////////// AGILITY ////////////////
// agility we would normally have right now
INT8 agility = gMercProfiles[ pSoldier->ubProfile ].bAgility - pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_AGILITY ];
INT8 agilitymodifier = pSoldier->drugs.bDrugEffect[ DRUG_TYPE_AGILITY ] - pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_AGILITY ];
// cap modifier at 25, as currently stats cant go above 127 (INT8)
agilitymodifier = min(25, agilitymodifier);
UINT32 newagility = max(1, agility + agilitymodifier);
newagility = min(126, newagility);
pSoldier->stats.bAgility = newagility;
if ( agilitymodifier > 0 )
{
pSoldier->timeChanges.uiChangeAgilityTime = GetJA2Clock();
pSoldier->usValueGoneUp |= ( AGIL_INCREASE );
}
else if ( agilitymodifier < 0 )
{
pSoldier->timeChanges.uiChangeAgilityTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( AGIL_INCREASE );
}
//////////////// WISDOM ////////////////
// wisdom we would normally have right now
INT8 wisdom = gMercProfiles[ pSoldier->ubProfile ].bWisdom - pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_WISDOM ];
INT8 wisdommodifier = pSoldier->drugs.bDrugEffect[ DRUG_TYPE_WISDOM ] - pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_WISDOM ];
// cap modifier at 25, as currently stats cant go above 127 (INT8)
wisdommodifier = min(25, wisdommodifier);
UINT32 newwisdom = max(1, wisdom + wisdommodifier);
newwisdom = min(126, newwisdom);
pSoldier->stats.bWisdom = newwisdom;
if ( wisdommodifier > 0 )
{
pSoldier->timeChanges.uiChangeWisdomTime = GetJA2Clock();
pSoldier->usValueGoneUp |= ( WIS_INCREASE );
}
else if ( wisdommodifier < 0 )
{
pSoldier->timeChanges.uiChangeWisdomTime = GetJA2Clock();
pSoldier->usValueGoneUp &= ~( WIS_INCREASE );
}
// if our sideeffect count is 1 (which should occur a while AFTER we took the drug), we suddenly become blind for a few turns...
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_BLIND ] == 0 && pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_BLIND ] == 1 )
{
pSoldier->bBlindedCounter = 3;
}
// if our sideeffect count is 1 (which should occur a while AFTER we took the drug), we get a heart-attack and get knocked out...
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_KNOCKOUT ] == 0 && pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_KNOCKOUT ] == 1 )
{
// Keel over...
DeductPoints( pSoldier, 0, 20000 );
}
}
INT8 GetDrugEffect( SOLDIERTYPE *pSoldier, UINT8 ubDrugType )
@@ -425,7 +513,7 @@ void HandleAPEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT16 *pubPoints )
sPoints = APBPConstants[APBPConstants[APBPConstants[AP_MINIMUM]]];
}
}
bDrunkLevel = GetDrunkLevel( pSoldier );
if ( bDrunkLevel == HUNGOVER )
@@ -468,6 +556,21 @@ void HandleBPEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT16 *psPointReduction )
}
}
void HandleDamageResistanceEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT32 *psPointReduction )
{
// Are we in a side effect or good effect?
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_RESISTANCE ] )
{
// Adjust!
(*psPointReduction) += pSoldier->drugs.bDrugEffect[ DRUG_TYPE_RESISTANCE ];
}
else if ( pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_RESISTANCE ] )
{
// Adjust!
(*psPointReduction) -= pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_RESISTANCE ];
}
}
INT8 GetDrunkLevel( SOLDIERTYPE *pSoldier )
{
@@ -485,7 +588,7 @@ INT8 GetDrunkLevel( SOLDIERTYPE *pSoldier )
}
// Calculate how many dinks we have had....
bNumDrinks = ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ALCOHOL ] / ubDrugEffect[ DRUG_TYPE_ALCOHOL ] );
bNumDrinks = ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ALCOHOL ] / Drug[DRUG_TYPE_ALCOHOL].ubDrugEffect );
if ( bNumDrinks <= 3 )
{
@@ -510,17 +613,34 @@ INT32 EffectStatForBeingDrunk( SOLDIERTYPE *pSoldier, INT32 iStat )
BOOLEAN MercUnderTheInfluence( SOLDIERTYPE *pSoldier )
{
// Are we in a side effect or good effect?
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ADRENALINE ] )
for (UINT8 cnt = DRUG_TYPE_ADRENALINE; cnt < DRUG_TYPE_MAX; ++cnt)
{
return( TRUE );
}
else if ( pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_ADRENALINE ] )
{
return( TRUE );
// Are we in a side effect or good effect?
if ( pSoldier->drugs.bDrugEffect[ cnt ] )
{
return( TRUE );
}
else if ( pSoldier->drugs.bDrugSideEffect[ cnt ] )
{
return( TRUE );
}
}
if ( GetDrunkLevel( pSoldier ) != SOBER )
return( FALSE );
}
BOOLEAN MercUnderTheInfluence( SOLDIERTYPE *pSoldier, UINT8 aDrugType )
{
// in case of wrong inout, stay safe
if ( aDrugType >= DRUG_TYPE_MAX )
return( FALSE );
// Are we in a side effect or good effect?
if ( pSoldier->drugs.bDrugEffect[ aDrugType ] )
{
return( TRUE );
}
else if ( pSoldier->drugs.bDrugSideEffect[ aDrugType ] )
{
return( TRUE );
}
+81 -12
View File
@@ -1,35 +1,104 @@
#ifndef __DRUGS_AND_ALCOHOL_H
#define __DRUGS_AND_ALCOHOL_H
#include "soldier control.h"
#define DRUG_TYPE_ADRENALINE 0
#define DRUG_TYPE_ALCOHOL 1
#define NO_DRUG 2
#define NUM_COMPLEX_DRUGS 2
#define DRUG_TYPE_REGENERATION 3
#define SOBER 0
#define FEELING_GOOD 1
#define BORDERLINE 2
#define DRUNK 3
#define HUNGOVER 4
#define SOBER 0
#define FEELING_GOOD 1
#define BORDERLINE 2
#define DRUNK 3
#define HUNGOVER 4
#define REGEN_POINTS_PER_BOOSTER 4
#define LIFE_GAIN_PER_REGEN_POINT 10
UINT8 GetDrugType( UINT16 usItem );
enum {
DRUG_TYPE_ADRENALINE = 0,
DRUG_TYPE_ALCOHOL,
DRUG_TYPE_REGENERATION,
DRUG_TYPE_RESISTANCE,
DRUG_TYPE_STRENGTH,
DRUG_TYPE_AGILITY, // 5
DRUG_TYPE_DEXTERITY,
DRUG_TYPE_WISDOM,
DRUG_TYPE_PERCEPTION,
DRUG_TYPE_PSYCHO,
DRUG_TYPE_NERVOUS, // 10
DRUG_TYPE_CLAUSTROPHOBIC,
DRUG_TYPE_HEATINTOLERANT,
DRUG_TYPE_FEAROFINSECTS,
DRUG_TYPE_FORGETFUL,
DRUG_TYPE_BLIND, // 15
DRUG_TYPE_KNOCKOUT,
DRUG_TYPE_VISION,
DRUG_TYPE_TUNNELVISION
};
// Flugente, 12-04-21
// These flags determine the different types of 'pure' drugs that we have. Each one has specific effects and sideeffects
// Note that a consumable can be a combination of several different drugs
#define DRUG_ADRENALINE (1 << DRUG_TYPE_ADRENALINE) //0x00000001 //1
#define DRUG_ALCOHOL (1 << DRUG_TYPE_ALCOHOL) //0x00000002 //2
#define DRUG_REGENERATION (1 << DRUG_TYPE_REGENERATION) //0x00000004 //4
#define DRUG_DAMAGERESISTANCE (1 << DRUG_TYPE_RESISTANCE) //0x00000008 //8
#define DRUG_STRENGTH (1 << DRUG_TYPE_STRENGTH) //0x00000010 //16
#define DRUG_AGILITY (1 << DRUG_TYPE_AGILITY) //0x00000020 //32
#define DRUG_DEXTERITY (1 << DRUG_TYPE_DEXTERITY) //0x00000040 //64
#define DRUG_WISDOM (1 << DRUG_TYPE_WISDOM) //0x00000080 //128
#define DRUG_PERCEPTION (1 << DRUG_TYPE_PERCEPTION) //0x00000100 //256
#define DRUG_PSYCHO (1 << DRUG_TYPE_PSYCHO) //0x00000200 //512
#define DRUG_NERVOUS (1 << DRUG_TYPE_NERVOUS) //0x00000400 //1024
#define DRUG_CLAUSTROPHOBIC (1 << DRUG_TYPE_CLAUSTROPHOBIC) //0x00000800 //2048
#define DRUG_HEATINTOLERANT (1 << DRUG_TYPE_HEATINTOLERANT) //0x00001000 //4096
#define DRUG_FEAROFINSECTS (1 << DRUG_TYPE_FEAROFINSECTS) //0x00002000 //8192
#define DRUG_FORGETFUL (1 << DRUG_TYPE_FORGETFUL) //0x00004000 //16384
#define DRUG_BLIND (1 << DRUG_TYPE_BLIND) //0x00008000 //32768
#define DRUG_KNOCKOUT (1 << DRUG_TYPE_KNOCKOUT) //0x00010000 //65536
#define DRUG_VISION (1 << DRUG_TYPE_VISION) //0x00020000 //131072
#define DRUG_TUNNELVISION (1 << DRUG_TYPE_TUNNELVISION) //0x00040000 //262144
#define DRUG_MISC_6 0x00080000 //524288
#define DRUG_MISC_7 0x00100000 //1048576
#define DRUG_MISC_8 0x00200000 //2097152
#define DRUG_MISC_9 0x00400000 //4194304
#define DRUG_MISC_10 0x00800000 //8388608
#define DRUG_MISC_11 0x01000000 //16777216
#define DRUG_MISC_12 0x02000000 //33554432
#define DRUG_MISC_13 0x04000000 //67108864
#define DRUG_MISC_14 0x08000000 //134217728
#define DRUG_MISC_15 0x10000000 //268435456
#define DRUG_MISC_16 0x20000000 //536870912
#define DRUG_MISC_17 0x40000000 //1073741824
#define DRUG_MISC_18 0x80000000 //2147483648
typedef struct
{
UINT8 ubType; // type of drug: bit field
UINT8 ubDrugTravelRate;
UINT8 ubDrugWearoffRate;
UINT8 ubDrugEffect;
UINT8 ubDrugSideEffect;
UINT8 ubDrugSideEffectRate;
UINT8 ubMoralBacklash;
} DRUGTYPE;
//GLOBALS
extern DRUGTYPE Drug[DRUG_TYPE_MAX];
BOOLEAN ApplyDrugs( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject );
void HandleEndTurnDrugAdjustments( SOLDIERTYPE *pSoldier );
void HandleAPEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT16 *pubPoints );
void HandleBPEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT16 *psPoints );
void HandleDamageResistanceEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT32 *psPoints );
INT8 GetDrugEffect( SOLDIERTYPE *pSoldier, UINT8 ubDrugType );
INT8 GetDrugSideEffect( SOLDIERTYPE *pSoldier, UINT8 ubDrugType );
INT8 GetDrugAllEffect( SOLDIERTYPE *pSoldier, UINT8 ubDrugType );
INT8 GetDrunkLevel( SOLDIERTYPE *pSoldier );
INT32 EffectStatForBeingDrunk( SOLDIERTYPE *pSoldier, INT32 iStat );
BOOLEAN MercUnderTheInfluence( SOLDIERTYPE *pSoldier );
BOOLEAN MercUnderTheInfluence( SOLDIERTYPE *pSoldier, UINT8 aDrugType );
#endif
+2 -1
View File
@@ -2273,7 +2273,8 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE
bNumRightIcons++;
}
if ( MercPtrs[ pFace->ubSoldierID ]->drugs.bDrugEffect[ DRUG_TYPE_ADRENALINE ] )
// Flugente: add the drug symbol for more drugs
if ( MercPtrs[ pFace->ubSoldierID ]->drugs.bDrugEffect[ DRUG_TYPE_ADRENALINE ] || MercPtrs[ pFace->ubSoldierID ]->drugs.bDrugEffect[ DRUG_TYPE_STRENGTH ] || MercPtrs[ pFace->ubSoldierID ]->drugs.bDrugEffect[ DRUG_TYPE_AGILITY ] || MercPtrs[ pFace->ubSoldierID ]->drugs.bDrugEffect[ DRUG_TYPE_DEXTERITY ] || MercPtrs[ pFace->ubSoldierID ]->drugs.bDrugEffect[ DRUG_TYPE_WISDOM ] )
{
DoRightIcon( uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons, 7 );
bNumRightIcons++;
+6 -2
View File
@@ -64,6 +64,8 @@
// added by SANDRO
#include "Game Clock.h"
#include "Morale.h"
// added by Flugente
#include "drugs and alcohol.h"
#endif
#ifdef JA2UB
@@ -445,7 +447,8 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
// If this is a player guy, show message about no APS
if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) )
{
if ( (pSoldier->ubProfile != NO_PROFILE) && (gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO) )
// Flugente: drugs can temporarily cause a merc to go psycho
if ( (pSoldier->ubProfile != NO_PROFILE) && ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO) || MercUnderTheInfluence(pSoldier, DRUG_TYPE_PSYCHO) ) )
{
// psychos might possibly switch to burst if they can
// Changed by ADB, rev 1513
@@ -519,7 +522,8 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
UINT32 roll;
// SANDRO - changed Random to PreRandom to avoid save-load mania
if((pSoldier->ubProfile != NO_PROFILE) && (gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO) && PreRandom(100) < 20)
// Flugente: drugs can temporarily cause a merc to go psycho
if((pSoldier->ubProfile != NO_PROFILE) && ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO) || MercUnderTheInfluence(pSoldier, DRUG_TYPE_PSYCHO) ) && PreRandom(100) < 20)
{
chanceToMisfire = diceSides;
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, gzLateLocalizedString[ 26 ], pSoldier->name );
+8 -2
View File
@@ -2958,7 +2958,10 @@ void RenderSMPanel( BOOLEAN *pfDirty )
if ( MercUnderTheInfluence( gpSMCurrentMerc ) )
{
SetFontBackground( FONT_MCOLOR_BLACK );
SetFontForeground( FONT_MCOLOR_LTBLUE );
//SetFontForeground( FONT_MCOLOR_LTBLUE );
// Flugente: new colour for being drugged, as blue on black was hard to see
SetRGBFontForeground( 250, 5, 250 );
}
else if ( gpSMCurrentMerc->bStealthMode )
{
@@ -5469,7 +5472,10 @@ void RenderTEAMPanel( BOOLEAN fDirty )
if ( MercUnderTheInfluence( pSoldier ) )
{
SetFontBackground( FONT_MCOLOR_BLACK );
SetFontForeground( FONT_MCOLOR_LTBLUE );
//SetFontForeground( FONT_MCOLOR_LTBLUE );
// Flugente: new colour for being drugged, as blue on black was hard to see
SetRGBFontForeground( 250, 5, 250 );
}
else if ( pSoldier->bStealthMode )
{
+2
View File
@@ -943,6 +943,8 @@ typedef struct
BOOLEAN tripwireactivation; // item (mine) can be activated by nearby tripwire
BOOLEAN tripwire; // item is tripwire
BOOLEAN directional; // item is a directional mine/bomb (actual direction is set upon planting)
UINT32 drugtype; // this flagmask determines what different components are used in a drug, which results in different effects
} INVTYPE;
+20
View File
@@ -58,6 +58,8 @@
// THE_BOB : added for pocket popup definitions
#include <map>
#include "popup_definition.h"
#include "drugs and alcohol.h"
#endif
#ifdef JA2UB
@@ -1251,6 +1253,8 @@ std::map<UINT8,popupDef> LBEPocketPopup;
// { /* Knife Pocket */ 5, 0, 1, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }
//};
DRUGTYPE Drug[DRUG_TYPE_MAX];
BOOLEAN ItemIsLegal( UINT16 usItemIndex, BOOLEAN fIgnoreCoolness )
{
if ( Item[usItemIndex].ubCoolness == 0 && !fIgnoreCoolness )
@@ -10594,6 +10598,16 @@ INT16 GetTotalVisionRangeBonus( SOLDIERTYPE * pSoldier, UINT8 bLightLevel )
bonus += GetBrightLightVisionRangeBonus(pSoldier, bLightLevel);
}
// Flugente: drugs can alter our sight
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_VISION ] )
{
bonus += 10;
}
else if ( pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_VISION ] )
{
bonus -= 10;
}
// SANDRO - STOMP traits - Scouting bonus for sight range with binoculars and similar
if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pSoldier, SCOUTING_NT ) && pSoldier->pathing.bLevel == 0 )
{
@@ -10731,6 +10745,12 @@ UINT8 GetPercentTunnelVision( SOLDIERTYPE * pSoldier )
}
}
// Flugente: drugs can alter our vision
if ( pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_TUNNELVISION ] )
{
bonus = __min(100, bonus + 25);
}
if ( !PTR_OURTEAM ) // Madd: adjust tunnel vision by difficulty level
bonus /= gGameOptions.ubDifficultyLevel;
+62 -50
View File
@@ -72,7 +72,7 @@ MoraleEvent gbMoraleEvent[NUM_MORALE_EVENTS] =
{ STRATEGIC_MORALE_EVENT, -5}, // MORALE_HIGH_DEATHRATE,
{ STRATEGIC_MORALE_EVENT, +2}, // MORALE_GREAT_MORALE,
{ STRATEGIC_MORALE_EVENT, -2}, // MORALE_POOR_MORALE,
{ TACTICAL_MORALE_EVENT, -10}, // MORALE_DRUGS_CRASH
{ TACTICAL_MORALE_EVENT, -5}, // MORALE_DRUGS_CRASH // Flugente: lowered as drugs can have several components that have a backlash, causing the the morale to plummet drastical
{ TACTICAL_MORALE_EVENT, -10}, // MORALE_ALCOHOL_CRASH
{ STRATEGIC_MORALE_EVENT, +15}, // MORALE_MONSTER_QUEEN_KILLED
{ STRATEGIC_MORALE_EVENT, +25}, // MORALE_DEIDRANNA_KILLED
@@ -185,67 +185,79 @@ void DecayTacticalMoraleModifiers( void )
continue;
}
switch( gMercProfiles[ pSoldier->ubProfile ].bDisability )
// Flugente: drugs can temporarily cause a merc get a new disability
// therefore we change this routine
BOOLEAN isClaustrophobic = gMercProfiles[ pSoldier->ubProfile ].bDisability == CLAUSTROPHOBIC ? TRUE : FALSE;
BOOLEAN isNervous = gMercProfiles[ pSoldier->ubProfile ].bDisability == NERVOUS ? TRUE : FALSE;
if ( MercUnderTheInfluence(pSoldier, DRUG_TYPE_CLAUSTROPHOBIC) )
isClaustrophobic = TRUE;
if ( MercUnderTheInfluence(pSoldier, DRUG_TYPE_NERVOUS) )
isNervous = TRUE;
if ( isClaustrophobic )
{
case CLAUSTROPHOBIC:
if ( pSoldier->bSectorZ > 0 )
if ( pSoldier->bSectorZ > 0 )
{
// underground, no recovery... in fact, if tact morale is high, decay
if ( pSoldier->aiData.bTacticalMoraleMod > PHOBIC_LIMIT )
{
// underground, no recovery... in fact, if tact morale is high, decay
if ( pSoldier->aiData.bTacticalMoraleMod > PHOBIC_LIMIT )
{
HandleMoraleEvent( pSoldier, MORALE_CLAUSTROPHOBE_UNDERGROUND, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ );
}
continue;
HandleMoraleEvent( pSoldier, MORALE_CLAUSTROPHOBE_UNDERGROUND, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ );
}
break;
case NERVOUS:
if ( pSoldier->aiData.bMorale < 50 )
{
if (pSoldier->ubGroupID != 0 && PlayerIDGroupInMotion( pSoldier->ubGroupID ))
{
if ( NumberOfPeopleInSquad( pSoldier->bAssignment ) == 1 )
{
fHandleNervous = TRUE;
}
else
{
fHandleNervous = FALSE;
}
}
else if ( pSoldier->bActive && pSoldier->bInSector )
}
}
if ( isNervous )
{
if ( pSoldier->aiData.bMorale < 50 )
{
if (pSoldier->ubGroupID != 0 && PlayerIDGroupInMotion( pSoldier->ubGroupID ))
{
if ( NumberOfPeopleInSquad( pSoldier->bAssignment ) == 1 )
{
if ( DistanceToClosestFriend( pSoldier ) > NERVOUS_RADIUS )
{
fHandleNervous = TRUE;
}
else
{
fHandleNervous = FALSE;
}
fHandleNervous = TRUE;
}
else
{
// look for anyone else in same sector
fHandleNervous = FALSE;
}
}
else if ( pSoldier->bActive && pSoldier->bInSector )
{
if ( DistanceToClosestFriend( pSoldier ) > NERVOUS_RADIUS )
{
fHandleNervous = TRUE;
for ( ubLoop2 = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; ubLoop2 <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ubLoop2++ )
}
else
{
fHandleNervous = FALSE;
}
}
else
{
// look for anyone else in same sector
fHandleNervous = TRUE;
for ( ubLoop2 = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; ubLoop2 <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ubLoop2++ )
{
if ( MercPtrs[ ubLoop2 ] != pSoldier && MercPtrs[ ubLoop2 ]->bActive && MercPtrs[ ubLoop2 ]->sSectorX == pSoldier->sSectorX && MercPtrs[ ubLoop2 ]->sSectorY == pSoldier->sSectorY && MercPtrs[ ubLoop2 ]->bSectorZ == pSoldier->bSectorZ )
{
if ( MercPtrs[ ubLoop2 ] != pSoldier && MercPtrs[ ubLoop2 ]->bActive && MercPtrs[ ubLoop2 ]->sSectorX == pSoldier->sSectorX && MercPtrs[ ubLoop2 ]->sSectorY == pSoldier->sSectorY && MercPtrs[ ubLoop2 ]->bSectorZ == pSoldier->bSectorZ )
{
// found someone!
fHandleNervous = FALSE;
break;
}
// found someone!
fHandleNervous = FALSE;
break;
}
}
}
if ( fHandleNervous )
if ( fHandleNervous )
{
if ( pSoldier->aiData.bTacticalMoraleMod == PHOBIC_LIMIT )
{
// don't change morale
//continue;
}
else
{
if ( pSoldier->aiData.bTacticalMoraleMod == PHOBIC_LIMIT )
{
// don't change morale
continue;
}
// alone, no recovery... in fact, if tact morale is high, decay
if ( !(pSoldier->usQuoteSaidFlags & SOLDIER_QUOTE_SAID_PERSONALITY) )
{
@@ -253,9 +265,9 @@ void DecayTacticalMoraleModifiers( void )
pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_PERSONALITY;
}
HandleMoraleEvent( pSoldier, MORALE_NERVOUS_ALONE, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ );
continue;
}
}
}
}
DecayTacticalMorale( pSoldier );
+9
View File
@@ -3235,6 +3235,15 @@ void InternalSelectSoldier( UINT16 usSoldierID, BOOLEAN fAcknowledge, BOOLEAN fF
}
break;
default:
// Flugente: drugs can temporarily cause a merc to go psycho
if ( MercUnderTheInfluence(pSoldier, DRUG_TYPE_PSYCHO) )
{
if ( Random( 50 ) == 0 )
{
TacticalCharacterDialogue( pSoldier, QUOTE_PERSONALITY_TRAIT );
pSoldier->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_PERSONALITY;
}
}
break;
}
}
+4 -3
View File
@@ -152,12 +152,13 @@ INT8 EffectiveExpLevel( SOLDIERTYPE * pSoldier )
if (pSoldier->ubProfile != NO_PROFILE)
{
if ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == CLAUSTROPHOBIC) && pSoldier->bActive && pSoldier->bInSector && gbWorldSectorZ > 0)
// Flugente: drugs can temporarily cause a merc to be claustrophobic
if ( ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == CLAUSTROPHOBIC) || MercUnderTheInfluence(pSoldier, DRUG_TYPE_CLAUSTROPHOBIC) ) && pSoldier->bActive && pSoldier->bInSector && gbWorldSectorZ > 0)
{
// claustrophobic!
iEffExpLevel -= 2;
}
else if ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == FEAR_OF_INSECTS) && MercIsInTropicalSector( pSoldier ) )
else if ( ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == FEAR_OF_INSECTS) || MercUnderTheInfluence(pSoldier, DRUG_TYPE_FEAROFINSECTS) )&& MercIsInTropicalSector( pSoldier ) )
{
// SANDRO - fear of insects, and we are in tropical sector
iEffExpLevel -= 1;
@@ -564,7 +565,7 @@ INT32 SkillCheck( SOLDIERTYPE * pSoldier, INT8 bReason, INT8 bChanceMod )
iChance -= 15;
}
// also added a small penalty for fear of insects in tropical sectors
else if ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == FEAR_OF_INSECTS) && MercIsInTropicalSector( pSoldier ))
else if ( ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == FEAR_OF_INSECTS) || MercUnderTheInfluence(pSoldier, DRUG_TYPE_FEAROFINSECTS) ) && MercIsInTropicalSector( pSoldier ))
{
// fear of insects, and we are in tropical sector
iChance -= 5;
+127 -63
View File
@@ -380,7 +380,8 @@ void STRUCT_TimeCounters::ConvertFrom_101_To_102(const OLDSOLDIERTYPE_101& src)
void STRUCT_Drugs::ConvertFrom_101_To_102(const OLDSOLDIERTYPE_101& src)
{
for (int x = 0; x < 2; ++x)
int x = 0;
for (; x < 2; ++x)
{
this->bFutureDrugEffect[x] = src.bFutureDrugEffect[x]; // value to represent effect of a needle
this->bDrugEffectRate[x] = src.bDrugEffectRate[x]; // represents rate of increase and decrease of effect
@@ -389,6 +390,16 @@ void STRUCT_Drugs::ConvertFrom_101_To_102(const OLDSOLDIERTYPE_101& src)
this->bDrugSideEffect[x] = src.bDrugSideEffect[x]; // duration of negative AP and morale effect
this->bTimesDrugUsedSinceSleep[x] = src.bTimesDrugUsedSinceSleep[x];
}
for (; x < DRUG_TYPE_MAX; ++x)
{
this->bFutureDrugEffect[x] = 0; // value to represent effect of a needle
this->bDrugEffectRate[x] = 0; // represents rate of increase and decrease of effect
this->bDrugEffect[x] = 0; // value that affects AP & morale calc ( -ve is poorly )
this->bDrugSideEffectRate[x] = 0; // duration of negative AP and morale effect
this->bDrugSideEffect[x] = 0; // duration of negative AP and morale effect
this->bTimesDrugUsedSinceSleep[x] = 0;
}
}
void STRUCT_TimeChanges::ConvertFrom_101_To_102(const OLDSOLDIERTYPE_101& src)
@@ -1979,15 +1990,16 @@ INT16 SOLDIERTYPE::CalcActionPoints( void )
// adjust APs for phobia situations
if ( this->ubProfile != NO_PROFILE )
{
if ( (gMercProfiles[ this->ubProfile ].bDisability == CLAUSTROPHOBIC) && (gbWorldSectorZ > 0) )
// Flugente: drugs can temporarily cause a merc to be claustrophobic
if ( ( (gMercProfiles[ this->ubProfile ].bDisability == CLAUSTROPHOBIC) || MercUnderTheInfluence(this, DRUG_TYPE_CLAUSTROPHOBIC) ) && (gbWorldSectorZ > 0) )
{
ubPoints = (ubPoints * APBPConstants[AP_CLAUSTROPHOBE]) / 10;
}
else if ( (gMercProfiles[ this->ubProfile ].bDisability == FEAR_OF_INSECTS) && (MercSeesCreature( this ) ) )
else if ( ( (gMercProfiles[ this->ubProfile ].bDisability == FEAR_OF_INSECTS) || MercUnderTheInfluence(this, DRUG_TYPE_FEAROFINSECTS) ) && (MercSeesCreature( this ) ) )
{
ubPoints = (ubPoints * APBPConstants[AP_AFRAID_OF_INSECTS]) / 10;
}
else if ( (gMercProfiles[ this->ubProfile ].bDisability == FEAR_OF_INSECTS) && (MercIsInTropicalSector( this ) ) )
else if ( ( (gMercProfiles[ this->ubProfile ].bDisability == FEAR_OF_INSECTS) || MercUnderTheInfluence(this, DRUG_TYPE_FEAROFINSECTS) )&& (MercIsInTropicalSector( this ) ) )
{
ubPoints = (ubPoints * 9) / 10;
}
@@ -2119,7 +2131,7 @@ void SOLDIERTYPE::CalcNewActionPoints( void )
this->bActionPoints = APBPConstants[AP_MIN_LIMIT];
// Don't max out if we are drugged....
if ( !GetDrugEffect( this, DRUG_TYPE_ADRENALINE ) )
if ( !GetDrugEffect( this, (DRUG_TYPE_ADRENALINE|DRUG_TYPE_AGILITY) ) )
{
///////////////////////////////////////////////////////////////////////////////////////////
// SANDRO - following code messed a bit
@@ -5606,54 +5618,9 @@ void SOLDIERTYPE::EVENT_SoldierGotHit( UINT16 usWeaponIndex, INT16 sDamage, INT1
}
#endif
////////////////////////////////////////////////////////////////////////////////////
// SANDRO - Increased breath damage resistance of Militia (bonus counted twice)
if (this->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA && gGameExternalOptions.bGreenMilitiaDamageResistance != 0)
sBreathLoss -= ((sBreathLoss * gGameExternalOptions.bGreenMilitiaDamageResistance) /75);
else if (this->ubSoldierClass == SOLDIER_CLASS_REG_MILITIA && gGameExternalOptions.bRegularMilitiaDamageResistance != 0)
sBreathLoss -= ((sBreathLoss * gGameExternalOptions.bRegularMilitiaDamageResistance) /75);
else if (this->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA && gGameExternalOptions.bVeteranMilitiaDamageResistance != 0)
sBreathLoss -= ((sBreathLoss * gGameExternalOptions.bVeteranMilitiaDamageResistance) /75);
// bonus for enemy too
else if (this->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR && gGameExternalOptions.sEnemyAdminDamageResistance != 0)
sBreathLoss -= ((sBreathLoss * gGameExternalOptions.sEnemyAdminDamageResistance) /100);
else if (this->ubSoldierClass == SOLDIER_CLASS_ARMY && gGameExternalOptions.sEnemyRegularDamageResistance != 0)
sBreathLoss -= ((sBreathLoss * gGameExternalOptions.sEnemyRegularDamageResistance) /100);
else if (this->ubSoldierClass == SOLDIER_CLASS_ELITE && gGameExternalOptions.sEnemyEliteDamageResistance != 0)
sBreathLoss -= ((sBreathLoss * gGameExternalOptions.sEnemyEliteDamageResistance) /100);
//////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// SANDRO - option to make special NPCs stronger - breath damage resistance
if (gGameExternalOptions.usSpecialNPCStronger > 0)
{
switch( this->ubProfile )
{
case CARMEN:
case QUEEN:
case JOE:
case ANNIE:
case CHRIS:
case KINGPIN:
case TIFFANY:
case T_REX:
case DRUGGIST:
case GENERAL:
case JACK:
case OLAF:
case RAY:
case OLGA:
case TYRONE:
case MIKE:
sBreathLoss -= (sBreathLoss * gGameExternalOptions.usSpecialNPCStronger / 100);
break;
}
}
if ( sBreathLoss < 0 )
sBreathLoss = 0;
////////////////////////////////////////////////////////////////////////////////////
// Flugente: moved the damage calculation into a separate function
sBreathLoss = max( 1, (INT16)(sBreathLoss * (100 - this->GetDamageResistance(FALSE, TRUE)) / 100 ) );
// OK, If we are a vehicle.... damage vehicle...( people inside... )
if ( this->flags.uiStatusFlags & SOLDIER_VEHICLE )
{
@@ -7205,10 +7172,27 @@ void SOLDIERTYPE::EVENT_BeginMercTurn( BOOLEAN fFromRealTime, INT32 iRealTimeCou
if ( (this->bTeam == gbPlayerNum) && (this->ubProfile != NO_PROFILE) )
{
switch( gMercProfiles[ this->ubProfile ].bDisability )
// Flugente: drugs can temporarily cause a merc get a new disability
// therefore we change this routine
BOOLEAN isHeatIntolerant = gMercProfiles[ this->ubProfile ].bDisability == HEAT_INTOLERANT ? TRUE : FALSE;
BOOLEAN isFearOfInsects = gMercProfiles[ this->ubProfile ].bDisability == FEAR_OF_INSECTS ? TRUE : FALSE;
BOOLEAN isClaustrophobic = gMercProfiles[ this->ubProfile ].bDisability == CLAUSTROPHOBIC ? TRUE : FALSE;
BOOLEAN isNervous = gMercProfiles[ this->ubProfile ].bDisability == NERVOUS ? TRUE : FALSE;
if ( MercUnderTheInfluence(this, DRUG_TYPE_HEATINTOLERANT) )
isHeatIntolerant = TRUE;
if ( MercUnderTheInfluence(this, DRUG_TYPE_FEAROFINSECTS) )
isFearOfInsects = TRUE;
if ( MercUnderTheInfluence(this, DRUG_TYPE_CLAUSTROPHOBIC) )
isClaustrophobic = TRUE;
if ( MercUnderTheInfluence(this, DRUG_TYPE_NERVOUS) )
isNervous = TRUE;
if ( isHeatIntolerant )
{
// SANDRO - added heat intolerant
case HEAT_INTOLERANT:
if ( MercIsHot( this ) )
{
HandleMoraleEvent( this, MORALE_HEAT_INTOLERANT_IN_DESERT, this->sSectorX, this->sSectorY, this->bSectorZ );
@@ -7218,8 +7202,10 @@ void SOLDIERTYPE::EVENT_BeginMercTurn( BOOLEAN fFromRealTime, INT32 iRealTimeCou
this->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_PERSONALITY;
}
}
break;
case FEAR_OF_INSECTS:
}
if ( isFearOfInsects )
{
if ( MercSeesCreature( this ) )
{
HandleMoraleEvent( this, MORALE_INSECT_PHOBIC_SEES_CREATURE, this->sSectorX, this->sSectorY, this->bSectorZ );
@@ -7229,8 +7215,10 @@ void SOLDIERTYPE::EVENT_BeginMercTurn( BOOLEAN fFromRealTime, INT32 iRealTimeCou
this->usQuoteSaidFlags |= SOLDIER_QUOTE_SAID_PERSONALITY;
}
}
break;
case CLAUSTROPHOBIC:
}
if ( isClaustrophobic )
{
if ( gbWorldSectorZ > 0 && Random( 6 - gbWorldSectorZ ) == 0 )
{
// underground!
@@ -7242,8 +7230,10 @@ void SOLDIERTYPE::EVENT_BeginMercTurn( BOOLEAN fFromRealTime, INT32 iRealTimeCou
}
}
break;
case NERVOUS:
}
if ( isNervous )
{
if ( DistanceToClosestFriend( this ) > NERVOUS_RADIUS )
{
// augh!!
@@ -7265,7 +7255,6 @@ void SOLDIERTYPE::EVENT_BeginMercTurn( BOOLEAN fFromRealTime, INT32 iRealTimeCou
this->usQuoteSaidFlags &= ~SOLDIER_QUOTE_SAID_PERSONALITY;
}
}
break;
}
}
}
@@ -13066,6 +13055,81 @@ UINT16 SOLDIERTYPE::GetUsedWeaponNumber( OBJECTTYPE * pObj )
return( pObj->usItem );
}
INT32 SOLDIERTYPE::GetDamageResistance(BOOLEAN fAutoResolve, BOOLEAN fCalcBreathLoss)
{
INT32 resistance = 0;
FLOAT breathmodifiermilitia = 1.0;
FLOAT breathmodifierspecialNPC = 2.0;
if ( fCalcBreathLoss )
{
breathmodifiermilitia = 0.75;
breathmodifierspecialNPC = 1.0;
}
// SANDRO - Damage resistance for Militia
if (!fAutoResolve)
{
if (this->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA && gGameExternalOptions.bGreenMilitiaDamageResistance != 0)
resistance += (INT32)(gGameExternalOptions.bGreenMilitiaDamageResistance / breathmodifiermilitia);
else if (this->ubSoldierClass == SOLDIER_CLASS_REG_MILITIA && gGameExternalOptions.bRegularMilitiaDamageResistance != 0)
resistance += (INT32)(gGameExternalOptions.bRegularMilitiaDamageResistance / breathmodifiermilitia);
else if (this->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA && gGameExternalOptions.bVeteranMilitiaDamageResistance != 0)
resistance += (INT32)(gGameExternalOptions.bVeteranMilitiaDamageResistance / breathmodifiermilitia);
// bonus for enemy too
else if (this->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR && gGameExternalOptions.sEnemyAdminDamageResistance != 0)
resistance += gGameExternalOptions.sEnemyAdminDamageResistance;
else if (this->ubSoldierClass == SOLDIER_CLASS_ARMY && gGameExternalOptions.sEnemyRegularDamageResistance != 0)
resistance += gGameExternalOptions.sEnemyRegularDamageResistance;
else if (this->ubSoldierClass == SOLDIER_CLASS_ELITE && gGameExternalOptions.sEnemyEliteDamageResistance != 0)
resistance += gGameExternalOptions.sEnemyEliteDamageResistance;
}
//////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// SANDRO - option to make special NPCs stronger - damage resistance
if (gGameExternalOptions.usSpecialNPCStronger > 0)
{
switch( this->ubProfile )
{
case CARMEN:
case QUEEN:
case JOE:
case ANNIE:
case CHRIS:
case KINGPIN:
case TIFFANY:
case T_REX:
case DRUGGIST:
case GENERAL:
case JACK:
case OLAF:
case RAY:
case OLGA:
case TYRONE:
case MIKE:
resistance += (INT32)(gGameExternalOptions.usSpecialNPCStronger / breathmodifierspecialNPC);
break;
}
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// STOMP traits - Bodybuilding damage resistance
if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( this, BODYBUILDING_NT ) )
resistance += gSkillTraitValues.ubBBDamageResistance;
////////////////////////////////////////////////////////////////////////////////////
// Flugente: drugs can now have an effect on damage resistance
HandleDamageResistanceEffectDueToDrugs(this, &resistance);
// resistance is between -100% and 100%
resistance = max( 0, resistance);
resistance = min(100, resistance);
return( resistance );
}
INT32 CheckBleeding( SOLDIERTYPE *pSoldier )
{
INT8 bBandaged; //,savedOurTurn;
+17 -13
View File
@@ -20,6 +20,7 @@
#define PTR_STANDING (gAnimControl[ pSoldier->usAnimState ].ubHeight == ANIM_STAND)
#define PTR_PRONE (gAnimControl[ pSoldier->usAnimState ].ubHeight == ANIM_PRONE)
#define DRUG_TYPE_MAX 20
// TEMP VALUES FOR NAMES
#define MAXCIVLASTNAMES 30
@@ -611,12 +612,12 @@ class STRUCT_Drugs//last edited at version 102
{
public:
void ConvertFrom_101_To_102(const OLDSOLDIERTYPE_101& src);
INT8 bFutureDrugEffect[2]; // value to represent effect of a needle
INT8 bDrugEffectRate[2]; // represents rate of increase and decrease of effect
INT8 bDrugEffect[2]; // value that affects AP & morale calc ( -ve is poorly )
INT8 bDrugSideEffectRate[2]; // duration of negative AP and morale effect
INT8 bDrugSideEffect[2]; // duration of negative AP and morale effect
INT8 bTimesDrugUsedSinceSleep[2];
INT8 bFutureDrugEffect[DRUG_TYPE_MAX]; // value to represent effect of a needle
INT8 bDrugEffectRate[DRUG_TYPE_MAX]; // represents rate of increase and decrease of effect
INT8 bDrugEffect[DRUG_TYPE_MAX]; // value that affects AP & morale calc ( -ve is poorly )
INT8 bDrugSideEffectRate[DRUG_TYPE_MAX]; // duration of negative AP and morale effect
INT8 bDrugSideEffect[DRUG_TYPE_MAX]; // duration of negative AP and morale effect
INT8 bTimesDrugUsedSinceSleep[DRUG_TYPE_MAX];
};
class STRUCT_TimeCounters//last edited at version 102
@@ -1324,7 +1325,10 @@ public:
void SoldierInventoryCoolDown( void ); // Flugente FTW 1: Cool down all items in inventory
BOOLEAN IsWeaponMounted( void ); // determine if we receive a bonus for mounting our weapon on something
OBJECTTYPE* GetUsedWeapon( OBJECTTYPE * pObj ); // if in an underbarrel fire mode, return underbarrel weapon
UINT16 GetUsedWeaponNumber( OBJECTTYPE * pObj ); // if in an underbarrel fire mode, return number of underbarrel weapon
UINT16 GetUsedWeaponNumber( OBJECTTYPE * pObj ); // if in an underbarrel fire mode, return number of underbarrel weapon
// returns damage resistance in percent
INT32 GetDamageResistance( BOOLEAN fAutoResolve = FALSE, BOOLEAN fCalcBreathLoss = FALSE);
}; // SOLDIERTYPE;
@@ -2018,12 +2022,12 @@ public:
INT8 bSleepDrugCounter;
UINT8 ubMilitiaKills;
INT8 bFutureDrugEffect[2]; // value to represent effect of a needle
INT8 bDrugEffectRate[2]; // represents rate of increase and decrease of effect
INT8 bDrugEffect[2]; // value that affects AP & morale calc ( -ve is poorly )
INT8 bDrugSideEffectRate[2]; // duration of negative AP and morale effect
INT8 bDrugSideEffect[2]; // duration of negative AP and morale effect
INT8 bTimesDrugUsedSinceSleep[2];
INT8 bFutureDrugEffect[DRUG_TYPE_MAX]; // value to represent effect of a needle
INT8 bDrugEffectRate[DRUG_TYPE_MAX]; // represents rate of increase and decrease of effect
INT8 bDrugEffect[DRUG_TYPE_MAX]; // value that affects AP & morale calc ( -ve is poorly )
INT8 bDrugSideEffectRate[DRUG_TYPE_MAX]; // duration of negative AP and morale effect
INT8 bDrugSideEffect[DRUG_TYPE_MAX]; // duration of negative AP and morale effect
INT8 bTimesDrugUsedSinceSleep[DRUG_TYPE_MAX];
INT8 bBlindedCounter;
BOOLEAN fMercCollapsedFlag;
+3 -1
View File
@@ -55,6 +55,7 @@
#include "Player Command.h"
#include "strategic.h"
#include "strategicmap.h" // added by SANDRO
#include "drugs and alcohol.h" // added by Flugente
#endif
#include "aim.h"
@@ -2041,7 +2042,8 @@ BOOLEAN DoesMercHaveABuddyOnTheTeam( UINT8 ubMercID )
BOOLEAN MercIsHot( SOLDIERTYPE * pSoldier )
{
// SANDRO - added argument
if ( pSoldier->ubProfile != NO_PROFILE && gMercProfiles[ pSoldier->ubProfile ].bDisability == HEAT_INTOLERANT && !pSoldier->MercInWater())
// Flugente: drugs can temporarily cause a merc to be heat intolerant
if ( pSoldier->ubProfile != NO_PROFILE && (gMercProfiles[ pSoldier->ubProfile ].bDisability == HEAT_INTOLERANT || MercUnderTheInfluence(pSoldier, DRUG_TYPE_HEATINTOLERANT) ) && !pSoldier->MercInWater())
{
if ((pSoldier->bSectorZ > 0) || (guiEnvWeather & ( WEATHER_FORECAST_SHOWERS | WEATHER_FORECAST_THUNDERSHOWERS )))
{
+4
View File
@@ -1020,6 +1020,10 @@
RelativePath=".\XML_CompatibleFaceItems.cpp"
>
</File>
<File
RelativePath=".\XML_Drugs.cpp"
>
</File>
<File
RelativePath=".\XML_EnemyAmmoDrops.cpp"
>
+4
View File
@@ -1022,6 +1022,10 @@
RelativePath="XML_CompatibleFaceItems.cpp"
>
</File>
<File
RelativePath=".\XML_Drugs.cpp"
>
</File>
<File
RelativePath="XML_EnemyAmmoDrops.cpp"
>
+1
View File
@@ -194,6 +194,7 @@
<ClCompile Include="XML_CivGroupNames.cpp" />
<ClCompile Include="XML_ComboMergeInfo.cpp" />
<ClCompile Include="XML_CompatibleFaceItems.cpp" />
<ClCompile Include="XML_Drugs.cpp" />
<ClCompile Include="XML_EnemyAmmoDrops.cpp" />
<ClCompile Include="XML_EnemyArmourDrops.cpp" />
<ClCompile Include="XML_EnemyExplosiveDrops.cpp" />
+3
View File
@@ -617,5 +617,8 @@
<ClCompile Include="XML_ItemAdjustments.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="XML_Drugs.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
+11
View File
@@ -46,6 +46,7 @@
#include "Soldier macros.h"
#include "Soldier Profile.h"
#include "NPC.h"
#include "drugs and alcohol.h" // added by Flugente
#endif
#ifdef JA2UB
@@ -1879,6 +1880,16 @@ INT8 CalcInterruptDuelPts( SOLDIERTYPE * pSoldier, UINT8 ubOpponentID, BOOLEAN f
}
}
// Flugente: drugs can alter our perception
if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_PERCEPTION ] )
{
iPoints += 1;
}
else if ( pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_PERCEPTION ] )
{
iPoints -= 1;
}
// if he's a computer soldier
// CJC note: this will affect friendly AI as well...
+24 -141
View File
@@ -4958,7 +4958,8 @@ UINT32 CalcNewChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTi
iTraitModifier -= 15;
}
// Small penalty for fear of insects in tropical sectors
else if ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == FEAR_OF_INSECTS) && MercIsInTropicalSector( pSoldier ) )
// Flugente: drugs can temporarily cause a merc get a new disability
else if ( ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == FEAR_OF_INSECTS) || MercUnderTheInfluence(pSoldier, DRUG_TYPE_FEAROFINSECTS) )&& MercIsInTropicalSector( pSoldier ) )
{
// fear of insects, and we are in tropical sector
iTraitModifier -= 5;
@@ -4980,7 +4981,8 @@ UINT32 CalcNewChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTi
else
{
// PSYCHO
if ( pSoldier->ubProfile != NO_PROFILE && gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO )
// Flugente: drugs can temporarily cause a merc to go psycho
if ( pSoldier->ubProfile != NO_PROFILE && (gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO || MercUnderTheInfluence(pSoldier, DRUG_TYPE_PSYCHO) ) )
{
iBaseModifier += (FLOAT)gGameCTHConstants.BASE_PSYCHO;
}
@@ -5287,7 +5289,8 @@ UINT32 CalcNewChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTi
}
else
{
if ( pSoldier->ubProfile != NO_PROFILE && gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO )
// Flugente: drugs can temporarily cause a merc to go psycho
if ( pSoldier->ubProfile != NO_PROFILE && (gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO || MercUnderTheInfluence(pSoldier, DRUG_TYPE_PSYCHO) ) )
{
iAimModifier += gGameCTHConstants.AIM_PSYCHO;
}
@@ -6087,7 +6090,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
accuracyheatmultiplicator = (FLOAT)max(0.0, 1.0 - accuracymalus);
}
iAccRangeMod = iRange * accuracyheatmultiplicator * Weapon[usItemUsed].bAccuracy / 100;
iAccRangeMod = (INT32)(iRange * accuracyheatmultiplicator * Weapon[usItemUsed].bAccuracy / 100);
/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
@@ -6481,7 +6484,8 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime,
iChance -= 15;
}
// Small penalty for fear of insects in tropical sectors
else if ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == FEAR_OF_INSECTS) && MercIsInTropicalSector( pSoldier ) )
// Flugente: drugs can temporarily cause a merc get a new disability
else if ( ( (gMercProfiles[ pSoldier->ubProfile ].bDisability == FEAR_OF_INSECTS) || MercUnderTheInfluence(pSoldier, DRUG_TYPE_FEAROFINSECTS) )&& MercIsInTropicalSector( pSoldier ) )
{
// fear of insects, and we are in tropical sector
iChance -= 5;
@@ -8725,89 +8729,19 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget,
iImpact += (INT32)(iImpact * (pFirer->aiData.bAimTime - gSkillTraitValues.ubSNDamageBonusFromNumClicks + 1) * gSkillTraitValues.ubSNDamageBonusPerClick * NUM_SKILL_TRAITS( pFirer, SNIPER_NT ))/100; // +5% per trait
}
}
////////////////////////////////////////////////////////////////////////////////////
// SANDRO - Damage resistance for Militia
if (!IsAutoResolveActive())
// Flugente: moved the damage calculation into a separate function
BOOLEAN autoresolve = IsAutoResolveActive();
// HEADROCK HAM 5.1: Oh sandro, you rendered zerominimumdamage moot...
if ( AmmoTypes[ubAmmoType].zeroMinimumDamage )
{
if (pTarget->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA && gGameExternalOptions.bGreenMilitiaDamageResistance != 0)
iImpact -= ((iImpact * gGameExternalOptions.bGreenMilitiaDamageResistance) /100);
else if (pTarget->ubSoldierClass == SOLDIER_CLASS_REG_MILITIA && gGameExternalOptions.bRegularMilitiaDamageResistance != 0)
iImpact -= ((iImpact * gGameExternalOptions.bRegularMilitiaDamageResistance) /100);
else if (pTarget->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA && gGameExternalOptions.bVeteranMilitiaDamageResistance != 0)
iImpact -= ((iImpact * gGameExternalOptions.bVeteranMilitiaDamageResistance) /100);
// bonus for enemy too
else if (pTarget->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR && gGameExternalOptions.sEnemyAdminDamageResistance != 0)
iImpact -= ((iImpact * gGameExternalOptions.sEnemyAdminDamageResistance) /100);
else if (pTarget->ubSoldierClass == SOLDIER_CLASS_ARMY && gGameExternalOptions.sEnemyRegularDamageResistance != 0)
iImpact -= ((iImpact * gGameExternalOptions.sEnemyRegularDamageResistance) /100);
else if (pTarget->ubSoldierClass == SOLDIER_CLASS_ELITE && gGameExternalOptions.sEnemyEliteDamageResistance != 0)
iImpact -= ((iImpact * gGameExternalOptions.sEnemyEliteDamageResistance) /100);
// HEADROCK HAM 5.1: Oh sandro, you rendered zerominimumdamage moot...
if ( AmmoTypes[ubAmmoType].zeroMinimumDamage )
{
iImpact = __max( 0, iImpact );
}
else
{
iImpact = __max( 1, iImpact);
}
iImpact = __max( 0, (INT32)(iImpact * (100 - pTarget->GetDamageResistance(autoresolve, FALSE)) / 100 ) );
}
//////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// SANDRO - option to make special NPCs stronger - damage resistance
if (gGameExternalOptions.usSpecialNPCStronger > 0)
else
{
switch( pTarget->ubProfile )
{
case CARMEN:
case QUEEN:
case JOE:
case ANNIE:
case CHRIS:
case KINGPIN:
case TIFFANY:
case T_REX:
case DRUGGIST:
case GENERAL:
case JACK:
case OLAF:
case RAY:
case OLGA:
case TYRONE:
case MIKE:
// Only 1/2 of the bonus
iImpact -= (INT32)(iImpact * gGameExternalOptions.usSpecialNPCStronger / 200);
// HEADROCK HAM 5.1: Oh sandro, you rendered zerominimumdamage moot...
if ( AmmoTypes[ubAmmoType].zeroMinimumDamage )
{
iImpact = __max( 0, iImpact );
}
else
{
iImpact = __max( 1, iImpact);
}
break;
}
iImpact = __max( 1, (INT32)(iImpact * (100 - pTarget->GetDamageResistance(autoresolve, FALSE)) / 100 ) );
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// STOMP traits - Bodybuilding damage resistance
if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pTarget, BODYBUILDING_NT ) )
// HEADROCK HAM 5.1: Oh sandro, you rendered zerominimumdamage moot...
if ( AmmoTypes[ubAmmoType].zeroMinimumDamage )
{
iImpact = __max( 0, (INT32)(iImpact * (100 - gSkillTraitValues.ubBBDamageResistance) / 100));
}
else
{
iImpact = __max( 1, (INT32)(iImpact * (100 - gSkillTraitValues.ubBBDamageResistance) / 100));
}
////////////////////////////////////////////////////////////////////////////////////
AdjustImpactByHitLocation( iImpact, ubHitLocation, &iImpact, &iImpactForCrits );
@@ -9418,62 +9352,9 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO
iImpact = (INT32)((iImpact * 11 / 10) + 0.5); // +10%
}
////////////////////////////////////////////////////////////////////////////////////
// SANDRO - Damage resistance for Militia
if (!IsAutoResolveActive())
{
if (pTarget->ubSoldierClass == SOLDIER_CLASS_GREEN_MILITIA && gGameExternalOptions.bGreenMilitiaDamageResistance != 0)
iImpact -= ((iImpact * gGameExternalOptions.bGreenMilitiaDamageResistance) /100);
else if (pTarget->ubSoldierClass == SOLDIER_CLASS_REG_MILITIA && gGameExternalOptions.bRegularMilitiaDamageResistance != 0)
iImpact -= ((iImpact * gGameExternalOptions.bRegularMilitiaDamageResistance) /100);
else if (pTarget->ubSoldierClass == SOLDIER_CLASS_ELITE_MILITIA && gGameExternalOptions.bVeteranMilitiaDamageResistance != 0)
iImpact -= ((iImpact * gGameExternalOptions.bVeteranMilitiaDamageResistance) /100);
// bonus for enemy too
else if (pTarget->ubSoldierClass == SOLDIER_CLASS_ADMINISTRATOR && gGameExternalOptions.sEnemyAdminDamageResistance != 0)
iImpact -= ((iImpact * gGameExternalOptions.sEnemyAdminDamageResistance) /100);
else if (pTarget->ubSoldierClass == SOLDIER_CLASS_ARMY && gGameExternalOptions.sEnemyRegularDamageResistance != 0)
iImpact -= ((iImpact * gGameExternalOptions.sEnemyRegularDamageResistance) /100);
else if (pTarget->ubSoldierClass == SOLDIER_CLASS_ELITE && gGameExternalOptions.sEnemyEliteDamageResistance != 0)
iImpact -= ((iImpact * gGameExternalOptions.sEnemyEliteDamageResistance) /100);
iImpact = max( 1, iImpact);
}
//////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// SANDRO - option to make special NPCs stronger - damage resistance
if (gGameExternalOptions.usSpecialNPCStronger > 0)
{
switch( pTarget->ubProfile )
{
case CARMEN:
case QUEEN:
case JOE:
case ANNIE:
case CHRIS:
case KINGPIN:
case TIFFANY:
case T_REX:
case DRUGGIST:
case GENERAL:
case JACK:
case OLAF:
case RAY:
case OLGA:
case TYRONE:
case MIKE:
iImpact -= (INT32)(iImpact * gGameExternalOptions.usSpecialNPCStronger / 200);
iImpact = max( 1, iImpact);
break;
}
}
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
// STOMP traits - Bodybuilding damage resistance
if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pTarget, BODYBUILDING_NT ) )
iImpact = max( 1, (INT32)(iImpact * (100 - gSkillTraitValues.ubBBDamageResistance) / 100));
////////////////////////////////////////////////////////////////////////////////////
// Flugente: moved the damage calculation into a separate function
BOOLEAN autoresolve = IsAutoResolveActive();
iImpact = max( 1, (INT32)(iImpact * (100 - pTarget->GetDamageResistance(autoresolve, FALSE)) / 100 ) );
return( iImpact );
}
@@ -9619,7 +9500,8 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi
iAttRating /= 6; // convert from 6-600 to 1-100
// psycho bonus - only with old traits - SANDRO
if ( !( gGameOptions.fNewTraitSystem ) && pAttacker->ubProfile != NO_PROFILE && gMercProfiles[ pAttacker->ubProfile ].bDisability == PSYCHO )
// Flugente: drugs can temporarily cause a merc to go psycho
if ( !( gGameOptions.fNewTraitSystem ) && pAttacker->ubProfile != NO_PROFILE && (gMercProfiles[ pAttacker->ubProfile ].bDisability == PSYCHO || MercUnderTheInfluence(pAttacker, DRUG_TYPE_PSYCHO) ) )
{
iAttRating += AIM_BONUS_PSYCHO;
}
@@ -11135,7 +11017,8 @@ void EstimateBulletsLeft( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj )
}
// Is this Soldier a psycho?
if ( pSoldier->ubProfile != NO_PROFILE && gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO )
// Flugente: drugs can temporarily cause a merc to go psycho
if ( pSoldier->ubProfile != NO_PROFILE && (gMercProfiles[ pSoldier->ubProfile ].bDisability == PSYCHO || MercUnderTheInfluence(pSoldier, DRUG_TYPE_PSYCHO) ) )
{
fPsycho = TRUE;
}
+5
View File
@@ -65,6 +65,7 @@ typedef PARSE_STAGE;
#define MAGAZINESFILENAME "Magazines.xml"
#define ARMOURSFILENAME "Armours.xml"
#define EXPLOSIVESFILENAME "Explosives.xml"
#define DRUGSFILENAME "Drugs.xml"
#define AMMOFILENAME "AmmoStrings.xml"
#define AMMOTYPESFILENAME "AmmoTypes.xml"
#define INCOMPATIBLEATTACHMENTSFILENAME "IncompatibleAttachments.xml"
@@ -296,6 +297,10 @@ extern BOOLEAN WriteMercStartingGearStats();
extern BOOLEAN ReadInExplosiveStats(STR fileName);
extern BOOLEAN WriteExplosiveStats();
// Flugente: externalisation of drugs
extern BOOLEAN ReadInDrugsStats(STR fileName);
extern BOOLEAN WriteDrugsStats();
extern BOOLEAN ReadInAmmoStats(STR fileName);
extern BOOLEAN WriteAmmoStats();
+245
View File
@@ -0,0 +1,245 @@
#ifdef PRECOMPILEDHEADERS
#include "Tactical All.h"
#else
#include "sgp.h"
#include "overhead.h"
#include "Drugs And Alcohol.h"
#include "Debug Control.h"
#include "expat.h"
#include "XML.h"
#endif
struct
{
PARSE_STAGE curElement;
CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1];
DRUGTYPE curDrugs;
DRUGTYPE * curArray;
UINT32 maxArraySize;
UINT32 currentDepth;
UINT32 maxReadDepth;
}
typedef drugsParseData;
static void XMLCALL
drugsStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts)
{
drugsParseData * pData = (drugsParseData *)userData;
if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element?
{
if(strcmp(name, "DRUGSLIST") == 0 && pData->curElement == ELEMENT_NONE)
{
pData->curElement = ELEMENT_LIST;
memset(pData->curArray,0,sizeof(DRUGTYPE)*pData->maxArraySize);
pData->maxReadDepth++; //we are not skipping this element
}
else if(strcmp(name, "DRUG") == 0 && pData->curElement == ELEMENT_LIST)
{
pData->curElement = ELEMENT;
memset(&pData->curDrugs,0,sizeof(DRUGTYPE));
pData->maxReadDepth++; //we are not skipping this element
}
else if(pData->curElement == ELEMENT &&
(strcmp(name, "ubType") == 0 ||
strcmp(name, "ubDrugTravelRate") == 0 ||
strcmp(name, "ubDrugWearoffRate") == 0 ||
strcmp(name, "ubDrugEffect") == 0 ||
strcmp(name, "ubDrugSideEffect") == 0 ||
strcmp(name, "ubDrugSideEffectRate") == 0 ||
strcmp(name, "ubMoralBacklash") ))
{
pData->curElement = ELEMENT_PROPERTY;
pData->maxReadDepth++; //we are not skipping this element
}
pData->szCharData[0] = '\0';
}
pData->currentDepth++;
}
static void XMLCALL
drugsCharacterDataHandle(void *userData, const XML_Char *str, int len)
{
drugsParseData * pData = (drugsParseData *)userData;
if( (pData->currentDepth <= pData->maxReadDepth) &&
(strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH)
){
strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData)));
}
}
static void XMLCALL
drugsEndElementHandle(void *userData, const XML_Char *name)
{
drugsParseData * pData = (drugsParseData *)userData;
if(pData->currentDepth <= pData->maxReadDepth) //we're at the end of an element that we've been reading
{
if(strcmp(name, "DRUGSLIST") == 0)
{
pData->curElement = ELEMENT_NONE;
}
else if(strcmp(name, "DRUG") == 0)
{
pData->curElement = ELEMENT_LIST;
if(pData->curDrugs.ubType < pData->maxArraySize && pData->curDrugs.ubType > 0) // do not write the first item into our array
{
pData->curArray[pData->curDrugs.ubType - 1] = pData->curDrugs; //write the drugs into the table
}
}
else if(strcmp(name, "ubType") == 0)
{
pData->curElement = ELEMENT;
pData->curDrugs.ubType = (UINT8) atol(pData->szCharData);
}
else if(strcmp(name, "ubDrugTravelRate") == 0)
{
pData->curElement = ELEMENT;
pData->curDrugs.ubDrugTravelRate = (UINT8) atol(pData->szCharData);
}
else if(strcmp(name, "ubDrugWearoffRate") == 0)
{
pData->curElement = ELEMENT;
pData->curDrugs.ubDrugWearoffRate = (UINT8) atol(pData->szCharData);
}
else if(strcmp(name, "ubDrugEffect") == 0)
{
pData->curElement = ELEMENT;
pData->curDrugs.ubDrugEffect = (UINT8) atol(pData->szCharData);
}
else if(strcmp(name, "ubDrugSideEffect") == 0)
{
pData->curElement = ELEMENT;
pData->curDrugs.ubDrugSideEffect = (UINT8) atol(pData->szCharData);
}
else if(strcmp(name, "ubDrugSideEffectRate") == 0)
{
pData->curElement = ELEMENT;
pData->curDrugs.ubDrugSideEffectRate = (UINT8) atol(pData->szCharData);
}
else if(strcmp(name, "ubMoralBacklash") == 0)
{
pData->curElement = ELEMENT;
pData->curDrugs.ubMoralBacklash = (UINT8) atol(pData->szCharData);
}
pData->maxReadDepth--;
}
pData->currentDepth--;
}
BOOLEAN ReadInDrugsStats(STR fileName)
{
HWFILE hFile;
UINT32 uiBytesRead;
UINT32 uiFSize;
CHAR8 * lpcBuffer;
XML_Parser parser = XML_ParserCreate(NULL);
drugsParseData pData;
DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading Drugs.xml" );
// Open drugs file
hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE );
if ( !hFile )
return( FALSE );
uiFSize = FileGetSize(hFile);
lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1);
//Read in block
if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) )
{
MemFree(lpcBuffer);
return( FALSE );
}
lpcBuffer[uiFSize] = 0; //add a null terminator
FileClose( hFile );
XML_SetElementHandler(parser, drugsStartElementHandle, drugsEndElementHandle);
XML_SetCharacterDataHandler(parser, drugsCharacterDataHandle);
memset(&pData,0,sizeof(pData));
pData.curArray = Drug;
pData.maxArraySize = DRUG_TYPE_MAX;
XML_SetUserData(parser, &pData);
if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE))
{
CHAR8 errorBuf[511];
sprintf(errorBuf, "XML Parser Error in Drugs.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser));
LiveMessage(errorBuf);
MemFree(lpcBuffer);
return FALSE;
}
MemFree(lpcBuffer);
XML_ParserFree(parser);
return( TRUE );
}
BOOLEAN WriteDrugsStats()
{
//DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"writedrugsstats");
HWFILE hFile;
//Debug code; make sure that what we got from the file is the same as what's there
// Open a new file
hFile = FileOpen( "TABLEDATA\\Drugs out.xml", FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE );
if ( !hFile )
return( FALSE );
{
UINT32 cnt;
FilePrintf(hFile,"<DRUGSLIST>\r\n");
for(cnt = 0;cnt < MAXITEMS;cnt++)
{
FilePrintf(hFile,"\t<DRUG>\r\n");
FilePrintf(hFile,"\t\t<ubType>%d</ubType>\r\n", cnt );
FilePrintf(hFile,"\t\t<ubDrugTravelRate>%d</ubDrugTravelRate>\r\n", Drug[cnt].ubDrugTravelRate );
FilePrintf(hFile,"\t\t<ubDrugWearoffRate>%d</ubDrugWearoffRate>\r\n", Drug[cnt].ubDrugWearoffRate );
FilePrintf(hFile,"\t\t<ubDrugEffect>%d</ubDrugEffect>\r\n", Drug[cnt].ubDrugEffect );
FilePrintf(hFile,"\t\t<ubDrugSideEffect>%d</ubDrugSideEffect>\r\n", Drug[cnt].ubDrugSideEffect );
FilePrintf(hFile,"\t\t<ubDrugSideEffectRate>%d</ubDrugSideEffectRate>\r\n", Drug[cnt].ubDrugSideEffectRate );
FilePrintf(hFile,"\t\t<ubMoralBacklash>%d</ubMoralBacklash>\r\n", Drug[cnt].ubMoralBacklash );
FilePrintf(hFile,"\t</DRUG>\r\n");
}
FilePrintf(hFile,"</DRUGSLIST>\r\n");
}
FileClose( hFile );
return( TRUE );
}
+8
View File
@@ -260,6 +260,7 @@ itemStartElementHandle(void *userData, const XML_Char *name, const XML_Char **at
strcmp(name, "TripWireActivation") == 0 ||
strcmp(name, "TripWire") == 0 ||
strcmp(name, "Directional") == 0 ||
strcmp(name, "DrugType") == 0 ||
strcmp(name, "fFlags") == 0 ))
{
@@ -1301,6 +1302,11 @@ itemEndElementHandle(void *userData, const XML_Char *name)
pData->curElement = ELEMENT;
pData->curItem.directional = (BOOLEAN) atol(pData->szCharData);
}
else if(strcmp(name, "DrugType") == 0)
{
pData->curElement = ELEMENT;
pData->curItem.drugtype = (UINT32) atol(pData->szCharData);
}
pData->maxReadDepth--;
}
@@ -1912,6 +1918,8 @@ BOOLEAN WriteItemStats()
FilePrintf(hFile,"\t\t<TripWire>%d</TripWire>\r\n", Item[cnt].tripwire );
FilePrintf(hFile,"\t\t<Directional>%d</Directional>\r\n", Item[cnt].directional );
FilePrintf(hFile,"\t\t<DrugType>%d</DrugType>\r\n", Item[cnt].drugtype );
FilePrintf(hFile,"\t</ITEM>\r\n");
}
FilePrintf(hFile,"</ITEMLIST>\r\n");