Vinifera-Developers / Vinifera

Vinifera is a C&C: Tiberian Sun engine extension implementing new logics and fixing bugs.
GNU General Public License v3.0
46 stars 10 forks source link

[Vanilla Bug] Undiscovered allied Medics draw their Medic indicator pip in shroud #1032

Closed Rampastring closed 2 months ago

Rampastring commented 1 year ago

First Check

Description

When a house is allied to you but you have not discovered their units (with [AudioVisual] AllyReveal=no), if the house has a Medic, the Medic's cross pip will be drawn in shroud.

Houses that are allied to you, but which you haven't discovered, are commonly used in singleplayer missions. This bug can make it more complicated to implement "bonuses" such as hidden Medic units that you can discover and get to join your forces by scouting the map.

Required Code (optional)

No response

Steps To Reproduce

Make a singleplayer map where a house is allied to the human player. Give the house a medic somewhere where the player can't see at the beginning of the mission.

Give the map the following code

[AudioVisual]
AllyReveal=no

Expected Behaviour

The Medic's cross pip should not be drawn until the player discovers the Medic.

Actual Behaviour

As you launch the mission and scroll around, you'll see the Medic's red cross pip drawn within the shroud.

Additional Context

Screenshot of the issue: https://cdn.discordapp.com/attachments/668443771364442112/1146909947595079720/image.png

Note the seemingly random red cross in the shroud at the bottom of the image.

The following code, patched in with a jump at 0x00637B83, seems to fix this bug:

/**
 *  Fixes a bug where the Medic indicator is drawn for a medic that has
 *  not been discovered by the player.
 * 
 *  @author: Rampastring
 */
DECLARE_PATCH(_TechnoClass_Draw_Pips_No_Medic_Indicator_In_Shroud_Patch)
{
    GET_REGISTER_STATIC(TechnoClass *, this_ptr, esi);

    if (!this_ptr->IsDiscoveredByPlayer || this_ptr->Combat_Damage() >= 0) {
        goto no_indicator;
    }

    /**
     *  Draw the medic indicator pip.
     */
display_indicator:
    JMP(0x00637B90);

    /**
     *  Continue the function, but skip drawing the medic indicator pip.
     */
no_indicator:
    JMP(0x00637BD2);
}
ZivDero commented 2 months ago

Likely caused by ts-patches hack meant to always draw unit pips not checking if a unit is visible