Jump to content

Class mod wont work.


Pandandrew1

Recommended Posts

Ok so i took a look at some other mods and I found the issue in my X2Ability file, but now i am getting this error

" Warning/Error Summary
---------------------
C:\Program Files (x86)\Steam\steamapps\common\XCOM 2 SDK\Development\Src\OfficerMod\Classes\X2Ability_OfficerMod.uc(5) : Error, Missing '{' in function

Failure - 1 error(s), 0 warning(s) (1 Unique Errors, 0 Unique Warnings)"

But if I add a bracket it tells me that the bracket is unexpected

 

 

 

class X2Ability_OfficerMod extends X2Ability dependson(XComGameStateContext_Ability) config(GameData_OfficerMod);
static function array<X2DataTemplate> CreateTemplates()

var name EverVigilantEffectName;
var config int FACEOFF_COOLDOWN;
var config int FANFIRE_COOLDOWN;
var localized string HoloTargetEffectName;
var localized string HoloTargetEffectDesc;

var config int BULLET_SHRED;
var config int DEMO_HIT_BONUS;
var config int MARK_TARGET_LOCAL_COOLDOWN;

var localized string TargetGettingMarkedFriendlyName;
var localized string TargetGettingMarkedFriendlyDesc;


static function array<X2DataTemplate> CreateTemplates()
{
local array<X2DataTemplate> Templates;

Templates.AddItem(CreateMarkTargetAbility());

return Templates;
}

{
local array<X2DataTemplate> Templates;

Templates.AddItem(MarkTarget());
Templates.AddItem(HoloTargeting());
Templates.AddItem(BulletShred());
Templates.AddItem(Demolition());
Templates.AddItem(Shadowstep());
Templates.AddItem(EverVigilant());
Templates.AddItem(EverVigilantTrigger());
Templates.AddItem(Implacable());
Templates.AddItem(Faceoff());
Templates.AddItem(PurePassive('Quickdraw', "img:///UILibrary_PerkIcons.UIPerk_quickdraw"));
Templates.AddItem(ReturnFire());
Templates.AddItem(LightningHands());
Templates.AddItem(FanFire());
Templates.AddItem(RapidFire());
Templates.AddItem(RapidFire2());

return Templates;
}

static function X2DataTemplate CreateMarkTargetAbility()
{
local X2AbilityTemplate Template;
local X2AbilityCost_ActionPoints ActionPointCost;
local X2Condition_UnitProperty UnitPropertyCondition;
local X2Condition_Visibility TargetVisibilityCondition;
local X2Condition_UnitEffects UnitEffectsCondition;
local X2AbilityTarget_Single SingleTarget;
local X2AbilityTrigger_PlayerInput InputTrigger;
local X2Effect_Persistent MarkedEffect;
local X2AbilityCooldown_LocalAndGlobal Cooldown;

`CREATE_X2ABILITY_TEMPLATE(Template, 'MarkTarget');

Template.IconImage = "img:///UILibrary_PerkIcons.UIPerk_advent_marktarget";
Template.eAbilityIconBehaviorHUD = eAbilityIconBehavior_AlwaysShow;
Template.AbilitySourceName = 'eAbilitySource_Standard';
Template.Hostility = eHostility_Offensive;

Cooldown = new class'X2AbilityCooldown_LocalAndGlobal';
Cooldown.iNumTurns = default.MARK_TARGET_LOCAL_COOLDOWN;
Template.AbilityCooldown = Cooldown;

ActionPointCost = new class'X2AbilityCost_ActionPoints';
ActionPointCost.iNumPoints = 1;
ActionPointCost.bFreeCost = false;
Template.AbilityCosts.AddItem(ActionPointCost);

// The shooter cannot be mind controlled
UnitEffectsCondition = new class'X2Condition_UnitEffects';
UnitEffectsCondition.AddExcludeEffect(class'X2Effect_MindControl'.default.EffectName, 'AA_UnitIsMindControlled');
Template.AbilityShooterConditions.AddItem(UnitEffectsCondition);

Template.AbilityShooterConditions.AddItem(default.LivingShooterProperty);

// Target must be an enemy
UnitPropertyCondition = new class'X2Condition_UnitProperty';
UnitPropertyCondition.ExcludeDead = true;
UnitPropertyCondition.ExcludeFriendlyToSource = true;
UnitPropertyCondition.RequireWithinRange = false;
Template.AbilityTargetConditions.AddItem(UnitPropertyCondition);

// Target must be visible and may use squad sight
TargetVisibilityCondition = new class'X2Condition_Visibility';
TargetVisibilityCondition.bRequireGameplayVisible = true;
TargetVisibilityCondition.bAllowSquadsight = true;
Template.AbilityTargetConditions.AddItem(TargetVisibilityCondition);

// Target cannot already be marked
UnitEffectsCondition = new class'X2Condition_UnitEffects';
UnitEffectsCondition.AddExcludeEffect(class'X2StatusEffects'.default.MarkedName, 'AA_UnitIsMarked');
Template.AbilityTargetConditions.AddItem(UnitEffectsCondition);

// 100% chance to hit
Template.AbilityToHitCalc = default.DeadEye;

SingleTarget = new class'X2AbilityTarget_Single';
Template.AbilityTargetStyle = SingleTarget;

InputTrigger = new class'X2AbilityTrigger_PlayerInput';
Template.AbilityTriggers.AddItem(InputTrigger);

//// Create the Marked effect
MarkedEffect = class'X2StatusEffects'.static.CreateMarkedEffect(2, false);

Template.AddTargetEffect(MarkedEffect); //BMU - changing to an immediate execution for evaluation

Template.CustomFireAnim = 'HL_SignalPoint';
Template.BuildNewGameStateFn = TypicalAbility_BuildGameState;
Template.BuildInterruptGameStateFn = TypicalAbility_BuildInterruptGameState;
Template.BuildVisualizationFn = TargetGettingMarked_BuildVisualization;
Template.CinescriptCameraType = "Mark_Target";

return Template;
}

simulated function TargetGettingMarked_BuildVisualization(XComGameState VisualizeGameState, out array<VisualizationTrack> OutVisualizationTracks)
{
local XComGameStateHistory History;
local XComGameStateContext_Ability Context;
local StateObjectReference ShooterUnitRef;
local StateObjectReference TargetUnitRef;
local XComGameState_Ability Ability;
local X2AbilityTemplate AbilityTemplate;
local AbilityInputContext AbilityContext;

local VisualizationTrack EmptyTrack;
local VisualizationTrack BuildTrack;

local X2Action_PlaySoundAndFlyOver SoundAndFlyOver;
local X2Action_WaitForAbilityEffect WaitForAbilityEffect;
local X2Action_SendInterTrackMessage SendMessageAction;
local X2Action_PlayAnimation PlayAnimation;

local Actor TargetVisualizer, ShooterVisualizer;
local X2VisualizerInterface TargetVisualizerInterface, ShooterVisualizerInterface;
local int EffectIndex;

local name ApplyResult;


History = `XCOMHISTORY;
Context = XComGameStateContext_Ability(VisualizeGameState.GetContext());

AbilityContext = Context.InputContext;
Ability = XComGameState_Ability(History.GetGameStateForObjectID(AbilityContext.AbilityRef.ObjectID));
AbilityTemplate = class'XComGameState_Ability'.static.GetMyTemplateManager().FindAbilityTemplate(AbilityContext.AbilityTemplateName);

//Configure the visualization track for the shooter
//****************************************************************************************
ShooterUnitRef = Context.InputContext.SourceObject;
ShooterVisualizer = History.GetVisualizer(ShooterUnitRef.ObjectID);
ShooterVisualizerInterface = X2VisualizerInterface(ShooterVisualizer);

BuildTrack = EmptyTrack;
BuildTrack.StateObject_OldState = History.GetGameStateForObjectID(ShooterUnitRef.ObjectID, eReturnType_Reference, VisualizeGameState.HistoryIndex - 1);
BuildTrack.StateObject_NewState = VisualizeGameState.GetGameStateForObjectID(ShooterUnitRef.ObjectID);
BuildTrack.TrackActor = History.GetVisualizer(ShooterUnitRef.ObjectID);

if (AbilityTemplate != None)
{
if (!AbilityTemplate.bSkipFireAction && !AbilityTemplate.bSkipExitCoverWhenFiring)
{
class'X2Action_ExitCover'.static.AddToVisualizationTrack(BuildTrack, Context);
}
}

SoundAndFlyOver = X2Action_PlaySoundAndFlyOver(class'X2Action_PlaySoundAndFlyOver'.static.AddToVisualizationTrack(BuildTrack, Context));
SoundAndFlyOver.SetSoundAndFlyOverParameters(None, Ability.GetMyTemplate().LocFlyOverText, '', eColor_Good);

// Send an intertrack message letting the target know it can now die
SendMessageAction = X2Action_SendInterTrackMessage(class'X2Action_SendInterTrackMessage'.static.AddToVisualizationTrack(BuildTrack, Context));
SendMessageAction.SendTrackMessageToRef = Context.InputContext.PrimaryTarget;

PlayAnimation = X2Action_PlayAnimation(class'X2Action_PlayAnimation'.static.AddToVisualizationTrack(BuildTrack, Context));
PlayAnimation.Params.AnimName = 'HL_SignalPoint';

if (AbilityTemplate != None && AbilityTemplate.AbilityTargetEffects.Length > 0) //There are effects to apply
{
//Add any X2Actions that are specific to this effect being applied. These actions would typically be instantaneous, showing UI world messages
//playing any effect specific audio, starting effect specific effects, etc. However, they can also potentially perform animations on the
//track actor, so the design of effect actions must consider how they will look/play in sequence with other effects.
for (EffectIndex = 0; EffectIndex < AbilityTemplate.AbilityTargetEffects.Length; ++EffectIndex)
{
ApplyResult = Context.FindTargetEffectApplyResult(AbilityTemplate.AbilityTargetEffects[EffectIndex]);

// Source effect visualization
AbilityTemplate.AbilityTargetEffects[EffectIndex].AddX2ActionsForVisualizationSource(VisualizeGameState, BuildTrack, ApplyResult);
}
}

if (ShooterVisualizerInterface != none)
{
ShooterVisualizerInterface.BuildAbilityEffectsVisualization(VisualizeGameState, BuildTrack);
}

if (AbilityTemplate != None)
{
if (!AbilityTemplate.bSkipFireAction && !AbilityTemplate.bSkipExitCoverWhenFiring)
{
class'X2Action_EnterCover'.static.AddToVisualizationTrack(BuildTrack, Context);
}
}

OutVisualizationTracks.AddItem(BuildTrack);
//****************************************************************************************

//Configure the visualization track for the target
//****************************************************************************************
TargetUnitRef = Context.InputContext.PrimaryTarget;
TargetVisualizer = History.GetVisualizer(AbilityContext.PrimaryTarget.ObjectID);
TargetVisualizerInterface = X2VisualizerInterface(TargetVisualizer);

BuildTrack = EmptyTrack;
BuildTrack.StateObject_OldState = History.GetGameStateForObjectID(TargetUnitRef.ObjectID, eReturnType_Reference, VisualizeGameState.HistoryIndex - 1);
BuildTrack.StateObject_NewState = VisualizeGameState.GetGameStateForObjectID(TargetUnitRef.ObjectID);
BuildTrack.TrackActor = History.GetVisualizer(TargetUnitRef.ObjectID);

Ability = XComGameState_Ability(History.GetGameStateForObjectID(Context.InputContext.AbilityRef.ObjectID, eReturnType_Reference, VisualizeGameState.HistoryIndex - 1));

WaitForAbilityEffect = X2Action_WaitForAbilityEffect(class'X2Action_WaitForAbilityEffect'.static.AddToVisualizationTrack(BuildTrack, Context));
WaitForAbilityEffect.ChangeTimeoutLength(5.0f);

if (AbilityTemplate != None && AbilityTemplate.AbilityTargetEffects.Length > 0) //There are effects to apply
{
//Add any X2Actions that are specific to this effect being applied. These actions would typically be instantaneous, showing UI world messages
//playing any effect specific audio, starting effect specific effects, etc. However, they can also potentially perform animations on the
//track actor, so the design of effect actions must consider how they will look/play in sequence with other effects.
for (EffectIndex = 0; EffectIndex < AbilityTemplate.AbilityTargetEffects.Length; ++EffectIndex)
{
ApplyResult = Context.FindTargetEffectApplyResult(AbilityTemplate.AbilityTargetEffects[EffectIndex]);

// Target effect visualization
AbilityTemplate.AbilityTargetEffects[EffectIndex].AddX2ActionsForVisualization(VisualizeGameState, BuildTrack, ApplyResult);
}

if (TargetVisualizerInterface != none)
{
//Allow the visualizer to do any custom processing based on the new game state. For example, units will create a death action when they reach 0 HP.
TargetVisualizerInterface.BuildAbilityEffectsVisualization(VisualizeGameState, BuildTrack);
}
}

OutVisualizationTracks.AddItem(BuildTrack);
//****************************************************************************************
}

static function X2AbilityTemplate HoloTargeting()
{
local X2AbilityTemplate Template;
local X2Effect_Persistent PersistentEffect;

`CREATE_X2ABILITY_TEMPLATE(Template, 'HoloTargeting');

Template.IconImage = "img:///UILibrary_PerkIcons.UIPerk_holotargeting";
Template.AbilitySourceName = 'eAbilitySource_Perk';
Template.eAbilityIconBehaviorHUD = EAbilityIconBehavior_NeverShow;
Template.Hostility = eHostility_Neutral;
Template.bIsPassive = true;

Template.AbilityToHitCalc = default.DeadEye;
Template.AbilityTargetStyle = default.SelfTarget;
Template.AbilityTriggers.AddItem(default.UnitPostBeginPlayTrigger);

// This is a dummy effect so that an icon shows up in the UI.
// Shot and Suppression abilities make use of HoloTargetEffect().
PersistentEffect = new class'X2Effect_Persistent';
PersistentEffect.BuildPersistentEffect(1, true, true);
PersistentEffect.SetDisplayInfo(ePerkBuff_Passive, Template.LocFriendlyName, Template.LocLongDescription, Template.IconImage, true,,Template.AbilitySourceName);
Template.AddTargetEffect(PersistentEffect);

Template.BuildNewGameStateFn = TypicalAbility_BuildGameState;
// Note: no visualization on purpose!

Template.bCrossClassEligible = true;

return Template;
}

static function X2Effect_HoloTarget HoloTargetEffect()
{
local X2Effect_HoloTarget Effect;
local X2Condition_AbilityProperty AbilityCondition;
local X2AbilityTag AbilityTag;

Effect = new class'X2Effect_HoloTarget';
Effect.BuildPersistentEffect(1, false, false, false, eGameRule_PlayerTurnBegin);
Effect.bRemoveWhenTargetDies = true;
Effect.bUseSourcePlayerState = true;

AbilityTag = X2AbilityTag(`XEXPANDCONTEXT.FindTag("Ability"));
AbilityTag.ParseObj = Effect;

Effect.SetDisplayInfo(ePerkBuff_Penalty, default.HoloTargetEffectName, `XEXPAND.ExpandString(default.HoloTargetEffectDesc), "img:///UILibrary_PerkIcons.UIPerk_holotargeting", true);

AbilityCondition = new class'X2Condition_AbilityProperty';
AbilityCondition.OwnerHasSoldierAbilities.AddItem('HoloTargeting');
Effect.TargetConditions.AddItem(AbilityCondition);

return Effect;
}

static function X2AbilityTemplate BulletShred()
{
local X2AbilityTemplate Template;
local X2AbilityCost_Ammo AmmoCost;
local X2AbilityCost_ActionPoints ActionPointCost;
local X2Effect_ApplyWeaponDamage WeaponDamageEffect;
local array<name> SkipExclusions;
local X2AbilityToHitCalc_StandardAim StandardAim;
local X2AbilityCooldown Cooldown;

`CREATE_X2ABILITY_TEMPLATE(Template, 'BulletShred');

// Icon Properties
Template.IconImage = "img:///UILibrary_PerkIcons.UIPerk_bulletshred";
Template.ShotHUDPriority = class'UIUtilities_Tactical'.const.CLASS_COLONEL_PRIORITY;
Template.eAbilityIconBehaviorHUD = eAbilityIconBehavior_AlwaysShow;
Template.AbilitySourceName = 'eAbilitySource_Perk';
Template.DisplayTargetHitChance = true;
Template.AbilityConfirmSound = "TacticalUI_ActivateAbility";

// Activated by a button press; additionally, tells the AI this is an activatable
Template.AbilityTriggers.AddItem(default.PlayerInputTrigger);

// *** VALIDITY CHECKS *** //
// Normal effect restrictions (except disoriented)
SkipExclusions.AddItem(class'X2AbilityTemplateManager'.default.DisorientedName);
Template.AddShooterEffectExclusions(SkipExclusions);

// Targeting Details
// Can only shoot visible enemies
Template.AbilityTargetConditions.AddItem(default.GameplayVisibilityCondition);
// Can't target dead; Can't target friendlies
Template.AbilityTargetConditions.AddItem(default.LivingHostileTargetProperty);
// Can't shoot while dead
Template.AbilityShooterConditions.AddItem(default.LivingShooterProperty);
// Only at single targets that are in range.
Template.AbilityTargetStyle = default.SimpleSingleTarget;

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

// Ammo
AmmoCost = new class'X2AbilityCost_Ammo';
AmmoCost.iAmmo = 3;
Template.AbilityCosts.AddItem(AmmoCost);
Template.bAllowAmmoEffects = true;

Cooldown = new class'X2AbilityCooldown';
Cooldown.iNumTurns = 4;
Template.AbilityCooldown = Cooldown;

// Weapon Upgrade Compatibility
Template.bAllowFreeFireWeaponUpgrade = true; // Flag that permits action to become 'free action' via 'Hair Trigger' or similar upgrade / effects

WeaponDamageEffect = ShredderDamageEffect();
WeaponDamageEffect.EffectDamageValue.Rupture = default.BULLET_SHRED;
Template.AddTargetEffect(WeaponDamageEffect);

Template.AddTargetEffect(HoloTargetEffect());
Template.AssociatedPassives.AddItem('HoloTargeting');

StandardAim = new class'X2AbilityToHitCalc_StandardAim';
StandardAim.bHitsAreCrits = true;
Template.AbilityToHitCalc = StandardAim;
Template.AbilityToHitOwnerOnMissCalc = StandardAim;

// Targeting Method
Template.TargetingMethod = class'X2TargetingMethod_OverTheShoulder';
Template.bUsesFiringCamera = true;
Template.CinescriptCameraType = "StandardGunFiring";

// Voice events
Template.ActivationSpeech = 'BulletShred';

// MAKE IT LIVE!
Template.BuildNewGameStateFn = TypicalAbility_BuildGameState;
Template.BuildVisualizationFn = TypicalAbility_BuildVisualization;

Template.bCrossClassEligible = true;

return Template;
}

static function X2AbilityTemplate Demolition()
{
local X2AbilityTemplate Template;
local X2AbilityCost_ActionPoints ActionPointCost;
local X2AbilityCost_Ammo AmmoCost;
local X2Effect_ApplyDirectionalWorldDamage WorldDamage;
local X2AbilityCooldown Cooldown;
local X2Condition_UnitProperty TargetCondition;
local X2AbilityToHitCalc_RollStat RollStat;

`CREATE_X2ABILITY_TEMPLATE(Template, 'Demolition');

Template.ShotHUDPriority = class'UIUtilities_Tactical'.const.CLASS_SERGEANT_PRIORITY;
Template.AbilitySourceName = 'eAbilitySource_Perk';
Template.eAbilityIconBehaviorHUD = eAbilityIconBehavior_AlwaysShow;
Template.IconImage = "img:///UILibrary_PerkIcons.UIPerk_demolition";
Template.AbilityConfirmSound = "TacticalUI_ActivateAbility";
Template.bLimitTargetIcons = true;

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

Cooldown = new class'X2AbilityCooldown';
Cooldown.iNumTurns = 4;
Template.AbilityCooldown = Cooldown;

AmmoCost = new class'X2AbilityCost_Ammo';
AmmoCost.iAmmo = 2;
Template.AbilityCosts.AddItem(AmmoCost);

RollStat = new class'X2AbilityToHitCalc_RollStat';
RollStat.BaseChance = default.DEMO_HIT_BONUS;
Template.AbilityToHitCalc = RollStat;
Template.AbilityTargetStyle = default.SimpleSingleTarget;
Template.AbilityTriggers.AddItem(default.PlayerInputTrigger);

Template.AbilityShooterConditions.AddItem(default.LivingShooterProperty);
Template.AddShooterEffectExclusions();

TargetCondition = new class'X2Condition_UnitProperty';
TargetCondition.ExcludeAlive=false;
TargetCondition.ExcludeDead=true;
TargetCondition.ExcludeFriendlyToSource=true;
TargetCondition.ExcludeHostileToSource=false;
TargetCondition.TreatMindControlledSquadmateAsHostile=true;
TargetCondition.ExcludeNoCover=true;
TargetCondition.ExcludeNoCoverToSource=true;
Template.AbilityTargetConditions.AddItem(TargetCondition);
Template.AbilityTargetConditions.AddItem(default.GameplayVisibilityCondition);

WorldDamage = new class'X2Effect_ApplyDirectionalWorldDamage';
WorldDamage.bUseWeaponDamageType = true;
WorldDamage.bUseWeaponEnvironmentalDamage = false;
WorldDamage.EnvironmentalDamageAmount = 30;
WorldDamage.bApplyOnHit = true;
WorldDamage.bApplyOnMiss = false;
WorldDamage.bApplyToWorldOnHit = true;
WorldDamage.bApplyToWorldOnMiss = false;
WorldDamage.bHitAdjacentDestructibles = true;
WorldDamage.PlusNumZTiles = 1;
WorldDamage.bHitTargetTile = true;
Template.AddTargetEffect(WorldDamage);

// visually always appear as a miss so the target unit doesn't look like it's being damaged
Template.bOverrideVisualResult = true;
Template.OverrideVisualResult = eHit_Miss;

Template.BuildNewGameStateFn = TypicalAbility_BuildGameState;
Template.BuildVisualizationFn = TypicalAbility_BuildVisualization;
Template.BuildInterruptGameStateFn = TypicalAbility_BuildInterruptGameState;

return Template;
}

static function X2AbilityTemplate Shadowstep()
{
local X2AbilityTemplate Template;
local X2Effect_Persistent Effect;

`CREATE_X2ABILITY_TEMPLATE(Template, 'Shadowstep');

Template.AbilitySourceName = 'eAbilitySource_Perk';
Template.eAbilityIconBehaviorHUD = eAbilityIconBehavior_NeverShow;
Template.Hostility = eHostility_Neutral;
Template.IconImage = "img:///UILibrary_PerkIcons.UIPerk_shadowstep";

Template.AbilityToHitCalc = default.DeadEye;
Template.AbilityTargetStyle = default.SelfTarget;
Template.AbilityTriggers.AddItem(default.UnitPostBeginPlayTrigger);

Effect = new class'X2Effect_Persistent';
Effect.EffectName = 'Shadowstep';
Effect.DuplicateResponse = eDupe_Ignore;
Effect.BuildPersistentEffect(1, true, false);
Effect.SetDisplayInfo(ePerkBuff_Passive, Template.LocFriendlyName, Template.GetMyLongDescription(), Template.IconImage,,,Template.AbilitySourceName);
Template.AddTargetEffect(Effect);

Template.BuildNewGameStateFn = TypicalAbility_BuildGameState;
// NOTE: No visualization on purpose!

Template.bCrossClassEligible = true;

return Template;
}

static function X2AbilityTemplate EverVigilant()
{
local X2AbilityTemplate Template;

Template = PurePassive('EverVigilant', "img:///UILibrary_PerkIcons.UIPerk_evervigilant");
Template.AdditionalAbilities.AddItem('EverVigilantTrigger');

Template.bCrossClassEligible = true;

return Template;
}

static function X2AbilityTemplate EverVigilantTrigger()
{
local X2AbilityTemplate Template;
local X2AbilityTrigger_EventListener Trigger;
local X2Effect_Persistent VigilantEffect;

`CREATE_X2ABILITY_TEMPLATE(Template, 'EverVigilantTrigger');

Template.AbilityToHitCalc = default.DeadEye;
Template.AbilityShooterConditions.AddItem(default.LivingShooterProperty);
Template.AbilityTargetStyle = default.SelfTarget;
Template.eAbilityIconBehaviorHUD = eAbilityIconBehavior_NeverShow;
Template.Hostility = eHostility_Neutral;

Trigger = new class'X2AbilityTrigger_EventListener';
Trigger.ListenerData.Deferral = ELD_OnStateSubmitted;
Trigger.ListenerData.EventID = 'PlayerTurnEnded';
Trigger.ListenerData.Filter = eFilter_Player;
Trigger.ListenerData.EventFn = class'XComGameState_Ability'.static.EverVigilantTurnEndListener;
Template.AbilityTriggers.AddItem(Trigger);

VigilantEffect = new class'X2Effect_Persistent';
VigilantEffect.EffectName = default.EverVigilantEffectName;
VigilantEffect.BuildPersistentEffect(1, false, true, false, eGameRule_PlayerTurnBegin);
Template.AddShooterEffect(VigilantEffect);

Template.BuildNewGameStateFn = TypicalAbility_BuildGameState;

return Template;
}

static function X2AbilityTemplate Implacable()
{
local X2AbilityTemplate Template;
local X2Effect_Implacable ImplacableEffect;

`CREATE_X2ABILITY_TEMPLATE(Template, 'Implacable');

Template.AbilitySourceName = 'eAbilitySource_Perk';
Template.eAbilityIconBehaviorHUD = EAbilityIconBehavior_NeverShow;
Template.Hostility = eHostility_Neutral;
Template.IconImage = "img:///UILibrary_PerkIcons.UIPerk_implacable";

Template.AbilityToHitCalc = default.DeadEye;
Template.AbilityTargetStyle = default.SelfTarget;
Template.AbilityTriggers.AddItem(default.UnitPostBeginPlayTrigger);

ImplacableEffect = new class'X2Effect_Implacable';
ImplacableEffect.BuildPersistentEffect(1, true, false, false);
ImplacableEffect.SetDisplayInfo(ePerkBuff_Passive, Template.LocFriendlyName, Template.GetMyLongDescription(), Template.IconImage,,,Template.AbilitySourceName);
ImplacableEffect.DuplicateResponse = eDupe_Ignore;
Template.AddTargetEffect(ImplacableEffect);

Template.BuildNewGameStateFn = TypicalAbility_BuildGameState;
// NOTE: No visualization on purpose!

Template.bCrossClassEligible = true;

return Template;
}

static function X2AbilityTemplate Faceoff()
{
local X2AbilityTemplate Template;
local X2AbilityCooldown Cooldown;
local X2AbilityCost_ActionPoints ActionPointCost;
local X2AbilityToHitCalc_StandardAim ToHitCalc;

`CREATE_X2ABILITY_TEMPLATE(Template, 'Faceoff');

Template.IconImage = "img:///UILibrary_PerkIcons.UIPerk_faceoff";
Template.AbilitySourceName = 'eAbilitySource_Perk';
Template.eAbilityIconBehaviorHUD = eAbilityIconBehavior_AlwaysShow;
Template.Hostility = eHostility_Offensive;
Template.ShotHUDPriority = class'UIUtilities_Tactical'.const.CLASS_COLONEL_PRIORITY;
Template.AbilityConfirmSound = "TacticalUI_ActivateAbility";

Cooldown = new class'X2AbilityCooldown';
Cooldown.iNumTurns = default.FACEOFF_COOLDOWN;
Template.AbilityCooldown = Cooldown;

ToHitCalc = new class'X2AbilityToHitCalc_StandardAim';
ToHitCalc.bOnlyMultiHitWithSuccess = false;
Template.AbilityToHitCalc = ToHitCalc;

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

Template.AbilityTargetStyle = default.SimpleSingleTarget;
Template.AbilityMultiTargetStyle = new class'X2AbilityMultiTarget_AllAllies';
Template.AbilityTriggers.AddItem(default.PlayerInputTrigger);

Template.AbilityShooterConditions.AddItem(default.LivingShooterProperty);
Template.AddShooterEffectExclusions();

Template.AbilityTargetConditions.AddItem(default.GameplayVisibilityCondition);
Template.AbilityTargetConditions.AddItem(default.LivingHostileTargetProperty);

Template.AddTargetEffect(new class'X2Effect_ApplyWeaponDamage');
Template.AddMultiTargetEffect(new class'X2Effect_ApplyWeaponDamage');

Template.bAllowAmmoEffects = true;

Template.BuildNewGameStateFn = TypicalAbility_BuildGameState;
Template.BuildVisualizationFn = Faceoff_BuildVisualization;

return Template;
}

function Faceoff_BuildVisualization(XComGameState VisualizeGameState, out array<VisualizationTrack> OutVisualizationTracks)
{
local X2AbilityTemplate AbilityTemplate;
local XComGameStateContext_Ability Context;
local AbilityInputContext AbilityContext;
local StateObjectReference ShootingUnitRef;
local X2Action_Fire FireAction;
local X2Action_Fire_Faceoff FireFaceoffAction;
local XComGameState_BaseObject TargetStateObject;//Container for state objects within VisualizeGameState

local Actor TargetVisualizer, ShooterVisualizer;
local X2VisualizerInterface TargetVisualizerInterface;
local int EffectIndex, TargetIndex;

local VisualizationTrack EmptyTrack;
local VisualizationTrack BuildTrack;
local VisualizationTrack SourceTrack;
local XComGameStateHistory History;

local X2Action_PlaySoundAndFlyOver SoundAndFlyover;
local name ApplyResult;

local X2Action_StartCinescriptCamera CinescriptStartAction;
local X2Action_EndCinescriptCamera CinescriptEndAction;
local X2Camera_Cinescript CinescriptCamera;
local string PreviousCinescriptCameraType;
local X2Effect TargetEffect;


History = `XCOMHISTORY;
Context = XComGameStateContext_Ability(VisualizeGameState.GetContext());
AbilityContext = Context.InputContext;
AbilityTemplate = class'XComGameState_Ability'.static.GetMyTemplateManager().FindAbilityTemplate(AbilityContext.AbilityTemplateName);
ShootingUnitRef = Context.InputContext.SourceObject;

ShooterVisualizer = History.GetVisualizer(ShootingUnitRef.ObjectID);

SourceTrack = EmptyTrack;
SourceTrack.StateObject_OldState = History.GetGameStateForObjectID(ShootingUnitRef.ObjectID, eReturnType_Reference, VisualizeGameState.HistoryIndex - 1);
SourceTrack.StateObject_NewState = VisualizeGameState.GetGameStateForObjectID(ShootingUnitRef.ObjectID);
if (SourceTrack.StateObject_NewState == none)
SourceTrack.StateObject_NewState = SourceTrack.StateObject_OldState;
SourceTrack.TrackActor = ShooterVisualizer;

if (AbilityTemplate.ActivationSpeech != '') // allows us to change the template without modifying this function later
{
SoundAndFlyOver = X2Action_PlaySoundAndFlyOver(class'X2Action_PlaySoundAndFlyover'.static.AddToVisualizationTrack(SourceTrack, Context));
SoundAndFlyOver.SetSoundAndFlyOverParameters(None, "", AbilityTemplate.ActivationSpeech, eColor_Good);
}


// Add a Camera Action to the Shooter's track. Minor hack: To create a CinescriptCamera the AbilityTemplate
// must have a camera type. So manually set one here, use it, then restore.
PreviousCinescriptCameraType = AbilityTemplate.CinescriptCameraType;
AbilityTemplate.CinescriptCameraType = "StandardGunFiring";
CinescriptCamera = class'X2Camera_Cinescript'.static.CreateCinescriptCameraForAbility(Context);
CinescriptStartAction = X2Action_StartCinescriptCamera( class'X2Action_StartCinescriptCamera'.static.AddToVisualizationTrack(SourceTrack, Context ) );
CinescriptStartAction.CinescriptCamera = CinescriptCamera;
AbilityTemplate.CinescriptCameraType = PreviousCinescriptCameraType;


class'X2Action_ExitCover'.static.AddToVisualizationTrack(SourceTrack, Context);

// Fire at the primary target first
FireAction = X2Action_Fire(class'X2Action_Fire'.static.AddToVisualizationTrack(SourceTrack, Context));
FireAction.SetFireParameters(Context.IsResultContextHit(), , false);
// Setup target response
TargetVisualizer = History.GetVisualizer(AbilityContext.PrimaryTarget.ObjectID);
TargetVisualizerInterface = X2VisualizerInterface(TargetVisualizer);
BuildTrack = EmptyTrack;
BuildTrack.TrackActor = TargetVisualizer;
TargetStateObject = VisualizeGameState.GetGameStateForObjectID(AbilityContext.PrimaryTarget.ObjectID);
if( TargetStateObject != none )
{
History.GetCurrentAndPreviousGameStatesForObjectID(AbilityContext.PrimaryTarget.ObjectID,
BuildTrack.StateObject_OldState, BuildTrack.StateObject_NewState,
eReturnType_Reference,
VisualizeGameState.HistoryIndex);
`assert(BuildTrack.StateObject_NewState == TargetStateObject);
}
else
{
//If TargetStateObject is none, it means that the visualize game state does not contain an entry for the primary target. Use the history version
//and show no change.
BuildTrack.StateObject_OldState = History.GetGameStateForObjectID(AbilityContext.PrimaryTarget.ObjectID);
BuildTrack.StateObject_NewState = BuildTrack.StateObject_OldState;
}
class'X2Action_WaitForAbilityEffect'.static.AddToVisualizationTrack(BuildTrack, Context);
for (EffectIndex = 0; EffectIndex < AbilityTemplate.AbilityTargetEffects.Length; ++EffectIndex)
{
ApplyResult = Context.FindTargetEffectApplyResult(AbilityTemplate.AbilityTargetEffects[EffectIndex]);

// Target effect visualization
AbilityTemplate.AbilityTargetEffects[EffectIndex].AddX2ActionsForVisualization(VisualizeGameState, BuildTrack, ApplyResult);

// Source effect visualization
AbilityTemplate.AbilityTargetEffects[EffectIndex].AddX2ActionsForVisualizationSource(VisualizeGameState, SourceTrack, ApplyResult);
}
if( TargetVisualizerInterface != none )
{
//Allow the visualizer to do any custom processing based on the new game state. For example, units will create a death action when they reach 0 HP.
TargetVisualizerInterface.BuildAbilityEffectsVisualization(VisualizeGameState, BuildTrack);
}
OutVisualizationTracks.AddItem(BuildTrack);

// Now configure a fire action for each multi target
for (TargetIndex = 0; TargetIndex < AbilityContext.MultiTargets.Length; ++TargetIndex)
{
// Add an action to pop the previous CinescriptCamera off the camera stack.
CinescriptEndAction = X2Action_EndCinescriptCamera( class'X2Action_EndCinescriptCamera'.static.AddToVisualizationTrack( SourceTrack, Context ) );
CinescriptEndAction.CinescriptCamera = CinescriptCamera;
CinescriptEndAction.bForceEndImmediately = true;

// Add an action to push a new CinescriptCamera onto the camera stack.
AbilityTemplate.CinescriptCameraType = "StandardGunFiring";
CinescriptCamera = class'X2Camera_Cinescript'.static.CreateCinescriptCameraForAbility(Context);
CinescriptCamera.TargetObjectIdOverride = AbilityContext.MultiTargets[TargetIndex].ObjectID;
CinescriptStartAction = X2Action_StartCinescriptCamera( class'X2Action_StartCinescriptCamera'.static.AddToVisualizationTrack(SourceTrack, Context ) );
CinescriptStartAction.CinescriptCamera = CinescriptCamera;
AbilityTemplate.CinescriptCameraType = PreviousCinescriptCameraType;

// Add a custom Fire action to the shooter track.
TargetVisualizer = History.GetVisualizer(AbilityContext.MultiTargets[TargetIndex].ObjectID);
FireFaceoffAction = X2Action_Fire_Faceoff(class'X2Action_Fire_Faceoff'.static.AddToVisualizationTrack(SourceTrack, Context));
FireFaceoffAction.SetFireParameters(Context.IsResultContextMultiHit(TargetIndex), AbilityContext.MultiTargets[TargetIndex].ObjectID, false);
FireFaceoffAction.vTargetLocation = TargetVisualizer.Location;


// Setup target response
TargetVisualizerInterface = X2VisualizerInterface(TargetVisualizer);
BuildTrack = EmptyTrack;
BuildTrack.TrackActor = TargetVisualizer;
TargetStateObject = VisualizeGameState.GetGameStateForObjectID(AbilityContext.MultiTargets[TargetIndex].ObjectID);
if( TargetStateObject != none )
{
History.GetCurrentAndPreviousGameStatesForObjectID(AbilityContext.MultiTargets[TargetIndex].ObjectID,
BuildTrack.StateObject_OldState, BuildTrack.StateObject_NewState,
eReturnType_Reference,
VisualizeGameState.HistoryIndex);
`assert(BuildTrack.StateObject_NewState == TargetStateObject);
}
else
{
//If TargetStateObject is none, it means that the visualize game state does not contain an entry for the primary target. Use the history version
//and show no change.
BuildTrack.StateObject_OldState = History.GetGameStateForObjectID(AbilityContext.MultiTargets[TargetIndex].ObjectID);
BuildTrack.StateObject_NewState = BuildTrack.StateObject_OldState;
}

// Add WaitForAbilityEffect. To avoid time-outs when there are many targets, set a custom timeout
class'X2Action_WaitForAbilityEffect'.static.AddToVisualizationTrack(BuildTrack, Context);
BuildTrack.TrackActions[buildTrack.TrackActions.Length - 1].SetCustomTimeoutSeconds((10 + (10 * TargetIndex )));

for (EffectIndex = 0; EffectIndex < AbilityTemplate.AbilityMultiTargetEffects.Length; ++EffectIndex)
{
TargetEffect = AbilityTemplate.AbilityMultiTargetEffects[EffectIndex];
ApplyResult = Context.FindMultiTargetEffectApplyResult(TargetEffect, TargetIndex);

// Target effect visualization
AbilityTemplate.AbilityMultiTargetEffects[EffectIndex].AddX2ActionsForVisualization(VisualizeGameState, BuildTrack, ApplyResult);

// If the last Effect applied was weapon damage, then a weapon damage Action was added to the track.
// Find that weapon damage action, and extend its timeout so that we won't timeout if there are many
// targets to visualize before this one.
if ( X2Effect_ApplyWeaponDamage(TargetEffect) != none )
{
if ( X2Action_ApplyWeaponDamageToUnit(BuildTrack.TrackActions[buildTrack.TrackActions.Length - 1]) != none)
{
BuildTrack.TrackActions[buildTrack.TrackActions.Length - 1].SetCustomTimeoutSeconds((10 + (10 * TargetIndex )));
}
}

// Source effect visualization
AbilityTemplate.AbilityMultiTargetEffects[EffectIndex].AddX2ActionsForVisualizationSource(VisualizeGameState, SourceTrack, ApplyResult);
}
if( TargetVisualizerInterface != none )
{
//Allow the visualizer to do any custom processing based on the new game state. For example, units will create a death action when they reach 0 HP.
TargetVisualizerInterface.BuildAbilityEffectsVisualization(VisualizeGameState, BuildTrack);
}
OutVisualizationTracks.AddItem(BuildTrack);
}
class'X2Action_EnterCover'.static.AddToVisualizationTrack(SourceTrack, Context);

// Add an action to pop the last CinescriptCamera off the camera stack.
CinescriptEndAction = X2Action_EndCinescriptCamera( class'X2Action_EndCinescriptCamera'.static.AddToVisualizationTrack( SourceTrack, Context ) );
CinescriptEndAction.CinescriptCamera = CinescriptCamera;

OutVisualizationTracks.AddItem(SourceTrack);
}

static function X2AbilityTemplate ReturnFire()
{
local X2AbilityTemplate Template;
local X2AbilityTargetStyle TargetStyle;
local X2AbilityTrigger Trigger;
local X2Effect_ReturnFire FireEffect;

`CREATE_X2ABILITY_TEMPLATE(Template, 'ReturnFire');
Template.IconImage = "img:///UILibrary_PerkIcons.UIPerk_returnfire";

Template.AbilitySourceName = 'eAbilitySource_Perk';
Template.eAbilityIconBehaviorHUD = EAbilityIconBehavior_NeverShow;
Template.Hostility = eHostility_Neutral;

Template.AbilityToHitCalc = default.DeadEye;

TargetStyle = new class'X2AbilityTarget_Self';
Template.AbilityTargetStyle = TargetStyle;

Trigger = new class'X2AbilityTrigger_UnitPostBeginPlay';
Template.AbilityTriggers.AddItem(Trigger);

FireEffect = new class'X2Effect_ReturnFire';
FireEffect.BuildPersistentEffect(1, true, false, false, eGameRule_PlayerTurnBegin);
FireEffect.SetDisplayInfo(ePerkBuff_Passive, Template.LocFriendlyName, Template.GetMyLongDescription(), Template.IconImage,,,Template.AbilitySourceName);
Template.AddTargetEffect(FireEffect);

Template.BuildNewGameStateFn = TypicalAbility_BuildGameState;
// NOTE: No visualization on purpose!

Template.bCrossClassEligible = false; // this can only work with pistols, which only sharpshooters have

return Template;
}


static function X2AbilityTemplate LightningHands()
{
local X2AbilityTemplate Template;
local X2AbilityCost_Ammo AmmoCost;
local X2Effect_ApplyWeaponDamage WeaponDamageEffect;
local array<name> SkipExclusions;
local X2AbilityCooldown Cooldown;

`CREATE_X2ABILITY_TEMPLATE(Template, 'LightningHands');

// Icon Properties
Template.IconImage = "img:///UILibrary_PerkIcons.UIPerk_lightninghands";
Template.ShotHUDPriority = class'UIUtilities_Tactical'.const.CLASS_MAJOR_PRIORITY;
Template.eAbilityIconBehaviorHUD = eAbilityIconBehavior_AlwaysShow;
Template.DisplayTargetHitChance = true;
Template.AbilitySourceName = 'eAbilitySource_Perk';
Template.AbilityConfirmSound = "TacticalUI_ActivateAbility";

// Activated by a button press; additionally, tells the AI this is an activatable
Template.AbilityTriggers.AddItem(default.PlayerInputTrigger);

Cooldown = new class'X2AbilityCooldown';
Cooldown.iNumTurns = 4;
Template.AbilityCooldown = Cooldown;

// *** VALIDITY CHECKS *** //
// Normal effect restrictions (except disoriented)
SkipExclusions.AddItem(class'X2AbilityTemplateManager'.default.DisorientedName);
Template.AddShooterEffectExclusions(SkipExclusions);

// Targeting Details
// Can only shoot visible enemies
Template.AbilityTargetConditions.AddItem(default.GameplayVisibilityCondition);
// Can't target dead; Can't target friendlies
Template.AbilityTargetConditions.AddItem(default.LivingHostileTargetProperty);
// Can't shoot while dead
Template.AbilityShooterConditions.AddItem(default.LivingShooterProperty);
// Only at single targets that are in range.
Template.AbilityTargetStyle = default.SimpleSingleTarget;

// Ammo
AmmoCost = new class'X2AbilityCost_Ammo';
AmmoCost.iAmmo = 1;
Template.AbilityCosts.AddItem(AmmoCost);
Template.bAllowAmmoEffects = true; //

Template.AbilityCosts.AddItem(default.FreeActionCost);

// Damage Effect
WeaponDamageEffect = new class'X2Effect_ApplyWeaponDamage';
Template.AddTargetEffect(WeaponDamageEffect);

// Hit Calculation (Different weapons now have different calculations for range)
Template.AbilityToHitCalc = default.SimpleStandardAim;
Template.AbilityToHitOwnerOnMissCalc = default.SimpleStandardAim;

// Targeting Method
Template.TargetingMethod = class'X2TargetingMethod_OverTheShoulder';
Template.bUsesFiringCamera = true;
Template.CinescriptCameraType = "StandardGunFiring";

// MAKE IT LIVE!
Template.BuildNewGameStateFn = TypicalAbility_BuildGameState;
Template.BuildVisualizationFn = TypicalAbility_BuildVisualization;
return Template;
}

static function X2AbilityTemplate FanFire()
{
local X2AbilityTemplate Template;
local X2AbilityCost_Ammo AmmoCost;
local X2AbilityCost_ActionPoints ActionPointCost;
local X2Effect_ApplyWeaponDamage WeaponDamageEffect;
local X2AbilityMultiTarget_BurstFire BurstFireMultiTarget;
local X2AbilityCooldown Cooldown;
local X2AbilityToHitCalc_StandardAim ToHitCalc;

// Macro to do localisation and stuffs
`CREATE_X2ABILITY_TEMPLATE(Template, 'FanFire');

// Icon Properties
Template.IconImage = "img:///UILibrary_PerkIcons.UIPerk_fanfire";
Template.ShotHUDPriority = class'UIUtilities_Tactical'.const.CLASS_LIEUTENANT_PRIORITY;
Template.eAbilityIconBehaviorHUD = eAbilityIconBehavior_AlwaysShow;
Template.DisplayTargetHitChance = true;
Template.AbilitySourceName = 'eAbilitySource_Perk'; // color of the icon
Template.AbilityConfirmSound = "TacticalUI_ActivateAbility";

// Activated by a button press; additionally, tells the AI this is an activatable
Template.AbilityTriggers.AddItem(default.PlayerInputTrigger);

// *** VALIDITY CHECKS *** //
Template.AddShooterEffectExclusions();

// Targeting Details
// Can only shoot visible enemies
Template.AbilityTargetConditions.AddItem(default.GameplayVisibilityCondition);
// Can't target dead; Can't target friendlies
Template.AbilityTargetConditions.AddItem(default.LivingHostileTargetProperty);
// Can't shoot while dead
Template.AbilityShooterConditions.AddItem(default.LivingShooterProperty);
// Only at single targets that are in range.
Template.AbilityTargetStyle = default.SimpleSingleTarget;

// Action Point
ActionPointCost = new class'X2AbilityCost_ActionPoints';
ActionPointCost.iNumPoints = 1;
Template.AbilityCosts.AddItem(ActionPointCost);

Cooldown = new class'X2AbilityCooldown';
Cooldown.iNumTurns = default.FANFIRE_COOLDOWN;
Template.AbilityCooldown = Cooldown;

// Ammo
AmmoCost = new class'X2AbilityCost_Ammo';
AmmoCost.iAmmo = 1;
Template.AbilityCosts.AddItem(AmmoCost);
Template.bAllowAmmoEffects = true; //

// Weapon Upgrade Compatibility
Template.bAllowFreeFireWeaponUpgrade = true; // Flag that permits action to become 'free action' via 'Hair Trigger' or similar upgrade / effects

// Damage Effect
WeaponDamageEffect = new class'X2Effect_ApplyWeaponDamage';
Template.AddTargetEffect(WeaponDamageEffect);
Template.AddMultiTargetEffect(WeaponDamageEffect);

ToHitCalc = new class'X2AbilityToHitCalc_StandardAim';
Template.AbilityToHitCalc = ToHitCalc;
Template.AbilityToHitOwnerOnMissCalc = ToHitCalc;

BurstFireMultiTarget = new class'X2AbilityMultiTarget_BurstFire';
BurstFireMultiTarget.NumExtraShots = 2;
Template.AbilityMultiTargetStyle = BurstFireMultiTarget;

// Targeting Method
Template.TargetingMethod = class'X2TargetingMethod_OverTheShoulder';
Template.CinescriptCameraType = "StandardGunFiring";

// Voice events
Template.ActivationSpeech = 'FanFire';

// MAKE IT LIVE!
Template.BuildNewGameStateFn = TypicalAbility_BuildGameState;
Template.BuildVisualizationFn = TypicalAbility_BuildVisualization;

return Template;
}

static function X2AbilityTemplate RapidFire()
{
local X2AbilityTemplate Template;
local X2AbilityCost_ActionPoints ActionPointCost;
local X2AbilityCost_Ammo AmmoCost;
local X2AbilityToHitCalc_StandardAim ToHitCalc;

`CREATE_X2ABILITY_TEMPLATE(Template, 'RapidFire');

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

// require 2 ammo to be present so that both shots can be taken
AmmoCost = new class'X2AbilityCost_Ammo';
AmmoCost.iAmmo = 2;
AmmoCost.bFreeCost = true;
Template.AbilityCosts.AddItem(AmmoCost);
// actually charge 1 ammo for this shot. the 2nd shot will charge the extra ammo.
AmmoCost = new class'X2AbilityCost_Ammo';
AmmoCost.iAmmo = 1;
Template.AbilityCosts.AddItem(AmmoCost);

ToHitCalc = new class'X2AbilityToHitCalc_StandardAim';
ToHitCalc.BuiltInHitMod = default.RAPIDFIRE_AIM;
Template.AbilityToHitCalc = ToHitCalc;
Template.AbilityToHitOwnerOnMissCalc = ToHitCalc;

Template.AbilityTargetStyle = default.SimpleSingleTarget;

Template.AbilityShooterConditions.AddItem(default.LivingShooterProperty);
Template.AddShooterEffectExclusions();

Template.AbilityTargetConditions.AddItem(default.LivingHostileTargetProperty);
Template.AbilityTargetConditions.AddItem(default.GameplayVisibilityCondition);

Template.AddTargetEffect(class'X2Ability_GrenadierAbilitySet'.static.HoloTargetEffect());
Template.AssociatedPassives.AddItem('HoloTargeting');
Template.AddTargetEffect(class'X2Ability_GrenadierAbilitySet'.static.ShredderDamageEffect());
Template.bAllowAmmoEffects = true;

Template.AbilityTriggers.AddItem(default.PlayerInputTrigger);

Template.ShotHUDPriority = class'UIUtilities_Tactical'.const.CLASS_COLONEL_PRIORITY;
Template.AbilitySourceName = 'eAbilitySource_Perk';
Template.eAbilityIconBehaviorHUD = eAbilityIconBehavior_AlwaysShow;
Template.IconImage = "img:///UILibrary_PerkIcons.UIPerk_rapidfire";
Template.AbilityConfirmSound = "TacticalUI_ActivateAbility";
Template.CinescriptCameraType = "StandardGunFiring";
Template.TargetingMethod = class'X2TargetingMethod_OverTheShoulder';

Template.BuildNewGameStateFn = TypicalAbility_BuildGameState;
Template.BuildVisualizationFn = TypicalAbility_BuildVisualization;
Template.BuildInterruptGameStateFn = TypicalAbility_BuildInterruptGameState;

Template.AdditionalAbilities.AddItem('RapidFire2');
Template.PostActivationEvents.AddItem('RapidFire2');

Template.bCrossClassEligible = true;
Template.bPreventsTargetTeleport = true;

return Template;
}

static function X2AbilityTemplate RapidFire2()
{
local X2AbilityTemplate Template;
local X2AbilityCost_Ammo AmmoCost;
local X2AbilityToHitCalc_StandardAim ToHitCalc;
local X2AbilityTrigger_EventListener Trigger;

`CREATE_X2ABILITY_TEMPLATE(Template, 'RapidFire2');

AmmoCost = new class'X2AbilityCost_Ammo';
AmmoCost.iAmmo = 1;
Template.AbilityCosts.AddItem(AmmoCost);

ToHitCalc = new class'X2AbilityToHitCalc_StandardAim';
ToHitCalc.BuiltInHitMod = default.RAPIDFIRE_AIM;
Template.AbilityToHitCalc = ToHitCalc;
Template.AbilityToHitOwnerOnMissCalc = ToHitCalc;

Template.AbilityTargetStyle = default.SimpleSingleTarget;

Template.AbilityShooterConditions.AddItem(default.LivingShooterProperty);
Template.AddShooterEffectExclusions();

Template.AbilityTargetConditions.AddItem(default.LivingHostileTargetProperty);

Template.AddTargetEffect(class'X2Ability_GrenadierAbilitySet'.static.HoloTargetEffect());
Template.AssociatedPassives.AddItem('HoloTargeting');
Template.AddTargetEffect(class'X2Ability_GrenadierAbilitySet'.static.ShredderDamageEffect());
Template.bAllowAmmoEffects = true;

Trigger = new class'X2AbilityTrigger_EventListener';
Trigger.ListenerData.Deferral = ELD_OnStateSubmitted;
Trigger.ListenerData.EventID = 'RapidFire2';
Trigger.ListenerData.Filter = eFilter_Unit;
Trigger.ListenerData.EventFn = class'XComGameState_Ability'.static.RapidFireListener;
Template.AbilityTriggers.AddItem(Trigger);

Template.ShotHUDPriority = class'UIUtilities_Tactical'.const.CLASS_COLONEL_PRIORITY;
Template.AbilitySourceName = 'eAbilitySource_Perk';
Template.eAbilityIconBehaviorHUD = eAbilityIconBehavior_NeverShow;
Template.IconImage = "img:///UILibrary_PerkIcons.UIPerk_rapidfire";
Template.CinescriptCameraType = "StandardGunFiring";

Template.BuildNewGameStateFn = TypicalAbility_BuildGameState;
Template.BuildVisualizationFn = TypicalAbility_BuildVisualization;
Template.bShowActivation = true;

return Template;
}

static function SuperKillRestrictions(X2AbilityTemplate Template, name ThisSuperKill)
{
local X2Condition_UnitValue ValueCondition;
local X2Effect_SetUnitValue ValueEffect;

ValueCondition = new class'X2Condition_UnitValue';
ValueCondition.AddCheckValue('RunAndGun_SuperKillCheck', 0, eCheck_Exact,,,'AA_RunAndGunUsed');
ValueCondition.AddCheckValue('Reaper_SuperKillCheck', 0, eCheck_Exact,,,'AA_ReaperUsed');
ValueCondition.AddCheckValue('Serial_SuperKillCheck', 0, eCheck_Exact,,,'AA_SerialUsed');
Template.AbilityShooterConditions.AddItem(ValueCondition);

ValueEffect = new class'X2Effect_SetUnitValue';
ValueEffect.UnitName = ThisSuperKill;
ValueEffect.NewValueToSet = 1;
ValueEffect.CleanupType = eCleanup_BeginTurn;
Template.AddShooterEffect(ValueEffect);
}
{
+MARK_TARGET_LOCAL_COOLDOWN=2
+BULLETSHRED_COOLDOWN=4
+BULLET_SHRED=3
+LIGHTNINGHANDS_COOLDOWN=4
+FACEOFF_COOLDOWN=4
+FANFIRE_COOLDOWN=4
+RAPIDFIRE_AIM=-15
+DEMO_HIT_BONUS=10
+DEMOLITION_COOLDOWN=4
}

 

 

Link to comment
Share on other sites

For one, what are you actually doing? You are duplicating the vanilla templates, which won't have a noticable effect.

Secondly, you are putting stuff that belongs into config files into the class itself, which won't have an effect.

Third, this

 

 

 

static function array<X2DataTemplate> CreateTemplates()
{
    local array<X2DataTemplate> Templates;
    
    Templates.AddItem(CreateMarkTargetAbility());
    
    return Templates;
}

{
    local array<X2DataTemplate> Templates;
    
    Templates.AddItem(MarkTarget());
    Templates.AddItem(HoloTargeting());
    Templates.AddItem(BulletShred());
    Templates.AddItem(Demolition());
    Templates.AddItem(Shadowstep());
    Templates.AddItem(EverVigilant());
    Templates.AddItem(EverVigilantTrigger());
    Templates.AddItem(Implacable());
    Templates.AddItem(Faceoff());
    Templates.AddItem(PurePassive('Quickdraw', "img:///UILibrary_PerkIcons.UIPerk_quickdraw"));
    Templates.AddItem(ReturnFire());
    Templates.AddItem(LightningHands());
    Templates.AddItem(FanFire());
    Templates.AddItem(RapidFire());
    Templates.AddItem(RapidFire2());

    return Templates;
}

 

 

 

should look like this

 

 

 

static function array<X2DataTemplate> CreateTemplates()
{
    local array<X2DataTemplate> Templates;
    
    Templates.AddItem(CreateMarkTargetAbility());
    Templates.AddItem(HoloTargeting());
    Templates.AddItem(BulletShred());
    Templates.AddItem(Demolition());
    Templates.AddItem(Shadowstep());
    Templates.AddItem(EverVigilant());
    Templates.AddItem(EverVigilantTrigger());
    Templates.AddItem(Implacable());
    Templates.AddItem(Faceoff());
    Templates.AddItem(PurePassive('Quickdraw', "img:///UILibrary_PerkIcons.UIPerk_quickdraw"));
    Templates.AddItem(ReturnFire());
    Templates.AddItem(LightningHands());
    Templates.AddItem(FanFire());
    Templates.AddItem(RapidFire());
    Templates.AddItem(RapidFire2());

    return Templates;
}

 

 

Link to comment
Share on other sites

Im trying to set up a custom class, but really I don't know what I'm doing because I am fairly new to any kind of modding. All I know is from following these two guides and poking around in other mods trying to figure out how this stuff works and what does what.

 

Guide 1: https://imgur.com/a/5NRRW#otymAih

 

Guide 2:

 

 

I have a new problem, where do I define cooldown and such?

 

 

C:\Program Files (x86)\Steam\steamapps\common\XCOM 2 SDK\Development\Src\OfficerMod\Classes\X2Ability_OfficerMod.uc(1007) : Error, Unknown Property 'RAPIDFIRE_AIM' in 'Function OfficerMod.X2Ability_OfficerMod:RapidFire'
C:\Program Files (x86)\Steam\steamapps\common\XCOM 2 SDK\Development\Src\OfficerMod\Classes\X2Ability_OfficerMod.uc(942) : Error, Unknown Property 'FANFIRE_COOLDOWN' in 'Function OfficerMod.X2Ability_OfficerMod:FanFire'
C:\Program Files (x86)\Steam\steamapps\common\XCOM 2 SDK\Development\Src\OfficerMod\Classes\X2Ability_OfficerMod.uc(572) : Error, Unknown Property 'FACEOFF_COOLDOWN' in 'Function OfficerMod.X2Ability_OfficerMod:Faceoff'
C:\Program Files (x86)\Steam\steamapps\common\XCOM 2 SDK\Development\Src\OfficerMod\Classes\X2Ability_OfficerMod.uc(516) : Error, Unknown Property 'EverVigilantEffectName' in 'Function OfficerMod.X2Ability_OfficerMod:EverVigilantTrigger'
C:\Program Files (x86)\Steam\steamapps\common\XCOM 2 SDK\Development\Src\OfficerMod\Classes\X2Ability_OfficerMod.uc(408) : Error, Unknown Property 'DEMO_HIT_BONUS' in 'Function OfficerMod.X2Ability_OfficerMod:Demolition'
C:\Program Files (x86)\Steam\steamapps\common\XCOM 2 SDK\Development\Src\OfficerMod\Classes\X2Ability_OfficerMod.uc(346) : Error, Bad or missing expression for token: ShredderDamageEffect, in '='
C:\Program Files (x86)\Steam\steamapps\common\XCOM 2 SDK\Development\Src\OfficerMod\Classes\X2Ability_OfficerMod.uc(280) : Error, Unknown Property 'HoloTargetEffectName' in 'Function OfficerMod.X2Ability_OfficerMod:HoloTargetEffect'
C:\Program Files (x86)\Steam\steamapps\common\XCOM 2 SDK\Development\Src\OfficerMod\Classes\X2Ability_OfficerMod.uc(47) : Error, Unknown Property 'MARK_TARGET_LOCAL_COOLDOWN' in

 

 

 

Edited by Pandandrew1
Link to comment
Share on other sites

  • Recently Browsing   0 members

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