Jump to content

R&D AI Improvements


Amineri

Recommended Posts

 

Is good addition, as it adds a bit of unpredictability to the game. So were are those values listed? And can we tweak them as well?

 

 

Those values are not explicitly defined via an assignment in the code, but are the default values of the alien-specific child classes of XGAIBehavior.

 

For example, the m_fMinAggro = 0.50 for the Floater is set in :

 

XGAIBehavior_Floater.default.m_fMinAggro

 

Changing these is generally what I would consider an "advanced" hex editing technique (meaning I don't have a good way to explain how I figure it out -- it's largely intuitive for me so far). I've done it twice -- once for the perk tree to set the default m_iEnergy in XGStrategySoldier to 0 instead of 100, and once in for the ammo mod to change the both which variable had a default value, and the value itself, changing :

Need to create default value of m_iTurnFired of 100 

Change XGWeapon.default.fFiringRate=1.5 into XGWeapon.default.m_iTurnFired=100

original:
02 2D 00 00 00 00 00 00 2A 2E 00 00 00 00 00 00 04 00 00 00 00 00 00 00 00 00 C0 3F 

new:
1E 4C 00 00 00 00 00 00 9D 3B 00 00 00 00 00 00 04 00 00 00 00 00 00 00 64 00 00 00 

I haven't come up with an easy way to explain how to do this... for me it's involved a lot of staring at the hex code in the UE Explorer default buffer, which is accessed through right-clicking on the main class name, selecting "view buffer" , then selecting "DefaultProperties Buffer". After a lot of staring and a lot of guess-and-check I was able to get it changed.

Link to comment
Share on other sites

  • Replies 144
  • Created
  • Last Reply

Top Posters In This Topic

XGAIBehavior_Floater.default.m_fMinAggro

Now I remember, where I have seen that before, but I should leave tinkering with this to coding experts (like you), because I'm far far away from pulling off guru stuff like that :no:.

Edited by Tycus
Link to comment
Share on other sites

Okay, here's the set of hex changes reworking the Overwatch Dangerzone calculations. Function ended up structured a bit different than planned, as I had to put some functionality into a helper function to get it all to fit.

 

I only had 4 bytes left in each, so haven't added anything relating to aggression. Might revisit it later but didn't want too many drastic changes all at once.

 

Following JL's suggestion I've taken to prefixing my renamed functions with "#" to make them more easily identifiable at a modder-renamed function.

 

Here is the hex code:

 

 

\\\\\\\\\\\\\\\\\\\\\\\\\\\Overwatch Dangerzone AI Hex Changes \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\



XGAIPlayer.DetermineOverwatchDangerZone

original hex:
header:
4D 96 00 00 50 55 00 00 00 00 00 00 2E 96 00 00 00 00 00 00 00 00 00 00 38 96 00 00 00 00 00 00 3D 04 00 00 0C 97 00 00 DD 01 00 00 51 01 00 00 

body:
07 12 00 9A 36 01 77 BB 00 00 25 16 04 25 07 4A 00 77 00 38 96 00 00 2A 16 14 2D 00 31 96 00 00 1B E0 3C 00 00 00 00 00 00 00 38 96 00 00 10 25 01 77 BB 00 00 16 58 01 77 BB 00 00 00 35 96 00 00 00 4A 7E 01 07 89 00 81 19 00 35 96 00 00 0A 00 FF 32 00 00 00 1B D1 3C 00 00 00 00 00 00 16 16 31 06 7E 01 0F 00 34 96 00 00 38 3F 90 19 00 35 96 00 00 0A 00 94 31 00 00 00 1B A6 34 00 00 00 00 00 00 16 2C 40 16 0F 00 33 96 00 00 AB 00 34 96 00 00 1B E2 30 00 00 00 00 00 00 16 16 0F 00 34 96 00 00 C2 00 34 96 00 00 16 0F 00 33 96 00 00 C2 00 33 96 00 00 16 0F 00 32 96 00 00 E4 D8 19 00 35 96 00 00 09 00 DE F8 FF FF 00 01 DE F8 FF FF 00 37 96 00 00 16 16 07 5B 01 B0 00 32 96 00 00 00 33 96 00 00 16 A5 00 30 96 00 00 16 06 7D 01 07 7D 01 B0 00 32 96 00 00 00 34 96 00 00 16 A5 00 2F 96 00 00 16 31 30 07 91 01 97 00 30 96 00 00 25 16 04 2C 03 07 A2 01 9A 00 2F 96 00 00 25 16 04 26 07 C4 01 2D 00 31 96 00 00 07 C1 01 97 00 2F 96 00 00 26 16 04 2C 03 04 2C 02 04 F9 2C 03 00 2F 96 00 00 16 04 3A 36 96 00 00 53 


new hex: (virtual 0x1D5)
header:
4D 96 00 00 50 55 00 00 00 00 00 00 2E 96 00 00 00 00 00 00 00 00 00 00 38 96 00 00 00 00 00 00 3D 04 00 00 0C 97 00 00 D5 01 00 00 51 01 00 00 

body:
07 12 00 9A 36 01 77 BB 00 00 25 16 04 25 07 4A 00 77 00 38 96 00 00 2A 16 14 2D 00 31 96 00 00 1B E0 3C 00 00 00 00 00 00 00 38 96 00 00 10 25 01 77 BB 00 00 16 0F 00 8B 99 00 00 01 4C BB 00 00 0F 01 4C BB 00 00 00 37 96 00 00 0F 00 33 96 00 00 1B E2 30 00 00 00 00 00 00 16 0F 01 4C BB 00 00 00 8B 99 00 00 0F 00 34 96 00 00 AC 38 3F 93 2C 46 19 00 38 96 00 00 0A 00 18 B3 00 00 00 1B 13 32 00 00 00 00 00 00 16 16 38 3F 2C 64 16 07 FE 00 19 00 38 96 00 00 0A 00 60 B6 00 00 00 1B 63 3D 00 00 00 00 00 00 16 B9 00 34 96 00 00 1E CD CC 4C 3E 16 B6 00 34 96 00 00 AF 38 3F 26 AB 1E CD CC 4C 3D 38 3F 1A 2C 04 19 00 38 96 00 00 09 00 0D 31 00 00 00 01 0D 31 00 00 16 16 16 0F 00 2F 96 00 00 38 44 AE AB 00 33 96 00 00 00 34 96 00 00 16 1E 67 66 66 3F 16 07 7C 01 2D 00 31 96 00 00 9F 00 2F 96 00 00 1E 00 00 00 40 16 07 C2 01 19 19 00 38 96 00 00 09 00 0A 31 00 00 00 01 0A 31 00 00 0C 00 EA A2 00 00 00 1B B8 36 00 00 00 00 00 00 2C 5F 16 A2 00 2F 96 00 00 2C 01 16 04 F9 2C 03 00 2F 96 00 00 16 0B 0B 0B 0B 53 	

-----------------

XGAIPlayer.GetAcceptableOverwatchMovementSightRadiusPercent / ###GetNumberOfOverwatchShotsFromUnitsWithinRange

original hex:
header:
42 96 00 00 50 55 00 00 00 00 00 00 2B 96 00 00 00 00 00 00 00 00 00 00 2D 96 00 00 00 00 00 00 1D 04 00 00 E0 8F 00 00 DC 00 00 00 94 00 00 00 

body: (148 storage bytes)
05 B2 9F 00 00 00 19 19 19 2E 64 2D 00 00 19 12 20 4F FE FF FF 0A 00 D8 F9 FF FF 00 1C F6 FB FF FF 16 09 00 98 F9 FF FF 00 01 98 F9 FF FF 09 00 71 2D 00 00 00 01 71 2D 00 00 09 00 A3 9C 00 00 00 01 A3 9C 00 00 09 00 B2 9F 00 00 00 01 B2 9F 00 00 0A 9C 00 25 0F 00 2C 96 00 00 1E C3 F5 28 3F 06 C7 00 0A B2 00 26 0F 00 2C 96 00 00 1E 66 66 66 3F 06 C7 00 0A FF FF 0F 00 2C 96 00 00 1E 66 66 66 3F 06 C7 00 04 00 2C 96 00 00 04 3A 2D 96 00 00 53 


new hex: (virtual 0xCC)
header:
42 96 00 00 50 55 00 00 00 00 00 00 2B 96 00 00 00 00 00 00 00 00 00 00 2D 96 00 00 00 00 00 00 1D 04 00 00 E0 8F 00 00 CC 00 00 00 94 00 00 00 

body: (148 storage bytes)
58 01 77 BB 00 00 00 35 96 00 00 00 4A BC 00 07 3F 00 81 19 00 35 96 00 00 0A 00 FF 32 00 00 00 1B D1 3C 00 00 00 00 00 00 16 16 31 06 BC 00 0F 00 32 96 00 00 E4 D8 19 00 35 96 00 00 09 00 DE F8 FF FF 00 01 DE F8 FF FF 01 4C BB 00 00 16 16 07 9A 00 B0 00 32 96 00 00 1E 00 00 C8 48 16 B8 00 2C 96 00 00 1E 00 00 C0 3F 16 06 BB 00 07 BB 00 B0 00 32 96 00 00 1E 00 40 36 4A 16 B8 00 2C 96 00 00 38 3F 26 16 31 30 04 00 2C 96 00 00 0B 0B 0B 0B 53 

----------------


variables/functions renamed:
change:
fRadiusPercent
0F 00 00 00 66 52 61 64 69 75 73 50 65 72 63 65 6E 74

to:
#fOverwatchers
0F 00 00 00 23 66 4F 76 65 72 77 61 74 63 68 65 72 73

change:
GetAcceptableOverwatchMovementSightRadiusPercent
31 00 00 00 47 65 74 41 63 63 65 70 74 61 62 6C 65 4F 76 65 72 77 61 74 63 68 4D 6F 76 65 6D 65 6E 74 53 69 67 68 74 52 61 64 69 75 73 50 65 72 63 65 6E 74

to:
###GetNumberOfOverwatchShotsFromUnitsWithinRange
31 00 00 00 23 23 23 47 65 74 4E 75 6D 62 65 72 4F 66 4F 76 65 72 77 61 74 63 68 53 68 6F 74 73 46 72 6F 6D 55 6E 69 74 73 57 69 74 68 69 6E 52 61 6E 67 65


change:
fSightRangeMed
0F 00 00 00 66 53 69 67 68 74 52 61 6E 67 65 4D 65 64

to:
#fNum_OW_Shots
0F 00 00 00 23 66 4E 75 6D 5F 4F 57 5F 53 68 6F 74 73


change:
fSightRangeMax
0F 00 00 00 66 53 69 67 68 74 52 61 6E 67 65 4D 61 78

to:
####fHitChance
0F 00 00 00 23 23 23 23 66 48 69 74 43 68 61 6E 63 65


change:
nOverwatchersInOuterRange
1A 00 00 00 6E 4F 76 65 72 77 61 74 63 68 65 72 73 49 6E 4F 75 74 65 72 52 61 6E 67 65

to:
###iExpectedOverwatchHits
1A 00 00 00 23 23 23 69 45 78 70 65 63 74 65 64 4F 76 65 72 77 61 74 63 68 48 69 74 73

 

 

 

I've tested that the code doesn't crash the game, either on startup or when the AI is executing.

 

Initial test was against a group of Mutons. They were a bit more active then they generally are.

 

I had 1 Muton suppress and then another dash forward breaking Suppression, charging toward my lines. Definitely more aggressive behavior (I suspect that this might be related to the "last alien standing" code, although he had a two friends still in his Pod, soo...)

 

Definitely would need more feedback as to how the AI play-style changes. The AI may be a bit less cautious about moving in Overwatch or breaking Suppression, so lock-down tactics will be harder to achieve generally.

Edited by Amineri
Link to comment
Share on other sites

I found a crashing bug relating to Suppression during a playthough, and I can reproduce it, but it appears to be unrelated to the AI changes from earlier in the thread.

 

Situation :

  • Two floaters remain from the pod
  • One is at 1 HP and is Suppressing my scout (who is in cover with the Low Profile perk)
  • The other is exposed and at full health, 6 HP
  • My Gunner suppresses the supressing Floater, who continues to suppress
  • The scout then shoots at the exposed floater, killing it (laser rifle)
  • 2 units move, 1 to within visual range
  • 2 units out of visual range go on overwatch

Result:

During the alien turn, the floater appears to begin to take an action and then the game crashes. Reloading and performing the same sequence of actions consistently reproduces the crash.

 

Removing all of the AI code that I've developed results in no change -- the same sequence of actions still results in the game crashing.

 

------------------

 

Changing the order slightly by suppressing the full health floater (which wasn't suppressing) and killing the suppressing unit, and having all other units perform the same actions -- game does not crash.

 

Without the new AI code in place the floater took no action

With the new AI code in place the floater shot at my unit without Tactical sense (lowest defense)

 

Is there a known issue when trying to suppress a unit that is suppressing someone else already?

Link to comment
Share on other sites

So this is a kind of specific AI change, but as there are at least three people I know of who are giving aliens passive perks (including the Low Profile perk), I thought I'd release this generally.

 

The AI has a general sort of preference for using full cover, rather like the player does ^_^. (I know I have a hard time remembering to move my Low Profile unit into low cover to free up additional full cover spots for other troops).

 

The AI was built with a function to allow units to prefer low cover instead of full cover. This function was used to make Easy and Normal easier. The default for all units' XGAIBehavior.PrefersLowCover() function was to return false. However, on Easy and Normal difficulties both Sectoids and Thin Men were set to return true, which made them generally easier targets on these two difficulties, making the early game just a bit easier.

 

I've re-purposed these functions (snagging an unused boolean variable to do so) to make the AI handle units with Low Profile appropriately. Simple enough : units with Low Profile prefer low cover.

 

Generally aliens are granted perks through the old XGunit.DebugAnims function (which I've renamed UpgrdAliens). This mod will require setting a boolean variable for such aliens.

 

Here are the set of changes to XGAIBehavior (and its child classes) to get the AI to use the boolean:

 

 

to change variable name use :
original:
m_bCallResponse
10 00 00 00 6D 5F 62 43 61 6C 6C 52 65 73 70 6F 6E 73 65 

new:
m_bPrefLowCover
10 00 00 00 6D 5F 62 50 72 65 66 4C 6F 77 43 6F 76 65 72


---------------------

Changes to make PrefersLowCover() to use the new variable

XGAIBehavior.PrefersLowCover
original hex:
return false; return ReturnValue; EOS
04 28 04 3A 0A 8C 00 00 53 

new hex:
return m_bPrefLowCover; EOS
04 2D 01 D7 8A 00 00 0B 53 


-----------

Make the two over-riding functions simply return super.PrefersLowCover, as the specific behavior per alien isn't needed.

XGAIBehavior_Sectoid.PrefersLowCover
original:
return false; return ReturnValue; EOS
04 28 04 3A 7F 92 00 00 53 

new:
return super.PrefersLowCover(); EOS
04 1C 0B 8C 00 00 16 0B 53 


XGAIBehavior_ThinMan.PrefersLowCover
original:
return false ; return ReturnValue; EOS
04 28 04 3A 40 93 00 00 53 

new:
return super.PrefersLowCover(); EOS
0B 04 1C 0B 8C 00 00 16 53  

 

 

 

This doesn't alter the difficulty adjustment overrides for Easy and Normal (which have been changed to Easy-only in Long War).

 

For example, XGAIBehavior_Sectoid (in Long War) after the change reads:

function bool PrefersLowCover()
{
    if(XComTacticalGRI(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kBattle.GetDifficulty() < 1)
    {
        return true;
    }
    return super(XGAIBehavior).PrefersLowCover();        
}

The parent function simply returns the boolean variable :

function bool PrefersLowCover()
{
    return m_bPrefLowCover;        
}

I didn't explicitly set a default value for m_bPrefLowCover, as the default value should be false.

 

------------------

 

To set the new boolean value to true for aliens with Low Profile requires the hex line:

m_kBehavior.m_bPrefLowCover = true;
14 19 01 D9 30 00 00 0A 00 D7 8A 00 00 00 2D 01 D7 8A 00 00 27 

This line will only work when used within the XGUnit class.

Link to comment
Share on other sites

  • 2 weeks later...

I've decided to start working again on "fixing" some of the undesirable teleporting behavior.

 

The "teleporting" is implemented through the function XGAIBehavior.WarpTo.

 

I say "undesirable" behavior because many of the places WarpTo are called are to handle various error conditions. For example, in XGAIBehavior.MoveTo (which is the principal function for "normal" movement of alien units), WarpTo shows up in the following circumstance :

    if(!XComTacticalGRI(WorldInfo.GRI).IsValidLocation(m_kUnit.Location, m_kUnit))
    {
        WarpTo(XComTacticalGRI(WorldInfo.GRI).GetClosestValidLocation(m_kUnit.Location, m_kUnit, m_kUnit.m_bIsFlying, false));
    }

This teleports the unit to the closest valid location if it's currently location isn't valid.

 

This helps prevent issues like uncompletable missions because the last alien is stuck inside a wall and can't be damaged, and can't move. In such a case the alien unit will be teleported to the nearest "safe" location and the game can be continued.

 

WarpTo is also used to implement the functionality of the Floater Launch command, as well as the alien drop-ins (I think) during special missions.

 

-----------------------

 

The two principal cases I see of WarpTo being used to speed up the alien turns, and that can cause problems :

 

1) XComAlienPod.InitMoveManeuver

 

This function is what maneuvers a pod around the map. This is how any patrolling aliens move before they are revealed. Instead of one at a time they are moved as an entire pod.

 

This function also has error checking that is fixed through WarpTo:

    if(!XComTacticalGRI(WorldInfo.GRI).IsValidLocation(vOffset, kUnit, true, true) || !class'XComWorldData'.static.GetWorldData().IsPositionOnFloor(vOffset))
    {
        vDestination = XComTacticalGRI(WorldInfo.GRI).GetClosestValidLocation(vOffset, kUnit, false, false, true);
        kUnit.m_kBehavior.WarpTo(vDestination);
    }

which shouldn't be changed.

 

The function has quite a bit of somewhat complicated code that picks the destination, invokes the path manager to find a path to that destination, then tries to see whether or not that path will cause the pod to be revealed.

 

Ultimately the pod is moved via the call :

WalkPodToLocation(Location, !bReveal);

The WalkPodToLocation uses the second parameter as an indicator of whether it should teleport the pod or do the "simultaneous move". So the code is set up that any pod that will not be revealed by its move will be teleported to it's destination.

 

My first attempt to change this was a pretty straightforward change, which was :

	change:
	WalkPodToLocation(Location, !bReveal);
	
	to
	WalkPodToLocation(Location, false);
	bReveal;
	
	original:
	1B 54 71 00 00 00 00 00 00 01 DE F8 FF FF 81 2D 00 59 39 00 00 16 16
	
	new:
	1B 54 71 00 00 00 00 00 00 01 DE F8 FF FF 28 16 2D 00 59 39 00 00 0B 

This basically forced the game to always disallow warping of alien pods during movement and instead perform the simultaneous move, regardless of whether the aliens can be seen or not. Because the game goes through the timings for animating the movement even though it is hidden in the fog of war, this can make alien turns last a bit longer.

 

 

---------------------------

 

2) XGAIBehavior.MoveToPoint

 

This function is what moves individual units. That is, after a pod becomes active, each alien unit in the pod has to move one at a time, and this is the function that handles that.

 

This function has some complex logic that enables aliens to use WarpTo to skip past portion of its path that are not visible to an enemy unit. This happens in two stages.

 

The first step is to check whether the entire path is visible, using :

            if(IsPathVisible(vDestination, vWarpTo))
            {
                bHiddenMovement = false;
            }

followed by:

        if(!bHiddenMovement)
        {
            <more complex stuff in here>
        }
        else
        {
            WarpTo(vDestination);
        }

The inner portion executed if(!bHiddenMovement) is what attempts to allow the alien unit to move along the portion of its path that is hidden from view.

 

This code looks basically like so:

            if(VSizeSq2D(vWarpTo) > float(0))
            {
                WarpTo(vWarpTo);
                ComputePathTo(vDestination, true, false, m_bMoveToActionPoint, true);
            }
            <excised code for civilians>
            XComTacticalController(GetALocalPlayerController()).PerformPath(m_kUnit);
            bUsedEndMoveAction = true;

I think what is happening is that the IsPathVisible function is returning what it thinks is the initial portion of the path that is hidden from view. If the size of this path is non-zero, then the game teleports the unit to the location, then computes a new path from the new location to the final vDestination.

 

It then calls PerformPath to move the unit along the defined path for the unit.

 

My hex change for this function was two-fold:

1) Force the code to execute the first branch of conditional (disallowing any complete teleports even if the entire path isn't visible)

2) Force the code to skip the WarpTo the "safe" point computed by IsPathVisible and instead force it to call PerformPath on the entire path.

 

These two changes were implemented via this hex change :

	original: (from if(!bHiddenMovement) to if(VSizeSq2D(vWarpTo) < float(0))
	07 F7 04 81 2D 00 18 8D 00 00 16 07 64 04 B1 1C 8B FC FF FF 00 13 8D 00 00 16 38 3F 25 16 
	
	new:
	07 F7 04 28 2D 00 18 8D 00 00 0B 07 64 04 B0 1C 8B FC FF FF 00 13 8D 00 00 16 38 3F 25 16 

This changes just part of the conditional, from :

        if(!bHiddenMovement)
        {
            if(VSizeSq2D(vWarpTo) > float(0))

to:

        if(true) // always evaluate this branch
        {
            bHiddenMovement // preserve virtual size
            if(VSizeSq2D(vWarpTo) < float(0))  //disable this conditional

-------------------------------

 

The issues with this were :

a) longer alien turns

b) teleporting from flanked + overwatched aliens

 

I'm going to be testing each of these individually in Long War 1.91, (which fixes a divide-by-zero error that was present for flanked+overwatched aliens) and see how each individually affects the alien turn length, as well as if there is any undesirable teleporting.

 

Ideally the first change should prevent units spotted with battlescanners from teleporting away after beginning their patrol.

 

Any help with testing this would be most appreciated.

Link to comment
Share on other sites

Hi again, Amineri. I'm currently playing with your AI improvements and want to post a feedback and some suggestions.

I think the idea of warping pods around isn't terrible by itself, it's the logical flaws in the code which make it terrible.

Some time ago I knew nothing about beta patch 4, so I played with patch 3 and hunker-down-teleport bug was very annoying. I've got so desperate, that I tried to look through decompiled code, was able to understand some things, but unable to change anything. But I came to understand that warping isn't really so terrible idea if it used properly.

Vanila game with patch 4 fixed hunker-down teleports, but introduced flanked+overwatched teleports. And nothing was done about "soft" teleports when alien teleport at the edge of your view radius, teleport back and activate.

Using your AI fixes removes flanked+overwatched teleports, because aliens no longer "stuck" in this situation. And using your patrol distance modification (from 40 to 20) minimized "soft" teleporting for me — I saw it only once since then.

In fact, I saw only one annoying teleport in my last playthrough: a Cyberdisc was stuck in the wall behind a corner two tiles away from my assault. When it got activated, it teleported to the different side of the map! That was really annoying. I thought warping algorithm for "stuck" situations was supposed to look for the nearest valid point.

I think, the reason for remaining teleporting bugs is random pod members placing algorithm, not the warping. If I understand this correctly, the engine calculates visibility for one central point — the pod central location — and then randomly places actual pod members around that point. The total randomness of the process sometimes causes an alien to appear inside a wall, or place one alien on the other side of a wall than the others where he suddenly becomes visible and activates. I think this is the actual reason for "soft" teleporting and for teleporting away during the player's turn after activation. If something can be done about this placing algorithm, like check for valid position and/or visibility check for actual placing point and not only the central one, it should eliminate teleporting bug altogether.

And another little observation about "stupid" AI behaviour. It happens on vanilla too. The perfect way to make an alien flank himself is to hide from his view behind some long hard cover. It's almost guarantee to have alien take wrong cover, which puts him in flank, even on impossible.

Edited by wghost81
Link to comment
Share on other sites

Hi, I have run into a weird issue when changing the 'Overwatch Dangerzone calculations' changes from your post above. It is not a problem with your mod, rather a weird code difference from your original and mine (see below). I'm not sure how to proceed, the offset and length are the same, but the function hex-code has a different tail.

 

Here's the relevant code from your post:

 

 

XGAIPlayer.GetAcceptableOverwatchMovementSightRadiusPercent / ###GetNumberOfOverwatchShotsFromUnitsWithinRange

original hex:
header:
42 96 00 00 50 55 00 00 00 00 00 00 2B 96 00 00 00 00 00 00 00 00 00 00 2D 96 00 00 00 00 00 00 1D 04 00 00 E0 8F 00 00 DC 00 00 00 94 00 00 00 

body: (148 storage bytes)
05 B2 9F 00 00 00 19 19 19 2E 64 2D 00 00 19 12 20 4F FE FF FF 0A 00 D8 F9 FF FF 00 1C F6 FB FF FF 16 09 00 98 F9 FF FF 00 01 98 F9 FF FF 09 00 71 2D 00 00 00 01 71 2D 00 00 09 00 A3 9C 00 00 00 01 A3 9C 00 00 09 00 B2 9F 00 00 00 01 B2 9F 00 00 0A 9C 00 25 0F 00 2C 96 00 00 1E C3 F5 28 3F 06 C7 00 0A B2 00 26 0F 00 2C 96 00 00 1E 66 66 66 3F 06 C7 00 0A FF FF 0F 00 2C 96 00 00 1E 66 66 66 3F 06 C7 00 04 00 2C 96 00 00 04 3A 2D 96 00 00 53 


new hex: (virtual 0xCC)
header:
42 96 00 00 50 55 00 00 00 00 00 00 2B 96 00 00 00 00 00 00 00 00 00 00 2D 96 00 00 00 00 00 00 1D 04 00 00 E0 8F 00 00 CC 00 00 00 94 00 00 00 

body: (148 storage bytes)
58 01 77 BB 00 00 00 35 96 00 00 00 4A BC 00 07 3F 00 81 19 00 35 96 00 00 0A 00 FF 32 00 00 00 1B D1 3C 00 00 00 00 00 00 16 16 31 06 BC 00 0F 00 32 96 00 00 E4 D8 19 00 35 96 00 00 09 00 DE F8 FF FF 00 01 DE F8 FF FF 01 4C BB 00 00 16 16 07 9A 00 B0 00 32 96 00 00 1E 00 00 C8 48 16 B8 00 2C 96 00 00 1E 00 00 C0 3F 16 06 BB 00 07 BB 00 B0 00 32 96 00 00 1E 00 40 36 4A 16 B8 00 2C 96 00 00 38 3F 26 16 31 30 04 00 2C 96 00 00 0B 0B 0B 0B 53 

 

 

 

 

And this is a comparison between your original hex body (top) and mine (bottom):

 

 

 

your body: (148 storage bytes)
05 B2 9F 00 00 00 19 19 19 2E 64 2D 00 00 19 12 20 4F FE FF FF 0A 00 D8 F9 FF FF 00 1C F6 FB FF FF 16 09 00 98 F9 FF FF 00 01 98 F9 FF FF 09 00 71 2D 00 00 00 01 71 2D 00 00 09 00 A3 9C 00 00 00 01 A3 9C 00 00 09 00 B2 9F 00 00 00 01 B2 9F 00 00 0A 9C 00 25 0F 00 2C 96 00 00 1E C3 F5 28 3F 06 C7 00 0A B2 00 26 0F 00 2C 96 00 00 1E 66 66 66 3F 06 C7 00 0A FF FF 0F 00 2C 96 00 00 1E 66 66 66 3F 06 C7 00 04 00 2C 96 00 00 04 3A 2D 96 00 00 53

my body: (148 storage bytes)
05 B2 9F 00 00 00 19 19 19 2E 64 2D 00 00 19 12 20 4F FE FF FF 0A 00 D8 F9 FF FF 00 1C F6 FB FF FF 16 09 00 98 F9 FF FF 00 01 98 F9 FF FF 09 00 71 2D 00 00 00 01 71 2D 00 00 09 00 A3 9C 00 00 00 01 A3 9C 00 00 09 00 B2 9F 00 00 00 01 B2 9F 00 00 0A 9C 00 25 0F 00 2C 96 00 00 1E C3 F5 28 3F 06 C7 00 0A B2 00 26 0F 00 2C 96 00 00 1E 00 00 40 3F 06 C7 00 0A FF FF 0F 00 2C 96 00 00 1E 66 66 66 3F 06 C7 00 04 00 2C 96 00 00 04 3A 2D 96 00 00 53

 

 

 

As you can see, in my non-modified, decompressed XcomGame.upk, the original body hex-code (0x8368FB) is a bit different at the almost-end of the string. I'd appreciate any input on why this could be so.

 

Meanwhile, I'll make the changes anyway and see what happens. For science :tongue:

 

 

Edit: It actually looks the freaking same when I post it like that, but it isn't... it is subtle, a few changed bytes here and there, and there might also be an logic-order swap. Can't say without looking at the actual code, but it seems to be largely the same save for some minor tweaks.

 

Edit2: I actually had a save with two soldiers in overwatch, one of them flanking three aliens, and another two solidiers out of moves but also in their visual range. Aliens repositioned and managed to kill one and injure another. My two soldiers missed like the suckers they are, but it was very nice seeing that exploit gone. I'll report if I see something weird.

 

 

http://i.imgur.com/qZXHR9l.jpg

 

Edited by FogGene
Link to comment
Share on other sites

The hex difference was between: 1E 66 66 66 3F (mine) and 1E 00 00 40 3F (yours). The 0x1E is the float constant token.

 

1E 66 66 66 3F is very slightly less than 0.90 (IEEE hex value 0x3F666666)

1E 00 00 40 3F is 0.75

 

In my original code the 0.90 was being used to set the boundary between close and long range overwatchers to 90% of visual range, while your appears to be using 75%, which would make it harder to lock down aliens using overwatch.

 

--------------

 

So far from my own playthroughs and watching videos of others playing with the changes it seems that the AI is a bit more aggressive about moving when there is overwatch fire, but not stupidly so. Using a single overwatcher doesn't appear to be locking large numbers of aliens in place any longer generally. However, having a large number of overwatchers the AI does avoid movement and shoots instead, which I think is probably the right choice.

 

Some units explicitly ignore overwatch (as in vanilla) -- in particular Zombies, Chryssalids and Sectopods ignore it completely.

Link to comment
Share on other sites

Ah that explains it then. I repeated the scene but this time killed a couple of those aliens in the screenie above and left the survivor on overwatch by two soldiers. The surviving alien didn't move on its turn, but still took a shot at one of the flankers, so it seems to be coherent with your explanation. Thanks for the tweaks mate, it's a very nice improvement over vanilla.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...