From 36e9d15edc2a3154f3650fdc40f1482c2c871c2c Mon Sep 17 00:00:00 2001 From: Flugente Date: Sun, 10 Aug 2014 13:45:11 +0000 Subject: [PATCH] =?UTF-8?q?New=20feature:=20Diseaes=20affect=20your=20merc?= =?UTF-8?q?enaries.=20They=20can=20be=20contracted=20in=20var=C3=ADous=20w?= =?UTF-8?q?ays=20and=20have=20varying=20effects.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit For more info, see http://www.ja-galaxy-forum.com/ubbthreads.php/topics/334918#Post334918 Requires GameDir >= r2099. Does not break savegame compatibility. git-svn-id: https://ja2svn.mooo.com/source/ja2/trunk/GameSource/ja2_v1.13/Build@7384 3b4a5df2-a311-0410-b5c6-a8a6f20db521 --- GameSettings.cpp | 13 +- GameSettings.h | 5 + GameVersion.cpp | 18 +- GameVersion.h | 3 +- Init.cpp | 4 + Laptop/CampaignHistoryMain.cpp | 34 +- Laptop/CampaignHistoryMain.h | 25 +- Laptop/CampaignStats.cpp | 2 - Laptop/IMP Background.cpp | 2 +- Laptop/Laptop_VS2005.vcproj | 8 + Laptop/Laptop_VS2008.vcproj | 8 + Laptop/Laptop_VS2010.vcxproj | 2 + Laptop/Laptop_VS2010.vcxproj.filters | 6 + Laptop/Laptop_VS2013.vcxproj | 2 + Laptop/Laptop_VS2013.vcxproj.filters | 6 + Laptop/WHO.cpp | 396 +++++++++++ Laptop/WHO.h | 27 + Laptop/finances.cpp | 4 + Laptop/finances.h | 1 + Laptop/laptop.cpp | 299 ++++---- Laptop/laptop.h | 6 + Laptop/merccompare.cpp | 334 ++++----- Laptop/merccompare.h | 5 - SaveLoadGame.cpp | 51 +- Strategic/Assignments.cpp | 827 ++++++++++++++++++++-- Strategic/Assignments.h | 17 +- Strategic/Auto Resolve.cpp | 6 + Strategic/Campaign Types.h | 11 +- Strategic/Game Init.cpp | 3 + Strategic/LuaInitNPCs.cpp | 123 ++-- Strategic/Map Screen Interface Border.cpp | 258 +++++-- Strategic/Map Screen Interface Border.h | 12 +- Strategic/Map Screen Interface Map.cpp | 721 ++++++------------- Strategic/Map Screen Interface Map.h | 36 +- Strategic/Map Screen Interface.cpp | 14 +- Strategic/Map Screen Interface.h | 1 + Strategic/MilitiaSquads.cpp | 12 + Strategic/Queen Command.cpp | 83 ++- Strategic/Quests.h | 5 + Strategic/Reinforcement.cpp | 5 +- Strategic/Strategic Merc Handler.cpp | 3 + Strategic/Strategic Mines.cpp | 5 +- Strategic/Strategic Movement.cpp | 149 ++-- Strategic/XML_SectorNames.cpp | 233 +++--- Strategic/mapscreen.cpp | 15 +- Strategic/strategicmap.cpp | 13 +- Tactical/Bullets.h | 21 +- Tactical/Civ Quotes.cpp | 6 +- Tactical/Disease.cpp | 727 +++++++++++++++++++ Tactical/Disease.h | 159 +++++ Tactical/Drugs And Alcohol.cpp | 8 + Tactical/Drugs And Alcohol.h | 4 +- Tactical/DynamicDialogue.cpp | 118 +-- Tactical/DynamicDialogue.h | 20 +- Tactical/Faces.cpp | 32 + Tactical/Food.cpp | 24 +- Tactical/Handle Items.cpp | 9 + Tactical/Interface Enhanced.cpp | 37 + Tactical/Interface Panels.cpp | 20 + Tactical/Interface.cpp | 5 +- Tactical/Interface.h | 5 +- Tactical/Item Types.h | 14 +- Tactical/Items.cpp | 7 +- Tactical/Items.h | 2 + Tactical/LOS.cpp | 26 + Tactical/Morale.cpp | 6 + Tactical/Overhead.cpp | 8 +- Tactical/SkillCheck.cpp | 43 +- Tactical/Soldier Ani.cpp | 3 + Tactical/Soldier Control.cpp | 335 ++++++++- Tactical/Soldier Control.h | 31 +- Tactical/Soldier Create.cpp | 122 +++- Tactical/Tactical_VS2005.vcproj | 12 + Tactical/Tactical_VS2008.vcproj | 12 + Tactical/Tactical_VS2010.vcxproj | 3 + Tactical/Tactical_VS2010.vcxproj.filters | 9 + Tactical/Tactical_VS2013.vcxproj | 3 + Tactical/Tactical_VS2013.vcxproj.filters | 9 + Tactical/Weapons.cpp | 16 +- Tactical/XML.h | 5 + Tactical/XML_Background.cpp | 20 +- Tactical/XML_Disease.cpp | 479 +++++++++++++ Tactical/XML_Drugs.cpp | 10 +- TacticalAI/AIMain.cpp | 10 +- TacticalAI/DecideAction.cpp | 8 - TileEngine/Explosion Control.cpp | 4 - Utils/Text.h | 56 +- Utils/XML_Items.cpp | 27 +- Utils/_ChineseText.cpp | 105 ++- Utils/_DutchText.cpp | 105 ++- Utils/_EnglishText.cpp | 117 ++- Utils/_FrenchText.cpp | 105 ++- Utils/_GermanText.cpp | 105 ++- Utils/_ItalianText.cpp | 105 ++- Utils/_PolishText.cpp | 105 ++- Utils/_RussianText.cpp | 107 ++- 96 files changed, 5569 insertions(+), 1573 deletions(-) create mode 100644 Laptop/WHO.cpp create mode 100644 Laptop/WHO.h create mode 100644 Tactical/Disease.cpp create mode 100644 Tactical/Disease.h create mode 100644 Tactical/XML_Disease.cpp diff --git a/GameSettings.cpp b/GameSettings.cpp index db6992f4..4ca19753 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -1689,7 +1689,11 @@ void LoadGameExternalOptions() gGameExternalOptions.sFoodDecayModificator = iniReader.ReadFloat("Tactical Food Settings", "FOOD_DECAY_MODIFICATOR", 1.0f, 0.1f, 10.0f); gGameExternalOptions.usFoodMaxPoisoning = iniReader.ReadInteger("Tactical Food Settings", "FOOD_MAX_POISONING", 5, 0, 100); gGameExternalOptions.fFoodEatingSounds = iniReader.ReadBoolean("Tactical Food Settings", "FOOD_EATING_SOUNDS", TRUE); - + + //################# Disease Settings ################## + gGameExternalOptions.fDisease = iniReader.ReadBoolean( "Disease Settings", "DISEASE", FALSE ); + gGameExternalOptions.fDiseaseStrategic = iniReader.ReadBoolean( "Disease Settings", "DISEASE_STRATEGIC", FALSE ); + gGameExternalOptions.sDiseaseWHOSubscriptionCost = iniReader.ReadInteger( "Disease Settings", "DISEASE_WHO_SUBSCRIPTIONCOST", 2000, 1000, 10000 ); //################# Strategic Gamestart Settings ################## @@ -3310,6 +3314,11 @@ void LoadCTHConstants() gGameCTHConstants.SCOPE_EFFECTIVENESS_MINIMUM_RANGER = iniReader.ReadInteger("General", "SCOPE_EFFECTIVENESS_MINIMUM_RANGER", 80, 0, 100); gGameCTHConstants.SCOPE_EFFECTIVENESS_MINIMUM_MARKSMAN = iniReader.ReadInteger("General", "SCOPE_EFFECTIVENESS_MINIMUM_MARKSMAN", 90, 0, 100); gGameCTHConstants.SCOPE_EFFECTIVENESS_MINIMUM_SNIPER = iniReader.ReadInteger("General", "SCOPE_EFFECTIVENESS_MINIMUM_SNIPER", 100, 0, 100); + gGameCTHConstants.SCOPE_EFFECTIVENESS_MULTIPLIER = iniReader.ReadFloat("General", "SCOPE_EFFECTIVENESS_MULTIPLIER", 1.1f, 0.5f, 1.5f); + gGameCTHConstants.SCOPE_EFFECTIVENESS_MINIMUM = iniReader.ReadInteger("General", "SCOPE_EFFECTIVENESS_MINIMUM", 50, 0, 100); + gGameCTHConstants.SCOPE_EFFECTIVENESS_MINIMUM_RANGER = iniReader.ReadInteger("General", "SCOPE_EFFECTIVENESS_MINIMUM_RANGER", 80, 0, 100); + gGameCTHConstants.SCOPE_EFFECTIVENESS_MINIMUM_MARKSMAN = iniReader.ReadInteger("General", "SCOPE_EFFECTIVENESS_MINIMUM_MARKSMAN", 90, 0, 100); + gGameCTHConstants.SCOPE_EFFECTIVENESS_MINIMUM_SNIPER = iniReader.ReadInteger("General", "SCOPE_EFFECTIVENESS_MINIMUM_SNIPER", 100, 0, 100); gGameCTHConstants.SIDE_FACING_DIVISOR = iniReader.ReadFloat("General", "SIDE_FACING_DIVISOR", 2.0, 1.0f, 10.0f); // HEADROCK HAM 5: Basic chance to lose condition point when firing gGameCTHConstants.BASIC_RELIABILITY_ODDS = iniReader.ReadInteger("General", "BASIC_RELIABILITY_ODDS", 15, 0, 10000); @@ -3656,6 +3665,8 @@ void LoadMoraleSettings() gDynamicOpinionEvent[OPINIONEVENT_SOLVECONFLICT_REASON_BAD].sOpinionModifier = iniReader.ReadInteger( "Dynamic Opinion Modifiers Settings", "OPINIONEVENT_SOLVECONFLICT_REASON_BAD", -2, -50, 0 ); gDynamicOpinionEvent[OPINIONEVENT_SOLVECONFLICT_AGGRESSIVE_GOOD].sOpinionModifier = iniReader.ReadInteger( "Dynamic Opinion Modifiers Settings", "OPINIONEVENT_SOLVECONFLICT_AGGRESSIVE_GOOD", 3, 0, 50 ); gDynamicOpinionEvent[OPINIONEVENT_SOLVECONFLICT_AGGRESSIVE_BAD].sOpinionModifier = iniReader.ReadInteger( "Dynamic Opinion Modifiers Settings", "OPINIONEVENT_SOLVECONFLICT_AGGRESSIVE_BAD", -3, -50, 0 ); + gDynamicOpinionEvent[OPINIONEVENT_DISEASE_DISGUSTING].sOpinionModifier = iniReader.ReadInteger( "Dynamic Opinion Modifiers Settings", "OPINIONEVENT_DISEASE_DISGUSTING", -3, -50, 0 ); + gDynamicOpinionEvent[OPINIONEVENT_DISEASE_TREATMENT].sOpinionModifier = iniReader.ReadInteger( "Dynamic Opinion Modifiers Settings", "OPINIONEVENT_DISEASE_TREATMENT", 1, 0, 50 ); } void LoadReputationSettings() diff --git a/GameSettings.h b/GameSettings.h index f2b2f523..16fe51c7 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -446,6 +446,11 @@ typedef struct UINT8 usFoodMaxPoisoning; BOOLEAN fFoodEatingSounds; + + // Flugente: disease settings + BOOLEAN fDisease; + BOOLEAN fDiseaseStrategic; + INT32 sDiseaseWHOSubscriptionCost; //Animation settings FLOAT giPlayerTurnSpeedUpFactor; diff --git a/GameVersion.cpp b/GameVersion.cpp index 99563039..cf698a33 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.7327 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Unfinished Business - Map Editor v1.13.7384 (Development Build)" }; #else - CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.7327 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Map Editor v1.13.7384 (Development Build)" }; #endif // ------------------------------ @@ -27,11 +27,11 @@ //DEBUG BUILD VERSION #ifdef JA2UB - CHAR16 zVersionLabel[256] = { L"Debug: Unfinished Business - v1.13.7327 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Debug: Unfinished Business - v1.13.7384 (Development Build)" }; #elif defined (JA113DEMO) - CHAR16 zVersionLabel[256] = { L"Debug: JA2 Demo - v1.13.7327 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Debug: JA2 Demo - v1.13.7384 (Development Build)" }; #else - CHAR16 zVersionLabel[256] = { L"Debug: v1.13.7327 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Debug: v1.13.7384 (Development Build)" }; #endif #elif defined CRIPPLED_VERSION @@ -46,16 +46,16 @@ //RELEASE BUILD VERSION #ifdef JA2UB - CHAR16 zVersionLabel[256] = { L"Release Unfinished Business - v1.13.7327 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Release Unfinished Business - v1.13.7384 (Development Build)" }; #elif defined (JA113DEMO) - CHAR16 zVersionLabel[256] = { L"Release JA2 Demo - v1.13.7327 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Release JA2 Demo - v1.13.7384 (Development Build)" }; #else - CHAR16 zVersionLabel[256] = { L"Release v1.13.7327 (Development Build)" }; + CHAR16 zVersionLabel[256] = { L"Release v1.13.7384 (Development Build)" }; #endif #endif -CHAR8 czVersionNumber[16] = { "Build 14.07.10" }; //YY.MM.DD +CHAR8 czVersionNumber[16] = { "Build 14.08.10" }; //YY.MM.DD CHAR16 zTrackingNumber[16] = { L"Z" }; // SAVE_GAME_VERSION is defined in header, change it there diff --git a/GameVersion.h b/GameVersion.h index 6ac50713..2f471a56 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 DISEASE_SYSTEM 159 // Flugente: mercs can get diseases #define PRISONER_EXPANSION 158 // Flugente: more types of prisoners #define DYNAMIC_DIALOGUE 157 // Flugente: mercs have dynamic dialogue depending on newly formed opinions, an the player can interact with them #define DYNAMIC_OPINIONS 156 // Flugente: mercs can form opinions on other people depending on their behaviour @@ -77,7 +78,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 PRISONER_EXPANSION +#define SAVE_GAME_VERSION DISEASE_SYSTEM //#define RUSSIANGOLD #ifdef __cplusplus diff --git a/Init.cpp b/Init.cpp index c7535a35..55ddd4b6 100644 --- a/Init.cpp +++ b/Init.cpp @@ -365,6 +365,10 @@ BOOLEAN LoadExternalGameplayData(STR directoryName) strcat(fileName, FOODFILENAME); SGP_THROW_IFFALSE(ReadInFoodStats(fileName),FOODFILENAME); + strcpy( fileName, directoryName ); + strcat( fileName, DISEASEFILENAME ); + SGP_THROW_IFFALSE( ReadInDiseaseStats( fileName ), DISEASEFILENAME ); + strcpy(fileName, directoryName); strcat(fileName, MERCHANTSFILENAME); SGP_THROW_IFFALSE(ReadInMerchantStats(fileName),MERCHANTSFILENAME); diff --git a/Laptop/CampaignHistoryMain.cpp b/Laptop/CampaignHistoryMain.cpp index 5ac5ff3e..d8f799cb 100644 --- a/Laptop/CampaignHistoryMain.cpp +++ b/Laptop/CampaignHistoryMain.cpp @@ -22,45 +22,15 @@ #endif -#define CAMPAIGN_HISTORY_BACKGROUND_WIDTH 125 +#define BACKGROUND_WIDTH 125 #define CAMPAIGN_HISTORY_BACKGROUND_HEIGHT 100 #define CAMPAIGN_HISTORY_BIG_TITLE_X 115 + LAPTOP_SCREEN_UL_X #define CAMPAIGN_HISTORY_BIG_TITLE_Y 10 + LAPTOP_SCREEN_WEB_UL_Y -#define CAMPAIGN_HISTORY_RED_BAR_X LAPTOP_SCREEN_UL_X -#define CAMPAIGN_HISTORY_RED_BAR_Y LAPTOP_SCREEN_WEB_UL_Y - -#define CAMPAIGN_HISTORY_TOP_RED_BAR_X LAPTOP_SCREEN_UL_X + 66 -#define CAMPAIGN_HISTORY_TOP_RED_BAR_Y 109 + LAPTOP_SCREEN_WEB_UL_Y -#define CAMPAIGN_HISTORY_TOP_RED_BAR_Y1 31 + LAPTOP_SCREEN_WEB_UL_Y - -#define CAMPAIGN_HISTORY_BOTTOM_RED_BAR_Y 345 + LAPTOP_SCREEN_WEB_UL_Y - -#define CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_X 77 + LAPTOP_SCREEN_UL_X -#define CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_Y 392 + LAPTOP_SCREEN_WEB_UL_Y -#define CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_WIDTH 107 -#define CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_OFFSET 148 -#define CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_X_2 CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_X + CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_OFFSET -#define CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_X_3 CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_X_2 + CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_OFFSET - #define CAMPAIGN_HISTORY_SUBTITLE_X CAMPAIGN_HISTORY_BIG_TITLE_X #define CAMPAIGN_HISTORY_SUBTITLE_Y CAMPAIGN_HISTORY_BIG_TITLE_Y + 20 -#define CAMPAIGN_HISTORY_BULLET_TEXT_1_Y 188 + LAPTOP_SCREEN_WEB_UL_Y -#define CAMPAIGN_HISTORY_BULLET_TEXT_2_Y 215 + LAPTOP_SCREEN_WEB_UL_Y -#define CAMPAIGN_HISTORY_BULLET_TEXT_3_Y 242 + LAPTOP_SCREEN_WEB_UL_Y - -#define CAMPAIGN_HISTORY_BOTTOM_SLOGAN_X CAMPAIGN_HISTORY_SUBTITLE_X -#define CAMPAIGN_HISTORY_BOTTOM_SLOGAN_Y 285 + LAPTOP_SCREEN_WEB_UL_Y -#define CAMPAIGN_HISTORY_BOTTOM_SLOGAN_WIDTH 370 - -#define CAMPAIGN_HISTORY_SMALL_TITLE_X 64 + LAPTOP_SCREEN_UL_X -#define CAMPAIGN_HISTORY_SMALL_TITLE_Y 5 + LAPTOP_SCREEN_WEB_UL_Y - -#define CAMPAIGN_HISTORY_SMALL_TITLE_WIDTH 434 - 170 -#define CAMPAIGN_HISTORY_SMALL_TITLE_HEIGHT 40 - 10 - extern UINT32 guiInsuranceBackGround; extern UINT32 guiInsuranceSmallTitleImage; @@ -203,7 +173,7 @@ void DisplayCampaignHistoryDefaults() UINT16 usPosX = CAMPAIGN_HISTORY_LINK_START_X; UINT16 usPosY = CAMPAIGN_HISTORY_LINK_START_Y; - WebPageTileBackground(4, 4, CAMPAIGN_HISTORY_BACKGROUND_WIDTH, CAMPAIGN_HISTORY_BACKGROUND_HEIGHT, guiInsuranceBackGround); + WebPageTileBackground( 4, 4, BACKGROUND_WIDTH, CAMPAIGN_HISTORY_BACKGROUND_HEIGHT, guiInsuranceBackGround ); //Display the title slogan GetCampaignHistoryText( TEXT_CAMPAIGNHISTORY_NAME_PRESSORGANISATION, sText ); diff --git a/Laptop/CampaignHistoryMain.h b/Laptop/CampaignHistoryMain.h index ee9f7737..dad20d28 100644 --- a/Laptop/CampaignHistoryMain.h +++ b/Laptop/CampaignHistoryMain.h @@ -6,26 +6,13 @@ * @author Flugente (bears-pit.com) */ -//#include "insurance.h" +#define CAMPHIS_FONT_COLOR 2 +#define CAMPHIS_FONT_COLOR_RED FONT_MCOLOR_RED +#define CAMPHIS_FONT_BIG FONT14ARIAL +#define CAMPHIS_FONT_MED FONT12ARIAL +#define CAMPHIS_FONT_SMALL FONT10ARIAL -#define CAMPHIS_FONT_COLOR 2 -#define CAMPHIS_FONT_COLOR_RED FONT_MCOLOR_RED -#define CAMPHIS_FONT_BIG FONT14ARIAL -#define CAMPHIS_FONT_MED FONT12ARIAL -#define CAMPHIS_FONT_SMALL FONT10ARIAL - -#define CAMPHIS_FONT_BTN_COLOR FONT_MCOLOR_WHITE -#define CAMPHIS_FONT_BTN_SHADOW_COLOR 2 - -#define CAMPHIS_FONT_SHADOW FONT_MCOLOR_WHITE - -#define CAMPAIGN_HISTORY_BULLET_TEXT_OFFSET_X 21 - -#define CAMPHIS_INFO_LEFT_ARROW_BUTTON_X 71 + LAPTOP_SCREEN_UL_X -#define CAMPHIS_INFO_LEFT_ARROW_BUTTON_Y 354 + LAPTOP_SCREEN_WEB_UL_Y - -#define CAMPHIS_INFO_RIGHT_ARROW_BUTTON_X 409 + LAPTOP_SCREEN_UL_X -#define CAMPHIS_INFO_RIGHT_ARROW_BUTTON_Y CAMPHIS_INFO_LEFT_ARROW_BUTTON_Y +#define CAMPHIS_FONT_SHADOW FONT_MCOLOR_WHITE #define CAMPAIGN_HISTORY_LINK_START_X LAPTOP_SCREEN_UL_X #define CAMPAIGN_HISTORY_LINK_START_Y LAPTOP_SCREEN_WEB_UL_Y + 5 diff --git a/Laptop/CampaignStats.cpp b/Laptop/CampaignStats.cpp index 668c2518..579a161b 100644 --- a/Laptop/CampaignStats.cpp +++ b/Laptop/CampaignStats.cpp @@ -168,11 +168,9 @@ Incident_Stats::AddStat( SOLDIERTYPE* pSoldier, UINT8 aType ) break; case CREATURE_TEAM: -#ifdef ENABLE_ZOMBIES if ( pSoldier->IsZombie() ) group = CAMPAIGNHISTORY_SD_ZOMBIE; else -#endif group = CAMPAIGNHISTORY_SD_CREATURE; break; diff --git a/Laptop/IMP Background.cpp b/Laptop/IMP Background.cpp index 4d822dc2..1d534caa 100644 --- a/Laptop/IMP Background.cpp +++ b/Laptop/IMP Background.cpp @@ -494,7 +494,7 @@ void AssignBackgroundHelpText( UINT16 ubNumber, MOUSE_REGION* pMouseregion ) for ( UINT8 i = 0; i < BG_MAX; ++i) { - if ( BG_DISLIKEBG == i ) + if ( BG_DISLIKEBG == i && zBackground[ubNumber].value[i] ) { swprintf( atStr, szBackgroundText_Value[i] ); wcscat( apStr, atStr ); diff --git a/Laptop/Laptop_VS2005.vcproj b/Laptop/Laptop_VS2005.vcproj index 365c92fc..da45b9a9 100644 --- a/Laptop/Laptop_VS2005.vcproj +++ b/Laptop/Laptop_VS2005.vcproj @@ -666,6 +666,10 @@ RelativePath=".\Store Inventory.h" > + + + + diff --git a/Laptop/Laptop_VS2008.vcproj b/Laptop/Laptop_VS2008.vcproj index fdc53971..c142804f 100644 --- a/Laptop/Laptop_VS2008.vcproj +++ b/Laptop/Laptop_VS2008.vcproj @@ -658,6 +658,10 @@ RelativePath="Store Inventory.h" > + + + + diff --git a/Laptop/Laptop_VS2010.vcxproj b/Laptop/Laptop_VS2010.vcxproj index 9d583ae6..aa845bb8 100644 --- a/Laptop/Laptop_VS2010.vcxproj +++ b/Laptop/Laptop_VS2010.vcxproj @@ -105,6 +105,7 @@ + @@ -184,6 +185,7 @@ + diff --git a/Laptop/Laptop_VS2010.vcxproj.filters b/Laptop/Laptop_VS2010.vcxproj.filters index d55202ea..086b6fe9 100644 --- a/Laptop/Laptop_VS2010.vcxproj.filters +++ b/Laptop/Laptop_VS2010.vcxproj.filters @@ -213,6 +213,9 @@ Header Files + + Header Files + Header Files @@ -449,6 +452,9 @@ Source Files + + Source Files + Source Files diff --git a/Laptop/Laptop_VS2013.vcxproj b/Laptop/Laptop_VS2013.vcxproj index 27cee785..0f870f41 100644 --- a/Laptop/Laptop_VS2013.vcxproj +++ b/Laptop/Laptop_VS2013.vcxproj @@ -105,6 +105,7 @@ + @@ -184,6 +185,7 @@ + diff --git a/Laptop/Laptop_VS2013.vcxproj.filters b/Laptop/Laptop_VS2013.vcxproj.filters index 40f25a5b..db1ffffb 100644 --- a/Laptop/Laptop_VS2013.vcxproj.filters +++ b/Laptop/Laptop_VS2013.vcxproj.filters @@ -255,6 +255,9 @@ Header Files + + Header Files + @@ -521,5 +524,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/Laptop/WHO.cpp b/Laptop/WHO.cpp new file mode 100644 index 00000000..dbd4630d --- /dev/null +++ b/Laptop/WHO.cpp @@ -0,0 +1,396 @@ +/** +* @file +* @author Flugente (bears-pit.com) +*/ + +#ifdef PRECOMPILEDHEADERS +#include "Laptop All.h" +#else +#include "laptop.h" +#include "insurance.h" +#include "insurance Contract.h" +#include "WCheck.h" +#include "Utilities.h" +#include "WordWrap.h" +#include "Cursors.h" +#include "Line.h" +#include "Insurance Text.h" +#include "Encrypted File.h" +#include "Text.h" +#include "Multi Language Graphic Utils.h" +#include "WHO.h" +#include "random.h" +#include "Interface.h" +#include "Soldier Add.h" +#include "Soldier Profile.h" +#include "DropDown.h" +#include "Overhead.h" +#include "Map Screen Interface.h" +#include "Quests.h" +#include "finances.h" +#include "Game Clock.h" +#endif + + +#define MERCOMP_FONT_COLOR 2 +#define CAMPHIS_FONT_COLOR_RED FONT_MCOLOR_RED +#define CAMPHIS_FONT_BIG FONT14ARIAL +#define CAMPHIS_FONT_MED FONT12ARIAL +#define CAMPHIS_FONT_SMALL FONT10ARIAL + +#define MERCOMP_FONT_SHADOW FONT_MCOLOR_WHITE + +#define CAMPAIGN_HISTORY_LINK_START_X LAPTOP_SCREEN_UL_X +#define CAMPAIGN_HISTORY_LINK_START_Y LAPTOP_SCREEN_WEB_UL_Y + 5 +#define CAMPAIGN_HISTORY_LINK_TEXT_WIDTH 107 +#define CAMPAIGN_HISTORY_LINK_STEP_Y 14 + +#define BACKGROUND_WIDTH 125 +#define CAMPAIGN_HISTORY_BACKGROUND_HEIGHT 100 + +#define CAMPAIGN_HISTORY_BIG_TITLE_X 115 + LAPTOP_SCREEN_UL_X +#define CAMPAIGN_HISTORY_BIG_TITLE_Y 10 + LAPTOP_SCREEN_WEB_UL_Y + +#define CAMPAIGN_HISTORY_SUBTITLE_X CAMPAIGN_HISTORY_BIG_TITLE_X +#define CAMPAIGN_HISTORY_SUBTITLE_Y CAMPAIGN_HISTORY_BIG_TITLE_Y + 20 + +#define NUM_LINKS 3 +#define MCA_START_CONTENT_Y (LAPTOP_SCREEN_WEB_UL_Y + NUM_LINKS * 17) + + +extern UINT32 guiInsuranceBackGround; +extern UINT32 guiInsuranceSmallTitleImage; +extern UINT32 guiInsuranceBigRedLineImage; +extern UINT32 guiMercCompareBulletImage; +extern UINT32 guiMercCompareLogoImage; + +//link to the various pages +MOUSE_REGION gLinkRegion_WHO[NUM_LINKS]; + +void SelectLinkRegionCallBack_WHO( MOUSE_REGION * pRegion, INT32 iReason ) +{ + if ( iReason & MSYS_CALLBACK_REASON_INIT ) + { + } + else if ( iReason & MSYS_CALLBACK_REASON_LBUTTON_UP ) + { + UINT32 uiLink = MSYS_GetRegionUserData( pRegion, 0 ); + + if ( uiLink == 0 ) + guiCurrentLaptopMode = LAPTOP_MODE_WHO_MAIN; + else if ( uiLink == 1 ) + guiCurrentLaptopMode = LAPTOP_MODE_WHO_CONTRACT; + else if ( uiLink == 2 ) + guiCurrentLaptopMode = LAPTOP_MODE_WHO_TIPS; + } + else if ( iReason & MSYS_CALLBACK_REASON_RBUTTON_UP ) + { + } +} + +void InitDefaults_WHO( ) +{ + VOBJECT_DESC VObjectDesc; + + // load the Insurance bullet graphic and add it + VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; + FilenameForBPP( "LAPTOP\\bullet.sti", VObjectDesc.ImageFile ); + CHECKV( AddVideoObject( &VObjectDesc, &guiMercCompareBulletImage ) ); + + // load the Flower Account Box graphic and add it + VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; + FilenameForBPP( "LAPTOP\\BackGroundTile.sti", VObjectDesc.ImageFile ); + CHECKV( AddVideoObject( &VObjectDesc, &guiInsuranceBackGround ) ); + + // load the red bar on the side of the page and add it + VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; + FilenameForBPP( "LAPTOP\\LargeBar.sti", VObjectDesc.ImageFile ); + CHECKV( AddVideoObject( &VObjectDesc, &guiInsuranceBigRedLineImage ) ); + + VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; + FilenameForBPP( "LAPTOP\\PressLogos.sti", VObjectDesc.ImageFile ); + CHECKV( AddVideoObject( &VObjectDesc, &guiMercCompareLogoImage ) ); + + UINT16 usPosX = CAMPAIGN_HISTORY_LINK_START_X; + UINT16 usPosY = CAMPAIGN_HISTORY_LINK_START_Y; + for ( int i = 0; i= LAPTOP_MODE_WWW ) @@ -1896,6 +1921,18 @@ void EnterNewLaptopMode() EnterBobbyRShipments(); break; + case LAPTOP_MODE_WHO_MAIN: + EnterWHOMain( ); + break; + + case LAPTOP_MODE_WHO_CONTRACT: + EnterWHOContract( ); + break; + + case LAPTOP_MODE_WHO_TIPS: + EnterWHOTips( ); + break; + } // first time using webbrowser in this laptop session @@ -2145,6 +2182,18 @@ void HandleLapTopHandles() case LAPTOP_MODE_MERCCOMPARE_MAIN: HandleMercCompareMain(); break; + + case LAPTOP_MODE_WHO_MAIN: + HandleWHOMain( ); + break; + + case LAPTOP_MODE_WHO_CONTRACT: + HandleWHOContract( ); + break; + + case LAPTOP_MODE_WHO_TIPS: + HandleWHOTips( ); + break; } } @@ -2703,6 +2752,18 @@ UINT32 ExitLaptopMode(UINT32 uiMode) case LAPTOP_MODE_MERCCOMPARE_MAIN: ExitMercCompareMain(); break; + + case LAPTOP_MODE_WHO_MAIN: + ExitWHOMain(); + break; + + case LAPTOP_MODE_WHO_CONTRACT: + ExitWHOContract( ); + break; + + case LAPTOP_MODE_WHO_TIPS: + ExitWHOTips( ); + break; } if( ( uiMode != LAPTOP_MODE_NONE )&&( uiMode < LAPTOP_MODE_WWW ) ) @@ -3676,7 +3737,7 @@ void SetBookMark(INT32 iBookId) { while(LaptopSaveInfo.iBookMarkList[iCounter]!=-1) { - // move trhough list until empty + // move through list until empty if( LaptopSaveInfo.iBookMarkList[iCounter]==iBookId) { // found it, return @@ -3957,7 +4018,7 @@ void DeleteBookmarkRegions() while( LaptopSaveInfo.iBookMarkList[iCounter] != -1 ) { MSYS_RemoveRegion(&gBookmarkMouseRegions[iCounter]); - iCounter++; + ++iCounter; } // now one for the cancel @@ -4278,6 +4339,27 @@ if( (gubQuest[ QUEST_FIX_LAPTOP ] != QUESTINPROGRESS) || (gGameUBOptions.LaptopQ } } break; + + case WHO_BOOKMARK: + { + guiCurrentWWWMode = LAPTOP_MODE_WHO_MAIN; + guiCurrentLaptopMode = LAPTOP_MODE_WHO_MAIN; + + // do we have to have a World Wide Wait + if ( LaptopSaveInfo.fVisitedBookmarkAlready[WHO_BOOKMARK] == FALSE ) + { + // reset flag and set load pending flag + LaptopSaveInfo.fVisitedBookmarkAlready[WHO_BOOKMARK] = TRUE; + fLoadPendingFlag = TRUE; + } + else + { + // fast reload + fLoadPendingFlag = TRUE; + fFastLoadFlag = TRUE; + } + } + break; } #ifdef JA2UB @@ -6285,8 +6367,7 @@ BOOLEAN RenderWWWProgramTitleBar( void ) // blit title GetVideoObject(&hHandle, uiTITLEFORWWW); BltVideoObject( FRAME_BUFFER, hHandle, 0,LAPTOP_SCREEN_UL_X, LAPTOP_SCREEN_UL_Y - 2, VO_BLT_SRCTRANSPARENCY,NULL ); - - + // now delete DeleteVideoObjectFromIndex( uiTITLEFORWWW ); @@ -6299,12 +6380,10 @@ BOOLEAN RenderWWWProgramTitleBar( void ) // no page loaded yet, do not handle yet - if( guiCurrentLaptopMode == LAPTOP_MODE_WWW ) { - mprintf(iScreenWidthOffset + 140 , iScreenHeightOffset + 33 ,pWebTitle[0]); + mprintf(iScreenWidthOffset + 140 , iScreenHeightOffset + 33 ,pWebTitle[0]); } - else { iIndex = guiCurrentLaptopMode - LAPTOP_MODE_WWW-1; @@ -6318,10 +6397,7 @@ BOOLEAN RenderWWWProgramTitleBar( void ) swprintf( sString, L"%s - %s", pWebTitle[0], pWebPagesTitles[ iIndex ] ); mprintf(iScreenWidthOffset + 140 ,iScreenHeightOffset + 33 ,sString); } - - - - + BlitTitleBarIcons( ); DisplayProgramBoundingBox( FALSE ); @@ -6333,18 +6409,15 @@ BOOLEAN RenderWWWProgramTitleBar( void ) void HandleDefaultWebpageForLaptop( void ) { - // go to first page in bookmark list if( guiCurrentLaptopMode == LAPTOP_MODE_WWW ) { // if valid entry go there if( LaptopSaveInfo.iBookMarkList[ 0 ] != -1 ) { - GoToWebPage( LaptopSaveInfo.iBookMarkList[ 0 ] ); + GoToWebPage( LaptopSaveInfo.iBookMarkList[ 0 ] ); } } - - return; } @@ -6354,8 +6427,6 @@ void CreateMinimizeRegionsForLaptopProgramIcons( void ) MSYS_DefineRegion( &gLapTopProgramMinIcon,LAPTOP_PROGRAM_ICON_X, LAPTOP_PROGRAM_ICON_Y ,LAPTOP_PROGRAM_ICON_X + LAPTOP_PROGRAM_ICON_WIDTH ,LAPTOP_PROGRAM_ICON_Y + LAPTOP_PROGRAM_ICON_HEIGHT, MSYS_PRIORITY_NORMAL+1, CURSOR_LAPTOP_SCREEN, MSYS_NO_CALLBACK, LaptopProgramIconMinimizeCallback ); - - return; } @@ -6365,8 +6436,6 @@ void DestroyMinimizeRegionsForLaptopProgramIcons( void ) // displayed on the top of the laptop program bar MSYS_RemoveRegion( &gLapTopProgramMinIcon); - - return; } @@ -6375,83 +6444,87 @@ void LaptopProgramIconMinimizeCallback( MOUSE_REGION * pRegion, INT32 iReason ) // callback handler for the minize region that is attatched to the laptop program icon if(iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) { - switch( guiCurrentLaptopMode ) - { - case( LAPTOP_MODE_EMAIL ): - gLaptopProgramStates[ LAPTOP_PROGRAM_MAILER ] = LAPTOP_PROGRAM_MINIMIZED; - InitTitleBarMaximizeGraphics(guiTITLEBARLAPTOP, pLaptopIcons[0], guiTITLEBARICONS, 0 ); - SetCurrentToLastProgramOpened( ); - fMinizingProgram = TRUE; - fInitTitle = TRUE; - break; - case( LAPTOP_MODE_FILES ): - gLaptopProgramStates[ LAPTOP_PROGRAM_FILES ] = LAPTOP_PROGRAM_MINIMIZED; - InitTitleBarMaximizeGraphics(guiTITLEBARLAPTOP, pLaptopIcons[5], guiTITLEBARICONS, 2 ); - SetCurrentToLastProgramOpened( ); - fMinizingProgram = TRUE; - fInitTitle = TRUE; - break; - case( LAPTOP_MODE_FINANCES ): - gLaptopProgramStates[ LAPTOP_PROGRAM_FINANCES ] = LAPTOP_PROGRAM_MINIMIZED; - InitTitleBarMaximizeGraphics(guiTITLEBARLAPTOP, pLaptopIcons[2], guiTITLEBARICONS, 5 ); - SetCurrentToLastProgramOpened( ); - fMinizingProgram = TRUE; - fInitTitle = TRUE; - break; - case( LAPTOP_MODE_HISTORY ): - gLaptopProgramStates[ LAPTOP_PROGRAM_HISTORY ] = LAPTOP_PROGRAM_MINIMIZED; - InitTitleBarMaximizeGraphics(guiTITLEBARLAPTOP, pLaptopIcons[4], guiTITLEBARICONS, 4 ); - SetCurrentToLastProgramOpened( ); - fMinizingProgram = TRUE; - fInitTitle = TRUE; - break; - case( LAPTOP_MODE_PERSONNEL ): - gLaptopProgramStates[ LAPTOP_PROGRAM_PERSONNEL ] = LAPTOP_PROGRAM_MINIMIZED; - InitTitleBarMaximizeGraphics(guiTITLEBARLAPTOP, pLaptopIcons[3], guiTITLEBARICONS, 3 ); - SetCurrentToLastProgramOpened( ); - fMinizingProgram = TRUE; - fInitTitle = TRUE; - break; - case( LAPTOP_MODE_NONE ): - // nothing - break; - default: - gLaptopProgramStates[ LAPTOP_PROGRAM_WEB_BROWSER ] = LAPTOP_PROGRAM_MINIMIZED; - InitTitleBarMaximizeGraphics(guiTITLEBARLAPTOP, pWebTitle[ 0 ], guiTITLEBARICONS, 1 ); - SetCurrentToLastProgramOpened( ); - gfShowBookmarks = FALSE; - fShowBookmarkInfo = FALSE; - fMinizingProgram = TRUE; - fInitTitle = TRUE; - break; - } + switch( guiCurrentLaptopMode ) + { + case( LAPTOP_MODE_EMAIL ): + gLaptopProgramStates[ LAPTOP_PROGRAM_MAILER ] = LAPTOP_PROGRAM_MINIMIZED; + InitTitleBarMaximizeGraphics(guiTITLEBARLAPTOP, pLaptopIcons[0], guiTITLEBARICONS, 0 ); + SetCurrentToLastProgramOpened( ); + fMinizingProgram = TRUE; + fInitTitle = TRUE; + break; + + case( LAPTOP_MODE_FILES ): + gLaptopProgramStates[ LAPTOP_PROGRAM_FILES ] = LAPTOP_PROGRAM_MINIMIZED; + InitTitleBarMaximizeGraphics(guiTITLEBARLAPTOP, pLaptopIcons[5], guiTITLEBARICONS, 2 ); + SetCurrentToLastProgramOpened( ); + fMinizingProgram = TRUE; + fInitTitle = TRUE; + break; + + case( LAPTOP_MODE_FINANCES ): + gLaptopProgramStates[ LAPTOP_PROGRAM_FINANCES ] = LAPTOP_PROGRAM_MINIMIZED; + InitTitleBarMaximizeGraphics(guiTITLEBARLAPTOP, pLaptopIcons[2], guiTITLEBARICONS, 5 ); + SetCurrentToLastProgramOpened( ); + fMinizingProgram = TRUE; + fInitTitle = TRUE; + break; + + case( LAPTOP_MODE_HISTORY ): + gLaptopProgramStates[ LAPTOP_PROGRAM_HISTORY ] = LAPTOP_PROGRAM_MINIMIZED; + InitTitleBarMaximizeGraphics(guiTITLEBARLAPTOP, pLaptopIcons[4], guiTITLEBARICONS, 4 ); + SetCurrentToLastProgramOpened( ); + fMinizingProgram = TRUE; + fInitTitle = TRUE; + break; + + case( LAPTOP_MODE_PERSONNEL ): + gLaptopProgramStates[ LAPTOP_PROGRAM_PERSONNEL ] = LAPTOP_PROGRAM_MINIMIZED; + InitTitleBarMaximizeGraphics(guiTITLEBARLAPTOP, pLaptopIcons[3], guiTITLEBARICONS, 3 ); + SetCurrentToLastProgramOpened( ); + fMinizingProgram = TRUE; + fInitTitle = TRUE; + break; + + case( LAPTOP_MODE_NONE ): + // nothing + break; + + default: + gLaptopProgramStates[ LAPTOP_PROGRAM_WEB_BROWSER ] = LAPTOP_PROGRAM_MINIMIZED; + InitTitleBarMaximizeGraphics(guiTITLEBARLAPTOP, pWebTitle[ 0 ], guiTITLEBARICONS, 1 ); + SetCurrentToLastProgramOpened( ); + gfShowBookmarks = FALSE; + fShowBookmarkInfo = FALSE; + fMinizingProgram = TRUE; + fInitTitle = TRUE; + break; + } } - return; } void DisplayProgramBoundingBox( BOOLEAN fMarkButtons ) { - // the border fot eh program + // the border fot eh program HVOBJECT hHandle; GetVideoObject(&hHandle, guiLaptopBACKGROUND); BltVideoObject(FRAME_BUFFER, hHandle, 1, iScreenWidthOffset + 25, iScreenHeightOffset + 23, VO_BLT_SRCTRANSPARENCY,NULL); -// no laptop mode, no border around the program + // no laptop mode, no border around the program if( guiCurrentLaptopMode != LAPTOP_MODE_NONE ) { - GetVideoObject(&hHandle, guiLaptopBACKGROUND); - BltVideoObject(FRAME_BUFFER, hHandle, 0, iScreenWidthOffset + 108, iScreenHeightOffset + 23, VO_BLT_SRCTRANSPARENCY,NULL); + GetVideoObject(&hHandle, guiLaptopBACKGROUND); + BltVideoObject(FRAME_BUFFER, hHandle, 0, iScreenWidthOffset + 108, iScreenHeightOffset + 23, VO_BLT_SRCTRANSPARENCY,NULL); } if( fMarkButtons || fLoadPendingFlag ) { - MarkButtonsDirty( ); - RenderButtons( ); + MarkButtonsDirty( ); + RenderButtons( ); } - - + PrintDate( ); PrintBalance( ); @@ -6460,8 +6533,6 @@ void DisplayProgramBoundingBox( BOOLEAN fMarkButtons ) // new files or email? DisplayTaskBarIcons( ); - - return; } @@ -6501,7 +6572,6 @@ void NewEmailIconCallback( MOUSE_REGION * pRegion, INT32 iReason ) guiCurrentLaptopMode = LAPTOP_MODE_EMAIL; } } - } @@ -6515,7 +6585,6 @@ void NewFileIconCallback( MOUSE_REGION * pRegion, INT32 iReason ) guiCurrentLaptopMode = LAPTOP_MODE_FILES; } } - } void HandleWWWSubSites( void ) @@ -6551,8 +6620,6 @@ void HandleWWWSubSites( void ) gfWWWaitSubSitesVisitedFlags[ LAPTOP_MODE_AIM_MEMBERS_FACIAL_INDEX - ( LAPTOP_MODE_WWW + 1 ) ] = TRUE; gfWWWaitSubSitesVisitedFlags[ LAPTOP_MODE_AIM_MEMBERS - ( LAPTOP_MODE_WWW + 1 ) ] = TRUE; } - - return; } @@ -6563,8 +6630,6 @@ void UpdateStatusOfDisplayingBookMarks( void ) { gfShowBookmarks = FALSE; } - - return; } @@ -6573,11 +6638,10 @@ void InitalizeSubSitesList( void ) INT32 iCounter = 0; // init all subsites list to not visited - for( iCounter = LAPTOP_MODE_WWW + 1 ; iCounter <= LAPTOP_MODE_SIRTECH; iCounter++ ) + for( iCounter = LAPTOP_MODE_WWW + 1 ; iCounter <= LAPTOP_MODE_SIRTECH; ++iCounter ) { - gfWWWaitSubSitesVisitedFlags[ iCounter - ( LAPTOP_MODE_WWW + 1 ) ] = FALSE; + gfWWWaitSubSitesVisitedFlags[ iCounter - ( LAPTOP_MODE_WWW + 1 ) ] = FALSE; } - return; } @@ -6592,7 +6656,6 @@ void SetSubSiteAsVisted( void ) { gfWWWaitSubSitesVisitedFlags[ guiCurrentLaptopMode - ( LAPTOP_MODE_WWW + 1 ) ] = TRUE; } - } @@ -6735,8 +6798,6 @@ void DisplayWebBookMarkNotify( void ) } SetFontShadow(DEFAULT_SHADOW); - - return; } void HandleWebBookMarkNotifyTimer( void ) @@ -6745,7 +6806,6 @@ void HandleWebBookMarkNotifyTimer( void ) INT32 iDifference = 0; static BOOLEAN fOldShowBookMarkInfo = FALSE; - // check if maxing or mining? if( ( fMaximizingProgram == TRUE ) || ( fMinizingProgram == TRUE ) ) { @@ -6779,7 +6839,6 @@ void HandleWebBookMarkNotifyTimer( void ) return; } - // check if this is the first time in here if( iBaseTime == 0 ) { @@ -6797,8 +6856,6 @@ void HandleWebBookMarkNotifyTimer( void ) iBaseTime = 0; fShowBookmarkInfo = FALSE; } - - return; } @@ -6833,7 +6890,6 @@ void ClearOutTempLaptopFiles( void ) FileClearAttributes( "history.dat" ); FileDelete( "history.dat" ); } - } @@ -6842,7 +6898,6 @@ BOOLEAN SaveLaptopInfoToSavedGame( HWFILE hFile ) UINT32 uiNumBytesWritten=0; UINT32 uiSize; - // Save The laptop information FileWrite( hFile, &LaptopSaveInfo, sizeof( LaptopSaveInfoStruct ), &uiNumBytesWritten ); if( uiNumBytesWritten != sizeof( LaptopSaveInfoStruct ) ) @@ -6864,7 +6919,6 @@ BOOLEAN SaveLaptopInfoToSavedGame( HWFILE hFile ) } } - //If there is any Insurance Payouts in progress if( LaptopSaveInfo.ubNumberLifeInsurancePayoutUsed ) { @@ -6890,7 +6944,6 @@ BOOLEAN LoadLaptopInfoFromSavedGame( HWFILE hFile ) UINT32 uiNumBytesRead=0; UINT32 uiSize; - //if there is memory allocated for the BobbyR orders if( LaptopSaveInfo.usNumberOfBobbyRayOrderItems ) { @@ -6939,8 +6992,7 @@ BOOLEAN LoadLaptopInfoFromSavedGame( HWFILE hFile ) LaptopSaveInfo.usNumberOfBobbyRayOrderItems = 0; LaptopSaveInfo.BobbyRayOrdersOnDeliveryArray = NULL; } - - + //If there is any Insurance Payouts in progress if( LaptopSaveInfo.ubNumberLifeInsurancePayoutUsed ) { @@ -6962,8 +7014,7 @@ BOOLEAN LoadLaptopInfoFromSavedGame( HWFILE hFile ) LaptopSaveInfo.ubNumberLifeInsurancePayouts = 0; LaptopSaveInfo.pLifeInsurancePayouts = NULL; } - - + return( TRUE ); } @@ -6993,8 +7044,8 @@ BOOLEAN IsItRaining() { if( guiEnvWeather & WEATHER_FORECAST_SHOWERS || guiEnvWeather & WEATHER_FORECAST_THUNDERSHOWERS ) return( TRUE ); - else - return( FALSE ); + + return( FALSE ); } @@ -7057,7 +7108,3 @@ void ShouldImpReminderEmailBeSentWhenLaptopBackOnline() } } #endif - - - - diff --git a/Laptop/laptop.h b/Laptop/laptop.h index cdf8a716..9934297d 100644 --- a/Laptop/laptop.h +++ b/Laptop/laptop.h @@ -150,6 +150,11 @@ enum LAPTOP_MODE_MERCCOMPARE_MATRIX, LAPTOP_MODE_MERCCOMPARE_ANALYZE, LAPTOP_MODE_MERCCOMPARE_CUSTOMERS, + + // Flugente: World Health Organization + LAPTOP_MODE_WHO_MAIN, + LAPTOP_MODE_WHO_CONTRACT, + LAPTOP_MODE_WHO_TIPS, LAPTOP_MODE_BOBBYR_SHIPMENTS, @@ -226,6 +231,7 @@ enum{ BRIEFING_ROOM_BOOKMARK, CAMPAIGNHISTORY_BOOKMARK, // added by Flugente MERCCOMPARE_BOOKMARK, // added by Flugente + WHO_BOOKMARK, // added by Flugente TEXT_NUM_LAPTOP_BOOKMARKS }; diff --git a/Laptop/merccompare.cpp b/Laptop/merccompare.cpp index b2111c9c..693afd70 100644 --- a/Laptop/merccompare.cpp +++ b/Laptop/merccompare.cpp @@ -30,65 +30,30 @@ #endif -#define MERCOMP_FONT_COLOR 2 -#define CAMPHIS_FONT_COLOR_RED FONT_MCOLOR_RED -#define CAMPHIS_FONT_BIG FONT14ARIAL -#define CAMPHIS_FONT_MED FONT12ARIAL -#define CAMPHIS_FONT_SMALL FONT10ARIAL +#define MERCOMP_FONT_COLOR 2 +#define CAMPHIS_FONT_COLOR_RED FONT_MCOLOR_RED +#define CAMPHIS_FONT_BIG FONT14ARIAL +#define CAMPHIS_FONT_MED FONT12ARIAL +#define CAMPHIS_FONT_SMALL FONT10ARIAL -#define CAMPHIS_FONT_BTN_COLOR FONT_MCOLOR_WHITE -#define CAMPHIS_FONT_BTN_SHADOW_COLOR 2 - -#define MERCOMP_FONT_SHADOW FONT_MCOLOR_WHITE - -#define CAMPAIGN_HISTORY_BULLET_TEXT_OFFSET_X 21 +#define MERCOMP_FONT_SHADOW FONT_MCOLOR_WHITE #define CAMPAIGN_HISTORY_LINK_START_X LAPTOP_SCREEN_UL_X #define CAMPAIGN_HISTORY_LINK_START_Y LAPTOP_SCREEN_WEB_UL_Y + 5 #define CAMPAIGN_HISTORY_LINK_TEXT_WIDTH 107 #define CAMPAIGN_HISTORY_LINK_STEP_Y 14 -#define CAMPAIGN_HISTORY_BACKGROUND_WIDTH 125 -#define CAMPAIGN_HISTORY_BACKGROUND_HEIGHT 100 +#define BACKGROUND_WIDTH 125 +#define CAMPAIGN_HISTORY_BACKGROUND_HEIGHT 100 -#define CAMPAIGN_HISTORY_BIG_TITLE_X 115 + LAPTOP_SCREEN_UL_X -#define CAMPAIGN_HISTORY_BIG_TITLE_Y 10 + LAPTOP_SCREEN_WEB_UL_Y +#define CAMPAIGN_HISTORY_BIG_TITLE_X 115 + LAPTOP_SCREEN_UL_X +#define CAMPAIGN_HISTORY_BIG_TITLE_Y 10 + LAPTOP_SCREEN_WEB_UL_Y -#define CAMPAIGN_HISTORY_RED_BAR_X LAPTOP_SCREEN_UL_X -#define CAMPAIGN_HISTORY_RED_BAR_Y LAPTOP_SCREEN_WEB_UL_Y +#define CAMPAIGN_HISTORY_SUBTITLE_X CAMPAIGN_HISTORY_BIG_TITLE_X +#define CAMPAIGN_HISTORY_SUBTITLE_Y CAMPAIGN_HISTORY_BIG_TITLE_Y + 20 -#define CAMPAIGN_HISTORY_TOP_RED_BAR_X LAPTOP_SCREEN_UL_X + 66 -#define CAMPAIGN_HISTORY_TOP_RED_BAR_Y 109 + LAPTOP_SCREEN_WEB_UL_Y -#define CAMPAIGN_HISTORY_TOP_RED_BAR_Y1 31 + LAPTOP_SCREEN_WEB_UL_Y - -#define CAMPAIGN_HISTORY_BOTTOM_RED_BAR_Y 345 + LAPTOP_SCREEN_WEB_UL_Y - -#define CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_X 77 + LAPTOP_SCREEN_UL_X -#define CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_Y 392 + LAPTOP_SCREEN_WEB_UL_Y -#define CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_WIDTH 107 -#define CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_OFFSET 148 -#define CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_X_2 CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_X + CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_OFFSET -#define CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_X_3 CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_X_2 + CAMPAIGN_HISTORY_BOTTOM_LINK_RED_BAR_OFFSET - -#define CAMPAIGN_HISTORY_SUBTITLE_X CAMPAIGN_HISTORY_BIG_TITLE_X -#define CAMPAIGN_HISTORY_SUBTITLE_Y CAMPAIGN_HISTORY_BIG_TITLE_Y + 20 - -#define CAMPAIGN_HISTORY_BULLET_TEXT_1_Y 188 + LAPTOP_SCREEN_WEB_UL_Y -#define CAMPAIGN_HISTORY_BULLET_TEXT_2_Y 215 + LAPTOP_SCREEN_WEB_UL_Y -#define CAMPAIGN_HISTORY_BULLET_TEXT_3_Y 242 + LAPTOP_SCREEN_WEB_UL_Y - -#define CAMPAIGN_HISTORY_BOTTOM_SLOGAN_X CAMPAIGN_HISTORY_SUBTITLE_X -#define CAMPAIGN_HISTORY_BOTTOM_SLOGAN_Y 285 + LAPTOP_SCREEN_WEB_UL_Y -#define CAMPAIGN_HISTORY_BOTTOM_SLOGAN_WIDTH 370 - -#define CAMPAIGN_HISTORY_SMALL_TITLE_X 64 + LAPTOP_SCREEN_UL_X -#define CAMPAIGN_HISTORY_SMALL_TITLE_Y 5 + LAPTOP_SCREEN_WEB_UL_Y - -#define CAMPAIGN_HISTORY_SMALL_TITLE_WIDTH 434 - 170 -#define CAMPAIGN_HISTORY_SMALL_TITLE_HEIGHT 40 - 10 - -#define MERCCOMPARE_NUM_LINKS 4 -#define MCA_START_CONTENT_Y (LAPTOP_SCREEN_WEB_UL_Y + MERCCOMPARE_NUM_LINKS * 17) +#define NUM_LINKS 4 +#define MCA_START_CONTENT_Y (LAPTOP_SCREEN_WEB_UL_Y + NUM_LINKS * 17) extern UINT32 guiInsuranceBackGround; @@ -98,18 +63,133 @@ UINT32 guiMercCompareBulletImage; UINT32 guiMercCompareLogoImage; //link to the various pages -MOUSE_REGION gMercCompareLinkRegion[MERCCOMPARE_NUM_LINKS]; -void SelectMercCompareRegionCallBack( MOUSE_REGION * pRegion, INT32 iReason ); +MOUSE_REGION gMercCompareLinkRegion[NUM_LINKS]; - -void GameInitMercCompare( ) +void SelectLinkRegionCallBack_MercCompare( MOUSE_REGION * pRegion, INT32 iReason ) { + if ( iReason & MSYS_CALLBACK_REASON_INIT ) + { + } + else if ( iReason & MSYS_CALLBACK_REASON_LBUTTON_UP ) + { + UINT32 uiLink = MSYS_GetRegionUserData( pRegion, 0 ); + if ( uiLink == 0 ) + guiCurrentLaptopMode = LAPTOP_MODE_MERCCOMPARE_MAIN; + else if ( uiLink == 1 ) + guiCurrentLaptopMode = LAPTOP_MODE_MERCCOMPARE_MATRIX; + else if ( uiLink == 2 ) + guiCurrentLaptopMode = LAPTOP_MODE_MERCCOMPARE_ANALYZE; + else if ( uiLink == 3 ) + guiCurrentLaptopMode = LAPTOP_MODE_MERCCOMPARE_CUSTOMERS; + } + else if ( iReason & MSYS_CALLBACK_REASON_RBUTTON_UP ) + { + } +} + +void GetMercCompareText( UINT8 ubNumber, STR16 pString ) +{ + if ( ubNumber >= TEXT_MERCCOMPARE_MAX ) + wcscpy( pString, L"???" ); + + wcscpy( pString, szMercCompareWebSite[ubNumber] ); +} + +void InitDefaults( ) +{ + VOBJECT_DESC VObjectDesc; + + // load the Insurance bullet graphic and add it + VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; + FilenameForBPP( "LAPTOP\\bullet.sti", VObjectDesc.ImageFile ); + CHECKV( AddVideoObject( &VObjectDesc, &guiMercCompareBulletImage ) ); + + // load the Flower Account Box graphic and add it + VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; + FilenameForBPP( "LAPTOP\\BackGroundTile.sti", VObjectDesc.ImageFile ); + CHECKV( AddVideoObject( &VObjectDesc, &guiInsuranceBackGround ) ); + + // load the red bar on the side of the page and add it + VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; + FilenameForBPP( "LAPTOP\\LargeBar.sti", VObjectDesc.ImageFile ); + CHECKV( AddVideoObject( &VObjectDesc, &guiInsuranceBigRedLineImage ) ); + + VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; + FilenameForBPP( "LAPTOP\\PressLogos.sti", VObjectDesc.ImageFile ); + CHECKV( AddVideoObject( &VObjectDesc, &guiMercCompareLogoImage ) ); + + UINT16 usPosX = CAMPAIGN_HISTORY_LINK_START_X; + UINT16 usPosY = CAMPAIGN_HISTORY_LINK_START_Y; + for ( int i = 0; i= TEXT_MERCCOMPARE_MAX ) - wcscpy( pString, L"???" ); - - wcscpy( pString, szMercCompareWebSite[ubNumber] ); -} - - -void SelectMercCompareRegionCallBack( MOUSE_REGION * pRegion, INT32 iReason ) -{ - if ( iReason & MSYS_CALLBACK_REASON_INIT ) - { - } - else if ( iReason & MSYS_CALLBACK_REASON_LBUTTON_UP ) - { - UINT32 uiLink = MSYS_GetRegionUserData( pRegion, 0 ); - - if ( uiLink == 0 ) - guiCurrentLaptopMode = LAPTOP_MODE_MERCCOMPARE_MAIN; - else if ( uiLink == 1 ) - guiCurrentLaptopMode = LAPTOP_MODE_MERCCOMPARE_MATRIX; - else if ( uiLink == 2 ) - guiCurrentLaptopMode = LAPTOP_MODE_MERCCOMPARE_ANALYZE; - else if ( uiLink == 3 ) - guiCurrentLaptopMode = LAPTOP_MODE_MERCCOMPARE_CUSTOMERS; - } - else if ( iReason & MSYS_CALLBACK_REASON_RBUTTON_UP ) - { - } -} - - ////////////////////////// MERC COMPARE CUSTOMERS //////////////////////////////// BOOLEAN EnterMercCompareCustomers( ) { - InitMercCompareDefaults( ); + InitDefaults( ); RenderMercCompareCustomers( ); @@ -307,7 +263,7 @@ BOOLEAN EnterMercCompareCustomers( ) void ExitMercCompareCustomers( ) { - RemoveMercCompareDefaults( ); + RemoveDefaults( ); } void HandleMercCompareCustomers( ) @@ -325,7 +281,7 @@ void RenderMercCompareCustomers( ) //Get the bullet GetVideoObject( &hPixHandle, guiMercCompareBulletImage ); - DisplayMercCompareDefaults( ); + DisplayDefaults( ); SetFontShadow( MERCOMP_FONT_SHADOW ); @@ -383,7 +339,7 @@ template<> void DropDownTemplate::SetRefresh( ) { fMerc BOOLEAN EnterMercCompareAnalyze() { - InitMercCompareDefaults( ); + InitDefaults( ); // We fill two dropdowns with all mercs on our team std::vector > mercvector; @@ -422,7 +378,7 @@ BOOLEAN EnterMercCompareAnalyze() void ExitMercCompareAnalyze() { - RemoveMercCompareDefaults( ); + RemoveDefaults( ); DropDownTemplate::getInstance( ).Destroy( ); DropDownTemplate::getInstance( ).Destroy( ); @@ -447,7 +403,7 @@ void RenderMercCompareAnalyze() //Get the bullet GetVideoObject( &hPixHandle, guiMercCompareBulletImage ); - DisplayMercCompareDefaults( ); + DisplayDefaults( ); SetFontShadow( MERCOMP_FONT_SHADOW ); @@ -978,7 +934,7 @@ template<> void DropDownTemplate::SetRefr BOOLEAN EnterMercCompareMatrix( ) { - InitMercCompareDefaults( ); + InitDefaults( ); // We fill two dropdowns with all mercs on our team std::vector > dropdownvector; @@ -1026,7 +982,7 @@ BOOLEAN EnterMercCompareMatrix( ) void ExitMercCompareMatrix( ) { - RemoveMercCompareDefaults( ); + RemoveDefaults( ); DropDownTemplate::getInstance( ).Destroy( ); @@ -1055,7 +1011,7 @@ void RenderMercCompareMatrix( ) swprintf( sText, L"" ); UINT16 usPosX, usPosY; - DisplayMercCompareDefaults( ); + DisplayDefaults( ); SetFontShadow( MERCOMP_FONT_SHADOW ); diff --git a/Laptop/merccompare.h b/Laptop/merccompare.h index e907c510..d056b01e 100644 --- a/Laptop/merccompare.h +++ b/Laptop/merccompare.h @@ -12,11 +12,6 @@ void ExitMercCompareMain( ); void HandleMercCompareMain( ); void RenderMercCompareMain( ); -void InitMercCompareDefaults( ); -void DisplayMercCompareDefaults( ); -void RemoveMercCompareDefaults( ); -void GetMercCompareText( UINT8 ubNumber, STR16 pString ); - // displays a few quotes of customers BOOLEAN EnterMercCompareCustomers( ); void ExitMercCompareCustomers( ); diff --git a/SaveLoadGame.cpp b/SaveLoadGame.cpp index 035c1873..9939cf7b 100644 --- a/SaveLoadGame.cpp +++ b/SaveLoadGame.cpp @@ -494,7 +494,10 @@ typedef struct // Buggler: New global variable that tracks money earned for facility use. INT32 iTotalEarnedForFacilityOperationsToday; - UINT8 ubFiller[266]; //This structure should be 1588 bytes + // Flugente + UINT8 fShowStrategicDiseaseFlag; + + UINT8 ubFiller[265]; //This structure should be 1588 bytes } GENERAL_SAVE_INFO; @@ -2231,7 +2234,28 @@ BOOLEAN SOLDIERTYPE::Load(HWFILE hFile) numBytesRead = ReadFieldByField(hFile, &this->usAISkillUse, sizeof(usAISkillUse), sizeof(UINT8), numBytesRead); numBytesRead = ReadFieldByField(hFile, &this->usSkillCounter, sizeof(usSkillCounter), sizeof(UINT16), numBytesRead); numBytesRead = ReadFieldByField(hFile, &this->usSkillCooldown, sizeof(usSkillCooldown), sizeof(UINT32), numBytesRead); - numBytesRead = ReadFieldByField(hFile, &this->ubFiller, sizeof(ubFiller), sizeof(UINT8), numBytesRead); + + if ( guiCurrentSaveGameVersion >= DISEASE_SYSTEM ) + { + numBytesRead = ReadFieldByField( hFile, &this->sDiseasePoints, sizeof(sDiseasePoints), sizeof(INT32), numBytesRead ); + numBytesRead = ReadFieldByField( hFile, &this->sDiseaseFlag, sizeof(sDiseaseFlag), sizeof(UINT8), numBytesRead ); + numBytesRead = ReadFieldByField( hFile, &this->ubFiller, sizeof(ubFiller), sizeof(UINT8), numBytesRead ); + } + else + { + buffer += sizeof(sDiseasePoints); + while ( (buffer % 4) > 0 ) ++buffer; + buffer += sizeof(sDiseaseFlag); + while ( (buffer % 4) > 0 ) ++buffer; + + for ( UINT8 i = 0; i < NUM_DISEASES; ++i ) + { + this->sDiseasePoints[i] = 0; + this->sDiseaseFlag[i] = 0; + } + + numBytesRead = ReadFieldByField( hFile, &this->ubFiller, sizeof(ubFiller), sizeof(UINT8), numBytesRead ); + } } else { @@ -3745,6 +3769,15 @@ BOOLEAN SaveGame( int ubSaveGameID, STR16 pGameDesc ) SaveGameFilePosition( FileGetPos( hFile ), "Strategic Information" ); #endif + /*// Flugente: Save the strategic supply + if( !SaveStrategicSupplyToSavedFile( hFile ) ) + { + ScreenMsg( FONT_MCOLOR_WHITE, MSG_ERROR, L"ERROR writing strategic supply"); + goto FAILED_TO_SAVE; + } +#ifdef JA2BETAVERSION + SaveGameFilePosition( FileGetPos( hFile ), "Strategic Supply" ); +#endif*/ @@ -4886,6 +4919,17 @@ BOOLEAN LoadSavedGame( int ubSavedGameID ) LoadGameFilePosition( FileGetPos( hFile ), "Strategic Information" ); #endif + /*// Flugente: Load strategic supply data + if( !LoadStrategicSupplyFromSavedFile( hFile ) ) + { + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, String("LoadStrategicSupplyFromSavedFile failed" ) ); + FileClose( hFile ); + return( FALSE ); + } +#ifdef JA2BETAVERSION + LoadGameFilePosition( FileGetPos( hFile ), "Strategic Supply" ); +#endif*/ + #ifdef JA2UB //JA25 UB // ATE: Validate any new maps... @@ -8305,6 +8349,8 @@ BOOLEAN SaveGeneralInfo( HWFILE hFile ) sGeneralInfo.sMercArrivalGridNo = gGameExternalOptions.iInitialMercArrivalLocation; + sGeneralInfo.fShowStrategicDiseaseFlag = fShowStrategicDiseaseFlag; + #ifdef JA2UB sGeneralInfo.sINITIALHELIGRIDNO[ 0 ] = gGameUBOptions.InitialHeliGridNo[ 0 ];//14947; sGeneralInfo.sINITIALHELIGRIDNO[ 1 ] = gGameUBOptions.InitialHeliGridNo[ 1 ];//15584;//16067; @@ -8619,6 +8665,7 @@ BOOLEAN LoadGeneralInfo( HWFILE hFile ) fShowAircraftFlag = sGeneralInfo.fShowAircraftFlag; fShowTeamFlag = sGeneralInfo.fShowTeamFlag; fShowMobileRestrictionsFlag = sGeneralInfo.fShowMobileRestrictionsFlag; + fShowStrategicDiseaseFlag = sGeneralInfo.fShowStrategicDiseaseFlag; fHelicopterAvailable = sGeneralInfo.fHelicopterAvailable; diff --git a/Strategic/Assignments.cpp b/Strategic/Assignments.cpp index 9ef1601d..630c213d 100644 --- a/Strategic/Assignments.cpp +++ b/Strategic/Assignments.cpp @@ -67,6 +67,8 @@ #include "Campaign Types.h" // added by Flugente #include "Strategic Town Loyalty.h" #include "DynamicDialogue.h" // added by Flugente + #include "Disease.h" // added by Flugente + #include "Queen Command.h" // added by Flugente #endif #include #include @@ -141,6 +143,12 @@ enum{ MOVEITEM_MENU_CANCEL, }; +enum { + DISEASE_MENU_DIAGNOSE, + DISEASE_MENU_SECTOR_TREATMENT, + DISEASE_MENU_CANCEL, +}; + /* CHRISL: Adjusted enumerations to allow for seperation of the three different pocket types in the new inventory system. */ @@ -187,6 +195,7 @@ INT32 ghSquadBox = -1; INT32 ghVehicleBox = -1; INT32 ghRepairBox = -1; INT32 ghMoveItemBox = -1; +INT32 ghDiseaseBox = -1; INT32 ghTrainingBox = -1; INT32 ghAttributeBox = -1; INT32 ghRemoveMercAssignBox = -1; @@ -218,6 +227,7 @@ MOUSE_REGION gRemoveMercAssignRegion[ MAX_REMOVE_MERC_COUNT ]; MOUSE_REGION gEpcMenuRegion[ MAX_EPC_MENU_STRING_COUNT ]; MOUSE_REGION gRepairMenuRegion[ 20 ]; MOUSE_REGION gMoveItem[ 20 ]; +MOUSE_REGION gDisease[DISEASE_MENU_CANCEL + 1]; #define MOVEITEM_MAX_SECTORS 10 UINT8 usMoveItemSectors[MOVEITEM_MAX_SECTORS]; @@ -240,6 +250,7 @@ BOOLEAN fShownAssignmentMenu = FALSE; BOOLEAN fShowVehicleMenu = FALSE; BOOLEAN fShowRepairMenu = FALSE; BOOLEAN fShowMoveItemMenu = FALSE; +BOOLEAN fShowDiseaseMenu = FALSE; BOOLEAN fShownContractMenu = FALSE; // anv: snitch menus BOOLEAN fShowSnitchMenu = FALSE; @@ -447,7 +458,7 @@ void TrainSoldierWithPts( SOLDIERTYPE *pSoldier, INT16 sTrainPts ); // train militia in this sector with this soldier BOOLEAN TrainTownInSector( SOLDIERTYPE *pTrainer, INT16 sMapX, INT16 sMapY, INT16 sTrainingPts ); -// Flugente:: handle processing of prisoners +// Flugente: handle processing of prisoners void HandlePrisonerProcessingInSector( INT16 sMapX, INT16 sMapY, INT8 bZ ); // Flugente: prisons can riot if there aren't enough guards around @@ -459,6 +470,10 @@ void HandleEquipmentMove( INT16 sMapX, INT16 sMapY, INT8 bZ ); // Flugente: handle radio scanning assignments void HandleRadioScanInSector( INT16 sMapX, INT16 sMapY, INT8 bZ ); +// Flugente: disease +void HandleDiseaseDiagnosis(); +void HandleDiseaseSectorTreatment( ); + // reset scan flags in all sectors void ClearSectorScanResults(); @@ -495,6 +510,7 @@ void HandleShadingOfLinesForSquadMenu( void ); void HandleShadingOfLinesForVehicleMenu( void ); void HandleShadingOfLinesForRepairMenu( void ); void HandleShadingOfLinesForMoveItemMenu( void ); +void HandleShadingOfLinesForDiseaseMenu(); void HandleShadingOfLinesForTrainingMenu( void ); void HandleShadingOfLinesForAttributeMenus( void ); // HEADROCK HAM 3.6: Shade Facility Box Lines @@ -523,12 +539,17 @@ BOOLEAN DisplayFacilityAssignmentMenu( SOLDIERTYPE *pSoldier, UINT8 ubFacilityTy // Flugente: move items menu BOOLEAN DisplayMoveItemsMenu( SOLDIERTYPE *pSoldier ); +// Flugente: disease menu +BOOLEAN DisplayDiseaseMenu( SOLDIERTYPE *pSoldier ); + + // create menus void CreateEPCBox( void ); void CreateSquadBox( void ); void CreateVehicleBox(); void CreateRepairBox( void ); void CreateMoveItemBox( void ); +void CreateDiseaseBox(); // HEADROCK HAM 3.6: Facility Box. void CreateFacilityBox( void ); void CreateFacilityAssignmentBox( void ); @@ -873,10 +894,52 @@ BOOLEAN CanCharacterDoctor( SOLDIERTYPE *pSoldier ) // all criteria fit, can doctor return ( TRUE ); - } +// can this character diagnose diseases? +BOOLEAN CanCharacterDiagnoseDisease( SOLDIERTYPE *pSoldier ) +{ + if ( !gGameExternalOptions.fDisease ) + return FALSE; + AssertNotNIL( pSoldier ); + + if ( !BasicCanCharacterAssignment( pSoldier, TRUE ) ) + return(FALSE); + + // all criteria fit, can doctor + return TRUE; +} + +// can this character treat diseases of the population (NOT mercs)? +BOOLEAN CanCharacterTreatSectorDisease( SOLDIERTYPE *pSoldier ) +{ + BOOLEAN fFoundMedKit = FALSE; + INT8 bPocket = 0; + + if ( !gGameExternalOptions.fDisease || !gGameExternalOptions.fDiseaseStrategic ) + return FALSE; + + AssertNotNIL( pSoldier ); + + if ( !BasicCanCharacterAssignment( pSoldier, TRUE ) ) + return(FALSE); + + if ( !CanCharacterDoctorButDoesntHaveMedKit( pSoldier ) ) + return(FALSE); + + // there has to officially be an outbreak in this sector - if we don't know of a disease, we cannot treat it! + UINT8 sector = SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ); + + SECTORINFO *pSectorInfo = &(SectorInfo[sector]); + + // we can only treat disease if we have data on it - either our team diagnosed it, or the WHO did and we have access to their data + if ( pSectorInfo && ((pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_PLAYER) || (gubFact[FACT_DISEASE_WHODATA_ACCESS] && pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_WHO)) ) + return TRUE; + + // all criteria fit, can doctor + return FALSE; +} BOOLEAN IsAnythingAroundForSoldierToRepair( SOLDIERTYPE * pSoldier ) { @@ -1222,6 +1285,9 @@ BOOLEAN CanCharacterPatient( SOLDIERTYPE *pSoldier ) if ( pSoldier->bPoisonSum > 0 ) return( TRUE ); + if ( pSoldier->HasDisease( TRUE, TRUE ) ) + return TRUE; + // if we don't have damaged stat, look if we need healing if ( pSoldier->stats.bLife == pSoldier->stats.bLifeMax ) return( FALSE ); @@ -2390,7 +2456,7 @@ void UpdateAssignments() // build list BuildSectorsWithSoldiersList( ); - + // handle natural healing HandleNaturalHealing( ); @@ -2421,11 +2487,11 @@ void UpdateAssignments() ClearSectorScanResults(); // run through sectors and handle each type in sector - for(sX = 0 ; sX < MAP_WORLD_X; sX++ ) + for(sX = 0 ; sX < MAP_WORLD_X; ++sX ) { - for( sY =0; sY < MAP_WORLD_X; sY++ ) + for( sY =0; sY < MAP_WORLD_X; ++sY ) { - for( bZ = 0; bZ < 4; bZ++) + for( bZ = 0; bZ < 4; ++bZ ) { // handle militia squads movings and creating (not an assignment) if(!bZ && sX < 17 && sY < 17 && sX > 0 && sY > 0) @@ -2465,10 +2531,14 @@ void UpdateAssignments() // Flugente: handle militia command HandleMilitiaCommand(); + // Flugente: disease + HandleDisease(); + HandleDiseaseDiagnosis(); // this must come after HandleDisease() so we discover fresh infections + HandleDiseaseSectorTreatment(); + // check to see if anyone is done healing? UpdatePatientsWhoAreDoneHealing( ); - // check if we have anyone who just finished their assignment if( gfAddDisplayBoxToWaitingQueue ) { @@ -2476,7 +2546,6 @@ void UpdateAssignments() gfAddDisplayBoxToWaitingQueue = FALSE; } - HandleContinueOfTownTraining( ); // check if anyone is on an assignment where they have nothing to do @@ -3437,7 +3506,7 @@ void UpdatePatientsWhoAreDoneHealing( void ) if( pTeamSoldier->bActive ) { // patient who doesn't need healing or curing - if( ( pTeamSoldier->bAssignment == PATIENT ) &&( pTeamSoldier->stats.bLife == pTeamSoldier->stats.bLifeMax ) && ( pTeamSoldier->bPoisonSum == 0 ) ) + if ( (pTeamSoldier->bAssignment == PATIENT) && (pTeamSoldier->stats.bLife == pTeamSoldier->stats.bLifeMax) && (pTeamSoldier->bPoisonSum == 0) && pTeamSoldier->HasDisease(TRUE, TRUE) ) { // Flugente: stats can also be damaged if ( !gGameOptions.fFoodSystem || (gGameOptions.fFoodSystem && pSoldier->bFoodLevel > FoodMoraleMods[FOOD_NORMAL].bThreshold && pSoldier->bDrinkLevel > FoodMoraleMods[FOOD_NORMAL].bThreshold) ) @@ -3698,14 +3767,19 @@ BOOLEAN CanSoldierBeHealedByDoctor( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pDoctor, { fHealDamagedStat = TRUE; } + // added check for surgery if ( !fHealDamagedStat && fCheckForSurgery && pSoldier->iHealableInjury < 100 ) // at least one life can be healed { // cannot be healed return( FALSE ); } + + // Flugente: are we infected with a curable disease that we know of? + BOOLEAN fDisease = pSoldier->HasDisease( TRUE, TRUE ); + // if we have no damaged stat and don't need healing - if (!fHealDamagedStat && (pSoldier->stats.bLife == pSoldier->stats.bLifeMax) ) + if ( !fHealDamagedStat && !fDisease && (pSoldier->stats.bLife == pSoldier->stats.bLifeMax) ) { // if we are poisoned if ( pSoldier->bPoisonSum ) @@ -3717,7 +3791,7 @@ BOOLEAN CanSoldierBeHealedByDoctor( SOLDIERTYPE *pSoldier, SOLDIERTYPE *pDoctor, return( FALSE ); } } - else // if we are not poisoned + else { // cannot be healed return( FALSE ); @@ -3880,7 +3954,7 @@ UINT16 HealPatient( SOLDIERTYPE *pPatient, SOLDIERTYPE * pDoctor, UINT16 usHealA pPatient->stats.bLife = min( pPatient->stats.bLifeMax, (pPatient->stats.bLife + bPointsHealed)); - // potentially increase bPoisonLife: as life points are healed, unhealed poinson points become healed poison points + // potentially increase bPoisonLife: as life points are healed, unhealed poison points become healed poison points if ( pPatient->bPoisonSum > 0 ) { // check if there are unhealed poison points @@ -3927,7 +4001,7 @@ UINT16 HealPatient( SOLDIERTYPE *pPatient, SOLDIERTYPE * pDoctor, UINT16 usHealA } } - // As curing poison happens only when there is no more life to heal ortats to repair, we don't have to edit the above function - we simply cure afterwards + // As curing poison happens only when there is no more life to heal or stats to repair, we don't have to edit the above function - we simply cure afterwards // Look how much poison needs to be cured. Conversion of fresh life points to poison points has already taken place if ( pPatient->bPoisonSum > 0 || pPatient->sFractLife < 0 ) { @@ -3985,6 +4059,69 @@ UINT16 HealPatient( SOLDIERTYPE *pPatient, SOLDIERTYPE * pDoctor, UINT16 usHealA } } + // Flugente: heal diseases if we know of them and they can be cured + if ( pPatient->HasDisease( TRUE, TRUE ) && usHealAmount > 0) + { + // loop over all diseases and determine how much we can heal for every one + INT32 totaldiseasepoints = 0; + for ( int i = 0; i < NUM_DISEASES; ++i ) + { + if ( (pPatient->sDiseaseFlag[i] & SOLDIERDISEASE_DIAGNOSED) && ( Disease[i].usDiseaseProperties & DISEASE_PROPERTY_CANBECURED ) ) + { + totaldiseasepoints += pPatient->sDiseasePoints[i]; + } + } + + // we cannot cure more than we have + INT32 curablepoints = min( totaldiseasepoints, usHealAmount ); + + if ( curablepoints > 0 ) + { + // calculate how much total points we have in all medical bags + UINT16 usTotalMedPointsLeft = TotalMedicalKitPoints( pDoctor ); + + if ( usTotalMedPointsLeft > 0 ) + { + UINT16 useablepoints = min( 100 * usTotalMedPointsLeft, curablepoints ); + + useablepoints /= bMedFactor; + + // now apply healing: reduce disease points for each disease by the determined factor + UINT16 healingdone = 0; + for ( int i = 0; i < NUM_DISEASES; ++i ) + { + if ( (pPatient->sDiseaseFlag[i] & SOLDIERDISEASE_DIAGNOSED) && (Disease[i].usDiseaseProperties & DISEASE_PROPERTY_CANBECURED) ) + { + // amount cured is fraction of disease to total disease times fraction of healing done + INT32 cured = (useablepoints * useablepoints * pPatient->sDiseasePoints[i]) / (FLOAT)(curablepoints * totaldiseasepoints); + + if ( cured > 0 ) + { + healingdone += cured; + usHundredthsHealed += cured; + + usHealAmount = max( 0, usHealAmount - cured); + + pPatient->AddDiseasePoints( i, -cured ); + } + } + } + + // Finally use all kit points (we are sure, we have that much) + if ( UseTotalMedicalKitPoints( pDoctor, healingdone / 100 ) == FALSE ) + { + // throw message if this went wrong for feedback on debugging + #ifdef JA2TESTVERSION + ScreenMsg( FONT_MCOLOR_RED, MSG_TESTVERSION, L"Warning! UseTotalKitPOints returned false, not all points were probably used." ); + #endif + } + + // patient expresses his gratitude + AddOpinionEvent( pPatient->ubProfile, pDoctor->ubProfile, OPINIONEVENT_DISEASE_TREATMENT, TRUE ); + } + } + } + return ( usHundredthsHealed ); } @@ -5062,6 +5199,13 @@ void RestCharacter( SOLDIERTYPE *pSoldier ) pSoldier->bBreathMax += bMaxBreathRegain; + // Flugente: diseases can affect stat effectivity + UINT16 diseasemaxbreathreduction = 0; + for ( int i = 0; i < NUM_DISEASES; ++i ) + diseasemaxbreathreduction += Disease[i].usMaxBreath * pSoldier->GetDiseaseMagnitude( i ); + + pSoldier->bBreathMax = min( pSoldier->bBreathMax, 100 - diseasemaxbreathreduction ); + if( pSoldier->bBreathMax > 100 ) { pSoldier->bBreathMax = 100; @@ -5073,7 +5217,6 @@ void RestCharacter( SOLDIERTYPE *pSoldier ) pSoldier->bBreath = pSoldier->bBreathMax; - if ( pSoldier->bBreathMax >= BREATHMAX_CANCEL_TIRED ) { pSoldier->flags.fComplainedThatTired = FALSE; @@ -5610,13 +5753,125 @@ void ClearSectorScanResults() } } +// Flugente: handle disease diagnosis +void HandleDiseaseDiagnosis() +{ + // requires dieases, duh + if ( !gGameExternalOptions.fDisease ) + return; + + // every merc on diagnosis examines every other merc in this sector for diseases that are currently now known + // depending on his skills how far an infection has gotten, the infection will be made public, giving us more time to cure it + SOLDIERTYPE *pSoldier = NULL; + UINT32 uiCnt = 0; + for ( uiCnt = 0, pSoldier = MercPtrs[uiCnt]; uiCnt <= gTacticalStatus.Team[MercPtrs[0]->bTeam].bLastID; ++uiCnt, pSoldier++ ) + { + if ( pSoldier->bActive && pSoldier->bAssignment == DISEASE_DIAGNOSE && CanCharacterDiagnoseDisease( pSoldier ) && !pSoldier->flags.fMercAsleep && EnoughTimeOnAssignment( pSoldier ) ) + { + // determine our skill at detecting disease + UINT16 skill = pSoldier->stats.bMedical / 2 + NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ) * 15; + + skill = (skill * (100 + pSoldier->GetBackgroundValue( BG_PERC_DISEASE_DIAGNOSE ))) / 100; + + // loop over all other soldiers and determine the chance that they will infect us + SOLDIERTYPE *pTeamSoldier = NULL; + UINT32 uiCnt2 = 0; + for ( uiCnt2 = 0, pTeamSoldier = MercPtrs[uiCnt2]; uiCnt2 <= gTacticalStatus.Team[gbPlayerNum].bLastID; ++uiCnt2, ++pTeamSoldier ) + { + if ( pTeamSoldier->bActive + && pTeamSoldier->sSectorX == pSoldier->sSectorX && pTeamSoldier->sSectorY == pSoldier->sSectorY && pTeamSoldier->bSectorZ == pSoldier->bSectorZ ) + { + for ( int i = 0; i < NUM_DISEASES; ++i ) + { + // if teammember has disease, but this is not yet known + if ( pTeamSoldier->sDiseasePoints[i] > 0 && !(pTeamSoldier->sDiseaseFlag[i] & SOLDIERDISEASE_DIAGNOSED) ) + { + if ( Chance( skill ) ) + { + // doctor discovered a disease - make it known + pTeamSoldier->AnnounceDisease( i ); + } + } + } + } + } + + // we can also diagnose disease in a sector + if ( gGameExternalOptions.fDiseaseStrategic ) + { + UINT8 sector = SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ); + + SECTORINFO *pSectorInfo = &(SectorInfo[sector]); + + if ( pSectorInfo && pSectorInfo->usInfected && Chance( skill ) ) + pSectorInfo->usInfectionFlag |= SECTORDISEASE_DIAGNOSED_PLAYER; + } + } + } +} + +// handle treating the population (NOT our mercs) against diseases +// our mercs are healed via the regular doctoring procedure +void HandleDiseaseSectorTreatment() +{ + // requires dieases, duh + if ( !gGameExternalOptions.fDisease || !gGameExternalOptions.fDiseaseStrategic ) + return; + + // every merc on diagnosis examines every other merc in this sector for diseases that are currently now known + // depending on his skills how far an infection has gotten, the infection will be made public, giving us more time to cure it + SOLDIERTYPE *pSoldier = NULL; + UINT32 uiCnt = 0; + for ( uiCnt = 0, pSoldier = MercPtrs[uiCnt]; uiCnt <= gTacticalStatus.Team[gbPlayerNum].bLastID; ++uiCnt, pSoldier++ ) + { + MakeSureMedKitIsInHand( pSoldier ); + + if ( pSoldier->bActive && pSoldier->bAssignment == DISEASE_DOCTOR_SECTOR && CanCharacterTreatSectorDisease( pSoldier ) && !pSoldier->flags.fMercAsleep && EnoughTimeOnAssignment( pSoldier ) ) + { + // get available healing pts + UINT16 max = 0; + UINT16 ptsavailable = CalculateHealingPointsForDoctor( pSoldier, &max, TRUE ); + + ptsavailable = (ptsavailable * (100 + pSoldier->GetBackgroundValue( BG_PERC_DISEASE_TREAT ))) / 100; + + // calculate how much total points we have in all medical bags + UINT16 usTotalMedPoints = TotalMedicalKitPoints( pSoldier ); + + // doctoring points are limited by medical supplies + ptsavailable = min( ptsavailable, usTotalMedPoints * 100 ); + + // if we are doctoring in a sector, then we know for sure that there is disease here + SECTORINFO *pSectorInfo = &(SectorInfo[ SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ) ]); + + if ( pSectorInfo && pSectorInfo->usInfected ) + pSectorInfo->usInfectionFlag |= SECTORDISEASE_DIAGNOSED_PLAYER; + + UINT32 ptsused = HealSectorPopulation( pSoldier->sSectorX, pSoldier->sSectorY, ptsavailable ); + + // Finaly use all kit points (we are sure, we have that much) + if ( !UseTotalMedicalKitPoints( pSoldier, ptsused / 100 ) ) + { + // throw message if this went wrong for feedback on debugging +#ifdef JA2TESTVERSION + ScreenMsg( FONT_MCOLOR_RED, MSG_TESTVERSION, L"Warning! UseTotalKitPOints returned false, not all points were probably used." ); +#endif + } + + // increment skills based on healing pts used + StatChange( pSoldier, MEDICALAMT, (UINT16)(ptsused / 100), FALSE ); + StatChange( pSoldier, DEXTAMT, (UINT16)(ptsused / 100), FALSE ); + StatChange( pSoldier, WISDOMAMT, (UINT16)(ptsused / 100), FALSE ); + } + } +} + // Flugente: handle militia command void HandleMilitiaCommand() { SOLDIERTYPE *pSoldier = NULL; UINT32 uiCnt = 0; - UINT32 firstid = gTacticalStatus.Team[ OUR_TEAM ].bFirstID; - UINT32 lastid = gTacticalStatus.Team[ OUR_TEAM ].bLastID; + UINT32 firstid = gTacticalStatus.Team[gbPlayerNum].bFirstID; + UINT32 lastid = gTacticalStatus.Team[gbPlayerNum].bLastID; for ( uiCnt = firstid, pSoldier = MercPtrs[ uiCnt ]; uiCnt <= lastid; ++uiCnt, ++pSoldier) { if( pSoldier && pSoldier->bAssignment == FACILITY_STRATEGIC_MILITIA_MOVEMENT && pSoldier->flags.fMercAsleep == FALSE ) @@ -7565,7 +7820,7 @@ void HandleHealingByNaturalCauses( SOLDIERTYPE *pSoldier ) } // lost any pts? - if( pSoldier->stats.bLife == pSoldier->stats.bLifeMax && pSoldier->bPoisonLife == 0 ) + if ( pSoldier->stats.bLife == pSoldier->stats.bLifeMax && pSoldier->bPoisonLife == 0 && !pSoldier->HasDisease( FALSE, FALSE ) ) { return; } @@ -7619,7 +7874,7 @@ void HandleHealingByNaturalCauses( SOLDIERTYPE *pSoldier ) // how much is he poisoned? uiPercentPoison = ( pSoldier->bPoisonSum * 100 ) / pSoldier->stats.bLifeMax; - // SANDRO - experimental - increase health regenariton of soldiers when doctors are around + // SANDRO - experimental - increase health regeneration of soldiers when doctors are around if ( gGameOptions.fNewTraitSystem ) { SOLDIERTYPE * pMedic = NULL; @@ -7665,6 +7920,12 @@ void HandleHealingByNaturalCauses( SOLDIERTYPE *pSoldier ) // a high activity level (stress) increases poisoning pSoldier->sFractLife -= ( INT16 ) ( (uiPercentPoison * (100 - pSoldier->GetPoisonResistance())/100) * gGameExternalOptions.sPoisonInfectionDamageMultiplier * ((99 + bActivityLevelDivisor)/100) ); + // Flugente: diseases can lower health regen + for ( int i = 0; i < NUM_DISEASES; ++i ) + { + pSoldier->sFractLife += Disease[i].sLifeRegenHundreds * pSoldier->GetDiseaseMagnitude( i ); + } + // now update the real life values UpDateSoldierLife( pSoldier ); } @@ -7684,7 +7945,7 @@ void UpDateSoldierLife( SOLDIERTYPE *pSoldier ) sAddedLife += sPoisonAbsorped; // if we're not fully poisoned, we are now poisoned a bit more, even if we won life thanks to absorption - if ( pSoldier->bPoisonSum < pSoldier->stats.bLifeMax ) + if ( 0 && pSoldier->bPoisonSum < pSoldier->stats.bLifeMax ) { pSoldier->bPoisonSum += abs(sAddedLife); } @@ -8854,6 +9115,18 @@ void HandleShadingOfLinesForAssignmentMenus( void ) } } + // diagnosis + if ( CanCharacterDiagnoseDisease( pSoldier ) ) + { + // unshade line + UnShadeStringInBox( ghAssignmentBox, ASSIGN_MENU_DOCTOR_DIAGNOSIS ); + } + else + { + // shade line + ShadeStringInBox( ghAssignmentBox, ASSIGN_MENU_DOCTOR_DIAGNOSIS ); + } + // repair if( CanCharacterRepair( pSoldier ) ) { @@ -8977,6 +9250,9 @@ void HandleShadingOfLinesForAssignmentMenus( void ) // move item submenu HandleShadingOfLinesForMoveItemMenu(); + // disease menu + HandleShadingOfLinesForDiseaseMenu(); + // training submenu HandleShadingOfLinesForTrainingMenu( ); @@ -9036,13 +9312,14 @@ void DetermineWhichAssignmentMenusCanBeShown( void ) } // determine which assign menu needs to be shown - if( ( ( fShowAssignmentMenu == FALSE ) )||( fCharacterNoLongerValid == TRUE ) ) + if( !fShowAssignmentMenu || fCharacterNoLongerValid ) { // reset show assignment menus fShowAssignmentMenu = FALSE; fShowVehicleMenu = FALSE; fShowRepairMenu = FALSE; fShowMoveItemMenu = FALSE; + fShowDiseaseMenu = FALSE; // HEADROCK HAM 3.6: Reset Facility menu fShowFacilityMenu = FALSE; // anv: reset show snitch menu @@ -9059,6 +9336,7 @@ void DetermineWhichAssignmentMenusCanBeShown( void ) CreateDestroyMouseRegionsForSquadMenu( TRUE ); CreateDestroyMouseRegionForRepairMenu( ); CreateDestroyMouseRegionForMoveItemMenu(); + CreateDestroyMouseRegionForDiseaseMenu(); // HEADROCK HAM 3.6: Facility Menu, Submenu CreateDestroyMouseRegionForFacilityMenu( ); CreateDestroyMouseRegionsForFacilityAssignmentMenu( ); @@ -9101,6 +9379,12 @@ void DetermineWhichAssignmentMenusCanBeShown( void ) fTeamPanelDirty = TRUE; gfRenderPBInterface = TRUE; } + if ( IsBoxShown( ghDiseaseBox ) ) + { + HideBox( ghDiseaseBox ); + fTeamPanelDirty = TRUE; + gfRenderPBInterface = TRUE; + } if ( IsBoxShown( ghAttributeBox ) ) { HideBox( ghAttributeBox ); @@ -9186,6 +9470,7 @@ void DetermineWhichAssignmentMenusCanBeShown( void ) CreateDestroyMouseRegionsForSquadMenu( TRUE ); CreateDestroyMouseRegionForRepairMenu( ); CreateDestroyMouseRegionForMoveItemMenu(); + CreateDestroyMouseRegionForDiseaseMenu( ); CreateDestroyMouseRegionsForSnitchMenu( ); CreateDestroyMouseRegionsForSnitchToggleMenu( ); CreateDestroyMouseRegionsForSnitchSectorMenu( ); @@ -9249,7 +9534,7 @@ void DetermineWhichAssignmentMenusCanBeShown( void ) } // Move Item menu - if( fShowMoveItemMenu == TRUE ) + if( fShowMoveItemMenu ) { HandleShadingOfLinesForMoveItemMenu( ); ShowBox( ghMoveItemBox ); @@ -9263,7 +9548,24 @@ void DetermineWhichAssignmentMenusCanBeShown( void ) fTeamPanelDirty = TRUE; fMapPanelDirty = TRUE; gfRenderPBInterface = TRUE; - // SetRenderFlags(RENDER_FLAG_FULL); + } + } + + // Disease menu + if ( fShowDiseaseMenu ) + { + HandleShadingOfLinesForDiseaseMenu( ); + ShowBox( ghDiseaseBox ); + } + else + { + // hide box + if ( IsBoxShown( ghDiseaseBox ) ) + { + HideBox( ghDiseaseBox ); + fTeamPanelDirty = TRUE; + fMapPanelDirty = TRUE; + gfRenderPBInterface = TRUE; } } @@ -9507,6 +9809,7 @@ void ClearScreenMaskForMapScreenExit( void ) CreateDestroyMouseRegionsForSquadMenu( TRUE ); CreateDestroyMouseRegionForRepairMenu( ); CreateDestroyMouseRegionForMoveItemMenu(); + CreateDestroyMouseRegionForDiseaseMenu( ); // HEADROCK HAM 3.6: Facility Menu CreateDestroyMouseRegionForFacilityMenu( ); CreateDestroyMouseRegionsForSnitchMenu( ); @@ -11838,6 +12141,7 @@ void SetShowAllMenus( BOOLEAN fShowMenu ) fShowFacilityMenu = fShowMenu; fShowRepairMenu = fShowMenu; fShowMoveItemMenu = fShowMenu; + fShowDiseaseMenu = fShowMenu; fShowSnitchMenu = fShowMenu; } @@ -11853,7 +12157,7 @@ void AssignmentMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ) if (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) { // HEADROCK HAM 3.6: Added facility menu. - if( ( fShowAttributeMenu )||( fShowTrainingMenu ) || ( fShowRepairMenu ) || fShowMoveItemMenu || ( fShowVehicleMenu ) ||( fShowSquadMenu ) || ( fShowFacilityMenu ) || ( fShowFacilityAssignmentMenu ) || ( fShowSnitchMenu ) ) + if ( fShowAttributeMenu || fShowTrainingMenu || fShowRepairMenu || fShowMoveItemMenu || fShowDiseaseMenu || fShowVehicleMenu || fShowSquadMenu || fShowFacilityMenu || fShowFacilityAssignmentMenu || fShowSnitchMenu ) { return; } @@ -12021,6 +12325,7 @@ void AssignmentMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ) fMapScreenBottomDirty = TRUE; fShowRepairMenu = FALSE; fShowMoveItemMenu = FALSE; + fShowDiseaseMenu = FALSE; } break; case( ASSIGN_MENU_DOCTOR ): @@ -12032,7 +12337,6 @@ void AssignmentMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ) fShowAssignmentMenu = FALSE; giAssignHighLine = -1; - pSoldier->bOldAssignment = pSoldier->bAssignment; if( ( pSoldier->bAssignment != DOCTOR ) ) @@ -12083,8 +12387,43 @@ void AssignmentMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ) DoScreenIndependantMessageBox( sString , MSG_BOX_FLAG_OK, NULL ); } + break; - break; + case ASSIGN_MENU_DOCTOR_DIAGNOSIS: + if ( 1 ) + { + fShowSquadMenu = FALSE; + fShowTrainingMenu = FALSE; + fShowVehicleMenu = FALSE; + fShowFacilityMenu = FALSE; // HEADROCK HAM 3.6: Facility Menu + fShowPrisonerMenu = FALSE; + fShowRepairMenu = FALSE; + fShownContractMenu = FALSE; + fTeamPanelDirty = TRUE; + fMapScreenBottomDirty = TRUE; + + pSoldier->bOldAssignment = pSoldier->bAssignment; + + if ( pSoldier->bSectorZ == 0 ) + { + fShowDiseaseMenu = FALSE; + + if ( DisplayDiseaseMenu( pSoldier ) ) + { + fShowDiseaseMenu = TRUE; + DetermineBoxPositions( ); + } + } + } + else if ( 0 ) + { + fTeamPanelDirty = TRUE; + fMapScreenBottomDirty = TRUE; + swprintf( sString, zMarksMapScreenText[18], pSoldier->GetName( ) ); + + DoScreenIndependantMessageBox( sString, MSG_BOX_FLAG_OK, NULL ); + } + break; case( ASSIGN_MENU_PATIENT ): // can character patient? @@ -12203,6 +12542,7 @@ void AssignmentMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ) fShowFacilityMenu = FALSE; // HEADROCK HAM 3.6: Facility Menu fShowPrisonerMenu = FALSE; fShowMoveItemMenu = FALSE; + fShowDiseaseMenu = FALSE; fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; @@ -12279,6 +12619,7 @@ void AssignmentMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ) fShowRepairMenu = FALSE; fShowTrainingMenu = FALSE; fShowMoveItemMenu = FALSE; + fShowDiseaseMenu = FALSE; fShowFacilityMenu = FALSE; fShowPrisonerMenu = FALSE; @@ -12295,6 +12636,7 @@ void AssignmentMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ) fShowVehicleMenu = FALSE; fShowRepairMenu = FALSE; fShowMoveItemMenu = FALSE; + fShowDiseaseMenu = FALSE; fShowFacilityMenu = FALSE; // HEADROCK HAM 3.6: Facility Menu fShowPrisonerMenu = FALSE; fShowSnitchMenu = FALSE; @@ -12307,12 +12649,12 @@ void AssignmentMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ) case( ASSIGN_MENU_MOVE_ITEMS ): if( 1 ) { - fShowSquadMenu = FALSE; fShowTrainingMenu = FALSE; fShowVehicleMenu = FALSE; fShowFacilityMenu = FALSE; // HEADROCK HAM 3.6: Facility Menu fShowPrisonerMenu = FALSE; + fShowDiseaseMenu = FALSE; //fShownAssignmentMenu = FALSE; fShowRepairMenu = FALSE; fShownContractMenu = FALSE; @@ -12352,6 +12694,7 @@ void AssignmentMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ) fShowVehicleMenu = FALSE; fShowRepairMenu = FALSE; fShowMoveItemMenu = FALSE; + fShowDiseaseMenu = FALSE; fShowFacilityMenu = TRUE; // HEADROCK HAM 3.6: Facility Menu fShowPrisonerMenu = FALSE; fTeamPanelDirty = TRUE; @@ -12387,12 +12730,13 @@ void AssignmentMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ) else if( iReason & MSYS_CALLBACK_REASON_RBUTTON_UP ) { // HEADROCK HAM 3.6: Added facility menu - if( ( fShowAttributeMenu )||( fShowTrainingMenu ) || ( fShowRepairMenu ) || fShowMoveItemMenu || ( fShowVehicleMenu ) ||( fShowSquadMenu ) || ( fShowFacilityMenu ) || ( fShowFacilityAssignmentMenu ) || ( fShowSnitchMenu ) ) + if ( fShowAttributeMenu || fShowTrainingMenu || fShowRepairMenu || fShowMoveItemMenu || fShowDiseaseMenu || fShowVehicleMenu || fShowSquadMenu || fShowFacilityMenu || fShowFacilityAssignmentMenu || fShowSnitchMenu ) { fShowAttributeMenu = FALSE; fShowTrainingMenu = FALSE; fShowRepairMenu = FALSE; fShowMoveItemMenu = FALSE; + fShowDiseaseMenu = FALSE; fShowVehicleMenu = FALSE; fShowSquadMenu = FALSE; fShowFacilityMenu = FALSE; // Added facilities @@ -12716,7 +13060,6 @@ void CreateRepairBox() void CreateMoveItemBox() { - // will create a pop up box for squad selection SGPPoint pPoint; SGPRect pDimensions; @@ -12746,6 +13089,37 @@ void CreateMoveItemBox() SetBoxPosition( ghMoveItemBox, pPoint ); } +void CreateDiseaseBox() +{ + SGPPoint pPoint; + SGPRect pDimensions; + + CreatePopUpBox( &ghDiseaseBox, FacilityAssignmentDimensions, FacilityAssignmentPosition, (POPUP_BOX_FLAG_CLIP_TEXT | POPUP_BOX_FLAG_CENTER_TEXT | POPUP_BOX_FLAG_RESIZE) ); + SetBoxBuffer( ghDiseaseBox, FRAME_BUFFER ); + SetBorderType( ghDiseaseBox, guiPOPUPBORDERS ); + SetBackGroundSurface( ghDiseaseBox, guiPOPUPTEX ); + SetMargins( ghDiseaseBox, 6, 6, 4, 4 ); + SetLineSpace( ghDiseaseBox, 2 ); + + // set current box to this one + SetCurrentBox( ghDiseaseBox ); + + // resize box to text + ResizeBoxToText( ghDiseaseBox ); + + DetermineBoxPositions( ); + + GetBoxPosition( ghDiseaseBox, &pPoint ); + GetBoxSize( ghDiseaseBox, &pDimensions ); + + if ( giBoxY + pDimensions.iBottom > 479 ) + { + pPoint.iY = FacilityAssignmentPosition.iY = 479 - pDimensions.iBottom; + } + + SetBoxPosition( ghDiseaseBox, pPoint ); +} + void CreateSnitchBox() { UINT32 hStringHandle; @@ -13434,6 +13808,7 @@ BOOLEAN CreateDestroyAssignmentPopUpBoxes( void ) CreateVehicleBox(); CreateRepairBox(); CreateMoveItemBox(); + CreateDiseaseBox(); // HEADROCK HAM 3.6: Facility Menu CreateFacilityBox( ); CreateFacilityAssignmentBox( ); @@ -13474,6 +13849,9 @@ BOOLEAN CreateDestroyAssignmentPopUpBoxes( void ) RemoveBox(ghMoveItemBox); ghMoveItemBox = -1; + RemoveBox( ghDiseaseBox); + ghDiseaseBox = -1; + RemoveBox(ghTrainingBox); ghTrainingBox = -1; @@ -13574,7 +13952,16 @@ void DetermineBoxPositions( void ) SetBoxPosition( ghMoveItemBox, pNewPoint ); CreateDestroyMouseRegionForMoveItemMenu( ); } - + + if ( (fShowDiseaseMenu == TRUE) && (ghDiseaseBox != -1) ) + { + //CreateDestroyMouseRegionForMoveItemMenu( ); + pNewPoint.iY += ((GetFontHeight( MAP_SCREEN_FONT ) + 2) * ASSIGN_MENU_DOCTOR_DIAGNOSIS); + + SetBoxPosition( ghDiseaseBox, pNewPoint ); + CreateDestroyMouseRegionForDiseaseMenu( ); + } + if( ( fShowTrainingMenu == TRUE ) && ( ghTrainingBox != -1 ) ) { pNewPoint.iY += ( ( GetFontHeight( MAP_SCREEN_FONT ) + 2 ) * ASSIGN_MENU_TRAIN ); @@ -13811,7 +14198,7 @@ void CheckAndUpdateTacticalAssignmentPopUpPositions( void ) SetBoxPosition( ghRepairBox, pPoint ); } - else if( fShowMoveItemMenu == TRUE ) + else if( fShowMoveItemMenu ) { GetBoxSize( ghMoveItemBox, &pDimensions ); @@ -13950,6 +14337,29 @@ void CheckAndUpdateTacticalAssignmentPopUpPositions( void ) SetBoxPosition( ghMoveItemBox, pPoint ); } + else if ( fShowDiseaseMenu ) + { + GetBoxSize( ghDiseaseBox, &pDimensions ); + + if ( gsAssignmentBoxesX + pDimensions2.iRight + pDimensions.iRight >= SCREEN_WIDTH ) + { + gsAssignmentBoxesX = (INT16)((SCREEN_WIDTH - 1) - (pDimensions2.iRight + pDimensions.iRight)); + SetRenderFlags( RENDER_FLAG_FULL ); + } + + if ( gsAssignmentBoxesY + pDimensions2.iBottom + ((GetFontHeight( MAP_SCREEN_FONT ) + 2) * ASSIGN_MENU_DOCTOR_DIAGNOSIS) >= (SCREEN_HEIGHT - 120) ) + { + gsAssignmentBoxesY = (INT16)((SCREEN_HEIGHT - 121) - (pDimensions2.iBottom) - ((GetFontHeight( MAP_SCREEN_FONT ) + 2) * ASSIGN_MENU_DOCTOR_DIAGNOSIS)); + SetRenderFlags( RENDER_FLAG_FULL ); + } + + pPoint.iX = gsAssignmentBoxesX + pDimensions2.iRight; + pPoint.iY = gsAssignmentBoxesY; + pPoint.iY += ((GetFontHeight( MAP_SCREEN_FONT ) + 2) * ASSIGN_MENU_DOCTOR_DIAGNOSIS); + + SetBoxPosition( ghDiseaseBox, pPoint ); + } + // HEADROCK HAM 3.6: Facility Sub-menu else if( fShowFacilityAssignmentMenu == TRUE ) { @@ -14578,10 +14988,8 @@ void SetSoldierAssignment( SOLDIERTYPE *pSoldier, INT8 bAssignment, INT32 iParam case( DOCTOR ): if( CanCharacterDoctor( pSoldier ) ) { - pSoldier->bOldAssignment = pSoldier->bAssignment; - - + // set dirty flag fTeamPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; @@ -14996,6 +15404,55 @@ void SetSoldierAssignment( SOLDIERTYPE *pSoldier, INT8 bAssignment, INT32 iParam AssignMercToAMovementGroup( pSoldier ); } break; + + case DISEASE_DIAGNOSE: + if ( CanCharacterDiagnoseDisease( pSoldier ) ) + { + pSoldier->bOldAssignment = pSoldier->bAssignment; + + // remove from squad + RemoveCharacterFromSquads( pSoldier ); + + // remove from any vehicle + if ( pSoldier->bOldAssignment == VEHICLE ) + { + TakeSoldierOutOfVehicle( pSoldier ); + } + + if ( pSoldier->bAssignment != bAssignment ) + { + SetTimeOfAssignmentChangeForMerc( pSoldier ); + } + + ChangeSoldiersAssignment( pSoldier, bAssignment ); + AssignMercToAMovementGroup( pSoldier ); + } + break; + + case DISEASE_DOCTOR_SECTOR: + if ( CanCharacterTreatSectorDisease( pSoldier ) ) + { + pSoldier->bOldAssignment = pSoldier->bAssignment; + + // remove from squad + RemoveCharacterFromSquads( pSoldier ); + + // remove from any vehicle + if ( pSoldier->bOldAssignment == VEHICLE ) + { + TakeSoldierOutOfVehicle( pSoldier ); + } + + if ( pSoldier->bAssignment != bAssignment ) + { + SetTimeOfAssignmentChangeForMerc( pSoldier ); + } + + ChangeSoldiersAssignment( pSoldier, bAssignment ); + AssignMercToAMovementGroup( pSoldier ); + } + break; + case( VEHICLE ): if( CanCharacterVehicle( pSoldier ) && IsThisVehicleAccessibleToSoldier( pSoldier, iParam1 ) ) { @@ -15189,10 +15646,14 @@ BOOLEAN HandleAssignmentExpansionAndHighLightForAssignMenu( SOLDIERTYPE *pSoldie } else if( fShowMoveItemMenu ) { - // highlight repair line the previous menu HighLightBoxLine( ghAssignmentBox, ASSIGN_MENU_MOVE_ITEMS ); return( TRUE ); } + else if ( fShowDiseaseMenu ) + { + HighLightBoxLine( ghAssignmentBox, ASSIGN_MENU_DOCTOR_DIAGNOSIS ); + return(TRUE); + } else if( fShowVehicleMenu ) { // highlight vehicle line the previous menu @@ -16276,6 +16737,14 @@ void ReEvaluateEveryonesNothingToDo() fNothingToDo = FALSE; break; + case DISEASE_DIAGNOSE: + fNothingToDo = !CanCharacterDiagnoseDisease( pSoldier ); + break; + + case DISEASE_DOCTOR_SECTOR: + fNothingToDo = !CanCharacterTreatSectorDisease( pSoldier ); + break; + case VEHICLE: default: // squads fNothingToDo = FALSE; @@ -16400,13 +16869,13 @@ void SetAssignmentForList( INT8 bAssignment, INT8 bParam ) // make sure he can repair the SPECIFIC thing being repaired too (must be in its sector, for example) -/* + /* if ( pSelectedSoldier->flags.fFixingSAMSite ) { fCanFixSpecificTarget = CanSoldierRepairSAM( pSoldier, SAM_SITE_REPAIR_DIVISOR ); } else -*/ + */ if ( pSelectedSoldier->bVehicleUnderRepairID != -1 ) { fCanFixSpecificTarget = CanCharacterRepairVehicle( pSoldier, pSelectedSoldier->bVehicleUnderRepairID ); @@ -16565,6 +17034,22 @@ void SetAssignmentForList( INT8 bAssignment, INT8 bParam ) fItWorked = TRUE; } break; + case DISEASE_DIAGNOSE: + if ( CanCharacterDiagnoseDisease( pSoldier ) ) + { + pSoldier->bOldAssignment = pSoldier->bAssignment; + SetSoldierAssignment( pSoldier, DISEASE_DIAGNOSE, bParam, 0, 0 ); + fItWorked = TRUE; + } + break; + case DISEASE_DOCTOR_SECTOR: + if ( CanCharacterTreatSectorDisease( pSoldier ) ) + { + pSoldier->bOldAssignment = pSoldier->bAssignment; + SetSoldierAssignment( pSoldier, DISEASE_DOCTOR_SECTOR, bParam, 0, 0 ); + fItWorked = TRUE; + } + break; case( SQUAD_1 ): case( SQUAD_2 ): case( SQUAD_3 ): @@ -16968,6 +17453,13 @@ UINT8 CalcSoldierNeedForSleep( SOLDIERTYPE *pSoldier ) ubNeedForSleep += pSoldier->GetBackgroundValue(BG_PERC_SLEEP); + // Flugente: diseases can affect stat effectivity + INT16 diseaseeffect = 0; + for ( int i = 0; i < NUM_DISEASES; ++i ) + diseaseeffect += Disease[i].sNeedToSleep * pSoldier->GetDiseaseMagnitude( i ); + + ubNeedForSleep += diseaseeffect; + // Re-Enforce a maximum of 18 hours after injury penalties. if ( ubNeedForSleep > 18 ) { @@ -20554,10 +21046,7 @@ BOOLEAN DisplayMoveItemsMenu( SOLDIERTYPE *pSoldier ) CreateMoveItemBox(); SetCurrentBox(ghMoveItemBox); - - // PLEASE NOTE: make sure any changes you do here are reflected in all 3 routines which must remain in synch: - // CreateDestroyMouseRegionForMoveItemMenu(), DisplayRepairMenu(), and HandleShadingOfLinesForMoveItemMenu(). - + // delete old sectors for (UINT8 i = 0; i < MOVEITEM_MAX_SECTORS; ++i) { @@ -20590,7 +21079,7 @@ BOOLEAN DisplayMoveItemsMenu( SOLDIERTYPE *pSoldier ) AddMonoString( (UINT32 *)&hStringHandle, wSectorName ); - iCount++; + ++iCount; if ( iCount >= MOVEITEM_MAX_SECTORS ) break; } @@ -20628,7 +21117,6 @@ void HandleShadingOfLinesForMoveItemMenu( void ) pSoldier = GetSelectedAssignSoldier( FALSE ); - // PLEASE NOTE: make sure any changes you do here are reflected in all 3 routines which must remain in synch: // CreateDestroyMouseRegionForMoveItemMenu(), DisplayRepairMenu(), and HandleShadingOfLinesForMoveItemMenu(). @@ -20664,7 +21152,6 @@ void HandleShadingOfLinesForMoveItemMenu( void ) } } - //if ( DoesCharacterHaveAnyItemsToRepair( pSoldier, FINAL_REPAIR_PASS ) ) if ( 1 ) { // unshade items line @@ -20676,10 +21163,7 @@ void HandleShadingOfLinesForMoveItemMenu( void ) ShadeStringInBox( ghMoveItemBox, iCount ); } - iCount++; - - - return; + ++iCount; } @@ -20908,3 +21392,252 @@ BOOLEAN MercStaffsMilitaryHQ() return FALSE; } + + + + + + + + + + +// Flugente: disease menu +BOOLEAN DisplayDiseaseMenu( SOLDIERTYPE *pSoldier ) +{ + INT32 hStringHandle = 0; + INT32 iCount = 0; + + // first, clear pop up box + RemoveBox( ghDiseaseBox ); + ghDiseaseBox = -1; + + CreateDiseaseBox( ); + SetCurrentBox( ghDiseaseBox ); + + AddMonoString( (UINT32 *)&hStringHandle, L"Diagnosis" ); + AddMonoString( (UINT32 *)&hStringHandle, L"Treatment" ); + + // cancel + AddMonoString( (UINT32 *)&hStringHandle, L"Cancel" ); + + SetBoxFont( ghDiseaseBox, MAP_SCREEN_FONT ); + SetBoxHighLight( ghDiseaseBox, FONT_WHITE ); + SetBoxShade( ghDiseaseBox, FONT_GRAY7 ); + SetBoxForeground( ghDiseaseBox, FONT_LTGREEN ); + SetBoxBackground( ghDiseaseBox, FONT_BLACK ); + + // resize box to text + ResizeBoxToText( ghDiseaseBox ); + + CheckAndUpdateTacticalAssignmentPopUpPositions( ); + + return TRUE; +} + + +void HandleShadingOfLinesForDiseaseMenu( void ) +{ + INT32 iVehicleIndex = 0; + INT32 iCount = 0; + + if ( (fShowDiseaseMenu == FALSE) || (ghDiseaseBox == -1) ) + { + return; + } + + UnShadeStringInBox( ghDiseaseBox, iCount++ ); + UnShadeStringInBox( ghDiseaseBox, iCount++ ); + + if ( 1 ) + { + // unshade items line + UnShadeStringInBox( ghDiseaseBox, iCount ); + } + else + { + // shade items line + ShadeStringInBox( ghDiseaseBox, iCount ); + } +} + + +void CreateDestroyMouseRegionForDiseaseMenu( void ) +{ + static BOOLEAN fCreated = FALSE; + + UINT32 uiCounter = 0; + INT32 iCount = 0; + INT32 iFontHeight = 0; + INT32 iBoxXPosition = 0; + INT32 iBoxYPosition = 0; + SGPPoint pPosition; + INT32 iBoxWidth = 0; + SGPRect pDimensions; + SOLDIERTYPE *pSoldier = NULL; + INT32 iVehicleIndex = 0; + + if ( fShowDiseaseMenu && !fCreated ) + { + // grab height of font + iFontHeight = GetLineSpace( ghDiseaseBox ) + GetFontHeight( GetBoxFont( ghDiseaseBox ) ); + + // get x.y position of box + GetBoxPosition( ghDiseaseBox, &pPosition ); + + // grab box x and y position + iBoxXPosition = pPosition.iX; + iBoxYPosition = pPosition.iY; + + // get dimensions..mostly for width + GetBoxSize( ghDiseaseBox, &pDimensions ); + + // get width + iBoxWidth = pDimensions.iRight; + + SetCurrentBox( ghDiseaseBox ); + + pSoldier = GetSelectedAssignSoldier( FALSE ); + + // diagnose assignment + MSYS_DefineRegion( &gDisease[iCount], (INT16)(iBoxXPosition), (INT16)(iBoxYPosition + GetTopMarginSize( ghAssignmentBox ) + (iFontHeight)* iCount), (INT16)(iBoxXPosition + iBoxWidth), (INT16)(iBoxYPosition + GetTopMarginSize( ghAssignmentBox ) + (iFontHeight)* (iCount + 1)), MSYS_PRIORITY_HIGHEST - 4, + MSYS_NO_CURSOR, DiseaseMenuMvtCallback, DiseaseMenuBtnCallback ); + + MSYS_SetRegionUserData( &gDisease[iCount], 0, iCount ); + MSYS_SetRegionUserData( &gDisease[iCount], 1, iCount ); + ++iCount; + + // treatment assignment + MSYS_DefineRegion( &gDisease[iCount], (INT16)(iBoxXPosition), (INT16)(iBoxYPosition + GetTopMarginSize( ghAssignmentBox ) + (iFontHeight)* iCount), (INT16)(iBoxXPosition + iBoxWidth), (INT16)(iBoxYPosition + GetTopMarginSize( ghAssignmentBox ) + (iFontHeight)* (iCount + 1)), MSYS_PRIORITY_HIGHEST - 4, + MSYS_NO_CURSOR, DiseaseMenuMvtCallback, DiseaseMenuBtnCallback ); + + MSYS_SetRegionUserData( &gDisease[iCount], 0, iCount ); + MSYS_SetRegionUserData( &gDisease[iCount], 1, iCount ); + ++iCount; + + // cancel + MSYS_DefineRegion( &gDisease[iCount], (INT16)(iBoxXPosition), (INT16)(iBoxYPosition + GetTopMarginSize( ghAssignmentBox ) + (iFontHeight)* iCount), (INT16)(iBoxXPosition + iBoxWidth), (INT16)(iBoxYPosition + GetTopMarginSize( ghAssignmentBox ) + (iFontHeight)* (iCount + 1)), MSYS_PRIORITY_HIGHEST - 4, + MSYS_NO_CURSOR, DiseaseMenuMvtCallback, DiseaseMenuBtnCallback ); + + MSYS_SetRegionUserData( &gDisease[iCount], 0, iCount ); + MSYS_SetRegionUserData( &gDisease[iCount], 1, DISEASE_MENU_CANCEL ); + + PauseGame( ); + + // unhighlight all strings in box + UnHighLightBox( ghDiseaseBox ); + + fCreated = TRUE; + } + else if ( ( !fShowDiseaseMenu || !fShowAssignmentMenu ) && fCreated ) + { + fCreated = FALSE; + + // remove these regions + for ( uiCounter = 0; uiCounter < GetNumberOfLinesOfTextInBox( ghDiseaseBox ); ++uiCounter ) + { + MSYS_RemoveRegion( &gDisease[uiCounter] ); + } + + fShowDiseaseMenu = FALSE; + + SetRenderFlags( RENDER_FLAG_FULL ); + + HideBox( ghDiseaseBox ); + + if ( fShowAssignmentMenu ) + { + // remove highlight on the parent menu + UnHighLightBox( ghAssignmentBox ); + } + } +} + +void DiseaseMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ) +{ + INT32 iValue = MSYS_GetRegionUserData( pRegion, 0 ); + + // ignore clicks on disabled lines + if ( GetBoxShadeFlag( ghDiseaseBox, iValue ) ) + return; + + // WHAT is being repaired is stored in the second user data argument + INT32 iWhat = MSYS_GetRegionUserData( pRegion, 1 ); + + SOLDIERTYPE* pSoldier = GetSelectedAssignSoldier( FALSE ); + + if ( pSoldier && pSoldier->bActive && (iReason & MSYS_CALLBACK_REASON_LBUTTON_UP) ) + { + if ( iWhat < DISEASE_MENU_CANCEL ) + { + pSoldier->bOldAssignment = pSoldier->bAssignment; + + INT8 newassignment = DISEASE_DIAGNOSE; + if ( iWhat == DISEASE_MENU_SECTOR_TREATMENT ) + newassignment = DISEASE_DOCTOR_SECTOR; + + if ( pSoldier->bAssignment != newassignment ) + { + SetTimeOfAssignmentChangeForMerc( pSoldier ); + } + + if ( pSoldier->bOldAssignment == VEHICLE ) + { + TakeSoldierOutOfVehicle( pSoldier ); + } + + // remove from squad + RemoveCharacterFromSquads( pSoldier ); + + ChangeSoldiersAssignment( pSoldier, newassignment ); + + // assign to a movement group + AssignMercToAMovementGroup( pSoldier ); + + // set assignment for group + SetAssignmentForList( (INT8)newassignment, 0 ); + fShowAssignmentMenu = FALSE; + } + else + { + // CANCEL + fShowDiseaseMenu = FALSE; + } + + // update mapscreen + fCharacterInfoPanelDirty = TRUE; + fTeamPanelDirty = TRUE; + fMapScreenBottomDirty = TRUE; + + giAssignHighLine = -1; + } +} + + +void DiseaseMenuMvtCallback( MOUSE_REGION * pRegion, INT32 iReason ) +{ + // mvt callback handler for assignment region + INT32 iValue = MSYS_GetRegionUserData( pRegion, 0 ); + + if ( iReason & MSYS_CALLBACK_REASON_GAIN_MOUSE ) + { + if ( iValue < DISEASE_MENU_CANCEL ) + { + if ( GetBoxShadeFlag( ghDiseaseBox, iValue ) == FALSE ) + { + // highlight choice + HighLightBoxLine( ghDiseaseBox, iValue ); + } + } + else + { + // highlight cancel line + HighLightBoxLine( ghDiseaseBox, GetNumberOfLinesOfTextInBox( ghDiseaseBox ) - 1 ); + } + } + else if ( iReason & MSYS_CALLBACK_REASON_LOST_MOUSE ) + { + // unhighlight all strings in box + UnHighLightBox( ghDiseaseBox ); + } +} \ No newline at end of file diff --git a/Strategic/Assignments.h b/Strategic/Assignments.h index e3b1b379..0c330730 100644 --- a/Strategic/Assignments.h +++ b/Strategic/Assignments.h @@ -56,7 +56,7 @@ enum VEHICLE, IN_TRANSIT, REPAIR, - RADIO_SCAN, // added by Flugente + RADIO_SCAN, // added by Flugente: a radio operators scans for enemy patrols in nearby sectors TRAIN_SELF, TRAIN_TOWN, TRAIN_MOBILE, // HEADROCK HAM 3.6: Training mobile militia. @@ -79,6 +79,8 @@ enum SNITCH_SPREAD_PROPAGANDA, SNITCH_GATHER_RUMOURS, FACILITY_STRATEGIC_MILITIA_MOVEMENT, // Flugente: merc staffs a military HQ, we can now control militia movement on the map + DISEASE_DIAGNOSE, // Flugente: check for diseases among mercs and local population + DISEASE_DOCTOR_SECTOR, // Flugente: treatpopulation (all non-mercs in the sector) against disease NUM_ASSIGNMENTS, }; @@ -142,6 +144,12 @@ typedef struct TOWN_TRAINER_TYPE // can this character be assigned as a doctor? BOOLEAN CanCharacterDoctor( SOLDIERTYPE *pCharacter ); +// can this character diagnose diseases? +BOOLEAN CanCharacterDiagnoseDisease( SOLDIERTYPE *pSoldier ); + +// can this character treat diseases of the population (NOT mercs)? +BOOLEAN CanCharacterTreatSectorDisease( SOLDIERTYPE *pSoldier ); + // can this character be assigned as a repairman? BOOLEAN CanCharacterRepair( SOLDIERTYPE *pCharacter ); @@ -262,6 +270,7 @@ extern INT32 ghVehicleBox; extern INT32 ghRepairBox; extern INT32 ghTrainingBox; extern INT32 ghMoveItemBox; +extern INT32 ghDiseaseBox; extern INT32 ghAttributeBox; extern INT32 ghRemoveMercAssignBox; extern INT32 ghContractBox; @@ -296,6 +305,7 @@ extern BOOLEAN fShownContractMenu; extern BOOLEAN fShownAssignmentMenu; extern BOOLEAN fShowRepairMenu; extern BOOLEAN fShowMoveItemMenu; +extern BOOLEAN fShowDiseaseMenu; extern BOOLEAN fFirstClickInAssignmentScreenMask; @@ -338,6 +348,11 @@ void CreateDestroyMouseRegionForMoveItemMenu( void ); void MoveItemMenuMvtCallback(MOUSE_REGION * pRegion, INT32 iReason ); void MoveItemMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ); +// Flugente: disease menu +void CreateDestroyMouseRegionForDiseaseMenu( void ); +void DiseaseMenuMvtCallback( MOUSE_REGION * pRegion, INT32 iReason ); +void DiseaseMenuBtnCallback( MOUSE_REGION * pRegion, INT32 iReason ); + // HEADROCK HAM 3.6: Facility Menu void CreateDestroyMouseRegionForFacilityMenu( void ); void FacilityMenuMvtCallback(MOUSE_REGION * pRegion, INT32 iReason ); diff --git a/Strategic/Auto Resolve.cpp b/Strategic/Auto Resolve.cpp index 675ca8b8..ce308e1f 100644 --- a/Strategic/Auto Resolve.cpp +++ b/Strategic/Auto Resolve.cpp @@ -4672,6 +4672,9 @@ void AttackTarget( SOLDIERCELL *pAttacker, SOLDIERCELL *pTarget ) // Flugente: campaign stats gCurrentIncident.AddStat( pTarget->pSoldier, CAMPAIGNHISTORY_TYPE_KILL ); + // Flugente: disease + HandleDeathDiseaseImplications( pTarget->pSoldier ); + if( pAttacker->uiFlags & CELL_MERC ) { //Player killed the enemy soldier -- update his stats as well as any assisters. ///////////////////////////////////////////////////////////////////////////////////// @@ -4858,6 +4861,9 @@ void TargetHitCallback( SOLDIERCELL *pTarget, INT32 index ) // Flugente: campaign stats gCurrentIncident.AddStat( pTarget->pSoldier, CAMPAIGNHISTORY_TYPE_KILL ); + // Flugente: disease + HandleDeathDiseaseImplications( pTarget->pSoldier ); + //soldier has been killed if( pTarget->pAttacker[ index ]->uiFlags & CELL_PLAYER ) { //Player killed the enemy soldier -- update his stats as well as any assisters. diff --git a/Strategic/Campaign Types.h b/Strategic/Campaign Types.h index 29ced08c..e48c2b72 100644 --- a/Strategic/Campaign Types.h +++ b/Strategic/Campaign Types.h @@ -500,7 +500,7 @@ typedef struct SECTORINFO BOOLEAN fCampaignSector; #endif - UINT8 uiNumberOfPrisonersOfWar[PRISONER_MAX]; // TODO: PRISONER_MAX got expanded - Varaiblen werden falsch ausgelesen!!! + UINT8 uiNumberOfPrisonersOfWar[PRISONER_MAX]; UINT8 uiInterrogationHundredsLeft[PRISONER_MAX]; UINT32 uiTimeAIArtillerywasOrdered; // Flugente: updated every time an artillery strike is ordered from the militia @@ -508,7 +508,14 @@ typedef struct SECTORINFO UINT8 ubNumTanks; UINT8 ubTanksInBattle; - INT8 bPadding[ 20 ]; + // Flugente: disease + UINT16 usInfected; // how many people (civilians + enemy + militia) are infected in this sector? Does NOT count our mercs + FLOAT fInfectionSeverity; // mean infection rate of those infected (percentage) + UINT8 usDiseaseDoctoringDelay; // AI doctoring in this sector is delayed due to player interference + UINT8 usInfectionFlag; + + + INT8 bPadding[ 12 ]; }SECTORINFO; diff --git a/Strategic/Game Init.cpp b/Strategic/Game Init.cpp index a2aba33b..63c2a525 100644 --- a/Strategic/Game Init.cpp +++ b/Strategic/Game Init.cpp @@ -487,6 +487,9 @@ void InitStrategicLayer( void ) // HEADROCK HAM 4: Initialize Manual Mobile Militia Restrictions. InitManualMobileRestrictions(); + // Flugente: initialize dynamic supply data + //InitStrategicSupplies(); + // free up any leave list arrays that were left allocated ShutDownLeaveList( ); // re-set up leave list arrays for dismissed mercs diff --git a/Strategic/LuaInitNPCs.cpp b/Strategic/LuaInitNPCs.cpp index e3b07e32..12e50d33 100644 --- a/Strategic/LuaInitNPCs.cpp +++ b/Strategic/LuaInitNPCs.cpp @@ -7072,78 +7072,81 @@ static int l_ACTION_ITEM_SEX (lua_State *L) { sGridNo = lua_tointeger(L, 1); - if ( ! (gTacticalStatus.uiFlags & INCOMBAT) ) - { - UINT8 ubID; - OBJECTTYPE DoorCloser; - INT16 sTeleportSpot; - INT16 sDoorSpot; - UINT8 ubDirection; - //DBrot: More Rooms - //UINT8 ubRoom, ubOldRoom; - UINT16 usRoom, usOldRoom; - - // Flugente: check for valid sGridNo - if ( TileIsOutOfBounds(sGridNo) ) - return 0; - - ubID = WhoIsThere2( sGridNo, 0 ); - if ( (ubID != NOBODY) && (MercPtrs[ ubID ]->bTeam == gbPlayerNum) ) + if ( ! (gTacticalStatus.uiFlags & INCOMBAT) ) { - if ( InARoom( sGridNo, &usRoom ) && InARoom( MercPtrs[ ubID ]->sOldGridNo, &usOldRoom ) && usOldRoom != usRoom ) + UINT8 ubID; + OBJECTTYPE DoorCloser; + INT16 sTeleportSpot; + INT16 sDoorSpot; + UINT8 ubDirection; + //DBrot: More Rooms + //UINT8 ubRoom, ubOldRoom; + UINT16 usRoom, usOldRoom; + + // Flugente: check for valid sGridNo + if ( TileIsOutOfBounds(sGridNo) ) + return 0; + + ubID = WhoIsThere2( sGridNo, 0 ); + if ( (ubID != NOBODY) && (MercPtrs[ ubID ]->bTeam == gbPlayerNum) ) { - // also require there to be a miniskirt civ in the room - if ( HookerInRoom( usRoom ) ) + if ( InARoom( sGridNo, &usRoom ) && InARoom( MercPtrs[ ubID ]->sOldGridNo, &usOldRoom ) && usOldRoom != usRoom ) { - // stop the merc... - MercPtrs[ ubID ]->EVENT_StopMerc( MercPtrs[ ubID ]->sGridNo, MercPtrs[ ubID ]->ubDirection ); + // also require there to be a miniskirt civ in the room + if ( HookerInRoom( usRoom ) ) + { + // stop the merc... + MercPtrs[ ubID ]->EVENT_StopMerc( MercPtrs[ ubID ]->sGridNo, MercPtrs[ ubID ]->ubDirection ); - if ( sGridNo == gModSettings.iCarlaDoorGridNo +1 ) - { - sDoorSpot = gModSettings.iCarlaDoorGridNo; - sTeleportSpot = gModSettings.iCarlaDoorGridNo; - } - else if ( sGridNo == gModSettings.iCindyDoorGridNo +1 ) - { - sDoorSpot = gModSettings.iCindyDoorGridNo; - sTeleportSpot = gModSettings.iCindyDoorGridNo; - } - else if ( sGridNo == gModSettings.iBambiDoorGridNo ) - { - sDoorSpot = gModSettings.iBambiDoorGridNo; - sTeleportSpot = gModSettings.iBambiDoorGridNo +1; - } - else - { - sDoorSpot = NOWHERE; - sTeleportSpot = NOWHERE; - } + if ( sGridNo == gModSettings.iCarlaDoorGridNo +1 ) + { + sDoorSpot = gModSettings.iCarlaDoorGridNo; + sTeleportSpot = gModSettings.iCarlaDoorGridNo; + } + else if ( sGridNo == gModSettings.iCindyDoorGridNo +1 ) + { + sDoorSpot = gModSettings.iCindyDoorGridNo; + sTeleportSpot = gModSettings.iCindyDoorGridNo; + } + else if ( sGridNo == gModSettings.iBambiDoorGridNo ) + { + sDoorSpot = gModSettings.iBambiDoorGridNo; + sTeleportSpot = gModSettings.iBambiDoorGridNo +1; + } + else + { + sDoorSpot = NOWHERE; + sTeleportSpot = NOWHERE; + } - if (!TileIsOutOfBounds(sDoorSpot) && !TileIsOutOfBounds(sTeleportSpot) ) - { - // close the door... - DoorCloser[0]->data.misc.bActionValue = ACTION_ITEM_CLOSE_DOOR; - PerformItemAction( sDoorSpot, &DoorCloser ); + if (!TileIsOutOfBounds(sDoorSpot) && !TileIsOutOfBounds(sTeleportSpot) ) + { + // close the door... + DoorCloser[0]->data.misc.bActionValue = ACTION_ITEM_CLOSE_DOOR; + PerformItemAction( sDoorSpot, &DoorCloser ); - // have sex - HandleNPCDoAction( 0, NPC_ACTION_SEX, 0 ); + // have sex + HandleNPCDoAction( 0, NPC_ACTION_SEX, 0 ); - // move the merc outside of the room again - sTeleportSpot = FindGridNoFromSweetSpotWithStructData( MercPtrs[ ubID ], STANDING, sTeleportSpot, 2, &ubDirection, FALSE ); - MercPtrs[ ubID ]->ChangeSoldierState( STANDING, 0, TRUE ); - TeleportSoldier( MercPtrs[ ubID ], sTeleportSpot, FALSE ); + // move the merc outside of the room again + sTeleportSpot = FindGridNoFromSweetSpotWithStructData( MercPtrs[ ubID ], STANDING, sTeleportSpot, 2, &ubDirection, FALSE ); + MercPtrs[ ubID ]->ChangeSoldierState( STANDING, 0, TRUE ); + TeleportSoldier( MercPtrs[ ubID ], sTeleportSpot, FALSE ); - HandleMoraleEvent( MercPtrs[ ubID ], MORALE_SEX, gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); - FatigueCharacter( MercPtrs[ ubID ] ); - FatigueCharacter( MercPtrs[ ubID ] ); - FatigueCharacter( MercPtrs[ ubID ] ); - FatigueCharacter( MercPtrs[ ubID ] ); - DirtyMercPanelInterface( MercPtrs[ ubID ], DIRTYLEVEL1 ); + HandleMoraleEvent( MercPtrs[ ubID ], MORALE_SEX, gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); + FatigueCharacter( MercPtrs[ ubID ] ); + FatigueCharacter( MercPtrs[ ubID ] ); + FatigueCharacter( MercPtrs[ ubID ] ); + FatigueCharacter( MercPtrs[ ubID ] ); + DirtyMercPanelInterface( MercPtrs[ ubID ], DIRTYLEVEL1 ); + + // Flugente: we might get a disease from this... + HandlePossibleInfection( MercPtrs[ubID], NULL, INFECTION_TYPE_SEX ); + } } } } } - } } return 0; } diff --git a/Strategic/Map Screen Interface Border.cpp b/Strategic/Map Screen Interface Border.cpp index 6b83bc88..4545bb74 100644 --- a/Strategic/Map Screen Interface Border.cpp +++ b/Strategic/Map Screen Interface Border.cpp @@ -55,6 +55,8 @@ UINT16 MAP_BORDER_MILITIA_BTN_X; UINT16 MAP_BORDER_MILITIA_BTN_Y; UINT16 MAP_BORDER_MOBILE_BTN_X; UINT16 MAP_BORDER_MOBILE_BTN_Y; +UINT16 MAP_BORDER_DISEASE_BTN_X; // Flugente: disease +UINT16 MAP_BORDER_DISEASE_BTN_Y; UINT16 MAP_LEVEL_MARKER_X; UINT16 MAP_LEVEL_MARKER_Y; @@ -81,7 +83,8 @@ BOOLEAN fShowTeamFlag = FALSE; BOOLEAN fShowMilitia = FALSE; BOOLEAN fShowAircraftFlag = FALSE; BOOLEAN fShowItemsFlag = FALSE; -BOOLEAN fShowMobileRestrictionsFlag = FALSE; // HEADROCK HAM 4 +BOOLEAN fShowMobileRestrictionsFlag = FALSE; // HEADROCK HAM 4 +UINT8 fShowStrategicDiseaseFlag = 0; // Flugente: disease //BOOLEAN fShowVehicleFlag = FALSE; @@ -98,8 +101,8 @@ extern int CLOCK_Y_START; // buttons & button images // HEADROCK HAM 4: Increase both arrays by one to accomodate new Mobile Restrictions button -INT32 giMapBorderButtons[ 7 ] = { -1, -1, -1, -1, -1, -1, -1 }; -INT32 giMapBorderButtonsImage[ 7 ] = { -1, -1, -1, -1, -1, -1, -1 }; +INT32 giMapBorderButtons[ NUM_MAP_BORDER_BTNS ] = { -1, -1, -1, -1, -1, -1, -1, -1 }; +INT32 giMapBorderButtonsImage[ NUM_MAP_BORDER_BTNS ] = { -1, -1, -1, -1, -1, -1, -1, -1 }; void DeleteMapBorderButtons( void ); BOOLEAN CreateButtonsForMapBorder( void ); @@ -124,6 +127,9 @@ void BtnMilitiaCallback(GUI_BUTTON *btn,INT32 reason); // HEADROCK HAM 4: Mobile Restrictions Button callback void BtnMobileCallback(GUI_BUTTON *btn,INT32 reason); +// Flugente: disease +void BtnDiseaseCallback(GUI_BUTTON *btn,INT32 reason); + void LevelMarkerBtnCallback(MOUSE_REGION * pRegion, INT32 iReason ); void CommonBtnCallbackBtnDownChecks( void ); @@ -303,29 +309,40 @@ BOOLEAN CreateButtonsForMapBorder( void ) BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGH, (GUI_CALLBACK)MSYS_NO_CALLBACK, (GUI_CALLBACK)BtnMobileCallback); } - - + // set up fast help text - SetButtonFastHelpText( giMapBorderButtons[ 0 ], pMapScreenBorderButtonHelpText[ 0 ] ); - SetButtonFastHelpText( giMapBorderButtons[ 1 ], pMapScreenBorderButtonHelpText[ 1 ] ); - SetButtonFastHelpText( giMapBorderButtons[ 2 ], pMapScreenBorderButtonHelpText[ 2 ] ); - SetButtonFastHelpText( giMapBorderButtons[ 3 ], pMapScreenBorderButtonHelpText[ 3 ] ); - SetButtonFastHelpText( giMapBorderButtons[ 4 ], pMapScreenBorderButtonHelpText[ 4 ] ); - SetButtonFastHelpText( giMapBorderButtons[ 5 ], pMapScreenBorderButtonHelpText[ 5 ] ); + SetButtonFastHelpText( giMapBorderButtons[ MAP_BORDER_TOWN_BTN ], pMapScreenBorderButtonHelpText[ MAP_BORDER_TOWN_BTN ] ); + SetButtonFastHelpText( giMapBorderButtons[ MAP_BORDER_MINE_BTN ], pMapScreenBorderButtonHelpText[ MAP_BORDER_MINE_BTN ] ); + SetButtonFastHelpText( giMapBorderButtons[ MAP_BORDER_TEAMS_BTN ], pMapScreenBorderButtonHelpText[ MAP_BORDER_TEAMS_BTN ] ); + SetButtonFastHelpText( giMapBorderButtons[ MAP_BORDER_AIRSPACE_BTN ], pMapScreenBorderButtonHelpText[ MAP_BORDER_AIRSPACE_BTN ] ); + SetButtonFastHelpText( giMapBorderButtons[ MAP_BORDER_ITEM_BTN ], pMapScreenBorderButtonHelpText[ MAP_BORDER_ITEM_BTN ] ); + SetButtonFastHelpText( giMapBorderButtons[ MAP_BORDER_MILITIA_BTN ], pMapScreenBorderButtonHelpText[ MAP_BORDER_MILITIA_BTN ] ); + + if (gGameExternalOptions.gfAllowMilitiaGroups) + SetButtonFastHelpText( giMapBorderButtons[ MAP_BORDER_MOBILE_BTN ], pMapScreenBorderButtonHelpText[ MAP_BORDER_MOBILE_BTN ] ); // HEADROCK HAM 4: Mobile Militia button + + SetButtonCursor(giMapBorderButtons[ MAP_BORDER_TOWN_BTN ], MSYS_NO_CURSOR ); + SetButtonCursor(giMapBorderButtons[ MAP_BORDER_MINE_BTN ], MSYS_NO_CURSOR ); + SetButtonCursor(giMapBorderButtons[ MAP_BORDER_TEAMS_BTN ], MSYS_NO_CURSOR ); + SetButtonCursor(giMapBorderButtons[ MAP_BORDER_AIRSPACE_BTN ], MSYS_NO_CURSOR ); + SetButtonCursor(giMapBorderButtons[ MAP_BORDER_ITEM_BTN ], MSYS_NO_CURSOR ); + SetButtonCursor(giMapBorderButtons[ MAP_BORDER_MILITIA_BTN ], MSYS_NO_CURSOR ); if (gGameExternalOptions.gfAllowMilitiaGroups) - SetButtonFastHelpText( giMapBorderButtons[ 6 ], pMapScreenBorderButtonHelpText[ 6 ] ); // HEADROCK HAM 4: Mobile Militia button + SetButtonCursor(giMapBorderButtons[ MAP_BORDER_MOBILE_BTN ], MSYS_NO_CURSOR ); // HEADROCK HAM 4: Mobile Militia button + + // Flugente: disease + if ( gGameExternalOptions.fDisease && gGameExternalOptions.fDiseaseStrategic ) + { + giMapBorderButtonsImage[MAP_BORDER_DISEASE_BTN] = LoadButtonImage( "INTERFACE\\map_border_buttons.sti", -1, 31, -1, 32, -1 ); + giMapBorderButtons[MAP_BORDER_DISEASE_BTN] = QuickCreateButton( giMapBorderButtonsImage[MAP_BORDER_DISEASE_BTN], MAP_BORDER_DISEASE_BTN_X, MAP_BORDER_DISEASE_BTN_Y, + BUTTON_NO_TOGGLE, MSYS_PRIORITY_HIGH, + (GUI_CALLBACK)MSYS_NO_CALLBACK, (GUI_CALLBACK)BtnDiseaseCallback ); - SetButtonCursor(giMapBorderButtons[ 0 ], MSYS_NO_CURSOR ); - SetButtonCursor(giMapBorderButtons[ 1 ], MSYS_NO_CURSOR ); - SetButtonCursor(giMapBorderButtons[ 2 ], MSYS_NO_CURSOR ); - SetButtonCursor(giMapBorderButtons[ 3 ], MSYS_NO_CURSOR ); - SetButtonCursor(giMapBorderButtons[ 4 ], MSYS_NO_CURSOR ); - SetButtonCursor(giMapBorderButtons[ 5 ], MSYS_NO_CURSOR ); - - if (gGameExternalOptions.gfAllowMilitiaGroups) - SetButtonCursor(giMapBorderButtons[ 6 ], MSYS_NO_CURSOR ); // HEADROCK HAM 4: Mobile Militia button + SetButtonFastHelpText( giMapBorderButtons[MAP_BORDER_DISEASE_BTN], pMapScreenBorderButtonHelpText[MAP_BORDER_DISEASE_BTN] ); + SetButtonCursor( giMapBorderButtons[MAP_BORDER_DISEASE_BTN], MSYS_NO_CURSOR ); + } #ifdef JA2UB //EnableButton @@ -392,8 +409,9 @@ BOOLEAN CreateButtonsForMapBorder( void ) DisableButton( giMapBorderButtons[ MAP_BORDER_MILITIA_BTN ]); DisableButton( giMapBorderButtons[ MAP_BORDER_AIRSPACE_BTN ]); DisableButton( giMapBorderButtons[ MAP_BORDER_ITEM_BTN ]); - DisableButton( giMapBorderButtons[ MAP_BORDER_MOBILE_BTN ]); - + DisableButton( giMapBorderButtons[ MAP_BORDER_MOBILE_BTN ]); + DisableButton( giMapBorderButtons[ MAP_BORDER_DISEASE_BTN ]); + fShowTownFlag = FALSE; #endif @@ -407,33 +425,38 @@ void DeleteMapBorderButtons( void ) { UINT8 ubCnt; - RemoveButton( giMapBorderButtons[ 0 ]); - RemoveButton( giMapBorderButtons[ 1 ]); - RemoveButton( giMapBorderButtons[ 2 ]); - RemoveButton( giMapBorderButtons[ 3 ]); - RemoveButton( giMapBorderButtons[ 4 ]); - RemoveButton( giMapBorderButtons[ 5 ]); + RemoveButton( giMapBorderButtons[ MAP_BORDER_TOWN_BTN ]); + RemoveButton( giMapBorderButtons[ MAP_BORDER_MINE_BTN ]); + RemoveButton( giMapBorderButtons[ MAP_BORDER_TEAMS_BTN ]); + RemoveButton( giMapBorderButtons[ MAP_BORDER_AIRSPACE_BTN ]); + RemoveButton( giMapBorderButtons[ MAP_BORDER_ITEM_BTN ]); + RemoveButton( giMapBorderButtons[ MAP_BORDER_MILITIA_BTN ]); // WANNE: Only remove if we added the button if (gGameExternalOptions.gfAllowMilitiaGroups) - RemoveButton( giMapBorderButtons[ 6 ]); // HEADROCK HAM 4 + RemoveButton( giMapBorderButtons[ MAP_BORDER_MOBILE_BTN ]); // HEADROCK HAM 4 + + if ( giMapBorderButtons[MAP_BORDER_DISEASE_BTN] != -1 ) + RemoveButton( giMapBorderButtons[MAP_BORDER_DISEASE_BTN] ); // images - UnloadButtonImage( giMapBorderButtonsImage[ 0 ] ); - UnloadButtonImage( giMapBorderButtonsImage[ 1 ] ); - UnloadButtonImage( giMapBorderButtonsImage[ 2 ] ); - UnloadButtonImage( giMapBorderButtonsImage[ 3 ] ); - UnloadButtonImage( giMapBorderButtonsImage[ 4 ] ); - UnloadButtonImage( giMapBorderButtonsImage[ 5 ] ); + UnloadButtonImage( giMapBorderButtonsImage[ MAP_BORDER_TOWN_BTN ] ); + UnloadButtonImage( giMapBorderButtonsImage[ MAP_BORDER_MINE_BTN ] ); + UnloadButtonImage( giMapBorderButtonsImage[ MAP_BORDER_TEAMS_BTN ] ); + UnloadButtonImage( giMapBorderButtonsImage[ MAP_BORDER_AIRSPACE_BTN ] ); + UnloadButtonImage( giMapBorderButtonsImage[ MAP_BORDER_ITEM_BTN ] ); + UnloadButtonImage( giMapBorderButtonsImage[ MAP_BORDER_MILITIA_BTN ] ); // WANNE: Only unload if we added the button if (gGameExternalOptions.gfAllowMilitiaGroups) - UnloadButtonImage( giMapBorderButtonsImage[ 6 ] ); // HEADROCK HAM 4 - + UnloadButtonImage( giMapBorderButtonsImage[ MAP_BORDER_MOBILE_BTN ] ); // HEADROCK HAM 4 + if ( giMapBorderButtonsImage[MAP_BORDER_DISEASE_BTN] != -1 ) + UnloadButtonImage( giMapBorderButtonsImage[MAP_BORDER_DISEASE_BTN] ); + // HEADROCK HAM 4: Increased number of buttons by one. - for ( ubCnt = 0; ubCnt < NUM_MAP_BORDER_BTNS; ubCnt++ ) + for ( ubCnt = 0; ubCnt < NUM_MAP_BORDER_BTNS; ++ubCnt ) { giMapBorderButtons[ ubCnt ] = -1; giMapBorderButtonsImage[ ubCnt ] = -1; @@ -527,6 +550,21 @@ void BtnItemCallback(GUI_BUTTON *btn,INT32 reason) } } +// Flugente: disease +void BtnDiseaseCallback( GUI_BUTTON *btn, INT32 reason ) +{ + if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN ) + { + CommonBtnCallbackBtnDownChecks(); + + ToggleDiseaseFilter(); + } + else if(reason & MSYS_CALLBACK_REASON_RBUTTON_DWN ) + { + CommonBtnCallbackBtnDownChecks(); + } +} + // HEADROCK HAM 4: Callback for Mobile Restrictions Button void BtnMobileCallback(GUI_BUTTON *btn,INT32 reason) { @@ -616,6 +654,12 @@ void ToggleShowMinesMode( void ) fShowMobileRestrictionsFlag = FALSE; MapBorderButtonOff( MAP_BORDER_MOBILE_BTN ); } + + if ( fShowStrategicDiseaseFlag ) + { + fShowStrategicDiseaseFlag = MAPMODE_DISEASE; + MapBorderButtonOff( MAP_BORDER_DISEASE_BTN ); + } } fMapPanelDirty = TRUE; @@ -765,6 +809,27 @@ void ToggleItemsFilter( void ) } } +// Flugente: disease +void ToggleDiseaseFilter( void ) +{ + if ( fShowStrategicDiseaseFlag == MAPMODE_MAX - 1 ) + { + // turn items OFF + fShowStrategicDiseaseFlag = MAPMODE_OFF; + MapBorderButtonOff( MAP_BORDER_DISEASE_BTN ); + + // dirty regions + fMapPanelDirty = TRUE; + fTeamPanelDirty = TRUE; + fCharacterInfoPanelDirty = TRUE; + } + else + { + // turn ON + TurnOnDiseaseFilterMode( ); + } +} + // HEADROCK HAM 4: Toggle Mobile Restrictions Button void ToggleMobileFilter( void ) { @@ -890,13 +955,11 @@ void TurnOnShowTeamsMode( void ) MapBorderButtonOff( MAP_BORDER_MOBILE_BTN ); } -/* - if( fShowAircraftFlag == TRUE ) + if ( fShowStrategicDiseaseFlag ) { - fShowAircraftFlag = FALSE; - MapBorderButtonOff( MAP_BORDER_AIRSPACE_BTN ); + fShowStrategicDiseaseFlag = MAPMODE_DISEASE; + MapBorderButtonOff( MAP_BORDER_DISEASE_BTN ); } -*/ if( fShowItemsFlag == TRUE ) { @@ -958,6 +1021,12 @@ void TurnOnAirSpaceMode( void ) MapBorderButtonOff( MAP_BORDER_MOBILE_BTN ); } + if ( fShowStrategicDiseaseFlag ) + { + fShowStrategicDiseaseFlag = MAPMODE_DISEASE; + MapBorderButtonOff( MAP_BORDER_DISEASE_BTN ); + } + // Turn off items if( fShowItemsFlag == TRUE ) { @@ -1004,7 +1073,6 @@ void TurnOnItemFilterMode( void ) fShowItemsFlag = TRUE; MapBorderButtonOn( MAP_BORDER_ITEM_BTN ); - // Turn off towns, mines, teams, militia & airspace if any are on if( fShowTownFlag == TRUE ) { @@ -1036,6 +1104,12 @@ void TurnOnItemFilterMode( void ) MapBorderButtonOff( MAP_BORDER_MOBILE_BTN ); } + if ( fShowStrategicDiseaseFlag ) + { + fShowStrategicDiseaseFlag = MAPMODE_DISEASE; + MapBorderButtonOff( MAP_BORDER_DISEASE_BTN ); + } + if( fShowAircraftFlag == TRUE ) { fShowAircraftFlag = FALSE; @@ -1059,6 +1133,80 @@ void TurnOnItemFilterMode( void ) } } +void TurnOnDiseaseFilterMode( void ) +{ + // if mode already on, leave, else set and redraw + if ( fShowStrategicDiseaseFlag < MAPMODE_MAX - 1 ) + { + ++fShowStrategicDiseaseFlag; + MapBorderButtonOn( MAP_BORDER_DISEASE_BTN ); + + if( fShowItemsFlag == TRUE ) + { + fShowItemsFlag = FALSE; + MapBorderButtonOff( MAP_BORDER_ITEM_BTN ); + } + + // Turn off towns, mines, teams, militia & airspace if any are on + if( fShowTownFlag == TRUE ) + { + fShowTownFlag = FALSE; + MapBorderButtonOff( MAP_BORDER_TOWN_BTN ); + } + + if( fShowMineFlag == TRUE ) + { + fShowMineFlag = FALSE; + MapBorderButtonOff( MAP_BORDER_MINE_BTN ); + } + + if( fShowTeamFlag == TRUE ) + { + fShowTeamFlag = FALSE; + MapBorderButtonOff( MAP_BORDER_TEAMS_BTN ); + } + + if( fShowMilitia == TRUE ) + { + fShowMilitia = FALSE; + MapBorderButtonOff( MAP_BORDER_MILITIA_BTN ); + } + // HEADROCK HAM 4: Turn off Militia Restrictions + if (fShowMobileRestrictionsFlag == TRUE) + { + fShowMobileRestrictionsFlag = FALSE; + MapBorderButtonOff( MAP_BORDER_MOBILE_BTN ); + } + + if( fShowAircraftFlag == TRUE ) + { + fShowAircraftFlag = FALSE; + MapBorderButtonOff( MAP_BORDER_AIRSPACE_BTN ); + } + + if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) + { + AbortMovementPlottingMode( ); + } + else if ( gfInChangeArrivalSectorMode ) + { + CancelChangeArrivalSectorMode( ); + } + + if ( fShowStrategicDiseaseFlag == MAPMODE_DISEASE && !gubFact[FACT_DISEASE_VIEWED] ) + { + MapScreenMessage( FONT_MCOLOR_LTYELLOW, MSG_MAP_UI_POSITION_MIDDLE, zMarksMapScreenText[27] ); + + SetFactTrue( FACT_DISEASE_VIEWED ); + } + + // dirty regions + fMapPanelDirty = TRUE; + fTeamPanelDirty = TRUE; + fCharacterInfoPanelDirty = TRUE; + } +} + // HEADROCK HAM 4: Activate "View Mobile Restrictions" mode. void TurnOnMobileFilterMode( void ) { @@ -1098,6 +1246,12 @@ void TurnOnMobileFilterMode( void ) MapBorderButtonOff( MAP_BORDER_ITEM_BTN ); } + if ( fShowStrategicDiseaseFlag ) + { + fShowStrategicDiseaseFlag = MAPMODE_DISEASE; + MapBorderButtonOff( MAP_BORDER_DISEASE_BTN ); + } + if( ( bSelectedDestChar != -1 ) || ( fPlotForHelicopter == TRUE ) ) { AbortMovementPlottingMode( ); @@ -1201,6 +1355,15 @@ void InitializeMapBorderButtonStates( void ) { MapBorderButtonOff( MAP_BORDER_MOBILE_BTN ); } + + if ( fShowStrategicDiseaseFlag ) + { + MapBorderButtonOn( MAP_BORDER_DISEASE_BTN ); + } + else + { + MapBorderButtonOff( MAP_BORDER_DISEASE_BTN ); + } } @@ -1292,6 +1455,9 @@ void InitMapScreenFlags( void ) // HEADROCK HAM 4: Militia Restrictions fShowMobileRestrictionsFlag = FALSE; + + // Flugente + fShowStrategicDiseaseFlag = MAPMODE_DISEASE; } @@ -1356,6 +1522,8 @@ void InitMapBorderButtonCoordinates() MAP_BORDER_MILITIA_BTN_Y = (SCREEN_HEIGHT - yResOffset - buttonOffset); MAP_BORDER_MOBILE_BTN_X = xResSize; MAP_BORDER_MOBILE_BTN_Y = 0; + MAP_BORDER_DISEASE_BTN_X = xResOffset + MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X - 2 * xResOffset) / 2) + 190; + MAP_BORDER_DISEASE_BTN_Y = (SCREEN_HEIGHT - yResOffset - buttonOffset); MAP_LEVEL_MARKER_X = xResOffset + MAP_BORDER_X + ((SCREEN_WIDTH - MAP_BORDER_X - 2 * xResOffset) / 2) + 114; MAP_LEVEL_MARKER_Y = (SCREEN_HEIGHT - yResOffset - buttonOffset); diff --git a/Strategic/Map Screen Interface Border.h b/Strategic/Map Screen Interface Border.h index b2e7747a..bb554b4f 100644 --- a/Strategic/Map Screen Interface Border.h +++ b/Strategic/Map Screen Interface Border.h @@ -30,8 +30,9 @@ enum{ MAP_BORDER_AIRSPACE_BTN, MAP_BORDER_ITEM_BTN, MAP_BORDER_MILITIA_BTN, - MAP_BORDER_MOBILE_BTN, // HEADROCK HAM 4: Mobile Militia Restrictions button - NUM_MAP_BORDER_BTNS, // end enumeration marker + MAP_BORDER_MOBILE_BTN, // HEADROCK HAM 4: Mobile Militia Restrictions button + MAP_BORDER_DISEASE_BTN, // Flugente: toggle disease views + NUM_MAP_BORDER_BTNS, // end enumeration marker }; @@ -50,6 +51,7 @@ extern BOOLEAN fShowMilitia; extern BOOLEAN fShowAircraftFlag; extern BOOLEAN fShowItemsFlag; extern BOOLEAN fShowMobileRestrictionsFlag; // HEADROCK HAM 4: Manual Mobile Militia mode +extern UINT8 fShowStrategicDiseaseFlag; // Flugente: disease //extern BOOLEAN fShowVehicleFlag; // scroll animation @@ -70,12 +72,18 @@ void ToggleItemsFilter( void ); // HEADROCK HAM 4: Toggle Mobile Militia Restrictions Filter void ToggleMobileFilter( void ); +// Flugente: disease +void ToggleDiseaseFilter( ); + void TurnOnShowTeamsMode( void ); void TurnOnAirSpaceMode( void ); void TurnOnItemFilterMode( void ); // HEADROCK HAM 4: Turn on Mobile Militia Restrictions Filter void TurnOnMobileFilterMode( void ); +// Flugente: disease +void TurnOnDiseaseFilterMode(); + // create/destroy buttons for map border region void DeleteMapBorderButtons( void ); BOOLEAN CreateButtonsForMapBorder( void ); diff --git a/Strategic/Map Screen Interface Map.cpp b/Strategic/Map Screen Interface Map.cpp index 54f9129c..e637567c 100644 --- a/Strategic/Map Screen Interface Map.cpp +++ b/Strategic/Map Screen Interface Map.cpp @@ -55,6 +55,9 @@ #include "LaptopSave.h" +// added by Flugente +extern CHAR16 gzSectorNames[256][4][MAX_SECTOR_NAME_LENGTH]; + UINT16 MAP_GRID_X; UINT16 MAP_GRID_Y; @@ -271,24 +274,6 @@ UINT16 MAP_LEVEL_STRING_Y; // HEADROCK HAM 5: Externalized for larger map fonts. //#define MAP_MVT_ICON_FONT SMALLCOMPFONT - -// map shading colors - -enum{ - MAP_SHADE_BLACK =0, - MAP_SHADE_LT_GREEN, - MAP_SHADE_DK_GREEN, - MAP_SHADE_LT_RED, - MAP_SHADE_DK_RED, - // HEADROCK HAM 4: Several new shades, used with the new Manual Mobile Militia restrictions, and the greyed-out map display. - MAP_SHADE_MD_RED, - MAP_SHADE_LT_YELLOW, - MAP_SHADE_DK_YELLOW, - MAP_SHADE_LT_CYAN, - MAP_SHADE_DK_CYAN, - MAP_SHADE_LT_GREY, - MAP_SHADE_DK_GREY, -}; // the big map .pcx UINT32 guiBIGMAP; @@ -314,8 +299,6 @@ UINT16 MAP_MILITIA_BOX_POS_Y; #define MILITIA_BOX_BOX_HEIGHT 36 #define MILITIA_BOX_BOX_WIDTH 42 - - #define POPUP_MILITIA_ICONS_PER_ROW 5 // max 6 rows gives the limit of 30 militia #define MEDIUM_MILITIA_ICON_SPACING 5 #define LARGE_MILITIA_ICON_SPACING 6 @@ -347,6 +330,7 @@ UINT16 MAP_MILITIA_BOX_POS_Y; INT32 giMapMilitiaButtonImage[ 6 ]; INT32 giMapMilitiaButton[ 6 ] = { -1, -1, -1, -1, -1, -1 }; +extern SECTOR_EXT_DATA SectorExternalData[256][4]; INT16 gsMilitiaSectorButtonColors[]={ FONT_LTGREEN, @@ -362,7 +346,6 @@ INT16 sElitesOnCursor = 0; // the current militia town id INT16 sSelectedMilitiaTown = 0; - //extern MINE_LOCATION_TYPE gMineLocation[]; //extern MINE_STATUS_TYPE gMineStatus[]; @@ -392,19 +375,8 @@ INT16 gsHighlightSectorY=-1; INT32 iCurrentMapSectorZ = 0; // the palettes -UINT16 *pMapLTRedPalette; -UINT16 *pMapDKRedPalette; -UINT16 *pMapLTGreenPalette; -UINT16 *pMapDKGreenPalette; -// HEADROCK HAM 4: Several new palettes for yellow, cyan, grey. -UINT16 *pMapMDRedPalette; -UINT16 *pMapLTYellowPalette; -UINT16 *pMapDKYellowPalette; -UINT16 *pMapLTCyanPalette; -UINT16 *pMapDKCyanPalette; -UINT16 *pMapLTGreyPalette; -UINT16 *pMapDKGreyPalette; - +// Flugente: unified palette code +UINT16* pMapPalette[MAP_SHADE_MAX]; // the map border eta pop up UINT32 guiMapBorderEtaPopUp; @@ -502,7 +474,8 @@ INT8 bSelectedContractChar = -1; BOOLEAN fTempPathAlreadyDrawn = FALSE; // the regions for the mapscreen militia box -MOUSE_REGION gMapScreenMilitiaBoxRegions[ 36 ]; +#define MILITIA_BOXREGIONS 36 +MOUSE_REGION gMapScreenMilitiaBoxRegions[ MILITIA_BOXREGIONS ]; MOUSE_REGION gMapScreenMilitiaRegion; // the mine icon @@ -519,7 +492,6 @@ INT16 sSectorMilitiaMapSector = -1; BOOLEAN fMilitiaMapButtonsCreated = FALSE; INT16 sSectorMilitiaMapSectorOutline = -1; - // have any nodes in the current path list been deleted? BOOLEAN fDeletedNode = FALSE; @@ -531,7 +503,6 @@ INT32 giAnimateRouteBaseTime = 0; INT32 giPotHeliPathBaseTime = 0; INT32 giClickHeliIconBaseTime = 0; - // display the level string on the strategic map void DisplayLevelString( void ); @@ -587,6 +558,7 @@ void HandleShowingOfEnemyForcesInSector( INT16 sSectorX, INT16 sSectorY, INT8 bS BOOLEAN CanMilitiaAutoDistribute( void ); void ShowItemsOnMap( void ); +void ShowDiseaseOnMap( ); void DrawMapBoxIcon( HVOBJECT hIconHandle, UINT16 usVOIndex, INT16 sMapX, INT16 sMapY, UINT8 ubIconPosition ); void DisplayDestinationOfHelicopter( void ); void DrawOrta(); @@ -754,151 +726,109 @@ UINT32 DrawMap( void ) UnLockVideoSurface( guiBIGMAP ); UnLockVideoSurface( guiSAVEBUFFER ); - - // shade map sectors (must be done after Tixa/Orta/Mine icons have been blitted, but before icons!) - for ( cnt = 1; cnt < MAP_WORLD_X - 1; cnt++ ) + if ( !iCurrentMapSectorZ ) { - for ( cnt2 = 1; cnt2 < MAP_WORLD_Y - 1; cnt2++ ) + // shade map sectors (must be done after Tixa/Orta/Mine icons have been blitted, but before icons!) + for ( cnt = 1; cnt < MAP_WORLD_X - 1; ++cnt ) { - // LATE DESIGN CHANGE: darken sectors not yet visited, instead of those under known enemy control - if(!is_networked) //hayden - dont darken anything + for ( cnt2 = 1; cnt2 < MAP_WORLD_Y - 1; ++cnt2 ) { - // HEADROCK HAM 4: Mobile View shows all tiles as explored. - if (!fShowMobileRestrictionsFlag && !iCurrentMapSectorZ ) + // LATE DESIGN CHANGE: darken sectors not yet visited, instead of those under known enemy control + if(!is_networked) //hayden - dont darken anything { - if( GetSectorFlagStatus( cnt, cnt2, ( UINT8 ) iCurrentMapSectorZ, SF_ALREADY_VISITED ) == FALSE ) - // if ( IsTheSectorPerceivedToBeUnderEnemyControl( cnt, cnt2, ( INT8 )( iCurrentMapSectorZ ) ) ) + // HEADROCK HAM 4: Mobile View shows all tiles as explored. + if (!fShowMobileRestrictionsFlag ) { - if( fShowAircraftFlag && !iCurrentMapSectorZ ) + if( GetSectorFlagStatus( cnt, cnt2, ( UINT8 ) iCurrentMapSectorZ, SF_ALREADY_VISITED ) == FALSE ) + // if ( IsTheSectorPerceivedToBeUnderEnemyControl( cnt, cnt2, ( INT8 )( iCurrentMapSectorZ ) ) ) { - if( !StrategicMap[ cnt + cnt2 * WORLD_MAP_X ].fEnemyAirControlled ) + if( fShowAircraftFlag ) { - // sector not visited, not air controlled - ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_GREEN ); + if( !StrategicMap[ cnt + cnt2 * WORLD_MAP_X ].fEnemyAirControlled ) + { + // sector not visited, not air controlled + ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_GREEN ); + } + else + { + // sector not visited, controlled and air not + ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_RED ); + } + } + else if ( fShowStrategicDiseaseFlag ) + { + ShadeMapElem( cnt, cnt2, GetMapColour(cnt, cnt2, fShowStrategicDiseaseFlag) ); } else { - // sector not visited, controlled and air not - ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_RED ); + // not visited + if (gGameSettings.fOptions[TOPTION_ALT_MAP_COLOR]) + { + // HEADROCK HAM 4: An alternate display for the map in normal mode. Unexplored sectors + // are in grey, similar to a recon map. Others are left in normal vivid color. + ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_GREY ); + } + else + { + ShadeMapElem( cnt, cnt2, MAP_SHADE_BLACK ); + } } } - // HEADROCK HAM 4: Show Manual Mobile Militia Restrictions - else if (fShowMobileRestrictionsFlag && !iCurrentMapSectorZ ) - { - /* For now, Mobile View Mode shows all tiles as explored. - UINT8 ubManualMobileMovementAllowed = ManualMobileMovementAllowed( SECTOR(cnt,cnt2) ); - switch ( ubManualMobileMovementAllowed ) - { - case 0: - // Sector not visited, Mobiles not allowed here at all. - ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_RED ); - break; - case 1: - // sector not visited, Mobiles forbidden by player - ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_YELLOW ); - break; - case 2: - // sector not visited, Mobiles forbidden by player - ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_CYAN ); - break; - case 3: - // sector not visited, Mobiles forbidden by player - ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_GREEN ); - break; - }*/ - } else { - // not visited - if (gGameSettings.fOptions[TOPTION_ALT_MAP_COLOR]) + if( fShowAircraftFlag ) { - // HEADROCK HAM 4: An alternate display for the map in normal mode. Unexplored sectors - // are in grey, similar to a recon map. Others are left in normal vivid color. - ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_GREY ); - } - else - { - ShadeMapElem( cnt, cnt2, MAP_SHADE_BLACK ); - } - } - } - else - { - if( fShowAircraftFlag && !iCurrentMapSectorZ ) - { - if( !StrategicMap[ cnt + cnt2 * WORLD_MAP_X ].fEnemyAirControlled ) - { - // sector visited and air controlled - ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_GREEN); - } - else - { - // sector visited but not air controlled - ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_RED ); - } - } - // HEADROCK HAM 4: Show Manual Mobile Militia Restrictions - else if (fShowMobileRestrictionsFlag && !iCurrentMapSectorZ ) - { - /* For now, Mobile View Mode shows all tiles as explored. - UINT8 ubManualMobileMovementAllowed = ManualMobileMovementAllowed( SECTOR(cnt, cnt2) ); - switch ( ubManualMobileMovementAllowed ) - { - case 0: - // Sector not visited, Mobiles not allowed here at all. + if( !StrategicMap[ cnt + cnt2 * WORLD_MAP_X ].fEnemyAirControlled ) + { + // sector visited and air controlled + ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_GREEN); + } + else + { + // sector visited but not air controlled ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_RED ); - break; - case 1: - // sector not visited, Mobiles forbidden by player - ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_YELLOW ); - break; - case 2: - // sector not visited, Mobiles forbidden by player - ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_CYAN ); - break; - case 3: - // sector not visited, Mobiles forbidden by player - ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_GREEN ); - break; - }*/ + } + } + else if ( fShowStrategicDiseaseFlag ) + { + ShadeMapElem( cnt, cnt2, GetMapColour(cnt, cnt2, fShowStrategicDiseaseFlag) ); + } } } - } - else if (fShowMobileRestrictionsFlag && !iCurrentMapSectorZ) - { - // HEADROCK HAM 4: Show Manual Mobile Militia Restrictions - - UINT8 ubManualMobileMovementAllowed = ManualMobileMovementAllowed( SECTOR(cnt, cnt2) ); - switch ( ubManualMobileMovementAllowed ) + else if (fShowMobileRestrictionsFlag ) { - case 0: - // Mobiles not allowed here at all. - ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_GREY ); - break; - case 1: - // Mobiles forbidden by player - ShadeMapElem( cnt, cnt2, MAP_SHADE_MD_RED ); - break; - case 2: - // Mobiles can enter but not leave - ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_YELLOW ); - break; - case 3: - // Mobiles can enter - ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_GREEN ); - break; + // HEADROCK HAM 4: Show Manual Mobile Militia Restrictions + UINT8 ubManualMobileMovementAllowed = ManualMobileMovementAllowed( SECTOR(cnt, cnt2) ); + switch ( ubManualMobileMovementAllowed ) + { + case 0: + // Mobiles not allowed here at all. + ShadeMapElem( cnt, cnt2, MAP_SHADE_DK_GREY ); + break; + case 1: + // Mobiles forbidden by player + ShadeMapElem( cnt, cnt2, MAP_SHADE_MD_RED ); + break; + case 2: + // Mobiles can enter but not leave + ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_YELLOW ); + break; + case 3: + // Mobiles can enter + ShadeMapElem( cnt, cnt2, MAP_SHADE_LT_GREEN ); + break; + } } } } } } - // UNFORTUNATELY, WE CAN'T SHADE THESE ICONS AS PART OF SHADING THE MAP, BECAUSE FOR AIRSPACE, THE SHADE FUNCTION // DOESN'T MERELY SHADE THE EXISTING MAP SURFACE, BUT INSTEAD GRABS THE ORIGINAL GRAPHICS FROM BIGMAP, AND CHANGES // THEIR PALETTE. BLITTING ICONS PRIOR TO SHADING WOULD MEAN THEY DON'T SHOW UP IN AIRSPACE VIEW AT ALL. - for (cnt = 1; cnt < NUM_TOWNS; cnt++) + for (cnt = 1; cnt < NUM_TOWNS; ++cnt) { if ( gfHiddenTown[ cnt ] == TRUE ) { @@ -935,7 +865,7 @@ UINT32 DrawMap( void ) ShowSAMSitesOnStrategicMap( ); // draw mine icons - for( iCounter = 0; iCounter < MAX_NUMBER_OF_MINES; iCounter++ ) + for( iCounter = 0; iCounter < MAX_NUMBER_OF_MINES; ++iCounter ) { //BlitMineIcon( gMineLocation[ iCounter ].sSectorX, gMineLocation[ iCounter ].sSectorY ); BlitMineIcon( gMineStatus[ iCounter ].sSectorX, gMineStatus[ iCounter ].sSectorY ); @@ -946,7 +876,7 @@ UINT32 DrawMap( void ) if( fShowMineFlag ) { // show mine name/production text - for( iCounter = 0; iCounter < MAX_NUMBER_OF_MINES; iCounter++ ) + for( iCounter = 0; iCounter < MAX_NUMBER_OF_MINES; ++iCounter ) { //BlitMineText( gMineLocation[ iCounter ].sSectorX, gMineLocation[ iCounter ].sSectorY ); BlitMineText( gMineStatus[ iCounter ].sSectorX, gMineStatus[ iCounter ].sSectorY ); @@ -965,7 +895,7 @@ UINT32 DrawMap( void ) { DrawTownMilitiaForcesOnMap( ); } - + if ( fShowAircraftFlag && !gfInChangeArrivalSectorMode ) { DrawBullseye(); @@ -980,7 +910,6 @@ UINT32 DrawMap( void ) HandleLowerLevelMapBlit( ); } - // show mine outlines even when viewing underground sublevels - they indicate where the mine entrances are if( fShowMineFlag ) // draw grey mine sector borders @@ -1015,6 +944,11 @@ UINT32 DrawMap( void ) ShowItemsOnMap(); } + if ( fShowStrategicDiseaseFlag ) + { + ShowDiseaseOnMap( ); + } + DisplayLevelString( ); RestoreClipRegionToFullScreen( ); @@ -1507,23 +1441,15 @@ BOOLEAN ShadeMapElem( INT16 sMapX, INT16 sMapY, INT32 iColor ) { INT16 sScreenX, sScreenY; HVSURFACE hSrcVSurface; - //HVSURFACE hSAMSurface; - //HVSURFACE hMineSurface; - UINT32 uiDestPitchBYTES; + UINT32 uiDestPitchBYTES; UINT32 uiSrcPitchBYTES; - UINT16 *pDestBuf; + UINT16 *pDestBuf; UINT8 *pSrcBuf; SGPRect clip; - UINT16 *pOriginalPallette; - + UINT16 *pOriginalPallette; // get original video surface palette CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP ) ); - // get original video surface palette - //CHECKF( GetVideoSurface( &hSAMSurface, guiSAMICON ) ); - // get original video surface palette - //CHECKF( GetVideoSurface( &hMineSurface, guiMINEICON ) ); - // get original video surface palette pOriginalPallette = hSrcVSurface->p16BPPPalette; @@ -1538,262 +1464,35 @@ BOOLEAN ShadeMapElem( INT16 sMapX, INT16 sMapY, INT32 iColor ) clip.iRight = clip.iLeft + ( 2 * MAP_GRID_X ); clip.iBottom = clip.iTop + ( 2 * MAP_GRID_Y ); - if( iColor != MAP_SHADE_BLACK ) - { - //sScreenX +=1; - // airspace -/* - if( sMapX == 1 ) - { - clip.iLeft -= 4; - clip.iRight += 4; - sScreenX -= 2; - } - else - { - sScreenX += 1; - } -*/ - } - else + if( iColor == MAP_SHADE_BLACK ) { // non-airspace sScreenY -= 1; + + // simply shade darker + ShadowVideoSurfaceRect( guiSAVEBUFFER, sScreenX, sScreenY, sScreenX + MAP_GRID_X - 1, sScreenY + MAP_GRID_Y - 1 ); } - - switch( iColor ) + else if ( iColor < MAP_SHADE_MAX ) { - case( MAP_SHADE_BLACK ): - // simply shade darker - ShadowVideoSurfaceRect( guiSAVEBUFFER, sScreenX, sScreenY, sScreenX + MAP_GRID_X - 1, sScreenY + MAP_GRID_Y - 1 ); - break; + // grab video surface and set palette + CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP ) ); + hSrcVSurface->p16BPPPalette = pMapPalette[iColor]; + // lock source and dest buffers + pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES ); + CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP ) ); + pSrcBuf = LockVideoSurface( guiBIGMAP, &uiSrcPitchBYTES ); - case( MAP_SHADE_LT_GREEN ): - // grab video surface and set palette - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); + Blt8BPPDataTo16BPPBufferHalfRect( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf, uiSrcPitchBYTES, sScreenX, sScreenY, &clip ); - hSrcVSurface->p16BPPPalette = pMapLTGreenPalette; - //hMineSurface->p16BPPPalette = pMapLTGreenPalette; - //hSAMSurface->p16BPPPalette = pMapLTGreenPalette; - - // lock source and dest buffers - pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES); - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); - pSrcBuf = LockVideoSurface( guiBIGMAP, &uiSrcPitchBYTES); - - Blt8BPPDataTo16BPPBufferHalfRect( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX, sScreenY, &clip ); - - // now blit - //Blt8BPPDataSubTo16BPPBuffer( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX, sScreenY, &clip); - - // unlock source and dest buffers - UnLockVideoSurface( guiBIGMAP ); - UnLockVideoSurface( guiSAVEBUFFER ); - break; - - - case( MAP_SHADE_DK_GREEN ): - // grab video surface and set palette - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); - hSrcVSurface->p16BPPPalette = pMapDKGreenPalette; - //hMineSurface->p16BPPPalette = pMapDKGreenPalette; - //hSAMSurface->p16BPPPalette = pMapDKGreenPalette; - - /// lock source and dest buffers - pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES); - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); - pSrcBuf = LockVideoSurface( guiBIGMAP, &uiSrcPitchBYTES); - - Blt8BPPDataTo16BPPBufferHalfRect( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX , sScreenY, &clip ); - - // now blit - //Blt8BPPDataSubTo16BPPBuffer( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX , sScreenY , &clip); - - // unlock source and dest buffers - UnLockVideoSurface( guiBIGMAP ); - UnLockVideoSurface( guiSAVEBUFFER ); - break; - - - case( MAP_SHADE_LT_RED ): - // grab video surface and set palette - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); - hSrcVSurface->p16BPPPalette = pMapLTRedPalette; - //hMineSurface->p16BPPPalette = pMapLTRedPalette; - //hSAMSurface->p16BPPPalette = pMapLTRedPalette; - - // lock source and dest buffers - pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES); - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); - pSrcBuf = LockVideoSurface( guiBIGMAP, &uiSrcPitchBYTES); - - Blt8BPPDataTo16BPPBufferHalfRect( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX , sScreenY, &clip ); - - // now blit - //Blt8BPPDataSubTo16BPPBuffer( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX , sScreenY , &clip); - - // unlock source and dest buffers - UnLockVideoSurface( guiBIGMAP ); - UnLockVideoSurface( guiSAVEBUFFER ); - break; - - case( MAP_SHADE_DK_RED ): - // grab video surface and set palette - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); - hSrcVSurface->p16BPPPalette = pMapDKRedPalette; - //hMineSurface->p16BPPPalette = pMapDKRedPalette; - //hSAMSurface->p16BPPPalette = pMapDKRedPalette; - - // lock source and dest buffers - pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES); - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); - pSrcBuf = LockVideoSurface( guiBIGMAP, &uiSrcPitchBYTES); - - Blt8BPPDataTo16BPPBufferHalfRect( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX, sScreenY, &clip ); - - // now blit - //Blt8BPPDataSubTo16BPPBuffer( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX , sScreenY , &clip); - - // unlock source and dest buffers - UnLockVideoSurface( guiBIGMAP ); - UnLockVideoSurface( guiSAVEBUFFER ); - break; - - ///////////////////////////////////////////////////////// - // HEADROCK HAM 4: New colors for map shaders - ///////////////////////////////////////////////////////// - - case( MAP_SHADE_MD_RED ): - // grab video surface and set palette - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); - hSrcVSurface->p16BPPPalette = pMapMDRedPalette; - - // lock source and dest buffers - pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES); - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); - pSrcBuf = LockVideoSurface( guiBIGMAP, &uiSrcPitchBYTES); - - Blt8BPPDataTo16BPPBufferHalfRect( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX, sScreenY, &clip ); - - // unlock source and dest buffers - UnLockVideoSurface( guiBIGMAP ); - UnLockVideoSurface( guiSAVEBUFFER ); - break; - - case( MAP_SHADE_LT_YELLOW ): - // grab video surface and set palette - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); - hSrcVSurface->p16BPPPalette = pMapLTYellowPalette; - - // lock source and dest buffers - pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES); - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); - pSrcBuf = LockVideoSurface( guiBIGMAP, &uiSrcPitchBYTES); - - Blt8BPPDataTo16BPPBufferHalfRect( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX, sScreenY, &clip ); - - // unlock source and dest buffers - UnLockVideoSurface( guiBIGMAP ); - UnLockVideoSurface( guiSAVEBUFFER ); - break; - - case( MAP_SHADE_DK_YELLOW ): - // grab video surface and set palette - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); - hSrcVSurface->p16BPPPalette = pMapDKYellowPalette; - - // lock source and dest buffers - pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES); - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); - pSrcBuf = LockVideoSurface( guiBIGMAP, &uiSrcPitchBYTES); - - Blt8BPPDataTo16BPPBufferHalfRect( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX, sScreenY, &clip ); - - // unlock source and dest buffers - UnLockVideoSurface( guiBIGMAP ); - UnLockVideoSurface( guiSAVEBUFFER ); - break; - - case( MAP_SHADE_LT_CYAN ): - // grab video surface and set palette - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); - hSrcVSurface->p16BPPPalette = pMapLTCyanPalette; - - // lock source and dest buffers - pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES); - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); - pSrcBuf = LockVideoSurface( guiBIGMAP, &uiSrcPitchBYTES); - - Blt8BPPDataTo16BPPBufferHalfRect( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX, sScreenY, &clip ); - - // unlock source and dest buffers - UnLockVideoSurface( guiBIGMAP ); - UnLockVideoSurface( guiSAVEBUFFER ); - break; - - case( MAP_SHADE_DK_CYAN ): - // grab video surface and set palette - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); - hSrcVSurface->p16BPPPalette = pMapDKCyanPalette; - - // lock source and dest buffers - pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES); - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); - pSrcBuf = LockVideoSurface( guiBIGMAP, &uiSrcPitchBYTES); - - Blt8BPPDataTo16BPPBufferHalfRect( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX, sScreenY, &clip ); - - // unlock source and dest buffers - UnLockVideoSurface( guiBIGMAP ); - UnLockVideoSurface( guiSAVEBUFFER ); - break; - - case( MAP_SHADE_LT_GREY ): - // grab video surface and set palette - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); - hSrcVSurface->p16BPPPalette = pMapLTGreyPalette; - - // lock source and dest buffers - pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES); - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); - pSrcBuf = LockVideoSurface( guiBIGMAP, &uiSrcPitchBYTES); - - Blt8BPPDataTo16BPPBufferHalfRect( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX, sScreenY, &clip ); - - // unlock source and dest buffers - UnLockVideoSurface( guiBIGMAP ); - UnLockVideoSurface( guiSAVEBUFFER ); - break; - - case( MAP_SHADE_DK_GREY ): - // grab video surface and set palette - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); - hSrcVSurface->p16BPPPalette = pMapDKGreyPalette; - - // lock source and dest buffers - pDestBuf = (UINT16*)LockVideoSurface( guiSAVEBUFFER, &uiDestPitchBYTES); - CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); - pSrcBuf = LockVideoSurface( guiBIGMAP, &uiSrcPitchBYTES); - - Blt8BPPDataTo16BPPBufferHalfRect( pDestBuf, uiDestPitchBYTES, hSrcVSurface, pSrcBuf,uiSrcPitchBYTES, sScreenX, sScreenY, &clip ); - - // unlock source and dest buffers - UnLockVideoSurface( guiBIGMAP ); - UnLockVideoSurface( guiSAVEBUFFER ); - break; - - /////////////////////////////////////////////// - // HEADROCK HAM 4: End new shaders - /////////////////////////////////////////////// + // unlock source and dest buffers + UnLockVideoSurface( guiBIGMAP ); + UnLockVideoSurface( guiSAVEBUFFER ); } // restore original palette CHECKF( GetVideoSurface( &hSrcVSurface, guiBIGMAP) ); hSrcVSurface->p16BPPPalette = pOriginalPallette; - //hMineSurface->p16BPPPalette = pOriginalPallette; - //hSAMSurface->p16BPPPalette = pOriginalPallette; - return ( TRUE ); } @@ -1846,23 +1545,35 @@ BOOLEAN InitializePalettesForMap( void ) GetVSurfacePaletteEntries( hSrcVSurface, pPalette ); // set up various palettes - pMapLTRedPalette = Create16BPPPaletteShaded( pPalette, 400, 0, 0, TRUE ); - pMapDKRedPalette = Create16BPPPaletteShaded( pPalette, 200, 0, 0, TRUE ); - pMapLTGreenPalette = Create16BPPPaletteShaded( pPalette, 100, 300, 0, TRUE ); - pMapDKGreenPalette = Create16BPPPaletteShaded( pPalette, 0, 200, 0, TRUE ); - // HEADROCK HAM 4: Several new palettes for Yellow, Cyan, Grey - pMapMDRedPalette = Create16BPPPaletteShaded( pPalette, 300, 0, 0, TRUE ); - pMapLTYellowPalette = Create16BPPPaletteShaded( pPalette, 400, 350, 0, TRUE ); - pMapDKYellowPalette = Create16BPPPaletteShaded( pPalette, 200, 200, 0, TRUE ); - pMapLTCyanPalette = Create16BPPPaletteShaded( pPalette, 0, 350, 350, TRUE ); - pMapDKCyanPalette = Create16BPPPaletteShaded( pPalette, 0, 200, 200, TRUE ); - pMapLTGreyPalette = Create16BPPPaletteShaded( pPalette, 400, 400, 400, TRUE ); - pMapDKGreyPalette = Create16BPPPaletteShaded( pPalette, 250, 250, 250, TRUE ); + pMapPalette[MAP_SHADE_LT_GREEN] = Create16BPPPaletteShaded( pPalette, 100, 300, 0, TRUE ); + pMapPalette[MAP_SHADE_MD_GREEN] = Create16BPPPaletteShaded( pPalette, 50, 250, 0, TRUE ); + pMapPalette[MAP_SHADE_DK_GREEN] = Create16BPPPaletteShaded( pPalette, 0, 200, 0, TRUE ); + pMapPalette[MAP_SHADE_LT_RED] = Create16BPPPaletteShaded( pPalette, 400, 0, 0, TRUE ); + pMapPalette[MAP_SHADE_MD_RED] = Create16BPPPaletteShaded( pPalette, 300, 0, 0, TRUE ); + pMapPalette[MAP_SHADE_DK_RED] = Create16BPPPaletteShaded( pPalette, 200, 0, 0, TRUE ); + + pMapPalette[MAP_SHADE_LT_YELLOW] = Create16BPPPaletteShaded( pPalette, 400, 350, 0, TRUE ); + pMapPalette[MAP_SHADE_MD_YELLOW] = Create16BPPPaletteShaded( pPalette, 300, 275, 0, TRUE ); + pMapPalette[MAP_SHADE_DK_YELLOW] = Create16BPPPaletteShaded( pPalette, 200, 200, 0, TRUE ); + + pMapPalette[MAP_SHADE_LT_CYAN] = Create16BPPPaletteShaded( pPalette, 0, 350, 350, TRUE ); + pMapPalette[MAP_SHADE_MD_CYAN] = Create16BPPPaletteShaded( pPalette, 0, 275, 275, TRUE ); + pMapPalette[MAP_SHADE_DK_CYAN] = Create16BPPPaletteShaded( pPalette, 0, 200, 200, TRUE ); + + pMapPalette[MAP_SHADE_LT_GREY] = Create16BPPPaletteShaded( pPalette, 400, 400, 400, TRUE ); + pMapPalette[MAP_SHADE_MD_GREY] = Create16BPPPaletteShaded( pPalette, 325, 325, 325, TRUE ); + pMapPalette[MAP_SHADE_DK_GREY] = Create16BPPPaletteShaded( pPalette, 250, 250, 250, TRUE ); + + pMapPalette[MAP_SHADE_LT_BLUE] = Create16BPPPaletteShaded( pPalette, 0, 0, 400, TRUE ); + pMapPalette[MAP_SHADE_MD_BLUE] = Create16BPPPaletteShaded( pPalette, 0, 0, 300, TRUE ); + pMapPalette[MAP_SHADE_DK_BLUE] = Create16BPPPaletteShaded( pPalette, 0, 0, 200, TRUE ); + + pMapPalette[MAP_SHADE_LT_PINK] = Create16BPPPaletteShaded( pPalette, 200, 40, 175, TRUE ); + pMapPalette[MAP_SHADE_ORANGE] = Create16BPPPaletteShaded( pPalette, 255, 127, 40, TRUE ); // delete image - DeleteVideoSurfaceFromIndex(uiTempMap); - + DeleteVideoSurfaceFromIndex(uiTempMap); return ( TRUE ); } @@ -1870,33 +1581,11 @@ BOOLEAN InitializePalettesForMap( void ) void ShutDownPalettesForMap( void ) { - - MemFree( pMapLTRedPalette ); - MemFree( pMapDKRedPalette ); - MemFree( pMapLTGreenPalette ); - MemFree( pMapDKGreenPalette ); - // HEADROCK HAM 4: Several new palettes (see also below) - MemFree( pMapMDRedPalette ); - MemFree( pMapLTYellowPalette ); - MemFree( pMapDKYellowPalette ); - MemFree( pMapLTCyanPalette ); - MemFree( pMapDKCyanPalette ); - MemFree( pMapLTGreyPalette ); - MemFree( pMapDKGreyPalette ); - - pMapLTRedPalette = NULL; - pMapDKRedPalette = NULL; - pMapLTGreenPalette = NULL; - pMapDKGreenPalette = NULL; - pMapMDRedPalette = NULL; - pMapLTYellowPalette = NULL; - pMapDKYellowPalette = NULL; - pMapLTCyanPalette = NULL; - pMapDKCyanPalette = NULL; - pMapLTGreyPalette = NULL; - pMapDKGreyPalette = NULL; - - return; + for ( UINT8 i = 0; i < MAP_SHADE_MAX; ++i ) + { + MemFree( pMapPalette[i] ); + pMapPalette[i] = NULL; + } } void PlotPathForCharacter( SOLDIERTYPE *pCharacter, INT16 sX, INT16 sY, BOOLEAN fTacticalTraversal ) @@ -5094,7 +4783,7 @@ void CreateDestroyMilitiaPopUPRegions( void ) if( fShowMilitia && sSelectedMilitiaTown && !gfMilitiaPopupCreated ) { - for( iCounter = 0; iCounter < 36; iCounter++ ) + for( iCounter = 0; iCounter < MILITIA_BOXREGIONS; ++iCounter ) { MSYS_DefineRegion( &gMapScreenMilitiaBoxRegions[ iCounter ], ( INT16 ) ( MAP_MILITIA_BOX_POS_X + MAP_MILITIA_MAP_X + ( iCounter % MILITIA_BOX_ROWS ) * MILITIA_BOX_BOX_WIDTH ), ( INT16 )( MAP_MILITIA_BOX_POS_Y + MAP_MILITIA_MAP_Y + ( iCounter / MILITIA_BOX_ROWS ) * MILITIA_BOX_BOX_HEIGHT ), ( INT16 )( MAP_MILITIA_BOX_POS_X + MAP_MILITIA_MAP_X + ( ( ( iCounter ) % MILITIA_BOX_ROWS ) + 1 ) * MILITIA_BOX_BOX_WIDTH ), ( INT16 )( MAP_MILITIA_BOX_POS_Y + MAP_MILITIA_MAP_Y + ( ( ( iCounter ) / MILITIA_BOX_ROWS ) + 1 ) * MILITIA_BOX_BOX_HEIGHT ), MSYS_PRIORITY_HIGHEST - 3, MSYS_NO_CURSOR, MilitiaRegionMoveCallback, MilitiaRegionClickCallback ); @@ -5112,7 +4801,7 @@ void CreateDestroyMilitiaPopUPRegions( void ) else if( gfMilitiaPopupCreated && ( !fShowMilitia || !sSelectedMilitiaTown ) ) { - for( iCounter = 0; iCounter < 36; iCounter++ ) + for( iCounter = 0; iCounter < MILITIA_BOXREGIONS; ++iCounter ) { // remove region MSYS_RemoveRegion( &gMapScreenMilitiaBoxRegions[ iCounter ] ); @@ -5147,7 +4836,6 @@ void RenderIconsPerSectorForSelectedTown( void ) INT16 sSectorX = 0, sSectorY = 0; UINT8 ubGreen, ubRegular, ubElite, ub10xGreen, ub10xRegular, ub10xElite; - // get the sector value for the upper left corner sBaseSectorValue = GetBaseSectorForCurrentTown( ); @@ -5270,8 +4958,6 @@ void ShowHighLightedSectorOnMilitiaMap( void ) HVOBJECT hVObject; INT16 sX = 0, sY = 0; - - if( sSectorMilitiaMapSector != -1 ) { sX = MAP_MILITIA_BOX_POS_X + MAP_MILITIA_MAP_X + ( ( sSectorMilitiaMapSector % MILITIA_BOX_ROWS ) * MILITIA_BOX_BOX_WIDTH ); @@ -5453,7 +5139,6 @@ void SetMilitiaMapButtonsText( void ) INT32 iNumberOfGreens = 0, iNumberOfRegulars = 0, iNumberOfElites = 0; INT16 sBaseSectorValue = 0, sGlobalMapSector = 0; - if( !fMilitiaMapButtonsCreated ) { return; @@ -5478,14 +5163,11 @@ void SetMilitiaMapButtonsText( void ) // the number of elites in this sector swprintf( sString, L"%d", iNumberOfElites ); SpecifyButtonText( giMapMilitiaButton[ 2 ], sString ); - - return; } void MilitiaButtonCallback(GUI_BUTTON *btn,INT32 reason) { - INT16 sGlobalMapSector = 0; INT16 sBaseSectorValue = 0; INT32 iValue = 0; @@ -5501,7 +5183,6 @@ void MilitiaButtonCallback(GUI_BUTTON *btn,INT32 reason) sBaseSectorValue = GetBaseSectorForCurrentTown( ); sGlobalMapSector = sBaseSectorValue + ( ( sSectorMilitiaMapSector % MILITIA_BOX_ROWS ) + ( sSectorMilitiaMapSector / MILITIA_BOX_ROWS ) * ( 16 ) ); - if(reason & MSYS_CALLBACK_REASON_LBUTTON_DWN ) { btn->uiFlags|=(BUTTON_CLICKED_ON); @@ -5677,8 +5358,6 @@ void DrawTownMilitiaName( void ) // show the amount of unassigned militia swprintf( sString, L"(%d/%d/%d/%d)", sGreensOnCursor, sRegularsOnCursor, sElitesOnCursor, sGreensOnCursor + sRegularsOnCursor + sElitesOnCursor ); mprintf( MAP_MILITIA_BOX_POS_X + MAP_MILITIA_MAP_X, MAP_MILITIA_BOX_POS_Y + MILITIA_BOX_UNASSIGNED_TEXT_OFFSET_Y, sString ); - - return; } @@ -5796,12 +5475,11 @@ void HandleRemovalOfAllTroopsAmongstSectors( void ) return; } - // get the sector value for the upper left corner sBaseSectorValue = GetBaseSectorForCurrentTown( ); // render icons for map - for( iCounter = 0; iCounter < 36; iCounter++ ) + for( iCounter = 0; iCounter < MILITIA_BOXREGIONS; ++iCounter ) { // grab current sector value sCurrentSectorValue = sBaseSectorValue + ( ( iCounter % MILITIA_BOX_ROWS ) + ( iCounter / MILITIA_BOX_ROWS ) * ( 16 ) ); @@ -5835,8 +5513,6 @@ void HandleRemovalOfAllTroopsAmongstSectors( void ) if( ( sGreensOnCursor > 0 ) || ( sRegularsOnCursor > 0 ) || ( sElitesOnCursor > 0 ) ) SpecifyButtonText( giMapMilitiaButton[ 4 ], pMilitiaButtonString[ 2 ] ); - - return; } void HandleEveningOutOfTroopsAmongstSectors( void ) @@ -5850,7 +5526,6 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Map Screen4"); INT16 sSectorX = 0, sSectorY = 0, sSector = 0; INT16 sTotalSoFar = 0; - // how many sectors in the selected town do we control? iNumberUnderControl = GetTownSectorsUnderControl( ( INT8 ) sSelectedMilitiaTown ); @@ -5860,12 +5535,11 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Map Screen4"); return; } - // get the sector value for the upper left corner sBaseSectorValue = GetBaseSectorForCurrentTown( ); // render icons for map - for( iCounter = 0; iCounter < 36; iCounter++ ) + for( iCounter = 0; iCounter < MILITIA_BOXREGIONS; ++iCounter ) { // grab current sector value sCurrentSectorValue = sBaseSectorValue + ( ( iCounter % MILITIA_BOX_ROWS ) + ( iCounter / MILITIA_BOX_ROWS ) * ( 16 ) ); @@ -5963,7 +5637,7 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Map Screen4"); } } - iCounter++; + ++iCounter; } @@ -5973,8 +5647,6 @@ DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"Map Screen4"); sElitesOnCursor = 0; SpecifyButtonText( giMapMilitiaButton[ 4 ], pMilitiaButtonString[ 1 ] ); - - return; } void CreateMilitiaPanelBottomButton( void ) @@ -6155,7 +5827,7 @@ void RenderShadingForUnControlledSectors( void ) sBaseSectorValue = GetBaseSectorForCurrentTown( ); // render icons for map - for( iCounter = 0; iCounter < 36; iCounter++ ) + for( iCounter = 0; iCounter < MILITIA_BOXREGIONS; ++iCounter ) { // grab current sector value sCurrentSectorValue = sBaseSectorValue + ( ( iCounter % MILITIA_BOX_ROWS ) + ( iCounter / MILITIA_BOX_ROWS ) * ( 16 ) ); @@ -6446,8 +6118,6 @@ void MilitiaBoxMaskBtnCallback(MOUSE_REGION * pRegion, INT32 iReason ) { sSectorMilitiaMapSector = -1; } - - return; } @@ -7060,7 +6730,7 @@ BOOLEAN CanMilitiaAutoDistribute( void ) sBaseSectorValue = GetBaseSectorForCurrentTown( ); // render icons for map - for( iCounter = 0; iCounter < 36; iCounter++ ) + for( iCounter = 0; iCounter < MILITIA_BOXREGIONS; ++iCounter ) { // grab current sector value sCurrentSectorValue = sBaseSectorValue + ( ( iCounter % MILITIA_BOX_ROWS ) + ( iCounter / MILITIA_BOX_ROWS ) * ( 16 ) ); @@ -7100,7 +6770,87 @@ BOOLEAN CanMilitiaAutoDistribute( void ) return( TRUE ); } +void ShowDiseaseOnMap() +{ + INT16 sMapX, sMapY; + INT16 sXCorner, sYCorner; + INT16 usXPos, usYPos; + CHAR16 sString[ 10 ]; + // clip blits to mapscreen region + ClipBlitsToMapViewRegion( ); + + SetFontDestBuffer( guiSAVEBUFFER, MapScreenRect.iLeft + 2, MapScreenRect.iTop, MapScreenRect.iRight, MapScreenRect.iBottom , FALSE ); + + // HEADROCK HAM 5: Map Font now dynamic. + INT32 MapItemsFont; + if (iResolution <= _800x600 ) + { + MapItemsFont = MAP_FONT; + } + else + { + MapItemsFont = FONT14ARIAL; + } + + SetFont(MapItemsFont); + SetFontForeground(FONT_MCOLOR_LTGREEN); + SetFontBackground(FONT_MCOLOR_BLACK); + + // run through sectors + for( sMapX = 1; sMapX < ( MAP_WORLD_X - 1 ); ++sMapX ) + { + for( sMapY = 1; sMapY < ( MAP_WORLD_Y - 1 ); ++sMapY ) + { + UINT8 sector = SECTOR( sMapX, sMapY ); + + SECTORINFO *pSectorInfo = &(SectorInfo[sector]); + + if ( pSectorInfo && ((pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_PLAYER) || (gubFact[FACT_DISEASE_WHODATA_ACCESS] && pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_WHO)) ) + { + if ( fShowStrategicDiseaseFlag == MAPMODE_DISEASE ) + // hide this information, as it might allow the player to deduct enemy positions and numbers + /*{ + UINT16 population = GetSectorPopulation( sMapX, sMapY ); + + if ( population ) + { + sXCorner = (INT16)(MAP_VIEW_START_X + (sMapX * MAP_GRID_X)); + sYCorner = (INT16)(MAP_VIEW_START_Y + (sMapY * MAP_GRID_Y)); + + SetFontForeground( FONT_MCOLOR_WHITE ); + if ( pSectorInfo->usInfectionFlag & SECTORDISEASE_OUTBREAK ) + swprintf( sString, L"%d/%d", pSectorInfo->usInfected, population ); + else + swprintf( sString, L"%d", population ); + + FindFontCenterCoordinates( sXCorner, sYCorner, MAP_GRID_X, MAP_GRID_Y, sString, MapItemsFont, &usXPos, &usYPos ); + + mprintf( usXPos, usYPos, sString ); + } + } + else if ( fShowStrategicDiseaseFlag == MAPMODE_SEVERITY )*/ + { + if ( pSectorInfo->fInfectionSeverity > 0 ) + { + sXCorner = (INT16)(MAP_VIEW_START_X + (sMapX * MAP_GRID_X)); + sYCorner = (INT16)(MAP_VIEW_START_Y + (sMapY * MAP_GRID_Y)); + + SetFontForeground( FONT_MCOLOR_WHITE ); + swprintf( sString, L"%4.2f%%", 100 * pSectorInfo->fInfectionSeverity ); + + FindFontCenterCoordinates( sXCorner, sYCorner, MAP_GRID_X, MAP_GRID_Y, sString, MapItemsFont, &usXPos, &usYPos ); + + mprintf( usXPos, usYPos, sString ); + } + } + } + } + } + + // restore clip blits + RestoreClipRegionToFullScreen( ); +} void ShowItemsOnMap( void ) { @@ -7110,7 +6860,6 @@ void ShowItemsOnMap( void ) UINT32 uiItemCnt; CHAR16 sString[ 10 ]; - // clip blits to mapscreen region ClipBlitsToMapViewRegion( ); @@ -7132,9 +6881,9 @@ void ShowItemsOnMap( void ) SetFontBackground(FONT_MCOLOR_BLACK); // run through sectors - for( sMapX = 1; sMapX < ( MAP_WORLD_X - 1 ); sMapX++ ) + for( sMapX = 1; sMapX < ( MAP_WORLD_X - 1 ); ++sMapX ) { - for( sMapY = 1; sMapY < ( MAP_WORLD_Y - 1 ); sMapY++ ) + for( sMapY = 1; sMapY < ( MAP_WORLD_Y - 1 ); ++sMapY ) { // to speed this up, only look at sector that player has visited if( GetSectorFlagStatus( sMapX, sMapY, ( UINT8 ) iCurrentMapSectorZ, SF_ALREADY_VISITED ) ) @@ -7159,7 +6908,6 @@ void ShowItemsOnMap( void ) } } - // restore clip blits RestoreClipRegionToFullScreen( ); } @@ -7320,7 +7068,6 @@ BOOLEAN CanRedistributeMilitiaInSector( INT16 sClickedSectorX, INT16 sClickedSec return( TRUE ); } - INT32 iCounter = 0; INT16 sBaseSectorValue = 0, sCurrentSectorValue = 0; INT16 sSectorX = 0, sSectorY = 0; @@ -7330,7 +7077,7 @@ BOOLEAN CanRedistributeMilitiaInSector( INT16 sClickedSectorX, INT16 sClickedSec sBaseSectorValue = sBaseSectorList[ bClickedTownId - 1 ]; // render icons for map - for( iCounter = 0; iCounter < 36; iCounter++ ) + for( iCounter = 0; iCounter < MILITIA_BOXREGIONS; ++iCounter ) { // grab current sector value sCurrentSectorValue = sBaseSectorValue + ( ( iCounter % MILITIA_BOX_ROWS ) + ( iCounter / MILITIA_BOX_ROWS ) * ( 16 ) ); @@ -7364,7 +7111,6 @@ BOOLEAN CanRedistributeMilitiaInSector( INT16 sClickedSectorX, INT16 sClickedSec } } - // the fight is elsewhere - ok to redistribute return( TRUE ); } @@ -7398,10 +7144,8 @@ void MilitiaDisbandYesNoBoxCallback( UINT8 bExitValue ) } else if( bExitValue == MSG_BOX_RETURN_NO ) { - return; - } - return; +} } #ifdef JA2UB @@ -7552,3 +7296,4 @@ BOOLEAN LoadHiddenTownFromLoadGameFile( HWFILE hFile ) return( TRUE ); } + diff --git a/Strategic/Map Screen Interface Map.h b/Strategic/Map Screen Interface Map.h index a0dd5469..caf9ad8e 100644 --- a/Strategic/Map Screen Interface Map.h +++ b/Strategic/Map Screen Interface Map.h @@ -29,6 +29,41 @@ typedef struct } MINERALS_VALUES; +// map shading colors +enum{ + MAP_SHADE_BLACK =0, + + MAP_SHADE_LT_GREEN, + MAP_SHADE_MD_GREEN, + MAP_SHADE_DK_GREEN, + + MAP_SHADE_LT_RED, + MAP_SHADE_MD_RED, + MAP_SHADE_DK_RED, + + MAP_SHADE_LT_YELLOW, + MAP_SHADE_MD_YELLOW, + MAP_SHADE_DK_YELLOW, + + MAP_SHADE_LT_CYAN, + MAP_SHADE_MD_CYAN, + MAP_SHADE_DK_CYAN, + + MAP_SHADE_LT_GREY, + MAP_SHADE_MD_GREY, + MAP_SHADE_DK_GREY, + + MAP_SHADE_LT_BLUE, + MAP_SHADE_MD_BLUE, + MAP_SHADE_DK_BLUE, + + MAP_SHADE_LT_PINK, + + MAP_SHADE_ORANGE, + + MAP_SHADE_MAX, +}; + extern MINERALS_VALUES MineralsName[255]; extern ICON_FILE gHiddenIcon[ 256 ]; @@ -131,7 +166,6 @@ void BlitTownGridMarkers( void ); BOOLEAN LoadMilitiaPopUpBox( void ); void RemoveMilitiaPopUpBox( void ); - // check if anyone left behind, if not, move selected cursor along with movement group //void CheckIfAnyoneLeftInSector( INT16 sX, INT16 sY, INT16 sNewX, INT16 sNewY, INT8 bZ ); diff --git a/Strategic/Map Screen Interface.cpp b/Strategic/Map Screen Interface.cpp index 4aab8b93..13d4fa3d 100644 --- a/Strategic/Map Screen Interface.cpp +++ b/Strategic/Map Screen Interface.cpp @@ -1987,7 +1987,7 @@ void RemoveMapStatusBarsRegion( void ) void UpdateCharRegionHelpText( void ) { - CHAR16 sString[ 256 ], sTemp[ 20 ]; + CHAR16 sString[ 6000 ], sTemp[ 20 ]; CHAR16 pMoraleStr[ 128 ]; SOLDIERTYPE *pSoldier = NULL; @@ -2060,6 +2060,10 @@ void UpdateCharRegionHelpText( void ) pMapScreenStatusStrings[ 2 ], pMoraleStr ); } } + + { + pSoldier->PrintDiseaseDesc( sString, TRUE ); + } } } else @@ -2321,6 +2325,14 @@ void UpdateMapScreenAssignmentPositions( void ) SetBoxPosition( ghMoveItemBox, pPoint ); } + if ( fShowDiseaseMenu ) + { + GetBoxPosition( ghDiseaseBox, &pPoint ); + pPoint.iY = giBoxY + (GetFontHeight( MAP_SCREEN_FONT ) + 2) * ASSIGN_MENU_DOCTOR_DIAGNOSIS; + + SetBoxPosition( ghDiseaseBox, pPoint ); + } + // HEADROCK HAM 3.6: Facility Menu if( fShowFacilityMenu ) { diff --git a/Strategic/Map Screen Interface.h b/Strategic/Map Screen Interface.h index 9a2bf3a2..56939de5 100644 --- a/Strategic/Map Screen Interface.h +++ b/Strategic/Map Screen Interface.h @@ -122,6 +122,7 @@ enum{ enum { ASSIGN_MENU_ON_DUTY=0, ASSIGN_MENU_DOCTOR, + ASSIGN_MENU_DOCTOR_DIAGNOSIS, // added by Flugente ASSIGN_MENU_PATIENT, ASSIGN_MENU_VEHICLE, ASSIGN_MENU_REPAIR, diff --git a/Strategic/MilitiaSquads.cpp b/Strategic/MilitiaSquads.cpp index 4f1f1dac..cd80892b 100644 --- a/Strategic/MilitiaSquads.cpp +++ b/Strategic/MilitiaSquads.cpp @@ -615,6 +615,9 @@ void MoveMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, BOOL UINT8 regulars = max(0, bRegularsDestTeam - pTSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ]); UINT8 greens = max(0, bGreensDestTeam - pTSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ]); MoveMilitiaEquipment(sMapX, sMapY, sTMapX, sTMapY, elites, regulars, greens); + + // Flugente: disease + PopulationMove( sMapX, sMapY, sTMapX, sTMapY, elites + regulars + greens ); // Erase ALL militia from both locations. StrategicRemoveMilitiaFromSector( sMapX, sMapY, GREEN_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] ); @@ -651,6 +654,9 @@ void MoveMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, BOOL UINT8 greens = max(0, bGreensDestTeam - pTSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ]); MoveMilitiaEquipment(sMapX, sMapY, sTMapX, sTMapY, elites, regulars, greens); + // Flugente: disease + PopulationMove( sMapX, sMapY, sTMapX, sTMapY, elites + regulars + greens ); + // Add half team to target sector StrategicAddMilitiaToSector( sTMapX, sTMapY, GREEN_MILITIA, bGreensDestTeam ); StrategicAddMilitiaToSector( sTMapX, sTMapY, REGULAR_MILITIA, bRegularsDestTeam ); @@ -734,6 +740,9 @@ void MoveMilitiaSquad(INT16 sMapX, INT16 sMapY, INT16 sTMapX, INT16 sTMapY, BOOL UINT8 greens = max(0, bGreensDestTeam - pTSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ]); MoveMilitiaEquipment(sMapX, sMapY, sTMapX, sTMapY, elites, regulars, greens); + // Flugente: disease + PopulationMove( sMapX, sMapY, sTMapX, sTMapY, elites + regulars + greens ); + // Erase ALL militia from both locations. StrategicRemoveMilitiaFromSector( sMapX, sMapY, GREEN_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ GREEN_MILITIA ] ); StrategicRemoveMilitiaFromSector( sMapX, sMapY, REGULAR_MILITIA, pSectorInfo->ubNumberOfCivsAtLevel[ REGULAR_MILITIA ] ); @@ -2770,6 +2779,9 @@ void MobileMilitiaDeserters(INT16 sMapX, INT16 sMapY, BOOLEAN fDeleteEquip, BOOL } } + // Flugente: disease + PopulationMove( sMapX, sMapY, -1, -1, desertersGreen + desertersRegular ); + /////////////////////////// //notify player if ( fPrintMessage ) diff --git a/Strategic/Queen Command.cpp b/Strategic/Queen Command.cpp index 7ed4ee93..8424f519 100644 --- a/Strategic/Queen Command.cpp +++ b/Strategic/Queen Command.cpp @@ -108,7 +108,7 @@ void ValidateEnemiesHaveWeapons() SOLDIERTYPE *pSoldier; INT32 iNumInvalid = 0; - for( i = gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID; i <= gTacticalStatus.Team[ ENEMY_TEAM ].bLastID; i++ ) + for( i = gTacticalStatus.Team[ ENEMY_TEAM ].bFirstID; i <= gTacticalStatus.Team[ ENEMY_TEAM ].bLastID; ++i ) { pSoldier = MercPtrs[ i ]; if( !pSoldier->bActive || !pSoldier->bInSector ) @@ -116,15 +116,13 @@ void ValidateEnemiesHaveWeapons() continue; } -#ifdef ENABLE_ZOMBIES // Flugente: zombies are fine with having no weapons... if ( pSoldier->IsZombie() ) continue; -#endif if( !pSoldier->inv[ HANDPOS ].usItem ) { - iNumInvalid++; + ++iNumInvalid; } // WDS DEBUG // Uncommenting the following two lines will cause all the PLACED soldiers to instantly drop dead, @@ -552,7 +550,7 @@ BOOLEAN PrepareEnemyForSectorBattle() GROUP *pGroup; SOLDIERTYPE *pSoldier; unsigned ubNumAdmins, ubNumTroops, ubNumElites, ubNumTanks; - unsigned ubTotalAdmins, ubTotalElites, ubTotalTroops, ubTotalTanks; + unsigned ubTotalAdmins, ubTotalElites, ubTotalTroops, ubTotalTanks = 0; unsigned totalCountOfStationaryEnemies = 0; unsigned totalCountOfMobileEnemies = 0; int sNumSlots; @@ -611,9 +609,9 @@ BOOLEAN PrepareEnemyForSectorBattle() { HandleArrivalOfReinforcements( pGroup ); } + pGroup = pGroup->next; } - } ValidateEnemiesHaveWeapons(); @@ -623,8 +621,10 @@ BOOLEAN PrepareEnemyForSectorBattle() // WDS Count the number of placements. This will limit the maximum number of enemies we can place on the map SOLDIERINITNODE *curr = gSoldierInitHead; unsigned mapMaximumNumberOfEnemies = 0; - while( curr ) { - if( curr->pBasicPlacement->bTeam == ENEMY_TEAM ) { + while( curr ) + { + if( curr->pBasicPlacement->bTeam == ENEMY_TEAM ) + { ++mapMaximumNumberOfEnemies; } curr = curr->next; @@ -653,8 +653,8 @@ BOOLEAN PrepareEnemyForSectorBattle() while (totalEnemies < mapMaximumNumberOfEnemies) { // just fill out with standard troops - ubTotalTroops++; - totalEnemies++; + ++ubTotalTroops; + ++totalEnemies; } pSector->ubNumAdmins = ubTotalAdmins; @@ -668,39 +668,38 @@ BOOLEAN PrepareEnemyForSectorBattle() } else { - - if( pSector->uiFlags & SF_USE_MAP_SETTINGS ) - { //count the number of enemy placements in a map and use those - SOLDIERINITNODE *curr = gSoldierInitHead; - ubTotalAdmins = ubTotalTroops = ubTotalElites = 0; - while( curr ) - { - if( curr->pBasicPlacement->bTeam == ENEMY_TEAM ) + if( pSector->uiFlags & SF_USE_MAP_SETTINGS ) + { //count the number of enemy placements in a map and use those + SOLDIERINITNODE *curr = gSoldierInitHead; + ubTotalAdmins = ubTotalTroops = ubTotalElites = 0; + while( curr ) { - switch( curr->pBasicPlacement->ubSoldierClass ) + if( curr->pBasicPlacement->bTeam == ENEMY_TEAM ) { - case SOLDIER_CLASS_ADMINISTRATOR: ubTotalAdmins++; break; - case SOLDIER_CLASS_ARMY: ubTotalTroops++; break; - case SOLDIER_CLASS_ELITE: ubTotalElites++; break; + switch( curr->pBasicPlacement->ubSoldierClass ) + { + case SOLDIER_CLASS_ADMINISTRATOR: ubTotalAdmins++; break; + case SOLDIER_CLASS_ARMY: ubTotalTroops++; break; + case SOLDIER_CLASS_ELITE: ubTotalElites++; break; + } } + curr = curr->next; } - curr = curr->next; + pSector->ubNumAdmins = ubTotalAdmins; + pSector->ubNumTroops = ubTotalTroops; + pSector->ubNumElites = ubTotalElites; + pSector->ubNumTanks = ubTotalTanks; + pSector->ubAdminsInBattle = 0; + pSector->ubTroopsInBattle = 0; + pSector->ubElitesInBattle = 0; + pSector->ubTanksInBattle = 0; } - pSector->ubNumAdmins = ubTotalAdmins; - pSector->ubNumTroops = ubTotalTroops; - pSector->ubNumElites = ubTotalElites; - pSector->ubNumTanks = ubTotalTanks; - pSector->ubAdminsInBattle = 0; - pSector->ubTroopsInBattle = 0; - pSector->ubElitesInBattle = 0; - pSector->ubTanksInBattle = 0; - } - else - { - ubTotalAdmins = pSector->ubNumAdmins - pSector->ubAdminsInBattle; - ubTotalTroops = pSector->ubNumTroops - pSector->ubTroopsInBattle; - ubTotalElites = pSector->ubNumElites - pSector->ubElitesInBattle; - ubTotalTanks = pSector->ubNumTanks - pSector->ubTanksInBattle; + else + { + ubTotalAdmins = pSector->ubNumAdmins - pSector->ubAdminsInBattle; + ubTotalTroops = pSector->ubNumTroops - pSector->ubTroopsInBattle; + ubTotalElites = pSector->ubNumElites - pSector->ubElitesInBattle; + ubTotalTanks = pSector->ubNumTanks - pSector->ubTanksInBattle; } } @@ -726,7 +725,7 @@ BOOLEAN PrepareEnemyForSectorBattle() pSector->ubElitesInBattle += ubTotalElites; pSector->ubTanksInBattle += ubTotalTanks; - #ifdef JA2TESTVERSION +#ifdef JA2TESTVERSION if( gfOverrideSector ) { //if there are no troops in the current groups, then we're done. @@ -736,7 +735,7 @@ BOOLEAN PrepareEnemyForSectorBattle() ValidateEnemiesHaveWeapons(); return TRUE; } - #endif +#endif //Search for movement groups that happen to be in the sector. sNumSlots = NumFreeEnemySlots(); @@ -1758,8 +1757,8 @@ void AddPossiblePendingEnemiesToBattle() // The group has no movement orders. Where did it come from? Assert(0); } - - if( pGroup->pEnemyGroup->ubElitesInBattle < pGroup->pEnemyGroup->ubNumElites ) + + if ( pGroup->pEnemyGroup->ubElitesInBattle < pGroup->pEnemyGroup->ubNumElites ) { //Add an elite troop pGroup->pEnemyGroup->ubElitesInBattle++; ubSlots--; diff --git a/Strategic/Quests.h b/Strategic/Quests.h index f8e1d129..006d334b 100644 --- a/Strategic/Quests.h +++ b/Strategic/Quests.h @@ -554,6 +554,11 @@ enum Facts FACT_WALDO_MET, + // Flugente: disease + FACT_DISEASE_VIEWED, + FACT_DISEASE_WHODATA_SUBSCRIBED, // if we are currently subscripted, we will pay x$ per day + FACT_DISEASE_WHODATA_ACCESS, // do we currently have access to the data + #ifdef JA2UB //Ja25 UB diff --git a/Strategic/Reinforcement.cpp b/Strategic/Reinforcement.cpp index c4389a83..d4e50722 100644 --- a/Strategic/Reinforcement.cpp +++ b/Strategic/Reinforcement.cpp @@ -261,6 +261,9 @@ UINT8 DoReinforcementAsPendingEnemy( INT16 sMapX, INT16 sMapY ) { while ((pGroup = GetEnemyGroupInSector( SECTORX( pusMoveDir[ ubIndex][ 0 ] ), SECTORY( pusMoveDir[ ubIndex ][ 0 ] ) ) ) != NULL) { + // Flugente: disease + PopulationMove( pGroup->ubSectorX, pGroup->ubSectorY, sMapX, sMapY, pGroup->ubGroupSize ); + pGroup->ubPrevX = pGroup->ubSectorX; pGroup->ubPrevY = pGroup->ubSectorY; @@ -269,7 +272,7 @@ UINT8 DoReinforcementAsPendingEnemy( INT16 sMapX, INT16 sMapY ) gfPendingEnemies = TRUE; ResetMortarsOnTeamCount(); - ResetNumSquadleadersInArmyGroup(); // added by SANDRO + ResetNumSquadleadersInArmyGroup(); // added by SANDRO } } diff --git a/Strategic/Strategic Merc Handler.cpp b/Strategic/Strategic Merc Handler.cpp index e19c6187..0bc5f93b 100644 --- a/Strategic/Strategic Merc Handler.cpp +++ b/Strategic/Strategic Merc Handler.cpp @@ -614,6 +614,9 @@ void MercDailyUpdate() // Flugente: dynmaic opinion rollover HandleDynamicOpinionsDailyRefresh( ); + + // Flugente: disease + HandleDiseaseDailyRefresh(); } /* diff --git a/Strategic/Strategic Mines.cpp b/Strategic/Strategic Mines.cpp index eb0fb30d..c8694877 100644 --- a/Strategic/Strategic Mines.cpp +++ b/Strategic/Strategic Mines.cpp @@ -510,13 +510,11 @@ INT32 GetAvailableWorkForceForMineForPlayer( INT8 bMineIndex ) return ( 0 ); } - //bTownId = gMineLocation[ bMineIndex ].bAssociatedTown; bTownId = gMineStatus[ bMineIndex ].bAssociatedTown; Assert ( GetTownSectorSize( bTownId ) != 0 ); - // get workforce size (is 0-100 based on local town's loyalty) iWorkForceSize = gTownLoyalty[ bTownId ].ubRating; @@ -526,6 +524,9 @@ INT32 GetAvailableWorkForceForMineForPlayer( INT8 bMineIndex ) iWorkForceSize /= 100; */ + // Flugente: if strategic disease is active, disease can affect out workforce, so the calculation gets slightly more complicated + iWorkForceSize *= GetWorkforceEffectivenessWithDisease( bTownId, OUR_TEAM ); + // now adjust for town size.. the number of sectors you control iWorkForceSize *= GetTownSectorsUnderControl( bTownId ); iWorkForceSize /= GetTownSectorSize( bTownId ); diff --git a/Strategic/Strategic Movement.cpp b/Strategic/Strategic Movement.cpp index dfbb623f..d37dc087 100644 --- a/Strategic/Strategic Movement.cpp +++ b/Strategic/Strategic Movement.cpp @@ -1684,8 +1684,6 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe } } - - while( curr ) { curr->pSoldier->flags.uiStatusFlags &= ~SOLDIER_SHOULD_BE_TACTICALLY_VALID; @@ -1717,6 +1715,7 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe } } } + //Check for exception cases which if( gTacticalStatus.bBoxingState != NOT_BOXING ) { @@ -1725,6 +1724,7 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe fExceptionQueue = TRUE; } } + //First check if the group arriving is going to queue another battle. //NOTE: We can't have more than one battle ongoing at a time. if( fExceptionQueue || fCheckForBattle && gTacticalStatus.fEnemyInSector && @@ -1773,6 +1773,11 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe return; } + // Flugente: disease + if ( !pGroup->fPlayer ) + { + PopulationMove( pGroup->ubSectorX, pGroup->ubSectorY, pGroup->ubNextX, pGroup->ubNextY, pGroup->ubGroupSize ); + } //Update the position of the group pGroup->ubPrevX = pGroup->ubSectorX; @@ -1782,7 +1787,6 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe pGroup->ubNextX = 0; pGroup->ubNextY = 0; - if( pGroup->fPlayer ) { if( pGroup->ubSectorZ == 0 ) @@ -1828,7 +1832,6 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe fMapPanelDirty = TRUE; fMapScreenBottomDirty = TRUE; - // if a player group if( pGroup->fPlayer ) { @@ -1867,7 +1870,6 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe #endif } - if( pGroup->ubSectorX < pGroup->ubPrevX ) { ubInsertionDirection = SOUTHWEST; @@ -1894,7 +1896,6 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe return; } - if( pGroup->fVehicle == FALSE ) { // non-vehicle player group @@ -1974,7 +1975,6 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe // update passengers position UpdatePositionOfMercsInVehicle( iVehId ); - if( iVehId != iHelicopterVehicleId ) { pSoldier = GetSoldierStructureForVehicle( iVehId ); @@ -1998,8 +1998,6 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe UpdateMercInSector( pSoldier, gWorldSectorX, gWorldSectorY, gbWorldSectorZ ); } - - // set directions of insertion curr = pGroup->pPlayerList; while( curr ) @@ -2034,7 +2032,6 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe } } - if ( !fGroupDestroyed ) { // don't print any messages when arriving underground, there's no delay involved @@ -2047,7 +2044,6 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe } } - if ( !fGroupDestroyed ) { // check if sector had been visited previously @@ -2157,16 +2153,15 @@ void GroupArrivedAtSector( UINT8 ubGroupID, BOOLEAN fCheckForBattle, BOOLEAN fNe void HandleNonCombatGroupArrival( GROUP *pGroup, BOOLEAN fMainGroup, BOOLEAN fNeverLeft ) { // if any mercs are actually in the group - - #ifdef JA2UB +#ifdef JA2UB //Ja25 No strategic ai - #else +#else if( StrategicAILookForAdjacentGroups( pGroup ) ) { //The routine actually just deleted the enemy group (player's don't get deleted), so we are done! return; } - #endif +#endif if( pGroup->fPlayer ) { @@ -2203,7 +2198,6 @@ void HandleNonCombatGroupArrival( GROUP *pGroup, BOOLEAN fMainGroup, BOOLEAN fNe } } - //MilitiaFollowPlayer( pGroup->ubPrevX, pGroup->ubPrevY, pGroup->ubSectorX, pGroup->ubSectorY ); // look for NPCs to stop for, anyone is too tired to keep going, if all OK rebuild waypoints & continue movement @@ -2313,6 +2307,7 @@ void PrepareGroupsForSimultaneousArrival() } pGroup = pGroup->next; } + //We still have the first group that has arrived. Because they are set up to be in the destination //sector, we will "warp" them back to the last sector, and also setup a new arrival time for them. pGroup = gpPendingSimultaneousGroup; @@ -2388,7 +2383,8 @@ BOOLEAN PossibleToCoordinateSimultaneousGroupArrivals( GROUP *pFirstGroup ) } if( ubNumNearbyGroups ) - { //postpone the battle until the user answers the dialog. + { + //postpone the battle until the user answers the dialog. CHAR16 str[255]; STR16 pStr, pEnemyType; InterruptTime(); @@ -2412,6 +2408,7 @@ BOOLEAN PossibleToCoordinateSimultaneousGroupArrivals( GROUP *pFirstGroup ) { pEnemyType = gpStrategicString[ STR_PB_ENEMIES ]; } + //header, sector, singular/plural str, confirmation string. //Ex: Enemies have been detected in sector J9 and another squad is // about to arrive. Do you wish to coordinate a simultaneous arrival? @@ -2430,6 +2427,7 @@ BOOLEAN PossibleToCoordinateSimultaneousGroupArrivals( GROUP *pFirstGroup ) gfWaitingForInput = TRUE; return TRUE; } + return FALSE; } @@ -2443,6 +2441,7 @@ void PlanSimultaneousGroupArrivalCallback( UINT8 bMessageValue ) { PrepareForPreBattleInterface( gpPendingSimultaneousGroup, gpPendingSimultaneousGroup ); } + UnLockPauseState(); UnPauseGame(); } @@ -2454,14 +2453,17 @@ void DelayEnemyGroupsIfPathsCross( GROUP *pPlayerGroup ) while( pGroup ) { if( !pGroup->fPlayer ) - { //then check to see if this group will arrive in next sector before the player group. + { + //then check to see if this group will arrive in next sector before the player group. if( pGroup->uiArrivalTime < pPlayerGroup->uiArrivalTime ) - { //check to see if enemy group will cross paths with player group. + { + //check to see if enemy group will cross paths with player group. if( pGroup->ubNextX == pPlayerGroup->ubSectorX && pGroup->ubNextY == pPlayerGroup->ubSectorY && pGroup->ubSectorX == pPlayerGroup->ubNextX && pGroup->ubSectorY == pPlayerGroup->ubNextY ) - { //Okay, the enemy group will cross paths with the player, so find and delete the arrival event + { + //Okay, the enemy group will cross paths with the player, so find and delete the arrival event //and repost it in the future (like a minute or so after the player arrives) DeleteStrategicEvent( EVENT_GROUP_ARRIVAL, pGroup->ubGroupID ); @@ -2473,6 +2475,7 @@ void DelayEnemyGroupsIfPathsCross( GROUP *pPlayerGroup ) } } } + pGroup = pGroup->next; } } @@ -2489,12 +2492,12 @@ void InitiateGroupMovementToNextSector( GROUP *pGroup ) SOLDIERTYPE *pSoldier = NULL; UINT32 uiSleepMinutes = 0; - Assert( pGroup ); i = pGroup->ubNextWaypointID; wp = pGroup->pWaypoints; while( i-- ) - { //Traverse through the waypoint list to the next waypoint ID + { + //Traverse through the waypoint list to the next waypoint ID Assert( wp ); wp = wp->next; } @@ -2610,8 +2613,7 @@ void InitiateGroupMovementToNextSector( GROUP *pGroup ) pGroup->uiTraverseTime = 1 + Random( pGroup->uiTraverseTime - 1 ); SetGroupArrivalTime( pGroup, GetWorldTotalMin() + pGroup->uiTraverseTime ); } - - + if( pGroup->fVehicle == TRUE ) { // vehicle, set fact it is between sectors too @@ -2626,7 +2628,6 @@ void InitiateGroupMovementToNextSector( GROUP *pGroup ) // OK, Remove the guy from tactical engine! RemoveSoldierFromTacticalSector( pSoldier, TRUE ); - } } } @@ -2707,8 +2708,6 @@ void SetWayPointsAsCanceled( UINT8 ubGroupID ) Assert( pGroup ); //pGroup->fWaypointsCancelled = TRUE; - - return; } @@ -2722,7 +2721,6 @@ void SetGroupPrevSectors( UINT8 ubGroupID, UINT8 ubX, UINT8 ubY ) // since we have a group, set prev sector's x and y pGroup->ubPrevX = ubX; pGroup->ubPrevY = ubY; - } @@ -2759,7 +2757,6 @@ void RemovePGroup( GROUP *pGroup ) curr->next = pGroup->next; } - //Remove the waypoints. RemovePGroupWaypoints( pGroup ); @@ -2944,8 +2941,7 @@ INT32 CalculateTravelTimeOfGroup( GROUP *pGroup ) // not going anywhere...return current time return( uiEtaTime ); } - - + // if already on the road if ( pGroup->fBetweenSectors ) { @@ -2993,7 +2989,6 @@ INT32 FindTravelTimeBetweenWaypoints( WAYPOINT * pSource, WAYPOINT * pDest, GROU UINT8 ubDirection; INT32 iThisCostInTime; - // find travel time between waypoints if( !pSource || !pDest ) { @@ -3082,7 +3077,6 @@ INT32 GetSectorMvtTimeForGroup( UINT8 ubSector, UINT8 ubDirection, GROUP *pGroup UINT8 ubTraverseType; UINT8 ubTraverseMod; - // THIS FUNCTION WAS WRITTEN TO HANDLE MOVEMENT TYPES WHERE MORE THAN ONE TRANSPORTAION TYPE IS AVAILABLE. //Determine the group's method(s) of tranportation. If more than one, @@ -3153,6 +3147,7 @@ INT32 GetSectorMvtTimeForGroup( UINT8 ubSector, UINT8 ubDirection, GROUP *pGroup } } } + if( fCar ) { switch( ubTraverseType ) @@ -3166,6 +3161,7 @@ INT32 GetSectorMvtTimeForGroup( UINT8 ubSector, UINT8 ubDirection, GROUP *pGroup if( iTraverseTime < iBestTraverseTime ) iBestTraverseTime = iTraverseTime; } + if( fTruck ) { switch( ubTraverseType ) @@ -3182,6 +3178,7 @@ INT32 GetSectorMvtTimeForGroup( UINT8 ubSector, UINT8 ubDirection, GROUP *pGroup if( iTraverseTime < iBestTraverseTime ) iBestTraverseTime = iTraverseTime; } + if( fTracked ) { switch( ubTraverseType ) @@ -3202,6 +3199,7 @@ INT32 GetSectorMvtTimeForGroup( UINT8 ubSector, UINT8 ubDirection, GROUP *pGroup if( iTraverseTime < iBestTraverseTime ) iBestTraverseTime = iTraverseTime; } + if( fAir ) { iTraverseTime = AIR_TRAVEL_TIME; @@ -3303,7 +3301,7 @@ UINT8 PlayerMercsInSector( UINT8 ubSectorX, UINT8 ubSectorY, UINT8 ubSectorZ ) // robots count as mercs here, because they can fight, but vehicles don't if( ( pPlayer->pSoldier->stats.bLife ) && !( pPlayer->pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE ) ) { - ubNumMercs++; + ++ubNumMercs; } pPlayer = pPlayer->next; } @@ -3332,7 +3330,7 @@ UINT8 PlayerGroupsInSector( UINT8 ubSectorX, UINT8 ubSectorY, UINT8 ubSectorZ ) { if( pPlayer->pSoldier->stats.bLife ) { - ubNumGroups++; + ++ubNumGroups; break; } pPlayer = pPlayer->next; @@ -3341,6 +3339,7 @@ UINT8 PlayerGroupsInSector( UINT8 ubSectorX, UINT8 ubSectorY, UINT8 ubSectorZ ) } pGroup = pGroup->next; } + return ubNumGroups; } @@ -3348,10 +3347,8 @@ UINT8 PlayerGroupsInSector( UINT8 ubSectorX, UINT8 ubSectorY, UINT8 ubSectorZ ) // is the player group with this id in motion? BOOLEAN PlayerIDGroupInMotion( UINT8 ubID ) { - GROUP *pGroup; - // get the group - pGroup = GetGroup( ubID ); + GROUP* pGroup = GetGroup( ubID ); // make sure it is valid @@ -3361,7 +3358,6 @@ BOOLEAN PlayerIDGroupInMotion( UINT8 ubID ) return ( FALSE ); } - return( PlayerGroupInMotion( pGroup ) ); } @@ -3394,7 +3390,6 @@ INT32 GetTravelTimeForFootTeam( UINT8 ubSector, UINT8 ubDirection ) Group.ubTransportationMask = FOOT; return( GetSectorMvtTimeForGroup( ubSector, ubDirection, &( Group ) ) ); - } //Add this group to the current battle fray! @@ -3444,7 +3439,7 @@ void HandleArrivalOfReinforcements( GROUP *pGroup ) { TacticalCharacterDialogue( pSoldier, QUOTE_MERC_REACHED_DESTINATION ); } - cnt++; + ++cnt; } ScreenMsg( FONT_YELLOW, MSG_INTERFACE, Message[ STR_PLAYER_REINFORCEMENTS ] ); @@ -3482,12 +3477,10 @@ BOOLEAN PlayersBetweenTheseSectors( INT16 sSource, INT16 sDest, INT32 *iCountEnt BOOLEAN fHelicopterGroup = FALSE; UINT8 ubMercsInGroup = 0; - *iCountEnter = 0; *iCountExit = 0; *fAboutToArriveEnter = FALSE; - if( gpBattleGroup ) { // Assert( gfPreBattleInterfaceActive ); @@ -3500,7 +3493,6 @@ BOOLEAN PlayersBetweenTheseSectors( INT16 sSource, INT16 sDest, INT32 *iCountEnt // Assert( gfPreBattleInterfaceActive ); } - // get number of characters entering/existing between these two sectors. Special conditions during // pre-battle interface to return where this function is used to show potential retreating directions instead! @@ -3576,10 +3568,8 @@ BOOLEAN PlayersBetweenTheseSectors( INT16 sSource, INT16 sDest, INT32 *iCountEnt { return ( TRUE ); } - else - { - return( FALSE ); - } + + return( FALSE ); } void MoveAllGroupsInCurrentSectorToSector( UINT8 ubSectorX, UINT8 ubSectorY, UINT8 ubSectorZ ) @@ -3639,9 +3629,6 @@ void GetGroupPosition( UINT8 *ubNextX, UINT8 *ubNextY, UINT8 *ubPrevX, UINT8 *ub *ubPrevY = pGroup->ubPrevY; *uiTraverseTime = pGroup->uiTraverseTime; *uiArriveTime = pGroup->uiArrivalTime; - - - return; } @@ -3651,14 +3638,12 @@ void SetGroupPosition( UINT8 ubNextX, UINT8 ubNextY, UINT8 ubPrevX, UINT8 ubPrev GROUP *pGroup; PLAYERGROUP *pPlayer; - // get the group pGroup = GetGroup( ubGroupId ); // no group if( pGroup == NULL ) { - return; } @@ -3671,7 +3656,6 @@ void SetGroupPosition( UINT8 ubNextX, UINT8 ubNextY, UINT8 ubPrevX, UINT8 ubPrev SetGroupArrivalTime( pGroup, uiArriveTime ); pGroup->fBetweenSectors = TRUE; - AddWaypointToPGroup( pGroup, pGroup->ubNextX, pGroup->ubNextY ); //now, if player group set all grunts in the group to be between secotrs if( pGroup->fPlayer == TRUE ) @@ -3683,9 +3667,6 @@ void SetGroupPosition( UINT8 ubNextX, UINT8 ubNextY, UINT8 ubPrevX, UINT8 ubPrev pPlayer = pPlayer->next; } } - - - return; } BOOLEAN SaveStrategicMovementGroupsToSaveGameFile( HWFILE hFile ) @@ -3699,11 +3680,10 @@ BOOLEAN SaveStrategicMovementGroupsToSaveGameFile( HWFILE hFile ) //Count the number of active groups while( pGroup ) { - uiNumberOfGroups++; + ++uiNumberOfGroups; pGroup = pGroup->next; } - // Save the number of movement groups to the saved game file FileWrite( hFile, &uiNumberOfGroups, sizeof( UINT32 ), &uiNumBytesWritten ); if( uiNumBytesWritten != sizeof( UINT32 ) ) @@ -3712,7 +3692,6 @@ BOOLEAN SaveStrategicMovementGroupsToSaveGameFile( HWFILE hFile ) return( FALSE ); } - pGroup = gpGroupList; //Loop through the linked lists and add each node @@ -3751,9 +3730,7 @@ BOOLEAN SaveStrategicMovementGroupsToSaveGameFile( HWFILE hFile ) //Save the waypoint list for the group, if they have one SaveWayPointList( hFile, pGroup ); - - - + pGroup = pGroup->next; } @@ -3765,7 +3742,6 @@ BOOLEAN SaveStrategicMovementGroupsToSaveGameFile( HWFILE hFile ) return( FALSE ); } - return( TRUE ); } @@ -3785,13 +3761,10 @@ BOOLEAN LoadStrategicMovementGroupsFromSavedGameFile( HWFILE hFile ) UINT8 ubNumPlayerGroupsFull = 0; UINT8 ubNumEnemyGroupsFull = 0; - - //delete the existing group list while( gpGroupList ) RemoveGroupFromList( gpGroupList ); - //load the number of nodes in the list FileRead( hFile, &uiNumberOfGroups, sizeof( UINT32 ), &uiNumBytesRead ); if( uiNumBytesRead != sizeof( UINT32 ) ) @@ -3819,7 +3792,6 @@ BOOLEAN LoadStrategicMovementGroupsFromSavedGameFile( HWFILE hFile ) return( FALSE ); } - // // Add either the pointer or the linked list. // @@ -3838,11 +3810,9 @@ BOOLEAN LoadStrategicMovementGroupsFromSavedGameFile( HWFILE hFile ) LoadEnemyGroupStructFromSavedGame( hFile, pTemp ); } - //Save the waypoint list for the group, if they have one LoadWayPointList( hFile, pTemp ); - - + pTemp->next = NULL; //add the node to the list @@ -3873,22 +3843,22 @@ BOOLEAN LoadStrategicMovementGroupsFromSavedGameFile( HWFILE hFile ) { if( pGroup->ubGroupSize ) { - ubNumPlayerGroupsFull++; + ++ubNumPlayerGroupsFull; } else { - ubNumPlayerGroupsEmpty++; + ++ubNumPlayerGroupsEmpty; } } else { if( pGroup->ubGroupSize ) { - ubNumEnemyGroupsFull++; + ++ubNumEnemyGroupsFull; } else { - ubNumEnemyGroupsEmpty++; + ++ubNumEnemyGroupsEmpty; } } if( ubNumPlayerGroupsEmpty || ubNumEnemyGroupsEmpty ) @@ -3980,16 +3950,14 @@ BOOLEAN LoadPlayerGroupList( HWFILE hFile, GROUP **pGroup ) return( FALSE ); } - //loop through all the nodes and set them up - for( cnt=0; cnt< uiNumberOfNodes; cnt++) + for( cnt=0; cnt< uiNumberOfNodes; ++cnt) { //allcate space for the current node pTemp = (PLAYERGROUP *) MemAlloc( sizeof( PLAYERGROUP ) ); if( pTemp == NULL ) return( FALSE ); - // Load the ubProfile ID for this node FileRead( hFile, &uiProfileID, sizeof( UINT32 ), &uiNumBytesRead ); if( uiNumBytesRead != sizeof( UINT32 ) ) @@ -4115,12 +4083,11 @@ void CheckMembersOfMvtGroupAndComplainAboutBleeding( SOLDIERTYPE *pSoldier ) // complain about bleeding TacticalCharacterDialogue( pCurrentSoldier, QUOTE_STARTING_TO_BLEED ); } - pPlayer = pPlayer->next; + pPlayer = pPlayer->next; } BeginLoggingForBleedMeToos( FALSE ); - } @@ -4134,7 +4101,7 @@ BOOLEAN SaveWayPointList( HWFILE hFile, GROUP *pGroup ) //loop trhough and count all the node in the waypoint list while( pWayPoints != NULL ) { - uiNumberOfWayPoints++; + ++uiNumberOfWayPoints; pWayPoints = pWayPoints->next; } @@ -4146,11 +4113,10 @@ BOOLEAN SaveWayPointList( HWFILE hFile, GROUP *pGroup ) return( FALSE ); } - if( uiNumberOfWayPoints ) { pWayPoints = pGroup->pWaypoints; - for(cnt=0; cntpWaypoints; WAYPOINT *pTemp=NULL; - //Load the number of waypoints FileRead( hFile, &uiNumberOfWayPoints, sizeof( UINT32 ), &uiNumBytesRead ); if( uiNumBytesRead != sizeof( UINT32 ) ) @@ -4187,7 +4152,6 @@ BOOLEAN LoadWayPointList(HWFILE hFile, GROUP *pGroup ) return( FALSE ); } - if( uiNumberOfWayPoints ) { pWayPoints = pGroup->pWaypoints; @@ -4207,10 +4171,8 @@ BOOLEAN LoadWayPointList(HWFILE hFile, GROUP *pGroup ) return( FALSE ); } - pTemp->next = NULL; - //if its the first node if( cnt == 0 ) { @@ -4269,6 +4231,7 @@ void CalculateGroupRetreatSector( GROUP *pGroup ) AssertMsg( 0, String("Player group cannot retreat from sector %c%d ", pGroup->ubSectorY+'A'-1, pGroup->ubSectorX ) ); return; } + if( pGroup->fPlayer ) { //update the previous sector for the mercs PLAYERGROUP *pPlayer; @@ -4363,7 +4326,6 @@ void RetreatGroupToPreviousSector( GROUP *pGroup ) AddStrategicEvent( EVENT_GROUP_ABOUT_TO_ARRIVE, pGroup->uiArrivalTime - ABOUT_TO_ARRIVE_DELAY, pGroup->ubGroupID ); } - while( curr ) { curr->pSoldier->flags.fBetweenSectors = TRUE; @@ -4429,14 +4391,12 @@ BOOLEAN GroupAtFinalDestination( GROUP *pGroup ) WAYPOINT *GetFinalWaypoint( GROUP *pGroup ) { - WAYPOINT *wp; - Assert( pGroup ); //Make sure they're on a one way route, otherwise this request is illegal Assert( pGroup->ubMoveType == ONE_WAY ); - wp = pGroup->pWaypoints; + WAYPOINT* wp = pGroup->pWaypoints; if( wp ) { while( wp->next ) @@ -4488,11 +4448,12 @@ void ResetMovementForEnemyGroup( GROUP *pGroup ) if( !pGroup->fBetweenSectors || !pGroup->ubNextX || !pGroup->ubNextY ) { //Reset the group's assignment by moving it to the group's original sector as it's pending group. - #ifdef JA2UB +#ifdef JA2UB //Ja25 No strategic ai - #else +#else RepollSAIGroup( pGroup ); - #endif +#endif + return; } diff --git a/Strategic/XML_SectorNames.cpp b/Strategic/XML_SectorNames.cpp index bd94fc21..c60a345f 100644 --- a/Strategic/XML_SectorNames.cpp +++ b/Strategic/XML_SectorNames.cpp @@ -27,17 +27,9 @@ extern SECTOR_EXT_DATA SectorExternalData[256][4]; //extern CHAR16 gzSectorUndergroundNames2[256][4][MAX_SECTOR_NAME_LENGTH]; //extern CHAR16 gzSectorUndergroundNames3[256][4][MAX_SECTOR_NAME_LENGTH]; -typedef enum -{ - SECTORNAME_ELEMENT_NONE = 0, - SECTORNAME_ELEMENT_SECTOR_NAMES, - SECTORNAME_ELEMENT_SECTOR, - SECTORNAME_ELEMENT, -} SECTORNAME_PARSE_STAGE; - typedef struct { - SECTORNAME_PARSE_STAGE curElement; + PARSE_STAGE curElement; CHAR8 szCharData[MAX_CHAR_DATA_LENGTH+1]; UINT8 sCurSectorX; UINT8 sCurSectorY; @@ -45,15 +37,13 @@ typedef struct CHAR16 szCurDetailedUnexploredName[MAX_SECTOR_NAME_LENGTH]; CHAR16 szCurExploredName[MAX_SECTOR_NAME_LENGTH]; CHAR16 szCurDetailedExploredName[MAX_SECTOR_NAME_LENGTH]; - UINT8 sWaterType; // Food System - UINT16 usNaturalDirt; // Dirt System - UINT8 usCurfewValue; // Covert Ops - INT8 sRadioScanModifier; // Radio Operator - UINT16 usPrisonRoomNumber[MAX_PRISON_ROOMS]; // Prisoner System + SECTOR_EXT_DATA sectordata; + UINT8 curSupplyType; UINT32 currentDepth; UINT32 maxReadDepth; } SectorNameParseData; + BOOLEAN SectorName_TextOnly; INT8 Sector_Level; @@ -67,9 +57,9 @@ SectorNameStartElementHandle(void *userData, const XML_Char *name, const char ** if(pData->currentDepth <= pData->maxReadDepth) //are we reading this element? { - if(strcmp(name, "SECTOR_NAMES") == 0 && pData->curElement == SECTORNAME_ELEMENT_NONE) + if(strcmp(name, "SECTOR_NAMES") == 0 && pData->curElement == ELEMENT_NONE) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR_NAMES; + pData->curElement = ELEMENT_LIST; pData->maxReadDepth++; //we are not skipping this element // Initiate Array by setting first character to 0. for (UINT16 x = 0; x < 256; x++) @@ -104,40 +94,16 @@ SectorNameStartElementHandle(void *userData, const XML_Char *name, const char ** gzSectorNames[x][2][0]=0; gzSectorNames[x][3][0]=0; } - - // moved to lua - //if (Sector_Level == 1 ) - //{ - // gzSectorUndergroundNames1[x][0][0]=0; - // gzSectorUndergroundNames1[x][1][0]=0; - // gzSectorUndergroundNames1[x][2][0]=0; - // gzSectorUndergroundNames1[x][3][0]=0; - //} - // if (Sector_Level == 2 ) - //{ - // gzSectorUndergroundNames2[x][0][0]=0; - // gzSectorUndergroundNames2[x][1][0]=0; - // gzSectorUndergroundNames2[x][2][0]=0; - // gzSectorUndergroundNames2[x][3][0]=0; - //} - //if (Sector_Level == 3 ) - //{ - // gzSectorUndergroundNames3[x][0][0]=0; - // gzSectorUndergroundNames3[x][1][0]=0; - // gzSectorUndergroundNames3[x][2][0]=0; - // gzSectorUndergroundNames3[x][3][0]=0; - //} - } } - else if(strcmp(name, "SECTOR") == 0 && pData->curElement == SECTORNAME_ELEMENT_SECTOR_NAMES) + else if(strcmp(name, "SECTOR") == 0 && pData->curElement == ELEMENT_LIST) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; + pData->curElement = ELEMENT; pData->maxReadDepth++; //we are not skipping this element } - else if(pData->curElement == SECTORNAME_ELEMENT_SECTOR && + else if(pData->curElement == ELEMENT && (strcmp(name, "SectorGrid") == 0 || strcmp(name, "szUnexploredName") == 0 || strcmp(name, "szDetailedUnexploredName") == 0 || @@ -162,9 +128,10 @@ SectorNameStartElementHandle(void *userData, const XML_Char *name, const char ** strcmp(name, "usPrisonRoomNumber12") == 0 || strcmp(name, "usPrisonRoomNumber13") == 0 || strcmp(name, "usPrisonRoomNumber14") == 0 || - strcmp(name, "usPrisonRoomNumber15") == 0 )) + strcmp(name, "usPrisonRoomNumber15") == 0 || + strcmp(name, "usCivilianPopulation") == 0 )) { - pData->curElement = SECTORNAME_ELEMENT; + pData->curElement = ELEMENT_PROPERTY; pData->maxReadDepth++; //we are not skipping this element } @@ -173,7 +140,6 @@ SectorNameStartElementHandle(void *userData, const XML_Char *name, const char ** } pData->currentDepth++; - } @@ -197,11 +163,11 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name) { if(strcmp(name, "SECTOR_NAMES") == 0) { - pData->curElement = SECTORNAME_ELEMENT_NONE; + pData->curElement = ELEMENT_NONE; } else if(strcmp(name, "SECTOR") == 0) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR_NAMES; + pData->curElement = ELEMENT_LIST; UINT8 ubSectorId = SECTOR(pData->sCurSectorX, pData->sCurSectorY); if (ubSectorId >= 0 && ubSectorId < 256) @@ -247,70 +213,54 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name) wcscpy(gzSectorNames[ubSectorId][2], pData->szCurExploredName); wcscpy(gzSectorNames[ubSectorId][3], pData->szCurDetailedExploredName); } - // moved to lua - //else if (Sector_Level == 1 ) - //{ - // wcscpy(gzSectorUndergroundNames1[ubSectorId][0], pData->szCurUnexploredName); - // wcscpy(gzSectorUndergroundNames1[ubSectorId][1], pData->szCurDetailedUnexploredName); - // wcscpy(gzSectorUndergroundNames1[ubSectorId][2], pData->szCurExploredName); - // wcscpy(gzSectorUndergroundNames1[ubSectorId][3], pData->szCurDetailedExploredName); - //} - //else if (Sector_Level == 2 ) - //{ - // wcscpy(gzSectorUndergroundNames2[ubSectorId][0], pData->szCurUnexploredName); - // wcscpy(gzSectorUndergroundNames2[ubSectorId][1], pData->szCurDetailedUnexploredName); - // wcscpy(gzSectorUndergroundNames2[ubSectorId][2], pData->szCurExploredName); - // wcscpy(gzSectorUndergroundNames2[ubSectorId][3], pData->szCurDetailedExploredName); - //} - //else if (Sector_Level == 3 ) - //{ - // wcscpy(gzSectorUndergroundNames3[ubSectorId][0], pData->szCurUnexploredName); - // wcscpy(gzSectorUndergroundNames3[ubSectorId][1], pData->szCurDetailedUnexploredName); - // wcscpy(gzSectorUndergroundNames3[ubSectorId][2], pData->szCurExploredName); - // wcscpy(gzSectorUndergroundNames3[ubSectorId][3], pData->szCurDetailedExploredName); - //} } - SectorExternalData[ubSectorId][0].usWaterType = pData->sWaterType; - SectorExternalData[ubSectorId][1].usWaterType = pData->sWaterType; - SectorExternalData[ubSectorId][2].usWaterType = pData->sWaterType; - SectorExternalData[ubSectorId][3].usWaterType = pData->sWaterType; + SectorExternalData[ubSectorId][0].usWaterType = pData->sectordata.usWaterType; + SectorExternalData[ubSectorId][1].usWaterType = pData->sectordata.usWaterType; + SectorExternalData[ubSectorId][2].usWaterType = pData->sectordata.usWaterType; + SectorExternalData[ubSectorId][3].usWaterType = pData->sectordata.usWaterType; - SectorExternalData[ubSectorId][0].usNaturalDirt = pData->usNaturalDirt; - SectorExternalData[ubSectorId][1].usNaturalDirt = pData->usNaturalDirt; - SectorExternalData[ubSectorId][2].usNaturalDirt = pData->usNaturalDirt; - SectorExternalData[ubSectorId][3].usNaturalDirt = pData->usNaturalDirt; + SectorExternalData[ubSectorId][0].usNaturalDirt = pData->sectordata.usNaturalDirt; + SectorExternalData[ubSectorId][1].usNaturalDirt = pData->sectordata.usNaturalDirt; + SectorExternalData[ubSectorId][2].usNaturalDirt = pData->sectordata.usNaturalDirt; + SectorExternalData[ubSectorId][3].usNaturalDirt = pData->sectordata.usNaturalDirt; - SectorExternalData[ubSectorId][0].usCurfewValue = pData->usCurfewValue; - SectorExternalData[ubSectorId][1].usCurfewValue = pData->usCurfewValue; - SectorExternalData[ubSectorId][2].usCurfewValue = pData->usCurfewValue; - SectorExternalData[ubSectorId][3].usCurfewValue = pData->usCurfewValue; + SectorExternalData[ubSectorId][0].usCurfewValue = pData->sectordata.usCurfewValue; + SectorExternalData[ubSectorId][1].usCurfewValue = pData->sectordata.usCurfewValue; + SectorExternalData[ubSectorId][2].usCurfewValue = pData->sectordata.usCurfewValue; + SectorExternalData[ubSectorId][3].usCurfewValue = pData->sectordata.usCurfewValue; - INT8 radioscanmod = max(-3, pData->sRadioScanModifier); - radioscanmod = min(3, pData->sRadioScanModifier); - SectorExternalData[ubSectorId][0].sRadioScanModifier = pData->sRadioScanModifier; - SectorExternalData[ubSectorId][1].sRadioScanModifier = pData->sRadioScanModifier; - SectorExternalData[ubSectorId][2].sRadioScanModifier = pData->sRadioScanModifier; - SectorExternalData[ubSectorId][3].sRadioScanModifier = pData->sRadioScanModifier; + INT8 radioscanmod = max( -3, pData->sectordata.sRadioScanModifier ); + radioscanmod = min( 3, pData->sectordata.sRadioScanModifier ); + SectorExternalData[ubSectorId][0].sRadioScanModifier = pData->sectordata.sRadioScanModifier; + SectorExternalData[ubSectorId][1].sRadioScanModifier = pData->sectordata.sRadioScanModifier; + SectorExternalData[ubSectorId][2].sRadioScanModifier = pData->sectordata.sRadioScanModifier; + SectorExternalData[ubSectorId][3].sRadioScanModifier = pData->sectordata.sRadioScanModifier; + SectorExternalData[ubSectorId][0].usCivilianPopulation = pData->sectordata.usCivilianPopulation; + SectorExternalData[ubSectorId][1].usCivilianPopulation = pData->sectordata.usCivilianPopulation; + SectorExternalData[ubSectorId][2].usCivilianPopulation = pData->sectordata.usCivilianPopulation; + SectorExternalData[ubSectorId][3].usCivilianPopulation = pData->sectordata.usCivilianPopulation; + for(UINT8 i = 0; i usPrisonRoomNumber[i]; - pData->usPrisonRoomNumber[i] = 0; + SectorExternalData[ubSectorId][0].usPrisonRoomNumber[i] = pData->sectordata.usPrisonRoomNumber[i]; + pData->sectordata.usPrisonRoomNumber[i] = 0; } // clean up values afterwards - pData->sWaterType = 0; - pData->usNaturalDirt = 100; - pData->usCurfewValue = 0; - pData->sRadioScanModifier = 0; + pData->sectordata.usWaterType = 0; + pData->sectordata.usNaturalDirt = 100; + pData->sectordata.usCurfewValue = 0; + pData->sectordata.sRadioScanModifier = 0; + pData->sectordata.usCivilianPopulation = 0; } } else if(strcmp(name, "SectorGrid") == 0 ) { UINT8 x, y; - pData->curElement = SECTORNAME_ELEMENT_SECTOR; + pData->curElement = ELEMENT; y = (UINT8)pData->szCharData[0] & 0x1F; x = (UINT8)atol(&pData->szCharData[1]); @@ -322,7 +272,7 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name) } else if(strcmp(name, "szUnexploredName") == 0 ) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; + pData->curElement = ELEMENT; MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->szCurUnexploredName, sizeof(pData->szCurUnexploredName)/sizeof(pData->szCurUnexploredName[0]) ); pData->szCurUnexploredName[sizeof(pData->szCurUnexploredName)/sizeof(pData->szCurUnexploredName[0]) - 1] = '\0'; @@ -330,7 +280,7 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name) else if(strcmp(name, "szDetailedUnexploredName") == 0 ) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; + pData->curElement = ELEMENT; MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->szCurDetailedUnexploredName, sizeof(pData->szCurDetailedUnexploredName)/sizeof(pData->szCurDetailedUnexploredName[0]) ); pData->szCurDetailedUnexploredName[sizeof(pData->szCurDetailedUnexploredName)/sizeof(pData->szCurDetailedUnexploredName[0]) - 1] = '\0'; @@ -338,7 +288,7 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name) else if(strcmp(name, "szExploredName") == 0 ) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; + pData->curElement = ELEMENT; MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->szCurExploredName, sizeof(pData->szCurExploredName)/sizeof(pData->szCurExploredName[0]) ); pData->szCurExploredName[sizeof(pData->szCurExploredName)/sizeof(pData->szCurExploredName[0]) - 1] = '\0'; @@ -346,7 +296,7 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name) else if(strcmp(name, "szDetailedExploredName") == 0 ) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; + pData->curElement = ELEMENT; MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->szCurDetailedExploredName, sizeof(pData->szCurDetailedExploredName)/sizeof(pData->szCurDetailedExploredName[0]) ); pData->szCurDetailedExploredName[sizeof(pData->szCurDetailedExploredName)/sizeof(pData->szCurDetailedExploredName[0]) - 1] = '\0'; @@ -354,104 +304,109 @@ SectorNameEndElementHandle(void *userData, const XML_Char *name) else if(strcmp(name, "sWaterType") == 0) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; - pData->sWaterType = (UINT8) atol(pData->szCharData); + pData->curElement = ELEMENT; + pData->sectordata.usWaterType = (UINT8)atol( pData->szCharData ); } else if(strcmp(name, "usNaturalDirt") == 0) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; - pData->usNaturalDirt = (UINT16) atoi(pData->szCharData); + pData->curElement = ELEMENT; + pData->sectordata.usNaturalDirt = (UINT16)atoi( pData->szCharData ); } else if(strcmp(name, "usCurfewValue") == 0) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; - pData->usCurfewValue = (UINT8) atoi(pData->szCharData); + pData->curElement = ELEMENT; + pData->sectordata.usCurfewValue = (UINT8)atoi( pData->szCharData ); } else if(strcmp(name, "sRadioScanModifier") == 0) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; - pData->sRadioScanModifier = (INT8) atoi(pData->szCharData); + pData->curElement = ELEMENT; + pData->sectordata.sRadioScanModifier = (INT8)atoi( pData->szCharData ); } else if(strcmp(name, "usPrisonRoomNumber00") == 0) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; - pData->usPrisonRoomNumber[0] = (UINT8) atoi(pData->szCharData); + pData->curElement = ELEMENT; + pData->sectordata.usPrisonRoomNumber[0] = (UINT8)atoi( pData->szCharData ); } else if(strcmp(name, "usPrisonRoomNumber01") == 0) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; - pData->usPrisonRoomNumber[1] = (UINT8) atoi(pData->szCharData); + pData->curElement = ELEMENT; + pData->sectordata.usPrisonRoomNumber[1] = (UINT8)atoi( pData->szCharData ); } else if(strcmp(name, "usPrisonRoomNumber02") == 0) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; - pData->usPrisonRoomNumber[2] = (UINT8) atoi(pData->szCharData); + pData->curElement = ELEMENT; + pData->sectordata.usPrisonRoomNumber[2] = (UINT8)atoi( pData->szCharData ); } else if(strcmp(name, "usPrisonRoomNumber03") == 0) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; - pData->usPrisonRoomNumber[3] = (UINT8) atoi(pData->szCharData); + pData->curElement = ELEMENT; + pData->sectordata.usPrisonRoomNumber[3] = (UINT8)atoi( pData->szCharData ); } else if(strcmp(name, "usPrisonRoomNumber04") == 0) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; - pData->usPrisonRoomNumber[4] = (UINT8) atoi(pData->szCharData); + pData->curElement = ELEMENT; + pData->sectordata.usPrisonRoomNumber[4] = (UINT8)atoi( pData->szCharData ); } else if(strcmp(name, "usPrisonRoomNumber05") == 0) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; - pData->usPrisonRoomNumber[5] = (UINT8) atoi(pData->szCharData); + pData->curElement = ELEMENT; + pData->sectordata.usPrisonRoomNumber[5] = (UINT8)atoi( pData->szCharData ); } else if(strcmp(name, "usPrisonRoomNumber06") == 0) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; - pData->usPrisonRoomNumber[6] = (UINT8) atoi(pData->szCharData); + pData->curElement = ELEMENT; + pData->sectordata.usPrisonRoomNumber[6] = (UINT8)atoi( pData->szCharData ); } else if(strcmp(name, "usPrisonRoomNumber07") == 0) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; - pData->usPrisonRoomNumber[7] = (UINT8) atoi(pData->szCharData); + pData->curElement = ELEMENT; + pData->sectordata.usPrisonRoomNumber[7] = (UINT8)atoi( pData->szCharData ); } else if(strcmp(name, "usPrisonRoomNumber08") == 0) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; - pData->usPrisonRoomNumber[8] = (UINT8) atoi(pData->szCharData); + pData->curElement = ELEMENT; + pData->sectordata.usPrisonRoomNumber[8] = (UINT8)atoi( pData->szCharData ); } else if(strcmp(name, "usPrisonRoomNumber09") == 0) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; - pData->usPrisonRoomNumber[9] = (UINT8) atoi(pData->szCharData); + pData->curElement = ELEMENT; + pData->sectordata.usPrisonRoomNumber[9] = (UINT8)atoi( pData->szCharData ); } else if(strcmp(name, "usPrisonRoomNumber10") == 0) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; - pData->usPrisonRoomNumber[10] = (UINT8) atoi(pData->szCharData); + pData->curElement = ELEMENT; + pData->sectordata.usPrisonRoomNumber[10] = (UINT8)atoi( pData->szCharData ); } else if(strcmp(name, "usPrisonRoomNumber11") == 0) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; - pData->usPrisonRoomNumber[11] = (UINT8) atoi(pData->szCharData); + pData->curElement = ELEMENT; + pData->sectordata.usPrisonRoomNumber[11] = (UINT8)atoi( pData->szCharData ); } else if(strcmp(name, "usPrisonRoomNumber12") == 0) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; - pData->usPrisonRoomNumber[12] = (UINT8) atoi(pData->szCharData); + pData->curElement = ELEMENT; + pData->sectordata.usPrisonRoomNumber[12] = (UINT8)atoi( pData->szCharData ); } else if(strcmp(name, "usPrisonRoomNumber13") == 0) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; - pData->usPrisonRoomNumber[13] = (UINT8) atoi(pData->szCharData); + pData->curElement = ELEMENT; + pData->sectordata.usPrisonRoomNumber[13] = (UINT8)atoi( pData->szCharData ); } else if(strcmp(name, "usPrisonRoomNumber14") == 0) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; - pData->usPrisonRoomNumber[14] = (UINT8) atoi(pData->szCharData); + pData->curElement = ELEMENT; + pData->sectordata.usPrisonRoomNumber[14] = (UINT8)atoi( pData->szCharData ); } else if(strcmp(name, "usPrisonRoomNumber15") == 0) { - pData->curElement = SECTORNAME_ELEMENT_SECTOR; - pData->usPrisonRoomNumber[15] = (UINT8) atoi(pData->szCharData); + pData->curElement = ELEMENT; + pData->sectordata.usPrisonRoomNumber[15] = (UINT8)atoi( pData->szCharData ); + } + else if(strcmp(name, "usCivilianPopulation") == 0) + { + pData->curElement = ELEMENT; + pData->sectordata.usCivilianPopulation = (UINT16)atoi( pData->szCharData ); } pData->maxReadDepth--; diff --git a/Strategic/mapscreen.cpp b/Strategic/mapscreen.cpp index 9cdd6f8f..3c882e0d 100644 --- a/Strategic/mapscreen.cpp +++ b/Strategic/mapscreen.cpp @@ -894,6 +894,7 @@ extern BOOLEAN CanPlayerUseSectorInventory( SOLDIERTYPE *pSelectedSoldier ); void HandleSpontanousTalking( void ); BOOLEAN ContinueDialogue(SOLDIERTYPE *pSoldier, BOOLEAN fDone ); extern void CreateDestroyMilitiaSectorButtons( void ); +extern void CreateDestroySupplySectorButtons(); // mouse position test BOOLEAN IsCursorWithInRegion(INT16 sLeft, INT16 sRight, INT16 sTop, INT16 sBottom ); @@ -5004,9 +5005,9 @@ UINT32 MapScreenHandle(void) // load the militia pop up box LoadMilitiaPopUpBox( ); - - // graphic for pool inventory - LoadInventoryPoolGraphic( ); + + // graphic for pool inventory + LoadInventoryPoolGraphic( ); //Kris: Added this because I need to blink the icons button. VObjectDesc.fCreateFlags = VOBJECT_CREATE_FROMFILE; @@ -5744,7 +5745,6 @@ UINT32 MapScreenHandle(void) DisplaySoldierUpdateBox( ); } - // pop up display boxes DisplayBoxes(FRAME_BUFFER); @@ -6892,6 +6892,10 @@ void GetMapKeyboardInput( UINT32 *puiNewEvent ) { fShowMoveItemMenu = FALSE; } + else if ( fShowDiseaseMenu == TRUE ) + { + fShowDiseaseMenu = FALSE; + } // HEADROCK HAM 3.6: Facility Menu else if( fShowFacilityMenu == TRUE ) { @@ -12168,7 +12172,6 @@ void ResetAllSelectedCharacterModes( void ) sSelectedMilitiaTown = 0; } - // cancel destination line highlight giDestHighLine = -1; @@ -15392,7 +15395,6 @@ void HandleMilitiaRedistributionClick( void ) } - #ifdef JA2TESTVERSION void DumpSectorDifficultyInfo( void ) { @@ -16083,7 +16085,6 @@ void RequestContractMenu( void ) AbortMovementPlottingMode( ); } - // in case we have multiple guys selected, turn off everyone but the guy we're negotiating with ChangeSelectedInfoChar( bSelectedInfoChar, TRUE ); diff --git a/Strategic/strategicmap.cpp b/Strategic/strategicmap.cpp index f7ef9c1e..5968f0ee 100644 --- a/Strategic/strategicmap.cpp +++ b/Strategic/strategicmap.cpp @@ -1841,13 +1841,13 @@ UINT8 GetTownSectorSize( INT8 bTownId ) UINT8 ubSectorSize = 0; INT32 iCounterA =0, iCounterB = 0; - for( iCounterA = 0; iCounterA < ( INT32 )( MAP_WORLD_X - 1 ); iCounterA++ ) + for( iCounterA = 0; iCounterA < ( INT32 )( MAP_WORLD_X - 1 ); ++iCounterA ) { - for( iCounterB = 0; iCounterB < ( INT32 )( MAP_WORLD_Y - 1 ); iCounterB++ ) + for( iCounterB = 0; iCounterB < ( INT32 )( MAP_WORLD_Y - 1 ); ++iCounterB ) { - if( StrategicMap[CALCULATE_STRATEGIC_INDEX( iCounterA, iCounterB )].bNameId == bTownId ) + if ( StrategicMap[CALCULATE_STRATEGIC_INDEX( iCounterA, iCounterB )].bNameId == bTownId ) { - ubSectorSize++; + ++ubSectorSize; } } } @@ -1878,12 +1878,11 @@ UINT8 GetMilitiaCountAtLevelAnywhereInTown( UINT8 ubTownValue, UINT8 ubLevelValu UINT8 GetTownSectorsUnderControl( INT8 bTownId ) { INT8 ubSectorsControlled = 0; - INT32 iCounterA =0, iCounterB = 0; UINT16 usSector = 0; - for( iCounterA = 0; iCounterA < ( INT32 )( MAP_WORLD_X - 1 ); iCounterA++ ) + for ( INT32 iCounterA = 0; iCounterA < (INT32)(MAP_WORLD_X - 1); iCounterA++ ) { - for( iCounterB = 0; iCounterB < ( INT32 )( MAP_WORLD_Y - 1 ); iCounterB++ ) + for ( INT32 iCounterB = 0; iCounterB < (INT32)(MAP_WORLD_Y - 1); iCounterB++ ) { usSector = (UINT16)CALCULATE_STRATEGIC_INDEX( iCounterA, iCounterB ); diff --git a/Tactical/Bullets.h b/Tactical/Bullets.h index 9b30a120..5f332b1e 100644 --- a/Tactical/Bullets.h +++ b/Tactical/Bullets.h @@ -7,16 +7,17 @@ #include "tile animation.h" -#define BULLET_FLAG_CREATURE_SPIT 0x0001 -#define BULLET_FLAG_KNIFE 0x0002 -#define BULLET_FLAG_MISSILE 0x0004 -#define BULLET_FLAG_SMALL_MISSILE 0x0008 -#define BULLET_STOPPED 0x0010 -#define BULLET_FLAG_TANK_CANNON 0x0020 -#define BULLET_FLAG_BUCKSHOT 0x0040 -#define BULLET_FLAG_FLAME 0x0080 -#define BULLET_FLAG_TRACER 0x0100 -#define BULLET_FLAG_ANTIMATERIEL 0x0200 // Flugente: bullet can destroy structures +#define BULLET_FLAG_CREATURE_SPIT 0x0001 +#define BULLET_FLAG_KNIFE 0x0002 +#define BULLET_FLAG_MISSILE 0x0004 +#define BULLET_FLAG_SMALL_MISSILE 0x0008 +#define BULLET_STOPPED 0x0010 +#define BULLET_FLAG_TANK_CANNON 0x0020 +#define BULLET_FLAG_BUCKSHOT 0x0040 +#define BULLET_FLAG_FLAME 0x0080 +#define BULLET_FLAG_TRACER 0x0100 +#define BULLET_FLAG_ANTIMATERIEL 0x0200 // Flugente: bullet can destroy structures +#define BULLET_FLAG_INFECTED 0x0400 // Flugente: bullet is infected //afp-start calculate line points between two point #define BULLET_TRACER_MAX_LENGTH 60 diff --git a/Tactical/Civ Quotes.cpp b/Tactical/Civ Quotes.cpp index 3a51698d..f5b241c7 100644 --- a/Tactical/Civ Quotes.cpp +++ b/Tactical/Civ Quotes.cpp @@ -1269,11 +1269,9 @@ void StartEnemyTaunt( SOLDIERTYPE *pCiv, TAUNTTYPE iTauntType, SOLDIERTYPE *pTar CHAR16 gzTauntQuote[ 320 ]; UINT16 iApplicableTaunts = 0; -#ifdef ENABLE_ZOMBIES // Flugente: zombies don't talk if ( pCiv->IsZombie() ) return; -#endif // gCivQuoteData.bActive is checked in ShowTauntPopupBox() instead, taunt can be shown in log though! // if we have a different quote on, return, this one is not important @@ -1720,9 +1718,7 @@ void StartEnemyTaunt( SOLDIERTYPE *pCiv, TAUNTTYPE iTauntType, SOLDIERTYPE *pTar if( zTaunt[ i ].uiFlags2 & TAUNT_T_ZOMBIE ) { // anv: moved ifdef - if zombies are off, we want to skip any taunts with TAUNT_T_ZOMBIE flag -#ifdef ENABLE_ZOMBIES - if( pTarget->IsZombie() == FALSE ) -#endif + if( !pTarget->IsZombie() ) continue; } diff --git a/Tactical/Disease.cpp b/Tactical/Disease.cpp new file mode 100644 index 00000000..68c5627d --- /dev/null +++ b/Tactical/Disease.cpp @@ -0,0 +1,727 @@ +/** +* @file +* @author Flugente (bears-pit.com) +*/ + +#include "Disease.h" + +#include "Overhead.h" +#include "random.h" +#include "Assignments.h" +#include "message.h" +#include "Soldier Profile.h" +#include "Map Screen Interface Map.h" +#include "Queen Command.h" +#include "Quests.h" +#include "finances.h" +#include "Game Clock.h" +#include "LaptopSave.h" +#include "strategic.h" +#include "DynamicDialogue.h" + +//GLOBALS +DISEASE Disease[NUM_DISEASES]; + +extern SECTOR_EXT_DATA SectorExternalData[256][4]; + +// if disease in a sector is high enough, there is a chance that neighbouring sectors can be affected too +#define DISEASE_STRATEGIC_ADJACENTINFECTION 0.3 + +#define MAPROWS (MAP_WORLD_X - 2) +#define MAPCOLS (MAP_WORLD_Y - 2) + +// percentage of population that has at least some medical skill +FLOAT GetCivPopulationDoctorRate( ) { return 0.1f; } + +// percentage of army population that has at least some medical skill +FLOAT GetMilitaryPopulationDoctorRate( ) { return 0.34f; } + +// healing points of a population doctor +FLOAT GetPopulationDoctorPoints( ) { return 20; } + +// if this fraction of a sector's population is infected, outbreak is declared regardless of infection severity +// Otherwise infection would be untreatable at this point +FLOAT GetSectorDiseaseOverFlowThreshold( ) +{ + /* disease in a sector is automatically revealed if the mean severity breaches the outbreak threshold + * however, we add a second condition: if a high enough percentage of the population is infected, disease is also revealed + * the reason is that otherwise the AI might have no chance at all to combat an outbreak + * It thus follows that + * population * percentage of doctors * healing points per doctor == population * disease overflow threshold * infection gain per hour + * which leads to + * disease overflow threshold = percentage of doctors * healing points per doctor / infection gain per hour + */ + if ( Disease[0].sInfectionPtsGainPerHour > 0 ) + return GetCivPopulationDoctorRate( ) * GetPopulationDoctorPoints( ) / (FLOAT)Disease[0].sInfectionPtsGainPerHour; + + return 0.3; +} + +void HandleDisease() +{ + if ( !gGameExternalOptions.fDisease ) + return; + + SOLDIERTYPE *pSoldier = NULL; + UINT32 uiCnt = 0; + + // increase existing diseases + for ( uiCnt = 0, pSoldier = MercPtrs[uiCnt]; uiCnt <= gTacticalStatus.Team[gbPlayerNum].bLastID; ++uiCnt, ++pSoldier ) + { + if ( pSoldier->bActive ) + { + for ( int i = 0; i < NUM_DISEASES; ++i ) + { + if ( pSoldier->sDiseasePoints[i] > 0 ) + { + // add disease points - some diseases can reverse on certain states + if ( pSoldier->sDiseaseFlag[i] & SOLDIERDISEASE_REVERSEAL ) + pSoldier->AddDiseasePoints( i, -Disease[i].sInfectionPtsGainPerHour ); + else + pSoldier->AddDiseasePoints( i, Disease[i].sInfectionPtsGainPerHour ); + } + } + } + } + + // chance for infection due to proximity to other mercs + for ( uiCnt = 0, pSoldier = MercPtrs[uiCnt]; uiCnt <= gTacticalStatus.Team[gbPlayerNum].bLastID; ++uiCnt, ++pSoldier ) + { + if ( pSoldier->bActive && pSoldier->stats.bLife > 0 ) + { + // loop over all other soldiers and determine the chance that they will infect us + SOLDIERTYPE *pTeamSoldier = NULL; + UINT32 uiCnt2 = 0; + + // chance for infection due to proximity to other mercs + for ( uiCnt2 = 0, pTeamSoldier = MercPtrs[uiCnt2]; uiCnt2 <= gTacticalStatus.Team[gbPlayerNum].bLastID; ++uiCnt2, ++pTeamSoldier ) + { + if ( pTeamSoldier->bActive && pTeamSoldier != pSoldier + && pTeamSoldier->sSectorX == pSoldier->sSectorX && pTeamSoldier->sSectorY == pSoldier->sSectorY && pTeamSoldier->bSectorZ == pSoldier->bSectorZ + && pTeamSoldier->stats.bLife > 0 ) + { + // infection chance gets modified depending on assignments + FLOAT modifier = 1.0f; + + // if both are in the same squad, chance is increased + if ( pTeamSoldier->bAssignment == pSoldier->bAssignment && pSoldier->bAssignment < ON_DUTY ) + modifier = 1.5; + // doctor-patient relations increase chance even more + else if ( (pTeamSoldier->bAssignment == DOCTOR || pTeamSoldier->bAssignment == PATIENT) && (pSoldier->bAssignment == DOCTOR || pSoldier->bAssignment == PATIENT) ) + modifier = 4; + + // we might get a disease from this... + HandlePossibleInfection( pSoldier, pTeamSoldier, INFECTION_TYPE_CONTACT_HUMAN, modifier ); + } + } + + // we can also be infected by the population + if ( gGameExternalOptions.fDiseaseStrategic ) + { + UINT16 population = GetSectorPopulation( pSoldier->sSectorX, pSoldier->sSectorY ); + + if ( population ) + { + UINT8 sector = SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ); + + SECTORINFO *pSectorInfo = &(SectorInfo[sector]); + + if ( pSectorInfo ) + { + // if there are infected people, we might get an infection (disease 0 only) + if ( pSectorInfo->usInfected ) + { + // infection is also possible by human contact + UINT32 usChance = Disease[0].usInfectionChance[INFECTION_TYPE_CONTACT_HUMAN]; + + // if disease is known, mercs will avoid the infected, lowering the chance of them being infected + UINT16 max = min(20, pSectorInfo->usInfected); + if ( (pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_PLAYER) || (gubFact[FACT_DISEASE_WHODATA_ACCESS] && pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_WHO) ) + max /= 4; + + for ( UINT16 i = 0; i < max; ++i ) + { + if ( Chance( usChance ) ) + HandlePossibleInfection( pSoldier, NULL, INFECTION_TYPE_CONTACT_HUMAN, 1.0f, TRUE ); + } + } + + // if we are infected, WE might infect other people + if ( pSoldier->sDiseasePoints[0] > 0 ) + { + if ( pSectorInfo->usInfected < population ) + { + if ( Chance( Disease[0].usInfectionChance[INFECTION_TYPE_CONTACT_HUMAN] ) ) + { + FLOAT infectedseverity = (FLOAT)Disease[0].sInfectionPtsInitial / (FLOAT)Disease[0].sInfectionPtsFull; + + pSectorInfo->fInfectionSeverity = (pSectorInfo->fInfectionSeverity * pSectorInfo->usInfected + infectedseverity * 1) / (pSectorInfo->usInfected + 1); + ++pSectorInfo->usInfected; + } + } + } + } + } + } + + // if we are infected, this might disgust other people + for ( int i = 0; i < NUM_DISEASES; ++i ) + { + if ( (Disease[i].usDiseaseProperties & DISEASE_PROPERTY_DISGUSTING) && (pSoldier->sDiseaseFlag[i] & SOLDIERDISEASE_DIAGNOSED) ) + { + HandleDynamicOpinionChange( pSoldier, OPINIONEVENT_DISEASE_DISGUSTING, TRUE, TRUE ); + break; + } + } + } + } + + // chance for infection due sector + for ( uiCnt = 0, pSoldier = MercPtrs[uiCnt]; uiCnt <= gTacticalStatus.Team[gbPlayerNum].bLastID; ++uiCnt, ++pSoldier ) + { + if ( pSoldier->bActive ) + { + UINT8 ubSector = (UINT8)SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ); + UINT8 ubTraverseType = SectorInfo[ubSector].ubTraversability[pSoldier->ubDirection]; + + switch ( ubTraverseType ) + { + case TROPICS_SAM_SITE: + case TROPICS: + case TROPICS_ROAD: + { + HandlePossibleInfection( pSoldier, NULL, INFECTION_TYPE_TROPICS ); + } + break; + case SWAMP: + case SWAMP_ROAD: + { + HandlePossibleInfection( pSoldier, NULL, INFECTION_TYPE_SWAMP ); + } + break; + default: + break; + } + } + } + + // now to handle strategic disease + if ( !gGameExternalOptions.fDiseaseStrategic ) + return; + + for ( UINT8 sX = 1; sX < MAP_WORLD_X - 1; ++sX ) + { + for ( UINT8 sY = 1; sY < MAP_WORLD_X - 1; ++sY ) + { + UINT8 sector = SECTOR( sX, sY ); + + SECTORINFO *pSectorInfo = &(SectorInfo[sector]); + + if ( !pSectorInfo ) + continue; + + // first, existing infections get worse + if ( pSectorInfo->fInfectionSeverity > 0 ) + { + pSectorInfo->fInfectionSeverity = min( 1.0f, pSectorInfo->fInfectionSeverity + ( FLOAT )(Disease[0].sInfectionPtsGainPerHour) / (FLOAT)(Disease[0].sInfectionPtsFull) ); + } + + UINT16 population = GetSectorPopulation( sX, sY ); + + if ( population ) + { + // how many people are already infected? + if ( pSectorInfo->usInfected < population ) + { + UINT16 lefttoinfect = population - pSectorInfo->usInfected; + UINT16 newinfected = 0; + + // population might get infected if this a swamp or tropical sector + switch ( SectorInfo[sector].ubTraversability[THROUGH_STRATEGIC_MOVE] ) + { + case TROPICS_SAM_SITE: + case TROPICS: + case TROPICS_ROAD: + { + UINT32 usChance = Disease[0].usInfectionChance[INFECTION_TYPE_TROPICS]; + for ( UINT16 i = 0; i < lefttoinfect; ++i ) + { + if ( Chance( usChance) ) + ++newinfected; + } + } + break; + case SWAMP: + case SWAMP_ROAD: + { + UINT32 usChance = Disease[0].usInfectionChance[INFECTION_TYPE_SWAMP]; + for ( UINT16 i = 0; i < lefttoinfect; ++i ) + { + if ( Chance( usChance ) ) + ++newinfected; + } + } + break; + default: + break; + } + + if ( lefttoinfect - newinfected > 1 && pSectorInfo->usInfected ) + { + // infection is also possible by human contact + UINT32 usChance = Disease[0].usInfectionChance[INFECTION_TYPE_CONTACT_HUMAN]; + UINT16 max = sqrt( min( lefttoinfect - newinfected, pSectorInfo->usInfected ) ); + for ( UINT16 i = 0; i < max; ++i ) + { + if ( Chance( usChance ) ) + ++newinfected; + } + } + + if ( lefttoinfect - newinfected > 0 ) + { + // there is also the chance to be infected by bad food, sex, contact with animals etc. + // For now, we assume this to be very rare events, so just add a small chance to be infected this way + FLOAT populationpercentage = (FLOAT)(lefttoinfect - newinfected) / (FLOAT)(population); + FLOAT basechance = sqrt( min( lefttoinfect, pSectorInfo->usInfected + newinfected ) ) * 0.5f; + + FLOAT chance_sex = Disease[0].usInfectionChance[INFECTION_TYPE_SEX] * basechance * populationpercentage; + FLOAT chance_corpse = 0; + + // if there was a fight here in the last 48 hours, then corpses will still be here - increase chance of infection + if ( pSectorInfo->uiTimeLastPlayerLiberated && pSectorInfo->uiTimeLastPlayerLiberated + (48 * 3600) > GetWorldTotalSeconds( ) ) + chance_corpse = Disease[0].usInfectionChance[INFECTION_TYPE_CONTACT_CORPSE] * populationpercentage; + + if ( Chance( chance_sex ) ) + ++newinfected; + + if ( Chance( chance_corpse ) ) + ++newinfected; + } + + if ( lefttoinfect - newinfected > 0 ) + { + // adjacent sectors can infect us too + for ( UINT8 dir = 0; dir < SP_DIR_MAX; ++dir ) + { + INT16 othersector = GetAdjacentSector( sector, dir ); + + if ( othersector > -1 ) + { + UINT16 population_other = GetSectorPopulation( SECTORX( othersector ), SECTORY( othersector ) ); + SECTORINFO *pSectorInfo_Other = &(SectorInfo[othersector]); + + if ( pSectorInfo_Other && pSectorInfo_Other->usInfected && population_other ) + { + FLOAT infectedothersector = (FLOAT)pSectorInfo_Other->usInfected / (FLOAT)(population_other); + + if ( infectedothersector > DISEASE_STRATEGIC_ADJACENTINFECTION ) + { + FLOAT percentage = (FLOAT)((lefttoinfect - newinfected) * Disease[0].usInfectionChance[INFECTION_TYPE_CONTACT_HUMAN]) / (FLOAT)(100 * population); + + if ( Chance( 100 * percentage ) ) + ++newinfected; + } + } + } + } + } + + if ( pSectorInfo->usInfected + newinfected > 0 && Disease[0].sInfectionPtsFull ) + { + FLOAT infectedseverity = (FLOAT)Disease[0].sInfectionPtsInitial / (FLOAT)Disease[0].sInfectionPtsFull; + + pSectorInfo->fInfectionSeverity = (pSectorInfo->fInfectionSeverity * pSectorInfo->usInfected + infectedseverity * newinfected) / (pSectorInfo->usInfected + newinfected); + pSectorInfo->usInfected += newinfected; + + pSectorInfo->usInfected = min( pSectorInfo->usInfected , population); + } + } + + // if infection is high enough, disease officially breaks out + FLOAT infectedpercentage = (FLOAT)pSectorInfo->usInfected / (FLOAT)(population); + + if ( infectedpercentage >= GetSectorDiseaseOverFlowThreshold() || pSectorInfo->fInfectionSeverity > ((FLOAT)Disease[0].sInfectionPtsOutbreak / (FLOAT)Disease[0].sInfectionPtsFull) ) + { + pSectorInfo->usInfectionFlag |= (SECTORDISEASE_OUTBREAK | SECTORDISEASE_DIAGNOSED_WHO); + } + + // if disease is known and doctoring isn't inhibited, use doctoring to remove disease + // doctors (civilian and military) can fight the disease + if ( (pSectorInfo->usInfectionFlag & (SECTORDISEASE_DIAGNOSED_WHO | SECTORDISEASE_DIAGNOSED_PLAYER)) && !pSectorInfo->usDiseaseDoctoringDelay) + { + // the country doesn't have many doctors... + UINT32 doctors = GetSectorPopulation( sX, sY, FALSE ) * GetCivPopulationDoctorRate(); + + // if this the hospital sector, the amount of doctoring is increased to marvellous levels + if ( sX == gModSettings.ubHospitalSectorX && sY == gModSettings.ubHospitalSectorY ) + { + doctors += 200; + } + + // the bulk of doctoring will come from the military + doctors += NumEnemiesInSector( sX, sY ) * GetMilitaryPopulationDoctorRate( ); + + UINT32 doctorpower = doctors * GetPopulationDoctorPoints( ); + + // if the disease escalates, increase doctor power! + if ( infectedpercentage > GetSectorDiseaseOverFlowThreshold( ) + 0.1f ) + doctorpower += doctors * 0.3f * GetPopulationDoctorPoints(); + + HealSectorPopulation( sX, sY, doctorpower ); + } + } + else + { + // if nobody is there, be sure to set infection data to 0 + pSectorInfo->usInfected = 0; + pSectorInfo->usInfectionFlag = 0; + pSectorInfo->fInfectionSeverity = 0; + pSectorInfo->usDiseaseDoctoringDelay = 0; + } + + // in any case, one hour has passed, update possible doctor replacements + pSectorInfo->usDiseaseDoctoringDelay = max( 0, pSectorInfo->usDiseaseDoctoringDelay - 1); + } + } +} + +// chance gets modified by aModifier (contextual modifier) +void HandlePossibleInfection( SOLDIERTYPE *pSoldier, SOLDIERTYPE* pOtherSoldier, UINT8 aInfectionType, FLOAT aModifier, BOOLEAN fStrategicOnly ) +{ + // only for living mercs with a profile with a valid infection method + if ( !pSoldier || pSoldier->flags.uiStatusFlags & SOLDIER_VEHICLE || pSoldier->ubProfile == NO_PROFILE || aInfectionType >= INFECTION_TYPE_MAX ) + return; + + int max = fStrategicOnly ? 1 : NUM_DISEASES; + for ( int i = 0; i < max; ++i ) + { + // do not infect us if we are already infected + if ( !(Disease[i].usDiseaseProperties & DISEASE_PROPERTY_CANREINFECT) && pSoldier->sDiseasePoints[i] > 0 ) + continue; + + // chance of infection by insects + UINT32 usChance = Disease[i].usInfectionChance[aInfectionType]; + + // alter chance by modifier and disease resistance + usChance = usChance * aModifier * ( 100 - pSoldier->GetDiseaseResistance( ) ) / 100; + + if ( aInfectionType == INFECTION_TYPE_TROPICS || aInfectionType == INFECTION_TYPE_SWAMP ) + { + // if we are afraid of insects, we will be more careful around them - lower chance to be infected + if ( gMercProfiles[pSoldier->ubProfile].bDisability == FEAR_OF_INSECTS ) + usChance *= 0.7f; + } + else if ( aInfectionType == INFECTION_TYPE_CONTACT_HUMAN ) + { + // if we check a specific soldier, he must have the disease himself + if ( pOtherSoldier && pOtherSoldier->sDiseasePoints[i] <= 0 ) + usChance = 0; + + // if we wear face or hand protection, lower chance of infection + usChance *= (1.0f - pSoldier->GetDiseaseContactProtection( )); + } + else if ( aInfectionType == INFECTION_TYPE_CONTACT_CORPSE ) + { + // if we wear face or hand protection, lower chance of infection + usChance *= (1.0f - pSoldier->GetDiseaseContactProtection( )); + } + + if ( Chance( usChance ) ) + { + // infect us + pSoldier->Infect( i ); + } + } +} + +// return number of adjacent sector or -1 if there is none +INT16 GetAdjacentSector( UINT8 sector, UINT8 spdir ) +{ + switch ( spdir ) + { + case SP_UP: + if ( SECTORY( sector ) > 0 ) + return sector - MAPCOLS; + break; + + case SP_LEFT: + if ( SECTORX( sector ) > 0 ) + return sector - 1; + break; + + case SP_RIGHT: + if ( SECTORX( sector ) < MAPCOLS ) + return sector + 1; + break; + + case SP_DOWN: + if ( SECTORY( sector ) < MAPCOLS ) + return sector + MAPCOLS; + break; + } + + return -1; +} + + +// get a sector population (not the tactical one - we use an xml estimation + troops present) +UINT16 GetSectorPopulation( INT16 sX, INT16 sY, BOOLEAN fWithMilitary ) +{ + UINT8 sector = SECTOR( sX, sY ); + + UINT16 population = SectorExternalData[sector][0].usCivilianPopulation; + + if ( fWithMilitary ) + { + // add number of enemies... + UINT16 sNumberOfEnemies = NumEnemiesInSector( sX, sY ); + population += sNumberOfEnemies; + } + + return population; +} + +// colour for a sector on the map +INT32 GetMapColour( INT16 sX, INT16 sY, UINT8 mode ) +{ + UINT8 sector = SECTOR( sX, sY ); + + switch ( mode ) + { + case MAPMODE_DISEASE: + { + UINT16 population = GetSectorPopulation( sX, sY ); + + if ( population ) + { + SECTORINFO *pSectorInfo = &(SectorInfo[sector]); + + // display sector information only if we know about infection there + if ( pSectorInfo && ((pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_PLAYER) || (gubFact[FACT_DISEASE_WHODATA_ACCESS] && pSectorInfo->usInfectionFlag & SECTORDISEASE_DIAGNOSED_WHO)) ) + { + FLOAT infectedpercentage = (FLOAT)pSectorInfo->usInfected / (FLOAT)(population); + + if ( infectedpercentage < 0.2f ) + return MAP_SHADE_DK_GREEN; + else if ( infectedpercentage < 0.3f ) + return MAP_SHADE_MD_GREEN; + else if ( infectedpercentage < 0.4f ) + return MAP_SHADE_LT_GREEN; + else if ( infectedpercentage < 0.5f ) + return MAP_SHADE_DK_YELLOW; + else if ( infectedpercentage < 0.6f ) + return MAP_SHADE_MD_YELLOW; + else if ( infectedpercentage < 0.7f ) + return MAP_SHADE_LT_YELLOW; + else if ( infectedpercentage < 0.8f ) + return MAP_SHADE_DK_RED; + else if ( infectedpercentage < 0.9f ) + return MAP_SHADE_MD_RED; + else + return MAP_SHADE_LT_RED; + } + } + } + break; + } + + return MAP_SHADE_DK_GREY; +} + +// handle infection redistribution if people move from A to B (set sXB and sYB to negative values to simply remove infected people in A) +void PopulationMove( INT16 sXA, INT16 sYA, INT16 sXB, INT16 sYB, UINT16 usAmount ) +{ + // we have to handle the impact on a sector's disease if people other than mercs move from A to B + if ( !gGameExternalOptions.fDiseaseStrategic ) + return; + + UINT8 sectorA = SECTOR( sXA, sYA ); + + SECTORINFO *pSectorInfoA = &(SectorInfo[sectorA]); + + UINT16 populationA = GetSectorPopulation( sXA, sYA ); + + if ( populationA ) + { + // how many people are already infected? + if ( pSectorInfoA ) + { + FLOAT infectionrateA = (FLOAT)(pSectorInfoA->usInfected) / (FLOAT)(populationA); + + UINT16 movinginfected = usAmount * infectionrateA; + + // we have to add the infection of movinginfected new infected with an infection level of pSectorInfoA->usInfectionSeverity + if ( movinginfected ) + { + // it is possible that there is no other sector + if ( sXB > -1 && sYB > -1 ) + { + UINT8 sectorB = SECTOR( sXB, sYB ); + + SECTORINFO *pSectorInfoB = &(SectorInfo[sectorB]); + + if ( pSectorInfoB ) + { + // new infection severity is the mean of old and new infected times their infection ratios + pSectorInfoB->fInfectionSeverity = (pSectorInfoB->fInfectionSeverity * pSectorInfoB->usInfected + pSectorInfoA->fInfectionSeverity * movinginfected) / (pSectorInfoB->usInfected + movinginfected); + pSectorInfoB->usInfected += movinginfected; + + // disease moves before population moves, so we have to add those too + UINT16 populationB = GetSectorPopulation( sXB, sYB ) + movinginfected; + + FLOAT infectedpercentage = 0; + if ( populationB ) + (FLOAT)pSectorInfoB->usInfected / (FLOAT)(populationB); + + if ( infectedpercentage >= GetSectorDiseaseOverFlowThreshold() || pSectorInfoB->fInfectionSeverity > ((FLOAT)Disease[0].sInfectionPtsOutbreak / (FLOAT)Disease[0].sInfectionPtsFull) ) + pSectorInfoB->usInfectionFlag |= (SECTORDISEASE_OUTBREAK | SECTORDISEASE_DIAGNOSED_WHO); + } + } + + // reduce the amount of infected in sector A + pSectorInfoA->usInfected -= movinginfected; + + // if no infected remain, clean up data + if ( !pSectorInfoA->usInfected ) + { + pSectorInfoA->fInfectionSeverity = 0; + pSectorInfoA->usInfectionFlag &= ~(SECTORDISEASE_OUTBREAK | SECTORDISEASE_DIAGNOSED_WHO | SECTORDISEASE_DIAGNOSED_PLAYER); + } + } + } + } +} + +void HandleDeathDiseaseImplications( SOLDIERTYPE *pSoldier ) +{ + if ( !gGameExternalOptions.fDisease || !gGameExternalOptions.fDiseaseStrategic || !pSoldier ) + return; + + UINT8 sector = SECTOR( pSoldier->sSectorX, pSoldier->sSectorY ); + + SECTORINFO *pSectorInfo = &(SectorInfo[sector]); + + if ( pSectorInfo ) + { + // if the deceased was infected and not a merc, reduce sector number of infected + if ( pSoldier->sDiseasePoints[0] && pSoldier->bTeam != OUR_TEAM ) + { + pSectorInfo->usInfected = max( 0, pSectorInfo->usInfected - 1 ); + } + + // if this guy was a medic, then medical personnel was killed - it will take a while before he will be replaced + if ( HAS_SKILL_TRAIT( pSoldier, DOCTOR_NT ) ) + { + pSectorInfo->usDiseaseDoctoringDelay = min( 255, pSectorInfo->usDiseaseDoctoringDelay + 12 ); + } + } +} + +void HandleDiseaseDailyRefresh() +{ + if ( gGameExternalOptions.fDisease && gGameExternalOptions.fDiseaseStrategic && gubFact[FACT_DISEASE_WHODATA_SUBSCRIBED] && LaptopSaveInfo.iCurrentBalance > gGameExternalOptions.sDiseaseWHOSubscriptionCost ) + { + gubFact[FACT_DISEASE_WHODATA_ACCESS] = TRUE; + + AddTransactionToPlayersBook( WHO_SUBSCRIPTION, 0, GetWorldTotalMin( ), (-1) * (INT32)gGameExternalOptions.sDiseaseWHOSubscriptionCost ); + } + else + { + gubFact[FACT_DISEASE_WHODATA_ACCESS] = FALSE; + } +} + +// heal sector population, return number of points used +UINT32 HealSectorPopulation( INT16 sX, INT16 sY, UINT32 uHealpts ) +{ + // how many points are needed to cure all disease? + UINT8 sector = SECTOR( sX, sY ); + + SECTORINFO *pSectorInfo = &(SectorInfo[sector]); + + if ( !pSectorInfo ) + return 0; + + UINT32 ptsused = uHealpts; + + // the amount of points needed to cure a single patient + UINT32 ptsneededforcure = pSectorInfo->fInfectionSeverity * Disease[0].sInfectionPtsFull; + + // if possible, cure people (we prioritise on this, as we want to lower the number os possible infection sources) + while ( pSectorInfo->usInfected && uHealpts >= ptsneededforcure ) + { + uHealpts -= ptsneededforcure; + --pSectorInfo->usInfected; + } + + // if there are still points let, but we cannot cure someone, at least lower their disease + if ( pSectorInfo->usInfected && uHealpts > 0 && Disease[0].sInfectionPtsFull ) + { + UINT32 totaldiseasepoints = pSectorInfo->usInfected * ptsneededforcure; + totaldiseasepoints = max( 0, totaldiseasepoints - uHealpts ); + + pSectorInfo->fInfectionSeverity = (FLOAT)totaldiseasepoints / (FLOAT)(pSectorInfo->usInfected * Disease[0].sInfectionPtsFull); + } + + // if there are no more infected, or infection is at 0, remove all traces of disease + if ( !pSectorInfo->usInfected || !pSectorInfo->fInfectionSeverity ) + { + pSectorInfo->usInfected = 0; + pSectorInfo->fInfectionSeverity = 0; + pSectorInfo->usInfectionFlag &= ~(SECTORDISEASE_OUTBREAK | SECTORDISEASE_DIAGNOSED_WHO | SECTORDISEASE_DIAGNOSED_PLAYER); + } + + ptsused -= uHealpts; + + return ptsused; +} + +// Flugente: get workforce effectiveness with regards to strategic disease +FLOAT GetWorkforceEffectivenessWithDisease( INT8 bTownId, UINT8 usTeam ) +{ + if ( !gGameExternalOptions.fDisease || !gGameExternalOptions.fDiseaseStrategic ) + return 1.0f; + + FLOAT val = 0.0f; + UINT8 sectors = 0; + + for ( UINT8 sX = 1; sX < MAP_WORLD_X - 1; ++sX ) + { + for ( UINT8 sY = 1; sY < MAP_WORLD_X - 1; ++sY ) + { + UINT16 strategicsector = CALCULATE_STRATEGIC_INDEX( sX, sY ); + + if ( StrategicMap[strategicsector].bNameId == bTownId ) + { + // if we check for the player team, we look for sectors free of the enemy + if ( OUR_TEAM == usTeam && StrategicMap[strategicsector].fEnemyControlled ) + continue; + else if ( ENEMY_TEAM == usTeam && !StrategicMap[strategicsector].fEnemyControlled ) + continue; + + UINT8 sector = SECTOR( sX, sY ); + SECTORINFO *pSectorInfo = &(SectorInfo[sector]); + + if ( !pSectorInfo ) + continue; + + UINT16 population = GetSectorPopulation( sX, sY, FALSE ); + + // only civilian population is relevant here + if ( population ) + { + // workforce effectivity in a sector is population minus cumulated effectivity loss of all infected, divided by entire population + val += (population - min( pSectorInfo->usInfected, population ) * pSectorInfo->fInfectionSeverity ) / population; + } + + ++sectors; + } + } + } + + if ( sectors ) + val /= sectors; + + return val; +} diff --git a/Tactical/Disease.h b/Tactical/Disease.h new file mode 100644 index 00000000..51d54c28 --- /dev/null +++ b/Tactical/Disease.h @@ -0,0 +1,159 @@ +#ifndef __DISEASE_H +#define __DISEASE_H + +/** +* @file +* @author Flugente (bears-pit.com) +*/ + +#include "Types.h" + +// number of different diseases. Altering this will alter the size of INT32 sDiseasePoints[NUM_DISEASES]; in SOLDIERTYPE +#define NUM_DISEASES 20 + +#include "Soldier Control.h" + +// infection types - how can we be infected +enum +{ + // infection depending on sector type + INFECTION_TYPE_SWAMP = 0, + INFECTION_TYPE_TROPICS, + + // infection by having sex + INFECTION_TYPE_SEX, + + // infection by contact with lifeforms + INFECTION_TYPE_CONTACT_HUMAN, // infection by human interaction + INFECTION_TYPE_CONTACT_CORPSE, // infection by interacting with corpses + + // infections when taking damage + INFECTION_TYPE_WOUND_ANIMAL, // wounded by an animal (bloodcat) + INFECTION_TYPE_WOUND_OPEN, // we have a new non-bandaged wound + INFECTION_TYPE_WOUND_GUNSHOT, // we were wounded by gunshot + + // wound caused statloss + INFECTION_TYPE_WOUND_AGI, + INFECTION_TYPE_WOUND_DEX, + INFECTION_TYPE_WOUND_STR, + INFECTION_TYPE_WOUND_WIS, + + INFECTION_TYPE_TRAUMATIC, // certain events traumatized us + + // infection by bad foodstuff + INFECTION_TYPE_BADFOOD, + INFECTION_TYPE_BADWATER, + + INFECTION_TYPE_MAX +}; + +// stats that can be affected +enum +{ + INFST_AGI = 0, + INFST_DEX, + INFST_STR, + INFST_WIS, + INFST_EXP, + + INFST_MAX +}; + +// disase flags for a sector +#define SECTORDISEASE_OUTBREAK 0x01 //1 // disease has officially broken out here - it can now be seen on the map, and the AI will try to remove it +#define SECTORDISEASE_DIAGNOSED_WHO 0x02 //2 // disease has been diagnosed by the WHO. This information can only be seen if the player has a contract with the WHO +#define SECTORDISEASE_DIAGNOSED_PLAYER 0x04 //4 // disease has been diagnosed by the player + +// properties of diseases +#define DISEASE_PROPERTY_CANBECURED 0x00000001 // this disease can be healed by doctoring +#define DISEASE_PROPERTY_REVERSEONFULL 0x00000002 // once sInfectionPtsFull are reached, the infection reverses - negative sInfectionPtsGainPerHour is used +#define DISEASE_PROPERTY_CANREINFECT 0x00000004 // infection can be reapplied if already infected +#define DISEASE_PROPERTY_HIDESYMBOL 0x00000008 // do not show a symbol for this disease on the merc's face, even if diagnosed + +#define DISEASE_PROPERTY_DISGUSTING 0x00000010 // other merc's will be disgusted by anyone with this disease if broken out + +typedef struct +{ + UINT8 uiIndex; + CHAR16 szName[80]; // name of disease, used for display + CHAR16 szFatName[80]; // name of disease, used for display + CHAR16 szDescription[256]; // a short description of the disease. Observe and learn, kids! + + // diseases are measured in disease points + INT32 sInfectionPtsInitial; // number of points gained on infection + INT32 sInfectionPtsOutbreak; // at this many points, the disease breaks out - effects start and one can see it + INT32 sInfectionPtsFull; // the nominal point of a full-blown infection. Effects are scaled towards this + INT32 sInfectionPtsGainPerHour; // extra points gained every hour if infected + + // infection chances and behaviour + UINT8 usInfectionChance[INFECTION_TYPE_MAX]; // percentage chance of being infected this way if conditions are fulfilled + UINT32 usDiseaseProperties; // properties of the disease + + // effects of disease (effect at sInfectionPtsFull points), scaled + INT8 sEffStat[INFST_MAX]; // stat effectivity is altered + INT8 sEffAP; // alter APs + UINT8 usMaxBreath; // max Breath is lowered by this percentage + INT8 sEffCarryStrength; // carrying strength + INT16 sLifeRegenHundreds; // alter hourly life regen by these hundreds + INT8 sNeedToSleep; // +/- need to sleep + INT16 sDrinkModifier; // +/- % water consumption + INT16 sFoodModifier; // +/- % water consumption +} DISEASE; + +//GLOBALS +extern DISEASE Disease[NUM_DISEASES]; + +void HandleDisease(); + +// handle possible infection of type aInfectionType to pSoldier. Possible related to pOtherSoldier (can be NULL !) +// chance gets modified by aModifier (contextual modifier) +// if fStrategicOnly == TRUE, then we only handle disease 0 +void HandlePossibleInfection( SOLDIERTYPE *pSoldier, SOLDIERTYPE* pOtherSoldier, UINT8 aInfectionType, FLOAT aModifier = 1.0f, BOOLEAN fStrategicOnly = FALSE ); + +////////////// STRATEGIC DISEASE ////////////////////////// + +enum +{ + MAPMODE_OFF = 0, + MAPMODE_DISEASE, + + MAPMODE_MAX, +}; + +// directions for adjacent sectors +enum { + SP_UP, + SP_LEFT, + SP_RIGHT, + SP_DOWN, + + SP_DIR_MAX, +}; + +// return number of adjacent sector or -1 if there is none +INT16 GetAdjacentSector( UINT8 sector, UINT8 spdir ); + +// get a sector population (not the tactical one - we use an xml estimation + troops present) +UINT16 GetSectorPopulation( INT16 sX, INT16 sY, BOOLEAN fWithMilitary = TRUE ); + +// colour for a sector on the map +INT32 GetMapColour( INT16 sX, INT16 sY, UINT8 mode ); + +// handle infection redistribution if people move from A to B (set sXB and sYB to negative values to simply remove infected people in A) +void PopulationMove( INT16 sXA, INT16 sYA, INT16 sXB, INT16 sYB, UINT16 usAmount ); + +void HandleDeathDiseaseImplications( SOLDIERTYPE *pSoldier ); + +void HandleDiseaseDailyRefresh(); + +// heal sector population, return number of points used +UINT32 HealSectorPopulation( INT16 sX, INT16 sY, UINT32 uHealpts ); + +// Flugente: get workforce effectiveness with regards to strategic disease +FLOAT GetWorkforceEffectivenessWithDisease( INT8 bTownId, UINT8 usTeam ); + +// if this fraction of a sector's population is infected, outbreak is declared regardless of infection severity +// Otherwise infection would be untreatable at this point +FLOAT GetSectorDiseaseOverFlowThreshold(); + +#endif //__DISEASE_H diff --git a/Tactical/Drugs And Alcohol.cpp b/Tactical/Drugs And Alcohol.cpp index 06e256b0..eebcc1ea 100644 --- a/Tactical/Drugs And Alcohol.cpp +++ b/Tactical/Drugs And Alcohol.cpp @@ -177,6 +177,14 @@ BOOLEAN ApplyDrugs( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject ) // SANDRO - merc records - stat damaged gMercProfiles[ pSoldier->ubProfile ].records.usTimesStatDamaged++; } + + // Flugente: if this can cure a disease, do so + if ( Drug[i].ubDiseaseCure > 0 ) + { + // we cure exactly enough to cure an outbreak + // Drug[i].ubDiseaseCure - 1 - the xml value is simply one higher than the disease type, otherwise we couldn't identify disease 0 + pSoldier->AddDiseasePoints( Drug[i].ubDiseaseCure - 1, -Disease[Drug[i].ubDiseaseCure - 1].sInfectionPtsOutbreak ); + } } } diff --git a/Tactical/Drugs And Alcohol.h b/Tactical/Drugs And Alcohol.h index 581facb9..0688fff5 100644 --- a/Tactical/Drugs And Alcohol.h +++ b/Tactical/Drugs And Alcohol.h @@ -1,7 +1,7 @@ #ifndef __DRUGS_AND_ALCOHOL_H #define __DRUGS_AND_ALCOHOL_H -#include "soldier control.h" +#include "Soldier Control.h" #define SOBER 0 #define FEELING_GOOD 1 @@ -84,6 +84,8 @@ typedef struct UINT8 ubDrugSideEffect; UINT8 ubDrugSideEffectRate; UINT8 ubMoralBacklash; + + UINT8 ubDiseaseCure; // this is a cure for disease x - 1. It will cure Disease[x].sInfectionPtsOutbreak points of disease. } DRUGTYPE; //GLOBALS diff --git a/Tactical/DynamicDialogue.cpp b/Tactical/DynamicDialogue.cpp index 4412cff9..b57a93aa 100644 --- a/Tactical/DynamicDialogue.cpp +++ b/Tactical/DynamicDialogue.cpp @@ -1243,11 +1243,14 @@ void AddOpinionEvent( UINT8 usProfileA, UINT8 usProfileB, UINT8 usEvent, BOOLEAN case OPINIONEVENT_AGAINST_US: gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] |= OPINIONFLAG_STAGE1_AGAINST_US; break; case OPINIONEVENT_FOR_US: gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] |= OPINIONFLAG_STAGE1_FOR_US; break; case OPINIONEVENT_AGAINST_ENEMY: gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] |= OPINIONFLAG_STAGE1_AGAINST_ENEMY; break; + case OPINIONEVENT_FOR_ENEMY: gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] |= OPINIONFLAG_STAGE1_FOR_ENEMY; break; case OPINIONEVENT_SOLVECONFLICT_REASON_GOOD: gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] |= OPINIONFLAG_STAGE1_SOLVECONFLICT_REASON_GOOD; break; case OPINIONEVENT_SOLVECONFLICT_REASON_BAD: gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] |= OPINIONFLAG_STAGE1_SOLVECONFLICT_REASON_BAD; break; case OPINIONEVENT_SOLVECONFLICT_AGGRESSIVE_GOOD:gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] |= OPINIONFLAG_STAGE1_SOLVECONFLICT_AGGRESSIVE_GOOD; break; case OPINIONEVENT_SOLVECONFLICT_AGGRESSIVE_BAD: gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] |= OPINIONFLAG_STAGE1_SOLVECONFLICT_AGGRESSIVE_BAD; break; + case OPINIONEVENT_DISEASE_DISGUSTING: gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] |= OPINIONFLAG_STAGE1_DISEASE_DISGUSTING; break; + case OPINIONEVENT_DISEASE_TREATMENT: gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] |= OPINIONFLAG_STAGE1_DISEASE_TREATMENT; break; default: break; } @@ -1322,88 +1325,6 @@ INT8 GetDynamicOpinionDay( UINT8 usProfileA, UINT8 usProfileB, UINT8 usDay ) opinion += gDynamicOpinionEvent[event].sOpinionModifier; } - /*if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][0] & OPINIONFLAG_STAGE1_FRIENDLYFIRE << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_FRIENDLYFIRE].sOpinionModifier; - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][0] & OPINIONFLAG_STAGE1_SNITCHSOLDMEOUT << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_SNITCHSOLDMEOUT].sOpinionModifier; - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][0] & OPINIONFLAG_STAGE1_INTERFERENCE << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_SNITCHINTERFERENCE].sOpinionModifier; - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][0] & OPINIONFLAG_STAGE1_FRIENDSWITHHATED << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_FRIENDSWITHHATED].sOpinionModifier; - - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][0] & OPINIONFLAG_STAGE1_CONTRACTEXTENSION << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_CONTRACTEXTENSION].sOpinionModifier; - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][0] & OPINIONFLAG_STAGE1_ORDEREDRETREAT << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_ORDEREDRETREAT].sOpinionModifier; - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][0] & OPINIONFLAG_STAGE1_CIVKILLER << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_CIVKILLER].sOpinionModifier; - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][0] & OPINIONFLAG_STAGE1_SLOWSUSDOWN << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_SLOWSUSDOWN].sOpinionModifier; - - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][1] & OPINIONFLAG_STAGE1_NOSHARINGFOOD << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_NOSHARINGFOOD].sOpinionModifier; - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][1] & OPINIONFLAG_STAGE1_ANNOYINGDISABILITY << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_ANNOYINGDISABILITY].sOpinionModifier; - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][1] & OPINIONFLAG_STAGE1_ADDICT << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_ADDICT].sOpinionModifier; - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][1] & OPINIONFLAG_STAGE1_THIEF << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_THIEF].sOpinionModifier; - - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][1] & OPINIONFLAG_STAGE1_WORSTCOMMANDEREVER << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_WORSTCOMMANDEREVER].sOpinionModifier; - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][1] & OPINIONFLAG_STAGE1_RICHGUY << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_RICHGUY].sOpinionModifier; - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][1] & OPINIONFLAG_STAGE1_BETTERGEAR << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_BETTERGEAR].sOpinionModifier; - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][1] & OPINIONFLAG_STAGE1_YOUMOUNTEDAGUNONMYBREASTS << usDay ) opinion += gDynamicOpinionEvent[OPINIONEVENT_YOUMOUNTEDAGUNONMYBREASTS].sOpinionModifier; - - - - - case OPINIONEVENT_BANDAGED: - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] & OPINIONFLAG_STAGE1_BANDAGED << usDay ) ++numflags; - break; - - case OPINIONEVENT_DRINKBUDDIES_GOOD: - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] & OPINIONFLAG_STAGE1_DRINKBUDDIES_GOOD << usDay ) ++numflags; - break; - - case OPINIONEVENT_DRINKBUDDIES_SUPER: - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] & OPINIONFLAG_STAGE1_DRINKBUDDIES_SUPER << usDay ) ++numflags; - break; - - case OPINIONEVENT_DRINKBUDDIES_BAD: - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] & OPINIONFLAG_STAGE1_DRINKBUDDIES_BAD << usDay ) ++numflags; - break; - - case OPINIONEVENT_DRINKBUDDIES_WORSE: - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] & OPINIONFLAG_STAGE1_DRINKBUDDIES_WORSE << usDay ) ++numflags; - break; - - case OPINIONEVENT_AGAINST_US: - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] & OPINIONFLAG_STAGE1_AGAINST_US << usDay ) ++numflags; - break; - - case OPINIONEVENT_FOR_US: - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] & OPINIONFLAG_STAGE1_FOR_US << usDay ) ++numflags; - break; - - case OPINIONEVENT_AGAINST_ENEMY: - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][2] & OPINIONFLAG_STAGE1_AGAINST_ENEMY << usDay ) ++numflags; - break; - - case OPINIONEVENT_FOR_ENEMY: - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE1_FOR_ENEMY << usDay ) ++numflags; - break; - - case OPINIONEVENT_SOLVECONFLICT_REASON_GOOD: - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE1_SOLVECONFLICT_REASON_GOOD << usDay ) ++numflags; - break; - - case OPINIONEVENT_SOLVECONFLICT_REASON_BAD: - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE1_SOLVECONFLICT_REASON_BAD << usDay ) ++numflags; - break; - - case OPINIONEVENT_SOLVECONFLICT_AGGRESSIVE_GOOD: - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE1_SOLVECONFLICT_AGGRESSIVE_GOOD << usDay ) ++numflags; - break; - - case OPINIONEVENT_SOLVECONFLICT_AGGRESSIVE_BAD: - if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE1_SOLVECONFLICT_AGGRESSIVE_BAD << usDay ) ++numflags; - break; - - default: - break; - } - - // event opinion is number of times this happened times opinion modifer - opinion = numflags * gDynamicOpinionEvent[usEvent].sOpinionModifier;*/ - // cut it down to INT8 return (INT8)opinion; } @@ -1626,6 +1547,20 @@ INT8 GetDynamicOpinion( UINT8 usProfileA, UINT8 usProfileB, UINT8 usEvent ) if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE4_SOLVECONFLICT_AGGRESSIVE_BAD ) ++numflags; break; + case OPINIONEVENT_DISEASE_DISGUSTING: + if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE1_DISEASE_DISGUSTING ) ++numflags; + if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE2_DISEASE_DISGUSTING ) ++numflags; + if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE3_DISEASE_DISGUSTING ) ++numflags; + if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE4_DISEASE_DISGUSTING ) ++numflags; + break; + + case OPINIONEVENT_DISEASE_TREATMENT: + if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE1_DISEASE_TREATMENT ) ++numflags; + if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE2_DISEASE_TREATMENT ) ++numflags; + if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE3_DISEASE_TREATMENT ) ++numflags; + if ( gMercProfiles[usProfileA].usDynamicOpinionFlagmask[usProfileB][3] & OPINIONFLAG_STAGE4_DISEASE_TREATMENT ) ++numflags; + break; + default: break; } @@ -2005,14 +1940,14 @@ void HandleDynamicOpinionChange( SOLDIERTYPE* pSoldier, UINT8 usEvent, BOOLEAN f switch ( usEvent ) { case OPINIONEVENT_CONTRACTEXTENSION: - break; - case OPINIONEVENT_ORDEREDRETREAT: case OPINIONEVENT_CIVKILLER: case OPINIONEVENT_ANNOYINGDISABILITY: case OPINIONEVENT_ADDICT: case OPINIONEVENT_THIEF: case OPINIONEVENT_WORSTCOMMANDEREVER: + case OPINIONEVENT_DISEASE_DISGUSTING: + case OPINIONEVENT_DISEASE_TREATMENT: break; case OPINIONEVENT_SLOWSUSDOWN: @@ -2046,12 +1981,6 @@ void HandleDynamicOpinionChange( SOLDIERTYPE* pSoldier, UINT8 usEvent, BOOLEAN f highestcoolness = HighestInventoryCoolness( pSoldier ); break; - case OPINIONEVENT_DRINKBUDDIES_GOOD: - break; - - case OPINIONEVENT_DRINKBUDDIES_BAD: - break; - default: // either unknown event, or event is handled elsewhere - exit return; @@ -2163,6 +2092,15 @@ void HandleDynamicOpinionChange( SOLDIERTYPE* pSoldier, UINT8 usEvent, BOOLEAN f case OPINIONEVENT_DRINKBUDDIES_BAD: break; + case OPINIONEVENT_DISEASE_DISGUSTING: + // not if the other guy is a doctor, is currently used as a doctor, or has disease themself + if ( pTeamSoldier->bAssignment == DOCTOR || pTeamSoldier->bAssignment == DISEASE_DOCTOR_SECTOR || HAS_SKILL_TRAIT( pTeamSoldier, DOCTOR_NT ) || pTeamSoldier->HasDisease(TRUE, FALSE, FALSE) ) + continue; + break; + + case OPINIONEVENT_DISEASE_TREATMENT: + break; + default: // either unknown event, or event is handled elsewhere - exit return; diff --git a/Tactical/DynamicDialogue.h b/Tactical/DynamicDialogue.h index 6a905c50..6668d793 100644 --- a/Tactical/DynamicDialogue.h +++ b/Tactical/DynamicDialogue.h @@ -54,6 +54,8 @@ enum OPINIONEVENT_SOLVECONFLICT_AGGRESSIVE_GOOD, // other guy attempted to solve the conflict agressively, and we thought that was good OPINIONEVENT_SOLVECONFLICT_AGGRESSIVE_BAD, // other guy attempted to solve the conflict agressively, and we thought that was bad + OPINIONEVENT_DISEASE_DISGUSTING, // we have a disease, which others might find disgusting + OPINIONEVENT_DISEASE_TREATMENT, // someone treated our diseases OPINIONEVENT_MAX }; @@ -223,17 +225,17 @@ extern DynamicOpinionEvent gDynamicOpinionEvent[OPINIONEVENT_MAX]; #define OPINIONFLAG_STAGE3_SOLVECONFLICT_AGGRESSIVE_BAD 0x00040000 //262144 #define OPINIONFLAG_STAGE4_SOLVECONFLICT_AGGRESSIVE_BAD 0x00080000 //524288 -/*#define OPINIONFLAG_STAGE1_AGAINST_US 0x00100000 //1048576 // was against us in dialogue -#define OPINIONFLAG_STAGE2_AGAINST_US 0x00200000 //2097152 -#define OPINIONFLAG_STAGE3_AGAINST_US 0x00400000 //4194304 -#define OPINIONFLAG_STAGE4_AGAINST_US 0x00800000 //8388608 +#define OPINIONFLAG_STAGE1_DISEASE_DISGUSTING 0x00100000 //1048576 // is diseased, which we find disgusting +#define OPINIONFLAG_STAGE2_DISEASE_DISGUSTING 0x00200000 //2097152 +#define OPINIONFLAG_STAGE3_DISEASE_DISGUSTING 0x00400000 //4194304 +#define OPINIONFLAG_STAGE4_DISEASE_DISGUSTING 0x00800000 //8388608 -#define OPINIONFLAG_STAGE1_FOR_US 0x01000000 //16777216 // other guy was for us in dialogue -#define OPINIONFLAG_STAGE2_FOR_US 0x02000000 //33554432 -#define OPINIONFLAG_STAGE3_FOR_US 0x04000000 //67108864 -#define OPINIONFLAG_STAGE4_FOR_US 0x08000000 //134217728 +#define OPINIONFLAG_STAGE1_DISEASE_TREATMENT 0x01000000 //16777216 // treated our disease, which we like +#define OPINIONFLAG_STAGE2_DISEASE_TREATMENT 0x02000000 //33554432 +#define OPINIONFLAG_STAGE3_DISEASE_TREATMENT 0x04000000 //67108864 +#define OPINIONFLAG_STAGE4_DISEASE_TREATMENT 0x08000000 //134217728 -#define OPINIONFLAG_STAGE1_AGAINST_ENEMY 0x10000000 //268435456 // was against our dialogue enemy in dialogue +/*#define OPINIONFLAG_STAGE1_AGAINST_ENEMY 0x10000000 //268435456 // was against our dialogue enemy in dialogue #define OPINIONFLAG_STAGE2_AGAINST_ENEMY 0x20000000 //536870912 #define OPINIONFLAG_STAGE3_AGAINST_ENEMY 0x40000000 //1073741824 #define OPINIONFLAG_STAGE4_AGAINST_ENEMY 0x80000000 //2147483648*/ diff --git a/Tactical/Faces.cpp b/Tactical/Faces.cpp index a47340cb..da65d5e5 100644 --- a/Tactical/Faces.cpp +++ b/Tactical/Faces.cpp @@ -2237,6 +2237,13 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE } } + // Flugente: disease + if ( MercPtrs[pFace->ubSoldierID]->HasDisease(TRUE, FALSE, TRUE) ) + { + DoRightIcon( uiRenderBuffer, pFace, sFaceX, sFaceY, bNumRightIcons, 28 ); + bNumRightIcons++; + } + switch( pSoldier->bAssignment ) { case DOCTOR: @@ -2361,6 +2368,31 @@ void HandleRenderFaceAdjustments( FACETYPE *pFace, BOOLEAN fDisplayBuffer, BOOLE sIconIndex_Assignment = 16; fDoIcon_Assignment = TRUE; break; + + case DISEASE_DIAGNOSE: + { + sIconIndex_Assignment = 29; + fDoIcon_Assignment = TRUE; + // determine our skill at detecting disease + sPtsAvailable = pSoldier->stats.bMedical / 2 + NUM_SKILL_TRAITS( pSoldier, DOCTOR_NT ) * 15; + sPtsAvailable = (sPtsAvailable * (100 + pSoldier->GetBackgroundValue( BG_PERC_DISEASE_DIAGNOSE ))) / 100; + + fShowNumber = TRUE; + fShowMaximum = FALSE; + } + break; + + case DISEASE_DOCTOR_SECTOR: + sIconIndex_Assignment = 1; + fDoIcon_Assignment = TRUE; + sPtsAvailable = CalculateHealingPointsForDoctor( MercPtrs[pFace->ubSoldierID], &usMaximumPts, FALSE ); + fShowNumber = TRUE; + fShowMaximum = TRUE; + + // divide both amounts by 10 to make the displayed numbers a little more user-palatable (smaller) + sPtsAvailable = (sPtsAvailable + 5) / 10; + usMaximumPts = (usMaximumPts + 5) / 10; + break; } // Check for being serviced... diff --git a/Tactical/Food.cpp b/Tactical/Food.cpp index 7ae51a81..02fa0eac 100644 --- a/Tactical/Food.cpp +++ b/Tactical/Food.cpp @@ -178,6 +178,10 @@ BOOLEAN ApplyFood( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject, BOOLEAN fForce, B poisonadd = min(poisonadd, gGameExternalOptions.usFoodMaxPoisoning), pSoldier->AddPoison(poisonadd); + + // we might get a disease from this... + FLOAT modifier = 1.0f - 2 * foodcondition; + HandlePossibleInfection( pSoldier, NULL, type == AP_EAT ? INFECTION_TYPE_BADFOOD : INFECTION_TYPE_BADWATER, modifier ); } FLOAT conditionmodifier = 0.5f * (1.0f + sqrt(foodcondition)); @@ -236,6 +240,13 @@ BOOLEAN ApplyFood( SOLDIERTYPE *pSoldier, OBJECTTYPE *pObject, BOOLEAN fForce, B ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szFoodTextStr[STR_FOOD_ATE], pSoldier->GetName(), Item[pObject->usItem].szItemName ); else ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szFoodTextStr[STR_FOOD_DRANK], pSoldier->GetName(), Item[pObject->usItem].szItemName ); + + // Flugente: if this guy has the disease, infect object + if ( pSoldier->sDiseasePoints[0] > 0 ) + (*pObject)[0]->data.sObjectFlag |= INFECTED; + // if object is infected, infect the victim + else if ( (*pObject)[0]->data.sObjectFlag & INFECTED ) + pSoldier->Infect( 0 ); // now remove a portion of the food item (or the whole item altogether) UINT16 ptsconsumed = UseKitPoints( pObject, Food[foodtype].ubPortionSize, pSoldier ); @@ -372,8 +383,17 @@ void HourlyFoodSituationUpdate( SOLDIERTYPE *pSoldier ) FLOAT temperaturemodifier = (FLOAT)(3 + sectortemperaturemod)/3; - FLOAT specialfoodmodifier = (100.0 + pSoldier->GetBackgroundValue(BG_PERC_FOOD) ) / 100.0; - FLOAT specialdrinkmodifier = (100.0 + pSoldier->GetBackgroundValue(BG_PERC_WATER)) / 100.0; + FLOAT specialfoodmodifier = 100.0 + pSoldier->GetBackgroundValue(BG_PERC_FOOD); + FLOAT specialdrinkmodifier = 100.0 + pSoldier->GetBackgroundValue(BG_PERC_WATER); + + for ( int i = 0; i < NUM_DISEASES; ++i ) + { + specialfoodmodifier += Disease[i].sFoodModifier * pSoldier->GetDiseaseMagnitude( i ); + specialdrinkmodifier += Disease[i].sDrinkModifier * pSoldier->GetDiseaseMagnitude( i ); + } + + specialfoodmodifier /= 100.0; + specialdrinkmodifier /= 100.0; // due to digestion, reduce our food and drink levels pSoldier->bFoodLevel = max(pSoldier->bFoodLevel - (INT32) (specialfoodmodifier * activitymodifier * gGameExternalOptions.usFoodDigestionHourlyBaseFood), FOOD_MIN); diff --git a/Tactical/Handle Items.cpp b/Tactical/Handle Items.cpp index acd3ee7c..60f81956 100644 --- a/Tactical/Handle Items.cpp +++ b/Tactical/Handle Items.cpp @@ -5247,6 +5247,15 @@ void CorpseMessageBoxCallBack( UINT8 ubExitValue ) } } } + + // we might get a disease from this... + // if the corpse is already rotting, chance of infection is greatly increased + FLOAT modifier = 1.0f; + ROTTING_CORPSE *pCorpse = GetCorpseAtGridNo( nextGridNoinSight, level ); + if ( pCorpse->def.ubType == ROTTING_STAGE2 ) + modifier = 5.0f; + + HandlePossibleInfection( gpTempSoldier, NULL, INFECTION_TYPE_CONTACT_CORPSE, modifier ); } } diff --git a/Tactical/Interface Enhanced.cpp b/Tactical/Interface Enhanced.cpp index 2e2975f7..500cb22b 100644 --- a/Tactical/Interface Enhanced.cpp +++ b/Tactical/Interface Enhanced.cpp @@ -2680,6 +2680,25 @@ void InternalInitEDBTooltipRegion( OBJECTTYPE * gpItemDescObject, UINT32 guiCurr MSYS_EnableRegion( &gUDBFasthelpRegions[ iFirstDataRegion + cnt ] ); cnt++; } + + //////////////////// DISEASE + if ( gGameExternalOptions.fDisease ) + { + if ( HasItemFlag( gpItemDescObject->usItem, DISEASEPROTECTION_FACE ) ) + { + swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[38], szUDBGenSecondaryStatsExplanationsTooltipText[38] ); + SetRegionFastHelpText( &(gUDBFasthelpRegions[iFirstDataRegion + cnt]), pStr ); + MSYS_EnableRegion( &gUDBFasthelpRegions[iFirstDataRegion + cnt] ); + cnt++; + } + else if ( HasItemFlag( gpItemDescObject->usItem, DISEASEPROTECTION_HAND ) ) + { + swprintf( pStr, L"%s%s", szUDBGenSecondaryStatsTooltipText[39], szUDBGenSecondaryStatsExplanationsTooltipText[39] ); + SetRegionFastHelpText( &(gUDBFasthelpRegions[iFirstDataRegion + cnt]), pStr ); + MSYS_EnableRegion( &gUDBFasthelpRegions[iFirstDataRegion + cnt] ); + cnt++; + } + } } ////////////////////////////////////////////////////// @@ -6252,6 +6271,7 @@ void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject ) cnt++; } } + ////////////////// DEFUSAL KIT //JMich_SkillsModifiers: Still needs a picture, currently using the wirecutters. if ( ( Item[gpItemDescObject->usItem].DisarmModifier > 0 && !fComparisonMode ) || @@ -6308,6 +6328,23 @@ void DrawSecondaryStats( OBJECTTYPE * gpItemDescObject ) BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 35, gItemDescGenSecondaryRegions[cnt].sLeft+sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop+sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL ); cnt++; } + + //////////////////// DISEASE + if ( gGameExternalOptions.fDisease ) + { + if ( (HasItemFlag( gpItemDescObject->usItem, DISEASEPROTECTION_FACE ) && !fComparisonMode) || + (fComparisonMode && HasItemFlag( gpComparedItemDescObject->usItem, DISEASEPROTECTION_FACE )) ) + { + BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 37, gItemDescGenSecondaryRegions[cnt].sLeft + sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL ); + ++cnt; + } + else if ( (HasItemFlag( gpItemDescObject->usItem, DISEASEPROTECTION_HAND ) && !fComparisonMode) || + (fComparisonMode && HasItemFlag( gpComparedItemDescObject->usItem, DISEASEPROTECTION_HAND )) ) + { + BltVideoObjectFromIndex( guiSAVEBUFFER, guiItemInfoSecondaryIcon, 37, gItemDescGenSecondaryRegions[cnt].sLeft + sOffsetX, gItemDescGenSecondaryRegions[cnt].sTop + sOffsetY, VO_BLT_SRCTRANSPARENCY, NULL ); + ++cnt; + } + } } void DrawPropertyValueInColour( INT16 iValue, UINT8 ubNumLine, UINT8 ubNumRegion, BOOLEAN fComparisonMode, BOOLEAN fModifier, BOOLEAN fHigherBetter, UINT16 uiOverwriteColour = 0, BOOLEAN fPercentSign = FALSE ) diff --git a/Tactical/Interface Panels.cpp b/Tactical/Interface Panels.cpp index fa948d2b..c43d75ca 100644 --- a/Tactical/Interface Panels.cpp +++ b/Tactical/Interface Panels.cpp @@ -2998,6 +2998,16 @@ void RenderSMPanel( BOOLEAN *pfDirty ) swprintf( pStr, TacticalStr[ MERC_VITAL_STATS_POPUPTEXT ], gpSMCurrentMerc->stats.bLife, gpSMCurrentMerc->stats.bLifeMax, gpSMCurrentMerc->bBreath, gpSMCurrentMerc->bBreathMax, pMoraleStr ); } } + + { + CHAR16 atStr[500]; + swprintf( atStr, L"" ); + + gpSMCurrentMerc->PrintDiseaseDesc( atStr ); + + wcscat( pStr, atStr ); + } + SetRegionFastHelpText( &(gSM_SELMERCBarsRegion), pStr ); // Buggler: skills/traits tooltip on merc portrait @@ -5688,6 +5698,16 @@ void RenderTEAMPanel( BOOLEAN fDirty ) swprintf( pStr, TacticalStr[ MERC_VITAL_STATS_POPUPTEXT ], pSoldier->stats.bLife, pSoldier->stats.bLifeMax, pSoldier->bBreath, pSoldier->bBreathMax, pMoraleStr ); } } + + { + CHAR16 atStr[500]; + swprintf( atStr, L"" ); + + pSoldier->PrintDiseaseDesc( atStr ); + + wcscat( pStr, atStr ); + } + SetRegionFastHelpText( &(gTEAM_BarsRegions[ cnt ]), pStr ); // Buggler: skills/traits tooltip on merc portrait diff --git a/Tactical/Interface.cpp b/Tactical/Interface.cpp index 7ff2b8e7..b4f1c701 100644 --- a/Tactical/Interface.cpp +++ b/Tactical/Interface.cpp @@ -2311,7 +2311,6 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID ) //----------------- if ( pSoldier->bInSector && pSoldier->ubProfile == NO_PROFILE ) { -#ifdef ENABLE_ZOMBIES if ( pSoldier->IsZombie() ) { swprintf(NameStr, pSoldier->name); @@ -2324,9 +2323,7 @@ void DrawSelectedUIAboveGuy( UINT16 usSoldierID ) gprintfdirty( sX, sY, NameStr ); mprintf( sX, sY, NameStr ); } - else -#endif - if ( pSoldier->bTeam == ENEMY_TEAM ) + else if ( pSoldier->bTeam == ENEMY_TEAM ) { // Flugente: soldier profiles if ( gGameExternalOptions.fSoldierProfiles_Enemy && pSoldier->usSoldierProfile ) diff --git a/Tactical/Interface.h b/Tactical/Interface.h index 963d599c..e347e8d4 100644 --- a/Tactical/Interface.h +++ b/Tactical/Interface.h @@ -152,6 +152,7 @@ enum { BG_RESI_SUPPRESSION, BG_RESI_PHYSICAL, BG_RESI_ALCOHOL, + BG_RESI_DISEASE, // various BG_PERC_INTERROGATION, @@ -173,7 +174,7 @@ enum { BG_PERC_CTH_MAX, BG_PERC_HEARING_NIGHT, BG_PERC_HEARING_DAY, - BG_TRAP_DISARM, + BG_PERC_DISARM, // approaches BG_PERC_APPROACH_FRIENDLY, @@ -186,6 +187,8 @@ enum { BG_PERC_CTH_CREATURE, BG_PERC_INSURANCE, BG_PERC_SPOTTER, + BG_PERC_DISEASE_DIAGNOSE, + BG_PERC_DISEASE_TREAT, BG_DISLIKEBG, // dislike any other background that has the negative of this value set diff --git a/Tactical/Item Types.h b/Tactical/Item Types.h index 4328a738..0d975e69 100644 --- a/Tactical/Item Types.h +++ b/Tactical/Item Types.h @@ -765,10 +765,10 @@ extern OBJECTTYPE gTempObject; #define SIGNAL_SHELL 0x04000000 //67108864 // this is a signal shell that precedes artillery barrages #define POWER_PACK 0x08000000 //134217728 // item continously powers an item it is attached to -/*#define SPOTTERITEM 0x10000000 //268435456 // binocular -#define PLAYER_NET_2_LVL_4 0x20000000 //536870912 -#define PLAYER_NET_3_LVL_4 0x40000000 //1073741824 -#define PLAYER_NET_4_LVL_4 0x80000000 //2147483648*/ +#define SPOTTERITEM 0x10000000 //268435456 // binocular +#define DISEASEPROTECTION_FACE 0x20000000 //536870912 // this item protects us from getting diseases by human contact if worn in a face slot +#define DISEASEPROTECTION_HAND 0x40000000 //1073741824 // this item protects us from getting diseases by human contact if kept in inventory +/*#define PLAYER_NET_4_LVL_4 0x80000000 //2147483648*/ // ---------------------------------------------------------------- // -------- added by Flugente: flags for objects -------- @@ -813,11 +813,13 @@ extern OBJECTTYPE gTempObject; #define CORPSE_NO_VEST 0x40000000 //1073741824 // corpse has no vest item (it has been either taken or been destroyed) #define CORPSE_NO_PANTS 0x80000000 //2147483648 // corpse has no pants item/for tripwire activation (gets set and unset when activating tripwire) -#define TRIPWIRE_ACTIVATED 0x0000000100000000 // 4294967296 -#define TAKEN_BY_MILITIA 0x0000000200000000 // 8589934592 +#define TRIPWIRE_ACTIVATED 0x0000000100000000 // 4294967296 +#define TAKEN_BY_MILITIA 0x0000000200000000 // 8589934592 // this item was picked up by militia #define TAKEN_BY_MILITIA_TABOO_GREEN 0x0000000400000000 // 17179869184 // this item is taboo for green militia (have to reset flag for world item upon dropping it) #define TAKEN_BY_MILITIA_TABOO_BLUE 0x0000000800000000 // 34359738368 // this item is taboo for blue militia (have to reset flag for world item upon dropping it) +#define INFECTED 0x0000001000000000 // // this item is infected with disease 0, getting damaged by this will infect you + // Flugente TODO 2012-09-17: next time we break savegame compatibility, extend the flagmasks from UINT32 to UINT64. I didn't do it this time (see double-used flag above), as we try to minimise those breaks. But it is needed. // ---------------------------------------------------------------- diff --git a/Tactical/Items.cpp b/Tactical/Items.cpp index f19e61b8..d0b00b28 100644 --- a/Tactical/Items.cpp +++ b/Tactical/Items.cpp @@ -3153,7 +3153,12 @@ UINT32 CalculateCarriedWeight( SOLDIERTYPE * pSoldier ) ubStrengthForCarrying = (ubStrengthForCarrying * (100 + gSkillTraitValues.ubBBCarryWeightBonus) / 100); // plus one third } - ubStrengthForCarrying = (ubStrengthForCarrying * (100 + pSoldier->GetBackgroundValue(BG_PERC_CARRYSTRENGTH)) / 100); + // Flugente: diseases can affect stat effectivity + INT16 diseaseeffect = 0; + for ( int i = 0; i < NUM_DISEASES; ++i ) + diseaseeffect += Disease[i].sEffCarryStrength * pSoldier->GetDiseaseMagnitude( i ); + + ubStrengthForCarrying = (ubStrengthForCarrying * (100 + diseaseeffect + 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 diff --git a/Tactical/Items.h b/Tactical/Items.h index 8a474510..4b401c12 100644 --- a/Tactical/Items.h +++ b/Tactical/Items.h @@ -509,6 +509,8 @@ typedef struct INT8 sRadioScanModifier; // modifies the scan range of the radio scan assignment in this sector UINT16 usPrisonRoomNumber[MAX_PRISON_ROOMS]; // room numbers of prisons + UINT16 usCivilianPopulation; // total amount of civilians that are supposed to be in this sector. This does not have to be the number of civilians in tactical + } SECTOR_EXT_DATA; // get dirt increase for object with attachments, fConsiderAmmo: with ammo diff --git a/Tactical/LOS.cpp b/Tactical/LOS.cpp index f13a8075..86845cf9 100644 --- a/Tactical/LOS.cpp +++ b/Tactical/LOS.cpp @@ -2585,9 +2585,20 @@ BOOLEAN BulletHitMerc( BULLET * pBullet, STRUCTURE * pStructure, BOOLEAN fIntend AddItemToPool(pTarget->sGridNo, &gTempObject, -1, pTarget->pathing.bLevel, 0, 0); // Make team look for items NotifySoldiersToLookforItems(); + + // Flugente: if this guy has the disease, or the blade was already infected, the new one will be too + if ( pTarget->sDiseasePoints[0] > 0 || pBullet->usFlags & BULLET_FLAG_INFECTED ) + (*&gTempObject)[0]->data.sObjectFlag |= INFECTED; } else + { CreateItem(usItem, usItemStatus, &pTarget->inv[bSlot]); + + // Flugente: if this guy has the disease, or the blade was already infected, the new one will be too + if ( pTarget->sDiseasePoints[0] > 0 || pBullet->usFlags & BULLET_FLAG_INFECTED ) + pTarget->inv[bSlot][0]->data.sObjectFlag |= INFECTED; + } + ubAmmoType = AMMO_KNIFE; } else if (pBullet->fFragment) @@ -2600,6 +2611,13 @@ BOOLEAN BulletHitMerc( BULLET * pBullet, STRUCTURE * pStructure, BOOLEAN fIntend ubAmmoType = pFirer->inv[pFirer->ubAttackingHand][0]->data.gun.ubGunAmmoType; } + // Flugente: if bullet is infected, give us disease (this is intended for throwing knifes) + if ( pBullet->usFlags & BULLET_FLAG_INFECTED ) + { + // infect us with the first disease + pTarget->Infect( 0 ); + } + // HEADROCK HAM 5.1: This is an utter hack, but it may be necessary. This soldier is hit by a fragment, // so he needs to have his animations be interruptible. This takes care of soldiers hitting themselves // with their own fragments. @@ -4503,6 +4521,10 @@ INT8 FireBulletGivenTargetNCTH( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, if ( AmmoTypes[(*pObjAttHand)[0]->data.gun.ubGunAmmoType].ammoflag & AMMO_ANTIMATERIEL ) usBulletFlags |= BULLET_FLAG_ANTIMATERIEL; + // Flugente: if object is infected, missile is too (intended for throwing knifes) + if ( (*pObjAttHand)[0]->data.sObjectFlag & INFECTED ) + usBulletFlags |= BULLET_FLAG_INFECTED; + ubImpact =(UINT8) GetDamage(&pFirer->inv[pFirer->ubAttackingHand]); //zilpin: Begin new code block for spread patterns, number of projectiles, impact adjustment, etc. { @@ -4987,6 +5009,10 @@ INT8 FireBulletGivenTarget( SOLDIERTYPE * pFirer, FLOAT dEndX, FLOAT dEndY, FLOA if ( AmmoTypes[ pFirer->inv[pFirer->ubAttackingHand][0]->data.gun.ubGunAmmoType ].ammoflag & AMMO_ANTIMATERIEL ) usBulletFlags |= BULLET_FLAG_ANTIMATERIEL; + // Flugente: if object is infected, missile is too (intended for throwing knifes) + if ( (*pObjAttHand)[0]->data.sObjectFlag & INFECTED ) + usBulletFlags |= BULLET_FLAG_INFECTED; + ubImpact =(UINT8) GetDamage(pObjAttHand); //zilpin: pellet spread patterns externalized in XML /* zilpin: The section below, including line comments, is the original adjustment made to multiple projectile stats. diff --git a/Tactical/Morale.cpp b/Tactical/Morale.cpp index 678b722f..1c56fc0a 100644 --- a/Tactical/Morale.cpp +++ b/Tactical/Morale.cpp @@ -145,6 +145,9 @@ DynamicOpinionEvent gDynamicOpinionEvent[OPINIONEVENT_MAX] = {OPINIONEVENT_SOLVECONFLICT_REASON_BAD, -2, TRUE, FALSE, TRUE, FALSE}, {OPINIONEVENT_SOLVECONFLICT_AGGRESSIVE_GOOD, 3, TRUE, FALSE, TRUE, FALSE}, {OPINIONEVENT_SOLVECONFLICT_AGGRESSIVE_BAD, -3, TRUE, FALSE, TRUE, FALSE}, + {OPINIONEVENT_DISEASE_DISGUSTING, -3, TRUE, FALSE, TRUE, FALSE}, + {OPINIONEVENT_DISEASE_TREATMENT, 1, TRUE, FALSE, TRUE, FALSE}, + }; BOOLEAN gfSomeoneSaidMoraleQuote = FALSE; @@ -1023,6 +1026,9 @@ void HandleMoraleEvent( SOLDIERTYPE *pSoldier, INT8 bMoraleEvent, INT16 sMapX, I break; } + // Flugente: if the situation is really, REALLY bad, we can get traumatized + if ( pSoldier && pSoldier->aiData.bMorale < 15 ) + HandlePossibleInfection( pSoldier, NULL, INFECTION_TYPE_TRAUMATIC ); // some morale events also impact the player's reputation with the mercs back home switch( bMoraleEvent ) diff --git a/Tactical/Overhead.cpp b/Tactical/Overhead.cpp index c823b9de..3e8d94a4 100644 --- a/Tactical/Overhead.cpp +++ b/Tactical/Overhead.cpp @@ -8316,16 +8316,14 @@ void HandleSuppressionFire( UINT8 ubTargetedMerc, UINT8 ubCausedAttacker ) //////////////////////////////////////////////////////////////////////////////////////////////////// // Loop through every character. - for (uiLoop = 0; uiLoop < guiNumMercSlots; uiLoop++) + for (uiLoop = 0; uiLoop < guiNumMercSlots; ++uiLoop ) { DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("HandleSuppressionFire: loop = %d, numslots = %d ",uiLoop, guiNumMercSlots)); pSoldier = MercSlots[uiLoop]; -#ifdef ENABLE_ZOMBIES // Flugente: zombies do not receive any suppression at all! if ( pSoldier != NULL && pSoldier->IsZombie() ) continue; -#endif // Has this character received any Suppression Points since the last attack? // HEADROCK: Suppression Points accumulate by bullets flying near the character. It includes @@ -9949,11 +9947,11 @@ BOOLEAN HostileZombiesPresent( ) return( FALSE ); } - for ( iLoop = gTacticalStatus.Team[ CREATURE_TEAM ].bFirstID; iLoop <= gTacticalStatus.Team[ CREATURE_TEAM ].bLastID; iLoop++ ) + for ( iLoop = gTacticalStatus.Team[ CREATURE_TEAM ].bFirstID; iLoop <= gTacticalStatus.Team[ CREATURE_TEAM ].bLastID; ++iLoop ) { pSoldier = MercPtrs[ iLoop ]; - if ( pSoldier->bActive && pSoldier->bInSector && pSoldier->stats.bLife > 0 && pSoldier->IsZombie() ) + if ( pSoldier && pSoldier->bActive && pSoldier->bInSector && pSoldier->stats.bLife > 0 && pSoldier->IsZombie( ) ) { return( TRUE ); } diff --git a/Tactical/SkillCheck.cpp b/Tactical/SkillCheck.cpp index b49374ec..61bcce04 100644 --- a/Tactical/SkillCheck.cpp +++ b/Tactical/SkillCheck.cpp @@ -50,7 +50,12 @@ INT16 EffectiveStrength( SOLDIERTYPE *pSoldier, BOOLEAN fTrainer ) iEffStrength = 0; } - iEffStrength = (iEffStrength * (100 + pSoldier->GetBackgroundValue(BG_STRENGTH))) / 100; + // Flugente: diseases can affect stat effectivity + INT16 diseaseeffect = 0; + for ( int i = 0; i < NUM_DISEASES; ++i ) + diseaseeffect += Disease[i].sEffStat[INFST_STR] * pSoldier->GetDiseaseMagnitude( i ); + + iEffStrength = (iEffStrength * (100 + diseaseeffect + pSoldier->GetBackgroundValue( BG_STRENGTH ))) / 100; // ATE: Make sure at least 2... iEffStrength = __max( iEffStrength, 2 ); @@ -69,7 +74,12 @@ INT16 EffectiveWisdom( SOLDIERTYPE * pSoldier) iEffWisdom = EffectStatForBeingDrunk( pSoldier, iEffWisdom ); - iEffWisdom = (iEffWisdom * (100 + pSoldier->GetBackgroundValue(BG_WISDOM))) / 100; + // Flugente: diseases can affect stat effectivity + INT16 diseaseeffect = 0; + for ( int i = 0; i < NUM_DISEASES; ++i ) + diseaseeffect += Disease[i].sEffStat[INFST_WIS] * pSoldier->GetDiseaseMagnitude( i ); + + iEffWisdom = (iEffWisdom * (100 + diseaseeffect + pSoldier->GetBackgroundValue( BG_WISDOM ))) / 100; return( (INT16) iEffWisdom ); } @@ -90,7 +100,12 @@ INT16 EffectiveAgility( SOLDIERTYPE * pSoldier, BOOLEAN fTrainer ) iEffAgility = (iEffAgility * 100) / pSoldier->sWeightCarriedAtTurnStart; } - iEffAgility = (iEffAgility * (100 + pSoldier->GetBackgroundValue(BG_AGILITY))) / 100; + // Flugente: diseases can affect stat effectivity + INT16 diseaseeffect = 0; + for ( int i = 0; i < NUM_DISEASES; ++i ) + diseaseeffect += Disease[i].sEffStat[INFST_AGI] * pSoldier->GetDiseaseMagnitude( i ); + + iEffAgility = (iEffAgility * (100 + diseaseeffect + pSoldier->GetBackgroundValue( BG_AGILITY ))) / 100; return( (INT16) iEffAgility ); } @@ -196,7 +211,12 @@ INT8 EffectiveExpLevel( SOLDIERTYPE * pSoldier ) } } - iEffExpLevel += pSoldier->bExtraExpLevel; + // Flugente: diseases can affect stat effectivity + INT16 diseaseeffect = 0; + for ( int i = 0; i < NUM_DISEASES; ++i ) + diseaseeffect += Disease[i].sEffStat[INFST_EXP] * pSoldier->GetDiseaseMagnitude( i ); + + iEffExpLevel += diseaseeffect + pSoldier->bExtraExpLevel; if (iEffExpLevel > 10) { @@ -208,10 +228,8 @@ INT8 EffectiveExpLevel( SOLDIERTYPE * pSoldier ) // can't go below 1 return( 1 ); } - else - { - return( (INT8) iEffExpLevel ); - } + + return( (INT8) iEffExpLevel ); } INT8 EffectiveMarksmanship( SOLDIERTYPE * pSoldier ) @@ -238,7 +256,12 @@ INT16 EffectiveDexterity( SOLDIERTYPE * pSoldier, BOOLEAN fTrainer ) iEffDexterity = EffectStatForBeingDrunk( pSoldier, iEffDexterity ); - iEffDexterity = (iEffDexterity * (100 + pSoldier->GetBackgroundValue(BG_DEXTERITY))) / 100; + // Flugente: diseases can affect stat effectivity + INT16 diseaseeffect = 0; + for ( int i = 0; i < NUM_DISEASES; ++i ) + diseaseeffect += Disease[i].sEffStat[INFST_DEX] * pSoldier->GetDiseaseMagnitude( i ); + + iEffDexterity = (iEffDexterity * (100 + diseaseeffect + pSoldier->GetBackgroundValue( BG_DEXTERITY ))) / 100; return( (INT16) iEffDexterity ); } @@ -458,7 +481,7 @@ INT32 SkillCheck( SOLDIERTYPE * pSoldier, INT8 bReason, INT8 bChanceMod ) iSkill += EffectiveExpLevel( pSoldier ) * 10; // Flugente: backgrounds - iSkill += pSoldier->GetBackgroundValue(BG_TRAP_DISARM); + iSkill += pSoldier->GetBackgroundValue( BG_PERC_DISARM ); iSkill = iSkill / 10; // bring the value down to a percentage //JMich_SkillModifiers: Adding a Disarm Trap bonus diff --git a/Tactical/Soldier Ani.cpp b/Tactical/Soldier Ani.cpp index d93bceaa..092f548e 100644 --- a/Tactical/Soldier Ani.cpp +++ b/Tactical/Soldier Ani.cpp @@ -4006,6 +4006,9 @@ BOOLEAN HandleSoldierDeath( SOLDIERTYPE *pSoldier , BOOLEAN *pfMadeCorpse ) // Flugente: campaign stats gCurrentIncident.AddStat( pSoldier, CAMPAIGNHISTORY_TYPE_KILL ); + // Flugente: disease + HandleDeathDiseaseImplications( pSoldier ); + if ( TurnSoldierIntoCorpse( pSoldier, TRUE, TRUE ) ) { *pfMadeCorpse = TRUE; diff --git a/Tactical/Soldier Control.cpp b/Tactical/Soldier Control.cpp index 65aaf92d..39d3aee4 100644 --- a/Tactical/Soldier Control.cpp +++ b/Tactical/Soldier Control.cpp @@ -5807,10 +5807,24 @@ void SOLDIERTYPE::EVENT_SoldierGotHit( UINT16 usWeaponIndex, INT16 sDamage, INT1 ubReason = TAKE_DAMAGE_BLADE; // Flugente: check wether we can make this blade bloody - if ( ubAttackerID != NOBODY && MercPtrs[ubAttackerID]->inv[HANDPOS].exists( ) && Item[MercPtrs[ubAttackerID]->inv[HANDPOS].usItem].bloodieditem > 0 ) + if ( ubAttackerID != NOBODY && MercPtrs[ubAttackerID]->inv[HANDPOS].exists( ) ) { - // magic happens - MercPtrs[ubAttackerID]->inv[HANDPOS].usItem = Item[MercPtrs[ubAttackerID]->inv[HANDPOS].usItem].bloodieditem; + if ( Item[MercPtrs[ubAttackerID]->inv[HANDPOS].usItem].bloodieditem > 0 ) + { + // magic happens + MercPtrs[ubAttackerID]->inv[HANDPOS].usItem = Item[MercPtrs[ubAttackerID]->inv[HANDPOS].usItem].bloodieditem; + } + + // Flugente: if the blade is infected, infect the victim + if ( *&(MercPtrs[ubAttackerID]->inv[HANDPOS])[0]->data.sObjectFlag & INFECTED ) + { + // infect us with the first disease + this->Infect( 0 ); + } + + // if this guy has the disease, infect the blade + if ( this->sDiseasePoints[0] > 0 ) + *&(MercPtrs[ubAttackerID]->inv[HANDPOS])[0]->data.sObjectFlag |= INFECTED; } } else if ( Item[usWeaponIndex].usItemClass & IC_PUNCH ) @@ -9984,11 +9998,7 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sPo // ATE: Put some logic in here to allow enemies to die quicker..... // Are we an enemy? // zombies don't die suddenly, as they regenerate health by bloodloss and poison. You have to make sure they die! -#ifdef ENABLE_ZOMBIES if ( this->bSide != gbPlayerNum && !this->aiData.bNeutral && this->ubProfile == NO_PROFILE && !this->IsZombie( ) ) -#else - if ( this->bSide != gbPlayerNum && !this->aiData.bNeutral && this->ubProfile == NO_PROFILE ) -#endif { // ATE: Give them a chance to fall down... if ( this->stats.bLife > 0 && this->stats.bLife < (OKLIFE - 1) ) @@ -10051,6 +10061,26 @@ UINT8 SOLDIERTYPE::SoldierTakeDamage( INT8 bHeight, INT16 sLifeDeduct, INT16 sPo if ( sLifeDeduct > 0 ) this->usSoldierFlagMask |= SOLDIER_FRESHWOUND; + // Flugente we might get a disease from this... + if ( gGameExternalOptions.fDisease ) + { + if ( ubAttacker != NOBODY && MercPtrs[ubAttacker] && CREATURE_OR_BLOODCAT( MercPtrs[ubAttacker] ) ) + HandlePossibleInfection( this, MercPtrs[ubAttacker], INFECTION_TYPE_WOUND_ANIMAL ); + + if ( sLifeDeduct > 0 && ubReason == TAKE_DAMAGE_GUNFIRE ) + HandlePossibleInfection( this, NULL, INFECTION_TYPE_WOUND_GUNSHOT ); + else if ( sLifeDeduct > 0 && ( ubReason == TAKE_DAMAGE_BLADE || ubReason == TAKE_DAMAGE_HANDTOHAND + || ubReason == TAKE_DAMAGE_EXPLOSION || ubReason == TAKE_DAMAGE_STRUCTURE_EXPLOSION || ubReason == TAKE_DAMAGE_TENTACLES ) ) + { + FLOAT modifier = 0.5f + sLifeDeduct/100; + HandlePossibleInfection( this, NULL, INFECTION_TYPE_WOUND_OPEN, modifier ); + } + + // possibly get traumatized if we're hit really bad + if ( this->stats.bLife < OKLIFE ) + HandlePossibleInfection( this, NULL, INFECTION_TYPE_TRAUMATIC ); + } + // Calculate damage to our items if from an explosion! if ( ubReason == TAKE_DAMAGE_EXPLOSION || ubReason == TAKE_DAMAGE_STRUCTURE_EXPLOSION ) { @@ -12297,13 +12327,7 @@ void SOLDIERTYPE::EVENT_SoldierBeginPunchAttack( INT32 sGridNo, UINT8 ubDirectio #ifdef JA2UB if ( fMartialArtist && !Item[usItem].crowbar && this->ubBodyType == REGMALE ) #else - -#ifdef ENABLE_ZOMBIES if ( fMartialArtist && !AreInMeanwhile( ) && !Item[usItem].crowbar && this->ubBodyType == REGMALE && !IsZombie( ) ) // SANDRO - added check for body type -#else - if ( fMartialArtist && !AreInMeanwhile( ) && !Item[usItem].crowbar && this->ubBodyType == REGMALE ) // SANDRO - added check for body type -#endif - #endif { // Are we in attack mode yet? @@ -14649,12 +14673,14 @@ INT16 SOLDIERTYPE::GetSoldierCriticalDamageBonus( void ) } -#ifdef ENABLE_ZOMBIES BOOLEAN SOLDIERTYPE::IsZombie( void ) { +#ifdef ENABLE_ZOMBIES return(ubSoldierClass == SOLDIER_CLASS_ZOMBIE); -} +#else + return FALSE; #endif +} INT16 SOLDIERTYPE::GetPoisonResistance( void ) { @@ -14690,11 +14716,9 @@ INT16 SOLDIERTYPE::GetPoisonDamagePercentage( void ) // Flugente: this percentage has to be between 0% and 100% INT16 val = 0; -#ifdef ENABLE_ZOMBIES // zombies poison damage percentage is externalised if ( IsZombie( ) ) val += gGameExternalOptions.sZombiePoisonDamagePercentage; -#endif if ( this->usAttackingWeapon ) { @@ -15873,11 +15897,9 @@ BOOLEAN SOLDIERTYPE::RecognizeAsCombatant( UINT8 ubTargetID ) if ( !pSoldier ) return TRUE; -#ifdef ENABLE_ZOMBIES // zombies don't care about disguises if ( IsZombie( ) ) return TRUE; -#endif // not in covert mode: we recognize him if ( (pSoldier->usSoldierFlagMask & (SOLDIER_COVERT_CIV | SOLDIER_COVERT_SOLDIER)) == 0 ) @@ -17297,6 +17319,13 @@ INT16 SOLDIERTYPE::GetAPBonus( ) if ( this->pathing.bLevel ) bonus += this->GetBackgroundValue( BG_HEIGHT ); + // diseases can affect stat effectivity + INT16 diseaseeffect = 0; + for ( int i = 0; i < NUM_DISEASES; ++i ) + diseaseeffect += Disease[i].sEffAP * this->GetDiseaseMagnitude( i ); + + bonus += diseaseeffect; + return bonus; } @@ -18663,6 +18692,274 @@ void SOLDIERTYPE::DeleteBoxingFlag( ) flags.uiStatusFlags &= (~SOLDIER_BOXER); } +// Flugente: disease +void SOLDIERTYPE::Infect( UINT8 aDisease ) +{ + // we are getting infected. Raise our disease points, but not over the level of an infection + if ( aDisease < NUM_DISEASES && this->sDiseasePoints[aDisease] < Disease[aDisease].sInfectionPtsInitial ) + { + // if this guy is not of our team, note that a new infected person is in the sector + if ( this->bTeam != gbPlayerNum && aDisease == 0 && this->sDiseasePoints[0] <= 0 ) + { + UINT8 sector = SECTOR( this->sSectorX, this->sSectorY ); + + SECTORINFO *pSectorInfo = &(SectorInfo[sector]); + + if ( pSectorInfo ) + ++pSectorInfo->usInfected; + } + + this->sDiseasePoints[aDisease] = min( this->sDiseasePoints[aDisease] + Disease[aDisease].sInfectionPtsInitial, Disease[aDisease].sInfectionPtsInitial ); + + if ( this->sDiseasePoints[aDisease] > Disease[aDisease].sInfectionPtsOutbreak ) + { + this->sDiseaseFlag[aDisease] |= SOLDIERDISEASE_OUTBREAK; + + this->AnnounceDisease( aDisease ); + } + + // remove later on, for testing only + if ( 1 ) + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, L"%s was infected with %s", gMercProfiles[this->ubProfile].zNickname, Disease[aDisease].szName ); + } +} + +void SOLDIERTYPE::AddDiseasePoints( UINT8 aDisease, INT32 aVal ) +{ + if ( aDisease < NUM_DISEASES ) + { + this->sDiseasePoints[aDisease] = min( Disease[aDisease].sInfectionPtsFull, max( this->sDiseasePoints[aDisease] + aVal, -Disease[aDisease].sInfectionPtsOutbreak ) ); + + // if the disease 'breaks out', make it known + if ( this->sDiseasePoints[aDisease] > Disease[aDisease].sInfectionPtsOutbreak ) + { + this->sDiseaseFlag[aDisease] |= SOLDIERDISEASE_OUTBREAK; + + if ( !(this->sDiseaseFlag[aDisease] & SOLDIERDISEASE_DIAGNOSED) ) + this->AnnounceDisease( aDisease ); + } + + // once disease is fullblown, some diseases reverse themself + if ( (Disease[aDisease].usDiseaseProperties & DISEASE_PROPERTY_REVERSEONFULL) && this->sDiseasePoints[aDisease] >= Disease[aDisease].sInfectionPtsFull ) + { + this->sDiseaseFlag[aDisease] |= SOLDIERDISEASE_REVERSEAL; + } + + // if disease is cured, remove traces of it + if ( this->sDiseasePoints[aDisease] <= 0 ) + { + this->sDiseaseFlag[aDisease] &= ~(SOLDIERDISEASE_DIAGNOSED | SOLDIERDISEASE_OUTBREAK); + + if ( this->bTeam == gbPlayerNum ) + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szDiseaseText[TEXT_DISEASE_CURED], this->GetName( ), Disease[aDisease].szName ); + } + } +} + +void SOLDIERTYPE::AnnounceDisease( UINT8 aDisease ) +{ + this->sDiseaseFlag[aDisease] |= SOLDIERDISEASE_DIAGNOSED; + + if ( this->bTeam == gbPlayerNum ) + ScreenMsg( FONT_MCOLOR_LTYELLOW, MSG_INTERFACE, szDiseaseText[TEXT_DISEASE_DIAGNOSE_GENERAL], this->GetName( ), Disease[aDisease].szName ); +} + +// do we have any disease? fDiagnosedOnly: check for wether we know of this infection fHealableOnly: check wether it can be healed +BOOLEAN SOLDIERTYPE::HasDisease( BOOLEAN fDiagnosedOnly, BOOLEAN fHealableOnly, BOOLEAN fSymbolOnly ) +{ + for ( int i = 0; i < NUM_DISEASES; ++i ) + { + // disease is relevant if we are infected and are not looking for symbols only while the disease has no symbol + if ( this->sDiseasePoints[i] > 0 && !(fSymbolOnly && (Disease[i].usDiseaseProperties & DISEASE_PROPERTY_HIDESYMBOL)) ) + { + // only if we don't check for diagnosis, or we already know of this + if ( !fDiagnosedOnly || (this->sDiseaseFlag[i] & SOLDIERDISEASE_DIAGNOSED) ) + { + // only if we don't check for cure, or this can be cured + if ( !fHealableOnly || (Disease[i].usDiseaseProperties & DISEASE_PROPERTY_CANBECURED) ) + { + return TRUE; + } + } + } + } + + return FALSE; +} + +// get the magnitude os a disease we might have, used to determine wether there are any effects +FLOAT SOLDIERTYPE::GetDiseaseMagnitude( UINT8 aDisease ) +{ + // diseases only have effects once they have broken out (otherwise stuff happens without the player having any clue as to why) + if ( aDisease < NUM_DISEASES && this->sDiseasePoints[aDisease] > 0 && (this->sDiseaseFlag[aDisease] & SOLDIERDISEASE_OUTBREAK) ) + { + return ((FLOAT)this->sDiseasePoints[aDisease] / (FLOAT)Disease[aDisease].sInfectionPtsFull); + } + + return 0.0f; +} + +void SOLDIERTYPE::PrintDiseaseDesc( CHAR16* apStr, BOOLEAN fFullDesc ) +{ + // only for living mercs with a profile with a valid infection method + if ( this->flags.uiStatusFlags & SOLDIER_VEHICLE || this->ubProfile == NO_PROFILE ) + return; + + CHAR16 atStr[500]; + swprintf( atStr, L"" ); + + for ( int i = 0; i < NUM_DISEASES; ++i ) + { + if ( this->sDiseaseFlag[i] & SOLDIERDISEASE_DIAGNOSED ) + { + swprintf( atStr, L"\n\n%s\n", Disease[i].szFatName ); + wcscat( apStr, atStr ); + + // if we give a full description, also print out the effects at the moment + if ( fFullDesc ) + { + swprintf( atStr, L"%s\n", Disease[i].szDescription ); + wcscat( apStr, atStr ); + + FLOAT magnitude = GetDiseaseMagnitude(i); + + for ( int j = 0; j < INFST_MAX; ++j ) + { + INT8 val = Disease[i].sEffStat[j] * magnitude; + + if ( val ) + { + swprintf( atStr, szDiseaseText[j], val > 0 ? L"+" : L"", val ); + wcscat( apStr, atStr ); + } + } + + { + INT8 val = Disease[i].sEffAP * magnitude; + + if ( val ) + { + swprintf( atStr, szDiseaseText[TEXT_DISEASE_AP], val > 0 ? L"+" : L"", val ); + wcscat( apStr, atStr ); + } + } + + { + UINT8 val = Disease[i].usMaxBreath * magnitude; + + if ( val ) + { + swprintf( atStr, szDiseaseText[TEXT_DISEASE_MAXBREATH], L"-", val ); + wcscat( apStr, atStr ); + } + } + + { + INT8 val = Disease[i].sEffCarryStrength * magnitude; + + if ( val ) + { + swprintf( atStr, szDiseaseText[TEXT_DISEASE_CARRYSTRENGTH], val > 0 ? L"+" : L"", val ); + wcscat( apStr, atStr ); + } + } + + { + FLOAT val = (FLOAT)(Disease[i].sLifeRegenHundreds) * magnitude / 100; + + if ( val ) + { + swprintf( atStr, szDiseaseText[TEXT_DISEASE_LIFEREGENHUNDREDS], val > 0 ? L"+" : L"", val ); + wcscat( apStr, atStr ); + } + } + + { + INT8 val = Disease[i].sNeedToSleep * magnitude; + + if ( val ) + { + swprintf( atStr, szDiseaseText[TEXT_DISEASE_NEEDTOSLEEP], val > 0 ? L"+" : L"", val ); + wcscat( apStr, atStr ); + } + } + + { + INT16 val = Disease[i].sDrinkModifier * magnitude; + + if ( val ) + { + swprintf( atStr, szDiseaseText[TEXT_DISEASE_DRINK], val > 0 ? L"+" : L"", val ); + wcscat( apStr, atStr ); + } + } + + { + INT16 val = Disease[i].sFoodModifier * magnitude; + + if ( val ) + { + swprintf( atStr, szDiseaseText[TEXT_DISEASE_FOOD], val > 0 ? L"+" : L"", val ); + wcscat( apStr, atStr ); + } + } + } + } + } +} + +// get percentage protection from infections via contact +FLOAT SOLDIERTYPE::GetDiseaseContactProtection( ) +{ + FLOAT val = 0.0f; + + // if we wear special equipment, lower our chances of being infected + FLOAT bestfacegear = 0.0f; + FLOAT bestprotectivegear = 0.0f; + INT8 invsize = (INT8)inv.size( ); // remember inventorysize, so we don't call size() repeatedly + for ( INT8 bLoop = 0; bLoop < invsize; ++bLoop ) + { + if ( inv[bLoop].exists( ) ) + { + OBJECTTYPE* pObj = &(inv[bLoop]); + + if ( pObj && (*pObj)[0]->data.objectStatus >= USABLE ) + { + if ( (bLoop == HEAD1POS || bLoop == HEAD2POS) ) + { + if ( HasItemFlag( pObj->usItem, DISEASEPROTECTION_FACE ) ) + { + bestfacegear = max( bestfacegear, (FLOAT)((*pObj)[0]->data.objectStatus / 100) ); + } + } + else if ( HasItemFlag( pObj->usItem, DISEASEPROTECTION_HAND ) ) + { + bestprotectivegear = max( bestprotectivegear, (FLOAT)((*pObj)[0]->data.objectStatus / 100) ); + } + } + } + } + + // up to 100% protection if face and hand protection is worn + val += (bestfacegear + bestprotectivegear) / 2; + + // not higher than 100% + return min( val, 1.0f ); +} + +INT16 SOLDIERTYPE::GetDiseaseResistance() +{ + // Flugente: resistance can per definition only be between -100 and 100 (at least that's my definition) + INT16 val = 0; + + val += this->GetBackgroundValue( BG_RESI_DISEASE ); + + val = max( -100, val ); + val = min( 100, val ); + + return(val); +} + INT32 CheckBleeding( SOLDIERTYPE *pSoldier ) { diff --git a/Tactical/Soldier Control.h b/Tactical/Soldier Control.h index c1333c75..fba0dad0 100644 --- a/Tactical/Soldier Control.h +++ b/Tactical/Soldier Control.h @@ -19,6 +19,7 @@ #include #include #include "GameSettings.h" // added by Flugente +#include "Disease.h" // added by Flugente #define PTR_CIVILIAN (pSoldier->bTeam == CIV_TEAM) #define PTR_CROUCHED (gAnimControl[ pSoldier->usAnimState ].ubHeight == ANIM_CROUCH) @@ -409,6 +410,15 @@ enum #define SOLDIER_INTERROGATE_ALL 0x000000F8 // all interrogation flags // ---------------------------------------------------------------- +// -------- added by Flugente: disease property flags -------- +// easier than adding 32 differently named variables. DO NOT CHANGE THEM, UNLESS YOU KNOW WHAT YOU ARE DOING!!! +// these flags describe how a disease has affected us so far +#define SOLDIERDISEASE_DIAGNOSED 0x00000001 //1 // it is now known that we have this disease - either a doctor diagnosed it, or it broke out an we are currently suffering +#define SOLDIERDISEASE_OUTBREAK 0x00000002 //2 // disease has broken out - we suffer the effects now. Without this flag, it is active but does not do any damage to us +#define SOLDIERDISEASE_REVERSEAL 0x00000004 //4 // disease is reversing - every hour we receive negative points. This is used to simulate a disease healing itself + + + // -------- 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 @@ -1469,6 +1479,10 @@ public: UINT8 usAISkillUse; // this variable allows the AI to remember which skill it wants to use UINT16 usSkillCounter[SOLDIER_COUNTER_MAX]; // counters used for various skill/trait/taint effects UINT32 usSkillCooldown[SOLDIER_COOLDOWN_MAX]; // cooldown used for various skill/trait/taint effects + + // Flugente: diseases + INT16 sDiseasePoints[NUM_DISEASES]; // we store the state of our diseases here + UINT8 sDiseaseFlag[NUM_DISEASES]; // we need to store some special flags for every disease // Flugente: Decrease this filler by 1 for each new UINT8 / BOOLEAN variable, so we can maintain savegame compatibility!! // Note that we also have to account for padding, so you might need to substract more than just the size of the new variables @@ -1691,10 +1705,8 @@ public: INT16 GetSoldierCriticalDamageBonus( void ); // Flugente: determines critical damage bonus depending on class, skill, etc. -#ifdef ENABLE_ZOMBIES // Flugente: Zombies BOOLEAN IsZombie( void ); -#endif // Flugente: poison system // These functions might one day be modified by traits etc. We'll keep that in these functions and not clutter the rest of the code @@ -1849,6 +1861,21 @@ public: // Flugente: boxing fix: this shall be the only location where the boxing flag gets removed (easier debugging) void DeleteBoxingFlag(); + // Flugente: disease + void Infect( UINT8 aDisease ); + void AddDiseasePoints( UINT8 aDisease, INT32 aVal ); + void AnnounceDisease( UINT8 aDisease ); + + // do we have any disease? + // fDiagnosedOnly: check for wether we know of this infection + // fHealableOnly: check wether it can be healed + // fSymbolOnly: only show if symbol should be shown + BOOLEAN HasDisease(BOOLEAN fDiagnosedOnly, BOOLEAN fHealableOnly, BOOLEAN fSymbolOnly = FALSE); + FLOAT GetDiseaseMagnitude( UINT8 aDisease ); // get the magnitude os a disease we might have, used to determine wether there are any effects + void PrintDiseaseDesc( CHAR16* apStr, BOOLEAN fFullDesc = FALSE ); + FLOAT GetDiseaseContactProtection(); // get percentage protection from infections via contact + INT16 GetDiseaseResistance(); + ////////////////////////////////////////////////////////////////////////////// }; // SOLDIERTYPE; diff --git a/Tactical/Soldier Create.cpp b/Tactical/Soldier Create.cpp index b7aad00c..4bf4407a 100644 --- a/Tactical/Soldier Create.cpp +++ b/Tactical/Soldier Create.cpp @@ -581,33 +581,34 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 * tbTeam=pCreateStruct->bTeam; tfPP=pCreateStruct->fPlayerPlan; //used as temp indicator of struct sent from the server //hayden. - if(is_networked) { - if(is_networked && (pCreateStruct->fOnRoof==1)) + if(is_networked) { - ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"skipping roof merc"); - return NULL; - } + if(is_networked && (pCreateStruct->fOnRoof==1)) + { + ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"skipping roof merc"); + return NULL; + } - if(is_client && !is_server && (tbTeam >0 && tbTeam < 5) && tfPP==0) - { - return NULL; // pure client to not spawn AI unless from server, Hayden. - //gTacticalStatus.Team[ tbTeam ].bTeamActive=0; - } - //if(is_server && tbTeam>0 && tbTeam<5) - if(is_server && tbTeam>0 && tbTeam<5) - { - send_AI(pCreateStruct,pubID); - } - if(is_client && !is_server && tfPP==1) - { - pCreateStruct->fPlayerPlan = 0; - } + if(is_client && !is_server && (tbTeam >0 && tbTeam < 5) && tfPP==0) + { + return NULL; // pure client to not spawn AI unless from server, Hayden. + //gTacticalStatus.Team[ tbTeam ].bTeamActive=0; + } + //if(is_server && tbTeam>0 && tbTeam<5) + if(is_server && tbTeam>0 && tbTeam<5) + { + send_AI(pCreateStruct,pubID); + } + if(is_client && !is_server && tfPP==1) + { + pCreateStruct->fPlayerPlan = 0; + } - if(is_networked && (pCreateStruct->bBodyType==23 || pCreateStruct->bBodyType==24)) - { - ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"skipping tank"); - return NULL; - } + if(is_networked && (pCreateStruct->bBodyType==23 || pCreateStruct->bBodyType==24)) + { + ScreenMsg( FONT_YELLOW, MSG_MPSYSTEM, L"skipping tank"); + return NULL; + } } //hayden @@ -785,19 +786,68 @@ SOLDIERTYPE* TacticalCreateSoldier( SOLDIERCREATE_STRUCT *pCreateStruct, UINT8 * } Soldier.bActionPoints = Soldier.CalcActionPoints( ); - Soldier.bInitialActionPoints = Soldier.bActionPoints; - Soldier.bSide = gTacticalStatus.Team[ Soldier.bTeam ].bSide; - Soldier.bActive = TRUE; - Soldier.sSectorX = pCreateStruct->sSectorX; - Soldier.sSectorY = pCreateStruct->sSectorY; - Soldier.bSectorZ = pCreateStruct->bSectorZ; - Soldier.ubInsertionDirection = pCreateStruct->ubDirection; - Soldier.pathing.bDesiredDirection = pCreateStruct->ubDirection; - Soldier.aiData.bDominantDir = pCreateStruct->ubDirection; + Soldier.bInitialActionPoints = Soldier.bActionPoints; + Soldier.bSide = gTacticalStatus.Team[ Soldier.bTeam ].bSide; + Soldier.bActive = TRUE; + Soldier.sSectorX = pCreateStruct->sSectorX; + Soldier.sSectorY = pCreateStruct->sSectorY; + Soldier.bSectorZ = pCreateStruct->bSectorZ; + Soldier.ubInsertionDirection = pCreateStruct->ubDirection; + Soldier.pathing.bDesiredDirection = pCreateStruct->ubDirection; + Soldier.aiData.bDominantDir = pCreateStruct->ubDirection; Soldier.ubDirection = pCreateStruct->ubDirection; - Soldier.sInsertionGridNo = pCreateStruct->sInsertionGridNo; - Soldier.bOldLife = Soldier.stats.bLifeMax; + Soldier.sInsertionGridNo = pCreateStruct->sInsertionGridNo; + Soldier.bOldLife = Soldier.stats.bLifeMax; + + // Flugente: disease can affect a soldier's health + if ( gGameExternalOptions.fDisease && gGameExternalOptions.fDiseaseStrategic && Soldier.bTeam != OUR_TEAM && Soldier.bTeam != CREATURE_TEAM && Soldier.ubSoldierClass != SOLDIER_CLASS_TANK ) + { + UINT8 sector = SECTOR( Soldier.sSectorX, Soldier.sSectorY ); + UINT16 population = GetSectorPopulation( Soldier.sSectorX, Soldier.sSectorY ); + + // if this is autoresolve, we have to get the sector in a different way.. + if ( guiCurrentScreen == AUTORESOLVE_SCREEN ) + { + sector = GetAutoResolveSectorID( ); + + population = GetSectorPopulation( SECTORX( sector ), SECTORY( sector ) ); + } + + if ( population ) + { + SECTORINFO *pSectorInfo = &(SectorInfo[sector]); + + if ( pSectorInfo && pSectorInfo->usInfected ) + { + UINT16 chanceofinfection = 100 * (FLOAT)(pSectorInfo->usInfected) / (FLOAT)(population); + + if ( Chance( chanceofinfection ) ) + { + INT32 diseaseamount = Disease[0].sInfectionPtsFull * pSectorInfo->fInfectionSeverity; + Soldier.AddDiseasePoints( 0, diseaseamount ); + + // if disease has broken out, lower life points + if ( Soldier.sDiseaseFlag[0] & SOLDIERDISEASE_OUTBREAK ) + { + // we only alter breath and life points here, stats effectivity will be handled automatically + FLOAT magnitude = Soldier.GetDiseaseMagnitude( 0 ); + + UINT16 diseasemaxbreathreduction = Disease[0].usMaxBreath * magnitude; + + Soldier.bBreathMax = min( Soldier.bBreathMax, 100 - diseasemaxbreathreduction ); + Soldier.bBreath = min( Soldier.bBreath, Soldier.bBreathMax ); + + INT8 lifereduction = (6 * Disease[0].sLifeRegenHundreds) * (magnitude / 100); + + Soldier.stats.bLifeMax = max( OKLIFE, Soldier.stats.bLifeMax + lifereduction ); + Soldier.stats.bLifeMax = min( 100, Soldier.stats.bLifeMax ); + Soldier.stats.bLife = min( Soldier.stats.bLife, Soldier.stats.bLifeMax ); + } + } + } + } + } // If a civvy, set neutral if ( Soldier.bTeam == CIV_TEAM ) @@ -1923,12 +1973,10 @@ BOOLEAN TacticalCopySoldierFromCreateStruct( SOLDIERTYPE *pSoldier, SOLDIERCREAT { swprintf( pSoldier->name, gzLateLocalizedString[ 36 ] ); } -#ifdef ENABLE_ZOMBIES else if ( pSoldier->IsZombie() ) { swprintf( pSoldier->name, TacticalStr[ ZOMBIE_TEAM_MERC_NAME ] ); } -#endif else { swprintf( pSoldier->name, TacticalStr[ CREATURE_TEAM_MERC_NAME ] ); break; diff --git a/Tactical/Tactical_VS2005.vcproj b/Tactical/Tactical_VS2005.vcproj index d2b5058f..99f065eb 100644 --- a/Tactical/Tactical_VS2005.vcproj +++ b/Tactical/Tactical_VS2005.vcproj @@ -394,6 +394,10 @@ RelativePath=".\Dialogue Control.h" > + + @@ -744,6 +748,10 @@ RelativePath=".\Dialogue Control.cpp" > + + @@ -1068,6 +1076,10 @@ RelativePath=".\XML_CompatibleFaceItems.cpp" > + + diff --git a/Tactical/Tactical_VS2008.vcproj b/Tactical/Tactical_VS2008.vcproj index a821ba55..fb52a9ee 100644 --- a/Tactical/Tactical_VS2008.vcproj +++ b/Tactical/Tactical_VS2008.vcproj @@ -398,6 +398,10 @@ RelativePath="Dialogue Control.h" > + + @@ -746,6 +750,10 @@ RelativePath="Dialogue Control.cpp" > + + @@ -1070,6 +1078,10 @@ RelativePath="XML_CompatibleFaceItems.cpp" > + + diff --git a/Tactical/Tactical_VS2010.vcxproj b/Tactical/Tactical_VS2010.vcxproj index d0c31564..d77237f7 100644 --- a/Tactical/Tactical_VS2010.vcxproj +++ b/Tactical/Tactical_VS2010.vcxproj @@ -37,6 +37,7 @@ + @@ -124,6 +125,7 @@ + @@ -204,6 +206,7 @@ + diff --git a/Tactical/Tactical_VS2010.vcxproj.filters b/Tactical/Tactical_VS2010.vcxproj.filters index 3eb2a027..ef03e050 100644 --- a/Tactical/Tactical_VS2010.vcxproj.filters +++ b/Tactical/Tactical_VS2010.vcxproj.filters @@ -51,6 +51,9 @@ Header Files + + Header Files + Header Files @@ -308,6 +311,9 @@ Source Files + + Source Files + Source Files @@ -625,6 +631,9 @@ Source Files + + + Source Files Source Files diff --git a/Tactical/Tactical_VS2013.vcxproj b/Tactical/Tactical_VS2013.vcxproj index 49f40446..92464f4f 100644 --- a/Tactical/Tactical_VS2013.vcxproj +++ b/Tactical/Tactical_VS2013.vcxproj @@ -37,6 +37,7 @@ + @@ -125,6 +126,7 @@ + @@ -205,6 +207,7 @@ + diff --git a/Tactical/Tactical_VS2013.vcxproj.filters b/Tactical/Tactical_VS2013.vcxproj.filters index a2bbcdf9..64296322 100644 --- a/Tactical/Tactical_VS2013.vcxproj.filters +++ b/Tactical/Tactical_VS2013.vcxproj.filters @@ -273,6 +273,9 @@ Header Files + + Header Files + @@ -680,5 +683,11 @@ Source Files + + Source Files + + + Source Files + \ No newline at end of file diff --git a/Tactical/Weapons.cpp b/Tactical/Weapons.cpp index f9eb92fd..e5a206f3 100644 --- a/Tactical/Weapons.cpp +++ b/Tactical/Weapons.cpp @@ -9442,7 +9442,6 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget, INT8 bStatLoss = 0; UINT8 ubAmmoType; -#ifdef ENABLE_ZOMBIES if ( pTarget->IsZombie() ) { // if bullet does not hits anything other than the head, it doesn't do any damage @@ -9458,7 +9457,6 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget, pTarget->usSoldierFlagMask &= ~SOLDIER_HEADSHOT; } } -#endif // NOTE: reduction of bullet impact due to range and obstacles is handled // in MoveBullet. @@ -9843,6 +9841,9 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget, gMercProfiles[ pTarget->ubProfile ].bWisdom = pTarget->stats.bWisdom; } + // Flugente: disease + HandlePossibleInfection( pTarget, pFirer, INFECTION_TYPE_WOUND_WIS ); + if (pTarget->name[0] && pTarget->bVisible == TRUE) { // make stat RED for a while... @@ -9935,6 +9936,9 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget, gMercProfiles[ pTarget->ubProfile ].bDexterity = pTarget->stats.bDexterity; } + // Flugente: disease + HandlePossibleInfection( pTarget, pFirer, INFECTION_TYPE_WOUND_DEX ); + if (pTarget->name[0] && pTarget->bVisible == TRUE) { // make stat RED for a while... @@ -9969,6 +9973,9 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget, gMercProfiles[ pTarget->ubProfile ].bStrength = pTarget->stats.bStrength; } + // Flugente: disease + HandlePossibleInfection( pTarget, pFirer, INFECTION_TYPE_WOUND_STR ); + if (pTarget->name[0] && pTarget->bVisible == TRUE) { // make stat RED for a while... @@ -10004,6 +10011,9 @@ INT32 BulletImpact( SOLDIERTYPE *pFirer, BULLET *pBullet, SOLDIERTYPE * pTarget, gMercProfiles[ pTarget->ubProfile ].bAgility = pTarget->stats.bAgility; } + // Flugente: disease + HandlePossibleInfection( pTarget, pFirer, INFECTION_TYPE_WOUND_AGI ); + if (pTarget->name[0] && pTarget->bVisible == TRUE) { // make stat RED for a while... @@ -10330,7 +10340,6 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO BOOLEAN autoresolve = IsAutoResolveActive(); iImpact = max( 1, (INT32)(iImpact * (100 - pTarget->GetDamageResistance(autoresolve, FALSE)) / 100 ) ); -#ifdef ENABLE_ZOMBIES // Flugente: if the target is a zombie, any melee attack, regardless of hit location, will set the headshot flag. Thus any zombie killed in melee will stay dead (if you play with that option) if ( pTarget->IsZombie() ) { @@ -10340,7 +10349,6 @@ INT32 HTHImpact( SOLDIERTYPE * pSoldier, SOLDIERTYPE * pTarget, INT32 iHitBy, BO pTarget->usSoldierFlagMask |= SOLDIER_HEADSHOT; } } -#endif return( iImpact ); } diff --git a/Tactical/XML.h b/Tactical/XML.h index d2fe61a2..4999e430 100644 --- a/Tactical/XML.h +++ b/Tactical/XML.h @@ -238,6 +238,7 @@ typedef PARSE_STAGE; #define SQUADNAMEFILENAME "SquadNames.xml" #define BACKGROUNDSFILENAME "Backgrounds.xml" #define CAMPAIGNSTATSEVENTSFILENAME "CampaignStatsEvents.xml" +#define DISEASEFILENAME "Disease.xml" #define TAUNTSFOLDERNAME "EnemyTaunts\\" #define TAUNTSFILENAME "EnemyTaunts.xml" @@ -308,6 +309,10 @@ extern BOOLEAN WriteDrugsStats(); extern BOOLEAN ReadInFoodStats(STR fileName); extern BOOLEAN WriteFoodStats(); +// Flugente: disease +extern BOOLEAN ReadInDiseaseStats( STR fileName ); +extern BOOLEAN WriteDiseaseStats( ); + // Flugente: merchants extern BOOLEAN ReadInMerchantStats(STR fileName); extern BOOLEAN WriteMerchantStats(); diff --git a/Tactical/XML_Background.cpp b/Tactical/XML_Background.cpp index 91457e96..4f9aa971 100644 --- a/Tactical/XML_Background.cpp +++ b/Tactical/XML_Background.cpp @@ -97,6 +97,7 @@ backgroundStartElementHandle(void *userData, const XML_Char *name, const XML_Cha strcmp(name, "resistance_suppression") == 0 || strcmp(name, "resistance_physical") == 0 || strcmp(name, "resistance_alcohol") == 0 || + strcmp(name, "resistance_disease" ) == 0 || strcmp(name, "interrogation") == 0 || strcmp(name, "prisonguard") == 0 || strcmp(name, "betterprices_guns") == 0 || @@ -125,6 +126,8 @@ backgroundStartElementHandle(void *userData, const XML_Char *name, const XML_Cha strcmp(name, "cth_vs_creatures") == 0 || strcmp(name, "insurance") == 0 || strcmp(name, "spotter") == 0 || + strcmp(name, "disease_diagnose" ) == 0 || + strcmp(name, "disease_treatment" ) == 0 || strcmp(name, "dislikebackground" ) == 0 || strcmp(name, "druguse") == 0 || strcmp(name, "xenophobic") == 0 || @@ -380,6 +383,11 @@ backgroundEndElementHandle(void *userData, const XML_Char *name) 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, "resistance_disease" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_RESI_DISEASE] = min( XML_BACKGROUND_RESI_MAX, max( -XML_BACKGROUND_RESI_MAX, (INT8)atol( pData->szCharData ) ) ); + } else if(strcmp(name, "interrogation") == 0) { pData->curElement = ELEMENT; @@ -478,7 +486,7 @@ backgroundEndElementHandle(void *userData, const XML_Char *name) else if(strcmp(name, "disarm_trap") == 0) { pData->curElement = ELEMENT; - pData->curBackground.value[BG_TRAP_DISARM] = min(50, max(-50, (INT16) atol(pData->szCharData) )); + pData->curBackground.value[BG_PERC_DISARM] = min( 50, max( -50, (INT16)atol( pData->szCharData ) ) ); } else if(strcmp(name, "approach_friendly") == 0) { @@ -520,6 +528,16 @@ backgroundEndElementHandle(void *userData, const XML_Char *name) pData->curElement = ELEMENT; pData->curBackground.value[BG_PERC_SPOTTER] = min(30, max(-30, (INT16) atol(pData->szCharData) )); } + else if ( strcmp( name, "disease_diagnose" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_DISEASE_DIAGNOSE] = min( 50, max( -50, (INT16)atol( pData->szCharData ) ) ); + } + else if ( strcmp( name, "disease_treatment" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curBackground.value[BG_PERC_DISEASE_TREAT] = min( 50, max( -50, (INT16)atol( pData->szCharData ) ) ); + } else if ( strcmp( name, "dislikebackground" ) == 0 ) { pData->curElement = ELEMENT; diff --git a/Tactical/XML_Disease.cpp b/Tactical/XML_Disease.cpp new file mode 100644 index 00000000..a03ca6d7 --- /dev/null +++ b/Tactical/XML_Disease.cpp @@ -0,0 +1,479 @@ +#ifdef PRECOMPILEDHEADERS +#include "Tactical All.h" +#else +#include "sgp.h" +#include "overhead.h" +#include "Disease.h" +#include "Debug Control.h" +#include "expat.h" +#include "XML.h" +#endif + +struct +{ + PARSE_STAGE curElement; + + CHAR8 szCharData[MAX_CHAR_DATA_LENGTH + 1]; + DISEASE curItem; + DISEASE * curArray; + UINT32 maxArraySize; + + UINT32 currentDepth; + UINT32 maxReadDepth; +} +typedef parseData; + +static void XMLCALL +diseaseStartElementHandle( void *userData, const XML_Char *name, const XML_Char **atts ) +{ + parseData * pData = (parseData *)userData; + + if ( pData->currentDepth <= pData->maxReadDepth ) //are we reading this element? + { + if ( strcmp( name, "DISEASESLIST" ) == 0 && pData->curElement == ELEMENT_NONE ) + { + pData->curElement = ELEMENT_LIST; + + memset( pData->curArray, 0, sizeof(DISEASE)*pData->maxArraySize ); + + pData->maxReadDepth++; //we are not skipping this element + } + else if ( strcmp( name, "DISEASE" ) == 0 && pData->curElement == ELEMENT_LIST ) + { + pData->curElement = ELEMENT; + + memset( &pData->curItem, 0, sizeof(DISEASE) ); + + pData->maxReadDepth++; //we are not skipping this element + } + else if ( pData->curElement == ELEMENT && + (strcmp( name, "uiIndex" ) == 0 || + strcmp( name, "szName" ) == 0 || + strcmp( name, "szFatName" ) == 0 || + strcmp( name, "szDescription" ) == 0 || + strcmp( name, "sInfectionPtsInitial" ) == 0 || + strcmp( name, "sInfectionPtsOutbreak" ) == 0 || + strcmp( name, "sInfectionPtsFull" ) == 0 || + strcmp( name, "sInfectionPtsGainPerHour" ) == 0 || + strcmp( name, "usInfectionChance_SWAMP" ) == 0 || + strcmp( name, "usInfectionChance_TROPICS" ) == 0 || + strcmp( name, "usInfectionChance_SEX" ) == 0 || + strcmp( name, "usInfectionChance_CONTACT_HUMAN" ) == 0 || + strcmp( name, "usInfectionChance_CONTACT_CORPSE" ) == 0 || + strcmp( name, "usInfectionChance_WOUND_ANIMAL" ) == 0 || + strcmp( name, "usInfectionChance_WOUND_OPEN" ) == 0 || + strcmp( name, "usInfectionChance_WOUND_GUNSHOT" ) == 0 || + strcmp( name, "usInfectionChance_WOUND_AGI" ) == 0 || + strcmp( name, "usInfectionChance_WOUND_DEX" ) == 0 || + strcmp( name, "usInfectionChance_WOUND_STR" ) == 0 || + strcmp( name, "usInfectionChance_WOUND_WIS" ) == 0 || + strcmp( name, "usInfectionChance_WOUND_TRAUMATIC" ) == 0 || + strcmp( name, "usInfectionChance_BADFOOD" ) == 0 || + strcmp( name, "usInfectionChance_BADWATER" ) == 0 || + strcmp( name, "fCanBeCured" ) == 0 || + strcmp( name, "fReverseOnFull" ) == 0 || + strcmp( name, "fCanReInfect" ) == 0 || + strcmp( name, "fHideSymbol" ) == 0 || + strcmp( name, "fDisgusting" ) == 0 || + strcmp( name, "sEffStatAGI" ) == 0 || + strcmp( name, "sEffStatDEX" ) == 0 || + strcmp( name, "sEffStatSTR" ) == 0 || + strcmp( name, "sEffStatWIS" ) == 0 || + strcmp( name, "sEffStatEXP" ) == 0 || + strcmp( name, "sEffAP" ) == 0 || + strcmp( name, "usMaxBreath" ) == 0 || + strcmp( name, "sEffCarryStrength" ) == 0 || + strcmp( name, "sLifeRegenHundreds" ) == 0 || + strcmp( name, "sNeedToSleep" ) == 0 || + strcmp( name, "sDrinkModifier" ) == 0 || + strcmp( name, "sFoodModifier" ) == 0) ) + { + pData->curElement = ELEMENT_PROPERTY; + + pData->maxReadDepth++; //we are not skipping this element + } + + pData->szCharData[0] = '\0'; + } + + pData->currentDepth++; + +} + +static void XMLCALL +diseaseCharacterDataHandle( void *userData, const XML_Char *str, int len ) +{ + parseData * pData = (parseData *)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 +diseaseEndElementHandle( void *userData, const XML_Char *name ) +{ + parseData * pData = (parseData *)userData; + + if ( pData->currentDepth <= pData->maxReadDepth ) //we're at the end of an element that we've been reading + { + if ( strcmp( name, "DISEASESLIST" ) == 0 ) + { + pData->curElement = ELEMENT_NONE; + } + else if ( strcmp( name, "DISEASE" ) == 0 ) + { + pData->curElement = ELEMENT_LIST; + + // we do NOT want to read the first entry -> move stuff by 1 + if ( pData->curItem.uiIndex < pData->maxArraySize ) + { + pData->curArray[pData->curItem.uiIndex] = pData->curItem; //write the food into the table + } + } + else if ( strcmp( name, "uiIndex" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.uiIndex = (UINT16)atol( pData->szCharData ); + } + else if ( strcmp( name, "szName" ) == 0 ) + { + pData->curElement = ELEMENT; + + MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curItem.szName, sizeof(pData->curItem.szName) / sizeof(pData->curItem.szName[0]) ); + pData->curItem.szName[sizeof(pData->curItem.szName) / sizeof(pData->curItem.szName[0]) - 1] = '\0'; + } + else if ( strcmp( name, "szFatName" ) == 0 ) + { + pData->curElement = ELEMENT; + + MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curItem.szFatName, sizeof(pData->curItem.szFatName) / sizeof(pData->curItem.szFatName[0]) ); + pData->curItem.szFatName[sizeof(pData->curItem.szFatName) / sizeof(pData->curItem.szFatName[0]) - 1] = '\0'; + } + else if ( strcmp( name, "szDescription" ) == 0 ) + { + pData->curElement = ELEMENT; + + MultiByteToWideChar( CP_UTF8, 0, pData->szCharData, -1, pData->curItem.szDescription, sizeof(pData->curItem.szDescription) / sizeof(pData->curItem.szDescription[0]) ); + pData->curItem.szDescription[sizeof(pData->curItem.szDescription) / sizeof(pData->curItem.szDescription[0]) - 1] = '\0'; + } + else if ( strcmp( name, "sInfectionPtsInitial" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.sInfectionPtsInitial = (INT32)atol( pData->szCharData ); + } + else if ( strcmp( name, "sInfectionPtsOutbreak" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.sInfectionPtsOutbreak = (INT32)atol( pData->szCharData ); + } + else if ( strcmp( name, "sInfectionPtsFull" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.sInfectionPtsFull = (INT32)atol( pData->szCharData ); + } + else if ( strcmp( name, "sInfectionPtsGainPerHour" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.sInfectionPtsGainPerHour = (INT32)atol( pData->szCharData ); + } + else if ( strcmp( name, "usInfectionChance_SWAMP" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.usInfectionChance[INFECTION_TYPE_SWAMP] = (UINT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "usInfectionChance_TROPICS" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.usInfectionChance[INFECTION_TYPE_TROPICS] = (UINT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "usInfectionChance_SEX" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.usInfectionChance[INFECTION_TYPE_SEX] = (UINT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "usInfectionChance_CONTACT_HUMAN" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.usInfectionChance[INFECTION_TYPE_CONTACT_HUMAN] = (UINT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "usInfectionChance_CONTACT_CORPSE" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.usInfectionChance[INFECTION_TYPE_CONTACT_CORPSE] = (UINT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "usInfectionChance_WOUND_ANIMAL" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.usInfectionChance[INFECTION_TYPE_WOUND_ANIMAL] = (UINT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "usInfectionChance_WOUND_OPEN" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.usInfectionChance[INFECTION_TYPE_WOUND_OPEN] = (UINT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "usInfectionChance_WOUND_GUNSHOT" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.usInfectionChance[INFECTION_TYPE_WOUND_GUNSHOT] = (UINT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "usInfectionChance_WOUND_AGI" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.usInfectionChance[INFECTION_TYPE_WOUND_AGI] = (UINT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "usInfectionChance_WOUND_DEX" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.usInfectionChance[INFECTION_TYPE_WOUND_DEX] = (UINT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "usInfectionChance_WOUND_STR" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.usInfectionChance[INFECTION_TYPE_WOUND_STR] = (UINT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "usInfectionChance_WOUND_WIS" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.usInfectionChance[INFECTION_TYPE_WOUND_WIS] = (UINT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "usInfectionChance_WOUND_TRAUMATIC" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.usInfectionChance[INFECTION_TYPE_TRAUMATIC] = (UINT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "usInfectionChance_BADFOOD" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.usInfectionChance[INFECTION_TYPE_BADFOOD] = (UINT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "usInfectionChance_BADWATER" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.usInfectionChance[INFECTION_TYPE_BADWATER] = (UINT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "fCanBeCured" ) == 0 ) + { + pData->curElement = ELEMENT; + if ( atol( pData->szCharData ) ) + pData->curItem.usDiseaseProperties |= DISEASE_PROPERTY_CANBECURED; + } + else if ( strcmp( name, "fReverseOnFull" ) == 0 ) + { + pData->curElement = ELEMENT; + if ( atol( pData->szCharData ) ) + pData->curItem.usDiseaseProperties |= DISEASE_PROPERTY_REVERSEONFULL; + } + else if ( strcmp( name, "fCanReInfect" ) == 0 ) + { + pData->curElement = ELEMENT; + if ( atol( pData->szCharData ) ) + pData->curItem.usDiseaseProperties |= DISEASE_PROPERTY_CANREINFECT; + } + else if ( strcmp( name, "fHideSymbol" ) == 0 ) + { + pData->curElement = ELEMENT; + if ( atol( pData->szCharData ) ) + pData->curItem.usDiseaseProperties |= DISEASE_PROPERTY_HIDESYMBOL; + } + else if ( strcmp( name, "fDisgusting" ) == 0 ) + { + pData->curElement = ELEMENT; + if ( atol( pData->szCharData ) ) + pData->curItem.usDiseaseProperties |= DISEASE_PROPERTY_DISGUSTING; + } + else if ( strcmp( name, "sEffStatAGI" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.sEffStat[INFST_AGI] = (INT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "sEffStatDEX" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.sEffStat[INFST_DEX] = (INT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "sEffStatSTR" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.sEffStat[INFST_STR] = (INT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "sEffStatWIS" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.sEffStat[INFST_WIS] = (INT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "sEffStatEXP" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.sEffStat[INFST_EXP] = (INT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "sEffAP" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.sEffAP = (INT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "usMaxBreath" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.usMaxBreath = (UINT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "sEffCarryStrength" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.sEffCarryStrength = (INT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "sLifeRegenHundreds" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.sLifeRegenHundreds = (INT16)atol( pData->szCharData ); + } + else if ( strcmp( name, "sNeedToSleep" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.sNeedToSleep = (INT8)atol( pData->szCharData ); + } + else if ( strcmp( name, "sDrinkModifier" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.sDrinkModifier = (INT16)atol( pData->szCharData ); + } + else if ( strcmp( name, "sFoodModifier" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curItem.sFoodModifier = (INT16)atol( pData->szCharData ); + } + + pData->maxReadDepth--; + } + + pData->currentDepth--; +} + + +BOOLEAN ReadInDiseaseStats( STR fileName ) +{ + HWFILE hFile; + UINT32 uiBytesRead; + UINT32 uiFSize; + CHAR8 * lpcBuffer; + XML_Parser parser = XML_ParserCreate( NULL ); + + parseData pData; + + DebugMsg( TOPIC_JA2, DBG_LEVEL_3, "Loading Disease.xml" ); + + // Open foods 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, diseaseStartElementHandle, diseaseEndElementHandle ); + XML_SetCharacterDataHandler( parser, diseaseCharacterDataHandle ); + + memset( &pData, 0, sizeof(pData) ); + pData.curArray = Disease; + pData.maxArraySize = NUM_DISEASES; + + XML_SetUserData( parser, &pData ); + + if ( !XML_Parse( parser, lpcBuffer, uiFSize, TRUE ) ) + { + CHAR8 errorBuf[511]; + + sprintf( errorBuf, "XML Parser Error in Disease.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 WriteDiseaseStats( ) +{ + //DebugMsg (TOPIC_JA2,DBG_LEVEL_3,"writefoodsstats"); + 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( "TABLEDATA\\Disease out.xml", FILE_ACCESS_WRITE | FILE_CREATE_ALWAYS, FALSE ); + if ( !hFile ) + return(FALSE); + + { + FilePrintf( hFile, "\r\n" ); + for ( UINT32 cnt = 0; cnt < NUM_DISEASES; ++cnt ) + { + FilePrintf( hFile, "\t\r\n" ); + + FilePrintf( hFile, "\t\t%d\r\n", cnt ); + FilePrintf( hFile, "\t\t%s\r\n", Disease[cnt].szName ); + FilePrintf( hFile, "\t\t%s\r\n", Disease[cnt].szFatName ); + FilePrintf( hFile, "\t\t%s\r\n", Disease[cnt].szDescription ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].sInfectionPtsInitial ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].sInfectionPtsOutbreak ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].sInfectionPtsFull ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].sInfectionPtsGainPerHour ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_SWAMP] ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_TROPICS] ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_SEX] ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_CONTACT_HUMAN] ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_CONTACT_CORPSE] ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_WOUND_ANIMAL] ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_WOUND_OPEN] ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_WOUND_GUNSHOT] ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_WOUND_AGI] ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_WOUND_DEX] ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_WOUND_STR] ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_WOUND_WIS] ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_TRAUMATIC] ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_BADFOOD] ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].usInfectionChance[INFECTION_TYPE_BADWATER] ); + FilePrintf( hFile, "\t\t%d\r\n", (Disease[cnt].usDiseaseProperties & DISEASE_PROPERTY_CANBECURED) ? 1 : 0 ); + FilePrintf( hFile, "\t\t%d\r\n", (Disease[cnt].usDiseaseProperties & DISEASE_PROPERTY_REVERSEONFULL) ? 1 : 0 ); + FilePrintf( hFile, "\t\t%d\r\n", (Disease[cnt].usDiseaseProperties & DISEASE_PROPERTY_CANREINFECT) ? 1 : 0 ); + FilePrintf( hFile, "\t\t%d\r\n", (Disease[cnt].usDiseaseProperties & DISEASE_PROPERTY_HIDESYMBOL) ? 1 : 0 ); + FilePrintf( hFile, "\t\t%d\r\n", (Disease[cnt].usDiseaseProperties & DISEASE_PROPERTY_DISGUSTING) ? 1 : 0 ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].sEffStat[INFST_AGI] ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].sEffStat[INFST_DEX] ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].sEffStat[INFST_STR] ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].sEffStat[INFST_WIS] ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].sEffStat[INFST_EXP] ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].sEffAP ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].usMaxBreath ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].sEffCarryStrength ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].sLifeRegenHundreds ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].sNeedToSleep ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].sDrinkModifier ); + FilePrintf( hFile, "\t\t%d\r\n", Disease[cnt].sFoodModifier ); + + FilePrintf( hFile, "\t\r\n" ); + } + FilePrintf( hFile, "\r\n" ); + } + FileClose( hFile ); + + return(TRUE); +} diff --git a/Tactical/XML_Drugs.cpp b/Tactical/XML_Drugs.cpp index 1ff82f5d..92c74385 100644 --- a/Tactical/XML_Drugs.cpp +++ b/Tactical/XML_Drugs.cpp @@ -54,7 +54,9 @@ drugsStartElementHandle(void *userData, const XML_Char *name, const XML_Char **a strcmp(name, "ubDrugEffect") == 0 || strcmp(name, "ubDrugSideEffect") == 0 || strcmp(name, "ubDrugSideEffectRate") == 0 || - strcmp(name, "ubMoralBacklash") )) + strcmp(name, "ubMoralBacklash" ) == 0 || + strcmp(name, "ubMoralBacklash" ) == 0 || + strcmp(name, "ubDiseaseCure" ) == 0 )) { pData->curElement = ELEMENT_PROPERTY; @@ -142,6 +144,11 @@ drugsEndElementHandle(void *userData, const XML_Char *name) pData->curElement = ELEMENT; pData->curDrugs.ubMoralBacklash = (UINT8) atol(pData->szCharData); } + else if ( strcmp( name, "ubDiseaseCure" ) == 0 ) + { + pData->curElement = ELEMENT; + pData->curDrugs.ubDiseaseCure = (UINT8)atol( pData->szCharData ); + } pData->maxReadDepth--; } @@ -241,6 +248,7 @@ BOOLEAN WriteDrugsStats() FilePrintf(hFile,"\t\t%d\r\n", Drug[cnt].ubDrugSideEffect ); FilePrintf(hFile,"\t\t%d\r\n", Drug[cnt].ubDrugSideEffectRate ); FilePrintf(hFile,"\t\t%d\r\n", Drug[cnt].ubMoralBacklash ); + FilePrintf(hFile,"\t\t%d\r\n", Drug[cnt].ubDiseaseCure ); FilePrintf(hFile,"\t\r\n"); } diff --git a/TacticalAI/AIMain.cpp b/TacticalAI/AIMain.cpp index e074613d..f7ba195e 100644 --- a/TacticalAI/AIMain.cpp +++ b/TacticalAI/AIMain.cpp @@ -1725,14 +1725,12 @@ INT8 ExecuteAction(SOLDIERTYPE *pSoldier) PossiblyStartEnemyTaunt( pSoldier, TAUNT_SEEK_NOISE ); else if (pSoldier->aiData.bAction == AI_ACTION_RUN_AWAY ) PossiblyStartEnemyTaunt( pSoldier, TAUNT_RUN_AWAY ); - #ifdef ENABLE_ZOMBIES - if ( Random( 5 ) == 0 ) - { - if ( pSoldier->IsZombie() ) // Madd: Zombies randomly moan... - pSoldier->DoMercBattleSound( (INT8)( BATTLE_SOUND_LAUGH1 ) ); + if ( !Random( 5 ) && pSoldier->IsZombie( ) ) + { + // Madd: Zombies randomly moan... + pSoldier->DoMercBattleSound( (INT8)( BATTLE_SOUND_LAUGH1 ) ); } - #endif } } case AI_ACTION_APPROACH_MERC: // walk up to someone to talk diff --git a/TacticalAI/DecideAction.cpp b/TacticalAI/DecideAction.cpp index e1b26f04..d4fe5603 100644 --- a/TacticalAI/DecideAction.cpp +++ b/TacticalAI/DecideAction.cpp @@ -700,11 +700,9 @@ INT8 DecideActionGreen(SOLDIERTYPE *pSoldier) STR16 tempstr; #endif -#ifdef ENABLE_ZOMBIES // Flugente: to prevent an accidental call if ( pSoldier->IsZombie() ) return( ZombieDecideActionGreen(pSoldier) ); -#endif DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionGreen, orders = %d",pSoldier->aiData.bOrders)); @@ -1543,11 +1541,9 @@ INT8 DecideActionYellow(SOLDIERTYPE *pSoldier) STR16 tempstr; #endif -#ifdef ENABLE_ZOMBIES // Flugente: to prevent an accidental call if ( pSoldier->IsZombie() ) return( ZombieDecideActionYellow(pSoldier) ); -#endif if (fCivilian || (gGameExternalOptions.fAllNamedNpcsDecideAction && pSoldier->ubProfile != NO_PROFILE)) { @@ -2422,11 +2418,9 @@ INT8 DecideActionRed(SOLDIERTYPE *pSoldier, UINT8 ubUnconsciousOK) (pSoldier->aiData.bNeutral && gTacticalStatus.fCivGroupHostile[pSoldier->ubCivilianGroup] == CIV_GROUP_NEUTRAL) || (pSoldier->ubBodyType >= FATCIV && pSoldier->ubBodyType <= CRIPPLECIV) ) ); -#ifdef ENABLE_ZOMBIES // Flugente: to prevent an accidental call if ( pSoldier->IsZombie() ) return( ZombieDecideActionRed(pSoldier, ubUnconsciousOK) ); -#endif // WANNE: Headrock informed me that I should remove that because it needs a lot of CPU! // HEADROCK HAM B2.7: Calculate the overall tactical situation @@ -4353,11 +4347,9 @@ INT16 ubMinAPCost; #endif DebugMsg(TOPIC_JA2,DBG_LEVEL_3,String("DecideActionBlack: soldier = %d, orders = %d, attitude = %d",pSoldier->ubID,pSoldier->aiData.bOrders,pSoldier->aiData.bAttitude)); -#ifdef ENABLE_ZOMBIES // Flugente: to prevent an accidental call if ( pSoldier->IsZombie() ) return( ZombieDecideActionBlack(pSoldier) ); -#endif ATTACKTYPE BestShot, BestThrow, BestStab ,BestAttack;//dnl ch69 150913 BOOLEAN fCivilian = (PTR_CIVILIAN && (pSoldier->ubCivilianGroup == NON_CIV_GROUP || pSoldier->aiData.bNeutral || (pSoldier->ubBodyType >= FATCIV && pSoldier->ubBodyType <= CRIPPLECIV) ) ); diff --git a/TileEngine/Explosion Control.cpp b/TileEngine/Explosion Control.cpp index 7276e32e..462e9ea0 100644 --- a/TileEngine/Explosion Control.cpp +++ b/TileEngine/Explosion Control.cpp @@ -1999,11 +1999,7 @@ BOOLEAN DishOutGasDamage( SOLDIERTYPE * pSoldier, EXPLOSIVETYPE * pExplosive, IN if ( pExplosive->ubType == EXPLOSV_TEARGAS ) { // zombies and robots are unaffected by tear gas -#ifdef ENABLE_ZOMBIES if ( AM_A_ROBOT( pSoldier ) || pSoldier->IsZombie() ) -#else - if ( AM_A_ROBOT( pSoldier ) ) -#endif { return( fRecompileMovementCosts ); } diff --git a/Utils/Text.h b/Utils/Text.h index 0716cdc5..f38ff386 100644 --- a/Utils/Text.h +++ b/Utils/Text.h @@ -2752,12 +2752,10 @@ enum TEXT_MERCCOMPARE_WEBSITENAME, TEXT_MERCCOMPARE_SLOGAN, + // links to other pages TEXT_MERCCOMPARE_SUBSITE1, - TEXT_MERCCOMPARE_SUBSITE2, - TEXT_MERCCOMPARE_SUBSITE3, - TEXT_MERCCOMPARE_SUBSITE4, - TEXT_MERCCOMPARE_INTRO1, + TEXT_MERCCOMPARE_INTRO1 = TEXT_MERCCOMPARE_SUBSITE1 + 4, TEXT_MERCCOMPARE_BULLET1, TEXT_MERCCOMPARE_BULLET2, TEXT_MERCCOMPARE_BULLET3, @@ -2782,6 +2780,31 @@ enum extern STR16 szMercCompareWebSite[]; extern STR16 szMercCompareEventText[]; +// Flugente: WHO website +enum +{ + // main page + TEXT_WHO_WEBSITENAME, + TEXT_WHO_SLOGAN, + + // links to other pages + TEXT_WHO_SUBSITE1, + + TEXT_WHO_MAIN1 = TEXT_WHO_SUBSITE1 + 3, + + TEXT_WHO_CONTRACT1 = TEXT_WHO_MAIN1 + 3, + TEXT_WHO_CONTRACT_ACQUIRED_NOT = TEXT_WHO_CONTRACT1 + 4, + TEXT_WHO_CONTRACT_ACQUIRED, + TEXT_WHO_CONTRACT_BUTTON_SUBSCRIBE, + TEXT_WHO_CONTRACT_BUTTON_UNSUBSCRIBE, + + TEXT_WHO_TIPS1, + + TEXT_WHO_MAX = TEXT_WHO_TIPS1 + 8, +}; + +extern STR16 szWHOWebSite[]; + extern STR16 szTacticalInventoryDialogString[]; extern STR16 szTacticalCoverDialogString[]; extern STR16 szTacticalCoverDialogPrintString[]; @@ -2807,6 +2830,31 @@ extern STR16 szDynamicDialogueText_DOST_SIDEWITH_CAUSE[]; extern STR16 szDynamicDialogueText_DOST_INTERJECTOR_DIALOGUESELECTION_SHORTTEXT[]; extern STR16 szDynamicDialogueText_GenderText[]; +// Flugente: disease +enum +{ + // effect description + TEXT_DISEASE_EFFSTAT_AGI, + TEXT_DISEASE_EFFSTAT_DEX, + TEXT_DISEASE_EFFSTAT_STR, + TEXT_DISEASE_EFFSTAT_WIS, + TEXT_DISEASE_EFFSTAT_EXP, + + TEXT_DISEASE_AP, + TEXT_DISEASE_MAXBREATH, + TEXT_DISEASE_CARRYSTRENGTH, + TEXT_DISEASE_LIFEREGENHUNDREDS, + TEXT_DISEASE_NEEDTOSLEEP, + TEXT_DISEASE_DRINK, + TEXT_DISEASE_FOOD, + + // text when diagnosed + TEXT_DISEASE_DIAGNOSE_GENERAL, + TEXT_DISEASE_CURED, +}; + +extern STR16 szDiseaseText[]; + #define TACTICAL_INVENTORY_DIALOG_NUM 16 #define TACTICAL_COVER_DIALOG_NUM 16 diff --git a/Utils/XML_Items.cpp b/Utils/XML_Items.cpp index dbc01215..9c073b03 100644 --- a/Utils/XML_Items.cpp +++ b/Utils/XML_Items.cpp @@ -281,7 +281,9 @@ itemStartElementHandle(void *userData, const XML_Char *name, const XML_Char **at strcmp(name, "SleepModifier") == 0 || strcmp(name, "usSpotting") == 0 || strcmp(name, "sBackpackWeightModifier") == 0 || - strcmp(name, "fAllowClimbing") == 0)) + strcmp(name, "fAllowClimbing") == 0 || + strcmp(name, "diseaseprotectionface" ) == 0 || + strcmp(name, "diseaseprotectionhand" ) == 0)) { pData->curElement = ELEMENT_PROPERTY; //DebugMsg(TOPIC_JA2, DBG_LEVEL_3, String("itemStartElementHandle: going into element, name = %s",name) ); @@ -1457,6 +1459,23 @@ itemEndElementHandle(void *userData, const XML_Char *name) pData->curElement = ELEMENT; pData->curItem.fAllowClimbing = (BOOLEAN)atol(pData->szCharData); } + // Flugente: simple tags in the xml get translated into flags + else if ( strcmp( name, "diseaseprotectionface" ) == 0 ) + { + pData->curElement = ELEMENT; + BOOLEAN val = (BOOLEAN)atol( pData->szCharData ); + + if ( val ) + pData->curItem.usItemFlag |= DISEASEPROTECTION_FACE; + } + else if ( strcmp( name, "diseaseprotectionhand" ) == 0 ) + { + pData->curElement = ELEMENT; + BOOLEAN val = (BOOLEAN)atol( pData->szCharData ); + + if ( val ) + pData->curItem.usItemFlag |= DISEASEPROTECTION_HAND; + } pData->maxReadDepth--; } @@ -2102,6 +2121,12 @@ BOOLEAN WriteItemStats() FilePrintf(hFile,"\t\t%d\r\n", Item[cnt].usSpotting ); FilePrintf(hFile, "\t\t%d\r\n", Item[cnt].sBackpackWeightModifier); FilePrintf(hFile, "\t\t%d\r\n", Item[cnt].fAllowClimbing); + + if ( Item[cnt].usItemFlag & DISEASEPROTECTION_FACE ) + FilePrintf( hFile, "\t\t%d\r\n", 1 ); + if ( Item[cnt].usItemFlag & DISEASEPROTECTION_HAND ) + FilePrintf( hFile, "\t\t%d\r\n", 1 ); + FilePrintf(hFile,"\t\r\n"); } FilePrintf(hFile,"\r\n"); diff --git a/Utils/_ChineseText.cpp b/Utils/_ChineseText.cpp index b344f829..12f8a9a9 100644 --- a/Utils/_ChineseText.cpp +++ b/Utils/_ChineseText.cpp @@ -1864,6 +1864,8 @@ STR16 pAssignmentStrings[] = L"造谣", // spread propaganda L"谣言", // gather information L"Command", // militia movement orders + L"Diagnose", // disease diagnosis //TODO.Translate + L"Treat D.", // treat disease among the population }; @@ -1960,6 +1962,8 @@ STR16 pPersonnelAssignmentStrings[] = L"派发传单", // spread propaganda L"搜集谣言", // gather information L"Commanding Militia", // militia movement orders // TODO.Translate + L"Diagnose", // disease diagnosis + L"Treat Population disease", // treat disease among the population }; @@ -2015,6 +2019,8 @@ STR16 pLongAssignmentStrings[] = L"派发传单", // spread propaganda L"搜集谣言", // gather information L"Commanding Militia", // militia movement orders // TODO.Translate + L"Diagnose", // disease diagnosis + L"Treat Population disease", // treat disease among the population }; @@ -2127,6 +2133,7 @@ STR16 pAssignMenuStrings[] = { L"编队", L"医生", + L"Disease", // merc is a doctor doing diagnosis TODO.Translate L"病人", L"交通工具", L"修理", @@ -3658,6 +3665,7 @@ STR16 pMapScreenBorderButtonHelpText[] = L"显示物品 (|I)", L"显示民兵和敌人 (|Z)", L"显示民兵移动 (|R)", // HEADROCK HAM 4: Mobile Restrictions Button + L"Show Disease Data", // TODO.Translate }; STR16 pMapScreenInvenButtonHelpText[] = @@ -3889,6 +3897,7 @@ STR16 pTransactionText[] = L"工厂使用", // L"Facility Use", // HEADROCK HAM 3.6 L"民兵保养", // L"Militia upkeep", // HEADROCK HAM 3.6 L"释放俘虏所需的赎金", //L"Ransom for released prisoners", + L"WHO data subscription", // Flugente: disease TODO.Translate }; STR16 pTransactionAlternateText[] = @@ -4329,6 +4338,7 @@ STR16 pBookMarkStrings[] = L"简报室", L"战役历史", L"MeLoDY", + L"WHO", }; STR16 pBookmarkTitle[] = @@ -4445,6 +4455,9 @@ STR16 pWebPagesTitles[] = L"Mercs Love or Dislike You - Analyze a team", L"Mercs Love or Dislike You - Pairwise comparison", L"Mercs Love or Dislike You - About us", + L"WHO - About WHO", + L"WHO - Disease in Arulco", + L"WHO - Helpful Tips", L"Bobby Ray - 最近的运货", L"百科全书", L"百科全书 - 数据", @@ -5506,6 +5519,9 @@ STR16 zMarksMapScreenText[] = // HEADROCK HAM 4: Prompt messages when turning on Mobile Militia Restrictions view. L"你目前没有民兵。当你招募了一些后再返回这个显示模式。", L"这个视图显示你的移动民兵能去和不能去哪里。 灰色 = 移动民兵拒绝来这里. 红色 = 移动民兵能来这里, 但是你告诉他们不要这样. 黄色 = 移动民兵能进入这个区域, 但是不能离开. 绿色 = 移动民兵可以自由的进入这里. 右击一个绿色/黄色区域循环它的行为.", + + // Flugente: disease texts describing what a map view does TODO.Translate + L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.", }; @@ -6231,6 +6247,7 @@ STR16 gzLaptopHelpText[] = L"简报室", L"战役历史", L"Mercenaries Love or Dislike You", // TODO.Translate + L"World Health Organization", }; @@ -7651,6 +7668,8 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|双|手|操|作", //|T|w|o|-|H|a|n|d|e|d", L"|挡|住|准|心", //L"|B|l|o|c|k|s |I|r|o|n |S|i|g|h|t|s", L"|A|n|t|i|-|M|a|t|e|r|i|a|l |A|m|m|o", // TODO.Translate + L"|F|a|c|e |P|r|o|t|e|c|t|i|o|n", + L"|I|n|f|e|c|t|i|o|n |P|r|o|t|e|c|t|i|o|n", // 39 }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -7693,6 +7712,8 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \n这个物品需要两只手一起操作使用", //L"\n \nThis item requires both hands to be used.", L"\n \n这个物品会挡住准心\n 你无法再使用准心瞄准", //L"\n \nThis item will block your iron sights\nso you cannot use them.", L"\n \nThis ammo can destroy light walls\nand various other objects.", // TODO.Translate + L"\n \nIf worn on your face, this will lower\nthe chance to be infected by other people.", + L"\n \nIf kept in your inventory, this will\nlower\nthe chance to be infected by other people.", }; STR16 szUDBAdvStatsTooltipText[]= @@ -8179,6 +8200,7 @@ STR16 szBackgroundText_Value[]= L" %s%d%%压制忍耐\n", //L" %s%d%% suppression resistance\n", L" %s%d%%近战抗性\n", //L" %s%d%% physical resistance\n", L" %s%d%%酒精耐性\n", //L" %s%d%% alcohol resistance\n", + L" %s%d%% disease resistance\n", // TODO.Translate L" %s%d%%审问效率\n", //L" %s%d%% interrogation effectiveness\n", L" %s%d%%监狱守卫强度\n", //L" %s%d%% prison guard strength\n", @@ -8210,6 +8232,8 @@ STR16 szBackgroundText_Value[]= L" %s%d%%射击生物准确率(CTH)\n", //L" %s%d%% cth with firearms against creatures\n", L" %s%d%%医疗保证金\n", //L" %s%d%% insurance cost\n", L" %s%d%%发现狙击手的成功率\n", + L" %s%d%% effectiveness at diagnosing diseases\n", // TODO.Translate + L" %s%d%% effectiveness at treating population against diseases\n", L" dislikes some other backgrounds", // TODO.Translate }; @@ -8663,7 +8687,7 @@ STR16 szMercCompareEventText[]= L"%s mounted a gun on me", L"%s treated my wounds", - L"Had a good drink %s", + L"Had a good drink with %s", L"%s is fun to get wasted with", L"%s is annoying when drunk", @@ -8678,6 +8702,45 @@ STR16 szMercCompareEventText[]= L"%s puts people in their places", L"%s is way too impulsive", + L"%s is disease-ridden", + L"%s treated my diseases", +}; + +STR16 szWHOWebSite[] = +{ + // main page + L"World Health Organization", + L"Bringing health to life", + + // links to other pages + L"About WHO", + L"Disease in Arulco", + L"About diseases", + + // text on the main page + L"WHO is the directing and coordinating authority for health within the United Nations system.", + L"It is responsible for providing leadership on global health matters, shaping the health research agenda, setting norms and standards, articulating evidence-based policy options, providing technical support to countries and monitoring and assessing health trends.", + L"In the 21st century, health is a shared responsibility, involving equitable access to essential care and collective defence against transnational threats.", + + // contract page + L"The small country of Arulco is currently experiencing an outbreak of the deadly arulcan plague.", + L"Due to the catastrophic state of the state's health system, only the armies' medical corps is there to combat the deadly disease.", + L"With the country being of limits to UN affiliates, all we can currently do is provide detailed maps on the current status of infection in Arulco. Due to the difficulty in dealing with Arulco, we regret to have to ask for a daily fee of %d$ for anyone wishing to obtain these maps.", + L"Do you wish to acquire detailed data on the current status of diease in Arulco? You can access this data on the strategic map once aquired.", + L"You currently do not have access to WHO data on the arulcan plague.", + L"You have acquired detailed maps on the status of the disease.", + L"Subscribe to map updates", + L"Unsubscribe map updates", + + // helpful tips page + L"The arulcan plague is a deadly strain of the plague unique to the small country of Arulco. In a typical outbreak, the first victims get infected by a mosquito in a swamp or tropical sector. These first victims then inadvertently infect the population of nearby cities.", + L"You won't immediately notice when you are infected - it might take days for the symptoms to show.", + L"You can see the current effects of known diseases your mercs suffer from by hovering over their portrait in the strategic map.", + L"Most diseases get worse over time, be sure to assign a doctor as soon as possible.", + L"Some diseases can be treated with special medicine. You might find some in a well-equipped drugstore.", + L"Doctors can be ordered to check on all local teammates for diseases. You can find out about a disease before it breaks out!", + L"Doctors have a much higher chance to be infected when treating infected patients. Protective gear is very useful.", + L"If a blade weapon hits an infected person, the blade becomes infected, and can be used to spread the infection further.", }; STR16 szTacticalInventoryDialogString[]= @@ -8793,6 +8856,8 @@ STR16 szDynamicDialogueText_DOST_VICTIM_INITIATE[] = L"Alright alright. Jeez. I'm over it, okay?", L"Who do you think you are, $CAUSE$? No, I won't be quiet about this!", + L"Ewww! $CAUSE$ is sick! Get away from me, that looks disgusting!", + L"Thanks, $CAUSE$. I'm already feeling better.", }; STR16 szDynamicDialogueText_DOST_VICTIM_TO_INTERJECTOR_DENY[] = @@ -8880,6 +8945,8 @@ STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_DENY[] = L"Cut it, drama queen.", L"I'm the one who tells you to shut up! I'm your superior, $VICTIM$!", + L"Oh yeah? Back off, before I cough on you!", + L"How did you get that in the first place? Did you forget to wash your hands again?", }; STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_AGREE[] = @@ -8920,6 +8987,8 @@ STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_AGREE[] = L"As long as it does not happen again.", L"The two of us are going to have real problem soon, $VICTIM$.", + L"It really is. I... *cough* don't feel so well...", + L"No problem, we can't have you running around coughing blood, right? Riiight?", }; STR16 szDynamicDialogueText_DOST_CAUSE_TO_INTERJECTOR_DENY[] = @@ -9008,6 +9077,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_DIALOGUESELECTION[] = L"$VICTIM$ was reined in by $CAUSE$. What do you do?", L"$VICTIM$ did not take $CAUSE$'s words of action well. What do you do?", + L"$VICTIM$ is offended by $CAUSE$ diseases. What do you do?", + L"$VICTIM$ has treated $CAUSE$'s diseases. What do you do?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_DENY[] = @@ -9048,6 +9119,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_DENY[] = L"No reason to be so stiff about it.", L"Pfft. Don't make a fuss out of it.", + L"Stop behaving like a first grader. We need to get $CAUSE$ to a doctor!", + L"Where did you get that stuff from in the first place?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_AGREE[] = @@ -9088,6 +9161,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_AGREE[] = L"Yeah, keep it down, will ya?", L"Yeah, you won't boss us around anymore!", + L"This does look unhealthy. That better not be contagious!", + L"Great. Are you sure it's fully treated now?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_DENY[] = @@ -9128,6 +9203,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_DENY[] = L"Pah. You're the one making all the fuss about it...", L"You are certainly nobodies superior!", + L"Stop it! We don't need more of whatever it is you have!", + L"The important thing is that it's gone now... It is, right?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_AGREE[] = @@ -9168,6 +9245,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_AGREE[] = L"Yeah, drop that attitude, $VICTIM$.", L"Not sure about that, but yep!", + L"Yeah, there's nothing you can do against this stuff, right?", + L"I told you pople before... this country a dirty place, so beware of what you touch.", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_REASON[] = @@ -9208,6 +9287,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_REASON[] = L"Sigh. More of this?", L"Hey. Hey! Both of you, cut it out! What are you doing?", + L"The important thing is to get $CAUSE$ to a doctor, and to make sure $CAUSE_GENDER$ doesn't infect anybody else.", + L"We have to be careful. The army isn't the only thing that wants us dead.", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_AGGRESSIVE[] = @@ -9248,6 +9329,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_AGGRESSIVE[] = L"Sigh. More of this?", L"If anybody is superior here, then that's me... and I'm ordering you to stand down!", + L"Stop whining! $CAUSE$, get that treated, and the rest of you, back to business!", + L"Great. Everything done? Then let's get back to shooting stuff!", }; STR16 szDynamicDialogueText_DOST_SIDEWITH_VICTIM[] = @@ -9309,6 +9392,26 @@ STR16 szDynamicDialogueText_GenderText[] = L"her", }; +STR16 szDiseaseText[] = +{ + L" %s%d%% agility stat\n", + L" %s%d%% dexterity stat\n", + L" %s%d%% strength stat\n", + L" %s%d%% wisdom stat\n", + L" %s%d%% effective level\n", + + L" %s%d%% APs\n", + L" %s%d maximum breath\n", + L" %s%d%% strength to carry items\n", + L" %s%2.2f life regeneration/hour\n", + L" %s%d need for sleep\n", + L" %s%d%% water consumption\n", + L" %s%d%% food consumption\n", + + L"%s was diagnosed with %s!", + L"%s is cured of %s!", +}; + // WANNE: Some Chinese specific strings that needs to be in unicode! STR16 ChineseSpecString1 = L"%%"; //defined in _ChineseText.cpp as this file is already unicode STR16 ChineseSpecString2 = L"*%3d%%%%"; //defined in _ChineseText.cpp as this file is already unicode diff --git a/Utils/_DutchText.cpp b/Utils/_DutchText.cpp index c2b95812..952084af 100644 --- a/Utils/_DutchText.cpp +++ b/Utils/_DutchText.cpp @@ -1861,6 +1861,8 @@ STR16 pAssignmentStrings[] = L"Propag.", // spread propaganda L"Rumours", // gather information L"Command", // militia movement orders + L"Diagnose", // disease diagnosis //TODO.Translate + L"Treat D.", // treat disease among the population }; @@ -1957,6 +1959,8 @@ STR16 pPersonnelAssignmentStrings[] = L"Spreading Propaganda",// TODO.Translate // spread propaganda L"Gathering Rumours",// TODO.Translate // gather information L"Commanding Militia", // militia movement orders // TODO.Translate + L"Diagnose", // disease diagnosis + L"Treat Population disease", // treat disease among the population }; @@ -2012,6 +2016,8 @@ STR16 pLongAssignmentStrings[] = L"Spread Propaganda",// TODO.Translate // spread propaganda L"Gather Rumours",// TODO.Translate // gather information L"Commanding Militia", // militia movement orders // TODO.Translate + L"Diagnose", // disease diagnosis + L"Treat Population disease", // treat disease among the population }; @@ -2124,6 +2130,7 @@ STR16 pAssignMenuStrings[] = { L"On duty", // merc is on active duty L"Doctor", // the merc is acting as a doctor + L"Disease", // merc is a doctor doing diagnosis TODO.Translate L"Patient", // the merc is receiving medical attention L"Vehicle", // the merc is in a vehicle L"Repair", // the merc is repairing items @@ -3656,6 +3663,7 @@ STR16 pMapScreenBorderButtonHelpText[] = L"Toon |Items", L"Toon Milities & Vijanden (|Z)", L"Show Mobile Militia |Restrictions", // HEADROCK HAM 4: Mobile Restrictions Button // TODO.Translate + L"Show Disease Data", // TODO.Translate }; STR16 pMapScreenInvenButtonHelpText[] = @@ -3888,6 +3896,7 @@ STR16 pTransactionText[] = L"Facility Use", // HEADROCK HAM 3.6 // TODO.Translate L"Militia upkeep", // HEADROCK HAM 3.6 // TODO.Translate L"Ransom for released prisoners", // Flugente: prisoner system TODO.Translate + L"WHO data subscription", // Flugente: disease TODO.Translate }; STR16 pTransactionAlternateText[] = @@ -4331,6 +4340,7 @@ STR16 pBookMarkStrings[] = L"Briefing Room", L"Campaign History", // TODO.Translate L"MeLoDY", + L"WHO", }; STR16 pBookmarkTitle[] = @@ -4447,6 +4457,9 @@ STR16 pWebPagesTitles[] = L"Mercs Love or Dislike You - Analyze a team", L"Mercs Love or Dislike You - Pairwise comparison", L"Mercs Love or Dislike You - About us", + L"WHO - About WHO", + L"WHO - Disease in Arulco", + L"WHO - Helpful Tips", L"Bobby Ray's - Recentelijke Zendingen", L"Encyclopedia", L"Encyclopedia - Data", @@ -5508,6 +5521,9 @@ STR16 zMarksMapScreenText[] = // HEADROCK HAM 4: Prompt messages when turning on Mobile Militia Restrictions view. L"You currently have no Mobile Militia. Return to this view mode once you've recruited some.", L"This view shows where your Mobile Militia can and cannot go. GREY = Mobile Militia refuse to go here. RED = Mobile Militia can go here, but you've told them not to. YELLOW = Mobile Militia can enter this sector, but not leave. GREEN = Mobile Militia can go here freely. Right click a Green/Yellow sector to cycle its behavior.", + + // Flugente: disease texts describing what a map view does TODO.Translate + L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.", }; @@ -6244,6 +6260,7 @@ STR16 gzLaptopHelpText[] = L"Briefing Room", L"Campaign History", // TODO.Translate L"Mercenaries Love or Dislike You", // TODO.Translate + L"World Health Organization", }; @@ -7663,6 +7680,8 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|T|w|o|-|H|a|n|d|e|d", L"|B|l|o|c|k|s |I|r|o|n |S|i|g|h|t|s", L"|A|n|t|i|-|M|a|t|e|r|i|a|l |A|m|m|o", // TODO.Translate + L"|F|a|c|e |P|r|o|t|e|c|t|i|o|n", + L"|I|n|f|e|c|t|i|o|n |P|r|o|t|e|c|t|i|o|n", // 39 }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -7705,6 +7724,8 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nThis item requires both hands to be used.", L"\n \nThis item will block your iron sights\nso you cannot use them.", L"\n \nThis ammo can destroy light walls\nand various other objects.", // TODO.Translate + L"\n \nIf worn on your face, this will lower\nthe chance to be infected by other people.", + L"\n \nIf kept in your inventory, this will\nlower\nthe chance to be infected by other people.", }; STR16 szUDBAdvStatsTooltipText[]= @@ -8196,6 +8217,7 @@ STR16 szBackgroundText_Value[]= L" %s%d%% suppression resistance\n", L" %s%d%% physical resistance\n", L" %s%d%% alcohol resistance\n", + L" %s%d%% disease resistance\n", // TODO.Translate L" %s%d%% interrogation effectiveness\n", L" %s%d%% prison guard strength\n", @@ -8227,6 +8249,8 @@ STR16 szBackgroundText_Value[]= L" %s%d%% cth with firearms against creatures\n", L" %s%d%% insurance cost\n", L" %s%d%% effectiveness as spotter for fellow snipers\n", // TODO.Translate + L" %s%d%% effectiveness at diagnosing diseases\n", // TODO.Translate + L" %s%d%% effectiveness at treating population against diseases\n", L" dislikes some other backgrounds", // TODO.Translate }; @@ -8678,7 +8702,7 @@ STR16 szMercCompareEventText[]= L"%s mounted a gun on me", L"%s treated my wounds", - L"Had a good drink %s", + L"Had a good drink with %s", L"%s is fun to get wasted with", L"%s is annoying when drunk", @@ -8693,6 +8717,45 @@ STR16 szMercCompareEventText[]= L"%s puts people in their places", L"%s is way too impulsive", + L"%s is disease-ridden", + L"%s treated my diseases", +}; + +STR16 szWHOWebSite[] = +{ + // main page + L"World Health Organization", + L"Bringing health to life", + + // links to other pages + L"About WHO", + L"Disease in Arulco", + L"About diseases", + + // text on the main page + L"WHO is the directing and coordinating authority for health within the United Nations system.", + L"It is responsible for providing leadership on global health matters, shaping the health research agenda, setting norms and standards, articulating evidence-based policy options, providing technical support to countries and monitoring and assessing health trends.", + L"In the 21st century, health is a shared responsibility, involving equitable access to essential care and collective defence against transnational threats.", + + // contract page + L"The small country of Arulco is currently experiencing an outbreak of the deadly arulcan plague.", + L"Due to the catastrophic state of the state's health system, only the armies' medical corps is there to combat the deadly disease.", + L"With the country being of limits to UN affiliates, all we can currently do is provide detailed maps on the current status of infection in Arulco. Due to the difficulty in dealing with Arulco, we regret to have to ask for a daily fee of %d$ for anyone wishing to obtain these maps.", + L"Do you wish to acquire detailed data on the current status of diease in Arulco? You can access this data on the strategic map once aquired.", + L"You currently do not have access to WHO data on the arulcan plague.", + L"You have acquired detailed maps on the status of the disease.", + L"Subscribe to map updates", + L"Unsubscribe map updates", + + // helpful tips page + L"The arulcan plague is a deadly strain of the plague unique to the small country of Arulco. In a typical outbreak, the first victims get infected by a mosquito in a swamp or tropical sector. These first victims then inadvertently infect the population of nearby cities.", + L"You won't immediately notice when you are infected - it might take days for the symptoms to show.", + L"You can see the current effects of known diseases your mercs suffer from by hovering over their portrait in the strategic map.", + L"Most diseases get worse over time, be sure to assign a doctor as soon as possible.", + L"Some diseases can be treated with special medicine. You might find some in a well-equipped drugstore.", + L"Doctors can be ordered to check on all local teammates for diseases. You can find out about a disease before it breaks out!", + L"Doctors have a much higher chance to be infected when treating infected patients. Protective gear is very useful.", + L"If a blade weapon hits an infected person, the blade becomes infected, and can be used to spread the infection further.", }; STR16 szTacticalInventoryDialogString[]= @@ -8808,6 +8871,8 @@ STR16 szDynamicDialogueText_DOST_VICTIM_INITIATE[] = L"Alright alright. Jeez. I'm over it, okay?", L"Who do you think you are, $CAUSE$? No, I won't be quiet about this!", + L"Ewww! $CAUSE$ is sick! Get away from me, that looks disgusting!", + L"Thanks, $CAUSE$. I'm already feeling better.", }; STR16 szDynamicDialogueText_DOST_VICTIM_TO_INTERJECTOR_DENY[] = @@ -8895,6 +8960,8 @@ STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_DENY[] = L"Cut it, drama queen.", L"I'm the one who tells you to shut up! I'm your superior, $VICTIM$!", + L"Oh yeah? Back off, before I cough on you!", + L"How did you get that in the first place? Did you forget to wash your hands again?", }; STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_AGREE[] = @@ -8935,6 +9002,8 @@ STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_AGREE[] = L"As long as it does not happen again.", L"The two of us are going to have real problem soon, $VICTIM$.", + L"It really is. I... *cough* don't feel so well...", + L"No problem, we can't have you running around coughing blood, right? Riiight?", }; STR16 szDynamicDialogueText_DOST_CAUSE_TO_INTERJECTOR_DENY[] = @@ -9023,6 +9092,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_DIALOGUESELECTION[] = L"$VICTIM$ was reined in by $CAUSE$. What do you do?", L"$VICTIM$ did not take $CAUSE$'s words of action well. What do you do?", + L"$VICTIM$ is offended by $CAUSE$ diseases. What do you do?", + L"$VICTIM$ has treated $CAUSE$'s diseases. What do you do?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_DENY[] = @@ -9063,6 +9134,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_DENY[] = L"No reason to be so stiff about it.", L"Pfft. Don't make a fuss out of it.", + L"Stop behaving like a first grader. We need to get $CAUSE$ to a doctor!", + L"Where did you get that stuff from in the first place?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_AGREE[] = @@ -9103,6 +9176,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_AGREE[] = L"Yeah, keep it down, will ya?", L"Yeah, you won't boss us around anymore!", + L"This does look unhealthy. That better not be contagious!", + L"Great. Are you sure it's fully treated now?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_DENY[] = @@ -9143,6 +9218,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_DENY[] = L"Pah. You're the one making all the fuss about it...", L"You are certainly nobodies superior!", + L"Stop it! We don't need more of whatever it is you have!", + L"The important thing is that it's gone now... It is, right?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_AGREE[] = @@ -9183,6 +9260,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_AGREE[] = L"Yeah, drop that attitude, $VICTIM$.", L"Not sure about that, but yep!", + L"Yeah, there's nothing you can do against this stuff, right?", + L"I told you pople before... this country a dirty place, so beware of what you touch.", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_REASON[] = @@ -9223,6 +9302,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_REASON[] = L"Sigh. More of this?", L"Hey. Hey! Both of you, cut it out! What are you doing?", + L"The important thing is to get $CAUSE$ to a doctor, and to make sure $CAUSE_GENDER$ doesn't infect anybody else.", + L"We have to be careful. The army isn't the only thing that wants us dead.", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_AGGRESSIVE[] = @@ -9263,6 +9344,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_AGGRESSIVE[] = L"Sigh. More of this?", L"If anybody is superior here, then that's me... and I'm ordering you to stand down!", + L"Stop whining! $CAUSE$, get that treated, and the rest of you, back to business!", + L"Great. Everything done? Then let's get back to shooting stuff!", }; STR16 szDynamicDialogueText_DOST_SIDEWITH_VICTIM[] = @@ -9324,4 +9407,24 @@ STR16 szDynamicDialogueText_GenderText[] = L"her", }; +STR16 szDiseaseText[] = +{ + L" %s%d%% agility stat\n", + L" %s%d%% dexterity stat\n", + L" %s%d%% strength stat\n", + L" %s%d%% wisdom stat\n", + L" %s%d%% effective level\n", + + L" %s%d%% APs\n", + L" %s%d maximum breath\n", + L" %s%d%% strength to carry items\n", + L" %s%2.2f life regeneration/hour\n", + L" %s%d need for sleep\n", + L" %s%d%% water consumption\n", + L" %s%d%% food consumption\n", + + L"%s was diagnosed with %s!", + L"%s is cured of %s!", +}; + #endif //DUTCH diff --git a/Utils/_EnglishText.cpp b/Utils/_EnglishText.cpp index dcebfb30..30a0a6ef 100644 --- a/Utils/_EnglishText.cpp +++ b/Utils/_EnglishText.cpp @@ -1865,6 +1865,8 @@ STR16 pAssignmentStrings[] = L"Propag.", // spread propaganda L"Rumours", // gather information L"Command", // militia movement orders + L"Diagnose", // disease diagnosis + L"Treat D.", // treat disease among the population }; @@ -1961,6 +1963,8 @@ STR16 pPersonnelAssignmentStrings[] = L"Spreading Propaganda", // spread propaganda L"Gathering Rumours", // gather information L"Commanding Militia", // militia movement orders + L"Diagnose", // disease diagnosis + L"Treat Population disease", // treat disease among the population }; @@ -2016,6 +2020,8 @@ STR16 pLongAssignmentStrings[] = L"Spread Propaganda", // spread propaganda L"Gather Rumours", // gather information L"Commanding Militia", // militia movement orders + L"Diagnose", // disease diagnosis + L"Treat Population disease", // treat disease among the population }; @@ -2128,6 +2134,7 @@ STR16 pAssignMenuStrings[] = { L"On Duty", // merc is on active duty L"Doctor", // the merc is acting as a doctor + L"Disease", // merc is a doctor doing diagnosis L"Patient", // the merc is receiving medical attention L"Vehicle", // the merc is in a vehicle L"Repair", // the merc is repairing items @@ -3657,6 +3664,7 @@ STR16 pMapScreenBorderButtonHelpText[] = L"Show |Items", L"Show Militia & Enemies (|Z)", L"Show Mobile Militia |Restrictions", // HEADROCK HAM 4: Mobile Restrictions Button + L"Show Disease Data", }; STR16 pMapScreenInvenButtonHelpText[] = @@ -3888,6 +3896,7 @@ STR16 pTransactionText[] = L"Facility Use", // HEADROCK HAM 3.6 L"Militia upkeep", // HEADROCK HAM 3.6 L"Ransom for released prisoners", // Flugente: prisoner system + L"WHO data subscription", // Flugente: disease }; STR16 pTransactionAlternateText[] = @@ -4328,6 +4337,7 @@ STR16 pBookMarkStrings[] = L"Briefing Room", L"Campaign History", L"MeLoDY", + L"WHO", }; STR16 pBookmarkTitle[] = @@ -4444,6 +4454,9 @@ STR16 pWebPagesTitles[] = L"Mercs Love or Dislike You - Analyze a team", L"Mercs Love or Dislike You - Pairwise comparison", L"Mercs Love or Dislike You - About us", + L"WHO - About WHO", + L"WHO - Disease in Arulco", + L"WHO - Helpful Tips", L"Bobby Ray's - Recent Shipments", L"Encyclopedia", L"Encyclopedia - Data", @@ -5505,6 +5518,9 @@ STR16 zMarksMapScreenText[] = // HEADROCK HAM 4: Prompt messages when turning on Mobile Militia Restrictions view. L"You currently have no Mobile Militia. Return to this view mode once you've recruited some.", L"This view shows where your Mobile Militia can and cannot go. GREY = Mobile Militia refuse to go here. RED = Mobile Militia can go here, but you've told them not to. YELLOW = Mobile Militia can enter this sector, but not leave. GREEN = Mobile Militia can go here freely. Right click a Green/Yellow sector to cycle its behavior.", + + // Flugente: disease texts describing what a map view does + L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.", }; @@ -6232,6 +6248,7 @@ STR16 gzLaptopHelpText[] = L"Briefing Room", L"Campaign History", L"Mercenaries Love or Dislike You", + L"World Health Organization", }; @@ -7617,40 +7634,42 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|A|n|t|i|-|T|a|n|k |A|m|m|o", L"|I|g|n|o|r|e|s |A|r|m|o|r", L"|A|c|i|d|i|c |A|m|m|o", - L"|L|o|c|k|-|B|u|s|t|i|n|g |A|m|m|o", + L"|L|o|c|k|-|B|u|s|t|i|n|g |A|m|m|o", // 4 L"|R|e|s|i|s|t|a|n|t |t|o |E|x|p|l|o|s|i|v|e|s", L"|W|a|t|e|r|p|r|o|o|f", L"|E|l|e|c|t|r|o|n|i|c", L"|G|a|s |M|a|s|k", - L"|N|e|e|d|s |B|a|t|t|e|r|i|e|s", + L"|N|e|e|d|s |B|a|t|t|e|r|i|e|s", // 9 L"|C|a|n |P|i|c|k |L|o|c|k|s", L"|C|a|n |C|u|t |W|i|r|e|s", L"|C|a|n |S|m|a|s|h |L|o|c|k|s", L"|M|e|t|a|l |D|e|t|e|c|t|o|r", - L"|R|e|m|o|t|e |T|r|i|g|g|e|r", + L"|R|e|m|o|t|e |T|r|i|g|g|e|r", // 14 L"|R|e|m|o|t|e |D|e|t|o|n|a|t|o|r", L"|T|i|m|e|r |D|e|t|o|n|a|t|o|r", L"|C|o|n|t|a|i|n|s |G|a|s|o|l|i|n|e", L"|T|o|o|l |K|i|t", - L"|T|h|e|r|m|a|l |O|p|t|i|c|s", + L"|T|h|e|r|m|a|l |O|p|t|i|c|s", // 19 L"|X|-|R|a|y |D|e|v|i|c|e", L"|C|o|n|t|a|i|n|s |D|r|i|n|k|i|n|g |W|a|t|e|r", L"|C|o|n|t|a|i|n|s |A|l|c|o|h|o|l", L"|F|i|r|s|t |A|i|d |K|i|t", - L"|M|e|d|i|c|a|l |K|i|t", + L"|M|e|d|i|c|a|l |K|i|t", // 24 L"|L|o|c|k |B|o|m|b", L"|D|r|i|n|k", L"|M|e|a|l", L"|A|m|m|o |B|e|l|t", - L"|A|m|m|o |V|e|s|t", + L"|A|m|m|o |V|e|s|t", // 29 L"|D|e|f|u|s|a|l |K|i|t", L"|C|o|v|e|r|t |I|t|e|m", L"|C|a|n|n|o|t |b|e |d|a|m|a|g|e|d", L"|M|a|d|e |o|f |M|e|t|a|l", - L"|S|i|n|k|s", + L"|S|i|n|k|s", // 34 L"|T|w|o|-|H|a|n|d|e|d", L"|B|l|o|c|k|s |I|r|o|n |S|i|g|h|t|s", L"|A|n|t|i|-|M|a|t|e|r|i|e|l |A|m|m|o", + L"|F|a|c|e |P|r|o|t|e|c|t|i|o|n", + L"|I|n|f|e|c|t|i|o|n |P|r|o|t|e|c|t|i|o|n", // 39 }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -7693,6 +7712,8 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nThis item requires both hands to be used.", L"\n \nThis item will block your iron sights\nso you cannot use them.", L"\n \nThis ammo can destroy light walls\nand various other objects.", + L"\n \nIf worn on your face, this will lower\nthe chance to be infected by other people.", + L"\n \nIf kept in your inventory, this will\nlower\nthe chance to be infected by other people.", }; STR16 szUDBAdvStatsTooltipText[]= @@ -8179,6 +8200,7 @@ STR16 szBackgroundText_Value[]= L" %s%d%% suppression resistance\n", L" %s%d%% physical resistance\n", L" %s%d%% alcohol resistance\n", + L" %s%d%% disease resistance\n", L" %s%d%% interrogation effectiveness\n", L" %s%d%% prison guard strength\n", @@ -8210,6 +8232,8 @@ STR16 szBackgroundText_Value[]= L" %s%d%% cth with firearms against creatures\n", L" %s%d%% insurance cost\n", L" %s%d%% effectiveness as spotter for fellow snipers\n", + L" %s%d%% effectiveness at diagnosing diseases\n", + L" %s%d%% effectiveness at treating population against diseases\n", L" dislikes some other backgrounds", }; @@ -8662,7 +8686,7 @@ STR16 szMercCompareEventText[]= L"%s mounted a gun on me", L"%s treated my wounds", - L"Had a good drink %s", + L"Had a good drink with %s", L"%s is fun to get wasted with", L"%s is annoying when drunk", @@ -8677,6 +8701,45 @@ STR16 szMercCompareEventText[]= L"%s puts people in their places", L"%s is way too impulsive", + L"%s is disease-ridden", + L"%s treated my diseases", +}; + +STR16 szWHOWebSite[] = +{ + // main page + L"World Health Organization", + L"Bringing health to life", + + // links to other pages + L"About WHO", + L"Disease in Arulco", + L"About diseases", + + // text on the main page + L"WHO is the directing and coordinating authority for health within the United Nations system.", + L"It is responsible for providing leadership on global health matters, shaping the health research agenda, setting norms and standards, articulating evidence-based policy options, providing technical support to countries and monitoring and assessing health trends.", + L"In the 21st century, health is a shared responsibility, involving equitable access to essential care and collective defence against transnational threats.", + + // contract page + L"The small country of Arulco is currently experiencing an outbreak of the deadly arulcan plague.", + L"Due to the catastrophic state of the state's health system, only the armies' medical corps is there to combat the deadly disease.", + L"With the country being of limits to UN affiliates, all we can currently do is provide detailed maps on the current status of infection in Arulco. Due to the difficulty in dealing with Arulco, we regret to have to ask for a daily fee of %d$ for anyone wishing to obtain these maps.", + L"Do you wish to acquire detailed data on the current status of diease in Arulco? You can access this data on the strategic map once aquired.", + L"You currently do not have access to WHO data on the arulcan plague.", + L"You have acquired detailed maps on the status of the disease.", + L"Subscribe to map updates", + L"Unsubscribe map updates", + + // helpful tips page + L"The arulcan plague is a deadly strain of the plague unique to the small country of Arulco. In a typical outbreak, the first victims get infected by a mosquito in a swamp or tropical sector. These first victims then inadvertently infect the population of nearby cities.", + L"You won't immediately notice when you are infected - it might take days for the symptoms to show.", + L"You can see the current effects of known diseases your mercs suffer from by hovering over their portrait in the strategic map.", + L"Most diseases get worse over time, be sure to assign a doctor as soon as possible.", + L"Some diseases can be treated with special medicine. You might find some in a well-equipped drugstore.", + L"Doctors can be ordered to check on all local teammates for diseases. You can find out about a disease before it breaks out!", + L"Doctors have a much higher chance to be infected when treating infected patients. Protective gear is very useful.", + L"If a blade weapon hits an infected person, the blade becomes infected, and can be used to spread the infection further.", }; STR16 szTacticalInventoryDialogString[]= @@ -8791,6 +8854,8 @@ STR16 szDynamicDialogueText_DOST_VICTIM_INITIATE[] = L"Alright alright. Jeez. I'm over it, okay?", L"Who do you think you are, $CAUSE$? No, I won't be quiet about this!", + L"Ewww! $CAUSE$ is sick! Get away from me, that looks disgusting!", + L"Thanks, $CAUSE$. I'm already feeling better.", }; STR16 szDynamicDialogueText_DOST_VICTIM_TO_INTERJECTOR_DENY[] = @@ -8878,6 +8943,8 @@ STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_DENY[] = L"Cut it, drama queen.", L"I'm the one who tells you to shut up! I'm your superior, $VICTIM$!", + L"Oh yeah? Back off, before I cough on you!", + L"How did you get that in the first place? Did you forget to wash your hands again?", }; STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_AGREE[] = @@ -8918,6 +8985,8 @@ STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_AGREE[] = L"As long as it does not happen again.", L"The two of us are going to have real problem soon, $VICTIM$.", + L"It really is. I... *cough* don't feel so well...", + L"No problem, we can't have you running around coughing blood, right? Riiight?", }; STR16 szDynamicDialogueText_DOST_CAUSE_TO_INTERJECTOR_DENY[] = @@ -9006,6 +9075,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_DIALOGUESELECTION[] = L"$VICTIM$ was reined in by $CAUSE$. What do you do?", L"$VICTIM$ did not take $CAUSE$'s words of action well. What do you do?", + L"$VICTIM$ is offended by $CAUSE$ diseases. What do you do?", + L"$VICTIM$ has treated $CAUSE$'s diseases. What do you do?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_DENY[] = @@ -9046,6 +9117,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_DENY[] = L"No reason to be so stiff about it.", L"Pfft. Don't make a fuss out of it.", + L"Stop behaving like a first grader. We need to get $CAUSE$ to a doctor!", + L"Where did you get that stuff from in the first place?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_AGREE[] = @@ -9086,6 +9159,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_AGREE[] = L"Yeah, keep it down, will ya?", L"Yeah, you won't boss us around anymore!", + L"This does look unhealthy. That better not be contagious!", + L"Great. Are you sure it's fully treated now?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_DENY[] = @@ -9126,6 +9201,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_DENY[] = L"Pah. You're the one making all the fuss about it...", L"You are certainly nobodies superior!", + L"Stop it! We don't need more of whatever it is you have!", + L"The important thing is that it's gone now... It is, right?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_AGREE[] = @@ -9166,6 +9243,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_AGREE[] = L"Yeah, drop that attitude, $VICTIM$.", L"Not sure about that, but yep!", + L"Yeah, there's nothing you can do against this stuff, right?", + L"I told you pople before... this country a dirty place, so beware of what you touch.", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_REASON[] = @@ -9206,6 +9285,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_REASON[] = L"Sigh. More of this?", L"Hey. Hey! Both of you, cut it out! What are you doing?", + L"The important thing is to get $CAUSE$ to a doctor, and to make sure $CAUSE_GENDER$ doesn't infect anybody else.", + L"We have to be careful. The army isn't the only thing that wants us dead.", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_AGGRESSIVE[] = @@ -9246,6 +9327,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_AGGRESSIVE[] = L"Sigh. More of this?", L"If anybody is superior here, then that's me... and I'm ordering you to stand down!", + L"Stop whining! $CAUSE$, get that treated, and the rest of you, back to business!", + L"Great. Everything done? Then let's get back to shooting stuff!", }; STR16 szDynamicDialogueText_DOST_SIDEWITH_VICTIM[] = @@ -9307,6 +9390,24 @@ STR16 szDynamicDialogueText_GenderText[] = L"her", }; +STR16 szDiseaseText[] = +{ + L" %s%d%% agility stat\n", + L" %s%d%% dexterity stat\n", + L" %s%d%% strength stat\n", + L" %s%d%% wisdom stat\n", + L" %s%d%% effective level\n", + L" %s%d%% APs\n", + L" %s%d maximum breath\n", + L" %s%d%% strength to carry items\n", + L" %s%2.2f life regeneration/hour\n", + L" %s%d need for sleep\n", + L" %s%d%% water consumption\n", + L" %s%d%% food consumption\n", + + L"%s was diagnosed with %s!", + L"%s is cured of %s!", +}; #endif //ENGLISH diff --git a/Utils/_FrenchText.cpp b/Utils/_FrenchText.cpp index 6d293301..c329518b 100644 --- a/Utils/_FrenchText.cpp +++ b/Utils/_FrenchText.cpp @@ -1871,6 +1871,8 @@ STR16 pAssignmentStrings[] = L"Propag.", // spread propaganda L"Rumeur", // gather information L"Command.", // militia movement orders + L"Diagnose", // disease diagnosis //TODO.Translate + L"Treat D.", // treat disease among the population }; @@ -1967,6 +1969,8 @@ STR16 pPersonnelAssignmentStrings[] = L"Propagande", // spread propaganda // TODO.Translate //A voir fini (to see finished) L"Rumeur", // gather information // TODO.Translate //A voir fini (to see finished) L"Commande", // militia movement orders + L"Diagnose", // disease diagnosis + L"Treat Population disease", // treat disease among the population }; @@ -2022,6 +2026,8 @@ STR16 pLongAssignmentStrings[] = L"Propagande", // spread propaganda L"Rumeurs", // gather information L"Commander", // militia movement orders + L"Diagnose", // disease diagnosis + L"Treat Population disease", // treat disease among the population }; @@ -2134,6 +2140,7 @@ STR16 pAssignMenuStrings[] = { L"Service", // merc is on active duty L"Docteur", // the merc is acting as a doctor + L"Disease", // merc is a doctor doing diagnosis TODO.Translate L"Patient(e)", // the merc is receiving medical attention L"Transport", // the merc is in a vehicle L"Réparat.", // the merc is repairing items @@ -3664,6 +3671,7 @@ STR16 pMapScreenBorderButtonHelpText[] = L"Objets (|I)", L"Milice & Ennemis (|Z)", L"Montrer la milice mobile |Restrictions", // HEADROCK HAM 4: Mobile Restrictions Button + L"Show Disease Data", // TODO.Translate }; STR16 pMapScreenInvenButtonHelpText[] = @@ -3897,6 +3905,7 @@ STR16 pTransactionText[] = L"Infrastucture utilisée", // HEADROCK HAM 3.6 L"Entretien de la milice", // HEADROCK HAM 3.6 L"Argent des prisonniers libérés", // Flugente: prisoner system + L"WHO data subscription", // Flugente: disease TODO.Translate }; STR16 pTransactionAlternateText[] = @@ -4341,6 +4350,7 @@ STR16 pBookMarkStrings[] = L"Briefing", L"Comptes rendus", L"MeLoDY", + L"WHO", }; STR16 pBookmarkTitle[] = @@ -4457,6 +4467,9 @@ STR16 pWebPagesTitles[] = L"Mercs Love or Dislike You - Analyze a team", L"Mercs Love or Dislike You - Pairwise comparison", L"Mercs Love or Dislike You - About us", + L"WHO - About WHO", + L"WHO - Disease in Arulco", + L"WHO - Helpful Tips", L"Bobby Ray : Dernières commandes", L"Encyclopédie", L"Encyclopédie : Données", @@ -5518,6 +5531,9 @@ STR16 zMarksMapScreenText[] = // HEADROCK HAM 4: Prompt messages when turning on Mobile Militia Restrictions view. L"Vous n'avez actuellement aucune milice mobile. Retournez à ce mode du vue quand vous en aurez recruté.", L"Cette vue montre où votre milice mobile peut aller ou pas. Gris = La milice mobile refuse d'y aller. ROUGE = La milice mobile peut y aller, mais vous avez dit de ne pas y aller. JAUNE = La milice mobile peut entrer dans ce secteur, mais ne peut pas en sortir. VERT = la milice mobile peut y aller librement. Clic droit sur un secteur vert/jaune/rouge pour changer de couleur.", + + // Flugente: disease texts describing what a map view does TODO.Translate + L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.", }; @@ -6246,6 +6262,7 @@ STR16 gzLaptopHelpText[] = L"Salle de briefing", L"Comptes rendus", L"Mercenaries Love or Dislike You", // TODO.Translate + L"World Health Organization", }; @@ -7655,6 +7672,8 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|À |d|e|u|x |m|a|i|n|s", L"|B|l|o|q|u|e |l|e |v|i|s|e|u|r", L"|A|n|t|i|-|M|a|t|e|r|i|a|l |A|m|m|o", // TODO.Translate + L"|F|a|c|e |P|r|o|t|e|c|t|i|o|n", + L"|I|n|f|e|c|t|i|o|n |P|r|o|t|e|c|t|i|o|n", // 39 }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -7697,6 +7716,8 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nCet objet exige les deux mains pour être utilisé.", L"\n \nCet Objet bloquera votre viseur\nde ce fait vous ne pouvez pas l'utiliser.", L"\n \nThis ammo can destroy light walls\nand various other objects.", // TODO.Translate + L"\n \nIf worn on your face, this will lower\nthe chance to be infected by other people.", + L"\n \nIf kept in your inventory, this will\nlower\nthe chance to be infected by other people.", }; STR16 szUDBAdvStatsTooltipText[]= @@ -8183,6 +8204,7 @@ STR16 szBackgroundText_Value[]= L" %s%d%% de résistance au tir de couverture\n", L" %s%d%% de résistance physique\n", L" %s%d%% de résistance à l'alcool\n", + L" %s%d%% disease resistance\n", // TODO.Translate L" %s%d%% d'efficacité dans les interrogatoires\n", L" %s%d%% d'efficacité comme gardien de prison\n", @@ -8214,6 +8236,8 @@ STR16 szBackgroundText_Value[]= L" %s%d%% de CDT avec des armes à feu contre les créatures\n", L" %s%d%% du coût de l'assurance\n", L" %s%d%% d'efficacité comme guetteur pour vos tireurs d'élite\n", + L" %s%d%% effectiveness at diagnosing diseases\n", // TODO.Translate + L" %s%d%% effectiveness at treating population against diseases\n", L" dislikes some other backgrounds", // TODO.Translate }; @@ -8665,7 +8689,7 @@ STR16 szMercCompareEventText[]= L"%s mounted a gun on me", L"%s treated my wounds", - L"Had a good drink %s", + L"Had a good drink with %s", L"%s is fun to get wasted with", L"%s is annoying when drunk", @@ -8680,6 +8704,45 @@ STR16 szMercCompareEventText[]= L"%s puts people in their places", L"%s is way too impulsive", + L"%s is disease-ridden", + L"%s treated my diseases", +}; + +STR16 szWHOWebSite[] = +{ + // main page + L"World Health Organization", + L"Bringing health to life", + + // links to other pages + L"About WHO", + L"Disease in Arulco", + L"About diseases", + + // text on the main page + L"WHO is the directing and coordinating authority for health within the United Nations system.", + L"It is responsible for providing leadership on global health matters, shaping the health research agenda, setting norms and standards, articulating evidence-based policy options, providing technical support to countries and monitoring and assessing health trends.", + L"In the 21st century, health is a shared responsibility, involving equitable access to essential care and collective defence against transnational threats.", + + // contract page + L"The small country of Arulco is currently experiencing an outbreak of the deadly arulcan plague.", + L"Due to the catastrophic state of the state's health system, only the armies' medical corps is there to combat the deadly disease.", + L"With the country being of limits to UN affiliates, all we can currently do is provide detailed maps on the current status of infection in Arulco. Due to the difficulty in dealing with Arulco, we regret to have to ask for a daily fee of %d$ for anyone wishing to obtain these maps.", + L"Do you wish to acquire detailed data on the current status of diease in Arulco? You can access this data on the strategic map once aquired.", + L"You currently do not have access to WHO data on the arulcan plague.", + L"You have acquired detailed maps on the status of the disease.", + L"Subscribe to map updates", + L"Unsubscribe map updates", + + // helpful tips page + L"The arulcan plague is a deadly strain of the plague unique to the small country of Arulco. In a typical outbreak, the first victims get infected by a mosquito in a swamp or tropical sector. These first victims then inadvertently infect the population of nearby cities.", + L"You won't immediately notice when you are infected - it might take days for the symptoms to show.", + L"You can see the current effects of known diseases your mercs suffer from by hovering over their portrait in the strategic map.", + L"Most diseases get worse over time, be sure to assign a doctor as soon as possible.", + L"Some diseases can be treated with special medicine. You might find some in a well-equipped drugstore.", + L"Doctors can be ordered to check on all local teammates for diseases. You can find out about a disease before it breaks out!", + L"Doctors have a much higher chance to be infected when treating infected patients. Protective gear is very useful.", + L"If a blade weapon hits an infected person, the blade becomes infected, and can be used to spread the infection further.", }; STR16 szTacticalInventoryDialogString[]= @@ -8795,6 +8858,8 @@ STR16 szDynamicDialogueText_DOST_VICTIM_INITIATE[] = L"Alright alright. Jeez. I'm over it, okay?", L"Who do you think you are, $CAUSE$? No, I won't be quiet about this!", + L"Ewww! $CAUSE$ is sick! Get away from me, that looks disgusting!", + L"Thanks, $CAUSE$. I'm already feeling better.", }; STR16 szDynamicDialogueText_DOST_VICTIM_TO_INTERJECTOR_DENY[] = @@ -8882,6 +8947,8 @@ STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_DENY[] = L"Cut it, drama queen.", L"I'm the one who tells you to shut up! I'm your superior, $VICTIM$!", + L"Oh yeah? Back off, before I cough on you!", + L"How did you get that in the first place? Did you forget to wash your hands again?", }; STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_AGREE[] = @@ -8922,6 +8989,8 @@ STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_AGREE[] = L"As long as it does not happen again.", L"The two of us are going to have real problem soon, $VICTIM$.", + L"It really is. I... *cough* don't feel so well...", + L"No problem, we can't have you running around coughing blood, right? Riiight?", }; STR16 szDynamicDialogueText_DOST_CAUSE_TO_INTERJECTOR_DENY[] = @@ -9010,6 +9079,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_DIALOGUESELECTION[] = L"$VICTIM$ was reined in by $CAUSE$. What do you do?", L"$VICTIM$ did not take $CAUSE$'s words of action well. What do you do?", + L"$VICTIM$ is offended by $CAUSE$ diseases. What do you do?", + L"$VICTIM$ has treated $CAUSE$'s diseases. What do you do?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_DENY[] = @@ -9050,6 +9121,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_DENY[] = L"No reason to be so stiff about it.", L"Pfft. Don't make a fuss out of it.", + L"Stop behaving like a first grader. We need to get $CAUSE$ to a doctor!", + L"Where did you get that stuff from in the first place?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_AGREE[] = @@ -9090,6 +9163,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_AGREE[] = L"Yeah, keep it down, will ya?", L"Yeah, you won't boss us around anymore!", + L"This does look unhealthy. That better not be contagious!", + L"Great. Are you sure it's fully treated now?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_DENY[] = @@ -9130,6 +9205,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_DENY[] = L"Pah. You're the one making all the fuss about it...", L"You are certainly nobodies superior!", + L"Stop it! We don't need more of whatever it is you have!", + L"The important thing is that it's gone now... It is, right?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_AGREE[] = @@ -9170,6 +9247,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_AGREE[] = L"Yeah, drop that attitude, $VICTIM$.", L"Not sure about that, but yep!", + L"Yeah, there's nothing you can do against this stuff, right?", + L"I told you pople before... this country a dirty place, so beware of what you touch.", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_REASON[] = @@ -9210,6 +9289,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_REASON[] = L"Sigh. More of this?", L"Hey. Hey! Both of you, cut it out! What are you doing?", + L"The important thing is to get $CAUSE$ to a doctor, and to make sure $CAUSE_GENDER$ doesn't infect anybody else.", + L"We have to be careful. The army isn't the only thing that wants us dead.", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_AGGRESSIVE[] = @@ -9250,6 +9331,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_AGGRESSIVE[] = L"Sigh. More of this?", L"If anybody is superior here, then that's me... and I'm ordering you to stand down!", + L"Stop whining! $CAUSE$, get that treated, and the rest of you, back to business!", + L"Great. Everything done? Then let's get back to shooting stuff!", }; STR16 szDynamicDialogueText_DOST_SIDEWITH_VICTIM[] = @@ -9311,4 +9394,24 @@ STR16 szDynamicDialogueText_GenderText[] = L"her", }; +STR16 szDiseaseText[] = +{ + L" %s%d%% agility stat\n", + L" %s%d%% dexterity stat\n", + L" %s%d%% strength stat\n", + L" %s%d%% wisdom stat\n", + L" %s%d%% effective level\n", + + L" %s%d%% APs\n", + L" %s%d maximum breath\n", + L" %s%d%% strength to carry items\n", + L" %s%2.2f life regeneration/hour\n", + L" %s%d need for sleep\n", + L" %s%d%% water consumption\n", + L" %s%d%% food consumption\n", + + L"%s was diagnosed with %s!", + L"%s is cured of %s!", +}; + #endif //FRENCH diff --git a/Utils/_GermanText.cpp b/Utils/_GermanText.cpp index 0fe40ae6..ca9fbdad 100644 --- a/Utils/_GermanText.cpp +++ b/Utils/_GermanText.cpp @@ -1876,6 +1876,8 @@ STR16 pAssignmentStrings[] = L"Propag.", // spread propaganda L"Rumours", // gather information L"Command", // militia movement orders + L"Diagnose", // disease diagnosis //TODO.Translate + L"Treat D.", // treat disease among the population }; STR16 pMilitiaString[] = @@ -1968,6 +1970,8 @@ STR16 pPersonnelAssignmentStrings[] = L"Spreading Propaganda",// TODO.Translate // spread propaganda L"Gathering Rumours",// TODO.Translate // gather information L"Commanding Militia", // militia movement orders // TODO.Translate + L"Diagnose", // disease diagnosis + L"Treat Population disease", // treat disease among the population }; // refer to above for comments @@ -2021,6 +2025,8 @@ STR16 pLongAssignmentStrings[] = L"Spread Propaganda",// TODO.Translate // spread propaganda L"Gather Rumours",// TODO.Translate // gather information L"Commanding Militia", // militia movement orders // TODO.Translate + L"Diagnose", // disease diagnosis + L"Treat Population disease", // treat disease among the population }; // the contract options @@ -2129,6 +2135,7 @@ STR16 pAssignMenuStrings[] = { L"Dienst", // merc is on active duty L"Doktor", // the merc is acting as a doctor + L"Disease", // merc is a doctor doing diagnosis TODO.Translate L"Patient", // the merc is receiving medical attention L"Fahrzeug", // the merc is in a vehicle L"Repar.", // the merc is repairing items @@ -3647,6 +3654,7 @@ STR16 pMapScreenBorderButtonHelpText[] = L"Gegenstände zeigen (|I)", L"Mili|z & Feinde zeigen", L"Zeige Mobile Miliz Begrenzungen (|R)", // HEADROCK HAM 4: Mobile Restrictions Button + L"Show Disease Data", // TODO.Translate }; STR16 pMapScreenInvenButtonHelpText[] = @@ -3865,6 +3873,7 @@ STR16 pTransactionText[] = L"Betriebskosten", // HEADROCK HAM 3.6 L"Unterhaltskosten für Miliz", // HEADROCK HAM 3.6 L"Lösegeld erpresst", // Flugente: prisoner system + L"WHO data subscription", // Flugente: disease TODO.Translate }; STR16 pTransactionAlternateText[] = @@ -4282,6 +4291,7 @@ STR16 pBookMarkStrings[] = L"Besprechung", L"Geschichte", L"MeLoDY", + L"WHO", }; STR16 pBookmarkTitle[] = @@ -4390,6 +4400,9 @@ STR16 pWebPagesTitles[] = L"Mercs Love or Dislike You - Analyze a team", L"Mercs Love or Dislike You - Pairwise comparison", L"Mercs Love or Dislike You - About us", + L"WHO - About WHO", + L"WHO - Disease in Arulco", + L"WHO - Helpful Tips", L"Bobby Rays - Letzte Lieferungen", L"Enzyklopädie", L"Enzyklopädie - Daten", @@ -5355,6 +5368,9 @@ STR16 zMarksMapScreenText[] = // HEADROCK HAM 4: Prompt messages when turning on Mobile Militia Restrictions view. L"Sie haben derzeit keine Mobile Miliz. Rekrutieren Sie einige Milizen und kehren Sie zurück zu dieser Ansicht.", L"Diese Ansicht zeigt Ihnen, wo Ihre Mobile Miliz ins feindliche Gebiet vorrücken kann. GRAU = Mobile Miliz verweigern hier vorzurücken. ROT = Mobile Miliz kann hier vorrücken, aber Sie haben den Befehl nicht gegeben. GELB = Mobile Miliz kann in den Sektor vorrücken, aber nicht verlassen. GRÜN = Mobile Miliz kann sich hier frei bewegen. Rechtsklick auf einen GRÜNEN / GELBEN Bereich um das Verhalten der Miliz zu ändern.", + + // Flugente: disease texts describing what a map view does TODO.Translate + L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.", }; STR16 pLandMarkInSectorString[] = @@ -6076,6 +6092,7 @@ STR16 gzLaptopHelpText[] = L"Einsatzbesprechung", L"Geschichte", L"Mercenaries Love or Dislike You", // TODO.Translate + L"World Health Organization", }; STR16 gzHelpScreenText[] = @@ -7481,6 +7498,8 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|T|w|o|-|H|a|n|d|e|d", L"|B|l|o|c|k|s |I|r|o|n |S|i|g|h|t|s", L"|A|n|t|i|-|M|a|t|e|r|i|a|l |A|m|m|o", // TODO.Translate + L"|F|a|c|e |P|r|o|t|e|c|t|i|o|n", + L"|I|n|f|e|c|t|i|o|n |P|r|o|t|e|c|t|i|o|n", // 39 }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -7523,6 +7542,8 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nDieser Gegenstand muß mit beiden Händen benutzt werden.", L"\n \nDieser Gegenstand verhindert die Verwendung von Kimme und Korn.", L"\n \nThis ammo can destroy light walls\nand various other objects.", // TODO.Translate + L"\n \nIf worn on your face, this will lower\nthe chance to be infected by other people.", + L"\n \nIf kept in your inventory, this will\nlower\nthe chance to be infected by other people.", }; STR16 szUDBAdvStatsTooltipText[]= @@ -8010,6 +8031,7 @@ STR16 szBackgroundText_Value[]= L" %s%d%% suppression resistance\n", L" %s%d%% physical resistance\n", L" %s%d%% alcohol resistance\n", + L" %s%d%% disease resistance\n", // TODO.Translate L" %s%d%% interrogation effectiveness\n", L" %s%d%% prison guard strength\n", @@ -8041,6 +8063,8 @@ STR16 szBackgroundText_Value[]= L" %s%d%% cth with firearms against creatures\n", L" %s%d%% insurance cost\n", L" %s%d%% effectiveness as spotter for fellow snipers\n", // TODO.Translate + L" %s%d%% effectiveness at diagnosing diseases\n", // TODO.Translate + L" %s%d%% effectiveness at treating population against diseases\n", L" dislikes some other backgrounds", // TODO.Translate }; @@ -8492,7 +8516,7 @@ STR16 szMercCompareEventText[]= L"%s mounted a gun on me", L"%s treated my wounds", - L"Had a good drink %s", + L"Had a good drink with %s", L"%s is fun to get wasted with", L"%s is annoying when drunk", @@ -8507,6 +8531,45 @@ STR16 szMercCompareEventText[]= L"%s puts people in their places", L"%s is way too impulsive", + L"%s is disease-ridden", + L"%s treated my diseases", +}; + +STR16 szWHOWebSite[] = +{ + // main page + L"World Health Organization", + L"Bringing health to life", + + // links to other pages + L"About WHO", + L"Disease in Arulco", + L"About diseases", + + // text on the main page + L"WHO is the directing and coordinating authority for health within the United Nations system.", + L"It is responsible for providing leadership on global health matters, shaping the health research agenda, setting norms and standards, articulating evidence-based policy options, providing technical support to countries and monitoring and assessing health trends.", + L"In the 21st century, health is a shared responsibility, involving equitable access to essential care and collective defence against transnational threats.", + + // contract page + L"The small country of Arulco is currently experiencing an outbreak of the deadly arulcan plague.", + L"Due to the catastrophic state of the state's health system, only the armies' medical corps is there to combat the deadly disease.", + L"With the country being of limits to UN affiliates, all we can currently do is provide detailed maps on the current status of infection in Arulco. Due to the difficulty in dealing with Arulco, we regret to have to ask for a daily fee of %d$ for anyone wishing to obtain these maps.", + L"Do you wish to acquire detailed data on the current status of diease in Arulco? You can access this data on the strategic map once aquired.", + L"You currently do not have access to WHO data on the arulcan plague.", + L"You have acquired detailed maps on the status of the disease.", + L"Subscribe to map updates", + L"Unsubscribe map updates", + + // helpful tips page + L"The arulcan plague is a deadly strain of the plague unique to the small country of Arulco. In a typical outbreak, the first victims get infected by a mosquito in a swamp or tropical sector. These first victims then inadvertently infect the population of nearby cities.", + L"You won't immediately notice when you are infected - it might take days for the symptoms to show.", + L"You can see the current effects of known diseases your mercs suffer from by hovering over their portrait in the strategic map.", + L"Most diseases get worse over time, be sure to assign a doctor as soon as possible.", + L"Some diseases can be treated with special medicine. You might find some in a well-equipped drugstore.", + L"Doctors can be ordered to check on all local teammates for diseases. You can find out about a disease before it breaks out!", + L"Doctors have a much higher chance to be infected when treating infected patients. Protective gear is very useful.", + L"If a blade weapon hits an infected person, the blade becomes infected, and can be used to spread the infection further.", }; STR16 szTacticalInventoryDialogString[]= @@ -8622,6 +8685,8 @@ STR16 szDynamicDialogueText_DOST_VICTIM_INITIATE[] = L"Alright alright. Jeez. I'm over it, okay?", L"Who do you think you are, $CAUSE$? No, I won't be quiet about this!", + L"Ewww! $CAUSE$ is sick! Get away from me, that looks disgusting!", + L"Thanks, $CAUSE$. I'm already feeling better.", }; STR16 szDynamicDialogueText_DOST_VICTIM_TO_INTERJECTOR_DENY[] = @@ -8709,6 +8774,8 @@ STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_DENY[] = L"Cut it, drama queen.", L"I'm the one who tells you to shut up! I'm your superior, $VICTIM$!", + L"Oh yeah? Back off, before I cough on you!", + L"How did you get that in the first place? Did you forget to wash your hands again?", }; STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_AGREE[] = @@ -8749,6 +8816,8 @@ STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_AGREE[] = L"As long as it does not happen again.", L"The two of us are going to have real problem soon, $VICTIM$.", + L"It really is. I... *cough* don't feel so well...", + L"No problem, we can't have you running around coughing blood, right? Riiight?", }; STR16 szDynamicDialogueText_DOST_CAUSE_TO_INTERJECTOR_DENY[] = @@ -8837,6 +8906,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_DIALOGUESELECTION[] = L"$VICTIM$ was reined in by $CAUSE$. What do you do?", L"$VICTIM$ did not take $CAUSE$'s words of action well. What do you do?", + L"$VICTIM$ is offended by $CAUSE$ diseases. What do you do?", + L"$VICTIM$ has treated $CAUSE$'s diseases. What do you do?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_DENY[] = @@ -8877,6 +8948,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_DENY[] = L"No reason to be so stiff about it.", L"Pfft. Don't make a fuss out of it.", + L"Stop behaving like a first grader. We need to get $CAUSE$ to a doctor!", + L"Where did you get that stuff from in the first place?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_AGREE[] = @@ -8917,6 +8990,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_AGREE[] = L"Yeah, keep it down, will ya?", L"Yeah, you won't boss us around anymore!", + L"This does look unhealthy. That better not be contagious!", + L"Great. Are you sure it's fully treated now?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_DENY[] = @@ -8957,6 +9032,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_DENY[] = L"Pah. You're the one making all the fuss about it...", L"You are certainly nobodies superior!", + L"Stop it! We don't need more of whatever it is you have!", + L"The important thing is that it's gone now... It is, right?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_AGREE[] = @@ -8997,6 +9074,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_AGREE[] = L"Yeah, drop that attitude, $VICTIM$.", L"Not sure about that, but yep!", + L"Yeah, there's nothing you can do against this stuff, right?", + L"I told you pople before... this country a dirty place, so beware of what you touch.", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_REASON[] = @@ -9037,6 +9116,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_REASON[] = L"Sigh. More of this?", L"Hey. Hey! Both of you, cut it out! What are you doing?", + L"The important thing is to get $CAUSE$ to a doctor, and to make sure $CAUSE_GENDER$ doesn't infect anybody else.", + L"We have to be careful. The army isn't the only thing that wants us dead.", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_AGGRESSIVE[] = @@ -9077,6 +9158,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_AGGRESSIVE[] = L"Sigh. More of this?", L"If anybody is superior here, then that's me... and I'm ordering you to stand down!", + L"Stop whining! $CAUSE$, get that treated, and the rest of you, back to business!", + L"Great. Everything done? Then let's get back to shooting stuff!", }; STR16 szDynamicDialogueText_DOST_SIDEWITH_VICTIM[] = @@ -9138,4 +9221,24 @@ STR16 szDynamicDialogueText_GenderText[] = L"her", }; +STR16 szDiseaseText[] = +{ + L" %s%d%% agility stat\n", + L" %s%d%% dexterity stat\n", + L" %s%d%% strength stat\n", + L" %s%d%% wisdom stat\n", + L" %s%d%% effective level\n", + + L" %s%d%% APs\n", + L" %s%d maximum breath\n", + L" %s%d%% strength to carry items\n", + L" %s%2.2f life regeneration/hour\n", + L" %s%d need for sleep\n", + L" %s%d%% water consumption\n", + L" %s%d%% food consumption\n", + + L"%s was diagnosed with %s!", + L"%s is cured of %s!", +}; + #endif //GERMAN diff --git a/Utils/_ItalianText.cpp b/Utils/_ItalianText.cpp index d7fb7400..4fe8d805 100644 --- a/Utils/_ItalianText.cpp +++ b/Utils/_ItalianText.cpp @@ -1857,6 +1857,8 @@ STR16 pAssignmentStrings[] = L"Propag.", // spread propaganda L"Rumours", // gather information L"Command", // militia movement orders + L"Diagnose", // disease diagnosis //TODO.Translate + L"Treat D.", // treat disease among the population }; @@ -1953,6 +1955,8 @@ STR16 pPersonnelAssignmentStrings[] = L"Spreading Propaganda",// TODO.Translate // spread propaganda L"Gathering Rumours",// TODO.Translate // gather information L"Commanding Militia", // militia movement orders // TODO.Translate + L"Diagnose", // disease diagnosis + L"Treat Population disease", // treat disease among the population }; @@ -2008,6 +2012,8 @@ STR16 pLongAssignmentStrings[] = L"Spread Propaganda",// TODO.Translate // spread propaganda L"Gather Rumours",// TODO.Translate // gather information L"Commanding Militia", // militia movement orders // TODO.Translate + L"Diagnose", // disease diagnosis + L"Treat Population disease", // treat disease among the population }; @@ -2120,6 +2126,7 @@ STR16 pAssignMenuStrings[] = { L"In servizio", // merc is on active duty L"Dottore", // the merc is acting as a doctor + L"Disease", // merc is a doctor doing diagnosis TODO.Translate L"Paziente", // the merc is receiving medical attention L"Veicolo", // the merc is in a vehicle L"Ripara", // the merc is repairing items @@ -3652,6 +3659,7 @@ STR16 pMapScreenBorderButtonHelpText[] = L"Mostra oggett|i", L"Mostra esercito & nemici (|Z)", L"Show Mobile Militia |Restrictions", // HEADROCK HAM 4: Mobile Restrictions Button // TODO.Translate + L"Show Disease Data", // TODO.Translate }; STR16 pMapScreenInvenButtonHelpText[] = @@ -3884,6 +3892,7 @@ STR16 pTransactionText[] = L"Facility Use", // HEADROCK HAM 3.6 // TODO.Translate L"Militia upkeep", // HEADROCK HAM 3.6 // TODO.Translate L"Ransom for released prisoners", // Flugente: prisoner system TODO.Translate + L"WHO data subscription", // Flugente: disease TODO.Translate }; STR16 pTransactionAlternateText[] = @@ -4320,6 +4329,7 @@ STR16 pBookMarkStrings[] = L"Annulla", L"Campaign History", // TODO.Translate L"MeLoDY", + L"WHO", }; STR16 pBookmarkTitle[] = @@ -4436,6 +4446,9 @@ STR16 pWebPagesTitles[] = L"Mercs Love or Dislike You - Analyze a team", L"Mercs Love or Dislike You - Pairwise comparison", L"Mercs Love or Dislike You - About us", + L"WHO - About WHO", + L"WHO - Disease in Arulco", + L"WHO - Helpful Tips", L"Bobby Ray - Spedizioni recenti", L"Encyclopedia", L"Encyclopedia - Data", @@ -5493,6 +5506,9 @@ STR16 zMarksMapScreenText[] = // HEADROCK HAM 4: Prompt messages when turning on Mobile Militia Restrictions view. L"You currently have no Mobile Militia. Return to this view mode once you've recruited some.", L"This view shows where your Mobile Militia can and cannot go. GREY = Mobile Militia refuse to go here. RED = Mobile Militia can go here, but you've told them not to. YELLOW = Mobile Militia can enter this sector, but not leave. GREEN = Mobile Militia can go here freely. Right click a Green/Yellow sector to cycle its behavior.", + + // Flugente: disease texts describing what a map view does TODO.Translate + L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.", }; @@ -6230,6 +6246,7 @@ STR16 gzLaptopHelpText[] = L"Briefing Room", L"Campaign History", // TODO.Translate L"Mercenaries Love or Dislike You", // TODO.Translate + L"World Health Organization", }; @@ -7655,6 +7672,8 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|T|w|o|-|H|a|n|d|e|d", L"|B|l|o|c|k|s |I|r|o|n |S|i|g|h|t|s", L"|A|n|t|i|-|M|a|t|e|r|i|a|l |A|m|m|o", // TODO.Translate + L"|F|a|c|e |P|r|o|t|e|c|t|i|o|n", + L"|I|n|f|e|c|t|i|o|n |P|r|o|t|e|c|t|i|o|n", // 39 }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -7697,6 +7716,8 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nThis item requires both hands to be used.", L"\n \nThis item will block your iron sights\nso you cannot use them.", L"\n \nThis ammo can destroy light walls\nand various other objects.", // TODO.Translate + L"\n \nIf worn on your face, this will lower\nthe chance to be infected by other people.", + L"\n \nIf kept in your inventory, this will\nlower\nthe chance to be infected by other people.", }; STR16 szUDBAdvStatsTooltipText[]= @@ -8189,6 +8210,7 @@ STR16 szBackgroundText_Value[]= L" %s%d%% suppression resistance\n", L" %s%d%% physical resistance\n", L" %s%d%% alcohol resistance\n", + L" %s%d%% disease resistance\n", // TODO.Translate L" %s%d%% interrogation effectiveness\n", L" %s%d%% prison guard strength\n", @@ -8220,6 +8242,8 @@ STR16 szBackgroundText_Value[]= L" %s%d%% cth with firearms against creatures\n", L" %s%d%% insurance cost\n", L" %s%d%% effectiveness as spotter for fellow snipers\n", // TODO.Translate + L" %s%d%% effectiveness at diagnosing diseases\n", // TODO.Translate + L" %s%d%% effectiveness at treating population against diseases\n", L" dislikes some other backgrounds", // TODO.Translate }; @@ -8671,7 +8695,7 @@ STR16 szMercCompareEventText[]= L"%s mounted a gun on me", L"%s treated my wounds", - L"Had a good drink %s", + L"Had a good drink with %s", L"%s is fun to get wasted with", L"%s is annoying when drunk", @@ -8686,6 +8710,45 @@ STR16 szMercCompareEventText[]= L"%s puts people in their places", L"%s is way too impulsive", + L"%s is disease-ridden", + L"%s treated my diseases", +}; + +STR16 szWHOWebSite[] = +{ + // main page + L"World Health Organization", + L"Bringing health to life", + + // links to other pages + L"About WHO", + L"Disease in Arulco", + L"About diseases", + + // text on the main page + L"WHO is the directing and coordinating authority for health within the United Nations system.", + L"It is responsible for providing leadership on global health matters, shaping the health research agenda, setting norms and standards, articulating evidence-based policy options, providing technical support to countries and monitoring and assessing health trends.", + L"In the 21st century, health is a shared responsibility, involving equitable access to essential care and collective defence against transnational threats.", + + // contract page + L"The small country of Arulco is currently experiencing an outbreak of the deadly arulcan plague.", + L"Due to the catastrophic state of the state's health system, only the armies' medical corps is there to combat the deadly disease.", + L"With the country being of limits to UN affiliates, all we can currently do is provide detailed maps on the current status of infection in Arulco. Due to the difficulty in dealing with Arulco, we regret to have to ask for a daily fee of %d$ for anyone wishing to obtain these maps.", + L"Do you wish to acquire detailed data on the current status of diease in Arulco? You can access this data on the strategic map once aquired.", + L"You currently do not have access to WHO data on the arulcan plague.", + L"You have acquired detailed maps on the status of the disease.", + L"Subscribe to map updates", + L"Unsubscribe map updates", + + // helpful tips page + L"The arulcan plague is a deadly strain of the plague unique to the small country of Arulco. In a typical outbreak, the first victims get infected by a mosquito in a swamp or tropical sector. These first victims then inadvertently infect the population of nearby cities.", + L"You won't immediately notice when you are infected - it might take days for the symptoms to show.", + L"You can see the current effects of known diseases your mercs suffer from by hovering over their portrait in the strategic map.", + L"Most diseases get worse over time, be sure to assign a doctor as soon as possible.", + L"Some diseases can be treated with special medicine. You might find some in a well-equipped drugstore.", + L"Doctors can be ordered to check on all local teammates for diseases. You can find out about a disease before it breaks out!", + L"Doctors have a much higher chance to be infected when treating infected patients. Protective gear is very useful.", + L"If a blade weapon hits an infected person, the blade becomes infected, and can be used to spread the infection further.", }; STR16 szTacticalInventoryDialogString[]= @@ -8801,6 +8864,8 @@ STR16 szDynamicDialogueText_DOST_VICTIM_INITIATE[] = L"Alright alright. Jeez. I'm over it, okay?", L"Who do you think you are, $CAUSE$? No, I won't be quiet about this!", + L"Ewww! $CAUSE$ is sick! Get away from me, that looks disgusting!", + L"Thanks, $CAUSE$. I'm already feeling better.", }; STR16 szDynamicDialogueText_DOST_VICTIM_TO_INTERJECTOR_DENY[] = @@ -8888,6 +8953,8 @@ STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_DENY[] = L"Cut it, drama queen.", L"I'm the one who tells you to shut up! I'm your superior, $VICTIM$!", + L"Oh yeah? Back off, before I cough on you!", + L"How did you get that in the first place? Did you forget to wash your hands again?", }; STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_AGREE[] = @@ -8928,6 +8995,8 @@ STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_AGREE[] = L"As long as it does not happen again.", L"The two of us are going to have real problem soon, $VICTIM$.", + L"It really is. I... *cough* don't feel so well...", + L"No problem, we can't have you running around coughing blood, right? Riiight?", }; STR16 szDynamicDialogueText_DOST_CAUSE_TO_INTERJECTOR_DENY[] = @@ -9016,6 +9085,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_DIALOGUESELECTION[] = L"$VICTIM$ was reined in by $CAUSE$. What do you do?", L"$VICTIM$ did not take $CAUSE$'s words of action well. What do you do?", + L"$VICTIM$ is offended by $CAUSE$ diseases. What do you do?", + L"$VICTIM$ has treated $CAUSE$'s diseases. What do you do?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_DENY[] = @@ -9056,6 +9127,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_DENY[] = L"No reason to be so stiff about it.", L"Pfft. Don't make a fuss out of it.", + L"Stop behaving like a first grader. We need to get $CAUSE$ to a doctor!", + L"Where did you get that stuff from in the first place?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_AGREE[] = @@ -9096,6 +9169,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_AGREE[] = L"Yeah, keep it down, will ya?", L"Yeah, you won't boss us around anymore!", + L"This does look unhealthy. That better not be contagious!", + L"Great. Are you sure it's fully treated now?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_DENY[] = @@ -9136,6 +9211,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_DENY[] = L"Pah. You're the one making all the fuss about it...", L"You are certainly nobodies superior!", + L"Stop it! We don't need more of whatever it is you have!", + L"The important thing is that it's gone now... It is, right?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_AGREE[] = @@ -9176,6 +9253,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_AGREE[] = L"Yeah, drop that attitude, $VICTIM$.", L"Not sure about that, but yep!", + L"Yeah, there's nothing you can do against this stuff, right?", + L"I told you pople before... this country a dirty place, so beware of what you touch.", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_REASON[] = @@ -9216,6 +9295,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_REASON[] = L"Sigh. More of this?", L"Hey. Hey! Both of you, cut it out! What are you doing?", + L"The important thing is to get $CAUSE$ to a doctor, and to make sure $CAUSE_GENDER$ doesn't infect anybody else.", + L"We have to be careful. The army isn't the only thing that wants us dead.", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_AGGRESSIVE[] = @@ -9256,6 +9337,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_AGGRESSIVE[] = L"Sigh. More of this?", L"If anybody is superior here, then that's me... and I'm ordering you to stand down!", + L"Stop whining! $CAUSE$, get that treated, and the rest of you, back to business!", + L"Great. Everything done? Then let's get back to shooting stuff!", }; STR16 szDynamicDialogueText_DOST_SIDEWITH_VICTIM[] = @@ -9317,4 +9400,24 @@ STR16 szDynamicDialogueText_GenderText[] = L"her", }; +STR16 szDiseaseText[] = +{ + L" %s%d%% agility stat\n", + L" %s%d%% dexterity stat\n", + L" %s%d%% strength stat\n", + L" %s%d%% wisdom stat\n", + L" %s%d%% effective level\n", + + L" %s%d%% APs\n", + L" %s%d maximum breath\n", + L" %s%d%% strength to carry items\n", + L" %s%2.2f life regeneration/hour\n", + L" %s%d need for sleep\n", + L" %s%d%% water consumption\n", + L" %s%d%% food consumption\n", + + L"%s was diagnosed with %s!", + L"%s is cured of %s!", +}; + #endif //ITALIAN diff --git a/Utils/_PolishText.cpp b/Utils/_PolishText.cpp index 37320ece..b36d7bad 100644 --- a/Utils/_PolishText.cpp +++ b/Utils/_PolishText.cpp @@ -1873,6 +1873,8 @@ STR16 pAssignmentStrings[] = L"Propag.", // spread propaganda L"Rumours", // gather information L"Command", // militia movement orders + L"Diagnose", // disease diagnosis //TODO.Translate + L"Treat D.", // treat disease among the population }; @@ -1969,6 +1971,8 @@ STR16 pPersonnelAssignmentStrings[] = L"Szerzy propagandę", // spread propaganda L"Zbiera plotki", // gather information L"Commanding Militia", // militia movement orders // TODO.Translate + L"Diagnose", // disease diagnosis + L"Treat Population disease", // treat disease among the population }; @@ -2024,6 +2028,8 @@ STR16 pLongAssignmentStrings[] = L"Szerz propagandę", // spread propaganda L"Zbieraj plotki", // gather information L"Commanding Militia", // militia movement orders // TODO.Translate + L"Diagnose", // disease diagnosis + L"Treat Population disease", // treat disease among the population }; @@ -2136,6 +2142,7 @@ STR16 pAssignMenuStrings[] = { L"Służba", // merc is on active duty L"Lekarz", // the merc is acting as a doctor + L"Disease", // merc is a doctor doing diagnosis TODO.Translate L"Pacjent", // the merc is receiving medical attention L"Pojazd", // the merc is in a vehicle L"Naprawa", // the merc is repairing items @@ -3665,6 +3672,7 @@ STR16 pMapScreenBorderButtonHelpText[] = L"Pokaż przedmioty (|I)", L"Pokaż samoobronę i wrogów (|Z)", L"Show Mobile Militia |Restrictions", // HEADROCK HAM 4: Mobile Restrictions Button // TODO.Translate + L"Show Disease Data", // TODO.Translate }; STR16 pMapScreenInvenButtonHelpText[] = @@ -3898,6 +3906,7 @@ STR16 pTransactionText[] = L"Wykorzystanie Placówki", // HEADROCK HAM 3.6 L"Utrzymanie Samoobr.", // HEADROCK HAM 3.6 L"Ransom for released prisoners", // Flugente: prisoner system TODO.Translate + L"WHO data subscription", // Flugente: disease TODO.Translate }; STR16 pTransactionAlternateText[] = @@ -4338,6 +4347,7 @@ STR16 pBookMarkStrings[] = L"Briefing Room", L"Campaign History", // TODO.Translate L"MeLoDY", + L"WHO", }; STR16 pBookmarkTitle[] = @@ -4454,6 +4464,9 @@ STR16 pWebPagesTitles[] = L"Mercs Love or Dislike You - Analyze a team", L"Mercs Love or Dislike You - Pairwise comparison", L"Mercs Love or Dislike You - About us", + L"WHO - About WHO", + L"WHO - Disease in Arulco", + L"WHO - Helpful Tips", L"Bobby Ray's - Ostatnie dostawy", L"Encyclopedia", L"Encyclopedia - Dane", @@ -5514,6 +5527,9 @@ STR16 zMarksMapScreenText[] = // HEADROCK HAM 4: Prompt messages when turning on Mobile Militia Restrictions view. L"You currently have no Mobile Militia. Return to this view mode once you've recruited some.", L"This view shows where your Mobile Militia can and cannot go. GREY = Mobile Militia refuse to go here. RED = Mobile Militia can go here, but you've told them not to. YELLOW = Mobile Militia can enter this sector, but not leave. GREEN = Mobile Militia can go here freely. Right click a Green/Yellow sector to cycle its behavior.", + + // Flugente: disease texts describing what a map view does TODO.Translate + L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.", }; @@ -6247,6 +6263,7 @@ STR16 gzLaptopHelpText[] = L"Briefing Room", L"Campaign History", // TODO.Translate L"Mercenaries Love or Dislike You", // TODO.Translate + L"World Health Organization", }; @@ -7670,6 +7687,8 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|T|w|o|-|H|a|n|d|e|d", L"|B|l|o|c|k|s |I|r|o|n |S|i|g|h|t|s", L"|A|n|t|i|-|M|a|t|e|r|i|a|l |A|m|m|o", // TODO.Translate + L"|F|a|c|e |P|r|o|t|e|c|t|i|o|n", + L"|I|n|f|e|c|t|i|o|n |P|r|o|t|e|c|t|i|o|n", // 39 }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -7712,6 +7731,8 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nThis item requires both hands to be used.", L"\n \nThis item will block your iron sights\nso you cannot use them.", L"\n \nThis ammo can destroy light walls\nand various other objects.", // TODO.Translate + L"\n \nIf worn on your face, this will lower\nthe chance to be infected by other people.", + L"\n \nIf kept in your inventory, this will\nlower\nthe chance to be infected by other people.", }; STR16 szUDBAdvStatsTooltipText[]= @@ -8205,6 +8226,7 @@ STR16 szBackgroundText_Value[]= L" %s%d%% suppression resistance\n", L" %s%d%% physical resistance\n", L" %s%d%% alcohol resistance\n", + L" %s%d%% disease resistance\n", // TODO.Translate L" %s%d%% interrogation effectiveness\n", L" %s%d%% prison guard strength\n", @@ -8236,6 +8258,8 @@ STR16 szBackgroundText_Value[]= L" %s%d%% cth with firearms against creatures\n", L" %s%d%% insurance cost\n", L" %s%d%% effectiveness as spotter for fellow snipers\n", // TODO.Translate + L" %s%d%% effectiveness at diagnosing diseases\n", // TODO.Translate + L" %s%d%% effectiveness at treating population against diseases\n", L" dislikes some other backgrounds", // TODO.Translate }; @@ -8687,7 +8711,7 @@ STR16 szMercCompareEventText[]= L"%s mounted a gun on me", L"%s treated my wounds", - L"Had a good drink %s", + L"Had a good drink with %s", L"%s is fun to get wasted with", L"%s is annoying when drunk", @@ -8702,6 +8726,45 @@ STR16 szMercCompareEventText[]= L"%s puts people in their places", L"%s is way too impulsive", + L"%s is disease-ridden", + L"%s treated my diseases", +}; + +STR16 szWHOWebSite[] = +{ + // main page + L"World Health Organization", + L"Bringing health to life", + + // links to other pages + L"About WHO", + L"Disease in Arulco", + L"About diseases", + + // text on the main page + L"WHO is the directing and coordinating authority for health within the United Nations system.", + L"It is responsible for providing leadership on global health matters, shaping the health research agenda, setting norms and standards, articulating evidence-based policy options, providing technical support to countries and monitoring and assessing health trends.", + L"In the 21st century, health is a shared responsibility, involving equitable access to essential care and collective defence against transnational threats.", + + // contract page + L"The small country of Arulco is currently experiencing an outbreak of the deadly arulcan plague.", + L"Due to the catastrophic state of the state's health system, only the armies' medical corps is there to combat the deadly disease.", + L"With the country being of limits to UN affiliates, all we can currently do is provide detailed maps on the current status of infection in Arulco. Due to the difficulty in dealing with Arulco, we regret to have to ask for a daily fee of %d$ for anyone wishing to obtain these maps.", + L"Do you wish to acquire detailed data on the current status of diease in Arulco? You can access this data on the strategic map once aquired.", + L"You currently do not have access to WHO data on the arulcan plague.", + L"You have acquired detailed maps on the status of the disease.", + L"Subscribe to map updates", + L"Unsubscribe map updates", + + // helpful tips page + L"The arulcan plague is a deadly strain of the plague unique to the small country of Arulco. In a typical outbreak, the first victims get infected by a mosquito in a swamp or tropical sector. These first victims then inadvertently infect the population of nearby cities.", + L"You won't immediately notice when you are infected - it might take days for the symptoms to show.", + L"You can see the current effects of known diseases your mercs suffer from by hovering over their portrait in the strategic map.", + L"Most diseases get worse over time, be sure to assign a doctor as soon as possible.", + L"Some diseases can be treated with special medicine. You might find some in a well-equipped drugstore.", + L"Doctors can be ordered to check on all local teammates for diseases. You can find out about a disease before it breaks out!", + L"Doctors have a much higher chance to be infected when treating infected patients. Protective gear is very useful.", + L"If a blade weapon hits an infected person, the blade becomes infected, and can be used to spread the infection further.", }; STR16 szTacticalInventoryDialogString[]= @@ -8817,6 +8880,8 @@ STR16 szDynamicDialogueText_DOST_VICTIM_INITIATE[] = L"Alright alright. Jeez. I'm over it, okay?", L"Who do you think you are, $CAUSE$? No, I won't be quiet about this!", + L"Ewww! $CAUSE$ is sick! Get away from me, that looks disgusting!", + L"Thanks, $CAUSE$. I'm already feeling better.", }; STR16 szDynamicDialogueText_DOST_VICTIM_TO_INTERJECTOR_DENY[] = @@ -8904,6 +8969,8 @@ STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_DENY[] = L"Cut it, drama queen.", L"I'm the one who tells you to shut up! I'm your superior, $VICTIM$!", + L"Oh yeah? Back off, before I cough on you!", + L"How did you get that in the first place? Did you forget to wash your hands again?", }; STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_AGREE[] = @@ -8944,6 +9011,8 @@ STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_AGREE[] = L"As long as it does not happen again.", L"The two of us are going to have real problem soon, $VICTIM$.", + L"It really is. I... *cough* don't feel so well...", + L"No problem, we can't have you running around coughing blood, right? Riiight?", }; STR16 szDynamicDialogueText_DOST_CAUSE_TO_INTERJECTOR_DENY[] = @@ -9032,6 +9101,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_DIALOGUESELECTION[] = L"$VICTIM$ was reined in by $CAUSE$. What do you do?", L"$VICTIM$ did not take $CAUSE$'s words of action well. What do you do?", + L"$VICTIM$ is offended by $CAUSE$ diseases. What do you do?", + L"$VICTIM$ has treated $CAUSE$'s diseases. What do you do?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_DENY[] = @@ -9072,6 +9143,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_DENY[] = L"No reason to be so stiff about it.", L"Pfft. Don't make a fuss out of it.", + L"Stop behaving like a first grader. We need to get $CAUSE$ to a doctor!", + L"Where did you get that stuff from in the first place?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_AGREE[] = @@ -9112,6 +9185,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_AGREE[] = L"Yeah, keep it down, will ya?", L"Yeah, you won't boss us around anymore!", + L"This does look unhealthy. That better not be contagious!", + L"Great. Are you sure it's fully treated now?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_DENY[] = @@ -9152,6 +9227,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_DENY[] = L"Pah. You're the one making all the fuss about it...", L"You are certainly nobodies superior!", + L"Stop it! We don't need more of whatever it is you have!", + L"The important thing is that it's gone now... It is, right?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_AGREE[] = @@ -9192,6 +9269,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_AGREE[] = L"Yeah, drop that attitude, $VICTIM$.", L"Not sure about that, but yep!", + L"Yeah, there's nothing you can do against this stuff, right?", + L"I told you pople before... this country a dirty place, so beware of what you touch.", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_REASON[] = @@ -9232,6 +9311,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_REASON[] = L"Sigh. More of this?", L"Hey. Hey! Both of you, cut it out! What are you doing?", + L"The important thing is to get $CAUSE$ to a doctor, and to make sure $CAUSE_GENDER$ doesn't infect anybody else.", + L"We have to be careful. The army isn't the only thing that wants us dead.", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_AGGRESSIVE[] = @@ -9272,6 +9353,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_AGGRESSIVE[] = L"Sigh. More of this?", L"If anybody is superior here, then that's me... and I'm ordering you to stand down!", + L"Stop whining! $CAUSE$, get that treated, and the rest of you, back to business!", + L"Great. Everything done? Then let's get back to shooting stuff!", }; STR16 szDynamicDialogueText_DOST_SIDEWITH_VICTIM[] = @@ -9333,4 +9416,24 @@ STR16 szDynamicDialogueText_GenderText[] = L"her", }; +STR16 szDiseaseText[] = +{ + L" %s%d%% agility stat\n", + L" %s%d%% dexterity stat\n", + L" %s%d%% strength stat\n", + L" %s%d%% wisdom stat\n", + L" %s%d%% effective level\n", + + L" %s%d%% APs\n", + L" %s%d maximum breath\n", + L" %s%d%% strength to carry items\n", + L" %s%2.2f life regeneration/hour\n", + L" %s%d need for sleep\n", + L" %s%d%% water consumption\n", + L" %s%d%% food consumption\n", + + L"%s was diagnosed with %s!", + L"%s is cured of %s!", +}; + #endif //POLISH diff --git a/Utils/_RussianText.cpp b/Utils/_RussianText.cpp index 61029b0b..2ebb7900 100644 --- a/Utils/_RussianText.cpp +++ b/Utils/_RussianText.cpp @@ -1865,6 +1865,8 @@ STR16 pAssignmentStrings[] = L"Propag.", // spread propaganda L"Rumours", // gather information L"Command", // militia movement orders + L"Diagnose", // disease diagnosis //TODO.Translate + L"Treat D.", // treat disease among the population }; @@ -1961,6 +1963,8 @@ STR16 pPersonnelAssignmentStrings[] = L"Spreading Propaganda",// TODO.Translate // spread propaganda L"Gathering Rumours",// TODO.Translate // gather information L"Commanding Militia", // militia movement orders // TODO.Translate + L"Diagnose", // disease diagnosis + L"Treat Population disease", // treat disease among the population }; @@ -2016,6 +2020,8 @@ STR16 pLongAssignmentStrings[] = L"Spread Propaganda",// TODO.Translate // spread propaganda L"Gather Rumours",// TODO.Translate // gather information L"Commanding Militia", // militia movement orders // TODO.Translate + L"Diagnose", // disease diagnosis + L"Treat Population disease", // treat disease among the population }; @@ -2128,6 +2134,7 @@ STR16 pAssignMenuStrings[] = { L"На службе", // merc is on active duty L"Медик", // the merc is acting as a doctor + L"Disease", // merc is a doctor doing diagnosis TODO.Translate L"Пациент", // the merc is receiving medical attention L"Машина", // the merc is in a vehicle L"Ремонт", // the merc is repairing items @@ -3658,6 +3665,7 @@ STR16 pMapScreenBorderButtonHelpText[] = L"Вещи (|I)", L"Ополчение и враги (|Z)", L"Мобильные группы ополченцев (|R)", //HAM 4: Show Mobile Militia Restrictions + L"Show Disease Data", // TODO.Translate }; STR16 pMapScreenInvenButtonHelpText[] = @@ -3889,6 +3897,7 @@ STR16 pTransactionText[] = L"Оснащение персонала", // HEADROCK HAM 3.6 //Facility Use L"Содержание ополчения", // HEADROCK HAM 3.6 //Militia upkeep L"Выкуп за освобожденных заключенных", // Ransom for released prisoners + L"WHO data subscription", // Flugente: disease TODO.Translate }; STR16 pTransactionAlternateText[] = @@ -4329,6 +4338,7 @@ STR16 pBookMarkStrings[] = L"Briefing Room", L"Campaign History", // TODO.Translate L"MeLoDY", + L"WHO", }; STR16 pBookmarkTitle[] = @@ -4445,6 +4455,9 @@ STR16 pWebPagesTitles[] = L"Mercs Love or Dislike You - Analyze a team", L"Mercs Love or Dislike You - Pairwise comparison", L"Mercs Love or Dislike You - About us", + L"WHO - About WHO", + L"WHO - Disease in Arulco", + L"WHO - Helpful Tips", L"Бобби Рэй - последние поступления", L"Энциклопедия", L"Энциклопедия - данные", @@ -5505,7 +5518,10 @@ STR16 zMarksMapScreenText[] = L"Стратегическая Карта", // HEADROCK HAM 4: Prompt messages when turning on Mobile Militia Restrictions view. L"Сейчас у вас нет мобильных групп ополчения. Включите этот режим в следующий раз, когда наберёте их.", - L"Здесь показано куда ваши мобильные отряды могут пройти и куда нет. СЕРЫЙ = не пойдут туда. КРАСНЫЙ = могут пойти туда, но вы запретили им. ЖЁЛТЫЙ = могут вступить в сектор, но не могут его покинуть. ЗЕЛЁНЫЙ = могут свободно передвигаться. Правым щелчком кнопки мыши можно менять цветовой статус сектора.", + L"Здесь показано куда ваши мобильные отряды могут пройти и куда нет. СЕРЙ = не пойдут туда. КРАСНЫЙ = могут пойти туда, но вы запретили им. ЖЁЛТЫЙ = могут вступить в сектор, но не могут его покинуть. ЗЕЛЁНЫЙ = могут свободно передвигаться. Правым щелчком кнопки мыши можно менять цветовой статус сектора.", + + // Flugente: disease texts describing what a map view does TODO.Translate + L"This view shows in which sectors disease has broken out. The number indicates the mean magnitude of infection per person, the colour indicates how widespread it is. GREY= No disease known of. GREEN to RED = escalating levels of infection.", }; @@ -6234,6 +6250,7 @@ STR16 gzLaptopHelpText[] = L"Briefing Room", L"Campaign History", // TODO.Translate L"Mercenaries Love or Dislike You", // TODO.Translate + L"World Health Organization", }; @@ -7654,6 +7671,8 @@ STR16 szUDBGenSecondaryStatsTooltipText[]= L"|T|w|o|-|H|a|n|d|e|d", L"|B|l|o|c|k|s |I|r|o|n |S|i|g|h|t|s", L"|A|n|t|i|-|M|a|t|e|r|i|a|l |A|m|m|o", // TODO.Translate + L"|F|a|c|e |P|r|o|t|e|c|t|i|o|n", + L"|I|n|f|e|c|t|i|o|n |P|r|o|t|e|c|t|i|o|n", // 39 }; STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= @@ -7696,6 +7715,8 @@ STR16 szUDBGenSecondaryStatsExplanationsTooltipText[]= L"\n \nThis item requires both hands to be used.", L"\n \nThis item will block your iron sights\nso you cannot use them.", L"\n \nThis ammo can destroy light walls\nand various other objects.", // TODO.Translate + L"\n \nIf worn on your face, this will lower\nthe chance to be infected by other people.", + L"\n \nIf kept in your inventory, this will\nlower\nthe chance to be infected by other people.", }; STR16 szUDBAdvStatsTooltipText[]= @@ -8185,6 +8206,7 @@ STR16 szBackgroundText_Value[]= L" %s%d%% suppression resistance\n", L" %s%d%% physical resistance\n", L" %s%d%% alcohol resistance\n", + L" %s%d%% disease resistance\n", // TODO.Translate L" %s%d%% interrogation effectiveness\n", L" %s%d%% prison guard strength\n", @@ -8216,6 +8238,8 @@ STR16 szBackgroundText_Value[]= L" %s%d%% cth with firearms against creatures\n", L" %s%d%% insurance cost\n", L" %s%d%% effectiveness as spotter for fellow snipers\n", // TODO.Translate + L" %s%d%% effectiveness at diagnosing diseases\n", // TODO.Translate + L" %s%d%% effectiveness at treating population against diseases\n", L" dislikes some other backgrounds", // TODO.Translate }; @@ -8667,7 +8691,7 @@ STR16 szMercCompareEventText[]= L"%s mounted a gun on me", L"%s treated my wounds", - L"Had a good drink %s", + L"Had a good drink with %s", L"%s is fun to get wasted with", L"%s is annoying when drunk", @@ -8682,6 +8706,45 @@ STR16 szMercCompareEventText[]= L"%s puts people in their places", L"%s is way too impulsive", + L"%s is disease-ridden", + L"%s treated my diseases", +}; + +STR16 szWHOWebSite[] = +{ + // main page + L"World Health Organization", + L"Bringing health to life", + + // links to other pages + L"About WHO", + L"Disease in Arulco", + L"About diseases", + + // text on the main page + L"WHO is the directing and coordinating authority for health within the United Nations system.", + L"It is responsible for providing leadership on global health matters, shaping the health research agenda, setting norms and standards, articulating evidence-based policy options, providing technical support to countries and monitoring and assessing health trends.", + L"In the 21st century, health is a shared responsibility, involving equitable access to essential care and collective defence against transnational threats.", + + // contract page + L"The small country of Arulco is currently experiencing an outbreak of the deadly arulcan plague.", + L"Due to the catastrophic state of the state's health system, only the armies' medical corps is there to combat the deadly disease.", + L"With the country being of limits to UN affiliates, all we can currently do is provide detailed maps on the current status of infection in Arulco. Due to the difficulty in dealing with Arulco, we regret to have to ask for a daily fee of %d$ for anyone wishing to obtain these maps.", + L"Do you wish to acquire detailed data on the current status of diease in Arulco? You can access this data on the strategic map once aquired.", + L"You currently do not have access to WHO data on the arulcan plague.", + L"You have acquired detailed maps on the status of the disease.", + L"Subscribe to map updates", + L"Unsubscribe map updates", + + // helpful tips page + L"The arulcan plague is a deadly strain of the plague unique to the small country of Arulco. In a typical outbreak, the first victims get infected by a mosquito in a swamp or tropical sector. These first victims then inadvertently infect the population of nearby cities.", + L"You won't immediately notice when you are infected - it might take days for the symptoms to show.", + L"You can see the current effects of known diseases your mercs suffer from by hovering over their portrait in the strategic map.", + L"Most diseases get worse over time, be sure to assign a doctor as soon as possible.", + L"Some diseases can be treated with special medicine. You might find some in a well-equipped drugstore.", + L"Doctors can be ordered to check on all local teammates for diseases. You can find out about a disease before it breaks out!", + L"Doctors have a much higher chance to be infected when treating infected patients. Protective gear is very useful.", + L"If a blade weapon hits an infected person, the blade becomes infected, and can be used to spread the infection further.", }; STR16 szTacticalInventoryDialogString[]= @@ -8797,6 +8860,8 @@ STR16 szDynamicDialogueText_DOST_VICTIM_INITIATE[] = L"Alright alright. Jeez. I'm over it, okay?", L"Who do you think you are, $CAUSE$? No, I won't be quiet about this!", + L"Ewww! $CAUSE$ is sick! Get away from me, that looks disgusting!", + L"Thanks, $CAUSE$. I'm already feeling better.", }; STR16 szDynamicDialogueText_DOST_VICTIM_TO_INTERJECTOR_DENY[] = @@ -8884,6 +8949,8 @@ STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_DENY[] = L"Cut it, drama queen.", L"I'm the one who tells you to shut up! I'm your superior, $VICTIM$!", + L"Oh yeah? Back off, before I cough on you!", + L"How did you get that in the first place? Did you forget to wash your hands again?", }; STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_AGREE[] = @@ -8924,6 +8991,8 @@ STR16 szDynamicDialogueText_DOST_CAUSE_TO_VICTIM_AGREE[] = L"As long as it does not happen again.", L"The two of us are going to have real problem soon, $VICTIM$.", + L"It really is. I... *cough* don't feel so well...", + L"No problem, we can't have you running around coughing blood, right? Riiight?", }; STR16 szDynamicDialogueText_DOST_CAUSE_TO_INTERJECTOR_DENY[] = @@ -9012,6 +9081,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_DIALOGUESELECTION[] = L"$VICTIM$ was reined in by $CAUSE$. What do you do?", L"$VICTIM$ did not take $CAUSE$'s words of action well. What do you do?", + L"$VICTIM$ is offended by $CAUSE$ diseases. What do you do?", + L"$VICTIM$ has treated $CAUSE$'s diseases. What do you do?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_DENY[] = @@ -9052,6 +9123,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_DENY[] = L"No reason to be so stiff about it.", L"Pfft. Don't make a fuss out of it.", + L"Stop behaving like a first grader. We need to get $CAUSE$ to a doctor!", + L"Where did you get that stuff from in the first place?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_AGREE[] = @@ -9092,6 +9165,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_VICTIM_AGREE[] = L"Yeah, keep it down, will ya?", L"Yeah, you won't boss us around anymore!", + L"This does look unhealthy. That better not be contagious!", + L"Great. Are you sure it's fully treated now?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_DENY[] = @@ -9132,6 +9207,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_DENY[] = L"Pah. You're the one making all the fuss about it...", L"You are certainly nobodies superior!", + L"Stop it! We don't need more of whatever it is you have!", + L"The important thing is that it's gone now... It is, right?", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_AGREE[] = @@ -9172,6 +9249,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_TO_CAUSE_AGREE[] = L"Yeah, drop that attitude, $VICTIM$.", L"Not sure about that, but yep!", + L"Yeah, there's nothing you can do against this stuff, right?", + L"I told you pople before... this country a dirty place, so beware of what you touch.", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_REASON[] = @@ -9212,6 +9291,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_REASON[] = L"Sigh. More of this?", L"Hey. Hey! Both of you, cut it out! What are you doing?", + L"The important thing is to get $CAUSE$ to a doctor, and to make sure $CAUSE_GENDER$ doesn't infect anybody else.", + L"We have to be careful. The army isn't the only thing that wants us dead.", }; STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_AGGRESSIVE[] = @@ -9252,6 +9333,8 @@ STR16 szDynamicDialogueText_DOST_INTERJECTOR_SOLVE_AGGRESSIVE[] = L"Sigh. More of this?", L"If anybody is superior here, then that's me... and I'm ordering you to stand down!", + L"Stop whining! $CAUSE$, get that treated, and the rest of you, back to business!", + L"Great. Everything done? Then let's get back to shooting stuff!", }; STR16 szDynamicDialogueText_DOST_SIDEWITH_VICTIM[] = @@ -9313,4 +9396,24 @@ STR16 szDynamicDialogueText_GenderText[] = L"her", }; +STR16 szDiseaseText[] = +{ + L" %s%d%% agility stat\n", + L" %s%d%% dexterity stat\n", + L" %s%d%% strength stat\n", + L" %s%d%% wisdom stat\n", + L" %s%d%% effective level\n", + + L" %s%d%% APs\n", + L" %s%d maximum breath\n", + L" %s%d%% strength to carry items\n", + L" %s%2.2f life regeneration/hour\n", + L" %s%d need for sleep\n", + L" %s%d%% water consumption\n", + L" %s%d%% food consumption\n", + + L"%s was diagnosed with %s!", + L"%s is cured of %s!", +}; + #endif //RUSSIAN