#ifdef PRECOMPILEDHEADERS #include "Tactical All.h" #else #include "sgp.h" #include "soldier control.h" #include "soldier profile.h" #include "drugs and alcohol.h" #include "items.h" #include "morale.h" #include "points.h" #include "message.h" #include "GameSettings.h" // SANDRO - had to add this, dammit! #include "Random.h" #include "Text.h" #include "Interface.h" #include "Food.h" // added by Flugente #include "Animation data.h" // added by Flugente for SoldierBodyTypes #include "CampaignStats.h" // added by Flugente #include "DynamicDialogue.h"// added by Flugente #endif //forward declarations of common classes to eliminate includes class OBJECTTYPE; class SOLDIERTYPE; BOOLEAN ApplyDrugs_New( SOLDIERTYPE *pSoldier, UINT16 usItem, UINT16 uStatusUsed ) { // If not a drug, return if ( !Item[usItem].drugtype || !uStatusUsed || !pSoldier ) return(FALSE); UINT32 drugused = Item[usItem].drugtype; // we might not use up the entire item, so reduce effects accordingly FLOAT effectivepercentage = uStatusUsed / 100.0; // if this alcohol, alcohol resistance can lower the effects if ( Item[usItem].alcohol > 0.0f ) { effectivepercentage = effectivepercentage * ((100.0 - pSoldier->GetBackgroundValue( BG_RESI_ALCOHOL )) / 100.0); FLOAT weight = pSoldier->GetBodyWeight( ); // the alcohol amounts in the xml are intended for a person with weight 80. We thus have to alter the effective value if ( weight > 0.0f ) { effectivepercentage *= 80.0f / weight; } } // we now add drug, disease, personality and disability effects // every effect has a chance of happening (not entering a chance, so 0, always results in a effect for xml editing simplicity reasons) // add effects std::vector vec_drug = NewDrug[drugused].drug_effects; std::vector::iterator drug_effects_itend = vec_drug.end( ); for ( std::vector::iterator drug_effects_it = vec_drug.begin( ); drug_effects_it != drug_effects_itend; ++drug_effects_it ) { if ( !(*drug_effects_it).chance || Chance( (*drug_effects_it).chance ) ) { // if we are already under influence of this effect, merge them, otherwise just add effect if ( pSoldier->newdrugs.duration[(*drug_effects_it).effect] ) { INT32 effectsum_existing = pSoldier->newdrugs.duration[(*drug_effects_it).effect] * pSoldier->newdrugs.size[(*drug_effects_it).effect]; INT32 effectsum_new = (*drug_effects_it).duration * (*drug_effects_it).size; INT32 effectsum_total = effectsum_existing + effectsum_new * effectivepercentage; UINT16 newduration = (pSoldier->newdrugs.duration[(*drug_effects_it).effect] + (*drug_effects_it).duration) / 2; if ( newduration ) { INT32 newsize = effectsum_total / newduration; pSoldier->newdrugs.duration[(*drug_effects_it).effect] = newduration; pSoldier->newdrugs.size[(*drug_effects_it).effect] = newsize; } } else { pSoldier->newdrugs.duration[(*drug_effects_it).effect] = (*drug_effects_it).duration; pSoldier->newdrugs.size[(*drug_effects_it).effect] = (*drug_effects_it).size * effectivepercentage; } } } // add diseases std::vector vec_disease = NewDrug[drugused].disease_effects; std::vector::iterator disease_effects_itend = vec_disease.end( ); for ( std::vector::iterator disease_effects_it = vec_disease.begin( ); disease_effects_it != disease_effects_itend; ++disease_effects_it ) { if ( !(*disease_effects_it).chance || Chance( (*disease_effects_it).chance ) ) { pSoldier->AddDiseasePoints( (*disease_effects_it).disease, (*disease_effects_it).size * effectivepercentage ); } } // add disability std::vector vec_disability = NewDrug[drugused].disability_effects; std::vector::iterator disability_effects_itend = vec_disability.end( ); for ( std::vector::iterator disability_effects_it = vec_disability.begin( ); disability_effects_it != disability_effects_itend; ++disability_effects_it ) { if ( !(*disability_effects_it).chance || Chance( (*disability_effects_it).chance ) ) { if ( pSoldier->newdrugs.drugdisability == (*disability_effects_it).disability ) { pSoldier->newdrugs.drugdisability_duration += (*disability_effects_it).duration * effectivepercentage; } else { pSoldier->newdrugs.drugdisability = (*disability_effects_it).disability; pSoldier->newdrugs.drugdisability_duration = (*disability_effects_it).duration * effectivepercentage; } } } // add personality std::vector vec_personality = NewDrug[drugused].personality_effects; std::vector::iterator personality_effects_itend = vec_personality.end( ); for ( std::vector::iterator personality_effects_it = vec_personality.begin( ); personality_effects_it != personality_effects_itend; ++personality_effects_it ) { if ( !(*personality_effects_it).chance || Chance( (*personality_effects_it).chance ) ) { if ( pSoldier->newdrugs.drugpersonality == (*personality_effects_it).personality ) { pSoldier->newdrugs.drugpersonality_duration += (*personality_effects_it).duration * effectivepercentage; } else { pSoldier->newdrugs.drugpersonality = (*personality_effects_it).personality; pSoldier->newdrugs.drugpersonality_duration = (*personality_effects_it).duration * effectivepercentage; } } } // do switch for Larry!! if ( pSoldier->ubProfile == LARRY_NORMAL ) { pSoldier = SwapLarrysProfiles( pSoldier ); } else if ( pSoldier->ubProfile == LARRY_DRUNK ) { gMercProfiles[LARRY_DRUNK].bNPCData = 0; } if ( NewDrug[drugused].opinionevent ) { HandleDynamicOpinionChange( pSoldier, OPINIONEVENT_ADDICT, TRUE, TRUE ); } if ( Item[usItem].alcohol > 0.0f ) { FLOAT weight = pSoldier->GetBodyWeight( ); // the alcohol amounts in the xml are intended for a person with weight 80. We thus have to alter the effective value if ( weight > 0.0f ) { // added promille = alcohol added (g) / (weight of person (kg) * 0.7) FLOAT addedpromille = (Item[usItem].alcohol * effectivepercentage) / (weight * 0.7); pSoldier->newdrugs.drinkstaken += addedpromille; } ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[MSG_DRANK_SOME], pSoldier->GetName( ), ShortItemNames[usItem] ); HandleDynamicOpinionTeamDrinking( pSoldier ); } else { // set flag: we are on non-alcoholic drugs pSoldier->usSoldierFlagMask |= SOLDIER_DRUGGED; if ( gMercProfiles[pSoldier->ubProfile].ubNumTimesDrugUseInLifetime != 255 ) { gMercProfiles[pSoldier->ubProfile].ubNumTimesDrugUseInLifetime++; } if ( Item[usItem].cigarette ) { ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[MSG_MERC_TOOK_CIGARETTE], pSoldier->GetName( ), ShortItemNames[usItem] ); } else { ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[MSG_MERC_TOOK_DRUG], pSoldier->GetName( ) ); } } // Dirty panel fInterfacePanelDirty = DIRTYLEVEL2; return TRUE; } void HandleEndTurnDrugAdjustments_New( SOLDIERTYPE *pSoldier ) { // some effects are handled here if ( pSoldier->newdrugs.size[DRUG_EFFECT_HP] ) { // increase life pSoldier->stats.bLife = __min( pSoldier->stats.bLife + pSoldier->newdrugs.size[DRUG_EFFECT_HP], pSoldier->stats.bLifeMax ); //SANDRO - Insta-healable injury reduction if ( pSoldier->newdrugs.size[DRUG_EFFECT_HP] > 0 ) { pSoldier->iHealableInjury = max( 0, (pSoldier->iHealableInjury - (100 * pSoldier->newdrugs.size[DRUG_EFFECT_HP])) ); } if ( pSoldier->stats.bLife == pSoldier->stats.bLifeMax ) { pSoldier->bBleeding = 0; pSoldier->iHealableInjury = 0; } else if ( pSoldier->bBleeding + pSoldier->stats.bLife > pSoldier->stats.bLifeMax ) { // got to reduce amount of bleeding pSoldier->bBleeding = (pSoldier->stats.bLifeMax - pSoldier->stats.bLife); } } pSoldier->bExtraStrength += pSoldier->newdrugs.size[DRUG_EFFECT_STR]; pSoldier->bExtraDexterity += pSoldier->newdrugs.size[DRUG_EFFECT_DEX]; pSoldier->bExtraAgility += pSoldier->newdrugs.size[DRUG_EFFECT_AGI]; pSoldier->bExtraWisdom += pSoldier->newdrugs.size[DRUG_EFFECT_WIS]; BOOLEAN fStillDrugged = FALSE; // as time progresses, effects wear off for ( UINT8 i = 0; i < DRUG_EFFECT_MAX; ++i ) { pSoldier->newdrugs.duration[i] = max( 0, pSoldier->newdrugs.duration[i] - 1 ); if ( !pSoldier->newdrugs.duration[i] ) pSoldier->newdrugs.size[i] = 0; else fStillDrugged = TRUE; } pSoldier->newdrugs.drugpersonality_duration = max( 0, pSoldier->newdrugs.drugpersonality_duration - 1 ); if ( !pSoldier->newdrugs.drugpersonality_duration ) pSoldier->newdrugs.drugpersonality = 0; else fStillDrugged = TRUE; pSoldier->newdrugs.drugdisability_duration = max( 0, pSoldier->newdrugs.drugdisability_duration - 1 ); if ( !pSoldier->newdrugs.drugdisability_duration ) pSoldier->newdrugs.drugdisability = 0; else fStillDrugged = TRUE; if ( !fStillDrugged ) { pSoldier->usSoldierFlagMask &= ~SOLDIER_DRUGGED; fInterfacePanelDirty = DIRTYLEVEL1; } } INT8 GetDrunkLevel( SOLDIERTYPE *pSoldier ) { if ( pSoldier->usSoldierFlagMask2 & SOLDIER_HUNGOVER ) { return HUNGOVER; } if ( pSoldier->newdrugs.drinkstaken <= 0.01 ) { return SOBER; } else if ( pSoldier->newdrugs.drinkstaken <= 0.7 ) { return FEELING_GOOD; } else if ( pSoldier->newdrugs.drinkstaken <= 2.0 ) { return BORDERLINE; } return DRUNK; } // does a merc have a disability/personality, or is he under drugs that simulate this? BOOLEAN DoesMercHaveDisability( SOLDIERTYPE *pSoldier, UINT8 aVal ) { if ( pSoldier->ubProfile != NO_PROFILE ) { if ( gMercProfiles[pSoldier->ubProfile].bDisability == aVal ) return TRUE; if ( pSoldier->newdrugs.drugdisability == aVal ) return TRUE; } return FALSE; } BOOLEAN DoesMercHavePersonality( SOLDIERTYPE *pSoldier, UINT8 aVal ) { // personalities are new trait system only! if ( !gGameOptions.fNewTraitSystem ) return FALSE; if ( pSoldier->ubProfile != NO_PROFILE ) { if ( gMercProfiles[pSoldier->ubProfile].bCharacterTrait == aVal ) return TRUE; if ( pSoldier->newdrugs.drugpersonality == aVal ) return TRUE; } return FALSE; } //------------------------------------------------------- /*UINT8 ubDrugTravelRate[] = { 4, 2 }; UINT8 ubDrugWearoffRate[] = { 2, 2 }; UINT8 ubDrugEffect[] = { 15, 8 }; UINT8 ubDrugSideEffect[] = { 20, 10 }; UINT8 ubDrugSideEffectRate[] = { 2, 1 };*/ INT32 giDrunkModifier[] = { 100, // Sober 75, // Feeling good, 65, // Bporderline 50, // Drunk 100, // HungOver }; #define HANGOVER_AP_REDUCE 5 #define HANGOVER_BP_REDUCE 200 /*BOOLEAN ApplyDrugs( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject ) { UINT32 ubDrugType; INT8 bRegenPointsGained; UINT16 usItem; usItem = pObject->usItem; // Determine what type of drug.... ubDrugType = Item[usItem].drugtype; // If not a drug, return if ( ubDrugType == 0 ) { return( FALSE ); } // do switch for Larry!! if ( pSoldier->ubProfile == LARRY_NORMAL ) { pSoldier = SwapLarrysProfiles( pSoldier ); } else if ( pSoldier->ubProfile == LARRY_DRUNK ) { gMercProfiles[ LARRY_DRUNK ].bNPCData = 0; } BOOLEAN consumeitem = TRUE; // if item is also a food item, don't use it up here, it will be consumed in ApplyFood, which will be called afterwards UINT32 foodtype = Item[pObject->usItem].foodtype; // if not a food item, nothing to see here if ( gGameOptions.fFoodSystem && foodtype > 0 ) consumeitem = FALSE; // 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 // we do not actually test for DRUG_REGENERATION, because that is checked afterwards separately if ( (drugtestflag & DRUG_REGENERATION ) != 0 ) continue; if ( (ubDrugType & drugtestflag) != 0 ) { // Add effects pSoldier->AddDrugValues( i, Drug[i].ubDrugEffect, Drug[i].ubDrugTravelRate, Drug[i].ubDrugSideEffect ); // ATE: Make guy collapse from heart attack if too much stuff taken.... if ( pSoldier->drugs.bDrugSideEffectRate[ i ] > ( Drug[i].ubDrugSideEffect * 3 ) ) { // Keel over... DeductPoints( pSoldier, 0, 10000 ); //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // SANDRO - if our stat is damaged through facility event, make it healable // Permanently lower certain stats... if ( gGameOptions.fNewTraitSystem ) { // WISDOM decrease if ( pSoldier->stats.bWisdom > 5 ) { pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_WISDOM ] += 5; pSoldier->stats.bWisdom -= 5; } else { pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_WISDOM ] += (pSoldier->stats.bWisdom - 1); pSoldier->stats.bWisdom = 1; } // DEXTERITY decrease if ( pSoldier->stats.bDexterity > 5 ) { pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_DEXTERITY ] += 5; pSoldier->stats.bDexterity -= 5; } else { pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_DEXTERITY ] += (pSoldier->stats.bDexterity - 1); pSoldier->stats.bDexterity = 1; } // STRENGTH decrease if ( pSoldier->stats.bStrength > 5 ) { pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_STRENGTH ] += 5; pSoldier->stats.bStrength -= 5; } else { pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_STRENGTH ] += (pSoldier->stats.bStrength - 1); pSoldier->stats.bStrength = 1; } // AGILITY decrease if ( pSoldier->stats.bAgility > 5 ) { pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_AGILITY ] += 5; pSoldier->stats.bAgility -= 5; } else { pSoldier->ubCriticalStatDamage[ DAMAGED_STAT_AGILITY ] += (pSoldier->stats.bAgility - 1); pSoldier->stats.bAgility = 1; } } else // old system { pSoldier->stats.bAgility = __max(1, pSoldier->stats.bWisdom-5); pSoldier->stats.bDexterity = __max(1, pSoldier->stats.bDexterity-5); pSoldier->stats.bStrength = __max(1, pSoldier->stats.bStrength-5); pSoldier->stats.bAgility = __max(1, pSoldier->stats.bAgility-5); // make those stats RED for a while... // SANDRO - we don't need to do this with new system, as we simply show all damaged stats in red until healed pSoldier->timeChanges.uiChangeWisdomTime = GetJA2Clock(); pSoldier->usValueGoneUp &= ~( WIS_INCREASE ); pSoldier->timeChanges.uiChangeDexterityTime = GetJA2Clock(); pSoldier->usValueGoneUp &= ~( DEX_INCREASE ); pSoldier->timeChanges.uiChangeStrengthTime = GetJA2Clock(); pSoldier->usValueGoneUp &= ~( STRENGTH_INCREASE ); pSoldier->timeChanges.uiChangeAgilityTime = GetJA2Clock(); pSoldier->usValueGoneUp &= ~( AGIL_INCREASE ); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // export stat changes to profile gMercProfiles[ pSoldier->ubProfile ].bWisdom = pSoldier->stats.bWisdom; gMercProfiles[ pSoldier->ubProfile ].bDexterity = pSoldier->stats.bDexterity; gMercProfiles[ pSoldier->ubProfile ].bStrength = pSoldier->stats.bStrength; gMercProfiles[ pSoldier->ubProfile ].bAgility = pSoldier->stats.bAgility; // SANDRO - merc records - stat damaged gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++; } // Flugente: if this can cure a disease, do so if ( Drug[i].ubDiseaseCure > 0 ) { // we cure exactly enough to cure an outbreak // Drug[i].ubDiseaseCure - 1 - the xml value is simply one higher than the disease type, otherwise we couldn't identify disease 0 pSoldier->AddDiseasePoints( Drug[i].ubDiseaseCure - 1, -Disease[Drug[i].ubDiseaseCure - 1].sInfectionPtsOutbreak ); } } } 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 ) ) ) { ++bRegenPointsGained; } } bRegenPointsGained -= pSoldier->bRegenBoostersUsedToday; if (bRegenPointsGained > 0) { // can't go above the points you get for a full boost pSoldier->bRegenerationCounter = __min( pSoldier->bRegenerationCounter + bRegenPointsGained, REGEN_POINTS_PER_BOOSTER ); } pSoldier->bRegenBoostersUsedToday++; // set flag: we are on drugs pSoldier->usSoldierFlagMask |= SOLDIER_DRUGGED; } // increase drug counter if not alcoholic drug if ( usItem != ALCOHOL && usItem != WINE && usItem != BEER ) { if ( gMercProfiles[ pSoldier->ubProfile ].ubNumTimesDrugUseInLifetime != 255 ) { gMercProfiles[ pSoldier->ubProfile ].ubNumTimesDrugUseInLifetime++; } } // ATE: use kit points... if ( consumeitem ) { if ( usItem == ALCOHOL ) UseKitPoints( pObject, 10, pSoldier ); else if ( usItem == WINE ) UseKitPoints( pObject, 20, pSoldier ); else if ( usItem == BEER ) UseKitPoints( pObject, 100, pSoldier ); else { UINT16 ptsused = (*pObject)[0]->data.objectStatus; gCampaignStats.AddConsumption(CAMPAIGN_CONSUMED_MEDICAL, (FLOAT)(ptsused * Item[usItem].ubWeight / 100.0) ); // remove object pObject->RemoveObjectsFromStack(1); } } if ( (ubDrugType & DRUG_ALCOHOL) ) { ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_DRANK_SOME ], pSoldier->GetName(), ShortItemNames[ usItem ] ); // Flugente: dynamic opinions HandleDynamicOpinionTeamDrinking( pSoldier ); } else { ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, pMessageStrings[ MSG_MERC_TOOK_DRUG ], pSoldier->GetName() ); } // Dirty panel fInterfacePanelDirty = DIRTYLEVEL2; if ( !consumeitem ) ApplyFood( pSoldier, pObject, TRUE, TRUE ); return( TRUE ); }*/ /*void HandleEndTurnDrugAdjustments( SOLDIERTYPE *pSoldier ) { INT32 cnt, cnt2; INT32 iNumLoops; // if were not on drugs, nothing to do here if ( ( pSoldier->usSoldierFlagMask & SOLDIER_DRUGGED ) == 0 ) return; // We test for every 'pure' drug separately for (cnt = DRUG_TYPE_ADRENALINE; cnt < DRUG_TYPE_MAX; ++cnt) { // omit DRUG_TYPE_REGENERATION, because that is checked afterwards separately if ( cnt == DRUG_TYPE_REGENERATION ) continue; // If side effect aret is non-zero.... if ( pSoldier->drugs.bDrugSideEffectRate[ cnt ] > 0 ) { // Subtract some... pSoldier->drugs.bDrugSideEffect[ cnt ] -= pSoldier->drugs.bDrugSideEffectRate[ cnt ]; // If we're done, we're done! if ( pSoldier->drugs.bDrugSideEffect[ cnt ] <= 0 ) { pSoldier->drugs.bDrugSideEffect[ cnt ] = 0; pSoldier->drugs.bDrugSideEffectRate[ cnt ] = 0; fInterfacePanelDirty = DIRTYLEVEL1; } } // IF drug rate is -ve, it's being worn off... if ( pSoldier->drugs.bDrugEffectRate[ cnt ] < 0 ) { pSoldier->drugs.bDrugEffect[ cnt ] -= ( -1 * pSoldier->drugs.bDrugEffectRate[ cnt ] ); // Have we run out? if ( pSoldier->drugs.bDrugEffect[ cnt ] <= 0 ) { pSoldier->drugs.bDrugEffect[ cnt ] = 0; // Dirty panel fInterfacePanelDirty = DIRTYLEVEL2; // Start the bad news! pSoldier->drugs.bDrugSideEffectRate[ cnt ] = Drug[cnt].ubDrugSideEffectRate; // The drug rate is 0 now too pSoldier->drugs.bDrugEffectRate[ cnt ] = 0; // morale downer only if side effect exists and this effect is allowed for a drug if ( Drug[cnt].ubDrugSideEffect > 0 && Drug[cnt].ubMoralBacklash > 0 ) { // Once for each 'level' of crash.... iNumLoops = ( pSoldier->drugs.bDrugSideEffect[ cnt ] / Drug[cnt].ubDrugSideEffect ) + 1; for ( cnt2 = 0; cnt2 < iNumLoops; ++cnt2 ) { // OK, give a much BIGGER morale downer if ( cnt == DRUG_TYPE_ALCOHOL ) { HandleMoraleEvent( pSoldier, MORALE_ALCOHOL_CRASH, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ ); } else { HandleMoraleEvent( pSoldier, MORALE_DRUGS_CRASH, pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ ); } } } } } // Add increase ineffect.... if ( pSoldier->drugs.bDrugEffectRate[ cnt ] > 0 ) { // Seap some in.... pSoldier->drugs.bFutureDrugEffect[ cnt ] -= pSoldier->drugs.bDrugEffectRate[ cnt ]; pSoldier->drugs.bDrugEffect[ cnt ] += pSoldier->drugs.bDrugEffectRate[ cnt ]; // Refresh morale w/ new drug value... RefreshSoldierMorale( pSoldier ); // Check if we need to stop 'adding' if ( pSoldier->drugs.bFutureDrugEffect[ cnt ] <= 0 ) { pSoldier->drugs.bFutureDrugEffect[ cnt ] = 0; // Change rate to -ve.. pSoldier->drugs.bDrugEffectRate[ cnt ] = -Drug[cnt].ubDrugWearoffRate; } } } if ( pSoldier->bRegenerationCounter > 0) { // increase life pSoldier->stats.bLife = __min( pSoldier->stats.bLife + LIFE_GAIN_PER_REGEN_POINT, pSoldier->stats.bLifeMax ); //SANDRO - Insta-healable injury reduction if( pSoldier->iHealableInjury > 0 ) { pSoldier->iHealableInjury = max(0, (pSoldier->iHealableInjury - (100 * LIFE_GAIN_PER_REGEN_POINT))); } if ( pSoldier->stats.bLife == pSoldier->stats.bLifeMax ) { pSoldier->bBleeding = 0; pSoldier->iHealableInjury = 0; } else if ( pSoldier->bBleeding + pSoldier->stats.bLife > pSoldier->stats.bLifeMax ) { // got to reduce amount of bleeding pSoldier->bBleeding = (pSoldier->stats.bLifeMax - pSoldier->stats.bLife); } // decrement counter pSoldier->bRegenerationCounter--; } // Flugente: always do the following checks. Thereby, if the effect runs out, our stats will be back to normal //////////////// STRENGTH //////////////// pSoldier->bExtraStrength = pSoldier->drugs.bDrugEffect[ DRUG_TYPE_STRENGTH ] - pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_STRENGTH ]; //////////////// DEXTERITY //////////////// pSoldier->bExtraDexterity = pSoldier->drugs.bDrugEffect[ DRUG_TYPE_DEXTERITY ] - pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_DEXTERITY ]; //////////////// AGILITY //////////////// pSoldier->bExtraAgility = pSoldier->drugs.bDrugEffect[ DRUG_TYPE_AGILITY ] - pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_AGILITY ]; //////////////// WISDOM //////////////// pSoldier->bExtraWisdom = pSoldier->drugs.bDrugEffect[ DRUG_TYPE_WISDOM ] - pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_WISDOM ]; // 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 ); } // if we have a life damaging effect, deduct life points if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_LIFEDAMAGE ] == 0 && pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_LIFEDAMAGE ] > 0 ) { pSoldier->EVENT_SoldierGotHit( 0, 10, 0, pSoldier->ubDirection, 320, NOBODY , FIRE_WEAPON_NO_SPECIAL, pSoldier->bAimShotLocation, 0, -1 ); } // etorphine stuns while it lasts. It can also damage and possibly kill the target if overdosed. The dosage depends on our bodytype if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_STUNANDKILL ] ) { // Keel over... DeductPoints( pSoldier, 0, 20000 ); UINT8 bodyweight = 10; switch ( pSoldier->ubBodyType ) { case REGMALE: case MANCIV: bodyweight = 10; break; case BIGMALE: case STOCKYMALE: bodyweight = 12; break; case REGFEMALE: bodyweight = 9; break; case ADULTFEMALEMONSTER: case AM_MONSTER: bodyweight = 30; break; case YAF_MONSTER: case YAM_MONSTER: bodyweight = 20; break; case LARVAE_MONSTER: bodyweight = 4; break; case INFANT_MONSTER: bodyweight = 10; break; case QUEENMONSTER: bodyweight = 100; break; case FATCIV: case MINICIV: case DRESSCIV: bodyweight = 8; break; case HATKIDCIV: case KIDCIV: bodyweight = 4; break; case CRIPPLECIV: bodyweight = 7; break; case COW: bodyweight = 20; break; case CROW: bodyweight = 1; break; case BLOODCAT: bodyweight = 20; break; case ROBOTNOWEAPON: case HUMVEE: case TANK_NW: case TANK_NE: case ELDORADO: case ICECREAMTRUCK: case JEEP: // this should not happen anyway... bodyweight = 100; break; } if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_STUNANDKILL ] > bodyweight ) { if ( Chance( 10 * (pSoldier->drugs.bDrugEffect[ DRUG_TYPE_STUNANDKILL ] - bodyweight) ) ) pSoldier->EVENT_SoldierGotHit( 0, 400, 0, pSoldier->ubDirection, 320, NOBODY , FIRE_WEAPON_NO_SPECIAL, pSoldier->bAimShotLocation, 0, -1 ); } } // if all drug effects have ended, delete flag if ( !MercUnderTheInfluence(pSoldier) ) pSoldier->usSoldierFlagMask &= ~SOLDIER_DRUGGED; }*/ void HandleAPEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT16 *pubPoints ) { *pubPoints += pSoldier->newdrugs.size[DRUG_EFFECT_AP]; if ( GetDrunkLevel( pSoldier ) == HUNGOVER ) { // Reduce.... *pubPoints -= HANGOVER_AP_REDUCE; if ( *pubPoints < APBPConstants[AP_MINIMUM] ) { *pubPoints = APBPConstants[AP_MINIMUM]; } } } void HandleBPEffectDueToDrugs( SOLDIERTYPE *pSoldier, INT16 *psPointReduction ) { *psPointReduction -= pSoldier->newdrugs.size[DRUG_EFFECT_BP]; if ( GetDrunkLevel( pSoldier ) == HUNGOVER ) { // Reduce.... (*psPointReduction) += HANGOVER_BP_REDUCE; } } /*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 ) { INT8 bNumDrinks; // If we have a -ve effect ... if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ALCOHOL ] == 0 && pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_ALCOHOL ] == 0 ) { return( SOBER ); } if ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ALCOHOL ] == 0 && pSoldier->drugs.bDrugSideEffect[ DRUG_TYPE_ALCOHOL ] != 0 ) { return( HUNGOVER ); } // Calculate how many dinks we have had.... bNumDrinks = ( pSoldier->drugs.bDrugEffect[ DRUG_TYPE_ALCOHOL ] / Drug[DRUG_TYPE_ALCOHOL].ubDrugEffect ); if ( bNumDrinks <= 3 ) { return( FEELING_GOOD ); } else if ( bNumDrinks <= 4 ) { return( BORDERLINE ); } else { return( DRUNK ); } }*/ INT32 EffectStatForBeingDrunk( SOLDIERTYPE *pSoldier, INT32 iStat ) { return( ( iStat * giDrunkModifier[ GetDrunkLevel( pSoldier ) ] / 100 ) ); } /*BOOLEAN MercUnderTheInfluence( SOLDIERTYPE *pSoldier ) { for (UINT8 cnt = DRUG_TYPE_ADRENALINE; cnt < DRUG_TYPE_MAX; ++cnt) { if ( MercUnderTheInfluence(pSoldier, cnt) ) return TRUE; } return( FALSE ); }*/ BOOLEAN MercDruggedOrDrunk( SOLDIERTYPE *pSoldier ) { if ( pSoldier->newdrugs.drinkstaken ) return TRUE; if ( pSoldier->usSoldierFlagMask & SOLDIER_DRUGGED ) return TRUE; 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 ); if ( pSoldier->drugs.bDrugSideEffect[ aDrugType ] ) return( TRUE ); if ( pSoldier->bRegenerationCounter > 0) return( TRUE ); return( FALSE ); }*/ BOOLEAN MercDrugged( SOLDIERTYPE *pSoldier ) { return (pSoldier->usSoldierFlagMask & SOLDIER_DRUGGED); } void HourlyDrugUpdate( ) { for ( UINT16 ubID = gTacticalStatus.Team[OUR_TEAM].bFirstID; ubID <= gTacticalStatus.Team[OUR_TEAM].bLastID; ++ubID ) { // every hour, we lower our alcohol counter if ( MercPtrs[ubID]->newdrugs.drinkstaken > 0.0f ) { MercPtrs[ubID]->newdrugs.drinkstaken = max( 0.0, MercPtrs[ubID]->newdrugs.drinkstaken - 0.15f ); if ( MercPtrs[ubID]->newdrugs.drinkstaken <= 0.0f ) { MercPtrs[ubID]->usSoldierFlagMask2 &= ~SOLDIER_HUNGOVER; } } } }