diff --git a/GameSettings.cpp b/GameSettings.cpp index ed817817..107df533 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -1378,7 +1378,6 @@ void LoadGameExternalOptions() gGameExternalOptions.fDisplayOverheatThermometer = iniReader.ReadBoolean("Tactical Weapon Overheating Settings","OVERHEATING_DISPLAY_THERMOMETER",TRUE); gGameExternalOptions.ubOverheatThermometerRedOffset = iniReader.ReadInteger("Tactical Weapon Overheating Settings","OVERHEATING_DISPLAY_THERMOMETER_RED_OFFSET", 100, 0, 255); gGameExternalOptions.iCooldownModificatorLonelyBarrel = iniReader.ReadFloat ("Tactical Weapon Overheating Settings","OVERHEATING_COOLDOWN_MODIFICATOR_LONELYBARREL", 1.15f, 1.0f, 10.0f); - gGameExternalOptions.fSetZeroUponNewSector = iniReader.ReadBoolean("Tactical Weapon Overheating Settings","OVERHEATING_SET_ZERO_UPON_NEW_SECTOR",TRUE); #ifdef ENABLE_ZOMBIES //################# Tactical Zombie Settings ################## diff --git a/GameSettings.h b/GameSettings.h index 98f2e4ad..0f37420d 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -1128,7 +1128,6 @@ typedef struct BOOLEAN fDisplayOverheatThermometer; // Should a 'thermometer' for guns and replacable barrels be displayed? UINT8 ubOverheatThermometerRedOffset; // amount of red colour while temperature is below threshold FLOAT iCooldownModificatorLonelyBarrel; // Cooldown modificator for barrels alone in the landscape ;-) - BOOLEAN fSetZeroUponNewSector; // Should loading a new sector set the temperatures of all items in the old sector to zero? (this doesn't apply to inventories) // Flugente: Weapon Mounting BOOLEAN fWeaponResting; // Should it be possible to rest your weapon on structures in crouched position? diff --git a/Strategic/Map Screen Interface Map Inventory.cpp b/Strategic/Map Screen Interface Map Inventory.cpp index d21c68ef..585156a0 100644 --- a/Strategic/Map Screen Interface Map Inventory.cpp +++ b/Strategic/Map Screen Interface Map Inventory.cpp @@ -42,6 +42,7 @@ #include "Map Information.h"//dnl ch51 091009 #include "Interface Items.h" #include "Food.h" // added by Flugente +#include "Campaign Types.h" // added by Flugente //forward declarations of common classes to eliminate includes class OBJECTTYPE; @@ -234,6 +235,8 @@ extern MOUSE_REGION gMPanelRegion; extern void InternalMAPBeginItemPointer( SOLDIERTYPE *pSoldier ); +extern UINT32 GetLastTimePlayerWasInSector(INT16 sMapX, INT16 sMapY, INT8 sMapZ); // Flugente: get time for another sector + // HEADROCK HAM 5: Because BigItem graphics are not loaded into memory by default, we need to load them to // display the large map inventory. We save their indexes in this array: typedef struct @@ -291,8 +294,6 @@ INT32 MapScreenSectorInventoryCompare( const void *pNum1, const void *pNum2); void SortSectorInventory( std::vector& pInventory, UINT32 uiSizeOfArray ); BOOLEAN CanPlayerUseSectorInventory( SOLDIERTYPE *pSelectedSoldier ); -void BuildStashForSelectedSectorAndDecayFood( INT16 sMapX, INT16 sMapY, INT16 sMapZ ); // Flugente: for food decay - extern void MAPEndItemPointer( ); extern BOOLEAN GetCurrentBattleSectorXYZAndReturnTRUEIfThereIsABattle( INT16 *psSectorX, INT16 *psSectorY, INT16 *psSectorZ ); extern BOOLEAN MAPInternalInitItemDescriptionBox( OBJECTTYPE *pObject, UINT8 ubStatusIndex, SOLDIERTYPE *pSoldier ); @@ -749,6 +750,11 @@ void CreateDestroyMapInventoryPoolButtons( BOOLEAN fExitFromMapScreen ) // create buttons CreateMapInventoryButtons( ); + // Flugente: certain features need to alter an item's temperature value depending on the time passed + // if we do these functions here and adjust for the time passed since this sector was loaded last, it will seem to the player + // as if these checks are always performed in any sector + SectorInventoryCooldownFunctions(sSelMapX, sSelMapY, ( INT16 )( iCurrentMapSectorZ )); + // build stash BuildStashForSelectedSector( sSelMapX, sSelMapY, ( INT16 )( iCurrentMapSectorZ ) ); @@ -5024,13 +5030,14 @@ void HandleSetFilterButtons() } } -void BuildStashForSelectedSectorAndDecayFood( INT16 sMapX, INT16 sMapY, INT16 sMapZ ) +// Flugente: handle various cooldown functions in a sector +void SectorInventoryCooldownFunctions( INT16 sMapX, INT16 sMapY, INT16 sMapZ ) { UINT32 uiTotalNumberOfRealItems = 0; WORLDITEM * pTotalSectorList = NULL; // #ifdef _DEBUG - BOOLEAN fReturn = TRUE; + BOOLEAN fReturn = TRUE; // #endif // now load these items into memory, based on fact if sector is in fact loaded @@ -5063,12 +5070,105 @@ void BuildStashForSelectedSectorAndDecayFood( INT16 sMapX, INT16 sMapY, INT16 sM LoadWorldItemsFromTempItemFile( sMapX, sMapY, ( INT8 ) ( sMapZ ), pTotalSectorList ); } } - - //Check to see if any of the items in the list have a gridno of NOWHERE and the entry point flag NOT set - //CheckGridNoOfItemsInMapScreenMapInventory(); - - SectorFoodDecay( pTotalSectorList, uiTotalNumberOfRealItems ); + + HandleSectorCooldownFunctions( sMapX, sMapY, (INT8)sMapZ, pTotalSectorList, uiTotalNumberOfRealItems, TRUE ); //Save the Items to the the file SaveWorldItemsToTempItemFile( sMapX, sMapY, (INT8)sMapZ, uiTotalNumberOfRealItems, pTotalSectorList ); +} + +// Flugente: handle various cooldwon functions over an array of items in a specific sector. +// if fWithMinutes = true, adjust cooldown for time since sector was last entered +// otherwise its used for a turn-precise cooldown +void HandleSectorCooldownFunctions( INT16 sMapX, INT16 sMapY, INT8 sMapZ, WORLDITEM* pWorldItem, UINT32 size, BOOLEAN fWithMinutes ) +{ + // if not using overheating or food system, no point in all this + if ( !gGameOptions.fWeaponOverheating && !gGameOptions.fFoodSystem ) + return; + + UINT32 tickspassed = 1; + + if ( fWithMinutes ) + { + INT32 sMinutesPassed = __max(0, GetWorldTotalMin() - GetLastTimePlayerWasInSector(sMapX, sMapY, sMapZ) ); + + if ( sMinutesPassed == 0 ) + return; + + // it is assumed that one turn equals to 5 seconds + tickspassed = 12*sMinutesPassed; + } + + FLOAT foofdecaymod = tickspassed * gGameExternalOptions.sFoodDecayModificator; + + // food decays slower if underground + if ( sMapZ > 0 ) + foofdecaymod *= 0.8f; + + for( UINT32 uiCount = 0; uiCount < size; ++uiCount ) // ... for all items in the world ... + { + if( pWorldItem[ uiCount ].fExists ) // ... if item exists ... + { + OBJECTTYPE* pObj = &(pWorldItem[ uiCount ].object); // ... get pointer for this item ... + + if ( pObj != NULL ) // ... if pointer is not obviously useless ... + { + // ... if we use overheating and item is a gun, a launcher or a barrel ... + if ( gGameOptions.fWeaponOverheating && ( Item[pWorldItem[ uiCount ].object.usItem].usItemClass & (IC_GUN|IC_LAUNCHER) || Item[pWorldItem[ uiCount ].object.usItem].barrel == TRUE ) ) + { + for(INT16 i = 0; i < pObj->ubNumberOfObjects; ++i) // ... there might be multiple items here (item stack), so for each one ... + { + FLOAT guntemperature = (*pObj)[i]->data.bTemperature; // ... get temperature ... + + FLOAT cooldownfactor = GetItemCooldownFactor(pObj); // ... get item cooldown factor provided of attachments ... + + if ( Item[pWorldItem[ uiCount ].object.usItem].barrel == TRUE ) // ... a barrel lying around cools down a bit faster ... + cooldownfactor *= gGameExternalOptions.iCooldownModificatorLonelyBarrel; + + FLOAT newguntemperature = max(0.0f, guntemperature - tickspassed * cooldownfactor); // ... calculate new temperature ... + +#if 0//def JA2TESTVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"World: Item temperature lowered from %4.2f to %4.2f", guntemperature, newguntemperature ); +#endif + + (*pObj)[i]->data.bTemperature = newguntemperature; // ... set new temperature + + // for every objects, we also have to check wether there are weapon attachments (eg. underbarrel weapons), and cool them down too + attachmentList::iterator iterend = (*pObj)[i]->attachments.end(); + for (attachmentList::iterator iter = (*pObj)[i]->attachments.begin(); iter != iterend; ++iter) + { + if ( iter->exists() && Item[ iter->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) ) + { + FLOAT temperature = (*iter)[i]->data.bTemperature; // ... get temperature of item ... + + FLOAT cooldownfactor = GetItemCooldownFactor( &(*iter) ); // ... get cooldown factor ... + + FLOAT newtemperature = max(0.0f, temperature - tickspassed * cooldownfactor); // ... calculate new temperature ... + + (*iter)[i]->data.bTemperature = newtemperature; // ... set new temperature + +#if 0//def JA2TESTVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"World: Item temperature lowered from %4.2f to %4.2f", temperature, newtemperature ); +#endif + + // we assume that there can exist only 1 underbarrel weapon per gun + break; + } + } + } + } + + if ( gGameOptions.fFoodSystem && Item[pWorldItem[ uiCount ].object.usItem].foodtype > 0 ) // ... if it is food and the food system is active ... + { + if ( Food[Item[pObj->usItem].foodtype].usDecayRate > 0.0f ) // ... if the food can decay... + { + for(INT16 i = 0; i < pObj->ubNumberOfObjects; ++i) // ... there might be multiple items here (item stack), so for each one ... + { + (*pObj)[i]->data.bTemperature = max(0.0f, (*pObj)[i]->data.bTemperature - foofdecaymod * Food[Item[pObj->usItem].foodtype].usDecayRate); // set new temperature + } + } + } + } + } + } } \ No newline at end of file diff --git a/Strategic/Map Screen Interface Map Inventory.h b/Strategic/Map Screen Interface Map Inventory.h index f24265db..382caa5e 100644 --- a/Strategic/Map Screen Interface Map Inventory.h +++ b/Strategic/Map Screen Interface Map Inventory.h @@ -75,4 +75,12 @@ BOOLEAN SaveInventoryPoolQ(UINT8 ubSaveGameID); BOOLEAN SortInventoryPoolQ(void); BOOLEAN SwitchToInventoryPoolQ(UINT8 newidx); -#endif \ No newline at end of file +#endif + +// Flugente: handle various cooldown functions in a sector +void SectorInventoryCooldownFunctions( INT16 sMapX, INT16 sMapY, INT16 sMapZ ); + +// Flugente: handle various cooldown functions over an array of items in a specific sector. +// if fWithMinutes = true, adjust cooldown for time since sector was last entered +// otherwise its used for a turn-precise cooldown +void HandleSectorCooldownFunctions( INT16 sMapX, INT16 sMapY, INT8 sMapZ, WORLDITEM* pWorldItem, UINT32 size, BOOLEAN fWithMinutes ); \ No newline at end of file diff --git a/Strategic/strategicmap.cpp b/Strategic/strategicmap.cpp index d414eb73..e9777b32 100644 --- a/Strategic/strategicmap.cpp +++ b/Strategic/strategicmap.cpp @@ -135,6 +135,8 @@ #include "sgp_logger.h" +#include "Map Screen Interface Map Inventory.h" // added by Flugente + //forward declarations of common classes to eliminate includes class OBJECTTYPE; class SOLDIERTYPE; @@ -3001,6 +3003,11 @@ BOOLEAN EnterSector( INT16 sSectorX, INT16 sSectorY , INT8 bSectorZ ) // This function will either hide or display the tree tops, depending on the game setting SetTreeTopStateForMap(); + // Flugente: certain features need to alter an item's temperature value depending on the time passed + // if we do these functions here and adjust for the time passed since this sector was loaded last, it will seem to the player + // as if these checks are always performed in any sector + SectorInventoryCooldownFunctions(sSectorX, sSectorY, bSectorZ); + return TRUE; //because the map was loaded. } @@ -6113,9 +6120,6 @@ BOOLEAN HandleDefiniteUnloadingOfWorld( UINT8 ubUnloadCode ) //if we arent loading a saved game if( !(gTacticalStatus.uiFlags & LOADING_SAVED_GAME ) ) { - // Flugente: Set temperatures of all items in the old sector to zero before entering a new sector - CoolDownWorldItems( TRUE ); - // Save the current sectors Item list to a temporary file, if its not the first time in SaveCurrentSectorsInformationToTempItemFile(); diff --git a/Tactical/Food.cpp b/Tactical/Food.cpp index c44b0879..53c26a3d 100644 --- a/Tactical/Food.cpp +++ b/Tactical/Food.cpp @@ -38,7 +38,6 @@ UINT8 gSectorWaterType[256][4]; //extern BOOLEAN HandleSoldierDeath( SOLDIERTYPE *pSoldier , BOOLEAN *pfMadeCorpse ); //extern BOOLEAN TacticalRemoveSoldier( UINT16 usSoldierIndex ); extern BOOLEAN GetSectorFlagStatus( INT16 sMapX, INT16 sMapY, UINT8 bMapZ, UINT32 uiFlagToSet ); -extern void BuildStashForSelectedSectorAndDecayFood( INT16 sMapX, INT16 sMapY, INT16 sMapZ ); // these midifiers are applied separately for both food and water // apart from the ubStatDamageChance values, be careful not to set any modifiers below -50 or above 0 unless you know what you are doing!!! @@ -699,9 +698,6 @@ void HourlyFoodUpdate( void ) HourlyFoodAutoDigestion( pSoldier ); } } - - // decay food everywhere - HourlyFoodDecay(); } UINT8 GetWaterQuality(INT16 asMapX, INT16 asMapY, INT8 asMapZ) @@ -970,135 +966,3 @@ OBJECTTYPE* GetUsableWaterDrumInSector( void ) return( NULL ); } -void HourlyFoodDecay( void ) -{ - // decay food in all inventories - UINT32 cnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID; - for ( SOLDIERTYPE* pSoldier = MercPtrs[ cnt ]; cnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; cnt++, pSoldier++) - { - if ( pSoldier && pSoldier->bActive ) - { - pSoldier->SoldierInventoryFoodDecay(); - } - } - - if ( gGameExternalOptions.fFoodDecayInSectors ) - { - INT16 currentSectorX = gWorldSectorX; - INT16 currentSectorY = gWorldSectorY; - INT8 currentSectorZ = gbWorldSectorZ; - - // decay food in all visited sectors - for ( INT16 sbMapX = 1; sbMapX < MAP_WORLD_X - 1; ++sbMapX ) - { - for ( INT16 sbMapY = 1; sbMapY < MAP_WORLD_Y - 1; ++sbMapY ) - { - for ( UINT8 ubMapZ = 0; ubMapZ < 4; ++ubMapZ ) - { - // only if sector has already been visisted - if( GetSectorFlagStatus( sbMapX, sbMapY, ubMapZ, SF_ALREADY_VISITED ) == TRUE ) - { - BuildStashForSelectedSectorAndDecayFood(sbMapX, sbMapY, (INT16)ubMapZ); - } - } - } - } - } -} - -void SectorFoodDecay( WORLDITEM* pWorldItem, UINT32 size ) -{ - // one hour has 60 minutes, with 12 5-second-intervals (cooldown values are based on 5-second values) - FLOAT decaymod = 12*60*gGameExternalOptions.sFoodDecayModificator; - - for( UINT32 uiCount = 0; uiCount < size; ++uiCount ) // ... for all items in the world ... - { - if( pWorldItem[ uiCount ].fExists ) // ... if item exists ... - { - if ( Item[pWorldItem[ uiCount ].object.usItem].foodtype > 0 ) // ... if is food... - { - OBJECTTYPE* pObj = &(pWorldItem[ uiCount ].object); // ... get pointer for this item ... - - if ( pObj != NULL ) // ... if pointer is not obviously useless ... - { - if ( Food[Item[pObj->usItem].foodtype].usDecayRate > 0.0f ) // ... if the food can decay... - { - for(INT16 i = 0; i < pObj->ubNumberOfObjects; ++i) // ... there might be multiple items here (item stack), so for each one ... - { - (*pObj)[i]->data.bTemperature = max(0.0f, (*pObj)[i]->data.bTemperature - decaymod * Food[Item[pObj->usItem].foodtype].usDecayRate); // set new temperature - } - } - } - } - } - } -} - -// commented out, as we now look for an xml value. Might be relevant in the future, though -/*BOOLEAN DrinkableWaterInSector(INT16 asMapX, INT16 asMapY, INT8 asMapZ) -{ - // static variables allow us to remember the result of the last time this function was called - this way, only one call per sector is required - static INT16 sMapX = 0; - static INT16 sMapY = 0; - static INT8 sMapZ = 0; - static BOOLEAN drinkablewaterfound = FALSE; - - if ( asMapX != sMapX || asMapY != sMapY || asMapZ != sMapZ ) - { - drinkablewaterfound = FALSE; - - for( INT32 sGridNo = 0; sGridNo < MAX_MAP_POS; ++sGridNo ) - { - if ( Water(sGridNo) || IsKitchenFurnitureWaterSource(sGridNo) ) - { - drinkablewaterfound = TRUE; - break; - } - } - - UINT8 ubSectorId = SECTOR(asMapX, asMapY); - if (ubSectorId >= 0 && ubSectorId < 256 && gSectorWaterType[ubSectorId][asMapZ] == WATER_DRINKABLE ) - { - drinkablewaterfound = TRUE; - } - - sMapX = asMapX; - sMapY = asMapY; - sMapZ = asMapZ; - } - - return drinkablewaterfound; -}*/ - -// commented out, as we now look for an xml value. Might be relevant in the future, though -/*// determine wether there is a kitechen furniture here (we assume its a sink, so it'll have water) -BOOLEAN IsKitchenFurnitureWaterSource( INT32 sGridNo ) -{ - STRUCTURE* pStruct = FindStructure(sGridNo, STRUCTURE_GENERIC); - - if ( pStruct != NULL ) - { - // Get LEVELNODE for struct and remove! - LEVELNODE* pNode = FindLevelNodeBasedOnStructure( pStruct->sGridNo, pStruct ); - - if ( pNode ) - { - UINT32 uiTileType = 0; - if ( GetTileType( pNode->usIndex, &uiTileType ) ) - { - UINT16 usIndex = pNode->usIndex; - - // Check if we are a sandbag - if ( ( _strnicmp( gTilesets[ giCurrentTilesetID ].TileSurfaceFilenames[ uiTileType ], "furn_6.sti", 10) == 0 ) || - ( _strnicmp( gTilesets[ giCurrentTilesetID ].TileSurfaceFilenames[ uiTileType ], "old_furn.sti", 12) == 0 ) || - ( _strnicmp( gTilesets[ giCurrentTilesetID ].TileSurfaceFilenames[ uiTileType ], "furnmix.sti", 11) == 0 ) || - ( _strnicmp( gTilesets[ giCurrentTilesetID ].TileSurfaceFilenames[ uiTileType ], "furn_mix.sti", 12) == 0 ) ) - { - return TRUE; - } - } - } - } - - return FALSE; -}*/ diff --git a/Tactical/Food.h b/Tactical/Food.h index 62102313..a1fd5087 100644 --- a/Tactical/Food.h +++ b/Tactical/Food.h @@ -96,15 +96,4 @@ void SectorFillCanteens( void ); OBJECTTYPE* GetUsableWaterDrumInSector( void ); -void HourlyFoodDecay( void ); - -// Decay the food in a sector, performed every hour -void SectorFoodDecay( WORLDITEM* pWorldItem, UINT32 size ); - -// checks wether there is any drinkable water source in this sector. Atm every water found is taken as 'drinkable' -//BOOLEAN DrinkableWaterInSector(INT16 asMapX, INT16 asMapY, INT8 asMapZ); - -// determine wether there is a kitechen furniture here (we assume its a sink, so it'll have water) -//BOOLEAN IsKitchenFurnitureWaterSource( INT32 sGridNo ); - #endif diff --git a/Tactical/Interface Enhanced.cpp b/Tactical/Interface Enhanced.cpp index 658c2700..0f85488a 100644 --- a/Tactical/Interface Enhanced.cpp +++ b/Tactical/Interface Enhanced.cpp @@ -3939,7 +3939,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr ///////////////////// poison percentage // only draw if item is poisoned in any way - if ( Item[gpItemDescObject->usItem].bPoisonPercentage != 0 || (Item[gpItemDescObject->usItem].usItemClass == IC_GUN && AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].poisonPercentage != 0 ) ) + if ( Item[gpItemDescObject->usItem].bPoisonPercentage != 0 || ( (Item[gpItemDescObject->usItem].usItemClass & IC_GUN) && AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].poisonPercentage != 0 ) ) { if (cnt >= sFirstLine && cnt < sLastLine) { @@ -5252,7 +5252,7 @@ void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject ) ///////////////////// poison percentage // only draw if item is poisoned in any way - if ( Item[gpItemDescObject->usItem].bPoisonPercentage != 0 || (Item[gpItemDescObject->usItem].usItemClass == IC_GUN && AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].poisonPercentage != 0 ) ) + if ( Item[gpItemDescObject->usItem].bPoisonPercentage != 0 || ( (Item[gpItemDescObject->usItem].usItemClass & IC_GUN) && AmmoTypes[Magazine[ Item[ gpItemDescObject->usItem ].ubClassIndex].ubAmmoType].poisonPercentage != 0 ) ) { if (cnt >= sFirstLine && cnt < sLastLine) { diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index 7eaab63b..93a8ac09 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -7355,11 +7355,8 @@ void SOLDIERTYPE::EVENT_BeginMercTurn( BOOLEAN fFromRealTime, INT32 iRealTimeCou this->sOldXPos = sStartPosX; this->sOldYPos = sStartPosY; - // Flugente FTW 1: Cool down all weapons in inventory - if ( gGameOptions.fWeaponOverheating ) - { - this->SoldierInventoryCoolDown(); - } + // Flugente: Cool down all weapons and decay food in inventory + this->SoldierInventoryCoolDown(); } // UTILITY FUNCTIONS CALLED BY OVERHEAD.H @@ -13242,57 +13239,81 @@ BOOLEAN SOLDIERTYPE::SoldierCarriesTwoHandedWeapon( void ) return( FALSE ); } -// Flugente FTW 1: Cool down all items in inventory +// Flugente: Cool down/decay all items in inventory void SOLDIERTYPE::SoldierInventoryCoolDown(void) { - INT8 invsize = (INT8)this->inv.size(); // remember inventorysize, so we don't call size() repeatedly + if ( !gGameOptions.fWeaponOverheating && !gGameOptions.fFoodSystem ) + return; - for ( INT8 bLoop = 0; bLoop < invsize; ++bLoop) // ... for all items in our inventory ... - { - // ... if Item exists and is a gun, a launcher or a barrel ... - if (this->inv[bLoop].exists() == true && ( Item[this->inv[bLoop].usItem].usItemClass & (IC_GUN|IC_LAUNCHER) || Item[this->inv[bLoop].usItem].barrel == TRUE ) ) + // one hour has 60 minutes, with 12 5-second-intervals (cooldown values are based on 5-second values) + FLOAT fooddecaymod = gGameExternalOptions.sFoodDecayModificator; + + // food decays slower if underground + if ( gbWorldSectorZ > 0 ) + fooddecaymod *= 0.8f; + + INT8 invsize = (INT8)this->inv.size(); // remember inventorysize, so we don't call size() repeatedly + + for ( INT8 bLoop = 0; bLoop < invsize; ++bLoop) // ... for all items in our inventory ... { - OBJECTTYPE * pObj = &(this->inv[bLoop]); // ... get pointer for this item ... - - if ( pObj != NULL ) // ... if pointer is not obviously useless ... + if ( this->inv[bLoop].exists() ) { - for(INT16 i = 0; i < pObj->ubNumberOfObjects; ++i) // ... there might be multiple items here (item stack), so for each one ... + OBJECTTYPE * pObj = &(this->inv[bLoop]); // ... get pointer for this item ... + + if ( pObj != NULL ) // ... if pointer is not obviously useless ... { - FLOAT temperature = (*pObj)[i]->data.bTemperature; // ... get temperature of item ... - - FLOAT cooldownfactor = GetItemCooldownFactor(pObj); // ... get cooldown factor ... - - FLOAT newtemperature = max(0.0f, temperature - cooldownfactor); // ... calculate new temperature ... - (*pObj)[i]->data.bTemperature = newtemperature; // ... set new temperature - -#if 0//def JA2TESTVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Item temperature lowered from %4.2f to %4.2f", temperature, newtemperature ); -#endif - // for every objects, we also have to check wether there are weapon attachments (eg. underbarrel grenade launchers), and cool them down too - attachmentList::iterator iterend = (*pObj)[i]->attachments.end(); - for (attachmentList::iterator iter = (*pObj)[i]->attachments.begin(); iter != iterend; ++iter) + // ... if Item exists and is a gun, a launcher or a barrel ... + if ( gGameOptions.fWeaponOverheating && ( Item[pObj->usItem].usItemClass & (IC_GUN|IC_LAUNCHER) || Item[pObj->usItem].barrel == TRUE ) ) { - if ( iter->exists() && Item[ iter->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) ) + for(INT16 i = 0; i < pObj->ubNumberOfObjects; ++i) // ... there might be multiple items here (item stack), so for each one ... { - FLOAT temperature = (*iter)[i]->data.bTemperature; // ... get temperature of item ... + FLOAT temperature = (*pObj)[i]->data.bTemperature; // ... get temperature of item ... - FLOAT cooldownfactor = GetItemCooldownFactor( &(*iter) ); // ... get cooldown factor ... + FLOAT cooldownfactor = GetItemCooldownFactor(pObj); // ... get cooldown factor ... FLOAT newtemperature = max(0.0f, temperature - cooldownfactor); // ... calculate new temperature ... - (*iter)[i]->data.bTemperature = newtemperature; // ... set new temperature + (*pObj)[i]->data.bTemperature = newtemperature; // ... set new temperature #if 0//def JA2TESTVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Item temperature lowered from %4.2f to %4.2f", temperature, newtemperature ); + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Item temperature lowered from %4.2f to %4.2f", temperature, newtemperature ); +#endif + // for every objects, we also have to check wether there are weapon attachments (eg. underbarrel grenade launchers), and cool them down too + attachmentList::iterator iterend = (*pObj)[i]->attachments.end(); + for (attachmentList::iterator iter = (*pObj)[i]->attachments.begin(); iter != iterend; ++iter) + { + if ( iter->exists() && Item[ iter->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) ) + { + FLOAT temperature = (*iter)[i]->data.bTemperature; // ... get temperature of item ... + + FLOAT cooldownfactor = GetItemCooldownFactor( &(*iter) ); // ... get cooldown factor ... + + FLOAT newtemperature = max(0.0f, temperature - cooldownfactor); // ... calculate new temperature ... + (*iter)[i]->data.bTemperature = newtemperature; // ... set new temperature + +#if 0//def JA2TESTVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"Item temperature lowered from %4.2f to %4.2f", temperature, newtemperature ); #endif - // we assume that there can exist only 1 UGL per weapon - break; + // we assume that there can exist only 1 UGL per weapon + break; + } + } + } + } + + if ( gGameOptions.fFoodSystem && Item[pObj->usItem].foodtype > 0 ) + { + if ( Food[Item[pObj->usItem].foodtype].usDecayRate > 0.0f ) // ... if the food can decay... + { + for(INT16 i = 0; i < pObj->ubNumberOfObjects; ++i) // ... there might be multiple items here (item stack), so for each one ... + { + (*pObj)[i]->data.bTemperature = max(0.0f, (*pObj)[i]->data.bTemperature - fooddecaymod * Food[Item[pObj->usItem].foodtype].usDecayRate); // set new temperature + } } } } } } - } } // Flugente: determine if we can rest our weapon on something. This ca6n only happen when STANDING/CROUCHED. As a result, we get superior handling modifiers (we apply the PRONE modfiers) @@ -13669,33 +13690,6 @@ void SOLDIERTYPE::InventoryExplosion( void ) } } -// Flugente: Food decay in inventory (once an hour) -void SOLDIERTYPE::SoldierInventoryFoodDecay(void) -{ - if ( !gGameOptions.fFoodSystem ) - return; - - // one hour has 60 minutes, with 12 5-second-intervals (cooldown values are based on 5-second values) - FLOAT decaymod = 12*60*gGameExternalOptions.sFoodDecayModificator; - - INT8 invsize = (INT8)this->inv.size(); // remember inventorysize, so we don't call size() repeatedly - for ( INT8 bLoop = 0; bLoop < invsize; ++bLoop) // ... for all items in our inventory ... - { - if ( Item[this->inv[bLoop].usItem].foodtype > 0 ) // food decays - { - OBJECTTYPE * pObj = &(this->inv[bLoop]); // ... get pointer for this item ... - - if ( pObj != NULL ) // ... if pointer is not obviously useless ... - { - for(INT16 i = 0; i < pObj->ubNumberOfObjects; ++i) // ... there might be multiple items here (item stack), so for each one ... - { - (*pObj)[i]->data.bTemperature = max(0.0f, (*pObj)[i]->data.bTemperature - decaymod * Food[Item[pObj->usItem].foodtype].usDecayRate); // set new temperature - } - } - } - } -} - // Flugente: do we currently provide ammo (pAmmoSlot) for someone else's (pubId) gun (pGunSlot)? BOOLEAN SOLDIERTYPE::IsFeedingExternal(UINT8* pubId1, UINT16* pGunSlot1, UINT16* pAmmoSlot1, UINT8* pubId2, UINT16* pGunSlot2, UINT16* pAmmoSlot2) { diff --git a/Tactical/Soldier Control.h b/Tactical/Soldier Control.h index 7cabedc3..51322b46 100644 --- a/Tactical/Soldier Control.h +++ b/Tactical/Soldier Control.h @@ -1403,7 +1403,7 @@ public: BOOLEAN IsValidSecondHandShot( void ); BOOLEAN IsValidSecondHandShotForReloadingPurposes( void ); BOOLEAN SoldierCarriesTwoHandedWeapon( void ); - void SoldierInventoryCoolDown( void ); // Flugente FTW 1: Cool down all items in inventory + void SoldierInventoryCoolDown( void ); // Flugente: Cool down/decay all items in inventory BOOLEAN IsWeaponMounted( void ); // determine if we receive a bonus for mounting our weapon on something OBJECTTYPE* GetUsedWeapon( OBJECTTYPE * pObj ); // if in an underbarrel fire mode, return underbarrel weapon UINT16 GetUsedWeaponNumber( OBJECTTYPE * pObj ); // if in an underbarrel fire mode, return number of underbarrel weapon @@ -1434,9 +1434,6 @@ public: // Flugente: inventory bombs can ignite while in mapscreen. Workaround: Damage items and health void InventoryExplosion( void ); - // Flugente: Food decay in inventory - void SoldierInventoryFoodDecay( void ); - // Flugente: do we currently provide ammo (pAmmoSlot) for someone else's (pubId) gun (pGunSlot)? BOOLEAN IsFeedingExternal(UINT8* pubId1, UINT16* pGunSlot1, UINT16* pAmmoSlot1, UINT8* pubId2, UINT16* pGunSlot2, UINT16* pAmmoSlot2); ////////////////////////////////////////////////////////////////////////////// diff --git a/Tactical/Tactical Save.cpp b/Tactical/Tactical Save.cpp index 1338dd86..f7031665 100644 --- a/Tactical/Tactical Save.cpp +++ b/Tactical/Tactical Save.cpp @@ -129,6 +129,7 @@ BOOLEAN InitTempNpcQuoteInfoForNPCFromTempFile(); BOOLEAN SaveTempNpcQuoteInfoForNPCToTempFile( UINT8 ubNpcId ); BOOLEAN LoadTempNpcQuoteInfoForNPCFromTempFile( UINT8 ubNpcId ); UINT32 GetLastTimePlayerWasInSector(); +UINT32 GetLastTimePlayerWasInSector(INT16 sMapX, INT16 sMapY, INT8 sMapZ); // Flugente: get time for another sector void SetLastTimePlayerWasInSector(); @@ -1411,6 +1412,39 @@ UINT32 GetLastTimePlayerWasInSector() return( 0 ); } +// Flugente: get time for another sector +UINT32 GetLastTimePlayerWasInSector(INT16 sMapX, INT16 sMapY, INT8 sMapZ) +{ + if( !sMapZ ) + return( SectorInfo[ SECTOR( sMapX,sMapY) ].uiTimeCurrentSectorWasLastLoaded ); + else if( sMapZ > 0 ) + { + UNDERGROUND_SECTORINFO *pTempNode = gpUndergroundSectorInfoHead; + + pTempNode = gpUndergroundSectorInfoHead; + + //loop through and look for the right underground sector + while( pTempNode ) + { + if( ( pTempNode->ubSectorX == sMapX ) && + ( pTempNode->ubSectorY == sMapY ) && + ( pTempNode->ubSectorZ == sMapZ ) ) + { + //set the flag indicating that ther is a temp item file exists for the sector + return( pTempNode->uiTimeCurrentSectorWasLastLoaded ); + } + pTempNode = pTempNode->next; + } + + #ifdef JA2TESTVERSION + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_TESTVERSION, L"Failed to Get the 'uiTimeCurrentSectorWasLastLoaded' from an underground sector" ); + #endif + + return( 0 ); + } + return( 0 ); +} + diff --git a/Tactical/Tactical Turns.cpp b/Tactical/Tactical Turns.cpp index cb2b7347..60ffb641 100644 --- a/Tactical/Tactical Turns.cpp +++ b/Tactical/Tactical Turns.cpp @@ -273,8 +273,8 @@ void HandleTacticalEndTurn( ) HandleRPCDescription( ); #endif - // Flugente: Cool down all items not in a soldier's inventory - CoolDownWorldItems( FALSE ); + // Flugente: Cool down/decay all items not in a soldier's inventory + CoolDownWorldItems(); #ifdef ENABLE_ZOMBIES // Flugente: raise zombies if in gamescreen and option set diff --git a/Tactical/TeamTurns.cpp b/Tactical/TeamTurns.cpp index ab58fa89..28cc2ce5 100644 --- a/Tactical/TeamTurns.cpp +++ b/Tactical/TeamTurns.cpp @@ -462,8 +462,8 @@ void EndTurnEvents( void ) DecaySmokeEffects( GetWorldTotalSeconds( ) ); DecayLightEffects( GetWorldTotalSeconds( ) ); - // Flugente: Cool down all items not in a soldier's inventory - CoolDownWorldItems( FALSE ); + // Flugente: Cool down/decay all items not in a soldier's inventory + CoolDownWorldItems(); #ifdef ENABLE_ZOMBIES // Flugente: raise zombies if in gamescreen and option set diff --git a/Tactical/World Items.cpp b/Tactical/World Items.cpp index 33ce52e9..d0eeeb1a 100644 --- a/Tactical/World Items.cpp +++ b/Tactical/World Items.cpp @@ -28,7 +28,7 @@ #include "Quests.h" #include "Soldier Profile.h" #include "message.h" - #include "Food.h" // added by Flugente + #include "map screen interface map inventory.h" // added by Flugente #include "connect.h" #endif @@ -827,88 +827,8 @@ void RefreshWorldItemsIntoItemPools( WORLDITEM * pItemList, INT32 iNumberOfItems } -// Flugente FTW 1: Cool down all items in the world (no, really) -// fSetZero sets all temperatures to 0 (used in old sector upon loading a new sector) -void CoolDownWorldItems( BOOLEAN fSetZero ) +// Flugente: Cool/decay down all items in this sector +void CoolDownWorldItems() { - if ( gGameOptions.fWeaponOverheating ) // if Overheating is used ... - { - for( UINT32 uiCount = 0; uiCount < guiNumWorldItems; ++uiCount ) // ... for all items in the world ... - { - if( gWorldItems[ uiCount ].fExists ) // ... if item exists ... - { - // ... if Item exists and is a gun, a launcher or a barrel ... - if (Item[gWorldItems[ uiCount ].object.usItem].usItemClass & (IC_GUN|IC_LAUNCHER) || Item[gWorldItems[ uiCount ].object.usItem].barrel == TRUE ) - { - OBJECTTYPE* pObj = &(gWorldItems[ uiCount ].object); // ... get pointer for this item ... - - if ( pObj != NULL ) // ... if pointer is not obviously useless ... - { - for(INT16 i = 0; i < pObj->ubNumberOfObjects; ++i) // ... there might be multiple items here (item stack), so for each one ... - { - FLOAT newguntemperature = 0.0f; - - if ( !fSetZero || !gGameExternalOptions.fSetZeroUponNewSector ) - { - FLOAT guntemperature = (*pObj)[i]->data.bTemperature; // ... get temperature ... - - FLOAT cooldownfactor = GetItemCooldownFactor(pObj); // ... get item cooldown factor provided of attachments ... - - if ( Item[gWorldItems[ uiCount ].object.usItem].barrel == TRUE ) // ... a barrel lying around cools down a bit faster ... - cooldownfactor *= gGameExternalOptions.iCooldownModificatorLonelyBarrel; - - newguntemperature = max(0.0f, guntemperature - cooldownfactor); // ... calculate new temperature ... - -#if 0//def JA2TESTVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"World: Item temperature lowered from %4.2f to %4.2f", guntemperature, newguntemperature ); -#endif - } - - (*pObj)[i]->data.bTemperature = newguntemperature; // ... set new temperature - - // for every objects, we also have to check wether there are weapon attachments (eg. underbarrel grenade launchers), and cool them down too - attachmentList::iterator iterend = (*pObj)[i]->attachments.end(); - for (attachmentList::iterator iter = (*pObj)[i]->attachments.begin(); iter != iterend; ++iter) - { - if ( iter->exists() && Item[ iter->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) ) - { - FLOAT newtemperature = 0.0f; - - if ( !fSetZero || !gGameExternalOptions.fSetZeroUponNewSector ) - { - FLOAT temperature = (*iter)[i]->data.bTemperature; // ... get temperature of item ... - - FLOAT cooldownfactor = GetItemCooldownFactor( &(*iter) ); // ... get cooldown factor ... - - newtemperature = max(0.0f, temperature - cooldownfactor); // ... calculate new temperature ... - } - - (*iter)[i]->data.bTemperature = newtemperature; // ... set new temperature - -#if 0//def JA2TESTVERSION - ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"World: Item temperature lowered from %4.2f to %4.2f", temperature, newtemperature ); -#endif - - // we assume that there can exist only 1 UGL per weapon - break; - } - } - } - } - } - else if ( Item[gWorldItems[ uiCount ].object.usItem].foodtype > 0 ) // food decays - { - OBJECTTYPE* pObj = &(gWorldItems[ uiCount ].object); // ... get pointer for this item ... - - if ( pObj != NULL ) // ... if pointer is not obviously useless ... - { - for(INT16 i = 0; i < pObj->ubNumberOfObjects; ++i) // ... there might be multiple items here (item stack), so for each one ... - { - (*pObj)[i]->data.bTemperature = max(0.0f, (*pObj)[i]->data.bTemperature - Food[Item[pObj->usItem].foodtype].usDecayRate); // set new temperature - } - } - } - } - } - } + HandleSectorCooldownFunctions( gWorldSectorX, gWorldSectorY, gbWorldSectorZ, gWorldItems, guiNumWorldItems, FALSE ); } diff --git a/Tactical/World Items.h b/Tactical/World Items.h index c483c1a8..22ad975e 100644 --- a/Tactical/World Items.h +++ b/Tactical/World Items.h @@ -119,6 +119,6 @@ extern void FindPanicBombsAndTriggers( void ); extern INT32 FindWorldItemForBombInGridNo( INT32 sGridNo, INT8 bLevel); void RefreshWorldItemsIntoItemPools( WORLDITEM * pItemList, INT32 iNumberOfItems ); -void CoolDownWorldItems( BOOLEAN fSetZero = FALSE ); // Flugente FTW 1: Cool down all items in the world (no, really) +void CoolDownWorldItems( ); // Flugente: Cool/decay down all items in this sector #endif \ No newline at end of file