Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Core/GameEngine/Include/Common/MessageStream.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ class GameMessage : public MemoryPoolObject
MSG_META_TOGGLE_LOWER_DETAILS, ///< toggles graphics options to crappy mode instantly
MSG_META_TOGGLE_CONTROL_BAR, ///< show/hide controlbar
MSG_META_TOGGLE_PLAYER_OBSERVER, ///< TheSuperHackers @feature Toggle the player observer view in game
MSG_META_CYCLE_HEALTH_BAR_MODE, ///< TheSuperHackers @feature Cycle HealthBarDisplayMode in game

MSG_META_BEGIN_PATH_BUILD, ///< enter path-building mode
MSG_META_END_PATH_BUILD, ///< exit path-building mode
Expand Down
15 changes: 15 additions & 0 deletions Core/GameEngine/Include/Common/OptionPreferences.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@
typedef UnsignedInt CursorCaptureMode;
typedef UnsignedInt ScreenEdgeScrollMode;

// TheSuperHackers @feature When health bars are shown above objects. Purely a client side
// display preference -- it never affects game logic, so it is safe in multiplayer and replays.
enum HealthBarDisplayMode CPP_11(: Int)
{
HealthBarDisplayMode_Classic = 0, ///< selected and moused over objects only (retail behavior)
HealthBarDisplayMode_Damaged, ///< the above, plus anything that is not at full health
HealthBarDisplayMode_Always, ///< the above, plus every undamaged unit and structure

HealthBarDisplayMode_Count,
HealthBarDisplayMode_Default = HealthBarDisplayMode_Classic
};

//-----------------------------------------------------------------------------
// OptionsPreferences options menu class
//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -71,6 +83,9 @@ class OptionPreferences : public UserPreferences
Bool getAlternateMouseModeEnabled();
Bool getRightMouseScrollWithAlternateMouseEnabled() const;
Bool getRetaliationModeEnabled();
HealthBarDisplayMode getHealthBarDisplayMode() const;
Bool getNumericalHealthEnabled() const;
Bool getSmartPipsEnabled() const;
Bool getDoubleClickAttackMoveEnabled();
Int getJpegQuality() const;
Real getScrollFactor();
Expand Down
1 change: 1 addition & 0 deletions Core/GameEngine/Source/Common/MessageStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,7 @@ const char *GameMessage::getCommandTypeAsString(GameMessage::Type t)
CASE_LABEL(MSG_META_TOGGLE_LOWER_DETAILS)
CASE_LABEL(MSG_META_TOGGLE_CONTROL_BAR)
CASE_LABEL(MSG_META_TOGGLE_PLAYER_OBSERVER)
CASE_LABEL(MSG_META_CYCLE_HEALTH_BAR_MODE)
CASE_LABEL(MSG_META_BEGIN_PATH_BUILD)
CASE_LABEL(MSG_META_END_PATH_BUILD)
CASE_LABEL(MSG_META_BEGIN_FORCEATTACK)
Expand Down
53 changes: 53 additions & 0 deletions Core/GameEngine/Source/Common/OptionPreferences.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,59 @@ Bool OptionPreferences::getRightMouseScrollWithAlternateMouseEnabled() const
return FALSE;
}

// TheSuperHackers @feature Health bar display mode, read from Options.ini as
// HealthBarDisplayMode = Classic | Damaged | Always (a plain index also works).
HealthBarDisplayMode OptionPreferences::getHealthBarDisplayMode() const
{
OptionPreferences::const_iterator it = find("HealthBarDisplayMode");
if (it == end())
return HealthBarDisplayMode_Default;

if (stricmp(it->second.str(), "Always") == 0)
return HealthBarDisplayMode_Always;
if (stricmp(it->second.str(), "Damaged") == 0)
return HealthBarDisplayMode_Damaged;
if (stricmp(it->second.str(), "Classic") == 0)
return HealthBarDisplayMode_Classic;

// also accept the raw index, so the value round trips if it is ever written numerically
Int mode = atoi(it->second.str());
if (mode >= 0 && mode < HealthBarDisplayMode_Count)
return (HealthBarDisplayMode)mode;

return HealthBarDisplayMode_Default;
}

// TheSuperHackers @feature Options.ini: NumericalHealth = Yes prints the hit points beside the
// health bar. Follows HealthBarDisplayMode, so the number appears exactly where a bar does.
Bool OptionPreferences::getNumericalHealthEnabled() const
{
OptionPreferences::const_iterator it = find("NumericalHealth");
if (it == end())
return FALSE;

if (stricmp(it->second.str(), "yes") == 0) {
return TRUE;
}
return FALSE;
}

// TheSuperHackers @feature Options.ini: SmartPips = Yes keeps ammo and passenger pips on screen
// instead of showing them only while the unit is selected or moused over. Own units only -- not
// allies, not enemies. Nothing is drawn when there is nothing to report: no shots left, or no
// one aboard. So the pips read as "still loaded" and "carrying someone" at a glance.
Bool OptionPreferences::getSmartPipsEnabled() const
{
OptionPreferences::const_iterator it = find("SmartPips");
if (it == end())
return FALSE;

if (stricmp(it->second.str(), "yes") == 0) {
return TRUE;
}
return FALSE;
}

Bool OptionPreferences::getRetaliationModeEnabled()
{
OptionPreferences::const_iterator it = find("Retaliation");
Expand Down
40 changes: 40 additions & 0 deletions Core/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@
#include "GameClient/GameClient.h"
#include "GameClient/GameWindowManager.h"
#include "GameClient/GameText.h"
// TheSuperHackers @feature for the health bar display mode cycle
#include "Common/OptionPreferences.h"
#include "GameClient/ParticleSys.h"
#include "GameClient/GUICallbacks.h"
#include "GameClient/Shell.h"
Expand Down Expand Up @@ -3455,6 +3457,44 @@ GameMessageDisposition CommandTranslator::translateGameMessage(const GameMessage
break;
}

//-----------------------------------------------------------------------------------------
#if RTS_ZEROHOUR
// TheSuperHackers @feature Cycle the health bar display mode in game, so the player can
// switch between Classic, Damaged and Always without leaving to edit Options.ini. Purely a
// client side display setting -- nothing here reaches the simulation, so it is safe in
// multiplayer and replays. The change is not written back to Options.ini, so it lasts for
// the session only and the configured mode returns next launch.
case GameMessage::MSG_META_CYCLE_HEALTH_BAR_MODE:
{
if( TheWritableGlobalData )
{
Int mode = TheGlobalData->m_healthBarDisplayMode + 1;
if( mode >= HealthBarDisplayMode_Count || mode < 0 )
mode = HealthBarDisplayMode_Classic;

TheWritableGlobalData->m_healthBarDisplayMode = mode;

switch( mode )
{
case HealthBarDisplayMode_Damaged:
TheInGameUI->messageNoFormat( TheGameText->FETCH_OR_SUBSTITUTE(
"GUI:HealthBarModeDamaged", L"Health bars: damaged only" ) );
break;
case HealthBarDisplayMode_Always:
TheInGameUI->messageNoFormat( TheGameText->FETCH_OR_SUBSTITUTE(
"GUI:HealthBarModeAlways", L"Health bars: always" ) );
break;
default:
TheInGameUI->messageNoFormat( TheGameText->FETCH_OR_SUBSTITUTE(
"GUI:HealthBarModeClassic", L"Health bars: classic" ) );
break;
}
}
disp = DESTROY_MESSAGE;
break;
}
#endif // RTS_ZEROHOUR

//-----------------------------------------------------------------------------------------
case GameMessage::MSG_META_TOGGLE_ATTACKMOVE:
TheInGameUI->toggleAttackMoveToMode();
Expand Down
18 changes: 18 additions & 0 deletions Core/GameEngine/Source/GameClient/MessageStream/MetaEvent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ static const LookupListRec GameMessageMetaTypeNames[] =
{ "TOGGLE_LOWER_DETAILS", GameMessage::MSG_META_TOGGLE_LOWER_DETAILS },
{ "TOGGLE_CONTROL_BAR", GameMessage::MSG_META_TOGGLE_CONTROL_BAR },
{ "TOGGLE_PLAYER_OBSERVER", GameMessage::MSG_META_TOGGLE_PLAYER_OBSERVER },
{ "CYCLE_HEALTH_BAR_MODE", GameMessage::MSG_META_CYCLE_HEALTH_BAR_MODE },
{ "BEGIN_PATH_BUILD", GameMessage::MSG_META_BEGIN_PATH_BUILD },
{ "END_PATH_BUILD", GameMessage::MSG_META_END_PATH_BUILD },
{ "BEGIN_FORCEATTACK", GameMessage::MSG_META_BEGIN_FORCEATTACK },
Expand Down Expand Up @@ -860,6 +861,23 @@ void MetaMap::generateMetaMap()
map->m_usableIn = COMMANDUSABLE_OBSERVER;
}
}
#if RTS_ZEROHOUR
{
// TheSuperHackers @feature Cycle the health bar display mode. Ctrl+` is unbound in
// retail and in the debug and demo command maps, so this takes a key nothing else wants.
// Note the tick key is layout dependent -- it is ` on a US keyboard but prints something
// else elsewhere -- however the binding is by scancode, so the same physical key works.
MetaMapRec *map = TheMetaMap->getMetaMapRec(GameMessage::MSG_META_CYCLE_HEALTH_BAR_MODE);
if (map->m_key == MK_NONE)
{
map->m_key = MK_TICK;
map->m_transition = DOWN;
map->m_modState = CTRL;
// in game and while observing, but not in the menus, where health bars mean nothing
map->m_usableIn = (CommandUsableInType)(COMMANDUSABLE_GAME | COMMANDUSABLE_OBSERVER);
}
}
#endif // RTS_ZEROHOUR
{
// Is mostly useful for Generals.
MetaMapRec *map = getMetaMapRec(GameMessage::MSG_META_TOGGLE_FAST_FORWARD_REPLAY);
Expand Down
9 changes: 9 additions & 0 deletions GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,15 @@ class GlobalData : public SubsystemInterface
Bool m_useAlternateMouse;
Bool m_useRightMouseScrollWithAlternateMouse; // TheSuperHackers @feature User option for RMB scroll in Alternate Mouse mode.
Bool m_clientRetaliationModeEnabled;
// TheSuperHackers @feature Client side health bar display preference, from Options.ini.
// Holds a HealthBarDisplayMode; stored as Int so this widely included header does not
// have to pull in OptionPreferences.h.
Int m_healthBarDisplayMode;
// TheSuperHackers @feature Print hit points beside the health bar.
Bool m_numericalHealth;
// TheSuperHackers @feature Keep ammo and passenger pips on screen when there is something
// to report, rather than only on selection or hover.
Bool m_smartPips;
Bool m_doubleClickAttackMove;
Bool m_rightMouseAlwaysScrolls;
Int m_jpegQuality; // TheSuperHackers @feature Quality for JPEG screenshots.
Expand Down
5 changes: 5 additions & 0 deletions GeneralsMD/Code/GameEngine/Include/GameClient/Drawable.h
Original file line number Diff line number Diff line change
Expand Up @@ -739,6 +739,8 @@ class Drawable : public Thing,
//Perhaps we can move this out of Drawable???
public:
static void killStaticImages();
// TheSuperHackers @feature Free shared display strings before the manager is destroyed.
static void killStaticDisplayStrings();

#ifdef DIRTY_CONDITION_FLAGS
// only for StDrawableDirtyStuffLocker!
Expand All @@ -755,6 +757,9 @@ class Drawable : public Thing,
void drawConstructPercent( const IRegion2D *healthBarRegion ); ///< display % construction complete
void drawCaption( const IRegion2D *healthBarRegion ); ///< draw caption
void drawAmmo( const IRegion2D *healthBarRegion ); ///< draw icons
// TheSuperHackers @feature hit points beside the bar (Options.ini: NumericalHealth)
void drawNumericalHealth( const IRegion2D *healthBarRegion, Real health, Real maxHealth,
Color color );
void drawContained( const IRegion2D *healthBarRegion ); ///< draw icons
void drawVeterancy( const IRegion2D *healthBarRegion ); ///< draw veterency information

Expand Down
7 changes: 7 additions & 0 deletions GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1063,6 +1063,10 @@ GlobalData::GlobalData()
#endif
m_clientRetaliationModeEnabled = TRUE; //On by default.
m_doubleClickAttackMove = FALSE;
// TheSuperHackers @feature Health bars behave exactly as they always have unless Options.ini says otherwise.
m_healthBarDisplayMode = HealthBarDisplayMode_Default;
m_numericalHealth = FALSE;
m_smartPips = FALSE;

}

Expand Down Expand Up @@ -1205,6 +1209,9 @@ void GlobalData::parseGameDataDefinition( INI* ini )
TheWritableGlobalData->m_useAlternateMouse = optionPref.getAlternateMouseModeEnabled();
TheWritableGlobalData->m_useRightMouseScrollWithAlternateMouse = optionPref.getRightMouseScrollWithAlternateMouseEnabled();
TheWritableGlobalData->m_clientRetaliationModeEnabled = optionPref.getRetaliationModeEnabled();
TheWritableGlobalData->m_healthBarDisplayMode = optionPref.getHealthBarDisplayMode();
TheWritableGlobalData->m_numericalHealth = optionPref.getNumericalHealthEnabled();
TheWritableGlobalData->m_smartPips = optionPref.getSmartPipsEnabled();
TheWritableGlobalData->m_doubleClickAttackMove = optionPref.getDoubleClickAttackMoveEnabled();
TheWritableGlobalData->m_jpegQuality = optionPref.getJpegQuality();
TheWritableGlobalData->m_keyboardScrollFactor = optionPref.getScrollFactor();
Expand Down
Loading