From fc88abaa5b6866d52770f0dc031b1f858d130272 Mon Sep 17 00:00:00 2001 From: Wanne Date: Fri, 27 Apr 2012 13:22:35 +0000 Subject: [PATCH] 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 -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 --- Init.cpp | 4 + Strategic/Facilities.cpp | 12 +- Tactical/Drugs And Alcohol.cpp | 384 +++++++++++++++-------- Tactical/Drugs And Alcohol.h | 93 +++++- Tactical/Faces.cpp | 3 +- Tactical/Handle Items.cpp | 8 +- Tactical/Interface Panels.cpp | 10 +- Tactical/Item Types.h | 2 + Tactical/Items.cpp | 20 ++ Tactical/Morale.cpp | 112 ++++--- Tactical/Overhead.cpp | 9 + Tactical/SkillCheck.cpp | 7 +- Tactical/Soldier Control.cpp | 190 +++++++---- Tactical/Soldier Control.h | 30 +- Tactical/Soldier Profile.cpp | 4 +- Tactical/Tactical_VS2005.vcproj | 4 + Tactical/Tactical_VS2008.vcproj | 4 + Tactical/Tactical_VS2010.vcxproj | 1 + Tactical/Tactical_VS2010.vcxproj.filters | 3 + Tactical/TeamTurns.cpp | 11 + Tactical/Weapons.cpp | 165 ++-------- Tactical/XML.h | 5 + Tactical/XML_Drugs.cpp | 245 +++++++++++++++ Utils/XML_Items.cpp | 8 + 24 files changed, 908 insertions(+), 426 deletions(-) create mode 100644 Tactical/XML_Drugs.cpp diff --git a/Init.cpp b/Init.cpp index 640757ca..33747e13 100644 --- a/Init.cpp +++ b/Init.cpp @@ -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); diff --git a/Strategic/Facilities.cpp b/Strategic/Facilities.cpp index 85a55ce1..460e75fc 100644 --- a/Strategic/Facilities.cpp +++ b/Strategic/Facilities.cpp @@ -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 ) { diff --git a/Tactical/Drugs And Alcohol.cpp b/Tactical/Drugs And Alcohol.cpp index f4f8d13e..5516c1b6 100644 --- a/Tactical/Drugs And Alcohol.cpp +++ b/Tactical/Drugs And Alcohol.cpp @@ -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 ); } diff --git a/Tactical/Drugs And Alcohol.h b/Tactical/Drugs And Alcohol.h index 4340fa38..74c8f891 100644 --- a/Tactical/Drugs And Alcohol.h +++ b/Tactical/Drugs And Alcohol.h @@ -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 diff --git a/Tactical/Faces.cpp b/Tactical/Faces.cpp index 77e29803..9d2a80a3 100644 --- a/Tactical/Faces.cpp +++ b/Tactical/Faces.cpp @@ -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++; diff --git a/Tactical/Handle Items.cpp b/Tactical/Handle Items.cpp index 20c62493..b94ab55b 100644 --- a/Tactical/Handle Items.cpp +++ b/Tactical/Handle Items.cpp @@ -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 ); diff --git a/Tactical/Interface Panels.cpp b/Tactical/Interface Panels.cpp index a620815f..c520478c 100644 --- a/Tactical/Interface Panels.cpp +++ b/Tactical/Interface Panels.cpp @@ -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 ) { diff --git a/Tactical/Item Types.h b/Tactical/Item Types.h index 496606e6..a8044ee6 100644 --- a/Tactical/Item Types.h +++ b/Tactical/Item Types.h @@ -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; diff --git a/Tactical/Items.cpp b/Tactical/Items.cpp index 69106e67..089599d9 100644 --- a/Tactical/Items.cpp +++ b/Tactical/Items.cpp @@ -58,6 +58,8 @@ // THE_BOB : added for pocket popup definitions #include #include "popup_definition.h" + + #include "drugs and alcohol.h" #endif #ifdef JA2UB @@ -1251,6 +1253,8 @@ std::map 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; diff --git a/Tactical/Morale.cpp b/Tactical/Morale.cpp index ca29fd50..93d347b9 100644 --- a/Tactical/Morale.cpp +++ b/Tactical/Morale.cpp @@ -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 ); diff --git a/Tactical/Overhead.cpp b/Tactical/Overhead.cpp index 4cf922d4..5c10a276 100644 --- a/Tactical/Overhead.cpp +++ b/Tactical/Overhead.cpp @@ -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; } } diff --git a/Tactical/SkillCheck.cpp b/Tactical/SkillCheck.cpp index 23c62405..e88986e4 100644 --- a/Tactical/SkillCheck.cpp +++ b/Tactical/SkillCheck.cpp @@ -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; diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index f406c3b9..928c9010 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -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; diff --git a/Tactical/Soldier Control.h b/Tactical/Soldier Control.h index 0240dac0..e81b7a61 100644 --- a/Tactical/Soldier Control.h +++ b/Tactical/Soldier Control.h @@ -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; diff --git a/Tactical/Soldier Profile.cpp b/Tactical/Soldier Profile.cpp index 2128b3db..8165f2af 100644 --- a/Tactical/Soldier Profile.cpp +++ b/Tactical/Soldier Profile.cpp @@ -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 ))) { diff --git a/Tactical/Tactical_VS2005.vcproj b/Tactical/Tactical_VS2005.vcproj index ca55c0b8..6e2e22df 100644 --- a/Tactical/Tactical_VS2005.vcproj +++ b/Tactical/Tactical_VS2005.vcproj @@ -1020,6 +1020,10 @@ RelativePath=".\XML_CompatibleFaceItems.cpp" > + + diff --git a/Tactical/Tactical_VS2008.vcproj b/Tactical/Tactical_VS2008.vcproj index 731bc979..e869a153 100644 --- a/Tactical/Tactical_VS2008.vcproj +++ b/Tactical/Tactical_VS2008.vcproj @@ -1022,6 +1022,10 @@ RelativePath="XML_CompatibleFaceItems.cpp" > + + diff --git a/Tactical/Tactical_VS2010.vcxproj b/Tactical/Tactical_VS2010.vcxproj index a27e5d28..82113272 100644 --- a/Tactical/Tactical_VS2010.vcxproj +++ b/Tactical/Tactical_VS2010.vcxproj @@ -194,6 +194,7 @@ + diff --git a/Tactical/Tactical_VS2010.vcxproj.filters b/Tactical/Tactical_VS2010.vcxproj.filters index e7264ba8..5a9ec163 100644 --- a/Tactical/Tactical_VS2010.vcxproj.filters +++ b/Tactical/Tactical_VS2010.vcxproj.filters @@ -617,5 +617,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/Tactical/TeamTurns.cpp b/Tactical/TeamTurns.cpp index 04501699..d1a831fd 100644 --- a/Tactical/TeamTurns.cpp +++ b/Tactical/TeamTurns.cpp @@ -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... diff --git a/Tactical/Weapons.cpp b/Tactical/Weapons.cpp index c0b94844..1e27de8a 100644 --- a/Tactical/Weapons.cpp +++ b/Tactical/Weapons.cpp @@ -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; } diff --git a/Tactical/XML.h b/Tactical/XML.h index e698ed25..bd74a405 100644 --- a/Tactical/XML.h +++ b/Tactical/XML.h @@ -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(); diff --git a/Tactical/XML_Drugs.cpp b/Tactical/XML_Drugs.cpp new file mode 100644 index 00000000..f8a31d92 --- /dev/null +++ b/Tactical/XML_Drugs.cpp @@ -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,"\r\n"); + for(cnt = 0;cnt < MAXITEMS;cnt++) + { + FilePrintf(hFile,"\t\r\n"); + + FilePrintf(hFile,"\t\t%d\r\n", cnt ); + FilePrintf(hFile,"\t\t%d\r\n", Drug[cnt].ubDrugTravelRate ); + FilePrintf(hFile,"\t\t%d\r\n", Drug[cnt].ubDrugWearoffRate ); + FilePrintf(hFile,"\t\t%d\r\n", Drug[cnt].ubDrugEffect ); + FilePrintf(hFile,"\t\t%d\r\n", Drug[cnt].ubDrugSideEffect ); + FilePrintf(hFile,"\t\t%d\r\n", Drug[cnt].ubDrugSideEffectRate ); + FilePrintf(hFile,"\t\t%d\r\n", Drug[cnt].ubMoralBacklash ); + + FilePrintf(hFile,"\t\r\n"); + } + FilePrintf(hFile,"\r\n"); + } + FileClose( hFile ); + + return( TRUE ); +} diff --git a/Utils/XML_Items.cpp b/Utils/XML_Items.cpp index bc6291e5..c6a47931 100644 --- a/Utils/XML_Items.cpp +++ b/Utils/XML_Items.cpp @@ -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%d\r\n", Item[cnt].tripwire ); FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].directional ); + FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].drugtype ); + FilePrintf(hFile,"\t\r\n"); } FilePrintf(hFile,"\r\n");