Jump to content

Scripts hang when triggering FuseEvent


Pyranara

Recommended Posts

I seem to have encountered a very troublesome error when activating the FuseEvent on custom abilities. Even just copypasting fuse ad verbatim from the psiop class causes these issues. I eventually narrowed it down to the specific event:

Template.PostActivationEvents.AddItem(class'X2Ability_PsiOperativeAbilitySet'.default.FuseEventName);

Which appears as :

Template.PostActivationEvents.AddItem(default.FuseEventName);

in the Psioperative file.

Interestingly, this seems to function: however, on activation, there is a ~10 second delay before the action occurs, along with redscreens giving timeouts for X2Action_WaitForWorldDamage and X2Action_Fire_IgniteFuse classes.

That's about as far as we could really get. It seems that the game is somehow waiting on phantom animations or performing some other black magic.

Here's fuse, cut out to be modified for use as an ability by a custom class. It functions, but with a 10 second delay, and several red screens. Also, the actual explosion is invisible:

static function X2AbilityTemplate Instability()
{
local X2AbilityTemplate             Template;
local X2AbilityCost_ActionPoints    ActionPointCost;


`CREATE_X2ABILITY_TEMPLATE(Template, 'Instability');


Template.IconImage = "img:///UILibrary_PerkIcons.UIPerk_fuse";
Template.AbilitySourceName = 'eAbilitySource_Psionic';
Template.ShotHUDPriority = class'UIUtilities_Tactical'.const.CLASS_MAJOR_PRIORITY;
Template.Hostility = eHostility_Offensive;
Template.bLimitTargetIcons = true;


ActionPointCost = new class'X2AbilityCost_ActionPoints';
ActionPointCost.iNumPoints = 1;
ActionPointCost.bConsumeAllPoints = true;
Template.AbilityCosts.AddItem(ActionPointCost);


Template.AbilityTriggers.AddItem(default.PlayerInputTrigger);
Template.AbilityTargetStyle = default.SimpleSingleTarget;
Template.AbilityToHitCalc = default.DeadEye;


Template.AbilityShooterConditions.AddItem(default.LivingShooterProperty); 
Template.AbilityTargetConditions.AddItem(default.GameplayVisibilityCondition);
Template.AbilityTargetConditions.AddItem(new class'X2Condition_FuseTarget'); 
Template.AddShooterEffectExclusions();


Template.PostActivationEvents.AddItem(default.FuseEventName);
Template.PostActivationEvents.AddItem(default.FusePostEventName);


//Template.bShowActivation = true;
//Template.CustomFireAnim = 'HL_Psi_SelfCast';
Template.bSkipFireAction = true;
Template.BuildNewGameStateFn = TypicalAbility_BuildGameState; 
Template.BuildVisualizationFn = TypicalAbility_BuildVisualization; 
Template.TargetingMethod = class'X2TargetingMethod_Fuse'; 
//Template.CinescriptCameraType = "Psionic_FireAtUnit"; 
//Retain concealment when activating Fuse - then break it after the explosions have occurred. 
Template.ConcealmentRule = eConceal_Always; 
Template.AdditionalAbilities.AddItem('FusePostActivationConcealmentBreaker');
 return Template; 
}

Anyone have any ideas? I'm almost at my wit's end with this one.

Link to comment
Share on other sites

I am far from being expert on these ability templates, but I've noticed Fuse template has this line

Temlate.DamagePreviewFn = FuseDamagePreview

Maybe you should copy-paste that FuseDamagePreview function to your class under different name, and then link DamagePreviewFn value to it.

Link to comment
Share on other sites

When making custom abilities that use custom animations (like psi abilities, or the shieldbearer shields) there are archetype files governing the animation and timing that can only be edited through the XCOM 2 Editor (see the Tools menu from Modbuddy). You'll need to find the archetype for the power you're copying, copy that into a new package for your mod, edit the archetype so that it's associated with YOUR custom ability (in your case, Instability), save the package, and ensure you add the package to your mod in Modbuddy (and declare the package in the right file, I'll find that and paste that here later).

 

That all said...I have had problems myself with the fuse animation in particular that I haven't encountered in other situations (stasis and shieldbearer effect work fine). Your case might be easier though, since you're attempting to replicate the power completely.

Link to comment
Share on other sites

Unfortunately, it's not that trivial.

The FuseDamagePreview class just provides the preview when you mouse over the target, and doesn't have any impact on the actual usability of the skill.

Grenades all have an ability called Fuse, which essentially just has a unit throw a grenade at itself without playing an animation.

There's also an event listener, X2Action_Fire_IgniteFuse, which listens for the 'Template.PostActivationEvents.AddItem(default.FuseEventName);'.

This script supposedly triggers fuse on the grenades, and this is where it seems to hang.

I'll have a look into the animations suggestion when I have free time today. I found there were issue with the missing animation at first, but then I decided to just skip having any fire animation, and that issue disappears.
For the time being, only X2Action_Fire_IgniteFuse and X2Action_WaitForWorldDamage hang, which are both events supposedly triggered by fuse.
I believe that X2Action_Fire_IgniteFuse hangs waiting for X2Action_WaitForWorldDamage to respond, and when it inevitably hangs, it's already imparted the timeout to X2Action_Fire_IgniteFuse - It seems the scripts all have a 10 second timeout window.
For reference, you can skip firing animations using Template.bSkipFireAction = true;
Link to comment
Share on other sites

I was helping Pyranara with this issue the other day, and near as I can figure it has to do with the unique function chain of Fuse. Like he briefly mentioned, the Fuse ability doesn't really "do" anything except kick off a Fuse Event (and a reveal event, but that's irrelevant here). Essentially, no shot is ever fired (hence the need for a separate "reveal" event). Instead there are listener functions sprinkled throughout the grenade/rocket/etc classes which are just waiting for the Fuse event (like little tiny suicide bombers :laugh:), and then they cause the grenade (rocket, etc) to immediately self-target without a throw animation. That's how fuse works in a nutshell.

 

The problem is, I think, the way the animations are strung together. Turns out, the "firing" animation from Fuse is just the soldier grabbing their Psi Amp and facing the target. That's it. The purple-psi tendrils that connect the source and target somehow seem to come from the grenade side of things, although I could never figure out how (likely didn't dig deep enough). When the GrenadeFuse() template is used it seems to know to look for a soldier who just used Fuse, but in this case it can never find one because they used 'Instability' instead. This means the purple-psi tendrils never show up, and because they never show up the animation chain times out. This is what causes the 10 second delay (that's the default watchdog time for unit animations) before the actual explosion occurs. It's supposed to go: "Face Target -> Psi Magic -> Boom" but without the middle bit the "boom" sits around waiting until the middle animation is declared dead.

 

So the only way I can think of doing this off the top of my head is to override every single grenade class in the game and add an Instability() template which listens for a new Instability event but doesn't require the same chain of animations. But that's a hideous sledgehammer of a solution and I have to believe there's a better way. I just couldn't think of it or find it in the scripts. Hence, I encouraged Pyranara to post here. It's an interesting problem and I'm sure one of you clever lot has a solution rattling around in their big ol' brain.

Edited by MachDelta
Link to comment
Share on other sites

  • Recently Browsing   0 members

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