Advertisement
Guest User

Untitled

a guest
Aug 5th, 2019
628
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. function SharedAnimation_MergeVisualization(X2Action BuildTree, out X2Action VisualizationTree)
  2. {
  3.     local XComGameStateVisualizationMgr     VisMgr;
  4.     local X2Action_MarkerNamed              MarkerNamed, JoinMarker, SecondJoin, FireReplace;
  5.     local array<X2Action>                   arrActions;
  6.     local X2Action                          Action, FirstFireAction, SecondFireAction, SpacerAction;
  7.     local int i;
  8.     local VisualizationActionMetadata       ActionMetadata;
  9.     local XComGameStateContext_Ability      FirstAbilityContext, SecondAbilityContext;
  10.     local StateObjectReference              Target;
  11.  
  12.    
  13.     `log("======================================",, 'IRIPISTOLVIZ');
  14.     `log("Build Tree",, 'IRIPISTOLVIZ');
  15.     PrintActionRecursive(BuildTree.TreeRoot, 0);
  16.     `log("--------------------------------------",, 'IRIPISTOLVIZ');
  17.    
  18.     `log("======================================",, 'IRIPISTOLVIZ');
  19.     `log("Viz tree",, 'IRIPISTOLVIZ');
  20.     PrintActionRecursive(VisualizationTree.TreeRoot, 0);
  21.     `log("--------------------------------------",, 'IRIPISTOLVIZ');
  22.  
  23.     VisMgr = `XCOMVISUALIZATIONMGR;
  24.  
  25.     SecondFireAction = VisMgr.GetNodeOfType(BuildTree, class'X2Action_Fire');
  26.     SecondAbilityContext = XComGameStateContext_Ability(BuildTree.StateChangeContext);
  27.  
  28.     `log(`showvar(SecondAbilityContext.DesiredVisualizationBlockIndex),, 'IRIPISTOLVIZ');
  29.  
  30.     Target = SecondAbilityContext.InputContext.PrimaryTarget;
  31.     //Mr. Nice Much simpler this time! Due to how the second shot is triggered, we know what index we want already!
  32.     VisMgr.GetNodesOfType(VisualizationTree, class'X2Action_Fire', arrActions, , , true);
  33.  
  34.     foreach arrActions(Action)
  35.     {  
  36.         // allows working correctly with abilities that have multiple Fire Actions, such as Faceoff
  37.         if (Action.StateChangeContext.AssociatedState.HistoryIndex == SecondAbilityContext.DesiredVisualizationBlockIndex)
  38.         {
  39.             `log("Found fire action with correct history index, TargetID: " @ X2Action_Fire(Action).PrimaryTargetID,, 'IRIPISTOLVIZ');
  40.  
  41.             //  Mr. Nice: if the PrimaryTargetID is zero, then juse the context primary instead
  42.             if (SecondAbilityContext.InputContext.PrimaryTarget.ObjectID == (X2Action_Fire(Action).PrimaryTargetID == 0 ? X2Action_Fire(Action).AbilityContext.InputContext.PrimaryTarget.ObjectID : X2Action_Fire(Action).PrimaryTargetID))
  43.             {
  44.                 `log("Found fire action with correct target: " @ SecondAbilityContext.InputContext.PrimaryTarget.ObjectID @ X2Action_Fire(Action).PrimaryTargetID == 0,, 'IRIPISTOLVIZ');
  45.                 FirstFireAction = Action;
  46.                 FirstAbilityContext = XComGameStateContext_Ability(Action.StateChangeContext);
  47.                 break;
  48.             }
  49.         }
  50.     }
  51.  
  52.     if (FirstFireAction == none || SecondFireAction == none)
  53.     {
  54.         //Mr. Nice: If this happens who knows what's going on? Just keep VisMgr happy with the most generic merge...
  55.         `log("Dual Shot Merge Failed?!?!",, 'IRIPISTOLVIZ');
  56.         XComGameStateContext_Ability(BuildTree.StateChangeContext).SuperMergeIntoVisualizationTree(BuildTree, VisualizationTree);
  57.         return;
  58.     }
  59.    
  60.     VisMgr.GetNodesOfType(VisualizationTree, class'X2Action_MarkerNamed', arrActions, , , true);
  61.     for (i = 0; i < arrActions.Length; ++i)
  62.     {
  63.         MarkerNamed = X2Action_MarkerNamed(arrActions[i]);
  64.         if (MarkerNamed.MarkerName == 'Join' && MarkerNamed.StateChangeContext.AssociatedState.HistoryIndex == SecondAbilityContext.DesiredVisualizationBlockIndex)
  65.         {
  66.             JoinMarker = MarkerNamed;
  67.             break;
  68.         }
  69.     }
  70.  
  71.     `assert(JoinMarker != none);
  72.    
  73.     VisMgr.GetNodesOfType(BuildTree, class'X2Action_MarkerNamed', arrActions, , , true);
  74.     for (i = 0; i < arrActions.Length; ++i)
  75.     {
  76.         MarkerNamed = X2Action_MarkerNamed(arrActions[i]);
  77.         if (MarkerNamed.MarkerName == 'Join')
  78.         {
  79.             SecondJoin = MarkerNamed;
  80.         }
  81.     }
  82.  
  83.     //Mr. Nice: If Second hit misses, animate first hit, otherwise animate second hit
  84.     //Means that if we kill on the second shot, we correctly get the death anim
  85.     //Well, that was the theory, but hiding hits is hard, and if you hide the first one, you don't get the projectile blood
  86.     if(IsContextMiss(SecondAbilityContext))
  87.     {
  88.         VisMgr.GetNodesOfType(BuildTree, class'X2Action_ApplyWeaponDamageToUnit', arrActions,, Target.ObjectID);
  89.         foreach arrActions(Action)
  90.         {
  91.             if(Action.ParentActions[0] == SecondFireAction)
  92.             {
  93.                 X2Action_ApplyWeaponDamageToUnit(Action).bPlayDamageAnim = false;
  94.             }
  95.         }
  96.     }
  97.     else
  98.     {
  99.         VisMgr.GetNodesOfType(VisualizationTree, class'X2Action_ApplyWeaponDamageToUnit', arrActions,, Target.ObjectID);
  100.         if (IsContextMiss(FirstAbilityContext))
  101.         {
  102.             foreach arrActions(Action)
  103.             {
  104.                 if(Action.ParentActions[0] == FirstFireAction)
  105.                 {
  106.                     X2Action_ApplyWeaponDamageToUnit(Action).bPlayDamageAnim = false;
  107.                 }
  108.             }
  109.         }
  110.        
  111.         //Mr. Nice: This makes sure you can see the counter attack, whether the second shot kills them or not
  112.         else if(FirstAbilityContext.ResultContext.HitResult == eHit_CounterAttack)
  113.         {
  114.             foreach arrActions(Action)
  115.             {
  116.                 if (Action.ParentActions[0] == FirstFireAction)
  117.                 {
  118.                     //if(default.ENABLE_LOGGING) `Log("Found miss/counter action...");
  119.                     if(XComGameState_Unit(`XCOMHISTORY.GetGameStateForObjectID(Target.ObjectID,, SecondAbilityContext.AssociatedState.HistoryIndex)).IsDead())
  120.                     {
  121.                         //Mr. Nice: If the second hit kills, stil want to show the counter animation before the unit animates its death
  122.                         SpacerAction = Action;
  123.                     }
  124.                     else
  125.                     {
  126.                         //Mr. Nice: If the second hit does not kill, want the counter animation, not the flinch animation, to get priority
  127.                         //Spacer both keeps the sets of damageotunit's from being siblings if both miss,
  128.                         //and helpfully makes sure you see the counter anim, not the flinch anim when you have a counter & hit result
  129.                         ActionMetaData = FirstFireAction.Metadata;
  130.                         SpacerAction = class'X2Action_ApplyDamageSpacer'.static.AddToVisualizationTree(ActionMetadata, FirstAbilityContext,, FirstFireAction);
  131.                         VisMgr.DisconnectAction(Action);
  132.                         VisMgr.ConnectAction(Action, VisualizationTree,, SpacerAction);
  133.                         SpacerAction = FirstFireAction;
  134.                     }
  135.                     break;
  136.                 }
  137.             }
  138.         }
  139.     }
  140.  
  141.     //If the second shot has a join created, then just slot it in above the first shots join
  142.     if (SecondJoin != none)
  143.     {
  144.         VisMgr.ConnectAction(SecondJoin, VisualizationTree,,, JoinMarker.ParentActions);
  145.         VisMgr.ConnectAction(JoinMarker, BuildTree,, SecondJoin);
  146.     }
  147.     //If the second shot does not have a join, then connect the leaf nodes to the first shots join
  148.     else
  149.     {
  150.         VisMgr.GetAllLeafNodes(BuildTree, arrActions);
  151.         VisMgr.ConnectAction(JoinMarker,BuildTree,,, arrActions);
  152.     }
  153.     //Mr. Nice, ok, want to connect children of secondfireaction, to firstfireaction
  154.     arrActions = SecondFireAction.ChildActions;
  155.     //If first hit was countered, then the attachment point for second hit applydamagetounit will have been set
  156.     //Otherwise, create a new SpacerAction for them
  157.     if (SpacerAction == none)
  158.     {
  159.         ActionMetaData = SecondFireAction.Metadata;
  160.         SpacerAction = class'X2Action_ApplyDamageSpacer'.static.AddToVisualizationTree(ActionMetadata, SecondAbilityContext,, FirstFireAction);
  161.     }
  162.     //if(default.ENABLE_LOGGING) `Log(`showvar(arrActions.Length));
  163.     foreach arrActions(Action)
  164.     {
  165.         VisMgr.ConnectAction(Action, VisualizationTree,, X2Action_ApplyWeaponDamageToUnit(Action) != none ? SpacerAction : FirstFireAction);
  166.     }
  167.     //For correct counter attack animations, need to be able to trace from BuildTree down to the second shots apply damages, without
  168.     //encountering the first shot's applydamages. So swap out the SecondFireAction for a marker, just to keep BuildTree traceable.
  169.     FireReplace = X2Action_MarkerNamed(class'X2Action'.static.CreateVisualizationActionClass(class'X2Action_MarkerNamed', SecondAbilityContext));
  170.     FireReplace.SetName("FireActionSharedAnimStub");
  171.     VisMgr.ReplaceNode(FireReplace, SecondFireAction)
  172.  
  173.     //Mr. Nice we have swapped out the SecondFireAction,
  174.     //So can destroy it now without "stranding" any other actions
  175.     VisMgr.DestroyAction(SecondFireAction);
  176. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement