mirror of
https://github.com/1dot13/source.git
synced 2026-08-26 14:30:26 +02:00
A paramedic can use empty bloodbags (<emptybloodbag>-tag, item #1756) to create blood bags (<bloodbag>-tag, item #1757) from other mercs. These can then boost the health returned by surgery by ONTOP_PERCENT_SURGERY_HEAL_BLOODBAG percent.
Requires GameDir >= r2467. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8662 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -319,8 +319,10 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
|
||||
|
||||
if ( fFromUI && pSoldier->bTeam == gbPlayerNum && pTargetSoldier &&
|
||||
(pTargetSoldier->bTeam == gbPlayerNum || pTargetSoldier->aiData.bNeutral) && pTargetSoldier->ubBodyType != CROW &&
|
||||
Item[usHandItem].usItemClass != IC_MEDKIT && !Item[usHandItem].gascan &&
|
||||
!ItemCanBeAppliedToOthers( usHandItem ) )
|
||||
Item[usHandItem].usItemClass != IC_MEDKIT &&
|
||||
!Item[usHandItem].gascan &&
|
||||
!ItemCanBeAppliedToOthers( usHandItem ) &&
|
||||
!HasItemFlag( usHandItem, EMPTY_BLOOD_BAG ) )
|
||||
{
|
||||
if ( pSoldier->ubProfile != NO_PROFILE )
|
||||
{
|
||||
@@ -1525,6 +1527,86 @@ INT32 HandleItem( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bLevel, UINT16 usHa
|
||||
}
|
||||
}
|
||||
|
||||
// Flugente: apply misc items to other soldiers
|
||||
if ( HasItemFlag( usHandItem, EMPTY_BLOOD_BAG ) )
|
||||
{
|
||||
// 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 = GetAPsToFillBloodbag( 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_FILLBLOODBAG;
|
||||
|
||||
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_SoldierTakeBloodFromPerson( 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;
|
||||
@@ -5431,7 +5513,7 @@ void BombMessageBoxCallBack( UINT8 ubExitValue )
|
||||
|
||||
// Flugente: tripwire rolls are not planted - instead we spawn tripwire and plant that
|
||||
OBJECTTYPE* pObj = &(gpTempSoldier->inv[HANDPOS]);
|
||||
if ( Item[ gpTempSoldier->inv[ HANDPOS ].usItem ].usItemFlag & TRIPWIREROLL && Item[ gpTempSoldier->inv[ HANDPOS ].usItem ].usBuddyItem != NOTHING )
|
||||
if ( HasItemFlag( gpTempSoldier->inv[HANDPOS].usItem, TRIPWIREROLL ) && Item[ gpTempSoldier->inv[ HANDPOS ].usItem ].usBuddyItem != NOTHING )
|
||||
{
|
||||
(*pObj)[0]->data.objectStatus--;
|
||||
|
||||
@@ -5794,11 +5876,11 @@ void BoobyTrapDialogueCallBack( void )
|
||||
// now prompt the user...
|
||||
if( guiTacticalInterfaceFlags & INTERFACE_MAPSCREEN )
|
||||
{
|
||||
DoScreenIndependantMessageBox( TacticalStr[ DISARM_BOOBYTRAP_PROMPT ], ( UINT8 )MSG_BOX_FLAG_YESNO, BoobyTrapInMapScreenMessageBoxCallBack );
|
||||
DoScreenIndependantMessageBox( TacticalStr[ DISARM_BOOBYTRAP_PROMPT ], MSG_BOX_FLAG_YESNO, BoobyTrapInMapScreenMessageBoxCallBack );
|
||||
}
|
||||
else
|
||||
{
|
||||
DoScreenIndependantMessageBox( TacticalStr[ DISARM_BOOBYTRAP_PROMPT ], ( UINT8 )MSG_BOX_FLAG_YESNO, BoobyTrapMessageBoxCallBack );
|
||||
DoScreenIndependantMessageBox( TacticalStr[ DISARM_BOOBYTRAP_PROMPT ], MSG_BOX_FLAG_YESNO, BoobyTrapMessageBoxCallBack );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+87
-11
@@ -1157,10 +1157,10 @@ UINT32 UIHandleNewBadMerc( UI_EVENT *pUIEvent )
|
||||
return( GAME_SCREEN );
|
||||
}
|
||||
|
||||
usRandom = (UINT16)Random( 20 );
|
||||
usRandom = 12;// (UINT16)Random( 20 );
|
||||
if( usRandom < 5 )
|
||||
pSoldier = TacticalCreateAdministrator();
|
||||
else if( usRandom < 10 )
|
||||
else if( usRandom < 15 )
|
||||
pSoldier = TacticalCreateArmyTroop();
|
||||
else if ( usRandom < 12 )
|
||||
pSoldier = TacticalCreateEnemyTank( );
|
||||
@@ -2838,14 +2838,35 @@ void AttackRequesterCallback( UINT8 bExitValue )
|
||||
// SANDRO - added function
|
||||
void SurgeryRequesterCallback( UINT8 bExitValue )
|
||||
{
|
||||
if( bExitValue == MSG_BOX_RETURN_YES )
|
||||
if ( bExitValue == 1 || bExitValue == MSG_BOX_RETURN_YES )
|
||||
{
|
||||
//gpRequesterMerc->ubSurgeryApprovalMerc = gpRequesterTargetMerc->ubID;
|
||||
// Flugente: use up a blood bag if we've requested that and boost surgery
|
||||
if ( bExitValue == 1 )
|
||||
{
|
||||
OBJECTTYPE* pObj = gpRequesterMerc->GetObjectWithItemFlag( BLOOD_BAG );
|
||||
|
||||
if ( pObj )
|
||||
{
|
||||
// if object is infected, infect the victim
|
||||
if ( ( *pObj )[0]->data.sObjectFlag & INFECTED && gGameExternalOptions.fDiseaseContaminatesItems )
|
||||
gpRequesterTargetMerc->Infect( 0 );
|
||||
|
||||
pObj->RemoveObjectsFromStack( 1 );
|
||||
|
||||
if ( pObj->ubNumberOfObjects <= 0 )
|
||||
{
|
||||
DeleteObj( pObj );
|
||||
}
|
||||
|
||||
gpRequesterMerc->usSoldierFlagMask2 |= SOLDIER_SURGERY_BOOSTED;
|
||||
}
|
||||
}
|
||||
|
||||
gTacticalStatus.ubLastRequesterSurgeryTargetID = gpRequesterTargetMerc->ubID;
|
||||
|
||||
UIHandleMercAttack( gpRequesterMerc , gpRequesterTargetMerc, gsRequesterGridNo );
|
||||
}
|
||||
else if( bExitValue == MSG_BOX_RETURN_NO )
|
||||
else if( bExitValue == MSG_BOX_RETURN_NO || bExitValue == 4 )
|
||||
{
|
||||
gTacticalStatus.ubLastRequesterSurgeryTargetID = NOBODY;
|
||||
|
||||
@@ -2920,20 +2941,43 @@ UINT32 UIHandleCAMercShoot( UI_EVENT *pUIEvent )
|
||||
gsRequesterGridNo = usMapPos;
|
||||
|
||||
fDidRequester = TRUE;
|
||||
|
||||
INT32 healwithout_bloodbag = pTSoldier->iHealableInjury * ( gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ) ) / 10000;
|
||||
|
||||
// Flugente: if we wouldn't really heal anything due to the wound being too small, tell us so
|
||||
if ( !pTSoldier->bBleeding && ( pTSoldier->iHealableInjury * (gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT )) / 10000 ) <= 0 )
|
||||
if ( !pTSoldier->bBleeding && healwithout_bloodbag <= 0 )
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_UI_FEEDBACK, gzLateLocalizedString[19], pTSoldier->GetName( ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pTSoldier->bBleeding)
|
||||
swprintf( zStr, New113Message[ MSG113_DO_WE_WANT_SURGERY_FIRST ], pTSoldier->GetName(), (pTSoldier->iHealableInjury * (gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT )) / 10000) );
|
||||
else
|
||||
swprintf( zStr, New113Message[ MSG113_DO_WE_WANT_SURGERY ], pTSoldier->GetName(), (pTSoldier->iHealableInjury * (gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT )) / 10000) );
|
||||
// Flugente: check whether we have a bloodbag we can use
|
||||
INT32 healwith_bloodbag = -1;
|
||||
if ( gSkillTraitValues.ubDOSurgeryHealPercentBloodbag > 0 && pSoldier->GetObjectWithItemFlag( BLOOD_BAG ) != NULL )
|
||||
healwith_bloodbag = pTSoldier->iHealableInjury * ( gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentBloodbag + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ) ) / 10000;
|
||||
|
||||
DoMessageBox( MSG_BOX_BASIC_STYLE, zStr, GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, SurgeryRequesterCallback, NULL );
|
||||
if ( healwith_bloodbag > healwithout_bloodbag )
|
||||
{
|
||||
if ( pTSoldier->bBleeding )
|
||||
swprintf( zStr, New113Message[MSG113_DO_WE_WANT_SURGERY_FIRST_BLOODBAG], pTSoldier->GetName(), healwithout_bloodbag, healwith_bloodbag );
|
||||
else
|
||||
swprintf( zStr, New113Message[MSG113_DO_WE_WANT_SURGERY_BLOODBAG], pTSoldier->GetName(), healwithout_bloodbag, healwith_bloodbag );
|
||||
|
||||
wcscpy( gzUserDefinedButton[0], L"Yes*" );
|
||||
wcscpy( gzUserDefinedButton[1], L"Yes" );
|
||||
wcscpy( gzUserDefinedButton[2], L"No" );
|
||||
wcscpy( gzUserDefinedButton[3], L"No" );
|
||||
DoMessageBox( MSG_BOX_BASIC_SMALL_BUTTONS, zStr, GAME_SCREEN, (MSG_BOX_FLAG_GENERIC_FOUR_BUTTONS| MSG_BOX_BUTTONS_HORIZONTAL_ORIENTATION), SurgeryRequesterCallback, NULL );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( pTSoldier->bBleeding )
|
||||
swprintf( zStr, New113Message[MSG113_DO_WE_WANT_SURGERY_FIRST], pTSoldier->GetName(), healwithout_bloodbag );
|
||||
else
|
||||
swprintf( zStr, New113Message[MSG113_DO_WE_WANT_SURGERY], pTSoldier->GetName(), healwithout_bloodbag );
|
||||
|
||||
DoMessageBox( MSG_BOX_BASIC_STYLE, zStr, GAME_SCREEN, (UINT8)MSG_BOX_FLAG_YESNO, SurgeryRequesterCallback, NULL );
|
||||
}
|
||||
}
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -4541,6 +4585,24 @@ INT8 DrawUIMovementPath( SOLDIERTYPE *pSoldier, INT32 usMapPos, UINT32 uiFlags )
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( uiFlags == MOVEUI_TARGET_BLOODBAG )
|
||||
{
|
||||
sActionGridNo = FindAdjacentGridEx( pSoldier, usMapPos, &ubDirection, NULL, FALSE, TRUE );
|
||||
if ( sActionGridNo == -1 )
|
||||
{
|
||||
sActionGridNo = usMapPos;
|
||||
}
|
||||
|
||||
sAPCost = GetAPsToFillBloodbag( pSoldier, sActionGridNo );
|
||||
|
||||
sAPCost += UIPlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, fPlot, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints );
|
||||
|
||||
if ( sActionGridNo != pSoldier->sGridNo )
|
||||
{
|
||||
gfUIHandleShowMoveGrid = TRUE;
|
||||
gsUIHandleShowMoveGridLocation = sActionGridNo;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
sAPCost += UIPlotPath( pSoldier, sActionGridNo, NO_COPYROUTE, fPlot, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints );
|
||||
@@ -4737,6 +4799,20 @@ BOOLEAN UIMouseOnValidAttackLocation( SOLDIERTYPE *pSoldier )
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( ubItemCursor == BLOODBAGCURS )
|
||||
{
|
||||
if ( HasItemFlag( ( &( pSoldier->inv[HANDPOS] ) )->usItem, EMPTY_BLOOD_BAG ) )
|
||||
{
|
||||
if ( gfUIFullTargetFound )
|
||||
{
|
||||
if ( pSoldier->ubID != gusUIFullTargetID && MercPtrs[gusUIFullTargetID]->IsValidBloodDonor() )
|
||||
return( TRUE );
|
||||
}
|
||||
}
|
||||
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
if ( ubItemCursor == APPLYITEMCURS )
|
||||
{
|
||||
if ( ItemCanBeAppliedToOthers( (&(pSoldier->inv[HANDPOS]))->usItem ) )
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#define MOVEUI_TARGET_HANDCUFF 14
|
||||
#define MOVEUI_TARGET_APPLYITEM 15
|
||||
#define MOVEUI_TARGET_INTERACTIVEACTION 16
|
||||
#define MOVEUI_TARGET_BLOODBAG 17
|
||||
|
||||
#define MOVEUI_RETURN_ON_TARGET_MERC 1
|
||||
|
||||
|
||||
@@ -235,6 +235,9 @@ UICursor gUICursors[ NUM_UI_CURSORS ] =
|
||||
|
||||
CAMERA_GREY_UICURSOR, UICURSOR_FREEFLOWING, CURSOR_CAMERA, 0,
|
||||
CAMERA_RED_UICURSOR, UICURSOR_FREEFLOWING, CURSOR_CAMERA_RED, 0,
|
||||
|
||||
BLOODBAG_GREY_UICURSOR, UICURSOR_FREEFLOWING, CURSOR_BLOODBAG, 0,
|
||||
BLOODBAG_RED_UICURSOR, UICURSOR_FREEFLOWING, CURSOR_BLOODBAG_RED, 0,
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -213,6 +213,9 @@ typedef enum
|
||||
CAMERA_GREY_UICURSOR,
|
||||
CAMERA_RED_UICURSOR,
|
||||
|
||||
BLOODBAG_GREY_UICURSOR,
|
||||
BLOODBAG_RED_UICURSOR,
|
||||
|
||||
NUM_UI_CURSORS
|
||||
|
||||
} UICursorDefines;
|
||||
|
||||
@@ -2729,7 +2729,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
|
||||
MSYS_EnableRegion( &gUDBFasthelpRegions[iFirstDataRegion + cnt] );
|
||||
++cnt;
|
||||
}
|
||||
|
||||
|
||||
//////////////////// BURIAL MODIFIER
|
||||
if ( Item[gpItemDescObject->usItem].usBurialModifier )
|
||||
{
|
||||
@@ -2738,6 +2738,24 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr
|
||||
MSYS_EnableRegion( &gUDBFasthelpRegions[iFirstDataRegion + cnt] );
|
||||
++cnt;
|
||||
}
|
||||
|
||||
//////////////////// EMPTY BLOOD BAG
|
||||
if ( HasItemFlag( gpItemDescObject->usItem, EMPTY_BLOOD_BAG ) )
|
||||
{
|
||||
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[43], szUDBGenSecondaryStatsExplanationsTooltipText[43] );
|
||||
SetRegionFastHelpText( &( gUDBFasthelpRegions[iFirstDataRegion + cnt] ), pStr );
|
||||
MSYS_EnableRegion( &gUDBFasthelpRegions[iFirstDataRegion + cnt] );
|
||||
++cnt;
|
||||
}
|
||||
|
||||
//////////////////// BLOOD BAG
|
||||
if ( HasItemFlag( gpItemDescObject->usItem, BLOOD_BAG ) )
|
||||
{
|
||||
swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[44], szUDBGenSecondaryStatsExplanationsTooltipText[44] );
|
||||
SetRegionFastHelpText( &( gUDBFasthelpRegions[iFirstDataRegion + cnt] ), pStr );
|
||||
MSYS_EnableRegion( &gUDBFasthelpRegions[iFirstDataRegion + cnt] );
|
||||
++cnt;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
@@ -6334,7 +6352,7 @@ void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject )
|
||||
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 39, gItemDescGenSecondaryRegions[cnt].sLeft + sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
|
||||
cnt++;
|
||||
}
|
||||
|
||||
|
||||
//////////////////// BURIAL MODIFIER
|
||||
if ( ( Item[gpItemDescObject->usItem].usBurialModifier && !fComparisonMode ) ||
|
||||
( fComparisonMode && Item[gpComparedItemDescObject->usItem].usBurialModifier ) )
|
||||
@@ -6342,6 +6360,22 @@ void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject )
|
||||
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 40, gItemDescGenSecondaryRegions[cnt].sLeft + sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
|
||||
cnt++;
|
||||
}
|
||||
|
||||
//////////////////// EMPTY BLOOD BAG
|
||||
if ( ( HasItemFlag( gpItemDescObject->usItem, EMPTY_BLOOD_BAG ) && !fComparisonMode ) ||
|
||||
( fComparisonMode && HasItemFlag( gpComparedItemDescObject->usItem, EMPTY_BLOOD_BAG ) ) )
|
||||
{
|
||||
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 41, gItemDescGenSecondaryRegions[cnt].sLeft + sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL );
|
||||
++cnt;
|
||||
}
|
||||
|
||||
//////////////////// BLOOD BAG
|
||||
if ( ( HasItemFlag( gpItemDescObject->usItem, BLOOD_BAG ) && !fComparisonMode ) ||
|
||||
( fComparisonMode && HasItemFlag( gpComparedItemDescObject->usItem, BLOOD_BAG ) ) )
|
||||
{
|
||||
BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 42, 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 )
|
||||
|
||||
@@ -178,6 +178,7 @@ typedef enum ATTACHMENT_SLOT{
|
||||
#define HANDCUFFCURS 25
|
||||
#define APPLYITEMCURS 26
|
||||
#define INTERACTIVEACTIONCURS 27
|
||||
#define BLOODBAGCURS 28
|
||||
|
||||
#define CAMERARANGE 10
|
||||
|
||||
@@ -734,7 +735,7 @@ extern OBJECTTYPE gTempObject;
|
||||
// -------- added by Flugente: various item flags --------
|
||||
// flags used for various item properties (easier than adding 32 differently named variables). DO NOT CHANGE THEM, UNLESS YOU KNOW WHAT YOU ARE DOING!!!
|
||||
// note that these should not be used to determine what kind of an attachment an item is, that is determined by attachmentclass and the AC_xxx flags above
|
||||
//#define EMPTY_SANDBAG 0x00000001 //1
|
||||
#define BLOOD_BAG 0x00000001 //1 // this item is a blood bag can can be used to boost surgery
|
||||
#define MANPAD 0x00000002 //2 // this item is a MAn-Portable Air-Defense System
|
||||
#define BEARTRAP 0x00000004 //4 // a mechanical trap that does no explosion, but causes leg damage to whoever activates it
|
||||
#define CAMERA 0x00000008 //8
|
||||
@@ -773,6 +774,10 @@ extern OBJECTTYPE gTempObject;
|
||||
#define DISEASEPROTECTION_1 0x20000000 //536870912 // this item protects us from getting diseases by human contact if kept in inventory
|
||||
#define DISEASEPROTECTION_2 0x40000000 //1073741824 // this item protects us from getting diseases by human contact if kept in inventory
|
||||
#define LBE_EXPLOSIONPROOF 0x80000000 //2147483648 // any gear in LBE with this flag is protected from explosions
|
||||
|
||||
// extended flagmask to UINT64
|
||||
#define EMPTY_BLOOD_BAG 0x0000000100000000 // this item is a empty blood bag
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
|
||||
// -------- added by Flugente: flags for objects --------
|
||||
@@ -1133,7 +1138,7 @@ typedef struct
|
||||
|
||||
BOOLEAN blockironsight; // if a gun or any attachment have this property, the iron sight won't be usable (if there is at least one other usable sight)
|
||||
|
||||
UINT32 usItemFlag; // bitflags to store various item properties (better than introducing 32 BOOLEAN values). If I only had thought of this earlier....
|
||||
UINT64 usItemFlag; // bitflags to store various item properties (better than introducing 32 BOOLEAN values). If I only had thought of this earlier....
|
||||
|
||||
// Flugente: food type
|
||||
UINT32 foodtype;
|
||||
|
||||
+4
-4
@@ -5324,7 +5324,7 @@ BOOLEAN OBJECTTYPE::AttachObjectNAS( SOLDIERTYPE * pSoldier, OBJECTTYPE * pAttac
|
||||
case TRIPWIRE_ROLL:
|
||||
{
|
||||
// check if this can work
|
||||
if ( Item[ this->usItem ].tripwire && Item[pAttachment->usItem].tripwire && Item[ this->usItem ].usItemFlag == TRIPWIREROLL )
|
||||
if ( Item[ this->usItem ].tripwire && Item[pAttachment->usItem].tripwire && HasItemFlag( this->usItem, TRIPWIREROLL ) )
|
||||
{
|
||||
if ( (*this)[subObject]->data.objectStatus < 100 )
|
||||
(*this)[subObject]->data.objectStatus++;
|
||||
@@ -5509,7 +5509,7 @@ BOOLEAN OBJECTTYPE::AttachObjectNAS( SOLDIERTYPE * pSoldier, OBJECTTYPE * pAttac
|
||||
(*this)[subObject]->data.objectStatus = ((*this)[subObject]->data.objectStatus + (*pAttachment)[0]->data.objectStatus) / 2;
|
||||
|
||||
// Flugente: if the new item has the TRIPWIREROLL property, it only gets status 2 upon creation via merges
|
||||
if ( Item[ this->usItem ].usItemFlag == TRIPWIREROLL )
|
||||
if ( HasItemFlag( this->usItem, TRIPWIREROLL ) )
|
||||
{
|
||||
(*this)[subObject]->data.objectStatus = 2;
|
||||
}
|
||||
@@ -14927,13 +14927,13 @@ void CheckBombSpecifics( OBJECTTYPE * pObj, INT8* detonatortype, INT8* setting,
|
||||
}
|
||||
|
||||
// Flugente: check for specific flags
|
||||
BOOLEAN HasItemFlag( UINT16 usItem, UINT32 aFlag )
|
||||
BOOLEAN HasItemFlag( UINT16 usItem, UINT64 aFlag )
|
||||
{
|
||||
return( (Item[usItem].usItemFlag & aFlag) != 0 );
|
||||
}
|
||||
|
||||
// Flugente: get first item number that has this flag. Use with caution, as we search in all items
|
||||
BOOLEAN GetFirstItemWithFlag( UINT16* pusItem, UINT32 aFlag )
|
||||
BOOLEAN GetFirstItemWithFlag( UINT16* pusItem, UINT64 aFlag )
|
||||
{
|
||||
register UINT16 i;
|
||||
for ( i = 1; i < gMAXITEMS_READ; ++i )
|
||||
|
||||
+2
-2
@@ -479,10 +479,10 @@ UINT64 GetAvailableAttachmentPoint ( OBJECTTYPE * pObject, UINT8 subObject );
|
||||
void CheckBombSpecifics( OBJECTTYPE * pObj, INT8* detonatortype, INT8* setting, INT8* defusefrequency );
|
||||
|
||||
// Flugente: check for specific flags
|
||||
BOOLEAN HasItemFlag( UINT16 usItem, UINT32 aFlag );
|
||||
BOOLEAN HasItemFlag( UINT16 usItem, UINT64 aFlag );
|
||||
|
||||
// Flugente: get first item number that has this flag. Use with caution, as we search in all items
|
||||
BOOLEAN GetFirstItemWithFlag( UINT16* pusItem, UINT32 aFlag );
|
||||
BOOLEAN GetFirstItemWithFlag( UINT16* pusItem, UINT64 aFlag );
|
||||
|
||||
// Flugente: check if this object is currently fed from an external source (belts in inventory, other mercs)
|
||||
BOOLEAN ObjectIsBeingFedExternal(SOLDIERTYPE* pSoldier, OBJECTTYPE * pObject);
|
||||
|
||||
@@ -1567,7 +1567,12 @@ BOOLEAN ExecuteOverhead( )
|
||||
pSoldier->EVENT_SoldierInteractiveAction( pSoldier->aiData.sPendingActionData2, pSoldier->aiData.bPendingActionData3 );
|
||||
pSoldier->aiData.ubPendingAction = NO_PENDING_ACTION;
|
||||
}
|
||||
|
||||
else if ( pSoldier->aiData.ubPendingAction == MERC_FILLBLOODBAG )
|
||||
{
|
||||
pSoldier->EVENT_SoldierTakeBloodFromPerson( pSoldier->aiData.sPendingActionData2, pSoldier->aiData.bPendingActionData3 );
|
||||
pSoldier->aiData.ubPendingAction = NO_PENDING_ACTION;
|
||||
}
|
||||
|
||||
if ( fNoAPsForPendingAction )
|
||||
{
|
||||
// Change status of guy to waiting
|
||||
|
||||
@@ -4111,6 +4111,17 @@ INT16 GetAPsToApplyItem( SOLDIERTYPE *pSoldier, INT32 usMapPos )
|
||||
return sAPCost;
|
||||
}
|
||||
|
||||
INT16 GetAPsToFillBloodbag( SOLDIERTYPE *pSoldier, INT32 usMapPos )
|
||||
{
|
||||
INT16 sAPCost = 0;
|
||||
|
||||
sAPCost = PlotPath( pSoldier, usMapPos, NO_COPYROUTE, NO_PLOT, TEMPORARY, (UINT16)pSoldier->usUIMovementMode, NOT_STEALTH, FORWARD, pSoldier->bActionPoints );
|
||||
|
||||
sAPCost += APBPConstants[AP_FILLBLOODBAG];
|
||||
|
||||
return sAPCost;
|
||||
}
|
||||
|
||||
// added by Flugente
|
||||
INT16 GetAPsForMultiTurnAction( SOLDIERTYPE *pSoldier, UINT8 usActionType )
|
||||
{
|
||||
|
||||
+1
-1
@@ -350,10 +350,10 @@ INT16 GetBPsToStealItem( SOLDIERTYPE *pSoldier );
|
||||
|
||||
INT16 GetAPsToUseJar( SOLDIERTYPE *pSoldier, INT32 usMapPos );
|
||||
INT16 GetAPsToUseCan( SOLDIERTYPE *pSoldier, INT32 usMapPos );
|
||||
INT16 GetBPsTouseJar( SOLDIERTYPE *pSoldier );
|
||||
|
||||
INT16 GetAPsToHandcuff( SOLDIERTYPE *pSoldier, INT32 usMapPos ); // added by Flugente
|
||||
INT16 GetAPsToApplyItem( SOLDIERTYPE *pSoldier, INT32 usMapPos ); // added by Flugente
|
||||
INT16 GetAPsToFillBloodbag( SOLDIERTYPE *pSoldier, INT32 usMapPos ); // added by Flugente
|
||||
INT16 GetAPsForMultiTurnAction( SOLDIERTYPE *pSoldier, UINT8 usActionType ); // added by Flugente
|
||||
|
||||
INT16 GetAPsForInteractiveAction( SOLDIERTYPE *pSoldier, UINT8 usActionType ); // added by Flugente
|
||||
|
||||
@@ -13315,7 +13315,10 @@ UINT32 SOLDIERTYPE::SoldierDressWound( SOLDIERTYPE *pVictim, INT16 sKitPts, INT1
|
||||
// this means the rest of HPs will remain as "unhealable", the patient will miss X HPs but has no HealableInjury on self..
|
||||
if ( ubPtsLeft >= (pVictim->iHealableInjury / 100) )
|
||||
{
|
||||
usLifeReturned = pVictim->iHealableInjury * (gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( this, DOCTOR_NT )) / 100;
|
||||
if ( this->usSoldierFlagMask2 & SOLDIER_SURGERY_BOOSTED )
|
||||
usLifeReturned = pVictim->iHealableInjury * ( gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentBloodbag + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( this, DOCTOR_NT ) ) / 100;
|
||||
else
|
||||
usLifeReturned = pVictim->iHealableInjury * (gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( this, DOCTOR_NT )) / 100;
|
||||
|
||||
pVictim->iHealableInjury = 0;
|
||||
//CHRISL: Why would we arbitrarily use all ubPtsLeft when a victim isn't bleeding? And why would the medical bag, which we have to use in order to
|
||||
@@ -13352,7 +13355,10 @@ UINT32 SOLDIERTYPE::SoldierDressWound( SOLDIERTYPE *pVictim, INT16 sKitPts, INT1
|
||||
}
|
||||
else
|
||||
{
|
||||
usLifeReturned = ubPtsLeft * (gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( this, DOCTOR_NT ));
|
||||
if ( this->usSoldierFlagMask2 & SOLDIER_SURGERY_BOOSTED )
|
||||
usLifeReturned = ubPtsLeft * ( gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentBloodbag + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( this, DOCTOR_NT ) );
|
||||
else
|
||||
usLifeReturned = ubPtsLeft * (gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( this, DOCTOR_NT ));
|
||||
|
||||
pVictim->iHealableInjury -= (ubPtsLeft * 100);
|
||||
ubPtsLeft = 0;
|
||||
@@ -13547,6 +13553,8 @@ void SOLDIERTYPE::InternalReceivingSoldierCancelServices( BOOLEAN fPlayEndAnim )
|
||||
// Flugente: additional dialogue
|
||||
AdditionalTacticalCharacterDialogue_CallsLua( pTSoldier, ADE_BANDAGE_PERFORM_END, this->ubProfile );
|
||||
AdditionalTacticalCharacterDialogue_CallsLua( this, ADE_BANDAGE_RECEIVE_END, pTSoldier->ubProfile );
|
||||
|
||||
pTSoldier->usSoldierFlagMask2 &= ~SOLDIER_SURGERY_BOOSTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15159,7 +15167,7 @@ BOOLEAN SOLDIERTYPE::IsFeedingExternal( UINT8* pubId1, UINT16* pGunSlot1, UINT1
|
||||
}
|
||||
|
||||
// Flugente: return first found object with a specific flag from our inventory
|
||||
OBJECTTYPE* SOLDIERTYPE::GetObjectWithFlag( UINT32 aFlag )
|
||||
OBJECTTYPE* SOLDIERTYPE::GetObjectWithFlag( UINT64 aFlag )
|
||||
{
|
||||
OBJECTTYPE* pObj = NULL;
|
||||
|
||||
@@ -20099,6 +20107,87 @@ void SOLDIERTYPE::DrugAutoUse()
|
||||
}
|
||||
}
|
||||
|
||||
OBJECTTYPE* SOLDIERTYPE::GetObjectWithItemFlag( UINT64 aFlag )
|
||||
{
|
||||
for ( INT8 bLoop = 0, invsize = (INT8)inv.size(); bLoop < invsize; ++bLoop )
|
||||
{
|
||||
if ( inv[bLoop].exists() )
|
||||
{
|
||||
OBJECTTYPE* pObj = &( inv[bLoop] );
|
||||
|
||||
if ( pObj && HasItemFlag( pObj->usItem, aFlag ) )
|
||||
{
|
||||
return pObj;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SOLDIERTYPE::DestroyOneObjectWithItemFlag( UINT64 aFlag )
|
||||
{
|
||||
for ( INT8 bLoop = 0, invsize = (INT8)inv.size(); bLoop < invsize; ++bLoop )
|
||||
{
|
||||
if ( inv[bLoop].exists() )
|
||||
{
|
||||
OBJECTTYPE* pObj = &( inv[bLoop] );
|
||||
|
||||
if ( pObj && HasItemFlag( pObj->usItem, aFlag ) )
|
||||
{
|
||||
pObj->RemoveObjectsFromStack( 1 );
|
||||
|
||||
if ( pObj->ubNumberOfObjects <= 0 )
|
||||
{
|
||||
DeleteObj( pObj );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define BLOODDONATION_AMOUNT 10
|
||||
|
||||
// Flugente: can we fill a blood bag from this guy?
|
||||
BOOLEAN SOLDIERTYPE::IsValidBloodDonor()
|
||||
{
|
||||
// not during combat
|
||||
if ( gTacticalStatus.uiFlags & INCOMBAT )
|
||||
return FALSE;
|
||||
|
||||
// must be player team
|
||||
if ( this->bTeam != gbPlayerNum )
|
||||
return FALSE;
|
||||
|
||||
// not if wounded
|
||||
if ( this->stats.bLife < this->stats.bLifeMax )
|
||||
return FALSE;
|
||||
|
||||
// not if doing so would drop us into coma
|
||||
if ( this->stats.bLife - BLOODDONATION_AMOUNT < OKLIFE )
|
||||
return FALSE;
|
||||
|
||||
// not if we have any KNOWN disease
|
||||
if ( this->HasDisease( TRUE, FALSE ) )
|
||||
return FALSE;
|
||||
|
||||
// not if we're drunk or drugged
|
||||
if ( MercDruggedOrDrunk( this ) )
|
||||
return FALSE;
|
||||
|
||||
// need to be properly fed and watered
|
||||
if ( UsingFoodSystem() )
|
||||
{
|
||||
UINT8 foodsituation;
|
||||
UINT8 watersituation;
|
||||
GetFoodSituation( this, &foodsituation, &watersituation );
|
||||
if ( foodsituation > FOOD_NORMAL || watersituation > FOOD_NORMAL )
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
INT32 CheckBleeding( SOLDIERTYPE *pSoldier )
|
||||
{
|
||||
INT8 bBandaged; //,savedOurTurn;
|
||||
@@ -21200,6 +21289,77 @@ void SOLDIERTYPE::EVENT_SoldierApplyItemToPerson( INT32 sGridNo, UINT8 ubDirecti
|
||||
}
|
||||
}
|
||||
|
||||
void SOLDIERTYPE::EVENT_SoldierTakeBloodFromPerson( 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, EMPTY_BLOOD_BAG ) && pSoldier->IsValidBloodDonor() )
|
||||
{
|
||||
// delete empty blood bag
|
||||
DeleteObj( pObj );
|
||||
|
||||
// create full blood bag
|
||||
static UINT16 bloodbagitem = 1757;
|
||||
|
||||
if ( HasItemFlag( bloodbagitem, BLOOD_BAG ) || GetFirstItemWithFlag( &bloodbagitem, BLOOD_BAG ) )
|
||||
{
|
||||
CreateItem( bloodbagitem, 100, &gTempObject );
|
||||
|
||||
// Flugente: if this guy has the disease, infect object
|
||||
if ( pSoldier->sDiseasePoints[0] > 0 )
|
||||
gTempObject[0]->data.sObjectFlag |= INFECTED;
|
||||
|
||||
if ( !AutoPlaceObject( this, &gTempObject, FALSE ) )
|
||||
AddItemToPool( pSoldier->sGridNo, &gTempObject, VISIBLE, this->pathing.bLevel, 0, -1 );
|
||||
|
||||
// wound the donor
|
||||
// we don't want the health loss taken to be healable by surgery (how would surgery restore that), so reset it afterwards
|
||||
INT32 healableinjury_tmp = pSoldier->iHealableInjury;
|
||||
INT8 bleeding_tmp = pSoldier->bBleeding;
|
||||
|
||||
// we need to set attacker as NOBODY, otherwise this calls dialogue events. This can be justified since they 'volunteered' for this
|
||||
pSoldier->SoldierTakeDamage( 0, BLOODDONATION_AMOUNT, 0, TAKE_DAMAGE_BLOODLOSS, NOBODY, sGridNo, 0, TRUE );
|
||||
|
||||
pSoldier->iHealableInjury = healableinjury_tmp;
|
||||
pSoldier->bBleeding = bleeding_tmp;
|
||||
|
||||
DeductPoints( this, GetAPsToFillBloodbag( this, sGridNo ), APBPConstants[BP_FILLBLOODBAG], AFTERACTION_INTERRUPT );
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Error: no blood bag item found in Items.xml!" );
|
||||
}
|
||||
}
|
||||
|
||||
// Say NOTHING quote...
|
||||
this->DoMercBattleSound( BATTLE_SOUND_NOTHING );
|
||||
}
|
||||
else
|
||||
{
|
||||
// if this is bomb, but nobody is there, plant the bomb instead
|
||||
OBJECTTYPE* pObj = &( this->inv[HANDPOS] );
|
||||
|
||||
if ( pObj->exists() )
|
||||
{
|
||||
UINT16 usItem = pObj->usItem;
|
||||
|
||||
if ( Item[usItem].usItemClass == IC_BOMB )
|
||||
{
|
||||
this->EVENT_SoldierBeginDropBomb();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SOLDIERTYPE::EVENT_SoldierInteractiveAction( INT32 sGridNo, UINT16 usActionType )
|
||||
{
|
||||
DoInteractiveAction( sGridNo, this );
|
||||
@@ -23782,7 +23942,10 @@ UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OB
|
||||
// this means the rest of HPs will remain as "unhealable", the patient will miss X HPs but has no HealableInjury on self..
|
||||
if ( bPtsLeft >= (pVictim->iHealableInjury / 100) )
|
||||
{
|
||||
iLifeReturned = pVictim->iHealableInjury * (gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT )) / 100;
|
||||
if ( pSoldier->usSoldierFlagMask2 & SOLDIER_SURGERY_BOOSTED )
|
||||
iLifeReturned = pVictim->iHealableInjury * ( gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentBloodbag + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ) ) / 100;
|
||||
else
|
||||
iLifeReturned = pVictim->iHealableInjury * ( gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ) ) / 100;
|
||||
|
||||
pVictim->iHealableInjury = 0;
|
||||
// keep the rest of the points to bandaging if neccessary
|
||||
@@ -23806,7 +23969,10 @@ UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OB
|
||||
}
|
||||
else
|
||||
{
|
||||
iLifeReturned = bPtsLeft * (gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ));
|
||||
if ( pSoldier->usSoldierFlagMask2 & SOLDIER_SURGERY_BOOSTED )
|
||||
iLifeReturned = bPtsLeft * (gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentBloodbag + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ));
|
||||
else
|
||||
iLifeReturned = bPtsLeft * ( gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ) );
|
||||
|
||||
pVictim->iHealableInjury -= (bPtsLeft * 100);
|
||||
bPtsLeft = 0;
|
||||
|
||||
@@ -232,6 +232,7 @@ enum
|
||||
MERC_HANDCUFF_PERSON,
|
||||
MERC_APPLYITEM,
|
||||
MERC_INTERACTIVEACTION,
|
||||
MERC_FILLBLOODBAG,
|
||||
};
|
||||
|
||||
// ENUMERATIONS FOR THROW ACTIONS
|
||||
@@ -418,7 +419,8 @@ enum
|
||||
#define SOLDIER_CONCEALINSERTION 0x00008000 // we enteri a sector by transition from concealed state (which causes us to spawn at the location we left the sector in)
|
||||
|
||||
#define SOLDIER_CONCEALINSERTION_DISCOVERED 0x00010000 // we enter a sector by transition from concealed state, but as we were 'discovered', set red alert
|
||||
#define SOLDIER_MERC_POW_LOCATIONKNOWN 0x00020000 // we are a POW, but the player has discovered our location
|
||||
#define SOLDIER_MERC_POW_LOCATIONKNOWN 0x00020000 // we are a POW, but the player has discovered our location
|
||||
#define SOLDIER_SURGERY_BOOSTED 0x00040000 // we are a boosted performing surgery (e.g. by using up a blood bag)
|
||||
|
||||
#define SOLDIER_INTERROGATE_ALL 0x000001F8 // all interrogation flags
|
||||
// ----------------------------------------------------------------
|
||||
@@ -1658,6 +1660,7 @@ public:
|
||||
void EVENT_SoldierBuildStructure( INT32 sGridNo, UINT8 ubDirection ); // added by Flugente
|
||||
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_SoldierInteractiveAction( INT32 sGridNo, UINT16 usActionType ); // added by Flugente
|
||||
|
||||
BOOLEAN EVENT_InternalGetNewSoldierPath( INT32 sDestGridNo, UINT16 usMovementAnim, BOOLEAN fFromUI, BOOLEAN fForceRestart );
|
||||
@@ -1795,7 +1798,7 @@ public:
|
||||
BOOLEAN IsFeedingExternal(UINT8* pubId1, UINT16* pGunSlot1, UINT16* pAmmoSlot1, UINT8* pubId2, UINT16* pGunSlot2, UINT16* pAmmoSlot2);
|
||||
|
||||
// Flugente: return first found object with a specific flag from our inventory
|
||||
OBJECTTYPE* GetObjectWithFlag( UINT32 aFlag );
|
||||
OBJECTTYPE* GetObjectWithFlag( UINT64 aFlag );
|
||||
|
||||
// Flugente: functions for the covert ops trait
|
||||
|
||||
@@ -1992,6 +1995,12 @@ public:
|
||||
|
||||
void StopChatting();
|
||||
void DrugAutoUse();
|
||||
|
||||
OBJECTTYPE* GetObjectWithItemFlag( UINT64 aFlag );
|
||||
void DestroyOneObjectWithItemFlag( UINT64 aFlag );
|
||||
|
||||
// Flugente: can we fill a blood bag from this guy ?
|
||||
BOOLEAN IsValidBloodDonor();
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
}; // SOLDIERTYPE;
|
||||
|
||||
@@ -52,6 +52,7 @@ UINT8 HandleRepairCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT32 uiCursorF
|
||||
UINT8 HandleRefuelCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, UINT32 uiCursorFlags );
|
||||
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 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 );
|
||||
@@ -283,6 +284,10 @@ UINT8 GetProperItemCursor( UINT8 ubSoldierID, UINT16 ubItemIndex, INT32 usMapPos
|
||||
ubCursorID = HandleCameraCursor( pSoldier, sTargetGridNo, fActivated, uiCursorFlags );
|
||||
break;
|
||||
|
||||
case BLOODBAGCURS:
|
||||
ubCursorID = HandleBloodbagCursor( pSoldier, sTargetGridNo, fActivated, uiCursorFlags );
|
||||
break;
|
||||
|
||||
case REMOTECURS:
|
||||
|
||||
ubCursorID = HandleRemoteCursor( pSoldier, sTargetGridNo, fActivated, uiCursorFlags );
|
||||
@@ -2203,6 +2208,25 @@ UINT8 HandleCameraCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fActivat
|
||||
return CAMERA_RED_UICURSOR;
|
||||
}
|
||||
|
||||
UINT8 HandleBloodbagCursor( 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, EMPTY_BLOOD_BAG ) )
|
||||
{
|
||||
// is there a person here?
|
||||
UINT8 usSoldierIndex = WhoIsThere2( sGridNo, pSoldier->pathing.bLevel );
|
||||
if ( usSoldierIndex != NOBODY )
|
||||
{
|
||||
if ( usSoldierIndex != pSoldier->ubID && MercPtrs[usSoldierIndex]->IsValidBloodDonor() )
|
||||
return BLOODBAG_GREY_UICURSOR;
|
||||
}
|
||||
}
|
||||
|
||||
return BLOODBAG_RED_UICURSOR;
|
||||
}
|
||||
|
||||
UINT8 HandleBombCursor( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN fActivated, UINT32 uiCursorFlags )
|
||||
{
|
||||
|
||||
@@ -2869,6 +2893,10 @@ UINT8 GetActionModeCursor( SOLDIERTYPE *pSoldier )
|
||||
if ( HasItemFlag( usInHand, CAMERA ) )
|
||||
ubCursor = CAMERACURS;
|
||||
|
||||
// Flugente: blood bag cursor
|
||||
if ( HasItemFlag( usInHand, EMPTY_BLOOD_BAG ) )
|
||||
ubCursor = BLOODBAGCURS;
|
||||
|
||||
// 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
|
||||
|
||||
Reference in New Issue
Block a user