Skip to content

Commit 1991c78

Browse files
authored
bugfix(client): Fix crash in WorldBuilder scene (#1723)
1 parent cd2e5bc commit 1991c78

File tree

8 files changed

+43
-14
lines changed

8 files changed

+43
-14
lines changed

Core/GameEngine/Include/Common/GameUtility.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,15 @@
2121
// For miscellaneous game utility functions.
2222

2323
class Player;
24+
typedef Int PlayerIndex;
2425

2526
namespace rts
2627
{
2728

2829
Bool localPlayerIsObserving();
2930
Player* getObservedOrLocalPlayer(); ///< Get the current observed or local player. Is never null.
31+
Player* getObservedOrLocalPlayer_Safe(); ///< Get the current observed or local player. Is never null, except when the application does not have players.
32+
PlayerIndex getObservedOrLocalPlayerIndex_Safe(); ///< Get the current observed or local player index. Returns 0 when the application does not have players.
3033

3134
void changeLocalPlayer(Player* player); //< Change local player during game
3235
void changeObservedPlayer(Player* player); ///< Change observed player during game

Core/GameEngine/Source/Common/GameUtility.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,38 @@ Bool localPlayerIsObserving()
6262

6363
Player* getObservedOrLocalPlayer()
6464
{
65+
DEBUG_ASSERTCRASH(TheControlBar != NULL, ("TheControlBar is NULL"));
6566
Player* player = TheControlBar->getObservedPlayer();
6667
if (player == NULL)
68+
{
69+
DEBUG_ASSERTCRASH(ThePlayerList != NULL, ("ThePlayerList is NULL"));
6770
player = ThePlayerList->getLocalPlayer();
71+
}
72+
return player;
73+
}
74+
75+
Player* getObservedOrLocalPlayer_Safe()
76+
{
77+
Player* player = NULL;
78+
79+
if (TheControlBar != NULL)
80+
player = TheControlBar->getObservedPlayer();
81+
82+
if (player == NULL)
83+
if (ThePlayerList != NULL)
84+
player = ThePlayerList->getLocalPlayer();
85+
6886
return player;
6987
}
7088

89+
PlayerIndex getObservedOrLocalPlayerIndex_Safe()
90+
{
91+
if (Player* player = getObservedOrLocalPlayer_Safe())
92+
return player->getPlayerIndex();
93+
94+
return 0;
95+
}
96+
7197
void changeLocalPlayer(Player* player)
7298
{
7399
ThePlayerList->setLocalPlayer(player);

Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -513,7 +513,7 @@ void RTS3DScene::renderSpecificDrawables(RenderInfoClass &rinfo, Int numDrawable
513513
#ifdef DIRTY_CONDITION_FLAGS
514514
StDrawableDirtyStuffLocker lockDirtyStuff;
515515
#endif
516-
const Int localPlayerIndex = rts::getObservedOrLocalPlayer()->getPlayerIndex();
516+
const Int localPlayerIndex = rts::getObservedOrLocalPlayerIndex_Safe();
517517
RefRenderObjListIterator it(&UpdateList);
518518
// loop through all render objects in the list:
519519
for (it.First(&RenderList); !it.Is_Done();)
@@ -1041,7 +1041,7 @@ void RTS3DScene::Customized_Render( RenderInfoClass &rinfo )
10411041
m_translucentObjectsCount = 0; //start of new frame so no translucent objects
10421042
m_occludedObjectsCount = 0;
10431043

1044-
const Int localPlayerIndex = rts::getObservedOrLocalPlayer()->getPlayerIndex();
1044+
const Int localPlayerIndex = rts::getObservedOrLocalPlayerIndex_Safe();
10451045

10461046
#define USE_LIGHT_ENV 1
10471047

@@ -1292,7 +1292,7 @@ void RTS3DScene::flushOccludedObjectsIntoStencil(RenderInfoClass & rinfo)
12921292
//Assume no player colors are visible and all stencil bits are free for use by shadows.
12931293
TheW3DShadowManager->setStencilShadowMask(0);
12941294

1295-
const Int localPlayerIndex = rts::getObservedOrLocalPlayer()->getPlayerIndex();
1295+
const Int localPlayerIndex = rts::getObservedOrLocalPlayerIndex_Safe();
12961296

12971297
if (m_numPotentialOccludees && m_numPotentialOccluders)
12981298
{
@@ -1470,7 +1470,7 @@ void RTS3DScene::flushOccludedObjects(RenderInfoClass & rinfo)
14701470

14711471
if (m_occludedObjectsCount)
14721472
{
1473-
const Int localPlayerIndex = rts::getObservedOrLocalPlayer()->getPlayerIndex();
1473+
const Int localPlayerIndex = rts::getObservedOrLocalPlayerIndex_Safe();
14741474

14751475
if (DX8Wrapper::Has_Stencil()) //just in case we have shadows, disable them over occluded pixels.
14761476
{
@@ -1540,7 +1540,7 @@ void RTS3DScene::flushTranslucentObjects(RenderInfoClass & rinfo)
15401540

15411541
if (m_translucentObjectsCount)
15421542
{
1543-
const Int localPlayerIndex = rts::getObservedOrLocalPlayer()->getPlayerIndex();
1543+
const Int localPlayerIndex = rts::getObservedOrLocalPlayerIndex_Safe();
15441544

15451545
for (Int i=0; i<m_translucentObjectsCount; i++)
15461546
{

Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -839,7 +839,7 @@ static void drawablePostDraw( Drawable *draw, void *userData )
839839
return;
840840

841841
Object* obj = draw->getObject();
842-
const Int localPlayerIndex = rts::getObservedOrLocalPlayer()->getPlayerIndex();
842+
const Int localPlayerIndex = rts::getObservedOrLocalPlayerIndex_Safe();
843843
#if ENABLE_CONFIGURABLE_SHROUD
844844
ObjectShroudStatus ss = (!obj || !TheGlobalData->m_shroudOn) ? OBJECTSHROUD_CLEAR : obj->getShroudedStatus(localPlayerIndex);
845845
#else

GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DPropBuffer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ void W3DPropBuffer::drawProps(RenderInfoClass &rinfo)
365365
m_props[i].ss = OBJECTSHROUD_CLEAR;
366366
}
367367
if (m_props[i].ss == OBJECTSHROUD_INVALID) {
368-
const Int localPlayerIndex = rts::getObservedOrLocalPlayer()->getPlayerIndex();
368+
const Int localPlayerIndex = rts::getObservedOrLocalPlayerIndex_Safe();
369369
m_props[i].ss = ThePartitionManager->getPropShroudStatusForPlayer(localPlayerIndex, &m_props[i].location);
370370
}
371371
if (m_props[i].ss >= OBJECTSHROUD_SHROUDED) {

GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DScene.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ void RTS3DScene::renderSpecificDrawables(RenderInfoClass &rinfo, Int numDrawable
537537
#ifdef DIRTY_CONDITION_FLAGS
538538
StDrawableDirtyStuffLocker lockDirtyStuff;
539539
#endif
540-
const Int localPlayerIndex = rts::getObservedOrLocalPlayer()->getPlayerIndex();
540+
const Int localPlayerIndex = rts::getObservedOrLocalPlayerIndex_Safe();
541541
RefRenderObjListIterator it(&UpdateList);
542542
// loop through all render objects in the list:
543543
for (it.First(&RenderList); !it.Is_Done();)
@@ -1089,7 +1089,7 @@ void RTS3DScene::Customized_Render( RenderInfoClass &rinfo )
10891089
m_translucentObjectsCount = 0; //start of new frame so no translucent objects
10901090
m_occludedObjectsCount = 0;
10911091

1092-
const Int localPlayerIndex = rts::getObservedOrLocalPlayer()->getPlayerIndex();
1092+
const Int localPlayerIndex = rts::getObservedOrLocalPlayerIndex_Safe();
10931093

10941094
#define USE_LIGHT_ENV 1
10951095

@@ -1339,7 +1339,7 @@ void RTS3DScene::flushOccludedObjectsIntoStencil(RenderInfoClass & rinfo)
13391339
//Assume no player colors are visible and all stencil bits are free for use by shadows.
13401340
TheW3DShadowManager->setStencilShadowMask(0);
13411341

1342-
const Int localPlayerIndex = rts::getObservedOrLocalPlayer()->getPlayerIndex();
1342+
const Int localPlayerIndex = rts::getObservedOrLocalPlayerIndex_Safe();
13431343

13441344
if (m_numPotentialOccludees && m_numPotentialOccluders)
13451345
{
@@ -1533,7 +1533,7 @@ void RTS3DScene::flushOccludedObjects(RenderInfoClass & rinfo)
15331533

15341534
if (m_occludedObjectsCount)
15351535
{
1536-
const Int localPlayerIndex = rts::getObservedOrLocalPlayer()->getPlayerIndex();
1536+
const Int localPlayerIndex = rts::getObservedOrLocalPlayerIndex_Safe();
15371537

15381538
if (DX8Wrapper::Has_Stencil()) //just in case we have shadows, disable them over occluded pixels.
15391539
{
@@ -1603,7 +1603,7 @@ void RTS3DScene::flushTranslucentObjects(RenderInfoClass & rinfo)
16031603

16041604
if (m_translucentObjectsCount)
16051605
{
1606-
const Int localPlayerIndex = rts::getObservedOrLocalPlayer()->getPlayerIndex();
1606+
const Int localPlayerIndex = rts::getObservedOrLocalPlayerIndex_Safe();
16071607

16081608
for (Int i=0; i<m_translucentObjectsCount; i++)
16091609
{

GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTreeBuffer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1849,7 +1849,7 @@ void W3DTreeBuffer::updateTopplingTree(TTree *tree, Real timeScale)
18491849
return;
18501850

18511851
const W3DTreeDrawModuleData* d = m_treeTypes[tree->treeType].m_data;
1852-
const Int localPlayerIndex = rts::getObservedOrLocalPlayer()->getPlayerIndex();
1852+
const Int localPlayerIndex = rts::getObservedOrLocalPlayerIndex_Safe();
18531853
Coord3D pos;
18541854
pos.set(tree->location.X, tree->location.Y, tree->location.Z);
18551855
ObjectShroudStatus ss = ThePartitionManager->getPropShroudStatusForPlayer(localPlayerIndex, &pos);

GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DView.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -980,7 +980,7 @@ static void drawablePostDraw( Drawable *draw, void *userData )
980980
return;
981981

982982
Object* obj = draw->getObject();
983-
const Int localPlayerIndex = rts::getObservedOrLocalPlayer()->getPlayerIndex();
983+
const Int localPlayerIndex = rts::getObservedOrLocalPlayerIndex_Safe();
984984
#if ENABLE_CONFIGURABLE_SHROUD
985985
ObjectShroudStatus ss = (!obj || !TheGlobalData->m_shroudOn) ? OBJECTSHROUD_CLEAR : obj->getShroudedStatus(localPlayerIndex);
986986
#else

0 commit comments

Comments
 (0)