diff --git a/GameVersion.h b/GameVersion.h index d51e5bbd..4ba87f75 100644 --- a/GameVersion.h +++ b/GameVersion.h @@ -21,6 +21,7 @@ extern CHAR16 zTrackingNumber[16]; // Keeps track of the saved game version. Increment the saved game version whenever // you will invalidate the saved game file +#define DYNAMIC_FLASHLIGHTS 142 // Flugente: had to add variables to LIGHTEFFECT-struct #define ENLARGED_OPINIONS 141 // Flugente: increased numberof merc opinions to 255, thus need to change savegame reading #define MODULARIZED_AI 140 // Flugente: new savegame version due to modularized AI #define MILITIA_EQUIPMENT 139 // Flugente: militia can equip from sector inventory @@ -60,7 +61,7 @@ extern CHAR16 zTrackingNumber[16]; #define AP100_SAVEGAME_DATATYPE_CHANGE 105 // Before this, we didn't have the 100AP structure changes #define NIV_SAVEGAME_DATATYPE_CHANGE 102 // Before this, we used the old structure system -#define SAVE_GAME_VERSION ENLARGED_OPINIONS +#define SAVE_GAME_VERSION DYNAMIC_FLASHLIGHTS //#define RUSSIANGOLD #ifdef __cplusplus diff --git a/Tactical/Handle Doors.cpp b/Tactical/Handle Doors.cpp index 960cdb4a..dafb0e0d 100644 --- a/Tactical/Handle Doors.cpp +++ b/Tactical/Handle Doors.cpp @@ -96,6 +96,9 @@ void HandleDoorChangeFromGridNo( SOLDIERTYPE *pSoldier, INT32 sGridNo, BOOLEAN f { pDoorStatus->ubFlags |= DOOR_BUSY; } + + // Flugente: we have to redo flashlights + pSoldier->HandleFlashLights(); } UINT16 GetAnimStateForInteraction( SOLDIERTYPE *pSoldier, BOOLEAN fDoor, UINT16 usAnimState ) diff --git a/Tactical/Interface Control.cpp b/Tactical/Interface Control.cpp index 6db2b30a..86db69a6 100644 --- a/Tactical/Interface Control.cpp +++ b/Tactical/Interface Control.cpp @@ -111,6 +111,25 @@ void HandleTacticalPanelSwitch( ) } } +// Flugente: handle flashlights +void HandleFlashLights() +{ + if ( !fInterfacePanelDirty ) + return; + + SOLDIERTYPE* pSoldier = NULL; + + for (UINT32 uiLoop = 0; uiLoop < guiNumMercSlots; ++uiLoop ) + { + pSoldier = MercSlots[ uiLoop ]; + + if ( pSoldier != NULL && pSoldier->bSoldierFlagMask & SOLDIER_REDOFLASHLIGHT ) + { + pSoldier->HandleFlashLights(); + } + } +} + void RenderTacticalInterface( ) { @@ -143,6 +162,8 @@ void RenderTacticalInterface( ) if( !(guiTacticalInterfaceFlags & INTERFACE_SHOPKEEP_INTERFACE ) ) HandleAutoFaces( ); + // Flugente: handle flashlights + HandleFlashLights(); } diff --git a/Tactical/Interface Control.h b/Tactical/Interface Control.h index 0f42bd2e..898d3587 100644 --- a/Tactical/Interface Control.h +++ b/Tactical/Interface Control.h @@ -17,6 +17,9 @@ void ResetInterface( ); void RenderTopmostTacticalInterface( ); void RenderTacticalInterface( ); +// Flugente: handle flashlights +void HandleFlashLights(); + void StartViewportOverlays( ); void EndViewportOverlays( ); diff --git a/Tactical/Interface Panels.cpp b/Tactical/Interface Panels.cpp index 6e2efee5..985e6bef 100644 --- a/Tactical/Interface Panels.cpp +++ b/Tactical/Interface Panels.cpp @@ -4089,6 +4089,10 @@ void SMInvClickCallback( MOUSE_REGION * pRegion, INT32 iReason ) */ } } + + // Flugente: we have to recheck our flashlights, as we changed items + //gpSMCurrentMerc->bSoldierFlagMask |= SOLDIER_REDOFLASHLIGHT; + gpSMCurrentMerc->HandleFlashLights(); } else if (iReason & MSYS_CALLBACK_REASON_RBUTTON_DWN) { diff --git a/Tactical/Item Types.h b/Tactical/Item Types.h index 144f6dfe..1cb634f5 100644 --- a/Tactical/Item Types.h +++ b/Tactical/Item Types.h @@ -1150,6 +1150,9 @@ typedef struct UINT16 randomitem; INT8 randomitemcoolnessmodificator; // alters the allowed maximum coolness a random item can have + // Flugente: range of a flashlight (an item with usFlashLightRange > 0 is deemed a flashlight) + UINT8 usFlashLightRange; + } INVTYPE; diff --git a/Tactical/Items.cpp b/Tactical/Items.cpp index dad3103c..394dabaf 100644 --- a/Tactical/Items.cpp +++ b/Tactical/Items.cpp @@ -8665,6 +8665,9 @@ void SwapHandItems( SOLDIERTYPE * pSoldier ) SwapObjs( pSoldier, HANDPOS, SECONDHANDPOS, TRUE ); DirtyMercPanelInterface( pSoldier, DIRTYLEVEL2 ); } + + // Flugente: we have to recheck our flashlights + pSoldier->HandleFlashLights(); } void SwapOutHandItem( SOLDIERTYPE * pSoldier ) @@ -8694,6 +8697,9 @@ void SwapOutHandItem( SOLDIERTYPE * pSoldier ) // otherwise there's no room for the item anywhere! } } + + // Flugente: we have to recheck our flashlights + pSoldier->HandleFlashLights(); } void WaterDamage( SOLDIERTYPE *pSoldier ) @@ -14407,6 +14413,9 @@ BOOLEAN OBJECTTYPE::TransformObject( SOLDIERTYPE * pSoldier, UINT8 ubStatusIndex } } + // Flugente: we have to recheck our flashlights + pSoldier->HandleFlashLights(); + // Signal a successful transformation. return TRUE; } diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index 001c23f1..a879e10f 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -108,6 +108,7 @@ #include "IMP Skill Trait.h" // added by Flugente #include "Food.h" // added by Flugente #include "Tactical Save.h" // added by Flugente for AddItemsToUnLoadedSector() +#include "LightEffects.h" // added by Flugente for CreatePersonalLight() //forward declarations of common classes to eliminate includes class OBJECTTYPE; @@ -4613,6 +4614,8 @@ void SOLDIERTYPE::SetSoldierGridNo( INT32 sNewGridNo, BOOLEAN fForceRemove ) } } + this->HandleFlashLights(); + ///HandlePlacingRoofMarker( this, this->sGridNo, TRUE, FALSE ); this->HandleAnimationProfile( this->usAnimState, FALSE ); @@ -7008,9 +7011,11 @@ void SOLDIERTYPE::ChangeSoldierStance( UINT8 ubDesiredStance ) // Now change to appropriate animation this->EVENT_InitNewSoldierAnim( usNewState, 0 , FALSE ); - } } + this->bSoldierFlagMask |= SOLDIER_REDOFLASHLIGHT; +} + void SOLDIERTYPE::EVENT_InternalSetSoldierDestination( UINT16 usNewDirection, BOOLEAN fFromMove, UINT16 usAnimState ) { INT32 sNewGridNo; @@ -7277,6 +7282,9 @@ void SOLDIERTYPE::EVENT_SetSoldierDirection( UINT16 usNewDirection ) // Remove old location data this->HandleAnimationProfile( this->usAnimState, TRUE ); + // Flugente + BOOLEAN fNew = (this->ubDirection != (INT8)usNewDirection); + this->ubDirection = (INT8)usNewDirection; // Updated extended direction..... @@ -7307,6 +7315,9 @@ void SOLDIERTYPE::EVENT_SetSoldierDirection( UINT16 usNewDirection ) // Change values! SetSoldierLocatorOffsets( this ); + // Flugente: only update flashlights if we changed our direction + if ( fNew ) + this->HandleFlashLights(); } @@ -13674,6 +13685,52 @@ BOOLEAN SOLDIERTYPE::SoldierCarriesTwoHandedWeapon( void ) // Flugente: Cool down/decay all items in inventory void SOLDIERTYPE::SoldierInventoryCoolDown(void) { + // if we have any active flashlights (in our hands for simplicity), drain their batteries + // do this check for both hands + UINT16 firstslot = HANDPOS; + UINT16 lastslot = VESTPOCKPOS; + for (UINT16 invpos = firstslot; invpos < lastslot; ++invpos) + { + OBJECTTYPE* pObj = &(this->inv[invpos]); + + if ( !pObj || !(pObj->exists()) ) + // can't use this, end + continue; + + OBJECTTYPE* pBattery = FindAttachedBatteries(pObj); + if ( !pBattery ) + continue; + + BOOLEAN flashlightfound = FALSE; + if ( Item [ pObj->usItem ].usFlashLightRange ) + flashlightfound = TRUE; + + if ( !flashlightfound ) + { + attachmentList::iterator iterend = (*pObj)[0]->attachments.end(); + for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != iterend; ++iter) + flashlightfound = TRUE; + } + + if ( flashlightfound ) + { + // 5% chance to lose 1 point + if ( pBattery && Chance(5) ) + (*pBattery)[0]->data.objectStatus -= 1; + + if ( (*pBattery)[0]->data.objectStatus <= 0 ) + { + // destroy batteries + pBattery->RemoveObjectsFromStack(1); + if (pBattery->exists() == false) + this->inv[HANDPOS].RemoveAttachment(pBattery); + } + } + } + + // handle flashlight. This is necessary in this location, as we need to do this at least once per turn + this->HandleFlashLights(); + if ( !gGameOptions.fWeaponOverheating && !gGameExternalOptions.fDirtSystem && !gGameOptions.fFoodSystem ) return; @@ -15975,6 +16032,9 @@ void SOLDIERTYPE::SwitchWeapons( BOOLEAN fKnife, BOOLEAN fSideArm ) } fCharacterInfoPanelDirty = TRUE; fInterfacePanelDirty = DIRTYLEVEL2; + + // Flugente: we have to recheck our flashlights + this->HandleFlashLights(); } UINT8 tmpuser = 0; @@ -16185,6 +16245,139 @@ void SOLDIERTYPE::AddDrugValues(UINT8 uDrugType, UINT8 usEffect, UINT8 usTravelR this->bSoldierFlagMask |= SOLDIER_DRUGGED; } +void SOLDIERTYPE::HandleFlashLights() +{ + // no more need to redo this check + this->bSoldierFlagMask &= ~SOLDIER_REDOFLASHLIGHT; + + // we must be active and in a sector (not travelling) in a valid position + if ( !bActive || !bInSector || TileIsOutOfBounds(this->sGridNo) ) + return; + + // no flashlight stuff if it isn't night, and we aren't underground + if ( !NightTime() && !gbWorldSectorZ ) + return; + + // remove existing lights we 'own' + if ( this->bSoldierFlagMask & SOLDIER_LIGHT_OWNER ) + { + RemovePersonalLights( this->ubID ); + + this->bSoldierFlagMask &= ~SOLDIER_LIGHT_OWNER; + } + + // not possible to get this bonus on a roof, due to our lighting system + if ( !this->pathing.bLevel ) + { + UINT8 flashlightrange = this->GetBestEquippedFlashLightRange(); + + // the range at which we create additional light sources to the side + UINT8 firstexpand = 8; + UINT8 secondexpand = 12; + + // depending on our direction, alter range + if ( this->ubDirection == NORTHEAST || this->ubDirection == NORTHWEST || this->ubDirection == SOUTHEAST || this->ubDirection == SOUTHWEST ) + { + flashlightrange = std::sqrt( (FLOAT)flashlightrange*(FLOAT)flashlightrange / 2.0f ); + firstexpand = std::sqrt( (FLOAT)firstexpand*(FLOAT)firstexpand / 2.0f ); + secondexpand = std::sqrt( (FLOAT)secondexpand*(FLOAT)secondexpand / 2.0f ); + } + + // if no flashlight is found, this will be 0 + if ( flashlightrange ) + { + // we determine the height of the next tile in our direction. Because of the way structures are handled, we sometimes have to take the very tile we're occupying right now + INT32 nextGridNoinSight = this->sGridNo; + + for(UINT8 i = 0; i < flashlightrange; ++i) + { + nextGridNoinSight = NewGridNo( nextGridNoinSight, DirectionInc( this->ubDirection ) ); + + if ( SoldierToVirtualSoldierLineOfSightTest( this, nextGridNoinSight, this->pathing.bLevel, gAnimControl[ this->usAnimState ].ubEndHeight, FALSE ) ) + CreatePersonalLight( nextGridNoinSight, this->ubID ); + + // after a certain range, add new lights to the side to simulate a light cone + if ( i > firstexpand ) + { + INT8 sidedir1 = (this->ubDirection + 2) % NUM_WORLD_DIRECTIONS; + INT8 sidedir2 = (this->ubDirection - 2) % NUM_WORLD_DIRECTIONS; + + INT32 sideGridNo1 = NewGridNo( nextGridNoinSight, DirectionInc( sidedir1 ) ); + sideGridNo1 = NewGridNo( sideGridNo1, DirectionInc( sidedir1 ) ); + + if ( SoldierToVirtualSoldierLineOfSightTest( this, sideGridNo1, this->pathing.bLevel, gAnimControl[ this->usAnimState ].ubEndHeight, FALSE, NO_DISTANCE_LIMIT ) ) + CreatePersonalLight( sideGridNo1, this->ubID ); + + if ( i > secondexpand ) + { + sideGridNo1 = NewGridNo( sideGridNo1, DirectionInc( sidedir1 ) ); + + if ( SoldierToVirtualSoldierLineOfSightTest( this, sideGridNo1, this->pathing.bLevel, gAnimControl[ this->usAnimState ].ubEndHeight, FALSE, NO_DISTANCE_LIMIT ) ) + CreatePersonalLight( sideGridNo1, this->ubID ); + } + + INT32 sideGridNo2 = NewGridNo( nextGridNoinSight, DirectionInc( sidedir2 ) ); + sideGridNo2 = NewGridNo( sideGridNo2, DirectionInc( sidedir2 ) ); + + if ( SoldierToVirtualSoldierLineOfSightTest( this, sideGridNo2, this->pathing.bLevel, gAnimControl[ this->usAnimState ].ubEndHeight, FALSE, NO_DISTANCE_LIMIT ) ) + CreatePersonalLight( sideGridNo2, this->ubID ); + + if ( i > secondexpand ) + { + sideGridNo2 = NewGridNo( sideGridNo2, DirectionInc( sidedir2 ) ); + + if ( SoldierToVirtualSoldierLineOfSightTest( this, sideGridNo2, this->pathing.bLevel, gAnimControl[ this->usAnimState ].ubEndHeight, FALSE, NO_DISTANCE_LIMIT ) ) + CreatePersonalLight( sideGridNo2, this->ubID ); + } + } + } + + // take note: we own a light source + this->bSoldierFlagMask |= SOLDIER_LIGHT_OWNER; + } + } + + // refresh sight for everybody + AllTeamsLookForAll( TRUE ); + + SetRenderFlags(RENDER_FLAG_FULL); +} + +UINT8 SOLDIERTYPE::GetBestEquippedFlashLightRange() +{ + UINT8 bestrange = 0; + + // do this check for both hands + UINT16 firstslot = HANDPOS; + UINT16 lastslot = VESTPOCKPOS; + for (UINT16 invpos = firstslot; invpos < lastslot; ++invpos) + { + OBJECTTYPE* pObj = &(this->inv[invpos]); + + if ( !pObj || !(pObj->exists()) ) + // can't use this, end + continue; + + // due to our attachment system, flashlights on guns do not require the batteries to be attached to the flashlight itself - anywhere will do + if ( !FindAttachedBatteries(pObj) ) + continue; + + if ( Item [ pObj->usItem ].usFlashLightRange ) + { + bestrange = max(bestrange, Item [ pObj->usItem ].usFlashLightRange); + } + + attachmentList::iterator iterend = (*pObj)[0]->attachments.end(); + for (attachmentList::iterator iter = (*pObj)[0]->attachments.begin(); iter != iterend; ++iter) + { + if(iter->exists() && Item [ iter->usItem ].usFlashLightRange ) + bestrange = max(bestrange, Item [ iter->usItem ].usFlashLightRange); + } + } + + return( bestrange ); +} + INT32 CheckBleeding( SOLDIERTYPE *pSoldier ) { INT8 bBandaged; //,savedOurTurn; diff --git a/Tactical/Soldier Control.h b/Tactical/Soldier Control.h index 96c04a8d..ccf8b954 100644 --- a/Tactical/Soldier Control.h +++ b/Tactical/Soldier Control.h @@ -367,10 +367,10 @@ enum #define SOLDIER_POW_PRISON 0x00001000 //4096 // this guy is a prisoner of war in a prison sector. SOLDIER_POW refers to people we capture, this refers to people we hold captive #define SOLDIER_EQUIPMENT_DROPPED 0x00002000 //8192 // under certain circumstances, militia can be ordered to drop their gear twice. Thus we set a marker to avoid that. #define SOLDIER_ACCESSTEAMMEMBER 0x00004000 //16384 // this merc is accessing another team member'S inventory (via abusing the stealing mechanic) -/*#define ENEMY_NET_4_LVL_4 0x00008000 //32768 +#define SOLDIER_REDOFLASHLIGHT 0x00008000 //32768 // this flag signifies that we somehow interacted with the items in our hands. Thus we have to possible redo lighting from flashlights -#define PLAYER_NET_1_LVL_1 0x00010000 //65536 -#define PLAYER_NET_2_LVL_1 0x00020000 //131072 +#define SOLDIER_LIGHT_OWNER 0x00010000 //65536 // we 'own' at least one light source (via flashlights) +/*#define PLAYER_NET_2_LVL_1 0x00020000 //131072 #define PLAYER_NET_3_LVL_1 0x00040000 //262144 #define PLAYER_NET_4_LVL_1 0x00080000 //524288 @@ -1560,6 +1560,9 @@ public: INT8 GetTraitCTHModifier( UINT16 usItem, INT16 ubAimTime, UINT8 ubTargetProfile ); void AddDrugValues(UINT8 uDrugType, UINT8 usEffect, UINT8 usTravelRate, UINT8 usSideEffect ); + + void HandleFlashLights(); + UINT8 GetBestEquippedFlashLightRange(); ////////////////////////////////////////////////////////////////////////////// }; // SOLDIERTYPE; diff --git a/TileEngine/LightEffects.cpp b/TileEngine/LightEffects.cpp index a2bc900a..b569db62 100644 --- a/TileEngine/LightEffects.cpp +++ b/TileEngine/LightEffects.cpp @@ -26,6 +26,7 @@ #endif #include "SaveLoadGame.h" +#include "GameVersion.h" // added by Flugente //forward declarations of common classes to eliminate includes @@ -33,7 +34,7 @@ class OBJECTTYPE; class SOLDIERTYPE; -#define NUM_LIGHT_EFFECT_SLOTS 25 +#define NUM_LIGHT_EFFECT_SLOTS 500 // 25 // Flugente: raised to 500 - lets see what happens // GLOBAL FOR LIGHT LISTING @@ -102,8 +103,8 @@ void UpdateLightingSprite( LIGHTEFFECT *pLight ) LightSpritePosition( pLight->iLight, (INT16)( CenterX( pLight->sGridNo ) / CELL_X_SIZE ), (INT16)( CenterY( pLight->sGridNo ) / CELL_Y_SIZE ) ); } - -INT32 NewLightEffect( INT32 sGridNo, UINT8 ubDuration, UINT8 ubStartRadius ) +// Flugente: create a pure light, worry about updating sight in other functions +INT32 NewLightEffectInternal( INT32 sGridNo, UINT8 ubDuration, UINT8 ubStartRadius ) { LIGHTEFFECT *pLight; INT32 iLightIndex; @@ -127,13 +128,27 @@ INT32 NewLightEffect( INT32 sGridNo, UINT8 ubDuration, UINT8 ubStartRadius ) UpdateLightingSprite( pLight ); + return iLightIndex; +} + +INT32 NewLightEffect( INT32 sGridNo, UINT8 ubDuration, UINT8 ubStartRadius ) +{ + INT32 iLightIndex = NewLightEffectInternal( sGridNo, ubDuration, ubStartRadius ); + // Handle sight here.... AllTeamsLookForAll( FALSE ); //Play the breaklight sound // PlayJA2Sample( BREAK_LIGHT_IGNITING, RATE_11025, SoundVolume( LOWVOLUME, sGridNo ), 1, SoundDir( sGridNo ) ); // MAdd: for some reason this crashes the game! - return( pLight->iLight ); + + if ( iLightIndex > -1 ) + { + LIGHTEFFECT *pLight = &gLightEffectData[ iLightIndex ]; + return( pLight->iLight ); + } + + return -1; } @@ -468,12 +483,25 @@ BOOLEAN LoadLightEffectsFromMapTempFile( INT16 sMapX, INT16 sMapY, INT8 bMapZ ) //loop through and load the list for( uiCnt=0; uiCnt= DYNAMIC_FLASHLIGHTS) { - FileClose( hFile ); - return( FALSE ); + //Load the Light effect Data + FileRead( hFile, &gLightEffectData[ uiCnt ], sizeof( LIGHTEFFECT ), &uiNumBytesRead ); + if( uiNumBytesRead != sizeof( LIGHTEFFECT ) ) + { + return( FALSE ); + } + } + else + { + UINT16 bla = sizeof( LIGHTEFFECT ); + + //Load the Light effect Data + FileRead( hFile, &gLightEffectData[ uiCnt ], LIGHTEFFECT_OLDSIZE, &uiNumBytesRead ); + if( uiNumBytesRead != LIGHTEFFECT_OLDSIZE ) + { + return( FALSE ); + } } } @@ -497,3 +525,34 @@ void ResetLightEffects() memset( gLightEffectData, 0, sizeof( LIGHTEFFECT ) * NUM_LIGHT_EFFECT_SLOTS ); guiNumLightEffects = 0; } + +// Flugente: create and destroy light sources tied to a person +void CreatePersonalLight( INT32 sGridNo, UINT8 ubID ) +{ + INT32 iLightIndex = NewLightEffectInternal( sGridNo, 0, 1 ); + + if ( iLightIndex > -1 ) + { + gLightEffectData[ iLightIndex ].ubOwner = ubID; + gLightEffectData[ iLightIndex ].flags |= LIGHTEFFECT_FLASHLIGHT; + } +} + +void RemovePersonalLights( UINT8 ubID ) +{ + LIGHTEFFECT *pLight; + + // Set to unallocated.... + for ( UINT32 cnt = 0; cnt < guiNumLightEffects; ++cnt ) + { + pLight = &gLightEffectData[ cnt ]; + + if ( pLight->iLight != (-1) && pLight->flags & LIGHTEFFECT_FLASHLIGHT && pLight->ubOwner == ubID && pLight->fAllocated ) + { + pLight->fAllocated = FALSE; + pLight->flags &= ~LIGHTEFFECT_FLASHLIGHT; + + LightSpriteDestroy( pLight->iLight ); + } + } +} diff --git a/TileEngine/LightEffects.h b/TileEngine/LightEffects.h index 35e74de9..783f6695 100644 --- a/TileEngine/LightEffects.h +++ b/TileEngine/LightEffects.h @@ -23,8 +23,14 @@ typedef struct INT32 iLight; UINT32 uiTimeOfLastUpdate; + // Flugente: added variables necessary for dynamic (flash-)lighting + INT32 flags; + UINT8 ubOwner; + } LIGHTEFFECT; +#define LIGHTEFFECT_OLDSIZE 20 // Flugente: the old size of LIGHTEFFECT (before Gameversion DYNAMIC_FLASHLIGHTS) +#define LIGHTEFFECT_FLASHLIGHT 0x00000001 // Decays all light effects... @@ -48,4 +54,8 @@ void ResetLightEffects(); BOOLEAN IsLightEffectAtTile( INT32 sGridNo ); +// Flugente: create and destroy light sources tied to a person +void CreatePersonalLight( INT32 sGridNo, UINT8 ubID ); +void RemovePersonalLights( UINT8 ubID ); + #endif \ No newline at end of file diff --git a/Utils/XML_Items.cpp b/Utils/XML_Items.cpp index 111d32b1..6e839ade 100644 --- a/Utils/XML_Items.cpp +++ b/Utils/XML_Items.cpp @@ -272,7 +272,8 @@ itemStartElementHandle(void *userData, const XML_Char *name, const XML_Char **at strcmp(name, "usActionItemFlag") == 0 || strcmp(name, "clothestype") == 0 || strcmp(name, "randomitem") == 0 || - strcmp(name, "randomitemcoolnessmodificator") == 0 )) + strcmp(name, "randomitemcoolnessmodificator") == 0 || + strcmp(name, "FlashLightRange") == 0 )) { pData->curElement = ELEMENT_PROPERTY; //DebugMsg(TOPIC_JA2, DBG_LEVEL_3, String("itemStartElementHandle: going into element, name = %s",name) ); @@ -1406,8 +1407,12 @@ itemEndElementHandle(void *userData, const XML_Char *name) // no nonsense, only values between -20 and + 20 pData->curItem.randomitemcoolnessmodificator = min(20, max(-20, pData->curItem.randomitemcoolnessmodificator) ); } - - + else if(strcmp(name, "FlashLightRange") == 0) + { + pData->curElement = ELEMENT; + pData->curItem.usFlashLightRange = (UINT8) atol(pData->szCharData); + } + pData->maxReadDepth--; } @@ -2044,7 +2049,8 @@ BOOLEAN WriteItemStats() FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].clothestype ); FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].randomitem ); FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].randomitemcoolnessmodificator ); - + FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].usFlashLightRange ); + FilePrintf(hFile,"\t\r\n"); } FilePrintf(hFile,"\r\n");