Jump to content

Mimetic Skin perk rebalancing


Amineri

Recommended Posts

I've been working on some changes to the Mimetic Skin perk to keep it from being quite so overpowered, and have managed to mod it to the following conditions:

 

1) Mimetic skin only work in full cover. Low Profile no longer allows it to work with Low Cover.

2) The unit must not be seen when it starts moving or it loses stealth.

3) If the unit moves to a flanked position the unit lose stealth after arriving (stealth will last while the unit is moving, however).

4) If an enemy unit moves to a flanking position, the unit immediately loses stealth. The flanking unit can immediately shoot/take other action if it has remaining actions.

 

For Long War we're also strongly considering moving Mimetic Skin perk into the psi tree as a fairly high-level perk (probably rank 5), which would limit it's availability.

 

Here are the three upk_mod files I used to implement the change:

 

 

MODFILEVERSION=4
UPKFILE=XComGame.upk
GUID=5B 06 B8 18 67 22 12 44 85 9B A8 5B 9D 57 1D 4B // XComGame_EW_patch1.upk
FUNCTION=CheckMimeticSkinForUnhide@XGUnitNativeBase

// allow flanking to break mimetic skin
// disallow synergy with low profile (full cover is always required)

[BEFORE_HEX]
[HEADER]
58 01 00 00 F4 00 00 00 
[/HEADER]
[CODE]
//if((IsHiding(self)) && m_kCharacter.m_kChar.aUpgrades[95] > 0)
07 55 01 82 1B AA 44 00 00 00 00 00 00 17 16 18 38 00 97 1A 2C 5F 35 54 0F 00 00 58 0F 00 00 00 00 19 01 35 3A 00 00 09 00 E8 B5 00 00 00 01 E8 B5 00 00 25 16 16 

	//bMimeticValid = class'XComWorldData'.static.GetWorldData().IsLocationHighCover(m_kPawn.Location) || class'XComWorldData'.static.GetWorldData().IsLocationLowCover(m_kPawn.Location) && m_kCharacter.m_kChar.aUpgrades[5] > 0
	14 2D 00 01 3B 00 00 84 19 12 20 2A 0C 00 00 0A 00 A9 D0 00 00 00 1B EA 3B 00 00 00 00 00 00 16 28 00 CD D0 00 00 00 1B 06 45 00 00 00 00 00 00 19 01 34 3A 00 00 09 00 9E F8 FF FF 00 01 9E F8 FF FF 16 18 90 00 82 19 12 20 2A 0C 00 00 0A 00 A9 D0 00 00 00 1B EA 3B 00 00 00 00 00 00 16 28 00 D0 D0 00 00 00 1B 07 45 00 00 00 00 00 00 19 01 34 3A 00 00 09 00 9E F8 FF FF 00 01 9E F8 FF FF 16 18 38 00 97 1A 2C 05 35 54 0F 00 00 58 0F 00 00 00 00 19 01 35 3A 00 00 09 00 E8 B5 00 00 00 01 E8 B5 00 00 25 16 16 16 

	//if(!bMimeticValid)
	07 55 01 81 2D 00 01 3B 00 00 16 

		//Unhide()
		1C 78 37 00 00 16 

//return
04 0B 

//EOS
53 

[/CODE]
[/BEFORE_HEX]


[AFTER_HEX]
[HEADER]
30 01 00 00 F4 00 00 00 
[/HEADER]
[CODE]
//if((IsHiding(self)) && m_kCharacter.m_kChar.aUpgrades[95] > 0)
07 DF 00 82 1B AA 44 00 00 00 00 00 00 17 16 18 38 00 97 1A 2C 5F 35 54 0F 00 00 58 0F 00 00 00 00 19 01 35 3A 00 00 09 00 E8 B5 00 00 00 01 E8 B5 00 00 25 16 16 

	//if(class'XComWorldData'.static.GetWorldData().IsLocationHighCover(m_kPawn.Location))
	07 D5 00 19 12 20 2A 0C 00 00 0A 00 A9 D0 00 00 00 1B EA 3B 00 00 00 00 00 00 16 28 00 CD D0 00 00 00 1B 06 45 00 00 00 00 00 00 19 01 34 3A 00 00 09 00 9E F8 FF FF 00 01 9E F8 FF FF 16 

		//if(!XGUnit(self).IsCoverExposed(GetCoverPoint(),,,,))
		07 D5 00 81 19 2E 22 CC 00 00 17 18 00 6B C8 00 00 00 1B 3C 44 00 00 00 00 00 00 1C 4D 36 00 00 16 4A 4A 4A 4A 16 16 

			//return
			04 0B 

	//Unhide()
	1C 78 37 00 00 16 

//return
04 0B 

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

//EOS
53 
[/CODE]
[/AFTER_HEX]
MODFILEVERSION=4
UPKFILE=XComGame.upk
GUID=5B 06 B8 18 67 22 12 44 85 9B A8 5B 9D 57 1D 4B // XComGame_EW_patch1.upk
FUNCTION=ProcessNewPosition@XGUnit

// add call to CheckMimeticSkinForUnhide after soldier enters a new position
// make room for call by allowing ePerk_DistortionField to work for the unit with the ability

[BEFORE_HEX]
[HEADER]

[/HEADER]
[CODE]
//start 0x54
//if(GetCharacter().HasUpgrade(146))
07 25 01 19 1B 8F 37 00 00 00 00 00 00 16 0C 00 14 B6 00 00 00 1B 55 3D 00 00 00 00 00 00 2C 92 16 

	//iSquad = 0
	0F 00 B0 C3 00 00 25 

	//if(iSquad < GetSquad().GetNumMembers())
	07 25 01 96 00 B0 C3 00 00 19 1B 34 3B 00 00 00 00 00 00 16 0A 00 8C BF 00 00 00 1B FC 39 00 00 00 00 00 00 16 16 

		//kSquadmate = GetSquad().GetMemberAt(iSquad)
		0F 00 B1 C3 00 00 19 1B 34 3B 00 00 00 00 00 00 16 13 00 8E BF 00 00 00 1B 89 39 00 00 00 00 00 00 00 B0 C3 00 00 16 

		//if(kSquadmate == self)
		07 F7 00 72 00 B1 C3 00 00 17 16 

		//else
		06 17 01 

			//kSquadmate.UpdateCoverBonuses(none)
			19 00 B1 C3 00 00 0B 00 00 00 00 00 00 1B 55 7A 00 00 00 00 00 00 2A 16 

		//++ iSquad
		A5 00 B0 C3 00 00 16 

		//while loop
		06 84 00 

//0b
[/CODE]
[/BEFORE_HEX]


[AFTER_HEX]
[HEADER]

[/HEADER]
[CODE]
//start 0x54
//if(m_kCharacter.HasUpgrade(146))
07 12 01 19 01 35 3A 00 00 0C 00 14 B6 00 00 00 1B 55 3D 00 00 00 00 00 00 2C 92 16 

	//iSquad = 0
	0F 00 B0 C3 00 00 25 

	//if(iSquad < GetSquad().GetNumMembers())
	07 12 01 96 00 B0 C3 00 00 19 1B 34 3B 00 00 00 00 00 00 16 0A 00 8C BF 00 00 00 1B FC 39 00 00 00 00 00 00 16 16 

		//kSquadmate = GetSquad().GetMemberAt(iSquad)
		0F 00 B1 C3 00 00 19 1B 34 3B 00 00 00 00 00 00 16 13 00 8E BF 00 00 00 1B 89 39 00 00 00 00 00 00 00 B0 C3 00 00 16 

		//kSquadmate.UpdateCoverBonuses(none)
		19 00 B1 C3 00 00 0B 00 00 00 00 00 00 1B 55 7A 00 00 00 00 00 00 2A 16 

		//++ iSquad
		A5 00 B0 C3 00 00 16 

		//while loop
		06 83 00 

//CheckMimeticSkinForUnhide()
1B 68 12 00 00 00 00 00 00 16 

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

//0b
[/CODE]
[/AFTER_HEX] 
MODFILEVERSION=4
UPKFILE=XComGame.upk
GUID=5B 06 B8 18 67 22 12 44 85 9B A8 5B 9D 57 1D 4B // XComGame_EW_patch1.upk
FUNCTION=UpdateMeleeEnemiesInRange@XGUnit

// add call to test all enemy soldiers to remove stealth

[BEFORE_HEX]
[HEADER]
E1 01 00 00 59 01 00 00 
[/HEADER]
[CODE]
//UpdateCiviliansInRange()
1B 48 7A 00 00 00 00 00 00 16 

//kEnemySquad = XComTacticalGRI(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kBattle.GetEnemySquad(m_kPlayer)
0F 00 B9 C3 00 00 19 19 2E BD 32 00 00 19 12 20 36 FE FF FF 0A 00 9E F9 FF FF 00 1C DE FB FF FF 16 09 00 5C F9 FF FF 00 01 5C F9 FF FF 09 00 C9 32 00 00 00 01 C9 32 00 00 13 00 BE AE 00 00 00 1B 60 38 00 00 00 00 00 00 01 D4 C2 00 00 16 

//if(kEnemySquad == none)
07 96 00 72 00 B9 C3 00 00 2A 16 

	//return
	04 0B 

//kEnemy = kEnemySquad.GetNextGoodMember(none, true, false)
0F 00 B8 C3 00 00 19 00 B9 C3 00 00 11 00 3F C0 00 00 00 1B D7 39 00 00 00 00 00 00 2A 27 28 4A 4A 4A 4A 16 

//if(kEnemy != none)
07 B2 01 77 00 B8 C3 00 00 2A 16 

	//if(kEnemy.IsAliveHealthyAndActive() && kEnemy.IsMeleeOnly())
	07 77 01 82 19 00 B8 C3 00 00 0B 00 77 C8 00 00 00 1B F0 43 00 00 00 00 00 00 4A 16 18 20 00 19 00 B8 C3 00 00 0A 00 83 3A 00 00 00 1B 18 45 00 00 00 00 00 00 16 16 

		//if(!kEnemy.IsInEngagementRange(self))
		07 77 01 81 19 00 B8 C3 00 00 0B 00 08 C6 00 00 00 1B CC 44 00 00 00 00 00 00 17 16 16 

			//kEnemy.RemoveEngagingEnemy(self)
			19 00 B8 C3 00 00 0B 00 00 00 00 00 00 1C 30 37 00 00 17 16 

			//arrRemoveList.AddItem(kEnemy)
			55 00 B7 C3 00 00 0A 00 00 B8 C3 00 00 16 

	//kEnemy = kEnemySquad.GetNextGoodMember(kEnemy, true, false)
	0F 00 B8 C3 00 00 19 00 B9 C3 00 00 19 00 3F C0 00 00 00 1B D7 39 00 00 00 00 00 00 00 B8 C3 00 00 27 28 4A 4A 4A 4A 16 

	//while loop
	06 C6 00 

//foreach arrRemoveList(kEnemy,)
58 00 B7 C3 00 00 00 B8 C3 00 00 00 4A DD 01 

	//RemoveEnemyEngagedBy(kEnemy)
	1B E4 67 00 00 00 00 00 00 00 B8 C3 00 00 16 

	//IN
	31 

	//IP
	30 
	
//return
04 0B 

//EOS
53 

[/CODE]
[/BEFORE_HEX]


[AFTER_HEX]
[HEADER]
D9 01 00 00 59 01 00 00 
[/HEADER]
[CODE]
//UpdateCiviliansInRange()
1B 48 7A 00 00 00 00 00 00 16 

//kEnemySquad = XComTacticalGRI(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kBattle.GetEnemySquad(m_kPlayer)
0F 00 B9 C3 00 00 19 19 2E BD 32 00 00 19 12 20 36 FE FF FF 0A 00 9E F9 FF FF 00 1C DE FB FF FF 16 09 00 5C F9 FF FF 00 01 5C F9 FF FF 09 00 C9 32 00 00 00 01 C9 32 00 00 13 00 BE AE 00 00 00 1B 60 38 00 00 00 00 00 00 01 D4 C2 00 00 16 

//if(kEnemySquad == none)
07 96 00 72 00 B9 C3 00 00 2A 16 

	//return
	04 0B 

//kEnemy = kEnemySquad.GetNextGoodMember(none, true, false)
0F 00 B8 C3 00 00 19 00 B9 C3 00 00 11 00 3F C0 00 00 00 1B D7 39 00 00 00 00 00 00 2A 27 28 4A 4A 4A 4A 16 

//if(kEnemy != none)
07 CE 01 77 00 B8 C3 00 00 2A 16 

	//kEnemy.CheckMimeticSkinForUnhide()
	19 00 B8 C3 00 00 0A 00 00 00 00 00 00 1B 68 12 00 00 00 00 00 00 16 

	//if(kEnemy.IsAliveHealthyAndActive() && kEnemy.IsMeleeOnly())
	07 93 01 82 19 00 B8 C3 00 00 0B 00 77 C8 00 00 00 1B F0 43 00 00 00 00 00 00 4A 16 18 20 00 19 00 B8 C3 00 00 0A 00 83 3A 00 00 00 1B 18 45 00 00 00 00 00 00 16 16 

		//if(!kEnemy.IsInEngagementRange(self))
		07 93 01 81 19 00 B8 C3 00 00 0B 00 08 C6 00 00 00 1B CC 44 00 00 00 00 00 00 17 16 16 

			//kEnemy.RemoveEngagingEnemy(self)
			19 00 B8 C3 00 00 0B 00 00 00 00 00 00 1C 30 37 00 00 17 16 

			//RemoveEnemyEngagedBy(kEnemy)
			1B E4 67 00 00 00 00 00 00 00 B8 C3 00 00 16 

	//kEnemy = kEnemySquad.GetNextGoodMember(kEnemy, true, false)
	0F 00 B8 C3 00 00 19 00 B9 C3 00 00 19 00 3F C0 00 00 00 1B D7 39 00 00 00 00 00 00 00 B8 C3 00 00 27 28 4A 4A 4A 4A 16 

	//while loop
	06 C6 00 

//return
04 0B 

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

//EOS
53 

[/CODE]
[/AFTER_HEX] 

 

 

 

1) XGUnitNativeBase.CheckMimeticSkinForUnhide -- alters the base conditions for revealing (not in full cover, or in cover but position is flanked)

2) XGUnit.ProcessNewPosition -- adds check to CheckMimeticSkinForUnhide after unit has finished movement

3) XGUnit.UpdateMeleeEnemiesInRange -- a convenient place to reveal mimetic stealthed units on the enemy team after movement.

 

I think mimetic skin is still powerful but I think with these changes it's no longer quite so overwhelmingly so.

 

I'm going to look into making similar changes to the stealth effect from ghost armor (the difference there is that you can activate stealth while in view of an enemy, but it only lasts 1 turn and with a limited number of charges).

Link to comment
Share on other sites

Amineri, could stealth effect be removed from mimetic skin and ghost armor altogether? I've always wanted to turn it into defense bonus, as invisibility is bad for current game mechanics, IMO. I realize there are number of defense bonuses in game, especially in EW, and it still needs to be balanced, but I want to try it anyway.
Link to comment
Share on other sites

I've been working on some changes to the Mimetic Skin perk to keep it from being quite so overpowered, and have managed to mod it to the following conditions:

 

1) Mimetic skin only work in full cover. Low Profile no longer allows it to work with Low Cover.

2) The unit must not be seen when it starts moving or it loses stealth.

3) If the unit moves to a flanked position the unit lose stealth after arriving (stealth will last while the unit is moving, however).

4) If an enemy unit moves to a flanking position, the unit immediately loses stealth. The flanking unit can immediately shoot/take other action if it has remaining actions.

 

(...)

 

I think mimetic skin is still powerful but I think with these changes it's no longer quite so overwhelmingly so.

 

I'm going to look into making similar changes to the stealth effect from ghost armor (the difference there is that you can activate stealth while in view of an enemy, but it only lasts 1 turn and with a limited number of charges).

 

1) Sounds very good

2) Isn't it what happens already with Mimetic Skin? If an alien has LoS on the unit it loses stealth if it moves?

3) Also makes sense

4) This may be a little extreme since it poses a huge risk when advancing and most likely will mean that Mimetic will only be used by scout units or to position soldiers for a kill. A matter of testing though.

 

About Ghost armor, do you mean that the stealth will only last during the soldiers turn (i.e. disappears when the alien turn starts?). Limited charges (2 rather than 4) would be very good.

Link to comment
Share on other sites

Do aliens get any type of "Bioelectric Skin" skill? That would be a good counter, perhaps enhancing a grenade with an skill to do a 3x3 AoE that uncovers any hidden operatives (without damage or something), or give electric skin to leaders and navigators so they can check around them in a given area.

Link to comment
Share on other sites

Amineri, could stealth effect be removed from mimetic skin and ghost armor altogether? I've always wanted to turn it into defense bonus, as invisibility is bad for current game mechanics, IMO. I realize there are number of defense bonuses in game, especially in EW, and it still needs to be balanced, but I want to try it anyway.

 

The to-hit value calculation appears to be buried somewhere in native code, which makes it a bit tricky to change. There are already a ton of perks that grant defense modifiers (like Tactical Sense, Telekinetic Field, Distortion Field, etc), so I like the general concept of stealth. As Mr. Gupta pointed out, though, balancing stealth is quite tricky.

 

That said, following how bonuses are granted for MindMerge, what you'd do is temporarily add to the m_aInventoryStat[2] when the unit stealths and remove from m_aInventoryStat[2] when it destealths -- replacing the usual stealth / Unhide() calls. You might also need to call LoadoutChanged_UpdateModifiers() in order to properly update the inventory stats into the current stats.

Link to comment
Share on other sites

 

I've been working on some changes to the Mimetic Skin perk to keep it from being quite so overpowered, and have managed to mod it to the following conditions:

 

1) Mimetic skin only work in full cover. Low Profile no longer allows it to work with Low Cover.

2) The unit must not be seen when it starts moving or it loses stealth.

3) If the unit moves to a flanked position the unit lose stealth after arriving (stealth will last while the unit is moving, however).

4) If an enemy unit moves to a flanking position, the unit immediately loses stealth. The flanking unit can immediately shoot/take other action if it has remaining actions.

 

(...)

 

I think mimetic skin is still powerful but I think with these changes it's no longer quite so overwhelmingly so.

 

I'm going to look into making similar changes to the stealth effect from ghost armor (the difference there is that you can activate stealth while in view of an enemy, but it only lasts 1 turn and with a limited number of charges).

 

1) Sounds very good

2) Isn't it what happens already with Mimetic Skin? If an alien has LoS on the unit it loses stealth if it moves?

3) Also makes sense

4) This may be a little extreme since it poses a huge risk when advancing and most likely will mean that Mimetic will only be used by scout units or to position soldiers for a kill. A matter of testing though.

 

About Ghost armor, do you mean that the stealth will only last during the soldiers turn (i.e. disappears when the alien turn starts?). Limited charges (2 rather than 4) would be very good.

 

 

#2 is indeed the current vanilla mechanic ... I was simply restating the complete set of conditions.

 

#4 will probably be the most controversial, but follows the general "being flanked is bad" rule-of-thumb and extends it to include stealthed units. I think nearly unlimited duration stealth is going to have plenty of uses, but having it make units effectively invulnerable for a turn even if flanked/etc seems a bit strong.

 

As for ghost armor, by "1 turn" I meant XCOM + alien turn, so you're right in that it technically is 2 turns (in the code). We'll probably adjust the number of ghost charges granted as well.

 

An interesting tradeoff might be to to limit to 2 charges but increase the duration to 2 (technically 4) turns, but have the stealth effect by losable in similar situations to mimetic skin.

Link to comment
Share on other sites

Do aliens get any type of "Bioelectric Skin" skill? That would be a good counter, perhaps enhancing a grenade with an skill to do a 3x3 AoE that uncovers any hidden operatives (without damage or something), or give electric skin to leaders and navigators so they can check around them in a given area.

 

It appears that bioelectric skin is hard-coded to only remove seeker stealth, not stealth in general.

 

However it appears that the way that the AI is coded, it bases its movement on positions -- positions that can be flanked or, will result in the unit being flanked. These calculations appear to take into account stealthed units, so effectively the AI knows where the stealthed unit is, but simply is unable to actually target the stealthed unit (I envision this like the Predator stealth where you can kind of tell where the unit is).

 

Alien units will move to get out of being flanked by stealthed units, and know how to move to flank a stealthed unit (which with the above changes will break the stealth, allowing the alien to shoot at the unit).

Link to comment
Share on other sites

Another interesting tidbit I found ... :

    if(m_kUnit.IsAffectedByAbility(eAbility_ActivateStealthMP))
    {
        if(m_kUnit.SetStealthCharges(m_kUnit.GetStealthCharges() - 1))
        {
            kBroadcastWorldMessage = XComPresentationLayer(XComPlayerController(WorldInfo.GetALocalPlayerController()).m_Pres).GetWorldMessenger().Message(XComGameReplicationInfo(class'Engine'.static.GetCurrentWorldInfo().GRI).m_kGameCore.GetUnexpandedLocalizedMessageString(eULS_StealthChargeBurn), m_kUnit.Location, 3,,, m_kUnit.m_eTeamVisibilityFlags,,,, class'XComUIBroadcastWorldMessage_UnexpandedLocalizedString');
            if(kBroadcastWorldMessage != none)
            {
                XComUIBroadcastWorldMessage_UnexpandedLocalizedString(kBroadcastWorldMessage).Init_UnexpandedLocalizedString(31, m_kUnit.Location, 3, m_kUnit.m_eTeamVisibilityFlags);
            }
        }
    }

This appear to be the mechanic (used only in multiplayer) which makes stealth charges burn down. I'm thinking that perhaps a similar mechanic could be applied to ghost armor stealth?

Link to comment
Share on other sites

Amineri, Yes, I know it needs careful balancing, but I still want to try it. :smile: I don't like medals bonuses either, I want to turn all of them into morale bonuses, if I could. I think EW introduced too many overlapping features anyway, so I want to try and change some of them... someday. :smile:
Link to comment
Share on other sites

 

Do aliens get any type of "Bioelectric Skin" skill? That would be a good counter, perhaps enhancing a grenade with an skill to do a 3x3 AoE that uncovers any hidden operatives (without damage or something), or give electric skin to leaders and navigators so they can check around them in a given area.

 

It appears that bioelectric skin is hard-coded to only remove seeker stealth, not stealth in general.

 

However it appears that the way that the AI is coded, it bases its movement on positions -- positions that can be flanked or, will result in the unit being flanked. These calculations appear to take into account stealthed units, so effectively the AI knows where the stealthed unit is, but simply is unable to actually target the stealthed unit (I envision this like the Predator stealth where you can kind of tell where the unit is).

 

Alien units will move to get out of being flanked by stealthed units, and know how to move to flank a stealthed unit (which with the above changes will break the stealth, allowing the alien to shoot at the unit).

 

 

Bioelectric Skin detects all stealth in multiplayer. Is that another MP only feature?

Link to comment
Share on other sites

  • Recently Browsing   0 members

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