Jump to content

Enemy Within Hologlobe Rotation Fix


Amineri

Recommended Posts

I spent a little time comparing the Enemy Unknown and Enemy Within files, and was finally able to trace down the source of the problem with the Geoscape rotation in Enemy Within.

It's somewhat odd, but from the code it appears that the hologlobe rotation should work properly when using touch controls, but for some reason it was disabled with regular mouse controls.

 

The issue is in XComHeadquartersInput.

 

In EnemyUnknown this class is much simpler, containing only the member functions:

  • CheckForFacilityClicked
  • EscapeKey
  • Key_F10
  • LMouse
  • PostProcessCheckGameLogic
  • PreProcessCheckGameLogic
  • ProcessGeoscapeRotation
  • QuicksaveComeplete
  • Start_Button

In EnemyWithin this was substantially increased. I won't list them all, but in particular the new member function Touch_LMouse was added.

 

In EnemyUnknown's XComHeadquartersInput.LMouse, part of what enables mouse left-click geoscape rotation is :

    if((Actionmask & 32) != 0)
    {
        m_bMouseDraggingGeoscape = false;
        if(!CheckForFacilityClick())
        {
            kHitEntity = XGEntity(bool(kHUD.CachedMouseInteractionInterface));
            if(kHitEntity != none)
            {
                return HandleClickedGlobeActor(kHitEntity.m_kGameActor);
            }
        }
    }
    else
    {
        if((Actionmask & 1) != 0)
        {
            kHitActor = StaticMeshActor(bool(kHUD.CachedMouseInteractionInterface));
            if((kHitActor != none) && (kHitActor.StaticMeshComponent.StaticMesh == staticmesh'Globe') || kHitActor.StaticMeshComponent.StaticMesh == staticmesh'Clouds_Flowing')
            {
                m_bMouseDraggingGeoscape = true;
                return true;
            }
        }
    }

The geoscape rotation is handled in the latter part of the conditional with the m_bMouseDraggingGeoscape = true; statement.

 

For some reason not clear to me, this LMouse functionality was changed in Enemy Within to :

    if(UseTouchInput())
    {
        return Touch_LMouse(Actionmask);
    }
    kHUD = GetXComHUD();
    if(kHUD == none)
    {
        return false;
    }
    if((Actionmask & 32) != 0)
    {
        m_bMouseDraggingGeoscape = false;
        if(!CheckForFacilityClick())
        {
            kHitEntity = XGEntity(bool(kHUD.CachedMouseInteractionInterface));
            if(kHitEntity != none)
            {
                return HandleClickedGlobeActor(kHitEntity.m_kGameActor);
            }
        }
    }
    else
    {
        // End:0xF4
        if((Actionmask & 1) != 0)
        {
        }
    }

This explicitly disables geoscape dragging with a regular mouse. However the new Touch_LMouse contains very similar code to the Enemy Unknown LMouse function:

    else
    {
        if((Actionmask & 1) != 0)
        {
            kHitActor = StaticMeshActor(bool(kHUD.CachedMouseInteractionInterface));
            if((kHitActor != none) && (kHitActor.StaticMeshComponent.StaticMesh.Name == 'Globe') || kHitActor.StaticMeshComponent.StaticMesh.Name == 'Clouds_Flowing')
            {
                m_bMouseDraggingGeoscape = true;
                return true;
            }
        }
    }

This leads me to suspect that geoscape rotation should be possible still with a touchpad, but I'm a bit mystified as to why it was disabled for the regular mouse.

 

The EnemyWithin LMouse function still contains the necessary local variables (although they aren't used), so I went ahead and expanded the function and added the same geoscape rotation code present in EnemyUnknown's LMouse and Enemy Within's Touch_LMouse.

 

The result appears to be a properly rotate-able geoscape globe.

 

Below is the UPKmodder file I used to make the fix :

 

 

MODFILEVERSION=4
UPKFILE=XComStrategyGame.upk 
GUID=BB 93 C6 C8 D2 91 82 44 87 9B 79 9B 49 5B 8D E9 // XComStrategyGame_EW_patch3.upk
FUNCTION=LMouse@XComHeadquartersInput
RESIZE=B0

// re-enable geoscape dragging

[BEFORE_HEX]
[HEADER]
01 01 00 00 C1 00 00 00 
[/HEADER]
[code]
//if(UseTouchInput())
07 21 00 1B CD 34 00 00 00 00 00 00 16 

//return Touch_LMouse(Actionmask)
04 1B 73 31 00 00 00 00 00 00 00 6C 24 00 00 16 

//kHUD = GetXComHUD()
0F 00 68 24 00 00 1B AC 13 00 00 00 00 00 00 16 

//if(kHUD == none)
07 46 00 72 00 68 24 00 00 2A 16 

	//return false
	04 28 

//if((Actionmask & 32) != 0)
07 E2 00 9B 9C 00 6C 24 00 00 2C 20 16 25 16 

	//m_bMouseDraggingGeoscape = false
	14 2D 01 0B 24 00 00 28 

	//if(!CheckForFacilityClick())
	07 DF 00 81 1B 2E 06 00 00 00 00 00 00 16 16 

		//kHitEntity = XGEntity(bool(kHUD.CachedMouseInteractionInterface))
		0F 00 69 24 00 00 2E AF 29 00 00 38 36 19 00 68 24 00 00 09 00 D6 FB FF FF 00 01 D6 FB FF FF 

		//if(kHitEntity != none)
		07 DF 00 77 00 69 24 00 00 2A 16 

			//return HandleClickedGlobeActor(kHitEntity.m_kGameActor)
			04 1B 16 14 00 00 00 00 00 00 19 00 69 24 00 00 09 00 9B 29 00 00 00 01 9B 29 00 00 16 

//else
06 F4 00 

	//if((Actionmask & 1) != 0)
	07 F4 00 9B 9C 00 6C 24 00 00 26 16 25 16 

		//return false
		04 28 

//return ReturnValue
04 3A 6B 24 00 00 

//EOS
53 
[/CODE]
[/BEFORE_HEX]


[AFTER_HEX]
[HEADER]
05 02 00 00 71 01 00 00 
[/HEADER]
[code]
//if(UseTouchInput())
07 21 00 1B CD 34 00 00 00 00 00 00 16 

//return Touch_LMouse(Actionmask)
04 1B 73 31 00 00 00 00 00 00 00 6C 24 00 00 16 

//kHUD = GetXComHUD()
0F 00 68 24 00 00 1B AC 13 00 00 00 00 00 00 16 

//if(kHUD == none)
07 46 00 72 00 68 24 00 00 2A 16 

	//return false
	04 28 

//if((Actionmask & 32) != 0)
07 E2 00 9B 9C 00 6C 24 00 00 2C 20 16 25 16 

	//m_bMouseDraggingGeoscape = false
	14 2D 01 0B 24 00 00 28 

	//if(!CheckForFacilityClick())
	07 DF 00 81 1B 2E 06 00 00 00 00 00 00 16 16 

		//kHitEntity = XGEntity(bool(kHUD.CachedMouseInteractionInterface))
		0F 00 69 24 00 00 2E AF 29 00 00 38 36 19 00 68 24 00 00 09 00 D6 FB FF FF 00 01 D6 FB FF FF 

		//if(kHitEntity != none)
		07 DF 00 77 00 69 24 00 00 2A 16 

			//return HandleClickedGlobeActor(kHitEntity.m_kGameActor)
			04 1B 16 14 00 00 00 00 00 00 19 00 69 24 00 00 09 00 9B 29 00 00 00 01 9B 29 00 00 16 

//else
06 F4 01 

	//if((Actionmask & 1) != 0)
	07 F4 01 9B 9C 00 63 24 00 00 26 16 25 16 

		//kHitActor = StaticMeshActor(bool(kHUD.CachedMouseInteractionInterface))
		0F 00 6A 24 00 00 2E 94 FE FF FF 38 36 19 00 68 24 00 00 09 00 D6 FB FF FF 00 01 D6 FB FF FF 

		//if((kHitActor != none) && (kHitActor.StaticMeshComponent.StaticMesh.Name == 'Globe') || kHitActor.StaticMeshComponent.StaticMesh.Name == 'Clouds_Flowing')
		07 F4 01 82 77 00 6A 24 00 00 2A 16 18 AC 00 84 FE 19 19 19 00 6A 24 00 00 09 00 1F FE FF FF 00 01 1F FE FF FF 09 00 7C FA FF FF 00 01 7C FA FF FF 09 00 A6 FA FF FF 00 01 A6 FA FF FF 21 F9 13 00 00 00 00 00 00 16 18 54 00 FE 19 19 19 00 6A 24 00 00 09 00 1F FE FF FF 00 01 1F FE FF FF 09 00 7C FA FF FF 00 01 7C FA FF FF 09 00 A6 FA FF FF 00 01 A6 FA FF FF 21 CC 06 00 00 00 00 00 00 16 16 16 

			//m_bMouseDraggingGeoscape = true
			14 2D 01 0B 24 00 00 27 

			//return true
			04 27 

//return false
04 28 

//null ops
0B 0B 0B 0B 

//return ReturnValue
04 3A 6B 24 00 00 

//EOS
53 
[/CODE]
[/AFTER_HEX] 

 

 

 

After the change is applied the function should look like :

 

 

function bool LMouse(int Actionmask)
{
    local StaticMeshActor kHitActor;
    local XGEntity kHitEntity;
    local XComHUD kHUD;

    // End:0x21
    if(UseTouchInput())
    {
        return Touch_LMouse(Actionmask);
    }
    kHUD = GetXComHUD();
    // End:0x46
    if(kHUD == none)
    {
        return false;
    }
    // End:0xE2
    if((Actionmask & 32) != 0)
    {
        m_bMouseDraggingGeoscape = false;
        // End:0xDF
        if(!CheckForFacilityClick())
        {
            kHitEntity = XGEntity(bool(kHUD.CachedMouseInteractionInterface));
            // End:0xDF
            if(kHitEntity != none)
            {
                return HandleClickedGlobeActor(kHitEntity.m_kGameActor);
            }
        }
    }
    // End:0x1F4
    else
    {
        // End:0x1F4
        if((Actionmask & 1) != 0)
        {
            kHitActor = StaticMeshActor(bool(kHUD.CachedMouseInteractionInterface));
            // End:0x1F4
            if((kHitActor != none) && (kHitActor.StaticMeshComponent.StaticMesh.Name == 'Globe') || kHitActor.StaticMeshComponent.StaticMesh.Name == 'Clouds_Flowing')
            {
                m_bMouseDraggingGeoscape = true;
                return true;
            }
        }
    }
    return false;                
    //return ReturnValue;    
} 

 

 

 

 

Enjoy :smile:

Link to comment
Share on other sites

Fantastic work!

 

Here is PatchUPK/PatcherGUI version:

 

UPK_FILE=XComStrategyGame.upk 

// re-enable geoscape dragging
OBJECT=XComHeadquartersInput.LMouse:AUTO
[BEFORE_HEX]
01 01 00 00 C1 00 00 00 
//if(UseTouchInput())
07 21 00 1B CD 34 00 00 00 00 00 00 16 
//return Touch_LMouse(Actionmask)
04 1B 73 31 00 00 00 00 00 00 00 6C 24 00 00 16 
//kHUD = GetXComHUD()
0F 00 68 24 00 00 1B AC 13 00 00 00 00 00 00 16 
//if(kHUD == none)
07 46 00 72 00 68 24 00 00 2A 16 
	//return false
	04 28 
//if((Actionmask & 32) != 0)
07 E2 00 9B 9C 00 6C 24 00 00 2C 20 16 25 16 
	//m_bMouseDraggingGeoscape = false
	14 2D 01 0B 24 00 00 28 
	//if(!CheckForFacilityClick())
	07 DF 00 81 1B 2E 06 00 00 00 00 00 00 16 16 
		//kHitEntity = XGEntity(bool(kHUD.CachedMouseInteractionInterface))
		0F 00 69 24 00 00 2E AF 29 00 00 38 36 19 00 68 24 00 00 09 00 D6 FB FF FF 00 01 D6 FB FF FF 
		//if(kHitEntity != none)
		07 DF 00 77 00 69 24 00 00 2A 16 
			//return HandleClickedGlobeActor(kHitEntity.m_kGameActor)
			04 1B 16 14 00 00 00 00 00 00 19 00 69 24 00 00 09 00 9B 29 00 00 00 01 9B 29 00 00 16 
//else
06 F4 00 
	//if((Actionmask & 1) != 0)
	07 F4 00 9B 9C 00 6C 24 00 00 26 16 25 16 
		//return false
		04 28 
//return ReturnValue
04 3A 6B 24 00 00 
//EOS
53 
[/BEFORE_HEX]

[AFTER_HEX]
05 02 00 00 71 01 00 00 
//if(UseTouchInput())
07 21 00 1B CD 34 00 00 00 00 00 00 16 
//return Touch_LMouse(Actionmask)
04 1B 73 31 00 00 00 00 00 00 00 6C 24 00 00 16 
//kHUD = GetXComHUD()
0F 00 68 24 00 00 1B AC 13 00 00 00 00 00 00 16 
//if(kHUD == none)
07 46 00 72 00 68 24 00 00 2A 16 
	//return false
	04 28 
//if((Actionmask & 32) != 0)
07 E2 00 9B 9C 00 6C 24 00 00 2C 20 16 25 16 
	//m_bMouseDraggingGeoscape = false
	14 2D 01 0B 24 00 00 28 
	//if(!CheckForFacilityClick())
	07 DF 00 81 1B 2E 06 00 00 00 00 00 00 16 16 
		//kHitEntity = XGEntity(bool(kHUD.CachedMouseInteractionInterface))
		0F 00 69 24 00 00 2E AF 29 00 00 38 36 19 00 68 24 00 00 09 00 D6 FB FF FF 00 01 D6 FB FF FF 
		//if(kHitEntity != none)
		07 DF 00 77 00 69 24 00 00 2A 16 
			//return HandleClickedGlobeActor(kHitEntity.m_kGameActor)
			04 1B 16 14 00 00 00 00 00 00 19 00 69 24 00 00 09 00 9B 29 00 00 00 01 9B 29 00 00 16 
//else
06 F4 01 
	//if((Actionmask & 1) != 0)
	07 F4 01 9B 9C 00 63 24 00 00 26 16 25 16 
		//kHitActor = StaticMeshActor(bool(kHUD.CachedMouseInteractionInterface))
		0F 00 6A 24 00 00 2E 94 FE FF FF 38 36 19 00 68 24 00 00 09 00 D6 FB FF FF 00 01 D6 FB FF FF 
		//if((kHitActor != none) && (kHitActor.StaticMeshComponent.StaticMesh.Name == 'Globe') || kHitActor.StaticMeshComponent.StaticMesh.Name == 'Clouds_Flowing')
		07 F4 01 82 77 00 6A 24 00 00 2A 16 18 AC 00 84 FE 19 19 19 00 6A 24 00 00 09 00 1F FE FF FF 00 01 1F FE FF FF 09 00 7C FA FF FF 00 01 7C FA FF FF 09 00 A6 FA FF FF 00 01 A6 FA FF FF 21 F9 13 00 00 00 00 00 00 16 18 54 00 FE 19 19 19 00 6A 24 00 00 09 00 1F FE FF FF 00 01 1F FE FF FF 09 00 7C FA FF FF 00 01 7C FA FF FF 09 00 A6 FA FF FF 00 01 A6 FA FF FF 21 CC 06 00 00 00 00 00 00 16 16 16 
			//m_bMouseDraggingGeoscape = true
			14 2D 01 0B 24 00 00 27 
			//return true
			04 27 
//return false
04 28 
//null ops
0B 0B 0B 0B 
//return ReturnValue
04 3A 6B 24 00 00 
//EOS
53 
[/AFTER_HEX]

 

Link to comment
Share on other sites

Awesome-sauce.

 

I think I also have a fix for the Suppression "unglueing" issue that cropped up in Enemy Within -- not fixing the root cause of the problem, which seems to be buried in native code, but hacking in a check after Suppression ends (there are no less than 15 separate code conditions that can cause Suppression to end).

 

At the least I've fixed the issue with the unit being unable to use cover, but I think I've also fixed it so that units properly return to cover, but it really could stand some more testing. Once we release Long War beta 7 (which has the change) and we get some feedback, I'll post up some code. The other small issue is that it's slightly convolved with some other balance changes in terms of hex, so will need a little untangling.

Link to comment
Share on other sites

  • 5 months later...

BlackoutRogue, are you sure you're pointing the patcher to the right folder? You must install EW mods into XEW folder, not the root folder.

 

In case you really have an older game version, try this one:

 

MOD_NAME=EW Hologlobe Rotation Fix 
AUTHOR=Amineri
DESCRIPTION=Re-enables mouse left-click geoscape rotation.

Version: 1.0

Compatible with XCOM Enemy Within versions:
 - Any

UPK_FILE=XComStrategyGame.upk 

// re-enable geoscape dragging
OBJECT=XComHeadquartersInput.LMouse:AUTO
[REPLACEMENT_CODE]
//if(UseTouchInput())
07 21 00 1B <UseTouchInput> 16 
//return Touch_LMouse(Actionmask)
04 1B <Touch_LMouse> 00 <.Actionmask> 16 
//kHUD = GetXComHUD()
0F 00 <.kHUD> 1B <GetXComHUD> 16 
//if(kHUD == none)
07 46 00 72 00 <.kHUD> 2A 16 
	//return false
	04 28 
//if((Actionmask & 32) != 0)
07 E2 00 9B 9C 00 <.Actionmask> 2C 20 16 25 16 
	//m_bMouseDraggingGeoscape = false
	14 2D 01 <@m_bMouseDraggingGeoscape> 28 
	//if(!CheckForFacilityClick())
	07 DF 00 81 1B <CheckForFacilityClick> 16 16 
		//kHitEntity = XGEntity(bool(kHUD.CachedMouseInteractionInterface))
		0F 00 <.kHitEntity> 2E <Class.XGEntity> 38 36 19 00 <.kHUD> 09 00 <XComGame.XComHUD.CachedMouseInteractionInterface> 00 01 <XComGame.XComHUD.CachedMouseInteractionInterface> 
		//if(kHitEntity != none)
		07 DF 00 77 00 <.kHitEntity> 2A 16 
			//return HandleClickedGlobeActor(kHitEntity.m_kGameActor)
			04 1B <HandleClickedGlobeActor> 19 00 <.kHitEntity> 09 00 <XGEntity.m_kGameActor> 00 01 <XGEntity.m_kGameActor> 16 
//else
06 F4 01 
	//if((Actionmask & 1) != 0)
	07 F4 01 9B 9C 00 <.Actionmask> 26 16 25 16 
		//kHitActor = StaticMeshActor(bool(kHUD.CachedMouseInteractionInterface))
		0F 00 <.kHitActor> 2E <Engine.StaticMeshActor> 38 36 19 00 <.kHUD> 09 00 <XComGame.XComHUD.CachedMouseInteractionInterface> 00 01 <XComGame.XComHUD.CachedMouseInteractionInterface> 
		//if((kHitActor != none) && (kHitActor.StaticMeshComponent.StaticMesh.Name == 'Globe') || kHitActor.StaticMeshComponent.StaticMesh.Name == 'Clouds_Flowing')
		07 F4 01 82 77 00 <.kHitActor> 2A 16 18 AC 00 84 FE 19 19 19 00 <.kHitActor> 09 00 <Engine.StaticMeshActor.StaticMeshComponent> 00 01 <Engine.StaticMeshActor.StaticMeshComponent> 09 00 <Engine.StaticMeshComponent.StaticMesh> 00 01 <Engine.StaticMeshComponent.StaticMesh> 09 00 <Core.Object.Name> 00 01 <Core.Object.Name> 21 <Globe> 16 18 54 00 FE 19 19 19 00 <.kHitActor> 09 00 <Engine.StaticMeshActor.StaticMeshComponent> 00 01 <Engine.StaticMeshActor.StaticMeshComponent> 09 00 <Engine.StaticMeshComponent.StaticMesh> 00 01 <Engine.StaticMeshComponent.StaticMesh> 09 00 <Core.Object.Name> 00 01 <Core.Object.Name> 21 <Clouds_Flowing> 16 16 16 
			//m_bMouseDraggingGeoscape = true
			14 2D 01 <@m_bMouseDraggingGeoscape> 27 
			//return true
			04 27 
//return false
04 28 
//null ops
0B 0B 0B 0B 
//return ReturnValue
04 3A <.ReturnValue> 
//EOS
53 

 

Edited by wghost81
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...