Kregano Posted April 22, 2016 Author Share Posted April 22, 2016 After talking to one of the Firaxis devs, Shadowman in its current incarnation doesn't work and probably will never work. eConceal_ stuff doesn't work on passive abilities, but it's entirely possible that creating variants of the fire weapons and overwatch abilities may get it to work. The same dev mentioned how to get something like Tactical Sense/Aggression working: It depends on which bonus you're trying to implement. Either way you'd make an infinite duration persistent effect on the unit with the ability, and you would implement the function GetToHitModifiers (which is defined in X2Effect_Persistent). To count the number of visible enemies, you probably want to call class'X2TacticalVisibilityHelpers'.static.GetNumVisibleEnemyTargetsToSource. Inside of GetToHitModifiers you'd return a bonus of something like TheBonusAmount * min(NumEnemies, 5). Make sense? I'll be trying this out soon. Link to comment Share on other sites More sharing options...
Kregano Posted April 22, 2016 Author Share Posted April 22, 2016 Tried to make a Tactical Sense/Aggression derivative, but I'm getting a weird error: static function X2AbilityTemplate ChallengeLover() { local X2AbilityTemplate Template; local X2AbilityTargetStyle TargetStyle; local X2AbilityTrigger Trigger; local X2Effect_Persistent PersistentEffect; local X2Effect_PersistentStatChange StatChangeEffect; local X2Effect_ToHitModifier ToHitModifier; `CREATE_X2ABILITY_TEMPLATE(Template, 'ChallengeLover'); Template.IconImage = "img:///UILibrary_PerkIcons.UIPerk_hithurts"; Template.AbilitySourceName = 'eAbilitySource_Perk'; Template.eAbilityIconBehaviorHUD = EAbilityIconBehavior_NeverShow; Template.Hostility = eHostility_Neutral; // this effect stays on the unit indefinitely PersistentEffect = new class'X2Effect_Persistent'; PersistentEffect.EffectName = 'ChallengeLover'; PersistentEffect.BuildPersistentEffect(1, true, true, false, eGameRule_PlayerTurnBegin); PersistentEffect.SetDisplayInfo(ePerkBuff_Passive, Template.LocFriendlyName, Template.GetMyHelpText(), Template.IconImage, true,,Template.AbilitySourceName); // each turn this effect is applied StatChangeEffect = new class'X2Effect_PersistentStatChange'; StatChangeEffect.EffectName = 'ChallengeLoverStatBoost'; StatChangeEffect.BuildPersistentEffect(1, false, true, false, eGameRule_PlayerTurnEnd); StatChangeEffect.AddPersistentStatChange(eStat_Offense, CHALLENGE_AIM_BONUS); StatChangeEffect.AddPersistentStatChange(eStat_Defense, CHALLENGE_DEF_BONUS); Template.AbilityToHitCalc = default.DeadEye; TargetStyle = new class'X2AbilityTarget_Self'; Template.AbilityTargetStyle = TargetStyle; Trigger = new class'X2AbilityTrigger_UnitPostBeginPlay'; Template.AbilityTriggers.AddItem(Trigger); //class'X2TacticalVisibilityHelpers'.static.GetNumVisibleEnemyTargetsToSource; // NumEnemies = UnitState.GetNumVisibleEnemyUnits(true,true); ToHitModifier = new class'X2Effect_ToHitModifier'; ToHitModifier.BuildPersistentEffect(1, true, true, true); ToHitModifier.SetDisplayInfo(ePerkBuff_Passive, Template.LocFriendlyName, Template.GetMyLongDescription(), Template.IconImage,,,Template.AbilitySourceName); NumEnemies = UnitState.GetNumVisibleEnemyUnits(true,true); ToHitModifier.CHALLENGE_AIM_BONUS = 5 * min(NumEnemies, 5) ToHitModifier.CHALLENGE_DEF_BONUS = 5 * min(NumEnemies, 5) Template.AddTargetEffect(ToHitModifier); Template.BuildNewGameStateFn = TypicalAbility_BuildGameState; // NOTE: No visualization on purpose! return Template; } StatChangeEffect.AddPersistentStatChange(eStat_Offense, CHALLENGE_AIM_BONUS); gives me weird "you can only use default values" errors, even though I defined the aim and defense bonus in a .ini file. Link to comment Share on other sites More sharing options...
davidlallen Posted April 22, 2016 Share Posted April 22, 2016 To reference an ini variable XYZ from a static function, use default.XYZ. Link to comment Share on other sites More sharing options...
Kregano Posted April 23, 2016 Author Share Posted April 23, 2016 Someone on Reddit pointed me to a simpler method: class X2Effect_Aggression extends X2Effect_Persistent config(GameData_SoldierSkills); var int CritModifier, MaxCritModifier; function GetToHitModifiers(XComGameState_Effect EffectState, XComGameState_Unit Attacker, XComGameState_Unit Target, XComGameState_Ability AbilityState, class<X2AbilityToHitCalc> ToHitType, bool bMelee, bool bFlanking, bool bIndirectFire, out array<ShotModifierInfo> ShotModifiers) { local ShotModifierInfo ModInfo; local float VisibleEnemies; VisibleEnemies = class'X2TacticalVisibilityHelpers'.static.GetNumVisibleEnemyTargetsToSource(Attacker.ObjectId,,class'X2TacticalVisibilityHelpers'.default.LivingGameplayVisibleFilter); ModInfo.ModType = eHit_Crit; ModInfo.Reason = FriendlyName; ModInfo.Value = min(CritModifier * VisibleEnemies, MaxCritModifier); ShotModifiers.AddItem(ModInfo); } The only disadvantage is that you'll need to rewrite a bunch of it to get it to change any stat besides crit. Link to comment Share on other sites More sharing options...
Kregano Posted May 28, 2016 Author Share Posted May 28, 2016 Bumping this, since this might help anyone trying to make stealth skills derived from Shadowfall:ModBuddy doesn't like static function XComGame.XComGameState.EventListenerReturn ShadowmanListener(Object EventData, Object EventSource, XComGameState GameState, name EventID) for whatever reason (the only change is turning Shadowfall into Shadowman). It'll give you this error: E:\SteamLibrary\SteamApps\common\XCOM 2 SDK\Development\Src\Shadowman\Classes\X2Effect_Shadowman.uc(16) : Error, Bad function definition Here's some experimental code you guys can play with: class X2Effect_Shadowman extends X2Effect_Persistent; function RegisterForEvents(XComGameState_Effect EffectGameState) { local X2EventManager EventMgr; local XComGameState_Unit UnitState; local Object EffectObj; EventMgr = class'X2EventManager'.static.GetEventManager(); EffectObj = EffectGameState; UnitState = XComGameState_Unit(class'XComGameStateHistory'.static.GetGameStateHistory().GetGameStateForObjectID(EffectGameState.ApplyEffectParameters.SourceStateObjectRef.ObjectID)); EventMgr.RegisterForEvent(EffectObj, 'KillMail', ShadowmanListener, 1,, UnitState); //return; } static function XComGame.XComGameState.EventListenerReturn ShadowmanListener(Object EventData, Object EventSource, XComGameState GameState, name EventID) { local XComGameStateContext_Ability AbilityContext; local XComGameState_Unit Killer; Killer = XComGameState_Unit(EventSource); AbilityContext = XComGameStateContext_Ability(GameState.GetContext()); // End:0xF4 if((((Killer != none) && AbilityContext != none) && AbilityContext.InputContext.AbilityTemplateName == 'OverwatchShot') && Killer.IsConcealed()) { Killer.RetainConcealment(); } if((((Killer != none) && AbilityContext != none) && AbilityContext.InputContext.AbilityTemplateName == 'PistolOverwatchShotHelper') && Killer.IsConcealed()) { Killer.RetainConcealment(); } if((((Killer != none) && AbilityContext != none) && AbilityContext.InputContext.AbilityTemplateName == 'PistolReturnFire') && Killer.IsConcealed()) { Killer.RetainConcealment(); } if((((Killer != none) && AbilityContext != none) && AbilityContext.InputContext.AbilityTemplateName == 'StandardShot') && Killer.IsConcealed()) { Killer.RetainConcealment(); } if((((Killer != none) && AbilityContext != none) && AbilityContext.InputContext.AbilityTemplateName == 'StandardShot_NoEnd') && Killer.IsConcealed()) { Killer.RetainConcealment(); } if((((Killer != none) && AbilityContext != none) && AbilityContext.InputContext.AbilityTemplateName == 'PistolStandardShot') && Killer.IsConcealed()) { Killer.RetainConcealment(); } if((((Killer != none) && AbilityContext != none) && AbilityContext.InputContext.AbilityTemplateName == 'SniperStandardFire') && Killer.IsConcealed()) { Killer.RetainConcealment(); } if((((Killer != none) && AbilityContext != none) && AbilityContext.InputContext.AbilityTemplateName == 'SniperRifleOverwatch') && Killer.IsConcealed()) { Killer.RetainConcealment(); } return 0; //return ReturnValue; } No idea if it works, due to ModBuddy hating that line. Link to comment Share on other sites More sharing options...
Deleted32045420User Posted May 28, 2016 Share Posted May 28, 2016 You defined the function as static function XComGame.XComGameState.EventListenerReturn ShadowmanListener(Object EventData, Object EventSource, XComGameState GameState, name EventID) That's not how you do it, you just specify a type and that's it. Example: static function EventListenerReturn ShadowmanListener(Object EventData, Object EventSource, XComGameState GameState, name EventID) Link to comment Share on other sites More sharing options...
Kregano Posted May 28, 2016 Author Share Posted May 28, 2016 I didn't define it that way. Firaxis did, for whatever reason, and it worked in the Alien Hunters DLC. Link to comment Share on other sites More sharing options...
Deleted32045420User Posted May 28, 2016 Share Posted May 28, 2016 I didn't define it that way. Firaxis did, for whatever reason, and it worked in the Alien Hunters DLC.That's what the IDE is saying, just try (also i'd recommend not putting this as a static function) Link to comment Share on other sites More sharing options...
Recommended Posts