Amineri Posted January 23, 2014 Share Posted January 23, 2014 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 movement3) 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 More sharing options...
wghost81 Posted January 23, 2014 Share Posted January 23, 2014 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 More sharing options...
Hobbes77 Posted January 23, 2014 Share Posted January 23, 2014 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 good2) 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 sense4) 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 More sharing options...
osito2dancer Posted January 23, 2014 Share Posted January 23, 2014 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 More sharing options...
Amineri Posted January 23, 2014 Author Share Posted January 23, 2014 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 More sharing options...
Amineri Posted January 23, 2014 Author Share Posted January 23, 2014 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 good2) 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 sense4) 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 More sharing options...
Amineri Posted January 23, 2014 Author Share Posted January 23, 2014 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 More sharing options...
Amineri Posted January 23, 2014 Author Share Posted January 23, 2014 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 More sharing options...
wghost81 Posted January 24, 2014 Share Posted January 24, 2014 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 More sharing options...
amanasleep Posted January 25, 2014 Share Posted January 25, 2014 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 More sharing options...
Recommended Posts