diff --git a/GameSettings.cpp b/GameSettings.cpp index 5d2ea0f3..c0d50323 100644 --- a/GameSettings.cpp +++ b/GameSettings.cpp @@ -904,6 +904,7 @@ void LoadGameExternalOptions() gGameExternalOptions.giCivilianTurnSpeedUpFactor = iniReader.ReadFloat("Graphics Settings","CIVILIAN_TURN_SPEED_UP_FACTOR",1.0, 0, 1.0); gGameExternalOptions.gfUseExternalLoadscreens = iniReader.ReadBoolean("Graphics Settings","USE_EXTERNALIZED_LOADSCREENS", FALSE); + gGameExternalOptions.gfUseLoadScreenHints = iniReader.ReadBoolean("Graphics Settings","USE_LOADSCREENHINTS", TRUE); //tais: enable/disable New Starting Gear Interface (0 = disabled, classic style; 1 = enabled, new 21 item view and up to 5 gearkit selection) gGameExternalOptions.gfUseNewStartingGearInterface = iniReader.ReadBoolean("Graphics Settings","USE_NEW_STARTING_GEAR_INTERFACE", FALSE); diff --git a/GameSettings.h b/GameSettings.h index dd04b37f..3f903313 100644 --- a/GameSettings.h +++ b/GameSettings.h @@ -622,6 +622,7 @@ typedef struct INT32 ubEnemiesItemDrop; BOOLEAN gfUseExternalLoadscreens; + BOOLEAN gfUseLoadScreenHints; // added by Flugente //tais: nsgi BOOLEAN gfUseNewStartingGearInterface; diff --git a/Init.cpp b/Init.cpp index 2df6a923..33a91c80 100644 --- a/Init.cpp +++ b/Init.cpp @@ -384,6 +384,10 @@ BOOLEAN LoadExternalGameplayData(STR directoryName) strcat(fileName, SQUADNAMEFILENAME); SGP_THROW_IFFALSE(ReadInSquadNamesStats(fileName),SQUADNAMEFILENAME); + strcpy(fileName, directoryName); + strcat(fileName, LOADSCREENHINTSFILENAME); + SGP_THROW_IFFALSE(ReadInLoadScreenHints(fileName),LOADSCREENHINTSFILENAME); + strcpy(fileName, directoryName); strcat(fileName, ARMOURSFILENAME); SGP_THROW_IFFALSE(ReadInArmourStats(fileName),ARMOURSFILENAME); diff --git a/Tactical/Food.cpp b/Tactical/Food.cpp index 4134f957..5202fba1 100644 --- a/Tactical/Food.cpp +++ b/Tactical/Food.cpp @@ -535,8 +535,8 @@ void HourlyFoodAutoDigestion( SOLDIERTYPE *pSoldier ) // if we're a prisoner, we can't feed ourself, and the player can't do that either. Instead the army provides food (not much and of bad quality) if (pSoldier->bAssignment == ASSIGNMENT_POW) { - INT16 powwater = gGameExternalOptions.usFoodDigestionHourlyBaseDrink * FOOD_POW_MULTIPLICATOR; - INT16 powfoodadd = powwater * gGameExternalOptions.usFoodDigestionHourlyBaseFood / gGameExternalOptions.usFoodDigestionHourlyBaseDrink; + INT16 powwater = gGameExternalOptions.usFoodDigestionHourlyBaseDrink * gGameExternalOptions.sFoodDigestionAssignment * FOOD_POW_MULTIPLICATOR; + INT16 powfoodadd = powwater * gGameExternalOptions.usFoodDigestionHourlyBaseFood / max(1, gGameExternalOptions.usFoodDigestionHourlyBaseDrink); // if we're thirsty or hungry, and this is nutritious, consume it if ( pSoldier->bDrinkLevel < FoodMoraleMods[FOOD_VERY_LOW].bThreshold ) diff --git a/Tactical/Tactical_VS2005.vcproj b/Tactical/Tactical_VS2005.vcproj index e743092e..2b361a0b 100644 --- a/Tactical/Tactical_VS2005.vcproj +++ b/Tactical/Tactical_VS2005.vcproj @@ -1112,6 +1112,10 @@ RelativePath=".\XML_LoadBearingEquipment.cpp" > + + diff --git a/Tactical/Tactical_VS2008.vcproj b/Tactical/Tactical_VS2008.vcproj index 98cd2218..13aefa38 100644 --- a/Tactical/Tactical_VS2008.vcproj +++ b/Tactical/Tactical_VS2008.vcproj @@ -1113,6 +1113,9 @@ + + diff --git a/Tactical/Tactical_VS2010.vcxproj.filters b/Tactical/Tactical_VS2010.vcxproj.filters index 14521817..5534d926 100644 --- a/Tactical/Tactical_VS2010.vcxproj.filters +++ b/Tactical/Tactical_VS2010.vcxproj.filters @@ -638,5 +638,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/Tactical/XML.h b/Tactical/XML.h index 56eddb3a..b2b0cff1 100644 --- a/Tactical/XML.h +++ b/Tactical/XML.h @@ -218,6 +218,7 @@ typedef PARSE_STAGE; #define MERCAVAILABILITY "MercAvailability.xml" #define MERCOPINIONSFILENAME "MercOpinions.xml" #define MERCPROFILESFILENAME "MercProfiles.xml" +#define LOADSCREENHINTSFILENAME "LoadScreenHints.xml" #ifdef JA2UB #define MERCPROFILESFILENAME25 "MercProfiles25.xml" @@ -302,6 +303,10 @@ extern BOOLEAN WriteRandomItemStats(); extern BOOLEAN ReadInSquadNamesStats(STR fileName); extern BOOLEAN WriteSquadNamesStats(); +// Flugente: loadscreen hints +extern BOOLEAN ReadInLoadScreenHints(STR fileName); +extern BOOLEAN WriteLoadScreenHints(); + extern BOOLEAN ReadInAmmoStats(STR fileName); extern BOOLEAN WriteAmmoStats(); diff --git a/TileEngine/worlddef.cpp b/TileEngine/worlddef.cpp index a1e36190..87f26158 100644 --- a/TileEngine/worlddef.cpp +++ b/TileEngine/worlddef.cpp @@ -2843,6 +2843,9 @@ BOOLEAN LoadWorld(const STR8 puiFilename, FLOAT* pMajorMapVersion, UINT8* pMinor gfBasement = FALSE; gfCaves = FALSE; + // Flugente: select loadscreen hint + SetNewLoadScreenHint(); + SetRelativeStartAndEndPercentage(0, 0, 1, L"Trashing world..."); #ifdef JA2TESTVERSION uiStartTime = GetJA2Clock(); diff --git a/Utils/Animated ProgressBar.cpp b/Utils/Animated ProgressBar.cpp index 99024c13..025bbc21 100644 --- a/Utils/Animated ProgressBar.cpp +++ b/Utils/Animated ProgressBar.cpp @@ -12,7 +12,8 @@ #include "music control.h" #include "Timer Control.h" #include "sysutil.h" -#include "math.h" + #include "random.h" + #include "math.h" #endif double rStart, rEnd; @@ -218,6 +219,52 @@ void RemoveProgressBar( UINT8 ubID ) } } +// Flugente: stuff needed for loadscreen hints +extern UINT16 num_found_loadscreenhints; +static UINT16 usCurrentLoadScreenHint = 0; + +// Flugente: this function selects the next hint to display, and makes sure it is not played again during this run of the exe +void SetNewLoadScreenHint() +{ + if ( !gGameExternalOptions.gfUseLoadScreenHints ) + return; + + UINT16 lastfnd = 0; + UINT8 possiblehints[LOADSCREENHINT_MAX]; + + for(UINT32 cnt = 1; cnt <= num_found_loadscreenhints; ++cnt) + { + if ( !zLoadScreenHint[cnt].fAlreadyShown ) + { + // we now check the flags of a hint to determine wether it can show up. It can if at least one flag is valid + BOOLEAN fShow = FALSE; + // still unsure how to check for these... + if ( zLoadScreenHint[cnt].usFlags & (LOADSCREEN_LORE|LOADSCREEN_WEAPON|LOADSCREEN_ITEM|LOADSCREEN_KEYBIND) ) + fShow = TRUE; + else if ( zLoadScreenHint[cnt].usFlags & LOADSCREEN_FOOD && gGameOptions.fFoodSystem ) + fShow = TRUE; +#ifdef ENABLE_ZOMBIES + else if ( zLoadScreenHint[cnt].usFlags & LOADSCREEN_ZOMBIE && gGameSettings.fOptions[TOPTION_ZOMBIES] ) + fShow = TRUE; +#endif + else if ( zLoadScreenHint[cnt].usFlags & LOADSCREEN_OVERHEAT_DIRT && (gGameOptions.fWeaponOverheating || gGameExternalOptions.fDirtSystem) ) + fShow = TRUE; + else if ( zLoadScreenHint[cnt].usFlags & LOADSCREEN_NCTH && UsingNewCTHSystem() ) + fShow = TRUE; + else if ( zLoadScreenHint[cnt].usFlags & LOADSCREEN_COVERTOPS && gGameOptions.fNewTraitSystem ) + fShow = TRUE; + + if ( fShow ) + possiblehints[lastfnd++] = cnt; + } + } + + UINT16 sel = possiblehints[ Random(lastfnd) ]; + zLoadScreenHint[sel].fAlreadyShown = TRUE; + + usCurrentLoadScreenHint = sel; +} + //An important setup function. The best explanation is through example. The example being the loading //of a file -- there are many stages of the map loading. In JA2, the first step is to load the tileset. //Because it is a large chunk of the total loading of the map, we may gauge that it takes up 30% of the @@ -282,6 +329,13 @@ void SetRelativeStartAndEndPercentage( UINT8 ubID, UINT16 uiRelStartPerc, UINT16 SetFontShadow( pCurr->ubMsgFontShadowColor ); SetFontBackground( 0 ); mprintf( pCurr->usBarLeft, pCurr->usBarBottom + 3, str ); + + // Flugente: loadscreen hints + if ( usCurrentLoadScreenHint ) + { + gprintfinvalidate( pCurr->usBarLeft, pCurr->usBarBottom + 3 - 200, L"%s", zLoadScreenHint[usCurrentLoadScreenHint].szName ); + mprintf( pCurr->usBarLeft, pCurr->usBarBottom + 3 - 200, L"%s", zLoadScreenHint[usCurrentLoadScreenHint].szName ); + } } } } diff --git a/Utils/Animated ProgressBar.h b/Utils/Animated ProgressBar.h index 1101076d..436cee8d 100644 --- a/Utils/Animated ProgressBar.h +++ b/Utils/Animated ProgressBar.h @@ -31,6 +31,64 @@ typedef struct PROGRESSBAR extern PROGRESSBAR *pBar[ MAX_PROGRESSBARS ]; +// Flugente: a structure for clothing items +typedef struct +{ + UINT16 uiIndex; + CHAR16 szName[256]; // name of these clothes + UINT32 usFlags; // flags that can be used to determine wether a hint is currently appropriate + BOOLEAN fAlreadyShown; // to remember if this hint has already been shown in this game (reset on starting exe) +} LOADSCREENHINT_STRUCT; + +#define LOADSCREENHINT_MAX 200 + +extern LOADSCREENHINT_STRUCT zLoadScreenHint[LOADSCREENHINT_MAX]; + +// Flugente: this function selects the next hint to display, and makes sure it is not played again during this run of the exe +void SetNewLoadScreenHint(); + +// -------- added by Flugente: various flags for loadscreen hints-------- +// easier than adding 32 differently named variables. DO NOT CHANGE THEM, UNLESS YOU KNOW WHAT YOU ARE DOING!!! +#define LOADSCREEN_LORE 0x00000001 //1 // ingame history and background +#define LOADSCREEN_WEAPON 0x00000002 //2 // tips on weapons +#define LOADSCREEN_ITEM 0x00000004 //4 // general tip on items +#define LOADSCREEN_KEYBIND 0x00000008 //8 // tip on new key commands + +#define LOADSCREEN_FOOD 0x00000010 //16 // food tips +#define LOADSCREEN_ZOMBIE 0x00000020 //32 // zombie tips +#define LOADSCREEN_OVERHEAT_DIRT 0x00000040 //64 // tips on overheating & dirt +#define LOADSCREEN_NCTH 0x00000080 //128 // tips on using NCTH + +#define LOADSCREEN_COVERTOPS 0x00000100 //256 // tips on using the covert ops trait +//#define SOLDIER_HEADSHOT 0x00000200 //512 // last hit received was a headshot (attack to the head, so knifes/punches also work) +//#define SOLDIER_POW 0x00000400 //1024 // we are a prisoner of war +//#define SOLDIER_ASSASSIN 0x00000800 //2048 // we are an enemy assassin, and thus we will behave very different from normal enemies + +//#define SOLDIER_POW_PRISON 0x00001000 //4096 // this guy is a prisoner of war in a prison sector. SOLDIER_POW refers to people we capture, this refers to people we hold captive +//#define SOLDIER_EQUIPMENT_DROPPED 0x00002000 //8192 // under certain circumstances, militia can be ordered to drop their gear twice. Thus we set a marker to avoid that +//#define ENEMY_NET_3_LVL_4 0x00004000 //16384 +/*#define WH40K_SOLDIER_BLANK 0x00008000 //32768 // we are a blank, the ultimate weapon against psykers and daemons + +#define WH40K_SOLDIER_IDENTIFIED_BLANK 0x00010000 //65536 // we are a blank, and the player has learned this (used for laptop display) +#define WH40K_SOLDIER_DEMON_DAMMALUS_ACTIVE 0x00020000 //131072 // demon disability: damage malus is active +#define WH40K_SOLDIER_DEMON_LINKEDBULLETS 0x00040000 //262144 // demon dual wield: our first bullet hit, thus we get a huge bonus to the second bullet +#define WH40K_SOLDIER_OBLITERATOR 0x00080000 //524288 // soldier has the obliterator virus + +#define WH40K_SOLDIER_ADEPTA_PRAYER_DAMAGE 0x00100000 //1048576 +#define WH40K_SOLDIER_ADEPTA_PRAYER_CTH 0x00200000 //2097152 +#define WH40K_SOLDIER_ADEPTA_PRAYER_SUPPRESSION 0x00400000 //4194304 +#define WH40K_SOLDIER_ADEPTA_PRAYER_ENERGYREGEN 0x00800000 //8388608 + +#define WH40K_SOLDIER_TIMEBUBBLEEFFECT 0x01000000 //16777216 +#define WH40K_SOLDIER_VOX_OPERATOR_LISTENING 0x02000000 //33554432 +#define WH40K_SOLDIER_VOX_OPERATOR_JAMMING 0x04000000 //67108864 +#define WH40K_SOLDIER_VOX_OPERATOR_SCANNING 0x08000000 //134217728 + +#define WH40K_SOLDIER_COMMISSAR_MILITIA_KILL_BONUS 0x10000000 //268435456 // guardsmen under our command killed a heretic. This grants a bonus to our next hit with one-handed weapons +#define WH40K_SOLDIER_ADEPTA_PRAYER_REDUCEDAMAGE 0x20000000 //536870912 // reduce damage taken by 2 +#define WH40K_SOLDIER_ILLUSION 0x40000000 //1073741824 // Soldier is an Illusion +#define WH40K_SOLDIER_KILLSTREAK 0x80000000 //2147483648 // Soldier is on a kill streak*/ + void CreateLoadingScreenProgressBar(); void RemoveLoadingScreenProgressBar();