Skip to content

Commit 94e3e06

Browse files
committed
feat(radar): Save Radar hidden and forced status for each Player to show correct radar states when switching teams (#1715)
1 parent df6ebbd commit 94e3e06

File tree

12 files changed

+107
-78
lines changed

12 files changed

+107
-78
lines changed

Core/GameEngine/Include/Common/GameUtility.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ class Player;
2525
namespace rts
2626
{
2727

28-
Bool localPlayerIsObserving();
28+
bool localPlayerIsObserving();
29+
bool localPlayerHasRadar();
2930
Player* getObservedOrLocalPlayer(); ///< Get the current observed or local player. Is never null.
3031

3132
void changeLocalPlayer(Player* player); //< Change local player during game

Core/GameEngine/Source/Common/GameUtility.cpp

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ static void changePlayerCommon(Player* player)
4949

5050
} // namespace detail
5151

52-
Bool localPlayerIsObserving()
52+
bool localPlayerIsObserving()
5353
{
5454
if (TheGameLogic->isInReplayGame() || TheGameLogic->isInShellGame())
5555
return true;
@@ -60,6 +60,22 @@ Bool localPlayerIsObserving()
6060
return false;
6161
}
6262

63+
bool localPlayerHasRadar()
64+
{
65+
// Using "local" instead of "observed or local" player because as an observer we prefer
66+
// the radar to be turned on when observing a player that has no radar.
67+
const Player* player = ThePlayerList->getLocalPlayer();
68+
const PlayerIndex index = player->getPlayerIndex();
69+
70+
if (TheRadar->isRadarForced(index))
71+
return true;
72+
73+
if (!TheRadar->isRadarHidden(index) && player->hasRadar())
74+
return true;
75+
76+
return false;
77+
}
78+
6379
Player* getObservedOrLocalPlayer()
6480
{
6581
Player* player = TheControlBar->getObservedPlayer();

GeneralsMD/Code/GameEngine/Include/Common/Radar.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -180,9 +180,9 @@ class Radar : public Snapshot,
180180
Bool radarToWorld( const ICoord2D *radar, Coord3D *world ); ///< radar point to world point on terrain
181181
Bool radarToWorld2D( const ICoord2D *radar, Coord3D *world ); ///< radar point to world point (x,y only!)
182182
Bool worldToRadar( const Coord3D *world, ICoord2D *radar ); ///< translate world point to radar (x,y)
183-
Bool localPixelToRadar( const ICoord2D *pixel, ICoord2D *radar ); ///< translate pixel (with UL of radar being (0,0)) to logical radar coords
183+
Bool localPixelToRadar( const ICoord2D *pixel, ICoord2D *radar ); ///< translate pixel (with UL of radar being (0,0)) to logical radar coordinates
184184
Bool screenPixelToWorld( const ICoord2D *pixel, Coord3D *world ); ///< translate pixel (with UL of the screen being (0,0)) to world position in the world
185-
Object *objectUnderRadarPixel( const ICoord2D *pixel ); ///< return the object (if any) represented by the pixel coords passed in
185+
Object *objectUnderRadarPixel( const ICoord2D *pixel ); ///< return the object (if any) represented by the pixel coordinates passed in
186186
void findDrawPositions( Int startX, Int startY, Int width, Int height,
187187
ICoord2D *ul, ICoord2D *lr ); ///< make translation for screen area of radar square to scaled aspect ratio preserving points inside the radar area
188188

@@ -203,22 +203,22 @@ class Radar : public Snapshot,
203203
virtual RadarObjectType removeObject( Object *obj ); ///< remove object from radar
204204

205205
// radar options
206-
void hide( Bool hide ) { m_radarHidden = hide; } ///< hide/unhide the radar
207-
Bool isRadarHidden( void ) { return m_radarHidden; } ///< is radar hidden
206+
void hide( Int playerIndex, Bool hide ) { m_radarHidden[playerIndex] = hide; } ///< hide/show the radar
207+
Bool isRadarHidden( Int playerIndex ) { return m_radarHidden[playerIndex]; } ///< is radar hidden
208208
// other radar option methods here like the ability to show a certain
209209
// team, show buildings, show units at all, etc
210210

211211
// forcing the radar on/off regardless of player situation
212-
void forceOn( Bool force ) { m_radarForceOn = force; } ///< force the radar to be on
213-
Bool isRadarForced( void ) { return m_radarForceOn; } ///< is radar forced on?
212+
void forceOn( Int playerIndex, Bool force ) { m_radarForceOn[playerIndex] = force; } ///< force the radar to be on
213+
Bool isRadarForced( Int playerIndex ) { return m_radarForceOn[playerIndex]; } ///< is radar forced on?
214214

215215
/// refresh the water values for the radar
216216
virtual void refreshTerrain( TerrainLogic *terrain );
217217

218218
/// refresh the radar when the state of world objects changes drastically
219219
virtual void refreshObjects() {};
220220

221-
/// queue a refresh of the terran at the next available time
221+
/// queue a refresh of the terrain at the next available time
222222
virtual void queueTerrainRefresh( void );
223223

224224
virtual void newMap( TerrainLogic *terrain ); ///< reset radar for new map
@@ -252,11 +252,11 @@ class Radar : public Snapshot,
252252

253253
void clearAllEvents( void ); ///< remove all radar events in progress
254254

255-
// search the object list for an object that maps to the given logical radar coords
255+
// search the object list for an object that maps to the given logical radar coordinates
256256
Object *searchListForRadarLocationMatch( RadarObject *listHead, ICoord2D *radarMatch );
257257

258-
Bool m_radarHidden; ///< true when radar is not visible
259-
Bool m_radarForceOn; ///< true when radar is forced to be on
258+
Bool m_radarHidden[MAX_PLAYER_COUNT]; ///< true when radar is not visible
259+
Bool m_radarForceOn[MAX_PLAYER_COUNT]; ///< true when radar is forced to be on
260260
RadarObject *m_objectList; ///< list of objects in the radar
261261
RadarObject *m_localObjectList; /** list of objects for the local player, sorted
262262
* in exactly the same priority as the regular

GeneralsMD/Code/GameEngine/Source/Common/System/Radar.cpp

Lines changed: 36 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,8 @@ Radar::Radar( void )
214214
m_radarWindow = NULL;
215215
m_objectList = NULL;
216216
m_localObjectList = NULL;
217-
m_radarHidden = false;
218-
m_radarForceOn = false;
217+
std::fill(m_radarHidden, m_radarHidden + ARRAY_SIZE(m_radarHidden), false);
218+
std::fill(m_radarForceOn, m_radarForceOn + ARRAY_SIZE(m_radarForceOn), false);
219219
m_terrainAverageZ = 0.0f;
220220
m_waterAverageZ = 0.0f;
221221
m_xSample = 0.0f;
@@ -291,8 +291,11 @@ void Radar::reset( void )
291291
// clear all events
292292
clearAllEvents();
293293

294+
// TheSuperHackers @todo Reset m_radarHidden?
295+
//std::fill(m_radarHidden, m_radarHidden + ARRAY_SIZE(m_radarHidden), false);
296+
294297
// stop forcing the radar on
295-
m_radarForceOn = false;
298+
std::fill(m_radarForceOn, m_radarForceOn + ARRAY_SIZE(m_radarForceOn), false);
296299

297300
}
298301

@@ -1487,21 +1490,46 @@ static void xferRadarObjectList( Xfer *xfer, RadarObject **head )
14871490
// ------------------------------------------------------------------------------------------------
14881491
/** Xfer Method
14891492
* Version Info:
1490-
* 1: Initial version */
1493+
* 1: Initial version
1494+
* 2: TheSuperHackers @tweak Serialize m_radarHidden, m_radarForceOn for each player
1495+
*/
14911496
// ------------------------------------------------------------------------------------------------
14921497
void Radar::xfer( Xfer *xfer )
14931498
{
14941499

14951500
// version
1501+
#if RETAIL_COMPATIBLE_XFER_SAVE
14961502
XferVersion currentVersion = 1;
1503+
#else
1504+
XferVersion currentVersion = 2;
1505+
#endif
14971506
XferVersion version = currentVersion;
14981507
xfer->xferVersion( &version, currentVersion );
14991508

1500-
// radar hidden
1501-
xfer->xferBool( &m_radarHidden );
1509+
1510+
if (version <= 1)
1511+
{
1512+
const Int localPlayerIndex = ThePlayerList->getLocalPlayer()->getPlayerIndex();
1513+
Bool value;
1514+
1515+
// radar hidden
1516+
value = m_radarHidden[localPlayerIndex];
1517+
xfer->xferBool( &value );
1518+
m_radarHidden[localPlayerIndex] = value;
1519+
1520+
// radar force on
1521+
value = m_radarForceOn[localPlayerIndex];
1522+
xfer->xferBool( &value );
1523+
m_radarForceOn[localPlayerIndex] = value;
1524+
}
1525+
else
1526+
{
1527+
static_assert(sizeof(m_radarHidden) == 16, "Increase version if size changes");
1528+
xfer->xferUser(&m_radarHidden, sizeof(m_radarHidden));
15021529

1503-
// radar force on
1504-
xfer->xferBool( &m_radarForceOn );
1530+
static_assert(sizeof(m_radarForceOn) == 16, "Increase version if size changes");
1531+
xfer->xferUser(&m_radarForceOn, sizeof(m_radarForceOn));
1532+
}
15051533

15061534
// save our local object list
15071535
xferRadarObjectList( xfer, &m_localObjectList );

GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarCallback.cpp

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
3232
#include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine
3333

34+
#include "Common/GameUtility.h"
3435
#include "Common/NameKeyGenerator.h"
3536
#include "Common/Player.h"
3637
#include "Common/PlayerList.h"
@@ -64,15 +65,11 @@ WindowLayout *popupCommunicatorLayout = NULL;
6465
WindowMsgHandledType LeftHUDInput( GameWindow *window, UnsignedInt msg,
6566
WindowMsgData mData1, WindowMsgData mData2 )
6667
{
67-
68-
// get player
69-
Player *player = ThePlayerList->getLocalPlayer();
70-
7168
//
7269
// if the player doesn't have a radar, or the radar is hidden, and the radar is not being
7370
// forced to on, we just eat input over the radar window
7471
//
75-
if( !TheRadar->isRadarForced() && (TheRadar->isRadarHidden() || !player->hasRadar()) )
72+
if( !rts::localPlayerHasRadar() )
7673
return MSG_HANDLED;
7774

7875
// If the middle mouse button is depressed, then just let the message fall all the
@@ -152,15 +149,14 @@ WindowMsgHandledType LeftHUDInput( GameWindow *window, UnsignedInt msg,
152149

153150
// is the mouse in the radar window
154151
ICoord2D radar;
155-
if( (TheRadar->isRadarHidden() == FALSE || TheRadar->isRadarForced()) &&
156-
TheRadar->localPixelToRadar( &mouse, &radar ) )
152+
if( TheRadar->localPixelToRadar( &mouse, &radar ) )
157153
{
158154

159155
/*
160156
//
161157
// this is an example piece of code to find the object under the pixel position
162158
// of the radar ... should we in the future wish to allow commands to be executed
163-
// on objects throught he radar. note tho that this is extremely hard to do because
159+
// on objects through the radar. note tho that this is extremely hard to do because
164160
// the pixels on the radar are very small and it's hard to do accurate targeting
165161
//
166162
@@ -252,9 +248,8 @@ WindowMsgHandledType LeftHUDInput( GameWindow *window, UnsignedInt msg,
252248
// completely drawn with the radar ... so it's just a translation from
253249
// our window size we're drawing into to the radar cell size
254250
//
255-
if( (TheRadar->isRadarHidden() == FALSE || TheRadar->isRadarForced()) &&
256-
TheRadar->localPixelToRadar( &mouse, &radar ) &&
257-
TheRadar->radarToWorld( &radar, &world ) )
251+
if( TheRadar->localPixelToRadar( &mouse, &radar ) &&
252+
TheRadar->radarToWorld( &radar, &world ) )
258253
{
259254

260255
// No drawables, or a right click automatically means its a look at.

GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,13 +1391,7 @@ void InGameUI::handleRadiusCursor()
13911391
// from screen to world
13921392
// But only if the radar is on.
13931393
//
1394-
Bool radarOn = TheRadar->isRadarForced()
1395-
|| ( !TheRadar->isRadarHidden()
1396-
&& ThePlayerList->getLocalPlayer()
1397-
&& ThePlayerList->getLocalPlayer()->hasRadar()
1398-
);
1399-
1400-
if( !radarOn || (TheRadar->screenPixelToWorld( &mouseIO->pos, &pos ) == FALSE) )// if radar off, or point not on radar
1394+
if( !rts::localPlayerHasRadar() || (TheRadar->screenPixelToWorld( &mouseIO->pos, &pos ) == FALSE) )// if radar off, or point not on radar
14011395
TheTacticalView->screenToTerrain( &mouseIO->pos, &pos );
14021396

14031397

@@ -2772,10 +2766,7 @@ void InGameUI::createCommandHint( const GameMessage *msg )
27722766
setMouseCursor( Mouse::GENERIC_INVALID );
27732767
else if( drawSelectable && obj->isLocallyControlled() && !obj->isKindOf(KINDOF_MINE))
27742768
setMouseCursor( Mouse::SELECTING );
2775-
else if( TheRadar->isRadarWindow( window ) &&
2776-
TheRadar->isRadarForced() == FALSE &&
2777-
(TheRadar->isRadarHidden() ||
2778-
ThePlayerList->getLocalPlayer()->hasRadar() == FALSE) )
2769+
else if( TheRadar->isRadarWindow( window ) && !rts::localPlayerHasRadar() )
27792770
setMouseCursor( Mouse::ARROW );
27802771
else
27812772
setMouseCursor( Mouse::MOVETO );

GeneralsMD/Code/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3022,18 +3022,11 @@ GameMessageDisposition CommandTranslator::translateGameMessage(const GameMessage
30223022
//-----------------------------------------------------------------------------------------
30233023
case GameMessage::MSG_META_VIEW_LAST_RADAR_EVENT:
30243024
{
3025-
// Player *player = ThePlayerList->getLocalPlayer();
3025+
// You don't need radar for the space bar. That's silly.
3026+
Coord3D lastEvent;
30263027

3027-
// if the local player has a radar, center on last event (if any)
3028-
// Excuse me? You don't need radar for the spacebar. That's silly.
3029-
// if( TheRadar->isRadarForced() || ( TheRadar->isRadarHidden() == false && player->hasRadar() ) )
3030-
{
3031-
Coord3D lastEvent;
3032-
3033-
if( TheRadar->getLastEventLoc( &lastEvent ) )
3034-
TheTacticalView->lookAt( &lastEvent );
3035-
3036-
}
3028+
if( TheRadar->getLastEventLoc( &lastEvent ) )
3029+
TheTacticalView->lookAt( &lastEvent );
30373030

30383031
disp = DESTROY_MESSAGE;
30393032
break;

GeneralsMD/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptActions.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2970,15 +2970,15 @@ void ScriptActions::doTeamRadarCreateEvent(const AsciiString& teamName, Int even
29702970
//-------------------------------------------------------------------------------------------------
29712971
void ScriptActions::doRadarDisable(void)
29722972
{
2973-
TheRadar->hide(true);
2973+
TheRadar->hide(ThePlayerList->getLocalPlayer()->getPlayerIndex(), true);
29742974
}
29752975

29762976
//-------------------------------------------------------------------------------------------------
29772977
/** doRadarEnable */
29782978
//-------------------------------------------------------------------------------------------------
29792979
void ScriptActions::doRadarEnable(void)
29802980
{
2981-
TheRadar->hide(false);
2981+
TheRadar->hide(ThePlayerList->getLocalPlayer()->getPlayerIndex(), false);
29822982
}
29832983

29842984
//-------------------------------------------------------------------------------------------------
@@ -5120,15 +5120,15 @@ void ScriptActions::doDestroyAllContained(const AsciiString& unitName, Int damag
51205120
//-------------------------------------------------------------------------------------------------
51215121
void ScriptActions::doRadarForceEnable(void)
51225122
{
5123-
TheRadar->forceOn(true);
5123+
TheRadar->forceOn(ThePlayerList->getLocalPlayer()->getPlayerIndex(), true);
51245124
}
51255125

51265126
//-------------------------------------------------------------------------------------------------
51275127
/** doRadarRevertNormal */
51285128
//-------------------------------------------------------------------------------------------------
51295129
void ScriptActions::doRadarRevertNormal(void)
51305130
{
5131-
TheRadar->forceOn(false);
5131+
TheRadar->forceOn(ThePlayerList->getLocalPlayer()->getPlayerIndex(), false);
51325132
}
51335133

51345134
//-------------------------------------------------------------------------------------------------

GeneralsMD/Code/GameEngine/Source/GameLogic/ScriptEngine/VictoryConditions.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "Common/GameAudio.h"
3333
#include "Common/GameCommon.h"
3434
#include "Common/GameEngine.h"
35+
#include "Common/GameUtility.h"
3536
#include "Common/KindOf.h"
3637
#include "Common/PlayerList.h"
3738
#include "Common/Player.h"
@@ -141,7 +142,7 @@ void VictoryConditions::reset( void )
141142
//-------------------------------------------------------------------------------------------------
142143
void VictoryConditions::update( void )
143144
{
144-
if (!TheRecorder->isMultiplayer() || (m_localSlotNum == -1 && !m_isObserver))
145+
if (!TheRecorder->isMultiplayer() || (m_localSlotNum < 0 && !m_isObserver))
145146
return;
146147

147148
// Check for a single winning alliance
@@ -228,7 +229,7 @@ void VictoryConditions::update( void )
228229
//MessageBoxOk(TheGameText->fetch("GUI:Defeat"), TheGameText->fetch("GUI:LocalDefeat"), NULL);
229230
}
230231
m_localPlayerDefeated = true; // don't check again
231-
TheRadar->forceOn(TRUE);
232+
TheRadar->forceOn(localPlayer->getPlayerIndex(), TRUE);
232233
SetInGameChatType( INGAME_CHAT_EVERYONE ); // can't chat to allies after death. Only to other observers.
233234
}
234235
}
@@ -328,8 +329,6 @@ void VictoryConditions::cachePlayerPtrs( void )
328329
if (m_localSlotNum < 0)
329330
{
330331
m_localPlayerDefeated = true; // if we have no local player, don't check for defeat
331-
DEBUG_ASSERTCRASH(TheRadar, ("No Radar!"));
332-
TheRadar->forceOn(TRUE);
333332
m_isObserver = true;
334333
}
335334
}

0 commit comments

Comments
 (0)