Skip to content

Commit

Permalink
Merge pull request #4615 from SolastaMods/dev
Browse files Browse the repository at this point in the history
1.5.97.9
  • Loading branch information
ThyWoof authored May 14, 2024
2 parents a0c6b9f + 211295e commit 34709e6
Show file tree
Hide file tree
Showing 385 changed files with 2,845 additions and 5,062 deletions.
21 changes: 21 additions & 0 deletions Demoted/PathOfTheWildMagic-en.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Condition/&ConditionPathOfTheWildMagicBolsteringMagicRollDescription=You roll a d3 whenever making an attack roll or an ability check and add the number rolled to the d20 roll.
Condition/&ConditionPathOfTheWildMagicBolsteringMagicRollTitle=Bolstering Magic: Roll
Condition/&ConditionPathOfTheWildMagicBolsteringMagicSlotDescription=You gained one random spell slot between levels 1 and 3.
Condition/&ConditionPathOfTheWildMagicBolsteringMagicSlotTitle=Bolstering Magic: Slot
Feature/&FeaturePathOfTheWildMagicControlledSurgeDescription=Whenever you roll on the Wild Magic table, you can roll the die twice and choose which of the two effects to unleash. If you roll the same number on both dice, you can ignore the number and choose any effect on the table.
Feature/&FeaturePathOfTheWildMagicControlledSurgeTitle=Controlled Surge
Feature/&FeaturePathOfTheWildMagicUnstableBackslashDescription=Immediately after you take damage or fail a saving throw while raging, you can use your reaction to roll on the Wild Magic table and immediately produce the effect rolled. This effect replaces your current Wild Magic effect.
Feature/&FeaturePathOfTheWildMagicUnstableBackslashTitle=Unstable Backslash
Feature/&FeatureSetPathOfTheWildMagicWildSurgeDescription=When you enter your rage, roll on the Wild Magic table to determine the magical effect produced. If the effect requires a saving throw, the DC equals 8 + your proficiency bonus + your Constitution modifier.
Feature/&FeatureSetPathOfTheWildMagicWildSurgeTitle=Wild Surge
Feature/&PowerPathOfTheWildMagicBolsteringMagicDescription=As an action, you can touch one ally and confer one of the following benefits of your choice:\n• For 10 minutes, the creature can roll a d3 whenever making an attack roll or an ability check and add the number rolled to the d20 roll.\n• Roll a d3. The creature regains one expended spell slot, the level of which equals the number rolled. Once a creature receives this benefit, that creature can’t receive it again until after a long rest.\nYou can take this action a number of times equal to your proficiency bonus, and you regain all expended uses when you finish a long rest.
Feature/&PowerPathOfTheWildMagicBolsteringMagicRollDescription=As an action, you can touch one ally and for 10 minutes, they can roll a d3 whenever making an attack roll or an ability check and add the number rolled to the d20 roll.
Feature/&PowerPathOfTheWildMagicBolsteringMagicRollTitle=Bolstering Magic: Roll
Feature/&PowerPathOfTheWildMagicBolsteringMagicSpellDescription=As an action, you can touch one ally and roll a d3. The creature regains one expended spell slot, the level of which equals the number rolled. Once a creature receives this benefit, that creature can’t receive it again until after a long rest.
Feature/&PowerPathOfTheWildMagicBolsteringMagicSpellTitle=Bolstering Magic: Spell
Feature/&PowerPathOfTheWildMagicBolsteringMagicTitle=Bolstering Magic
Feature/&PowerPathOfTheWildMagicMagicAwarenessDescription=As an action, you can open your awareness to the presence of concentrated magic. Over the next minute, you know the location of any spell or magic item within 60 feet of you.
Feature/&PowerPathOfTheWildMagicMagicAwarenessTitle=Magic Awareness
Subclass/&PathOfTheWildMagicDescription=Many places in the multiverse abound with beauty, intense emotion, and rampant magic. the Feywild, the Upper Planes, and other realms of supernatural power radiate with such forces and can profoundly influence people. As folk of deep feeling, barbarians are especially susceptible to these wild influences, with some barbarians being transformed by the magic. These magic-suffused barbarians walk the Path of Wild Magic. Elf, tiefling, and aasimars often seek this path, eager to manifest the otherworldly magic of their ancestors.
Subclass/&PathOfTheWildMagicTitle=Path of the Wild Magic
Tooltip/&MustNotHaveBolsteringMagicSpell=Must not have Bolstering Magic slots
230 changes: 230 additions & 0 deletions Demoted/PathOfTheWildMagic.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
using System.Collections;
using System.Linq;
using JetBrains.Annotations;
using SolastaUnfinishedBusiness.Api.GameExtensions;
using SolastaUnfinishedBusiness.Behaviors.Specific;
using SolastaUnfinishedBusiness.Builders;
using SolastaUnfinishedBusiness.Builders.Features;
using SolastaUnfinishedBusiness.Interfaces;
using static RuleDefinitions;
using static SolastaUnfinishedBusiness.Api.DatabaseHelper;

namespace SolastaUnfinishedBusiness.Subclasses;

[UsedImplicitly]
public sealed class PathOfTheWildMagic //: AbstractSubclass
{
private const string Name = "PathOfTheWildMagic";

public PathOfTheWildMagic()
{
// Magic Awareness

var powerMagicAwareness = FeatureDefinitionPowerBuilder
.Create($"Power{Name}MagicAwareness")
.SetGuiPresentation(Category.Feature, SpellDefinitions.DetectMagic)
.SetUsesProficiencyBonus(ActivationTime.Action)
.SetEffectDescription(
EffectDescriptionBuilder
.Create(SpellDefinitions.DetectMagic)
.SetDurationData(DurationType.Minute, 1)
.SetTargetingData(Side.Ally, RangeType.Self, 0, TargetType.Self, 0)
.SetEffectForms(
EffectFormBuilder
.Create()
.SetDivinationForm(
DivinationForm.Type.RevealEntitiesBearingTags,
[], [TagsDefinitions.Magical], 12)
.Build(),
EffectFormBuilder.ConditionForm(ConditionDefinitions.ConditionDetectMagicSight))
.Build())
.AddToDB();

// Wild Surge

var featureSetWildSurge = FeatureDefinitionFeatureSetBuilder
.Create($"FeatureSet{Name}WildSurge")
.SetGuiPresentation(Category.Feature)
.SetFeatureSet()
.AddToDB();

// Bolstering Magic

var powerBolsteringMagic = FeatureDefinitionPowerBuilder
.Create($"Power{Name}BolsteringMagic")
.SetGuiPresentation(Category.Feature)
.SetUsesProficiencyBonus(ActivationTime.Action)
.SetEffectDescription(
EffectDescriptionBuilder
.Create()
.SetTargetingData(Side.Ally, RangeType.Touch, 0, TargetType.IndividualsUnique)
.Build())
.AddToDB();

var conditionBolsteringMagicRoll = ConditionDefinitionBuilder
.Create($"Condition{Name}BolsteringMagicRoll")
.SetGuiPresentation(Category.Condition)
.AddToDB();

conditionBolsteringMagicRoll.AddCustomSubFeatures(
new CustomBehaviorBolsteringMagicRoll(conditionBolsteringMagicRoll));

var powerBolsteringMagicRoll = FeatureDefinitionPowerSharedPoolBuilder
.Create($"Power{Name}BolsteringMagicRoll")
.SetGuiPresentation(Category.Feature, hidden: true)
.SetSharedPool(ActivationTime.Action, powerBolsteringMagic)
.SetEffectDescription(
EffectDescriptionBuilder
.Create()
.SetDurationData(DurationType.Minute, 10)
.SetTargetingData(Side.Ally, RangeType.Touch, 0, TargetType.IndividualsUnique)
.SetEffectForms(EffectFormBuilder.ConditionForm(conditionBolsteringMagicRoll))
.Build())
.AddToDB();

var db = DatabaseRepository.GetDatabase<FeatureDefinitionMagicAffinity>();
var conditions = new ConditionDefinition[3];

for (var i = 1; i <= 3; i++)
{
conditions[i - 1] = ConditionDefinitionBuilder
.Create($"Condition{Name}BolsteringMagicSlot{i}")
.SetGuiPresentation($"Condition{Name}BolsteringMagicSlot", Category.Condition)
.SetSilent(Silent.WhenRemoved)
.SetFeatures(db.GetElement($"MagicAffinityAdditionalSpellSlot{i}"))
.AddToDB();
}

var powerBolsteringMagicSpell = FeatureDefinitionPowerSharedPoolBuilder
.Create($"Power{Name}BolsteringMagicSpell")
.SetGuiPresentation(Category.Feature, hidden: true)
.SetSharedPool(ActivationTime.Action, powerBolsteringMagic)
.SetEffectDescription(
EffectDescriptionBuilder
.Create()
.SetDurationData(DurationType.UntilLongRest)
.SetTargetingData(Side.Ally, RangeType.Touch, 0, TargetType.IndividualsUnique)
.SetEffectForms(
EffectFormBuilder
.Create()
.SetConditionForm(
conditions[0],
ConditionForm.ConditionOperation.AddRandom,
false, false, conditions)
.Build())
.Build())
.AddCustomSubFeatures(new FilterTargetingCharacterBolsteringMagicSpell(conditions))
.AddToDB();

PowerBundle.RegisterPowerBundle(powerBolsteringMagic, false,
powerBolsteringMagicRoll, powerBolsteringMagicSpell);

var featureSetBolsteringMagic = FeatureDefinitionFeatureSetBuilder
.Create($"FeatureSet{Name}BolsteringMagic")
.SetGuiPresentation($"Power{Name}BolsteringMagic", Category.Feature)
.SetFeatureSet(powerBolsteringMagic, powerBolsteringMagicRoll, powerBolsteringMagicSpell)
.AddToDB();

// Unstable Backslash

var featureUnstableBackslash = FeatureDefinitionBuilder
.Create($"Feature{Name}UnstableBackslash")
.SetGuiPresentation(Category.Feature)
.AddToDB();

// Controlled Surge

var featureControlledSurge = FeatureDefinitionBuilder
.Create($"Feature{Name}ControlledSurge")
.SetGuiPresentation(Category.Feature)
.AddToDB();

// MAIN

Subclass = CharacterSubclassDefinitionBuilder
.Create(Name)
.SetGuiPresentation(Category.Subclass, CharacterSubclassDefinitions.PathBerserker)
.AddFeaturesAtLevel(3, powerMagicAwareness, featureSetWildSurge)
.AddFeaturesAtLevel(6, featureSetBolsteringMagic)
.AddFeaturesAtLevel(10, featureUnstableBackslash)
.AddFeaturesAtLevel(14, featureControlledSurge)
.AddToDB();
}

internal CharacterClassDefinition Klass => CharacterClassDefinitions.Barbarian;

internal CharacterSubclassDefinition Subclass { get; }

internal FeatureDefinitionSubclassChoice SubclassChoice =>
FeatureDefinitionSubclassChoices.SubclassChoiceBarbarianPrimalPath;

// ReSharper disable once UnassignedGetOnlyAutoProperty
internal DeityDefinition DeityDefinition { get; }

private sealed class CustomBehaviorBolsteringMagicRoll(
ConditionDefinition conditionBolsteringMagicRoll) : ITryAlterOutcomeAttack, ITryAlterOutcomeAttributeCheck
{
public IEnumerator OnTryAlterOutcomeAttack(
GameLocationBattleManager instance,
CharacterAction action,
GameLocationCharacter attacker,
GameLocationCharacter defender,
GameLocationCharacter helper,
ActionModifier actionModifier)
{
if (helper != defender)
{
yield break;
}

var advantageType = actionModifier.AttackAdvantageTrend switch
{
> 0 => AdvantageType.Advantage,
< 0 => AdvantageType.Disadvantage,
_ => AdvantageType.None
};

var roll = RollDie(DieType.D3, advantageType, out _, out _);

actionModifier.AttacktoHitTrends.Add(
new TrendInfo(roll, FeatureSourceType.CharacterFeature, conditionBolsteringMagicRoll.Name,
conditionBolsteringMagicRoll));
}

public IEnumerator OnTryAlterAttributeCheck(
GameLocationBattleManager battleManager,
AbilityCheckData abilityCheckData,
GameLocationCharacter defender,
GameLocationCharacter helper,
ActionModifier abilityCheckModifier)
{
if (helper != defender ||
abilityCheckData.AbilityCheckRollOutcome != RollOutcome.Failure)
{
yield break;
}
}
}

private sealed class FilterTargetingCharacterBolsteringMagicSpell(
params ConditionDefinition[] conditions) : IFilterTargetingCharacter
{
private readonly string[] _conditionNames = conditions.Select(x => x.Name).ToArray();

public bool EnforceFullSelection => false;

public bool IsValid(CursorLocationSelectTarget __instance, GameLocationCharacter target)
{
var isValid = !target.RulesetActor.HasAnyConditionOfType(_conditionNames);

if (isValid)
{
return true;
}

__instance.actionModifier.FailureFlags.Add("Tooltip/&MustNotHaveBolsteringMagicSpell");

return false;
}
}
}
Loading

0 comments on commit 34709e6

Please sign in to comment.