Skip to content

Commit

Permalink
fix Corrupting Bolt, Ice Blade, Sanctuary, and Vitality Transfer inte…
Browse files Browse the repository at this point in the history
…raction with twinned
  • Loading branch information
ThyWoof committed Feb 8, 2024
1 parent a37e8df commit 896ebbd
Show file tree
Hide file tree
Showing 2 changed files with 104 additions and 85 deletions.
114 changes: 61 additions & 53 deletions SolastaUnfinishedBusiness/Spells/SpellBuildersLevel01.cs
Original file line number Diff line number Diff line change
Expand Up @@ -755,56 +755,60 @@ public IEnumerator OnMagicEffectFinishedByMe(CharacterActionMagicEffect action,
}

var caster = actionCastSpell.ActingCharacter;
var target = actionCastSpell.ActionParams.TargetCharacters[0];
var rulesetCaster = caster.RulesetCharacter;
var effectLevel = actionCastSpell.ActionParams.activeEffect.EffectLevel;
var isCritical = actionCastSpell.AttackRollOutcome == RollOutcome.CriticalSuccess;

foreach (var enemy in Gui.Battle
.GetContenders(target, isOppositeSide: false, excludeSelf: false, withinRange: 1))
// need to loop over target characters to support twinned metamagic scenarios
foreach (var target in actionCastSpell.ActionParams.TargetCharacters)
{
var rulesetEnemy = enemy.RulesetCharacter;
var casterSaveDC = 8 + actionCastSpell.ActiveSpell.MagicAttackBonus;
var modifierTrend = rulesetEnemy.actionModifier.savingThrowModifierTrends;
var advantageTrends = rulesetEnemy.actionModifier.savingThrowAdvantageTrends;
var enemyDexModifier = AttributeDefinitions.ComputeAbilityScoreModifier(
rulesetEnemy.TryGetAttributeValue(AttributeDefinitions.Dexterity));

rulesetEnemy.RollSavingThrow(
0, AttributeDefinitions.Dexterity, baseDefinition, modifierTrend, advantageTrends, enemyDexModifier,
casterSaveDC,
false, out var savingOutcome, out _);

if (savingOutcome is RollOutcome.Success or RollOutcome.CriticalSuccess)
foreach (var enemy in Gui.Battle
.GetContenders(target, isOppositeSide: false, excludeSelf: false, withinRange: 1))
{
continue;
var rulesetEnemy = enemy.RulesetCharacter;
var casterSaveDC = 8 + actionCastSpell.ActiveSpell.MagicAttackBonus;
var modifierTrend = rulesetEnemy.actionModifier.savingThrowModifierTrends;
var advantageTrends = rulesetEnemy.actionModifier.savingThrowAdvantageTrends;
var enemyDexModifier = AttributeDefinitions.ComputeAbilityScoreModifier(
rulesetEnemy.TryGetAttributeValue(AttributeDefinitions.Dexterity));

rulesetEnemy.RollSavingThrow(
0, AttributeDefinitions.Dexterity, baseDefinition, modifierTrend, advantageTrends,
enemyDexModifier,
casterSaveDC,
false, out var savingOutcome, out _);

if (savingOutcome is RollOutcome.Success or RollOutcome.CriticalSuccess)
{
continue;
}

var rolls = new List<int>();
var damageForm = new DamageForm
{
DamageType = DamageTypeCold,
DieType = DieType.D6,
DiceNumber = 2 + (effectLevel - 1),
BonusDamage = 0
};
var damageRoll =
rulesetCaster.RollDamage(damageForm, 0, false, 0, 0, 1, false, false, false, rolls);

EffectHelpers.StartVisualEffect(caster, target, ConeOfCold);
RulesetActor.InflictDamage(
damageRoll,
damageForm,
damageForm.DamageType,
new RulesetImplementationDefinitions.ApplyFormsParams { targetCharacter = rulesetEnemy },
rulesetEnemy,
isCritical,
rulesetCaster.Guid,
false,
[],
new RollInfo(damageForm.DieType, rolls, 0),
true,
out _);
}

var rolls = new List<int>();
var damageForm = new DamageForm
{
DamageType = DamageTypeCold,
DieType = DieType.D6,
DiceNumber = 2 + (effectLevel - 1),
BonusDamage = 0
};
var damageRoll =
rulesetCaster.RollDamage(damageForm, 0, false, 0, 0, 1, false, false, false, rolls);

EffectHelpers.StartVisualEffect(caster, target, ConeOfCold);
RulesetActor.InflictDamage(
damageRoll,
damageForm,
damageForm.DamageType,
new RulesetImplementationDefinitions.ApplyFormsParams { targetCharacter = rulesetEnemy },
rulesetEnemy,
isCritical,
rulesetCaster.Guid,
false,
[],
new RollInfo(damageForm.DieType, rolls, 0),
true,
out _);
}
}
}
Expand Down Expand Up @@ -1406,19 +1410,23 @@ public IEnumerator OnMagicEffectFinishedByMe(CharacterActionMagicEffect action,
}

var rulesetCaster = action.ActingCharacter.RulesetCharacter;
var rulesetTarget = action.ActionParams.TargetCharacters[0].RulesetCharacter;

if (!rulesetTarget.TryGetConditionOfCategoryAndType(
AttributeDefinitions.TagEffect,
conditionSanctuary.Name,
out var activeCondition))
// need to loop over target characters to support twinned metamagic scenarios
foreach (var rulesetTarget in action.ActionParams.TargetCharacters
.Select(target => target.RulesetCharacter))
{
yield break;
}
if (!rulesetTarget.TryGetConditionOfCategoryAndType(
AttributeDefinitions.TagEffect,
conditionSanctuary.Name,
out var activeCondition))
{
yield break;
}

rulesetTarget.EnumerateFeaturesToBrowse<ISpellCastingAffinityProvider>(
rulesetCaster.FeaturesToBrowse, rulesetCaster.FeaturesOrigin);
activeCondition.Amount = rulesetCaster.ComputeSaveDC(actionCastSpell.activeSpell.SpellRepertoire);
rulesetTarget.EnumerateFeaturesToBrowse<ISpellCastingAffinityProvider>(
rulesetCaster.FeaturesToBrowse, rulesetCaster.FeaturesOrigin);
activeCondition.Amount = rulesetCaster.ComputeSaveDC(actionCastSpell.activeSpell.SpellRepertoire);
}
}
}

Expand Down
75 changes: 43 additions & 32 deletions SolastaUnfinishedBusiness/Spells/SpellBuildersLevel03.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1190,28 +1190,33 @@ private sealed class MagicEffectFinishedByMeCorruptingBolt(ConditionDefinition c
{
public IEnumerator OnMagicEffectFinishedByMe(CharacterActionMagicEffect action, BaseDefinition baseDefinition)
{
var rulesetAttacker = action.ActingCharacter.RulesetCharacter;
var rulesetDefender = action.ActionParams.TargetCharacters[0].RulesetCharacter;

if (rulesetDefender is not { IsDeadOrDyingOrUnconscious: false }
|| !action.RolledSaveThrow || action.SaveOutcome == RollOutcome.Success)
if (!action.RolledSaveThrow || action.SaveOutcome == RollOutcome.Success)
{
yield break;
}

rulesetDefender.InflictCondition(
conditionCorruptingBolt.Name,
conditionCorruptingBolt.DurationType,
conditionCorruptingBolt.DurationParameter,
conditionCorruptingBolt.TurnOccurence,
AttributeDefinitions.TagEffect,
rulesetAttacker.guid,
rulesetAttacker.CurrentFaction.Name,
1,
conditionCorruptingBolt.Name,
0,
0,
0);
var rulesetAttacker = action.ActingCharacter.RulesetCharacter;

// need to loop over target characters to support twinned metamagic scenarios
foreach (var rulesetDefender in action.ActionParams.TargetCharacters
.Select(target => target.RulesetCharacter)
.Where(rulesetDefender =>
rulesetDefender is { IsDeadOrDyingOrUnconscious: false }))
{
rulesetDefender.InflictCondition(
conditionCorruptingBolt.Name,
conditionCorruptingBolt.DurationType,
conditionCorruptingBolt.DurationParameter,
conditionCorruptingBolt.TurnOccurence,
AttributeDefinitions.TagEffect,
rulesetAttacker.guid,
rulesetAttacker.CurrentFaction.Name,
1,
conditionCorruptingBolt.Name,
0,
0,
0);
}
}
}

Expand Down Expand Up @@ -1261,26 +1266,32 @@ public IEnumerator OnMagicEffectFinishedByMe(CharacterActionMagicEffect action,

var caster = action.ActingCharacter;
var rulesetCaster = caster.RulesetCharacter;
var rulesetTarget = action.ActionParams.TargetCharacters[0].RulesetCharacter;
var rolls = new List<int>();
var diceNumber = 4 + actionCastSpell.activeSpell.EffectLevel - 3;
var damageForm = new DamageForm

// need to loop over target characters to support twinned metamagic scenarios
foreach (var target in action.ActionParams.TargetCharacters)
{
DamageType = DamageTypeNecrotic, DiceNumber = diceNumber, DieType = DieType.D8
};
var totalDamage = rulesetCaster.RollDamage(damageForm, 0, false, 0, 0, 1, false, false, false, rolls);
var totalHealing = totalDamage * 2;
var currentHitPoints = rulesetCaster.CurrentHitPoints;
var rulesetTarget = target.RulesetCharacter;
var rolls = new List<int>();
var damageForm = new DamageForm
{
DamageType = DamageTypeNecrotic, DiceNumber = diceNumber, DieType = DieType.D8
};
var totalDamage = rulesetCaster.RollDamage(damageForm, 0, false, 0, 0, 1, false, false, false, rolls);
var totalHealing = totalDamage * 2;
var currentHitPoints = rulesetCaster.CurrentHitPoints;

rulesetCaster.SustainDamage(totalDamage, damageForm.DamageType, false, rulesetCaster.Guid,
new RollInfo(damageForm.DieType, rolls, 0), out _);
rulesetCaster.SustainDamage(totalDamage, damageForm.DamageType, false, rulesetCaster.Guid,
new RollInfo(damageForm.DieType, rolls, 0), out _);

EffectHelpers.StartVisualEffect(caster, caster, PowerSorcererChildRiftOffering);
EffectHelpers.StartVisualEffect(caster, caster, PowerSorcererChildRiftOffering);

rulesetCaster.DamageSustained?.Invoke(rulesetCaster, totalDamage, damageForm.DamageType, true,
currentHitPoints > totalDamage, false);
rulesetCaster.DamageSustained?.Invoke(rulesetCaster, totalDamage, damageForm.DamageType, true,
currentHitPoints > totalDamage, false);

rulesetTarget.ReceiveHealing(totalHealing, true, rulesetCaster.Guid);
}

rulesetTarget.ReceiveHealing(totalHealing, true, rulesetCaster.Guid);
}
}

Expand Down

0 comments on commit 896ebbd

Please sign in to comment.