Jump to content

PurePassive and Salvo


ClaytonCross

Recommended Posts

I made a class, I am giving it the ability salvo as a Corporal level ability option. It doesn't work. It grabs the Sargent ability instead. So I am just trying to get Salvo to register and work as intended.

That's why I said you might have to put it in the class's ability file, inside of the array where you've got all your other abilities. If you don't, the .ini file probably doesn't pick it up (which is the problem you have).

Link to comment
Share on other sites

  • Replies 44
  • Created
  • Last Reply

Top Posters In This Topic

Thanks for your help. It is resolved now. The issue was that the Sgt lvl in the SoldierRanks was missing the + at the beginning. Somehow that caused all the Sargent abilities to over right the Cpl abilities. I fixed that and tested it. It works fine now. So of course it was all a stupid mistake I just did not see it until I followed your guidance around. Now... my issues are:

 

1. Volatile Mix does not apply damage bonus

2. Overwatch with Ever vigilant is using the pistol instead of the rifle.

3. Return fire is till using the pistol even though I set it to primary

 

+SoldierRanks=( aAbilityTree=( (AbilityName="EverVigilant", ApplyToWeaponSlot=eInvSlot_PrimaryWeapon), --omited--

+SoldierRanks=( aAbilityTree=( (AbilityName="ReturnFire", ApplyToWeaponSlot=eInvSlot_PrimaryWeapon), --omited--

 

Thanks again for your patience and guidance.

Link to comment
Share on other sites

@ Kregano

you were right return fire ==> Template.bCrossClassEligible = false; // this can only work with pistols, which only sharpshooters have

@ prowler83

Not sure what you mean, but I recopied from the source classes everything I could find rebuilt and the errors persists. I am sure you are right I missed something stupid... that's usually how it goes for me. It seems like a general over watch issue to me but standard over-watch shoots work, its just when they would trigger a special ability for over-watch they use the pistol. For Volital mix I have no idea, the vanilla classes seem to be working with the ability if they get it via AWC or tree if heavies.

 

To clarify in case its something I missing here is everything I am looking at.

__________________________________________________________________________________________________________________________

[X2Ability_<Classname>]

---Omitted---

var name EverVigilantEffectName;
var config int VOLATILE_DAMAGE;
var config float VOLATILE_RADIUS;

---Omitted---

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

---Omitted---
Templates.AddItem(EverVigilant());
Templates.AddItem(EverVigilantTrigger());
---Omitted---
Templates.AddItem(VolatileMix());
Templates.AddItem(PurePassive('CoveringFire', "img:///UILibrary_PerkIcons.UIPerk_coverfire", true));
---Omitted---

return Templates;
}

---Omitted---

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;
}

---Omitted---

static function X2AbilityTemplate VolatileMix()
{
local X2AbilityTemplate Template;
local X2AbilityTargetStyle TargetStyle;
local X2AbilityTrigger Trigger;
local X2Effect_VolatileMix MixEffect;

`CREATE_X2ABILITY_TEMPLATE(Template, 'VolatileMix');

// Icon Properties
Template.IconImage = "img:///UILibrary_PerkIcons.UIPerk_volatilemix";

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);

MixEffect = new class'X2Effect_VolatileMix';
MixEffect.BuildPersistentEffect(1, true, true, true);
MixEffect.SetDisplayInfo(ePerkBuff_Passive, Template.LocFriendlyName, Template.GetMyLongDescription(), Template.IconImage,,,Template.AbilitySourceName);
MixEffect.BonusDamage = default.VOLATILE_DAMAGE;
Template.AddTargetEffect(MixEffect);

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

Template.bCrossClassEligible = true;

return Template;
}

---Omitted---

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;
}

---Omitted---

return Template;
}

DefaultProperties
{
EverVigilantEffectName = "EverVigilantTriggered";
}


__________________________________________________________________________________________________________________________

[X2AbilityTag.uc]
case 'VOLATILIEMIXDAMAGE':
OutString = string(class'X2Ability_GrenadierAbilitySet'.default.VOLATILE_DAMAGE);
break;
__________________________________________________________________________________________________________________________

[XcomClassData]
; Squaddie
+SoldierRanks=( aAbilityTree=( (AbilityName="PistolStandardShot", ApplyToWeaponSlot=eInvSlot_SecondaryWeapon), (AbilityName="BlastPadding", ApplyToWeaponSlot=eInvSlot_Unknown) ), aStatProgression=((StatType=eStat_Offense,StatAmount=10), (StatType=eStat_HP,StatAmount=1), (StatType=eStat_Strength,StatAmount=0), (StatType=eStat_Hacking,StatAmount=0), (StatType=eStat_CombatSims,StatAmount=1)), )
; Corporal
+SoldierRanks=( aAbilityTree=( (AbilityName="EverVigilant", ApplyToWeaponSlot=eInvSlot_PrimaryWeapon), (AbilityName="Salvo", ApplyToWeaponSlot=eInvSlot_Unknown) ), aStatProgression=((StatType=eStat_Offense,StatAmount=2), (StatType=eStat_HP,StatAmount=1), (StatType=eStat_Strength,StatAmount=1), (StatType=eStat_Hacking,StatAmount=5), (StatType=eStat_CombatSims,StatAmount=0)), )
; Sargeant
+SoldierRanks=( aAbilityTree=( (AbilityName="DeepCover"), (AbilityName="VolatileMix", ApplyToWeaponSlot=eInvSlot_Unknown) ), aStatProgression=((StatType=eStat_Offense,StatAmount=3), (StatType=eStat_HP,StatAmount=1), (StatType=eStat_Strength,StatAmount=0), (StatType=eStat_Hacking,StatAmount=5), (StatType=eStat_CombatSims,StatAmount=0)), )
; Lieutenant
+SoldierRanks=( aAbilityTree=( (AbilityName="CoveringFire", ApplyToWeaponSlot=eInvSlot_PrimaryWeapon), (AbilityName="Quickdraw") ), aStatProgression=((StatType=eStat_Offense,StatAmount=1), (StatType=eStat_HP,StatAmount=1), (StatType=eStat_Strength,StatAmount=0), (StatType=eStat_Hacking,StatAmount=5), (StatType=eStat_CombatSims,StatAmount=0)), )
; Captain
+SoldierRanks=( aAbilityTree=( (AbilityName="Sentinel", ApplyToWeaponSlot=eInvSlot_Unknown), (AbilityName="Suppression", ApplyToWeaponSlot=eInvSlot_PrimaryWeapon) ), aStatProgression=((StatType=eStat_Offense,StatAmount=2), (StatType=eStat_HP,StatAmount=1), (StatType=eStat_Strength,StatAmount=1), (StatType=eStat_Hacking,StatAmount=5), (StatType=eStat_CombatSims,StatAmount=0)), )
; Major
+SoldierRanks=( aAbilityTree=( (AbilityName="SharpshooterAim", ApplyToWeaponSlot=eInvSlot_PrimaryWeapon), (AbilityName="FieldMedic", ApplyToWeaponSlot=eInvSlot_Unknown) \\
), aStatProgression=((StatType=eStat_Offense,StatAmount=1), (StatType=eStat_HP,StatAmount=1), (StatType=eStat_Strength,StatAmount=0), (StatType=eStat_Hacking,StatAmount=5), (StatType=eStat_CombatSims,StatAmount=0)), )
; Colonel
+SoldierRanks=( aAbilityTree=( (AbilityName="ReturnFire", ApplyToWeaponSlot=eInvSlot_PrimaryWeapon), (AbilityName="Demolition", ApplyToWeaponSlot=eInvSlot_PrimaryWeapon) ), aStatProgression=((StatType=eStat_Offense,StatAmount=2), (StatType=eStat_HP,StatAmount=1), (StatType=eStat_Strength,StatAmount=0), (StatType=eStat_Hacking,StatAmount=5), (StatType=eStat_CombatSims,StatAmount=0)), )

__________________________________________________________________________________________________________________________

If I need another file beyond what is listed, that is surely what I am missing. Both Volatile Mix and EverVigilant show up and Ever vigilant even works its just that it uses the pistol instead of the rifle.

Link to comment
Share on other sites

ReturnFire is implemented to only work with pistols, but I don't see anywhere where it's hard-coded to use them. I suspect it's just that this is the only vanilla ranged weapon with infinite ammo.

 

What I mean is, put something in PostTemplatesCreated or wherever to grab the class template you're creating, and print all the soldier ranks to see if the game has set up Return Fire to apply to the primary weapon like you intend.

Link to comment
Share on other sites

ReturnFire is implemented to only work with pistols, but I don't see anywhere where it's hard-coded to use them. I suspect it's just that this is the only vanilla ranged weapon with infinite ammo.

 

What I mean is, put something in PostTemplatesCreated or wherever to grab the class template you're creating, and print all the soldier ranks to see if the game has set up Return Fire to apply to the primary weapon like you intend.

I've been told that putting a function in the hook that occurs whenever a saved game starts could do it if it called some part of XComGameState_Unit and iterates through the skill tree, or something like that. I haven't figured out how to do it myself.

Link to comment
Share on other sites

If its above your skill level, you can bet its above mine.

 

1. Any chance you know how to hard set the volatile mix radius and damage with variables? Since it does not work properly for me anyway maybe I could localize the variables and restore it to +2 damage and +1 radius.

 

2. It seems like ever vigilant is taking pistols before rifles. Maybe and overwatch order?

Link to comment
Share on other sites

static event OnPostTemplatesCreated()
{
	local X2SoldierClassTemplateManager ClassManager;
	local X2SoldierClassTemplate Template;
	local array<SoldierClassAbilityType> AbilityTree;
	local int i;

	Template = class'X2SoldierClassTemplateManager'.GetSoldierClassTemplateManager().FindSoldierClassTemplate('yourclassname');
	AbilityTree = Template.GetAbilityTree(iRank);
	for(i = 0; i < AbilityTree.length; ++i)
	{
		`log("Ability name:"@AbilityTree[i].AbilityName);
		`log("Applied to:"@AbilityTree.ApplyToWeaponSlot);
	}
}

I would do this for whatever rank(s) Return Fire and Ever Vigilant are at. Check if the output matches what you intended.

 

 

For Volatile Mix, I'm not good with implementing abilities but it looks like the damage and radius aren't directly set from whatever's in the config. Based on where they're used:

 

Damage:

 

Create a copy of VolatileMix (in X2Ability_GrenadierAbilitySet) and change the bonus damage for MixEffect to whatever you want.

 

Radius:

Not sure if there's a way to give an ability multiple AbilityMultiTargetStyle's but someone could probably figure it out.

Link to comment
Share on other sites

Sorry I am a bit of a Noob. I think understand what your saying for VolatileMix but I am not sure where you want me to apply the code for Return Fire and Ever Vigilant.

 

For Volatile Mix I changed:

MixEffect.BonusDamage = default.VOLATILE_DAMAGE;
-to-

MixEffect.BonusDamage = 2;

 

Seems to be working, but I do worry this breaks something. Seems too easy a fix.

Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...