Advertisement
Guest User

Untitled

a guest
May 15th, 2019
97
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. class Overhaul_Faceoff extends X2Ability config (WOTC_Pistol_Overhaul);
  2.  
  3. var config bool FACEOFF_FIX;
  4.  
  5. static function array<X2DataTemplate> CreateTemplates()
  6. {
  7.     local array<X2DataTemplate> Templates;
  8.     Templates.AddItem(Faceoff());
  9.     Templates.AddItem(FaceoffContinue());
  10.     return Templates;
  11. }
  12.  
  13. static function X2AbilityTemplate Faceoff()
  14. {
  15.     local X2AbilityTemplate                 Template;
  16.     local X2AbilityCost_ActionPoints        ActionPointCost;
  17.     local X2AbilityCost_Ammo                AmmoCost;
  18.     local X2AbilityToHitCalc_StandardAim    StandardAim;
  19.     local X2Effect_Persistent               FaceoffTargetEffect;
  20.     local X2Condition_UnitEffectsWithAbilitySource FaceoffTargetCondition;
  21.  
  22.     `LOG("Here is Faceoff Template",, 'FACEOFF');
  23.  
  24.     if(default.FACEOFF_FIX == true)
  25.     {  
  26.         `CREATE_X2ABILITY_TEMPLATE(Template, 'manyshots');
  27.  
  28.         ActionPointCost = new class'X2AbilityCost_ActionPoints';
  29.         ActionPointCost.iNumPoints = 1;
  30.         ActionPointCost.bConsumeAllPoints = true;
  31.         Template.AbilityCosts.AddItem(ActionPointCost);
  32.  
  33.         //  require 2 ammo to be present so that multiple shots will be taken - otherwise it's a waste
  34.         AmmoCost = new class'X2AbilityCost_Ammo';
  35.         AmmoCost.iAmmo = 2;
  36.         AmmoCost.bFreeCost = true;
  37.         Template.AbilityCosts.AddItem(AmmoCost);
  38.         //  actually charge 1 ammo for this shot. the 2nd shot will charge the extra ammo.
  39.         AmmoCost = new class'X2AbilityCost_Ammo';
  40.         AmmoCost.iAmmo = 1;
  41.         Template.AbilityCosts.AddItem(AmmoCost);
  42.  
  43.         StandardAim = new class'X2AbilityToHitCalc_StandardAim';
  44.         StandardAim.bAllowCrit = false;
  45.         //StandardAim.BuiltInHitMod = default.BanishFirstShotAimMod;
  46.         Template.AbilityToHitCalc = StandardAim;
  47.         Template.AbilityTargetStyle = default.SimpleSingleTarget;
  48.  
  49.         Template.AbilityShooterConditions.AddItem(default.LivingShooterProperty);
  50.         Template.AddShooterEffectExclusions();
  51.  
  52.         Template.AbilityTargetConditions.AddItem(default.LivingHostileUnitOnlyProperty);
  53.         Template.AbilityTargetConditions.AddItem(default.GameplayVisibilityCondition);
  54.  
  55.         Template.AddTargetEffect(class'X2Ability_GrenadierAbilitySet'.static.HoloTargetEffect());
  56.         Template.AssociatedPassives.AddItem('HoloTargeting');
  57.         Template.AddTargetEffect(class'X2Ability_GrenadierAbilitySet'.static.ShredderDamageEffect());
  58.         Template.bAllowAmmoEffects = true;
  59.         Template.bAllowBonusWeaponEffects = true;
  60.  
  61.         FaceoffTargetEffect = new class'X2Effect_Persistent';
  62.         FaceoffTargetEffect.BuildPersistentEffect(1, false, true, true, eGameRule_PlayerTurnEnd);
  63.         FaceoffTargetEffect.EffectName = 'FaceoffTarget';
  64.         FaceoffTargetEffect.bApplyOnMiss = true; //Only one chance, even if you miss (prevents crazy flailing counter-attack chains with a Muton, for example)
  65.         Template.AddTargetEffect(FaceoffTargetEffect);
  66.    
  67.         FaceoffTargetCondition = new class'X2Condition_UnitEffectsWithAbilitySource';
  68.         FaceoffTargetCondition.AddExcludeEffect('FaceoffTarget', 'AA_DuplicateEffectIgnored');
  69.         Template.AbilityTargetConditions.AddItem(FaceoffTargetCondition);
  70.  
  71.         Template.AbilityTriggers.AddItem(default.PlayerInputTrigger);
  72.  
  73.         Template.ShotHUDPriority = class'UIUtilities_Tactical'.const.CLASS_COLONEL_PRIORITY;
  74.         Template.AbilitySourceName = 'eAbilitySource_Perk';
  75.         Template.eAbilityIconBehaviorHUD = eAbilityIconBehavior_AlwaysShow;
  76.         Template.AbilityConfirmSound = "TacticalUI_ActivateAbility";
  77.  
  78.         Template.BuildNewGameStateFn = TypicalAbility_BuildGameState;
  79.         Template.BuildVisualizationFn = TypicalAbility_BuildVisualization;
  80.         Template.BuildInterruptGameStateFn = TypicalAbility_BuildInterruptGameState;
  81.         Template.SuperConcealmentLoss = 0;
  82.  
  83.         Template.AdditionalAbilities.AddItem('FaceoffContinue');
  84.         Template.PostActivationEvents.AddItem('FaceoffContinue');
  85.  
  86.         //  this ability will always break concealment at the end and we don't want to roll on it
  87.         Template.ConcealmentRule = eConceal_Always;
  88.         Template.SuperConcealmentLoss = 0;
  89.         Template.ChosenActivationIncreasePerUse = class'X2AbilityTemplateManager'.default.StandardShotChosenActivationIncreasePerUse;
  90.         Template.LostSpawnIncreasePerUse = class'X2AbilityTemplateManager'.default.StandardShotLostSpawnIncreasePerUse;
  91.         Template.bFrameEvenWhenUnitIsHidden = true;
  92.         Template.IconImage = "img:///UILibrary_PerkIcons.UIPerk_faceoff";
  93.         Template.ActivationSpeech = 'Faceoff';
  94.  
  95.         return Template;
  96.     }
  97. }
  98.  
  99. static function X2AbilityTemplate FaceoffContinue()
  100. {
  101.     local X2AbilityTemplate                 Template;
  102.     local X2AbilityCost_Ammo                AmmoCost;
  103.     local X2AbilityTrigger_EventListener    Trigger;
  104.     local X2AbilityToHitCalc_StandardAim    StandardAim;
  105.     local X2Effect_Persistent               FaceoffTargetEffect;
  106.     local X2Condition_UnitEffectsWithAbilitySource FaceoffTargetCondition;
  107.  
  108.     `LOG("Here is FaceoffContinue Template",, 'FACEOFF');
  109.  
  110.     `CREATE_X2ABILITY_TEMPLATE(Template, 'FaceoffContinue');
  111.  
  112.     AmmoCost = new class'X2AbilityCost_Ammo';
  113.     AmmoCost.iAmmo = 1;
  114.     Template.AbilityCosts.AddItem(AmmoCost);
  115.  
  116.     StandardAim = new class'X2AbilityToHitCalc_StandardAim';
  117.     StandardAim.bAllowCrit = false;
  118.     //StandardAim.BuiltInHitMod = default.BanishSubsequentShotsAimMod;
  119.     Template.AbilityToHitCalc = StandardAim;
  120.     Template.AbilityTargetStyle = default.SimpleSingleTarget;
  121.  
  122.     Template.AbilityShooterConditions.AddItem(default.LivingShooterProperty);
  123.     Template.AddShooterEffectExclusions();
  124.  
  125.     Template.AbilityTargetConditions.AddItem(default.LivingHostileTargetProperty);
  126.     Template.AbilityTargetConditions.AddItem(default.GameplayVisibilityCondition);
  127.  
  128.     Template.AddTargetEffect(class'X2Ability_GrenadierAbilitySet'.static.HoloTargetEffect());
  129.     Template.AssociatedPassives.AddItem('HoloTargeting');
  130.     Template.AddTargetEffect(class'X2Ability_GrenadierAbilitySet'.static.ShredderDamageEffect());
  131.     Template.bAllowAmmoEffects = true;
  132.     Template.bAllowBonusWeaponEffects = true;
  133.  
  134.     Trigger = new class'X2AbilityTrigger_EventListener';
  135.     Trigger.ListenerData.Deferral = ELD_OnStateSubmitted;
  136.     Trigger.ListenerData.EventID = 'FaceoffContinue';
  137.     Trigger.ListenerData.Filter = eFilter_Unit;
  138.     Trigger.ListenerData.EventFn = static.FaceoffListener;
  139.     Template.AbilityTriggers.AddItem(Trigger);
  140.  
  141.     FaceoffTargetEffect = new class'X2Effect_Persistent';
  142.     FaceoffTargetEffect.BuildPersistentEffect(1, false, true, true, eGameRule_PlayerTurnEnd);
  143.     FaceoffTargetEffect.EffectName = 'FaceoffTarget';
  144.     FaceoffTargetEffect.bApplyOnMiss = true; //Only one chance, even if you miss (prevents crazy flailing counter-attack chains with a Muton, for example)
  145.     Template.AddTargetEffect(FaceoffTargetEffect);
  146.    
  147.     FaceoffTargetCondition = new class'X2Condition_UnitEffectsWithAbilitySource';
  148.     FaceoffTargetCondition.AddExcludeEffect('FaceoffTarget', 'AA_DuplicateEffectIgnored');
  149.     Template.AbilityTargetConditions.AddItem(FaceoffTargetCondition);
  150.  
  151.     Template.ShotHUDPriority = class'UIUtilities_Tactical'.const.CLASS_COLONEL_PRIORITY;
  152.     Template.AbilitySourceName = 'eAbilitySource_Perk';
  153.     Template.eAbilityIconBehaviorHUD = eAbilityIconBehavior_NeverShow;
  154.  
  155.     Template.BuildNewGameStateFn = TypicalAbility_BuildGameState;
  156.     //Template.BuildVisualizationFn = TypicalAbility_BuildVisualization;
  157.     Template.BuildVisualizationFn = class'X2Ability_SharpshooterAbilitySet'.static.Faceoff_BuildVisualization;
  158.     Template.MergeVisualizationFn = SequentialShot_MergeVisualization;
  159.     Template.SuperConcealmentLoss = 0;
  160.  
  161.     Template.PostActivationEvents.AddItem('FaceoffContinue');
  162.     Template.bShowActivation = true;
  163.  
  164.     //  this ability will always break concealment at the end and we don't want to roll on it
  165.     Template.ConcealmentRule = eConceal_Always;
  166.     Template.SuperConcealmentLoss = 0;
  167.     Template.ChosenActivationIncreasePerUse = class'X2AbilityTemplateManager'.default.StandardShotChosenActivationIncreasePerUse;
  168.     Template.LostSpawnIncreasePerUse = class'X2AbilityTemplateManager'.default.StandardShotLostSpawnIncreasePerUse;
  169.     Template.bFrameEvenWhenUnitIsHidden = true;
  170.     Template.IconImage = "img:///UILibrary_XPACK_Common.PerkIcons.UIPerk_soulreaper";
  171.  
  172.     return Template;
  173. }
  174.  
  175. static function EventListenerReturn FaceoffListener(Object EventData, Object EventSource, XComGameState GameState, Name EventID, Object CallbackData)
  176. {
  177.     local XComGameStateHistory History;
  178.     local XComGameStateContext_Ability AbilityContext;
  179.     local XComGameState_Unit SourceUnit, TargetUnit;
  180.     local array<StateObjectReference> PossibleTargets;
  181.     local StateObjectReference BestTargetRef;
  182.     local int BestTargetHP;
  183.     local int i;
  184.     local bool bAbilityContinues;
  185.     local XComGameState_Ability         AbilityState;
  186.     local XComGameState_Item            ItemState;
  187.  
  188.     `LOG("Here is the Listener",, 'FACEOFF');
  189.  
  190.     AbilityContext = XComGameStateContext_Ability(GameState.GetContext());
  191.     if (AbilityContext != none && AbilityContext.InterruptionStatus != eInterruptionStatus_Interrupt)
  192.     {
  193.         SourceUnit = XComGameState_Unit(GameState.GetGameStateForObjectID(AbilityContext.InputContext.SourceObject.ObjectID));
  194.         TargetUnit = XComGameState_Unit(GameState.GetGameStateForObjectID(AbilityContext.InputContext.PrimaryTarget.ObjectID));
  195.         AbilityState = XComGameState_Ability(`XCOMHISTORY.GetGameStateForObjectID(SourceUnit.FindAbility('FaceoffContinue').ObjectID));
  196.         /*
  197.         foreach SourceUnit.Abilities(BestTargetRef)
  198.         {
  199.             AbilityState = XComGameState_Ability(GameState.GetGameStateForObjectID(BestTargetRef.ObjectID));
  200.             `LOG("Found ability: " @ AbilityState.GetMyTemplateName(),, 'FACEOFF');
  201.             if (AbilityState.GetMyTemplateName() == 'FaceoffContinue') break;
  202.         }*/
  203.          
  204.         `LOG("SourceUnit: " @ SourceUnit.GetFullName(),, 'FACEOFF');
  205.         `LOG("TargetUnit: " @ TargetUnit.GetFullName(),, 'FACEOFF');
  206.  
  207.         if (AbilityState == none)
  208.         {
  209.             `LOG("Ability State is none!",, 'FACEOFF');
  210.             return ELR_NoInterrupt;
  211.         }
  212.         else
  213.         {
  214.             `LOG("Ability State template is: " @ AbilityState.GetMyTemplateName(),, 'FACEOFF');
  215.         }
  216.        
  217.         ItemState = XComGameState_Item(GameState.GetGameStateForObjectID(AbilityState.SourceWeapon.ObjectID));
  218.         if (ItemState == none)
  219.         {
  220.             `LOG("Item State is none!",, 'FACEOFF');
  221.             return ELR_NoInterrupt;
  222.         }
  223.         else
  224.         {
  225.             `LOG("Item State template is: " @ ItemState.GetMyTemplateName() @ ", ammo: " @ ItemState.Ammo,, 'FACEOFF');
  226.         }
  227.        
  228.         if (ItemState.Ammo > 0)
  229.         {
  230.             History = `XCOMHISTORY;
  231.             //  find all possible new targets and select one with the highest HP to fire against
  232.             class'X2TacticalVisibilityHelpers'.static.GetAllVisibleEnemyUnitsForUnit(SourceUnit.ObjectID, PossibleTargets, AbilityState.GetMyTemplate().AbilityTargetConditions);
  233.             BestTargetHP = -1;
  234.             /*
  235.             `LOG("Looking for targets, step 1: " @ PossibleTargets.Length,, 'FACEOFF');
  236.             for (i = 0; i < PossibleTargets.Length; ++i)
  237.             {
  238.                 TargetUnit = XComGameState_Unit(History.GetGameStateForObjectID(PossibleTargets[i].ObjectID));
  239.                 if (TargetUnit.IsUnitAffectedByEffectName('FaceoffTarget'))
  240.                 {
  241.                     PossibleTargets.Remove(i, 1);
  242.                     i = 0;
  243.                 }
  244.             }*/
  245.             `LOG("Looking for targets: " @ PossibleTargets.Length,, 'FACEOFF');
  246.             for (i = 0; i < PossibleTargets.Length; ++i)
  247.             {
  248.                 TargetUnit = XComGameState_Unit(History.GetGameStateForObjectID(PossibleTargets[i].ObjectID));
  249.                 if (TargetUnit.GetCurrentStat(eStat_HP) > BestTargetHP)
  250.                 {                  
  251.                     BestTargetHP = TargetUnit.GetCurrentStat(eStat_HP);
  252.                     BestTargetRef = PossibleTargets[i];
  253.                 }
  254.                
  255.             }
  256.             if (BestTargetRef.ObjectID > 0)
  257.             {
  258.                 `LOG("Activating against: " @ TargetUnit.GetFullName(),, 'FACEOFF');
  259.  
  260.                 bAbilityContinues = AbilityState.AbilityTriggerAgainstSingleTarget(BestTargetRef, false);
  261.                
  262.                 `LOG("bAbilityContinues: " @ bAbilityContinues,, 'FACEOFF');
  263.             }
  264.         }
  265.         else
  266.         {
  267.             `LOG("Ability finished.",, 'FACEOFF');
  268.             bAbilityContinues = false;
  269.         }
  270.         if (!bAbilityContinues)
  271.         {
  272.             SourceUnit.BreakConcealment();
  273.         }
  274.     }
  275.     `LOG("Exiting listener.",, 'FACEOFF');
  276.     return ELR_NoInterrupt;
  277. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement