From 40979fce1c67f48d83c15dfd3ab54d7811025725 Mon Sep 17 00:00:00 2001 From: Flugente Date: Fri, 26 Apr 2013 00:54:22 +0000 Subject: [PATCH] code changes: - the amount of food points one gets for eating now depends on the current food situation - food/drink percentage now goes from 0 to 200%, with 100% being the optimal value git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6024 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- Strategic/Map Screen Interface.cpp | 8 ++-- Tactical/Food.cpp | 59 +++++++++++++++++++----------- Tactical/Food.h | 7 ++-- Tactical/Interface Panels.cpp | 8 ++-- 4 files changed, 49 insertions(+), 33 deletions(-) diff --git a/Strategic/Map Screen Interface.cpp b/Strategic/Map Screen Interface.cpp index 1d09176a..7dc2d28e 100644 --- a/Strategic/Map Screen Interface.cpp +++ b/Strategic/Map Screen Interface.cpp @@ -1989,8 +1989,8 @@ void UpdateCharRegionHelpText( void ) pMapScreenStatusStrings[ 5 ], pSoldier->bPoisonBleeding, bPoisonBandaged, pSoldier->bPoisonLife, pSoldier->bPoisonSum, pMapScreenStatusStrings[ 1 ], pSoldier->bBreath, pSoldier->bBreathMax, pMapScreenStatusStrings[ 2 ], pMoraleStr, - pMapScreenStatusStrings[ 6 ], (INT32)(100*pSoldier->bDrinkLevel/FOOD_MAX), L"%", - pMapScreenStatusStrings[ 7 ], (INT32)(100*pSoldier->bFoodLevel/FOOD_MAX), L"%" ); + pMapScreenStatusStrings[ 6 ], (INT32)(100*(pSoldier->bDrinkLevel - FOOD_MIN) / FOOD_HALF_RANGE), L"%", + pMapScreenStatusStrings[ 7 ], (INT32)(100*(pSoldier->bFoodLevel - FOOD_MIN) / FOOD_HALF_RANGE), L"%" ); } else { @@ -1998,8 +1998,8 @@ void UpdateCharRegionHelpText( void ) pMapScreenStatusStrings[ 0 ], pSoldier->stats.bLife, pSoldier->stats.bLifeMax, pMapScreenStatusStrings[ 1 ], pSoldier->bBreath, pSoldier->bBreathMax, pMapScreenStatusStrings[ 2 ], pMoraleStr, - pMapScreenStatusStrings[ 6 ], (INT32)(100*pSoldier->bDrinkLevel/FOOD_MAX), L"%", - pMapScreenStatusStrings[ 7 ], (INT32)(100*pSoldier->bFoodLevel/FOOD_MAX), L"%" ); + pMapScreenStatusStrings[ 6 ], (INT32)(100*(pSoldier->bDrinkLevel - FOOD_MIN) / FOOD_HALF_RANGE), L"%", + pMapScreenStatusStrings[ 7 ], (INT32)(100*(pSoldier->bFoodLevel - FOOD_MIN) / FOOD_HALF_RANGE), L"%" ); } } else diff --git a/Tactical/Food.cpp b/Tactical/Food.cpp index 5202fba1..8329871e 100644 --- a/Tactical/Food.cpp +++ b/Tactical/Food.cpp @@ -67,6 +67,36 @@ FoodMoraleMod FoodMoraleMods[NUM_FOOD_MORALE_TYPES] = { -10000, -40, +3, -45, -45, 100}, // FOOD_STARVING }; +// Flugente: LootFragg had a nice idea: food intake should be non-linear. +// The idea is that for a starving person, a piece of food raises the food percentage more than it would for somebody overfed. +// I thus created the 'food integral'. The points we get from food depend on the situation we are in when we eat something +// As a result, we dont have to stuff unholy amounts of food in when we ar elow on food, but overfeeding gets harder. +// It is thus more reasonable to eat when you are hungry instead of stuffing like a bear before hibernation. + +FLOAT FoodEfficiency_Primitive( FLOAT aVal ) +{ + return aVal - aVal*aVal/FOOD_HALF_RANGE + aVal*aVal*aVal/(3*FOOD_HALF_RANGE*FOOD_HALF_RANGE); +} + +FLOAT FoodIntegral( INT32 a, INT32 b ) +{ + if ( a >= b ) + return 0.0; + + if ( a < FOOD_MIN ) a = FOOD_MIN; + if ( b > FOOD_MAX ) b = FOOD_MAX; + + return ( FoodEfficiency_Primitive( (FLOAT)b ) - FoodEfficiency_Primitive( (FLOAT)a ) ); +} + +void AddFoodpoints( INT32& arCurrentFood, INT32 aVal ) +{ + // the amount of points we get depends on our current food situation and the amount of food points + INT32 intake = FoodIntegral( arCurrentFood, arCurrentFood + aVal ); + + arCurrentFood = min(arCurrentFood + intake, FOOD_MAX); + arCurrentFood = max(arCurrentFood, FOOD_MIN); +} BOOLEAN ApplyFood( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject, BOOLEAN fForce, BOOLEAN fForceFromDrugs ) { @@ -157,11 +187,8 @@ BOOLEAN ApplyFood( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject, BOOLEAN fForce, B INT32 drinkpts = (INT32) (Food[foodtype].bDrinkPoints * percentualsize * conditionmodifier ); // eat it! - pSoldier->bFoodLevel = min(pSoldier->bFoodLevel + foodpts, FOOD_MAX); - pSoldier->bFoodLevel = max(pSoldier->bFoodLevel, FOOD_MIN); - - pSoldier->bDrinkLevel = min(pSoldier->bDrinkLevel + drinkpts, DRINK_MAX); - pSoldier->bDrinkLevel = max(pSoldier->bDrinkLevel, DRINK_MIN); + AddFoodpoints(pSoldier->bFoodLevel, foodpts); + AddFoodpoints(pSoldier->bDrinkLevel, drinkpts); /////////////////// MORALE ////////////////////// INT8 moralemod = Food[foodtype].bMoraleMod; @@ -346,7 +373,7 @@ void HourlyFoodSituationUpdate( SOLDIERTYPE *pSoldier ) // due to digestion, reduce our food and drink levels pSoldier->bFoodLevel = max(pSoldier->bFoodLevel - (INT32) (activitymodifier * gGameExternalOptions.usFoodDigestionHourlyBaseFood), FOOD_MIN); - pSoldier->bDrinkLevel = max(pSoldier->bDrinkLevel - (INT32) (activitymodifier * temperaturemodifier * gGameExternalOptions.usFoodDigestionHourlyBaseDrink), DRINK_MIN); + pSoldier->bDrinkLevel = max(pSoldier->bDrinkLevel - (INT32) (activitymodifier * temperaturemodifier * gGameExternalOptions.usFoodDigestionHourlyBaseDrink), FOOD_MIN); // there is a chance that we take damage to our health and strength stats if we are starving (or insanely obese :-) ) UINT8 foodsituation; @@ -540,16 +567,10 @@ void HourlyFoodAutoDigestion( SOLDIERTYPE *pSoldier ) // if we're thirsty or hungry, and this is nutritious, consume it if ( pSoldier->bDrinkLevel < FoodMoraleMods[FOOD_VERY_LOW].bThreshold ) - { - pSoldier->bDrinkLevel = min(pSoldier->bDrinkLevel + powwater, DRINK_MAX); - pSoldier->bDrinkLevel = max(pSoldier->bDrinkLevel, DRINK_MIN); - } + AddFoodpoints(pSoldier->bDrinkLevel, powwater); if ( pSoldier->bFoodLevel < FoodMoraleMods[FOOD_VERY_LOW].bThreshold ) - { - pSoldier->bFoodLevel = min(pSoldier->bFoodLevel + powfoodadd, FOOD_MAX); - pSoldier->bFoodLevel = max(pSoldier->bFoodLevel, FOOD_MIN); - } + AddFoodpoints(pSoldier->bDrinkLevel, powfoodadd); } else { @@ -576,16 +597,10 @@ void HourlyFoodAutoDigestion( SOLDIERTYPE *pSoldier ) // if we're thirsty or hungry, and this is nutritious, consume it. When in a cantina, we are willing to eat a bit more if ( pSoldier->bDrinkLevel < FoodMoraleMods[FOOD_MERC_STOP_FACILITY].bThreshold ) - { - pSoldier->bDrinkLevel = min(pSoldier->bDrinkLevel + cantinawater, DRINK_MAX); - pSoldier->bDrinkLevel = max(pSoldier->bDrinkLevel, DRINK_MIN); - } + AddFoodpoints(pSoldier->bDrinkLevel, cantinawater); if ( pSoldier->bFoodLevel < FoodMoraleMods[FOOD_MERC_STOP_FACILITY].bThreshold ) - { - pSoldier->bFoodLevel = min(pSoldier->bFoodLevel + cantinafoodadd, FOOD_MAX); - pSoldier->bFoodLevel = max(pSoldier->bFoodLevel, FOOD_MIN); - } + AddFoodpoints(pSoldier->bFoodLevel, cantinafoodadd); } } } diff --git a/Tactical/Food.h b/Tactical/Food.h index 504e981e..b00e92e4 100644 --- a/Tactical/Food.h +++ b/Tactical/Food.h @@ -4,9 +4,10 @@ #include "soldier control.h" #define FOOD_MIN - 20000 -#define FOOD_MAX 10000 -#define DRINK_MIN - 20000 -#define DRINK_MAX 10000 +#define FOOD_MAX 20000 + +#define FOOD_RANGE (FOOD_MAX - FOOD_MIN) +#define FOOD_HALF_RANGE (FOOD_RANGE / 2) typedef enum { diff --git a/Tactical/Interface Panels.cpp b/Tactical/Interface Panels.cpp index 7b91f10e..a0d2b15e 100644 --- a/Tactical/Interface Panels.cpp +++ b/Tactical/Interface Panels.cpp @@ -2950,11 +2950,11 @@ void RenderSMPanel( BOOLEAN *pfDirty ) // Flugente: added a display for poison, only show text if actually poisoned if ( gpSMCurrentMerc->bPoisonSum > 0 ) { - swprintf( pStr, TacticalStr[ MERC_VITAL_STATS_WITH_POISON_AND_FOOD_POPUPTEXT ], gpSMCurrentMerc->stats.bLife, gpSMCurrentMerc->stats.bLifeMax, gpSMCurrentMerc->bPoisonSum, gpSMCurrentMerc->stats.bLifeMax, gpSMCurrentMerc->bBreath, gpSMCurrentMerc->bBreathMax, pMoraleStr, (INT32)(100*gpSMCurrentMerc->bDrinkLevel/FOOD_MAX), L"%", (INT32)(100*gpSMCurrentMerc->bFoodLevel/FOOD_MAX), L"%" ); + swprintf( pStr, TacticalStr[ MERC_VITAL_STATS_WITH_POISON_AND_FOOD_POPUPTEXT ], gpSMCurrentMerc->stats.bLife, gpSMCurrentMerc->stats.bLifeMax, gpSMCurrentMerc->bPoisonSum, gpSMCurrentMerc->stats.bLifeMax, gpSMCurrentMerc->bBreath, gpSMCurrentMerc->bBreathMax, pMoraleStr, (INT32)(100*(gpSMCurrentMerc->bDrinkLevel - FOOD_MIN) / FOOD_HALF_RANGE), L"%", (INT32)(100*(gpSMCurrentMerc->bFoodLevel - FOOD_MIN) / FOOD_HALF_RANGE), L"%" ); } else { - swprintf( pStr, TacticalStr[ MERC_VITAL_STATS_WITH_FOOD_POPUPTEXT ], gpSMCurrentMerc->stats.bLife, gpSMCurrentMerc->stats.bLifeMax, gpSMCurrentMerc->bBreath, gpSMCurrentMerc->bBreathMax, pMoraleStr, (INT32)(100*gpSMCurrentMerc->bDrinkLevel/FOOD_MAX), L"%", (INT32)(100*gpSMCurrentMerc->bFoodLevel/FOOD_MAX), L"%" ); + swprintf( pStr, TacticalStr[ MERC_VITAL_STATS_WITH_FOOD_POPUPTEXT ], gpSMCurrentMerc->stats.bLife, gpSMCurrentMerc->stats.bLifeMax, gpSMCurrentMerc->bBreath, gpSMCurrentMerc->bBreathMax, pMoraleStr, (INT32)(100*(gpSMCurrentMerc->bDrinkLevel - FOOD_MIN) / FOOD_HALF_RANGE), L"%", (INT32)(100*(gpSMCurrentMerc->bFoodLevel - FOOD_MIN) / FOOD_HALF_RANGE), L"%" ); } } else @@ -5617,11 +5617,11 @@ void RenderTEAMPanel( BOOLEAN fDirty ) // Flugente: added a display for poison, only show text if actually poisoned if ( pSoldier->bPoisonSum > 0 ) { - swprintf( pStr, TacticalStr[ MERC_VITAL_STATS_WITH_POISON_AND_FOOD_POPUPTEXT ], pSoldier->stats.bLife, pSoldier->stats.bLifeMax, pSoldier->bPoisonSum, pSoldier->stats.bLifeMax, pSoldier->bBreath, pSoldier->bBreathMax, pMoraleStr, (INT32)(100*pSoldier->bDrinkLevel/FOOD_MAX), L"%", (INT32)(100*pSoldier->bFoodLevel/FOOD_MAX), L"%" ); + swprintf( pStr, TacticalStr[ MERC_VITAL_STATS_WITH_POISON_AND_FOOD_POPUPTEXT ], pSoldier->stats.bLife, pSoldier->stats.bLifeMax, pSoldier->bPoisonSum, pSoldier->stats.bLifeMax, pSoldier->bBreath, pSoldier->bBreathMax, pMoraleStr, (INT32)(100*(pSoldier->bDrinkLevel - FOOD_MIN) / FOOD_HALF_RANGE), L"%", (INT32)(100*(pSoldier->bFoodLevel - FOOD_MIN) / FOOD_HALF_RANGE), L"%" ); } else { - swprintf( pStr, TacticalStr[ MERC_VITAL_STATS_WITH_FOOD_POPUPTEXT ], pSoldier->stats.bLife, pSoldier->stats.bLifeMax, pSoldier->bBreath, pSoldier->bBreathMax, pMoraleStr, (INT32)(100*pSoldier->bDrinkLevel/FOOD_MAX), L"%", (INT32)(100*pSoldier->bFoodLevel/FOOD_MAX), L"%" ); + swprintf( pStr, TacticalStr[ MERC_VITAL_STATS_WITH_FOOD_POPUPTEXT ], pSoldier->stats.bLife, pSoldier->stats.bLifeMax, pSoldier->bBreath, pSoldier->bBreathMax, pMoraleStr, (INT32)(100*(pSoldier->bDrinkLevel - FOOD_MIN) / FOOD_HALF_RANGE), L"%", (INT32)(100*(pSoldier->bFoodLevel - FOOD_MIN) / FOOD_HALF_RANGE), L"%" ); } } else