mirror of
https://github.com/1dot13/source.git
synced 2026-07-29 13:52:17 +02:00
If ALLOW_BANDAGING_DURING_TRAVEL is set to TRUE, travelling mercs will bandage themselves if they bleed. This behaviour is off by default.
git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7772 3b4a5df2-a311-0410-b5c6-a8a6f20db521
This commit is contained in:
@@ -2160,6 +2160,7 @@ void LoadGameExternalOptions()
|
||||
gGameExternalOptions.ubBaseMedicalSkillToDealWithEmergency = iniReader.ReadInteger("Strategic Assignment Settings","BASE_MEDICAL_SKILL_TO_DEAL_WITH_EMERGENCY",20, 0, 100);
|
||||
gGameExternalOptions.ubMultiplierForDifferenceInLifeValueForEmergency = iniReader.ReadInteger("Strategic Assignment Settings","MULTIPLIER_FOR_DIFFERENCE_IN_LIFE_VALUE_FOR_EMERGENCY",4, 1, 10);
|
||||
gGameExternalOptions.ubPointCostPerHealthBelowOkLife = iniReader.ReadInteger("Strategic Assignment Settings","POINT_COST_PER_HEALTH_BELOW_OKLIFE",2, 1, 5);//OKLIFE = 15
|
||||
gGameExternalOptions.fAllowBandagingDuringTravel = iniReader.ReadBoolean("Strategic Assignment Settings","ALLOW_BANDAGING_DURING_TRAVEL", FALSE );
|
||||
|
||||
////////// REPAIR //////////
|
||||
|
||||
|
||||
@@ -637,6 +637,7 @@ typedef struct
|
||||
INT32 ubBaseMedicalSkillToDealWithEmergency;
|
||||
INT32 ubMultiplierForDifferenceInLifeValueForEmergency;
|
||||
INT32 ubPointCostPerHealthBelowOkLife;//OKLIFE = 15
|
||||
BOOLEAN fAllowBandagingDuringTravel;
|
||||
|
||||
INT32 ubRepairCostPerJam;
|
||||
INT32 ubRepairRateDivisor;
|
||||
|
||||
@@ -599,8 +599,6 @@ extern BOOLEAN SectorIsImpassable( INT16 sSector );
|
||||
|
||||
extern BOOLEAN CanChangeSleepStatusForCharSlot( INT8 bCharNumber );
|
||||
|
||||
extern UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OBJECTTYPE *pKit, INT16 sKitPts, INT16 sStatus, BOOLEAN fOnSurgery ); // variable added by SANDRO
|
||||
|
||||
// only 2 trainers are allowed per sector, so this function counts the # in a guy's sector
|
||||
// HEADROCK HAM 3.6: Now takes an extra argument for Militia Type
|
||||
INT8 CountMilitiaTrainersInSoldiersSector( SOLDIERTYPE * pSoldier, UINT8 ubMilitiaType );
|
||||
|
||||
@@ -1473,351 +1473,6 @@ void ExpandWindow()
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SANDRO - This whole procedure was merged with the surgery ability of the doctor trait
|
||||
UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OBJECTTYPE *pKit, INT16 sKitPts, INT16 sStatus, BOOLEAN fOnSurgery )
|
||||
{
|
||||
UINT32 uiDressSkill, uiPossible, uiActual, uiMedcost, uiDeficiency, uiAvailAPs, uiUsedAPs;
|
||||
UINT8 bBelowOKlife, bPtsLeft;
|
||||
INT8 bInitialBleeding;
|
||||
|
||||
if( pVictim->bBleeding < 1 && !fOnSurgery )
|
||||
return 0; // nothing to do, shouldn't have even been called!
|
||||
if ( pVictim->stats.bLife == 0 )
|
||||
return 0;
|
||||
if (fOnSurgery && pVictim->ubID == pSoldier->ubID) // cannot make surgery on self
|
||||
return 0;
|
||||
|
||||
bInitialBleeding = pVictim->bBleeding;
|
||||
|
||||
if ( !gGameOptions.fNewTraitSystem && fOnSurgery) // cannot make surgery if not new traits
|
||||
fOnSurgery = FALSE;
|
||||
|
||||
// calculate wound-dressing skill (3x medical, 2x equip, 1x level, 1x dex)
|
||||
if ( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
uiDressSkill = ( ( 7 * EffectiveMedical( pSoldier ) ) + // medical knowledge
|
||||
( sStatus) + // state of medical kit
|
||||
(10 * EffectiveExpLevel( pSoldier ) ) + // battle injury experience
|
||||
EffectiveDexterity( pSoldier, FALSE ) ) / 10; // general "handiness"
|
||||
}
|
||||
else
|
||||
{
|
||||
uiDressSkill = ( ( 3 * EffectiveMedical( pSoldier ) ) + // medical knowledge
|
||||
( 2 * sStatus) + // state of medical kit
|
||||
(10 * EffectiveExpLevel( pSoldier ) ) + // battle injury experience
|
||||
EffectiveDexterity( pSoldier, FALSE ) ) / 7; // general "handiness"
|
||||
}
|
||||
|
||||
// try to use every AP that the merc has left
|
||||
uiAvailAPs = pSoldier->bActionPoints;
|
||||
|
||||
// OK, If we are in real-time, use another value...
|
||||
if (!(gTacticalStatus.uiFlags & TURNBASED) || !(gTacticalStatus.uiFlags & INCOMBAT ) )
|
||||
{ // Set to a value which looks good based on out tactical turns duration
|
||||
uiAvailAPs = RT_FIRST_AID_GAIN_MODIFIER;
|
||||
}
|
||||
|
||||
// calculate how much bandaging CAN be done this turn
|
||||
uiPossible = ( uiAvailAPs * uiDressSkill ) / 50; // max rate is 2 * fullAPs
|
||||
|
||||
// if no healing is possible (insufficient APs or insufficient dressSkill)
|
||||
if (!uiPossible)
|
||||
return 0;
|
||||
|
||||
if (Item[pSoldier->inv[0].usItem].medicalkit && !(fOnSurgery) ) // using the GOOD medic stuff
|
||||
uiPossible += ( uiPossible / 2); // add extra 50 %
|
||||
|
||||
// Doctor trait improves basic bandaging ability
|
||||
if (!(fOnSurgery) && gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pSoldier, DOCTOR_NT ))
|
||||
{
|
||||
uiPossible = uiPossible * (100 - gSkillTraitValues.bSpeedModifierBandaging) / 100;
|
||||
uiPossible += ( uiPossible * gSkillTraitValues.ubDOBandagingSpeedPercent * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ) + pSoldier->GetBackgroundValue(BG_PERC_BANDAGING) ) / 100;
|
||||
}
|
||||
|
||||
uiActual = uiPossible; // start by assuming maximum possible
|
||||
|
||||
// figure out how far below OKLIFE the victim is
|
||||
if (pVictim->stats.bLife >= OKLIFE)
|
||||
bBelowOKlife = 0;
|
||||
else
|
||||
bBelowOKlife = OKLIFE - pVictim->stats.bLife;
|
||||
|
||||
// figure out how many healing pts we need to stop dying (2x cost)
|
||||
uiDeficiency = (2 * bBelowOKlife );
|
||||
|
||||
// if, after that, the patient will still be bleeding
|
||||
if ( (pVictim->bBleeding - bBelowOKlife ) > 0)
|
||||
{ // then add how many healing pts we need to stop bleeding (1x cost)
|
||||
uiDeficiency += ( pVictim->bBleeding - bBelowOKlife );
|
||||
}
|
||||
// On surgery, alter this by amount of life we can heal
|
||||
if ( fOnSurgery )
|
||||
{
|
||||
uiDeficiency += (pVictim->iHealableInjury / 100);
|
||||
}
|
||||
// now, make sure we weren't going to give too much
|
||||
if ( uiActual > uiDeficiency) // if we were about to apply too much
|
||||
uiActual = uiDeficiency; // reduce actual not to waste anything
|
||||
|
||||
// now make sure we HAVE that much
|
||||
if( Item[pKit->usItem].medicalkit )
|
||||
{
|
||||
if (fOnSurgery)
|
||||
uiMedcost = (uiActual * gSkillTraitValues.usDOSurgeryMedBagConsumption ) /100; // surgery drains the kit a lot
|
||||
else
|
||||
uiMedcost = (uiActual + 1) / 2; // cost is only half, rounded up
|
||||
|
||||
if ( uiMedcost == 0 && uiActual > 0)
|
||||
uiMedcost = 1;
|
||||
if ( uiMedcost > (UINT32)sKitPts ) // if we can't afford this
|
||||
{
|
||||
uiMedcost = sKitPts; // what CAN we afford?
|
||||
if (fOnSurgery) // surgery check
|
||||
uiActual = (uiMedcost * 100 )/ gSkillTraitValues.usDOSurgeryMedBagConsumption;
|
||||
else
|
||||
uiActual = uiMedcost * 2; // give double this as aid
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uiMedcost = uiActual;
|
||||
if ( uiMedcost == 0 && uiActual > 0)
|
||||
uiMedcost = 1;
|
||||
if ( uiMedcost > (UINT32)sKitPts) // can't afford it
|
||||
uiMedcost = uiActual = sKitPts; // recalc cost AND aid
|
||||
}
|
||||
|
||||
bPtsLeft = (INT8)uiActual;
|
||||
// heal real life points first (if below OKLIFE) because we don't want the
|
||||
// patient still DYING if bandages run out, or medic is disabled/distracted!
|
||||
// NOTE: Dressing wounds for life below OKLIFE now costs 2 pts/life point!
|
||||
if ( bPtsLeft && pVictim->stats.bLife < OKLIFE)
|
||||
{
|
||||
// if we have enough points to bring him all the way to OKLIFE this turn
|
||||
if ( bPtsLeft >= (2 * bBelowOKlife ) )
|
||||
{
|
||||
// insta-healable injury check
|
||||
if (pVictim->iHealableInjury > 0)
|
||||
{
|
||||
pVictim->iHealableInjury -= ((OKLIFE - pVictim->stats.bLife) * 100);
|
||||
if (pVictim->iHealableInjury < 0)
|
||||
pVictim->iHealableInjury = 0;
|
||||
}
|
||||
// raise life to OKLIFE
|
||||
pVictim->stats.bLife = OKLIFE;
|
||||
// reduce bleeding by the same number of life points healed up
|
||||
pVictim->bBleeding -= bBelowOKlife;
|
||||
|
||||
// Flugente: increase bPoisonLife, decrease bPoisonBleeding
|
||||
pVictim->bPoisonLife = min(pVictim->bPoisonSum, pVictim->bPoisonLife + bBelowOKlife);
|
||||
pVictim->bPoisonBleeding = max(0, pVictim->bPoisonBleeding - bBelowOKlife);
|
||||
|
||||
// use up appropriate # of actual healing points
|
||||
bPtsLeft -= (2 * bBelowOKlife);
|
||||
}
|
||||
else
|
||||
{
|
||||
// insta-healable injury check
|
||||
if (pVictim->iHealableInjury > 0)
|
||||
{
|
||||
pVictim->iHealableInjury -= (( bPtsLeft / 2) * 100);
|
||||
if (pVictim->iHealableInjury < 0)
|
||||
pVictim->iHealableInjury = 0;
|
||||
}
|
||||
pVictim->stats.bLife += ( bPtsLeft / 2);
|
||||
pVictim->bBleeding -= ( bPtsLeft / 2);
|
||||
|
||||
// Flugente: increase bPoisonLife, decrease bPoisonBleeding
|
||||
pVictim->bPoisonLife = min(pVictim->bPoisonSum, pVictim->bPoisonLife + ( bPtsLeft / 2));
|
||||
pVictim->bPoisonBleeding = max(0, pVictim->bPoisonBleeding - ( bPtsLeft / 2));
|
||||
|
||||
bPtsLeft = bPtsLeft % 2; // if ptsLeft was odd, ptsLeft = 1
|
||||
}
|
||||
|
||||
// this should never happen any more, but make sure bleeding not negative
|
||||
if (pVictim->bBleeding < 0)
|
||||
{
|
||||
pVictim->bBleeding = 0;
|
||||
pVictim->bPoisonBleeding = 0;
|
||||
}
|
||||
|
||||
// if this healing brought the patient out of the worst of it, cancel dying
|
||||
if (pVictim->stats.bLife >= OKLIFE )
|
||||
{ // turn off merc QUOTE flags
|
||||
pVictim->flags.fDyingComment = FALSE;
|
||||
}
|
||||
|
||||
if ( pVictim->bBleeding <= MIN_BLEEDING_THRESHOLD )
|
||||
{
|
||||
pVictim->flags.fWarnedAboutBleeding = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// SURGERY
|
||||
// first return the real life back, then bandage the rest if possible
|
||||
if (fOnSurgery && gGameOptions.fNewTraitSystem) // double check for new traits
|
||||
{
|
||||
INT32 iLifeReturned = 0;
|
||||
UINT16 usReturnDamagedStatRate = 0;
|
||||
// find out if we will repair any stats...
|
||||
if ( NumberOfDamagedStats( pVictim ) > 0 )
|
||||
{
|
||||
usReturnDamagedStatRate = ((gSkillTraitValues.usDORepairStatsRateBasic + gSkillTraitValues.usDORepairStatsRateOnTop * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT )));
|
||||
usReturnDamagedStatRate -= max( 0, ((usReturnDamagedStatRate * gSkillTraitValues.ubDORepStPenaltyIfAlsoHealing ) / 100));
|
||||
|
||||
// ... in which case, reduce the points
|
||||
bPtsLeft = max(0, ((bPtsLeft * ( 100 - gSkillTraitValues.ubDOHealingPenaltyIfAlsoStatRepair )) / 100));
|
||||
}
|
||||
|
||||
// Important note! : HealableInjury is always stores the total HPs the victim is missing, not the amount which we will heal,
|
||||
// so we always take a portion of patient's damage here, reduce the HealableInjury by this portion, while only healing a portion of this portion in actual HPs;
|
||||
// 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;
|
||||
|
||||
pVictim->iHealableInjury = 0;
|
||||
// keep the rest of the points to bandaging if neccessary
|
||||
if (pVictim->bBleeding > 0)
|
||||
{
|
||||
bPtsLeft = max(0, (bPtsLeft - (iLifeReturned / 100)));
|
||||
bPtsLeft += (bPtsLeft/2); // we use medical bag so add the bonus for that.
|
||||
}
|
||||
else
|
||||
{
|
||||
bPtsLeft = 0;
|
||||
}
|
||||
|
||||
// add to record - another surgery undergoed
|
||||
if ( pVictim->ubProfile != NO_PROFILE && iLifeReturned >= 100 )
|
||||
gMercProfiles[ pVictim->ubProfile ].records.usTimesSurgeryUndergoed++;
|
||||
|
||||
// add to record - another surgery made
|
||||
if ( pSoldier->ubProfile != NO_PROFILE && iLifeReturned >= 100 )
|
||||
gMercProfiles[ pSoldier->ubProfile ].records.usSurgeriesMade++;
|
||||
}
|
||||
else
|
||||
{
|
||||
iLifeReturned = bPtsLeft * (gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ));
|
||||
|
||||
pVictim->iHealableInjury -= (bPtsLeft * 100);
|
||||
bPtsLeft = 0;
|
||||
}
|
||||
// repair the stats here!
|
||||
if ( usReturnDamagedStatRate > 0 )
|
||||
{
|
||||
RegainDamagedStats( pVictim, (iLifeReturned * usReturnDamagedStatRate / 100) );
|
||||
}
|
||||
|
||||
// some paranoya checks for sure
|
||||
if ((pVictim->stats.bLife + (iLifeReturned / 100)) <= pVictim->stats.bLifeMax)
|
||||
{
|
||||
pVictim->stats.bLife += (iLifeReturned/100);
|
||||
pVictim->bPoisonLife = min(pVictim->bPoisonSum, pVictim->bPoisonLife + (iLifeReturned/100));
|
||||
if (pVictim->bBleeding >= (iLifeReturned/100))
|
||||
{
|
||||
pVictim->bBleeding -= (iLifeReturned/100);
|
||||
pVictim->bPoisonBleeding = max(0, pVictim->bPoisonBleeding - (iLifeReturned/100));
|
||||
uiMedcost += (iLifeReturned / 200); // add medkit points cost for unbandaged part
|
||||
}
|
||||
else
|
||||
{
|
||||
pVictim->bBleeding = 0;
|
||||
pVictim->bPoisonBleeding = 0;
|
||||
uiMedcost += max( 0, (((iLifeReturned/100) - pVictim->bBleeding) / 2)); // add medkit points cost for unbandaged part
|
||||
}
|
||||
}
|
||||
else // this shouldn't even happen, but we still want to have it here for sure
|
||||
{
|
||||
pVictim->stats.bLife = pVictim->stats.bLifeMax;
|
||||
pVictim->bPoisonLife = pVictim->bPoisonSum;
|
||||
pVictim->iHealableInjury = 0;
|
||||
pVictim->bBleeding = 0;
|
||||
pVictim->bPoisonBleeding = 0;
|
||||
}
|
||||
// Reduce max breath based on life returned
|
||||
if ( (pVictim->bBreathMax - (((iLifeReturned/100) * gSkillTraitValues.usDOSurgeryMaxBreathLoss )/ 100)) <= BREATHMAX_ABSOLUTE_MINIMUM )
|
||||
{
|
||||
pVictim->bBreathMax = BREATHMAX_ABSOLUTE_MINIMUM;
|
||||
}
|
||||
else
|
||||
{
|
||||
pVictim->bBreathMax -= (((iLifeReturned/100) * gSkillTraitValues.usDOSurgeryMaxBreathLoss )/ 100);
|
||||
}
|
||||
|
||||
if (pVictim->iHealableInjury > ((pVictim->stats.bLifeMax - pVictim->stats.bLife)*100))
|
||||
pVictim->iHealableInjury = ((pVictim->stats.bLifeMax - pVictim->stats.bLife)*100);
|
||||
else if (pVictim->iHealableInjury < 0)
|
||||
pVictim->iHealableInjury = 0;
|
||||
|
||||
// Flugente: campaign stats
|
||||
gCurrentIncident.usIncidentFlags |= INCIDENT_SURGERY;
|
||||
}
|
||||
|
||||
// if any healing points remain, apply that to any remaining bleeding (1/1)
|
||||
// DON'T spend any APs/kit pts to cure bleeding until merc is no longer dying
|
||||
//if ( bPtsLeft && pVictim->bBleeding && !pVictim->dying)
|
||||
if ( bPtsLeft && pVictim->bBleeding )
|
||||
{ // if we have enough points to bandage all remaining bleeding this turn
|
||||
if (bPtsLeft >= pVictim->bBleeding )
|
||||
{
|
||||
bPtsLeft -= pVictim->bBleeding;
|
||||
pVictim->bBleeding = 0;
|
||||
pVictim->bPoisonBleeding = 0;
|
||||
}
|
||||
else // bandage what we can
|
||||
{
|
||||
pVictim->bBleeding -= bPtsLeft;
|
||||
pVictim->bPoisonBleeding = max(0, pVictim->bPoisonBleeding - bPtsLeft);
|
||||
bPtsLeft = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//CHRISL: If by some chance ubPtsLeft ends up being higher then uiActual, we'll end up with a huge value since uiActual is an unsigned variable.
|
||||
// if there are any ptsLeft now, then we didn't actually get to use them
|
||||
uiActual = max(0, (INT32)(uiActual - bPtsLeft));
|
||||
|
||||
// usedAPs equals (actionPts) * (%of possible points actually used)
|
||||
uiUsedAPs = ( uiActual * uiAvailAPs ) / uiPossible;
|
||||
|
||||
if (Item[pSoldier->inv[0].usItem].medicalkit && !(fOnSurgery)) // using the GOOD medic stuff
|
||||
uiUsedAPs = ( uiUsedAPs * 2) / 3; // reverse 50% bonus by taking 2/3rds
|
||||
|
||||
// surgery is harder so cost more BPs
|
||||
if (fOnSurgery)
|
||||
DeductPoints( pSoldier, (INT16)uiUsedAPs, (INT16)( uiUsedAPs * 15 ) );
|
||||
else
|
||||
DeductPoints( pSoldier, (INT16)uiUsedAPs, (INT16)( ( uiUsedAPs * APBPConstants[BP_PER_AP_LT_EFFORT]) ) );
|
||||
|
||||
// surgery is harder so gives more exp
|
||||
if (fOnSurgery)
|
||||
{
|
||||
// MEDICAL GAIN (actual / 2): Helped someone by giving first aid
|
||||
StatChange(pSoldier, MEDICALAMT, (UINT16)(uiActual + 2), FALSE);
|
||||
|
||||
// DEXTERITY GAIN (actual / 6): Helped someone by giving first aid
|
||||
StatChange(pSoldier, DEXTAMT, (UINT16)((uiActual / 3) + 2), FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( uiActual / 2)
|
||||
// MEDICAL GAIN (actual / 2): Helped someone by giving first aid
|
||||
StatChange(pSoldier,MEDICALAMT,( (UINT16)(uiActual / 2) ),FALSE);
|
||||
|
||||
if ( uiActual / 4)
|
||||
// DEXTERITY GAIN (actual / 4): Helped someone by giving first aid
|
||||
StatChange(pSoldier,DEXTAMT,(UINT16)( ( uiActual / 4) ),FALSE);
|
||||
}
|
||||
|
||||
// merc records - bandaging
|
||||
if( bInitialBleeding > 1 && pVictim->bBleeding == 0 && pSoldier->ubProfile != NO_PROFILE )
|
||||
gMercProfiles[ pSoldier->ubProfile ].records.usMercsBandaged++;
|
||||
|
||||
return uiMedcost;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
OBJECTTYPE* FindMedicalKit()
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
+15
-2
@@ -110,6 +110,7 @@
|
||||
#include "Facilities.h"
|
||||
// HEADROCK HAM 4: Include Militia Squads for Manual Militia Restrictions toggle.
|
||||
#include "MilitiaSquads.h"
|
||||
#include "Auto Bandage.h" // added by Flugente
|
||||
#endif
|
||||
|
||||
#include "connect.h" //hayden
|
||||
@@ -5243,8 +5244,7 @@ UINT32 MapScreenHandle(void)
|
||||
// now do the warning box
|
||||
DoMapMessageBox( MSG_BOX_BASIC_STYLE, pMapErrorString[ 4 ], MAP_SCREEN, MSG_BOX_FLAG_OK, MapScreenDefaultOkBoxCallback );
|
||||
}
|
||||
|
||||
|
||||
|
||||
fFirstTimeInMapScreen = FALSE;
|
||||
|
||||
if( gpCurrentTalkingFace != NULL )
|
||||
@@ -5313,6 +5313,13 @@ UINT32 MapScreenHandle(void)
|
||||
|
||||
HandleStrategicTurn( );
|
||||
|
||||
// Flugente: bandaging during retreat
|
||||
if ( RetreatBandagingPending() )
|
||||
{
|
||||
// now do the warning box
|
||||
DoScreenIndependantMessageBox( TacticalStr[ATTEMPT_BANDAGE_DURING_TRAVEL], MSG_BOX_FLAG_OK, RetreatBandageCallback );
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// update cursor based on state
|
||||
@@ -16774,3 +16781,9 @@ BOOLEAN CanGiveStrategicMilitiaMoveOrder( INT16 sMapX, INT16 sMapY )
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Flugente: bandaging during retreat
|
||||
void RetreatBandageCallback( UINT8 ubResult )
|
||||
{
|
||||
HandleRetreatBandaging( );
|
||||
}
|
||||
|
||||
@@ -161,4 +161,7 @@ BOOLEAN CanGiveStrategicMilitiaMoveOrder( INT16 sMapX, INT16 sMapY );
|
||||
void ConvertMinTimeToDayHourMinString( UINT32 uiTimeInMin, STR16 sString );
|
||||
void ConvertMinTimeToETADayHourMinString( UINT32 uiTimeInMin, STR16 sString );
|
||||
|
||||
// Flugente: bandaging during retreat
|
||||
void RetreatBandageCallback( UINT8 ubResult );
|
||||
|
||||
#endif
|
||||
+208
-92
@@ -27,6 +27,7 @@
|
||||
#include "WordWrap.h"
|
||||
#include "cursors.h"
|
||||
#include "English.h"
|
||||
#include "SkillCheck.h" // added by Flugente
|
||||
#endif
|
||||
|
||||
#include "Music Control.h"
|
||||
@@ -92,12 +93,11 @@ extern UINT8 NumEnemyInSector( );
|
||||
|
||||
void BeginAutoBandage( )
|
||||
{
|
||||
INT32 cnt;
|
||||
BOOLEAN fFoundAGuy = FALSE;
|
||||
INT32 cnt;
|
||||
BOOLEAN fFoundAGuy = FALSE;
|
||||
SOLDIERTYPE * pSoldier;
|
||||
BOOLEAN fFoundAMedKit = FALSE;
|
||||
|
||||
|
||||
BOOLEAN fFoundAMedKit = FALSE;
|
||||
|
||||
// If we are in combat, we con't...
|
||||
if ( (gTacticalStatus.uiFlags & INCOMBAT) || (NumEnemyInSector() != 0) )
|
||||
{
|
||||
@@ -107,7 +107,7 @@ void BeginAutoBandage( )
|
||||
|
||||
cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
|
||||
// check for anyone needing bandages
|
||||
for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++,pSoldier++ )
|
||||
for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ++cnt, ++pSoldier )
|
||||
{
|
||||
// if the soldier isn't active or in sector, we have problems..leave
|
||||
if ( !(pSoldier->bActive) || !(pSoldier->bInSector) || ( pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) || (pSoldier->bAssignment == VEHICLE ) )
|
||||
@@ -116,23 +116,14 @@ void BeginAutoBandage( )
|
||||
}
|
||||
|
||||
// can this character be helped out by a teammate?
|
||||
if ( CanCharacterBeAutoBandagedByTeammate( pSoldier ) == TRUE )
|
||||
{
|
||||
if ( CanCharacterBeAutoBandagedByTeammate( pSoldier ) )
|
||||
fFoundAGuy = TRUE;
|
||||
if ( fFoundAGuy && fFoundAMedKit )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( FindObjClass( pSoldier, IC_MEDKIT ) != NO_SLOT )
|
||||
{
|
||||
fFoundAMedKit = TRUE;
|
||||
if ( fFoundAGuy && fFoundAMedKit )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( FindObjClass( pSoldier, IC_MEDKIT ) != NO_SLOT )
|
||||
fFoundAMedKit = TRUE;
|
||||
|
||||
if ( fFoundAGuy && fFoundAMedKit )
|
||||
break;
|
||||
}
|
||||
|
||||
if ( !fFoundAGuy )
|
||||
@@ -190,7 +181,7 @@ void HandleAutoBandagePending( )
|
||||
|
||||
// Do any guys have pending actions...?
|
||||
cnt = gTacticalStatus.Team[ OUR_TEAM ].bFirstID;
|
||||
for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; cnt++,pSoldier++)
|
||||
for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; ++cnt, ++pSoldier)
|
||||
{
|
||||
// Are we in sector?
|
||||
if ( pSoldier->bActive )
|
||||
@@ -211,10 +202,8 @@ void HandleAutoBandagePending( )
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// If here, all's a go!
|
||||
gTacticalStatus.fAutoBandagePending = FALSE;
|
||||
SetAutoBandagePending( FALSE );
|
||||
BeginAutoBandage( );
|
||||
}
|
||||
}
|
||||
@@ -238,7 +227,7 @@ void ShouldBeginAutoBandage( )
|
||||
// ATE: If not in endgame
|
||||
if ( ( gTacticalStatus.uiFlags & IN_DEIDRANNA_ENDGAME ) )
|
||||
{
|
||||
return;
|
||||
return;
|
||||
}
|
||||
|
||||
if ( CanAutoBandage( FALSE ) )
|
||||
@@ -308,34 +297,33 @@ BOOLEAN HandleAutoBandage( )
|
||||
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return( FALSE );
|
||||
}
|
||||
|
||||
|
||||
BOOLEAN CreateAutoBandageString( void )
|
||||
{
|
||||
INT32 cnt;
|
||||
INT32 cnt;
|
||||
// WDS - make number of mercenaries, etc. be configurable
|
||||
UINT8 ubDoctor[CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS], ubDoctors = 0;
|
||||
UINT32 uiDoctorNameStringLength = 1; // for end-of-string character
|
||||
STR16 sTemp;
|
||||
UINT8 ubDoctor[CODE_MAXIMUM_NUMBER_OF_PLAYER_SLOTS], ubDoctors = 0;
|
||||
UINT32 uiDoctorNameStringLength = 1; // for end-of-string character
|
||||
STR16 sTemp;
|
||||
SOLDIERTYPE * pSoldier;
|
||||
|
||||
cnt = gTacticalStatus.Team[ OUR_TEAM ].bFirstID;
|
||||
for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; cnt++,pSoldier++)
|
||||
for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; ++cnt, ++pSoldier)
|
||||
{
|
||||
if ( pSoldier->bActive && pSoldier->bInSector && pSoldier->stats.bLife >= OKLIFE && !(pSoldier->bCollapsed) && pSoldier->stats.bMedical > 0 && FindObjClass( pSoldier, IC_MEDKIT ) != NO_SLOT)
|
||||
{
|
||||
ubDoctor[ubDoctors] = pSoldier->ubID;
|
||||
ubDoctors++;
|
||||
++ubDoctors;
|
||||
// increase the length of the string by the size of the name
|
||||
// plus 2, one for the comma and one for the space after that
|
||||
uiDoctorNameStringLength += wcslen( pSoldier->name ) + 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (ubDoctors == 0)
|
||||
{
|
||||
return( FALSE );
|
||||
@@ -370,7 +358,7 @@ BOOLEAN CreateAutoBandageString( void )
|
||||
return( FALSE );
|
||||
}
|
||||
wcscpy( sTemp, L"" );
|
||||
for (cnt = 0; cnt < ubDoctors - 1; cnt++)
|
||||
for (cnt = 0; cnt < ubDoctors - 1; ++cnt)
|
||||
{
|
||||
wcscat( sTemp, MercPtrs[ubDoctor[cnt]]->name );
|
||||
if (ubDoctors > 2)
|
||||
@@ -388,6 +376,7 @@ BOOLEAN CreateAutoBandageString( void )
|
||||
swprintf( sAutoBandageString, Message[STR_ARE_APPLYING_FIRST_AID], sTemp, MercPtrs[ubDoctor[ubDoctors - 1]]->name );
|
||||
MemFree( sTemp );
|
||||
}
|
||||
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
@@ -395,8 +384,6 @@ void SetAutoBandageComplete( void )
|
||||
{
|
||||
// this will set the fact autobandage is complete
|
||||
fAutoBandageComplete = TRUE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void AutoBandage( BOOLEAN fStart )
|
||||
@@ -413,7 +400,6 @@ void AutoBandage( BOOLEAN fStart )
|
||||
|
||||
gfAutoBandageFailed = FALSE;
|
||||
|
||||
|
||||
// ste up the autobandage panel
|
||||
SetUpAutoBandageUpdatePanel( );
|
||||
|
||||
@@ -426,7 +412,7 @@ void AutoBandage( BOOLEAN fStart )
|
||||
//SetGameTimeCompressionLevel( TIME_COMPRESS_5MINS );
|
||||
|
||||
cnt = gTacticalStatus.Team[ OUR_TEAM ].bFirstID;
|
||||
for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; cnt++,pSoldier++)
|
||||
for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; ++cnt, ++pSoldier)
|
||||
{
|
||||
if ( pSoldier->bActive )
|
||||
{
|
||||
@@ -450,8 +436,7 @@ void AutoBandage( BOOLEAN fStart )
|
||||
// Determine position ( centered in rect )
|
||||
gsX = (INT16)( ( ( ( aRect.iRight - aRect.iLeft ) - gusTextBoxWidth ) / 2 ) + aRect.iLeft );
|
||||
gsY = (INT16)( ( ( ( aRect.iBottom - aRect.iTop ) - gusTextBoxHeight ) / 2 ) + aRect.iTop );
|
||||
|
||||
|
||||
|
||||
// build a mask
|
||||
MSYS_DefineRegion( &gAutoBandageRegion, 0,0, SCREEN_WIDTH, SCREEN_HEIGHT, MSYS_PRIORITY_HIGHEST - 1,
|
||||
CURSOR_NORMAL, MSYS_NO_CALLBACK, MSYS_NO_CALLBACK );
|
||||
@@ -466,7 +451,7 @@ void AutoBandage( BOOLEAN fStart )
|
||||
|
||||
// make sure anyone under AI control has their action cancelled
|
||||
cnt = gTacticalStatus.Team[ OUR_TEAM ].bFirstID;
|
||||
for ( pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; cnt++,pSoldier++)
|
||||
for ( pSoldier = MercPtrs[cnt]; cnt <= gTacticalStatus.Team[OUR_TEAM].bLastID; ++cnt, ++pSoldier )
|
||||
{
|
||||
// 0verhaul: Make sure the merc is also in the sector before making him stand up!
|
||||
if ( pSoldier->bActive && pSoldier->bInSector )
|
||||
@@ -486,13 +471,11 @@ void AutoBandage( BOOLEAN fStart )
|
||||
pSoldier->ChangeSoldierStance( ANIM_STAND );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ubLoop = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
|
||||
for ( ; ubLoop <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ubLoop++)
|
||||
for ( ; ubLoop <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ++ubLoop)
|
||||
{
|
||||
ActionDone( MercPtrs[ ubLoop ] );
|
||||
|
||||
@@ -589,7 +572,6 @@ void SetUpAutoBandageUpdatePanel( void )
|
||||
// add to list, up the count
|
||||
iDoctorList[ iNumberDoctoring ] = iCounterA;
|
||||
iNumberDoctoring++;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -623,8 +605,6 @@ void SetUpAutoBandageUpdatePanel( void )
|
||||
AddFacesToAutoBandageBox( );
|
||||
|
||||
fAutoBandageComplete = FALSE;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void DisplayAutoBandageUpdatePanel( void )
|
||||
@@ -669,7 +649,6 @@ void DisplayAutoBandageUpdatePanel( void )
|
||||
}
|
||||
|
||||
// build dimensions of box
|
||||
|
||||
if( iNumberDoctors < NUMBER_MERC_FACES_AUTOBANDAGE_BOX )
|
||||
{
|
||||
// nope, get the base amount
|
||||
@@ -680,8 +659,6 @@ void DisplayAutoBandageUpdatePanel( void )
|
||||
iNumberDoctorsWide = NUMBER_MERC_FACES_AUTOBANDAGE_BOX;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// set the min number of mercs
|
||||
if( iNumberDoctorsWide < 3 )
|
||||
{
|
||||
@@ -738,9 +715,7 @@ void DisplayAutoBandageUpdatePanel( void )
|
||||
// now the patients
|
||||
iNumberPatientsHigh = ( iNumberPatients / ( NUMBER_MERC_FACES_AUTOBANDAGE_BOX ) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// now the actual pixel dimensions
|
||||
|
||||
iTotalPixelsHigh = ( iNumberPatientsHigh + iNumberDoctorsHigh ) * TACT_UPDATE_MERC_FACE_X_HEIGHT;
|
||||
@@ -760,12 +735,10 @@ void DisplayAutoBandageUpdatePanel( void )
|
||||
// now get the x and y position for the box
|
||||
sXPosition = ( SCREEN_WIDTH - iTotalPixelsWide ) / 2;
|
||||
sYPosition = ( INV_INTERFACE_START_Y - iTotalPixelsHigh ) / 2;
|
||||
|
||||
|
||||
|
||||
// now blit down the background
|
||||
GetVideoObject( &hBackGroundHandle, guiUpdatePanelTactical );
|
||||
|
||||
|
||||
|
||||
// first the doctors on top
|
||||
for( iCounterA = 0; iCounterA < iNumberDoctorsHigh; iCounterA++ )
|
||||
{
|
||||
@@ -776,13 +749,11 @@ void DisplayAutoBandageUpdatePanel( void )
|
||||
|
||||
// slap down background piece
|
||||
BltVideoObject( FRAME_BUFFER , hBackGroundHandle, 15, sCurrentXPosition, sCurrentYPosition, VO_BLT_SRCTRANSPARENCY, NULL );
|
||||
|
||||
|
||||
|
||||
iIndex = iCounterA * iNumberDoctorsWide + iCounterB;
|
||||
|
||||
if( iDoctorList[ iIndex ] != -1 )
|
||||
{
|
||||
|
||||
sCurrentXPosition += TACT_UPDATE_MERC_FACE_X_OFFSET;
|
||||
sCurrentYPosition += TACT_UPDATE_MERC_FACE_Y_OFFSET;
|
||||
|
||||
@@ -809,11 +780,9 @@ void DisplayAutoBandageUpdatePanel( void )
|
||||
|
||||
for( iCounterB = 0; iCounterB < iNumberPatientsWide; iCounterB ++ )
|
||||
{
|
||||
// slap down background piece
|
||||
BltVideoObject( FRAME_BUFFER , hBackGroundHandle, 16, sXPosition + ( iCounterB * TACT_UPDATE_MERC_FACE_X_WIDTH ), sCurrentYPosition + ( TACT_UPDATE_MERC_FACE_X_HEIGHT ), VO_BLT_SRCTRANSPARENCY, NULL );
|
||||
BltVideoObject( FRAME_BUFFER , hBackGroundHandle, 16, sXPosition + ( iCounterB * TACT_UPDATE_MERC_FACE_X_WIDTH ), sYPosition - 9 , VO_BLT_SRCTRANSPARENCY, NULL );
|
||||
|
||||
|
||||
// slap down background piece
|
||||
BltVideoObject( FRAME_BUFFER , hBackGroundHandle, 16, sXPosition + ( iCounterB * TACT_UPDATE_MERC_FACE_X_WIDTH ), sCurrentYPosition + ( TACT_UPDATE_MERC_FACE_X_HEIGHT ), VO_BLT_SRCTRANSPARENCY, NULL );
|
||||
BltVideoObject( FRAME_BUFFER , hBackGroundHandle, 16, sXPosition + ( iCounterB * TACT_UPDATE_MERC_FACE_X_WIDTH ), sYPosition - 9 , VO_BLT_SRCTRANSPARENCY, NULL );
|
||||
}
|
||||
|
||||
// bordering patient title
|
||||
@@ -827,16 +796,14 @@ void DisplayAutoBandageUpdatePanel( void )
|
||||
|
||||
// iCurPixelY = sYPosition;
|
||||
iCurPixelY = sYPosition + ( ( iCounterA - 1 ) * TACT_UPDATE_MERC_FACE_X_HEIGHT );
|
||||
|
||||
|
||||
|
||||
swprintf( sString, L"%s", zMarksMapScreenText[ 13 ] );
|
||||
FindFontCenterCoordinates( ( INT16 )( sXPosition ), ( INT16 )( sCurrentYPosition ), ( INT16 )( iTotalPixelsWide ), 0, sString, TINYFONT1, &sX, &sY );
|
||||
// print medic
|
||||
mprintf( sX, sYPosition - 7 , sString );
|
||||
|
||||
//DisplayWrappedString( ( INT16 )( sXPosition ), ( INT16 )( sCurrentYPosition - 40 ), ( INT16 )( iTotalPixelsWide ), 0, TINYFONT1, FONT_WHITE, pUpdateMercStrings[ 0 ], FONT_BLACK, 0, 0 );
|
||||
|
||||
|
||||
|
||||
sYPosition += 9;
|
||||
|
||||
// now the patients
|
||||
@@ -844,15 +811,12 @@ void DisplayAutoBandageUpdatePanel( void )
|
||||
{
|
||||
for( iCounterB = 0; iCounterB < iNumberPatientsWide; iCounterB ++ )
|
||||
{
|
||||
|
||||
sCurrentXPosition = sXPosition + ( iCounterB * TACT_UPDATE_MERC_FACE_X_WIDTH );
|
||||
sCurrentYPosition = sYPosition + ( ( iCounterA + iNumberDoctorsHigh ) * TACT_UPDATE_MERC_FACE_X_HEIGHT );
|
||||
|
||||
|
||||
|
||||
// slap down background piece
|
||||
BltVideoObject( FRAME_BUFFER , hBackGroundHandle, 15, sCurrentXPosition, sCurrentYPosition , VO_BLT_SRCTRANSPARENCY, NULL );
|
||||
|
||||
|
||||
|
||||
iIndex = iCounterA * iNumberPatientsWide + iCounterB;
|
||||
|
||||
if( iPatientList[ iIndex ] != -1 )
|
||||
@@ -875,11 +839,9 @@ void DisplayAutoBandageUpdatePanel( void )
|
||||
// print name
|
||||
mprintf( sX, sY , sString );
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// BORDER PIECES!!!!
|
||||
|
||||
// bordering patients squares
|
||||
@@ -889,7 +851,6 @@ void DisplayAutoBandageUpdatePanel( void )
|
||||
BltVideoObject( FRAME_BUFFER , hBackGroundHandle, 5, sXPosition + iTotalPixelsWide , sYPosition + ( ( iCounterA + iNumberDoctorsHigh ) * TACT_UPDATE_MERC_FACE_X_HEIGHT ), VO_BLT_SRCTRANSPARENCY,NULL );
|
||||
}
|
||||
|
||||
|
||||
// back up 11 pixels
|
||||
sYPosition-=9;
|
||||
|
||||
@@ -942,13 +903,9 @@ void DisplayAutoBandageUpdatePanel( void )
|
||||
// print patient
|
||||
mprintf( sX, iCurPixelY + ( TACT_UPDATE_MERC_FACE_X_HEIGHT ) + 2, sString );
|
||||
|
||||
|
||||
MarkAButtonDirty( iEndAutoBandageButton[ 0 ] );
|
||||
MarkAButtonDirty( iEndAutoBandageButton[ 1 ] );
|
||||
|
||||
|
||||
|
||||
|
||||
DrawButton( iEndAutoBandageButton[ 0 ] );
|
||||
DrawButton( iEndAutoBandageButton[ 1 ] );
|
||||
|
||||
@@ -968,8 +925,6 @@ void DisplayAutoBandageUpdatePanel( void )
|
||||
|
||||
// now make sure it goes to the screen
|
||||
InvalidateRegion( sXPosition - 4, sYPosition - 18, ( INT16 )( sXPosition + iTotalPixelsWide + 4), ( INT16 )( sYPosition + iTotalPixelsHigh ) );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1014,8 +969,6 @@ void CreateTerminateAutoBandageButton( INT16 sX, INT16 sY )
|
||||
SpecifyButtonFont( iEndAutoBandageButton[ 1 ], MAP_SCREEN_FONT );
|
||||
SpecifyButtonUpTextColors( iEndAutoBandageButton[ 1 ], FONT_MCOLOR_BLACK, FONT_BLACK );
|
||||
SpecifyButtonDownTextColors( iEndAutoBandageButton[ 1 ], FONT_MCOLOR_BLACK, FONT_BLACK );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1033,15 +986,12 @@ void StopAutoBandageButtonCallback(GUI_BUTTON *btn,INT32 reason)
|
||||
fEndAutoBandage = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void DestroyTerminateAutoBandageButton( void )
|
||||
{
|
||||
|
||||
// destroy the kill autobandage button
|
||||
if( fAutoEndBandageButtonCreated == FALSE )
|
||||
{
|
||||
@@ -1058,8 +1008,6 @@ void DestroyTerminateAutoBandageButton( void )
|
||||
// unload image
|
||||
UnloadButtonImage( iEndAutoBandageButtonImage[ 0 ] );
|
||||
UnloadButtonImage( iEndAutoBandageButtonImage[ 1 ] );
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1361,3 +1309,171 @@ BOOLEAN RenderSoldierSmallFaceForAutoBandagePanel( INT32 iIndex, INT16 sCurrentX
|
||||
|
||||
return( TRUE );
|
||||
}
|
||||
|
||||
// Flugente: bandaging during retreat
|
||||
BOOLEAN gRetreatBandagingPending = FALSE;
|
||||
|
||||
void SetRetreatBandaging(BOOLEAN aVal)
|
||||
{
|
||||
gRetreatBandagingPending = aVal;
|
||||
}
|
||||
|
||||
BOOLEAN RetreatBandagingPending()
|
||||
{
|
||||
return gRetreatBandagingPending;
|
||||
}
|
||||
|
||||
// return the ID of best doctor that has a medkit and is travelling with pPatient
|
||||
UINT8 GetBestRetreatingMercDoctor( SOLDIERTYPE* pPatient )
|
||||
{
|
||||
// if this is a travelling, bleeding merc, can somebody who travels with him bandage him/her?
|
||||
if ( pPatient && pPatient->bActive && pPatient->flags.fBetweenSectors && pPatient->bBleeding )
|
||||
{
|
||||
UINT16 cnt = gTacticalStatus.Team[OUR_TEAM].bFirstID;
|
||||
SOLDIERTYPE* pSoldier = NULL;
|
||||
for ( pSoldier = MercPtrs[cnt]; cnt <= gTacticalStatus.Team[OUR_TEAM].bLastID; ++cnt, ++pSoldier )
|
||||
{
|
||||
// this requires mercs to travel and thus NOT be in a sector
|
||||
// also we need to be in a specific sector
|
||||
if ( pSoldier->bActive && pSoldier->flags.fBetweenSectors && pSoldier->sSectorX == pPatient->sSectorX && pSoldier->sSectorY == pPatient->sSectorY )
|
||||
{
|
||||
// find the best conscious doctor that has a medkit
|
||||
if ( pSoldier->stats.bLife >= OKLIFE && pSoldier->stats.bMedical > 0 && FindObjClass( pSoldier, IC_MEDKIT ) != NO_SLOT )
|
||||
{
|
||||
return cnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NOBODY;
|
||||
}
|
||||
|
||||
|
||||
void HandleRetreatBandaging()
|
||||
{
|
||||
// handle bandaging of retreating mercs
|
||||
// this function will be called when a travelling merc is bleeding
|
||||
// make sure anyone under AI control has their action cancelled
|
||||
|
||||
// first, have every injured merc bandage himself
|
||||
// second, repeat tis process:
|
||||
// if non-bandaged mercs remain, find the best doctor that still has medkits, else break
|
||||
// if doctor exists, have the doctor treat all injured mercs, else break
|
||||
// third, set flag that calls this function off
|
||||
|
||||
// for each call, we only do this for one sector, thereby only for one group retreating from a sector
|
||||
// we can do this because a) it is unlikely that two wounded groups will retreat from combat at the same time, and b) bleeding calls this function again.
|
||||
// As long as people bleed, this function will be called, thereby we will get to the group in question at some point
|
||||
|
||||
BOOLEAN needhelpinsector = FALSE;
|
||||
INT16 sX = -1;
|
||||
INT16 sY = -1;
|
||||
UINT8 possiblepatient = NOBODY;
|
||||
|
||||
UINT16 cnt = gTacticalStatus.Team[OUR_TEAM].bFirstID;
|
||||
SOLDIERTYPE* pSoldier = NULL;
|
||||
for ( pSoldier = MercPtrs[cnt]; cnt <= gTacticalStatus.Team[OUR_TEAM].bLastID; ++cnt, ++pSoldier )
|
||||
{
|
||||
// this requires mercs to travel and thus NOT be in a sector
|
||||
// are we bleeding?
|
||||
if ( pSoldier->bActive && pSoldier->flags.fBetweenSectors && pSoldier->bBleeding )
|
||||
{
|
||||
// if we are still conscious, try bandaging ourself
|
||||
if ( pSoldier->stats.bLife >= OKLIFE )
|
||||
{
|
||||
UINT32 counter = 0;
|
||||
INT8 bSlot = -1;
|
||||
UINT32 uiPointsUsed;
|
||||
UINT16 usKitPts;
|
||||
OBJECTTYPE *pKit = NULL;
|
||||
if ( pSoldier->stats.bMedical > 0 && (bSlot = FindObjClass( pSoldier, IC_MEDKIT )) != NO_SLOT )
|
||||
{
|
||||
while ( pSoldier->bBleeding )
|
||||
{
|
||||
pKit = &pSoldier->inv[bSlot];
|
||||
usKitPts = TotalPoints( pKit );
|
||||
if ( !usKitPts )
|
||||
{
|
||||
//attempt to find another kit before stopping
|
||||
if ( (bSlot = FindObjClass( pSoldier, IC_MEDKIT )) != NO_SLOT )
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
uiPointsUsed = VirtualSoldierDressWound( pSoldier, pSoldier, pKit, usKitPts, usKitPts, FALSE ); // changed by SANDRO
|
||||
UseKitPoints( pKit, (UINT16)uiPointsUsed, pSoldier );
|
||||
++counter;
|
||||
|
||||
if ( counter > 50 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we are still bleeding, other mercs have to help us
|
||||
if ( pSoldier->bBleeding && !needhelpinsector )
|
||||
{
|
||||
needhelpinsector = TRUE;
|
||||
sX = pSoldier->sSectorX;
|
||||
sY = pSoldier->sSectorY;
|
||||
possiblepatient = cnt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// someone is bleeding and can't bandage himself, other mercs have to help
|
||||
if ( needhelpinsector && possiblepatient != NOBODY)
|
||||
{
|
||||
// find the best doctor here
|
||||
UINT16 bestdoctorid = GetBestRetreatingMercDoctor( MercPtrs[possiblepatient] );
|
||||
|
||||
if ( bestdoctorid != NOBODY )
|
||||
{
|
||||
// have the doctor treat people
|
||||
SOLDIERTYPE* pDoctor = MercPtrs[bestdoctorid];
|
||||
|
||||
cnt = gTacticalStatus.Team[OUR_TEAM].bFirstID;
|
||||
for ( pSoldier = MercPtrs[cnt]; cnt <= gTacticalStatus.Team[OUR_TEAM].bLastID; ++cnt, ++pSoldier )
|
||||
{
|
||||
// this requires mercs to travel and thus NOT be in a sector
|
||||
// also we need to be in a specific sector
|
||||
// treat bleeding people only
|
||||
if ( pSoldier->bActive && pSoldier->flags.fBetweenSectors && sX == pSoldier->sSectorX && sY == pSoldier->sSectorY && pSoldier->bBleeding )
|
||||
{
|
||||
UINT32 counter = 0;
|
||||
INT8 bSlot = -1;
|
||||
UINT32 uiPointsUsed;
|
||||
UINT16 usKitPts;
|
||||
OBJECTTYPE *pKit = NULL;
|
||||
if ( pDoctor->stats.bMedical > 0 && (bSlot = FindObjClass( pDoctor, IC_MEDKIT )) != NO_SLOT )
|
||||
{
|
||||
while ( pSoldier->bBleeding )
|
||||
{
|
||||
pKit = &pDoctor->inv[bSlot];
|
||||
usKitPts = TotalPoints( pKit );
|
||||
if ( !usKitPts )
|
||||
{
|
||||
//attempt to find another kit before stopping
|
||||
if ( (bSlot = FindObjClass( pDoctor, IC_MEDKIT )) != NO_SLOT )
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
uiPointsUsed = VirtualSoldierDressWound( pDoctor, pSoldier, pKit, usKitPts, usKitPts, FALSE ); // changed by SANDRO
|
||||
UseKitPoints( pKit, (UINT16)uiPointsUsed, pDoctor );
|
||||
++counter;
|
||||
|
||||
if ( counter > 50 )
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SetRetreatBandaging( FALSE );
|
||||
}
|
||||
|
||||
@@ -16,4 +16,13 @@ void HandleAutoBandagePending( );
|
||||
// ste the autobandage as complete
|
||||
void SetAutoBandageComplete( void );
|
||||
|
||||
// Flugente: bandaging during retreat
|
||||
void SetRetreatBandaging( BOOLEAN aVal );
|
||||
BOOLEAN RetreatBandagingPending( );
|
||||
|
||||
// return the ID of best doctor that has a medkit and is travelling with pPatient
|
||||
UINT8 GetBestRetreatingMercDoctor( SOLDIERTYPE* pPatient );
|
||||
|
||||
void HandleRetreatBandaging( );
|
||||
|
||||
#endif
|
||||
@@ -95,6 +95,7 @@
|
||||
#include "Interface Panels.h"
|
||||
#include "Queen Command.h" // added by Flugente
|
||||
#include "Town Militia.h" // added by Flugente
|
||||
#include "Auto Bandage.h" // added by Flugente
|
||||
#endif
|
||||
|
||||
#include "ub_config.h"
|
||||
@@ -10092,14 +10093,18 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sPo
|
||||
HandlePossibleInfection( this, NULL, INFECTION_TYPE_TRAUMATIC );
|
||||
}
|
||||
|
||||
// Flugente: bandaging during retreat
|
||||
if ( gGameExternalOptions.fAllowBandagingDuringTravel && ubReason == TAKE_DAMAGE_BLOODLOSS && this->flags.fBetweenSectors && GetBestRetreatingMercDoctor( this ) != NOBODY )
|
||||
{
|
||||
SetRetreatBandaging( TRUE );
|
||||
}
|
||||
|
||||
// Calculate damage to our items if from an explosion!
|
||||
if ( ubReason == TAKE_DAMAGE_EXPLOSION || ubReason == TAKE_DAMAGE_STRUCTURE_EXPLOSION )
|
||||
{
|
||||
CheckEquipmentForDamage( this, sLifeDeduct );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Calculate bleeding
|
||||
if ( ubReason != TAKE_DAMAGE_GAS && !AM_A_ROBOT( this ) )
|
||||
{
|
||||
@@ -22449,3 +22454,347 @@ void SetDamageDisplayCounter( SOLDIERTYPE* pSoldier )
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// SANDRO - This whole procedure was merged with the surgery ability of the doctor trait
|
||||
UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OBJECTTYPE *pKit, INT16 sKitPts, INT16 sStatus, BOOLEAN fOnSurgery )
|
||||
{
|
||||
UINT32 uiDressSkill, uiPossible, uiActual, uiMedcost, uiDeficiency, uiAvailAPs, uiUsedAPs;
|
||||
UINT8 bBelowOKlife, bPtsLeft;
|
||||
INT8 bInitialBleeding;
|
||||
|
||||
if ( pVictim->bBleeding < 1 && !fOnSurgery )
|
||||
return 0; // nothing to do, shouldn't have even been called!
|
||||
if ( pVictim->stats.bLife == 0 )
|
||||
return 0;
|
||||
if ( fOnSurgery && pVictim->ubID == pSoldier->ubID ) // cannot make surgery on self
|
||||
return 0;
|
||||
|
||||
bInitialBleeding = pVictim->bBleeding;
|
||||
|
||||
if ( !gGameOptions.fNewTraitSystem && fOnSurgery ) // cannot make surgery if not new traits
|
||||
fOnSurgery = FALSE;
|
||||
|
||||
// calculate wound-dressing skill (3x medical, 2x equip, 1x level, 1x dex)
|
||||
if ( gGameOptions.fNewTraitSystem )
|
||||
{
|
||||
uiDressSkill = ((7 * EffectiveMedical( pSoldier )) + // medical knowledge
|
||||
(sStatus)+ // state of medical kit
|
||||
(10 * EffectiveExpLevel( pSoldier )) + // battle injury experience
|
||||
EffectiveDexterity( pSoldier, FALSE )) / 10; // general "handiness"
|
||||
}
|
||||
else
|
||||
{
|
||||
uiDressSkill = ((3 * EffectiveMedical( pSoldier )) + // medical knowledge
|
||||
(2 * sStatus) + // state of medical kit
|
||||
(10 * EffectiveExpLevel( pSoldier )) + // battle injury experience
|
||||
EffectiveDexterity( pSoldier, FALSE )) / 7; // general "handiness"
|
||||
}
|
||||
|
||||
// try to use every AP that the merc has left
|
||||
uiAvailAPs = pSoldier->bActionPoints;
|
||||
|
||||
// OK, If we are in real-time, use another value...
|
||||
if ( !(gTacticalStatus.uiFlags & TURNBASED) || !(gTacticalStatus.uiFlags & INCOMBAT) )
|
||||
{ // Set to a value which looks good based on out tactical turns duration
|
||||
uiAvailAPs = RT_FIRST_AID_GAIN_MODIFIER;
|
||||
}
|
||||
|
||||
// calculate how much bandaging CAN be done this turn
|
||||
uiPossible = (uiAvailAPs * uiDressSkill) / 50; // max rate is 2 * fullAPs
|
||||
|
||||
// if no healing is possible (insufficient APs or insufficient dressSkill)
|
||||
if ( !uiPossible )
|
||||
return 0;
|
||||
|
||||
if ( Item[pSoldier->inv[0].usItem].medicalkit && !(fOnSurgery) ) // using the GOOD medic stuff
|
||||
uiPossible += (uiPossible / 2); // add extra 50 %
|
||||
|
||||
// Doctor trait improves basic bandaging ability
|
||||
if ( !(fOnSurgery) && gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pSoldier, DOCTOR_NT ) )
|
||||
{
|
||||
uiPossible = uiPossible * (100 - gSkillTraitValues.bSpeedModifierBandaging) / 100;
|
||||
uiPossible += (uiPossible * gSkillTraitValues.ubDOBandagingSpeedPercent * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ) + pSoldier->GetBackgroundValue( BG_PERC_BANDAGING )) / 100;
|
||||
}
|
||||
|
||||
uiActual = uiPossible; // start by assuming maximum possible
|
||||
|
||||
// figure out how far below OKLIFE the victim is
|
||||
if ( pVictim->stats.bLife >= OKLIFE )
|
||||
bBelowOKlife = 0;
|
||||
else
|
||||
bBelowOKlife = OKLIFE - pVictim->stats.bLife;
|
||||
|
||||
// figure out how many healing pts we need to stop dying (2x cost)
|
||||
uiDeficiency = (2 * bBelowOKlife);
|
||||
|
||||
// if, after that, the patient will still be bleeding
|
||||
if ( (pVictim->bBleeding - bBelowOKlife) > 0 )
|
||||
{ // then add how many healing pts we need to stop bleeding (1x cost)
|
||||
uiDeficiency += (pVictim->bBleeding - bBelowOKlife);
|
||||
}
|
||||
// On surgery, alter this by amount of life we can heal
|
||||
if ( fOnSurgery )
|
||||
{
|
||||
uiDeficiency += (pVictim->iHealableInjury / 100);
|
||||
}
|
||||
// now, make sure we weren't going to give too much
|
||||
if ( uiActual > uiDeficiency ) // if we were about to apply too much
|
||||
uiActual = uiDeficiency; // reduce actual not to waste anything
|
||||
|
||||
// now make sure we HAVE that much
|
||||
if ( Item[pKit->usItem].medicalkit )
|
||||
{
|
||||
if ( fOnSurgery )
|
||||
uiMedcost = (uiActual * gSkillTraitValues.usDOSurgeryMedBagConsumption) / 100; // surgery drains the kit a lot
|
||||
else
|
||||
uiMedcost = (uiActual + 1) / 2; // cost is only half, rounded up
|
||||
|
||||
if ( uiMedcost == 0 && uiActual > 0 )
|
||||
uiMedcost = 1;
|
||||
if ( uiMedcost > (UINT32)sKitPts ) // if we can't afford this
|
||||
{
|
||||
uiMedcost = sKitPts; // what CAN we afford?
|
||||
if ( fOnSurgery ) // surgery check
|
||||
uiActual = (uiMedcost * 100) / gSkillTraitValues.usDOSurgeryMedBagConsumption;
|
||||
else
|
||||
uiActual = uiMedcost * 2; // give double this as aid
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uiMedcost = uiActual;
|
||||
if ( uiMedcost == 0 && uiActual > 0 )
|
||||
uiMedcost = 1;
|
||||
if ( uiMedcost > (UINT32)sKitPts ) // can't afford it
|
||||
uiMedcost = uiActual = sKitPts; // recalc cost AND aid
|
||||
}
|
||||
|
||||
bPtsLeft = (INT8)uiActual;
|
||||
// heal real life points first (if below OKLIFE) because we don't want the
|
||||
// patient still DYING if bandages run out, or medic is disabled/distracted!
|
||||
// NOTE: Dressing wounds for life below OKLIFE now costs 2 pts/life point!
|
||||
if ( bPtsLeft && pVictim->stats.bLife < OKLIFE )
|
||||
{
|
||||
// if we have enough points to bring him all the way to OKLIFE this turn
|
||||
if ( bPtsLeft >= (2 * bBelowOKlife) )
|
||||
{
|
||||
// insta-healable injury check
|
||||
if ( pVictim->iHealableInjury > 0 )
|
||||
{
|
||||
pVictim->iHealableInjury -= ((OKLIFE - pVictim->stats.bLife) * 100);
|
||||
if ( pVictim->iHealableInjury < 0 )
|
||||
pVictim->iHealableInjury = 0;
|
||||
}
|
||||
// raise life to OKLIFE
|
||||
pVictim->stats.bLife = OKLIFE;
|
||||
// reduce bleeding by the same number of life points healed up
|
||||
pVictim->bBleeding -= bBelowOKlife;
|
||||
|
||||
// Flugente: increase bPoisonLife, decrease bPoisonBleeding
|
||||
pVictim->bPoisonLife = min( pVictim->bPoisonSum, pVictim->bPoisonLife + bBelowOKlife );
|
||||
pVictim->bPoisonBleeding = max( 0, pVictim->bPoisonBleeding - bBelowOKlife );
|
||||
|
||||
// use up appropriate # of actual healing points
|
||||
bPtsLeft -= (2 * bBelowOKlife);
|
||||
}
|
||||
else
|
||||
{
|
||||
// insta-healable injury check
|
||||
if ( pVictim->iHealableInjury > 0 )
|
||||
{
|
||||
pVictim->iHealableInjury -= ((bPtsLeft / 2) * 100);
|
||||
if ( pVictim->iHealableInjury < 0 )
|
||||
pVictim->iHealableInjury = 0;
|
||||
}
|
||||
pVictim->stats.bLife += (bPtsLeft / 2);
|
||||
pVictim->bBleeding -= (bPtsLeft / 2);
|
||||
|
||||
// Flugente: increase bPoisonLife, decrease bPoisonBleeding
|
||||
pVictim->bPoisonLife = min( pVictim->bPoisonSum, pVictim->bPoisonLife + (bPtsLeft / 2) );
|
||||
pVictim->bPoisonBleeding = max( 0, pVictim->bPoisonBleeding - (bPtsLeft / 2) );
|
||||
|
||||
bPtsLeft = bPtsLeft % 2; // if ptsLeft was odd, ptsLeft = 1
|
||||
}
|
||||
|
||||
// this should never happen any more, but make sure bleeding not negative
|
||||
if ( pVictim->bBleeding < 0 )
|
||||
{
|
||||
pVictim->bBleeding = 0;
|
||||
pVictim->bPoisonBleeding = 0;
|
||||
}
|
||||
|
||||
// if this healing brought the patient out of the worst of it, cancel dying
|
||||
if ( pVictim->stats.bLife >= OKLIFE )
|
||||
{ // turn off merc QUOTE flags
|
||||
pVictim->flags.fDyingComment = FALSE;
|
||||
}
|
||||
|
||||
if ( pVictim->bBleeding <= MIN_BLEEDING_THRESHOLD )
|
||||
{
|
||||
pVictim->flags.fWarnedAboutBleeding = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// SURGERY
|
||||
// first return the real life back, then bandage the rest if possible
|
||||
if ( fOnSurgery && gGameOptions.fNewTraitSystem ) // double check for new traits
|
||||
{
|
||||
INT32 iLifeReturned = 0;
|
||||
UINT16 usReturnDamagedStatRate = 0;
|
||||
// find out if we will repair any stats...
|
||||
if ( NumberOfDamagedStats( pVictim ) > 0 )
|
||||
{
|
||||
usReturnDamagedStatRate = ((gSkillTraitValues.usDORepairStatsRateBasic + gSkillTraitValues.usDORepairStatsRateOnTop * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT )));
|
||||
usReturnDamagedStatRate -= max( 0, ((usReturnDamagedStatRate * gSkillTraitValues.ubDORepStPenaltyIfAlsoHealing) / 100) );
|
||||
|
||||
// ... in which case, reduce the points
|
||||
bPtsLeft = max( 0, ((bPtsLeft * (100 - gSkillTraitValues.ubDOHealingPenaltyIfAlsoStatRepair)) / 100) );
|
||||
}
|
||||
|
||||
// Important note! : HealableInjury is always stores the total HPs the victim is missing, not the amount which we will heal,
|
||||
// so we always take a portion of patient's damage here, reduce the HealableInjury by this portion, while only healing a portion of this portion in actual HPs;
|
||||
// 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;
|
||||
|
||||
pVictim->iHealableInjury = 0;
|
||||
// keep the rest of the points to bandaging if neccessary
|
||||
if ( pVictim->bBleeding > 0 )
|
||||
{
|
||||
bPtsLeft = max( 0, (bPtsLeft - (iLifeReturned / 100)) );
|
||||
bPtsLeft += (bPtsLeft / 2); // we use medical bag so add the bonus for that.
|
||||
}
|
||||
else
|
||||
{
|
||||
bPtsLeft = 0;
|
||||
}
|
||||
|
||||
// add to record - another surgery undergoed
|
||||
if ( pVictim->ubProfile != NO_PROFILE && iLifeReturned >= 100 )
|
||||
gMercProfiles[pVictim->ubProfile].records.usTimesSurgeryUndergoed++;
|
||||
|
||||
// add to record - another surgery made
|
||||
if ( pSoldier->ubProfile != NO_PROFILE && iLifeReturned >= 100 )
|
||||
gMercProfiles[pSoldier->ubProfile].records.usSurgeriesMade++;
|
||||
}
|
||||
else
|
||||
{
|
||||
iLifeReturned = bPtsLeft * (gSkillTraitValues.ubDOSurgeryHealPercentBase + gSkillTraitValues.ubDOSurgeryHealPercentOnTop * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ));
|
||||
|
||||
pVictim->iHealableInjury -= (bPtsLeft * 100);
|
||||
bPtsLeft = 0;
|
||||
}
|
||||
// repair the stats here!
|
||||
if ( usReturnDamagedStatRate > 0 )
|
||||
{
|
||||
RegainDamagedStats( pVictim, (iLifeReturned * usReturnDamagedStatRate / 100) );
|
||||
}
|
||||
|
||||
// some paranoya checks for sure
|
||||
if ( (pVictim->stats.bLife + (iLifeReturned / 100)) <= pVictim->stats.bLifeMax )
|
||||
{
|
||||
pVictim->stats.bLife += (iLifeReturned / 100);
|
||||
pVictim->bPoisonLife = min( pVictim->bPoisonSum, pVictim->bPoisonLife + (iLifeReturned / 100) );
|
||||
if ( pVictim->bBleeding >= (iLifeReturned / 100) )
|
||||
{
|
||||
pVictim->bBleeding -= (iLifeReturned / 100);
|
||||
pVictim->bPoisonBleeding = max( 0, pVictim->bPoisonBleeding - (iLifeReturned / 100) );
|
||||
uiMedcost += (iLifeReturned / 200); // add medkit points cost for unbandaged part
|
||||
}
|
||||
else
|
||||
{
|
||||
pVictim->bBleeding = 0;
|
||||
pVictim->bPoisonBleeding = 0;
|
||||
uiMedcost += max( 0, (((iLifeReturned / 100) - pVictim->bBleeding) / 2) ); // add medkit points cost for unbandaged part
|
||||
}
|
||||
}
|
||||
else // this shouldn't even happen, but we still want to have it here for sure
|
||||
{
|
||||
pVictim->stats.bLife = pVictim->stats.bLifeMax;
|
||||
pVictim->bPoisonLife = pVictim->bPoisonSum;
|
||||
pVictim->iHealableInjury = 0;
|
||||
pVictim->bBleeding = 0;
|
||||
pVictim->bPoisonBleeding = 0;
|
||||
}
|
||||
// Reduce max breath based on life returned
|
||||
if ( (pVictim->bBreathMax - (((iLifeReturned / 100) * gSkillTraitValues.usDOSurgeryMaxBreathLoss) / 100)) <= BREATHMAX_ABSOLUTE_MINIMUM )
|
||||
{
|
||||
pVictim->bBreathMax = BREATHMAX_ABSOLUTE_MINIMUM;
|
||||
}
|
||||
else
|
||||
{
|
||||
pVictim->bBreathMax -= (((iLifeReturned / 100) * gSkillTraitValues.usDOSurgeryMaxBreathLoss) / 100);
|
||||
}
|
||||
|
||||
if ( pVictim->iHealableInjury > ((pVictim->stats.bLifeMax - pVictim->stats.bLife) * 100) )
|
||||
pVictim->iHealableInjury = ((pVictim->stats.bLifeMax - pVictim->stats.bLife) * 100);
|
||||
else if ( pVictim->iHealableInjury < 0 )
|
||||
pVictim->iHealableInjury = 0;
|
||||
|
||||
// Flugente: campaign stats
|
||||
gCurrentIncident.usIncidentFlags |= INCIDENT_SURGERY;
|
||||
}
|
||||
|
||||
// if any healing points remain, apply that to any remaining bleeding (1/1)
|
||||
// DON'T spend any APs/kit pts to cure bleeding until merc is no longer dying
|
||||
//if ( bPtsLeft && pVictim->bBleeding && !pVictim->dying)
|
||||
if ( bPtsLeft && pVictim->bBleeding )
|
||||
{ // if we have enough points to bandage all remaining bleeding this turn
|
||||
if ( bPtsLeft >= pVictim->bBleeding )
|
||||
{
|
||||
bPtsLeft -= pVictim->bBleeding;
|
||||
pVictim->bBleeding = 0;
|
||||
pVictim->bPoisonBleeding = 0;
|
||||
}
|
||||
else // bandage what we can
|
||||
{
|
||||
pVictim->bBleeding -= bPtsLeft;
|
||||
pVictim->bPoisonBleeding = max( 0, pVictim->bPoisonBleeding - bPtsLeft );
|
||||
bPtsLeft = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//CHRISL: If by some chance ubPtsLeft ends up being higher then uiActual, we'll end up with a huge value since uiActual is an unsigned variable.
|
||||
// if there are any ptsLeft now, then we didn't actually get to use them
|
||||
uiActual = max( 0, (INT32)(uiActual - bPtsLeft) );
|
||||
|
||||
// usedAPs equals (actionPts) * (%of possible points actually used)
|
||||
uiUsedAPs = (uiActual * uiAvailAPs) / uiPossible;
|
||||
|
||||
if ( Item[pSoldier->inv[0].usItem].medicalkit && !(fOnSurgery) ) // using the GOOD medic stuff
|
||||
uiUsedAPs = (uiUsedAPs * 2) / 3; // reverse 50% bonus by taking 2/3rds
|
||||
|
||||
// surgery is harder so cost more BPs
|
||||
if ( fOnSurgery )
|
||||
DeductPoints( pSoldier, (INT16)uiUsedAPs, (INT16)(uiUsedAPs * 15) );
|
||||
else
|
||||
DeductPoints( pSoldier, (INT16)uiUsedAPs, (INT16)((uiUsedAPs * APBPConstants[BP_PER_AP_LT_EFFORT])) );
|
||||
|
||||
// surgery is harder so gives more exp
|
||||
if ( fOnSurgery )
|
||||
{
|
||||
// MEDICAL GAIN (actual / 2): Helped someone by giving first aid
|
||||
StatChange( pSoldier, MEDICALAMT, (UINT16)(uiActual + 2), FALSE );
|
||||
|
||||
// DEXTERITY GAIN (actual / 6): Helped someone by giving first aid
|
||||
StatChange( pSoldier, DEXTAMT, (UINT16)((uiActual / 3) + 2), FALSE );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( uiActual / 2 )
|
||||
// MEDICAL GAIN (actual / 2): Helped someone by giving first aid
|
||||
StatChange( pSoldier, MEDICALAMT, ((UINT16)(uiActual / 2)), FALSE );
|
||||
|
||||
if ( uiActual / 4 )
|
||||
// DEXTERITY GAIN (actual / 4): Helped someone by giving first aid
|
||||
StatChange( pSoldier, DEXTAMT, (UINT16)((uiActual / 4)), FALSE );
|
||||
}
|
||||
|
||||
// merc records - bandaging
|
||||
if ( bInitialBleeding > 1 && pVictim->bBleeding == 0 && pSoldier->ubProfile != NO_PROFILE )
|
||||
gMercProfiles[pSoldier->ubProfile].records.usMercsBandaged++;
|
||||
|
||||
return uiMedcost;
|
||||
}
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -2728,6 +2728,9 @@ void HandleTakeDamageDeath( SOLDIERTYPE *pSoldier, UINT8 bOldLife, UINT8 ubReaso
|
||||
|
||||
void SetDamageDisplayCounter(SOLDIERTYPE* pSoldier);
|
||||
|
||||
// SANDRO - This whole procedure was merged with the surgery ability of the doctor trait
|
||||
UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OBJECTTYPE *pKit, INT16 sKitPts, INT16 sStatus, BOOLEAN fOnSurgery );
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1116,6 +1116,8 @@ enum
|
||||
QUICK_ITEM_NOT_FOUND,
|
||||
QUICK_ITEM_CANNOT_TAKE,
|
||||
|
||||
ATTEMPT_BANDAGE_DURING_TRAVEL,
|
||||
|
||||
TEXT_NUM_TACTICAL_STR
|
||||
};
|
||||
|
||||
|
||||
@@ -3389,6 +3389,8 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"没有空手来拿新物品",
|
||||
L"未发现物品",
|
||||
L"无法把物品转移到主手上",
|
||||
|
||||
L"Attempting to bandage travelling mercs...", //TODO.Translate
|
||||
};
|
||||
|
||||
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
|
||||
|
||||
@@ -3387,6 +3387,8 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"No free hand for new item",
|
||||
L"Item not found",
|
||||
L"Cannot take item to main hand",
|
||||
|
||||
L"Attempting to bandage travelling mercs...", //TODO.Translate
|
||||
};
|
||||
|
||||
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
|
||||
|
||||
@@ -3388,6 +3388,8 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"No free hand for new item",
|
||||
L"Item not found",
|
||||
L"Cannot take item to main hand",
|
||||
|
||||
L"Attempting to bandage travelling mercs...",
|
||||
};
|
||||
|
||||
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
|
||||
|
||||
@@ -3392,6 +3392,8 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"Aucune main libre pour un nouvel objet",
|
||||
L"Objet non trouvé",
|
||||
L"Vous ne pouvez pas prendre d'objet avec la main principale",
|
||||
|
||||
L"Attempting to bandage travelling mercs...", //TODO.Translate
|
||||
};
|
||||
|
||||
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
|
||||
|
||||
@@ -3394,6 +3394,8 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"No free hand for new item",
|
||||
L"Item not found",
|
||||
L"Cannot take item to main hand",
|
||||
|
||||
L"Attempting to bandage travelling mercs...", //TODO.Translate
|
||||
};
|
||||
|
||||
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
|
||||
|
||||
@@ -3382,6 +3382,8 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"No free hand for new item",
|
||||
L"Item not found",
|
||||
L"Cannot take item to main hand",
|
||||
|
||||
L"Attempting to bandage travelling mercs...", //TODO.Translate
|
||||
};
|
||||
|
||||
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
|
||||
|
||||
@@ -3397,6 +3397,8 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"No free hand for new item",
|
||||
L"Item not found",
|
||||
L"Cannot take item to main hand",
|
||||
|
||||
L"Attempting to bandage travelling mercs...", //TODO.Translate
|
||||
};
|
||||
|
||||
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
|
||||
|
||||
@@ -3385,6 +3385,8 @@ CHAR16 TacticalStr[][ MED_STRING_LENGTH ] =
|
||||
L"Нет свободной руки для предмета",
|
||||
L"Предмет не обнаружен",
|
||||
L"Невозможно взять предмет в руку",
|
||||
|
||||
L"Attempting to bandage travelling mercs...", //TODO.Translate
|
||||
};
|
||||
|
||||
//Varying helptext explains (for the "Go to Sector/Map" checkbox) what will happen given different circumstances in the "exiting sector" interface.
|
||||
|
||||
Reference in New Issue
Block a user