From 098dc8e2806cee0ea4573908cdf3499c70d60908 Mon Sep 17 00:00:00 2001 From: Flugente Date: Thu, 25 Jun 2020 22:42:44 +0000 Subject: [PATCH] Disease update: - can cause infections when taking fire damage - can cause infections when taking non-fire gas damage - causes the infected to be unable to use one arm - causes the infected to be unable to run, and walk and travel slowly - JA2_options.ini option DISEASE_SEVERE_LIMITATIONS controls whether , and are used For more info, see http://thepit.ja-galaxy-forum.com/index.php?t=msg&th=22099&goto=360451&#msg_360451 - Gas damage split up in fire and non-fire damage. - Flamethrower projectile damaged is affected by fire resistance. Requires GameDir >= r2553. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8828 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- GameSettings.cpp | 1 + GameSettings.h | 1 + GameVersion.cpp | 4 +- Multiplayer/client.cpp | 2 +- Strategic/Strategic Movement.cpp | 10 +- Tactical/Disease.cpp | 25 ++- Tactical/Disease.h | 19 +- Tactical/Drugs And Alcohol.cpp | 5 +- Tactical/Handle Items.cpp | 85 +++++++- Tactical/Handle UI.cpp | 16 +- Tactical/Interface Cursors.cpp | 3 + Tactical/Interface Cursors.h | 3 + Tactical/Interface Enhanced.cpp | 17 ++ Tactical/Item Types.h | 2 + Tactical/Items.cpp | 47 ++++- Tactical/Overhead.cpp | 5 + Tactical/Soldier Control.cpp | 346 +++++++++++++++++++++++++------ Tactical/Soldier Control.h | 10 +- Tactical/UI Cursors.cpp | 40 ++++ Tactical/Vehicles.cpp | 4 +- Tactical/XML_Disease.cpp | 30 +++ TacticalAI/AIUtils.cpp | 2 +- TileEngine/Explosion Control.cpp | 2 +- TileEngine/structure.cpp | 2 +- Utils/Cursors.cpp | 18 ++ Utils/Cursors.h | 5 + Utils/Text.h | 6 + Utils/XML_Items.cpp | 9 + Utils/_ChineseText.cpp | 8 + Utils/_DutchText.cpp | 8 + Utils/_EnglishText.cpp | 8 + Utils/_FrenchText.cpp | 8 + Utils/_GermanText.cpp | 8 + Utils/_ItalianText.cpp | 8 + Utils/_PolishText.cpp | 8 + Utils/_RussianText.cpp | 8 + 36 files changed, 694 insertions(+), 89 deletions(-) diff --git a/GameSettings.cpp b/GameSettings.cpp index 7830cfa3..8cb7e8cf 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -1729,6 +1729,7 @@ void LoadGameExternalOptions() gGameExternalOptions.fDiseaseStrategic = iniReader.ReadBoolean( "Disease Settings", "DISEASE_STRATEGIC", FALSE ); gGameExternalOptions.sDiseaseWHOSubscriptionCost = iniReader.ReadInteger( "Disease Settings", "DISEASE_WHO_SUBSCRIPTIONCOST", 2000, 1000, 10000 ); gGameExternalOptions.fDiseaseContaminatesItems = iniReader.ReadBoolean( "Disease Settings", "DISEASE_CONTAMINATES_ITEMS", TRUE ); + gGameExternalOptions.fDiseaseSevereLimitations = iniReader.ReadBoolean( "Disease Settings", "DISEASE_SEVERE_LIMITATIONS", FALSE ); //################# Strategic Gamestart Settings ################## diff --git a/GameSettings.h b/GameSettings.h index 5bea137c..da71c938 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -456,6 +456,7 @@ typedef struct BOOLEAN fDiseaseStrategic; INT32 sDiseaseWHOSubscriptionCost; BOOLEAN fDiseaseContaminatesItems; + BOOLEAN fDiseaseSevereLimitations; //Animation settings FLOAT giPlayerTurnSpeedUpFactor; diff --git a/GameVersion.cpp b/GameVersion.cpp index 111bfdcc..c5792c1e 100644 --- a/GameVersion.cpp +++ b/GameVersion.cpp @@ -55,8 +55,8 @@ #endif -CHAR8 czVersionNumber[16] = { "Build 20.06.20" }; //YY.MM.DD +CHAR8 czVersionNumber[16] = { "Build 20.06.25" }; //YY.MM.DD CHAR16 zTrackingNumber[16] = { L"Z" }; -CHAR16 zRevisionNumber[16] = { L"Revision 8826" }; +CHAR16 zRevisionNumber[16] = { L"Revision 8828" }; // SAVE_GAME_VERSION is defined in header, change it there diff --git a/Multiplayer/client.cpp b/Multiplayer/client.cpp index 3dee3ff1..7428d4ad 100644 --- a/Multiplayer/client.cpp +++ b/Multiplayer/client.cpp @@ -3691,7 +3691,7 @@ void recieveEXPLOSIONDAMAGE (RPCParameters *rpcParameters) // can use DishOutGasDamage() as it is dependant on the local state of the gas cloud which is not always in sync // but we have the definite results of damage on a merc, so : - pSoldier->SoldierTakeDamage( ANIM_STAND, exp->sWoundAmt, exp->sBreathAmt, TAKE_DAMAGE_GAS, NOBODY, NOWHERE, 0, TRUE ); + pSoldier->SoldierTakeDamage( ANIM_STAND, exp->sWoundAmt, exp->sBreathAmt, Explosive[Item[exp->usItem].ubClassIndex].ubType == EXPLOSV_BURNABLEGAS ? TAKE_DAMAGE_GAS_FIRE : TAKE_DAMAGE_GAS_NOTFIRE, NOBODY, NOWHERE, 0, TRUE ); } else if (exp->ubDamageFunc == 2) { diff --git a/Strategic/Strategic Movement.cpp b/Strategic/Strategic Movement.cpp index a111d6cc..53db6318 100644 --- a/Strategic/Strategic Movement.cpp +++ b/Strategic/Strategic Movement.cpp @@ -3472,8 +3472,16 @@ INT32 GetSectorMvtTimeForGroup( UINT8 ubSector, UINT8 ubDirection, GROUP *pGroup { pSoldier = curr->pSoldier; if( pSoldier->bAssignment != VEHICLE ) - { //Soldier is on foot and travelling. Factor encumbrance into movement rate. + { + //Soldier is on foot and travelling. Factor encumbrance into movement rate. iEncumbrance = CalculateCarriedWeight( pSoldier ); + + // Flugente: we are a lot slower if our leg is severely damaged, even if we can handle the weight + if ( gGameExternalOptions.fDisease + && gGameExternalOptions.fDiseaseSevereLimitations + && pSoldier->HasDiseaseWithFlag( DISEASE_PROPERTY_LIMITED_USE_LEGS ) ) + iEncumbrance = max( iEncumbrance * 2, 200); + if( iEncumbrance > iHighestEncumbrance ) { iHighestEncumbrance = iEncumbrance; diff --git a/Tactical/Disease.cpp b/Tactical/Disease.cpp index 362c8087..559c7c18 100644 --- a/Tactical/Disease.cpp +++ b/Tactical/Disease.cpp @@ -77,11 +77,22 @@ void HandleDisease() { if ( pSoldier->sDiseasePoints[i] > 0 ) { - // add disease points - some diseases can reverse on certain states + INT32 pointgain = Disease[i].sInfectionPtsGainPerHour; + + // if the arm/leg is severely wounded, a splint increases the healing speed (assuming the gain is negative to begin with and doesn't reverse) + if ( gGameExternalOptions.fDiseaseSevereLimitations + && Disease[i].usDiseaseProperties & (DISEASE_PROPERTY_LIMITED_USE_ARMS| DISEASE_PROPERTY_LIMITED_USE_LEGS) + && ( pSoldier->sDiseaseFlag[i] & (SOLDIERDISEASE_SPLINTAPPLIED_ARM| SOLDIERDISEASE_SPLINTAPPLIED_LEG) ) ) + { + pointgain *= 2; + } + + // some diseases can reverse on certain states if ( pSoldier->sDiseaseFlag[i] & SOLDIERDISEASE_REVERSEAL ) - pSoldier->AddDiseasePoints( i, -Disease[i].sInfectionPtsGainPerHour ); - else - pSoldier->AddDiseasePoints( i, Disease[i].sInfectionPtsGainPerHour ); + pointgain *= -1; + + // add disease points - some diseases can reverse on certain states + pSoldier->AddDiseasePoints( i, pointgain ); } } } @@ -192,10 +203,6 @@ void HandlePossibleInfection( SOLDIERTYPE *pSoldier, SOLDIERTYPE* pOtherSoldier, int max = fStrategicOnly ? 1 : NUM_DISEASES; for ( int i = 0; i < max; ++i ) { - // do not infect us if we are already infected - if ( !(Disease[i].usDiseaseProperties & DISEASE_PROPERTY_CANREINFECT) && pSoldier->sDiseasePoints[i] > 0 ) - continue; - // chance of infection by insects FLOAT dChance = Disease[i].dInfectionChance[aInfectionType]; @@ -223,7 +230,7 @@ void HandlePossibleInfection( SOLDIERTYPE *pSoldier, SOLDIERTYPE* pOtherSoldier, dChance *= (1.0f - pSoldier->GetDiseaseContactProtection( )); } - // chances ca be smaller than 1%, so we use a trick here by altering ou 'chance function'. This allows to have much smaller chances, as for diseases, 1% can be way too high. + // chances can be smaller than 1%, so we use a trick here by altering our 'chance function'. This allows to have much smaller chances, as for diseases, 1% can be way too high. if ( Random( 10000 ) < dChance * 100 ) { // infect us diff --git a/Tactical/Disease.h b/Tactical/Disease.h index fd81e324..3da6349c 100644 --- a/Tactical/Disease.h +++ b/Tactical/Disease.h @@ -31,6 +31,8 @@ enum INFECTION_TYPE_WOUND_ANIMAL, // wounded by an animal (bloodcat) INFECTION_TYPE_WOUND_OPEN, // we have a new non-bandaged wound INFECTION_TYPE_WOUND_GUNSHOT, // we were wounded by gunshot + INFECTION_TYPE_WOUND_FIRE, // we were wounded by fire + INFECTION_TYPE_WOUND_GAS, // we were wounded by gas (that isn't fire) // wound caused statloss INFECTION_TYPE_WOUND_AGI, @@ -63,14 +65,17 @@ enum #define SECTORDISEASE_DIAGNOSED_PLAYER 0x04 //4 // disease has been diagnosed by the player // properties of diseases -#define DISEASE_PROPERTY_CANBECURED 0x00000001 // this disease can be healed by doctoring -#define DISEASE_PROPERTY_REVERSEONFULL 0x00000002 // once sInfectionPtsFull are reached, the infection reverses - negative sInfectionPtsGainPerHour is used -#define DISEASE_PROPERTY_CANREINFECT 0x00000004 // infection can be reapplied if already infected -#define DISEASE_PROPERTY_HIDESYMBOL 0x00000008 // do not show a symbol for this disease on the merc's face, even if diagnosed +#define DISEASE_PROPERTY_CANBECURED 0x00000001 // this disease can be healed by doctoring +#define DISEASE_PROPERTY_REVERSEONFULL 0x00000002 // once sInfectionPtsFull are reached, the infection reverses - negative sInfectionPtsGainPerHour is used +#define DISEASE_PROPERTY_CANREINFECT 0x00000004 // infection can be reapplied if already infected +#define DISEASE_PROPERTY_HIDESYMBOL 0x00000008 // do not show a symbol for this disease on the merc's face, even if diagnosed -#define DISEASE_PROPERTY_DISGUSTING 0x00000010 // other merc's will be disgusted by anyone with this disease if broken out -#define DISEASE_PROPERTY_PTSD_BUNS 0x00000020 // if Buns has this disease, she can change personality -#define DISEASE_PROPERTY_ADD_DISABILITY 0x00000040 // whenever we contract this disease, we gain a new disability +#define DISEASE_PROPERTY_DISGUSTING 0x00000010 // other merc's will be disgusted by anyone with this disease if broken out +#define DISEASE_PROPERTY_PTSD_BUNS 0x00000020 // if Buns has this disease, she can change personality +#define DISEASE_PROPERTY_ADD_DISABILITY 0x00000040 // whenever we contract this disease, we gain a new disability +#define DISEASE_PROPERTY_LIMITED_USE_ARMS 0x00000080 // our arms have limited functionality + +#define DISEASE_PROPERTY_LIMITED_USE_LEGS 0x00000100 // our legs have limited functionality #define CORPSEREMOVALPOINTSPERCORPSE 1.0f // number of corpse removal points required to, you guessed it, remove a corpse #define DISEASE_PER_ROTTINGCORPSE 100.0f // if a corpse is removed by rotting, add this many disease points to the sector diff --git a/Tactical/Drugs And Alcohol.cpp b/Tactical/Drugs And Alcohol.cpp index c4dacc42..7bfad197 100644 --- a/Tactical/Drugs And Alcohol.cpp +++ b/Tactical/Drugs And Alcohol.cpp @@ -329,7 +329,10 @@ BOOLEAN DoesMercHaveDisability( SOLDIERTYPE *pSoldier, UINT8 aVal ) if ( pSoldier->newdrugs.drugdisability == aVal ) return TRUE; - if ( pSoldier->usDisabilityFlagMask & ( 1 << (aVal - 1) ) ) + // Flugente: if disease with severe limitations is active, we can have multiple disabilities + if ( gGameExternalOptions.fDisease + && gGameExternalOptions.fDiseaseSevereLimitations + && pSoldier->usDisabilityFlagMask & ( 1 << (aVal - 1) ) ) return TRUE; } diff --git a/Tactical/Handle Items.cpp b/Tactical/Handle Items.cpp index 49ea6b63..bc095973 100644 --- a/Tactical/Handle Items.cpp +++ b/Tactical/Handle Items.cpp @@ -324,7 +324,8 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa Item[usHandItem].usItemClass != IC_MEDKIT && !Item[usHandItem].gascan && !ItemCanBeAppliedToOthers(usHandItem) && - !HasItemFlag(usHandItem, EMPTY_BLOOD_BAG)) + !HasItemFlag(usHandItem, EMPTY_BLOOD_BAG) && + !HasItemFlag( usHandItem, MEDICAL_SPLINT ) ) { if (pTargetSoldier->bTeam == gbPlayerNum || pTargetSoldier->aiData.bNeutral) { @@ -1555,7 +1556,7 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa } } - // Flugente: apply misc items to other soldiers + // Flugente: take blood from a donor if ( HasItemFlag( usHandItem, EMPTY_BLOOD_BAG ) ) { // ATE: AI CANNOT GO THROUGH HERE! @@ -1635,6 +1636,86 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa } } + // Flugente: apply medical splint + if ( HasItemFlag( usHandItem, MEDICAL_SPLINT ) ) + { + // ATE: AI CANNOT GO THROUGH HERE! + BOOLEAN fHadToUseCursorPos = FALSE; + + // See if we can get there to stab + sActionGridNo = FindAdjacentGridEx( pSoldier, sGridNo, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); + if ( sActionGridNo == -1 ) + { + // Try another location... + sActionGridNo = FindAdjacentGridEx( pSoldier, usMapPos, &ubDirection, &sAdjustedGridNo, TRUE, FALSE ); + + if ( sActionGridNo == -1 ) + { + return( ITEM_HANDLE_CANNOT_GETTO_LOCATION ); + } + } + + // Calculate AP costs... + sAPCost = GetAPsToApplyItem( pSoldier, sActionGridNo ); + sAPCost += PlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, FALSE, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints ); + + // if we are at the action gridno, the item is a bomb, but nobody is at the gridno, do not apply and do not return - we will plant the bomb instead (handlded later in this function) + if ( Item[usHandItem].usItemClass == IC_BOMB && pSoldier->sGridNo == sActionGridNo && WhoIsThere2( usMapPos, pSoldier->pathing.bLevel ) == NOBODY ) + { + ; + } + else if ( EnoughPoints( pSoldier, sAPCost, 0, fFromUI ) ) + { + // OK, set UI + SetUIBusy( pSoldier->ubID ); + + // CHECK IF WE ARE AT THIS GRIDNO NOW + if ( pSoldier->sGridNo != sActionGridNo ) + { + // SEND PENDING ACTION + pSoldier->aiData.ubPendingAction = MERC_MEDICALSPLINT; + + if ( fHadToUseCursorPos ) + { + pSoldier->aiData.sPendingActionData2 = usMapPos; + } + else + { + if ( pTargetSoldier != NULL ) + { + pSoldier->aiData.sPendingActionData2 = pTargetSoldier->sGridNo; + } + else + { + pSoldier->aiData.sPendingActionData2 = sGridNo; + } + } + pSoldier->aiData.bPendingActionData3 = ubDirection; + pSoldier->aiData.ubPendingActionAnimCount = 0; + + // WALK UP TO DEST FIRST + pSoldier->EVENT_InternalGetNewSoldierPath( sActionGridNo, pSoldier->usUIMovementMode, FALSE, TRUE ); + } + else + { + pSoldier->EVENT_SoldierApplySplintToPerson( sAdjustedGridNo, ubDirection ); + + UnSetUIBusy( pSoldier->ubID ); + } + + if ( fFromUI ) + { + guiPendingOverrideEvent = A_CHANGE_TO_MOVE; + } + + return( ITEM_HANDLE_OK ); + } + else + { + return( ITEM_HANDLE_NOAPS ); + } + } + if ( Item[usHandItem].canandstring ) { STRUCTURE *pStructure; diff --git a/Tactical/Handle UI.cpp b/Tactical/Handle UI.cpp index 5e2a0cf8..80b65538 100644 --- a/Tactical/Handle UI.cpp +++ b/Tactical/Handle UI.cpp @@ -4860,6 +4860,20 @@ BOOLEAN UIMouseOnValidAttackLocation( SOLDIERTYPE *pSoldier ) return( FALSE ); } + if ( ubItemCursor == SPLINTCURS ) + { + if ( HasItemFlag( ( &( pSoldier->inv[HANDPOS] ) )->usItem, MEDICAL_SPLINT ) ) + { + if ( gfUIFullTargetFound ) + { + if ( pSoldier->ubID != gusUIFullTargetID && MercPtrs[gusUIFullTargetID]->CanReceiveSplint() ) + return( TRUE ); + } + } + + return( FALSE ); + } + if ( ubItemCursor == APPLYITEMCURS ) { if ( ItemCanBeAppliedToOthers( (&(pSoldier->inv[HANDPOS]))->usItem ) ) @@ -5247,7 +5261,7 @@ void SetConfirmMovementModeCursor( SOLDIERTYPE *pSoldier, BOOLEAN fFromMove ) } else { - if ( pSoldier->flags.fUIMovementFast && pSoldier->usAnimState == RUNNING && fFromMove ) + if ( pSoldier->IsFastMovement() && pSoldier->usAnimState == RUNNING && fFromMove ) { BeginDisplayTimedCursor( MOVE_RUN_REALTIME_UICURSOR, 300 ); } diff --git a/Tactical/Interface Cursors.cpp b/Tactical/Interface Cursors.cpp index c802cbfa..56619477 100644 --- a/Tactical/Interface Cursors.cpp +++ b/Tactical/Interface Cursors.cpp @@ -238,6 +238,9 @@ UICursor gUICursors[ NUM_UI_CURSORS ] = BLOODBAG_GREY_UICURSOR, UICURSOR_FREEFLOWING, CURSOR_BLOODBAG, 0, BLOODBAG_RED_UICURSOR, UICURSOR_FREEFLOWING, CURSOR_BLOODBAG_RED, 0, + + SPLINT_GREY_UICURSOR, UICURSOR_FREEFLOWING, CURSOR_SPLINT, 0, + SPLINT_RED_UICURSOR, UICURSOR_FREEFLOWING, CURSOR_SPLINT_RED, 0, }; diff --git a/Tactical/Interface Cursors.h b/Tactical/Interface Cursors.h index d6195a0b..b20eb713 100644 --- a/Tactical/Interface Cursors.h +++ b/Tactical/Interface Cursors.h @@ -216,6 +216,9 @@ typedef enum BLOODBAG_GREY_UICURSOR, BLOODBAG_RED_UICURSOR, + SPLINT_GREY_UICURSOR, + SPLINT_RED_UICURSOR, + NUM_UI_CURSORS } UICursorDefines; diff --git a/Tactical/Interface Enhanced.cpp b/Tactical/Interface Enhanced.cpp index 7ea6426f..0dcbdd2c 100644 --- a/Tactical/Interface Enhanced.cpp +++ b/Tactical/Interface Enhanced.cpp @@ -2792,6 +2792,15 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr MSYS_EnableRegion( &gUDBFasthelpRegions[iFirstDataRegion + cnt] ); ++cnt; } + + //////////////////// MEDICAL_SPLINT + if ( HasItemFlag( gpItemDescObject->usItem, MEDICAL_SPLINT ) ) + { + swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[48], szUDBGenSecondaryStatsExplanationsTooltipText[48] ); + SetRegionFastHelpText( &( gUDBFasthelpRegions[iFirstDataRegion + cnt] ), pStr ); + MSYS_EnableRegion( &gUDBFasthelpRegions[iFirstDataRegion + cnt] ); + ++cnt; + } } ////////////////////////////////////////////////////// @@ -6436,6 +6445,14 @@ void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject ) BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 45, gItemDescGenSecondaryRegions[cnt].sLeft + sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL ); ++cnt; } + + //////////////////// MEDICAL_SPLINT + if ( ( HasItemFlag( gpItemDescObject->usItem, MEDICAL_SPLINT ) && !fComparisonMode ) || + ( fComparisonMode && HasItemFlag( gpComparedItemDescObject->usItem, MEDICAL_SPLINT ) ) ) + { + BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 23, gItemDescGenSecondaryRegions[cnt].sLeft + sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL ); + ++cnt; + } } void DrawPropertyValueInColour( INT16 iValue, UINT8 ubNumLine, UINT8 ubNumRegion, BOOLEAN fComparisonMode, BOOLEAN fModifier, BOOLEAN fHigherBetter, UINT16 uiOverwriteColour = 0, BOOLEAN fPercentSign = FALSE ) diff --git a/Tactical/Item Types.h b/Tactical/Item Types.h index 3f30e8db..94783116 100644 --- a/Tactical/Item Types.h +++ b/Tactical/Item Types.h @@ -179,6 +179,7 @@ typedef enum ATTACHMENT_SLOT{ #define APPLYITEMCURS 26 #define INTERACTIVEACTIONCURS 27 #define BLOODBAGCURS 28 +#define SPLINTCURS 29 #define CAMERARANGE 10 @@ -777,6 +778,7 @@ extern OBJECTTYPE gTempObject; // extended flagmask to UINT64 #define EMPTY_BLOOD_BAG 0x0000000100000000 // this item is a empty blood bag +#define MEDICAL_SPLINT 0x0000000200000000 // this item is a medical splint that can be applied to some diseases // ---------------------------------------------------------------- diff --git a/Tactical/Items.cpp b/Tactical/Items.cpp index 296f0b15..69c0c2e8 100644 --- a/Tactical/Items.cpp +++ b/Tactical/Items.cpp @@ -6175,6 +6175,12 @@ BOOLEAN CanItemFitInPosition( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj, INT8 bPos switch( bPos ) { case SECONDHANDPOS: + // Flugente: disease can stop us from using our arms normally + if ( gGameExternalOptions.fDisease + && gGameExternalOptions.fDiseaseSevereLimitations + && pSoldier->HasDiseaseWithFlag( DISEASE_PROPERTY_LIMITED_USE_ARMS ) ) + return FALSE; + if (Item[pSoldier->inv[HANDPOS].usItem].twohanded ) { return( FALSE ); @@ -6183,6 +6189,12 @@ BOOLEAN CanItemFitInPosition( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj, INT8 bPos case HANDPOS: if (Item[ pObj->usItem ].twohanded ) { + // Flugente: disease can stop us from using our arms normally + if ( gGameExternalOptions.fDisease + && gGameExternalOptions.fDiseaseSevereLimitations + && pSoldier->HasDiseaseWithFlag( DISEASE_PROPERTY_LIMITED_USE_ARMS ) ) + return FALSE; + if ( pSoldier->inv[HANDPOS].exists() && pSoldier->inv[SECONDHANDPOS].exists() ) { // two items in hands; try moving the second one so we can swap @@ -9173,7 +9185,40 @@ void SwapHandItems( SOLDIERTYPE * pSoldier ) BOOLEAN fOk; CHECKV( pSoldier ); - if (pSoldier->inv[HANDPOS].exists() == false || pSoldier->inv[SECONDHANDPOS].exists() == false) + + // Flugente: disease can stop us from using our arms normally + if ( gGameExternalOptions.fDisease + && gGameExternalOptions.fDiseaseSevereLimitations + && pSoldier->HasDiseaseWithFlag( DISEASE_PROPERTY_LIMITED_USE_ARMS ) ) + { + // if we only have one usable hand, drop item in main hand to inventory + if ( pSoldier->inv[HANDPOS].exists() ) + { + // must move the item in the main hand elsewhere in the inventory + fOk = AutoPlaceObject( pSoldier, &( pSoldier->inv[HANDPOS] ), FALSE, HANDPOS ); + if ( !fOk ) + { + return; + } + } + + // if we somehow had an item in our second hand (which shouldn't be possible to begin with), drop it to inventory if twohanded + if ( TwoHandedItem( pSoldier->inv[SECONDHANDPOS].usItem ) ) + { + // must move the item in the main hand elsewhere in the inventory + fOk = AutoPlaceObject( pSoldier, &( pSoldier->inv[SECONDHANDPOS] ), FALSE, SECONDHANDPOS ); + if ( !fOk ) + { + return; + } + // the main hand is now empty so a swap is going to work... + } + + // whatever is in the second hand can be swapped to the main hand! + SwapObjs( pSoldier, HANDPOS, SECONDHANDPOS, TRUE ); + DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 ); + } + else if (pSoldier->inv[HANDPOS].exists() == false || pSoldier->inv[SECONDHANDPOS].exists() == false) { // whatever is in the second hand can be swapped to the main hand! SwapObjs( pSoldier, HANDPOS, SECONDHANDPOS, TRUE ); diff --git a/Tactical/Overhead.cpp b/Tactical/Overhead.cpp index 10167cd6..9caf4786 100644 --- a/Tactical/Overhead.cpp +++ b/Tactical/Overhead.cpp @@ -1587,6 +1587,11 @@ BOOLEAN ExecuteOverhead( ) pSoldier->EVENT_SoldierTakeBloodFromPerson( pSoldier->aiData.sPendingActionData2, pSoldier->aiData.bPendingActionData3 ); pSoldier->aiData.ubPendingAction = NO_PENDING_ACTION; } + else if ( pSoldier->aiData.ubPendingAction == MERC_MEDICALSPLINT ) + { + pSoldier->EVENT_SoldierApplySplintToPerson( pSoldier->aiData.sPendingActionData2, pSoldier->aiData.bPendingActionData3 ); + pSoldier->aiData.ubPendingAction = NO_PENDING_ACTION; + } if ( fNoAPsForPendingAction ) { diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index 61950133..9edfef1c 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -5446,7 +5446,7 @@ UINT16 SOLDIERTYPE::GetMoveStateBasedOnStance( UINT8 ubStanceHeight ) { case ANIM_STAND: //if ( this->flags.fUIMovementFast && !( this->flags.uiStatusFlags & SOLDIER_VEHICLE ) ) - if ( this->flags.fUIMovementFast ) + if ( this->IsFastMovement() ) { return(RUNNING); } @@ -5457,7 +5457,7 @@ UINT16 SOLDIERTYPE::GetMoveStateBasedOnStance( UINT8 ubStanceHeight ) break; case ANIM_PRONE: - if ( this->flags.fUIMovementFast ) + if ( this->IsFastMovement() ) { return(CRAWLING); } @@ -5468,7 +5468,7 @@ UINT16 SOLDIERTYPE::GetMoveStateBasedOnStance( UINT8 ubStanceHeight ) break; case ANIM_CROUCH: - if ( this->flags.fUIMovementFast ) + if ( this->IsFastMovement() ) { return(SWATTING); } @@ -5930,6 +5930,16 @@ void SOLDIERTYPE::EVENT_SoldierGotHit( UINT16 usWeaponIndex, INT16 sDamage, INT1 { ubReason = TAKE_DAMAGE_VEHICLE_TRAUMA; } + // Flugente: it would be more reasonable to check for the ammo or gun details, but that's what is used in other locations + else if ( usWeaponIndex == FLAMETHROWER ) + { + ubReason = TAKE_DAMAGE_GAS_FIRE; + + INT16 fireresistance = ArmourVersusFirePercent( this ); + + sDamage = max( 0, sDamage * ( 100 - fireresistance ) / 100 ); + } + // marke take out gunfire if ammotype is explosive // callahan update start @@ -8993,12 +9003,12 @@ void AdjustAniSpeed( SOLDIERTYPE *pSoldier ) void CalculateSoldierAniSpeed( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pStatsSoldier ) { DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "CalculateSoldierAniSpeed" ); - UINT32 uiTerrainDelay; - UINT32 uiSpeed = 0; + INT16 sTerrainDelay; INT8 bBreathDef = 0, bLifeDef = 0; INT16 bAgilDef = 0; - INT8 bAdditional = 0; + INT16 bAdditional = 0; + INT16 legbrokenpenalty = 60; // for those animations which have a speed of zero, we have to calculate it // here. Some animation, such as water-movement, have an ADDITIONAL speed @@ -9055,7 +9065,14 @@ void CalculateSoldierAniSpeed( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pStatsSoldier case WALKING_ALTERNATIVE_RDY: // Adjust based on body type - bAdditional = (UINT8)(gubAnimWalkSpeeds[pStatsSoldier->ubBodyType].sSpeed); + bAdditional = gubAnimWalkSpeeds[pStatsSoldier->ubBodyType].sSpeed; + + // Flugente: disease can stop us from using our arms normally + if ( gGameExternalOptions.fDisease + && gGameExternalOptions.fDiseaseSevereLimitations + && pSoldier->HasDiseaseWithFlag( DISEASE_PROPERTY_LIMITED_USE_LEGS ) ) + bAdditional += legbrokenpenalty; + if ( bAdditional < 0 ) bAdditional = 0; break; @@ -9063,7 +9080,14 @@ void CalculateSoldierAniSpeed( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pStatsSoldier case RUNNING: // Adjust based on body type - bAdditional = (UINT8)gubAnimRunSpeeds[pStatsSoldier->ubBodyType].sSpeed; + bAdditional = gubAnimWalkSpeeds[pStatsSoldier->ubBodyType].sSpeed; + + // Flugente: disease can stop us from using our arms normally + if ( gGameExternalOptions.fDisease + && gGameExternalOptions.fDiseaseSevereLimitations + && pSoldier->HasDiseaseWithFlag( DISEASE_PROPERTY_LIMITED_USE_LEGS ) ) + bAdditional += legbrokenpenalty; + if ( bAdditional < 0 ) bAdditional = 0; break; @@ -9082,7 +9106,14 @@ void CalculateSoldierAniSpeed( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pStatsSoldier // Adjust based on body type if ( pStatsSoldier->ubBodyType <= REGFEMALE ) { - bAdditional = (UINT8)gubAnimSwatSpeeds[pStatsSoldier->ubBodyType].sSpeed; + bAdditional = gubAnimWalkSpeeds[pStatsSoldier->ubBodyType].sSpeed; + + // Flugente: disease can stop us from using our arms normally + if ( gGameExternalOptions.fDisease + && gGameExternalOptions.fDiseaseSevereLimitations + && pSoldier->HasDiseaseWithFlag( DISEASE_PROPERTY_LIMITED_USE_LEGS ) ) + bAdditional += legbrokenpenalty; + if ( bAdditional < 0 ) bAdditional = 0; } @@ -9093,7 +9124,14 @@ void CalculateSoldierAniSpeed( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pStatsSoldier // Adjust based on body type if ( pStatsSoldier->ubBodyType <= REGFEMALE ) { - bAdditional = (UINT8)gubAnimCrawlSpeeds[pStatsSoldier->ubBodyType].sSpeed; + bAdditional = gubAnimWalkSpeeds[pStatsSoldier->ubBodyType].sSpeed; + + // Flugente: disease can stop us from using our arms normally + if ( gGameExternalOptions.fDisease + && gGameExternalOptions.fDiseaseSevereLimitations + && pSoldier->HasDiseaseWithFlag( DISEASE_PROPERTY_LIMITED_USE_LEGS ) ) + bAdditional += legbrokenpenalty; + if ( bAdditional < 0 ) bAdditional = 0; } @@ -9115,17 +9153,14 @@ void CalculateSoldierAniSpeed( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pStatsSoldier return; } - // figure out movement speed (terrspeed) if ( gAnimControl[pSoldier->usAnimState].uiFlags & ANIM_MOVING ) { - uiSpeed = gsTerrainTypeSpeedModifiers[pStatsSoldier->bOverTerrainType]; - - uiTerrainDelay = uiSpeed; + sTerrainDelay = gsTerrainTypeSpeedModifiers[pStatsSoldier->bOverTerrainType]; } else { - uiTerrainDelay = 40; // standing still + sTerrainDelay = 40; // standing still } if ( !(pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE) ) @@ -9151,8 +9186,8 @@ void CalculateSoldierAniSpeed( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pStatsSoldier bAgilDef = 30; } } - - uiTerrainDelay += (bLifeDef + bBreathDef + bAgilDef + bAdditional); + + sTerrainDelay += (bLifeDef + bBreathDef + bAgilDef + bAdditional); // Flugente: backgrounds switch ( pSoldier->usAnimState ) @@ -9172,14 +9207,14 @@ void CalculateSoldierAniSpeed( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pStatsSoldier case SIDE_STEP_CROUCH_DUAL: case SWAT_BACKWARDS_WK: // Flugente: background running speed reduces time needed: + is good, - is bad - uiTerrainDelay = (uiTerrainDelay * (100 - pSoldier->GetBackgroundValue( BG_PERC_SPEED_RUNNING ))) / 100; + sTerrainDelay = ( sTerrainDelay * (100 - pSoldier->GetBackgroundValue( BG_PERC_SPEED_RUNNING ))) / 100; break; default: break; } - pSoldier->sAniDelay = (INT16)uiTerrainDelay; + pSoldier->sAniDelay = sTerrainDelay; // If a moving animation and we're on drugs, increase speed.... if ( gAnimControl[pSoldier->usAnimState].uiFlags & ANIM_MOVING ) @@ -10058,7 +10093,8 @@ void HandleTakeDamageDeath( SOLDIERTYPE *pSoldier, UINT8 bOldLife, UINT8 ubReaso { case TAKE_DAMAGE_BLOODLOSS: case TAKE_DAMAGE_ELECTRICITY: - case TAKE_DAMAGE_GAS: + case TAKE_DAMAGE_GAS_FIRE: + case TAKE_DAMAGE_GAS_NOTFIRE: if ( pSoldier->bInSector ) { @@ -10470,6 +10506,11 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr if ( ubReason == TAKE_DAMAGE_TENTACLES ) HandlePossibleInfection( this, NULL, INFECTION_TYPE_WOUND_ANIMAL ); + if ( ubReason == TAKE_DAMAGE_GAS_FIRE ) + HandlePossibleInfection( this, NULL, INFECTION_TYPE_WOUND_FIRE ); + else if ( ubReason == TAKE_DAMAGE_GAS_NOTFIRE ) + HandlePossibleInfection( this, NULL, INFECTION_TYPE_WOUND_GAS ); + if ( ubReason == TAKE_DAMAGE_GUNFIRE && sLifeDeduct > 20 ) HandlePossibleInfection( this, NULL, INFECTION_TYPE_WOUND_GUNSHOT ); else if ( ubReason == TAKE_DAMAGE_BLADE || ubReason == TAKE_DAMAGE_HANDTOHAND @@ -10497,7 +10538,7 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr } // Calculate bleeding - if ( ubReason != TAKE_DAMAGE_GAS && !AM_A_ROBOT( this ) ) + if ( ubReason != TAKE_DAMAGE_GAS_FIRE && ubReason != TAKE_DAMAGE_GAS_NOTFIRE && !AM_A_ROBOT( this ) ) { if ( ubReason == TAKE_DAMAGE_HANDTOHAND ) { @@ -10584,17 +10625,52 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr //this->iLastArmourProtection = 0; } } + + // it is possible we have to drop the items in our hands + bool dropiteminmainhand = false; + + // Flugente: disease can stop us from using our arms normally + if ( gGameExternalOptions.fDisease + && gGameExternalOptions.fDiseaseSevereLimitations + && this->HasDiseaseWithFlag( DISEASE_PROPERTY_LIMITED_USE_ARMS ) ) + { + // drop item in main hand if twohanded + if ( this->inv[HANDPOS].exists() == true && TwoHandedItem( this->inv[HANDPOS].usItem ) ) + dropiteminmainhand = true; + + // we can only use one hand, so drop items in second hand + if ( this->inv[SECONDHANDPOS].exists() == true ) + { + // ATE: if our guy, make visible.... + if ( this->bTeam == gbPlayerNum ) + { + bVisible = 1; + } + //if this soldier was an enemy + // Kaiden Added for UB reveal All items after combat feature! + else if ( this->bTeam == ENEMY_TEAM ) + { + //add a flag to the item so when all enemies are killed, we can run through and reveal all the enemies items + usItemFlags |= WORLD_ITEM_DROPPED_FROM_ENEMY; + } + + if ( UsingNewAttachmentSystem() == true ) + ReduceAttachmentsOnGunForNonPlayerChars( this, &( this->inv[SECONDHANDPOS] ) ); + + AddItemToPool( this->sGridNo, &( this->inv[SECONDHANDPOS] ), bVisible, this->pathing.bLevel, usItemFlags, -1 ); //Madd: added usItemFlags to function arguments + DeleteObj( &( this->inv[SECONDHANDPOS] ) ); + } + } // OK, if here, let's see if we should drop our weapon.... - if ( ubReason != TAKE_DAMAGE_BLOODLOSS && !(AM_A_ROBOT( this )) ) + if ( !dropiteminmainhand && ubReason != TAKE_DAMAGE_BLOODLOSS && !(AM_A_ROBOT( this )) ) { INT16 sTestOne, sTestTwo, sChanceToDrop; INT8 bVisible = -1; sTestOne = EffectiveStrength( this, FALSE ); sTestTwo = (2 * (__max( sLifeDeduct, (sBreathLoss / 100) ))); - - + if ( this->ubAttackerID != NOBODY && MercPtrs[this->ubAttackerID]->ubBodyType == BLOODCAT ) { // bloodcat boost, let them make people drop items more @@ -10616,35 +10692,41 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr if ( Random( 100 ) < (UINT16)sChanceToDrop ) { - // OK, drop item in main hand... - if ( this->inv[HANDPOS].exists( ) == true ) + dropiteminmainhand = true; + } + } + + if ( dropiteminmainhand ) + { + // OK, drop item in main hand... + if ( this->inv[HANDPOS].exists() == true ) + { + // Flugente: If item has an attached rifle sling, place it the sling position instead + int bSlot = GUNSLINGPOCKPOS; + if ( HasAttachmentOfClass( &( this->inv[HANDPOS] ), AC_SLING ) && TryToPlaceInSlot( this, &( this->inv[HANDPOS] ), FALSE, bSlot, GUNSLINGPOCKPOS ) ) { - // Flugente: If item has an attached rifle sling, place it the sling position instead - int bSlot = GUNSLINGPOCKPOS; - if ( HasAttachmentOfClass( &(this->inv[HANDPOS]), AC_SLING ) && TryToPlaceInSlot( this, &(this->inv[HANDPOS]), FALSE, bSlot, GUNSLINGPOCKPOS ) ) + ; + } + else if ( !( this->inv[HANDPOS].fFlags & OBJECT_UNDROPPABLE ) ) + { + // ATE: if our guy, make visible.... + if ( this->bTeam == gbPlayerNum ) { - ; + bVisible = 1; } - else if ( !(this->inv[HANDPOS].fFlags & OBJECT_UNDROPPABLE) ) + //if this soldier was an enemy + // Kaiden Added for UB reveal All items after combat feature! + else if ( this->bTeam == ENEMY_TEAM ) { - // ATE: if our guy, make visible.... - if ( this->bTeam == gbPlayerNum ) - { - bVisible = 1; - } - //if this soldier was an enemy - // Kaiden Added for UB reveal All items after combat feature! - else if ( this->bTeam == ENEMY_TEAM ) - { - //add a flag to the item so when all enemies are killed, we can run through and reveal all the enemies items - usItemFlags |= WORLD_ITEM_DROPPED_FROM_ENEMY; - } - if ( UsingNewAttachmentSystem( ) == true ){ - ReduceAttachmentsOnGunForNonPlayerChars( this, &(this->inv[HANDPOS]) ); - } - AddItemToPool( this->sGridNo, &(this->inv[HANDPOS]), bVisible, this->pathing.bLevel, usItemFlags, -1 ); //Madd: added usItemFlags to function arguments - DeleteObj( &(this->inv[HANDPOS]) ); + //add a flag to the item so when all enemies are killed, we can run through and reveal all the enemies items + usItemFlags |= WORLD_ITEM_DROPPED_FROM_ENEMY; } + + if ( UsingNewAttachmentSystem() == true ) + ReduceAttachmentsOnGunForNonPlayerChars( this, &( this->inv[HANDPOS] ) ); + + AddItemToPool( this->sGridNo, &( this->inv[HANDPOS] ), bVisible, this->pathing.bLevel, usItemFlags, -1 ); //Madd: added usItemFlags to function arguments + DeleteObj( &( this->inv[HANDPOS] ) ); } } } @@ -10807,7 +10889,8 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sBr case TAKE_DAMAGE_BLOODLOSS: PossiblyStartEnemyTaunt( this, TAUNT_GOT_HIT_BLOODLOSS ); break; - case TAKE_DAMAGE_GAS: + case TAKE_DAMAGE_GAS_FIRE: + case TAKE_DAMAGE_GAS_NOTFIRE: PossiblyStartEnemyTaunt( this, TAUNT_GOT_HIT_GAS ); break; default: @@ -12797,7 +12880,8 @@ void SOLDIERTYPE::EVENT_SoldierBeginPunchAttack( INT32 sGridNo, UINT8 ubDirectio #ifdef JA2UB if ( fMartialArtist && !Item[usItem].crowbar && this->ubBodyType == REGMALE ) #else - if ( fMartialArtist && !AreInMeanwhile( ) && !Item[usItem].crowbar && this->ubBodyType == REGMALE && !IsZombie( ) ) // SANDRO - added check for body type + if ( fMartialArtist && !AreInMeanwhile( ) && !Item[usItem].crowbar && this->ubBodyType == REGMALE && !IsZombie( ) + && !( gGameExternalOptions.fDiseaseSevereLimitations && this->HasDiseaseWithFlag( DISEASE_PROPERTY_LIMITED_USE_LEGS )) ) // SANDRO - added check for body type #endif { // Are we in attack mode yet? @@ -12889,6 +12973,13 @@ void SOLDIERTYPE::EVENT_SoldierBeginPunchAttack( INT32 sGridNo, UINT8 ubDirectio nokick = TRUE; } + // Flugente: disease can stop us from using our arms normally + if ( !nokick + && gGameExternalOptions.fDisease + && gGameExternalOptions.fDiseaseSevereLimitations + && this->HasDiseaseWithFlag( DISEASE_PROPERTY_LIMITED_USE_LEGS ) ) + nokick = TRUE; + // Look at stance of target switch ( gAnimControl[pTSoldier->usAnimState].ubEndHeight ) { @@ -19220,17 +19311,22 @@ void SOLDIERTYPE::DeleteBoxingFlag( ) // Flugente: disease void SOLDIERTYPE::Infect( UINT8 aDisease ) { - if ( !gGameExternalOptions.fDisease ) + if ( !gGameExternalOptions.fDisease + || aDisease >= NUM_DISEASES ) return; // diseases should not affect machines if ( (this->flags.uiStatusFlags & SOLDIER_VEHICLE) || AM_A_ROBOT( this ) ) return; + // do not infect us if we are already infected + if ( !( Disease[aDisease].usDiseaseProperties & DISEASE_PROPERTY_CANREINFECT ) && this->sDiseasePoints[aDisease] > 0 ) + return; + // we are getting infected. Raise our disease points, but not over the level of an infection - if ( aDisease < NUM_DISEASES && this->sDiseasePoints[aDisease] <= Disease[aDisease].sInfectionPtsInitial ) + if ( this->sDiseasePoints[aDisease] <= Disease[aDisease].sInfectionPtsFull ) { - this->sDiseasePoints[aDisease] = min( this->sDiseasePoints[aDisease] + Disease[aDisease].sInfectionPtsInitial, Disease[aDisease].sInfectionPtsInitial ); + this->sDiseasePoints[aDisease] = min( this->sDiseasePoints[aDisease] + Disease[aDisease].sInfectionPtsInitial, Disease[aDisease].sInfectionPtsFull ); // possibly add a new disability if ( Disease[aDisease].usDiseaseProperties & DISEASE_PROPERTY_ADD_DISABILITY ) @@ -19250,7 +19346,7 @@ void SOLDIERTYPE::Infect( UINT8 aDisease ) } } - if ( this->sDiseasePoints[aDisease] > Disease[aDisease].sInfectionPtsOutbreak ) + if ( !( this->sDiseaseFlag[aDisease] & SOLDIERDISEASE_OUTBREAK ) && this->sDiseasePoints[aDisease] > Disease[aDisease].sInfectionPtsOutbreak ) { this->sDiseaseFlag[aDisease] |= SOLDIERDISEASE_OUTBREAK; @@ -19297,7 +19393,7 @@ void SOLDIERTYPE::AddDiseasePoints( UINT8 aDisease, INT32 aVal ) if ( this->sDiseaseFlag[aDisease] & SOLDIERDISEASE_DIAGNOSED && this->bTeam == gbPlayerNum ) ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szDiseaseText[TEXT_DISEASE_CURED], this->GetName( ), Disease[aDisease].szName ); - this->sDiseaseFlag[aDisease] &= ~(SOLDIERDISEASE_DIAGNOSED | SOLDIERDISEASE_OUTBREAK); + this->sDiseaseFlag[aDisease] &= ~(SOLDIERDISEASE_DIAGNOSED | SOLDIERDISEASE_OUTBREAK | SOLDIERDISEASE_SPLINTAPPLIED_LEG | SOLDIERDISEASE_SPLINTAPPLIED_ARM ); } } } @@ -19319,6 +19415,37 @@ void SOLDIERTYPE::AddDisability( UINT8 aDisability ) this->usDisabilityFlagMask |= ( 1 << (aDisability - 1 ) ); } +// Flugente: can we apply a medical splint to this guy? +bool SOLDIERTYPE::CanReceiveSplint() +{ + // not during combat + if ( gTacticalStatus.uiFlags & INCOMBAT ) + return FALSE; + + // must be player team + if ( this->bTeam != gbPlayerNum ) + return FALSE; + + if ( !gGameExternalOptions.fDisease + || !gGameExternalOptions.fDiseaseSevereLimitations ) + return FALSE; + + // check whether we have a disease that limits arm/leg use without having a splint + for ( int i = 0; i < NUM_DISEASES; ++i ) + { + if ( this->sDiseasePoints[i] > 0 && this->sDiseaseFlag[i] & SOLDIERDISEASE_DIAGNOSED ) + { + if ( (Disease[i].usDiseaseProperties & DISEASE_PROPERTY_LIMITED_USE_ARMS && !( this->sDiseaseFlag[i] & SOLDIERDISEASE_SPLINTAPPLIED_ARM ) ) + || ( Disease[i].usDiseaseProperties & DISEASE_PROPERTY_LIMITED_USE_LEGS && !( this->sDiseaseFlag[i] & SOLDIERDISEASE_SPLINTAPPLIED_LEG ) ) ) + { + return TRUE; + } + } + } + + return FALSE; +} + // do we have any disease? fDiagnosedOnly: check for wether we know of this infection fHealableOnly: check wether it can be healed BOOLEAN SOLDIERTYPE::HasDisease( BOOLEAN fDiagnosedOnly, BOOLEAN fHealableOnly, BOOLEAN fSymbolOnly ) { @@ -19505,10 +19632,35 @@ void SOLDIERTYPE::PrintDiseaseDesc( CHAR16* apStr, BOOLEAN fFullDesc ) wcscat( apStr, atStr ); } - if ( Disease[i].usDiseaseProperties & DISEASE_PROPERTY_ADD_DISABILITY ) + if ( gGameExternalOptions.fDiseaseSevereLimitations ) { - swprintf( atStr, szDiseaseText[TEXT_DISEASE_ADD_DISABILITY] ); - wcscat( apStr, atStr ); + if ( Disease[i].usDiseaseProperties & DISEASE_PROPERTY_ADD_DISABILITY ) + { + swprintf( atStr, szDiseaseText[TEXT_DISEASE_ADD_DISABILITY] ); + wcscat( apStr, atStr ); + } + + bool splintapplied = ( this->sDiseaseFlag[i] & ( SOLDIERDISEASE_SPLINTAPPLIED_ARM | SOLDIERDISEASE_SPLINTAPPLIED_LEG ) ); + + if ( Disease[i].usDiseaseProperties & DISEASE_PROPERTY_LIMITED_USE_ARMS ) + { + if ( splintapplied ) + swprintf( atStr, szDiseaseText[TEXT_DISEASE_LIMITED_ARMS_SPLINT] ); + else + swprintf( atStr, szDiseaseText[TEXT_DISEASE_LIMITED_ARMS] ); + + wcscat( apStr, atStr ); + } + + if ( Disease[i].usDiseaseProperties & DISEASE_PROPERTY_LIMITED_USE_LEGS ) + { + if ( splintapplied ) + swprintf( atStr, szDiseaseText[TEXT_DISEASE_LIMITED_LEGS_SPLINT] ); + else + swprintf( atStr, szDiseaseText[TEXT_DISEASE_LIMITED_LEGS] ); + + wcscat( apStr, atStr ); + } } } } @@ -21087,6 +21239,20 @@ UINT32 SOLDIERTYPE::GetExplorationPoints() return totalvalue; } +bool SOLDIERTYPE::IsFastMovement() +{ + if ( this->flags.fUIMovementFast ) + { + // Flugente: disease can stop us from using our legs normally + if ( gGameExternalOptions.fDisease + && gGameExternalOptions.fDiseaseSevereLimitations + && this->HasDiseaseWithFlag( DISEASE_PROPERTY_LIMITED_USE_LEGS ) ) + this->flags.fUIMovementFast = false; + } + + return this->flags.fUIMovementFast; +} + INT32 CheckBleeding( SOLDIERTYPE *pSoldier ) { INT8 bBandaged; //,savedOurTurn; @@ -22259,6 +22425,70 @@ void SOLDIERTYPE::EVENT_SoldierTakeBloodFromPerson( INT32 sGridNo, UINT8 ubDirec } } +void SOLDIERTYPE::EVENT_SoldierApplySplintToPerson( INT32 sGridNo, UINT8 ubDirection ) +{ + UINT8 ubPerson = WhoIsThere2( sGridNo, this->pathing.bLevel ); + + if ( ubPerson != NOBODY && ubPerson != this->ubID ) + { + // we found someone + SOLDIERTYPE* pSoldier = MercPtrs[ubPerson]; + + OBJECTTYPE* pObj = &( this->inv[HANDPOS] ); + + if ( pSoldier + && pObj->exists() + && HasItemFlag( pObj->usItem, MEDICAL_SPLINT ) + && pSoldier->CanReceiveSplint() + && ( (gGameOptions.fNewTraitSystem && NUM_SKILL_TRAITS( this, DOCTOR_NT ) > 0) || (!gGameOptions.fNewTraitSystem && EffectiveMedical( this ) >= 50) ) ) + { + UINT16 usItem = pObj->usItem; + + // delete object + DeleteObj( pObj ); + + // add flag to arm or leg (we'll find out which while we're doing it) + bool addtoarm = true; + bool addtoleg = true; + for ( int i = 0; i < NUM_DISEASES; ++i ) + { + if ( pSoldier->sDiseasePoints[i] > 0 ) + { + if ( addtoarm + && Disease[i].usDiseaseProperties & DISEASE_PROPERTY_LIMITED_USE_ARMS + && !( pSoldier->sDiseaseFlag[i] & SOLDIERDISEASE_SPLINTAPPLIED_ARM ) ) + { + pSoldier->sDiseaseFlag[i] |= SOLDIERDISEASE_SPLINTAPPLIED_ARM; + addtoleg = false; + } + + if ( addtoleg + && Disease[i].usDiseaseProperties & DISEASE_PROPERTY_LIMITED_USE_LEGS + && !( pSoldier->sDiseaseFlag[i] & SOLDIERDISEASE_SPLINTAPPLIED_LEG ) ) + { + pSoldier->sDiseaseFlag[i] |= SOLDIERDISEASE_SPLINTAPPLIED_LEG; + addtoarm = false; + } + } + } + + DeductPoints( this, GetAPsToApplyItem( this, sGridNo ), APBPConstants[BP_APPLYITEM], AFTERACTION_INTERRUPT ); + + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, New113Message[MSG113_X_APPLY_Y_TO_Z], this->GetName(), Item[usItem].szItemName, pSoldier->GetName() ); + + if ( !is_networked ) + this->EVENT_InitNewSoldierAnim( CUTTING_FENCE, 0, FALSE ); + else + this->ChangeSoldierState( CUTTING_FENCE, 0, 0 ); + + return; + } + } + + // If this didn't work, say NOTHING quote... + this->DoMercBattleSound( BATTLE_SOUND_NOTHING ); +} + void SOLDIERTYPE::EVENT_SoldierInteractiveAction( INT32 sGridNo, UINT16 usActionType ) { DoInteractiveAction( sGridNo, this ); diff --git a/Tactical/Soldier Control.h b/Tactical/Soldier Control.h index c24a80ec..161054ee 100644 --- a/Tactical/Soldier Control.h +++ b/Tactical/Soldier Control.h @@ -55,11 +55,12 @@ extern UINT16 CivLastNames[MAXCIVLASTNAMES][10]; #define TAKE_DAMAGE_BLOODLOSS 5 #define TAKE_DAMAGE_EXPLOSION 6 #define TAKE_DAMAGE_ELECTRICITY 7 -#define TAKE_DAMAGE_GAS 8 +#define TAKE_DAMAGE_GAS_FIRE 8 #define TAKE_DAMAGE_TENTACLES 9 #define TAKE_DAMAGE_STRUCTURE_EXPLOSION 10 #define TAKE_DAMAGE_OBJECT 11 #define TAKE_DAMAGE_VEHICLE_TRAUMA 12 +#define TAKE_DAMAGE_GAS_NOTFIRE 13 #define SOLDIER_UNBLIT_SIZE (75*75*2) @@ -233,6 +234,7 @@ enum MERC_APPLYITEM, MERC_INTERACTIVEACTION, MERC_FILLBLOODBAG, + MERC_MEDICALSPLINT, }; // ENUMERATIONS FOR THROW ACTIONS @@ -437,7 +439,9 @@ enum #define SOLDIERDISEASE_DIAGNOSED 0x00000001 //1 // it is now known that we have this disease - either a doctor diagnosed it, or it broke out an we are currently suffering #define SOLDIERDISEASE_OUTBREAK 0x00000002 //2 // disease has broken out - we suffer the effects now. Without this flag, it is active but does not do any damage to us #define SOLDIERDISEASE_REVERSEAL 0x00000004 //4 // disease is reversing - every hour we receive negative points. This is used to simulate a disease healing itself +#define SOLDIERDISEASE_SPLINTAPPLIED_LEG 0x00000008 // a spling has been applied to the leg. Diseases with the corresponding tag will heal faster +#define SOLDIERDISEASE_SPLINTAPPLIED_ARM 0x00000010 // a spling has been applied to the arm. Diseases with the corresponding tag will heal faster // -------- added by Flugente: background property flags -------- @@ -1677,6 +1681,7 @@ public: void EVENT_SoldierHandcuffPerson( INT32 sGridNo, UINT8 ubDirection ); // added by Flugente void EVENT_SoldierApplyItemToPerson( INT32 sGridNo, UINT8 ubDirection ); // added by Flugente void EVENT_SoldierTakeBloodFromPerson( INT32 sGridNo, UINT8 ubDirection ); // added by Flugente + void EVENT_SoldierApplySplintToPerson( INT32 sGridNo, UINT8 ubDirection ); // added by Flugente void EVENT_SoldierInteractiveAction( INT32 sGridNo, UINT16 usActionType ); // added by Flugente BOOLEAN EVENT_InternalGetNewSoldierPath( INT32 sDestGridNo, UINT16 usMovementAnim, BOOLEAN fFromUI, BOOLEAN fForceRestart ); @@ -1961,6 +1966,7 @@ public: void AddDiseasePoints( UINT8 aDisease, INT32 aVal ); void AnnounceDisease( UINT8 aDisease ); void AddDisability( UINT8 aDisability ); + bool CanReceiveSplint(); // do we have any disease? // fDiagnosedOnly: check for wether we know of this infection @@ -2044,6 +2050,8 @@ public: // Flugente: exploration assignment UINT32 GetExplorationPoints(); + + bool IsFastMovement(); ////////////////////////////////////////////////////////////////////////////// }; // SOLDIERTYPE; diff --git a/Tactical/UI Cursors.cpp b/Tactical/UI Cursors.cpp index c332a1d5..3eb3b3ac 100644 --- a/Tactical/UI Cursors.cpp +++ b/Tactical/UI Cursors.cpp @@ -53,6 +53,7 @@ UINT8 HandleRefuelCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT32 uiCursorF UINT8 HandleRemoteCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fActivated, UINT32 uiCursorFlags ); UINT8 HandleCameraCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fActivated, UINT32 uiCursorFlags ); UINT8 HandleBloodbagCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fActivated, UINT32 uiCursorFlags ); +UINT8 HandleSplintCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fActivated, UINT32 uiCursorFlags ); UINT8 HandleBombCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fActivated, UINT32 uiCursorFlags ); UINT8 HandleJarCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT32 uiCursorFlags ); UINT8 HandleTinCanCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT32 uiCursorFlags ); @@ -288,6 +289,10 @@ UINT8 GetProperItemCursor( UINT8 ubSoldierID, UINT16 ubItemIndex, INT32 usMapPos ubCursorID = HandleBloodbagCursor( pSoldier, sTargetGridNo, fActivated, uiCursorFlags ); break; + case SPLINTCURS: + ubCursorID = HandleSplintCursor( pSoldier, sTargetGridNo, fActivated, uiCursorFlags ); + break; + case REMOTECURS: ubCursorID = HandleRemoteCursor( pSoldier, sTargetGridNo, fActivated, uiCursorFlags ); @@ -2227,6 +2232,37 @@ UINT8 HandleBloodbagCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fActiv return BLOODBAG_RED_UICURSOR; } +UINT8 HandleSplintCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fActivated, UINT32 uiCursorFlags ) +{ + // DRAW PATH TO GUY + HandleUIMovementCursor( pSoldier, uiCursorFlags, sGridNo, MOVEUI_TARGET_APPLYITEM ); + + if ( HasItemFlag( ( &( pSoldier->inv[HANDPOS] ) )->usItem, MEDICAL_SPLINT ) ) + { + // are we actually qualified to use this? + if ( gGameOptions.fNewTraitSystem ) + { + if ( NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ) == 0 ) + return SPLINT_RED_UICURSOR; + } + else + { + if ( EffectiveMedical( pSoldier ) < 50 ) + return SPLINT_RED_UICURSOR; + } + + // is there a person here? + UINT8 usSoldierIndex = WhoIsThere2( sGridNo, pSoldier->pathing.bLevel ); + if ( usSoldierIndex != NOBODY ) + { + if ( usSoldierIndex != pSoldier->ubID && MercPtrs[usSoldierIndex]->CanReceiveSplint() ) + return SPLINT_GREY_UICURSOR; + } + } + + return SPLINT_RED_UICURSOR; +} + UINT8 HandleBombCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fActivated, UINT32 uiCursorFlags ) { @@ -2897,6 +2933,10 @@ UINT8 GetActionModeCursor( SOLDIERTYPE *pSoldier ) if ( HasItemFlag( usInHand, EMPTY_BLOOD_BAG ) ) ubCursor = BLOODBAGCURS; + // Flugente: disease + if ( HasItemFlag( usInHand, MEDICAL_SPLINT ) ) + ubCursor = SPLINTCURS; + // Flugente: interactive actions // we only check whether an action is possible in principle, not whether this particular guy can do it. That way we know an action is possible here even if we can't perform it at the moment. // only do this if the item doesn't already allow us to do something else diff --git a/Tactical/Vehicles.cpp b/Tactical/Vehicles.cpp index 515ef276..89381e29 100644 --- a/Tactical/Vehicles.cpp +++ b/Tactical/Vehicles.cpp @@ -1987,13 +1987,13 @@ void AddPassangersToTeamPanel( INT32 iId ) void VehicleTakeDamage( UINT8 ubID, UINT8 ubReason, INT16 sDamage, INT32 sGridNo, UINT8 ubAttackerID ) { - if ( ubReason != TAKE_DAMAGE_GAS ) + if ( ubReason != TAKE_DAMAGE_GAS_FIRE && ubReason != TAKE_DAMAGE_GAS_NOTFIRE ) { PlayJA2Sample( (UINT32)( S_METAL_IMPACT3 ), RATE_11025, SoundVolume( MIDVOLUME, sGridNo ), 1, SoundDir( sGridNo ) ); } // check if there was in fact damage done to the vehicle - if( ( ubReason == TAKE_DAMAGE_HANDTOHAND ) || ( ubReason == TAKE_DAMAGE_GAS ) ) + if( ( ubReason == TAKE_DAMAGE_HANDTOHAND ) || ( ubReason == TAKE_DAMAGE_GAS_FIRE ) || ( ubReason == TAKE_DAMAGE_GAS_NOTFIRE ) ) { // nope return; diff --git a/Tactical/XML_Disease.cpp b/Tactical/XML_Disease.cpp index e5137ffe..921809ce 100644 --- a/Tactical/XML_Disease.cpp +++ b/Tactical/XML_Disease.cpp @@ -70,6 +70,8 @@ diseaseStartElementHandle( void *userData, const XML_Char *name, const XML_Char strcmp( name, "InfectionChance_WOUND_ANIMAL" ) == 0 || strcmp( name, "InfectionChance_WOUND_OPEN" ) == 0 || strcmp( name, "InfectionChance_WOUND_GUNSHOT" ) == 0 || + strcmp( name, "InfectionChance_WOUND_FIRE" ) == 0 || + strcmp( name, "InfectionChance_WOUND_GAS" ) == 0 || strcmp( name, "InfectionChance_WOUND_AGI" ) == 0 || strcmp( name, "InfectionChance_WOUND_DEX" ) == 0 || strcmp( name, "InfectionChance_WOUND_STR" ) == 0 || @@ -84,6 +86,8 @@ diseaseStartElementHandle( void *userData, const XML_Char *name, const XML_Char strcmp( name, "fDisgusting" ) == 0 || strcmp( name, "fSpecialFlagPTSDBuns" ) == 0 || strcmp( name, "fSpecialFlagContractDisability" ) == 0 || + strcmp( name, "fSpecialFlagLimitedUseArms" ) == 0 || + strcmp( name, "fSpecialFlagLimitedUseLegs" ) == 0 || strcmp( name, "sEffStatAGI" ) == 0 || strcmp( name, "sEffStatDEX" ) == 0 || strcmp( name, "sEffStatSTR" ) == 0 || @@ -239,6 +243,16 @@ diseaseEndElementHandle( void *userData, const XML_Char *name ) pData->curElement = ELEMENT; pData->curItem.dInfectionChance[INFECTION_TYPE_WOUND_GUNSHOT] = max( 0.0f, min( 100.0f, atof( pData->szCharData ) ) ); } + else if ( strcmp( name, "InfectionChance_WOUND_FIRE" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.dInfectionChance[INFECTION_TYPE_WOUND_FIRE] = max( 0.0f, min( 100.0f, atof( pData->szCharData ) ) ); + } + else if ( strcmp( name, "InfectionChance_WOUND_GAS" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.dInfectionChance[INFECTION_TYPE_WOUND_GAS] = max( 0.0f, min( 100.0f, atof( pData->szCharData ) ) ); + } else if ( strcmp( name, "InfectionChance_WOUND_AGI" ) == 0 ) { pData->curElement = ELEMENT; @@ -316,6 +330,18 @@ diseaseEndElementHandle( void *userData, const XML_Char *name ) if ( atol( pData->szCharData ) ) pData->curItem.usDiseaseProperties |= DISEASE_PROPERTY_ADD_DISABILITY; } + else if ( strcmp( name, "fSpecialFlagLimitedUseArms" ) == 0 ) + { + pData->curElement = ELEMENT; + if ( atol( pData->szCharData ) ) + pData->curItem.usDiseaseProperties |= DISEASE_PROPERTY_LIMITED_USE_ARMS; + } + else if ( strcmp( name, "fSpecialFlagLimitedUseLegs" ) == 0 ) + { + pData->curElement = ELEMENT; + if ( atol( pData->szCharData ) ) + pData->curItem.usDiseaseProperties |= DISEASE_PROPERTY_LIMITED_USE_LEGS; + } else if ( strcmp( name, "sEffStatAGI" ) == 0 ) { pData->curElement = ELEMENT; @@ -482,6 +508,8 @@ BOOLEAN WriteDiseaseStats( ) FilePrintf( hFile, "\t\t%3.2f\r\n", Disease[cnt].dInfectionChance[INFECTION_TYPE_WOUND_ANIMAL] ); FilePrintf( hFile, "\t\t%3.2f\r\n", Disease[cnt].dInfectionChance[INFECTION_TYPE_WOUND_OPEN] ); FilePrintf( hFile, "\t\t%3.2f\r\n", Disease[cnt].dInfectionChance[INFECTION_TYPE_WOUND_GUNSHOT] ); + FilePrintf( hFile, "\t\t%3.2f\r\n", Disease[cnt].dInfectionChance[INFECTION_TYPE_WOUND_FIRE] ); + FilePrintf( hFile, "\t\t%3.2f\r\n", Disease[cnt].dInfectionChance[INFECTION_TYPE_WOUND_GAS] ); FilePrintf( hFile, "\t\t%3.2f\r\n", Disease[cnt].dInfectionChance[INFECTION_TYPE_WOUND_AGI] ); FilePrintf( hFile, "\t\t%3.2f\r\n", Disease[cnt].dInfectionChance[INFECTION_TYPE_WOUND_DEX] ); FilePrintf( hFile, "\t\t%3.2f\r\n", Disease[cnt].dInfectionChance[INFECTION_TYPE_WOUND_STR] ); @@ -496,6 +524,8 @@ BOOLEAN WriteDiseaseStats( ) FilePrintf( hFile, "\t\t%d\r\n", (Disease[cnt].usDiseaseProperties & DISEASE_PROPERTY_DISGUSTING) ? 1 : 0 ); FilePrintf( hFile, "\t\t%d\r\n", ( Disease[cnt].usDiseaseProperties & DISEASE_PROPERTY_PTSD_BUNS ) ? 1 : 0 ); FilePrintf( hFile, "\t\t%d\r\n", ( Disease[cnt].usDiseaseProperties & DISEASE_PROPERTY_ADD_DISABILITY ) ? 1 : 0 ); + FilePrintf( hFile, "\t\t%d\r\n", ( Disease[cnt].usDiseaseProperties & DISEASE_PROPERTY_LIMITED_USE_ARMS ) ? 1 : 0 ); + FilePrintf( hFile, "\t\t%d\r\n", ( Disease[cnt].usDiseaseProperties & DISEASE_PROPERTY_LIMITED_USE_LEGS ) ? 1 : 0 ); FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].sEffStat[INFST_AGI] ); FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].sEffStat[INFST_DEX] ); FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].sEffStat[INFST_STR] ); diff --git a/TacticalAI/AIUtils.cpp b/TacticalAI/AIUtils.cpp index 7677b0b5..ea63d1af 100644 --- a/TacticalAI/AIUtils.cpp +++ b/TacticalAI/AIUtils.cpp @@ -343,7 +343,7 @@ UINT8 ShootingStanceChange( SOLDIERTYPE * pSoldier, ATTACKTYPE * pAttack, INT8 b UINT16 DetermineMovementMode( SOLDIERTYPE * pSoldier, INT8 bAction ) { - if ( pSoldier->flags.fUIMovementFast ) + if ( pSoldier->IsFastMovement() ) { return( RUNNING ); } diff --git a/TileEngine/Explosion Control.cpp b/TileEngine/Explosion Control.cpp index 9c818526..59672974 100644 --- a/TileEngine/Explosion Control.cpp +++ b/TileEngine/Explosion Control.cpp @@ -2164,7 +2164,7 @@ BOOLEAN DishOutGasDamage( SOLDIERTYPE * pSoldier, EXPLOSIVETYPE * pExplosive, IN } // a gas effect, take damage directly... - pSoldier->SoldierTakeDamage( ANIM_STAND, sWoundAmt, sBreathAmt, TAKE_DAMAGE_GAS, NOBODY, NOWHERE, 0, TRUE ); + pSoldier->SoldierTakeDamage( ANIM_STAND, sWoundAmt, sBreathAmt, pExplosive->ubType == EXPLOSV_BURNABLEGAS ? TAKE_DAMAGE_GAS_FIRE : TAKE_DAMAGE_GAS_NOTFIRE, NOBODY, NOWHERE, 0, TRUE ); if (is_networked && is_client) { diff --git a/TileEngine/structure.cpp b/TileEngine/structure.cpp index 293f3b3f..711a5498 100644 --- a/TileEngine/structure.cpp +++ b/TileEngine/structure.cpp @@ -753,7 +753,7 @@ BOOLEAN OkayToAddStructureToTile( INT32 sBaseGridNo, INT16 sCubeOffset, DB_STRUC { pSoldier->EVENT_SoldierGotHit( 0, Random(10)+5, Random(200)+Random(200), MercPtrs[ sSoldierID ]->ubDirection, 0, sSoldierID, FIRE_WEAPON_VEHICLE_TRAUMA, 0, 0, pSoldier->sGridNo ); } - else if( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE && MercPtrs[ sSoldierID ]->flags.fUIMovementFast ) + else if( gAnimControl[ pSoldier->usAnimState ].ubEndHeight == ANIM_PRONE && MercPtrs[ sSoldierID ]->IsFastMovement() ) { pSoldier->EVENT_SoldierGotHit( 0, Random(5), Random(100)+Random(100), MercPtrs[ sSoldierID ]->ubDirection, 0, sSoldierID, FIRE_WEAPON_VEHICLE_TRAUMA, 0, 0, pSoldier->sGridNo ); } diff --git a/Utils/Cursors.cpp b/Utils/Cursors.cpp index e28995e6..f5f547e9 100644 --- a/Utils/Cursors.cpp +++ b/Utils/Cursors.cpp @@ -148,6 +148,9 @@ CursorFileData CursorFileDatabase[] = { "CURSORS\\bloodbag.sti" , FALSE, 0, ANIMATED_CURSOR, 11, NULL }, // Flugente: bloodbag { "CURSORS\\bloodbag_r.sti" , FALSE, 0, ANIMATED_CURSOR, 1, NULL }, + + { "CURSORS\\medicalsplint.sti" , FALSE, 0, ANIMATED_CURSOR, 11, NULL }, // Flugente: medical splint + { "CURSORS\\medicalsplint_r.sti" , FALSE, 0, ANIMATED_CURSOR, 1, NULL }, { "CURSORS\\can_01.sti" , FALSE, 0, 0, 0, NULL }, { "CURSORS\\can_02.sti" , FALSE, 0, 0, 0, NULL }, @@ -1358,6 +1361,21 @@ CursorData CursorDatabase[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, CENTER_CURSOR, CENTER_CURSOR, 0, 0, 0, 0 }, + + // Flugente: medical splint + { C_TRINGS, 6, 0, HIDE_SUBCURSOR, HIDE_SUBCURSOR, + C_SPLINT, 0, 0, CENTER_SUBCURSOR, CENTER_SUBCURSOR, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 2, CENTER_CURSOR, CENTER_CURSOR, 0, 0, 0, 0 }, + + { C_TRINGS, 6, 0, HIDE_SUBCURSOR, HIDE_SUBCURSOR, + C_SPLINT_RED, 0, 0, CENTER_SUBCURSOR, CENTER_SUBCURSOR, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, + 2, CENTER_CURSOR, CENTER_CURSOR, 0, 0, 0, 0 }, { C_TRINGS, 6, 0, HIDE_SUBCURSOR, HIDE_SUBCURSOR, C_FUEL , 0, 0, CENTER_SUBCURSOR, CENTER_SUBCURSOR, diff --git a/Utils/Cursors.h b/Utils/Cursors.h index 0ea744f0..d9a141e7 100644 --- a/Utils/Cursors.h +++ b/Utils/Cursors.h @@ -182,6 +182,9 @@ typedef enum CURSOR_BLOODBAG, CURSOR_BLOODBAG_RED, + + CURSOR_SPLINT, + CURSOR_SPLINT_RED, CURSOR_FUEL, CURSOR_FUEL_RED, @@ -276,6 +279,8 @@ typedef enum C_CAMERA_RED, C_BLOODBAG, C_BLOODBAG_RED, + C_SPLINT, + C_SPLINT_RED, C_FUEL, C_FUEL_RED, C_ACTIONMODERED_NCTH, diff --git a/Utils/Text.h b/Utils/Text.h index 58e26add..b91269b9 100644 --- a/Utils/Text.h +++ b/Utils/Text.h @@ -2544,6 +2544,7 @@ enum MSG113_BLOODBAGOPTIONS_YESSTAR, MSG113_BLOODBAGOPTIONS_YES, MSG113_BLOODBAGOPTIONS_NO, + MSG113_X_APPLY_Y_TO_Z, TEXT_NUM_MSG113, }; @@ -2984,6 +2985,11 @@ enum TEXT_DISEASE_PTSD_BUNS_SPECIAL, TEXT_DISEASE_CONTAMINATION_FOUND, TEXT_DISEASE_ADD_DISABILITY, + + TEXT_DISEASE_LIMITED_ARMS, + TEXT_DISEASE_LIMITED_ARMS_SPLINT, + TEXT_DISEASE_LIMITED_LEGS, + TEXT_DISEASE_LIMITED_LEGS_SPLINT, }; enum diff --git a/Utils/XML_Items.cpp b/Utils/XML_Items.cpp index 7e2476f9..ff8c850d 100644 --- a/Utils/XML_Items.cpp +++ b/Utils/XML_Items.cpp @@ -297,6 +297,7 @@ itemStartElementHandle(void *userData, const XML_Char *name, const XML_Char **at strcmp(name, "usRiotShieldGraphic" ) == 0 || strcmp(name, "bloodbag" ) == 0 || strcmp(name, "emptybloodbag" ) == 0 || + strcmp(name, "medicalsplint" ) == 0 || strcmp(name, "sFireResistance" ) == 0 || strcmp(name, "usAdministrationModifier" ) == 0)) { @@ -1535,6 +1536,13 @@ itemEndElementHandle(void *userData, const XML_Char *name) if ( (BOOLEAN)atol( pData->szCharData ) ) pData->curItem.usItemFlag |= EMPTY_BLOOD_BAG; } + else if ( strcmp( name, "medicalsplint" ) == 0 ) + { + pData->curElement = ELEMENT; + + if ( (BOOLEAN)atol( pData->szCharData ) ) + pData->curItem.usItemFlag |= MEDICAL_SPLINT; + } else if ( strcmp( name, "sFireResistance" ) == 0 ) { pData->curElement = ELEMENT; @@ -2183,6 +2191,7 @@ BOOLEAN WriteItemStats() if ( HasItemFlag( cnt, DISEASEPROTECTION_2 ) ) FilePrintf( hFile, "\t\t%d\r\n", 1 ); if ( HasItemFlag( cnt, BLOOD_BAG) ) FilePrintf( hFile, "\t\t%d\r\n", 1 ); if ( HasItemFlag( cnt, EMPTY_BLOOD_BAG ) ) FilePrintf( hFile, "\t\t%d\r\n", 1 ); + if ( HasItemFlag( cnt, MEDICAL_SPLINT ) ) FilePrintf( hFile, "\t\t%d\r\n", 1 ); FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].usRiotShieldStrength ); FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].usRiotShieldGraphic ); diff --git a/Utils/_ChineseText.cpp b/Utils/_ChineseText.cpp index 80a7a534..ad59aa0f 100644 --- a/Utils/_ChineseText.cpp +++ b/Utils/_ChineseText.cpp @@ -7477,6 +7477,7 @@ STR16 New113Message[] = L"是的*", //L"Yes*", L"是的", //L"Yes", L"不", //L"No", + L"%s applied %s to %s.", // TODO.Translate }; STR16 New113HAMMessage[] = @@ -8477,6 +8478,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|防|火|护|甲", //L"|R|e|s|i|s|t|a|n|t |t|o |F|i|r|e", L"|管|理|能|力|增|益|器", //L"|A|d|m|i|n|i|s|t|r|a|t|i|o|n |M|o|d|i|f|i|e|r", L"|间|谍|能|力|增|益|器", //L"|H|a|c|k|i|n|g |M|o|d|i|f|i|e|r", + L"|M|e|d|i|c|a|l |S|p|l|i|n|t", // TODO.Translate }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -8529,6 +8531,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \n可以降低%i%%的火焰伤害。", //L"\n \nThis armor lowers fire damage by %i%%.", L"\n \n这个工具可以\n提高%i%%的管理工作的效率。", //L"\n \nThis item makes you more effective at\nadministrative work by %i%%.", L"\n \n这个工具可以\n提高%i%%的间谍能力。", //L"\n \nThis item improves your hacking skills by %i%%.", + L"\n \nOnce applied, this item increases the healing\nspeed of severe wounds to either your arms or legs.", // TODO.Translate }; STR16 szUDBAdvStatsTooltipText[]= @@ -11113,6 +11116,11 @@ STR16 szDiseaseText[] = L"高度的痛苦会导致人格分裂\n", //L"High amount of distress can cause a personality split\n", L"在%s'库存中发现污染物品。\n", //L"Contaminated items found in %s' inventory.\n", L"Whenever we get this, a new disability is added.\n", // TODO.Translate + + L"Only one hand can be used.\n", + L"Only one hand can be used.\nA medical splint was applied to speed up the healing process.\n", + L"Leg functionality severely limited.\n", + L"Leg functionality severely limited.\nA medical splint was applied to speed up the healing process.\n", }; STR16 szSpyText[] = diff --git a/Utils/_DutchText.cpp b/Utils/_DutchText.cpp index b234e842..29672a7b 100644 --- a/Utils/_DutchText.cpp +++ b/Utils/_DutchText.cpp @@ -7489,6 +7489,7 @@ STR16 New113Message[] = L"Yes*", L"Yes", L"No", + L"%s applied %s to %s.", // TODO.Translate }; // TODO.Translate @@ -8493,6 +8494,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|R|e|s|i|s|t|a|n|t |t|o |F|i|r|e", L"|A|d|m|i|n|i|s|t|r|a|t|i|o|n |M|o|d|i|f|i|e|r", L"|H|a|c|k|i|n|g |M|o|d|i|f|i|e|r", + L"|M|e|d|i|c|a|l |S|p|l|i|n|t", // TODO.Translate }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -8545,6 +8547,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nThis armor lowers fire damage by %i%%.", L"\n \nThis item makes you more effective at\nadministrative work by %i%%.", L"\n \nThis item improves your hacking skills by %i%%.", + L"\n \nOnce applied, this item increases the healing\nspeed of severe wounds to either your arms or legs.", // TODO.Translate }; STR16 szUDBAdvStatsTooltipText[]= @@ -11129,6 +11132,11 @@ STR16 szDiseaseText[] = L"High amount of distress can cause a personality split\n", // TODO.Translate L"Contaminated items found in %s' inventory.\n", L"Whenever we get this, a new disability is added.\n", // TODO.Translate + + L"Only one hand can be used.\n", + L"Only one hand can be used.\nA medical splint was applied to speed up the healing process.\n", + L"Leg functionality severely limited.\n", + L"Leg functionality severely limited.\nA medical splint was applied to speed up the healing process.\n", }; STR16 szSpyText[] = diff --git a/Utils/_EnglishText.cpp b/Utils/_EnglishText.cpp index 8cce5ff8..8efc695a 100644 --- a/Utils/_EnglishText.cpp +++ b/Utils/_EnglishText.cpp @@ -7491,6 +7491,7 @@ STR16 New113Message[] = L"Yes*", L"Yes", L"No", + L"%s applied %s to %s.", }; STR16 New113HAMMessage[] = @@ -8491,6 +8492,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|R|e|s|i|s|t|a|n|t |t|o |F|i|r|e", L"|A|d|m|i|n|i|s|t|r|a|t|i|o|n |M|o|d|i|f|i|e|r", L"|H|a|c|k|i|n|g |M|o|d|i|f|i|e|r", + L"|M|e|d|i|c|a|l |S|p|l|i|n|t", }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -8543,6 +8545,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nThis armor lowers fire damage by %i%%.", L"\n \nThis item makes you more effective at\nadministrative work by %i%%.", L"\n \nThis item improves your hacking skills by %i%%.", + L"\n \nOnce applied, this item increases the healing\nspeed of severe wounds to either your arms or legs.", }; STR16 szUDBAdvStatsTooltipText[]= @@ -11127,6 +11130,11 @@ STR16 szDiseaseText[] = L"High amount of distress can cause a personality split\n", L"Contaminated items found in %s' inventory.\n", L"Whenever we get this, a new disability is added.\n", + + L"Only one hand can be used.\n", + L"Only one hand can be used.\nA medical splint was applied to speed up the healing process.\n", + L"Leg functionality severely limited.\n", + L"Leg functionality severely limited.\nA medical splint was applied to speed up the healing process.\n", }; STR16 szSpyText[] = diff --git a/Utils/_FrenchText.cpp b/Utils/_FrenchText.cpp index 8bd29f72..31b4af0b 100644 --- a/Utils/_FrenchText.cpp +++ b/Utils/_FrenchText.cpp @@ -7486,6 +7486,7 @@ STR16 New113Message[] = L"Yes*", L"Yes", L"No", + L"%s applied %s to %s.", // TODO.Translate }; STR16 New113HAMMessage[] = @@ -8480,6 +8481,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|R|e|s|i|s|t|a|n|t |t|o |F|i|r|e", L"|A|d|m|i|n|i|s|t|r|a|t|i|o|n |M|o|d|i|f|i|e|r", L"|H|a|c|k|i|n|g |M|o|d|i|f|i|e|r", + L"|M|e|d|i|c|a|l |S|p|l|i|n|t", // TODO.Translate }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -8532,6 +8534,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nThis armor lowers fire damage by %i%%.", L"\n \nThis item makes you more effective at\nadministrative work by %i%%.", L"\n \nThis item improves your hacking skills by %i%%.", + L"\n \nOnce applied, this item increases the healing\nspeed of severe wounds to either your arms or legs.", // TODO.Translate }; STR16 szUDBAdvStatsTooltipText[]= @@ -11111,6 +11114,11 @@ STR16 szDiseaseText[] = L"High amount of distress can cause a personality split\n", // TODO.Translate L"Contaminated items found in %s' inventory.\n", L"Whenever we get this, a new disability is added.\n", // TODO.Translate + + L"Only one hand can be used.\n", + L"Only one hand can be used.\nA medical splint was applied to speed up the healing process.\n", + L"Leg functionality severely limited.\n", + L"Leg functionality severely limited.\nA medical splint was applied to speed up the healing process.\n", }; STR16 szSpyText[] = diff --git a/Utils/_GermanText.cpp b/Utils/_GermanText.cpp index 2348050a..665c6c30 100644 --- a/Utils/_GermanText.cpp +++ b/Utils/_GermanText.cpp @@ -7313,6 +7313,7 @@ STR16 New113Message[] = L"Ja*", L"Ja", L"Nein", + L"%s applied %s to %s.", // TODO.Translate }; STR16 New113HAMMessage[] = @@ -8309,6 +8310,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|W|i|d|e|r|s|t|a|n|d|s|f|ä|h|i|g|k|e|i|t |g|e|g|e|n |F|e|u|e|r", L"|A|d|m|i|n|i|s|t|r|a|t|i|o|n |M|o|d|i|f|i|e|r", L"|H|a|c|k|i|n|g |M|o|d|i|f|i|e|r", + L"|M|e|d|i|c|a|l |S|p|l|i|n|t", // TODO.Translate }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -8361,6 +8363,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nThis armor lowers fire damage by %i%%.", L"\n \nThis item makes you more effective at\nadministrative work by %i%%.", L"\n \nThis item improves your hacking skills by %i%%.", + L"\n \nOnce applied, this item increases the healing\nspeed of severe wounds to either your arms or legs.", // TODO.Translate }; STR16 szUDBAdvStatsTooltipText[]= @@ -10941,6 +10944,11 @@ STR16 szDiseaseText[] = L"High amount of distress can cause a personality split\n", // TODO.Translate L"Contaminated items found in %s' inventory.\n", L"Whenever we get this, a new disability is added.\n", // TODO.Translate + + L"Only one hand can be used.\n", + L"Only one hand can be used.\nA medical splint was applied to speed up the healing process.\n", + L"Leg functionality severely limited.\n", + L"Leg functionality severely limited.\nA medical splint was applied to speed up the healing process.\n", }; STR16 szSpyText[] = diff --git a/Utils/_ItalianText.cpp b/Utils/_ItalianText.cpp index 5bf0fd0a..ed4b9c67 100644 --- a/Utils/_ItalianText.cpp +++ b/Utils/_ItalianText.cpp @@ -7480,6 +7480,7 @@ STR16 New113Message[] = L"Yes*", L"Yes", L"No", + L"%s applied %s to %s.", // TODO.Translate }; // TODO.Translate @@ -8483,6 +8484,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|R|e|s|i|s|t|a|n|t |t|o |F|i|r|e", L"|A|d|m|i|n|i|s|t|r|a|t|i|o|n |M|o|d|i|f|i|e|r", L"|H|a|c|k|i|n|g |M|o|d|i|f|i|e|r", + L"|M|e|d|i|c|a|l |S|p|l|i|n|t", // TODO.Translate }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -8535,6 +8537,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nThis armor lowers fire damage by %i%%.", L"\n \nThis item makes you more effective at\nadministrative work by %i%%.", L"\n \nThis item improves your hacking skills by %i%%.", + L"\n \nOnce applied, this item increases the healing\nspeed of severe wounds to either your arms or legs.", // TODO.Translate }; STR16 szUDBAdvStatsTooltipText[]= @@ -11120,6 +11123,11 @@ STR16 szDiseaseText[] = L"High amount of distress can cause a personality split\n", // TODO.Translate L"Contaminated items found in %s' inventory.\n", L"Whenever we get this, a new disability is added.\n", // TODO.Translate + + L"Only one hand can be used.\n", + L"Only one hand can be used.\nA medical splint was applied to speed up the healing process.\n", + L"Leg functionality severely limited.\n", + L"Leg functionality severely limited.\nA medical splint was applied to speed up the healing process.\n", }; STR16 szSpyText[] = diff --git a/Utils/_PolishText.cpp b/Utils/_PolishText.cpp index 4dd4ad8b..6be322c8 100644 --- a/Utils/_PolishText.cpp +++ b/Utils/_PolishText.cpp @@ -7489,6 +7489,7 @@ STR16 New113Message[] = L"Yes*", L"Yes", L"No", + L"%s applied %s to %s.", // TODO.Translate }; STR16 New113HAMMessage[] = @@ -8495,6 +8496,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|R|e|s|i|s|t|a|n|t |t|o |F|i|r|e", L"|A|d|m|i|n|i|s|t|r|a|t|i|o|n |M|o|d|i|f|i|e|r", L"|H|a|c|k|i|n|g |M|o|d|i|f|i|e|r", + L"|M|e|d|i|c|a|l |S|p|l|i|n|t", // TODO.Translate }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -8547,6 +8549,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nThis armor lowers fire damage by %i%%.", L"\n \nThis item makes you more effective at\nadministrative work by %i%%.", L"\n \nThis item improves your hacking skills by %i%%.", + L"\n \nOnce applied, this item increases the healing\nspeed of severe wounds to either your arms or legs.", // TODO.Translate }; STR16 szUDBAdvStatsTooltipText[]= @@ -11133,6 +11136,11 @@ STR16 szDiseaseText[] = L"High amount of distress can cause a personality split\n", // TODO.Translate L"Contaminated items found in %s' inventory.\n", L"Whenever we get this, a new disability is added.\n", // TODO.Translate + + L"Only one hand can be used.\n", + L"Only one hand can be used.\nA medical splint was applied to speed up the healing process.\n", + L"Leg functionality severely limited.\n", + L"Leg functionality severely limited.\nA medical splint was applied to speed up the healing process.\n", }; STR16 szSpyText[] = diff --git a/Utils/_RussianText.cpp b/Utils/_RussianText.cpp index 5c04d4fa..d96e07ca 100644 --- a/Utils/_RussianText.cpp +++ b/Utils/_RussianText.cpp @@ -7477,6 +7477,7 @@ STR16 New113Message[] = L"Yes*", L"Yes", L"No", + L"%s applied %s to %s.", // TODO.Translate }; STR16 New113HAMMessage[] = @@ -8477,6 +8478,7 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|R|e|s|i|s|t|a|n|t |t|o |F|i|r|e", L"|A|d|m|i|n|i|s|t|r|a|t|i|o|n |M|o|d|i|f|i|e|r", L"|H|a|c|k|i|n|g |M|o|d|i|f|i|e|r", + L"|M|e|d|i|c|a|l |S|p|l|i|n|t", // TODO.Translate }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -8529,6 +8531,7 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nThis armor lowers fire damage by %i%%.", L"\n \nThis item makes you more effective at\nadministrative work by %i%%.", L"\n \nThis item improves your hacking skills by %i%%.", + L"\n \nOnce applied, this item increases the healing\nspeed of severe wounds to either your arms or legs.", // TODO.Translate }; STR16 szUDBAdvStatsTooltipText[]= @@ -11113,6 +11116,11 @@ STR16 szDiseaseText[] = L"High amount of distress can cause a personality split\n", // TODO.Translate L"Contaminated items found in %s' inventory.\n", L"Whenever we get this, a new disability is added.\n", // TODO.Translate + + L"Only one hand can be used.\n", + L"Only one hand can be used.\nA medical splint was applied to speed up the healing process.\n", + L"Leg functionality severely limited.\n", + L"Leg functionality severely limited.\nA medical splint was applied to speed up the healing process.\n", }; STR16 szSpyText[] =