diff --git a/Tactical/Drugs And Alcohol.cpp b/Tactical/Drugs And Alcohol.cpp index 7cdb6d92..db136396 100644 --- a/Tactical/Drugs And Alcohol.cpp +++ b/Tactical/Drugs And Alcohol.cpp @@ -256,7 +256,7 @@ BOOLEAN ApplyDrugs( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject ) fInterfacePanelDirty = DIRTYLEVEL2; if ( !consumeitem ) - ApplyFood( pSoldier, pObject ); + ApplyFood( pSoldier, pObject, TRUE ); return( TRUE ); } diff --git a/Tactical/Food.cpp b/Tactical/Food.cpp index 38e82492..077e2a74 100644 --- a/Tactical/Food.cpp +++ b/Tactical/Food.cpp @@ -58,8 +58,12 @@ FoodMoraleMod FoodMoraleMods[NUM_FOOD_MORALE_TYPES] = }; -BOOLEAN ApplyFood( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject ) +BOOLEAN ApplyFood( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject, BOOLEAN fForce ) { + // static variables to remember the last food someone was forced to eat + static UINT8 lasteater = 0; + static UINT16 lastitem = 0; + // how did this even happen? if ( !pSoldier || !pObject || !(pObject->exists() ) || (*pObject)[0]->data.objectStatus < 1 ) return( FALSE); @@ -96,16 +100,28 @@ BOOLEAN ApplyFood( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject ) // we have to determine wether the food is rotten, that might influence its condition and poison us FLOAT foodcondition = (*pObject)[0]->data.bTemperature / OVERHEATING_MAX_TEMPERATURE; - FLOAT conditionmodifier = 0.5f * (1.0f + sqrt(foodcondition)); - - FLOAT percentualsize = min(Food[foodtype].ubPortionSize, (*pObject)[0]->data.objectStatus) / 100.0f; - - INT32 foodpts = (INT32) (Food[foodtype].bFoodPoints * percentualsize * conditionmodifier ); - INT32 drinkpts = (INT32) (Food[foodtype].bDrinkPoints * percentualsize * conditionmodifier ); - + // food in bad condition is harmful! if ( foodcondition < FOOD_BAD_THRESHOLD ) { + // if we can choose to reject a food and haven't yet done so with this type of bad food, do so. Works only once + if ( !fForce && ( lasteater != pSoldier->ubID || lastitem != pObject->usItem) ) + { + lasteater = pSoldier->ubID; + lastitem = pObject->usItem; + + // notification + if ( type == AP_EAT ) + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s does not want to eat %s", pSoldier->name, Item[pObject->usItem].szItemName ); + else + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s does not want to drink %s", pSoldier->name, Item[pObject->usItem].szItemName ); + + // Say quote! + TacticalCharacterDialogue( pSoldier, 61 ); + + return( FALSE); + } + // determine the max nutritional value INT32 maxpts = max(Food[foodtype].bFoodPoints, Food[foodtype].bDrinkPoints); @@ -116,6 +132,13 @@ BOOLEAN ApplyFood( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject ) pSoldier->AddPoison(poisonadd); } + FLOAT conditionmodifier = 0.5f * (1.0f + sqrt(foodcondition)); + + FLOAT percentualsize = min(Food[foodtype].ubPortionSize, (*pObject)[0]->data.objectStatus) / 100.0f; + + INT32 foodpts = (INT32) (Food[foodtype].bFoodPoints * percentualsize * conditionmodifier ); + 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); @@ -506,7 +529,7 @@ void HourlyFoodAutoDigestion( SOLDIERTYPE *pSoldier ) if ( Item[pObj->usItem].drugtype > 0 ) ApplyDrugs( pSoldier, pObj ); else - ApplyFood( pSoldier, pObj ); + ApplyFood( pSoldier, pObj, TRUE ); // cannot reject to eat this, we chose to eat this ourself! // if we're full, finish if ( pSoldier->bFoodLevel > FoodMoraleMods[FOOD_MERC_START_CONSUME].bThreshold && pSoldier->bDrinkLevel > FoodMoraleMods[FOOD_MERC_START_CONSUME].bThreshold ) @@ -538,7 +561,7 @@ void HourlyFoodAutoDigestion( SOLDIERTYPE *pSoldier ) if ( Item[pObj->usItem].drugtype > 0 ) ApplyDrugs( pSoldier, pObj ); else - ApplyFood( pSoldier, pObj ); + ApplyFood( pSoldier, pObj, TRUE ); // cannot reject to eat this, we chose to eat this ourself! // if we're full, finish if ( pSoldier->bFoodLevel > FoodMoraleMods[FOOD_MERC_START_CONSUME].bThreshold && pSoldier->bDrinkLevel > FoodMoraleMods[FOOD_MERC_START_CONSUME].bThreshold ) diff --git a/Tactical/Food.h b/Tactical/Food.h index 52c07057..78000ae7 100644 --- a/Tactical/Food.h +++ b/Tactical/Food.h @@ -72,7 +72,8 @@ typedef enum WATER_POISONOUS // there is water, but it is poisoned (swamps and polluted sectors) } FoodSectorWaterSupply; -BOOLEAN ApplyFood( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject ); +// eat a food object. if fForce = FALSE, the soldier can reject to eat this once +BOOLEAN ApplyFood( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject, BOOLEAN fForce ); UINT8 GetFoodSituation( SOLDIERTYPE *pSoldier ); void FoodMaxMoraleModifiy( SOLDIERTYPE *pSoldier, UINT8* pubMaxMorale ); diff --git a/Tactical/Interface Enhanced.cpp b/Tactical/Interface Enhanced.cpp index 2b2ba9a4..69b878f3 100644 --- a/Tactical/Interface Enhanced.cpp +++ b/Tactical/Interface Enhanced.cpp @@ -2484,6 +2484,25 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr cnt++; } } + + //////////////////// EXTERNAL FEEDING + if ( gGameExternalOptions.ubExternalFeeding ) + { + if ( HasItemFlag(gpItemDescObject->usItem, AMMO_BELT) ) + { + swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 28 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 28 ]); + SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr ); + MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] ); + cnt++; + } + else if ( HasItemFlag(gpItemDescObject->usItem, AMMO_BELT_VEST) ) + { + swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[ 29 ], szUDBGenSecondaryStatsExplanationsTooltipText[ 29 ]); + SetRegionFastHelpText( &(gUDBFasthelpRegions[ iFirstDataRegion + cnt ]), pStr ); + MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] ); + cnt++; + } + } } ////////////////////////////////////////////////////// @@ -5476,7 +5495,7 @@ void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject ) cnt++; } - //////////////////// drinkable WATER + //////////////////// FOOD UINT32 foodtype = Item[gpItemDescObject->usItem].foodtype; if ( foodtype > 0 ) { @@ -5492,6 +5511,21 @@ void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject ) cnt++; } } + + //////////////////// EXTERNAL FEEDING + if ( gGameExternalOptions.ubExternalFeeding ) + { + if ( HasItemFlag(gpItemDescObject->usItem, AMMO_BELT) ) + { + BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 28, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL ); + cnt++; + } + else if ( HasItemFlag(gpItemDescObject->usItem, AMMO_BELT_VEST) ) + { + BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 29, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL ); + cnt++; + } + } } void DrawWeaponValues( OBJECTTYPE * gpItemDescObject ) diff --git a/Tactical/Interface Panels.cpp b/Tactical/Interface Panels.cpp index b02aaeed..01efe0d6 100644 --- a/Tactical/Interface Panels.cpp +++ b/Tactical/Interface Panels.cpp @@ -3342,7 +3342,7 @@ void SMInvClickCamoCallback( MOUSE_REGION * pRegion, INT32 iReason ) gpSMCurrentMerc->DoMercBattleSound( BATTLE_SOUND_COOL1 ); } - else if ( gGameOptions.fFoodSystem && ApplyFood( gpSMCurrentMerc, gpItemPointer ) ) + else if ( gGameOptions.fFoodSystem && ApplyFood( gpSMCurrentMerc, gpItemPointer, FALSE ) ) { // Dirty fInterfacePanelDirty = DIRTYLEVEL2; diff --git a/Utils/Text.h b/Utils/Text.h index 732c2dbc..6914fa05 100644 --- a/Utils/Text.h +++ b/Utils/Text.h @@ -639,8 +639,8 @@ extern STR16 szUDBGenAmmoStatsTooltipText[ 5 ]; // Flugente Overheating: 3 extern STR16 szUDBGenAmmoStatsExplanationsTooltipText[ 5 ]; // Flugente Overheating: 3->4 poison: 4->5 extern STR16 szUDBGenExplosiveStatsTooltipText[ 22 ]; extern STR16 szUDBGenExplosiveStatsExplanationsTooltipText[ 22 ]; -extern STR16 szUDBGenSecondaryStatsTooltipText[ 28 ]; // Flugente Food System: 26 -> 28 -extern STR16 szUDBGenSecondaryStatsExplanationsTooltipText[ 28 ]; // Flugente Food System: 26 -> 28 +extern STR16 szUDBGenSecondaryStatsTooltipText[ 30 ]; // Flugente Food System: 26 -> 28 external feeding: 28->30 +extern STR16 szUDBGenSecondaryStatsExplanationsTooltipText[ 30 ]; // Flugente Food System: 26 -> 28 external feeding: 28->30 extern STR16 szUDBAdvStatsTooltipText[ 57 ]; // Flugente Overheating Weapons: 48->56 poison: 56->57 extern STR16 szUDBAdvStatsExplanationsTooltipText[ 57 ]; // Flugente Overheating Weapons: 48->56 poison: 56->57 extern STR16 szUDBAdvStatsExplanationsTooltipTextForWeapons[ 52 ]; // Flugente Overheating Weapons: 48->52 diff --git a/Utils/_ChineseText.cpp b/Utils/_ChineseText.cpp index 2b9ad1b3..9c085285 100644 --- a/Utils/_ChineseText.cpp +++ b/Utils/_ChineseText.cpp @@ -7053,6 +7053,8 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|破|锁|炸|弹", L"|D|r|i|n|k",// TODO. Translate L"|M|e|a|l", + L"|A|m|m|o |B|e|l|t", + L"|A|m|m|o |V|e|s|t", }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -7085,6 +7087,8 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \n该物品能够用于爆破锁具。\n \n使用它需要爆破技能以避免过早引爆。\n \n使用炸药是一个相对简单的破锁手段,但是会\n发出很大噪音,并且对于大部分佣兵来说过于\n危险。", L"\n \nThis item will still your thirst\nif you drink it.",// TODO. Translate L"\n \nThis item will still your hunger\nif you eat it.", + L"\n \With this ammo belt you can\nfeed someone else's MG.", + L"\n \You can feed an MG with ammo\nbelts stored in this vest.", }; STR16 szUDBAdvStatsTooltipText[]= diff --git a/Utils/_DutchText.cpp b/Utils/_DutchText.cpp index 6fc2913d..b5869558 100644 --- a/Utils/_DutchText.cpp +++ b/Utils/_DutchText.cpp @@ -7048,6 +7048,8 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|L|o|c|k |B|o|m|b", L"|D|r|i|n|k",// TODO. Translate L"|M|e|a|l", + L"|A|m|m|o |B|e|l|t", + L"|A|m|m|o |V|e|s|t", }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -7080,6 +7082,8 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nThis item can be used to blast open locked\ndoors and containers.\n \nExplosives skill is required to avoid\npremature detonation.\n \nBlowing locks is a relatively easy way of quickly\ngetting through locked doors. However,\nit is very loud, and dangerous to most characters.", L"\n \nThis item will still your thirst\nif you drink it.",// TODO. Translate L"\n \nThis item will still your hunger\nif you eat it.", + L"\n \With this ammo belt you can\nfeed someone else's MG.", + L"\n \You can feed an MG with ammo\nbelts stored in this vest.", }; STR16 szUDBAdvStatsTooltipText[]= diff --git a/Utils/_EnglishText.cpp b/Utils/_EnglishText.cpp index 6a00948b..be417ec6 100644 --- a/Utils/_EnglishText.cpp +++ b/Utils/_EnglishText.cpp @@ -7040,6 +7040,8 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|L|o|c|k |B|o|m|b", L"|D|r|i|n|k", L"|M|e|a|l", + L"|A|m|m|o |B|e|l|t", + L"|A|m|m|o |V|e|s|t", }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -7072,6 +7074,8 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nThis item can be used to blast open locked\ndoors and containers.\n \nExplosives skill is required to avoid\npremature detonation.\n \nBlowing locks is a relatively easy way of quickly\ngetting through locked doors. However,\nit is very loud, and dangerous to most characters.", L"\n \nThis item will still your thirst\nif you drink it.", L"\n \nThis item will still your hunger\nif you eat it.", + L"\n \With this ammo belt you can\nfeed someone else's MG.", + L"\n \You can feed an MG with ammo\nbelts stored in this vest.", }; STR16 szUDBAdvStatsTooltipText[]= diff --git a/Utils/_FrenchText.cpp b/Utils/_FrenchText.cpp index d6b68350..35826469 100644 --- a/Utils/_FrenchText.cpp +++ b/Utils/_FrenchText.cpp @@ -7023,6 +7023,8 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|B|o|m|b|e |p|o|u|r |s|e|r|r|u|r|e |d|e |p|o|r|t|e", L"|D|r|i|n|k",// TODO. Translate L"|M|e|a|l", + L"|A|m|m|o |B|e|l|t", + L"|A|m|m|o |V|e|s|t", }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -7055,6 +7057,8 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nCet objet peut être utilisé pour faire sauter les portes\nou containeurs vérouillés.\n \nDes compétences en explosion sont nécessaire pour éviter\nune explosion prématurée.\n \nExploser les serrures est relativement facile et rapide\nà faire. Cependant, c'est très bruyant et dangereux pour\nla plupart des mercernaires.", L"\n \nThis item will still your thirst\nif you drink it.",// TODO. Translate L"\n \nThis item will still your hunger\nif you eat it.", + L"\n \With this ammo belt you can\nfeed someone else's MG.", + L"\n \You can feed an MG with ammo\nbelts stored in this vest.", }; STR16 szUDBAdvStatsTooltipText[]= diff --git a/Utils/_GermanText.cpp b/Utils/_GermanText.cpp index 630f4c41..26ff0385 100644 --- a/Utils/_GermanText.cpp +++ b/Utils/_GermanText.cpp @@ -6868,6 +6868,8 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|T|ü|r|s|p|r|e|n|g|s|a|t|z", L"|W|a|s|s|e|r", L"|N|a|h|r|u|n|g", + L"|M|u|n|i|t|i|o|n|s|g|u|r|t", + L"|M|u|n|i|t|i|o|n|s|w|e|s|t|e", }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -6900,6 +6902,8 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nDieser Gegenstand kann dazu benutzt werden verschlossene\nTüren/Behälter zu sprengen.\n \nExplosionsfertigkeit ist erforderlich um\nvorzeitige Detonationen zu vermeiden.\n \nSchlösser zu sprengen ist der einfache Weg um schnell\ndurch verschlossene Türen/Behälter zu kommen. Wie auch immer,\nes ist Laut und für die meisten Personen gefährlich.", L"\n \nMan kann das trinken.", L"\n \nMan kann das essen.", + L"\n \Ein externer Munitionsgurt für MGs.", + L"\n \In diese Weste passen auch Munitionsgurte.", }; STR16 szUDBAdvStatsTooltipText[]= diff --git a/Utils/_ItalianText.cpp b/Utils/_ItalianText.cpp index a097f388..55554c3e 100644 --- a/Utils/_ItalianText.cpp +++ b/Utils/_ItalianText.cpp @@ -7036,6 +7036,8 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|L|o|c|k |B|o|m|b", L"|D|r|i|n|k",// TODO. Translate L"|M|e|a|l", + L"|A|m|m|o |B|e|l|t", + L"|A|m|m|o |V|e|s|t", }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -7068,6 +7070,8 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nThis item can be used to blast open locked\ndoors and containers.\n \nExplosives skill is required to avoid\npremature detonation.\n \nBlowing locks is a relatively easy way of quickly\ngetting through locked doors. However,\nit is very loud, and dangerous to most characters.", L"\n \nThis item will still your thirst\nif you drink it.",// TODO. Translate L"\n \nThis item will still your hunger\nif you eat it.", + L"\n \With this ammo belt you can\nfeed someone else's MG.", + L"\n \You can feed an MG with ammo\nbelts stored in this vest.", }; STR16 szUDBAdvStatsTooltipText[]= diff --git a/Utils/_PolishText.cpp b/Utils/_PolishText.cpp index 67b7c2b2..46edffea 100644 --- a/Utils/_PolishText.cpp +++ b/Utils/_PolishText.cpp @@ -7046,6 +7046,8 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|L|o|c|k |B|o|m|b", L"|D|r|i|n|k",// TODO. Translate L"|M|e|a|l", + L"|A|m|m|o |B|e|l|t", + L"|A|m|m|o |V|e|s|t", }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -7078,6 +7080,8 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nThis item can be used to blast open locked\ndoors and containers.\n \nExplosives skill is required to avoid\npremature detonation.\n \nBlowing locks is a relatively easy way of quickly\ngetting through locked doors. However,\nit is very loud, and dangerous to most characters.", L"\n \nThis item will still your thirst\nif you drink it.",// TODO. Translate L"\n \nThis item will still your hunger\nif you eat it.", + L"\n \With this ammo belt you can\nfeed someone else's MG.", + L"\n \You can feed an MG with ammo\nbelts stored in this vest.", }; STR16 szUDBAdvStatsTooltipText[]= diff --git a/Utils/_RussianText.cpp b/Utils/_RussianText.cpp index b2bce73c..b5f43bfb 100644 --- a/Utils/_RussianText.cpp +++ b/Utils/_RussianText.cpp @@ -7014,6 +7014,8 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|Б|о|м|б|а |д|л|я |з|а|м|к|о|в", L"|D|r|i|n|k",// TODO. Translate L"|M|e|a|l", + L"|A|m|m|o |B|e|l|t", + L"|A|m|m|o |V|e|s|t", }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -7046,6 +7048,8 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nThis item can be used to blast open locked\ndoors and containers.\n \nExplosives skill is required to avoid\npremature detonation.\n \nBlowing locks is a relatively easy way of quickly\ngetting through locked doors. However,\nit is very loud, and dangerous to most characters.", L"\n \nThis item will still your thirst\nif you drink it.",// TODO. Translate L"\n \nThis item will still your hunger\nif you eat it.", + L"\n \With this ammo belt you can\nfeed someone else's MG.", + L"\n \You can feed an MG with ammo\nbelts stored in this vest.", }; STR16 szUDBAdvStatsTooltipText[]= diff --git a/Utils/_TaiwaneseText.cpp b/Utils/_TaiwaneseText.cpp index b9238e35..49544782 100644 --- a/Utils/_TaiwaneseText.cpp +++ b/Utils/_TaiwaneseText.cpp @@ -7051,6 +7051,8 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|L|o|c|k |B|o|m|b", L"|D|r|i|n|k",// TODO. Translate L"|M|e|a|l", + L"|A|m|m|o |B|e|l|t", + L"|A|m|m|o |V|e|s|t", }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -7083,6 +7085,8 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nThis item can be used to blast open locked\ndoors and containers.\n \nExplosives skill is required to avoid\npremature detonation.\n \nBlowing locks is a relatively easy way of quickly\ngetting through locked doors. However,\nit is very loud, and dangerous to most characters.", L"\n \nThis item will still your thirst\nif you drink it.",// TODO. Translate L"\n \nThis item will still your hunger\nif you eat it.", + L"\n \With this ammo belt you can\nfeed someone else's MG.", + L"\n \You can feed an MG with ammo\nbelts stored in this vest.", }; STR16 szUDBAdvStatsTooltipText[]=