From e643c1ea5799f4d0a8ed1bab43904a351aae994c Mon Sep 17 00:00:00 2001 From: Flugente Date: Mon, 23 Jan 2017 23:05:30 +0000 Subject: [PATCH] - Hospital healing now uses the same function as normal healing - If surgery would not heal anything, don't do it - removed unnecessary defines git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@8375 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Strategic/Assignments.cpp | 136 ++++++++------------------ Strategic/Map Screen Helicopter.cpp | 4 +- Strategic/Strategic Event Handler.cpp | 2 +- Strategic/Strategic Event Handler.h | 4 - Strategic/strategicmap.cpp | 2 +- Tactical/Handle UI.cpp | 18 +++- 6 files changed, 58 insertions(+), 108 deletions(-) diff --git a/Strategic/Assignments.cpp b/Strategic/Assignments.cpp index 7943135e..4e985cde 100644 --- a/Strategic/Assignments.cpp +++ b/Strategic/Assignments.cpp @@ -575,7 +575,6 @@ BOOLEAN CanSoldierBeHealedByDoctor( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pDoctor, UINT8 GetNumberThatCanBeDoctored( SOLDIERTYPE *pDoctor, BOOLEAN fThisHour, BOOLEAN fSkipKitCheck, BOOLEAN fSkipSkillCheck, BOOLEAN fCheckForSurgery ); void CheckForAndHandleHospitalPatients( void ); -void HealHospitalPatient( SOLDIERTYPE *pPatient, UINT16 usHealingPtsLeft ); BOOLEAN MakeSureToolKitIsInHand( SOLDIERTYPE *pSoldier ); @@ -4044,6 +4043,11 @@ UINT16 HealPatient( SOLDIERTYPE *pPatient, SOLDIERTYPE * pDoctor, UINT16 usHealA // SANDRO - this whole procedure was heavily changed // Flugente: what he said //////////////////////////////////////////////////// + + // if pPatient does not exist, get out of here + // this does not apply for pDoctor. We also use this routine for hospital healing, where the pointer is NULL + if ( !pPatient ) + return 0; INT16 bPointsHealed = 0; UINT16 ubReturnDamagedStatRate = 0; @@ -4063,18 +4067,32 @@ UINT16 HealPatient( SOLDIERTYPE *pPatient, SOLDIERTYPE * pDoctor, UINT16 usHealA INT32 sHundredsToRepair_Used = 0; INT32 sHundredsToDiseaseCure_Used = 0; + // how good is the doctor? + INT8 sDoctortraits = 2; // we just assume doctors in hospitals are capable + if ( pDoctor ) + { + if ( gGameOptions.fNewTraitSystem ) + sDoctortraits = NUM_SKILL_TRAITS( pDoctor, DOCTOR_NT ); + else + sDoctortraits = 0; + } + INT8 bMedFactor = 1; // basic medical factor // Added a penalty for not experienced mercs, they consume the bag faster // if healing an repairing stat at the same time, this is increased again, but we wont recalculate for now - if ( gGameOptions.fNewTraitSystem && !HAS_SKILL_TRAIT( pDoctor, DOCTOR_NT ) && (pDoctor->stats.bMedical < 50) ) + if ( gGameOptions.fNewTraitSystem && pDoctor && !sDoctortraits && (pDoctor->stats.bMedical < 50) ) bMedFactor += 1; - - // calculate how much total points we have in all medical bags - this ultimately limits how much we can heal - UINT16 usTotalMedPoints = TotalMedicalKitPoints( pDoctor ); - + // we are limited by our supplies - UINT16 ptsleft = min( usHealAmount, (usTotalMedPoints * 100) / bMedFactor ); - + UINT16 ptsleft = usHealAmount; + if ( pDoctor ) + { + // calculate how much total points we have in all medical bags - this ultimately limits how much we can heal + UINT16 usTotalMedPoints = TotalMedicalKitPoints( pDoctor ); + + ptsleft = min( usHealAmount, (usTotalMedPoints * 100) / bMedFactor ); + } + //////// DETERMINE LIFE HEAL //////////////////// // Look how much life do we need to heal sHundredsToHeal = (pPatient->stats.bLifeMax - pPatient->stats.bLife) * 100; @@ -4090,18 +4108,18 @@ UINT16 HealPatient( SOLDIERTYPE *pPatient, SOLDIERTYPE * pDoctor, UINT16 usHealA fWillHealLife = TRUE; //////// DETERMINE STAT REPAIR //////////////////// - if ( gGameOptions.fNewTraitSystem && (NUM_SKILL_TRAITS( pDoctor, DOCTOR_NT ) > 0) && (NumberOfDamagedStats( pPatient ) > 0) ) + if ( sDoctortraits > 0 && (NumberOfDamagedStats( pPatient ) > 0) ) { fWillRepairStats = TRUE; sHundredsToRepair = 100 * NumberOfDamagedStats( pPatient ); - ubReturnDamagedStatRate = ((gSkillTraitValues.usDORepairStatsRateBasic + gSkillTraitValues.usDORepairStatsRateOnTop * NUM_SKILL_TRAITS( pDoctor, DOCTOR_NT ))); + ubReturnDamagedStatRate = ((gSkillTraitValues.usDORepairStatsRateBasic + gSkillTraitValues.usDORepairStatsRateOnTop * sDoctortraits)); // reduce rate if we are going to heal at the same time if ( fWillHealLife ) ubReturnDamagedStatRate -= ((ubReturnDamagedStatRate * gSkillTraitValues.ubDORepStPenaltyIfAlsoHealing) / 100); } - + //////// DETERMINE DISEASE CURE //////////////////// if ( pPatient->HasDisease( TRUE, TRUE ) ) { @@ -4216,12 +4234,13 @@ UINT16 HealPatient( SOLDIERTYPE *pPatient, SOLDIERTYPE * pDoctor, UINT16 usHealA } // patient expresses his gratitude - AddOpinionEvent( pPatient->ubProfile, pDoctor->ubProfile, OPINIONEVENT_DISEASE_TREATMENT, TRUE ); + if ( pDoctor ) + AddOpinionEvent( pPatient->ubProfile, pDoctor->ubProfile, OPINIONEVENT_DISEASE_TREATMENT, TRUE ); } } // Finally use all kit points (we are sure, we have that much) - if ( UseTotalMedicalKitPoints( pDoctor, max(1, ((sHundredsToHeal_Used + sHundredsToRepair_Used + sHundredsToDiseaseCure_Used) * bMedFactor) / 100) ) == FALSE ) + if ( pDoctor && UseTotalMedicalKitPoints( pDoctor, max( 1, ((sHundredsToHeal_Used + sHundredsToRepair_Used + sHundredsToDiseaseCure_Used) * bMedFactor) / 100 ) ) == FALSE ) { // throw message if this went wrong for feedback on debugging #ifdef JA2TESTVERSION @@ -4233,6 +4252,12 @@ UINT16 HealPatient( SOLDIERTYPE *pPatient, SOLDIERTYPE * pDoctor, UINT16 usHealA if ( (sHundredsToHeal_Used + sHundredsToRepair_Used + sHundredsToDiseaseCure_Used) > usHealAmount ) ScreenMsg( FONT_MCOLOR_RED, MSG_TESTVERSION, L"Warning! HealPatient uses more points than it should!" ); + // if this patient is fully healed and cured + if ( !pDoctor && pPatient->stats.bLife == pPatient->stats.bLifeMax && !NumberOfDamagedStats( pPatient ) && !pPatient->HasDisease( TRUE, TRUE ) ) + { + AssignmentDone( pPatient, TRUE, TRUE ); + } + return (sHundredsToHeal_Used + sHundredsToRepair_Used + sHundredsToDiseaseCure_Used); } @@ -4242,7 +4267,7 @@ void CheckForAndHandleHospitalPatients( void ) SOLDIERTYPE *pSoldier, *pTeamSoldier; INT32 cnt=0; - if( fSectorsWithSoldiers[ HOSPITAL_SECTOR_X + HOSPITAL_SECTOR_Y * MAP_WORLD_X ][ 0 ] == FALSE ) + if ( fSectorsWithSoldiers[gModSettings.ubHospitalSectorX + gModSettings.ubHospitalSectorY * MAP_WORLD_X][0] == FALSE ) { // nobody in the hospital sector... leave return; @@ -4258,95 +4283,16 @@ void CheckForAndHandleHospitalPatients( void ) { if ( pTeamSoldier->bAssignment == ASSIGNMENT_HOSPITAL ) { - if ( ( pTeamSoldier->sSectorX == HOSPITAL_SECTOR_X ) && ( pTeamSoldier->sSectorY == HOSPITAL_SECTOR_Y ) && ( pTeamSoldier->bSectorZ == 0 ) ) + if ( (pTeamSoldier->sSectorX == gModSettings.ubHospitalSectorX) && (pTeamSoldier->sSectorY == gModSettings.ubHospitalSectorY) && (pTeamSoldier->bSectorZ == gModSettings.ubHospitalSectorZ) ) { // heal this character - HealHospitalPatient( pTeamSoldier, gGameExternalOptions.ubHospitalHealingRate ); + HealPatient( pTeamSoldier, NULL, gGameExternalOptions.ubHospitalHealingRate * 100 ); } } } } } - -void HealHospitalPatient( SOLDIERTYPE *pPatient, UINT16 usHealingPtsLeft ) -{ - INT8 bPointsToUse; - - if (usHealingPtsLeft <= 0) - { - return; - } - -/* Stopping hospital patients' bleeding must be handled immediately, not during a regular hourly check - // stop all bleeding of patient..for 1 pt. - if (pPatient->bBleeding > 0) - { - usHealingPtsLeft--; - pPatient->bBleeding = 0; - } -*/ - - // if below ok life, heal these first at double cost - if( pPatient->stats.bLife < OKLIFE ) - { - // get points needed to heal him to OKLIFE - bPointsToUse = gGameExternalOptions.ubPointCostPerHealthBelowOkLife * ( OKLIFE - pPatient->stats.bLife ); - - // if he needs more than we have, reduce to that - if( bPointsToUse > usHealingPtsLeft ) - { - bPointsToUse = ( INT8 )usHealingPtsLeft; - } - - usHealingPtsLeft -= bPointsToUse; - - // heal person the amount / POINT_COST_PER_HEALTH_BELOW_OKLIFE - pPatient->stats.bLife += ( bPointsToUse / gGameExternalOptions.ubPointCostPerHealthBelowOkLife ); - - // SANDRO - doctor trait - when being healed normally, reduce insta-healable HPs value - if ( gGameOptions.fNewTraitSystem && pPatient->iHealableInjury > 0 ) - { - pPatient->iHealableInjury -= (bPointsToUse / gGameExternalOptions.ubPointCostPerHealthBelowOkLife * 100); - if (pPatient->iHealableInjury < 0) - pPatient->iHealableInjury = 0; - } - } - - // critical condition handled, now solve normal healing - - if ( pPatient->stats.bLife < pPatient->stats.bLifeMax ) - { - bPointsToUse = ( pPatient->stats.bLifeMax - pPatient->stats.bLife ); - - // if guy is hurt more than points we have...heal only what we have - if( bPointsToUse > usHealingPtsLeft ) - { - bPointsToUse = ( INT8 )usHealingPtsLeft; - } - - usHealingPtsLeft -= bPointsToUse; - - // heal person the amount - pPatient->stats.bLife += bPointsToUse; - - // SANDRO - doctor trait - when being healed normally, reduce insta-healable HPs value - if ( gGameOptions.fNewTraitSystem && pPatient->iHealableInjury > 0 ) - { - pPatient->iHealableInjury -= (bPointsToUse * 100); - if (pPatient->iHealableInjury < 0) - pPatient->iHealableInjury = 0; - } - } - - // if this patient is fully healed and cured - if ( pPatient->stats.bLife == pPatient->stats.bLifeMax ) - { - AssignmentDone( pPatient, TRUE, TRUE ); - } -} - - void HandleRepairmenInSector( INT16 sX, INT16 sY, INT8 bZ ) { SOLDIERTYPE *pSoldier, *pTeamSoldier; diff --git a/Strategic/Map Screen Helicopter.cpp b/Strategic/Map Screen Helicopter.cpp index 503dbe79..c480cddd 100644 --- a/Strategic/Map Screen Helicopter.cpp +++ b/Strategic/Map Screen Helicopter.cpp @@ -1925,7 +1925,7 @@ void CheckAndHandleSkyriderMonologues( void ) else if( guiHelicopterSkyriderTalkState == 1 ) { // if enemy still controls the Cambria hospital sector - if( StrategicMap[ CALCULATE_STRATEGIC_INDEX( HOSPITAL_SECTOR_X, HOSPITAL_SECTOR_Y ) ].fEnemyControlled ) + if ( StrategicMap[CALCULATE_STRATEGIC_INDEX( gModSettings.ubHospitalSectorX, gModSettings.ubHospitalSectorY )].fEnemyControlled ) { HandleSkyRiderMonologueEvent( SKYRIDER_MONOLOGUE_EVENT_CAMBRIA_HOSPITAL, 0 ); } @@ -1983,7 +1983,7 @@ void HandleAnimationOfSectors( void ) if( fShowCambriaHospitalHighLight ) { fOldShowCambriaHospitalHighLight = TRUE; - HandleBlitOfSectorLocatorIcon( HOSPITAL_SECTOR_X, HOSPITAL_SECTOR_Y, 0, LOCATOR_COLOR_RED ); + HandleBlitOfSectorLocatorIcon( gModSettings.ubHospitalSectorX, gModSettings.ubHospitalSectorY, 0, LOCATOR_COLOR_RED ); fSkipSpeakersLocator = TRUE; } else if( fOldShowCambriaHospitalHighLight ) diff --git a/Strategic/Strategic Event Handler.cpp b/Strategic/Strategic Event Handler.cpp index 927f24d8..b5c24db0 100644 --- a/Strategic/Strategic Event Handler.cpp +++ b/Strategic/Strategic Event Handler.cpp @@ -1090,7 +1090,7 @@ void HandleEarlyMorningEvents( void ) SetFactFalse( FACT_DAVE_HAS_GAS ); } - if ( gWorldSectorX == HOSPITAL_SECTOR_X && gWorldSectorY == HOSPITAL_SECTOR_Y && gbWorldSectorZ == HOSPITAL_SECTOR_Z ) + if ( gWorldSectorX == gModSettings.ubHospitalSectorX && gWorldSectorY == gModSettings.ubHospitalSectorY && gbWorldSectorZ == gModSettings.ubHospitalSectorZ ) { CheckForMissingHospitalSupplies(); } diff --git a/Strategic/Strategic Event Handler.h b/Strategic/Strategic Event Handler.h index 9aec99a6..caaaa9bd 100644 --- a/Strategic/Strategic Event Handler.h +++ b/Strategic/Strategic Event Handler.h @@ -7,10 +7,6 @@ #define KINGPIN_MONEY_SECTOR_Y gModSettings.ubKingpinMoneySectorY //MAP_ROW_D #define KINGPIN_MONEY_SECTOR_Z gModSettings.ubKingpinMoneySectorZ //1 -#define HOSPITAL_SECTOR_X gModSettings.ubHospitalSectorX //8 -#define HOSPITAL_SECTOR_Y gModSettings.ubHospitalSectorY //MAP_ROW_F -#define HOSPITAL_SECTOR_Z gModSettings.ubHospitalSectorZ //0 - extern UINT8 gubCambriaMedicalObjects; void CheckForKingpinsMoneyMissing( BOOLEAN fFirstCheck ); diff --git a/Strategic/strategicmap.cpp b/Strategic/strategicmap.cpp index e3330f0c..a260d141 100644 --- a/Strategic/strategicmap.cpp +++ b/Strategic/strategicmap.cpp @@ -2998,7 +2998,7 @@ void HandleQuestCodeOnSectorExit( INT16 sOldSectorX, INT16 sOldSectorY, INT8 bOl } } #endif - if ( sOldSectorX == HOSPITAL_SECTOR_X && sOldSectorY == HOSPITAL_SECTOR_Y && bOldSectorZ == HOSPITAL_SECTOR_Z ) + if ( sOldSectorX == gModSettings.ubHospitalSectorX && sOldSectorY == gModSettings.ubHospitalSectorY && bOldSectorZ == gModSettings.ubHospitalSectorZ ) { CheckForMissingHospitalSupplies( ); } diff --git a/Tactical/Handle UI.cpp b/Tactical/Handle UI.cpp index 01870720..57d9d585 100644 --- a/Tactical/Handle UI.cpp +++ b/Tactical/Handle UI.cpp @@ -2852,12 +2852,20 @@ UINT32 UIHandleCAMercShoot( UI_EVENT *pUIEvent ) fDidRequester = TRUE; - 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: 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 ) + { + 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) ); - DoMessageBox( MSG_BOX_BASIC_STYLE, zStr, GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, SurgeryRequesterCallback, NULL ); + DoMessageBox( MSG_BOX_BASIC_STYLE, zStr, GAME_SCREEN, ( UINT8 )MSG_BOX_FLAG_YESNO, SurgeryRequesterCallback, NULL ); + } } //////////////////////////////////////////////////////////////////////////////////////////////// }