From 4ccc6a5b2a5640b9084f1f21dadb126c16feaf4a Mon Sep 17 00:00:00 2001 From: Flugente Date: Tue, 3 Sep 2013 20:55:33 +0000 Subject: [PATCH] - new feature: backgrounds allow more personalisation of mercenaries - background feature replaces overheating on startup screen, moved overheating opion to ini WARNING: GameDir revision >= 1748 is required. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@6353 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- GameInitOptionsScreen.cpp | 170 ++-- GameSettings.cpp | 4 +- GameSettings.h | 3 +- GameVersion.cpp | 16 +- GameVersion.h | 3 +- Init.cpp | 16 +- Laptop/CharProfile.cpp | 22 +- Laptop/CharProfile.h | 4 + Laptop/IMP Background.cpp | 794 ++++++++++++++++++ Laptop/IMP Background.h | 16 + Laptop/IMP Compile Character.cpp | 3 + Laptop/IMP Minor Trait.cpp | 7 + Laptop/Laptop_VS2005.vcproj | 8 + Laptop/Laptop_VS2008.vcproj | 8 + Laptop/Laptop_VS2010.vcxproj | 2 + Laptop/Laptop_VS2010.vcxproj.filters | 6 + Laptop/personnel.cpp | 43 +- Multiplayer/client.cpp | 4 +- SaveLoadGame.cpp | 18 +- Strategic/Assignments.cpp | 14 +- Strategic/Auto Resolve.cpp | 2 +- Strategic/Hourly Update.cpp | 323 ++++--- .../Map Screen Interface Map Inventory.cpp | 4 +- Strategic/Strategic Movement.cpp | 25 +- Tactical/Food.cpp | 9 +- Tactical/Handle Items.cpp | 9 + Tactical/Interface Enhanced.cpp | 19 +- Tactical/Interface Items.cpp | 23 +- Tactical/Interface Panels.cpp | 5 +- Tactical/Interface.cpp | 2 + Tactical/Interface.h | 96 +++ Tactical/Items.cpp | 8 +- Tactical/Keys.cpp | 3 +- Tactical/LOS.cpp | 12 +- Tactical/Morale.cpp | 6 + Tactical/Overhead.cpp | 12 + Tactical/Points.cpp | 27 +- Tactical/ShopKeeper Interface.cpp | 43 +- Tactical/SkillCheck.cpp | 17 + Tactical/Soldier Add.cpp | 13 + Tactical/Soldier Control.cpp | 162 +++- Tactical/Soldier Control.h | 35 +- Tactical/Soldier Profile.cpp | 3 +- Tactical/Soldier Profile.h | 3 + Tactical/Tactical_VS2005.vcproj | 4 + Tactical/Tactical_VS2008.vcproj | 4 + Tactical/Tactical_VS2010.vcxproj | 1 + Tactical/Tactical_VS2010.vcxproj.filters | 3 + Tactical/Weapons.cpp | 34 +- Tactical/XML.h | 5 + Tactical/XML_Background.cpp | 602 +++++++++++++ Tactical/XML_Profiles.cpp | 14 +- Tactical/soldier profile type.h | 3 + TacticalAI/Attacks.cpp | 3 + TacticalAI/NPC.cpp | 25 + Utils/Animated ProgressBar.cpp | 2 +- Utils/Text.h | 5 +- Utils/_ChineseText.cpp | 78 ++ Utils/_DutchText.cpp | 78 ++ Utils/_EnglishText.cpp | 80 +- Utils/_FrenchText.cpp | 78 ++ Utils/_GermanText.cpp | 78 ++ Utils/_ItalianText.cpp | 78 ++ Utils/_PolishText.cpp | 78 ++ Utils/_RussianText.cpp | 78 ++ Utils/_TaiwaneseText.cpp | 78 ++ 66 files changed, 3128 insertions(+), 303 deletions(-) create mode 100644 Laptop/IMP Background.cpp create mode 100644 Laptop/IMP Background.h create mode 100644 Tactical/XML_Background.cpp diff --git a/GameInitOptionsScreen.cpp b/GameInitOptionsScreen.cpp index ca374a96c..8957e4558 100644 --- a/GameInitOptionsScreen.cpp +++ b/GameInitOptionsScreen.cpp @@ -154,12 +154,12 @@ #define GIO_DROPALL_SETTING_Y GIO_GUN_SETTING_Y + CHECK_Y_OFFSET + CORRECTION_Y_OFFSET #define GIO_DROPALL_SETTING_WIDTH CHECK_WIDTH -#define GIO_OVERHEATING_SETTING_X SECOND_COLUMN_X + CHECK_X_OFFSET -#define GIO_OVERHEATING_SETTING_Y GIO_DROPALL_SETTING_Y + CHECK_Y_OFFSET + CORRECTION_Y_OFFSET -#define GIO_OVERHEATING_SETTING_WIDTH CHECK_WIDTH +#define GIO_BACKGROUND_SETTING_X SECOND_COLUMN_X + CHECK_X_OFFSET +#define GIO_BACKGROUND_SETTING_Y GIO_DROPALL_SETTING_Y + CHECK_Y_OFFSET + CORRECTION_Y_OFFSET +#define GIO_BACKGROUND_SETTING_WIDTH CHECK_WIDTH #define GIO_FOODSYSTEM_SETTING_X SECOND_COLUMN_X + CHECK_X_OFFSET -#define GIO_FOODSYSTEM_SETTING_Y GIO_OVERHEATING_SETTING_Y + CHECK_Y_OFFSET + CORRECTION_Y_OFFSET +#define GIO_FOODSYSTEM_SETTING_Y GIO_BACKGROUND_SETTING_Y + CHECK_Y_OFFSET + CORRECTION_Y_OFFSET #define GIO_FOODSYSTEM_SETTING_WIDTH CHECK_WIDTH /********************************* @@ -545,11 +545,11 @@ UINT32 guiImprovedInterruptOptionToggles[ GIO_NUM_ONOFF_BUTTONS ]; void BtnGIOImprovedInterruptOffCallback(GUI_BUTTON *btn,INT32 reason); void BtnGIOImprovedInterruptOnCallback(GUI_BUTTON *btn,INT32 reason); -// Overheating -UINT32 guiOverheatingOptionTogglesImage[ GIO_NUM_ONOFF_BUTTONS ]; -UINT32 guiOverheatingOptionToggles[ GIO_NUM_ONOFF_BUTTONS ]; -void BtnGIOOverheatingOffCallback(GUI_BUTTON *btn,INT32 reason); -void BtnGIOOverheatingOnCallback(GUI_BUTTON *btn,INT32 reason); +// Background +UINT32 guiBackGroundOptionTogglesImage[ GIO_NUM_ONOFF_BUTTONS ]; +UINT32 guiBackGroundOptionToggles[ GIO_NUM_ONOFF_BUTTONS ]; +void BtnGIOBackGroundOffCallback(GUI_BUTTON *btn,INT32 reason); +void BtnGIOBackGroundOnCallback(GUI_BUTTON *btn,INT32 reason); // Food System UINT32 guiFoodSystemOptionTogglesImage[ GIO_NUM_ONOFF_BUTTONS ]; @@ -590,7 +590,7 @@ UINT8 GetCurrentTexAndJohnButtonSetting(); UINT8 GetCurrentInventoryAPButtonSetting(); UINT8 GetCurrentNCTHButtonSetting(); UINT8 GetCurrentIISButtonSetting(); -UINT8 GetCurrentOverheatingButtonSetting(); +UINT8 GetCurrentBackGroundButtonSetting(); UINT8 GetCurrentFoodSystemButtonSetting(); void DoneFadeOutForExitGameInitOptionScreen( void ); @@ -704,7 +704,7 @@ UINT32 GameInitOptionsScreenInit( void ) gGameOptions.fUseNCTH = FALSE; gGameOptions.fImprovedInterruptSystem = FALSE; - gGameOptions.fWeaponOverheating = FALSE; + gGameOptions.fBackGround = FALSE; gGameOptions.fFoodSystem = FALSE; gGameOptions.fAirStrikes = FALSE; @@ -1271,33 +1271,33 @@ BOOLEAN EnterGIOScreen() /////////////////////////////////////////////////////////////////////////////////////////////////////// - // OVERHEATING WEAPONS ON/OFF SETTING + // BACKGROUND ON/OFF SETTING - guiOverheatingOptionTogglesImage[ GIO_BUTTON_OFF ] = UseLoadedButtonImage( guiTraitsOptionTogglesImage[ GIO_TRAITS_OLD ], -1,1,-1,3,-1 ); - guiOverheatingOptionToggles[ GIO_BUTTON_OFF ] = CreateIconAndTextButton( guiOverheatingOptionTogglesImage[ GIO_BUTTON_OFF ], gzGIOScreenText[ GIO_DROPALL_OFF_TEXT ], GIO_TOGGLE_TEXT_FONT, + guiBackGroundOptionTogglesImage[ GIO_BUTTON_OFF ] = UseLoadedButtonImage( guiTraitsOptionTogglesImage[ GIO_TRAITS_OLD ], -1,1,-1,3,-1 ); + guiBackGroundOptionToggles[ GIO_BUTTON_OFF ] = CreateIconAndTextButton( guiBackGroundOptionTogglesImage[ GIO_BUTTON_OFF ], gzGIOScreenText[ GIO_DROPALL_OFF_TEXT ], GIO_TOGGLE_TEXT_FONT, GIO_TOGGLE_TEXT_COLOR, NO_SHADOW, GIO_TOGGLE_TEXT_COLOR, NO_SHADOW, TEXT_CJUSTIFIED, - (GIO_OVERHEATING_SETTING_X), (GIO_OVERHEATING_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, - DEFAULT_MOVE_CALLBACK, BtnGIOOverheatingOffCallback); + (GIO_BACKGROUND_SETTING_X), (GIO_BACKGROUND_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, + DEFAULT_MOVE_CALLBACK, BtnGIOBackGroundOffCallback); - guiOverheatingOptionTogglesImage[ GIO_BUTTON_ON ] = UseLoadedButtonImage( guiTraitsOptionTogglesImage[ GIO_TRAITS_OLD ], -1,1,-1,3,-1 ); - guiOverheatingOptionToggles[ GIO_BUTTON_ON ] = CreateIconAndTextButton( guiOverheatingOptionTogglesImage[ GIO_BUTTON_ON ], gzGIOScreenText[ GIO_DROPALL_ON_TEXT ], GIO_TOGGLE_TEXT_FONT, + guiBackGroundOptionTogglesImage[ GIO_BUTTON_ON ] = UseLoadedButtonImage( guiTraitsOptionTogglesImage[ GIO_TRAITS_OLD ], -1,1,-1,3,-1 ); + guiBackGroundOptionToggles[ GIO_BUTTON_ON ] = CreateIconAndTextButton( guiBackGroundOptionTogglesImage[ GIO_BUTTON_ON ], gzGIOScreenText[ GIO_DROPALL_ON_TEXT ], GIO_TOGGLE_TEXT_FONT, GIO_TOGGLE_TEXT_COLOR, NO_SHADOW, GIO_TOGGLE_TEXT_COLOR, NO_SHADOW, TEXT_CJUSTIFIED, - (GIO_OVERHEATING_SETTING_X + 74), (GIO_OVERHEATING_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, - DEFAULT_MOVE_CALLBACK, BtnGIOOverheatingOnCallback ); + (GIO_BACKGROUND_SETTING_X + 74), (GIO_BACKGROUND_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, + DEFAULT_MOVE_CALLBACK, BtnGIOBackGroundOnCallback ); - SpecifyButtonSoundScheme( guiOverheatingOptionToggles[ GIO_BUTTON_OFF ], BUTTON_SOUND_SCHEME_BIGSWITCH3 ); - SpecifyButtonSoundScheme( guiOverheatingOptionToggles[ GIO_BUTTON_ON ], BUTTON_SOUND_SCHEME_BIGSWITCH3 ); - MSYS_SetBtnUserData(guiOverheatingOptionToggles[ GIO_BUTTON_OFF ],0, 0 ); - MSYS_SetBtnUserData(guiOverheatingOptionToggles[ GIO_BUTTON_ON ],0, 1 ); + SpecifyButtonSoundScheme( guiBackGroundOptionToggles[ GIO_BUTTON_OFF ], BUTTON_SOUND_SCHEME_BIGSWITCH3 ); + SpecifyButtonSoundScheme( guiBackGroundOptionToggles[ GIO_BUTTON_ON ], BUTTON_SOUND_SCHEME_BIGSWITCH3 ); + MSYS_SetBtnUserData(guiBackGroundOptionToggles[ GIO_BUTTON_OFF ],0, 0 ); + MSYS_SetBtnUserData(guiBackGroundOptionToggles[ GIO_BUTTON_ON ],0, 1 ); - if( gGameOptions.fWeaponOverheating ) - ButtonList[ guiOverheatingOptionToggles[ GIO_BUTTON_ON ] ]->uiFlags |= BUTTON_CLICKED_ON; + if( gGameOptions.fBackGround ) + ButtonList[ guiBackGroundOptionToggles[ GIO_BUTTON_ON ] ]->uiFlags |= BUTTON_CLICKED_ON; else - ButtonList[ guiOverheatingOptionToggles[ GIO_BUTTON_OFF ] ]->uiFlags |= BUTTON_CLICKED_ON; + ButtonList[ guiBackGroundOptionToggles[ GIO_BUTTON_OFF ] ]->uiFlags |= BUTTON_CLICKED_ON; /////////////////////////////////////////////////////////////////////////////////////////////////////// // FOOD SYSTEM ON/OFF SETTING @@ -2267,34 +2267,34 @@ void BtnGIOImprovedInterruptOnCallback(GUI_BUTTON *btn,INT32 reason) } } -void BtnGIOOverheatingOffCallback(GUI_BUTTON *btn,INT32 reason) +void BtnGIOBackGroundOffCallback(GUI_BUTTON *btn,INT32 reason) { if (!(btn->uiFlags & BUTTON_ENABLED)) return; if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN ) { - RestoreExternBackgroundRect( (GIO_OVERHEATING_SETTING_X), (GIO_OVERHEATING_SETTING_Y + 10), 230, 40 ); + RestoreExternBackgroundRect( (GIO_BACKGROUND_SETTING_X), (GIO_BACKGROUND_SETTING_Y + 10), 230, 40 ); - ButtonList[ guiOverheatingOptionToggles[ GIO_BUTTON_ON ] ]->uiFlags &= ~BUTTON_CLICKED_ON; + ButtonList[ guiBackGroundOptionToggles[ GIO_BUTTON_ON ] ]->uiFlags &= ~BUTTON_CLICKED_ON; btn->uiFlags|=(BUTTON_CLICKED_ON); - PlayButtonSound( guiOverheatingOptionToggles[ GIO_BUTTON_OFF ], BUTTON_SOUND_CLICKED_ON ); + PlayButtonSound( guiBackGroundOptionToggles[ GIO_BUTTON_OFF ], BUTTON_SOUND_CLICKED_ON ); } } -void BtnGIOOverheatingOnCallback(GUI_BUTTON *btn,INT32 reason) +void BtnGIOBackGroundOnCallback(GUI_BUTTON *btn,INT32 reason) { if (!(btn->uiFlags & BUTTON_ENABLED)) return; if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN ) { - RestoreExternBackgroundRect( (GIO_OVERHEATING_SETTING_X), (GIO_OVERHEATING_SETTING_Y + 10), 230, 40 ); + RestoreExternBackgroundRect( (GIO_BACKGROUND_SETTING_X), (GIO_BACKGROUND_SETTING_Y + 10), 230, 40 ); - ButtonList[ guiOverheatingOptionToggles[ GIO_BUTTON_OFF ] ]->uiFlags &= ~BUTTON_CLICKED_ON; + ButtonList[ guiBackGroundOptionToggles[ GIO_BUTTON_OFF ] ]->uiFlags &= ~BUTTON_CLICKED_ON; btn->uiFlags|=(BUTTON_CLICKED_ON); - PlayButtonSound( guiOverheatingOptionToggles[ GIO_BUTTON_ON ], BUTTON_SOUND_CLICKED_ON ); + PlayButtonSound( guiBackGroundOptionToggles[ GIO_BUTTON_ON ], BUTTON_SOUND_CLICKED_ON ); } } @@ -2461,8 +2461,8 @@ BOOLEAN ExitGIOScreen() // Destroy Overheating Cost setting buttons for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON ) + if( ButtonList[ guiBackGroundOptionToggles[ cnt ] ]->uiFlags & BUTTON_CLICKED_ON ) { return( cnt ); } @@ -2981,7 +2981,7 @@ void DoneFadeOutForExitGameInitOptionScreen( void ) gGameOptions.fInventoryCostsAP = GetCurrentInventoryAPButtonSetting(); gGameOptions.fUseNCTH = GetCurrentNCTHButtonSetting(); gGameOptions.fImprovedInterruptSystem = GetCurrentIISButtonSetting(); - gGameOptions.fWeaponOverheating = GetCurrentOverheatingButtonSetting(); + gGameOptions.fBackGround = GetCurrentBackGroundButtonSetting(); gGameOptions.fFoodSystem = GetCurrentFoodSystemButtonSetting(); gubGIOExitScreen = INIT_SCREEN; @@ -3211,12 +3211,12 @@ void RenderGIOSmallSelectionFrame(INT16 sX, INT16 sY) #define GIO_DROPALL_SETTING_Y GIO_GUN_SETTING_Y + CHECK_Y_OFFSET + CORRECTION_Y_OFFSET #define GIO_DROPALL_SETTING_WIDTH CHECK_WIDTH -#define GIO_OVERHEATING_SETTING_X SECOND_COLUMN_X + CHECK_X_OFFSET -#define GIO_OVERHEATING_SETTING_Y GIO_DROPALL_SETTING_Y + CHECK_Y_OFFSET + CORRECTION_Y_OFFSET -#define GIO_OVERHEATING_SETTING_WIDTH CHECK_WIDTH +#define GIO_BACKGROUND_SETTING_X SECOND_COLUMN_X + CHECK_X_OFFSET +#define GIO_BACKGROUND_SETTING_Y GIO_DROPALL_SETTING_Y + CHECK_Y_OFFSET + CORRECTION_Y_OFFSET +#define GIO_BACKGROUND_SETTING_WIDTH CHECK_WIDTH #define GIO_FOODSYSTEM_SETTING_X SECOND_COLUMN_X + CHECK_X_OFFSET -#define GIO_FOODSYSTEM_SETTING_Y GIO_OVERHEATING_SETTING_Y + CHECK_Y_OFFSET + CORRECTION_Y_OFFSET +#define GIO_FOODSYSTEM_SETTING_Y GIO_BACKGROUND_SETTING_Y + CHECK_Y_OFFSET + CORRECTION_Y_OFFSET #define GIO_FOODSYSTEM_SETTING_WIDTH CHECK_WIDTH /********************************* @@ -3271,7 +3271,7 @@ void RenderGIOSmallSelectionFrame(INT16 sX, INT16 sY) #define JA2SP_INVENTORY_AP "INVENTORY_USE_AP" #define JA2SP_USE_NCTH "USE_NCTH" #define JA2SP_USE_IIS "IMPROVED_INTERRUPT_SYSTEM" -#define JA2SP_OVERHEATING "WEAPON_OVERHEATING" +#define JA2SP_BACKGROUNDS "BACKGROUNDS" #define JA2SP_FOODSYSTEM "FOOD_SYSTEM" @@ -3505,11 +3505,11 @@ UINT32 guiImprovedInterruptOptionToggles[ GIO_NUM_ONOFF_BUTTONS ]; void BtnGIOImprovedInterruptOffCallback(GUI_BUTTON *btn,INT32 reason); void BtnGIOImprovedInterruptOnCallback(GUI_BUTTON *btn,INT32 reason); -// Overheating -UINT32 guiOverheatingOptionTogglesImage[ GIO_NUM_ONOFF_BUTTONS ]; -UINT32 guiOverheatingOptionToggles[ GIO_NUM_ONOFF_BUTTONS ]; -void BtnGIOOverheatingOffCallback(GUI_BUTTON *btn,INT32 reason); -void BtnGIOOverheatingOnCallback(GUI_BUTTON *btn,INT32 reason); +// Background +UINT32 guiBackGroundOptionTogglesImage[ GIO_NUM_ONOFF_BUTTONS ]; +UINT32 guiBackGroundOptionToggles[ GIO_NUM_ONOFF_BUTTONS ]; +void BtnGIOBackGroundOffCallback(GUI_BUTTON *btn,INT32 reason); +void BtnGIOBackGroundOnCallback(GUI_BUTTON *btn,INT32 reason); // Food System UINT32 guiFoodSystemOptionTogglesImage[ GIO_NUM_ONOFF_BUTTONS ]; @@ -3547,7 +3547,7 @@ UINT8 GetCurrentDropAllButtonSetting(); UINT8 GetCurrentInventoryAPButtonSetting(); UINT8 GetCurrentNCTHButtonSetting(); UINT8 GetCurrentIISButtonSetting(); -UINT8 GetCurrentOverheatingButtonSetting(); +UINT8 GetCurrentBackGroundButtonSetting(); UINT8 GetCurrentFoodSystemButtonSetting(); void DoneFadeOutForExitGameInitOptionScreen( void ); @@ -3654,7 +3654,7 @@ UINT32 GameInitOptionsScreenInit( void ) gGameOptions.fUseNCTH = (BOOLEAN)props.getIntProperty(JA2SP_INI_INITIAL_SECTION, JA2SP_USE_NCTH, 0); gGameOptions.fImprovedInterruptSystem = (BOOLEAN)props.getIntProperty(JA2SP_INI_INITIAL_SECTION, JA2SP_USE_IIS, 0); - gGameOptions.fWeaponOverheating = (BOOLEAN)props.getIntProperty(JA2SP_INI_INITIAL_SECTION, JA2SP_OVERHEATING, 0); + gGameOptions.fBackGround = (BOOLEAN)props.getIntProperty(JA2SP_INI_INITIAL_SECTION, JA2SP_BACKGROUNDS, 0); gGameOptions.fFoodSystem = (BOOLEAN)props.getIntProperty(JA2SP_INI_INITIAL_SECTION, JA2SP_FOODSYSTEM, 0); // Air strikes @@ -4220,33 +4220,33 @@ BOOLEAN EnterGIOScreen() /////////////////////////////////////////////////////////////////////////////////////////////////////// - // OVERHEATING WEAPONS ON/OFF SETTING + // BACKGROUND ON/OFF SETTING - guiOverheatingOptionTogglesImage[ GIO_BUTTON_OFF ] = UseLoadedButtonImage( guiTraitsOptionTogglesImage[ GIO_TRAITS_OLD ], -1,1,-1,3,-1 ); - guiOverheatingOptionToggles[ GIO_BUTTON_OFF ] = CreateIconAndTextButton( guiOverheatingOptionTogglesImage[ GIO_BUTTON_OFF ], gzGIOScreenText[ GIO_DROPALL_OFF_TEXT ], GIO_TOGGLE_TEXT_FONT, + guiBackGroundOptionTogglesImage[ GIO_BUTTON_OFF ] = UseLoadedButtonImage( guiTraitsOptionTogglesImage[ GIO_TRAITS_OLD ], -1,1,-1,3,-1 ); + guiBackGroundOptionToggles[ GIO_BUTTON_OFF ] = CreateIconAndTextButton( guiBackGroundOptionTogglesImage[ GIO_BUTTON_OFF ], gzGIOScreenText[ GIO_DROPALL_OFF_TEXT ], GIO_TOGGLE_TEXT_FONT, GIO_TOGGLE_TEXT_COLOR, NO_SHADOW, GIO_TOGGLE_TEXT_COLOR, NO_SHADOW, TEXT_CJUSTIFIED, - (GIO_OVERHEATING_SETTING_X), (GIO_OVERHEATING_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, - DEFAULT_MOVE_CALLBACK, BtnGIOOverheatingOffCallback); + (GIO_BACKGROUND_SETTING_X), (GIO_BACKGROUND_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, + DEFAULT_MOVE_CALLBACK, BtnGIOBackGroundOffCallback); - guiOverheatingOptionTogglesImage[ GIO_BUTTON_ON ] = UseLoadedButtonImage( guiTraitsOptionTogglesImage[ GIO_TRAITS_OLD ], -1,1,-1,3,-1 ); - guiOverheatingOptionToggles[ GIO_BUTTON_ON ] = CreateIconAndTextButton( guiOverheatingOptionTogglesImage[ GIO_BUTTON_ON ], gzGIOScreenText[ GIO_DROPALL_ON_TEXT ], GIO_TOGGLE_TEXT_FONT, + guiBackGroundOptionTogglesImage[ GIO_BUTTON_ON ] = UseLoadedButtonImage( guiTraitsOptionTogglesImage[ GIO_TRAITS_OLD ], -1,1,-1,3,-1 ); + guiBackGroundOptionToggles[ GIO_BUTTON_ON ] = CreateIconAndTextButton( guiBackGroundOptionTogglesImage[ GIO_BUTTON_ON ], gzGIOScreenText[ GIO_DROPALL_ON_TEXT ], GIO_TOGGLE_TEXT_FONT, GIO_TOGGLE_TEXT_COLOR, NO_SHADOW, GIO_TOGGLE_TEXT_COLOR, NO_SHADOW, TEXT_CJUSTIFIED, - (GIO_OVERHEATING_SETTING_X + 74), (GIO_OVERHEATING_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, - DEFAULT_MOVE_CALLBACK, BtnGIOOverheatingOnCallback ); + (GIO_BACKGROUND_SETTING_X + 74), (GIO_BACKGROUND_SETTING_Y + 10), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, + DEFAULT_MOVE_CALLBACK, BtnGIOBackGroundOnCallback ); - SpecifyButtonSoundScheme( guiOverheatingOptionToggles[ GIO_BUTTON_OFF ], BUTTON_SOUND_SCHEME_BIGSWITCH3 ); - SpecifyButtonSoundScheme( guiOverheatingOptionToggles[ GIO_BUTTON_ON ], BUTTON_SOUND_SCHEME_BIGSWITCH3 ); - MSYS_SetBtnUserData(guiOverheatingOptionToggles[ GIO_BUTTON_OFF ],0, 0 ); - MSYS_SetBtnUserData(guiOverheatingOptionToggles[ GIO_BUTTON_ON ],0, 1 ); + SpecifyButtonSoundScheme( guiBackGroundOptionToggles[ GIO_BUTTON_OFF ], BUTTON_SOUND_SCHEME_BIGSWITCH3 ); + SpecifyButtonSoundScheme( guiBackGroundOptionToggles[ GIO_BUTTON_ON ], BUTTON_SOUND_SCHEME_BIGSWITCH3 ); + MSYS_SetBtnUserData(guiBackGroundOptionToggles[ GIO_BUTTON_OFF ],0, 0 ); + MSYS_SetBtnUserData(guiBackGroundOptionToggles[ GIO_BUTTON_ON ],0, 1 ); - if( gGameOptions.fWeaponOverheating ) - ButtonList[ guiOverheatingOptionToggles[ GIO_BUTTON_ON ] ]->uiFlags |= BUTTON_CLICKED_ON; + if( gGameOptions.fBackGround ) + ButtonList[ guiBackGroundOptionToggles[ GIO_BUTTON_ON ] ]->uiFlags |= BUTTON_CLICKED_ON; else - ButtonList[ guiOverheatingOptionToggles[ GIO_BUTTON_OFF ] ]->uiFlags |= BUTTON_CLICKED_ON; + ButtonList[ guiBackGroundOptionToggles[ GIO_BUTTON_OFF ] ]->uiFlags |= BUTTON_CLICKED_ON; /////////////////////////////////////////////////////////////////////////////////////////////////////// // FOOD SYSTEM ON/OFF SETTING @@ -5183,34 +5183,34 @@ void BtnGIOImprovedInterruptOnCallback(GUI_BUTTON *btn,INT32 reason) } } -void BtnGIOOverheatingOffCallback(GUI_BUTTON *btn,INT32 reason) +void BtnGIOBackGroundOffCallback(GUI_BUTTON *btn,INT32 reason) { if (!(btn->uiFlags & BUTTON_ENABLED)) return; if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN ) { - RestoreExternBackgroundRect( (GIO_OVERHEATING_SETTING_X), (GIO_OVERHEATING_SETTING_Y + 10), 230, 40 ); + RestoreExternBackgroundRect( (GIO_BACKGROUND_SETTING_X), (GIO_BACKGROUND_SETTING_Y + 10), 230, 40 ); - ButtonList[ guiOverheatingOptionToggles[ GIO_BUTTON_ON ] ]->uiFlags &= ~BUTTON_CLICKED_ON; + ButtonList[ guiBackGroundOptionToggles[ GIO_BUTTON_ON ] ]->uiFlags &= ~BUTTON_CLICKED_ON; btn->uiFlags|=(BUTTON_CLICKED_ON); - PlayButtonSound( guiOverheatingOptionToggles[ GIO_BUTTON_OFF ], BUTTON_SOUND_CLICKED_ON ); + PlayButtonSound( guiBackGroundOptionToggles[ GIO_BUTTON_OFF ], BUTTON_SOUND_CLICKED_ON ); } } -void BtnGIOOverheatingOnCallback(GUI_BUTTON *btn,INT32 reason) +void BtnGIOBackGroundOnCallback(GUI_BUTTON *btn,INT32 reason) { if (!(btn->uiFlags & BUTTON_ENABLED)) return; if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN ) { - RestoreExternBackgroundRect( (GIO_OVERHEATING_SETTING_X), (GIO_OVERHEATING_SETTING_Y + 10), 230, 40 ); + RestoreExternBackgroundRect( (GIO_BACKGROUND_SETTING_X), (GIO_BACKGROUND_SETTING_Y + 10), 230, 40 ); - ButtonList[ guiOverheatingOptionToggles[ GIO_BUTTON_OFF ] ]->uiFlags &= ~BUTTON_CLICKED_ON; + ButtonList[ guiBackGroundOptionToggles[ GIO_BUTTON_OFF ] ]->uiFlags &= ~BUTTON_CLICKED_ON; btn->uiFlags|=(BUTTON_CLICKED_ON); - PlayButtonSound( guiOverheatingOptionToggles[ GIO_BUTTON_ON ], BUTTON_SOUND_CLICKED_ON ); + PlayButtonSound( guiBackGroundOptionToggles[ GIO_BUTTON_ON ], BUTTON_SOUND_CLICKED_ON ); } } @@ -5374,11 +5374,11 @@ BOOLEAN ExitGIOScreen() UnloadButtonImage( guiImprovedInterruptOptionTogglesImage[ cnt ] ); } - // Destroy Overheating Cost setting buttons - for( cnt=0; cntuiFlags & BUTTON_CLICKED_ON ) + if( ButtonList[ guiBackGroundOptionToggles[ cnt ] ]->uiFlags & BUTTON_CLICKED_ON ) { return( cnt ); } @@ -5874,7 +5874,7 @@ void DoneFadeOutForExitGameInitOptionScreen( void ) gGameOptions.fUseNCTH = GetCurrentNCTHButtonSetting(); gGameOptions.fImprovedInterruptSystem = GetCurrentIISButtonSetting(); - gGameOptions.fWeaponOverheating = GetCurrentOverheatingButtonSetting(); + gGameOptions.fBackGround = GetCurrentBackGroundButtonSetting(); gGameOptions.fFoodSystem = GetCurrentFoodSystemButtonSetting(); diff --git a/GameSettings.cpp b/GameSettings.cpp index 67c3b73b1..ab2158d3c 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -622,7 +622,7 @@ void InitGameOptions() gGameOptions.fUseNCTH = FALSE; gGameOptions.fImprovedInterruptSystem = TRUE; - gGameOptions.fWeaponOverheating = TRUE; + gGameOptions.fBackGround = FALSE; gGameOptions.fFoodSystem = FALSE; //CHRISL: override default inventory mode when in low res @@ -1476,7 +1476,7 @@ void LoadGameExternalOptions() //################# Tactical Weapon Overheating Settings ################## // Flugente: These settings control the behavior of Weapon Overheating, its severity, and its display. - + gGameExternalOptions.fWeaponOverheating = iniReader.ReadBoolean("Tactical Weapon Overheating Settings","OVERHEATING",FALSE); 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); diff --git a/GameSettings.h b/GameSettings.h index db84fe615..ed84a65af 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -230,7 +230,7 @@ typedef struct BOOLEAN fUseNCTH; // ubFiller: From 499 to 498 BOOLEAN fImprovedInterruptSystem; // ubFiller: From 498 to 497 - BOOLEAN fWeaponOverheating; // ubFiller: From 497 to 496 + BOOLEAN fBackGround; // ubFiller: From 497 to 496 BOOLEAN fFoodSystem; // ubFiler: From 496 to 495 // WANNE: Decrease this filler by 1, for each new UINT8 / BOOLEAN variable, so we can maintain savegame compatibility!! @@ -1206,6 +1206,7 @@ typedef struct FLOAT fClockSpeedPercent; // Flugente: Weapon Overheating + BOOLEAN fWeaponOverheating; // Should weapons overheat, thus increasing the chance of malfunction? 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 left alone in the landscape ;-) diff --git a/GameVersion.cpp b/GameVersion.cpp index 40a5bb37f..c439ad76c 100644 --- a/GameVersion.cpp +++ b/GameVersion.cpp @@ -15,9 +15,9 @@ #ifdef JA2EDITOR #ifdef JA2UB - CHAR16 zVersionLabel[256] = { L"Unfinished Business - Map Editor v1.13.5520 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Unfinished Business - Map Editor v1.13.6353 (Development Build)" }; #else - CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.5520 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.6353 (Development Build)" }; #endif // ------------------------------ @@ -27,11 +27,11 @@ //DEBUG BUILD VERSION #ifdef JA2UB - CHAR16 zVersionLabel[256] = { L"Debug: Unfinished Business - v1.13.5520 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Debug: Unfinished Business - v1.13.6353 (Development Build)" }; #elif defined (JA113DEMO) - CHAR16 zVersionLabel[256] = { L"Debug: JA2 Demo - v1.13.5520 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Debug: JA2 Demo - v1.13.6353 (Development Build)" }; #else - CHAR16 zVersionLabel[256] = { L"Debug: v1.13.5520 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Debug: v1.13.6353 (Development Build)" }; #endif #elif defined CRIPPLED_VERSION @@ -46,11 +46,11 @@ //RELEASE BUILD VERSION #ifdef JA2UB - CHAR16 zVersionLabel[256] = { L"Release Unfinished Business - v1.13.5520 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Release Unfinished Business - v1.13.6353 (Development Build)" }; #elif defined (JA113DEMO) - CHAR16 zVersionLabel[256] = { L"Release JA2 Demo - v1.13.5520 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Release JA2 Demo - v1.13.6353 (Development Build)" }; #else - CHAR16 zVersionLabel[256] = { L"Release v1.13.5521 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Release v1.13.6353 (Development Build)" }; #endif #endif diff --git a/GameVersion.h b/GameVersion.h index ed1213d86..e6bf35abd 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 BACKGROUNDS 145 // Flugente: background feature #define NO_VEHICLE_SAVE 144 // Flugente: vehicle data isn't saved anymore, as it has long been externalised #define SOLDIER_PROFILES 143 // Flugente: profiles for enemy and militia (possibly any non-NPC/RPC character) #define DYNAMIC_FLASHLIGHTS 142 // Flugente: had to add variables to LIGHTEFFECT-struct @@ -63,7 +64,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 NO_VEHICLE_SAVE +#define SAVE_GAME_VERSION BACKGROUNDS //#define RUSSIANGOLD #ifdef __cplusplus diff --git a/Init.cpp b/Init.cpp index f46a06740..6384b0b56 100644 --- a/Init.cpp +++ b/Init.cpp @@ -998,11 +998,17 @@ BOOLEAN LoadExternalGameplayData(STR directoryName) #endif } - // IMP Portraits List by Jazz - strcpy(fileName, directoryName); - strcat(fileName, IMPPORTRAITS); - DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName)); - SGP_THROW_IFFALSE(ReadInIMPPortraits(fileName,FALSE), IMPPORTRAITS); + // Flugente: backgrounds + strcpy(fileName, directoryName); + strcat(fileName, BACKGROUNDSFILENAME); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName)); + SGP_THROW_IFFALSE(ReadInBackgrounds(fileName), BACKGROUNDSFILENAME); + + // IMP Portraits List by Jazz + strcpy(fileName, directoryName); + strcat(fileName, IMPPORTRAITS); + DebugMsg (TOPIC_JA2,DBG_LEVEL_3,String("LoadExternalGameplayData, fileName = %s", fileName)); + SGP_THROW_IFFALSE(ReadInIMPPortraits(fileName,FALSE), IMPPORTRAITS); #ifndef ENGLISH AddLanguagePrefix(fileName); diff --git a/Laptop/CharProfile.cpp b/Laptop/CharProfile.cpp index 876fd813f..33834d94c 100644 --- a/Laptop/CharProfile.cpp +++ b/Laptop/CharProfile.cpp @@ -31,6 +31,7 @@ #include "IMP Disability Trait.h" #include "IMP Color Choosing.h" #include "IMP Minor Trait.h" + #include "IMP Background.h" // added by Flugente #endif @@ -76,6 +77,8 @@ INT32 iPersonality = 0; // attitude INT32 iAttitude = 0; +// Flugente: background +UINT8 usBackground = 0; // additives, but no preservatives INT32 iAddStrength = 0; @@ -274,6 +277,9 @@ void HandleCharProfile() case( IMP_MINOR_TRAITS_PAGE ): HandleIMPMinorTrait( ); break; + case( IMP_BACKGROUND ): + HandleIMPBackground( ); + break; } return; @@ -350,6 +356,9 @@ void RenderCharProfile() case( IMP_MINOR_TRAITS_PAGE ): RenderIMPMinorTrait( ); break; + case( IMP_BACKGROUND ): + RenderIMPBackground( ); + break; } // render title bar @@ -455,6 +464,10 @@ void ExitOldIMPMode( void ) DestroyIMPButtons( ); ExitIMPMinorTrait( ); break; + case( IMP_BACKGROUND ): + DestroyIMPButtons( ); + ExitIMPBackground( ); + break; } return; @@ -542,6 +555,10 @@ void EnterNewIMPMode( void ) CreateIMPButtons( ); EnterIMPMinorTrait( ); break; + case( IMP_BACKGROUND ): + CreateIMPButtons( ); + EnterIMPBackground( ); + break; } @@ -577,11 +594,12 @@ void ResetCharacterStats( void ) // attitude iAttitude = 0; + // background + usBackground = 0; + // names memset( &pFullName, 0 , sizeof( pFullName) ); memset( &pNickName, 0 , sizeof( pNickName) ); - - } diff --git a/Laptop/CharProfile.h b/Laptop/CharProfile.h index f569b217d..21afdb219 100644 --- a/Laptop/CharProfile.h +++ b/Laptop/CharProfile.h @@ -46,6 +46,9 @@ extern INT32 iPersonality; // attitude extern INT32 iAttitude; +// Flugente: background +extern UINT8 usBackground; + //addtivies extern INT32 iAddStrength; extern INT32 iAddDexterity; @@ -85,6 +88,7 @@ enum{ IMP_DISABILITY_PAGE, IMP_COLOR_CHOICE_PAGE, IMP_MINOR_TRAITS_PAGE, + IMP_BACKGROUND, IMP_NUM_PAGES, }; diff --git a/Laptop/IMP Background.cpp b/Laptop/IMP Background.cpp new file mode 100644 index 000000000..d04a33fe0 --- /dev/null +++ b/Laptop/IMP Background.cpp @@ -0,0 +1,794 @@ +#ifdef PRECOMPILEDHEADERS + #include "Laptop All.h" + #include "IMP Skill Trait.h" + #include "_Ja25Englishtext.h" +#else + #include "IMP Background.h" + #include "IMP Skill Trait.h" + #include "Button System.h" + #include "utilities.h" + #include "Debug.h" + #include "Text.h" + #include "Font Control.h" + #include "font.h" + #include "laptop.h" + #include "cursors.h" + #include "IMP MainPage.h" + #include "IMPVideoObjects.h" + #include "_Ja25EnglishText.h" + #include "wordwrap.h" + #include "CharProfile.h" + #include "soldier profile type.h" + #include "IMP Compile Character.h" + #include "GameSettings.h" + #include "Interface.h" +#endif + + + +//******************************************************************* +// +// Local Defines +// +//******************************************************************* + +#define IMP_BACKGROUND__TITLE_FONT FONT14ARIAL + +#define IMP_BACKGROUND__FONT FONT12ARIAL +#define IMP_BACKGROUND__COLOR FONT_MCOLOR_WHITE + +#define IMP_BACKGROUND_COLUMN_START_X ( LAPTOP_SCREEN_UL_X + 136 ) +#define IMP_BACKGROUND_COLUMN_START_Y ( LAPTOP_SCREEN_WEB_UL_Y + 40 ) + +#define IMP_BACKGROUND__SPACE_BTN_BUTTONS ( 38 + 0 ) + +#define IMP_BACKGROUND__TRAITS_TO_START_RIGHT_COL 8 + +#define IMP_BACKGROUND__NONE_BTN_LOC_X ( LAPTOP_SCREEN_UL_X + 136 ) +#define IMP_BACKGROUND__NONE_BTN_LOC_Y ( LAPTOP_SCREEN_WEB_UL_Y + 306 ) + +#define IMP_BACKGROUND__TEXT_OFFSET_X 65 +#define IMP_BACKGROUND__TEXT_OFFSET_Y 12 + +#define IMP_BACKGROUND__TITLE_X LAPTOP_SCREEN_UL_X - 111 +#define IMP_BACKGROUND__TITLE_Y iScreenHeightOffset + 53 +#define IMP_BACKGROUND__TITLE_WIDTH ( LAPTOP_SCREEN_LR_X - LAPTOP_SCREEN_UL_X ) + +#define IMP_BACKGROUND__GREY_BOX_OFFSET_X 5 +#define IMP_BACKGROUND__GREY_BOX_OFFSET_Y 7 + +//******************************************************************* +// +// Global Variables +// +//******************************************************************* + +BOOLEAN gfIMPBackground_Redraw=FALSE; + +#define IMP_BACKGROUND_DISPLAYED_CHOICES 8 +#define IMP_BACKGROUND_NONE IMP_BACKGROUND_DISPLAYED_CHOICES - 1 +BOOLEAN gfBackgroundQuestions[ IMP_BACKGROUND_DISPLAYED_CHOICES ]; + +// these are the buttons for the questions +INT32 giIMPBackgroundAnswerButton[ IMP_BACKGROUND_DISPLAYED_CHOICES ]; +INT32 giIMPBackgroundAnswerButtonImage[ IMP_BACKGROUND_DISPLAYED_CHOICES ]; + +// this is the Done buttons +INT32 giIMPBackgroundFinsihButton; +INT32 giIMPBackgroundFinsihButtonImage; + +INT8 gbLastSelectedBackground[ 10 ]; + +//image handle +UINT32 guiIMPBackground_GreyGoldBox; + +MOUSE_REGION gMR_BackgroundHelpTextRegions[IMP_BACKGROUND_DISPLAYED_CHOICES]; + +// forward/backward buttons +INT32 giIMPBackgroundButton[ 2 ]; +INT32 giIMPBackgroundButtonImage[ 2 ]; + +//******************************************************************* +// +// Function Prototypes +// +//******************************************************************* + +void BtnIMPBackgroundAnswerCallback(GUI_BUTTON *btn,INT32 reason); +void BtnIMPBackgroundFinishCallback(GUI_BUTTON *btn,INT32 reason); +void AddIMPBackgroundButtons(); +void HandleBackgroundButtonStates( ); +void HandleIMPBackgroundAnswers( UINT32 uiSkillPressed ); +void IMPBackgroundDisplaySkills(); +BOOLEAN CameBackToBackgroundPageButNotFinished(); + +void DestroyIMPBackgroundButtons( void ); + +// callbacks +void BtnIMPBackgroundNextCallback(GUI_BUTTON *btn,INT32 reason); +void BtnIMPBackgroundPreviousCallback(GUI_BUTTON *btn,INT32 reason); + +void UpdateDisplaySkills( BOOLEAN fIncrease ); +UINT8 GetDisplaySkill( UINT8 aNr ); +void ResetDisplaySkills(); +//ppp + +//******************************************************************* +// +// Functions +// +//******************************************************************* + + + +void EnterIMPBackground( void ) +{ + UINT8 ubCnt; + + VOBJECT_DESC VObjectDesc; + + //add the skill trait buttons + AddIMPBackgroundButtons(); + + // load the stats graphic and add it + VObjectDesc.fCreateFlags=VOBJECT_CREATE_FROMFILE; + FilenameForBPP("LAPTOP\\SkillTraitSmallGreyIdent.sti", VObjectDesc.ImageFile); + if( !AddVideoObject(&VObjectDesc, &guiIMPBackground_GreyGoldBox ) ) + { + Assert( 0 ); + return; + } + + giIMPBackgroundFinsihButtonImage = LoadButtonImage( "LAPTOP\\button_5.sti" ,-1,0,-1,1,-1 ); + giIMPBackgroundFinsihButton = CreateIconAndTextButton( giIMPBackgroundFinsihButtonImage, pImpButtonText[ 24 ], FONT12ARIAL, + FONT_WHITE, DEFAULT_SHADOW, + FONT_WHITE, DEFAULT_SHADOW, + TEXT_CJUSTIFIED, + LAPTOP_SCREEN_UL_X + ( 350 ), LAPTOP_SCREEN_WEB_UL_Y + ( 340 ), BUTTON_TOGGLE, MSYS_PRIORITY_HIGH, + BtnGenericMouseMoveButtonCallback, (GUI_CALLBACK)BtnIMPBackgroundFinishCallback ); + + SetButtonCursor( giIMPBackgroundFinsihButton, CURSOR_WWW); + + //if we are not DONE and are just reviewing + if( iCurrentProfileMode != IMP__FINISH ) + { + for (ubCnt = 0; ubCntuiFlags & BUTTON_ENABLED)) + return; + + if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN ) + { + INT32 iBackground = MSYS_GetBtnUserData( btn, 0 ); + + HandleIMPBackgroundAnswers( iBackground ); + } +} + +void HandleIMPBackgroundAnswers( UINT32 uiSkillPressed ) +{ + UINT32 uiCnt; + + //if we are DONE and are just reviewing + if( iCurrentProfileMode == IMP__FINISH ) + { + return; + } + + //make sure its a valid skill + if( uiSkillPressed > IMP_BACKGROUND_DISPLAYED_CHOICES ) + { + Assert( 0 ); + return; + } + + //reset all other buttons + for( uiCnt=0; uiCntuiFlags |= BUTTON_CLICKED_ON; + } + else + { + ButtonList[ giIMPBackgroundAnswerButton[ uiCnt ] ]->uiFlags &= ~BUTTON_CLICKED_ON; + } + } +} + +void IMPBackgroundDisplaySkills() +{ + UINT32 uiCnt; + UINT16 usPosX, usPosY; + UINT16 usBoxPosX, usBoxPosY; + HVOBJECT hImageHandle; + + //Display the title + DrawTextToScreen( L"I.M.P. Background", IMP_BACKGROUND__TITLE_X, IMP_BACKGROUND__TITLE_Y, IMP_BACKGROUND__TITLE_WIDTH, IMP_BACKGROUND__TITLE_FONT, IMP_BACKGROUND__COLOR, FONT_MCOLOR_BLACK, FALSE, CENTER_JUSTIFIED ); + + // Stats + GetVideoObject(&hImageHandle, guiIMPBackground_GreyGoldBox ); + + usPosX = IMP_BACKGROUND_COLUMN_START_X + IMP_BACKGROUND__TEXT_OFFSET_X; + usPosY = IMP_BACKGROUND_COLUMN_START_Y + IMP_BACKGROUND__TEXT_OFFSET_Y; + + for( uiCnt=0; uiCntuiFlags & BUTTON_ENABLED)) + return; + + if( reason & MSYS_CALLBACK_REASON_LBUTTON_DWN ) + { + btn->uiFlags|=(BUTTON_CLICKED_ON); + + //if we are just reviewing the page + if( iCurrentProfileMode == IMP__FINISH ) + { + //go back tot he done screen + iCurrentImpPage = IMP_FINISH; + } + else + { + iCurrentImpPage = IMP_MAIN_PAGE; + + fButtonPendingFlag = TRUE; + + if( CameBackToBackgroundPageButNotFinished() ) + { + } + else + { + //We are finished on this page + iCurrentProfileMode = IMP__ATTRIBUTES; + } + } + } +} + +BOOLEAN CameBackToBackgroundPageButNotFinished() +{ + //if we are in a page that comes after this one + if( iCurrentProfileMode == IMP__ATTRIBUTES ) + { + return( TRUE ); + } + else + { + return( FALSE ); + } +} + +void AssignBackgroundHelpText( UINT8 ubNumber, MOUSE_REGION* pMouseregion ) +{ + CHAR16 apStr[ 4500 ]; + CHAR16 atStr[ 260 ]; + + swprintf( apStr, L"" ); + + if ( ubNumber ) + { + swprintf(atStr, zBackground[ ubNumber ].szName ); + wcscat( apStr, atStr ); + wcscat( apStr, L"\n" ); + + swprintf(atStr, zBackground[ ubNumber ].szDescription ); + wcscat( apStr, atStr ); + wcscat( apStr, L"\n" ); + + // ability description + for ( UINT8 i = 0; i < BACKGROUND_FLAG_MAX; ++i) + { + if ( zBackground[ ubNumber ].uiFlags & ((UINT64)1 << i) ) + { + swprintf(atStr, szBackgroundText_Flags[ i ] ); + wcscat( apStr, atStr ); + } + } + + for ( UINT8 i = 0; i < BG_MAX; ++i) + { + if ( zBackground[ ubNumber ].value[i] ) + { + swprintf(atStr, szBackgroundText_Value[ i ], zBackground[ ubNumber ].value[i] > 0 ? L"+" : L"", zBackground[ ubNumber ].value[i] ); + wcscat( apStr, atStr ); + } + } + } + else + return; + + // Set region help text + SetRegionFastHelpText( pMouseregion, apStr ); + SetRegionHelpEndCallback( pMouseregion, MSYS_NO_CALLBACK ); + + return; +} + + +UINT8 displayedskills[IMP_BACKGROUND_DISPLAYED_CHOICES]; +UINT8 gBackgroundFirstItem = 0; +UINT8 gBackgroundLastItem = 0; + +void UpdateDisplaySkills( BOOLEAN fIncrease ) +{ + // fill a helper array with all viable choices + UINT8 tmparray[NUM_BACKGROUND]; + UINT8 arraycounter = 0; + UINT8 found = 0; + for (UINT8 ubCnt = 0; ubCnt= IMP_BACKGROUND_DISPLAYED_CHOICES ) + return 0; + + return displayedskills[ aNr ]; +}; + +void ResetDisplaySkills() +{ + for (UINT8 ubCnt = 0; ubCnt 0 ) + return FALSE; + } + + if ( SkillsList[0] == SNIPER_NT || SkillsList[1] == SNIPER_NT || SkillsList[2] == SNIPER_NT ) + { + if ( zBackground[ ubNumber ].value[BG_PERC_CTH_MAX] < 0 ) + return FALSE; + } + + if ( SkillsList[0] == RANGER_NT || SkillsList[1] == RANGER_NT || SkillsList[2] == RANGER_NT ) + { + if ( zBackground[ ubNumber ].value[BG_PERC_CAMO] < 0 ) + return FALSE; + } + + if ( SkillsList[0] == MARTIAL_ARTS_NT || SkillsList[1] == MARTIAL_ARTS_NT || SkillsList[2] == MARTIAL_ARTS_NT ) + { + if ( zBackground[ ubNumber ].value[BG_PERC_DAMAGE_MELEE] < 0 ) + return FALSE; + } + + if ( SkillsList[0] == TECHNICIAN_NT || SkillsList[1] == TECHNICIAN_NT || SkillsList[2] == TECHNICIAN_NT ) + { + if ( zBackground[ ubNumber ].value[MECHANICAL] < 0 ) + return FALSE; + } + + if ( SkillsList[0] == DOCTOR_NT || SkillsList[1] == DOCTOR_NT || SkillsList[2] == DOCTOR_NT ) + { + if ( zBackground[ ubNumber ].value[MEDICAL] < 0 ) + return FALSE; + } + + if ( SkillsList[0] == MELEE_NT || SkillsList[1] == MELEE_NT || SkillsList[2] == MELEE_NT ) + { + if ( zBackground[ ubNumber ].value[BG_PERC_CTH_BLADE] < 0 ) + return FALSE; + } + + if ( SkillsList[0] == STEALTHY_NT || SkillsList[1] == STEALTHY_NT || SkillsList[2] == STEALTHY_NT ) + { + if ( zBackground[ ubNumber ].value[BG_PERC_STEALTH] < 0 ) + return FALSE; + } + + if ( SkillsList[0] == ATHLETICS_NT || SkillsList[1] == ATHLETICS_NT || SkillsList[2] == ATHLETICS_NT ) + { + if ( zBackground[ ubNumber ].value[BG_PERC_SPEED_RUNNING] < 0 ) + return FALSE; + } + + if ( SkillsList[0] == DEMOLITIONS_NT || SkillsList[1] == DEMOLITIONS_NT || SkillsList[2] == DEMOLITIONS_NT ) + { + if ( zBackground[ ubNumber ].value[EXPLOSIVE_ASSIGN] < 0 ) + return FALSE; + } + + switch ( iPersonality ) + { + case HEAT_INTOLERANT: + if ( zBackground[ ubNumber ].value[BG_DESERT] > 0 ) + return FALSE; + break; + case NERVOUS: + break; + case CLAUSTROPHOBIC: + if ( zBackground[ ubNumber ].uiFlags & BACKGROUND_EXP_UNDERGROUND ) + return FALSE; + break; + case NONSWIMMER: + if ( zBackground[ ubNumber ].value[BG_RIVER] > 0 || zBackground[ ubNumber ].value[BG_COASTAL] > 0 || zBackground[ ubNumber ].value[BG_SWIMMING] > 0 ) + return FALSE; + break; + case FEAR_OF_INSECTS: + if ( zBackground[ ubNumber ].value[BG_SWAMP] > 0 || zBackground[ ubNumber ].value[BG_TROPICAL] > 0 ) + return FALSE; + break; + case FORGETFUL: + if ( zBackground[ ubNumber ].value[LEADERSHIP] > 0 ) + return FALSE; + break; + case PSYCHO: + if ( zBackground[ ubNumber ].value[LEADERSHIP] > 0 ) + return FALSE; + break; + default: + break; + } + + + switch ( iAttitude ) + { + case CHAR_TRAIT_SOCIABLE: + if ( zBackground[ ubNumber ].uiFlags & BACKGROUND_XENOPHOBIC ) + return FALSE; + break; + case CHAR_TRAIT_LONER: + if ( zBackground[ ubNumber ].value[LEADERSHIP] > 0 ) + return FALSE; + break; + case CHAR_TRAIT_OPTIMIST: + case CHAR_TRAIT_ASSERTIVE: + case CHAR_TRAIT_INTELLECTUAL: + case CHAR_TRAIT_PRIMITIVE: + case CHAR_TRAIT_AGGRESSIVE: + case CHAR_TRAIT_PHLEGMATIC: + case CHAR_TRAIT_DAUNTLESS: + case CHAR_TRAIT_PACIFIST: + case CHAR_TRAIT_MALICIOUS: + case CHAR_TRAIT_SHOWOFF: + break; + default: + break; + } + + return TRUE; +} + +void DestroyIMPBackgroundButtons( void ) +{ + // the next button + RemoveButton(giIMPBackgroundButton[ 0 ] ); + UnloadButtonImage(giIMPBackgroundButtonImage[ 0 ] ); + + // the previous button + RemoveButton(giIMPBackgroundButton[ 1 ] ); + UnloadButtonImage(giIMPBackgroundButtonImage[ 1 ] ); +} + +void BtnIMPBackgroundNextCallback(GUI_BUTTON *btn,INT32 reason) +{ + + // btn callback for IMP attrbite begin button + if (!(btn->uiFlags & BUTTON_ENABLED)) + return; + + if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN ) + { + btn->uiFlags|=(BUTTON_CLICKED_ON); + } + else if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) + { + if (btn->uiFlags & BUTTON_CLICKED_ON) + { + btn->uiFlags&=~(BUTTON_CLICKED_ON); + + // next picture!! + UpdateDisplaySkills( TRUE ); + + gfIMPBackground_Redraw = TRUE; + + //reset all other buttons + for( UINT8 uiCnt=0; uiCntuiFlags & BUTTON_ENABLED)) + return; + + if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN ) + { + btn->uiFlags|=(BUTTON_CLICKED_ON); + } + else if(reason & MSYS_CALLBACK_REASON_LBUTTON_UP ) + { + if (btn->uiFlags & BUTTON_CLICKED_ON) + { + btn->uiFlags&=~(BUTTON_CLICKED_ON); + + // previous picture, please!!! + UpdateDisplaySkills( FALSE ); + + gfIMPBackground_Redraw = TRUE; + + //reset all other buttons + for( UINT8 uiCnt=0; uiCnt + + @@ -772,6 +776,10 @@ RelativePath=".\IMP Attribute Selection.cpp" > + + diff --git a/Laptop/Laptop_VS2008.vcproj b/Laptop/Laptop_VS2008.vcproj index ba3f9c59b..d04c7f0b3 100644 --- a/Laptop/Laptop_VS2008.vcproj +++ b/Laptop/Laptop_VS2008.vcproj @@ -482,6 +482,10 @@ RelativePath="IMP Attribute Selection.h" > + + @@ -774,6 +778,10 @@ RelativePath="IMP Attribute Selection.cpp" > + + diff --git a/Laptop/Laptop_VS2010.vcxproj b/Laptop/Laptop_VS2010.vcxproj index 35e3e05b6..836d0813e 100644 --- a/Laptop/Laptop_VS2010.vcxproj +++ b/Laptop/Laptop_VS2010.vcxproj @@ -59,6 +59,7 @@ + @@ -133,6 +134,7 @@ + diff --git a/Laptop/Laptop_VS2010.vcxproj.filters b/Laptop/Laptop_VS2010.vcxproj.filters index cd8ce1ec9..eb82d04fb 100644 --- a/Laptop/Laptop_VS2010.vcxproj.filters +++ b/Laptop/Laptop_VS2010.vcxproj.filters @@ -225,6 +225,9 @@ Header Files + + Header Files + @@ -461,5 +464,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/Laptop/personnel.cpp b/Laptop/personnel.cpp index 00e996765..54a5e1e28 100644 --- a/Laptop/personnel.cpp +++ b/Laptop/personnel.cpp @@ -35,7 +35,10 @@ #include "Soldier Macros.h" #include "InterfaceItemImages.h" +#include "IMP Skill Trait.h" // added by Flugente #include "Map Screen Interface.h" // added by Flugente +#include "Interface.h" // added by Flugente +#include "IMP Background.h" // added by Flugente for AssignBackgroundHelpText() // WDS - make number of mercenaries, etc. be configurable @@ -1673,6 +1676,44 @@ void DisplayCharStats(INT32 iId, INT32 iSlot) mprintf(sX,pPersonnelScreenPoints[iCounter].y,sString); break; + // Added by Flugente + case 16: + // Background + + // display background + if ( gGameOptions.fBackGround ) + { + UINT8 loc = 21; + UINT8 regionnr = 12; + + mprintf((INT16)(pPersonnelScreenPoints[loc].x+(iSlot*TEXT_BOX_WIDTH)),(pPersonnelScreenPoints[loc].y + 15), L"Background:"); + + if ( !gMercProfiles[pSoldier->ubProfile].usBackground ) + swprintf(sString, L"unknown"); + else + swprintf(sString, zBackground[ gMercProfiles[pSoldier->ubProfile].usBackground ].szShortName); + + FindFontRightCoordinates((INT16)(pPersonnelScreenPoints[loc].x+(iSlot*TEXT_BOX_WIDTH)),0,TEXT_BOX_WIDTH-20,0,sString, PERS_FONT, &sX, &sY); + mprintf(sX,(pPersonnelScreenPoints[loc].y + 15),sString); + + // Add specific region for fast help window + if( fAddedTraitRegion[regionnr] ) + { + MSYS_RemoveRegion( &gSkillTraitHelpTextRegion[regionnr] ); + } + MSYS_DefineRegion( &gSkillTraitHelpTextRegion[regionnr], ( sX - 3 ), (UINT16)( pPersonnelScreenPoints[loc].y + 15), + ( sX + StringPixLength(sString,PERS_FONT) + 3 ), (UINT16)( pPersonnelScreenPoints[loc].y + 23 ), MSYS_PRIORITY_HIGH, + MSYS_NO_CURSOR, MSYS_NO_CALLBACK, NULL ); + + MSYS_AddRegion( &gSkillTraitHelpTextRegion[regionnr] ); + fAddedTraitRegion[regionnr] = TRUE; + + // Info about our background + AssignBackgroundHelpText( gMercProfiles[pSoldier->ubProfile].usBackground, &(gSkillTraitHelpTextRegion[12]) ); + } + + break; + ///////////////////////////////////////////////////////////////////////// // Added by SANDRO case 15: @@ -8664,5 +8705,3 @@ INT8 CalculateMercsAchievemntPercentage( INT32 IMercId ) else return( 0 ); } - - diff --git a/Multiplayer/client.cpp b/Multiplayer/client.cpp index a55b61e77..1e0d9e27d 100644 --- a/Multiplayer/client.cpp +++ b/Multiplayer/client.cpp @@ -2585,7 +2585,7 @@ void recieveSETTINGS (RPCParameters *rpcParameters) //recive settings from serve gGameOptions.fUseNCTH = FALSE; gGameOptions.fImprovedInterruptSystem = FALSE; - gGameOptions.fWeaponOverheating = FALSE; + gGameOptions.fBackGround = FALSE; gGameOptions.fFoodSystem = FALSE; @@ -2808,7 +2808,7 @@ void reapplySETTINGS() gGameOptions.fUseNCTH = FALSE; gGameOptions.fImprovedInterruptSystem = FALSE; - gGameOptions.fWeaponOverheating = FALSE; + gGameOptions.fBackGround = FALSE; gGameOptions.fFoodSystem = FALSE; // WANNE - MP: We have to re-initialize the correct interface diff --git a/SaveLoadGame.cpp b/SaveLoadGame.cpp index 82f1dfddb..3fb663225 100644 --- a/SaveLoadGame.cpp +++ b/SaveLoadGame.cpp @@ -1492,6 +1492,15 @@ BOOLEAN MERCPROFILESTRUCT::Load(HWFILE hFile, bool forceLoadOldVersion, bool for { return(FALSE); } + + // Flugente: backgrounds + if(guiCurrentSaveGameVersion >= BACKGROUNDS) + { + if ( !FileRead( hFile, &this->usBackground, sizeof(UINT8), &uiNumBytesRead ) ) + { + return(FALSE); + } + } } if ( this->uiProfileChecksum != this->GetChecksum() ) { @@ -1570,6 +1579,13 @@ BOOLEAN MERCPROFILESTRUCT::Save(HWFILE hFile) { return(FALSE); } + + // Flugente: background + if ( !FileWrite( hFile, &this->usBackground, sizeof(UINT8), &uiNumBytesWritten ) ) + { + return(FALSE); + } + return TRUE; } @@ -3127,7 +3143,7 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc ) SaveGameHeader.sInitialGameOptions.fUseNCTH = gGameOptions.fUseNCTH; SaveGameHeader.sInitialGameOptions.fImprovedInterruptSystem = gGameOptions.fImprovedInterruptSystem; - SaveGameHeader.sInitialGameOptions.fWeaponOverheating = gGameOptions.fWeaponOverheating; + SaveGameHeader.sInitialGameOptions.fBackGround = gGameOptions.fBackGround; // // Save the Save Game header file diff --git a/Strategic/Assignments.cpp b/Strategic/Assignments.cpp index 4a4e68f1a..a102c47f7 100644 --- a/Strategic/Assignments.cpp +++ b/Strategic/Assignments.cpp @@ -2670,9 +2670,13 @@ UINT32 CalculateInterrogationValue(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPts ) // adjust for threatening value INT32 threatenvalue = CalcThreateningEffectiveness( pSoldier->ubProfile ) * gMercProfiles[pSoldier->ubProfile].usApproachFactor[2] ; - + + threatenvalue = (threatenvalue * (100 + pSoldier->GetBackgroundValue(BG_PERC_APPROACH_THREATEN))) / 100; + usInterrogationPoints *= threatenvalue; - + + usInterrogationPoints = (usInterrogationPoints * (100 + pSoldier->GetBackgroundValue(BG_PERC_INTERROGATION))) / 100; + UINT16 performancemodifier = 100; for (UINT16 cnt = 0; cnt < NUM_FACILITY_TYPES; ++cnt) { @@ -2721,7 +2725,9 @@ UINT32 CalculatePrisonGuardValue(SOLDIERTYPE *pSoldier, UINT16 *pusMaxPts ) { usValue += 25 * NUM_SKILL_TRAITS( pSoldier, MARTIALARTS_OT ) + 25 * NUM_SKILL_TRAITS( pSoldier, HANDTOHAND_OT ) + 10 * HAS_SKILL_TRAIT( pSoldier, KNIFING_OT ); } - + + usValue = (usValue * (100 + max(0, pSoldier->GetBackgroundValue(BG_PERC_GUARD)))) / 100; + // adjust for fatigue ReducePointsForFatigue( pSoldier, &usValue ); @@ -14206,6 +14212,8 @@ UINT8 CalcSoldierNeedForSleep( SOLDIERTYPE *pSoldier ) } } } + + ubNeedForSleep += pSoldier->GetBackgroundValue(BG_PERC_SLEEP); // Re-Enforce a maximum of 18 hours after injury penalties. if ( ubNeedForSleep > 18 ) diff --git a/Strategic/Auto Resolve.cpp b/Strategic/Auto Resolve.cpp index 3b7a13719..f9e99b16e 100644 --- a/Strategic/Auto Resolve.cpp +++ b/Strategic/Auto Resolve.cpp @@ -1475,7 +1475,7 @@ UINT32 VirtualSoldierDressWound( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pVictim, OB if (!(fOnSurgery) && gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pSoldier, DOCTOR_NT )) { uiPossible = uiPossible * (100 - gSkillTraitValues.bSpeedModifierBandaging) / 100; - uiPossible += ( uiPossible * gSkillTraitValues.ubDOBandagingSpeedPercent * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ) / 100); + uiPossible += ( uiPossible * gSkillTraitValues.ubDOBandagingSpeedPercent * NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ) + pSoldier->GetBackgroundValue(BG_PERC_BANDAGING) ) / 100; } uiActual = uiPossible; // start by assuming maximum possible diff --git a/Strategic/Hourly Update.cpp b/Strategic/Hourly Update.cpp index 3766c274b..cbe777e3b 100644 --- a/Strategic/Hourly Update.cpp +++ b/Strategic/Hourly Update.cpp @@ -18,6 +18,7 @@ #include "history.h" #include "Dialogue Control.h" #include "Strategic AI.h" + #include "Tactical Save.h" // added by Flugente #endif #include "Luaglobal.h" @@ -32,8 +33,9 @@ #include "Facilities.h" #include "Food.h" // added by Flugente -void HourlyQuestUpdate( void ); -void HourlyLarryUpdate( void ); +void HourlyQuestUpdate(); +void HourlyLarryUpdate(); +void HourlyStealUpdate(); // Flugente: certain characters might steal equipment (backgrounds) extern INT32 GetCurrentBalance( void ); extern void PayOffSkyriderDebtIfAny( ); @@ -99,6 +101,9 @@ CHAR16 zString[128]; HourlyQuestUpdate(); HourlyLarryUpdate(); + + HourlyStealUpdate(); + #if (defined JA2UB) // no UB #else @@ -230,7 +235,7 @@ void HandleQuarterHourUpdate() } -void HourlyQuestUpdate( void ) +void HourlyQuestUpdate() { UINT32 uiHour = GetWorldHour(); @@ -311,9 +316,9 @@ UINT16 LarryItems[ NUM_LARRY_ITEMS ][ 3 ] = #define LARRY_FALLS_OFF_WAGON 8 -void HourlyLarryUpdate( void ) +void HourlyLarryUpdate() { - SOLDIERTYPE * pSoldier; + SOLDIERTYPE * pSoldier = NULL; INT8 bSlot = NO_SLOT, bBoozeSlot; INT8 bLarryItemLoop; UINT16 usTemptation = 0; @@ -321,79 +326,68 @@ void HourlyLarryUpdate( void ) BOOLEAN fBar = FALSE; OBJECTTYPE* pObj = NULL; - pSoldier = FindSoldierByProfileID( LARRY_NORMAL, TRUE ); - if ( !pSoldier ) + for( INT32 cnt = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; cnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; ++cnt ) { - pSoldier = FindSoldierByProfileID( LARRY_DRUNK, TRUE ); - } - if ( pSoldier ) - { - if ( pSoldier->bAssignment >= ON_DUTY ) - { - return; - } - if ( pSoldier->flags.fBetweenSectors ) - { - return; - } - if ( pSoldier->bActive && pSoldier->bInSector && (gTacticalStatus.fEnemyInSector || guiCurrentScreen == GAME_SCREEN ) ) - { - return; - } + pSoldier = MercPtrs[ cnt ]; - // Flugente: reworked this for the new drug system. We now loop over our entire inventory - INT8 invsize = (INT8)pSoldier->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 ( pSoldier && pSoldier->bAssignment < ON_DUTY && !pSoldier->flags.fBetweenSectors && pSoldier->bActive && pSoldier->bInSector && !(gTacticalStatus.fEnemyInSector || guiCurrentScreen == GAME_SCREEN ) ) { - if ( pSoldier->inv[bLoop].exists() && Item[ pSoldier->inv[bLoop].usItem ].drugtype > 0 ) + if ( pSoldier->ubProfile == LARRY_NORMAL || pSoldier->ubProfile == LARRY_DRUNK || pSoldier->HasBackgroundFlag( BACKGROUND_DRUGUSE ) ) { - pObj = &(pSoldier->inv[bLoop]); - - usTemptation = 5; - - // any drug will do... I'm not going to create a new tag for sth minor like this - break; - } - } - - // look for items in Larry's inventory to maybe use - /*for ( bLarryItemLoop = 0; bLarryItemLoop < NUM_LARRY_ITEMS; bLarryItemLoop++ ) - { - bSlot = FindObj( pSoldier, LarryItems[ bLarryItemLoop ][ 0 ] ); - if ( bSlot != NO_SLOT ) - { - usTemptation = LarryItems[ bLarryItemLoop ][ 1 ]; - break; - } - }*/ - - // check to see if we're in a bar sector, if we are, we have access to alcohol - // which may be better than anything we've got... - if ( usTemptation < BAR_TEMPTATION && GetCurrentBalance() >= Item[ ALCOHOL ].usPrice ) - { - if ( pSoldier->bSectorZ == 0 && - ( ( pSoldier->sSectorX == 13 && pSoldier->sSectorY == MAP_ROW_D) || - ( pSoldier->sSectorX == 13 && pSoldier->sSectorY == MAP_ROW_C) || - ( pSoldier->sSectorX == 5 && pSoldier->sSectorY == MAP_ROW_C) || - ( pSoldier->sSectorX == 6 && pSoldier->sSectorY == MAP_ROW_C) || - ( pSoldier->sSectorX == 5 && pSoldier->sSectorY == MAP_ROW_D) || - ( pSoldier->sSectorX == 2 && pSoldier->sSectorY == MAP_ROW_H) - ) - ) - { - // in a bar! - fBar = TRUE; - usTemptation = BAR_TEMPTATION; - } - } - - if ( usTemptation > 0 ) - { - if ( pSoldier->ubProfile == LARRY_NORMAL ) - { - gMercProfiles[ LARRY_NORMAL ].bNPCData += (INT8) Random( usTemptation ); - if ( gMercProfiles[ LARRY_NORMAL ].bNPCData >= LARRY_FALLS_OFF_WAGON ) + // Flugente: reworked this for the new drug system. We now loop over our entire inventory + INT8 invsize = (INT8)pSoldier->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 ( pSoldier->inv[bLoop].exists() && Item[ pSoldier->inv[bLoop].usItem ].drugtype > 0 ) + { + pObj = &(pSoldier->inv[bLoop]); + + usTemptation = 5; + + // any drug will do... I'm not going to create a new tag for sth minor like this + break; + } + } + + // check to see if we're in a bar sector, if we are, we have access to alcohol + // which may be better than anything we've got... + if ( usTemptation < BAR_TEMPTATION && GetCurrentBalance() >= Item[ ALCOHOL ].usPrice ) + { + if ( pSoldier->bSectorZ == 0 && + ( ( pSoldier->sSectorX == 13 && pSoldier->sSectorY == MAP_ROW_D) || + ( pSoldier->sSectorX == 13 && pSoldier->sSectorY == MAP_ROW_C) || + ( pSoldier->sSectorX == 5 && pSoldier->sSectorY == MAP_ROW_C) || + ( pSoldier->sSectorX == 6 && pSoldier->sSectorY == MAP_ROW_C) || + ( pSoldier->sSectorX == 5 && pSoldier->sSectorY == MAP_ROW_D) || + ( pSoldier->sSectorX == 2 && pSoldier->sSectorY == MAP_ROW_H) + ) + ) + { + // in a bar! + fBar = TRUE; + usTemptation = BAR_TEMPTATION; + } + } + + if ( usTemptation > 0 ) + { + if ( pSoldier->ubProfile == LARRY_DRUNK ) + { + // NB store all drunkenness info in LARRY_NORMAL profile (to use same values) + // so long as he keeps consuming, keep number above level at which he cracked + gMercProfiles[ LARRY_NORMAL ].bNPCData = __max( gMercProfiles[ LARRY_NORMAL ].bNPCData, LARRY_FALLS_OFF_WAGON ); + gMercProfiles[ LARRY_NORMAL ].bNPCData += (INT8) Random( usTemptation ); + // allow value to keep going up to 24 (about 2 days since we subtract Random( 2 ) when he has no access ) + gMercProfiles[ LARRY_NORMAL ].bNPCData = __min( gMercProfiles[ LARRY_NORMAL ].bNPCData, 24 ); + } + else + { + gMercProfiles[ pSoldier->ubProfile ].bNPCData += (INT8) Random( usTemptation ); + + if ( gMercProfiles[ pSoldier->ubProfile ].bNPCData < LARRY_FALLS_OFF_WAGON ) + continue; + } + if ( fBar ) { // take $ from player's account @@ -409,61 +403,140 @@ void HourlyLarryUpdate( void ) } bSlot = bBoozeSlot; bLarryItemLoop = 1; - } - // ahhhh!!! - SwapLarrysProfiles( pSoldier ); - if ( bSlot != NO_SLOT ) - { - UseKitPoints( &(pSoldier->inv[ bSlot ]), 25/*LarryItems[ bLarryItemLoop ][ 2 ]*/, pSoldier ); - } - } - } - else - { - // NB store all drunkenness info in LARRY_NORMAL profile (to use same values) - // so long as he keeps consuming, keep number above level at which he cracked - gMercProfiles[ LARRY_NORMAL ].bNPCData = __max( gMercProfiles[ LARRY_NORMAL ].bNPCData, LARRY_FALLS_OFF_WAGON ); - gMercProfiles[ LARRY_NORMAL ].bNPCData += (INT8) Random( usTemptation ); - // allow value to keep going up to 24 (about 2 days since we subtract Random( 2 ) when he has no access ) - gMercProfiles[ LARRY_NORMAL ].bNPCData = __min( gMercProfiles[ LARRY_NORMAL ].bNPCData, 24 ); - if ( fBar ) - { - // take $ from player's account - usCashAmount = Item[ ALCOHOL ].usPrice; - AddTransactionToPlayersBook ( TRANSFER_FUNDS_TO_MERC, pSoldier->ubProfile, GetWorldTotalMin() , -( usCashAmount ) ); - // give Larry some booze and set slot etc values appropriately - // CHRISL: Change final parameter to allow dynamic control of inventory slots - bBoozeSlot = FindEmptySlotWithin( pSoldier, HANDPOS, NUM_INV_SLOTS ); - if ( bBoozeSlot != NO_SLOT ) - { - // give Larry booze here - CreateItem( ALCOHOL, 100, &(pSoldier->inv[bBoozeSlot]) ); - } - bSlot = bBoozeSlot; - bLarryItemLoop = 1; - } - if ( bSlot != NO_SLOT ) - { - // Flugente: abandoned LarryItems - // ahhhh!!! - if ( pObj ) - UseKitPoints( pObj, 100/*LarryItems[ bLarryItemLoop ][ 2 ]*/, pSoldier ); - } - } - } - else if ( pSoldier->ubProfile == LARRY_DRUNK ) - { - gMercProfiles[ LARRY_NORMAL ].bNPCData -= (INT8) Random( 2 ); - if ( gMercProfiles[ LARRY_NORMAL ].bNPCData <= 0 ) - { - // goes sober! - SwapLarrysProfiles( pSoldier ); - } - } + if ( pSoldier->ubProfile == LARRY_DRUNK ) + { + SwapLarrysProfiles( pSoldier ); + } + + if ( bSlot != NO_SLOT ) + { + UseKitPoints( &(pSoldier->inv[ bSlot ]), 25/*LarryItems[ bLarryItemLoop ][ 2 ]*/, pSoldier ); + } + } + else + { + if ( pObj ) + UseKitPoints( pObj, 100/*LarryItems[ bLarryItemLoop ][ 2 ]*/, pSoldier ); + } + } + else if ( pSoldier->ubProfile == LARRY_DRUNK ) + { + gMercProfiles[ LARRY_NORMAL ].bNPCData -= (INT8) Random( 2 ); + if ( gMercProfiles[ LARRY_NORMAL ].bNPCData <= 0 ) + { + // goes sober! + SwapLarrysProfiles( pSoldier ); + } + } + } + } } - } + +// Flugente: certain characters might steal equipment (backgrounds) +void HourlyStealUpdate() +{ + SOLDIERTYPE * pSoldier = NULL; + INT8 bSlot = NO_SLOT; + UINT16 usTemptation = 0; + BOOLEAN fBar = FALSE; + OBJECTTYPE* pObj = NULL; + + for( INT32 cnt = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; cnt <= gTacticalStatus.Team[ OUR_TEAM ].bLastID; ++cnt ) + { + pSoldier = MercPtrs[ cnt ]; + + if ( pSoldier && !pSoldier->flags.fBetweenSectors && pSoldier->bActive && pSoldier->bInSector && !pSoldier->flags.fMercAsleep && !(gTacticalStatus.fEnemyInSector || guiCurrentScreen == GAME_SCREEN ) ) + { + if ( pSoldier->HasBackgroundFlag( BACKGROUND_SCROUNGING ) ) + { + // 20% chance that we'll steal something + if ( Chance(20) ) + { + // we loop over this sector's inventory and look for something shiny. We will pick it up if we hae enough space in our inventory + // open sector inv + UINT32 uiTotalNumberOfRealItems = 0; + WORLDITEM* pWorldItem = NULL; + BOOLEAN fReturn = FALSE; + + if( ( gWorldSectorX == pSoldier->sSectorX ) && ( gWorldSectorY == pSoldier->sSectorY ) && (gbWorldSectorZ == pSoldier->bSectorZ ) ) + { + uiTotalNumberOfRealItems = guiNumWorldItems; + + if ( !uiTotalNumberOfRealItems ) + continue; + + pWorldItem = gWorldItems; + } + else + { + // not loaded, load + // get total number, visable and invisible + fReturn = GetNumberOfWorldItemsFromTempItemFile( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ, &( uiTotalNumberOfRealItems ), FALSE ); + Assert( fReturn ); + + if( uiTotalNumberOfRealItems > 0 ) + { + // allocate space for the list + pWorldItem = new WORLDITEM[ uiTotalNumberOfRealItems ]; + + if ( !uiTotalNumberOfRealItems ) + continue; + + // now load into mem + LoadWorldItemsFromTempItemFile( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ, pWorldItem ); + } + } + + FLOAT bestpriceweightratio = 50.0f; // msut have a value of at least 50$/100 gram + OBJECTTYPE* pTargetObj = NULL; + for( UINT32 uiCount = 0; uiCount < uiTotalNumberOfRealItems; ++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 && pObj->exists() ) // ... if pointer is not obviously useless ... + { + // test wether item is reachable and useable by militia + if ( (pWorldItem[ uiCount ].usFlags & WORLD_ITEM_REACHABLE) ) + { + // ignore objects without weight (how does that happen anyway? careless modders...) + if ( Item[pWorldItem[ uiCount ].object.usItem].ubWeight ) + { + if ( (FLOAT)(Item[pWorldItem[ uiCount ].object.usItem].usPrice) / (FLOAT)(Item[pWorldItem[ uiCount ].object.usItem].ubWeight) > bestpriceweightratio ) + { + bestpriceweightratio = (FLOAT)(Item[pWorldItem[ uiCount ].object.usItem].usPrice) / (FLOAT)(Item[pWorldItem[ uiCount ].object.usItem].ubWeight); + pTargetObj = &(pWorldItem[ uiCount ].object); + } + } + } + } + } + } + + if ( pTargetObj ) + AutoPlaceObject( pSoldier, pTargetObj, TRUE ); + + // save the changed inventory + // open sector inv + if( ( gWorldSectorX == pSoldier->sSectorX )&&( gWorldSectorY == pSoldier->sSectorY ) && (gbWorldSectorZ == pSoldier->bSectorZ ) ) + { + guiNumWorldItems = uiTotalNumberOfRealItems; + gWorldItems = pWorldItem; + } + else + { + //Save the Items to the the file + SaveWorldItemsToTempItemFile( pSoldier->sSectorX, pSoldier->sSectorY, pSoldier->bSectorZ, uiTotalNumberOfRealItems, pWorldItem ); + } + } + } + } + } +} + #if (defined JA2UB) // no JA25 UB #else diff --git a/Strategic/Map Screen Interface Map Inventory.cpp b/Strategic/Map Screen Interface Map Inventory.cpp index 171ccecad..ba3e20203 100644 --- a/Strategic/Map Screen Interface Map Inventory.cpp +++ b/Strategic/Map Screen Interface Map Inventory.cpp @@ -5255,7 +5255,7 @@ void SectorInventoryCooldownFunctions( INT16 sMapX, INT16 sMapY, INT16 sMapZ ) 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 && !gGameExternalOptions.fDirtSystem && !gGameOptions.fFoodSystem ) + if ( !gGameExternalOptions.fWeaponOverheating && !gGameExternalOptions.fDirtSystem && !gGameOptions.fFoodSystem ) return; UINT32 tickspassed = 1; @@ -5302,7 +5302,7 @@ void HandleSectorCooldownFunctions( INT16 sMapX, INT16 sMapY, INT8 sMapZ, WORLDI if ( pObj != NULL && pObj->exists() ) // ... 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 ) ) + if ( gGameExternalOptions.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 ... { diff --git a/Strategic/Strategic Movement.cpp b/Strategic/Strategic Movement.cpp index 407ee1aa5..d3eeac352 100644 --- a/Strategic/Strategic Movement.cpp +++ b/Strategic/Strategic Movement.cpp @@ -47,6 +47,7 @@ #include "Auto Resolve.h" #include "GameSettings.h" #include "Quests.h" + #include "Interface.h" // added by Flugente for zBackground #endif #include "MilitiaSquads.h" @@ -3208,31 +3209,53 @@ INT32 GetSectorMvtTimeForGroup( UINT8 ubSector, UINT8 ubDirection, GROUP *pGroup { // see if we have any ranger here UINT8 ubRangerHere = 0; + UINT8 ustravelbackground_foot = 0; + UINT8 ustravelbackground_car = 0; + UINT8 ustravelbackground_air = 0; + curr = pGroup->pPlayerList; while( curr ) { pSoldier = curr->pSoldier; if( HAS_SKILL_TRAIT( pSoldier, RANGER_NT )) ubRangerHere += NUM_SKILL_TRAITS( pSoldier, RANGER_NT ); + + // Flugente: backgrounds + ustravelbackground_foot = max(ustravelbackground_foot, pSoldier->GetBackgroundValue(BG_TRAVEL_FOOT)); + ustravelbackground_car = max(ustravelbackground_car, pSoldier->GetBackgroundValue(BG_TRAVEL_CAR)); + ustravelbackground_air = max(ustravelbackground_air, pSoldier->GetBackgroundValue(BG_TRAVEL_AIR)); curr = curr->next; } // yes, we have... - if( ubRangerHere > 0 ) + if( ubRangerHere || ustravelbackground_foot || ustravelbackground_car || ustravelbackground_air ) { // no more than certain number of simultaneous bonuses ubRangerHere = min( gSkillTraitValues.ubRAMaxBonusesToTravelSpeed, ubRangerHere ); + // on foot, the bonus should be higher if( fFoot ) { // however, we cannot be quicker than the helicopter iBestTraverseTime = max( 10, (iBestTraverseTime * (100 - ( ubRangerHere * gSkillTraitValues.ubRAGroupTimeSpentForTravellingFoot )) / 100)); + + iBestTraverseTime = max( 10, (iBestTraverseTime * (100 - ustravelbackground_foot) / 100)); } // all other types (except air) + else if ( fAir ) + { + // however, we cannot be quicker than the helicopter + iBestTraverseTime = max( 10, (iBestTraverseTime * (100 - ( ubRangerHere * gSkillTraitValues.ubRAGroupTimeSpentForTravellingVehicle )) / 100)); + + // yes, this background allows us to fly faster :-) + iBestTraverseTime = max( 9, (iBestTraverseTime * (100 - ustravelbackground_air) / 100)); + } else { // however, we cannot be quicker than the helicopter iBestTraverseTime = max( 10, (iBestTraverseTime * (100 - ( ubRangerHere * gSkillTraitValues.ubRAGroupTimeSpentForTravellingVehicle )) / 100)); + + iBestTraverseTime = max( 10, (iBestTraverseTime * (100 - ustravelbackground_car) / 100)); } } } diff --git a/Tactical/Food.cpp b/Tactical/Food.cpp index d86ef5464..9744aa5dd 100644 --- a/Tactical/Food.cpp +++ b/Tactical/Food.cpp @@ -369,10 +369,13 @@ void HourlyFoodSituationUpdate( SOLDIERTYPE *pSoldier ) ++sectortemperaturemod; FLOAT temperaturemodifier = (FLOAT)(3 + sectortemperaturemod)/3; - + + FLOAT specialfoodmodifier = (100 + pSoldier->GetBackgroundValue(BG_PERC_FOOD) ) / 100; + FLOAT specialdrinkmodifier = (100 + pSoldier->GetBackgroundValue(BG_PERC_WATER)) / 100; + // 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), FOOD_MIN); + pSoldier->bFoodLevel = max(pSoldier->bFoodLevel - (INT32) (specialfoodmodifier * activitymodifier * gGameExternalOptions.usFoodDigestionHourlyBaseFood), FOOD_MIN); + pSoldier->bDrinkLevel = max(pSoldier->bDrinkLevel - (INT32) (specialdrinkmodifier * 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; diff --git a/Tactical/Handle Items.cpp b/Tactical/Handle Items.cpp index 79568c871..11e50cc5f 100644 --- a/Tactical/Handle Items.cpp +++ b/Tactical/Handle Items.cpp @@ -1783,6 +1783,11 @@ void HandleSoldierDropBomb( SOLDIERTYPE *pSoldier, INT32 sGridNo ) { pSoldier->inv[ HANDPOS ][0]->data.bTrap = __min( 10, ( EffectiveExplosive( pSoldier ) / 20) + (EffectiveExpLevel( pSoldier ) / 3) ); } + + // Flugente: backgrounds + if ( pSoldier->HasBackgroundFlag( BACKGROUND_TRAPLEVEL ) ) + pSoldier->inv[ HANDPOS ][0]->data.bTrap++; + pSoldier->inv[ HANDPOS ][0]->data.misc.ubBombOwner = pSoldier->ubID + 2; // Flugente: determine the direction we are looking at and apply that direction to our explosive @@ -4993,6 +4998,10 @@ void BombMessageBoxCallBack( UINT8 ubExitValue ) { gpTempSoldier->inv[ HANDPOS ][0]->data.bTrap = __min( 10, ( EffectiveExplosive( gpTempSoldier ) / 20) + (EffectiveExpLevel( gpTempSoldier ) / 3) ); } + + // Flugente: backgrounds + if ( gpTempSoldier->HasBackgroundFlag( BACKGROUND_TRAPLEVEL ) ) + gpTempSoldier->inv[ HANDPOS ][0]->data.bTrap++; // HACK IMMINENT! // value of 1 is stored in maps for SIDE of bomb owner... when we want to use IDs! diff --git a/Tactical/Interface Enhanced.cpp b/Tactical/Interface Enhanced.cpp index 9e861ab48..da7e6bfc3 100644 --- a/Tactical/Interface Enhanced.cpp +++ b/Tactical/Interface Enhanced.cpp @@ -1906,7 +1906,8 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + 2 ] ); } - if ( gGameOptions.fWeaponOverheating ) // Flugente + // Flugente + if ( gGameExternalOptions.fWeaponOverheating ) { //////////////////// TEMPERATURE MODIFICATOR { @@ -3707,7 +3708,7 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr INT16 fDrawGenIndexes = FALSE; // Flugente - if ( gGameOptions.fWeaponOverheating ) + if ( gGameExternalOptions.fWeaponOverheating ) { if ( Item[gpItemDescObject->usItem].usItemClass & (IC_GUN|IC_LAUNCHER) ) { @@ -4290,7 +4291,8 @@ void DrawAmmoStats( OBJECTTYPE * gpItemDescObject ) BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoAmmoIcon, 2, gItemDescGenRegions[2][0].sLeft+sOffsetX, gItemDescGenRegions[2][0].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL ); } - if ( gGameOptions.fWeaponOverheating ) // Flugente + // Flugente + if ( gGameExternalOptions.fWeaponOverheating ) { //////////////// TEMPERATURE MODIFICATOR { @@ -5107,7 +5109,7 @@ void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject ) // Flugente // new line is necessary (Moa: only if needed) INT16 fDrawGenIndexes = FALSE; - if ( gGameOptions.fWeaponOverheating || gGameExternalOptions.fDirtSystem ) + if ( gGameExternalOptions.fWeaponOverheating || gGameExternalOptions.fDirtSystem ) { if( Item[gpItemDescObject->usItem].usItemClass & (IC_GUN|IC_LAUNCHER) || Item[gpItemDescObject->usItem].barrel == TRUE || ( Item[gpItemDescObject->usItem].overheatTemperatureModificator != 0.0 ) || ( Item[gpItemDescObject->usItem].overheatCooldownModificator != 0.0 ) || ( Item[gpItemDescObject->usItem].overheatJamThresholdModificator != 0.0 ) || ( Item[gpItemDescObject->usItem].overheatDamageThresholdModificator != 0.0 ) ) { @@ -5115,7 +5117,8 @@ void DrawAdvancedStats( OBJECTTYPE * gpItemDescObject ) } } - if ( gGameOptions.fWeaponOverheating ) + // Flugente + if ( gGameExternalOptions.fWeaponOverheating ) { if( Item[gpItemDescObject->usItem].usItemClass & (IC_GUN|IC_LAUNCHER) ) { @@ -7591,8 +7594,8 @@ void DrawAmmoValues( OBJECTTYPE * gpItemDescObject, int shotsLeft ) mprintf( usX, usY, pStr ); } - - if ( gGameOptions.fWeaponOverheating ) // Flugente + // Flugente + if ( gGameExternalOptions.fWeaponOverheating ) { ///////////////////// TEMPERATURE MODIFICATOR // Set line to draw into @@ -10963,7 +10966,7 @@ void DrawAdvancedValues( OBJECTTYPE *gpItemDescObject ) INT16 fDrawGenIndexes = FALSE; // Flugente - if ( gGameOptions.fWeaponOverheating ) + if ( gGameExternalOptions.fWeaponOverheating ) { if ( Item[gpItemDescObject->usItem].usItemClass & (IC_GUN|IC_LAUNCHER) ) { diff --git a/Tactical/Interface Items.cpp b/Tactical/Interface Items.cpp index 605718505..efd8465a3 100644 --- a/Tactical/Interface Items.cpp +++ b/Tactical/Interface Items.cpp @@ -763,7 +763,7 @@ void GenerateProsString( STR16 zItemPros, OBJECTTYPE * pObject, UINT32 uiPixLimi // Flugente: If overheating is allowed, an overheated gun receives a slight malus to accuracy FLOAT accuracyheatmultiplicator = 1.0; - if ( gGameOptions.fWeaponOverheating ) + if ( gGameExternalOptions.fWeaponOverheating ) { FLOAT overheatdamagepercentage = GetGunOverheatDamagePercentage( pObject ); FLOAT accuracymalus = (FLOAT)((max(1.0, overheatdamagepercentage) - 1.0) * 0.1); @@ -908,7 +908,7 @@ void GenerateConsString( STR16 zItemCons, OBJECTTYPE * pObject, UINT32 uiPixLimi // Flugente: If overheating is allowed, an overheated gun receives a slight malus to accuracy FLOAT accuracyheatmultiplicator = 1.0; - if ( gGameOptions.fWeaponOverheating ) + if ( gGameExternalOptions.fWeaponOverheating ) { FLOAT overheatdamagepercentage = GetGunOverheatDamagePercentage( pObject ); FLOAT accuracymalus = (FLOAT)((max(1.0, overheatdamagepercentage) - 1.0) * 0.1); @@ -3735,7 +3735,7 @@ void INVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pObjec sNewX = sX + 1; // Flugente: If we display the thermometer for overheating, move the ammo counter a bit to the right - if ( gGameOptions.fWeaponOverheating == TRUE && gGameExternalOptions.fDisplayOverheatThermometer == TRUE ) + if ( gGameExternalOptions.fWeaponOverheating && gGameExternalOptions.fDisplayOverheatThermometer ) sNewX = sX + 2; //6; // SANDRO - 6 ps too much, 2 are fine // Flugente: check for underbarrel weapons and use that object if necessary @@ -3890,7 +3890,7 @@ void INVRenderItem( UINT32 uiBuffer, SOLDIERTYPE * pSoldier, OBJECTTYPE *pObjec } // Flugente - if ( gGameOptions.fWeaponOverheating == TRUE && gGameExternalOptions.fDisplayOverheatThermometer == TRUE && ( pItem->usItemClass & (IC_GUN | IC_LAUNCHER) || Item[pObject->usItem].barrel == TRUE ) ) + if ( gGameExternalOptions.fWeaponOverheating && gGameExternalOptions.fDisplayOverheatThermometer && ( pItem->usItemClass & (IC_GUN | IC_LAUNCHER) || Item[pObject->usItem].barrel == TRUE ) ) { OBJECTTYPE* pObjShown = pObject; @@ -6702,7 +6702,8 @@ void RenderItemDescriptionBox( ) sCenY = sCenY + gItemDescAttachmentsXY[cnt].sBarDy; DrawItemUIBarEx( gpItemDescObject, (UINT8)(DRAW_ITEM_STATUS_ATTACHMENT1 + cnt), sCenX, sCenY, ITEM_BAR_WIDTH, ITEM_BAR_HEIGHT, Get16BPPColor( STATUS_BAR ), Get16BPPColor( STATUS_BAR_SHADOW ), TRUE , guiSAVEBUFFER, gubItemDescStatusIndex ); - if ( gGameOptions.fWeaponOverheating && ( Item[ (iter)->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) || Item[ (iter)->usItem ].barrel == TRUE) ) // Flugente FTW 1.1 + // Flugente: overheating + if ( gGameExternalOptions.fWeaponOverheating && ( Item[ (iter)->usItem ].usItemClass & (IC_GUN|IC_LAUNCHER) || Item[ (iter)->usItem ].barrel == TRUE) ) // Flugente FTW 1.1 { FLOAT overheatjampercentage = GetGunOverheatJamPercentage( &(*iter)); @@ -6868,8 +6869,8 @@ void RenderItemDescriptionBox( ) ////////// label if (UsingEDBSystem()) { - // Flugente FTW 1: display temperature string - if ( gGameOptions.fWeaponOverheating && ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN || Item[gpItemDescObject->usItem].usItemClass == IC_LAUNCHER || Item[gpItemDescObject->usItem].barrel == TRUE ) ) + // Flugente: display temperature string + if ( gGameExternalOptions.fWeaponOverheating && ( Item[ gpItemDescObject->usItem ].usItemClass == IC_GUN || Item[gpItemDescObject->usItem].usItemClass == IC_LAUNCHER || Item[gpItemDescObject->usItem].barrel == TRUE ) ) { // UDB system displays a string with colored condition text. int regionindex = 7; @@ -11598,7 +11599,7 @@ void GetHelpTextForItem( STR16 pzStr, OBJECTTYPE *pObject, SOLDIERTYPE *pSoldier // Flugente: If overheating is allowed, an overheated gun receives a slight malus to accuracy FLOAT accuracyheatmultiplicator = 1.0; - if ( gGameOptions.fWeaponOverheating ) + if ( gGameExternalOptions.fWeaponOverheating ) { FLOAT overheatdamagepercentage = GetGunOverheatDamagePercentage( pObject ); FLOAT accuracymalus = (FLOAT)((max(1.0, overheatdamagepercentage) - 1.0) * 0.1); @@ -11753,7 +11754,7 @@ void GetHelpTextForItem( STR16 pzStr, OBJECTTYPE *pObject, SOLDIERTYPE *pSoldier // Flugente: If overheating is allowed, an overheated gun receives a slight malus to accuracy FLOAT accuracyheatmultiplicator = 1.0; - if ( gGameOptions.fWeaponOverheating ) + if ( gGameExternalOptions.fWeaponOverheating ) { FLOAT overheatdamagepercentage = GetGunOverheatDamagePercentage( pObject ); FLOAT accuracymalus = (FLOAT)((max(1.0, overheatdamagepercentage) - 1.0) * 0.1); @@ -13237,6 +13238,10 @@ void BombInventoryMessageBoxCallBack( UINT8 ubExitValue ) { (*gpItemDescObject)[0]->data.bTrap = __min( 10, ( EffectiveExplosive( gpItemDescSoldier ) / 20) + (EffectiveExpLevel( gpItemDescSoldier ) / 3) ); } + + // Flugente: backgrounds + if ( gpItemDescSoldier->HasBackgroundFlag( BACKGROUND_TRAPLEVEL ) ) + (*gpItemDescObject)[0]->data.bTrap++; // Flugente: We armed a bomb in our inventory. We will NOT add it to the item pool and the world bombs. // Instead, we will count down the delay time every turn and eventually ignite the bomb from our inventory. diff --git a/Tactical/Interface Panels.cpp b/Tactical/Interface Panels.cpp index a9537ec5d..1383e9b1e 100644 --- a/Tactical/Interface Panels.cpp +++ b/Tactical/Interface Panels.cpp @@ -3880,7 +3880,10 @@ void SMInvClickCallback( MOUSE_REGION * pRegion, INT32 iReason ) if (INV_AP_COST) //Jenilee: determine the cost of moving this item around in our inventory usCostToMoveItem = GetInvMovementCost(gpItemPointer, uiLastHandPos, uiHandPos); - + + // Flugente: backgrounds + usCostToMoveItem = (usCostToMoveItem * (100 + gpSMCurrentMerc->GetBackgroundValue(BG_INVENTORY))) / 100; + if ( ( usCostToMoveItem == 0 ) || ( gpSMCurrentMerc->bActionPoints >= usCostToMoveItem ) ) { fOKToGo = TRUE; diff --git a/Tactical/Interface.cpp b/Tactical/Interface.cpp index 9e478004d..e05f6df49 100644 --- a/Tactical/Interface.cpp +++ b/Tactical/Interface.cpp @@ -107,6 +107,8 @@ CIV_NAMES_VALUES zCivGroupName[NUM_CIV_GROUPS]; SOLDIER_PROFILE_VALUES zSoldierProfile[6][NUM_SOLDIER_PROFILES]; UINT16 num_found_soldier_profiles[6]; // the correct number is set on reading the xml +BACKGROUND_VALUES zBackground[NUM_BACKGROUND]; // Flugente: backgrounds + BOOLEAN gfInMovementMenu = FALSE; INT32 giMenuAnchorX, giMenuAnchorY; diff --git a/Tactical/Interface.h b/Tactical/Interface.h index 75e14a839..10de1f508 100644 --- a/Tactical/Interface.h +++ b/Tactical/Interface.h @@ -4,6 +4,7 @@ #include "handle UI.h" #include "mousesystem.h" #include "structure.h" +#include "Assignments.h" // added by Flugente for the stat-enums #define MAX_UICOMPOSITES 4 @@ -106,6 +107,101 @@ extern SOLDIER_PROFILE_VALUES zSoldierProfile[6][NUM_SOLDIER_PROFILES]; extern UINT16 num_found_soldier_profiles[6]; // the correct number is set on reading the xml extern UINT16 num_found_profiles; // a helper variable during reading xmls +// Flugente: backgrounds +// enums for backgrounds +enum { + // sector dependent AP modifiers + BG_POLAR, // not used ingame (yet?) + BG_DESERT, + BG_SWAMP, + BG_URBAN, + BG_RIVER, + BG_TROPICAL, + BG_COASTAL, + BG_MOUNTAIN, + + // stat effectiveness modifiers + BG_AGILITY, + BG_DEXTERITY, + BG_STRENGTH, + BG_LEADERSHIP, + BG_MARKSMANSHIP, + BG_MECHANICAL, + BG_EXPLOSIVE_ASSIGN, + BG_MEDICAL, + + // ap modifiers for non-sector related tasks + BG_HEIGHT, + BG_SWIMMING, + BG_FORTIFY, + BG_ARTILLERY, + BG_INVENTORY, + BG_AIRDROP, + BG_ASSAULT, + + // travel speed modifiers + BG_TRAVEL_FOOT, + BG_TRAVEL_CAR, + BG_TRAVEL_AIR, + BG_TRAVEL_BOAT, + + // resistances + BG_RESI_POISON, + BG_RESI_FEAR, + BG_RESI_SUPPRESSION, + BG_RESI_PHYSICAL, + BG_RESI_ALCOHOL, + + // various + BG_PERC_INTERROGATION, + BG_PERC_GUARD, + BG_PERC_PRICES_GUNS, + BG_PERC_PRICES, + BG_PERC_CAPITULATION, + BG_PERC_SPEED_RUNNING, + BG_PERC_BANDAGING, + BG_PERC_REGEN_ENERGY, + BG_PERC_CARRYSTRENGTH, + BG_PERC_FOOD, + BG_PERC_WATER, + BG_PERC_SLEEP, + BG_PERC_DAMAGE_MELEE, + BG_PERC_CTH_BLADE, + BG_PERC_CAMO, + BG_PERC_STEALTH, + BG_PERC_CTH_MAX, + BG_PERC_HEARING_NIGHT, + BG_PERC_HEARING_DAY, + + // approaches + BG_PERC_APPROACH_FRIENDLY, + BG_PERC_APPROACH_DIRECT, + BG_PERC_APPROACH_THREATEN, + BG_PERC_APPROACH_RECRUIT, + + // various + BG_BONUS_BREACHINGCHARGE, + + BG_MAX, +}; + +typedef struct +{ + UINT16 uiIndex; + CHAR16 szName[MAX_ENEMY_NAMES_CHARS]; // name of a background etc. + CHAR16 szShortName[20]; // abbreviated name for laptop display + CHAR16 szDescription[256]; // description of background, should explain the abilities + + UINT64 uiFlags; // this flagmask defines what speial properties this background has (on/off behaviour) + INT16 value[BG_MAX]; // property values +} BACKGROUND_VALUES; + +#define NUM_BACKGROUND 100 + +extern BACKGROUND_VALUES zBackground[NUM_BACKGROUND]; + +extern UINT16 num_found_background; // the correct number is set on reading the xml + extern int INTERFACE_WIDTH; // 640 extern int INTERFACE_HEIGHT; // 120 extern int INV_INTERFACE_HEIGHT; // 140 diff --git a/Tactical/Items.cpp b/Tactical/Items.cpp index 83d440816..c5df43005 100644 --- a/Tactical/Items.cpp +++ b/Tactical/Items.cpp @@ -3125,6 +3125,8 @@ UINT32 CalculateCarriedWeight( SOLDIERTYPE * pSoldier ) { ubStrengthForCarrying = (ubStrengthForCarrying * (100 + gSkillTraitValues.ubBBCarryWeightBonus) / 100); // plus one third } + + ubStrengthForCarrying = (ubStrengthForCarrying * (100 + pSoldier->GetBackgroundValue(BG_PERC_CARRYSTRENGTH)) / 100); // for now, assume soldiers can carry 1/2 their strength in KGs without penalty. // instead of multiplying by 100 for percent, and then dividing by 10 to account @@ -13348,7 +13350,9 @@ INT16 GetWornStealth( SOLDIERTYPE * pSoldier ) // Add some default stealth ability to mercs with STEALTHY trait - SANDRO if ( gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( pSoldier, STEALTHY_NT )) - ttl += gSkillTraitValues.ubSTStealthBonus; + ttl += gSkillTraitValues.ubSTStealthBonus; + + ttl += pSoldier->GetBackgroundValue(BG_PERC_STEALTH); return __min( ttl, 100 ); } @@ -13643,7 +13647,7 @@ INT32 GetGunAccuracy( OBJECTTYPE *pObj ) { // Flugente: If overheating is allowed, an overheated gun receives a slight malus to accuracy FLOAT accuracyheatmultiplicator = 1.0; - if ( gGameOptions.fWeaponOverheating ) + if ( gGameExternalOptions.fWeaponOverheating ) { FLOAT overheatdamagepercentage = GetGunOverheatDamagePercentage( pObj ); FLOAT accuracymalus = (max(1.0f, overheatdamagepercentage) - 1.0f) * 0.1f; diff --git a/Tactical/Keys.cpp b/Tactical/Keys.cpp index b46062f86..f8ac8ed88 100644 --- a/Tactical/Keys.cpp +++ b/Tactical/Keys.cpp @@ -741,7 +741,8 @@ BOOLEAN AttemptToBlowUpLock( SOLDIERTYPE * pSoldier, DOOR * pDoor ) return( FALSE ); } - iResult = SkillCheck( pSoldier, PLANTING_BOMB_CHECK, 0 ); + // Flugente: flat bonus to using door breaching charges + iResult = SkillCheck( pSoldier, PLANTING_BOMB_CHECK, pSoldier->GetBackgroundValue(BG_BONUS_BREACHINGCHARGE) ); if (iResult >= -20) { // Do explosive graphic.... diff --git a/Tactical/LOS.cpp b/Tactical/LOS.cpp index 176701ef8..d7535df5d 100644 --- a/Tactical/LOS.cpp +++ b/Tactical/LOS.cpp @@ -520,7 +520,11 @@ INT8 GetSightAdjustmentCamouflageOnTerrain( SOLDIERTYPE* pSoldier, const UINT8& INT8 scaler = -(ANIM_STAND+1 - ubStance); // stand = 7-6 => 10%, crouch = 7-3 => 66%, prone = 7-1 => 100%; - scaler = gGameExternalOptions.ubCamouflageEffectiveness * scaler / 6; + UINT8 effectiveness = gGameExternalOptions.ubCamouflageEffectiveness; + + effectiveness += (UINT8)(pSoldier->GetBackgroundValue(BG_PERC_CAMO)); + + scaler = effectiveness * scaler / 6; switch(ubTerrainType) { case LOW_GRASS: @@ -5805,7 +5809,7 @@ INT8 FireBulletGivenTargetTrapOnly( SOLDIERTYPE* pThrower, OBJECTTYPE* pObj, INT ///////////////////////// OVERHEATING AND STATUS REDUCTION //////////////////////////// INT16 iOverheatReliabilityMalus = 0; // Flugente: Increase Weapon Temperature - if ( gGameOptions.fWeaponOverheating ) + if ( gGameExternalOptions.fWeaponOverheating ) { FLOAT overheatjampercentage = GetGunOverheatDamagePercentage( pObj ); // ... how much above the gun's usOverheatingDamageThreshold are we? ... @@ -5847,8 +5851,8 @@ INT8 FireBulletGivenTargetTrapOnly( SOLDIERTYPE* pThrower, OBJECTTYPE* pObj, INT int condition = (*pObj)[0]->data.gun.bGunStatus; int invertedBaseJamChance = condition + (reliability * 2) - gGameExternalOptions.ubWeaponReliabilityReductionPerRainIntensity * 1; - // Flugente FTW 1: If overheating is allowed, a gun will be prone to more overheating if its temperature is high - if ( gGameOptions.fWeaponOverheating ) + // Flugente: If overheating is allowed, a gun will be prone to more overheating if its temperature is high + if ( gGameExternalOptions.fWeaponOverheating ) { FLOAT overheatjampercentage = GetGunOverheatJamPercentage( pObj ); // how much above the gun's usOverheatingJamThreshold are we? ... diff --git a/Tactical/Morale.cpp b/Tactical/Morale.cpp index 0ccacf04b..048667147 100644 --- a/Tactical/Morale.cpp +++ b/Tactical/Morale.cpp @@ -357,6 +357,9 @@ void RefreshSoldierMorale( SOLDIERTYPE * pSoldier ) if ( gGameOptions.fFoodSystem ) FoodMaxMoraleModifiy(pSoldier, &ubMaxMorale); + // Flugente: max morale can be lowered + iActualMorale = min(iActualMorale, pSoldier->GetMoraleThreshold() ); + if (ubMaxMorale > 0 && iActualMorale > ubMaxMorale) { // Normalize to Max Morale @@ -1092,6 +1095,9 @@ void HourlyMoraleUpdate( void ) bOpinion = 0; } + if ( pSoldier->HasBackgroundFlag( BACKGROUND_XENOPHOBIC ) && pOtherSoldier->ubProfile != NO_PROFILE && gMercProfiles[pSoldier->ubProfile].usBackground != gMercProfiles[pOtherSoldier->ubProfile].usBackground ) + bOpinion -= 2; + if (bOpinion == HATED_OPINION) { diff --git a/Tactical/Overhead.cpp b/Tactical/Overhead.cpp index f28475e73..a9fb9efbe 100644 --- a/Tactical/Overhead.cpp +++ b/Tactical/Overhead.cpp @@ -7959,6 +7959,9 @@ INT8 CalcSuppressionTolerance( SOLDIERTYPE * pSoldier ) bTolerance = __max(bTolerance, gGameExternalOptions.ubSuppressionToleranceMin); bTolerance = __min(bTolerance, gGameExternalOptions.ubSuppressionToleranceMax); + // Flugente: add personal bonus to suppresion tolerance + bTolerance += pSoldier->GetSuppressionResistanceBonus(); + return( bTolerance ); } @@ -8189,6 +8192,9 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker ) { bShockForCower = (INT8)((bShockForCower * 17 / 20 ) + 0.5); // -15% as shock } + + // Flugente: personal fear resistance + bShockForCower = (INT8)((bShockForCower * (100 - pSoldier->GetFearResistanceBonus()) / 100 ) + 0.5); } if (bShockForCower >= bTolerance) { @@ -10037,6 +10043,12 @@ void PrisonerSurrenderMessageBoxCallBack( UINT8 ubExitValue ) } } + GetSoldier( &pSoldier, gusSelectedSoldier ); + + // if the merc asking for surrender is experienced in capitulation negotiations, we get a bonus to our strength + if ( pSoldier ) + playersidestrength = (playersidestrength * (100 + pSoldier->GetBackgroundValue(BG_PERC_CAPITULATION))) / 100; + // enemy team firstid = gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID; lastid = gTacticalStatus.Team[ ENEMY_TEAM ].bLastID; diff --git a/Tactical/Points.cpp b/Tactical/Points.cpp index 4035fcc5d..663e3ac03 100644 --- a/Tactical/Points.cpp +++ b/Tactical/Points.cpp @@ -349,15 +349,18 @@ INT16 TerrainBreathPoints(SOLDIERTYPE * pSoldier, INT32 sGridNo, INT8 bDir, UINT } } + // Flugente: backgrounds + if ( TERRAIN_IS_HIGH_WATER( ubTerrainID) ) + iPoints = (iPoints * (100 + pSoldier->GetBackgroundValue(BG_SWIMMING))) / 100; + // ATE: Adjust these by realtime movement - if (!(gTacticalStatus.uiFlags & TURNBASED) || !(gTacticalStatus.uiFlags & INCOMBAT ) ) - { + if (!(gTacticalStatus.uiFlags & TURNBASED) || !(gTacticalStatus.uiFlags & INCOMBAT ) ) + { // ATE: ADJUST FOR RT - MAKE BREATH GO A LITTLE FASTER! // silversurfer: now externalized to APBPConstants.ini //iPoints = (INT32)( iPoints * TB_BREATH_DEDUCT_MODIFIER ); iPoints = (INT32)( iPoints * APBPConstants[BP_RT_BREATH_DEDUCT_MODIFIER] / 100 ); - } - + } return( (INT16) iPoints); } @@ -477,6 +480,10 @@ INT16 ActionPointCost( SOLDIERTYPE *pSoldier, INT32 sGridNo, INT8 bDir, UINT16 u } } + // Flugente: swimming background + if ( TERRAIN_IS_HIGH_WATER( ubTerrainID) ) + sPoints = (sPoints * (100 + pSoldier->GetBackgroundValue(BG_SWIMMING))) / 100; + // Check if doors if not player's merc (they have to open them manually) if ( sSwitchValue == TRAVELCOST_DOOR && pSoldier->bTeam != gbPlayerNum ) { @@ -832,6 +839,9 @@ void DeductPoints( SOLDIERTYPE *pSoldier, INT16 sAPCost, INT32 iBPCost, UINT8 ub if ( iBPCost < 0 && gGameOptions.fFoodSystem ) ReduceBPRegenForHunger(pSoldier, &iBPCost); + // Flugente: backgrounds + iBPCost = (INT32) (iBPCost * (100 + pSoldier->GetBackgroundValue(BG_PERC_REGEN_ENERGY)) / 100); + if (is_networked) { // Adjust breath changes due to spending or regaining of energy @@ -2250,9 +2260,9 @@ INT16 MinAPsToShootOrStab(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 bAimTime, bAPCost = (INT16)((bAPCost * (100 - gSkillTraitValues.ubHWRocketLaunchersAPsReduction * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPONS_NT ) ) / 100)+ 0.5); } // Decreased APs needed for mortar - Heavy Weapons - else if ( Item[usUBItem].mortar && HAS_SKILL_TRAIT( pSoldier, HEAVY_WEAPONS_NT ) ) + else if ( Item[usUBItem].mortar ) { - bAPCost = (INT16)((bAPCost * (100 - gSkillTraitValues.ubHWMortarAPsReduction * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPONS_NT ) ) / 100)+ 0.5); + bAPCost = (INT16)((bAPCost * (100 - gSkillTraitValues.ubHWMortarAPsReduction * NUM_SKILL_TRAITS( pSoldier, HEAVY_WEAPONS_NT ) + pSoldier->GetBackgroundValue(BG_ARTILLERY) ) / 100)+ 0.5); } // Decreased APs needed for pistols and machine pistols - Gunslinger else if (Weapon[ usUBItem ].ubWeaponType == GUN_PISTOL && HAS_SKILL_TRAIT( pSoldier, GUNSLINGER_NT ) ) @@ -3754,6 +3764,11 @@ INT16 GetAPsForMultiTurnAction( SOLDIERTYPE *pSoldier, UINT8 usActionType ) break; } + if ( usActionType == MTA_FORTIFY || usActionType == MTA_REMOVE_FORTIFY || usActionType == MTA_FILL_SANDBAG ) + { + sAPCost = (sAPCost * (100 + pSoldier->GetBackgroundValue(BG_FORTIFY))) / 100; + } + return sAPCost; } diff --git a/Tactical/ShopKeeper Interface.cpp b/Tactical/ShopKeeper Interface.cpp index 9d4c9ffdb..e310ee622 100644 --- a/Tactical/ShopKeeper Interface.cpp +++ b/Tactical/ShopKeeper Interface.cpp @@ -3341,7 +3341,8 @@ UINT8 ubItemsNotCounted = 0; //ja25 UB uiItemPrice[ubCnt] += CalcShopKeeperItemPrice( fDealerSelling, fUnitPriceOnly, iter->usItem, dModifier, &(*iter)) ; } - // if Flo is doing the dealin' and wheelin' + // Flugente: used in backgrounds now, old code in comments for historical reasons + /*// if Flo is doing the dealin' and wheelin' if ( gpSMCurrentMerc->ubProfile == FLO ) { // if it's a GUN or AMMO (but not Launchers, and all attachments and payload is included) @@ -3364,6 +3365,46 @@ UINT8 ubItemsNotCounted = 0; //ja25 UB } break; } + }*/ + + // if it's a GUN or AMMO (but not Launchers, and all attachments and payload is included) + if ( Item [ usItemID ].usItemClass & (IC_GUN|IC_AMMO) ) + { + if ( gpSMCurrentMerc->GetBackgroundValue(BG_PERC_PRICES_GUNS) ) + uiDiscountValue = ( uiItemPrice[ubCnt] * gpSMCurrentMerc->GetBackgroundValue(BG_PERC_PRICES_GUNS) ) / 100; + // if we play without backgrounds, Flo gets the hardcoded bonus + else if ( gpSMCurrentMerc->ubProfile == FLO ) + uiDiscountValue = ( uiItemPrice[ubCnt] * FLO_DISCOUNT_PERCENTAGE ) / 100; + + // she gets a discount! Read her M.E.R.C. profile to understand why + if ( fDealerSelling ) + { + // she buys for less... + uiItemPrice[ubCnt] -= uiDiscountValue; + } + else + { + // and sells for more! + uiItemPrice[ubCnt] += uiDiscountValue; + } + break; + } + // Flugente: backgrounds + else if ( Item [ usItemID ].usItemClass & (IC_MAPFILTER_MELEE|IC_MAPFILTER_KIT|IC_MAPFILTER_LBE|IC_MAPFILTER_ARMOR|IC_MAPFILTER_MISC) ) + { + uiDiscountValue = ( uiItemPrice[ubCnt] * gpSMCurrentMerc->GetBackgroundValue(BG_PERC_PRICES) ) / 100; + + if ( fDealerSelling ) + { + // buy for less... + uiItemPrice[ubCnt] -= uiDiscountValue; + } + else + { + // and sell for more! + uiItemPrice[ubCnt] += uiDiscountValue; + } + break; } // if it's the dealer selling this, make sure the item is worth at least $1 diff --git a/Tactical/SkillCheck.cpp b/Tactical/SkillCheck.cpp index e62539d3c..08db13865 100644 --- a/Tactical/SkillCheck.cpp +++ b/Tactical/SkillCheck.cpp @@ -16,6 +16,7 @@ #include "GameSettings.h" #include "Animation Data.h" #include "Soldier Control.h" +#include "Interface.h" // added by Flugente for zBackground #endif extern void ReducePointsForHunger( SOLDIERTYPE *pSoldier, UINT32 *pusPoints ); @@ -47,6 +48,8 @@ INT16 EffectiveStrength( SOLDIERTYPE *pSoldier, BOOLEAN fTrainer ) { iEffStrength = 0; } + + iEffStrength = (iEffStrength * (100 + pSoldier->GetBackgroundValue(BG_STRENGTH))) / 100; // ATE: Make sure at least 2... iEffStrength = __max( iEffStrength, 2 ); @@ -84,6 +87,8 @@ INT16 EffectiveAgility( SOLDIERTYPE * pSoldier, BOOLEAN fTrainer ) iEffAgility = (iEffAgility * 100) / pSoldier->sWeightCarriedAtTurnStart; } + iEffAgility = (iEffAgility * (100 + pSoldier->GetBackgroundValue(BG_AGILITY))) / 100; + return( (INT16) iEffAgility ); } @@ -96,6 +101,8 @@ INT8 EffectiveMechanical( SOLDIERTYPE * pSoldier ) iEffMechanical = EffectStatForBeingDrunk( pSoldier, iEffMechanical ); + iEffMechanical = (iEffMechanical * (100 + pSoldier->GetBackgroundValue(BG_MECHANICAL))) / 100; + return( (INT8) iEffMechanical ); } @@ -108,6 +115,8 @@ INT8 EffectiveExplosive( SOLDIERTYPE * pSoldier ) iEffExplosive = EffectStatForBeingDrunk( pSoldier, iEffExplosive ); + iEffExplosive = (iEffExplosive * (100 + pSoldier->GetBackgroundValue(BG_EXPLOSIVE_ASSIGN))) / 100; + return( (INT8) iEffExplosive ); } @@ -120,6 +129,8 @@ INT8 EffectiveMedical( SOLDIERTYPE * pSoldier ) iEffMedical = EffectStatForBeingDrunk( pSoldier, iEffMedical ); + iEffMedical = (iEffMedical * (100 + pSoldier->GetBackgroundValue(BG_MEDICAL))) / 100; + return( (INT8) iEffMedical ); } @@ -138,6 +149,8 @@ INT8 EffectiveLeadership( SOLDIERTYPE * pSoldier ) iEffLeadership = ( iEffLeadership * 120 / 100 ); } + iEffLeadership = (iEffLeadership * (100 + pSoldier->GetBackgroundValue(BG_LEADERSHIP))) / 100; + return( (INT8) iEffLeadership ); } @@ -206,6 +219,8 @@ INT8 EffectiveMarksmanship( SOLDIERTYPE * pSoldier ) iEffMarksmanship = EffectStatForBeingDrunk( pSoldier, iEffMarksmanship ); + iEffMarksmanship = (iEffMarksmanship * (100 + pSoldier->GetBackgroundValue(BG_MARKSMANSHIP))) / 100; + return( (INT8) iEffMarksmanship ); } @@ -220,6 +235,8 @@ INT16 EffectiveDexterity( SOLDIERTYPE * pSoldier, BOOLEAN fTrainer ) iEffDexterity = EffectStatForBeingDrunk( pSoldier, iEffDexterity ); + iEffDexterity = (iEffDexterity * (100 + pSoldier->GetBackgroundValue(BG_DEXTERITY))) / 100; + return( (INT16) iEffDexterity ); } diff --git a/Tactical/Soldier Add.cpp b/Tactical/Soldier Add.cpp index 1b8f9c3b0..5f10a8d03 100644 --- a/Tactical/Soldier Add.cpp +++ b/Tactical/Soldier Add.cpp @@ -21,6 +21,7 @@ #include "Render Fun.h" #include "meanwhile.h" #include "Exit Grids.h" + #include "Interface.h" // added by Flugente for zBackground #endif #ifdef JA2UB @@ -1194,6 +1195,18 @@ BOOLEAN InternalAddSoldierToSector( UINT8 ubID, BOOLEAN fCalculateDirection, BOO } } + // Flugente backgrounds + if ( pSoldier->ubStrategicInsertionCode == INSERTION_CODE_CENTER && pSoldier->GetBackgroundValue(BG_AIRDROP) ) + { + fCalculateDirection = FALSE; + pSoldier->ubInsertionDirection = Random( DIRECTION_IRRELEVANT ); + + pSoldier->bSoldierFlagMask |= SOLDIER_AIRDROP_BONUS; + } + + // add this flag whenever we enter strategically enter a sector (= we attack a sector) + pSoldier->bSoldierFlagMask |= SOLDIER_ASSAULT_BONUS; + // Override calculated direction if we were told to.... if ( pSoldier->ubInsertionDirection > 100 ) { diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index 5017ae370..5205890d2 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -1512,6 +1512,7 @@ void MERCPROFILESTRUCT::initialize() clearInventory(); // SANDRO - added this memset( &records, 0, sizeof(STRUCT_Records) ); + memset( &usBackground, 0, sizeof(UINT8) ); } // Initialize the soldier. @@ -2073,6 +2074,9 @@ INT16 SOLDIERTYPE::CalcActionPoints( void ) //ubPoints += 0; } + // Flugente: personal AP adjustments + ubPoints = (INT16)( (ubPoints * (100 + this->GetAPBonus()) ) / 100); + // option to make special NPCs stronger - AP bonus if ( this->ubProfile != NO_PROFILE && gGameExternalOptions.usSpecialNPCStronger > 0 ) { @@ -2192,6 +2196,9 @@ void SOLDIERTYPE::CalcNewActionPoints( void ) //MaxActionPnts += 0; } + // Flugente: personal AP adjustments + usMaxActionPnts = (INT16)( (usMaxActionPnts * (100 + this->GetAPBonus()) ) / 100); + // option to make special NPCs stronger - AP bonus if ( this->ubProfile != NO_PROFILE && gGameExternalOptions.usSpecialNPCStronger > 0 ) { @@ -7426,6 +7433,9 @@ void SOLDIERTYPE::EVENT_BeginMercTurn( BOOLEAN fFromRealTime, INT32 iRealTimeCou // If an AI guy, and we have 0 life, and are still at higher hieght, // Kill them..... + // Flugente: update for various personal properties + // this has to happen before CalculateCarriedWeight(), otherwise strength modfiers will not be detected correctly + this->SoldierPropertyUpkeep(); this->sWeightCarriedAtTurnStart = (INT16) CalculateCarriedWeight( this ); @@ -8492,6 +8502,8 @@ void CalculateSoldierAniSpeed( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pStatsSoldier bLifeDef = 50 - ( pStatsSoldier->stats.bLife / 2 ); uiTerrainDelay += ( bLifeDef + bBreathDef + bAgilDef + bAdditional ); + + uiTerrainDelay = (uiTerrainDelay * (100 + pSoldier->GetBackgroundValue(BG_PERC_SPEED_RUNNING) )) / 100; pSoldier->sAniDelay = (INT16)uiTerrainDelay; @@ -12443,7 +12455,7 @@ UINT32 SOLDIERTYPE::SoldierDressWound( SOLDIERTYPE *pVictim, INT16 sKitPts, INT1 if (!(fOnSurgery) && gGameOptions.fNewTraitSystem && HAS_SKILL_TRAIT( this, DOCTOR_NT )) { uiPossible = uiPossible * (100 - gSkillTraitValues.bSpeedModifierBandaging) / 100; - uiPossible += ( uiPossible * gSkillTraitValues.ubDOBandagingSpeedPercent * NUM_SKILL_TRAITS( this, DOCTOR_NT ) / 100); + uiPossible += ( uiPossible * gSkillTraitValues.ubDOBandagingSpeedPercent * NUM_SKILL_TRAITS( this, DOCTOR_NT ) + this->GetBackgroundValue(BG_PERC_BANDAGING) ) / 100; } uiActual = uiPossible; // start by assuming maximum possible @@ -13745,7 +13757,7 @@ void SOLDIERTYPE::SoldierInventoryCoolDown(void) // 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 ) + if ( !gGameExternalOptions.fWeaponOverheating && !gGameExternalOptions.fDirtSystem && !gGameOptions.fFoodSystem ) return; // one hour has 60 minutes, with 12 5-second-intervals (cooldown values are based on 5-second values) @@ -13776,7 +13788,7 @@ void SOLDIERTYPE::SoldierInventoryCoolDown(void) if ( pObj != NULL ) // ... if pointer is not obviously useless ... { // ... 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 ( gGameExternalOptions.fWeaponOverheating && ( Item[pObj->usItem].usItemClass & (IC_GUN|IC_LAUNCHER) || Item[pObj->usItem].barrel == TRUE ) ) { for(INT16 i = 0; i < pObj->ubNumberOfObjects; ++i) // ... there might be multiple items here (item stack), so for each one ... { @@ -14070,6 +14082,8 @@ INT32 SOLDIERTYPE::GetDamageResistance(BOOLEAN fAutoResolve, BOOLEAN fCalcBreath // Flugente: drugs can now have an effect on damage resistance HandleDamageResistanceEffectDueToDrugs(this, &resistance); + + resistance += this->GetBackgroundValue(BG_RESI_PHYSICAL); // resistance is between -100% and 100% resistance = max( 0, resistance); @@ -14091,6 +14105,11 @@ INT8 SOLDIERTYPE::GetHearingBonus() if ( gMercProfiles[ this->ubProfile ].bDisability == DEAF ) bonus -= 5; + + if ( NightTime() ) + bonus += this->GetBackgroundValue(BG_PERC_HEARING_NIGHT); + else + bonus += this->GetBackgroundValue(BG_PERC_HEARING_DAY); return bonus; } @@ -14125,7 +14144,7 @@ INT16 SOLDIERTYPE::GetPoisonResistance( void ) // Flugente: resistance can per definition only be between -100 and 100 (at least that's my definition) INT16 val = bPoisonResistance; - // without WH40K, there are no modifiers + val += this->GetBackgroundValue(BG_RESI_POISON); val = max(-100, val); val = min(100, val); @@ -16360,6 +16379,13 @@ void SOLDIERTYPE::AddDrugValues(UINT8 uDrugType, UINT8 usEffect, UINT8 usTravelR if ( uDrugType >= DRUG_TYPE_MAX ) return; + // Flugente: backgrounds + if ( this->ubProfile != NOBODY && uDrugType == DRUG_TYPE_ALCOHOL ) + { + usEffect = usEffect * ((100 - this->GetBackgroundValue(BG_RESI_ALCOHOL)) / 100); + usSideEffect = usSideEffect * ((100 - this->GetBackgroundValue(BG_RESI_ALCOHOL)) / 100); + } + // Add effects if ( ( this->drugs.bFutureDrugEffect[ uDrugType ] + usEffect ) < 127 ) { @@ -16565,6 +16591,134 @@ INT8 SOLDIERTYPE::GetSoldierProfileType(UINT8 usTeam) return type; } +// Flugente: do we have a specific background flag? +BOOLEAN SOLDIERTYPE::HasBackgroundFlag( UINT64 aFlag) +{ + if ( gGameOptions.fBackGround && this->ubProfile != NO_PROFILE ) + { + if ( zBackground[ gMercProfiles[this->ubProfile].usBackground ].uiFlags & aFlag ) + return TRUE; + } + + return FALSE; +} + +INT16 SOLDIERTYPE::GetBackgroundValue( UINT16 aNr ) +{ + if ( gGameOptions.fBackGround && this->ubProfile != NO_PROFILE ) + { + return zBackground[ gMercProfiles[this->ubProfile].usBackground ].value[aNr]; + } + + return 0; +} + +INT8 SOLDIERTYPE::GetSuppressionResistanceBonus() +{ + INT8 bonus = 0; + + bonus += this->GetBackgroundValue(BG_RESI_SUPPRESSION); + + return min( 100, max( -100, bonus) ); +} + +INT16 SOLDIERTYPE::GetMeleeDamageBonus() +{ + INT8 bonus = 0; + + bonus += this->GetBackgroundValue(BG_PERC_DAMAGE_MELEE); + + return bonus; +} + +INT16 SOLDIERTYPE::GetAPBonus() +{ + INT16 bonus = 0; + + if ( this->bSoldierFlagMask & SOLDIER_AIRDROP_BONUS ) + bonus += this->GetBackgroundValue(BG_AIRDROP); + + if ( this->bSoldierFlagMask & SOLDIER_ASSAULT_BONUS ) + bonus += this->GetBackgroundValue(BG_ASSAULT); + + UINT8 ubSector = (UINT8)SECTOR( this->sSectorX, this->sSectorY ); + UINT8 ubTraverseType = SectorInfo[ ubSector ].ubTraversability[ ubDirection ]; + + switch ( ubTraverseType ) + { + case NS_RIVER: + case EW_RIVER: + bonus += this->GetBackgroundValue(BG_RIVER); + break; + case COASTAL: + case COASTAL_ROAD: + bonus += this->GetBackgroundValue(BG_COASTAL); + break; + case TROPICS_SAM_SITE: + bonus += this->GetBackgroundValue(BG_COASTAL); + bonus += this->GetBackgroundValue(BG_TROPICAL); + break; + case TROPICS: + case TROPICS_ROAD: + bonus += this->GetBackgroundValue(BG_TROPICAL); + break; + case HILLS: + case HILLS_ROAD: + bonus += this->GetBackgroundValue(BG_MOUNTAIN); + break; + case SWAMP: + case SWAMP_ROAD: + bonus += this->GetBackgroundValue(BG_SWAMP); + break; + case SAND: + case SAND_ROAD: + case SAND_SAM_SITE: + bonus += this->GetBackgroundValue(BG_DESERT); + break; + case TOWN: + case CAMBRIA_HOSPITAL_SITE: + case DRASSEN_AIRPORT_SITE: + case MEDUNA_AIRPORT_SITE: + bonus += this->GetBackgroundValue(BG_URBAN); + break; + default: + break; + } + + if ( this->pathing.bLevel ) + bonus += this->GetBackgroundValue(BG_HEIGHT); + + return bonus; +} + +INT8 SOLDIERTYPE::GetFearResistanceBonus() +{ + INT8 bonus = 0; + + bonus += this->GetBackgroundValue(BG_RESI_FEAR); + + return min(100, max(-100, bonus)); +} + +UINT8 SOLDIERTYPE::GetMoraleThreshold() +{ + UINT8 threshold = 100; + UINT8 moraledamage = 0; + + moraledamage = (moraledamage * (100 - GetFearResistanceBonus())) / 100; + + return min(threshold, max(0, threshold - moraledamage)); +} + +void SOLDIERTYPE::SoldierPropertyUpkeep() +{ + // these flags are only used for the first turn, and thus always removed + this->bSoldierFlagMask &= ~(SOLDIER_AIRDROP_BONUS|SOLDIER_ASSAULT_BONUS); + + if ( HasBackgroundFlag( BACKGROUND_EXP_UNDERGROUND ) && this->bSectorZ ) + ++bExtraExpLevel; +} + INT32 CheckBleeding( SOLDIERTYPE *pSoldier ) { INT8 bBandaged; //,savedOurTurn; diff --git a/Tactical/Soldier Control.h b/Tactical/Soldier Control.h index 9bf8af723..85c37cce6 100644 --- a/Tactical/Soldier Control.h +++ b/Tactical/Soldier Control.h @@ -370,9 +370,9 @@ enum #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 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 +#define SOLDIER_AIRDROP_BONUS 0x00020000 //131072 // backgrounds: special AP bonus during the first turn of an airdrop +#define SOLDIER_ASSAULT_BONUS 0x00040000 //262144 // backgrounds: our first turn in an assault +/*#define PLAYER_NET_4_LVL_1 0x00080000 //524288 #define PLAYER_NET_1_LVL_2 0x00100000 //1048576 #define PLAYER_NET_2_LVL_2 0x00200000 //2097152 @@ -390,6 +390,22 @@ enum #define WH40K_SOLDIER_KILLTHISTURN 0x80000000 //2147483648 // Soldier is on a kill streak*/ // ---------------------------------------------------------------- +// -------- added by Flugente: background property flags -------- +// easier than adding 32 differently named variables. DO NOT CHANGE THEM, UNLESS YOU KNOW WHAT YOU ARE DOING!!! +// a merc's background info reveals data about his previous life, like former regiments. These backgrounds add small abilities/disabilities. Nothing substantial, just small bits do +// diversify your mercs and add more personality +#define BACKGROUND_DRUGUSE 0x0000000000000001 //1 // might use drugs on his own (the 'Larry'-effect) +#define BACKGROUND_XENOPHOBIC 0x0000000000000002 //2 // arrogant towards others without this background +#define BACKGROUND_EXP_UNDERGROUND 0x0000000000000004 //4 // extra level in underground sectors +#define BACKGROUND_SCROUNGING 0x0000000000000008 //8 // might pick up valuable items on his own + +#define BACKGROUND_TRAPLEVEL 0x0000000000000010 //16 // trap level +1 +#define BACKGROUND_CORRUPTIONSPREAD 0x0000000000000020 //32 // spreads corruption to others - not used in trunk! +//#define BACKGROUND_XENOPHOBIC 0x0000000000000040 //64 // arrogant towards others without this background +//#define BACKGROUND_CAPITULATION 0x0000000000000080 //128 // if present, the team's surrender strength is higher + +#define BACKGROUND_FLAG_MAX 6 // number of flagged backgrounds - keep this updated, or properties will get lost! + // Flugente: types of multi-turn actions enum { @@ -1573,6 +1589,19 @@ public: // Flugente: soldier profiles INT8 GetSoldierProfileType(UINT8 usTeam); // retrieves the correct sub-array + + // Flugente: do we have a specific background flag? + BOOLEAN HasBackgroundFlag( UINT64 aFlag ); + INT16 GetBackgroundValue( UINT16 aNr ); + + INT8 GetSuppressionResistanceBonus(); // bonus to resistance against suppression + INT16 GetMeleeDamageBonus(); + INT16 GetAPBonus(); + INT8 GetFearResistanceBonus(); // fear resistance lowers shock and morale damage from horror + UINT8 GetMoraleThreshold(); + + void SoldierPropertyUpkeep(); // update functions for various properties (updating counters, resetting flags etc.) + ////////////////////////////////////////////////////////////////////////////// }; // SOLDIERTYPE; diff --git a/Tactical/Soldier Profile.cpp b/Tactical/Soldier Profile.cpp index 9622e068b..bd148455a 100644 --- a/Tactical/Soldier Profile.cpp +++ b/Tactical/Soldier Profile.cpp @@ -2345,7 +2345,7 @@ SOLDIERTYPE * SwapLarrysProfiles( SOLDIERTYPE * pSoldier ) pSoldier->stats.bMechanical = pNewProfile->bMechanical + pNewProfile->bMechanicDelta; pSoldier->stats.bMedical = pNewProfile->bMedical + pNewProfile->bMedicalDelta; pSoldier->stats.bExplosive = pNewProfile->bExplosive + pNewProfile->bExplosivesDelta; - + if ( pSoldier->ubProfile == LARRY_DRUNK ) { SetFactTrue( FACT_LARRY_CHANGED ); @@ -2594,6 +2594,7 @@ void OverwriteMercProfileWithXMLData( UINT32 uiLoop ) gMercProfiles[ uiLoop ].ubCivilianGroup = tempProfiles[uiLoop].ubCivilianGroup; gMercProfiles[ uiLoop ].bTown = tempProfiles[uiLoop].bTown; gMercProfiles[ uiLoop ].bTownAttachment = tempProfiles[uiLoop].bTownAttachment; + gMercProfiles[ uiLoop ].usBackground = tempProfiles[uiLoop].usBackground; //None if ( tempProfiles[uiLoop].Type == 0 ) diff --git a/Tactical/Soldier Profile.h b/Tactical/Soldier Profile.h index 7a373c209..25c1a6ebc 100644 --- a/Tactical/Soldier Profile.h +++ b/Tactical/Soldier Profile.h @@ -406,6 +406,9 @@ typedef struct INT8 bTown; INT8 bTownAttachment; + // Flugente: backgrounds + UINT8 usBackground; + } TEMPPROFILETYPE; extern TEMPPROFILETYPE tempProfiles[NUM_PROFILES+1]; diff --git a/Tactical/Tactical_VS2005.vcproj b/Tactical/Tactical_VS2005.vcproj index 36f794090..1d16e0691 100644 --- a/Tactical/Tactical_VS2005.vcproj +++ b/Tactical/Tactical_VS2005.vcproj @@ -1012,6 +1012,10 @@ RelativePath=".\XML_AttachmentSlots.cpp" > + + diff --git a/Tactical/Tactical_VS2008.vcproj b/Tactical/Tactical_VS2008.vcproj index 5feda15bd..9b06a448b 100644 --- a/Tactical/Tactical_VS2008.vcproj +++ b/Tactical/Tactical_VS2008.vcproj @@ -1014,6 +1014,10 @@ RelativePath=".\XML_AttachmentSlots.cpp" > + + diff --git a/Tactical/Tactical_VS2010.vcxproj b/Tactical/Tactical_VS2010.vcxproj index f273fba1d..f1b5e0361 100644 --- a/Tactical/Tactical_VS2010.vcxproj +++ b/Tactical/Tactical_VS2010.vcxproj @@ -192,6 +192,7 @@ + diff --git a/Tactical/Tactical_VS2010.vcxproj.filters b/Tactical/Tactical_VS2010.vcxproj.filters index a7744310a..350abdfbe 100644 --- a/Tactical/Tactical_VS2010.vcxproj.filters +++ b/Tactical/Tactical_VS2010.vcxproj.filters @@ -644,5 +644,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/Tactical/Weapons.cpp b/Tactical/Weapons.cpp index e8537fc10..37b810374 100644 --- a/Tactical/Weapons.cpp +++ b/Tactical/Weapons.cpp @@ -1282,7 +1282,7 @@ BOOLEAN CheckForGunJam( SOLDIERTYPE * pSoldier ) gGameExternalOptions.ubWeaponReliabilityReductionPerRainIntensity * gbCurrentRainIntensity; // Flugente: If overheating is allowed, a gun will be prone to more overheating if its temperature is high - if ( gGameOptions.fWeaponOverheating ) + if ( gGameExternalOptions.fWeaponOverheating ) { FLOAT overheatjampercentage = GetGunOverheatJamPercentage( pObj ); // how much above the gun's usOverheatingJamThreshold are we? ... @@ -2267,7 +2267,7 @@ BOOLEAN UseGunNCTH( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo ) INT16 iOverheatReliabilityMalus = 0; // Flugente: Increase Weapon Temperature - if ( gGameOptions.fWeaponOverheating ) + if ( gGameExternalOptions.fWeaponOverheating ) { FLOAT overheatjampercentage = GetGunOverheatDamagePercentage( pObjAttHand ); // ... how much above the gun's usOverheatingDamageThreshold are we? ... @@ -2888,7 +2888,7 @@ BOOLEAN UseGun( SOLDIERTYPE *pSoldier , INT32 sTargetGridNo ) INT16 iOverheatReliabilityMalus = 0; // Flugente: Increase Weapon Temperature - if ( gGameOptions.fWeaponOverheating ) + if ( gGameExternalOptions.fWeaponOverheating ) { FLOAT overheatjampercentage = GetGunOverheatDamagePercentage( pObjUsed ); // ... how much above the gun's usOverheatingDamageThreshold are we? ... @@ -6085,9 +6085,10 @@ else iChance = __max(iChance + (INT32)iAimPoints, iChance); iChance = __min(iChance, (INT32)uiCap); } - - // Impose global limits. - iChance = __min(iChance, gGameExternalOptions.ubMaximumCTH); + + // Impose global limits. + // Flugente: backgrounds + iChance = min(iChance, gGameExternalOptions.ubMaximumCTH + (UINT8)(pSoldier->GetBackgroundValue(BG_PERC_CTH_MAX)) ); iChance = __max(iChance, gGameExternalOptions.ubMinimumCTH); return (iChance); @@ -6552,7 +6553,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, // Flugente: If overheating is allowed, an overheated gun receives a slight malus to accuracy FLOAT accuracyheatmultiplicator = 1.0; - if ( gGameOptions.fWeaponOverheating ) + if ( gGameExternalOptions.fWeaponOverheating ) { FLOAT overheatjampercentage = GetGunOverheatJamPercentage( pInHand ); FLOAT accuracymalus = (FLOAT)((max(1.0, overheatjampercentage) - 1.0) * 0.1); @@ -7082,7 +7083,7 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, // Flugente: If overheating is allowed, an overheated gun receives a slight malus to accuracy FLOAT accuracyheatmultiplicator = 1.0; - if ( gGameOptions.fWeaponOverheating ) + if ( gGameExternalOptions.fWeaponOverheating ) { FLOAT overheatdamagepercentage = GetGunOverheatDamagePercentage( pInHand ); FLOAT accuracymalus = (FLOAT)((max(1.0, overheatdamagepercentage) - 1.0) * 0.1); @@ -7363,8 +7364,9 @@ UINT32 CalcChanceToHitGun(SOLDIERTYPE *pSoldier, INT32 sGridNo, INT16 ubAimTime, // HEADROCK (HAM): Externalized maximum to JA2_OPTIONS.INI // if (iChance > MAXCHANCETOHIT) // iChance = MAXCHANCETOHIT; - if (iChance > gGameExternalOptions.ubMaximumCTH) - iChance = gGameExternalOptions.ubMaximumCTH; + + // Flugente: backgrounds + iChance = min(iChance, gGameExternalOptions.ubMaximumCTH + (UINT8)(pSoldier->GetBackgroundValue(BG_PERC_CTH_MAX)) ); } ///////////////////////////////////////////////////////////////////////////////////// @@ -10184,7 +10186,13 @@ UINT32 CalcChanceHTH( SOLDIERTYPE * pAttacker,SOLDIERTYPE *pDefender, INT16 ubAi else if ( bNumMercs > 0 ) iAttRating += 2; } - } + } + + // Flugente: backgrounds + if (ubMode == HTH_MODE_STAB) + { + iAttRating = (iAttRating * (100 + pAttacker->GetBackgroundValue(BG_PERC_CTH_BLADE))) / 100; + } //////////////////////////////////////////////////////////////////////////////////// if (iAttRating < 1) @@ -11383,7 +11391,7 @@ BOOLEAN WillExplosiveWeaponFail( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObj ) { // malus for overheating INT16 iOverheatMalus = 0; - if ( gGameOptions.fWeaponOverheating ) + if ( gGameExternalOptions.fWeaponOverheating ) { FLOAT overheatjampercentage = GetGunOverheatDamagePercentage( pObj); @@ -11800,7 +11808,7 @@ void CalcMagFactorSimple( SOLDIERTYPE *pSoldier, FLOAT d2DDistance, INT16 bAimTi // Flugente: Increase temperature/dirt of gun in ubAttackingHand due to firing a shot void GunIncreaseHeat( OBJECTTYPE *pObj, SOLDIERTYPE* pSoldier ) { - if ( gGameOptions.fWeaponOverheating ) + if ( gGameExternalOptions.fWeaponOverheating ) { if ( Item[pObj->usItem].usItemClass & (IC_GUN|IC_LAUNCHER) ) // if item is a gun pr launcher... { diff --git a/Tactical/XML.h b/Tactical/XML.h index 71ed5cca1..bd11478ca 100644 --- a/Tactical/XML.h +++ b/Tactical/XML.h @@ -232,6 +232,7 @@ typedef PARSE_STAGE; #define SPREADPATTERNSFILENAME "SpreadPatterns.xml" #define VEHICLESFILENAME "Vehicles.xml" #define SQUADNAMEFILENAME "SquadNames.xml" +#define BACKGROUNDSFILENAME "Backgrounds.xml" #define ENEMY_ADMIN_PROFILE_FILENAME "Profiles\\SoldierProfileEnemyAdmin.xml" #define ENEMY_REGULAR_PROFILE_FILENAME "Profiles\\SoldierProfileEnemyRegular.xml" @@ -460,6 +461,10 @@ extern BOOLEAN WriteEnemyRank( STR fileName); extern BOOLEAN ReadInIMPPortraits(STR fileName, BOOLEAN localizedVersion); extern void LoadIMPPortraitsTEMP(); +// Flugente: backgrounds +extern BOOLEAN ReadInBackgrounds(STR fileName ); +extern BOOLEAN WriteBackgrounds( STR fileName); + //Enabled\Disabled profile sound by Jazz extern BOOLEAN ReadInSoundProfile( STR fileName ); extern BOOLEAN WriteSoundProfile( STR fileName ); diff --git a/Tactical/XML_Background.cpp b/Tactical/XML_Background.cpp new file mode 100644 index 000000000..c29eaf2e8 --- /dev/null +++ b/Tactical/XML_Background.cpp @@ -0,0 +1,602 @@ +#ifdef PRECOMPILEDHEADERS + #include "Tactical All.h" +#else + #include "sgp.h" + #include "Debug Control.h" + #include "expat.h" + #include "XML.h" + #include "Interface.h" +#endif + +struct +{ + PARSE_STAGE curElement; + + CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1]; + BACKGROUND_VALUES curBackground; + BACKGROUND_VALUES * curArray; + + UINT32 maxArraySize; + UINT32 curIndex; + UINT32 currentDepth; + UINT32 maxReadDepth; + CHAR16 gzBackground[MAX_ENEMY_NAMES_CHARS]; +} +typedef enemyRankParseData; + +UINT16 num_found_background = 0; // the correct number is set on reading the xml + +#define XML_BACKGROUND_AP_MAX 8 +#define XML_BACKGROUND_STAT_MAX 10 +#define XML_BACKGROUND_TRAVEL_MAX 20 +#define XML_BACKGROUND_RESI_MAX 20 +#define XML_VARIOUS_MAX 300 + +static void XMLCALL +backgroundStartElementHandle(void *userData, const XML_Char *name, const XML_Char **atts) +{ + enemyRankParseData * pData = (enemyRankParseData *)userData; + + if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element? + { + if(strcmp(name, "BACKGROUNDS") == 0 && pData->curElement == ELEMENT_NONE) + { + pData->curElement = ELEMENT_LIST; + + memset(pData->curArray,0,sizeof(BACKGROUND_VALUES)*pData->maxArraySize); + + pData->maxReadDepth++; //we are not skipping this element + } + else if(strcmp(name, "BACKGROUND") == 0 && pData->curElement == ELEMENT_LIST) + { + pData->curElement = ELEMENT; + + memset(&pData->curBackground,0,sizeof(BACKGROUND_VALUES)); + + pData->maxReadDepth++; //we are not skipping this element + } + else if(pData->curElement == ELEMENT && + (strcmp(name, "uiIndex") == 0 || + strcmp(name, "szName") == 0 || + strcmp(name, "szShortName") == 0 || + strcmp(name, "szDescription") == 0 || + strcmp(name, "ap_polar") == 0 || + strcmp(name, "ap_desert") == 0 || + strcmp(name, "ap_swamp") == 0 || + strcmp(name, "ap_urban") == 0 || + strcmp(name, "ap_river") == 0 || + strcmp(name, "ap_coastal") == 0 || + strcmp(name, "ap_tropical") == 0 || + strcmp(name, "ap_mountain") == 0 || + strcmp(name, "ap_height") == 0 || + strcmp(name, "ap_swimming") == 0 || + strcmp(name, "ap_fortify") == 0 || + strcmp(name, "ap_artillery") == 0 || + strcmp(name, "ap_inventory") == 0 || + strcmp(name, "ap_airdrop") == 0 || + strcmp(name, "ap_assault") == 0 || + strcmp(name, "agility") == 0 || + strcmp(name, "strength") == 0 || + strcmp(name, "dexterity") == 0 || + strcmp(name, "mechanical") == 0 || + strcmp(name, "medical") == 0 || + strcmp(name, "explosives") == 0 || + strcmp(name, "leadership") == 0 || + strcmp(name, "marksmanship") == 0 || + strcmp(name, "travel_foot") == 0 || + strcmp(name, "travel_car") == 0 || + strcmp(name, "travel_air") == 0 || + strcmp(name, "travel_boat") == 0 || + strcmp(name, "resistance_poison") == 0 || + strcmp(name, "resistance_fear") == 0 || + strcmp(name, "resistance_suppression") == 0 || + strcmp(name, "resistance_physical") == 0 || + strcmp(name, "resistance_alcohol") == 0 || + strcmp(name, "interrogation") == 0 || + strcmp(name, "prisonguard") == 0 || + strcmp(name, "betterprices_guns") == 0 || + strcmp(name, "betterprices") == 0 || + strcmp(name, "capitulation") == 0 || + strcmp(name, "speed_run") == 0 || + strcmp(name, "speed_bandaging") == 0 || + strcmp(name, "drink_energyregen") == 0 || + strcmp(name, "carrystrength") == 0 || + strcmp(name, "food") == 0 || + strcmp(name, "water") == 0 || + strcmp(name, "sleep") == 0 || + strcmp(name, "meleedamage") == 0 || + strcmp(name, "cth_blades") == 0 || + strcmp(name, "camo") == 0 || + strcmp(name, "stealth") == 0 || + strcmp(name, "increased_maxcth") == 0 || + strcmp(name, "hearing_night") == 0 || + strcmp(name, "hearing_day") == 0 || + strcmp(name, "approach_friendly") == 0 || + strcmp(name, "approach_direct") == 0 || + strcmp(name, "approach_threaten") == 0 || + strcmp(name, "approach_recruit") == 0 || + strcmp(name, "breachingcharge") == 0 || + strcmp(name, "druguse") == 0 || + strcmp(name, "xenophobic") == 0 || + strcmp(name, "corruptionspread") == 0 || + strcmp(name, "level_underground") == 0 || + strcmp(name, "scrounging") == 0 || + strcmp(name, "traplevel") == 0 )) + { + pData->curElement = ELEMENT_PROPERTY; + + pData->maxReadDepth++; //we are not skipping this element + } + + pData->szCharData[0] = '\0'; + } + + pData->currentDepth++; +} + +static void XMLCALL +backgroundCharacterDataHandle(void *userData, const XML_Char *str, int len) +{ + enemyRankParseData * pData = (enemyRankParseData *)userData; + + if( (pData->currentDepth <= pData->maxReadDepth) && + (strlen(pData->szCharData) < MAX_CHAR_DATA_LENGTH) + ){ + strncat(pData->szCharData,str,__min((unsigned int)len,MAX_CHAR_DATA_LENGTH-strlen(pData->szCharData))); + } +} + +static void XMLCALL +backgroundEndElementHandle(void *userData, const XML_Char *name) +{ + enemyRankParseData * pData = (enemyRankParseData *)userData; + + if(pData->currentDepth <= pData->maxReadDepth) + { + if(strcmp(name, "BACKGROUNDS") == 0) + { + pData->curElement = ELEMENT_NONE; + } + else if(strcmp(name, "BACKGROUND") == 0) + { + pData->curElement = ELEMENT_LIST; + + if(pData->curBackground.uiIndex < pData->maxArraySize) + { + pData->curArray[pData->curBackground.uiIndex] = pData->curBackground; + } + + num_found_background = pData->curBackground.uiIndex; + } + else if(strcmp(name, "uiIndex") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.uiIndex = (UINT16) atol(pData->szCharData); + } + else if(strcmp(name, "szName") == 0 ) + { + pData->curElement = ELEMENT; + + MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curBackground.szName, sizeof(pData->curBackground.szName)/sizeof(pData->curBackground.szName[0]) ); + pData->curBackground.szName[sizeof(pData->curBackground.szName)/sizeof(pData->curBackground.szName[0]) - 1] = '\0'; + } + else if(strcmp(name, "szShortName") == 0 ) + { + pData->curElement = ELEMENT; + + MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curBackground.szShortName, sizeof(pData->curBackground.szShortName)/sizeof(pData->curBackground.szShortName[0]) ); + pData->curBackground.szShortName[sizeof(pData->curBackground.szShortName)/sizeof(pData->curBackground.szShortName[0]) - 1] = '\0'; + } + else if(strcmp(name, "szDescription") == 0 ) + { + pData->curElement = ELEMENT; + + MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curBackground.szDescription, sizeof(pData->curBackground.szDescription)/sizeof(pData->curBackground.szDescription[0]) ); + pData->curBackground.szDescription[sizeof(pData->curBackground.szDescription)/sizeof(pData->curBackground.szDescription[0]) - 1] = '\0'; + } + else if(strcmp(name, "ap_polar") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_POLAR] = min(XML_BACKGROUND_AP_MAX, max(-XML_BACKGROUND_AP_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "ap_desert") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_DESERT] = min(XML_BACKGROUND_AP_MAX, max(-XML_BACKGROUND_AP_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "ap_swamp") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_SWAMP] = min(XML_BACKGROUND_AP_MAX, max(-XML_BACKGROUND_AP_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "ap_urban") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_URBAN] = min(XML_BACKGROUND_AP_MAX, max(-XML_BACKGROUND_AP_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "ap_river") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_RIVER] = min(XML_BACKGROUND_AP_MAX, max(-XML_BACKGROUND_AP_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "ap_coastal") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_COASTAL] = min(XML_BACKGROUND_AP_MAX, max(-XML_BACKGROUND_AP_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "ap_tropical") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_TROPICAL] = min(XML_BACKGROUND_AP_MAX, max(-XML_BACKGROUND_AP_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "ap_mountain") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_MOUNTAIN] = min(XML_BACKGROUND_AP_MAX, max(-XML_BACKGROUND_AP_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "ap_height") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_HEIGHT] = min(XML_BACKGROUND_AP_MAX, max(-XML_BACKGROUND_AP_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "ap_swimming") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_SWIMMING] = min(40, max(-40, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "ap_fortify") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_FORTIFY] = min(40, max(-40, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "ap_artillery") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_ARTILLERY] = min(40, max(-40, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "ap_inventory") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_INVENTORY] = min(40, max(-40, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "ap_airdrop") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_AIRDROP] = min(40, max(-40, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "ap_assault") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_ASSAULT] = min(10, max(-10, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "agility") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_AGILITY] = min(XML_BACKGROUND_STAT_MAX, max(-XML_BACKGROUND_STAT_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "strength") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_STRENGTH] = min(XML_BACKGROUND_STAT_MAX, max(-XML_BACKGROUND_STAT_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "dexterity") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_DEXTERITY] = min(XML_BACKGROUND_STAT_MAX, max(-XML_BACKGROUND_STAT_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "mechanical") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_MECHANICAL] = min(XML_BACKGROUND_STAT_MAX, max(-XML_BACKGROUND_STAT_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "medical") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_MEDICAL] = min(XML_BACKGROUND_STAT_MAX, max(-XML_BACKGROUND_STAT_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "explosives") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_EXPLOSIVE_ASSIGN] = min(XML_BACKGROUND_STAT_MAX, max(-XML_BACKGROUND_STAT_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "leadership") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_LEADERSHIP] = min(XML_BACKGROUND_STAT_MAX, max(-XML_BACKGROUND_STAT_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "marksmanship") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_MARKSMANSHIP] = min(XML_BACKGROUND_STAT_MAX, max(-XML_BACKGROUND_STAT_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "travel_foot") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_TRAVEL_FOOT] = min(XML_BACKGROUND_TRAVEL_MAX, max(-XML_BACKGROUND_TRAVEL_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "travel_car") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_TRAVEL_CAR] = min(XML_BACKGROUND_TRAVEL_MAX, max(-XML_BACKGROUND_TRAVEL_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "travel_air") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_TRAVEL_AIR] = min(XML_BACKGROUND_TRAVEL_MAX, max(-XML_BACKGROUND_TRAVEL_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "travel_boat") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_TRAVEL_BOAT] = min(XML_BACKGROUND_TRAVEL_MAX, max(-XML_BACKGROUND_TRAVEL_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "resistance_poison") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_RESI_POISON] = min(XML_BACKGROUND_RESI_MAX, max(-XML_BACKGROUND_RESI_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "resistance_fear") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_RESI_FEAR] = min(XML_BACKGROUND_RESI_MAX, max(-XML_BACKGROUND_RESI_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "resistance_suppression") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_RESI_SUPPRESSION] = min(XML_BACKGROUND_RESI_MAX, max(-XML_BACKGROUND_RESI_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "resistance_physical") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_RESI_PHYSICAL] = min(XML_BACKGROUND_RESI_MAX, max(-XML_BACKGROUND_RESI_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "resistance_alcohol") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_RESI_ALCOHOL] = min(XML_BACKGROUND_RESI_MAX, max(-XML_BACKGROUND_RESI_MAX, (INT8) atol(pData->szCharData) )); + } + else if(strcmp(name, "interrogation") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_INTERROGATION] = min(XML_VARIOUS_MAX, max(-50, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "prisonguard") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_GUARD] = min(XML_VARIOUS_MAX, max(-50, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "betterprices_guns") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_PRICES_GUNS] = min(20, max(-20, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "betterprices") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_PRICES] = min(20, max(-20, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "capitulation") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_CAPITULATION] = min(100, max(-50, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "speed_run") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_SPEED_RUNNING] = min(50, max(-50, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "speed_bandaging") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_BANDAGING] = min(50, max(-50, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "drink_energyregen") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_REGEN_ENERGY] = min(XML_VARIOUS_MAX, max(-80, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "carrystrength") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_CARRYSTRENGTH] = min(50, max(-50, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "food") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_FOOD] = min(100, max(-50, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "water") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_WATER] = min(100, max(-50, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "sleep") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_SLEEP] = min(2, max(-2, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "meleedamage") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_DAMAGE_MELEE] = min(10, max(-10, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "cth_blades") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_CTH_BLADE] = min(10, max(-10, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "camo") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_CAMO] = min(20, max(-20, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "stealth") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_STEALTH] = min(20, max(-20, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "increased_maxcth") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_CTH_MAX] = min(5, max(-5, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "hearing_night") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_HEARING_NIGHT] = min(10, max(-10, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "hearing_day") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_HEARING_DAY] = min(10, max(-10, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "approach_friendly") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_APPROACH_FRIENDLY] = min(50, max(-50, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "approach_direct") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_APPROACH_DIRECT] = min(50, max(-50, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "approach_threaten") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_APPROACH_THREATEN] = min(50, max(-50, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "approach_recruit") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_APPROACH_RECRUIT] = min(50, max(-50, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "breachingcharge") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_BONUS_BREACHINGCHARGE] = min(100, max(-100, (INT16) atol(pData->szCharData) )); + } + else if(strcmp(name, "druguse") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.uiFlags |= (UINT16) atol(pData->szCharData) ? BACKGROUND_DRUGUSE : 0; + } + else if(strcmp(name, "xenophobic") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.uiFlags |= (UINT16) atol(pData->szCharData) ? BACKGROUND_XENOPHOBIC : 0; + } + else if(strcmp(name, "corruptionspread") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.uiFlags |= (UINT16) atol(pData->szCharData) ? BACKGROUND_CORRUPTIONSPREAD : 0; + } + else if(strcmp(name, "level_underground") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.uiFlags |= (UINT16) atol(pData->szCharData) ? BACKGROUND_EXP_UNDERGROUND : 0; + } + else if(strcmp(name, "scrounging") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.uiFlags |= (UINT16) atol(pData->szCharData) ? BACKGROUND_SCROUNGING : 0; + } + else if(strcmp(name, "traplevel") == 0) + { + pData->curElement = ELEMENT; + pData->curBackground.uiFlags |= (UINT16) atol(pData->szCharData) ? BACKGROUND_TRAPLEVEL : 0; + } + + pData->maxReadDepth--; + } + pData->currentDepth--; +} + +BOOLEAN ReadInBackgrounds(STR fileName) +{ + HWFILE hFile; + UINT32 uiBytesRead; + UINT32 uiFSize; + CHAR8 * lpcBuffer; + XML_Parser parser = XML_ParserCreate(NULL); + + enemyRankParseData pData; + + DebugMsg(TOPIC_JA2, DBG_LEVEL_3, "Loading Backgrounds.xml" ); + + // Open file + hFile = FileOpen( fileName, FILE_ACCESS_READ, FALSE ); + if ( !hFile ) + return( FALSE ); + + uiFSize = FileGetSize(hFile); + lpcBuffer = (CHAR8 *) MemAlloc(uiFSize+1); + + //Read in block + if ( !FileRead( hFile, lpcBuffer, uiFSize, &uiBytesRead ) ) + { + MemFree(lpcBuffer); + return( FALSE ); + } + + lpcBuffer[uiFSize] = 0; //add a null terminator + + FileClose( hFile ); + + + XML_SetElementHandler(parser, backgroundStartElementHandle, backgroundEndElementHandle); + XML_SetCharacterDataHandler(parser, backgroundCharacterDataHandle); + + + memset(&pData,0,sizeof(pData)); + pData.curArray = zBackground; + pData.maxArraySize = NUM_BACKGROUND; + + XML_SetUserData(parser, &pData); + + if(!XML_Parse(parser, lpcBuffer, uiFSize, TRUE)) + { + CHAR8 errorBuf[511]; + + sprintf(errorBuf, "XML Parser Error in Backgrounds.xml: %s at line %d", XML_ErrorString(XML_GetErrorCode(parser)), XML_GetCurrentLineNumber(parser)); + LiveMessage(errorBuf); + + MemFree(lpcBuffer); + return FALSE; + } + + MemFree(lpcBuffer); + + + XML_ParserFree(parser); + + + return( TRUE ); +} + + +BOOLEAN WriteBackgrounds( STR fileName) +{ + HWFILE hFile; + + //Debug code; make sure that what we got from the file is the same as what's there + // Open a new file + hFile = FileOpen( fileName, FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE ); + if ( !hFile ) + return( FALSE ); + + { + UINT32 cnt; + + FilePrintf(hFile,"\r\n"); + for(cnt = 0; cnt < NUM_BACKGROUND; ++cnt) + { + FilePrintf(hFile,"\t\r\n"); + FilePrintf(hFile,"\t\t%d\r\n", cnt); + + FilePrintf(hFile,"\t\r\n"); + } + FilePrintf(hFile,"\r\n"); + } + FileClose( hFile ); + + return( TRUE ); +} diff --git a/Tactical/XML_Profiles.cpp b/Tactical/XML_Profiles.cpp index 4f015be96..afca3896d 100644 --- a/Tactical/XML_Profiles.cpp +++ b/Tactical/XML_Profiles.cpp @@ -179,8 +179,9 @@ profileStartElementHandle(void *userData, const XML_Char *name, const XML_Char * strcmp(name, "sSectorZ") == 0 || strcmp(name, "ubCivilianGroup") == 0 || strcmp(name, "bTown") == 0 || - strcmp(name, "bTownAttachment") == 0 - + strcmp(name, "bTownAttachment") == 0 || + strcmp(name, "usBackground") == 0 + )) { pData->curElement = ELEMENT_PROPERTY; @@ -335,6 +336,7 @@ profileEndElementHandle(void *userData, const XML_Char *name) tempProfiles[pData->curIndex].ubCivilianGroup = pData->curProfile.ubCivilianGroup; tempProfiles[pData->curIndex].bTown = pData->curProfile.bTown; tempProfiles[pData->curIndex].bTownAttachment = pData->curProfile.bTownAttachment; + tempProfiles[pData->curIndex].usBackground = pData->curProfile.usBackground; tempProfiles[pData->curIndex].fGoodGuy = pData->curProfile.fGoodGuy; memcpy( &(tempProfiles[pData->curIndex].usApproachFactor), &(pData->curProfile.usApproachFactor), 4 * sizeof (UINT16)); @@ -975,6 +977,11 @@ profileEndElementHandle(void *userData, const XML_Char *name) { pData->curElement = ELEMENT; pData->curProfile.bTownAttachment = (INT8) atol(pData->szCharData); + } + else if(strcmp(name, "usBackground") == 0) + { + pData->curElement = ELEMENT; + pData->curProfile.usBackground = (UINT8) atol(pData->szCharData); } @@ -1540,7 +1547,8 @@ BOOLEAN WriteMercProfiles() FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].ubCivilianGroup); FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bTown); FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].bTownAttachment); - + FilePrintf(hFile,"\t\t%d\r\n", gMercProfiles[ cnt ].usBackground); + FilePrintf(hFile,"\t\r\n"); } diff --git a/Tactical/soldier profile type.h b/Tactical/soldier profile type.h index c910944fb..65cf45cd3 100644 --- a/Tactical/soldier profile type.h +++ b/Tactical/soldier profile type.h @@ -839,6 +839,9 @@ public: // SANDRO - merc records STRUCT_Records records; + // Flugente: background + UINT8 usBackground; + }; // MERCPROFILESTRUCT; // WANNE - BMP: DONE! diff --git a/TacticalAI/Attacks.cpp b/TacticalAI/Attacks.cpp index c6aa16d8d..b91a0e1f7 100644 --- a/TacticalAI/Attacks.cpp +++ b/TacticalAI/Attacks.cpp @@ -2137,6 +2137,9 @@ INT32 EstimateStabDamage( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pOpponent, } } + // Flugente: Add personal damage bonus + iImpact = (iImpact * (100 + pSoldier->GetMeleeDamageBonus() ) / 100); + if (iImpact < 1) { iImpact = 1; diff --git a/TacticalAI/NPC.cpp b/TacticalAI/NPC.cpp index 0865be035..85f0b9b58 100644 --- a/TacticalAI/NPC.cpp +++ b/TacticalAI/NPC.cpp @@ -915,13 +915,38 @@ UINT8 CalcDesireToTalk( UINT8 ubNPC, UINT8 ubMerc, INT8 bApproach ) else if ( bApproach == APPROACH_THREATEN ) { iEffectiveLeadership = CalcThreateningEffectiveness( ubMerc ) * pMercProfile->usApproachFactor[bApproach - 1] / 100; + + // Flugente: backgrounds + SOLDIERTYPE* pSoldier = FindSoldierByProfileID( ubMerc, TRUE ); + + if ( pSoldier ) + { + if ( bApproach == APPROACH_THREATEN ) + iEffectiveLeadership = (iEffectiveLeadership * (100 + pSoldier->GetBackgroundValue(BG_PERC_APPROACH_THREATEN))) / 100; + } + iApproachVal = pNPCProfile->ubApproachVal[bApproach - 1] * iEffectiveLeadership / 50; } else { iEffectiveLeadership = ((INT32) pMercProfile->bLeadership) * pMercProfile->usApproachFactor[bApproach - 1] / 100; + + // Flugente: backgrounds + SOLDIERTYPE* pSoldier = FindSoldierByProfileID( ubMerc, TRUE ); + + if ( pSoldier ) + { + if ( bApproach == APPROACH_FRIENDLY ) + iEffectiveLeadership = (iEffectiveLeadership * (100 + pSoldier->GetBackgroundValue(BG_PERC_APPROACH_FRIENDLY))) / 100; + else if ( bApproach == APPROACH_DIRECT ) + iEffectiveLeadership = (iEffectiveLeadership * (100 + pSoldier->GetBackgroundValue(BG_PERC_APPROACH_DIRECT))) / 100; + else if ( bApproach == APPROACH_RECRUIT ) + iEffectiveLeadership = (iEffectiveLeadership * (100 + pSoldier->GetBackgroundValue(BG_PERC_APPROACH_RECRUIT))) / 100; + } + iApproachVal = pNPCProfile->ubApproachVal[bApproach - 1] * iEffectiveLeadership / 50; } + // NB if town attachment is less than 100% then we should make personal value proportionately more important! if ( pNPCProfile->bTownAttachment < 100 ) { diff --git a/Utils/Animated ProgressBar.cpp b/Utils/Animated ProgressBar.cpp index 489783776..fb485b76f 100644 --- a/Utils/Animated ProgressBar.cpp +++ b/Utils/Animated ProgressBar.cpp @@ -261,7 +261,7 @@ void SetNewLoadScreenHint() else if ( zLoadScreenHint[cnt].usFlags & LOADSCREEN_ZOMBIE && gGameSettings.fOptions[TOPTION_ZOMBIES] ) fShow = TRUE; #endif - else if ( zLoadScreenHint[cnt].usFlags & LOADSCREEN_OVERHEAT_DIRT && (gGameOptions.fWeaponOverheating || gGameExternalOptions.fDirtSystem) ) + else if ( zLoadScreenHint[cnt].usFlags & LOADSCREEN_OVERHEAT_DIRT && (gGameExternalOptions.fWeaponOverheating || gGameExternalOptions.fDirtSystem) ) fShow = TRUE; else if ( zLoadScreenHint[cnt].usFlags & LOADSCREEN_NCTH && UsingNewCTHSystem() ) fShow = TRUE; diff --git a/Utils/Text.h b/Utils/Text.h index 5d63bf003..d83aa05a9 100644 --- a/Utils/Text.h +++ b/Utils/Text.h @@ -1976,7 +1976,7 @@ enum GIO_NCTH_TITLE_TEXT, GIO_IIS_TITLE_TEXT, - GIO_OVERHEATING_TITLE_TEXT, + GIO_BACKGROUND_TITLE_TEXT, GIO_FOODSYSTEM_TITLE_TEXT, GIO_BR_QUANTITY_TEXT, @@ -2378,6 +2378,9 @@ enum }; extern STR16 gszPocketPopupText[]; +// Flugente: backgrounds +extern STR16 szBackgroundText_Flags[]; +extern STR16 szBackgroundText_Value[]; // Enumeration support typedef struct Str8EnumLookupType { diff --git a/Utils/_ChineseText.cpp b/Utils/_ChineseText.cpp index ed50bbe16..f8ef91877 100644 --- a/Utils/_ChineseText.cpp +++ b/Utils/_ChineseText.cpp @@ -7602,4 +7602,82 @@ STR16 szInventoryArmTextStr[]= // TODO.Translate L"解除", //L"Disarm", }; +STR16 szBackgroundText_Flags[]= +{ + L" might consume drugs in inventory\n", + L" disregard for other backgrounds\n", + L" +1 level in underground sectors\n", + L" might steal items\n", + + L" +1 traplevel to planted bombs\n", + L" spreads corruption to nearby mercs\n", +}; + +STR16 szBackgroundText_Value[]= +{ + L" %s%d%% APs in polar sectors\n", + L" %s%d%% APs in desert sectors\n", + L" %s%d%% APs in swamp sectors\n", + L" %s%d%% APs in urban sectors\n", + L" %s%d%% APs in river sectors\n", + L" %s%d%% APs in tropical sectors\n", + L" %s%d%% APs in coastal sectors\n", + L" %s%d%% APs in mountainous sectors\n", + + L" %s%d%% agility stat\n", + L" %s%d%% dexterity stat\n", + L" %s%d%% strength stat\n", + L" %s%d%% leadership stat\n", + L" %s%d%% marksmanship stat\n", + L" %s%d%% mechanical stat\n", + L" %s%d%% explosives stat\n", + L" %s%d%% medical stat\n", + + L" %s%d%% APs on rooftops\n", + L" %s%d%% APs needed to swim\n", + L" %s%d%% APs needed for fortification actions\n", + L" %s%d%% APs needed for mortars\n", + L" %s%d%% APs needed to access inventory\n", + L" looks in other direction on airdrops\n %s%d%% APs after airdrop\n", + L" %s%d%% APs on first turn when assaulting a sector\n", + + L" %s%d%% travel speed on foot\n", + L" %s%d%% travel speed on land vehicles\n", + L" %s%d%% travel speed on air vehicles\n", + L" %s%d%% travel speed on water vehicles\n", + + L" %s%d%% poison resistance\n", + L" %s%d%% fear resistance\n", + L" %s%d%% suppression resistance\n", + L" %s%d%% physical resistance\n", + L" %s%d%% alcohol resistance\n", + + L" %s%d%% interrogation effectiveness\n", + L" %s%d%% prison guard strength\n", + L" %s%d%% better prices when trading guns and ammo\n", + L" %s%d%% better prices when trading armour, lbe, blades, kits etc.\n", + L" %s%d%% team capitulation strength if we lead negotiations\n", + L" %s%d%% faster running\n", + L" %s%d%% bandaging speed\n", + L" drinking restores %s%d%% energy\n", + L" %s%d%% strength to carry items\n", + L" %s%d%% food consumption\n", + L" %s%d%% water consumption\n", + L" %s%d need for sleep\n", + L" %s%d%% melee damage\n", + L" %s%d%% cth with blades\n", + L" %s%d%% camo effectiveness\n", + L" %s%d%% stealth\n", + L" %s%d%% max CTH\n", + L" %s%d hearing range during the night\n", + L" %s%d hearing range during the day\n", + + L" %s%d%% effectiveness to friendly approach\n", + L" %s%d%% effectiveness to direct approach\n", + L" %s%d%% effectiveness to threaten approach\n", + L" %s%d%% effectiveness to recruit approach\n", + + L" %s%d%% chance of success with door breaching charges\n", +}; + #endif //CHINESE diff --git a/Utils/_DutchText.cpp b/Utils/_DutchText.cpp index cc4febc65..e46dc4185 100644 --- a/Utils/_DutchText.cpp +++ b/Utils/_DutchText.cpp @@ -7601,4 +7601,82 @@ STR16 szInventoryArmTextStr[]= // TODO.Translate L"Disarm", }; +STR16 szBackgroundText_Flags[]= +{ + L" might consume drugs in inventory\n", + L" disregard for other backgrounds\n", + L" +1 level in underground sectors\n", + L" might steal items\n", + + L" +1 traplevel to planted bombs\n", + L" spreads corruption to nearby mercs\n", +}; + +STR16 szBackgroundText_Value[]= +{ + L" %s%d%% APs in polar sectors\n", + L" %s%d%% APs in desert sectors\n", + L" %s%d%% APs in swamp sectors\n", + L" %s%d%% APs in urban sectors\n", + L" %s%d%% APs in river sectors\n", + L" %s%d%% APs in tropical sectors\n", + L" %s%d%% APs in coastal sectors\n", + L" %s%d%% APs in mountainous sectors\n", + + L" %s%d%% agility stat\n", + L" %s%d%% dexterity stat\n", + L" %s%d%% strength stat\n", + L" %s%d%% leadership stat\n", + L" %s%d%% marksmanship stat\n", + L" %s%d%% mechanical stat\n", + L" %s%d%% explosives stat\n", + L" %s%d%% medical stat\n", + + L" %s%d%% APs on rooftops\n", + L" %s%d%% APs needed to swim\n", + L" %s%d%% APs needed for fortification actions\n", + L" %s%d%% APs needed for mortars\n", + L" %s%d%% APs needed to access inventory\n", + L" looks in other direction on airdrops\n %s%d%% APs after airdrop\n", + L" %s%d%% APs on first turn when assaulting a sector\n", + + L" %s%d%% travel speed on foot\n", + L" %s%d%% travel speed on land vehicles\n", + L" %s%d%% travel speed on air vehicles\n", + L" %s%d%% travel speed on water vehicles\n", + + L" %s%d%% poison resistance\n", + L" %s%d%% fear resistance\n", + L" %s%d%% suppression resistance\n", + L" %s%d%% physical resistance\n", + L" %s%d%% alcohol resistance\n", + + L" %s%d%% interrogation effectiveness\n", + L" %s%d%% prison guard strength\n", + L" %s%d%% better prices when trading guns and ammo\n", + L" %s%d%% better prices when trading armour, lbe, blades, kits etc.\n", + L" %s%d%% team capitulation strength if we lead negotiations\n", + L" %s%d%% faster running\n", + L" %s%d%% bandaging speed\n", + L" drinking restores %s%d%% energy\n", + L" %s%d%% strength to carry items\n", + L" %s%d%% food consumption\n", + L" %s%d%% water consumption\n", + L" %s%d need for sleep\n", + L" %s%d%% melee damage\n", + L" %s%d%% cth with blades\n", + L" %s%d%% camo effectiveness\n", + L" %s%d%% stealth\n", + L" %s%d%% max CTH\n", + L" %s%d hearing range during the night\n", + L" %s%d hearing range during the day\n", + + L" %s%d%% effectiveness to friendly approach\n", + L" %s%d%% effectiveness to direct approach\n", + L" %s%d%% effectiveness to threaten approach\n", + L" %s%d%% effectiveness to recruit approach\n", + + L" %s%d%% chance of success with door breaching charges\n", +}; + #endif //DUTCH diff --git a/Utils/_EnglishText.cpp b/Utils/_EnglishText.cpp index b5157c444..d9bbae7f8 100644 --- a/Utils/_EnglishText.cpp +++ b/Utils/_EnglishText.cpp @@ -5401,7 +5401,7 @@ STR16 gzGIOScreenText[] = L"New Chance to Hit System", L"Improved Interrupt System", - L"Weapon Overheating", + L"Story Backgrounds", L"Food System", L"Bobby Ray Quantity", }; @@ -7588,4 +7588,82 @@ STR16 szInventoryArmTextStr[]= L"Disarm", }; +STR16 szBackgroundText_Flags[]= +{ + L" might consume drugs in inventory\n", + L" disregard for other backgrounds\n", + L" +1 level in underground sectors\n", + L" might steal items\n", + + L" +1 traplevel to planted bombs\n", + L" spreads corruption to nearby mercs\n", +}; + +STR16 szBackgroundText_Value[]= +{ + L" %s%d%% APs in polar sectors\n", + L" %s%d%% APs in desert sectors\n", + L" %s%d%% APs in swamp sectors\n", + L" %s%d%% APs in urban sectors\n", + L" %s%d%% APs in river sectors\n", + L" %s%d%% APs in tropical sectors\n", + L" %s%d%% APs in coastal sectors\n", + L" %s%d%% APs in mountainous sectors\n", + + L" %s%d%% agility stat\n", + L" %s%d%% dexterity stat\n", + L" %s%d%% strength stat\n", + L" %s%d%% leadership stat\n", + L" %s%d%% marksmanship stat\n", + L" %s%d%% mechanical stat\n", + L" %s%d%% explosives stat\n", + L" %s%d%% medical stat\n", + + L" %s%d%% APs on rooftops\n", + L" %s%d%% APs needed to swim\n", + L" %s%d%% APs needed for fortification actions\n", + L" %s%d%% APs needed for mortars\n", + L" %s%d%% APs needed to access inventory\n", + L" looks in other direction on airdrops\n %s%d%% APs after airdrop\n", + L" %s%d%% APs on first turn when assaulting a sector\n", + + L" %s%d%% travel speed on foot\n", + L" %s%d%% travel speed on land vehicles\n", + L" %s%d%% travel speed on air vehicles\n", + L" %s%d%% travel speed on water vehicles\n", + + L" %s%d%% poison resistance\n", + L" %s%d%% fear resistance\n", + L" %s%d%% suppression resistance\n", + L" %s%d%% physical resistance\n", + L" %s%d%% alcohol resistance\n", + + L" %s%d%% interrogation effectiveness\n", + L" %s%d%% prison guard strength\n", + L" %s%d%% better prices when trading guns and ammo\n", + L" %s%d%% better prices when trading armour, lbe, blades, kits etc.\n", + L" %s%d%% team capitulation strength if we lead negotiations\n", + L" %s%d%% faster running\n", + L" %s%d%% bandaging speed\n", + L" drinking restores %s%d%% energy\n", + L" %s%d%% strength to carry items\n", + L" %s%d%% food consumption\n", + L" %s%d%% water consumption\n", + L" %s%d need for sleep\n", + L" %s%d%% melee damage\n", + L" %s%d%% cth with blades\n", + L" %s%d%% camo effectiveness\n", + L" %s%d%% stealth\n", + L" %s%d%% max CTH\n", + L" %s%d hearing range during the night\n", + L" %s%d hearing range during the day\n", + + L" %s%d%% effectiveness to friendly approach\n", + L" %s%d%% effectiveness to direct approach\n", + L" %s%d%% effectiveness to threaten approach\n", + L" %s%d%% effectiveness to recruit approach\n", + + L" %s%d%% chance of success with door breaching charges\n", +}; + #endif //ENGLISH diff --git a/Utils/_FrenchText.cpp b/Utils/_FrenchText.cpp index f11bf86ed..a9053d1b7 100644 --- a/Utils/_FrenchText.cpp +++ b/Utils/_FrenchText.cpp @@ -7585,4 +7585,82 @@ STR16 szInventoryArmTextStr[]= // TODO.Translate L"Disarm", }; +STR16 szBackgroundText_Flags[]= +{ + L" might consume drugs in inventory\n", + L" disregard for other backgrounds\n", + L" +1 level in underground sectors\n", + L" might steal items\n", + + L" +1 traplevel to planted bombs\n", + L" spreads corruption to nearby mercs\n", +}; + +STR16 szBackgroundText_Value[]= +{ + L" %s%d%% APs in polar sectors\n", + L" %s%d%% APs in desert sectors\n", + L" %s%d%% APs in swamp sectors\n", + L" %s%d%% APs in urban sectors\n", + L" %s%d%% APs in river sectors\n", + L" %s%d%% APs in tropical sectors\n", + L" %s%d%% APs in coastal sectors\n", + L" %s%d%% APs in mountainous sectors\n", + + L" %s%d%% agility stat\n", + L" %s%d%% dexterity stat\n", + L" %s%d%% strength stat\n", + L" %s%d%% leadership stat\n", + L" %s%d%% marksmanship stat\n", + L" %s%d%% mechanical stat\n", + L" %s%d%% explosives stat\n", + L" %s%d%% medical stat\n", + + L" %s%d%% APs on rooftops\n", + L" %s%d%% APs needed to swim\n", + L" %s%d%% APs needed for fortification actions\n", + L" %s%d%% APs needed for mortars\n", + L" %s%d%% APs needed to access inventory\n", + L" looks in other direction on airdrops\n %s%d%% APs after airdrop\n", + L" %s%d%% APs on first turn when assaulting a sector\n", + + L" %s%d%% travel speed on foot\n", + L" %s%d%% travel speed on land vehicles\n", + L" %s%d%% travel speed on air vehicles\n", + L" %s%d%% travel speed on water vehicles\n", + + L" %s%d%% poison resistance\n", + L" %s%d%% fear resistance\n", + L" %s%d%% suppression resistance\n", + L" %s%d%% physical resistance\n", + L" %s%d%% alcohol resistance\n", + + L" %s%d%% interrogation effectiveness\n", + L" %s%d%% prison guard strength\n", + L" %s%d%% better prices when trading guns and ammo\n", + L" %s%d%% better prices when trading armour, lbe, blades, kits etc.\n", + L" %s%d%% team capitulation strength if we lead negotiations\n", + L" %s%d%% faster running\n", + L" %s%d%% bandaging speed\n", + L" drinking restores %s%d%% energy\n", + L" %s%d%% strength to carry items\n", + L" %s%d%% food consumption\n", + L" %s%d%% water consumption\n", + L" %s%d need for sleep\n", + L" %s%d%% melee damage\n", + L" %s%d%% cth with blades\n", + L" %s%d%% camo effectiveness\n", + L" %s%d%% stealth\n", + L" %s%d%% max CTH\n", + L" %s%d hearing range during the night\n", + L" %s%d hearing range during the day\n", + + L" %s%d%% effectiveness to friendly approach\n", + L" %s%d%% effectiveness to direct approach\n", + L" %s%d%% effectiveness to threaten approach\n", + L" %s%d%% effectiveness to recruit approach\n", + + L" %s%d%% chance of success with door breaching charges\n", +}; + #endif //FRENCH diff --git a/Utils/_GermanText.cpp b/Utils/_GermanText.cpp index 4a17170e7..c2e5c29ad 100644 --- a/Utils/_GermanText.cpp +++ b/Utils/_GermanText.cpp @@ -7411,4 +7411,82 @@ STR16 szInventoryArmTextStr[]= // TODO.Translate L"Disarm", }; +STR16 szBackgroundText_Flags[]= +{ + L" might consume drugs in inventory\n", + L" disregard for other backgrounds\n", + L" +1 level in underground sectors\n", + L" might steal items\n", + + L" +1 traplevel to planted bombs\n", + L" spreads corruption to nearby mercs\n", +}; + +STR16 szBackgroundText_Value[]= +{ + L" %s%d%% APs in polar sectors\n", + L" %s%d%% APs in desert sectors\n", + L" %s%d%% APs in swamp sectors\n", + L" %s%d%% APs in urban sectors\n", + L" %s%d%% APs in river sectors\n", + L" %s%d%% APs in tropical sectors\n", + L" %s%d%% APs in coastal sectors\n", + L" %s%d%% APs in mountainous sectors\n", + + L" %s%d%% agility stat\n", + L" %s%d%% dexterity stat\n", + L" %s%d%% strength stat\n", + L" %s%d%% leadership stat\n", + L" %s%d%% marksmanship stat\n", + L" %s%d%% mechanical stat\n", + L" %s%d%% explosives stat\n", + L" %s%d%% medical stat\n", + + L" %s%d%% APs on rooftops\n", + L" %s%d%% APs needed to swim\n", + L" %s%d%% APs needed for fortification actions\n", + L" %s%d%% APs needed for mortars\n", + L" %s%d%% APs needed to access inventory\n", + L" looks in other direction on airdrops\n %s%d%% APs after airdrop\n", + L" %s%d%% APs on first turn when assaulting a sector\n", + + L" %s%d%% travel speed on foot\n", + L" %s%d%% travel speed on land vehicles\n", + L" %s%d%% travel speed on air vehicles\n", + L" %s%d%% travel speed on water vehicles\n", + + L" %s%d%% poison resistance\n", + L" %s%d%% fear resistance\n", + L" %s%d%% suppression resistance\n", + L" %s%d%% physical resistance\n", + L" %s%d%% alcohol resistance\n", + + L" %s%d%% interrogation effectiveness\n", + L" %s%d%% prison guard strength\n", + L" %s%d%% better prices when trading guns and ammo\n", + L" %s%d%% better prices when trading armour, lbe, blades, kits etc.\n", + L" %s%d%% team capitulation strength if we lead negotiations\n", + L" %s%d%% faster running\n", + L" %s%d%% bandaging speed\n", + L" drinking restores %s%d%% energy\n", + L" %s%d%% strength to carry items\n", + L" %s%d%% food consumption\n", + L" %s%d%% water consumption\n", + L" %s%d need for sleep\n", + L" %s%d%% melee damage\n", + L" %s%d%% cth with blades\n", + L" %s%d%% camo effectiveness\n", + L" %s%d%% stealth\n", + L" %s%d%% max CTH\n", + L" %s%d hearing range during the night\n", + L" %s%d hearing range during the day\n", + + L" %s%d%% effectiveness to friendly approach\n", + L" %s%d%% effectiveness to direct approach\n", + L" %s%d%% effectiveness to threaten approach\n", + L" %s%d%% effectiveness to recruit approach\n", + + L" %s%d%% chance of success with door breaching charges\n", +}; + #endif //GERMAN diff --git a/Utils/_ItalianText.cpp b/Utils/_ItalianText.cpp index 1e5fdb87c..901bb46d3 100644 --- a/Utils/_ItalianText.cpp +++ b/Utils/_ItalianText.cpp @@ -7587,4 +7587,82 @@ STR16 szInventoryArmTextStr[]= // TODO.Translate L"Disarm", }; +STR16 szBackgroundText_Flags[]= +{ + L" might consume drugs in inventory\n", + L" disregard for other backgrounds\n", + L" +1 level in underground sectors\n", + L" might steal items\n", + + L" +1 traplevel to planted bombs\n", + L" spreads corruption to nearby mercs\n", +}; + +STR16 szBackgroundText_Value[]= +{ + L" %s%d%% APs in polar sectors\n", + L" %s%d%% APs in desert sectors\n", + L" %s%d%% APs in swamp sectors\n", + L" %s%d%% APs in urban sectors\n", + L" %s%d%% APs in river sectors\n", + L" %s%d%% APs in tropical sectors\n", + L" %s%d%% APs in coastal sectors\n", + L" %s%d%% APs in mountainous sectors\n", + + L" %s%d%% agility stat\n", + L" %s%d%% dexterity stat\n", + L" %s%d%% strength stat\n", + L" %s%d%% leadership stat\n", + L" %s%d%% marksmanship stat\n", + L" %s%d%% mechanical stat\n", + L" %s%d%% explosives stat\n", + L" %s%d%% medical stat\n", + + L" %s%d%% APs on rooftops\n", + L" %s%d%% APs needed to swim\n", + L" %s%d%% APs needed for fortification actions\n", + L" %s%d%% APs needed for mortars\n", + L" %s%d%% APs needed to access inventory\n", + L" looks in other direction on airdrops\n %s%d%% APs after airdrop\n", + L" %s%d%% APs on first turn when assaulting a sector\n", + + L" %s%d%% travel speed on foot\n", + L" %s%d%% travel speed on land vehicles\n", + L" %s%d%% travel speed on air vehicles\n", + L" %s%d%% travel speed on water vehicles\n", + + L" %s%d%% poison resistance\n", + L" %s%d%% fear resistance\n", + L" %s%d%% suppression resistance\n", + L" %s%d%% physical resistance\n", + L" %s%d%% alcohol resistance\n", + + L" %s%d%% interrogation effectiveness\n", + L" %s%d%% prison guard strength\n", + L" %s%d%% better prices when trading guns and ammo\n", + L" %s%d%% better prices when trading armour, lbe, blades, kits etc.\n", + L" %s%d%% team capitulation strength if we lead negotiations\n", + L" %s%d%% faster running\n", + L" %s%d%% bandaging speed\n", + L" drinking restores %s%d%% energy\n", + L" %s%d%% strength to carry items\n", + L" %s%d%% food consumption\n", + L" %s%d%% water consumption\n", + L" %s%d need for sleep\n", + L" %s%d%% melee damage\n", + L" %s%d%% cth with blades\n", + L" %s%d%% camo effectiveness\n", + L" %s%d%% stealth\n", + L" %s%d%% max CTH\n", + L" %s%d hearing range during the night\n", + L" %s%d hearing range during the day\n", + + L" %s%d%% effectiveness to friendly approach\n", + L" %s%d%% effectiveness to direct approach\n", + L" %s%d%% effectiveness to threaten approach\n", + L" %s%d%% effectiveness to recruit approach\n", + + L" %s%d%% chance of success with door breaching charges\n", +}; + #endif //ITALIAN diff --git a/Utils/_PolishText.cpp b/Utils/_PolishText.cpp index db2a8db13..c5d2e5808 100644 --- a/Utils/_PolishText.cpp +++ b/Utils/_PolishText.cpp @@ -7607,4 +7607,82 @@ STR16 szInventoryArmTextStr[]= // TODO.Translate L"Disarm", }; +STR16 szBackgroundText_Flags[]= +{ + L" might consume drugs in inventory\n", + L" disregard for other backgrounds\n", + L" +1 level in underground sectors\n", + L" might steal items\n", + + L" +1 traplevel to planted bombs\n", + L" spreads corruption to nearby mercs\n", +}; + +STR16 szBackgroundText_Value[]= +{ + L" %s%d%% APs in polar sectors\n", + L" %s%d%% APs in desert sectors\n", + L" %s%d%% APs in swamp sectors\n", + L" %s%d%% APs in urban sectors\n", + L" %s%d%% APs in river sectors\n", + L" %s%d%% APs in tropical sectors\n", + L" %s%d%% APs in coastal sectors\n", + L" %s%d%% APs in mountainous sectors\n", + + L" %s%d%% agility stat\n", + L" %s%d%% dexterity stat\n", + L" %s%d%% strength stat\n", + L" %s%d%% leadership stat\n", + L" %s%d%% marksmanship stat\n", + L" %s%d%% mechanical stat\n", + L" %s%d%% explosives stat\n", + L" %s%d%% medical stat\n", + + L" %s%d%% APs on rooftops\n", + L" %s%d%% APs needed to swim\n", + L" %s%d%% APs needed for fortification actions\n", + L" %s%d%% APs needed for mortars\n", + L" %s%d%% APs needed to access inventory\n", + L" looks in other direction on airdrops\n %s%d%% APs after airdrop\n", + L" %s%d%% APs on first turn when assaulting a sector\n", + + L" %s%d%% travel speed on foot\n", + L" %s%d%% travel speed on land vehicles\n", + L" %s%d%% travel speed on air vehicles\n", + L" %s%d%% travel speed on water vehicles\n", + + L" %s%d%% poison resistance\n", + L" %s%d%% fear resistance\n", + L" %s%d%% suppression resistance\n", + L" %s%d%% physical resistance\n", + L" %s%d%% alcohol resistance\n", + + L" %s%d%% interrogation effectiveness\n", + L" %s%d%% prison guard strength\n", + L" %s%d%% better prices when trading guns and ammo\n", + L" %s%d%% better prices when trading armour, lbe, blades, kits etc.\n", + L" %s%d%% team capitulation strength if we lead negotiations\n", + L" %s%d%% faster running\n", + L" %s%d%% bandaging speed\n", + L" drinking restores %s%d%% energy\n", + L" %s%d%% strength to carry items\n", + L" %s%d%% food consumption\n", + L" %s%d%% water consumption\n", + L" %s%d need for sleep\n", + L" %s%d%% melee damage\n", + L" %s%d%% cth with blades\n", + L" %s%d%% camo effectiveness\n", + L" %s%d%% stealth\n", + L" %s%d%% max CTH\n", + L" %s%d hearing range during the night\n", + L" %s%d hearing range during the day\n", + + L" %s%d%% effectiveness to friendly approach\n", + L" %s%d%% effectiveness to direct approach\n", + L" %s%d%% effectiveness to threaten approach\n", + L" %s%d%% effectiveness to recruit approach\n", + + L" %s%d%% chance of success with door breaching charges\n", +}; + #endif //POLISH diff --git a/Utils/_RussianText.cpp b/Utils/_RussianText.cpp index e4ee1b250..79ccba0f4 100644 --- a/Utils/_RussianText.cpp +++ b/Utils/_RussianText.cpp @@ -7587,4 +7587,82 @@ STR16 szInventoryArmTextStr[]= // TODO.Translate L"Disarm", }; +STR16 szBackgroundText_Flags[]= +{ + L" might consume drugs in inventory\n", + L" disregard for other backgrounds\n", + L" +1 level in underground sectors\n", + L" might steal items\n", + + L" +1 traplevel to planted bombs\n", + L" spreads corruption to nearby mercs\n", +}; + +STR16 szBackgroundText_Value[]= +{ + L" %s%d%% APs in polar sectors\n", + L" %s%d%% APs in desert sectors\n", + L" %s%d%% APs in swamp sectors\n", + L" %s%d%% APs in urban sectors\n", + L" %s%d%% APs in river sectors\n", + L" %s%d%% APs in tropical sectors\n", + L" %s%d%% APs in coastal sectors\n", + L" %s%d%% APs in mountainous sectors\n", + + L" %s%d%% agility stat\n", + L" %s%d%% dexterity stat\n", + L" %s%d%% strength stat\n", + L" %s%d%% leadership stat\n", + L" %s%d%% marksmanship stat\n", + L" %s%d%% mechanical stat\n", + L" %s%d%% explosives stat\n", + L" %s%d%% medical stat\n", + + L" %s%d%% APs on rooftops\n", + L" %s%d%% APs needed to swim\n", + L" %s%d%% APs needed for fortification actions\n", + L" %s%d%% APs needed for mortars\n", + L" %s%d%% APs needed to access inventory\n", + L" looks in other direction on airdrops\n %s%d%% APs after airdrop\n", + L" %s%d%% APs on first turn when assaulting a sector\n", + + L" %s%d%% travel speed on foot\n", + L" %s%d%% travel speed on land vehicles\n", + L" %s%d%% travel speed on air vehicles\n", + L" %s%d%% travel speed on water vehicles\n", + + L" %s%d%% poison resistance\n", + L" %s%d%% fear resistance\n", + L" %s%d%% suppression resistance\n", + L" %s%d%% physical resistance\n", + L" %s%d%% alcohol resistance\n", + + L" %s%d%% interrogation effectiveness\n", + L" %s%d%% prison guard strength\n", + L" %s%d%% better prices when trading guns and ammo\n", + L" %s%d%% better prices when trading armour, lbe, blades, kits etc.\n", + L" %s%d%% team capitulation strength if we lead negotiations\n", + L" %s%d%% faster running\n", + L" %s%d%% bandaging speed\n", + L" drinking restores %s%d%% energy\n", + L" %s%d%% strength to carry items\n", + L" %s%d%% food consumption\n", + L" %s%d%% water consumption\n", + L" %s%d need for sleep\n", + L" %s%d%% melee damage\n", + L" %s%d%% cth with blades\n", + L" %s%d%% camo effectiveness\n", + L" %s%d%% stealth\n", + L" %s%d%% max CTH\n", + L" %s%d hearing range during the night\n", + L" %s%d hearing range during the day\n", + + L" %s%d%% effectiveness to friendly approach\n", + L" %s%d%% effectiveness to direct approach\n", + L" %s%d%% effectiveness to threaten approach\n", + L" %s%d%% effectiveness to recruit approach\n", + + L" %s%d%% chance of success with door breaching charges\n", +}; + #endif //RUSSIAN diff --git a/Utils/_TaiwaneseText.cpp b/Utils/_TaiwaneseText.cpp index 2bf88801c..c8a5813c8 100644 --- a/Utils/_TaiwaneseText.cpp +++ b/Utils/_TaiwaneseText.cpp @@ -7605,4 +7605,82 @@ STR16 szInventoryArmTextStr[]= // TODO.Translate L"Disarm", }; +STR16 szBackgroundText_Flags[]= +{ + L" might consume drugs in inventory\n", + L" disregard for other backgrounds\n", + L" +1 level in underground sectors\n", + L" might steal items\n", + + L" +1 traplevel to planted bombs\n", + L" spreads corruption to nearby mercs\n", +}; + +STR16 szBackgroundText_Value[]= +{ + L" %s%d%% APs in polar sectors\n", + L" %s%d%% APs in desert sectors\n", + L" %s%d%% APs in swamp sectors\n", + L" %s%d%% APs in urban sectors\n", + L" %s%d%% APs in river sectors\n", + L" %s%d%% APs in tropical sectors\n", + L" %s%d%% APs in coastal sectors\n", + L" %s%d%% APs in mountainous sectors\n", + + L" %s%d%% agility stat\n", + L" %s%d%% dexterity stat\n", + L" %s%d%% strength stat\n", + L" %s%d%% leadership stat\n", + L" %s%d%% marksmanship stat\n", + L" %s%d%% mechanical stat\n", + L" %s%d%% explosives stat\n", + L" %s%d%% medical stat\n", + + L" %s%d%% APs on rooftops\n", + L" %s%d%% APs needed to swim\n", + L" %s%d%% APs needed for fortification actions\n", + L" %s%d%% APs needed for mortars\n", + L" %s%d%% APs needed to access inventory\n", + L" looks in other direction on airdrops\n %s%d%% APs after airdrop\n", + L" %s%d%% APs on first turn when assaulting a sector\n", + + L" %s%d%% travel speed on foot\n", + L" %s%d%% travel speed on land vehicles\n", + L" %s%d%% travel speed on air vehicles\n", + L" %s%d%% travel speed on water vehicles\n", + + L" %s%d%% poison resistance\n", + L" %s%d%% fear resistance\n", + L" %s%d%% suppression resistance\n", + L" %s%d%% physical resistance\n", + L" %s%d%% alcohol resistance\n", + + L" %s%d%% interrogation effectiveness\n", + L" %s%d%% prison guard strength\n", + L" %s%d%% better prices when trading guns and ammo\n", + L" %s%d%% better prices when trading armour, lbe, blades, kits etc.\n", + L" %s%d%% team capitulation strength if we lead negotiations\n", + L" %s%d%% faster running\n", + L" %s%d%% bandaging speed\n", + L" drinking restores %s%d%% energy\n", + L" %s%d%% strength to carry items\n", + L" %s%d%% food consumption\n", + L" %s%d%% water consumption\n", + L" %s%d need for sleep\n", + L" %s%d%% melee damage\n", + L" %s%d%% cth with blades\n", + L" %s%d%% camo effectiveness\n", + L" %s%d%% stealth\n", + L" %s%d%% max CTH\n", + L" %s%d hearing range during the night\n", + L" %s%d hearing range during the day\n", + + L" %s%d%% effectiveness to friendly approach\n", + L" %s%d%% effectiveness to direct approach\n", + L" %s%d%% effectiveness to threaten approach\n", + L" %s%d%% effectiveness to recruit approach\n", + + L" %s%d%% chance of success with door breaching charges\n", +}; + #endif //TAIWANESE