Skip to content

Commit 133a0d9

Browse files
committed
bugfix: Update visibility conditions for client-side effects
1 parent f4608df commit 133a0d9

File tree

9 files changed

+69
-24
lines changed

9 files changed

+69
-24
lines changed

Generals/Code/GameEngine/Include/GameLogic/Object.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@ class Object : public Thing, public Snapshot
420420
void friend_setContainedBy( Object *containedBy ) { m_containedBy = containedBy; }
421421
const Object* getEnclosingContainedBy() const; ///< Find the first enclosing container in the containment chain.
422422
const Object* getOuterObject() const; ///< Get the top-level object
423+
Bool isLogicallyVisible() const; ///< Returns whether the object is logically visible to the player.
423424

424425
// Special Powers -------------------------------------------------------------------------------
425426
SpecialPowerModuleInterface *getSpecialPowerModule( const SpecialPowerTemplate *specialPowerTemplate ) const;

Generals/Code/GameEngine/Source/GameLogic/Object/Object.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,36 @@ const Object* Object::getOuterObject() const
685685
return this;
686686
}
687687

688+
//-------------------------------------------------------------------------------------------------
689+
Bool Object::isLogicallyVisible() const
690+
{
691+
if (isLocallyViewed())
692+
return true;
693+
694+
if (TheControlBar->isObserverControlBarOn())
695+
{
696+
const Player* observedPlayer = TheControlBar->getObserverLookAtPlayer();
697+
if (!observedPlayer || !observedPlayer->isPlayerActive())
698+
return true;
699+
}
700+
701+
const Object* obj = getOuterObject();
702+
703+
if (obj->isKindOf(KINDOF_DISGUISER))
704+
return true;
705+
706+
if (obj->testStatus(OBJECT_STATUS_STEALTHED) && !obj->testStatus(OBJECT_STATUS_DETECTED))
707+
{
708+
const Player* player = rts::getObservedOrLocalPlayer();
709+
const Relationship relationship = player->getRelationship(getTeam());
710+
711+
if (relationship != ALLIES)
712+
return false;
713+
}
714+
715+
return true;
716+
}
717+
688718
//-------------------------------------------------------------------------------------------------
689719
/** Run from GameLogic::destroyObject */
690720
//-------------------------------------------------------------------------------------------------
@@ -2835,13 +2865,10 @@ void Object::onVeterancyLevelChanged( VeterancyLevel oldLevel, VeterancyLevel ne
28352865
break;
28362866
}
28372867

2838-
Drawable* outerDrawable = getOuterObject()->getDrawable();
2839-
28402868
Bool doAnimation = provideFeedback
28412869
&& newLevel > oldLevel
28422870
&& !isKindOf(KINDOF_IGNORED_IN_GUI)
2843-
&& outerDrawable
2844-
&& outerDrawable->isVisible();
2871+
&& isLogicallyVisible();
28452872

28462873
if( doAnimation && TheGameLogic->getDrawIconUI() )
28472874
{

Generals/Code/GameEngine/Source/GameLogic/Object/Weapon.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -886,11 +886,7 @@ UnsignedInt WeaponTemplate::fireWeaponTemplate
886886

887887
// TheSuperHackers @todo: Remove hardcoded KINDOF_MINE check and apply PlayFXWhenStealthed = Yes to the mine weapons instead.
888888

889-
Drawable* outerDrawable = sourceObj->getOuterObject()->getDrawable();
890-
const Bool isVisible = outerDrawable && outerDrawable->isVisible();
891-
892-
if (!isVisible // if user watching cannot see us
893-
&& sourceObj->testStatus(OBJECT_STATUS_STEALTHED) // if unit is stealthed (like a Pathfinder)
889+
if (!sourceObj->isLogicallyVisible() // if user watching cannot see us
894890
&& !sourceObj->isKindOf(KINDOF_MINE) // and not a mine (which always do the FX, even if hidden)...
895891
&& !isPlayFXWhenStealthed() // and not a weapon marked to playwhenstealthed
896892
)

GeneralsMD/Code/GameEngine/Include/GameLogic/Object.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,7 @@ class Object : public Thing, public Snapshot
445445
void friend_setContainedBy( Object *containedBy ) { m_containedBy = containedBy; }
446446
const Object* getEnclosingContainedBy() const; ///< Find the first enclosing container in the containment chain.
447447
const Object* getOuterObject() const; ///< Get the top-level object
448+
Bool isLogicallyVisible() const; ///< Returns whether the object is logically visible to the player.
448449

449450
// Special Powers -------------------------------------------------------------------------------
450451
SpecialPowerModuleInterface *getSpecialPowerModule( const SpecialPowerTemplate *specialPowerTemplate ) const;

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Object.cpp

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,36 @@ const Object* Object::getOuterObject() const
749749
return this;
750750
}
751751

752+
//-------------------------------------------------------------------------------------------------
753+
Bool Object::isLogicallyVisible() const
754+
{
755+
if (isLocallyViewed())
756+
return true;
757+
758+
if (TheControlBar->isObserverControlBarOn())
759+
{
760+
const Player* observedPlayer = TheControlBar->getObserverLookAtPlayer();
761+
if (!observedPlayer || !observedPlayer->isPlayerActive())
762+
return true;
763+
}
764+
765+
const Object* obj = getOuterObject();
766+
767+
if (obj->isKindOf(KINDOF_DISGUISER))
768+
return true;
769+
770+
if (obj->testStatus(OBJECT_STATUS_STEALTHED) && !obj->testStatus(OBJECT_STATUS_DETECTED))
771+
{
772+
const Player* player = rts::getObservedOrLocalPlayer();
773+
const Relationship relationship = player->getRelationship(getTeam());
774+
775+
if (relationship != ALLIES)
776+
return false;
777+
}
778+
779+
return true;
780+
}
781+
752782
//-------------------------------------------------------------------------------------------------
753783
/** Run from GameLogic::destroyObject */
754784
//-------------------------------------------------------------------------------------------------
@@ -3150,13 +3180,10 @@ void Object::onVeterancyLevelChanged( VeterancyLevel oldLevel, VeterancyLevel ne
31503180
break;
31513181
}
31523182

3153-
Drawable* outerDrawable = getOuterObject()->getDrawable();
3154-
31553183
Bool doAnimation = provideFeedback
31563184
&& newLevel > oldLevel
31573185
&& !isKindOf(KINDOF_IGNORED_IN_GUI)
3158-
&& outerDrawable
3159-
&& outerDrawable->isVisible();
3186+
&& isLogicallyVisible();
31603187

31613188
if( doAnimation && TheGameLogic->getDrawIconUI() )
31623189
{

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/HackInternetAIUpdate.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -543,8 +543,7 @@ StateReturnType HackInternetState::update()
543543
//Grant the unit some experience for a successful hack.
544544
xp->addExperiencePoints( ai->getXpPerCashUpdate() );
545545

546-
Drawable* outerDrawable = owner->getOuterObject()->getDrawable();
547-
if (outerDrawable && outerDrawable->isVisible())
546+
if (owner->isLogicallyVisible())
548547
{
549548
// OY LOOK! I AM USING LOCAL PLAYER. Do not put anything other than TheInGameUI->addFloatingText in the block this controls!!!
550549
//Display cash income floating over the hacker.

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AutoDepositUpdate.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,7 @@ UpdateSleepTime AutoDepositUpdate::update( void )
172172
getObject()->getControllingPlayer()->getScoreKeeper()->addMoneyEarned( modData->m_depositAmount);
173173
}
174174

175-
Drawable* outerDrawable = getObject()->getOuterObject()->getDrawable();
176-
if (moneyAmount > 0 && outerDrawable && outerDrawable->isVisible())
175+
if (moneyAmount > 0 && getObject()->isLogicallyVisible())
177176
{
178177

179178
const Object *owner = getObject();

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/DockUpdate/SupplyCenterDockUpdate.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,7 @@ Bool SupplyCenterDockUpdate::action( Object* docker, Object *drone )
129129
}
130130
}
131131

132-
Drawable* outerDrawable = getObject()->getOuterObject()->getDrawable();
133-
if (value > 0 && outerDrawable && outerDrawable->isVisible())
132+
if (value > 0 && getObject()->isLogicallyVisible())
134133
{
135134
// OY LOOK! I AM USING LOCAL PLAYER. Do not put anything other than TheInGameUI->addFloatingText in the block this controls!!!
136135
// Setup info for adding a floating text

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Weapon.cpp

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -917,11 +917,7 @@ UnsignedInt WeaponTemplate::fireWeaponTemplate
917917

918918
// TheSuperHackers @todo: Remove hardcoded KINDOF_MINE check and apply PlayFXWhenStealthed = Yes to the mine weapons instead.
919919

920-
Drawable* outerDrawable = sourceObj->getOuterObject()->getDrawable();
921-
const Bool isVisible = outerDrawable && outerDrawable->isVisible();
922-
923-
if (!isVisible // if user watching cannot see us
924-
&& sourceObj->testStatus(OBJECT_STATUS_STEALTHED) // if unit is stealthed (like a Pathfinder)
920+
if (!sourceObj->isLogicallyVisible() // if user watching cannot see us
925921
&& !sourceObj->isKindOf(KINDOF_MINE) // and not a mine (which always do the FX, even if hidden)...
926922
&& !isPlayFXWhenStealthed() // and not a weapon marked to playwhenstealthed
927923
)

0 commit comments

Comments
 (0)