Skip to content

Commit

Permalink
Merge pull request #4151 from SolastaMods/dev
Browse files Browse the repository at this point in the history
1.5.94.29
  • Loading branch information
ThyWoof authored Oct 20, 2023
2 parents 0ce5da9 + 4656e68 commit b509b3c
Show file tree
Hide file tree
Showing 34 changed files with 336 additions and 318 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
using System;
using SolastaUnfinishedBusiness.CustomBehaviors;
using SolastaUnfinishedBusiness.CustomInterfaces;
using static RuleDefinitions;

namespace SolastaUnfinishedBusiness.Api.GameExtensions;

internal static class CharacterActionExtensions
{
internal const string ShouldKeepConcentration = "ActionShouldKeepConcentration";

// ReSharper disable once InconsistentNaming
internal static int GetSaveDC(this CharacterAction action)
{
Expand Down Expand Up @@ -65,8 +65,6 @@ internal static string FormatTitle(this CharacterAction action)
: magicEffect.SourceDefinition.FormatTitle();
}

internal const string ShouldKeepConcentration = "ActionShouldKeepConcentration";

internal static bool ShouldKeepConcentrationOnPowerUseOrSpend(RulesetCharacter character)
{
var glc = GameLocationCharacter.GetFromActor(character);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Linq;
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using SolastaUnfinishedBusiness.Builders;
using SolastaUnfinishedBusiness.CustomBehaviors;
using SolastaUnfinishedBusiness.CustomValidators;
Expand Down Expand Up @@ -331,4 +333,33 @@ internal static bool CanCastAnyInvocationOfActionId(this GameLocationCharacter i

return false;
}

private const string RepertoireKey = nameof(RulesetSpellRepertoire);

internal static void SetUsedSpellRepertoire(this GameLocationCharacter caster, RulesetSpellRepertoire repertoire)
{
if (repertoire == null)
{
return;
}

var selectedRepertoireIndex = caster.RulesetCharacter.SpellRepertoires.IndexOf(repertoire);

if (!caster.UsedSpecialFeatures.TryAdd(RepertoireKey, selectedRepertoireIndex))
{
caster.UsedSpecialFeatures[RepertoireKey] = selectedRepertoireIndex;
}
}

[CanBeNull]
internal static RulesetSpellRepertoire GetUsedSpellRepertoire(this GameLocationCharacter caster)
{
if (!caster.UsedSpecialFeatures.TryGetValue(RepertoireKey, out var selectedRepertoireIndex)
|| selectedRepertoireIndex > caster.RulesetCharacter.SpellRepertoires.Count)
{
return null;
}

return caster.RulesetCharacter.SpellRepertoires[selectedRepertoireIndex];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,12 @@ public void StoreAttacks(GameLocationCharacter character, ActionDefinitions.Acti
switch (type)
{
case ActionDefinitions.ActionType.Main:
Main.Info(
Main.Log(
$"StoreAttacks [{character.Name}] type: {type} number: {number ?? character.UsedMainAttacks} {ToString()}");
character.UsedSpecialFeatures[Key(MainAttacks)] = number ?? character.UsedMainAttacks;
break;
case ActionDefinitions.ActionType.Bonus:
Main.Info(
Main.Log(
$"StoreAttacks [{character.Name}] type: {type} number: {number ?? character.UsedBonusAttacks} {ToString()}");
character.UsedSpecialFeatures[Key(BonusAttacks)] = number ?? character.UsedBonusAttacks;
break;
Expand All @@ -126,14 +126,14 @@ public void LoadAttacks(GameLocationCharacter character, ActionDefinitions.Actio
character.UsedMainAttacks = character.UsedSpecialFeatures.TryGetValue(Key(MainAttacks), out number)
? number
: 0;
Main.Info(
Main.Log(
$"LoadAttacks [{character.Name}] type: {type} number: {character.UsedMainAttacks} {ToString()}");
break;
case ActionDefinitions.ActionType.Bonus:
character.UsedBonusAttacks = character.UsedSpecialFeatures.TryGetValue(Key(BonusAttacks), out number)
? number
: 0;
Main.Info(
Main.Log(
$"LoadAttacks [{character.Name}] type: {type} number: {character.UsedBonusAttacks} {ToString()}");
break;
}
Expand All @@ -150,7 +150,7 @@ public void StoreSpellcasting(GameLocationCharacter character, ActionDefinitions
character.UsedSpecialFeatures[key] = (character.UsedMainSpell ? MainSpell : 0)
+ (character.UsedMainCantrip ? MainCantrip : 0)
+ (character.UsedBonusSpell ? BonusSpell : 0);
Main.Info(
Main.Log(
$"StoreSpellcasting [{character.Name}] type: {type} '{key}' flags: {character.UsedSpecialFeatures[key]} ms: {character.UsedMainSpell}, mc: {character.UsedMainCantrip}, bs: {character.UsedBonusSpell} {ToString()}");
}

Expand All @@ -171,7 +171,7 @@ public void LoadSpellcasting(GameLocationCharacter character, ActionDefinitions.
character.usedMainCantrip = (flags & MainCantrip) > 0;
character.usedBonusSpell = (flags & BonusSpell) > 0;

Main.Info(
Main.Log(
$"LoadSpellcasting [{character.Name}] type: {type} '{key}' flags: {flags} ms: {character.UsedMainSpell}, mc: {character.UsedMainCantrip}, bs: {character.UsedBonusSpell} {ToString()}");
}

Expand Down
9 changes: 8 additions & 1 deletion SolastaUnfinishedBusiness/ChangelogHistory.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
1.5.94.28:
1.5.94.29:

- added additional sample portraits under Portraits [Artyoan]
- fixed gamepad support on extended load and save menus
- fixed Stunning Strike not checking if toggle was enabled
- improved Inexorable Hex and Steel Whirlwind filtering logic

1.5.94.28:

- added initial gamepad support on extended Load / Save menus
- fixed a bad refactoring that inverted a sign and unleashed hell on game behaviors
Expand Down
48 changes: 32 additions & 16 deletions SolastaUnfinishedBusiness/CustomBehaviors/ActionSwitching.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,8 @@ private static List<FeatureDefinition> GetConditionFeatures<T>(

internal static void PrioritizeAction(GameLocationCharacter character, ActionDefinitions.ActionType type, int index)
{
Main.Info($"PrioritizeAction [{character.Name}] {type}");
// ReSharper disable once InvocationIsSkipped
Main.Log($"PrioritizeAction [{character.Name}] {type}");
var service = ServiceRepository.GetService<IGameLocationActionService>();
var actionParams = new CharacterActionParams
{
Expand All @@ -206,7 +207,8 @@ internal static void PrioritizeAction(GameLocationCharacter character, ActionDef
internal static void DoPrioritizeAction(GameLocationCharacter character, ActionDefinitions.ActionType type,
int index)
{
Main.Info($"DoPrioritizeAction [{character.Name}] {type}");
// ReSharper disable once InvocationIsSkipped
Main.Log($"DoPrioritizeAction [{character.Name}] {type}");
var rank = character.CurrentActionRankByType[type];
if (index <= rank)
{
Expand Down Expand Up @@ -282,13 +284,15 @@ private static bool CheckIfActionSwitched(GameLocationCharacter character, Actio

if (rank == wasRank)
{
Main.Info($"CheckIfActionSwitched [{character.Name}] {type} rank: {rank} - NO CHANGE");
// ReSharper disable once InvocationIsSkipped
Main.Log($"CheckIfActionSwitched [{character.Name}] {type} rank: {rank} - NO CHANGE");
newData?.StoreAttacks(character, type);
newData?.StoreSpellcasting(character, type);
return false;
}

Main.Info($"CheckIfActionSwitched [{character.Name}] {type} was: {wasRank} new: {rank}");
// ReSharper disable once InvocationIsSkipped
Main.Log($"CheckIfActionSwitched [{character.Name}] {type} was: {wasRank} new: {rank}");

if (wasRank >= filters.Count)
{
Expand Down Expand Up @@ -394,7 +398,8 @@ private static void ResortPerformancesOfType(GameLocationCharacter character,
var filters = character.ActionPerformancesByType[type];
var filtersCount = filters.Count;

Main.Info(
// ReSharper disable once InvocationIsSkipped
Main.Log(
$"ResortPerformancesOfType [{character.Name}] {type} filters: {filtersCount} features: [{string.Join(", ", features.Select(x => $"<{x.feature.Name}|{x.origin}>"))}]");

for (var i = 0; i < filtersCount; i++)
Expand All @@ -413,7 +418,8 @@ private static void ResortPerformancesOfType(GameLocationCharacter character,
var rank = character.CurrentActionRankByType[type];
var list = LoadIndexes(character.UsedSpecialFeatures, type, filtersCount);

Main.Info($"ResortPerformancesOfType [{character.Name}] {type} : [{string.Join(", ", list)}] rank: {rank}");
// ReSharper disable once InvocationIsSkipped
Main.Log($"ResortPerformancesOfType [{character.Name}] {type} : [{string.Join(", ", list)}] rank: {rank}");

var sorted = list.Select(k => filters[k]).ToList();

Expand All @@ -437,7 +443,8 @@ public static void AccountRemovedCondition(RulesetCharacter character, RulesetCo

if (locCharacter == null)
{
Main.Info($"AccountRemovedCondition [{character.Name}] '{condition.Name}' NO LOC CHAR");
// ReSharper disable once InvocationIsSkipped
Main.Log($"AccountRemovedCondition [{character.Name}] '{condition.Name}' NO LOC CHAR");
return;
}

Expand All @@ -447,15 +454,17 @@ public static void AccountRemovedCondition(RulesetCharacter character, RulesetCo

if (conditionFeatures.Empty())
{
Main.Info($"AccountRemovedCondition [{character.Name}] '{condition.Name}' NO ACTIONS");
// ReSharper disable once InvocationIsSkipped
Main.Log($"AccountRemovedCondition [{character.Name}] '{condition.Name}' NO ACTIONS");
return;
}

var features = EnumerateActorFeatures<IAdditionalActionsProvider>(character);

if (features == null)
{
Main.Info($"AccountRemovedCondition [{character.Name}] '{condition.Name}' NO FEATURES");
// ReSharper disable once InvocationIsSkipped
Main.Log($"AccountRemovedCondition [{character.Name}] '{condition.Name}' NO FEATURES");
return;
}

Expand All @@ -474,8 +483,10 @@ public static void AccountRemovedCondition(RulesetCharacter character, RulesetCo
var max = filters.Count;
var list = LoadIndexes(locCharacter.UsedSpecialFeatures, type, max);

Main.Info($"AccountRemovedCondition [{character.Name}] '{conditionFeature.Name}' from '{origin}'");
Main.Info($"AccountRemovedCondition [{character.Name}] WAS: [{string.Join(", ", list)}]");
// ReSharper disable once InvocationIsSkipped
Main.Log($"AccountRemovedCondition [{character.Name}] '{conditionFeature.Name}' from '{origin}'");
// ReSharper disable once InvocationIsSkipped
Main.Log($"AccountRemovedCondition [{character.Name}] WAS: [{string.Join(", ", list)}]");

var k = -1;

Expand All @@ -499,7 +510,8 @@ public static void AccountRemovedCondition(RulesetCharacter character, RulesetCo

var rank = locCharacter.CurrentActionRankByType[type];

Main.Info($"AccountRemovedCondition [{character.Name}] remove at: {k} rank was: {rank}");
// ReSharper disable once InvocationIsSkipped
Main.Log($"AccountRemovedCondition [{character.Name}] remove at: {k} rank was: {rank}");

if (rank > k)
{
Expand All @@ -518,7 +530,8 @@ public static void AccountRemovedCondition(RulesetCharacter character, RulesetCo
}
}

Main.Info($"AccountRemovedCondition [{character.Name}] BECAME: [{string.Join(", ", list)}]");
// ReSharper disable once InvocationIsSkipped
Main.Log($"AccountRemovedCondition [{character.Name}] BECAME: [{string.Join(", ", list)}]");

SaveIndexes(locCharacter.UsedSpecialFeatures, type, list);
}
Expand Down Expand Up @@ -551,7 +564,8 @@ public static void SpendActionType(GameLocationCharacter character, ActionDefini
return;
}

Main.Info($"SpendActionType [{character.Name}] {type} rank: {rank}, filters: {filters.Count}");
// ReSharper disable once InvocationIsSkipped
Main.Log($"SpendActionType [{character.Name}] {type} rank: {rank}, filters: {filters.Count}");

data.StoreAttacks(character, type);
data.StoreSpellcasting(character, type);
Expand Down Expand Up @@ -593,12 +607,14 @@ public static void RefundActionUse(GameLocationCharacter character, ActionDefini

var filters = character.actionPerformancesByType[type];

Main.Info($"RefundActionUse [{character.Name}] {type} rank: {rank}, filters: {filters.Count}");
// ReSharper disable once InvocationIsSkipped
Main.Log($"RefundActionUse [{character.Name}] {type} rank: {rank}, filters: {filters.Count}");

//PATCH: fixed action switching interaction with actions that offer further selections in a modal and get cancelled by player
if (filters.Count <= rank)
{
Main.Info($"RefundActionUse ABORTED [{character.Name}] {type} rank: {rank}, filters: {filters.Count}");
// ReSharper disable once InvocationIsSkipped
Main.Log($"RefundActionUse ABORTED [{character.Name}] {type} rank: {rank}, filters: {filters.Count}");

return;
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ namespace SolastaUnfinishedBusiness.CustomBehaviors;
internal static class GameLocationBattleManagerTweaks
{
// ReSharper disable once InconsistentNaming
private static int ComputeSavingThrowDC(RulesetCharacter character, IAdditionalDamageProvider provider)
private static int ComputeSavingThrowDC(GameLocationCharacter glc, IAdditionalDamageProvider provider)
{
var character = glc.RulesetCharacter;

// ReSharper disable once ConvertSwitchStatementToSwitchExpression
switch (provider.DcComputation)
{
Expand All @@ -26,13 +28,24 @@ private static int ComputeSavingThrowDC(RulesetCharacter character, IAdditionalD
case RuleDefinitions.EffectDifficultyClassComputation.SpellCastingFeature:
{
//BUGFIX: original game code considers first repertoire
return character.SpellRepertoires
var usedRepertoire = glc.GetUsedSpellRepertoire();

return usedRepertoire?.SaveDC ?? character.SpellRepertoires
.Select(x => x.SaveDC)
.Max();
}
case RuleDefinitions.EffectDifficultyClassComputation.AbilityScoreAndProficiency:
{
//BUGFIX: original game code considers first repertoire
var usedRepertoire = glc.GetUsedSpellRepertoire();

if (usedRepertoire != null)
{
return RuleDefinitions.ComputeAbilityScoreBasedDC(
character.TryGetAttributeValue(usedRepertoire.SpellCastingFeature.SpellcastingAbility),
character.TryGetAttributeValue(AttributeDefinitions.ProficiencyBonus));
}

return character.SpellRepertoires
.Select(x => RuleDefinitions.ComputeAbilityScoreBasedDC(
character.TryGetAttributeValue(x.SpellCastingFeature.SpellcastingAbility),
Expand Down Expand Up @@ -633,7 +646,7 @@ .SpellcastingBonus or RuleDefinitions.AdditionalDamageValueDetermination
// var rulesetImplementationService =
// ServiceRepository.GetService<IRulesetImplementationService>();
// ReSharper disable once InconsistentNaming
var saveDC = ComputeSavingThrowDC(attacker.RulesetCharacter, provider);
var saveDC = ComputeSavingThrowDC(attacker, provider);
newEffectForm.OverrideSavingThrowInfo = new OverrideSavingThrowInfo(provider.SavingThrowAbility,
saveDC, provider.Name, RuleDefinitions.FeatureSourceType.ExplicitFeature);
}
Expand Down Expand Up @@ -693,7 +706,7 @@ .SpellcastingBonus or RuleDefinitions.AdditionalDamageValueDetermination
// var rulesetImplementationService =
// ServiceRepository.GetService<IRulesetImplementationService>();
// ReSharper disable once InconsistentNaming
var saveDC = ComputeSavingThrowDC(attacker.RulesetCharacter, provider);
var saveDC = ComputeSavingThrowDC(attacker, provider);
newEffectForm.OverrideSavingThrowInfo = new OverrideSavingThrowInfo(provider.SavingThrowAbility,
saveDC, provider.Name, RuleDefinitions.FeatureSourceType.ExplicitFeature);
}
Expand Down
Loading

0 comments on commit b509b3c

Please sign in to comment.