diff --git a/Diagnostics/CE-Definitions-GuiPresentation-InvalidSyntaxTranslation-en.txt b/Diagnostics/CE-Definitions-GuiPresentation-InvalidSyntaxTranslation-en.txt
index 77064506c8..5d6539cd83 100644
--- a/Diagnostics/CE-Definitions-GuiPresentation-InvalidSyntaxTranslation-en.txt
+++ b/Diagnostics/CE-Definitions-GuiPresentation-InvalidSyntaxTranslation-en.txt
@@ -1248,6 +1248,8 @@ PowerCreateSpellStoringWandOfColorBurst Title='Color Burst'.
PowerCreateSpellStoringWandOfColorBurst Description='Create a wand that can cast Color Burst (II) spell using your Artificer spell attack modifier and save DC.'.
PowerCreateSpellStoringWandOfColorSpray Title='Color Spray'.
PowerCreateSpellStoringWandOfColorSpray Description='Create a wand that can cast Color Spray (I) spell using your Artificer spell attack modifier and save DC.'.
+PowerCreateSpellStoringWandOfCommandSpell Title='Command'.
+PowerCreateSpellStoringWandOfCommandSpell Description='Create a wand that can cast Command (I) spell using your Artificer spell attack modifier and save DC.'.
PowerCreateSpellStoringWandOfComprehendLanguages Title='Comprehend Languages'.
PowerCreateSpellStoringWandOfComprehendLanguages Description='Create a wand that can cast Comprehend Languages (I) spell using your Artificer spell attack modifier and save DC.'.
PowerCreateSpellStoringWandOfConjureGoblinoids Title='Conjure Goblinoids'.
@@ -1264,6 +1266,8 @@ PowerCreateSpellStoringWandOfDetectMagic Title='Detect Magic'.
PowerCreateSpellStoringWandOfDetectMagic Description='Create a wand that can cast Detect Magic (I) spell using your Artificer spell attack modifier and save DC.'.
PowerCreateSpellStoringWandOfDetectPoisonAndDisease Title='Detect Poison and Disease'.
PowerCreateSpellStoringWandOfDetectPoisonAndDisease Description='Create a wand that can cast Detect Poison and Disease (I) spell using your Artificer spell attack modifier and save DC.'.
+PowerCreateSpellStoringWandOfDissonantWhispers Title='Dissonant Whispers'.
+PowerCreateSpellStoringWandOfDissonantWhispers Description='Create a wand that can cast Dissonant Whispers (I) spell using your Artificer spell attack modifier and save DC.'.
PowerCreateSpellStoringWandOfEarthTremor Title='Earth Tremor'.
PowerCreateSpellStoringWandOfEarthTremor Description='Create a wand that can cast Earth Tremor (I) spell using your Artificer spell attack modifier and save DC.'.
PowerCreateSpellStoringWandOfEnhanceAbility Title='Enhance Ability'.
@@ -1782,6 +1786,8 @@ SpellStoringWandOfColorBurst Title='Wand of Color Burst'.
SpellStoringWandOfColorBurst Description='This wand allows casting the Color Burst spell using spell casting stats of the Artificer who created it.'.
SpellStoringWandOfColorSpray Title='Wand of Color Spray'.
SpellStoringWandOfColorSpray Description='This wand allows casting the Color Spray spell using spell casting stats of the Artificer who created it.'.
+SpellStoringWandOfCommandSpell Title='Wand of Command'.
+SpellStoringWandOfCommandSpell Description='This wand allows casting the Command spell using spell casting stats of the Artificer who created it.'.
SpellStoringWandOfComprehendLanguages Title='Wand of Comprehend Languages'.
SpellStoringWandOfComprehendLanguages Description='This wand allows casting the Comprehend Languages spell using spell casting stats of the Artificer who created it.'.
SpellStoringWandOfConjureGoblinoids Title='Wand of Conjure Goblinoids'.
@@ -1798,6 +1804,8 @@ SpellStoringWandOfDetectMagic Title='Wand of Detect Magic'.
SpellStoringWandOfDetectMagic Description='This wand allows casting the Detect Magic spell using spell casting stats of the Artificer who created it.'.
SpellStoringWandOfDetectPoisonAndDisease Title='Wand of Detect Poison and Disease'.
SpellStoringWandOfDetectPoisonAndDisease Description='This wand allows casting the Detect Poison and Disease spell using spell casting stats of the Artificer who created it.'.
+SpellStoringWandOfDissonantWhispers Title='Wand of Dissonant Whispers'.
+SpellStoringWandOfDissonantWhispers Description='This wand allows casting the Dissonant Whispers spell using spell casting stats of the Artificer who created it.'.
SpellStoringWandOfEarthTremor Title='Wand of Earth Tremor'.
SpellStoringWandOfEarthTremor Description='This wand allows casting the Earth Tremor spell using spell casting stats of the Artificer who created it.'.
SpellStoringWandOfEnhanceAbility Title='Wand of Enhance Ability'.
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ActionDefinition/CastInvocationBonus.json b/Diagnostics/UnfinishedBusinessBlueprints/ActionDefinition/CastInvocationBonus.json
index 9c49313057..15513e9f3e 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ActionDefinition/CastInvocationBonus.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ActionDefinition/CastInvocationBonus.json
@@ -63,7 +63,7 @@
"a": 1.0
},
"symbolChar": "221E",
- "sortOrder": 12,
+ "sortOrder": 43,
"unusedInSolastaCOTM": false,
"usedInValleyDLC": false
},
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ActionDefinition/CastInvocationNoCost.json b/Diagnostics/UnfinishedBusinessBlueprints/ActionDefinition/CastInvocationNoCost.json
index ad5edb39fb..f76f05806f 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ActionDefinition/CastInvocationNoCost.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ActionDefinition/CastInvocationNoCost.json
@@ -63,7 +63,7 @@
"a": 1.0
},
"symbolChar": "221E",
- "sortOrder": 12,
+ "sortOrder": 101,
"unusedInSolastaCOTM": false,
"usedInValleyDLC": false
},
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ActionDefinition/CastPlaneMagicBonus.json b/Diagnostics/UnfinishedBusinessBlueprints/ActionDefinition/CastPlaneMagicBonus.json
index 1101d52978..6e9a8273a2 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ActionDefinition/CastPlaneMagicBonus.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ActionDefinition/CastPlaneMagicBonus.json
@@ -63,7 +63,7 @@
"a": 1.0
},
"symbolChar": "221E",
- "sortOrder": 41,
+ "sortOrder": 42,
"unusedInSolastaCOTM": false,
"usedInValleyDLC": false
},
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ActionDefinition/CastPlaneMagicMain.json b/Diagnostics/UnfinishedBusinessBlueprints/ActionDefinition/CastPlaneMagicMain.json
index fe7b1b3ff1..70d2f75822 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ActionDefinition/CastPlaneMagicMain.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ActionDefinition/CastPlaneMagicMain.json
@@ -63,7 +63,7 @@
"a": 1.0
},
"symbolChar": "221E",
- "sortOrder": 10,
+ "sortOrder": 11,
"unusedInSolastaCOTM": false,
"usedInValleyDLC": false
},
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ActionDefinition/CastQuickened.json b/Diagnostics/UnfinishedBusinessBlueprints/ActionDefinition/CastQuickened.json
index 679cfd69a8..0b5dd97063 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ActionDefinition/CastQuickened.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ActionDefinition/CastQuickened.json
@@ -63,7 +63,7 @@
"a": 1.0
},
"symbolChar": "221E",
- "sortOrder": 0,
+ "sortOrder": 41,
"unusedInSolastaCOTM": false,
"usedInValleyDLC": false
},
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/Assets.txt b/Diagnostics/UnfinishedBusinessBlueprints/Assets.txt
index 303b8f7d68..6a3e86c1bc 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/Assets.txt
+++ b/Diagnostics/UnfinishedBusinessBlueprints/Assets.txt
@@ -692,6 +692,10 @@ ConditionCollegeOfLifeFly ConditionDefinition ConditionDefinition 2b3fe597-4816-
ConditionCollegeOfThespianCombatInspirationCombat ConditionDefinition ConditionDefinition 70a1a942-fa69-5449-9f20-8fdfe857701d
ConditionCollegeOfThespianCombatInspirationMovement ConditionDefinition ConditionDefinition 8fb4a5b0-92b5-546f-b7bb-732be8851e14
ConditionCollegeOfValianceDishearteningPerformance ConditionDefinition ConditionDefinition 8b075dec-4ac0-5331-b23e-df6924fdb447
+ConditionCommandSpellApproach ConditionDefinition ConditionDefinition bc446416-951a-5ad8-a0a0-f0e1eae119f4
+ConditionCommandSpellFlee ConditionDefinition ConditionDefinition b52e3cc4-15af-5123-a861-3fae68460977
+ConditionCommandSpellGrovel ConditionDefinition ConditionDefinition 6422ce36-c309-52f9-b699-bddb61fde71e
+ConditionCommandSpellHalt ConditionDefinition ConditionDefinition d20e7a46-e706-5c54-8bea-955b2054193a
ConditionCorruptingBolt ConditionDefinition ConditionDefinition c47e9ae4-841b-53af-b40f-2cb08dfa7d08
ConditionCrownOfStars ConditionDefinition ConditionDefinition 2d6f7c70-16fc-550b-83ff-f2e945b43449
ConditionCrusadersMantle ConditionDefinition ConditionDefinition 04a3a8c7-cf68-5a07-a0c1-9aabc911cad9
@@ -842,6 +846,7 @@ ConditionGiftOfTheChromaticDragonDamageCold ConditionDefinition ConditionDefinit
ConditionGiftOfTheChromaticDragonDamageFire ConditionDefinition ConditionDefinition 36e168e5-ccb2-539d-b735-7953ef295b21
ConditionGiftOfTheChromaticDragonDamageLightning ConditionDefinition ConditionDefinition a4ca0c1c-fbea-51b6-a622-9105a9a7932f
ConditionGiftOfTheChromaticDragonDamagePoison ConditionDefinition ConditionDefinition 6cf96f9b-b329-5af6-9c28-ead86e5b14b5
+ConditionGlibness ConditionDefinition ConditionDefinition 3182a19d-2d56-5f7a-849b-c2b28c7536b5
ConditionGrappledRestrainedEnsnared ConditionDefinition ConditionDefinition 526a12f3-594a-5627-82fa-8403e9315b07
ConditionGrappledRestrainedIceBound ConditionDefinition ConditionDefinition 968f2f49-dd5a-5f60-99e0-fe22f189bad2
ConditionGrappledRestrainedSpellWeb ConditionDefinition ConditionDefinition 7593e0f9-a1ff-539c-bf19-9ba1c7abfd60
@@ -852,6 +857,7 @@ ConditionHatredArdentHate ConditionDefinition ConditionDefinition c9abe651-5aed-
ConditionHeroicInfusion ConditionDefinition ConditionDefinition 6429a198-5027-5a66-8e22-494f70ed97b6
ConditionHeroicInfusionExhausted ConditionDefinition ConditionDefinition 1ecc7159-a625-5715-9fa4-2cb09b939b6c
ConditionHinderedForestGuardian ConditionDefinition ConditionDefinition c07233a3-2954-5516-9819-2191d857a927
+ConditionHolyWeapon ConditionDefinition ConditionDefinition 4abe721f-d87f-519b-a35d-152100b60eb4
ConditionHunterHordeBreaker ConditionDefinition ConditionDefinition a1a37dbb-4d25-5196-81e9-8a0306e988d5
ConditionImmuneAoO ConditionDefinition ConditionDefinition b5db9219-5090-54bb-977c-e45b622bc936
ConditionImpAssistedAlly ConditionDefinition ConditionDefinition 3c67b1a6-f256-58ee-98db-ab18678b302c
@@ -1179,6 +1185,7 @@ ConditionSunderingBlow ConditionDefinition ConditionDefinition c90e3266-d44c-5af
ConditionSunderingBlowAlly ConditionDefinition ConditionDefinition 73a99876-5aed-5b10-a854-b4c63147585a
ConditionSunlightBlade ConditionDefinition ConditionDefinition 6ac4b1f4-8f80-5e90-8e86-e66db308a40a
ConditionSunlightBladeHighlighted ConditionDefinition ConditionDefinition eb813adc-3ad0-52da-9836-0460b6c55291
+ConditionSwiftQuiver ConditionDefinition ConditionDefinition 1e981912-4130-58da-9464-ac4a23323337
ConditionSynapticStatic ConditionDefinition ConditionDefinition 0e14b879-1475-52c8-843b-429d5ee6bc8a
ConditionTaunted ConditionDefinition ConditionDefinition 4684284a-a3b2-54f9-9b40-0badf8e95081
ConditionTaunter ConditionDefinition ConditionDefinition 44ef4a88-e18c-5b4f-862b-0cf1ed14b71e
@@ -1235,10 +1242,26 @@ DecisionBreakFreeConditionGrappledRestrainedEnsnared TA.AI.DecisionDefinition TA
DecisionBreakFreeConditionGrappledRestrainedIceBound TA.AI.DecisionDefinition TA.AI.DecisionDefinition 017c5b82-f11c-5899-8729-947eabcf949f
DecisionBreakFreeConditionGrappledRestrainedSpellWeb TA.AI.DecisionDefinition TA.AI.DecisionDefinition 61e7fc96-8cb5-5c2b-8a67-75fbef4f333a
DecisionBreakFreeConditionNoxiousSpray TA.AI.DecisionDefinition TA.AI.DecisionDefinition 2f033fcf-d478-5581-94d9-27a3ad4496ad
+DecisionBreakFreeConditionOathOfAncientsNaturesWrath TA.AI.DecisionDefinition TA.AI.DecisionDefinition 25d7ad8d-27b8-5882-9bfb-acc37798812f
DecisionBreakFreeConditionRestrainedByEntangle TA.AI.DecisionDefinition TA.AI.DecisionDefinition 2a416669-5ec8-53c1-b07b-8fe6f29da4d2
DecisionBreakFreeConditionVileBrew TA.AI.DecisionDefinition TA.AI.DecisionDefinition 4b3278e8-334a-58d6-8c75-2f48e28b4e54
+DecisionBreakFreeConditionWrathfulSmiteEnemy TA.AI.DecisionDefinition TA.AI.DecisionDefinition 6400794a-3234-55f7-973f-d443c38c9a20
+Move_Approach TA.AI.DecisionDefinition TA.AI.DecisionDefinition 5cb2a87f-09a4-5fae-9b74-10516ea8a8ab
+Move_DissonantWhispers TA.AI.DecisionDefinition TA.AI.DecisionDefinition bdfa6649-5cad-5b35-a697-209ea53ca45d
+Approach TA.AI.DecisionPackageDefinition TA.AI.DecisionPackageDefinition 5043a0ec-c626-5877-bd87-c7bc0584366d
+BreakFreeAbilityCheckConditionFlashFreeze TA.AI.DecisionPackageDefinition TA.AI.DecisionPackageDefinition 5578aa14-4a4c-5aa0-b787-7203e14b8a36
+BreakFreeAbilityCheckConditionGrappledRestrainedEnsnared TA.AI.DecisionPackageDefinition TA.AI.DecisionPackageDefinition bf1d4828-465e-5897-91ca-bc8094b3d20e
+BreakFreeAbilityCheckConditionGrappledRestrainedIceBound TA.AI.DecisionPackageDefinition TA.AI.DecisionPackageDefinition 4702878b-3ac6-55e7-8954-7b1a8382aa7a
+BreakFreeAbilityCheckConditionGrappledRestrainedSpellWeb TA.AI.DecisionPackageDefinition TA.AI.DecisionPackageDefinition f265e068-e06c-503a-8aa5-dc39a214a7ec
+BreakFreeAbilityCheckConditionNoxiousSpray TA.AI.DecisionPackageDefinition TA.AI.DecisionPackageDefinition 1918a4d8-ff14-5aa1-9c20-1256e73c5730
+BreakFreeAbilityCheckConditionOathOfAncientsNaturesWrath TA.AI.DecisionPackageDefinition TA.AI.DecisionPackageDefinition c2d43b3b-7204-56df-a270-89202bf8ec7b
+BreakFreeAbilityCheckConditionRestrainedByEntangle TA.AI.DecisionPackageDefinition TA.AI.DecisionPackageDefinition 0d9623d9-0cd7-5c03-8275-e9e61f0f1b6a
+BreakFreeAbilityCheckConditionVileBrew TA.AI.DecisionPackageDefinition TA.AI.DecisionPackageDefinition 7b202c71-3241-5f80-8b02-ada4a0d9383f
+BreakFreeAbilityCheckConditionWrathfulSmiteEnemy TA.AI.DecisionPackageDefinition TA.AI.DecisionPackageDefinition 8952dfa4-c552-57f5-bf82-7e317c4e459d
+DissonantWhispers_Fear TA.AI.DecisionPackageDefinition TA.AI.DecisionPackageDefinition dfe2cc9e-cc70-5cfe-9057-19454acb1068
DieTypeD3 DieTypeDefinition DieTypeDefinition 63dc904b-8d78-5406-90aa-e7e1f3eefd84
ProxyCircleOfTheWildfireCauterizingFlames EffectProxyDefinition EffectProxyDefinition 5d3d90cd-1858-5044-b4f6-586754122132
+ProxyCreateBonfire EffectProxyDefinition EffectProxyDefinition a84e5459-b44a-5dfd-9f27-c4a44b571c3a
ProxyDawn EffectProxyDefinition EffectProxyDefinition 5c460453-060a-51c2-9099-a6a40908dba9
ProxyEarthTremor EffectProxyDefinition EffectProxyDefinition fdec4a73-e825-5a14-9f0e-1faca83c21d3
ProxyElementalBreathGreen EffectProxyDefinition EffectProxyDefinition d97ae7c7-c0e5-51d3-8e0b-6a517d0d6ef4
@@ -1586,6 +1609,7 @@ ActionAffinityBrutalStrikeToggle FeatureDefinitionActionAffinity FeatureDefiniti
ActionAffinityCaveWyrmkinBonusShove FeatureDefinitionActionAffinity FeatureDefinition feed7d9e-34bd-51b7-99a4-7a152bfab68f
ActionAffinityCircleOfTheWildfireSpirit FeatureDefinitionActionAffinity FeatureDefinition f129168e-25fa-5478-bde2-57246aca7066
ActionAffinityCollegeOfValianceHeroicInspiration FeatureDefinitionActionAffinity FeatureDefinition 951aafe4-9c11-50cf-a43d-8c23ace8983f
+ActionAffinityCommandSpellHalt FeatureDefinitionActionAffinity FeatureDefinition aefc4f30-7712-50b2-8a52-9368185278ab
ActionAffinityConditionBlind FeatureDefinitionActionAffinity FeatureDefinition ba8f244f-070a-5288-a482-e145ab83adef
ActionAffinityCoordinatedAssaultToggle FeatureDefinitionActionAffinity FeatureDefinition 2052bab8-0723-5f23-ba11-b5340f444906
ActionAffinityCrystalWyrmkinConditionCrystalDefense FeatureDefinitionActionAffinity FeatureDefinition 1274559b-34e5-5c07-acbe-9d51d149959e
@@ -1729,6 +1753,7 @@ AdditionalDamageFortuneFavorTheBoldPsychicDamage FeatureDefinitionAdditionalDama
AdditionalDamageGambitDie FeatureDefinitionAdditionalDamage FeatureDefinition 9f288fdb-82c8-5c55-8028-549986994481
AdditionalDamageGambitDieMelee FeatureDefinitionAdditionalDamage FeatureDefinition 0c8c9223-a0d3-53db-a806-39a146465c76
AdditionalDamageHeroicInfusion FeatureDefinitionAdditionalDamage FeatureDefinition 9a8b8e0b-f1e4-52c2-9684-d65755f7b0ce
+AdditionalDamageHolyWeapon FeatureDefinitionAdditionalDamage FeatureDefinition a818b04d-36eb-554a-921b-a4e00c1ac999
AdditionalDamageInfusionBloody FeatureDefinitionAdditionalDamage FeatureDefinition 17405e7d-32e9-52b9-ad6e-20bccb5e93a2
AdditionalDamageInfusionMajorElementalDamageAcid FeatureDefinitionAdditionalDamage FeatureDefinition 623d8c9f-8bf6-579e-9a92-018aed01c23f
AdditionalDamageInfusionMajorElementalDamageCold FeatureDefinitionAdditionalDamage FeatureDefinition 5ef736e9-38a2-5a96-828e-55d2f85b4942
@@ -3109,6 +3134,7 @@ PowerCreateSpellStoringWandOfChromaticOrb FeatureDefinitionPowerSharedPool Featu
PowerCreateSpellStoringWandOfCloudOfDaggers FeatureDefinitionPowerSharedPool FeatureDefinition ec91a2df-2e17-5e23-a557-b0a29988b1a0
PowerCreateSpellStoringWandOfColorBurst FeatureDefinitionPowerSharedPool FeatureDefinition 209756fb-1b4b-56ba-9e2b-6ef71ee0d83b
PowerCreateSpellStoringWandOfColorSpray FeatureDefinitionPowerSharedPool FeatureDefinition f8ac5039-bbe2-55ee-973f-85909724c643
+PowerCreateSpellStoringWandOfCommandSpell FeatureDefinitionPowerSharedPool FeatureDefinition e90dc523-a327-589e-bc84-4a3a73b789d7
PowerCreateSpellStoringWandOfComprehendLanguages FeatureDefinitionPowerSharedPool FeatureDefinition 9c84c91e-85d6-53c9-8ace-bd06c87d300c
PowerCreateSpellStoringWandOfConjureGoblinoids FeatureDefinitionPowerSharedPool FeatureDefinition 4e9b245c-0e4b-5690-95c7-467acccdd814
PowerCreateSpellStoringWandOfCureWounds FeatureDefinitionPowerSharedPool FeatureDefinition ef499f3d-b8d9-5292-a819-c9285ffc4c88
@@ -3117,6 +3143,7 @@ PowerCreateSpellStoringWandOfDarkvision FeatureDefinitionPowerSharedPool Feature
PowerCreateSpellStoringWandOfDetectEvilAndGood FeatureDefinitionPowerSharedPool FeatureDefinition c3203e0f-0e77-56d8-86da-73e22107707a
PowerCreateSpellStoringWandOfDetectMagic FeatureDefinitionPowerSharedPool FeatureDefinition 1898af57-819e-5e81-861e-4948a5e8ad5d
PowerCreateSpellStoringWandOfDetectPoisonAndDisease FeatureDefinitionPowerSharedPool FeatureDefinition 99a9adc4-e7b4-55a2-a606-ed192b8761b3
+PowerCreateSpellStoringWandOfDissonantWhispers FeatureDefinitionPowerSharedPool FeatureDefinition 3cdfcada-8b8a-5599-b7b0-ec9c8ea50675
PowerCreateSpellStoringWandOfEarthTremor FeatureDefinitionPowerSharedPool FeatureDefinition f6785f5d-7b01-5d61-b85e-8e4eb20dd0dc
PowerCreateSpellStoringWandOfEnhanceAbility FeatureDefinitionPowerSharedPool FeatureDefinition 6b586704-ffaf-5d38-ab50-115568e8f9b1
PowerCreateSpellStoringWandOfEntangle FeatureDefinitionPowerSharedPool FeatureDefinition e986e4ec-8073-5b88-b073-82166b07f749
@@ -3344,6 +3371,7 @@ PowerGiftOfTheChromaticDragonDamageFire FeatureDefinitionPowerSharedPool Feature
PowerGiftOfTheChromaticDragonDamageLightning FeatureDefinitionPowerSharedPool FeatureDefinition 612d9e92-f959-5b0a-9c88-320cd96e304c
PowerGiftOfTheChromaticDragonDamagePoison FeatureDefinitionPowerSharedPool FeatureDefinition 37753c37-0501-5ec7-96df-26cd5c2f5bea
PowerGiftOfTheChromaticDragonReactiveResistance FeatureDefinitionPower FeatureDefinition de9b1627-30f9-5f78-992a-58bbde7cbc90
+PowerGravityFissure FeatureDefinitionPower FeatureDefinition 684f8db8-663a-5332-bc46-1bbe219ffecb
PowerGrayDwarfInvisibility FeatureDefinitionPower FeatureDefinition c4864fef-ecc0-5cf5-bb63-638addf6e90a
PowerGrayDwarfStoneStrength FeatureDefinitionPower FeatureDefinition a3310dbb-532e-56a8-ba7d-cb855cabe127
PowerHandwrapsOfPulling FeatureDefinitionPower FeatureDefinition 81b318cf-8220-5876-bac8-996c44adcdb9
@@ -3354,6 +3382,7 @@ PowerHatredScornfulPrayerFeature FeatureDefinitionPower FeatureDefinition a18e30
PowerHelp FeatureDefinitionPower FeatureDefinition faded953-56c9-55e9-aa49-54a485c1de6d
PowerHighWyrmkinPsionicWave FeatureDefinitionPower FeatureDefinition 5183d28a-df58-5b9c-929b-d8c3cdf51e2f
PowerHighWyrmkinReactiveRetribution FeatureDefinitionPower FeatureDefinition cb04aa22-2f0c-5b00-8a7b-c372ace7890c
+PowerHolyWeapon FeatureDefinitionPower FeatureDefinition 998ab674-743b-5200-b721-4e4a915a38d8
PowerHungerOfTheVoidAcid FeatureDefinitionPower FeatureDefinition 03c80741-2e05-5a9a-bdfe-af0721f45ba2
PowerHungerOfTheVoidCold FeatureDefinitionPower FeatureDefinition 225a983d-6b7d-5249-8443-6cb000a6518e
PowerIceBlade FeatureDefinitionPower FeatureDefinition d5a3feae-4d32-5738-8e5c-2996e003e33f
@@ -4233,6 +4262,7 @@ ActionAffinityBrutalStrikeToggle FeatureDefinitionActionAffinity FeatureDefiniti
ActionAffinityCaveWyrmkinBonusShove FeatureDefinitionActionAffinity FeatureDefinitionActionAffinity feed7d9e-34bd-51b7-99a4-7a152bfab68f
ActionAffinityCircleOfTheWildfireSpirit FeatureDefinitionActionAffinity FeatureDefinitionActionAffinity f129168e-25fa-5478-bde2-57246aca7066
ActionAffinityCollegeOfValianceHeroicInspiration FeatureDefinitionActionAffinity FeatureDefinitionActionAffinity 951aafe4-9c11-50cf-a43d-8c23ace8983f
+ActionAffinityCommandSpellHalt FeatureDefinitionActionAffinity FeatureDefinitionActionAffinity aefc4f30-7712-50b2-8a52-9368185278ab
ActionAffinityConditionBlind FeatureDefinitionActionAffinity FeatureDefinitionActionAffinity ba8f244f-070a-5288-a482-e145ab83adef
ActionAffinityCoordinatedAssaultToggle FeatureDefinitionActionAffinity FeatureDefinitionActionAffinity 2052bab8-0723-5f23-ba11-b5340f444906
ActionAffinityCrystalWyrmkinConditionCrystalDefense FeatureDefinitionActionAffinity FeatureDefinitionActionAffinity 1274559b-34e5-5c07-acbe-9d51d149959e
@@ -4371,6 +4401,7 @@ AdditionalDamageFortuneFavorTheBoldPsychicDamage FeatureDefinitionAdditionalDama
AdditionalDamageGambitDie FeatureDefinitionAdditionalDamage FeatureDefinitionAdditionalDamage 9f288fdb-82c8-5c55-8028-549986994481
AdditionalDamageGambitDieMelee FeatureDefinitionAdditionalDamage FeatureDefinitionAdditionalDamage 0c8c9223-a0d3-53db-a806-39a146465c76
AdditionalDamageHeroicInfusion FeatureDefinitionAdditionalDamage FeatureDefinitionAdditionalDamage 9a8b8e0b-f1e4-52c2-9684-d65755f7b0ce
+AdditionalDamageHolyWeapon FeatureDefinitionAdditionalDamage FeatureDefinitionAdditionalDamage a818b04d-36eb-554a-921b-a4e00c1ac999
AdditionalDamageInfusionBloody FeatureDefinitionAdditionalDamage FeatureDefinitionAdditionalDamage 17405e7d-32e9-52b9-ad6e-20bccb5e93a2
AdditionalDamageInfusionMajorElementalDamageAcid FeatureDefinitionAdditionalDamage FeatureDefinitionAdditionalDamage 623d8c9f-8bf6-579e-9a92-018aed01c23f
AdditionalDamageInfusionMajorElementalDamageCold FeatureDefinitionAdditionalDamage FeatureDefinitionAdditionalDamage 5ef736e9-38a2-5a96-828e-55d2f85b4942
@@ -5927,6 +5958,7 @@ PowerCreateSpellStoringWandOfChromaticOrb FeatureDefinitionPowerSharedPool Featu
PowerCreateSpellStoringWandOfCloudOfDaggers FeatureDefinitionPowerSharedPool FeatureDefinitionPower ec91a2df-2e17-5e23-a557-b0a29988b1a0
PowerCreateSpellStoringWandOfColorBurst FeatureDefinitionPowerSharedPool FeatureDefinitionPower 209756fb-1b4b-56ba-9e2b-6ef71ee0d83b
PowerCreateSpellStoringWandOfColorSpray FeatureDefinitionPowerSharedPool FeatureDefinitionPower f8ac5039-bbe2-55ee-973f-85909724c643
+PowerCreateSpellStoringWandOfCommandSpell FeatureDefinitionPowerSharedPool FeatureDefinitionPower e90dc523-a327-589e-bc84-4a3a73b789d7
PowerCreateSpellStoringWandOfComprehendLanguages FeatureDefinitionPowerSharedPool FeatureDefinitionPower 9c84c91e-85d6-53c9-8ace-bd06c87d300c
PowerCreateSpellStoringWandOfConjureGoblinoids FeatureDefinitionPowerSharedPool FeatureDefinitionPower 4e9b245c-0e4b-5690-95c7-467acccdd814
PowerCreateSpellStoringWandOfCureWounds FeatureDefinitionPowerSharedPool FeatureDefinitionPower ef499f3d-b8d9-5292-a819-c9285ffc4c88
@@ -5935,6 +5967,7 @@ PowerCreateSpellStoringWandOfDarkvision FeatureDefinitionPowerSharedPool Feature
PowerCreateSpellStoringWandOfDetectEvilAndGood FeatureDefinitionPowerSharedPool FeatureDefinitionPower c3203e0f-0e77-56d8-86da-73e22107707a
PowerCreateSpellStoringWandOfDetectMagic FeatureDefinitionPowerSharedPool FeatureDefinitionPower 1898af57-819e-5e81-861e-4948a5e8ad5d
PowerCreateSpellStoringWandOfDetectPoisonAndDisease FeatureDefinitionPowerSharedPool FeatureDefinitionPower 99a9adc4-e7b4-55a2-a606-ed192b8761b3
+PowerCreateSpellStoringWandOfDissonantWhispers FeatureDefinitionPowerSharedPool FeatureDefinitionPower 3cdfcada-8b8a-5599-b7b0-ec9c8ea50675
PowerCreateSpellStoringWandOfEarthTremor FeatureDefinitionPowerSharedPool FeatureDefinitionPower f6785f5d-7b01-5d61-b85e-8e4eb20dd0dc
PowerCreateSpellStoringWandOfEnhanceAbility FeatureDefinitionPowerSharedPool FeatureDefinitionPower 6b586704-ffaf-5d38-ab50-115568e8f9b1
PowerCreateSpellStoringWandOfEntangle FeatureDefinitionPowerSharedPool FeatureDefinitionPower e986e4ec-8073-5b88-b073-82166b07f749
@@ -6162,6 +6195,7 @@ PowerGiftOfTheChromaticDragonDamageFire FeatureDefinitionPowerSharedPool Feature
PowerGiftOfTheChromaticDragonDamageLightning FeatureDefinitionPowerSharedPool FeatureDefinitionPower 612d9e92-f959-5b0a-9c88-320cd96e304c
PowerGiftOfTheChromaticDragonDamagePoison FeatureDefinitionPowerSharedPool FeatureDefinitionPower 37753c37-0501-5ec7-96df-26cd5c2f5bea
PowerGiftOfTheChromaticDragonReactiveResistance FeatureDefinitionPower FeatureDefinitionPower de9b1627-30f9-5f78-992a-58bbde7cbc90
+PowerGravityFissure FeatureDefinitionPower FeatureDefinitionPower 684f8db8-663a-5332-bc46-1bbe219ffecb
PowerGrayDwarfInvisibility FeatureDefinitionPower FeatureDefinitionPower c4864fef-ecc0-5cf5-bb63-638addf6e90a
PowerGrayDwarfStoneStrength FeatureDefinitionPower FeatureDefinitionPower a3310dbb-532e-56a8-ba7d-cb855cabe127
PowerHandwrapsOfPulling FeatureDefinitionPower FeatureDefinitionPower 81b318cf-8220-5876-bac8-996c44adcdb9
@@ -6172,6 +6206,7 @@ PowerHatredScornfulPrayerFeature FeatureDefinitionPower FeatureDefinitionPower a
PowerHelp FeatureDefinitionPower FeatureDefinitionPower faded953-56c9-55e9-aa49-54a485c1de6d
PowerHighWyrmkinPsionicWave FeatureDefinitionPower FeatureDefinitionPower 5183d28a-df58-5b9c-929b-d8c3cdf51e2f
PowerHighWyrmkinReactiveRetribution FeatureDefinitionPower FeatureDefinitionPower cb04aa22-2f0c-5b00-8a7b-c372ace7890c
+PowerHolyWeapon FeatureDefinitionPower FeatureDefinitionPower 998ab674-743b-5200-b721-4e4a915a38d8
PowerHungerOfTheVoidAcid FeatureDefinitionPower FeatureDefinitionPower 03c80741-2e05-5a9a-bdfe-af0721f45ba2
PowerHungerOfTheVoidCold FeatureDefinitionPower FeatureDefinitionPower 225a983d-6b7d-5249-8443-6cb000a6518e
PowerIceBlade FeatureDefinitionPower FeatureDefinitionPower d5a3feae-4d32-5738-8e5c-2996e003e33f
@@ -8327,6 +8362,7 @@ SpellStoringWandOfChromaticOrb ItemDefinition ItemDefinition f81eac13-8db9-57f5-
SpellStoringWandOfCloudOfDaggers ItemDefinition ItemDefinition a9043899-f63b-587b-ad52-0658c4da225f
SpellStoringWandOfColorBurst ItemDefinition ItemDefinition 9244c429-490f-59a2-942c-3cd08edc5bec
SpellStoringWandOfColorSpray ItemDefinition ItemDefinition c0453877-01a5-5123-907a-971a14bc4ef8
+SpellStoringWandOfCommandSpell ItemDefinition ItemDefinition 252920d8-129e-5ae7-a5fc-6bdccebf1d4f
SpellStoringWandOfComprehendLanguages ItemDefinition ItemDefinition caf4a9d0-9bc1-5062-9f72-3fb1362256cd
SpellStoringWandOfConjureGoblinoids ItemDefinition ItemDefinition 10451765-8ee3-5656-82d8-5ebd6af3aa4c
SpellStoringWandOfCureWounds ItemDefinition ItemDefinition 24c65d7b-0f85-5048-abf5-75e525e5ea43
@@ -8335,6 +8371,7 @@ SpellStoringWandOfDarkvision ItemDefinition ItemDefinition c0e87ea8-f654-5aae-90
SpellStoringWandOfDetectEvilAndGood ItemDefinition ItemDefinition 6bae061b-b4d8-5a31-9cd1-e8fdaf200eed
SpellStoringWandOfDetectMagic ItemDefinition ItemDefinition 38583cd3-9d35-5240-9c24-f4e9eee9e60e
SpellStoringWandOfDetectPoisonAndDisease ItemDefinition ItemDefinition 397a9d80-baf8-505f-808f-7df86e5c8de8
+SpellStoringWandOfDissonantWhispers ItemDefinition ItemDefinition 2f16c6e7-5a0d-5b07-89e6-b53f433567e8
SpellStoringWandOfEarthTremor ItemDefinition ItemDefinition e4c1eb68-0a74-5269-b12e-5f19026189aa
SpellStoringWandOfEnhanceAbility ItemDefinition ItemDefinition 7d2b47e2-5062-5db7-8bab-220b2a74e26c
SpellStoringWandOfEntangle ItemDefinition ItemDefinition 63c85249-2fb7-55f5-b577-19521bb06cce
@@ -12126,8 +12163,14 @@ ChromaticOrbDamageThunder SpellDefinition SpellDefinition 65e7665c-05b4-5745-b52
CircleOfMagicalNegation SpellDefinition SpellDefinition c03e2ec6-3fd5-5943-8750-0f75c275d9e0
CloudOfDaggers SpellDefinition SpellDefinition c95adfd0-7613-54ea-8270-b3624ae4dd78
ColorBurst SpellDefinition SpellDefinition c79e03ee-1d09-569f-85d9-27a50cfc7110
+CommandSpell SpellDefinition SpellDefinition 289ffbc5-ef5c-56b1-b6ba-79d88e236887
+CommandSpellApproach SpellDefinition SpellDefinition 395b1d47-bc7c-50e1-91e2-78e39a4e418b
+CommandSpellFlee SpellDefinition SpellDefinition 0bed52be-d94a-5da2-8cfe-d5784f55e6f8
+CommandSpellGrovel SpellDefinition SpellDefinition b48998ac-2379-5637-ad85-8e45cdd375ac
+CommandSpellHalt SpellDefinition SpellDefinition d4e87ec4-f113-5c33-b5c6-0452ab42231b
ConjureElementalInvisibleStalker SpellDefinition SpellDefinition 4f4b45b0-1a32-55c5-ab58-66d105a6f07f
CorruptingBolt SpellDefinition SpellDefinition 715e1a9b-115f-5036-99b9-bf54f7e34f01
+CreateBonfire SpellDefinition SpellDefinition 3f2e87e8-860f-58ce-b347-b54c8d6581ac
CreateDeadRisenGhost SpellDefinition SpellDefinition 02a12317-e3e2-5833-9611-eeaaead7c151
CreateDeadRisenGhoul SpellDefinition SpellDefinition 154586bd-b1a2-53d0-ac83-ecf3d0be8a7d
CreateDeadRisenSkeleton SpellDefinition SpellDefinition 86611dbf-bc5e-50d4-b699-bb09f11c79a5
@@ -12142,6 +12185,7 @@ CrusadersMantle SpellDefinition SpellDefinition d2077997-23c2-5d34-84b3-794a89ef
Dawn SpellDefinition SpellDefinition 1cc6ddda-bf5c-5961-9675-18e262a1f43d
DetectMagicCantrip SpellDefinition SpellDefinition 6ccf60b4-cfd7-5180-9a92-beb9454bfdfd
DispelMagicSpell SpellDefinition SpellDefinition c084fb4d-4762-5f1d-9e44-814a6af63b9f
+DissonantWhispers SpellDefinition SpellDefinition a3308f76-57c3-56a7-acaa-9c505d7fdaa7
DivineWrath SpellDefinition SpellDefinition 754381b9-32f7-575a-b831-aa815f9dd566
DivineWrathNecrotic SpellDefinition SpellDefinition 6627d4c5-b7ad-517a-8f1f-60d2af400885
DivineWrathRadiant SpellDefinition SpellDefinition e6d29d57-ae9f-5d52-938b-4a5fb7d44cf7
@@ -12172,8 +12216,11 @@ FlashFreeze SpellDefinition SpellDefinition c7bca121-71cb-5243-ad33-de4f547dd73b
Foresight SpellDefinition SpellDefinition 7e0b6dac-dd42-59de-8216-2a15d6b05693
ForestGuardian SpellDefinition SpellDefinition e84a5167-a3d0-5e96-b978-60039654e3bb
GiftOfAlacrity SpellDefinition SpellDefinition cfc1affd-8762-5031-b552-4a48251d784c
+Glibness SpellDefinition SpellDefinition 6fff4ed6-1408-5410-9bb6-16392e1e6b15
+GravityFissure SpellDefinition SpellDefinition e230eac9-00f7-5e9f-86f8-51c2796721cd
GravitySinkhole SpellDefinition SpellDefinition 42bea70d-ddc5-5295-8c18-c6b6b9c3abf6
HeroicInfusion SpellDefinition SpellDefinition cf5c6a2f-ae52-59d6-a88d-31bb5d00c17d
+HolyWeapon SpellDefinition SpellDefinition ed4a2ccf-c199-5f4c-bfc3-7bc8a584e4ce
HungerOfTheVoid SpellDefinition SpellDefinition fa794ede-4149-54ed-914d-f25cd55fb5b4
IceBlade SpellDefinition SpellDefinition 659510a2-17ce-5577-8f85-d7756eac3bd9
IlluminatingSphere SpellDefinition SpellDefinition e7fc59b8-93d9-53aa-86f7-659ac0d16fcf
@@ -12585,6 +12632,7 @@ StarryWisp SpellDefinition SpellDefinition 9856da86-1888-5630-8647-3a003421a268
SteelWhirlwind SpellDefinition SpellDefinition ab7f50cb-6f73-57c6-b96b-f06ac4ed17b3
StrikeWithTheWind SpellDefinition SpellDefinition d641e4ac-7291-5516-a07c-f45b6444dcfe
SunlightBlade SpellDefinition SpellDefinition 62effe92-a4c1-58ed-a9a0-06f1a64e8c8e
+SwiftQuiver SpellDefinition SpellDefinition 12962336-42c4-5ddc-8ea1-6092af61fe43
SwordStorm SpellDefinition SpellDefinition d3b6df03-2c2c-524a-a160-e988006a5fd8
SynapticStatic SpellDefinition SpellDefinition 5e75eeec-87bb-5e81-918a-03171bfea6a6
Telekinesis SpellDefinition SpellDefinition 4a9561ac-ffb6-5b44-b94a-24f69e41fd4c
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionBlindedByBlindingSmite.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionBlindedByBlindingSmite.json
index 52bf76c6d6..1f0bceb6cf 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionBlindedByBlindingSmite.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionBlindedByBlindingSmite.json
@@ -14,7 +14,7 @@
"durationParameterDie": "D1",
"durationParameter": 1,
"forceTurnOccurence": false,
- "turnOccurence": "StartOfTurn",
+ "turnOccurence": "EndOfTurn",
"specialInterruptions": [],
"interruptionRequiresSavingThrow": false,
"interruptionSavingThrowComputationMethod": "SaveOverride",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionBlindingSmite.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionBlindingSmite.json
index 209f720e25..cd49aaddf6 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionBlindingSmite.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionBlindingSmite.json
@@ -18,7 +18,7 @@
"forceTurnOccurence": false,
"turnOccurence": "EndOfTurn",
"specialInterruptions": [
- "AttacksAndDamages"
+ 9005
],
"interruptionRequiresSavingThrow": false,
"interruptionSavingThrowComputationMethod": "SaveOverride",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionCommandSpellApproach.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionCommandSpellApproach.json
new file mode 100644
index 0000000000..8d4ac544bd
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionCommandSpellApproach.json
@@ -0,0 +1,155 @@
+{
+ "$type": "ConditionDefinition, Assembly-CSharp",
+ "inDungeonEditor": false,
+ "parentCondition": null,
+ "conditionType": "Detrimental",
+ "features": [],
+ "allowMultipleInstances": false,
+ "silentWhenAdded": false,
+ "silentWhenRemoved": false,
+ "silentWhenRefreshed": false,
+ "terminateWhenRemoved": false,
+ "specialDuration": true,
+ "durationType": "Round",
+ "durationParameterDie": "D4",
+ "durationParameter": 0,
+ "forceTurnOccurence": false,
+ "turnOccurence": "EndOfTurn",
+ "specialInterruptions": [],
+ "interruptionRequiresSavingThrow": false,
+ "interruptionSavingThrowComputationMethod": "SaveOverride",
+ "interruptionSavingThrowAbility": "",
+ "interruptionDamageThreshold": 0,
+ "keepConditionIfSavingThrowSucceeds": false,
+ "interruptionSavingThrowAffinity": "None",
+ "conditionTags": [],
+ "recurrentEffectForms": [],
+ "cancellingConditions": [],
+ "additionalDamageWhenHit": false,
+ "additionalDamageTypeDetermination": "Specific",
+ "additionalDamageType": "",
+ "additionalDamageQuantity": "AbilityBonus",
+ "additionalDamageDieType": "D1",
+ "additionalDamageDieNumber": 1,
+ "additionalConditionWhenHit": false,
+ "additionalCondition": null,
+ "additionalConditionDurationType": "Round",
+ "additionalConditionDurationParameter": 1,
+ "additionalConditionTurnOccurenceType": "StartOfTurn",
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "recurrentEffectParticleReference": null,
+ "characterShaderReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "particlesBasedOnAncestryDamageType": false,
+ "ancestryType": "Sorcerer",
+ "acidParticleParameters": null,
+ "coldParticleParameters": null,
+ "fireParticleParameters": null,
+ "lightningParticleParameters": null,
+ "poisonParticleParameters": null,
+ "overrideCharacterShaderColors": false,
+ "firstCharacterShaderColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "secondCharacterShaderColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "timeToWaitBeforeApplyingShader": 0.5,
+ "timeToWaitBeforeRemovingShader": 0.5,
+ "possessive": true,
+ "amountOrigin": "None",
+ "baseAmount": 0,
+ "additiveAmount": false,
+ "sourceAbilityBonusMinValue": 1,
+ "subsequentOnRemoval": null,
+ "subsequentHasSavingThrow": false,
+ "subsequentSavingThrowAbilityScore": "Constitution",
+ "subsequentVariableForDC": "FrenzyExhaustionDC",
+ "subsequentDCIncrease": 5,
+ "effectFormsOnRemoved": [],
+ "forceBehavior": true,
+ "addBehavior": false,
+ "fearSource": true,
+ "battlePackage": "Definition:Approach:5043a0ec-c626-5877-bd87-c7bc0584366d",
+ "explorationPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "removedFromTheGame": false,
+ "permanentlyRemovedIfExtraPlanar": false,
+ "refundReceivedDamageWhenRemoved": false,
+ "followSourcePosition": false,
+ "disolveCharacterOnDeath": false,
+ "disolveParameters": {
+ "$type": "GraphicsCharacterDefinitions+DisolveParameters, Assembly-CSharp",
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "colorWidth": 0.0,
+ "noiseScale": 5.0,
+ "hueScale": 0.0,
+ "vertexOffset": 0.0,
+ "curve": {
+ "$type": "UnityEngine.AnimationCurve, UnityEngine.CoreModule"
+ },
+ "startAfterDeathAnimation": false,
+ "duration": 0.0
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Spell/&CommandSpellApproachTitle",
+ "description": "Spell/&CommandSpellApproachDescription",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "5e96eb4d8d8193a4cbddbf7477990f88",
+ "m_SubObjectName": "ConditionPossessed",
+ "m_SubObjectType": "UnityEngine.Sprite, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "bc446416-951a-5ad8-a0a0-f0e1eae119f4",
+ "contentPack": 9999,
+ "name": "ConditionCommandSpellApproach"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionCommandSpellFlee.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionCommandSpellFlee.json
new file mode 100644
index 0000000000..47e46742e9
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionCommandSpellFlee.json
@@ -0,0 +1,157 @@
+{
+ "$type": "ConditionDefinition, Assembly-CSharp",
+ "inDungeonEditor": false,
+ "parentCondition": null,
+ "conditionType": "Detrimental",
+ "features": [
+ "Definition:MovementAffinityConditionDashing:f04b97bac67dce94fae71500ae6412ad"
+ ],
+ "allowMultipleInstances": false,
+ "silentWhenAdded": false,
+ "silentWhenRemoved": false,
+ "silentWhenRefreshed": false,
+ "terminateWhenRemoved": false,
+ "specialDuration": true,
+ "durationType": "Round",
+ "durationParameterDie": "D4",
+ "durationParameter": 0,
+ "forceTurnOccurence": false,
+ "turnOccurence": "EndOfTurn",
+ "specialInterruptions": [],
+ "interruptionRequiresSavingThrow": false,
+ "interruptionSavingThrowComputationMethod": "SaveOverride",
+ "interruptionSavingThrowAbility": "",
+ "interruptionDamageThreshold": 0,
+ "keepConditionIfSavingThrowSucceeds": false,
+ "interruptionSavingThrowAffinity": "None",
+ "conditionTags": [],
+ "recurrentEffectForms": [],
+ "cancellingConditions": [],
+ "additionalDamageWhenHit": false,
+ "additionalDamageTypeDetermination": "Specific",
+ "additionalDamageType": "",
+ "additionalDamageQuantity": "AbilityBonus",
+ "additionalDamageDieType": "D1",
+ "additionalDamageDieNumber": 1,
+ "additionalConditionWhenHit": false,
+ "additionalCondition": null,
+ "additionalConditionDurationType": "Round",
+ "additionalConditionDurationParameter": 1,
+ "additionalConditionTurnOccurenceType": "StartOfTurn",
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "recurrentEffectParticleReference": null,
+ "characterShaderReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "particlesBasedOnAncestryDamageType": false,
+ "ancestryType": "Sorcerer",
+ "acidParticleParameters": null,
+ "coldParticleParameters": null,
+ "fireParticleParameters": null,
+ "lightningParticleParameters": null,
+ "poisonParticleParameters": null,
+ "overrideCharacterShaderColors": false,
+ "firstCharacterShaderColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "secondCharacterShaderColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "timeToWaitBeforeApplyingShader": 0.5,
+ "timeToWaitBeforeRemovingShader": 0.5,
+ "possessive": true,
+ "amountOrigin": "None",
+ "baseAmount": 0,
+ "additiveAmount": false,
+ "sourceAbilityBonusMinValue": 1,
+ "subsequentOnRemoval": null,
+ "subsequentHasSavingThrow": false,
+ "subsequentSavingThrowAbilityScore": "Constitution",
+ "subsequentVariableForDC": "FrenzyExhaustionDC",
+ "subsequentDCIncrease": 5,
+ "effectFormsOnRemoved": [],
+ "forceBehavior": true,
+ "addBehavior": false,
+ "fearSource": true,
+ "battlePackage": "Definition:Fear:67e55218421c6034d8ec7952695e5831",
+ "explorationPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "removedFromTheGame": false,
+ "permanentlyRemovedIfExtraPlanar": false,
+ "refundReceivedDamageWhenRemoved": false,
+ "followSourcePosition": false,
+ "disolveCharacterOnDeath": false,
+ "disolveParameters": {
+ "$type": "GraphicsCharacterDefinitions+DisolveParameters, Assembly-CSharp",
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "colorWidth": 0.0,
+ "noiseScale": 5.0,
+ "hueScale": 0.0,
+ "vertexOffset": 0.0,
+ "curve": {
+ "$type": "UnityEngine.AnimationCurve, UnityEngine.CoreModule"
+ },
+ "startAfterDeathAnimation": false,
+ "duration": 0.0
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Spell/&CommandSpellFleeTitle",
+ "description": "Spell/&CommandSpellFleeDescription",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "5e96eb4d8d8193a4cbddbf7477990f88",
+ "m_SubObjectName": "ConditionPossessed",
+ "m_SubObjectType": "UnityEngine.Sprite, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "b52e3cc4-15af-5123-a861-3fae68460977",
+ "contentPack": 9999,
+ "name": "ConditionCommandSpellFlee"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionCommandSpellGrovel.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionCommandSpellGrovel.json
new file mode 100644
index 0000000000..44fa5335da
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionCommandSpellGrovel.json
@@ -0,0 +1,155 @@
+{
+ "$type": "ConditionDefinition, Assembly-CSharp",
+ "inDungeonEditor": false,
+ "parentCondition": null,
+ "conditionType": "Detrimental",
+ "features": [],
+ "allowMultipleInstances": false,
+ "silentWhenAdded": false,
+ "silentWhenRemoved": false,
+ "silentWhenRefreshed": false,
+ "terminateWhenRemoved": false,
+ "specialDuration": true,
+ "durationType": "Round",
+ "durationParameterDie": "D4",
+ "durationParameter": 0,
+ "forceTurnOccurence": false,
+ "turnOccurence": "EndOfTurn",
+ "specialInterruptions": [],
+ "interruptionRequiresSavingThrow": false,
+ "interruptionSavingThrowComputationMethod": "SaveOverride",
+ "interruptionSavingThrowAbility": "",
+ "interruptionDamageThreshold": 0,
+ "keepConditionIfSavingThrowSucceeds": false,
+ "interruptionSavingThrowAffinity": "None",
+ "conditionTags": [],
+ "recurrentEffectForms": [],
+ "cancellingConditions": [],
+ "additionalDamageWhenHit": false,
+ "additionalDamageTypeDetermination": "Specific",
+ "additionalDamageType": "",
+ "additionalDamageQuantity": "AbilityBonus",
+ "additionalDamageDieType": "D1",
+ "additionalDamageDieNumber": 1,
+ "additionalConditionWhenHit": false,
+ "additionalCondition": null,
+ "additionalConditionDurationType": "Round",
+ "additionalConditionDurationParameter": 1,
+ "additionalConditionTurnOccurenceType": "StartOfTurn",
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "recurrentEffectParticleReference": null,
+ "characterShaderReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "particlesBasedOnAncestryDamageType": false,
+ "ancestryType": "Sorcerer",
+ "acidParticleParameters": null,
+ "coldParticleParameters": null,
+ "fireParticleParameters": null,
+ "lightningParticleParameters": null,
+ "poisonParticleParameters": null,
+ "overrideCharacterShaderColors": false,
+ "firstCharacterShaderColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "secondCharacterShaderColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "timeToWaitBeforeApplyingShader": 0.5,
+ "timeToWaitBeforeRemovingShader": 0.5,
+ "possessive": true,
+ "amountOrigin": "None",
+ "baseAmount": 0,
+ "additiveAmount": false,
+ "sourceAbilityBonusMinValue": 1,
+ "subsequentOnRemoval": null,
+ "subsequentHasSavingThrow": false,
+ "subsequentSavingThrowAbilityScore": "Constitution",
+ "subsequentVariableForDC": "FrenzyExhaustionDC",
+ "subsequentDCIncrease": 5,
+ "effectFormsOnRemoved": [],
+ "forceBehavior": false,
+ "addBehavior": false,
+ "fearSource": false,
+ "battlePackage": null,
+ "explorationPackage": null,
+ "removedFromTheGame": false,
+ "permanentlyRemovedIfExtraPlanar": false,
+ "refundReceivedDamageWhenRemoved": false,
+ "followSourcePosition": false,
+ "disolveCharacterOnDeath": false,
+ "disolveParameters": {
+ "$type": "GraphicsCharacterDefinitions+DisolveParameters, Assembly-CSharp",
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "colorWidth": 0.0,
+ "noiseScale": 5.0,
+ "hueScale": 0.0,
+ "vertexOffset": 0.0,
+ "curve": {
+ "$type": "UnityEngine.AnimationCurve, UnityEngine.CoreModule"
+ },
+ "startAfterDeathAnimation": false,
+ "duration": 0.0
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Spell/&CommandSpellGrovelTitle",
+ "description": "Spell/&CommandSpellGrovelDescription",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "5e96eb4d8d8193a4cbddbf7477990f88",
+ "m_SubObjectName": "ConditionPossessed",
+ "m_SubObjectType": "UnityEngine.Sprite, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "6422ce36-c309-52f9-b699-bddb61fde71e",
+ "contentPack": 9999,
+ "name": "ConditionCommandSpellGrovel"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionCommandSpellHalt.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionCommandSpellHalt.json
new file mode 100644
index 0000000000..f77afb492d
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionCommandSpellHalt.json
@@ -0,0 +1,157 @@
+{
+ "$type": "ConditionDefinition, Assembly-CSharp",
+ "inDungeonEditor": false,
+ "parentCondition": null,
+ "conditionType": "Detrimental",
+ "features": [
+ "Definition:ActionAffinityCommandSpellHalt:aefc4f30-7712-50b2-8a52-9368185278ab"
+ ],
+ "allowMultipleInstances": false,
+ "silentWhenAdded": false,
+ "silentWhenRemoved": false,
+ "silentWhenRefreshed": false,
+ "terminateWhenRemoved": false,
+ "specialDuration": true,
+ "durationType": "Round",
+ "durationParameterDie": "D4",
+ "durationParameter": 0,
+ "forceTurnOccurence": false,
+ "turnOccurence": "EndOfTurn",
+ "specialInterruptions": [],
+ "interruptionRequiresSavingThrow": false,
+ "interruptionSavingThrowComputationMethod": "SaveOverride",
+ "interruptionSavingThrowAbility": "",
+ "interruptionDamageThreshold": 0,
+ "keepConditionIfSavingThrowSucceeds": false,
+ "interruptionSavingThrowAffinity": "None",
+ "conditionTags": [],
+ "recurrentEffectForms": [],
+ "cancellingConditions": [],
+ "additionalDamageWhenHit": false,
+ "additionalDamageTypeDetermination": "Specific",
+ "additionalDamageType": "",
+ "additionalDamageQuantity": "AbilityBonus",
+ "additionalDamageDieType": "D1",
+ "additionalDamageDieNumber": 1,
+ "additionalConditionWhenHit": false,
+ "additionalCondition": null,
+ "additionalConditionDurationType": "Round",
+ "additionalConditionDurationParameter": 1,
+ "additionalConditionTurnOccurenceType": "StartOfTurn",
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "recurrentEffectParticleReference": null,
+ "characterShaderReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "particlesBasedOnAncestryDamageType": false,
+ "ancestryType": "Sorcerer",
+ "acidParticleParameters": null,
+ "coldParticleParameters": null,
+ "fireParticleParameters": null,
+ "lightningParticleParameters": null,
+ "poisonParticleParameters": null,
+ "overrideCharacterShaderColors": false,
+ "firstCharacterShaderColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "secondCharacterShaderColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "timeToWaitBeforeApplyingShader": 0.5,
+ "timeToWaitBeforeRemovingShader": 0.5,
+ "possessive": true,
+ "amountOrigin": "None",
+ "baseAmount": 0,
+ "additiveAmount": false,
+ "sourceAbilityBonusMinValue": 1,
+ "subsequentOnRemoval": null,
+ "subsequentHasSavingThrow": false,
+ "subsequentSavingThrowAbilityScore": "Constitution",
+ "subsequentVariableForDC": "FrenzyExhaustionDC",
+ "subsequentDCIncrease": 5,
+ "effectFormsOnRemoved": [],
+ "forceBehavior": false,
+ "addBehavior": false,
+ "fearSource": false,
+ "battlePackage": null,
+ "explorationPackage": null,
+ "removedFromTheGame": false,
+ "permanentlyRemovedIfExtraPlanar": false,
+ "refundReceivedDamageWhenRemoved": false,
+ "followSourcePosition": false,
+ "disolveCharacterOnDeath": false,
+ "disolveParameters": {
+ "$type": "GraphicsCharacterDefinitions+DisolveParameters, Assembly-CSharp",
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "colorWidth": 0.0,
+ "noiseScale": 5.0,
+ "hueScale": 0.0,
+ "vertexOffset": 0.0,
+ "curve": {
+ "$type": "UnityEngine.AnimationCurve, UnityEngine.CoreModule"
+ },
+ "startAfterDeathAnimation": false,
+ "duration": 0.0
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Spell/&CommandSpellHaltTitle",
+ "description": "Spell/&CommandSpellHaltDescription",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "5e96eb4d8d8193a4cbddbf7477990f88",
+ "m_SubObjectName": "ConditionPossessed",
+ "m_SubObjectType": "UnityEngine.Sprite, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "d20e7a46-e706-5c54-8bea-955b2054193a",
+ "contentPack": 9999,
+ "name": "ConditionCommandSpellHalt"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionFlashFreeze.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionFlashFreeze.json
index d3641e97f1..d42ec12fe9 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionFlashFreeze.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionFlashFreeze.json
@@ -1,13 +1,9 @@
{
"$type": "ConditionDefinition, Assembly-CSharp",
"inDungeonEditor": false,
- "parentCondition": "Definition:ConditionRestrainedByWeb:0a8efc601f1a64144905a95acf388a97",
+ "parentCondition": "Definition:ConditionRestrained:ec9fa707d4174c54bbdecde60a860c2c",
"conditionType": "Detrimental",
"features": [
- "Definition:MovementAffinityConditionRestrained:ed9d9d5986e47f845819579f936ee8cc",
- "Definition:CombatAffinityRestrained:dc755d1ea6b1ff0429ff9650d4a2d318",
- "Definition:SavingThrowAffinityConditionRestrained:fbdda0611e9c1254aa76ad4e303c668d",
- "Definition:ActionAffinityConditionRestrained:0a11d859909c2624086506f327824de8",
"Definition:ActionAffinityGrappled:1c2c02a0e9f823c489b3d62d03534617"
],
"allowMultipleInstances": false,
@@ -15,10 +11,10 @@
"silentWhenRemoved": false,
"silentWhenRefreshed": false,
"terminateWhenRemoved": false,
- "specialDuration": false,
- "durationType": "Round",
+ "specialDuration": true,
+ "durationType": "Minute",
"durationParameterDie": "D1",
- "durationParameter": 2,
+ "durationParameter": 1,
"forceTurnOccurence": false,
"turnOccurence": "EndOfTurn",
"specialInterruptions": [],
@@ -30,9 +26,7 @@
"interruptionSavingThrowAffinity": "None",
"conditionTags": [],
"recurrentEffectForms": [],
- "cancellingConditions": [
- "Definition:ConditionSwallowedRemorhaz:1bf833241755e684fbef755a54de3fd6"
- ],
+ "cancellingConditions": [],
"additionalDamageWhenHit": false,
"additionalDamageTypeDetermination": "Specific",
"additionalDamageType": "",
@@ -47,170 +41,35 @@
"conditionStartParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
"conditionParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
"conditionEndParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
+ "recurrentEffectParticleReference": null,
"characterShaderReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
"particlesBasedOnAncestryDamageType": false,
"ancestryType": "Sorcerer",
- "acidParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "coldParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "fireParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "lightningParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "poisonParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
+ "acidParticleParameters": null,
+ "coldParticleParameters": null,
+ "fireParticleParameters": null,
+ "lightningParticleParameters": null,
+ "poisonParticleParameters": null,
"overrideCharacterShaderColors": false,
"firstCharacterShaderColor": {
"$type": "UnityEngine.Color, UnityEngine.CoreModule",
@@ -229,8 +88,8 @@
"timeToWaitBeforeApplyingShader": 0.5,
"timeToWaitBeforeRemovingShader": 0.5,
"possessive": true,
- "amountOrigin": "None",
- "baseAmount": 0,
+ "amountOrigin": "Fixed",
+ "baseAmount": 20,
"additiveAmount": false,
"sourceAbilityBonusMinValue": 1,
"subsequentOnRemoval": null,
@@ -240,10 +99,10 @@
"subsequentDCIncrease": 5,
"effectFormsOnRemoved": [],
"forceBehavior": false,
- "addBehavior": false,
+ "addBehavior": true,
"fearSource": false,
- "battlePackage": null,
- "explorationPackage": null,
+ "battlePackage": "Definition:BreakFreeAbilityCheckConditionFlashFreeze:5578aa14-4a4c-5aa0-b787-7203e14b8a36",
+ "explorationPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
"removedFromTheGame": false,
"permanentlyRemovedIfExtraPlanar": false,
"refundReceivedDamageWhenRemoved": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionGlibness.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionGlibness.json
new file mode 100644
index 0000000000..902eeaadd1
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionGlibness.json
@@ -0,0 +1,155 @@
+{
+ "$type": "ConditionDefinition, Assembly-CSharp",
+ "inDungeonEditor": false,
+ "parentCondition": null,
+ "conditionType": "Beneficial",
+ "features": [],
+ "allowMultipleInstances": false,
+ "silentWhenAdded": false,
+ "silentWhenRemoved": false,
+ "silentWhenRefreshed": false,
+ "terminateWhenRemoved": false,
+ "specialDuration": false,
+ "durationType": "Hour",
+ "durationParameterDie": "D4",
+ "durationParameter": 1,
+ "forceTurnOccurence": false,
+ "turnOccurence": "EndOfTurn",
+ "specialInterruptions": [],
+ "interruptionRequiresSavingThrow": false,
+ "interruptionSavingThrowComputationMethod": "SaveOverride",
+ "interruptionSavingThrowAbility": "",
+ "interruptionDamageThreshold": 0,
+ "keepConditionIfSavingThrowSucceeds": false,
+ "interruptionSavingThrowAffinity": "None",
+ "conditionTags": [],
+ "recurrentEffectForms": [],
+ "cancellingConditions": [],
+ "additionalDamageWhenHit": false,
+ "additionalDamageTypeDetermination": "Specific",
+ "additionalDamageType": "",
+ "additionalDamageQuantity": "AbilityBonus",
+ "additionalDamageDieType": "D1",
+ "additionalDamageDieNumber": 1,
+ "additionalConditionWhenHit": false,
+ "additionalCondition": null,
+ "additionalConditionDurationType": "Round",
+ "additionalConditionDurationParameter": 1,
+ "additionalConditionTurnOccurenceType": "StartOfTurn",
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "recurrentEffectParticleReference": null,
+ "characterShaderReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "particlesBasedOnAncestryDamageType": false,
+ "ancestryType": "Sorcerer",
+ "acidParticleParameters": null,
+ "coldParticleParameters": null,
+ "fireParticleParameters": null,
+ "lightningParticleParameters": null,
+ "poisonParticleParameters": null,
+ "overrideCharacterShaderColors": false,
+ "firstCharacterShaderColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "secondCharacterShaderColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "timeToWaitBeforeApplyingShader": 0.5,
+ "timeToWaitBeforeRemovingShader": 0.5,
+ "possessive": true,
+ "amountOrigin": "None",
+ "baseAmount": 0,
+ "additiveAmount": false,
+ "sourceAbilityBonusMinValue": 1,
+ "subsequentOnRemoval": null,
+ "subsequentHasSavingThrow": false,
+ "subsequentSavingThrowAbilityScore": "Constitution",
+ "subsequentVariableForDC": "FrenzyExhaustionDC",
+ "subsequentDCIncrease": 5,
+ "effectFormsOnRemoved": [],
+ "forceBehavior": false,
+ "addBehavior": false,
+ "fearSource": false,
+ "battlePackage": null,
+ "explorationPackage": null,
+ "removedFromTheGame": false,
+ "permanentlyRemovedIfExtraPlanar": false,
+ "refundReceivedDamageWhenRemoved": false,
+ "followSourcePosition": false,
+ "disolveCharacterOnDeath": false,
+ "disolveParameters": {
+ "$type": "GraphicsCharacterDefinitions+DisolveParameters, Assembly-CSharp",
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "colorWidth": 0.0,
+ "noiseScale": 5.0,
+ "hueScale": 0.0,
+ "vertexOffset": 0.0,
+ "curve": {
+ "$type": "UnityEngine.AnimationCurve, UnityEngine.CoreModule"
+ },
+ "startAfterDeathAnimation": false,
+ "duration": 0.0
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Spell/&GlibnessTitle",
+ "description": "Spell/&GlibnessDescription",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "7e8c5d4d891953345b54b82e51c6d884",
+ "m_SubObjectName": "ConditionPositive",
+ "m_SubObjectType": "UnityEngine.Sprite, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "3182a19d-2d56-5f7a-849b-c2b28c7536b5",
+ "contentPack": 9999,
+ "name": "ConditionGlibness"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionGrappledRestrainedEnsnared.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionGrappledRestrainedEnsnared.json
index 49d7b5611b..d9c4007fc3 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionGrappledRestrainedEnsnared.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionGrappledRestrainedEnsnared.json
@@ -1,13 +1,9 @@
{
"$type": "ConditionDefinition, Assembly-CSharp",
"inDungeonEditor": false,
- "parentCondition": "Definition:ConditionRestrainedByWeb:0a8efc601f1a64144905a95acf388a97",
+ "parentCondition": "Definition:ConditionRestrained:ec9fa707d4174c54bbdecde60a860c2c",
"conditionType": "Detrimental",
"features": [
- "Definition:MovementAffinityConditionRestrained:ed9d9d5986e47f845819579f936ee8cc",
- "Definition:CombatAffinityRestrained:dc755d1ea6b1ff0429ff9650d4a2d318",
- "Definition:SavingThrowAffinityConditionRestrained:fbdda0611e9c1254aa76ad4e303c668d",
- "Definition:ActionAffinityConditionRestrained:0a11d859909c2624086506f327824de8",
"Definition:ActionAffinityGrappled:1c2c02a0e9f823c489b3d62d03534617"
],
"allowMultipleInstances": false,
@@ -20,7 +16,7 @@
"durationParameterDie": "D1",
"durationParameter": 1,
"forceTurnOccurence": false,
- "turnOccurence": "StartOfTurn",
+ "turnOccurence": "EndOfTurn",
"specialInterruptions": [],
"interruptionRequiresSavingThrow": false,
"interruptionSavingThrowComputationMethod": "SaveOverride",
@@ -66,9 +62,7 @@
"filterId": 0
}
],
- "cancellingConditions": [
- "Definition:ConditionSwallowedRemorhaz:1bf833241755e684fbef755a54de3fd6"
- ],
+ "cancellingConditions": [],
"additionalDamageWhenHit": false,
"additionalDamageTypeDetermination": "Specific",
"additionalDamageType": "",
@@ -107,146 +101,16 @@
"characterShaderReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
"particlesBasedOnAncestryDamageType": false,
"ancestryType": "Sorcerer",
- "acidParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "coldParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "fireParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "lightningParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "poisonParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
+ "acidParticleParameters": null,
+ "coldParticleParameters": null,
+ "fireParticleParameters": null,
+ "lightningParticleParameters": null,
+ "poisonParticleParameters": null,
"overrideCharacterShaderColors": false,
"firstCharacterShaderColor": {
"$type": "UnityEngine.Color, UnityEngine.CoreModule",
@@ -265,8 +129,8 @@
"timeToWaitBeforeApplyingShader": 0.5,
"timeToWaitBeforeRemovingShader": 0.5,
"possessive": false,
- "amountOrigin": "None",
- "baseAmount": 0,
+ "amountOrigin": "Fixed",
+ "baseAmount": 20,
"additiveAmount": false,
"sourceAbilityBonusMinValue": 1,
"subsequentOnRemoval": null,
@@ -276,10 +140,10 @@
"subsequentDCIncrease": 5,
"effectFormsOnRemoved": [],
"forceBehavior": false,
- "addBehavior": false,
+ "addBehavior": true,
"fearSource": false,
- "battlePackage": null,
- "explorationPackage": null,
+ "battlePackage": "Definition:BreakFreeAbilityCheckConditionGrappledRestrainedEnsnared:bf1d4828-465e-5897-91ca-bc8094b3d20e",
+ "explorationPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
"removedFromTheGame": false,
"permanentlyRemovedIfExtraPlanar": false,
"refundReceivedDamageWhenRemoved": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionGrappledRestrainedIceBound.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionGrappledRestrainedIceBound.json
index 54088ae417..6a955a6189 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionGrappledRestrainedIceBound.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionGrappledRestrainedIceBound.json
@@ -1,22 +1,20 @@
{
"$type": "ConditionDefinition, Assembly-CSharp",
"inDungeonEditor": false,
- "parentCondition": "Definition:ConditionGrappled:b9e3fa435129c33459a4847c9c551265",
+ "parentCondition": "Definition:ConditionRestrained:ec9fa707d4174c54bbdecde60a860c2c",
"conditionType": "Detrimental",
"features": [
- "Definition:ActionAffinityConditionRestrained:0a11d859909c2624086506f327824de8",
- "Definition:ActionAffinityGrappled:1c2c02a0e9f823c489b3d62d03534617",
- "Definition:MovementAffinityConditionRestrained:ed9d9d5986e47f845819579f936ee8cc"
+ "Definition:ActionAffinityGrappled:1c2c02a0e9f823c489b3d62d03534617"
],
"allowMultipleInstances": false,
"silentWhenAdded": false,
"silentWhenRemoved": false,
"silentWhenRefreshed": false,
"terminateWhenRemoved": false,
- "specialDuration": false,
- "durationType": "Round",
+ "specialDuration": true,
+ "durationType": "Minute",
"durationParameterDie": "D1",
- "durationParameter": 2,
+ "durationParameter": 1,
"forceTurnOccurence": false,
"turnOccurence": "EndOfTurn",
"specialInterruptions": [],
@@ -28,9 +26,7 @@
"interruptionSavingThrowAffinity": "None",
"conditionTags": [],
"recurrentEffectForms": [],
- "cancellingConditions": [
- "Definition:ConditionSwallowedRemorhaz:1bf833241755e684fbef755a54de3fd6"
- ],
+ "cancellingConditions": [],
"additionalDamageWhenHit": false,
"additionalDamageTypeDetermination": "Specific",
"additionalDamageType": "",
@@ -45,170 +41,35 @@
"conditionStartParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
"conditionParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
"conditionEndParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
+ "recurrentEffectParticleReference": null,
"characterShaderReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
"particlesBasedOnAncestryDamageType": false,
"ancestryType": "Sorcerer",
- "acidParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "coldParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "fireParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "lightningParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "poisonParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
+ "acidParticleParameters": null,
+ "coldParticleParameters": null,
+ "fireParticleParameters": null,
+ "lightningParticleParameters": null,
+ "poisonParticleParameters": null,
"overrideCharacterShaderColors": false,
"firstCharacterShaderColor": {
"$type": "UnityEngine.Color, UnityEngine.CoreModule",
@@ -227,8 +88,8 @@
"timeToWaitBeforeApplyingShader": 0.5,
"timeToWaitBeforeRemovingShader": 0.5,
"possessive": false,
- "amountOrigin": "None",
- "baseAmount": 0,
+ "amountOrigin": "Fixed",
+ "baseAmount": 10,
"additiveAmount": false,
"sourceAbilityBonusMinValue": 1,
"subsequentOnRemoval": null,
@@ -238,10 +99,10 @@
"subsequentDCIncrease": 5,
"effectFormsOnRemoved": [],
"forceBehavior": false,
- "addBehavior": false,
+ "addBehavior": true,
"fearSource": false,
- "battlePackage": null,
- "explorationPackage": null,
+ "battlePackage": "Definition:BreakFreeAbilityCheckConditionGrappledRestrainedIceBound:4702878b-3ac6-55e7-8954-7b1a8382aa7a",
+ "explorationPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
"removedFromTheGame": false,
"permanentlyRemovedIfExtraPlanar": false,
"refundReceivedDamageWhenRemoved": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionGrappledRestrainedSpellWeb.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionGrappledRestrainedSpellWeb.json
index 6263b29f1c..3d746a3cca 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionGrappledRestrainedSpellWeb.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionGrappledRestrainedSpellWeb.json
@@ -1,13 +1,9 @@
{
"$type": "ConditionDefinition, Assembly-CSharp",
"inDungeonEditor": false,
- "parentCondition": "Definition:ConditionRestrainedByWeb:0a8efc601f1a64144905a95acf388a97",
+ "parentCondition": "Definition:ConditionRestrained:ec9fa707d4174c54bbdecde60a860c2c",
"conditionType": "Detrimental",
"features": [
- "Definition:MovementAffinityConditionRestrained:ed9d9d5986e47f845819579f936ee8cc",
- "Definition:CombatAffinityRestrained:dc755d1ea6b1ff0429ff9650d4a2d318",
- "Definition:SavingThrowAffinityConditionRestrained:fbdda0611e9c1254aa76ad4e303c668d",
- "Definition:ActionAffinityConditionRestrained:0a11d859909c2624086506f327824de8",
"Definition:ActionAffinityGrappled:1c2c02a0e9f823c489b3d62d03534617"
],
"allowMultipleInstances": false,
@@ -15,10 +11,10 @@
"silentWhenRemoved": false,
"silentWhenRefreshed": false,
"terminateWhenRemoved": false,
- "specialDuration": false,
- "durationType": "Round",
+ "specialDuration": true,
+ "durationType": "Hour",
"durationParameterDie": "D1",
- "durationParameter": 2,
+ "durationParameter": 1,
"forceTurnOccurence": false,
"turnOccurence": "EndOfTurn",
"specialInterruptions": [],
@@ -30,9 +26,7 @@
"interruptionSavingThrowAffinity": "None",
"conditionTags": [],
"recurrentEffectForms": [],
- "cancellingConditions": [
- "Definition:ConditionSwallowedRemorhaz:1bf833241755e684fbef755a54de3fd6"
- ],
+ "cancellingConditions": [],
"additionalDamageWhenHit": false,
"additionalDamageTypeDetermination": "Specific",
"additionalDamageType": "",
@@ -47,170 +41,35 @@
"conditionStartParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
"conditionParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
"conditionEndParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
+ "recurrentEffectParticleReference": null,
"characterShaderReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
"particlesBasedOnAncestryDamageType": false,
"ancestryType": "Sorcerer",
- "acidParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "coldParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "fireParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "lightningParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "poisonParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
+ "acidParticleParameters": null,
+ "coldParticleParameters": null,
+ "fireParticleParameters": null,
+ "lightningParticleParameters": null,
+ "poisonParticleParameters": null,
"overrideCharacterShaderColors": false,
"firstCharacterShaderColor": {
"$type": "UnityEngine.Color, UnityEngine.CoreModule",
@@ -229,8 +88,8 @@
"timeToWaitBeforeApplyingShader": 0.5,
"timeToWaitBeforeRemovingShader": 0.5,
"possessive": false,
- "amountOrigin": "None",
- "baseAmount": 0,
+ "amountOrigin": "Fixed",
+ "baseAmount": 20,
"additiveAmount": false,
"sourceAbilityBonusMinValue": 1,
"subsequentOnRemoval": null,
@@ -240,10 +99,10 @@
"subsequentDCIncrease": 5,
"effectFormsOnRemoved": [],
"forceBehavior": false,
- "addBehavior": false,
+ "addBehavior": true,
"fearSource": false,
- "battlePackage": null,
- "explorationPackage": null,
+ "battlePackage": "Definition:BreakFreeAbilityCheckConditionGrappledRestrainedSpellWeb:f265e068-e06c-503a-8aa5-dc39a214a7ec",
+ "explorationPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
"removedFromTheGame": false,
"permanentlyRemovedIfExtraPlanar": false,
"refundReceivedDamageWhenRemoved": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionHolyWeapon.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionHolyWeapon.json
new file mode 100644
index 0000000000..be09291e5c
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionHolyWeapon.json
@@ -0,0 +1,157 @@
+{
+ "$type": "ConditionDefinition, Assembly-CSharp",
+ "inDungeonEditor": false,
+ "parentCondition": null,
+ "conditionType": "Beneficial",
+ "features": [
+ "Definition:PowerHolyWeapon:998ab674-743b-5200-b721-4e4a915a38d8"
+ ],
+ "allowMultipleInstances": false,
+ "silentWhenAdded": true,
+ "silentWhenRemoved": true,
+ "silentWhenRefreshed": false,
+ "terminateWhenRemoved": false,
+ "specialDuration": false,
+ "durationType": "Hour",
+ "durationParameterDie": "D4",
+ "durationParameter": 1,
+ "forceTurnOccurence": false,
+ "turnOccurence": "EndOfTurn",
+ "specialInterruptions": [],
+ "interruptionRequiresSavingThrow": false,
+ "interruptionSavingThrowComputationMethod": "SaveOverride",
+ "interruptionSavingThrowAbility": "",
+ "interruptionDamageThreshold": 0,
+ "keepConditionIfSavingThrowSucceeds": false,
+ "interruptionSavingThrowAffinity": "None",
+ "conditionTags": [],
+ "recurrentEffectForms": [],
+ "cancellingConditions": [],
+ "additionalDamageWhenHit": false,
+ "additionalDamageTypeDetermination": "Specific",
+ "additionalDamageType": "",
+ "additionalDamageQuantity": "AbilityBonus",
+ "additionalDamageDieType": "D1",
+ "additionalDamageDieNumber": 1,
+ "additionalConditionWhenHit": false,
+ "additionalCondition": null,
+ "additionalConditionDurationType": "Round",
+ "additionalConditionDurationParameter": 1,
+ "additionalConditionTurnOccurenceType": "StartOfTurn",
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "recurrentEffectParticleReference": null,
+ "characterShaderReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "particlesBasedOnAncestryDamageType": false,
+ "ancestryType": "Sorcerer",
+ "acidParticleParameters": null,
+ "coldParticleParameters": null,
+ "fireParticleParameters": null,
+ "lightningParticleParameters": null,
+ "poisonParticleParameters": null,
+ "overrideCharacterShaderColors": false,
+ "firstCharacterShaderColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "secondCharacterShaderColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "timeToWaitBeforeApplyingShader": 0.5,
+ "timeToWaitBeforeRemovingShader": 0.5,
+ "possessive": false,
+ "amountOrigin": "None",
+ "baseAmount": 0,
+ "additiveAmount": false,
+ "sourceAbilityBonusMinValue": 1,
+ "subsequentOnRemoval": null,
+ "subsequentHasSavingThrow": false,
+ "subsequentSavingThrowAbilityScore": "Constitution",
+ "subsequentVariableForDC": "FrenzyExhaustionDC",
+ "subsequentDCIncrease": 5,
+ "effectFormsOnRemoved": [],
+ "forceBehavior": false,
+ "addBehavior": false,
+ "fearSource": false,
+ "battlePackage": null,
+ "explorationPackage": null,
+ "removedFromTheGame": false,
+ "permanentlyRemovedIfExtraPlanar": false,
+ "refundReceivedDamageWhenRemoved": false,
+ "followSourcePosition": false,
+ "disolveCharacterOnDeath": false,
+ "disolveParameters": {
+ "$type": "GraphicsCharacterDefinitions+DisolveParameters, Assembly-CSharp",
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "colorWidth": 0.0,
+ "noiseScale": 5.0,
+ "hueScale": 0.0,
+ "vertexOffset": 0.0,
+ "curve": {
+ "$type": "UnityEngine.AnimationCurve, UnityEngine.CoreModule"
+ },
+ "startAfterDeathAnimation": false,
+ "duration": 0.0
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": true,
+ "title": "Feature/&NoContentTitle",
+ "description": "Feature/&NoContentTitle",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "4abe721f-d87f-519b-a35d-152100b60eb4",
+ "contentPack": 9999,
+ "name": "ConditionHolyWeapon"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionImpImpishWrathMark.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionImpImpishWrathMark.json
index 7ebab60e73..4a28f371b0 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionImpImpishWrathMark.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionImpImpishWrathMark.json
@@ -18,6 +18,7 @@
"specialInterruptions": [
"Attacks",
"CastSpellExecuted",
+ 9007,
"UsePowerExecuted"
],
"interruptionRequiresSavingThrow": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionInnovationVitriolistInfusionMark.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionInnovationVitriolistInfusionMark.json
index a7f394c9db..3d5187b1f3 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionInnovationVitriolistInfusionMark.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionInnovationVitriolistInfusionMark.json
@@ -18,6 +18,7 @@
"specialInterruptions": [
"Attacks",
"CastSpellExecuted",
+ 9007,
"UsePowerExecuted"
],
"interruptionRequiresSavingThrow": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionNoxiousSpray.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionNoxiousSpray.json
index 239da4d103..3e67b315aa 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionNoxiousSpray.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionNoxiousSpray.json
@@ -4,6 +4,7 @@
"parentCondition": null,
"conditionType": "Detrimental",
"features": [
+ "Definition:ActionAffinityGrappled:1c2c02a0e9f823c489b3d62d03534617",
"Definition:ActionAffinityNoxiousSpray:92fce887-eee5-549c-a04c-a32422effb56"
],
"allowMultipleInstances": false,
@@ -11,8 +12,8 @@
"silentWhenRemoved": false,
"silentWhenRefreshed": false,
"terminateWhenRemoved": false,
- "specialDuration": false,
- "durationType": "Hour",
+ "specialDuration": true,
+ "durationType": "Round",
"durationParameterDie": "D1",
"durationParameter": 1,
"forceTurnOccurence": false,
@@ -223,8 +224,8 @@
"timeToWaitBeforeApplyingShader": 0.5,
"timeToWaitBeforeRemovingShader": 0.5,
"possessive": true,
- "amountOrigin": "None",
- "baseAmount": 0,
+ "amountOrigin": "Fixed",
+ "baseAmount": 10,
"additiveAmount": false,
"sourceAbilityBonusMinValue": 1,
"subsequentOnRemoval": null,
@@ -234,10 +235,10 @@
"subsequentDCIncrease": 5,
"effectFormsOnRemoved": [],
"forceBehavior": false,
- "addBehavior": false,
+ "addBehavior": true,
"fearSource": false,
- "battlePackage": null,
- "explorationPackage": null,
+ "battlePackage": "Definition:BreakFreeAbilityCheckConditionNoxiousSpray:1918a4d8-ff14-5aa1-9c20-1256e73c5730",
+ "explorationPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
"removedFromTheGame": false,
"permanentlyRemovedIfExtraPlanar": false,
"refundReceivedDamageWhenRemoved": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionOathOfAncientsNaturesWrath.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionOathOfAncientsNaturesWrath.json
index 2e0eebdca4..39b1693beb 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionOathOfAncientsNaturesWrath.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionOathOfAncientsNaturesWrath.json
@@ -3,15 +3,17 @@
"inDungeonEditor": false,
"parentCondition": "Definition:ConditionRestrained:ec9fa707d4174c54bbdecde60a860c2c",
"conditionType": "Detrimental",
- "features": [],
+ "features": [
+ "Definition:ActionAffinityGrappled:1c2c02a0e9f823c489b3d62d03534617"
+ ],
"allowMultipleInstances": false,
"silentWhenAdded": false,
"silentWhenRemoved": false,
"silentWhenRefreshed": false,
"terminateWhenRemoved": false,
- "specialDuration": false,
- "durationType": "Round",
- "durationParameterDie": "D4",
+ "specialDuration": true,
+ "durationType": "Minute",
+ "durationParameterDie": "D1",
"durationParameter": 1,
"forceTurnOccurence": false,
"turnOccurence": "EndOfTurn",
@@ -39,170 +41,35 @@
"conditionStartParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
"conditionParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
"conditionEndParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
+ "recurrentEffectParticleReference": null,
"characterShaderReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
"particlesBasedOnAncestryDamageType": false,
"ancestryType": "Sorcerer",
- "acidParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "coldParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "fireParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "lightningParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "poisonParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
+ "acidParticleParameters": null,
+ "coldParticleParameters": null,
+ "fireParticleParameters": null,
+ "lightningParticleParameters": null,
+ "poisonParticleParameters": null,
"overrideCharacterShaderColors": false,
"firstCharacterShaderColor": {
"$type": "UnityEngine.Color, UnityEngine.CoreModule",
@@ -221,8 +88,8 @@
"timeToWaitBeforeApplyingShader": 0.5,
"timeToWaitBeforeRemovingShader": 0.5,
"possessive": false,
- "amountOrigin": "None",
- "baseAmount": 0,
+ "amountOrigin": "Fixed",
+ "baseAmount": 20,
"additiveAmount": false,
"sourceAbilityBonusMinValue": 1,
"subsequentOnRemoval": null,
@@ -232,10 +99,10 @@
"subsequentDCIncrease": 5,
"effectFormsOnRemoved": [],
"forceBehavior": false,
- "addBehavior": false,
+ "addBehavior": true,
"fearSource": false,
- "battlePackage": null,
- "explorationPackage": null,
+ "battlePackage": "Definition:BreakFreeAbilityCheckConditionOathOfAncientsNaturesWrath:c2d43b3b-7204-56df-a270-89202bf8ec7b",
+ "explorationPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
"removedFromTheGame": false,
"permanentlyRemovedIfExtraPlanar": false,
"refundReceivedDamageWhenRemoved": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionResonatingStrike.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionResonatingStrike.json
index 2c811f345b..f9a3235aef 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionResonatingStrike.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionResonatingStrike.json
@@ -18,7 +18,7 @@
"forceTurnOccurence": false,
"turnOccurence": "EndOfTurn",
"specialInterruptions": [
- "UsePowerExecuted"
+ 9007
],
"interruptionRequiresSavingThrow": false,
"interruptionSavingThrowComputationMethod": "SaveOverride",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionSearingSmite.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionSearingSmite.json
index 21e8e3e099..1740e0add8 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionSearingSmite.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionSearingSmite.json
@@ -18,7 +18,7 @@
"forceTurnOccurence": false,
"turnOccurence": "EndOfTurn",
"specialInterruptions": [
- "AttacksAndDamages"
+ 9005
],
"interruptionRequiresSavingThrow": false,
"interruptionSavingThrowComputationMethod": "SaveOverride",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionStaggeringSmite.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionStaggeringSmite.json
index dc4c2c6eec..e42cb55a06 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionStaggeringSmite.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionStaggeringSmite.json
@@ -18,7 +18,7 @@
"forceTurnOccurence": false,
"turnOccurence": "EndOfTurn",
"specialInterruptions": [
- "AttacksAndDamages"
+ 9005
],
"interruptionRequiresSavingThrow": false,
"interruptionSavingThrowComputationMethod": "SaveOverride",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionStrikeWithTheWind.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionStrikeWithTheWind.json
index a4167b8cff..61cbb98275 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionStrikeWithTheWind.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionStrikeWithTheWind.json
@@ -41,19 +41,19 @@
"additionalConditionTurnOccurenceType": "StartOfTurn",
"conditionStartParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
+ "m_AssetGUID": "26586e11a6341f142bd148aa07107e4e",
"m_SubObjectName": "",
"m_SubObjectType": ""
},
"conditionParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "ce76e6d0b360cd44da4abb7efe45187e",
+ "m_AssetGUID": "16f7e35a477e694418d4a62dfd0fe425",
"m_SubObjectName": "",
"m_SubObjectType": ""
},
"conditionEndParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "c5bd1eed8b51172459c06ed42ce4b095",
+ "m_AssetGUID": "4a751908e7238124d81c60a1fdfdaf9f",
"m_SubObjectName": "",
"m_SubObjectType": ""
},
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionStrikeWithTheWindAttack.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionStrikeWithTheWindAttack.json
index e4361e837f..382cfc0f75 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionStrikeWithTheWindAttack.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionStrikeWithTheWindAttack.json
@@ -44,20 +44,20 @@
"conditionStartParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
"conditionParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "ce76e6d0b360cd44da4abb7efe45187e",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
"conditionEndParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "c5bd1eed8b51172459c06ed42ce4b095",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
"recurrentEffectParticleReference": null,
"characterShaderReference": {
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionStrikeWithTheWindMovement.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionStrikeWithTheWindMovement.json
index 0f37b38454..bb14e9dede 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionStrikeWithTheWindMovement.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionStrikeWithTheWindMovement.json
@@ -41,20 +41,20 @@
"conditionStartParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
"conditionParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "8bc6a625e714ba043a1d90d489520d99",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
"conditionEndParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "aa315960d51fe0149842924060067b43",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
"recurrentEffectParticleReference": null,
"characterShaderReference": {
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionSwiftQuiver.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionSwiftQuiver.json
new file mode 100644
index 0000000000..abdcf08f11
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionSwiftQuiver.json
@@ -0,0 +1,155 @@
+{
+ "$type": "ConditionDefinition, Assembly-CSharp",
+ "inDungeonEditor": false,
+ "parentCondition": null,
+ "conditionType": "Beneficial",
+ "features": [],
+ "allowMultipleInstances": false,
+ "silentWhenAdded": false,
+ "silentWhenRemoved": false,
+ "silentWhenRefreshed": false,
+ "terminateWhenRemoved": false,
+ "specialDuration": false,
+ "durationType": "Hour",
+ "durationParameterDie": "D4",
+ "durationParameter": 1,
+ "forceTurnOccurence": false,
+ "turnOccurence": "EndOfTurn",
+ "specialInterruptions": [],
+ "interruptionRequiresSavingThrow": false,
+ "interruptionSavingThrowComputationMethod": "SaveOverride",
+ "interruptionSavingThrowAbility": "",
+ "interruptionDamageThreshold": 0,
+ "keepConditionIfSavingThrowSucceeds": false,
+ "interruptionSavingThrowAffinity": "None",
+ "conditionTags": [],
+ "recurrentEffectForms": [],
+ "cancellingConditions": [],
+ "additionalDamageWhenHit": false,
+ "additionalDamageTypeDetermination": "Specific",
+ "additionalDamageType": "",
+ "additionalDamageQuantity": "AbilityBonus",
+ "additionalDamageDieType": "D1",
+ "additionalDamageDieNumber": 1,
+ "additionalConditionWhenHit": false,
+ "additionalCondition": null,
+ "additionalConditionDurationType": "Round",
+ "additionalConditionDurationParameter": 1,
+ "additionalConditionTurnOccurenceType": "StartOfTurn",
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "recurrentEffectParticleReference": null,
+ "characterShaderReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "particlesBasedOnAncestryDamageType": false,
+ "ancestryType": "Sorcerer",
+ "acidParticleParameters": null,
+ "coldParticleParameters": null,
+ "fireParticleParameters": null,
+ "lightningParticleParameters": null,
+ "poisonParticleParameters": null,
+ "overrideCharacterShaderColors": false,
+ "firstCharacterShaderColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "secondCharacterShaderColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "timeToWaitBeforeApplyingShader": 0.5,
+ "timeToWaitBeforeRemovingShader": 0.5,
+ "possessive": false,
+ "amountOrigin": "None",
+ "baseAmount": 0,
+ "additiveAmount": false,
+ "sourceAbilityBonusMinValue": 1,
+ "subsequentOnRemoval": null,
+ "subsequentHasSavingThrow": false,
+ "subsequentSavingThrowAbilityScore": "Constitution",
+ "subsequentVariableForDC": "FrenzyExhaustionDC",
+ "subsequentDCIncrease": 5,
+ "effectFormsOnRemoved": [],
+ "forceBehavior": false,
+ "addBehavior": false,
+ "fearSource": false,
+ "battlePackage": null,
+ "explorationPackage": null,
+ "removedFromTheGame": false,
+ "permanentlyRemovedIfExtraPlanar": false,
+ "refundReceivedDamageWhenRemoved": false,
+ "followSourcePosition": false,
+ "disolveCharacterOnDeath": false,
+ "disolveParameters": {
+ "$type": "GraphicsCharacterDefinitions+DisolveParameters, Assembly-CSharp",
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "colorWidth": 0.0,
+ "noiseScale": 5.0,
+ "hueScale": 0.0,
+ "vertexOffset": 0.0,
+ "curve": {
+ "$type": "UnityEngine.AnimationCurve, UnityEngine.CoreModule"
+ },
+ "startAfterDeathAnimation": false,
+ "duration": 0.0
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Spell/&SwiftQuiverTitle",
+ "description": "Spell/&SwiftQuiverDescription",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "7e8c5d4d891953345b54b82e51c6d884",
+ "m_SubObjectName": "ConditionPositive",
+ "m_SubObjectType": "UnityEngine.Sprite, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "1e981912-4130-58da-9464-ac4a23323337",
+ "contentPack": 9999,
+ "name": "ConditionSwiftQuiver"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionThunderousSmite.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionThunderousSmite.json
index b589817715..0b1cd6dd51 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionThunderousSmite.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionThunderousSmite.json
@@ -10,7 +10,7 @@
"silentWhenAdded": false,
"silentWhenRemoved": false,
"silentWhenRefreshed": false,
- "terminateWhenRemoved": false,
+ "terminateWhenRemoved": true,
"specialDuration": false,
"durationType": "Hour",
"durationParameterDie": "D4",
@@ -18,7 +18,7 @@
"forceTurnOccurence": false,
"turnOccurence": "EndOfTurn",
"specialInterruptions": [
- "AttacksAndDamages"
+ 9005
],
"interruptionRequiresSavingThrow": false,
"interruptionSavingThrowComputationMethod": "SaveOverride",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionVileBrew.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionVileBrew.json
index 78c9314f92..7176b34a27 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionVileBrew.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionVileBrew.json
@@ -4,19 +4,17 @@
"parentCondition": null,
"conditionType": "Detrimental",
"features": [
- "Definition:ActionAffinityConditionRestrained:0a11d859909c2624086506f327824de8",
- "Definition:ActionAffinityGrappled:1c2c02a0e9f823c489b3d62d03534617",
- "Definition:MovementAffinityConditionRestrained:ed9d9d5986e47f845819579f936ee8cc"
+ "Definition:ActionAffinityGrappled:1c2c02a0e9f823c489b3d62d03534617"
],
"allowMultipleInstances": false,
"silentWhenAdded": false,
"silentWhenRemoved": false,
"silentWhenRefreshed": false,
"terminateWhenRemoved": false,
- "specialDuration": false,
- "durationType": "Round",
+ "specialDuration": true,
+ "durationType": "Minute",
"durationParameterDie": "D1",
- "durationParameter": 3,
+ "durationParameter": 1,
"forceTurnOccurence": false,
"turnOccurence": "EndOfTurn",
"specialInterruptions": [],
@@ -94,155 +92,20 @@
"m_SubObjectName": "",
"m_SubObjectType": ""
},
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
+ "recurrentEffectParticleReference": null,
"characterShaderReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
"particlesBasedOnAncestryDamageType": false,
"ancestryType": "Sorcerer",
- "acidParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "coldParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "fireParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "lightningParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
- "poisonParticleParameters": {
- "$type": "ConditionParticleParameters, Assembly-CSharp",
- "startParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "particleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "endParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- },
- "recurrentEffectParticleReference": {
- "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
- }
- },
+ "acidParticleParameters": null,
+ "coldParticleParameters": null,
+ "fireParticleParameters": null,
+ "lightningParticleParameters": null,
+ "poisonParticleParameters": null,
"overrideCharacterShaderColors": false,
"firstCharacterShaderColor": {
"$type": "UnityEngine.Color, UnityEngine.CoreModule",
@@ -261,8 +124,8 @@
"timeToWaitBeforeApplyingShader": 0.5,
"timeToWaitBeforeRemovingShader": 0.5,
"possessive": false,
- "amountOrigin": "None",
- "baseAmount": 0,
+ "amountOrigin": "Fixed",
+ "baseAmount": 10,
"additiveAmount": false,
"sourceAbilityBonusMinValue": 1,
"subsequentOnRemoval": null,
@@ -272,10 +135,10 @@
"subsequentDCIncrease": 5,
"effectFormsOnRemoved": [],
"forceBehavior": false,
- "addBehavior": false,
+ "addBehavior": true,
"fearSource": false,
- "battlePackage": null,
- "explorationPackage": null,
+ "battlePackage": "Definition:BreakFreeAbilityCheckConditionVileBrew:7b202c71-3241-5f80-8b02-ada4a0d9383f",
+ "explorationPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
"removedFromTheGame": false,
"permanentlyRemovedIfExtraPlanar": false,
"refundReceivedDamageWhenRemoved": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionWarMagicSurgeMark.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionWarMagicSurgeMark.json
index fa71864a20..750db02497 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionWarMagicSurgeMark.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionWarMagicSurgeMark.json
@@ -18,6 +18,7 @@
"specialInterruptions": [
"Attacks",
"CastSpellExecuted",
+ 9007,
"UsePowerExecuted"
],
"interruptionRequiresSavingThrow": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionWrathfulSmite.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionWrathfulSmite.json
index c9613d6b9e..692dfb4bfc 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionWrathfulSmite.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionWrathfulSmite.json
@@ -18,7 +18,7 @@
"forceTurnOccurence": false,
"turnOccurence": "EndOfTurn",
"specialInterruptions": [
- "AttacksAndDamages"
+ 9005
],
"interruptionRequiresSavingThrow": false,
"interruptionSavingThrowComputationMethod": "SaveOverride",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionWrathfulSmiteEnemy.json b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionWrathfulSmiteEnemy.json
index 9c80e56aee..20a4d53557 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionWrathfulSmiteEnemy.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ConditionDefinition/ConditionWrathfulSmiteEnemy.json
@@ -4,8 +4,7 @@
"parentCondition": "Definition:ConditionFrightened:5cbaee42aac310e42a407fc59bf65515",
"conditionType": "Detrimental",
"features": [
- "Definition:CombatAffinityFrightened:bd7a11317eacebb44966fa78e8b8f2dc",
- "Definition:AbilityCheckAffinityFrightened:2a2719b10ea87f34f9f29e03cbdba5c7"
+ "Definition:ActionAffinityGrappled:1c2c02a0e9f823c489b3d62d03534617"
],
"allowMultipleInstances": false,
"silentWhenAdded": false,
@@ -17,7 +16,7 @@
"durationParameterDie": "D1",
"durationParameter": 1,
"forceTurnOccurence": false,
- "turnOccurence": "StartOfTurn",
+ "turnOccurence": "EndOfTurn",
"specialInterruptions": [],
"interruptionRequiresSavingThrow": false,
"interruptionSavingThrowComputationMethod": "SaveOverride",
@@ -224,8 +223,8 @@
"timeToWaitBeforeApplyingShader": 0.5,
"timeToWaitBeforeRemovingShader": 0.5,
"possessive": false,
- "amountOrigin": "None",
- "baseAmount": 0,
+ "amountOrigin": "Fixed",
+ "baseAmount": 30,
"additiveAmount": false,
"sourceAbilityBonusMinValue": 1,
"subsequentOnRemoval": null,
@@ -235,10 +234,10 @@
"subsequentDCIncrease": 5,
"effectFormsOnRemoved": [],
"forceBehavior": false,
- "addBehavior": false,
+ "addBehavior": true,
"fearSource": false,
- "battlePackage": null,
- "explorationPackage": null,
+ "battlePackage": "Definition:BreakFreeAbilityCheckConditionWrathfulSmiteEnemy:8952dfa4-c552-57f5-bf82-7e317c4e459d",
+ "explorationPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
"removedFromTheGame": false,
"permanentlyRemovedIfExtraPlanar": false,
"refundReceivedDamageWhenRemoved": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionFlashFreeze.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionFlashFreeze.json
index a4eeaf309e..e06b7b48c5 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionFlashFreeze.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionFlashFreeze.json
@@ -2,7 +2,7 @@
"$type": "TA.AI.DecisionDefinition, Assembly-CSharp",
"decision": {
"$type": "TA.AI.DecisionDescription, Assembly-CSharp",
- "description": "if restrained and can use main action, try to break free",
+ "description": "if restrained from ConditionFlashFreeze, and can use main action, try to break free",
"scorer": {
"$type": "TA.AI.ActivityScorerDefinition, Assembly-CSharp",
"scorer": {
@@ -54,10 +54,10 @@
}
]
},
- "name": "BreakFree"
+ "name": "BreakFreeConditionFlashFreeze"
},
"activityType": "BreakFree",
- "stringParameter": "2",
+ "stringParameter": "",
"stringSecParameter": "",
"boolParameter": false,
"boolSecParameter": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionGrappledRestrainedEnsnared.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionGrappledRestrainedEnsnared.json
index 03f6a47058..9a376180a6 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionGrappledRestrainedEnsnared.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionGrappledRestrainedEnsnared.json
@@ -2,7 +2,7 @@
"$type": "TA.AI.DecisionDefinition, Assembly-CSharp",
"decision": {
"$type": "TA.AI.DecisionDescription, Assembly-CSharp",
- "description": "if restrained and can use main action, try to break free",
+ "description": "if restrained from ConditionGrappledRestrainedEnsnared, and can use main action, try to break free",
"scorer": {
"$type": "TA.AI.ActivityScorerDefinition, Assembly-CSharp",
"scorer": {
@@ -54,10 +54,10 @@
}
]
},
- "name": "BreakFree"
+ "name": "BreakFreeConditionGrappledRestrainedEnsnared"
},
"activityType": "BreakFree",
- "stringParameter": "2",
+ "stringParameter": "",
"stringSecParameter": "",
"boolParameter": false,
"boolSecParameter": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionGrappledRestrainedIceBound.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionGrappledRestrainedIceBound.json
index 9560fd47d2..46d3ca4130 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionGrappledRestrainedIceBound.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionGrappledRestrainedIceBound.json
@@ -2,7 +2,7 @@
"$type": "TA.AI.DecisionDefinition, Assembly-CSharp",
"decision": {
"$type": "TA.AI.DecisionDescription, Assembly-CSharp",
- "description": "if restrained and can use main action, try to break free",
+ "description": "if restrained from ConditionGrappledRestrainedIceBound, and can use main action, try to break free",
"scorer": {
"$type": "TA.AI.ActivityScorerDefinition, Assembly-CSharp",
"scorer": {
@@ -54,10 +54,10 @@
}
]
},
- "name": "BreakFree"
+ "name": "BreakFreeConditionGrappledRestrainedIceBound"
},
"activityType": "BreakFree",
- "stringParameter": "1",
+ "stringParameter": "",
"stringSecParameter": "",
"boolParameter": false,
"boolSecParameter": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionGrappledRestrainedSpellWeb.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionGrappledRestrainedSpellWeb.json
index 6ff7438b6d..03137c0b72 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionGrappledRestrainedSpellWeb.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionGrappledRestrainedSpellWeb.json
@@ -2,7 +2,7 @@
"$type": "TA.AI.DecisionDefinition, Assembly-CSharp",
"decision": {
"$type": "TA.AI.DecisionDescription, Assembly-CSharp",
- "description": "if restrained and can use main action, try to break free",
+ "description": "if restrained from ConditionGrappledRestrainedSpellWeb, and can use main action, try to break free",
"scorer": {
"$type": "TA.AI.ActivityScorerDefinition, Assembly-CSharp",
"scorer": {
@@ -54,10 +54,10 @@
}
]
},
- "name": "BreakFree"
+ "name": "BreakFreeConditionGrappledRestrainedSpellWeb"
},
"activityType": "BreakFree",
- "stringParameter": "2",
+ "stringParameter": "",
"stringSecParameter": "",
"boolParameter": false,
"boolSecParameter": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionNoxiousSpray.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionNoxiousSpray.json
index 95e4a44133..8bbd16e63b 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionNoxiousSpray.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionNoxiousSpray.json
@@ -2,7 +2,7 @@
"$type": "TA.AI.DecisionDefinition, Assembly-CSharp",
"decision": {
"$type": "TA.AI.DecisionDescription, Assembly-CSharp",
- "description": "if restrained and can use main action, try to break free",
+ "description": "if restrained from ConditionNoxiousSpray, and can use main action, try to break free",
"scorer": {
"$type": "TA.AI.ActivityScorerDefinition, Assembly-CSharp",
"scorer": {
@@ -54,10 +54,10 @@
}
]
},
- "name": "BreakFree"
+ "name": "BreakFreeConditionNoxiousSpray"
},
"activityType": "BreakFree",
- "stringParameter": "1",
+ "stringParameter": "",
"stringSecParameter": "",
"boolParameter": false,
"boolSecParameter": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionOathOfAncientsNaturesWrath.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionOathOfAncientsNaturesWrath.json
new file mode 100644
index 0000000000..c04023adfb
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionOathOfAncientsNaturesWrath.json
@@ -0,0 +1,94 @@
+{
+ "$type": "TA.AI.DecisionDefinition, Assembly-CSharp",
+ "decision": {
+ "$type": "TA.AI.DecisionDescription, Assembly-CSharp",
+ "description": "if restrained from ConditionOathOfAncientsNaturesWrath, and can use main action, try to break free",
+ "scorer": {
+ "$type": "TA.AI.ActivityScorerDefinition, Assembly-CSharp",
+ "scorer": {
+ "$type": "TA.AI.ActivityScorer, Assembly-CSharp",
+ "considerations": [
+ {
+ "$type": "TA.AI.WeightedConsiderationDescription, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDefinition, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDescription, Assembly-CSharp",
+ "considerationType": "HasCondition",
+ "curve": {
+ "$type": "UnityEngine.AnimationCurve, UnityEngine.CoreModule"
+ },
+ "stringParameter": "ConditionOathOfAncientsNaturesWrath",
+ "floatParameter": 2.0,
+ "intParameter": 2,
+ "byteParameter": 0,
+ "boolParameter": true,
+ "boolSecParameter": false,
+ "boolTerParameter": false
+ },
+ "name": "HasConditionOathOfAncientsNaturesWrath"
+ },
+ "weight": 1.0
+ },
+ {
+ "$type": "TA.AI.WeightedConsiderationDescription, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDefinition, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDescription, Assembly-CSharp",
+ "considerationType": "ActionTypeStatus",
+ "curve": {
+ "$type": "UnityEngine.AnimationCurve, UnityEngine.CoreModule"
+ },
+ "stringParameter": "",
+ "floatParameter": 1.0,
+ "intParameter": 0,
+ "byteParameter": 0,
+ "boolParameter": true,
+ "boolSecParameter": false,
+ "boolTerParameter": false
+ },
+ "name": "MainActionNotFullyConsumed"
+ },
+ "weight": 1.0
+ }
+ ]
+ },
+ "name": "BreakFreeConditionOathOfAncientsNaturesWrath"
+ },
+ "activityType": "BreakFree",
+ "stringParameter": "",
+ "stringSecParameter": "",
+ "boolParameter": false,
+ "boolSecParameter": false,
+ "floatParameter": 3.0,
+ "enumParameter": 1
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": true,
+ "title": "Feature/&NoContentTitle",
+ "description": "Feature/&NoContentTitle",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "25d7ad8d-27b8-5882-9bfb-acc37798812f",
+ "contentPack": 9999,
+ "name": "DecisionBreakFreeConditionOathOfAncientsNaturesWrath"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionRestrainedByEntangle.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionRestrainedByEntangle.json
index e6a5f84791..d16265bed1 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionRestrainedByEntangle.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionRestrainedByEntangle.json
@@ -2,7 +2,7 @@
"$type": "TA.AI.DecisionDefinition, Assembly-CSharp",
"decision": {
"$type": "TA.AI.DecisionDescription, Assembly-CSharp",
- "description": "if restrained and can use main action, try to break free",
+ "description": "if restrained from ConditionRestrainedByEntangle, and can use main action, try to break free",
"scorer": {
"$type": "TA.AI.ActivityScorerDefinition, Assembly-CSharp",
"scorer": {
@@ -54,10 +54,10 @@
}
]
},
- "name": "BreakFree"
+ "name": "BreakFreeConditionRestrainedByEntangle"
},
"activityType": "BreakFree",
- "stringParameter": "2",
+ "stringParameter": "",
"stringSecParameter": "",
"boolParameter": false,
"boolSecParameter": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionVileBrew.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionVileBrew.json
index c3add13f22..91c153a20e 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionVileBrew.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionVileBrew.json
@@ -2,7 +2,7 @@
"$type": "TA.AI.DecisionDefinition, Assembly-CSharp",
"decision": {
"$type": "TA.AI.DecisionDescription, Assembly-CSharp",
- "description": "if restrained and can use main action, try to break free",
+ "description": "if restrained from ConditionVileBrew, and can use main action, try to break free",
"scorer": {
"$type": "TA.AI.ActivityScorerDefinition, Assembly-CSharp",
"scorer": {
@@ -54,10 +54,10 @@
}
]
},
- "name": "BreakFree"
+ "name": "BreakFreeConditionVileBrew"
},
"activityType": "BreakFree",
- "stringParameter": "1",
+ "stringParameter": "",
"stringSecParameter": "",
"boolParameter": false,
"boolSecParameter": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionWrathfulSmiteEnemy.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionWrathfulSmiteEnemy.json
new file mode 100644
index 0000000000..56ae0aedac
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/DecisionBreakFreeConditionWrathfulSmiteEnemy.json
@@ -0,0 +1,94 @@
+{
+ "$type": "TA.AI.DecisionDefinition, Assembly-CSharp",
+ "decision": {
+ "$type": "TA.AI.DecisionDescription, Assembly-CSharp",
+ "description": "if restrained from ConditionWrathfulSmiteEnemy, and can use main action, try to break free",
+ "scorer": {
+ "$type": "TA.AI.ActivityScorerDefinition, Assembly-CSharp",
+ "scorer": {
+ "$type": "TA.AI.ActivityScorer, Assembly-CSharp",
+ "considerations": [
+ {
+ "$type": "TA.AI.WeightedConsiderationDescription, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDefinition, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDescription, Assembly-CSharp",
+ "considerationType": "HasCondition",
+ "curve": {
+ "$type": "UnityEngine.AnimationCurve, UnityEngine.CoreModule"
+ },
+ "stringParameter": "ConditionWrathfulSmiteEnemy",
+ "floatParameter": 2.0,
+ "intParameter": 2,
+ "byteParameter": 0,
+ "boolParameter": true,
+ "boolSecParameter": false,
+ "boolTerParameter": false
+ },
+ "name": "HasConditionWrathfulSmiteEnemy"
+ },
+ "weight": 1.0
+ },
+ {
+ "$type": "TA.AI.WeightedConsiderationDescription, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDefinition, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDescription, Assembly-CSharp",
+ "considerationType": "ActionTypeStatus",
+ "curve": {
+ "$type": "UnityEngine.AnimationCurve, UnityEngine.CoreModule"
+ },
+ "stringParameter": "",
+ "floatParameter": 1.0,
+ "intParameter": 0,
+ "byteParameter": 0,
+ "boolParameter": true,
+ "boolSecParameter": false,
+ "boolTerParameter": false
+ },
+ "name": "MainActionNotFullyConsumed"
+ },
+ "weight": 1.0
+ }
+ ]
+ },
+ "name": "BreakFreeConditionWrathfulSmiteEnemy"
+ },
+ "activityType": "BreakFree",
+ "stringParameter": "",
+ "stringSecParameter": "",
+ "boolParameter": false,
+ "boolSecParameter": false,
+ "floatParameter": 3.0,
+ "enumParameter": 1
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": true,
+ "title": "Feature/&NoContentTitle",
+ "description": "Feature/&NoContentTitle",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "6400794a-3234-55f7-973f-d443c38c9a20",
+ "contentPack": 9999,
+ "name": "DecisionBreakFreeConditionWrathfulSmiteEnemy"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/Move_Approach.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/Move_Approach.json
new file mode 100644
index 0000000000..2e549ada9d
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/Move_Approach.json
@@ -0,0 +1,138 @@
+{
+ "$type": "TA.AI.DecisionDefinition, Assembly-CSharp",
+ "decision": {
+ "$type": "TA.AI.DecisionDescription, Assembly-CSharp",
+ "description": "Go as close as possible to enemies.",
+ "scorer": {
+ "$type": "TA.AI.ActivityScorerDefinition, Assembly-CSharp",
+ "scorer": {
+ "$type": "TA.AI.ActivityScorer, Assembly-CSharp",
+ "considerations": [
+ {
+ "$type": "TA.AI.WeightedConsiderationDescription, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDefinition, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDescription, Assembly-CSharp",
+ "considerationType": "IsValidMoveDestination",
+ "curve": {
+ "$type": "UnityEngine.AnimationCurve, UnityEngine.CoreModule"
+ },
+ "stringParameter": "",
+ "floatParameter": 0.0,
+ "intParameter": 0,
+ "byteParameter": 0,
+ "boolParameter": false,
+ "boolSecParameter": false,
+ "boolTerParameter": false
+ },
+ "name": "IsValidMoveDestination"
+ },
+ "weight": 1.0
+ },
+ {
+ "$type": "TA.AI.WeightedConsiderationDescription, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDefinition, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDescription, Assembly-CSharp",
+ "considerationType": "InfluenceEnemyProximity",
+ "curve": {
+ "$type": "UnityEngine.AnimationCurve, UnityEngine.CoreModule"
+ },
+ "stringParameter": "ConditionCommandSpellApproach",
+ "floatParameter": 3.0,
+ "intParameter": 2,
+ "byteParameter": 0,
+ "boolParameter": true,
+ "boolSecParameter": false,
+ "boolTerParameter": false
+ },
+ "name": "PenalizeVeryCloseEnemyProximityAtPosition"
+ },
+ "weight": 1.0
+ },
+ {
+ "$type": "TA.AI.WeightedConsiderationDescription, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDefinition, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDescription, Assembly-CSharp",
+ "considerationType": "InfluenceFearSourceProximity",
+ "curve": {
+ "$type": "UnityEngine.AnimationCurve, UnityEngine.CoreModule"
+ },
+ "stringParameter": "ConditionCommandSpellApproach",
+ "floatParameter": 6.0,
+ "intParameter": 1,
+ "byteParameter": 0,
+ "boolParameter": true,
+ "boolSecParameter": false,
+ "boolTerParameter": false
+ },
+ "name": "PenalizeFearSourceProximityAtPosition"
+ },
+ "weight": 1.0
+ },
+ {
+ "$type": "TA.AI.WeightedConsiderationDescription, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDefinition, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDescription, Assembly-CSharp",
+ "considerationType": "DistanceFromMe",
+ "curve": {
+ "$type": "UnityEngine.AnimationCurve, UnityEngine.CoreModule"
+ },
+ "stringParameter": "",
+ "floatParameter": 20.0,
+ "intParameter": 0,
+ "byteParameter": 0,
+ "boolParameter": false,
+ "boolSecParameter": false,
+ "boolTerParameter": false
+ },
+ "name": "IsCloseFromMe"
+ },
+ "weight": 0.95
+ }
+ ]
+ },
+ "name": "MoveScorer_Approach"
+ },
+ "activityType": "Move",
+ "stringParameter": "",
+ "stringSecParameter": "",
+ "boolParameter": false,
+ "boolSecParameter": false,
+ "floatParameter": 0.0,
+ "enumParameter": 0
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": true,
+ "title": "Feature/&NoContentTitle",
+ "description": "Feature/&NoContentTitle",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "5cb2a87f-09a4-5fae-9b74-10516ea8a8ab",
+ "contentPack": 9999,
+ "name": "Move_Approach"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/Move_DissonantWhispers.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/Move_DissonantWhispers.json
new file mode 100644
index 0000000000..2cd7eb8447
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionDefinition/Move_DissonantWhispers.json
@@ -0,0 +1,116 @@
+{
+ "$type": "TA.AI.DecisionDefinition, Assembly-CSharp",
+ "decision": {
+ "$type": "TA.AI.DecisionDescription, Assembly-CSharp",
+ "description": "Go as far as possible from enemies.",
+ "scorer": {
+ "$type": "TA.AI.ActivityScorerDefinition, Assembly-CSharp",
+ "scorer": {
+ "$type": "TA.AI.ActivityScorer, Assembly-CSharp",
+ "considerations": [
+ {
+ "$type": "TA.AI.WeightedConsiderationDescription, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDefinition, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDescription, Assembly-CSharp",
+ "considerationType": "IsValidMoveDestination",
+ "curve": {
+ "$type": "UnityEngine.AnimationCurve, UnityEngine.CoreModule"
+ },
+ "stringParameter": "",
+ "floatParameter": 0.0,
+ "intParameter": 0,
+ "byteParameter": 0,
+ "boolParameter": false,
+ "boolSecParameter": false,
+ "boolTerParameter": false
+ },
+ "name": "IsValidMoveDestination"
+ },
+ "weight": 1.0
+ },
+ {
+ "$type": "TA.AI.WeightedConsiderationDescription, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDefinition, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDescription, Assembly-CSharp",
+ "considerationType": "InfluenceEnemyProximity",
+ "curve": {
+ "$type": "UnityEngine.AnimationCurve, UnityEngine.CoreModule"
+ },
+ "stringParameter": "",
+ "floatParameter": 3.0,
+ "intParameter": 2,
+ "byteParameter": 0,
+ "boolParameter": true,
+ "boolSecParameter": false,
+ "boolTerParameter": false
+ },
+ "name": "PenalizeVeryCloseEnemyProximityAtPosition"
+ },
+ "weight": 1.0
+ },
+ {
+ "$type": "TA.AI.WeightedConsiderationDescription, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDefinition, Assembly-CSharp",
+ "consideration": {
+ "$type": "TA.AI.ConsiderationDescription, Assembly-CSharp",
+ "considerationType": "InfluenceFearSourceProximity",
+ "curve": {
+ "$type": "UnityEngine.AnimationCurve, UnityEngine.CoreModule"
+ },
+ "stringParameter": "",
+ "floatParameter": 6.0,
+ "intParameter": 1,
+ "byteParameter": 0,
+ "boolParameter": true,
+ "boolSecParameter": false,
+ "boolTerParameter": false
+ },
+ "name": "PenalizeFearSourceProximityAtPosition"
+ },
+ "weight": 1.0
+ }
+ ]
+ },
+ "name": "MoveScorer_DissonantWhispers"
+ },
+ "activityType": "Move",
+ "stringParameter": "",
+ "stringSecParameter": "",
+ "boolParameter": false,
+ "boolSecParameter": false,
+ "floatParameter": 0.0,
+ "enumParameter": 0
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": true,
+ "title": "Feature/&NoContentTitle",
+ "description": "Feature/&NoContentTitle",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "bdfa6649-5cad-5b35-a697-209ea53ca45d",
+ "contentPack": 9999,
+ "name": "Move_DissonantWhispers"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/Approach.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/Approach.json
new file mode 100644
index 0000000000..07938b03c0
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/Approach.json
@@ -0,0 +1,43 @@
+{
+ "$type": "TA.AI.DecisionPackageDefinition, Assembly-CSharp",
+ "dungeonMakerPresence": false,
+ "package": {
+ "$type": "TA.AI.DecisionPackageDescription, Assembly-CSharp",
+ "weightedDecisions": [
+ {
+ "$type": "TA.AI.WeightedDecisionDescription, Assembly-CSharp",
+ "decision": "Definition:Move_Approach:5cb2a87f-09a4-5fae-9b74-10516ea8a8ab",
+ "weight": 9.0,
+ "cooldown": 0,
+ "dynamicCooldown": false
+ }
+ ]
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": true,
+ "title": "Feature/&NoContentTitle",
+ "description": "Feature/&NoContentTitle",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "5043a0ec-c626-5877-bd87-c7bc0584366d",
+ "contentPack": 9999,
+ "name": "Approach"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionFlashFreeze.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionFlashFreeze.json
new file mode 100644
index 0000000000..3d527d9ad1
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionFlashFreeze.json
@@ -0,0 +1,43 @@
+{
+ "$type": "TA.AI.DecisionPackageDefinition, Assembly-CSharp",
+ "dungeonMakerPresence": false,
+ "package": {
+ "$type": "TA.AI.DecisionPackageDescription, Assembly-CSharp",
+ "weightedDecisions": [
+ {
+ "$type": "TA.AI.WeightedDecisionDescription, Assembly-CSharp",
+ "decision": "Definition:DecisionBreakFreeConditionFlashFreeze:c1790fe7-d377-51c3-8bd4-3ff2556b771e",
+ "weight": 2.0,
+ "cooldown": 0,
+ "dynamicCooldown": false
+ }
+ ]
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": true,
+ "title": "Feature/&NoContentTitle",
+ "description": "Feature/&NoContentTitle",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "5578aa14-4a4c-5aa0-b787-7203e14b8a36",
+ "contentPack": 9999,
+ "name": "BreakFreeAbilityCheckConditionFlashFreeze"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionGrappledRestrainedEnsnared.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionGrappledRestrainedEnsnared.json
new file mode 100644
index 0000000000..f082844c2b
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionGrappledRestrainedEnsnared.json
@@ -0,0 +1,43 @@
+{
+ "$type": "TA.AI.DecisionPackageDefinition, Assembly-CSharp",
+ "dungeonMakerPresence": false,
+ "package": {
+ "$type": "TA.AI.DecisionPackageDescription, Assembly-CSharp",
+ "weightedDecisions": [
+ {
+ "$type": "TA.AI.WeightedDecisionDescription, Assembly-CSharp",
+ "decision": "Definition:DecisionBreakFreeConditionGrappledRestrainedEnsnared:69855aed-d774-527f-9de3-8de1e5a9743f",
+ "weight": 2.0,
+ "cooldown": 0,
+ "dynamicCooldown": false
+ }
+ ]
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": true,
+ "title": "Feature/&NoContentTitle",
+ "description": "Feature/&NoContentTitle",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "bf1d4828-465e-5897-91ca-bc8094b3d20e",
+ "contentPack": 9999,
+ "name": "BreakFreeAbilityCheckConditionGrappledRestrainedEnsnared"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionGrappledRestrainedIceBound.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionGrappledRestrainedIceBound.json
new file mode 100644
index 0000000000..15b83817b2
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionGrappledRestrainedIceBound.json
@@ -0,0 +1,43 @@
+{
+ "$type": "TA.AI.DecisionPackageDefinition, Assembly-CSharp",
+ "dungeonMakerPresence": false,
+ "package": {
+ "$type": "TA.AI.DecisionPackageDescription, Assembly-CSharp",
+ "weightedDecisions": [
+ {
+ "$type": "TA.AI.WeightedDecisionDescription, Assembly-CSharp",
+ "decision": "Definition:DecisionBreakFreeConditionGrappledRestrainedIceBound:017c5b82-f11c-5899-8729-947eabcf949f",
+ "weight": 2.0,
+ "cooldown": 0,
+ "dynamicCooldown": false
+ }
+ ]
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": true,
+ "title": "Feature/&NoContentTitle",
+ "description": "Feature/&NoContentTitle",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "4702878b-3ac6-55e7-8954-7b1a8382aa7a",
+ "contentPack": 9999,
+ "name": "BreakFreeAbilityCheckConditionGrappledRestrainedIceBound"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionGrappledRestrainedSpellWeb.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionGrappledRestrainedSpellWeb.json
new file mode 100644
index 0000000000..399f01aae2
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionGrappledRestrainedSpellWeb.json
@@ -0,0 +1,43 @@
+{
+ "$type": "TA.AI.DecisionPackageDefinition, Assembly-CSharp",
+ "dungeonMakerPresence": false,
+ "package": {
+ "$type": "TA.AI.DecisionPackageDescription, Assembly-CSharp",
+ "weightedDecisions": [
+ {
+ "$type": "TA.AI.WeightedDecisionDescription, Assembly-CSharp",
+ "decision": "Definition:DecisionBreakFreeConditionGrappledRestrainedSpellWeb:61e7fc96-8cb5-5c2b-8a67-75fbef4f333a",
+ "weight": 2.0,
+ "cooldown": 0,
+ "dynamicCooldown": false
+ }
+ ]
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": true,
+ "title": "Feature/&NoContentTitle",
+ "description": "Feature/&NoContentTitle",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "f265e068-e06c-503a-8aa5-dc39a214a7ec",
+ "contentPack": 9999,
+ "name": "BreakFreeAbilityCheckConditionGrappledRestrainedSpellWeb"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionNoxiousSpray.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionNoxiousSpray.json
new file mode 100644
index 0000000000..96a400543e
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionNoxiousSpray.json
@@ -0,0 +1,43 @@
+{
+ "$type": "TA.AI.DecisionPackageDefinition, Assembly-CSharp",
+ "dungeonMakerPresence": false,
+ "package": {
+ "$type": "TA.AI.DecisionPackageDescription, Assembly-CSharp",
+ "weightedDecisions": [
+ {
+ "$type": "TA.AI.WeightedDecisionDescription, Assembly-CSharp",
+ "decision": "Definition:DecisionBreakFreeConditionNoxiousSpray:2f033fcf-d478-5581-94d9-27a3ad4496ad",
+ "weight": 2.0,
+ "cooldown": 0,
+ "dynamicCooldown": false
+ }
+ ]
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": true,
+ "title": "Feature/&NoContentTitle",
+ "description": "Feature/&NoContentTitle",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "1918a4d8-ff14-5aa1-9c20-1256e73c5730",
+ "contentPack": 9999,
+ "name": "BreakFreeAbilityCheckConditionNoxiousSpray"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionOathOfAncientsNaturesWrath.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionOathOfAncientsNaturesWrath.json
new file mode 100644
index 0000000000..918eaae7ad
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionOathOfAncientsNaturesWrath.json
@@ -0,0 +1,43 @@
+{
+ "$type": "TA.AI.DecisionPackageDefinition, Assembly-CSharp",
+ "dungeonMakerPresence": false,
+ "package": {
+ "$type": "TA.AI.DecisionPackageDescription, Assembly-CSharp",
+ "weightedDecisions": [
+ {
+ "$type": "TA.AI.WeightedDecisionDescription, Assembly-CSharp",
+ "decision": "Definition:DecisionBreakFreeConditionOathOfAncientsNaturesWrath:25d7ad8d-27b8-5882-9bfb-acc37798812f",
+ "weight": 2.0,
+ "cooldown": 0,
+ "dynamicCooldown": false
+ }
+ ]
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": true,
+ "title": "Feature/&NoContentTitle",
+ "description": "Feature/&NoContentTitle",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "c2d43b3b-7204-56df-a270-89202bf8ec7b",
+ "contentPack": 9999,
+ "name": "BreakFreeAbilityCheckConditionOathOfAncientsNaturesWrath"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionRestrainedByEntangle.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionRestrainedByEntangle.json
new file mode 100644
index 0000000000..c794d4ecff
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionRestrainedByEntangle.json
@@ -0,0 +1,43 @@
+{
+ "$type": "TA.AI.DecisionPackageDefinition, Assembly-CSharp",
+ "dungeonMakerPresence": false,
+ "package": {
+ "$type": "TA.AI.DecisionPackageDescription, Assembly-CSharp",
+ "weightedDecisions": [
+ {
+ "$type": "TA.AI.WeightedDecisionDescription, Assembly-CSharp",
+ "decision": "Definition:DecisionBreakFreeConditionRestrainedByEntangle:2a416669-5ec8-53c1-b07b-8fe6f29da4d2",
+ "weight": 2.0,
+ "cooldown": 0,
+ "dynamicCooldown": false
+ }
+ ]
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": true,
+ "title": "Feature/&NoContentTitle",
+ "description": "Feature/&NoContentTitle",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "0d9623d9-0cd7-5c03-8275-e9e61f0f1b6a",
+ "contentPack": 9999,
+ "name": "BreakFreeAbilityCheckConditionRestrainedByEntangle"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionVileBrew.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionVileBrew.json
new file mode 100644
index 0000000000..4559d8ccc6
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionVileBrew.json
@@ -0,0 +1,43 @@
+{
+ "$type": "TA.AI.DecisionPackageDefinition, Assembly-CSharp",
+ "dungeonMakerPresence": false,
+ "package": {
+ "$type": "TA.AI.DecisionPackageDescription, Assembly-CSharp",
+ "weightedDecisions": [
+ {
+ "$type": "TA.AI.WeightedDecisionDescription, Assembly-CSharp",
+ "decision": "Definition:DecisionBreakFreeConditionVileBrew:4b3278e8-334a-58d6-8c75-2f48e28b4e54",
+ "weight": 2.0,
+ "cooldown": 0,
+ "dynamicCooldown": false
+ }
+ ]
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": true,
+ "title": "Feature/&NoContentTitle",
+ "description": "Feature/&NoContentTitle",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "7b202c71-3241-5f80-8b02-ada4a0d9383f",
+ "contentPack": 9999,
+ "name": "BreakFreeAbilityCheckConditionVileBrew"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionWrathfulSmiteEnemy.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionWrathfulSmiteEnemy.json
new file mode 100644
index 0000000000..8f148dc800
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/BreakFreeAbilityCheckConditionWrathfulSmiteEnemy.json
@@ -0,0 +1,43 @@
+{
+ "$type": "TA.AI.DecisionPackageDefinition, Assembly-CSharp",
+ "dungeonMakerPresence": false,
+ "package": {
+ "$type": "TA.AI.DecisionPackageDescription, Assembly-CSharp",
+ "weightedDecisions": [
+ {
+ "$type": "TA.AI.WeightedDecisionDescription, Assembly-CSharp",
+ "decision": "Definition:DecisionBreakFreeConditionWrathfulSmiteEnemy:6400794a-3234-55f7-973f-d443c38c9a20",
+ "weight": 2.0,
+ "cooldown": 0,
+ "dynamicCooldown": false
+ }
+ ]
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": true,
+ "title": "Feature/&NoContentTitle",
+ "description": "Feature/&NoContentTitle",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "8952dfa4-c552-57f5-bf82-7e317c4e459d",
+ "contentPack": 9999,
+ "name": "BreakFreeAbilityCheckConditionWrathfulSmiteEnemy"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/DissonantWhispers_Fear.json b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/DissonantWhispers_Fear.json
new file mode 100644
index 0000000000..71c0556900
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/DecisionPackageDefinition/DissonantWhispers_Fear.json
@@ -0,0 +1,43 @@
+{
+ "$type": "TA.AI.DecisionPackageDefinition, Assembly-CSharp",
+ "dungeonMakerPresence": false,
+ "package": {
+ "$type": "TA.AI.DecisionPackageDescription, Assembly-CSharp",
+ "weightedDecisions": [
+ {
+ "$type": "TA.AI.WeightedDecisionDescription, Assembly-CSharp",
+ "decision": "Definition:Move_DissonantWhispers:bdfa6649-5cad-5b35-a697-209ea53ca45d",
+ "weight": 9.0,
+ "cooldown": 0,
+ "dynamicCooldown": false
+ }
+ ]
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": true,
+ "title": "Feature/&NoContentTitle",
+ "description": "Feature/&NoContentTitle",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "dfe2cc9e-cc70-5cfe-9057-19454acb1068",
+ "contentPack": 9999,
+ "name": "DissonantWhispers_Fear"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/EffectProxyDefinition/ProxyCircleOfTheWildfireCauterizingFlames.json b/Diagnostics/UnfinishedBusinessBlueprints/EffectProxyDefinition/ProxyCircleOfTheWildfireCauterizingFlames.json
index 3589129c2c..1587612f27 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/EffectProxyDefinition/ProxyCircleOfTheWildfireCauterizingFlames.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/EffectProxyDefinition/ProxyCircleOfTheWildfireCauterizingFlames.json
@@ -18,10 +18,7 @@
"addAbilityToDamage": false,
"attackPower": null,
"impactsPlacement": false,
- "additionalFeatures": [
- "Definition:MoveModeMove2:0127a492ba7a429408b3282dde9374d7",
- "Definition:MoveModeFly12:5e70172c8e2a40146b375001ab656a44"
- ],
+ "additionalFeatures": [],
"attackParticle": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
@@ -34,7 +31,7 @@
"m_SubObjectName": "",
"m_SubObjectType": ""
},
- "addLightSource": false,
+ "addLightSource": true,
"lightSourceForm": {
"$type": "LightSourceForm, Assembly-CSharp",
"lightSourceType": "Basic",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/EffectProxyDefinition/ProxyCreateBonfire.json b/Diagnostics/UnfinishedBusinessBlueprints/EffectProxyDefinition/ProxyCreateBonfire.json
new file mode 100644
index 0000000000..4fd0a58767
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/EffectProxyDefinition/ProxyCreateBonfire.json
@@ -0,0 +1,149 @@
+{
+ "$type": "EffectProxyDefinition, Assembly-CSharp",
+ "canMove": false,
+ "canRotate": false,
+ "canMoveOnCharacters": false,
+ "canAttack": false,
+ "canTriggerPower": false,
+ "autoTerminateOnTriggerPower": false,
+ "incrementalDamageDice": 0,
+ "actionId": "NoAction",
+ "freeActionId": "NoAction",
+ "attackMethod": "CasterSpellAbility",
+ "firstAttackIsFree": false,
+ "constrainedToSpellArea": false,
+ "damageDie": "D8",
+ "damageDieNum": 1,
+ "damageType": "DamageRadiant",
+ "addAbilityToDamage": false,
+ "attackPower": null,
+ "impactsPlacement": false,
+ "additionalFeatures": [],
+ "attackParticle": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "attackImpactParticle": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "addLightSource": true,
+ "lightSourceForm": {
+ "$type": "LightSourceForm, Assembly-CSharp",
+ "lightSourceType": "Basic",
+ "brightRange": 2,
+ "dimAdditionalRange": 2,
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 0.5409614,
+ "b": 0.193396211,
+ "a": 1.0
+ },
+ "graphicsPrefabReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "792bd092227ae074ca8d89efc06dbfc6",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "applyToSelf": false,
+ "forceOnSelf": false
+ },
+ "lightSourceOffset": {
+ "$type": "UnityEngine.Vector3, UnityEngine.CoreModule",
+ "x": 0.0,
+ "y": 0.5,
+ "z": 0.0
+ },
+ "spellImmunityFromOutside": false,
+ "maxSpellLevelImmunity": 1,
+ "hasPresentation": true,
+ "prefabReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "58aff54afb62c3a43be06958596b2bf2",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "isEmptyPresentation": true,
+ "modelScale": 1.0,
+ "showWorldLocationFeedbacks": false,
+ "hasPortrait": false,
+ "portraitSpriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "startEvent": {
+ "$type": "AK.Wwise.Event, AK.Wwise.Unity.API.WwiseTypes",
+ "WwiseObjectReference": {
+ "$type": "WwiseEventReference, AK.Wwise.Unity.API.WwiseTypes",
+ "objectName": "Play_Vfx_EVO_WallOfFire_Cell",
+ "id": 1935475708,
+ "guid": "73EB45BB-E4D5-480F-B6D9-6BEEF1BF62E3",
+ "name": "73EB45BB-E4D5-480F-B6D9-6BEEF1BF62E3"
+ },
+ "idInternal": 0,
+ "valueGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ }
+ },
+ "stopEvent": {
+ "$type": "AK.Wwise.Event, AK.Wwise.Unity.API.WwiseTypes",
+ "WwiseObjectReference": null,
+ "idInternal": 0,
+ "valueGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ }
+ },
+ "soundEffectOnHitDescription": {
+ "$type": "SoundEffectOnHitDescription, Assembly-CSharp",
+ "switchOnHit": {
+ "$type": "AK.Wwise.Switch, AK.Wwise.Unity.API.WwiseTypes",
+ "WwiseObjectReference": null,
+ "groupIdInternal": 0,
+ "groupGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ },
+ "idInternal": 0,
+ "valueGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ }
+ }
+ },
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Proxy/&ProxyCreateBonfireTitle",
+ "description": "Feature/&NoContentTitle",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "4cfa51a7cbd64134d9097a59eefe34c7",
+ "m_SubObjectName": "WallOfFire",
+ "m_SubObjectType": "UnityEngine.Sprite, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "a84e5459-b44a-5dfd-9f27-c4a44b571c3a",
+ "contentPack": 9999,
+ "name": "ProxyCreateBonfire"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/EffectProxyDefinition/ProxyFaithfulHound.json b/Diagnostics/UnfinishedBusinessBlueprints/EffectProxyDefinition/ProxyFaithfulHound.json
index a69396513b..078304a384 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/EffectProxyDefinition/ProxyFaithfulHound.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/EffectProxyDefinition/ProxyFaithfulHound.json
@@ -133,7 +133,7 @@
"$type": "GuiPresentation, Assembly-CSharp",
"hidden": false,
"title": "Proxy/&ProxyFaithfulHoundTitle",
- "description": "Proxy/&ProxyFaithfulHoundDescription",
+ "description": "Feature/&NoContentTitle",
"spriteReference": {
"$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
"m_AssetGUID": "9ccae0cf-fedf-5b4b-a2fa-770939e6b8e9",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatDefinition/FeatGroupMediumArmor.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatDefinition/FeatGroupMediumArmor.json
index bdee712a4b..0f8f0d3a17 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatDefinition/FeatGroupMediumArmor.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatDefinition/FeatGroupMediumArmor.json
@@ -6,8 +6,8 @@
"minimalAbilityScorePrerequisite": false,
"minimalAbilityScoreValue": 13,
"minimalAbilityScoreName": "Strength",
- "armorProficiencyPrerequisite": false,
- "armorProficiencyCategory": "",
+ "armorProficiencyPrerequisite": true,
+ "armorProficiencyCategory": "LightArmorCategory",
"hasFamilyTag": true,
"familyTag": "MediumArmor",
"knownFeatsPrerequisite": [],
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatDefinition/FeatMobile.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatDefinition/FeatMobile.json
index 493695d33f..d84d456e09 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatDefinition/FeatMobile.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatDefinition/FeatMobile.json
@@ -3,9 +3,9 @@
"compatibleClassesPrerequisite": [],
"mustCastSpellsPrerequisite": false,
"compatibleRacesPrerequisite": [],
- "minimalAbilityScorePrerequisite": true,
+ "minimalAbilityScorePrerequisite": false,
"minimalAbilityScoreValue": 13,
- "minimalAbilityScoreName": "Dexterity",
+ "minimalAbilityScoreName": "Strength",
"armorProficiencyPrerequisite": false,
"armorProficiencyCategory": "",
"hasFamilyTag": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionActionAffinity/ActionAffinityCommandSpellHalt.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionActionAffinity/ActionAffinityCommandSpellHalt.json
new file mode 100644
index 0000000000..e6e299ada7
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionActionAffinity/ActionAffinityCommandSpellHalt.json
@@ -0,0 +1,48 @@
+{
+ "$type": "FeatureDefinitionActionAffinity, Assembly-CSharp",
+ "allowedActionTypes": [
+ false,
+ false,
+ false,
+ false,
+ false,
+ false
+ ],
+ "eitherMainOrBonus": false,
+ "maxAttacksNumber": -1,
+ "forbiddenActions": [],
+ "authorizedActions": [],
+ "restrictedActions": [],
+ "actionExecutionModifiers": [],
+ "specialBehaviour": "None",
+ "randomBehaviorDie": "D10",
+ "randomBehaviourOptions": [],
+ "rechargeReactionsAtEveryTurn": false,
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": true,
+ "title": "Feature/&NoContentTitle",
+ "description": "Feature/&NoContentTitle",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "aefc4f30-7712-50b2-8a52-9368185278ab",
+ "contentPack": 9999,
+ "name": "ActionAffinityCommandSpellHalt"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageBlindingSmite.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageBlindingSmite.json
index 249aebab5e..d1b47a8b52 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageBlindingSmite.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageBlindingSmite.json
@@ -6,7 +6,7 @@
"targetSide": "Enemy",
"otherSimilarAdditionalDamages": [],
"triggerCondition": "AlwaysActive",
- "requiredProperty": "None",
+ "requiredProperty": "MeleeWeapon",
"attackModeOnly": true,
"attackOnly": false,
"requiredTargetCondition": null,
@@ -42,7 +42,7 @@
"conditionDefinition": "Definition:ConditionBlindedByBlindingSmite:d3436e86-c822-51d0-ab7f-7301cd5ba1e2",
"saveAffinity": "Negates",
"canSaveToCancel": true,
- "saveOccurence": "StartOfTurn"
+ "saveOccurence": "EndOfTurn"
}
],
"addLightSource": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageHolyWeapon.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageHolyWeapon.json
new file mode 100644
index 0000000000..fa85244739
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageHolyWeapon.json
@@ -0,0 +1,75 @@
+{
+ "$type": "FeatureDefinitionAdditionalDamage, Assembly-CSharp",
+ "notificationTag": "HolyWeapon",
+ "limitedUsage": "None",
+ "firstTargetOnly": true,
+ "targetSide": "Enemy",
+ "otherSimilarAdditionalDamages": [],
+ "triggerCondition": "AlwaysActive",
+ "requiredProperty": "None",
+ "attackModeOnly": false,
+ "attackOnly": false,
+ "requiredTargetCondition": null,
+ "requiredTargetSenseType": "Darkvision",
+ "requiredTargetCreatureTag": "",
+ "requiredCharacterFamily": null,
+ "requiredSpecificSpell": null,
+ "requiredAncestryType": "Sorcerer",
+ "damageValueDetermination": "Die",
+ "flatBonus": 0,
+ "damageDieType": "D8",
+ "damageDiceNumber": 2,
+ "additionalDamageType": "Specific",
+ "specificDamageType": "DamageRadiant",
+ "ancestryTypeForDamageType": "Sorcerer",
+ "damageAdvancement": "None",
+ "diceByRankTable": [],
+ "familiesWithAdditionalDice": [],
+ "familiesDiceNumber": 1,
+ "ignoreCriticalDoubleDice": false,
+ "hasSavingThrow": false,
+ "savingThrowAbility": "Dexterity",
+ "dcComputation": "FixedValue",
+ "savingThrowDC": 10,
+ "savingThrowDCAbilityModifier": "Dexterity",
+ "damageSaveAffinity": "None",
+ "conditionOperations": [],
+ "addLightSource": false,
+ "lightSourceForm": null,
+ "impactParticleReference": null,
+ "particlesBasedOnAncestryDamageType": false,
+ "ancestryType": "Sorcerer",
+ "acidImpactParticleReference": null,
+ "coldImpactParticleReference": null,
+ "fireImpactParticleReference": null,
+ "lightningImpactParticleReference": null,
+ "poisonImpactParticleReference": null,
+ "computeDescription": false,
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Feature/&AdditionalDamageHolyWeaponTitle",
+ "description": "Feature/&AdditionalDamageHolyWeaponDescription",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "7892e11668806184fb7f0901204e6ddc",
+ "m_SubObjectName": "SpiritualWeapon",
+ "m_SubObjectType": "UnityEngine.Sprite, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "a818b04d-36eb-554a-921b-a4e00c1ac999",
+ "contentPack": 9999,
+ "name": "AdditionalDamageHolyWeapon"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageMalakhAngelicForm.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageMalakhAngelicForm.json
index 20aed1da8c..4f55d530d9 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageMalakhAngelicForm.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageMalakhAngelicForm.json
@@ -36,7 +36,12 @@
"conditionOperations": [],
"addLightSource": false,
"lightSourceForm": null,
- "impactParticleReference": null,
+ "impactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "dc52f8444fa49f24ca22b361d63dbb15",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
"particlesBasedOnAncestryDamageType": false,
"ancestryType": "Sorcerer",
"acidImpactParticleReference": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageOathOfDemonHunterTrialMark.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageOathOfDemonHunterTrialMark.json
index 54f1c4abfc..02adf6aa62 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageOathOfDemonHunterTrialMark.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageOathOfDemonHunterTrialMark.json
@@ -137,7 +137,12 @@
"conditionOperations": [],
"addLightSource": false,
"lightSourceForm": null,
- "impactParticleReference": null,
+ "impactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "5cdd6944009a9f14eae5a1f5e9bc0a82",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
"particlesBasedOnAncestryDamageType": false,
"ancestryType": "Sorcerer",
"acidImpactParticleReference": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageSearingSmite.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageSearingSmite.json
index 28282e6073..233b5a50ad 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageSearingSmite.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageSearingSmite.json
@@ -6,7 +6,7 @@
"targetSide": "Enemy",
"otherSimilarAdditionalDamages": [],
"triggerCondition": "AlwaysActive",
- "requiredProperty": "None",
+ "requiredProperty": "MeleeWeapon",
"attackModeOnly": true,
"attackOnly": false,
"requiredTargetCondition": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageStaggeringSmite.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageStaggeringSmite.json
index e6be9290b2..bf626b48c4 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageStaggeringSmite.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageStaggeringSmite.json
@@ -6,7 +6,7 @@
"targetSide": "Enemy",
"otherSimilarAdditionalDamages": [],
"triggerCondition": "AlwaysActive",
- "requiredProperty": "None",
+ "requiredProperty": "MeleeWeapon",
"attackModeOnly": true,
"attackOnly": false,
"requiredTargetCondition": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageWrathfulSmite.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageWrathfulSmite.json
index d0649a932d..a820289be4 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageWrathfulSmite.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionAdditionalDamage/AdditionalDamageWrathfulSmite.json
@@ -6,7 +6,7 @@
"targetSide": "Enemy",
"otherSimilarAdditionalDamages": [],
"triggerCondition": "AlwaysActive",
- "requiredProperty": "None",
+ "requiredProperty": "MeleeWeapon",
"attackModeOnly": true,
"attackOnly": false,
"requiredTargetCondition": null,
@@ -142,7 +142,7 @@
"conditionName": "",
"conditionDefinition": "Definition:ConditionWrathfulSmiteEnemy:08ab37a6-23bc-59c3-ac2b-09f02170a996",
"saveAffinity": "Negates",
- "canSaveToCancel": true,
+ "canSaveToCancel": false,
"saveOccurence": "StartOfTurn"
}
],
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerChaosBoltLeap.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerChaosBoltLeap.json
index 5f8c867ffa..c118b59fb6 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerChaosBoltLeap.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerChaosBoltLeap.json
@@ -25,8 +25,8 @@
"recurrentEffect": "No",
"retargetAfterDeath": false,
"retargetActionType": "Bonus",
- "poolFilterDiceNumber": 0,
- "poolFilterDieType": "D1",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
"trapRangeType": "Triggerer",
"targetConditionName": "",
"targetConditionAsset": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerCircleOfTheWildfireSpiritTeleportDamage.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerCircleOfTheWildfireSpiritTeleportDamage.json
index 3df0800746..fb33d65f9f 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerCircleOfTheWildfireSpiritTeleportDamage.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerCircleOfTheWildfireSpiritTeleportDamage.json
@@ -335,7 +335,7 @@
"includeBaseDescription": false,
"guiPresentation": {
"$type": "GuiPresentation, Assembly-CSharp",
- "hidden": false,
+ "hidden": true,
"title": "Feature/&PowerCircleOfTheWildfireSpiritTeleportDamageTitle",
"description": "Feature/&PowerCircleOfTheWildfireSpiritTeleportDamageDescription",
"spriteReference": {
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerCollegeOfEleganceAmazingDisplayEnemy.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerCollegeOfEleganceAmazingDisplayEnemy.json
index 096034a15e..9d44881a1c 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerCollegeOfEleganceAmazingDisplayEnemy.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerCollegeOfEleganceAmazingDisplayEnemy.json
@@ -142,7 +142,7 @@
"$type": "EffectParticleParameters, Assembly-CSharp",
"casterParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "8b9fa0fcdb99d2347a36d25a972de9f5",
+ "m_AssetGUID": "81560ac3813217d4d9fd281d5e73c234",
"m_SubObjectName": "",
"m_SubObjectType": ""
},
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerCrownOfStars.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerCrownOfStars.json
index 71c42ca875..5cbbec26c3 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerCrownOfStars.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerCrownOfStars.json
@@ -100,13 +100,13 @@
"specialFormsDescription": "",
"effectAdvancement": {
"$type": "EffectAdvancement, Assembly-CSharp",
- "effectIncrementMethod": "None",
+ "effectIncrementMethod": "PerAdditionalSlotLevel",
"incrementMultiplier": 1,
"additionalTargetsPerIncrement": 0,
"additionalSubtargetsPerIncrement": 0,
"additionalDicePerIncrement": 0,
"additionalSpellLevelPerIncrement": 0,
- "additionalSummonsPerIncrement": 0,
+ "additionalSummonsPerIncrement": 2,
"additionalHPPerIncrement": 0,
"additionalTempHPPerIncrement": 0,
"additionalTargetCellsPerIncrement": 0,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerDomainColdSummonBlizzard.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerDomainColdSummonBlizzard.json
index 3a6efc2245..ff4ff0be6a 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerDomainColdSummonBlizzard.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerDomainColdSummonBlizzard.json
@@ -85,7 +85,7 @@
"number": 2,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerDomainFireSummonInferno.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerDomainFireSummonInferno.json
index b166887a22..867271cdec 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerDomainFireSummonInferno.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerDomainFireSummonInferno.json
@@ -85,7 +85,7 @@
"number": 2,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerDomainSmithAdamantBenediction.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerDomainSmithAdamantBenediction.json
index f43c72d6a9..1dc91efb08 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerDomainSmithAdamantBenediction.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerDomainSmithAdamantBenediction.json
@@ -25,8 +25,8 @@
"recurrentEffect": "No",
"retargetAfterDeath": false,
"retargetActionType": "Bonus",
- "poolFilterDiceNumber": 0,
- "poolFilterDieType": "D1",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
"trapRangeType": "Triggerer",
"targetConditionName": "",
"targetConditionAsset": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerFeatFlamesOfPhlegethos.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerFeatFlamesOfPhlegethos.json
index 3104f7b85d..e01eef5bb7 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerFeatFlamesOfPhlegethos.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerFeatFlamesOfPhlegethos.json
@@ -13,11 +13,11 @@
"emissiveBorder": "None",
"emissiveParameter": 1,
"requiresTargetProximity": false,
- "targetProximityDistance": 6,
+ "targetProximityDistance": 30,
"targetExcludeCaster": false,
"canBePlacedOnCharacter": true,
"affectOnlyGround": false,
- "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringMethod": "AllCharacterAndGadgets",
"targetFilteringTag": "No",
"requiresVisibilityForPosition": true,
"inviteOptionalAlly": false,
@@ -35,7 +35,7 @@
"durationParameter": 1,
"endOfEffect": "EndOfTurn",
"hasSavingThrow": false,
- "disableSavingThrowOnAllies": false,
+ "disableSavingThrowOnAllies": true,
"savingThrowAbility": "Dexterity",
"ignoreCover": false,
"grantedConditionOnSave": null,
@@ -110,14 +110,14 @@
"dimAdditionalRange": 6,
"color": {
"$type": "UnityEngine.Color, UnityEngine.CoreModule",
- "r": 1.0,
- "g": 0.9778601,
- "b": 0.78039217,
+ "r": 0.8396226,
+ "g": 0.7766465,
+ "b": 0.5505073,
"a": 1.0
},
"graphicsPrefabReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "3e4cdebecc6e0db469720619529e3dc2",
+ "m_AssetGUID": "fc7cb53da57a8fb40a278d62a885ce58",
"m_SubObjectName": "",
"m_SubObjectType": ""
},
@@ -154,7 +154,7 @@
"$type": "EffectParticleParameters, Assembly-CSharp",
"casterParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "81560ac3813217d4d9fd281d5e73c234",
+ "m_AssetGUID": "74aff29d9a49eb042a3377c2511b13a2",
"m_SubObjectName": "",
"m_SubObjectType": ""
},
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerFeatPoisonousSkin.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerFeatPoisonousSkin.json
index 59fe6706ed..6ba66993bb 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerFeatPoisonousSkin.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerFeatPoisonousSkin.json
@@ -14,7 +14,7 @@
"emissiveParameter": 1,
"requiresTargetProximity": false,
"targetProximityDistance": 6,
- "targetExcludeCaster": true,
+ "targetExcludeCaster": false,
"canBePlacedOnCharacter": true,
"affectOnlyGround": false,
"targetFilteringMethod": "CharacterOnly",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerFightingStyleTorchbearer.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerFightingStyleTorchbearer.json
index b1b9c8436d..5a8d5304de 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerFightingStyleTorchbearer.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerFightingStyleTorchbearer.json
@@ -33,7 +33,7 @@
"targetSide": "Enemy",
"durationType": "Minute",
"durationParameter": 1,
- "endOfEffect": "StartOfTurn",
+ "endOfEffect": "EndOfTurn",
"hasSavingThrow": true,
"disableSavingThrowOnAllies": false,
"savingThrowAbility": "Dexterity",
@@ -42,7 +42,7 @@
"rollSaveOnlyIfRelevantForms": false,
"hasShoveRoll": false,
"createdByCharacter": true,
- "difficultyClassComputation": "FixedValue",
+ "difficultyClassComputation": "AbilityScoreAndProficiency",
"savingThrowDifficultyAbility": "Dexterity",
"fixedSavingThrowDifficultyClass": 8,
"savingThrowAffinitiesBySense": [],
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerFizbanPlatinumShield.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerFizbanPlatinumShield.json
index 2f9468afdd..7c1d0ebc8d 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerFizbanPlatinumShield.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerFizbanPlatinumShield.json
@@ -13,11 +13,11 @@
"emissiveBorder": "None",
"emissiveParameter": 1,
"requiresTargetProximity": false,
- "targetProximityDistance": 6,
+ "targetProximityDistance": 30,
"targetExcludeCaster": false,
"canBePlacedOnCharacter": true,
"affectOnlyGround": false,
- "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringMethod": "AllCharacterAndGadgets",
"targetFilteringTag": "No",
"requiresVisibilityForPosition": true,
"inviteOptionalAlly": false,
@@ -35,7 +35,7 @@
"durationParameter": 1,
"endOfEffect": "EndOfTurn",
"hasSavingThrow": false,
- "disableSavingThrowOnAllies": false,
+ "disableSavingThrowOnAllies": true,
"savingThrowAbility": "Dexterity",
"ignoreCover": false,
"grantedConditionOnSave": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerGravityFissure.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerGravityFissure.json
new file mode 100644
index 0000000000..72ca49bc03
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerGravityFissure.json
@@ -0,0 +1,388 @@
+{
+ "$type": "FeatureDefinitionPower, Assembly-CSharp",
+ "effectDescription": {
+ "$type": "EffectDescription, Assembly-CSharp",
+ "rangeType": "Distance",
+ "rangeParameter": 6,
+ "halfDamageOnAMiss": false,
+ "hitAffinitiesByTargetTag": [],
+ "targetType": "IndividualsUnique",
+ "itemSelectionType": "None",
+ "targetParameter": 1,
+ "targetParameter2": 2,
+ "emissiveBorder": "None",
+ "emissiveParameter": 1,
+ "requiresTargetProximity": false,
+ "targetProximityDistance": 6,
+ "targetExcludeCaster": false,
+ "canBePlacedOnCharacter": true,
+ "affectOnlyGround": false,
+ "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringTag": "No",
+ "requiresVisibilityForPosition": true,
+ "inviteOptionalAlly": false,
+ "slotTypes": [],
+ "recurrentEffect": "No",
+ "retargetAfterDeath": false,
+ "retargetActionType": "Bonus",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
+ "trapRangeType": "Triggerer",
+ "targetConditionName": "",
+ "targetConditionAsset": null,
+ "targetSide": "All",
+ "durationType": "Instantaneous",
+ "durationParameter": 1,
+ "endOfEffect": "EndOfTurn",
+ "hasSavingThrow": true,
+ "disableSavingThrowOnAllies": false,
+ "savingThrowAbility": "Constitution",
+ "ignoreCover": true,
+ "grantedConditionOnSave": null,
+ "rollSaveOnlyIfRelevantForms": false,
+ "hasShoveRoll": false,
+ "createdByCharacter": true,
+ "difficultyClassComputation": "SpellCastingFeature",
+ "savingThrowDifficultyAbility": "Wisdom",
+ "fixedSavingThrowDifficultyClass": 10,
+ "savingThrowAffinitiesBySense": [],
+ "savingThrowAffinitiesByFamily": [],
+ "damageAffinitiesByFamily": [],
+ "advantageForEnemies": false,
+ "canBeDispersed": false,
+ "hasVelocity": false,
+ "velocityCellsPerRound": 2,
+ "velocityType": "AwayFromSourceOriginalPosition",
+ "restrictedCreatureFamilies": [],
+ "immuneCreatureFamilies": [],
+ "restrictedCharacterSizes": [],
+ "hasLimitedEffectPool": false,
+ "effectPoolAmount": 60,
+ "effectApplication": "All",
+ "effectFormFilters": [],
+ "effectForms": [
+ {
+ "$type": "EffectForm, Assembly-CSharp",
+ "formType": "Damage",
+ "addBonusMode": "None",
+ "applyLevel": "No",
+ "levelType": "ClassLevel",
+ "levelMultiplier": 1,
+ "diceByLevelTable": [],
+ "createdByCharacter": true,
+ "createdByCondition": false,
+ "hasSavingThrow": true,
+ "savingThrowAffinity": "Negates",
+ "dcModifier": 0,
+ "canSaveToCancel": false,
+ "saveOccurence": "EndOfTurn",
+ "damageForm": {
+ "$type": "DamageForm, Assembly-CSharp",
+ "versatile": false,
+ "diceNumber": 8,
+ "dieType": "D8",
+ "overrideWithBardicInspirationDie": false,
+ "versatileDieType": "D1",
+ "bonusDamage": 0,
+ "damageType": "DamageForce",
+ "ancestryType": "Sorcerer",
+ "healFromInflictedDamage": "Never",
+ "hitPointsFloor": 0,
+ "forceKillOnZeroHp": false,
+ "specialDeathCondition": null,
+ "ignoreFlyingCharacters": false,
+ "ignoreCriticalDoubleDice": false
+ },
+ "hasFilterId": false,
+ "filterId": 0
+ },
+ {
+ "$type": "EffectForm, Assembly-CSharp",
+ "formType": "Motion",
+ "addBonusMode": "None",
+ "applyLevel": "No",
+ "levelType": "ClassLevel",
+ "levelMultiplier": 1,
+ "diceByLevelTable": [],
+ "createdByCharacter": true,
+ "createdByCondition": false,
+ "hasSavingThrow": true,
+ "savingThrowAffinity": "Negates",
+ "dcModifier": 0,
+ "canSaveToCancel": false,
+ "saveOccurence": "EndOfTurn",
+ "motionForm": {
+ "$type": "MotionForm, Assembly-CSharp",
+ "type": "DragToOrigin",
+ "distance": 2,
+ "forceTurnTowardsSourceCharacterAfterPush": false,
+ "forceSourceCharacterTurnTowardsTargetAfterPush": false
+ },
+ "hasFilterId": false,
+ "filterId": 0
+ }
+ ],
+ "specialFormsDescription": "",
+ "effectAdvancement": {
+ "$type": "EffectAdvancement, Assembly-CSharp",
+ "effectIncrementMethod": "PerAdditionalSlotLevel",
+ "incrementMultiplier": 1,
+ "additionalTargetsPerIncrement": 0,
+ "additionalSubtargetsPerIncrement": 0,
+ "additionalDicePerIncrement": 1,
+ "additionalSpellLevelPerIncrement": 0,
+ "additionalSummonsPerIncrement": 0,
+ "additionalHPPerIncrement": 0,
+ "additionalTempHPPerIncrement": 0,
+ "additionalTargetCellsPerIncrement": 0,
+ "additionalItemBonus": 0,
+ "additionalWeaponDie": 0,
+ "alteredDuration": "None"
+ },
+ "speedType": "Instant",
+ "speedParameter": 10.0,
+ "offsetImpactTimeBasedOnDistance": false,
+ "offsetImpactTimeBasedOnDistanceFactor": 0.1,
+ "offsetImpactTimePerTarget": 0.0,
+ "effectParticleParameters": {
+ "$type": "EffectParticleParameters, Assembly-CSharp",
+ "casterParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "81560ac3813217d4d9fd281d5e73c234",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterSelfParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterQuickSpellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "targetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectSubTargetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "zoneParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "beforeImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "impactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "570add77272f276419384de82fce1d15",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticlePerIndex": "",
+ "activeEffectSurfaceParticlePerIndexCount": 0,
+ "emissiveBorderCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "forceApplyZoneParticle": false,
+ "applyEmissionColorOnWeapons": false,
+ "emissionColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "emissionColorFadeInDuration": 0.0,
+ "emissionColorFadeOutDuration": 0.0
+ },
+ "effectAIParameters": {
+ "$type": "EffectAIParameters, Assembly-CSharp",
+ "aoeScoreMultiplier": 1.0,
+ "cooldownForCaster": 0,
+ "cooldownForBattle": 0,
+ "sortingScoreMultiplier": 1.0,
+ "dynamicCooldown": false
+ },
+ "animationMagicEffect": "Animation0",
+ "lightCounterDispellsEffect": false,
+ "hideSavingThrowAnimation": false
+ },
+ "delegatedToAction": false,
+ "surrogateToSpell": null,
+ "triggeredBySpecialMove": false,
+ "activationTime": "NoCost",
+ "autoActivationRequiredTargetSenseType": "None",
+ "autoActivationRequiredTargetCreatureTag": "",
+ "autoActivationPowerTag": "",
+ "triggeringPower": null,
+ "copyTargetingFromTriggeringPower": false,
+ "reactionContext": "None",
+ "damageTypes": [],
+ "reactionName": "",
+ "reactionActingCharacterParamIdx": 0,
+ "reactionAttackerParamIdx": -1,
+ "hasCastingFailure": false,
+ "castingSuccessComputation": "CasterLevel",
+ "canUseInDialog": false,
+ "disableIfConditionIsOwned": null,
+ "disableIfTargetConditionIsOwned": null,
+ "rechargeRate": "AtWill",
+ "costPerUse": 1,
+ "spellcastingFeature": null,
+ "usesDetermination": "Fixed",
+ "abilityScoreDetermination": "Explicit",
+ "usesAbilityScoreName": "Charisma",
+ "fixedUsesPerRecharge": 1,
+ "abilityScore": "Intelligence",
+ "attackHitComputation": "AbilityScore",
+ "fixedAttackHit": 0,
+ "abilityScoreBonusToAttack": false,
+ "proficiencyBonusToAttack": false,
+ "uniqueInstance": false,
+ "showCasting": false,
+ "shortTitleOverride": "",
+ "overriddenPower": null,
+ "includeBaseDescription": false,
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Spell/&GravityFissureTitle",
+ "description": "Spell/&GravityFissureDescription",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "543799d2-0a37-5662-8cb5-9ac355c09595",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "684f8db8-663a-5332-bc46-1bbe219ffecb",
+ "contentPack": 9999,
+ "name": "PowerGravityFissure"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerGrayDwarfInvisibility.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerGrayDwarfInvisibility.json
index 1d3f3bd17d..787fe9b505 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerGrayDwarfInvisibility.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerGrayDwarfInvisibility.json
@@ -33,7 +33,7 @@
"targetSide": "Ally",
"durationType": "Minute",
"durationParameter": 1,
- "endOfEffect": "StartOfTurn",
+ "endOfEffect": "EndOfTurn",
"hasSavingThrow": false,
"disableSavingThrowOnAllies": false,
"savingThrowAbility": "Dexterity",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerHolyWeapon.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerHolyWeapon.json
new file mode 100644
index 0000000000..5874e1524f
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerHolyWeapon.json
@@ -0,0 +1,390 @@
+{
+ "$type": "FeatureDefinitionPower, Assembly-CSharp",
+ "effectDescription": {
+ "$type": "EffectDescription, Assembly-CSharp",
+ "rangeType": "Distance",
+ "rangeParameter": 24,
+ "halfDamageOnAMiss": false,
+ "hitAffinitiesByTargetTag": [],
+ "targetType": "IndividualsUnique",
+ "itemSelectionType": "None",
+ "targetParameter": 1,
+ "targetParameter2": 2,
+ "emissiveBorder": "None",
+ "emissiveParameter": 1,
+ "requiresTargetProximity": false,
+ "targetProximityDistance": 6,
+ "targetExcludeCaster": false,
+ "canBePlacedOnCharacter": true,
+ "affectOnlyGround": false,
+ "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringTag": "No",
+ "requiresVisibilityForPosition": true,
+ "inviteOptionalAlly": false,
+ "slotTypes": [],
+ "recurrentEffect": "No",
+ "retargetAfterDeath": false,
+ "retargetActionType": "Bonus",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
+ "trapRangeType": "Triggerer",
+ "targetConditionName": "",
+ "targetConditionAsset": null,
+ "targetSide": "All",
+ "durationType": "Minute",
+ "durationParameter": 1,
+ "endOfEffect": "EndOfTurn",
+ "hasSavingThrow": true,
+ "disableSavingThrowOnAllies": false,
+ "savingThrowAbility": "Constitution",
+ "ignoreCover": true,
+ "grantedConditionOnSave": null,
+ "rollSaveOnlyIfRelevantForms": false,
+ "hasShoveRoll": false,
+ "createdByCharacter": true,
+ "difficultyClassComputation": "SpellCastingFeature",
+ "savingThrowDifficultyAbility": "Wisdom",
+ "fixedSavingThrowDifficultyClass": 10,
+ "savingThrowAffinitiesBySense": [],
+ "savingThrowAffinitiesByFamily": [],
+ "damageAffinitiesByFamily": [],
+ "advantageForEnemies": false,
+ "canBeDispersed": false,
+ "hasVelocity": false,
+ "velocityCellsPerRound": 2,
+ "velocityType": "AwayFromSourceOriginalPosition",
+ "restrictedCreatureFamilies": [],
+ "immuneCreatureFamilies": [],
+ "restrictedCharacterSizes": [],
+ "hasLimitedEffectPool": false,
+ "effectPoolAmount": 60,
+ "effectApplication": "All",
+ "effectFormFilters": [],
+ "effectForms": [
+ {
+ "$type": "EffectForm, Assembly-CSharp",
+ "formType": "Damage",
+ "addBonusMode": "None",
+ "applyLevel": "No",
+ "levelType": "ClassLevel",
+ "levelMultiplier": 1,
+ "diceByLevelTable": [],
+ "createdByCharacter": true,
+ "createdByCondition": false,
+ "hasSavingThrow": true,
+ "savingThrowAffinity": "HalfDamage",
+ "dcModifier": 0,
+ "canSaveToCancel": false,
+ "saveOccurence": "EndOfTurn",
+ "damageForm": {
+ "$type": "DamageForm, Assembly-CSharp",
+ "versatile": false,
+ "diceNumber": 4,
+ "dieType": "D8",
+ "overrideWithBardicInspirationDie": false,
+ "versatileDieType": "D1",
+ "bonusDamage": 0,
+ "damageType": "DamageRadiant",
+ "ancestryType": "Sorcerer",
+ "healFromInflictedDamage": "Never",
+ "hitPointsFloor": 0,
+ "forceKillOnZeroHp": false,
+ "specialDeathCondition": null,
+ "ignoreFlyingCharacters": false,
+ "ignoreCriticalDoubleDice": false
+ },
+ "hasFilterId": false,
+ "filterId": 0
+ },
+ {
+ "$type": "EffectForm, Assembly-CSharp",
+ "formType": "Condition",
+ "addBonusMode": "None",
+ "applyLevel": "No",
+ "levelType": "ClassLevel",
+ "levelMultiplier": 1,
+ "diceByLevelTable": [],
+ "createdByCharacter": true,
+ "createdByCondition": false,
+ "hasSavingThrow": true,
+ "savingThrowAffinity": "Negates",
+ "dcModifier": 0,
+ "canSaveToCancel": true,
+ "saveOccurence": "EndOfTurn",
+ "conditionForm": {
+ "$type": "ConditionForm, Assembly-CSharp",
+ "conditionDefinitionName": "ConditionBlinded",
+ "conditionDefinition": "Definition:ConditionBlinded:0a89e8d8ad8f21649b744191035357b3",
+ "operation": "Add",
+ "conditionsList": [],
+ "applyToSelf": false,
+ "forceOnSelf": false
+ },
+ "hasFilterId": false,
+ "filterId": 0
+ }
+ ],
+ "specialFormsDescription": "",
+ "effectAdvancement": {
+ "$type": "EffectAdvancement, Assembly-CSharp",
+ "effectIncrementMethod": "None",
+ "incrementMultiplier": 1,
+ "additionalTargetsPerIncrement": 0,
+ "additionalSubtargetsPerIncrement": 0,
+ "additionalDicePerIncrement": 0,
+ "additionalSpellLevelPerIncrement": 0,
+ "additionalSummonsPerIncrement": 0,
+ "additionalHPPerIncrement": 0,
+ "additionalTempHPPerIncrement": 0,
+ "additionalTargetCellsPerIncrement": 0,
+ "additionalItemBonus": 0,
+ "additionalWeaponDie": 0,
+ "alteredDuration": "None"
+ },
+ "speedType": "Instant",
+ "speedParameter": 10.0,
+ "offsetImpactTimeBasedOnDistance": false,
+ "offsetImpactTimeBasedOnDistanceFactor": 0.1,
+ "offsetImpactTimePerTarget": 0.0,
+ "effectParticleParameters": {
+ "$type": "EffectParticleParameters, Assembly-CSharp",
+ "casterParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "8b9fa0fcdb99d2347a36d25a972de9f5",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterSelfParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterQuickSpellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "targetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectSubTargetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "zoneParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "6937e1207989e6644ad591240a0bb88c",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "beforeImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "impactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "5cdd6944009a9f14eae5a1f5e9bc0a82",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticlePerIndex": "",
+ "activeEffectSurfaceParticlePerIndexCount": 0,
+ "emissiveBorderCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "a1709422dd78d964e9dbef20ad79c3d3",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "2fb59c86519dd104a8b75863927aea9a",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "48d43d702483f604685b7401f56dc4d7",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "forceApplyZoneParticle": false,
+ "applyEmissionColorOnWeapons": false,
+ "emissionColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "emissionColorFadeInDuration": 0.0,
+ "emissionColorFadeOutDuration": 0.0
+ },
+ "effectAIParameters": {
+ "$type": "EffectAIParameters, Assembly-CSharp",
+ "aoeScoreMultiplier": 1.0,
+ "cooldownForCaster": 0,
+ "cooldownForBattle": 0,
+ "sortingScoreMultiplier": 1.0,
+ "dynamicCooldown": false
+ },
+ "animationMagicEffect": "Animation0",
+ "lightCounterDispellsEffect": false,
+ "hideSavingThrowAnimation": false
+ },
+ "delegatedToAction": false,
+ "surrogateToSpell": null,
+ "triggeredBySpecialMove": false,
+ "activationTime": "BonusAction",
+ "autoActivationRequiredTargetSenseType": "None",
+ "autoActivationRequiredTargetCreatureTag": "",
+ "autoActivationPowerTag": "",
+ "triggeringPower": null,
+ "copyTargetingFromTriggeringPower": false,
+ "reactionContext": "None",
+ "damageTypes": [],
+ "reactionName": "",
+ "reactionActingCharacterParamIdx": 0,
+ "reactionAttackerParamIdx": -1,
+ "hasCastingFailure": false,
+ "castingSuccessComputation": "CasterLevel",
+ "canUseInDialog": false,
+ "disableIfConditionIsOwned": null,
+ "disableIfTargetConditionIsOwned": null,
+ "rechargeRate": "AtWill",
+ "costPerUse": 1,
+ "spellcastingFeature": null,
+ "usesDetermination": "Fixed",
+ "abilityScoreDetermination": "Explicit",
+ "usesAbilityScoreName": "Charisma",
+ "fixedUsesPerRecharge": 1,
+ "abilityScore": "Intelligence",
+ "attackHitComputation": "AbilityScore",
+ "fixedAttackHit": 0,
+ "abilityScoreBonusToAttack": false,
+ "proficiencyBonusToAttack": false,
+ "uniqueInstance": false,
+ "showCasting": true,
+ "shortTitleOverride": "",
+ "overriddenPower": null,
+ "includeBaseDescription": false,
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Feature/&PowerHolyWeaponTitle",
+ "description": "Feature/&PowerHolyWeaponDescription",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "fce89a39-76c3-5d2a-8b88-33e80cc88a44",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "998ab674-743b-5200-b721-4e4a915a38d8",
+ "contentPack": 9999,
+ "name": "PowerHolyWeapon"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerIceBlade.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerIceBlade.json
index 7b88237449..1ae4b20894 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerIceBlade.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerIceBlade.json
@@ -42,7 +42,7 @@
"rollSaveOnlyIfRelevantForms": false,
"hasShoveRoll": false,
"createdByCharacter": true,
- "difficultyClassComputation": "FixedValue",
+ "difficultyClassComputation": "SpellCastingFeature",
"savingThrowDifficultyAbility": "Wisdom",
"fixedSavingThrowDifficultyClass": 10,
"savingThrowAffinitiesBySense": [],
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerInnovationArtilleristEldritchCannonDetonate.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerInnovationArtilleristEldritchCannonDetonate.json
index 018547265e..36ed902e99 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerInnovationArtilleristEldritchCannonDetonate.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerInnovationArtilleristEldritchCannonDetonate.json
@@ -25,8 +25,8 @@
"recurrentEffect": "No",
"retargetAfterDeath": false,
"retargetActionType": "Bonus",
- "poolFilterDiceNumber": 0,
- "poolFilterDieType": "D1",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
"trapRangeType": "Triggerer",
"targetConditionName": "",
"targetConditionAsset": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerInnovationArtilleristEldritchCannonDismiss.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerInnovationArtilleristEldritchCannonDismiss.json
index fc82de93a8..1678cb8556 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerInnovationArtilleristEldritchCannonDismiss.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerInnovationArtilleristEldritchCannonDismiss.json
@@ -25,8 +25,8 @@
"recurrentEffect": "No",
"retargetAfterDeath": false,
"retargetActionType": "Bonus",
- "poolFilterDiceNumber": 0,
- "poolFilterDieType": "D1",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
"trapRangeType": "Triggerer",
"targetConditionName": "",
"targetConditionAsset": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerInnovationWeaponSummonAdvancedSteelDefender.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerInnovationWeaponSummonAdvancedSteelDefender.json
index c59aa641b5..6163132ef0 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerInnovationWeaponSummonAdvancedSteelDefender.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerInnovationWeaponSummonAdvancedSteelDefender.json
@@ -85,7 +85,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerInnovationWeaponSummonSteelDefender.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerInnovationWeaponSummonSteelDefender.json
index e0921ae3c0..40ec92e3fb 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerInnovationWeaponSummonSteelDefender.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerInnovationWeaponSummonSteelDefender.json
@@ -85,7 +85,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerMalakhAngelicRadiance.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerMalakhAngelicRadiance.json
index 30de1e3ef7..d7d419c873 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerMalakhAngelicRadiance.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerMalakhAngelicRadiance.json
@@ -13,11 +13,11 @@
"emissiveBorder": "None",
"emissiveParameter": 1,
"requiresTargetProximity": false,
- "targetProximityDistance": 6,
+ "targetProximityDistance": 30,
"targetExcludeCaster": false,
"canBePlacedOnCharacter": true,
"affectOnlyGround": false,
- "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringMethod": "AllCharacterAndGadgets",
"targetFilteringTag": "No",
"requiresVisibilityForPosition": true,
"inviteOptionalAlly": false,
@@ -35,7 +35,7 @@
"durationParameter": 1,
"endOfEffect": "EndOfTurn",
"hasSavingThrow": false,
- "disableSavingThrowOnAllies": false,
+ "disableSavingThrowOnAllies": true,
"savingThrowAbility": "Dexterity",
"ignoreCover": false,
"grantedConditionOnSave": null,
@@ -110,14 +110,14 @@
"dimAdditionalRange": 2,
"color": {
"$type": "UnityEngine.Color, UnityEngine.CoreModule",
- "r": 1.0,
- "g": 0.9778601,
- "b": 0.78039217,
+ "r": 0.8396226,
+ "g": 0.7766465,
+ "b": 0.5505073,
"a": 1.0
},
"graphicsPrefabReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "3e4cdebecc6e0db469720619529e3dc2",
+ "m_AssetGUID": "fc7cb53da57a8fb40a278d62a885ce58",
"m_SubObjectName": "",
"m_SubObjectType": ""
},
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerOathOfAncientsNaturesWrath.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerOathOfAncientsNaturesWrath.json
index e87d80ad4d..5602f0b451 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerOathOfAncientsNaturesWrath.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerOathOfAncientsNaturesWrath.json
@@ -31,8 +31,8 @@
"targetConditionName": "",
"targetConditionAsset": null,
"targetSide": "Enemy",
- "durationType": "Round",
- "durationParameter": 10,
+ "durationType": "Minute",
+ "durationParameter": 1,
"endOfEffect": "EndOfTurn",
"hasSavingThrow": true,
"disableSavingThrowOnAllies": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerOathOfAncientsTurnFaithless.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerOathOfAncientsTurnFaithless.json
index 9becc1ce1b..f88fb173af 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerOathOfAncientsTurnFaithless.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerOathOfAncientsTurnFaithless.json
@@ -25,8 +25,8 @@
"recurrentEffect": "No",
"retargetAfterDeath": false,
"retargetActionType": "Bonus",
- "poolFilterDiceNumber": 0,
- "poolFilterDieType": "D1",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
"trapRangeType": "Triggerer",
"targetConditionName": "",
"targetConditionAsset": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerOathOfDevotionHolyNimbus.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerOathOfDevotionHolyNimbus.json
index ad535599c1..d5a2899dad 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerOathOfDevotionHolyNimbus.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerOathOfDevotionHolyNimbus.json
@@ -13,11 +13,11 @@
"emissiveBorder": "None",
"emissiveParameter": 1,
"requiresTargetProximity": false,
- "targetProximityDistance": 6,
+ "targetProximityDistance": 30,
"targetExcludeCaster": true,
"canBePlacedOnCharacter": true,
"affectOnlyGround": false,
- "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringMethod": "AllCharacterAndGadgets",
"targetFilteringTag": "No",
"requiresVisibilityForPosition": true,
"inviteOptionalAlly": false,
@@ -35,7 +35,7 @@
"durationParameter": 1,
"endOfEffect": "EndOfTurn",
"hasSavingThrow": false,
- "disableSavingThrowOnAllies": false,
+ "disableSavingThrowOnAllies": true,
"savingThrowAbility": "Dexterity",
"ignoreCover": false,
"grantedConditionOnSave": null,
@@ -145,14 +145,14 @@
"dimAdditionalRange": 6,
"color": {
"$type": "UnityEngine.Color, UnityEngine.CoreModule",
- "r": 1.0,
- "g": 0.9778601,
- "b": 0.78039217,
+ "r": 0.8396226,
+ "g": 0.7766465,
+ "b": 0.5505073,
"a": 1.0
},
"graphicsPrefabReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "3e4cdebecc6e0db469720619529e3dc2",
+ "m_AssetGUID": "fc7cb53da57a8fb40a278d62a885ce58",
"m_SubObjectName": "",
"m_SubObjectType": ""
},
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerOathOfThunderBifrostDamage.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerOathOfThunderBifrostDamage.json
index 3000c04aff..44a62c5584 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerOathOfThunderBifrostDamage.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerOathOfThunderBifrostDamage.json
@@ -2,8 +2,8 @@
"$type": "FeatureDefinitionPower, Assembly-CSharp",
"effectDescription": {
"$type": "EffectDescription, Assembly-CSharp",
- "rangeType": "Touch",
- "rangeParameter": 0,
+ "rangeType": "Distance",
+ "rangeParameter": 6,
"halfDamageOnAMiss": false,
"hitAffinitiesByTargetTag": [],
"targetType": "IndividualsUnique",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerPathOfTheLightIlluminatingStrike.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerPathOfTheLightIlluminatingStrike.json
index 10dbb70a78..9fe6f695c5 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerPathOfTheLightIlluminatingStrike.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerPathOfTheLightIlluminatingStrike.json
@@ -33,7 +33,7 @@
"targetSide": "Enemy",
"durationType": "Minute",
"durationParameter": 1,
- "endOfEffect": "StartOfTurn",
+ "endOfEffect": "EndOfTurn",
"hasSavingThrow": false,
"disableSavingThrowOnAllies": false,
"savingThrowAbility": "Dexterity",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerPathOfTheYeomanMightyShot.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerPathOfTheYeomanMightyShot.json
index 87bce04a1c..c928895b0e 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerPathOfTheYeomanMightyShot.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerPathOfTheYeomanMightyShot.json
@@ -2,8 +2,8 @@
"$type": "FeatureDefinitionPower, Assembly-CSharp",
"effectDescription": {
"$type": "EffectDescription, Assembly-CSharp",
- "rangeType": "Touch",
- "rangeParameter": 0,
+ "rangeType": "Distance",
+ "rangeParameter": 6,
"halfDamageOnAMiss": false,
"hitAffinitiesByTargetTag": [],
"targetType": "IndividualsUnique",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerRangerHellWalkerFirebolt.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerRangerHellWalkerFirebolt.json
index 466802c6d1..5cc71ec108 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerRangerHellWalkerFirebolt.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerRangerHellWalkerFirebolt.json
@@ -25,8 +25,8 @@
"recurrentEffect": "No",
"retargetAfterDeath": false,
"retargetActionType": "Bonus",
- "poolFilterDiceNumber": 0,
- "poolFilterDieType": "D1",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
"trapRangeType": "Triggerer",
"targetConditionName": "",
"targetConditionAsset": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerRangerLightBearerBlessedGlow.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerRangerLightBearerBlessedGlow.json
index 61506fc833..415ab69afa 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerRangerLightBearerBlessedGlow.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerRangerLightBearerBlessedGlow.json
@@ -126,7 +126,7 @@
"$type": "EffectParticleParameters, Assembly-CSharp",
"casterParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "81560ac3813217d4d9fd281d5e73c234",
+ "m_AssetGUID": "fe6741763c3d4aa409a90a9c492a12ef",
"m_SubObjectName": "",
"m_SubObjectType": ""
},
@@ -150,7 +150,7 @@
},
"effectParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "",
+ "m_AssetGUID": "81aed95812430d647938852c84bc531f",
"m_SubObjectName": "",
"m_SubObjectType": ""
},
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerRavenScionHeartSeekingShot.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerRavenScionHeartSeekingShot.json
index 1781c6de82..04c737186e 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerRavenScionHeartSeekingShot.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerRavenScionHeartSeekingShot.json
@@ -33,7 +33,7 @@
"targetSide": "Ally",
"durationType": "Minute",
"durationParameter": 1,
- "endOfEffect": "StartOfTurn",
+ "endOfEffect": "EndOfTurn",
"hasSavingThrow": false,
"disableSavingThrowOnAllies": false,
"savingThrowAbility": "Dexterity",
@@ -256,8 +256,8 @@
"conditionParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
"m_AssetGUID": "",
- "m_SubObjectName": "",
- "m_SubObjectType": ""
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
},
"conditionEndParticleReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerSorcerousFieldManipulatorForcefulStepApply.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerSorcerousFieldManipulatorForcefulStepApply.json
index 4d0e521cbb..bef59a3fc5 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerSorcerousFieldManipulatorForcefulStepApply.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerSorcerousFieldManipulatorForcefulStepApply.json
@@ -2,8 +2,8 @@
"$type": "FeatureDefinitionPower, Assembly-CSharp",
"effectDescription": {
"$type": "EffectDescription, Assembly-CSharp",
- "rangeType": "Touch",
- "rangeParameter": 0,
+ "rangeType": "Distance",
+ "rangeParameter": 6,
"halfDamageOnAMiss": false,
"hitAffinitiesByTargetTag": [],
"targetType": "IndividualsUnique",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerSoulBladeHex.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerSoulBladeHex.json
index b21eb15d0e..f76f4216f5 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerSoulBladeHex.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerSoulBladeHex.json
@@ -25,8 +25,8 @@
"recurrentEffect": "No",
"retargetAfterDeath": false,
"retargetActionType": "Bonus",
- "poolFilterDiceNumber": 0,
- "poolFilterDieType": "D1",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
"trapRangeType": "Triggerer",
"targetConditionName": "",
"targetConditionAsset": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerSoulBladeMasterHex.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerSoulBladeMasterHex.json
index 7cf475014f..824df54536 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerSoulBladeMasterHex.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerSoulBladeMasterHex.json
@@ -25,8 +25,8 @@
"recurrentEffect": "No",
"retargetAfterDeath": true,
"retargetActionType": "Bonus",
- "poolFilterDiceNumber": 0,
- "poolFilterDieType": "D1",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
"trapRangeType": "Triggerer",
"targetConditionName": "",
"targetConditionAsset": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerThunderousSmiteThunderousSmite.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerThunderousSmiteThunderousSmite.json
index b1e4837971..2de700eeb3 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerThunderousSmiteThunderousSmite.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerThunderousSmiteThunderousSmite.json
@@ -2,8 +2,8 @@
"$type": "FeatureDefinitionPower, Assembly-CSharp",
"effectDescription": {
"$type": "EffectDescription, Assembly-CSharp",
- "rangeType": "Touch",
- "rangeParameter": 0,
+ "rangeType": "Distance",
+ "rangeParameter": 6,
"halfDamageOnAMiss": false,
"hitAffinitiesByTargetTag": [],
"targetType": "IndividualsUnique",
@@ -350,7 +350,7 @@
"delegatedToAction": false,
"surrogateToSpell": null,
"triggeredBySpecialMove": false,
- "activationTime": "OnAttackHitAuto",
+ "activationTime": "OnAttackHitMeleeAuto",
"autoActivationRequiredTargetSenseType": "None",
"autoActivationRequiredTargetCreatureTag": "",
"autoActivationPowerTag": "",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerWayOfTheDiscordanceDiscordance.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerWayOfTheDiscordanceDiscordance.json
index fac29bff24..9c30227ed7 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerWayOfTheDiscordanceDiscordance.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerWayOfTheDiscordanceDiscordance.json
@@ -2,8 +2,8 @@
"$type": "FeatureDefinitionPower, Assembly-CSharp",
"effectDescription": {
"$type": "EffectDescription, Assembly-CSharp",
- "rangeType": "Touch",
- "rangeParameter": 0,
+ "rangeType": "Distance",
+ "rangeParameter": 6,
"halfDamageOnAMiss": false,
"hitAffinitiesByTargetTag": [],
"targetType": "IndividualsUnique",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerWayOfTheDiscordanceTurmoil.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerWayOfTheDiscordanceTurmoil.json
index 6e0478b552..1d902d1397 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerWayOfTheDiscordanceTurmoil.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerWayOfTheDiscordanceTurmoil.json
@@ -2,8 +2,8 @@
"$type": "FeatureDefinitionPower, Assembly-CSharp",
"effectDescription": {
"$type": "EffectDescription, Assembly-CSharp",
- "rangeType": "Touch",
- "rangeParameter": 0,
+ "rangeType": "Distance",
+ "rangeParameter": 6,
"halfDamageOnAMiss": false,
"hitAffinitiesByTargetTag": [],
"targetType": "IndividualsUnique",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerWayOfTheStormSoulEyeOfTheStormLeap.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerWayOfTheStormSoulEyeOfTheStormLeap.json
index 17d6708675..1ba1e9e120 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerWayOfTheStormSoulEyeOfTheStormLeap.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPower/PowerWayOfTheStormSoulEyeOfTheStormLeap.json
@@ -3,7 +3,7 @@
"effectDescription": {
"$type": "EffectDescription, Assembly-CSharp",
"rangeType": "Distance",
- "rangeParameter": 0,
+ "rangeParameter": 6,
"halfDamageOnAMiss": false,
"hitAffinitiesByTargetTag": [],
"targetType": "IndividualsUnique",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerCreateSpellStoringWandOfCommandSpell.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerCreateSpellStoringWandOfCommandSpell.json
new file mode 100644
index 0000000000..800ed4294f
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerCreateSpellStoringWandOfCommandSpell.json
@@ -0,0 +1,358 @@
+{
+ "$type": "FeatureDefinitionPowerSharedPool, SolastaUnfinishedBusiness",
+ "effectDescription": {
+ "$type": "EffectDescription, Assembly-CSharp",
+ "rangeType": "Self",
+ "rangeParameter": 0,
+ "halfDamageOnAMiss": false,
+ "hitAffinitiesByTargetTag": [],
+ "targetType": "Self",
+ "itemSelectionType": "None",
+ "targetParameter": 1,
+ "targetParameter2": 2,
+ "emissiveBorder": "None",
+ "emissiveParameter": 1,
+ "requiresTargetProximity": false,
+ "targetProximityDistance": 6,
+ "targetExcludeCaster": false,
+ "canBePlacedOnCharacter": true,
+ "affectOnlyGround": false,
+ "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringTag": "No",
+ "requiresVisibilityForPosition": true,
+ "inviteOptionalAlly": false,
+ "slotTypes": [],
+ "recurrentEffect": "No",
+ "retargetAfterDeath": false,
+ "retargetActionType": "Bonus",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
+ "trapRangeType": "Triggerer",
+ "targetConditionName": "",
+ "targetConditionAsset": null,
+ "targetSide": "All",
+ "durationType": "Permanent",
+ "durationParameter": 0,
+ "endOfEffect": "EndOfTurn",
+ "hasSavingThrow": false,
+ "disableSavingThrowOnAllies": false,
+ "savingThrowAbility": "Dexterity",
+ "ignoreCover": false,
+ "grantedConditionOnSave": null,
+ "rollSaveOnlyIfRelevantForms": false,
+ "hasShoveRoll": false,
+ "createdByCharacter": true,
+ "difficultyClassComputation": "SpellCastingFeature",
+ "savingThrowDifficultyAbility": "Wisdom",
+ "fixedSavingThrowDifficultyClass": 15,
+ "savingThrowAffinitiesBySense": [],
+ "savingThrowAffinitiesByFamily": [],
+ "damageAffinitiesByFamily": [],
+ "advantageForEnemies": false,
+ "canBeDispersed": false,
+ "hasVelocity": false,
+ "velocityCellsPerRound": 2,
+ "velocityType": "AwayFromSourceOriginalPosition",
+ "restrictedCreatureFamilies": [],
+ "immuneCreatureFamilies": [],
+ "restrictedCharacterSizes": [],
+ "hasLimitedEffectPool": false,
+ "effectPoolAmount": 60,
+ "effectApplication": "All",
+ "effectFormFilters": [],
+ "effectForms": [
+ {
+ "$type": "EffectForm, Assembly-CSharp",
+ "formType": "Summon",
+ "addBonusMode": "None",
+ "applyLevel": "No",
+ "levelType": "ClassLevel",
+ "levelMultiplier": 1,
+ "diceByLevelTable": [],
+ "createdByCharacter": true,
+ "createdByCondition": false,
+ "hasSavingThrow": true,
+ "savingThrowAffinity": "None",
+ "dcModifier": 0,
+ "canSaveToCancel": false,
+ "saveOccurence": "EndOfTurn",
+ "summonForm": {
+ "$type": "SummonForm, Assembly-CSharp",
+ "summonType": "InventoryItem",
+ "itemDefinition": "Definition:SpellStoringWandOfCommandSpell:252920d8-129e-5ae7-a5fc-6bdccebf1d4f",
+ "trackItem": true,
+ "monsterDefinitionName": "",
+ "number": 1,
+ "conditionDefinition": null,
+ "persistOnConcentrationLoss": true,
+ "decisionPackage": null,
+ "effectProxyDefinitionName": null
+ },
+ "hasFilterId": false,
+ "filterId": 0
+ }
+ ],
+ "specialFormsDescription": "",
+ "effectAdvancement": {
+ "$type": "EffectAdvancement, Assembly-CSharp",
+ "effectIncrementMethod": "None",
+ "incrementMultiplier": 1,
+ "additionalTargetsPerIncrement": 0,
+ "additionalSubtargetsPerIncrement": 0,
+ "additionalDicePerIncrement": 0,
+ "additionalSpellLevelPerIncrement": 0,
+ "additionalSummonsPerIncrement": 0,
+ "additionalHPPerIncrement": 0,
+ "additionalTempHPPerIncrement": 0,
+ "additionalTargetCellsPerIncrement": 0,
+ "additionalItemBonus": 0,
+ "additionalWeaponDie": 0,
+ "alteredDuration": "None"
+ },
+ "speedType": "Instant",
+ "speedParameter": 10.0,
+ "offsetImpactTimeBasedOnDistance": false,
+ "offsetImpactTimeBasedOnDistanceFactor": 0.1,
+ "offsetImpactTimePerTarget": 0.0,
+ "effectParticleParameters": {
+ "$type": "EffectParticleParameters, Assembly-CSharp",
+ "casterParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "c61bb30a4b6e80642a36538c6ff1d675",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterSelfParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterQuickSpellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "targetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectSubTargetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "zoneParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "beforeImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "impactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticlePerIndex": "",
+ "activeEffectSurfaceParticlePerIndexCount": 0,
+ "emissiveBorderCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "f4489c0ea1762ec4dbe7fedbbcf0d4a8",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "3b107035e3bdbc6418aedb674221f5e3",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "forceApplyZoneParticle": false,
+ "applyEmissionColorOnWeapons": false,
+ "emissionColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "emissionColorFadeInDuration": 0.0,
+ "emissionColorFadeOutDuration": 0.0
+ },
+ "effectAIParameters": {
+ "$type": "EffectAIParameters, Assembly-CSharp",
+ "aoeScoreMultiplier": 1.0,
+ "cooldownForCaster": 0,
+ "cooldownForBattle": 0,
+ "sortingScoreMultiplier": 1.0,
+ "dynamicCooldown": false
+ },
+ "animationMagicEffect": "Animation1",
+ "lightCounterDispellsEffect": false,
+ "hideSavingThrowAnimation": false
+ },
+ "delegatedToAction": false,
+ "surrogateToSpell": null,
+ "triggeredBySpecialMove": false,
+ "activationTime": "Action",
+ "autoActivationRequiredTargetSenseType": "None",
+ "autoActivationRequiredTargetCreatureTag": "",
+ "autoActivationPowerTag": "",
+ "triggeringPower": null,
+ "copyTargetingFromTriggeringPower": false,
+ "reactionContext": "None",
+ "damageTypes": [],
+ "reactionName": "",
+ "reactionActingCharacterParamIdx": 0,
+ "reactionAttackerParamIdx": -1,
+ "hasCastingFailure": false,
+ "castingSuccessComputation": "CasterLevel",
+ "canUseInDialog": false,
+ "disableIfConditionIsOwned": null,
+ "disableIfTargetConditionIsOwned": null,
+ "rechargeRate": "LongRest",
+ "costPerUse": 1,
+ "spellcastingFeature": null,
+ "usesDetermination": "Fixed",
+ "abilityScoreDetermination": "Explicit",
+ "usesAbilityScoreName": "Charisma",
+ "fixedUsesPerRecharge": 1,
+ "abilityScore": "Intelligence",
+ "attackHitComputation": "AbilityScore",
+ "fixedAttackHit": 0,
+ "abilityScoreBonusToAttack": false,
+ "proficiencyBonusToAttack": false,
+ "uniqueInstance": true,
+ "showCasting": true,
+ "shortTitleOverride": "",
+ "overriddenPower": null,
+ "includeBaseDescription": false,
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Command",
+ "description": "Create a wand that can cast Command (I) spell using your Artificer spell attack modifier and save DC.",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "6edc0b78da56b1e4b94c3d7fb6c96dec",
+ "m_SubObjectName": "Command",
+ "m_SubObjectType": "UnityEngine.Sprite, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "e90dc523-a327-589e-bc84-4a3a73b789d7",
+ "contentPack": 9999,
+ "name": "PowerCreateSpellStoringWandOfCommandSpell"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerCreateSpellStoringWandOfDissonantWhispers.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerCreateSpellStoringWandOfDissonantWhispers.json
new file mode 100644
index 0000000000..545578bcd2
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerCreateSpellStoringWandOfDissonantWhispers.json
@@ -0,0 +1,358 @@
+{
+ "$type": "FeatureDefinitionPowerSharedPool, SolastaUnfinishedBusiness",
+ "effectDescription": {
+ "$type": "EffectDescription, Assembly-CSharp",
+ "rangeType": "Self",
+ "rangeParameter": 0,
+ "halfDamageOnAMiss": false,
+ "hitAffinitiesByTargetTag": [],
+ "targetType": "Self",
+ "itemSelectionType": "None",
+ "targetParameter": 1,
+ "targetParameter2": 2,
+ "emissiveBorder": "None",
+ "emissiveParameter": 1,
+ "requiresTargetProximity": false,
+ "targetProximityDistance": 6,
+ "targetExcludeCaster": false,
+ "canBePlacedOnCharacter": true,
+ "affectOnlyGround": false,
+ "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringTag": "No",
+ "requiresVisibilityForPosition": true,
+ "inviteOptionalAlly": false,
+ "slotTypes": [],
+ "recurrentEffect": "No",
+ "retargetAfterDeath": false,
+ "retargetActionType": "Bonus",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
+ "trapRangeType": "Triggerer",
+ "targetConditionName": "",
+ "targetConditionAsset": null,
+ "targetSide": "All",
+ "durationType": "Permanent",
+ "durationParameter": 0,
+ "endOfEffect": "EndOfTurn",
+ "hasSavingThrow": false,
+ "disableSavingThrowOnAllies": false,
+ "savingThrowAbility": "Dexterity",
+ "ignoreCover": false,
+ "grantedConditionOnSave": null,
+ "rollSaveOnlyIfRelevantForms": false,
+ "hasShoveRoll": false,
+ "createdByCharacter": true,
+ "difficultyClassComputation": "SpellCastingFeature",
+ "savingThrowDifficultyAbility": "Wisdom",
+ "fixedSavingThrowDifficultyClass": 15,
+ "savingThrowAffinitiesBySense": [],
+ "savingThrowAffinitiesByFamily": [],
+ "damageAffinitiesByFamily": [],
+ "advantageForEnemies": false,
+ "canBeDispersed": false,
+ "hasVelocity": false,
+ "velocityCellsPerRound": 2,
+ "velocityType": "AwayFromSourceOriginalPosition",
+ "restrictedCreatureFamilies": [],
+ "immuneCreatureFamilies": [],
+ "restrictedCharacterSizes": [],
+ "hasLimitedEffectPool": false,
+ "effectPoolAmount": 60,
+ "effectApplication": "All",
+ "effectFormFilters": [],
+ "effectForms": [
+ {
+ "$type": "EffectForm, Assembly-CSharp",
+ "formType": "Summon",
+ "addBonusMode": "None",
+ "applyLevel": "No",
+ "levelType": "ClassLevel",
+ "levelMultiplier": 1,
+ "diceByLevelTable": [],
+ "createdByCharacter": true,
+ "createdByCondition": false,
+ "hasSavingThrow": true,
+ "savingThrowAffinity": "None",
+ "dcModifier": 0,
+ "canSaveToCancel": false,
+ "saveOccurence": "EndOfTurn",
+ "summonForm": {
+ "$type": "SummonForm, Assembly-CSharp",
+ "summonType": "InventoryItem",
+ "itemDefinition": "Definition:SpellStoringWandOfDissonantWhispers:2f16c6e7-5a0d-5b07-89e6-b53f433567e8",
+ "trackItem": true,
+ "monsterDefinitionName": "",
+ "number": 1,
+ "conditionDefinition": null,
+ "persistOnConcentrationLoss": true,
+ "decisionPackage": null,
+ "effectProxyDefinitionName": null
+ },
+ "hasFilterId": false,
+ "filterId": 0
+ }
+ ],
+ "specialFormsDescription": "",
+ "effectAdvancement": {
+ "$type": "EffectAdvancement, Assembly-CSharp",
+ "effectIncrementMethod": "None",
+ "incrementMultiplier": 1,
+ "additionalTargetsPerIncrement": 0,
+ "additionalSubtargetsPerIncrement": 0,
+ "additionalDicePerIncrement": 0,
+ "additionalSpellLevelPerIncrement": 0,
+ "additionalSummonsPerIncrement": 0,
+ "additionalHPPerIncrement": 0,
+ "additionalTempHPPerIncrement": 0,
+ "additionalTargetCellsPerIncrement": 0,
+ "additionalItemBonus": 0,
+ "additionalWeaponDie": 0,
+ "alteredDuration": "None"
+ },
+ "speedType": "Instant",
+ "speedParameter": 10.0,
+ "offsetImpactTimeBasedOnDistance": false,
+ "offsetImpactTimeBasedOnDistanceFactor": 0.1,
+ "offsetImpactTimePerTarget": 0.0,
+ "effectParticleParameters": {
+ "$type": "EffectParticleParameters, Assembly-CSharp",
+ "casterParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "c61bb30a4b6e80642a36538c6ff1d675",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterSelfParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterQuickSpellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "targetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectSubTargetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "zoneParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "beforeImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "impactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticlePerIndex": "",
+ "activeEffectSurfaceParticlePerIndexCount": 0,
+ "emissiveBorderCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "f4489c0ea1762ec4dbe7fedbbcf0d4a8",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "3b107035e3bdbc6418aedb674221f5e3",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "forceApplyZoneParticle": false,
+ "applyEmissionColorOnWeapons": false,
+ "emissionColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "emissionColorFadeInDuration": 0.0,
+ "emissionColorFadeOutDuration": 0.0
+ },
+ "effectAIParameters": {
+ "$type": "EffectAIParameters, Assembly-CSharp",
+ "aoeScoreMultiplier": 1.0,
+ "cooldownForCaster": 0,
+ "cooldownForBattle": 0,
+ "sortingScoreMultiplier": 1.0,
+ "dynamicCooldown": false
+ },
+ "animationMagicEffect": "Animation1",
+ "lightCounterDispellsEffect": false,
+ "hideSavingThrowAnimation": false
+ },
+ "delegatedToAction": false,
+ "surrogateToSpell": null,
+ "triggeredBySpecialMove": false,
+ "activationTime": "Action",
+ "autoActivationRequiredTargetSenseType": "None",
+ "autoActivationRequiredTargetCreatureTag": "",
+ "autoActivationPowerTag": "",
+ "triggeringPower": null,
+ "copyTargetingFromTriggeringPower": false,
+ "reactionContext": "None",
+ "damageTypes": [],
+ "reactionName": "",
+ "reactionActingCharacterParamIdx": 0,
+ "reactionAttackerParamIdx": -1,
+ "hasCastingFailure": false,
+ "castingSuccessComputation": "CasterLevel",
+ "canUseInDialog": false,
+ "disableIfConditionIsOwned": null,
+ "disableIfTargetConditionIsOwned": null,
+ "rechargeRate": "LongRest",
+ "costPerUse": 1,
+ "spellcastingFeature": null,
+ "usesDetermination": "Fixed",
+ "abilityScoreDetermination": "Explicit",
+ "usesAbilityScoreName": "Charisma",
+ "fixedUsesPerRecharge": 1,
+ "abilityScore": "Intelligence",
+ "attackHitComputation": "AbilityScore",
+ "fixedAttackHit": 0,
+ "abilityScoreBonusToAttack": false,
+ "proficiencyBonusToAttack": false,
+ "uniqueInstance": true,
+ "showCasting": true,
+ "shortTitleOverride": "",
+ "overriddenPower": null,
+ "includeBaseDescription": false,
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Dissonant Whispers",
+ "description": "Create a wand that can cast Dissonant Whispers (I) spell using your Artificer spell attack modifier and save DC.",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "6b5b3868-2125-599d-a33d-8122477ebb41",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "3cdfcada-8b8a-5599-b7b0-ec9c8ea50675",
+ "contentPack": 9999,
+ "name": "PowerCreateSpellStoringWandOfDissonantWhispers"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonFlamethrower15.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonFlamethrower15.json
index b760fb2321..a69cd4558e 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonFlamethrower15.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonFlamethrower15.json
@@ -85,7 +85,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonFlamethrower3.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonFlamethrower3.json
index 651f9c184d..541aa625c2 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonFlamethrower3.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonFlamethrower3.json
@@ -85,7 +85,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonFlamethrower9.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonFlamethrower9.json
index 32ff6b9168..7ec84505c1 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonFlamethrower9.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonFlamethrower9.json
@@ -85,7 +85,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonForceBallista15.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonForceBallista15.json
index 3b5d4c130d..f35235fba3 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonForceBallista15.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonForceBallista15.json
@@ -85,7 +85,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonForceBallista3.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonForceBallista3.json
index 6a4f2a8284..d259c9ba77 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonForceBallista3.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonForceBallista3.json
@@ -85,7 +85,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonForceBallista9.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonForceBallista9.json
index 1d09b45112..bc5a178ed4 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonForceBallista9.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonForceBallista9.json
@@ -85,7 +85,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonProtector15.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonProtector15.json
index 2ba1eceb9a..674444b1d6 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonProtector15.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonProtector15.json
@@ -85,7 +85,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonProtector3.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonProtector3.json
index 933c0d3ba9..7765cb1e6f 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonProtector3.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonProtector3.json
@@ -85,7 +85,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonProtector9.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonProtector9.json
index 1a2be56cf0..a09c6e385a 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonProtector9.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerInnovationArtilleristSummonProtector9.json
@@ -85,7 +85,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerMartialArcaneArcherInsightArrow.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerMartialArcaneArcherInsightArrow.json
index e627a6d45a..52b18870d2 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerMartialArcaneArcherInsightArrow.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerMartialArcaneArcherInsightArrow.json
@@ -13,11 +13,11 @@
"emissiveBorder": "None",
"emissiveParameter": 1,
"requiresTargetProximity": false,
- "targetProximityDistance": 6,
+ "targetProximityDistance": 30,
"targetExcludeCaster": false,
"canBePlacedOnCharacter": true,
"affectOnlyGround": false,
- "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringMethod": "AllCharacterAndGadgets",
"targetFilteringTag": "No",
"requiresVisibilityForPosition": true,
"inviteOptionalAlly": false,
@@ -454,11 +454,11 @@
},
"effectAIParameters": {
"$type": "EffectAIParameters, Assembly-CSharp",
- "aoeScoreMultiplier": 1.0,
+ "aoeScoreMultiplier": 1.5,
"cooldownForCaster": 0,
- "cooldownForBattle": 0,
+ "cooldownForBattle": 2,
"sortingScoreMultiplier": 1.0,
- "dynamicCooldown": false
+ "dynamicCooldown": true
},
"animationMagicEffect": "Animation0",
"lightCounterDispellsEffect": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerMoonlitScionFullMoon.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerMoonlitScionFullMoon.json
index c1b17baa71..890fb46572 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerMoonlitScionFullMoon.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerMoonlitScionFullMoon.json
@@ -13,11 +13,11 @@
"emissiveBorder": "None",
"emissiveParameter": 1,
"requiresTargetProximity": false,
- "targetProximityDistance": 6,
+ "targetProximityDistance": 30,
"targetExcludeCaster": false,
"canBePlacedOnCharacter": true,
"affectOnlyGround": false,
- "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringMethod": "AllCharacterAndGadgets",
"targetFilteringTag": "No",
"requiresVisibilityForPosition": true,
"inviteOptionalAlly": false,
@@ -34,7 +34,7 @@
"durationType": "Minute",
"durationParameter": 1,
"endOfEffect": "EndOfTurn",
- "hasSavingThrow": false,
+ "hasSavingThrow": true,
"disableSavingThrowOnAllies": false,
"savingThrowAbility": "Dexterity",
"ignoreCover": false,
@@ -345,11 +345,11 @@
},
"effectAIParameters": {
"$type": "EffectAIParameters, Assembly-CSharp",
- "aoeScoreMultiplier": 1.0,
+ "aoeScoreMultiplier": 1.5,
"cooldownForCaster": 0,
- "cooldownForBattle": 0,
+ "cooldownForBattle": 2,
"sortingScoreMultiplier": 1.0,
- "dynamicCooldown": false
+ "dynamicCooldown": true
},
"animationMagicEffect": "Animation0",
"lightCounterDispellsEffect": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerRangerHellWalkerFiendishSpawnHezrou.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerRangerHellWalkerFiendishSpawnHezrou.json
index 7ff059d4b8..b91bee75a3 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerRangerHellWalkerFiendishSpawnHezrou.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerRangerHellWalkerFiendishSpawnHezrou.json
@@ -85,7 +85,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerRangerHellWalkerFiendishSpawnMarilith.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerRangerHellWalkerFiendishSpawnMarilith.json
index dac68cac64..391044b672 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerRangerHellWalkerFiendishSpawnMarilith.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerRangerHellWalkerFiendishSpawnMarilith.json
@@ -85,7 +85,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerRangerWildMasterSummonBeastCompanionKindredSpiritBear.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerRangerWildMasterSummonBeastCompanionKindredSpiritBear.json
index 3513315a33..6912b84b10 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerRangerWildMasterSummonBeastCompanionKindredSpiritBear.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerRangerWildMasterSummonBeastCompanionKindredSpiritBear.json
@@ -85,7 +85,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerRangerWildMasterSummonBeastCompanionKindredSpiritEagle.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerRangerWildMasterSummonBeastCompanionKindredSpiritEagle.json
index 58316cd9b7..000830be3f 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerRangerWildMasterSummonBeastCompanionKindredSpiritEagle.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerRangerWildMasterSummonBeastCompanionKindredSpiritEagle.json
@@ -85,7 +85,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerRangerWildMasterSummonBeastCompanionKindredSpiritWolf.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerRangerWildMasterSummonBeastCompanionKindredSpiritWolf.json
index cff6a901b2..03e5b694d4 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerRangerWildMasterSummonBeastCompanionKindredSpiritWolf.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerRangerWildMasterSummonBeastCompanionKindredSpiritWolf.json
@@ -85,7 +85,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerSharedPoolCircleOfTheWildfireSummonSpirit.json b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerSharedPoolCircleOfTheWildfireSummonSpirit.json
index 6d4f76a6da..1de98b872c 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerSharedPoolCircleOfTheWildfireSummonSpirit.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/FeatureDefinitionPowerSharedPool/PowerSharedPoolCircleOfTheWildfireSummonSpirit.json
@@ -85,7 +85,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ItemDefinition/SpellStoringWandOfCommandSpell.json b/Diagnostics/UnfinishedBusinessBlueprints/ItemDefinition/SpellStoringWandOfCommandSpell.json
new file mode 100644
index 0000000000..fd8c2a1018
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ItemDefinition/SpellStoringWandOfCommandSpell.json
@@ -0,0 +1,257 @@
+{
+ "$type": "ItemDefinition, Assembly-CSharp",
+ "inDungeonEditor": false,
+ "merchantCategory": "MagicDevice",
+ "weight": 0.5,
+ "slotTypes": [
+ "UtilitySlot",
+ "ContainerSlot"
+ ],
+ "slotsWhereActive": [
+ "MainHandSlot",
+ "OffHandSlot",
+ "UtilitySlot"
+ ],
+ "activeOnGround": false,
+ "destroyedWhenUnequiped": false,
+ "forceEquip": false,
+ "forceEquipSlot": "",
+ "canBeStacked": false,
+ "stackSize": 10,
+ "defaultStackCount": -1,
+ "costs": [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "itemTags": [
+ "Wood"
+ ],
+ "activeTags": [],
+ "inactiveTags": [],
+ "magical": true,
+ "requiresAttunement": false,
+ "requiresIdentification": false,
+ "requiredAttunementClasses": [],
+ "itemRarity": "Rare",
+ "incompatibleWithMonkReturnMissile": false,
+ "staticProperties": [],
+ "isArmor": false,
+ "isWeapon": false,
+ "isAmmunition": false,
+ "isUsableDevice": true,
+ "usableDeviceDescription": {
+ "$type": "UsableDeviceDescription, Assembly-CSharp",
+ "usage": "Charges",
+ "chargesCapital": "Fixed",
+ "chargesCapitalNumber": 6,
+ "chargesCapitalDie": "D1",
+ "chargesCapitalBonus": 0,
+ "rechargeRate": "None",
+ "rechargeNumber": 1,
+ "rechargeDie": "D1",
+ "rechargeBonus": 0,
+ "outOfChargesConsequence": "Destroy",
+ "magicAttackBonus": -2,
+ "saveDC": -2,
+ "deviceFunctions": [
+ {
+ "$type": "DeviceFunctionDescription, Assembly-CSharp",
+ "parentUsage": "ByFunction",
+ "useAffinity": "ChargeCost",
+ "useAmount": 1,
+ "rechargeRate": "Dawn",
+ "durationType": "Instantaneous",
+ "canOverchargeSpell": false,
+ "type": "Spell",
+ "spellDefinition": "Definition:CommandSpell:289ffbc5-ef5c-56b1-b6ba-79d88e236887",
+ "featureDefinitionPower": null
+ }
+ ],
+ "usableDeviceTags": [],
+ "onUseParticle": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ }
+ },
+ "isTool": false,
+ "isMusicalInstrument": false,
+ "musicalInstrumentDefinition": null,
+ "isStarterPack": false,
+ "isContainerItem": false,
+ "isLightSourceItem": false,
+ "isFocusItem": true,
+ "focusItemDefinition": {
+ "$type": "FocusItemDescription, Assembly-CSharp",
+ "focusType": "Arcane",
+ "shownAsFocus": true
+ },
+ "isWealthPile": false,
+ "isSpellbook": false,
+ "isDocument": false,
+ "isFood": false,
+ "isFactionRelic": false,
+ "personalityFlagOccurences": [],
+ "soundEffectDescriptionOverride": {
+ "$type": "SoundEffectDescription, Assembly-CSharp",
+ "startEvent": {
+ "$type": "AK.Wwise.Event, AK.Wwise.Unity.API.WwiseTypes",
+ "WwiseObjectReference": null,
+ "idInternal": 0,
+ "valueGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ }
+ },
+ "stopEvent": {
+ "$type": "AK.Wwise.Event, AK.Wwise.Unity.API.WwiseTypes",
+ "WwiseObjectReference": null,
+ "idInternal": 0,
+ "valueGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ }
+ },
+ "startSwitch": {
+ "$type": "AK.Wwise.Switch, AK.Wwise.Unity.API.WwiseTypes",
+ "WwiseObjectReference": null,
+ "groupIdInternal": 0,
+ "groupGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ },
+ "idInternal": 0,
+ "valueGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ }
+ },
+ "stopSwitch": {
+ "$type": "AK.Wwise.Switch, AK.Wwise.Unity.API.WwiseTypes",
+ "WwiseObjectReference": null,
+ "groupIdInternal": 0,
+ "groupGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ },
+ "idInternal": 0,
+ "valueGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ }
+ },
+ "guiStoreBody": {
+ "$type": "AK.Wwise.Event, AK.Wwise.Unity.API.WwiseTypes",
+ "WwiseObjectReference": null,
+ "idInternal": 0,
+ "valueGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ }
+ },
+ "guiPickBody": {
+ "$type": "AK.Wwise.Event, AK.Wwise.Unity.API.WwiseTypes",
+ "WwiseObjectReference": null,
+ "idInternal": 0,
+ "valueGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ }
+ },
+ "guiStoreOther": {
+ "$type": "AK.Wwise.Event, AK.Wwise.Unity.API.WwiseTypes",
+ "WwiseObjectReference": null,
+ "idInternal": 0,
+ "valueGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ }
+ },
+ "guiPickOther": {
+ "$type": "AK.Wwise.Event, AK.Wwise.Unity.API.WwiseTypes",
+ "WwiseObjectReference": null,
+ "idInternal": 0,
+ "valueGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ }
+ }
+ },
+ "soundEffectOnHitDescriptionOverride": {
+ "$type": "SoundEffectOnHitDescription, Assembly-CSharp",
+ "switchOnHit": {
+ "$type": "AK.Wwise.Switch, AK.Wwise.Unity.API.WwiseTypes",
+ "WwiseObjectReference": null,
+ "groupIdInternal": 0,
+ "groupGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ },
+ "idInternal": 0,
+ "valueGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ }
+ }
+ },
+ "itemPresentation": {
+ "$type": "ItemPresentation, Assembly-CSharp",
+ "unidentifiedTitle": "Equipment/&WandSpecialTitle",
+ "unidentifiedDescription": "Equipment/&WandSpecialDescription",
+ "overrideSubtype": "None",
+ "assetReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "scaleFactorWhileWielded": 1.0,
+ "useArmorAddressableName": false,
+ "isArmorAddressableNameGenderSpecific": false,
+ "armorAddressableName": "",
+ "maleArmorAddressableName": "",
+ "femaleArmorAddressableName": "",
+ "useCustomArmorMaterial": false,
+ "customArmorMaterial": "",
+ "ignoreCustomArmorMaterialOnCommonClothes": false,
+ "hasCrownVariationMask": false,
+ "crownVariationMask": 0,
+ "sameBehavioursForMaleAndFemale": true,
+ "maleBodyPartBehaviours": [],
+ "femaleBodyPartBehaviours": [],
+ "itemFlags": [],
+ "serializedVersion": 1
+ },
+ "clueSuspectPairs": [],
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Wand of Command",
+ "description": "This wand allows casting the Command spell using spell casting stats of the Artificer who created it.",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "99f5e6021bff7994bb5b9f6832f8145a",
+ "m_SubObjectName": "WandOfMagicMissiles",
+ "m_SubObjectType": "UnityEngine.Sprite, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "252920d8-129e-5ae7-a5fc-6bdccebf1d4f",
+ "contentPack": 9999,
+ "name": "SpellStoringWandOfCommandSpell"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/ItemDefinition/SpellStoringWandOfDissonantWhispers.json b/Diagnostics/UnfinishedBusinessBlueprints/ItemDefinition/SpellStoringWandOfDissonantWhispers.json
new file mode 100644
index 0000000000..5fa3b4a491
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/ItemDefinition/SpellStoringWandOfDissonantWhispers.json
@@ -0,0 +1,257 @@
+{
+ "$type": "ItemDefinition, Assembly-CSharp",
+ "inDungeonEditor": false,
+ "merchantCategory": "MagicDevice",
+ "weight": 0.5,
+ "slotTypes": [
+ "UtilitySlot",
+ "ContainerSlot"
+ ],
+ "slotsWhereActive": [
+ "MainHandSlot",
+ "OffHandSlot",
+ "UtilitySlot"
+ ],
+ "activeOnGround": false,
+ "destroyedWhenUnequiped": false,
+ "forceEquip": false,
+ "forceEquipSlot": "",
+ "canBeStacked": false,
+ "stackSize": 10,
+ "defaultStackCount": -1,
+ "costs": [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0
+ ],
+ "itemTags": [
+ "Wood"
+ ],
+ "activeTags": [],
+ "inactiveTags": [],
+ "magical": true,
+ "requiresAttunement": false,
+ "requiresIdentification": false,
+ "requiredAttunementClasses": [],
+ "itemRarity": "Rare",
+ "incompatibleWithMonkReturnMissile": false,
+ "staticProperties": [],
+ "isArmor": false,
+ "isWeapon": false,
+ "isAmmunition": false,
+ "isUsableDevice": true,
+ "usableDeviceDescription": {
+ "$type": "UsableDeviceDescription, Assembly-CSharp",
+ "usage": "Charges",
+ "chargesCapital": "Fixed",
+ "chargesCapitalNumber": 6,
+ "chargesCapitalDie": "D1",
+ "chargesCapitalBonus": 0,
+ "rechargeRate": "None",
+ "rechargeNumber": 1,
+ "rechargeDie": "D1",
+ "rechargeBonus": 0,
+ "outOfChargesConsequence": "Destroy",
+ "magicAttackBonus": -2,
+ "saveDC": -2,
+ "deviceFunctions": [
+ {
+ "$type": "DeviceFunctionDescription, Assembly-CSharp",
+ "parentUsage": "ByFunction",
+ "useAffinity": "ChargeCost",
+ "useAmount": 1,
+ "rechargeRate": "Dawn",
+ "durationType": "Instantaneous",
+ "canOverchargeSpell": false,
+ "type": "Spell",
+ "spellDefinition": "Definition:DissonantWhispers:a3308f76-57c3-56a7-acaa-9c505d7fdaa7",
+ "featureDefinitionPower": null
+ }
+ ],
+ "usableDeviceTags": [],
+ "onUseParticle": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ }
+ },
+ "isTool": false,
+ "isMusicalInstrument": false,
+ "musicalInstrumentDefinition": null,
+ "isStarterPack": false,
+ "isContainerItem": false,
+ "isLightSourceItem": false,
+ "isFocusItem": true,
+ "focusItemDefinition": {
+ "$type": "FocusItemDescription, Assembly-CSharp",
+ "focusType": "Arcane",
+ "shownAsFocus": true
+ },
+ "isWealthPile": false,
+ "isSpellbook": false,
+ "isDocument": false,
+ "isFood": false,
+ "isFactionRelic": false,
+ "personalityFlagOccurences": [],
+ "soundEffectDescriptionOverride": {
+ "$type": "SoundEffectDescription, Assembly-CSharp",
+ "startEvent": {
+ "$type": "AK.Wwise.Event, AK.Wwise.Unity.API.WwiseTypes",
+ "WwiseObjectReference": null,
+ "idInternal": 0,
+ "valueGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ }
+ },
+ "stopEvent": {
+ "$type": "AK.Wwise.Event, AK.Wwise.Unity.API.WwiseTypes",
+ "WwiseObjectReference": null,
+ "idInternal": 0,
+ "valueGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ }
+ },
+ "startSwitch": {
+ "$type": "AK.Wwise.Switch, AK.Wwise.Unity.API.WwiseTypes",
+ "WwiseObjectReference": null,
+ "groupIdInternal": 0,
+ "groupGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ },
+ "idInternal": 0,
+ "valueGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ }
+ },
+ "stopSwitch": {
+ "$type": "AK.Wwise.Switch, AK.Wwise.Unity.API.WwiseTypes",
+ "WwiseObjectReference": null,
+ "groupIdInternal": 0,
+ "groupGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ },
+ "idInternal": 0,
+ "valueGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ }
+ },
+ "guiStoreBody": {
+ "$type": "AK.Wwise.Event, AK.Wwise.Unity.API.WwiseTypes",
+ "WwiseObjectReference": null,
+ "idInternal": 0,
+ "valueGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ }
+ },
+ "guiPickBody": {
+ "$type": "AK.Wwise.Event, AK.Wwise.Unity.API.WwiseTypes",
+ "WwiseObjectReference": null,
+ "idInternal": 0,
+ "valueGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ }
+ },
+ "guiStoreOther": {
+ "$type": "AK.Wwise.Event, AK.Wwise.Unity.API.WwiseTypes",
+ "WwiseObjectReference": null,
+ "idInternal": 0,
+ "valueGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ }
+ },
+ "guiPickOther": {
+ "$type": "AK.Wwise.Event, AK.Wwise.Unity.API.WwiseTypes",
+ "WwiseObjectReference": null,
+ "idInternal": 0,
+ "valueGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ }
+ }
+ },
+ "soundEffectOnHitDescriptionOverride": {
+ "$type": "SoundEffectOnHitDescription, Assembly-CSharp",
+ "switchOnHit": {
+ "$type": "AK.Wwise.Switch, AK.Wwise.Unity.API.WwiseTypes",
+ "WwiseObjectReference": null,
+ "groupIdInternal": 0,
+ "groupGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ },
+ "idInternal": 0,
+ "valueGuidInternal": {
+ "$type": "System.Byte[], mscorlib",
+ "$value": ""
+ }
+ }
+ },
+ "itemPresentation": {
+ "$type": "ItemPresentation, Assembly-CSharp",
+ "unidentifiedTitle": "Equipment/&WandSpecialTitle",
+ "unidentifiedDescription": "Equipment/&WandSpecialDescription",
+ "overrideSubtype": "None",
+ "assetReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "scaleFactorWhileWielded": 1.0,
+ "useArmorAddressableName": false,
+ "isArmorAddressableNameGenderSpecific": false,
+ "armorAddressableName": "",
+ "maleArmorAddressableName": "",
+ "femaleArmorAddressableName": "",
+ "useCustomArmorMaterial": false,
+ "customArmorMaterial": "",
+ "ignoreCustomArmorMaterialOnCommonClothes": false,
+ "hasCrownVariationMask": false,
+ "crownVariationMask": 0,
+ "sameBehavioursForMaleAndFemale": true,
+ "maleBodyPartBehaviours": [],
+ "femaleBodyPartBehaviours": [],
+ "itemFlags": [],
+ "serializedVersion": 1
+ },
+ "clueSuspectPairs": [],
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Wand of Dissonant Whispers",
+ "description": "This wand allows casting the Dissonant Whispers spell using spell casting stats of the Artificer who created it.",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "99f5e6021bff7994bb5b9f6832f8145a",
+ "m_SubObjectName": "WandOfMagicMissiles",
+ "m_SubObjectType": "UnityEngine.Sprite, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "2f16c6e7-5a0d-5b07-89e6-b53f433567e8",
+ "contentPack": 9999,
+ "name": "SpellStoringWandOfDissonantWhispers"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/MonsterDefinition/InnovationWeaponAdvancedSteelDefender.json b/Diagnostics/UnfinishedBusinessBlueprints/MonsterDefinition/InnovationWeaponAdvancedSteelDefender.json
index f71e0da190..4943736ac8 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/MonsterDefinition/InnovationWeaponAdvancedSteelDefender.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/MonsterDefinition/InnovationWeaponAdvancedSteelDefender.json
@@ -53,7 +53,7 @@
"maxLegendaryActionPoints": 3,
"differentActionEachTurn": false,
"legendaryActionOptions": [],
- "defaultBattleDecisionPackage": "Definition:DefaultMeleeWithBackupRangeDecisions:36bb3688d84582249bf0f1c85064ad10",
+ "defaultBattleDecisionPackage": null,
"threatEvaluatorDefinition": null,
"languages": [],
"audioSwitches": [],
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/MonsterDefinition/InnovationWeaponSteelDefender.json b/Diagnostics/UnfinishedBusinessBlueprints/MonsterDefinition/InnovationWeaponSteelDefender.json
index 089004ef48..b32d902f9d 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/MonsterDefinition/InnovationWeaponSteelDefender.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/MonsterDefinition/InnovationWeaponSteelDefender.json
@@ -53,7 +53,7 @@
"maxLegendaryActionPoints": 3,
"differentActionEachTurn": false,
"legendaryActionOptions": [],
- "defaultBattleDecisionPackage": "Definition:DefaultMeleeWithBackupRangeDecisions:36bb3688d84582249bf0f1c85064ad10",
+ "defaultBattleDecisionPackage": null,
"threatEvaluatorDefinition": null,
"languages": [],
"audioSwitches": [],
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/MonsterDefinition/OwlFamiliar.json b/Diagnostics/UnfinishedBusinessBlueprints/MonsterDefinition/OwlFamiliar.json
index 5354075751..4a2acb479f 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/MonsterDefinition/OwlFamiliar.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/MonsterDefinition/OwlFamiliar.json
@@ -40,7 +40,7 @@
"maxLegendaryActionPoints": 3,
"differentActionEachTurn": false,
"legendaryActionOptions": [],
- "defaultBattleDecisionPackage": "Definition:DefaultSupportCasterWithBackupAttacksDecisions:f99448e8f4c2d9d478837c543e3e205f",
+ "defaultBattleDecisionPackage": "Definition:DefaultFlyingBeastWithBackupRangeCombatDecisions:2de7c4b469d4b984b80c0dbb2f82acab",
"threatEvaluatorDefinition": null,
"languages": [],
"audioSwitches": [],
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChaosBolt.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChaosBolt.json
index d6700c4c76..607002b358 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChaosBolt.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChaosBolt.json
@@ -37,8 +37,8 @@
"recurrentEffect": "No",
"retargetAfterDeath": false,
"retargetActionType": "Bonus",
- "poolFilterDiceNumber": 0,
- "poolFilterDieType": "D1",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
"trapRangeType": "Triggerer",
"targetConditionName": "",
"targetConditionAsset": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrb.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrb.json
index fa2b9b688b..2974b56f8c 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrb.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrb.json
@@ -44,8 +44,8 @@
"recurrentEffect": "No",
"retargetAfterDeath": false,
"retargetActionType": "Bonus",
- "poolFilterDiceNumber": 0,
- "poolFilterDieType": "D1",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
"trapRangeType": "Triggerer",
"targetConditionName": "",
"targetConditionAsset": null,
@@ -97,11 +97,11 @@
"additionalWeaponDie": 0,
"alteredDuration": "None"
},
- "speedType": "CellsPerSeconds",
- "speedParameter": 8.5,
+ "speedType": "Instant",
+ "speedParameter": 10.0,
"offsetImpactTimeBasedOnDistance": false,
"offsetImpactTimeBasedOnDistanceFactor": 0.1,
- "offsetImpactTimePerTarget": 0.1,
+ "offsetImpactTimePerTarget": 0.0,
"effectParticleParameters": {
"$type": "EffectParticleParameters, Assembly-CSharp",
"casterParticleReference": {
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamageAcid.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamageAcid.json
index 0c761ad755..dafcdd4ecb 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamageAcid.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamageAcid.json
@@ -37,8 +37,8 @@
"recurrentEffect": "No",
"retargetAfterDeath": false,
"retargetActionType": "Bonus",
- "poolFilterDiceNumber": 0,
- "poolFilterDieType": "D1",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
"trapRangeType": "Triggerer",
"targetConditionName": "",
"targetConditionAsset": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamageCold.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamageCold.json
index c27a5bd50e..3dc9546022 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamageCold.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamageCold.json
@@ -37,8 +37,8 @@
"recurrentEffect": "No",
"retargetAfterDeath": false,
"retargetActionType": "Bonus",
- "poolFilterDiceNumber": 0,
- "poolFilterDieType": "D1",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
"trapRangeType": "Triggerer",
"targetConditionName": "",
"targetConditionAsset": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamageFire.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamageFire.json
index 893e8e45df..16783f01d1 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamageFire.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamageFire.json
@@ -37,8 +37,8 @@
"recurrentEffect": "No",
"retargetAfterDeath": false,
"retargetActionType": "Bonus",
- "poolFilterDiceNumber": 0,
- "poolFilterDieType": "D1",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
"trapRangeType": "Triggerer",
"targetConditionName": "",
"targetConditionAsset": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamageLightning.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamageLightning.json
index fa51b70565..5db8c61409 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamageLightning.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamageLightning.json
@@ -37,8 +37,8 @@
"recurrentEffect": "No",
"retargetAfterDeath": false,
"retargetActionType": "Bonus",
- "poolFilterDiceNumber": 0,
- "poolFilterDieType": "D1",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
"trapRangeType": "Triggerer",
"targetConditionName": "",
"targetConditionAsset": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamagePoison.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamagePoison.json
index 514f3ac1be..240f37761f 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamagePoison.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamagePoison.json
@@ -37,8 +37,8 @@
"recurrentEffect": "No",
"retargetAfterDeath": false,
"retargetActionType": "Bonus",
- "poolFilterDiceNumber": 0,
- "poolFilterDieType": "D1",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
"trapRangeType": "Triggerer",
"targetConditionName": "",
"targetConditionAsset": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamageThunder.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamageThunder.json
index d882b2040e..1dffa258de 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamageThunder.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ChromaticOrbDamageThunder.json
@@ -37,8 +37,8 @@
"recurrentEffect": "No",
"retargetAfterDeath": false,
"retargetActionType": "Bonus",
- "poolFilterDiceNumber": 0,
- "poolFilterDieType": "D1",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
"trapRangeType": "Triggerer",
"targetConditionName": "",
"targetConditionAsset": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CommandSpell.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CommandSpell.json
new file mode 100644
index 0000000000..1a61dea8c1
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CommandSpell.json
@@ -0,0 +1,323 @@
+{
+ "$type": "SpellDefinition, Assembly-CSharp",
+ "spellsBundle": true,
+ "subspellsList": [
+ "Definition:CommandSpellApproach:395b1d47-bc7c-50e1-91e2-78e39a4e418b",
+ "Definition:CommandSpellFlee:0bed52be-d94a-5da2-8cfe-d5784f55e6f8",
+ "Definition:CommandSpellGrovel:b48998ac-2379-5637-ad85-8e45cdd375ac",
+ "Definition:CommandSpellHalt:d4e87ec4-f113-5c33-b5c6-0452ab42231b"
+ ],
+ "compactSubspellsTooltip": false,
+ "implemented": true,
+ "schoolOfMagic": "SchoolEnchantment",
+ "spellLevel": 1,
+ "ritual": false,
+ "uniqueInstance": false,
+ "castingTime": "Action",
+ "reactionContext": "None",
+ "ritualCastingTime": "Action",
+ "requiresConcentration": false,
+ "effectDescription": {
+ "$type": "EffectDescription, Assembly-CSharp",
+ "rangeType": "Distance",
+ "rangeParameter": 12,
+ "halfDamageOnAMiss": false,
+ "hitAffinitiesByTargetTag": [],
+ "targetType": "IndividualsUnique",
+ "itemSelectionType": "None",
+ "targetParameter": 1,
+ "targetParameter2": 2,
+ "emissiveBorder": "None",
+ "emissiveParameter": 1,
+ "requiresTargetProximity": false,
+ "targetProximityDistance": 6,
+ "targetExcludeCaster": false,
+ "canBePlacedOnCharacter": true,
+ "affectOnlyGround": false,
+ "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringTag": "No",
+ "requiresVisibilityForPosition": true,
+ "inviteOptionalAlly": false,
+ "slotTypes": [],
+ "recurrentEffect": "No",
+ "retargetAfterDeath": false,
+ "retargetActionType": "Bonus",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
+ "trapRangeType": "Triggerer",
+ "targetConditionName": "",
+ "targetConditionAsset": null,
+ "targetSide": "Enemy",
+ "durationType": "Instantaneous",
+ "durationParameter": 1,
+ "endOfEffect": "EndOfTurn",
+ "hasSavingThrow": true,
+ "disableSavingThrowOnAllies": false,
+ "savingThrowAbility": "Wisdom",
+ "ignoreCover": true,
+ "grantedConditionOnSave": null,
+ "rollSaveOnlyIfRelevantForms": false,
+ "hasShoveRoll": false,
+ "createdByCharacter": true,
+ "difficultyClassComputation": "SpellCastingFeature",
+ "savingThrowDifficultyAbility": "Wisdom",
+ "fixedSavingThrowDifficultyClass": 10,
+ "savingThrowAffinitiesBySense": [],
+ "savingThrowAffinitiesByFamily": [],
+ "damageAffinitiesByFamily": [],
+ "advantageForEnemies": false,
+ "canBeDispersed": false,
+ "hasVelocity": false,
+ "velocityCellsPerRound": 2,
+ "velocityType": "AwayFromSourceOriginalPosition",
+ "restrictedCreatureFamilies": [],
+ "immuneCreatureFamilies": [],
+ "restrictedCharacterSizes": [],
+ "hasLimitedEffectPool": false,
+ "effectPoolAmount": 60,
+ "effectApplication": "All",
+ "effectFormFilters": [],
+ "effectForms": [],
+ "specialFormsDescription": "",
+ "effectAdvancement": {
+ "$type": "EffectAdvancement, Assembly-CSharp",
+ "effectIncrementMethod": "PerAdditionalSlotLevel",
+ "incrementMultiplier": 1,
+ "additionalTargetsPerIncrement": 1,
+ "additionalSubtargetsPerIncrement": 0,
+ "additionalDicePerIncrement": 0,
+ "additionalSpellLevelPerIncrement": 0,
+ "additionalSummonsPerIncrement": 0,
+ "additionalHPPerIncrement": 0,
+ "additionalTempHPPerIncrement": 0,
+ "additionalTargetCellsPerIncrement": 0,
+ "additionalItemBonus": 0,
+ "additionalWeaponDie": 0,
+ "alteredDuration": "None"
+ },
+ "speedType": "Instant",
+ "speedParameter": 10.0,
+ "offsetImpactTimeBasedOnDistance": false,
+ "offsetImpactTimeBasedOnDistanceFactor": 0.1,
+ "offsetImpactTimePerTarget": 0.0,
+ "effectParticleParameters": {
+ "$type": "EffectParticleParameters, Assembly-CSharp",
+ "casterParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "81560ac3813217d4d9fd281d5e73c234",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterSelfParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterQuickSpellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "targetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectSubTargetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "zoneParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "beforeImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "impactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticlePerIndex": "",
+ "activeEffectSurfaceParticlePerIndexCount": 0,
+ "emissiveBorderCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "forceApplyZoneParticle": false,
+ "applyEmissionColorOnWeapons": false,
+ "emissionColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "emissionColorFadeInDuration": 0.0,
+ "emissionColorFadeOutDuration": 0.0
+ },
+ "effectAIParameters": {
+ "$type": "EffectAIParameters, Assembly-CSharp",
+ "aoeScoreMultiplier": 1.0,
+ "cooldownForCaster": 0,
+ "cooldownForBattle": 0,
+ "sortingScoreMultiplier": 1.0,
+ "dynamicCooldown": false
+ },
+ "animationMagicEffect": "Animation0",
+ "lightCounterDispellsEffect": false,
+ "hideSavingThrowAnimation": false
+ },
+ "aiParameters": {
+ "$type": "SpellAIParameters, Assembly-CSharp",
+ "learnPriority": "Low",
+ "preparePriority": "Low"
+ },
+ "concentrationAction": "None",
+ "verboseComponent": true,
+ "somaticComponent": false,
+ "materialComponentType": "Mundane",
+ "specificMaterialComponentTag": "Diamond",
+ "specificMaterialComponentCostGp": 100,
+ "specificMaterialComponentConsumed": true,
+ "terminateOnItemUnequip": false,
+ "displayConditionDuration": false,
+ "vocalSpellSemeType": "Attack",
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Spell/&CommandSpellTitle",
+ "description": "Spell/&CommandSpellDescription",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "6edc0b78da56b1e4b94c3d7fb6c96dec",
+ "m_SubObjectName": "Command",
+ "m_SubObjectType": "UnityEngine.Sprite, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "289ffbc5-ef5c-56b1-b6ba-79d88e236887",
+ "contentPack": 9999,
+ "name": "CommandSpell"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CommandSpellApproach.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CommandSpellApproach.json
new file mode 100644
index 0000000000..a7fb4ee8ca
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CommandSpellApproach.json
@@ -0,0 +1,346 @@
+{
+ "$type": "SpellDefinition, Assembly-CSharp",
+ "spellsBundle": false,
+ "subspellsList": [],
+ "compactSubspellsTooltip": false,
+ "implemented": true,
+ "schoolOfMagic": "SchoolEnchantment",
+ "spellLevel": 1,
+ "ritual": false,
+ "uniqueInstance": false,
+ "castingTime": "Action",
+ "reactionContext": "None",
+ "ritualCastingTime": "Action",
+ "requiresConcentration": false,
+ "effectDescription": {
+ "$type": "EffectDescription, Assembly-CSharp",
+ "rangeType": "Distance",
+ "rangeParameter": 12,
+ "halfDamageOnAMiss": false,
+ "hitAffinitiesByTargetTag": [],
+ "targetType": "IndividualsUnique",
+ "itemSelectionType": "None",
+ "targetParameter": 1,
+ "targetParameter2": 2,
+ "emissiveBorder": "None",
+ "emissiveParameter": 1,
+ "requiresTargetProximity": false,
+ "targetProximityDistance": 6,
+ "targetExcludeCaster": false,
+ "canBePlacedOnCharacter": true,
+ "affectOnlyGround": false,
+ "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringTag": "No",
+ "requiresVisibilityForPosition": true,
+ "inviteOptionalAlly": false,
+ "slotTypes": [],
+ "recurrentEffect": "No",
+ "retargetAfterDeath": false,
+ "retargetActionType": "Bonus",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
+ "trapRangeType": "Triggerer",
+ "targetConditionName": "",
+ "targetConditionAsset": null,
+ "targetSide": "Enemy",
+ "durationType": "Round",
+ "durationParameter": 1,
+ "endOfEffect": "EndOfTurn",
+ "hasSavingThrow": true,
+ "disableSavingThrowOnAllies": false,
+ "savingThrowAbility": "Wisdom",
+ "ignoreCover": true,
+ "grantedConditionOnSave": null,
+ "rollSaveOnlyIfRelevantForms": false,
+ "hasShoveRoll": false,
+ "createdByCharacter": true,
+ "difficultyClassComputation": "SpellCastingFeature",
+ "savingThrowDifficultyAbility": "Wisdom",
+ "fixedSavingThrowDifficultyClass": 10,
+ "savingThrowAffinitiesBySense": [],
+ "savingThrowAffinitiesByFamily": [],
+ "damageAffinitiesByFamily": [],
+ "advantageForEnemies": false,
+ "canBeDispersed": false,
+ "hasVelocity": false,
+ "velocityCellsPerRound": 2,
+ "velocityType": "AwayFromSourceOriginalPosition",
+ "restrictedCreatureFamilies": [],
+ "immuneCreatureFamilies": [],
+ "restrictedCharacterSizes": [],
+ "hasLimitedEffectPool": false,
+ "effectPoolAmount": 60,
+ "effectApplication": "All",
+ "effectFormFilters": [],
+ "effectForms": [
+ {
+ "$type": "EffectForm, Assembly-CSharp",
+ "formType": "Condition",
+ "addBonusMode": "None",
+ "applyLevel": "No",
+ "levelType": "ClassLevel",
+ "levelMultiplier": 1,
+ "diceByLevelTable": [],
+ "createdByCharacter": true,
+ "createdByCondition": false,
+ "hasSavingThrow": true,
+ "savingThrowAffinity": "Negates",
+ "dcModifier": 0,
+ "canSaveToCancel": false,
+ "saveOccurence": "EndOfTurn",
+ "conditionForm": {
+ "$type": "ConditionForm, Assembly-CSharp",
+ "conditionDefinitionName": "ConditionCommandSpellApproach",
+ "conditionDefinition": "Definition:ConditionCommandSpellApproach:bc446416-951a-5ad8-a0a0-f0e1eae119f4",
+ "operation": "Add",
+ "conditionsList": [],
+ "applyToSelf": false,
+ "forceOnSelf": false
+ },
+ "hasFilterId": false,
+ "filterId": 0
+ }
+ ],
+ "specialFormsDescription": "",
+ "effectAdvancement": {
+ "$type": "EffectAdvancement, Assembly-CSharp",
+ "effectIncrementMethod": "PerAdditionalSlotLevel",
+ "incrementMultiplier": 1,
+ "additionalTargetsPerIncrement": 1,
+ "additionalSubtargetsPerIncrement": 0,
+ "additionalDicePerIncrement": 0,
+ "additionalSpellLevelPerIncrement": 0,
+ "additionalSummonsPerIncrement": 0,
+ "additionalHPPerIncrement": 0,
+ "additionalTempHPPerIncrement": 0,
+ "additionalTargetCellsPerIncrement": 0,
+ "additionalItemBonus": 0,
+ "additionalWeaponDie": 0,
+ "alteredDuration": "None"
+ },
+ "speedType": "Instant",
+ "speedParameter": 10.0,
+ "offsetImpactTimeBasedOnDistance": false,
+ "offsetImpactTimeBasedOnDistanceFactor": 0.1,
+ "offsetImpactTimePerTarget": 0.0,
+ "effectParticleParameters": {
+ "$type": "EffectParticleParameters, Assembly-CSharp",
+ "casterParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "623efe782aaa3a84fbd91053c5fd1b39",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterSelfParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterQuickSpellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "targetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "19f4a5c35fbee93479226bd045a5ec1f",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectSubTargetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "zoneParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "beforeImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "impactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticlePerIndex": "",
+ "activeEffectSurfaceParticlePerIndexCount": 0,
+ "emissiveBorderCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "forceApplyZoneParticle": false,
+ "applyEmissionColorOnWeapons": false,
+ "emissionColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "emissionColorFadeInDuration": 0.0,
+ "emissionColorFadeOutDuration": 0.0
+ },
+ "effectAIParameters": {
+ "$type": "EffectAIParameters, Assembly-CSharp",
+ "aoeScoreMultiplier": 1.0,
+ "cooldownForCaster": 0,
+ "cooldownForBattle": 0,
+ "sortingScoreMultiplier": 1.0,
+ "dynamicCooldown": false
+ },
+ "animationMagicEffect": "Animation0",
+ "lightCounterDispellsEffect": false,
+ "hideSavingThrowAnimation": false
+ },
+ "aiParameters": {
+ "$type": "SpellAIParameters, Assembly-CSharp",
+ "learnPriority": "Low",
+ "preparePriority": "Low"
+ },
+ "concentrationAction": "None",
+ "verboseComponent": true,
+ "somaticComponent": false,
+ "materialComponentType": "Mundane",
+ "specificMaterialComponentTag": "Diamond",
+ "specificMaterialComponentCostGp": 100,
+ "specificMaterialComponentConsumed": true,
+ "terminateOnItemUnequip": false,
+ "displayConditionDuration": false,
+ "vocalSpellSemeType": "Attack",
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Spell/&CommandSpellApproachTitle",
+ "description": "Spell/&CommandSpellApproachDescription",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "6edc0b78da56b1e4b94c3d7fb6c96dec",
+ "m_SubObjectName": "Command",
+ "m_SubObjectType": "UnityEngine.Sprite, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "395b1d47-bc7c-50e1-91e2-78e39a4e418b",
+ "contentPack": 9999,
+ "name": "CommandSpellApproach"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CommandSpellFlee.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CommandSpellFlee.json
new file mode 100644
index 0000000000..a1a89de1bc
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CommandSpellFlee.json
@@ -0,0 +1,346 @@
+{
+ "$type": "SpellDefinition, Assembly-CSharp",
+ "spellsBundle": false,
+ "subspellsList": [],
+ "compactSubspellsTooltip": false,
+ "implemented": true,
+ "schoolOfMagic": "SchoolEnchantment",
+ "spellLevel": 1,
+ "ritual": false,
+ "uniqueInstance": false,
+ "castingTime": "Action",
+ "reactionContext": "None",
+ "ritualCastingTime": "Action",
+ "requiresConcentration": false,
+ "effectDescription": {
+ "$type": "EffectDescription, Assembly-CSharp",
+ "rangeType": "Distance",
+ "rangeParameter": 12,
+ "halfDamageOnAMiss": false,
+ "hitAffinitiesByTargetTag": [],
+ "targetType": "IndividualsUnique",
+ "itemSelectionType": "None",
+ "targetParameter": 1,
+ "targetParameter2": 2,
+ "emissiveBorder": "None",
+ "emissiveParameter": 1,
+ "requiresTargetProximity": false,
+ "targetProximityDistance": 6,
+ "targetExcludeCaster": false,
+ "canBePlacedOnCharacter": true,
+ "affectOnlyGround": false,
+ "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringTag": "No",
+ "requiresVisibilityForPosition": true,
+ "inviteOptionalAlly": false,
+ "slotTypes": [],
+ "recurrentEffect": "No",
+ "retargetAfterDeath": false,
+ "retargetActionType": "Bonus",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
+ "trapRangeType": "Triggerer",
+ "targetConditionName": "",
+ "targetConditionAsset": null,
+ "targetSide": "Enemy",
+ "durationType": "Round",
+ "durationParameter": 1,
+ "endOfEffect": "EndOfTurn",
+ "hasSavingThrow": true,
+ "disableSavingThrowOnAllies": false,
+ "savingThrowAbility": "Wisdom",
+ "ignoreCover": true,
+ "grantedConditionOnSave": null,
+ "rollSaveOnlyIfRelevantForms": false,
+ "hasShoveRoll": false,
+ "createdByCharacter": true,
+ "difficultyClassComputation": "SpellCastingFeature",
+ "savingThrowDifficultyAbility": "Wisdom",
+ "fixedSavingThrowDifficultyClass": 10,
+ "savingThrowAffinitiesBySense": [],
+ "savingThrowAffinitiesByFamily": [],
+ "damageAffinitiesByFamily": [],
+ "advantageForEnemies": false,
+ "canBeDispersed": false,
+ "hasVelocity": false,
+ "velocityCellsPerRound": 2,
+ "velocityType": "AwayFromSourceOriginalPosition",
+ "restrictedCreatureFamilies": [],
+ "immuneCreatureFamilies": [],
+ "restrictedCharacterSizes": [],
+ "hasLimitedEffectPool": false,
+ "effectPoolAmount": 60,
+ "effectApplication": "All",
+ "effectFormFilters": [],
+ "effectForms": [
+ {
+ "$type": "EffectForm, Assembly-CSharp",
+ "formType": "Condition",
+ "addBonusMode": "None",
+ "applyLevel": "No",
+ "levelType": "ClassLevel",
+ "levelMultiplier": 1,
+ "diceByLevelTable": [],
+ "createdByCharacter": true,
+ "createdByCondition": false,
+ "hasSavingThrow": true,
+ "savingThrowAffinity": "Negates",
+ "dcModifier": 0,
+ "canSaveToCancel": false,
+ "saveOccurence": "EndOfTurn",
+ "conditionForm": {
+ "$type": "ConditionForm, Assembly-CSharp",
+ "conditionDefinitionName": "ConditionCommandSpellFlee",
+ "conditionDefinition": "Definition:ConditionCommandSpellFlee:b52e3cc4-15af-5123-a861-3fae68460977",
+ "operation": "Add",
+ "conditionsList": [],
+ "applyToSelf": false,
+ "forceOnSelf": false
+ },
+ "hasFilterId": false,
+ "filterId": 0
+ }
+ ],
+ "specialFormsDescription": "",
+ "effectAdvancement": {
+ "$type": "EffectAdvancement, Assembly-CSharp",
+ "effectIncrementMethod": "PerAdditionalSlotLevel",
+ "incrementMultiplier": 1,
+ "additionalTargetsPerIncrement": 1,
+ "additionalSubtargetsPerIncrement": 0,
+ "additionalDicePerIncrement": 0,
+ "additionalSpellLevelPerIncrement": 0,
+ "additionalSummonsPerIncrement": 0,
+ "additionalHPPerIncrement": 0,
+ "additionalTempHPPerIncrement": 0,
+ "additionalTargetCellsPerIncrement": 0,
+ "additionalItemBonus": 0,
+ "additionalWeaponDie": 0,
+ "alteredDuration": "None"
+ },
+ "speedType": "Instant",
+ "speedParameter": 10.0,
+ "offsetImpactTimeBasedOnDistance": false,
+ "offsetImpactTimeBasedOnDistanceFactor": 0.1,
+ "offsetImpactTimePerTarget": 0.0,
+ "effectParticleParameters": {
+ "$type": "EffectParticleParameters, Assembly-CSharp",
+ "casterParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "623efe782aaa3a84fbd91053c5fd1b39",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterSelfParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterQuickSpellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "targetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "19f4a5c35fbee93479226bd045a5ec1f",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectSubTargetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "zoneParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "beforeImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "impactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticlePerIndex": "",
+ "activeEffectSurfaceParticlePerIndexCount": 0,
+ "emissiveBorderCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "forceApplyZoneParticle": false,
+ "applyEmissionColorOnWeapons": false,
+ "emissionColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "emissionColorFadeInDuration": 0.0,
+ "emissionColorFadeOutDuration": 0.0
+ },
+ "effectAIParameters": {
+ "$type": "EffectAIParameters, Assembly-CSharp",
+ "aoeScoreMultiplier": 1.0,
+ "cooldownForCaster": 0,
+ "cooldownForBattle": 0,
+ "sortingScoreMultiplier": 1.0,
+ "dynamicCooldown": false
+ },
+ "animationMagicEffect": "Animation0",
+ "lightCounterDispellsEffect": false,
+ "hideSavingThrowAnimation": false
+ },
+ "aiParameters": {
+ "$type": "SpellAIParameters, Assembly-CSharp",
+ "learnPriority": "Low",
+ "preparePriority": "Low"
+ },
+ "concentrationAction": "None",
+ "verboseComponent": true,
+ "somaticComponent": false,
+ "materialComponentType": "Mundane",
+ "specificMaterialComponentTag": "Diamond",
+ "specificMaterialComponentCostGp": 100,
+ "specificMaterialComponentConsumed": true,
+ "terminateOnItemUnequip": false,
+ "displayConditionDuration": false,
+ "vocalSpellSemeType": "Attack",
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Spell/&CommandSpellFleeTitle",
+ "description": "Spell/&CommandSpellFleeDescription",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "6edc0b78da56b1e4b94c3d7fb6c96dec",
+ "m_SubObjectName": "Command",
+ "m_SubObjectType": "UnityEngine.Sprite, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "0bed52be-d94a-5da2-8cfe-d5784f55e6f8",
+ "contentPack": 9999,
+ "name": "CommandSpellFlee"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CommandSpellGrovel.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CommandSpellGrovel.json
new file mode 100644
index 0000000000..31b33b395c
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CommandSpellGrovel.json
@@ -0,0 +1,346 @@
+{
+ "$type": "SpellDefinition, Assembly-CSharp",
+ "spellsBundle": false,
+ "subspellsList": [],
+ "compactSubspellsTooltip": false,
+ "implemented": true,
+ "schoolOfMagic": "SchoolEnchantment",
+ "spellLevel": 1,
+ "ritual": false,
+ "uniqueInstance": false,
+ "castingTime": "Action",
+ "reactionContext": "None",
+ "ritualCastingTime": "Action",
+ "requiresConcentration": false,
+ "effectDescription": {
+ "$type": "EffectDescription, Assembly-CSharp",
+ "rangeType": "Distance",
+ "rangeParameter": 12,
+ "halfDamageOnAMiss": false,
+ "hitAffinitiesByTargetTag": [],
+ "targetType": "IndividualsUnique",
+ "itemSelectionType": "None",
+ "targetParameter": 1,
+ "targetParameter2": 2,
+ "emissiveBorder": "None",
+ "emissiveParameter": 1,
+ "requiresTargetProximity": false,
+ "targetProximityDistance": 6,
+ "targetExcludeCaster": false,
+ "canBePlacedOnCharacter": true,
+ "affectOnlyGround": false,
+ "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringTag": "No",
+ "requiresVisibilityForPosition": true,
+ "inviteOptionalAlly": false,
+ "slotTypes": [],
+ "recurrentEffect": "No",
+ "retargetAfterDeath": false,
+ "retargetActionType": "Bonus",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
+ "trapRangeType": "Triggerer",
+ "targetConditionName": "",
+ "targetConditionAsset": null,
+ "targetSide": "Enemy",
+ "durationType": "Round",
+ "durationParameter": 1,
+ "endOfEffect": "EndOfTurn",
+ "hasSavingThrow": true,
+ "disableSavingThrowOnAllies": false,
+ "savingThrowAbility": "Wisdom",
+ "ignoreCover": true,
+ "grantedConditionOnSave": null,
+ "rollSaveOnlyIfRelevantForms": false,
+ "hasShoveRoll": false,
+ "createdByCharacter": true,
+ "difficultyClassComputation": "SpellCastingFeature",
+ "savingThrowDifficultyAbility": "Wisdom",
+ "fixedSavingThrowDifficultyClass": 10,
+ "savingThrowAffinitiesBySense": [],
+ "savingThrowAffinitiesByFamily": [],
+ "damageAffinitiesByFamily": [],
+ "advantageForEnemies": false,
+ "canBeDispersed": false,
+ "hasVelocity": false,
+ "velocityCellsPerRound": 2,
+ "velocityType": "AwayFromSourceOriginalPosition",
+ "restrictedCreatureFamilies": [],
+ "immuneCreatureFamilies": [],
+ "restrictedCharacterSizes": [],
+ "hasLimitedEffectPool": false,
+ "effectPoolAmount": 60,
+ "effectApplication": "All",
+ "effectFormFilters": [],
+ "effectForms": [
+ {
+ "$type": "EffectForm, Assembly-CSharp",
+ "formType": "Condition",
+ "addBonusMode": "None",
+ "applyLevel": "No",
+ "levelType": "ClassLevel",
+ "levelMultiplier": 1,
+ "diceByLevelTable": [],
+ "createdByCharacter": true,
+ "createdByCondition": false,
+ "hasSavingThrow": true,
+ "savingThrowAffinity": "Negates",
+ "dcModifier": 0,
+ "canSaveToCancel": false,
+ "saveOccurence": "EndOfTurn",
+ "conditionForm": {
+ "$type": "ConditionForm, Assembly-CSharp",
+ "conditionDefinitionName": "ConditionCommandSpellGrovel",
+ "conditionDefinition": "Definition:ConditionCommandSpellGrovel:6422ce36-c309-52f9-b699-bddb61fde71e",
+ "operation": "Add",
+ "conditionsList": [],
+ "applyToSelf": false,
+ "forceOnSelf": false
+ },
+ "hasFilterId": false,
+ "filterId": 0
+ }
+ ],
+ "specialFormsDescription": "",
+ "effectAdvancement": {
+ "$type": "EffectAdvancement, Assembly-CSharp",
+ "effectIncrementMethod": "PerAdditionalSlotLevel",
+ "incrementMultiplier": 1,
+ "additionalTargetsPerIncrement": 1,
+ "additionalSubtargetsPerIncrement": 0,
+ "additionalDicePerIncrement": 0,
+ "additionalSpellLevelPerIncrement": 0,
+ "additionalSummonsPerIncrement": 0,
+ "additionalHPPerIncrement": 0,
+ "additionalTempHPPerIncrement": 0,
+ "additionalTargetCellsPerIncrement": 0,
+ "additionalItemBonus": 0,
+ "additionalWeaponDie": 0,
+ "alteredDuration": "None"
+ },
+ "speedType": "Instant",
+ "speedParameter": 10.0,
+ "offsetImpactTimeBasedOnDistance": false,
+ "offsetImpactTimeBasedOnDistanceFactor": 0.1,
+ "offsetImpactTimePerTarget": 0.0,
+ "effectParticleParameters": {
+ "$type": "EffectParticleParameters, Assembly-CSharp",
+ "casterParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "623efe782aaa3a84fbd91053c5fd1b39",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterSelfParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterQuickSpellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "targetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "19f4a5c35fbee93479226bd045a5ec1f",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectSubTargetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "zoneParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "beforeImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "impactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticlePerIndex": "",
+ "activeEffectSurfaceParticlePerIndexCount": 0,
+ "emissiveBorderCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "forceApplyZoneParticle": false,
+ "applyEmissionColorOnWeapons": false,
+ "emissionColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "emissionColorFadeInDuration": 0.0,
+ "emissionColorFadeOutDuration": 0.0
+ },
+ "effectAIParameters": {
+ "$type": "EffectAIParameters, Assembly-CSharp",
+ "aoeScoreMultiplier": 1.0,
+ "cooldownForCaster": 0,
+ "cooldownForBattle": 0,
+ "sortingScoreMultiplier": 1.0,
+ "dynamicCooldown": false
+ },
+ "animationMagicEffect": "Animation0",
+ "lightCounterDispellsEffect": false,
+ "hideSavingThrowAnimation": false
+ },
+ "aiParameters": {
+ "$type": "SpellAIParameters, Assembly-CSharp",
+ "learnPriority": "Low",
+ "preparePriority": "Low"
+ },
+ "concentrationAction": "None",
+ "verboseComponent": true,
+ "somaticComponent": false,
+ "materialComponentType": "Mundane",
+ "specificMaterialComponentTag": "Diamond",
+ "specificMaterialComponentCostGp": 100,
+ "specificMaterialComponentConsumed": true,
+ "terminateOnItemUnequip": false,
+ "displayConditionDuration": false,
+ "vocalSpellSemeType": "Attack",
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Spell/&CommandSpellGrovelTitle",
+ "description": "Spell/&CommandSpellGrovelDescription",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "6edc0b78da56b1e4b94c3d7fb6c96dec",
+ "m_SubObjectName": "Command",
+ "m_SubObjectType": "UnityEngine.Sprite, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "b48998ac-2379-5637-ad85-8e45cdd375ac",
+ "contentPack": 9999,
+ "name": "CommandSpellGrovel"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CommandSpellHalt.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CommandSpellHalt.json
new file mode 100644
index 0000000000..ca21d61c39
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CommandSpellHalt.json
@@ -0,0 +1,346 @@
+{
+ "$type": "SpellDefinition, Assembly-CSharp",
+ "spellsBundle": false,
+ "subspellsList": [],
+ "compactSubspellsTooltip": false,
+ "implemented": true,
+ "schoolOfMagic": "SchoolEnchantment",
+ "spellLevel": 1,
+ "ritual": false,
+ "uniqueInstance": false,
+ "castingTime": "Action",
+ "reactionContext": "None",
+ "ritualCastingTime": "Action",
+ "requiresConcentration": false,
+ "effectDescription": {
+ "$type": "EffectDescription, Assembly-CSharp",
+ "rangeType": "Distance",
+ "rangeParameter": 12,
+ "halfDamageOnAMiss": false,
+ "hitAffinitiesByTargetTag": [],
+ "targetType": "IndividualsUnique",
+ "itemSelectionType": "None",
+ "targetParameter": 1,
+ "targetParameter2": 2,
+ "emissiveBorder": "None",
+ "emissiveParameter": 1,
+ "requiresTargetProximity": false,
+ "targetProximityDistance": 6,
+ "targetExcludeCaster": false,
+ "canBePlacedOnCharacter": true,
+ "affectOnlyGround": false,
+ "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringTag": "No",
+ "requiresVisibilityForPosition": true,
+ "inviteOptionalAlly": false,
+ "slotTypes": [],
+ "recurrentEffect": "No",
+ "retargetAfterDeath": false,
+ "retargetActionType": "Bonus",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
+ "trapRangeType": "Triggerer",
+ "targetConditionName": "",
+ "targetConditionAsset": null,
+ "targetSide": "Enemy",
+ "durationType": "Round",
+ "durationParameter": 1,
+ "endOfEffect": "EndOfTurn",
+ "hasSavingThrow": true,
+ "disableSavingThrowOnAllies": false,
+ "savingThrowAbility": "Wisdom",
+ "ignoreCover": true,
+ "grantedConditionOnSave": null,
+ "rollSaveOnlyIfRelevantForms": false,
+ "hasShoveRoll": false,
+ "createdByCharacter": true,
+ "difficultyClassComputation": "SpellCastingFeature",
+ "savingThrowDifficultyAbility": "Wisdom",
+ "fixedSavingThrowDifficultyClass": 10,
+ "savingThrowAffinitiesBySense": [],
+ "savingThrowAffinitiesByFamily": [],
+ "damageAffinitiesByFamily": [],
+ "advantageForEnemies": false,
+ "canBeDispersed": false,
+ "hasVelocity": false,
+ "velocityCellsPerRound": 2,
+ "velocityType": "AwayFromSourceOriginalPosition",
+ "restrictedCreatureFamilies": [],
+ "immuneCreatureFamilies": [],
+ "restrictedCharacterSizes": [],
+ "hasLimitedEffectPool": false,
+ "effectPoolAmount": 60,
+ "effectApplication": "All",
+ "effectFormFilters": [],
+ "effectForms": [
+ {
+ "$type": "EffectForm, Assembly-CSharp",
+ "formType": "Condition",
+ "addBonusMode": "None",
+ "applyLevel": "No",
+ "levelType": "ClassLevel",
+ "levelMultiplier": 1,
+ "diceByLevelTable": [],
+ "createdByCharacter": true,
+ "createdByCondition": false,
+ "hasSavingThrow": true,
+ "savingThrowAffinity": "Negates",
+ "dcModifier": 0,
+ "canSaveToCancel": false,
+ "saveOccurence": "EndOfTurn",
+ "conditionForm": {
+ "$type": "ConditionForm, Assembly-CSharp",
+ "conditionDefinitionName": "ConditionCommandSpellHalt",
+ "conditionDefinition": "Definition:ConditionCommandSpellHalt:d20e7a46-e706-5c54-8bea-955b2054193a",
+ "operation": "Add",
+ "conditionsList": [],
+ "applyToSelf": false,
+ "forceOnSelf": false
+ },
+ "hasFilterId": false,
+ "filterId": 0
+ }
+ ],
+ "specialFormsDescription": "",
+ "effectAdvancement": {
+ "$type": "EffectAdvancement, Assembly-CSharp",
+ "effectIncrementMethod": "PerAdditionalSlotLevel",
+ "incrementMultiplier": 1,
+ "additionalTargetsPerIncrement": 1,
+ "additionalSubtargetsPerIncrement": 0,
+ "additionalDicePerIncrement": 0,
+ "additionalSpellLevelPerIncrement": 0,
+ "additionalSummonsPerIncrement": 0,
+ "additionalHPPerIncrement": 0,
+ "additionalTempHPPerIncrement": 0,
+ "additionalTargetCellsPerIncrement": 0,
+ "additionalItemBonus": 0,
+ "additionalWeaponDie": 0,
+ "alteredDuration": "None"
+ },
+ "speedType": "Instant",
+ "speedParameter": 10.0,
+ "offsetImpactTimeBasedOnDistance": false,
+ "offsetImpactTimeBasedOnDistanceFactor": 0.1,
+ "offsetImpactTimePerTarget": 0.0,
+ "effectParticleParameters": {
+ "$type": "EffectParticleParameters, Assembly-CSharp",
+ "casterParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "623efe782aaa3a84fbd91053c5fd1b39",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterSelfParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterQuickSpellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "targetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "19f4a5c35fbee93479226bd045a5ec1f",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectSubTargetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "zoneParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "beforeImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "impactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticlePerIndex": "",
+ "activeEffectSurfaceParticlePerIndexCount": 0,
+ "emissiveBorderCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "forceApplyZoneParticle": false,
+ "applyEmissionColorOnWeapons": false,
+ "emissionColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "emissionColorFadeInDuration": 0.0,
+ "emissionColorFadeOutDuration": 0.0
+ },
+ "effectAIParameters": {
+ "$type": "EffectAIParameters, Assembly-CSharp",
+ "aoeScoreMultiplier": 1.0,
+ "cooldownForCaster": 0,
+ "cooldownForBattle": 0,
+ "sortingScoreMultiplier": 1.0,
+ "dynamicCooldown": false
+ },
+ "animationMagicEffect": "Animation0",
+ "lightCounterDispellsEffect": false,
+ "hideSavingThrowAnimation": false
+ },
+ "aiParameters": {
+ "$type": "SpellAIParameters, Assembly-CSharp",
+ "learnPriority": "Low",
+ "preparePriority": "Low"
+ },
+ "concentrationAction": "None",
+ "verboseComponent": true,
+ "somaticComponent": false,
+ "materialComponentType": "Mundane",
+ "specificMaterialComponentTag": "Diamond",
+ "specificMaterialComponentCostGp": 100,
+ "specificMaterialComponentConsumed": true,
+ "terminateOnItemUnequip": false,
+ "displayConditionDuration": false,
+ "vocalSpellSemeType": "Attack",
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Spell/&CommandSpellHaltTitle",
+ "description": "Spell/&CommandSpellHaltDescription",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "6edc0b78da56b1e4b94c3d7fb6c96dec",
+ "m_SubObjectName": "Command",
+ "m_SubObjectType": "UnityEngine.Sprite, UnityEngine.CoreModule, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "d4e87ec4-f113-5c33-b5c6-0452ab42231b",
+ "contentPack": 9999,
+ "name": "CommandSpellHalt"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateBonfire.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateBonfire.json
new file mode 100644
index 0000000000..fdc1cc5201
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateBonfire.json
@@ -0,0 +1,407 @@
+{
+ "$type": "SpellDefinition, Assembly-CSharp",
+ "spellsBundle": false,
+ "subspellsList": [],
+ "compactSubspellsTooltip": false,
+ "implemented": true,
+ "schoolOfMagic": "SchoolConjuration",
+ "spellLevel": 0,
+ "ritual": false,
+ "uniqueInstance": false,
+ "castingTime": "Action",
+ "reactionContext": "None",
+ "ritualCastingTime": "Action",
+ "requiresConcentration": true,
+ "effectDescription": {
+ "$type": "EffectDescription, Assembly-CSharp",
+ "rangeType": "Distance",
+ "rangeParameter": 6,
+ "halfDamageOnAMiss": false,
+ "hitAffinitiesByTargetTag": [],
+ "targetType": "Cube",
+ "itemSelectionType": "None",
+ "targetParameter": 1,
+ "targetParameter2": 0,
+ "emissiveBorder": "Outer",
+ "emissiveParameter": 2,
+ "requiresTargetProximity": false,
+ "targetProximityDistance": 30,
+ "targetExcludeCaster": false,
+ "canBePlacedOnCharacter": true,
+ "affectOnlyGround": false,
+ "targetFilteringMethod": "AllCharacterAndGadgets",
+ "targetFilteringTag": "No",
+ "requiresVisibilityForPosition": true,
+ "inviteOptionalAlly": false,
+ "slotTypes": [],
+ "recurrentEffect": "OnActivation, OnTurnEnd, OnEnter",
+ "retargetAfterDeath": false,
+ "retargetActionType": "Bonus",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
+ "trapRangeType": "Triggerer",
+ "targetConditionName": "",
+ "targetConditionAsset": null,
+ "targetSide": "All",
+ "durationType": "Minute",
+ "durationParameter": 1,
+ "endOfEffect": "EndOfTurn",
+ "hasSavingThrow": true,
+ "disableSavingThrowOnAllies": false,
+ "savingThrowAbility": "Dexterity",
+ "ignoreCover": false,
+ "grantedConditionOnSave": null,
+ "rollSaveOnlyIfRelevantForms": false,
+ "hasShoveRoll": false,
+ "createdByCharacter": true,
+ "difficultyClassComputation": "SpellCastingFeature",
+ "savingThrowDifficultyAbility": "Wisdom",
+ "fixedSavingThrowDifficultyClass": 10,
+ "savingThrowAffinitiesBySense": [],
+ "savingThrowAffinitiesByFamily": [],
+ "damageAffinitiesByFamily": [],
+ "advantageForEnemies": false,
+ "canBeDispersed": false,
+ "hasVelocity": false,
+ "velocityCellsPerRound": 2,
+ "velocityType": "AwayFromSourceOriginalPosition",
+ "restrictedCreatureFamilies": [],
+ "immuneCreatureFamilies": [],
+ "restrictedCharacterSizes": [],
+ "hasLimitedEffectPool": false,
+ "effectPoolAmount": 60,
+ "effectApplication": "All",
+ "effectFormFilters": [],
+ "effectForms": [
+ {
+ "$type": "EffectForm, Assembly-CSharp",
+ "formType": "Summon",
+ "addBonusMode": "None",
+ "applyLevel": "No",
+ "levelType": "ClassLevel",
+ "levelMultiplier": 1,
+ "diceByLevelTable": [],
+ "createdByCharacter": true,
+ "createdByCondition": false,
+ "hasSavingThrow": false,
+ "savingThrowAffinity": "None",
+ "dcModifier": 0,
+ "canSaveToCancel": false,
+ "saveOccurence": "EndOfTurn",
+ "summonForm": {
+ "$type": "SummonForm, Assembly-CSharp",
+ "summonType": "EffectProxy",
+ "itemDefinition": null,
+ "trackItem": false,
+ "monsterDefinitionName": "",
+ "number": 0,
+ "conditionDefinition": null,
+ "persistOnConcentrationLoss": true,
+ "decisionPackage": null,
+ "effectProxyDefinitionName": "ProxyCreateBonfire"
+ },
+ "hasFilterId": false,
+ "filterId": 0
+ },
+ {
+ "$type": "EffectForm, Assembly-CSharp",
+ "formType": "Topology",
+ "addBonusMode": "None",
+ "applyLevel": "No",
+ "levelType": "ClassLevel",
+ "levelMultiplier": 1,
+ "diceByLevelTable": [],
+ "createdByCharacter": true,
+ "createdByCondition": false,
+ "hasSavingThrow": false,
+ "savingThrowAffinity": "None",
+ "dcModifier": 0,
+ "canSaveToCancel": false,
+ "saveOccurence": "EndOfTurn",
+ "topologyForm": {
+ "$type": "TopologyForm, Assembly-CSharp",
+ "changeType": "DangerousZone",
+ "impactsFlyingCharacters": false
+ },
+ "hasFilterId": false,
+ "filterId": 0
+ },
+ {
+ "$type": "EffectForm, Assembly-CSharp",
+ "formType": "Damage",
+ "addBonusMode": "None",
+ "applyLevel": "No",
+ "levelType": "ClassLevel",
+ "levelMultiplier": 1,
+ "diceByLevelTable": [],
+ "createdByCharacter": true,
+ "createdByCondition": false,
+ "hasSavingThrow": true,
+ "savingThrowAffinity": "Negates",
+ "dcModifier": 0,
+ "canSaveToCancel": false,
+ "saveOccurence": "EndOfTurn",
+ "damageForm": {
+ "$type": "DamageForm, Assembly-CSharp",
+ "versatile": false,
+ "diceNumber": 1,
+ "dieType": "D8",
+ "overrideWithBardicInspirationDie": false,
+ "versatileDieType": "D1",
+ "bonusDamage": 0,
+ "damageType": "DamageFire",
+ "ancestryType": "Sorcerer",
+ "healFromInflictedDamage": "Never",
+ "hitPointsFloor": 0,
+ "forceKillOnZeroHp": false,
+ "specialDeathCondition": null,
+ "ignoreFlyingCharacters": false,
+ "ignoreCriticalDoubleDice": false
+ },
+ "hasFilterId": false,
+ "filterId": 0
+ }
+ ],
+ "specialFormsDescription": "",
+ "effectAdvancement": {
+ "$type": "EffectAdvancement, Assembly-CSharp",
+ "effectIncrementMethod": "CasterLevelTable",
+ "incrementMultiplier": 1,
+ "additionalTargetsPerIncrement": 0,
+ "additionalSubtargetsPerIncrement": 0,
+ "additionalDicePerIncrement": 1,
+ "additionalSpellLevelPerIncrement": 0,
+ "additionalSummonsPerIncrement": 0,
+ "additionalHPPerIncrement": 0,
+ "additionalTempHPPerIncrement": 0,
+ "additionalTargetCellsPerIncrement": 0,
+ "additionalItemBonus": 0,
+ "additionalWeaponDie": 0,
+ "alteredDuration": "None"
+ },
+ "speedType": "Instant",
+ "speedParameter": 10.0,
+ "offsetImpactTimeBasedOnDistance": false,
+ "offsetImpactTimeBasedOnDistanceFactor": 0.1,
+ "offsetImpactTimePerTarget": 0.0,
+ "effectParticleParameters": {
+ "$type": "EffectParticleParameters, Assembly-CSharp",
+ "casterParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "179010f7336fe024b8d0d1892b2386c9",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterSelfParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterQuickSpellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "targetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectSubTargetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "zoneParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "beforeImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "impactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "0337980aa6d17aa499baa006ca4dea96",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "36d6739006d39724999b07d8d8840fc6",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "786ab47a0a2827a448eadb610712686b",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticlePerIndex": "",
+ "activeEffectSurfaceParticlePerIndexCount": 0,
+ "emissiveBorderCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "e9168d3a71f96b241a436aa368035167",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "1c2affce0bafab1448dd5392598421c9",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "forceApplyZoneParticle": false,
+ "applyEmissionColorOnWeapons": false,
+ "emissionColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "emissionColorFadeInDuration": 0.0,
+ "emissionColorFadeOutDuration": 0.0
+ },
+ "effectAIParameters": {
+ "$type": "EffectAIParameters, Assembly-CSharp",
+ "aoeScoreMultiplier": 1.0,
+ "cooldownForCaster": 0,
+ "cooldownForBattle": 0,
+ "sortingScoreMultiplier": 1.0,
+ "dynamicCooldown": false
+ },
+ "animationMagicEffect": "Animation0",
+ "lightCounterDispellsEffect": false,
+ "hideSavingThrowAnimation": false
+ },
+ "aiParameters": {
+ "$type": "SpellAIParameters, Assembly-CSharp",
+ "learnPriority": "Low",
+ "preparePriority": "Low"
+ },
+ "concentrationAction": "None",
+ "verboseComponent": true,
+ "somaticComponent": true,
+ "materialComponentType": "None",
+ "specificMaterialComponentTag": "Diamond",
+ "specificMaterialComponentCostGp": 100,
+ "specificMaterialComponentConsumed": true,
+ "terminateOnItemUnequip": false,
+ "displayConditionDuration": false,
+ "vocalSpellSemeType": "Attack",
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Spell/&CreateBonfireTitle",
+ "description": "Spell/&CreateBonfireDescription",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "980d155a-27a5-504d-bff0-259234b00eeb",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "3f2e87e8-860f-58ce-b347-b54c8d6581ac",
+ "contentPack": 9999,
+ "name": "CreateBonfire"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenGhost.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenGhost.json
index d9bb21bdfd..b8dc76c389 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenGhost.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenGhost.json
@@ -97,7 +97,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenGhoul.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenGhoul.json
index eea0d57546..1bbf85c49d 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenGhoul.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenGhoul.json
@@ -97,7 +97,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenSkeleton.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenSkeleton.json
index 8064ccfce0..b6d5a6f925 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenSkeleton.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenSkeleton.json
@@ -97,7 +97,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenSkeleton_Archer.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenSkeleton_Archer.json
index d2f1c5e367..7ac84a8c7b 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenSkeleton_Archer.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenSkeleton_Archer.json
@@ -97,7 +97,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenSkeleton_Enforcer.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenSkeleton_Enforcer.json
index c7f61a3044..19954ee760 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenSkeleton_Enforcer.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenSkeleton_Enforcer.json
@@ -97,7 +97,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenSkeleton_Knight.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenSkeleton_Knight.json
index b753903e53..14318d694e 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenSkeleton_Knight.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenSkeleton_Knight.json
@@ -97,7 +97,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenSkeleton_Marksman.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenSkeleton_Marksman.json
index d238fd9e46..0b59d9e65a 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenSkeleton_Marksman.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenSkeleton_Marksman.json
@@ -97,7 +97,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenWight.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenWight.json
index 3ad8163888..5290a5a461 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenWight.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenWight.json
@@ -97,7 +97,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenWightLord.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenWightLord.json
index 7e23d5e3b9..79c59d1fc1 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenWightLord.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CreateDeadRisenWightLord.json
@@ -97,7 +97,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CrownOfStars.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CrownOfStars.json
index 910a453ec3..a89a8a2dfd 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CrownOfStars.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CrownOfStars.json
@@ -25,11 +25,11 @@
"emissiveBorder": "None",
"emissiveParameter": 1,
"requiresTargetProximity": false,
- "targetProximityDistance": 6,
+ "targetProximityDistance": 30,
"targetExcludeCaster": false,
"canBePlacedOnCharacter": true,
"affectOnlyGround": false,
- "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringMethod": "AllCharacterAndGadgets",
"targetFilteringTag": "No",
"requiresVisibilityForPosition": true,
"inviteOptionalAlly": false,
@@ -47,7 +47,7 @@
"durationParameter": 1,
"endOfEffect": "EndOfTurn",
"hasSavingThrow": false,
- "disableSavingThrowOnAllies": false,
+ "disableSavingThrowOnAllies": true,
"savingThrowAbility": "Dexterity",
"ignoreCover": false,
"grantedConditionOnSave": null,
@@ -122,14 +122,14 @@
"dimAdditionalRange": 6,
"color": {
"$type": "UnityEngine.Color, UnityEngine.CoreModule",
- "r": 1.0,
- "g": 0.9778601,
- "b": 0.78039217,
+ "r": 0.8396226,
+ "g": 0.7766465,
+ "b": 0.5505073,
"a": 1.0
},
"graphicsPrefabReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "3e4cdebecc6e0db469720619529e3dc2",
+ "m_AssetGUID": "fc7cb53da57a8fb40a278d62a885ce58",
"m_SubObjectName": "",
"m_SubObjectType": ""
},
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CrusadersMantle.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CrusadersMantle.json
index 7d9ea1810e..7efe7c1e2d 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CrusadersMantle.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/CrusadersMantle.json
@@ -37,8 +37,8 @@
"recurrentEffect": "OnActivation, OnTurnStart, OnEnter",
"retargetAfterDeath": false,
"retargetActionType": "Bonus",
- "poolFilterDiceNumber": 0,
- "poolFilterDieType": "D1",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
"trapRangeType": "Triggerer",
"targetConditionName": "",
"targetConditionAsset": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/Dawn.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/Dawn.json
index fbe5295baa..60e0793053 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/Dawn.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/Dawn.json
@@ -45,7 +45,7 @@
"targetSide": "All",
"durationType": "Minute",
"durationParameter": 1,
- "endOfEffect": "StartOfTurn",
+ "endOfEffect": "EndOfTurn",
"hasSavingThrow": true,
"disableSavingThrowOnAllies": false,
"savingThrowAbility": "Constitution",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/DissonantWhispers.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/DissonantWhispers.json
new file mode 100644
index 0000000000..f67fb88e24
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/DissonantWhispers.json
@@ -0,0 +1,354 @@
+{
+ "$type": "SpellDefinition, Assembly-CSharp",
+ "spellsBundle": false,
+ "subspellsList": [],
+ "compactSubspellsTooltip": false,
+ "implemented": true,
+ "schoolOfMagic": "SchoolEnchantment",
+ "spellLevel": 1,
+ "ritual": false,
+ "uniqueInstance": false,
+ "castingTime": "Action",
+ "reactionContext": "None",
+ "ritualCastingTime": "Action",
+ "requiresConcentration": false,
+ "effectDescription": {
+ "$type": "EffectDescription, Assembly-CSharp",
+ "rangeType": "Distance",
+ "rangeParameter": 12,
+ "halfDamageOnAMiss": false,
+ "hitAffinitiesByTargetTag": [],
+ "targetType": "IndividualsUnique",
+ "itemSelectionType": "None",
+ "targetParameter": 1,
+ "targetParameter2": 2,
+ "emissiveBorder": "None",
+ "emissiveParameter": 1,
+ "requiresTargetProximity": false,
+ "targetProximityDistance": 6,
+ "targetExcludeCaster": false,
+ "canBePlacedOnCharacter": true,
+ "affectOnlyGround": false,
+ "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringTag": "No",
+ "requiresVisibilityForPosition": true,
+ "inviteOptionalAlly": false,
+ "slotTypes": [],
+ "recurrentEffect": "No",
+ "retargetAfterDeath": false,
+ "retargetActionType": "Bonus",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
+ "trapRangeType": "Triggerer",
+ "targetConditionName": "",
+ "targetConditionAsset": null,
+ "targetSide": "Enemy",
+ "durationType": "Instantaneous",
+ "durationParameter": 1,
+ "endOfEffect": "EndOfTurn",
+ "hasSavingThrow": true,
+ "disableSavingThrowOnAllies": false,
+ "savingThrowAbility": "Wisdom",
+ "ignoreCover": true,
+ "grantedConditionOnSave": null,
+ "rollSaveOnlyIfRelevantForms": false,
+ "hasShoveRoll": false,
+ "createdByCharacter": true,
+ "difficultyClassComputation": "SpellCastingFeature",
+ "savingThrowDifficultyAbility": "Wisdom",
+ "fixedSavingThrowDifficultyClass": 10,
+ "savingThrowAffinitiesBySense": [],
+ "savingThrowAffinitiesByFamily": [],
+ "damageAffinitiesByFamily": [],
+ "advantageForEnemies": false,
+ "canBeDispersed": false,
+ "hasVelocity": false,
+ "velocityCellsPerRound": 2,
+ "velocityType": "AwayFromSourceOriginalPosition",
+ "restrictedCreatureFamilies": [],
+ "immuneCreatureFamilies": [],
+ "restrictedCharacterSizes": [],
+ "hasLimitedEffectPool": false,
+ "effectPoolAmount": 60,
+ "effectApplication": "All",
+ "effectFormFilters": [],
+ "effectForms": [
+ {
+ "$type": "EffectForm, Assembly-CSharp",
+ "formType": "Damage",
+ "addBonusMode": "None",
+ "applyLevel": "No",
+ "levelType": "ClassLevel",
+ "levelMultiplier": 1,
+ "diceByLevelTable": [],
+ "createdByCharacter": true,
+ "createdByCondition": false,
+ "hasSavingThrow": true,
+ "savingThrowAffinity": "HalfDamage",
+ "dcModifier": 0,
+ "canSaveToCancel": false,
+ "saveOccurence": "EndOfTurn",
+ "damageForm": {
+ "$type": "DamageForm, Assembly-CSharp",
+ "versatile": false,
+ "diceNumber": 3,
+ "dieType": "D6",
+ "overrideWithBardicInspirationDie": false,
+ "versatileDieType": "D1",
+ "bonusDamage": 0,
+ "damageType": "DamagePsychic",
+ "ancestryType": "Sorcerer",
+ "healFromInflictedDamage": "Never",
+ "hitPointsFloor": 0,
+ "forceKillOnZeroHp": false,
+ "specialDeathCondition": null,
+ "ignoreFlyingCharacters": false,
+ "ignoreCriticalDoubleDice": false
+ },
+ "hasFilterId": false,
+ "filterId": 0
+ }
+ ],
+ "specialFormsDescription": "",
+ "effectAdvancement": {
+ "$type": "EffectAdvancement, Assembly-CSharp",
+ "effectIncrementMethod": "PerAdditionalSlotLevel",
+ "incrementMultiplier": 1,
+ "additionalTargetsPerIncrement": 0,
+ "additionalSubtargetsPerIncrement": 0,
+ "additionalDicePerIncrement": 1,
+ "additionalSpellLevelPerIncrement": 0,
+ "additionalSummonsPerIncrement": 0,
+ "additionalHPPerIncrement": 0,
+ "additionalTempHPPerIncrement": 0,
+ "additionalTargetCellsPerIncrement": 0,
+ "additionalItemBonus": 0,
+ "additionalWeaponDie": 0,
+ "alteredDuration": "None"
+ },
+ "speedType": "Instant",
+ "speedParameter": 10.0,
+ "offsetImpactTimeBasedOnDistance": false,
+ "offsetImpactTimeBasedOnDistanceFactor": 0.1,
+ "offsetImpactTimePerTarget": 0.0,
+ "effectParticleParameters": {
+ "$type": "EffectParticleParameters, Assembly-CSharp",
+ "casterParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "3bbee0a8901577e4bb5b9c9f198695c5",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterSelfParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterQuickSpellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "targetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "be5fe98c7e555f94684032e273a1129a",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectSubTargetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "zoneParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "beforeImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "impactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticlePerIndex": "",
+ "activeEffectSurfaceParticlePerIndexCount": 0,
+ "emissiveBorderCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "forceApplyZoneParticle": false,
+ "applyEmissionColorOnWeapons": false,
+ "emissionColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "emissionColorFadeInDuration": 0.0,
+ "emissionColorFadeOutDuration": 0.0
+ },
+ "effectAIParameters": {
+ "$type": "EffectAIParameters, Assembly-CSharp",
+ "aoeScoreMultiplier": 1.0,
+ "cooldownForCaster": 0,
+ "cooldownForBattle": 0,
+ "sortingScoreMultiplier": 1.0,
+ "dynamicCooldown": false
+ },
+ "animationMagicEffect": "Animation0",
+ "lightCounterDispellsEffect": false,
+ "hideSavingThrowAnimation": false
+ },
+ "aiParameters": {
+ "$type": "SpellAIParameters, Assembly-CSharp",
+ "learnPriority": "Low",
+ "preparePriority": "Low"
+ },
+ "concentrationAction": "None",
+ "verboseComponent": true,
+ "somaticComponent": false,
+ "materialComponentType": "Mundane",
+ "specificMaterialComponentTag": "Diamond",
+ "specificMaterialComponentCostGp": 100,
+ "specificMaterialComponentConsumed": true,
+ "terminateOnItemUnequip": false,
+ "displayConditionDuration": false,
+ "vocalSpellSemeType": "Attack",
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Spell/&DissonantWhispersTitle",
+ "description": "Spell/&DissonantWhispersDescription",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "6b5b3868-2125-599d-a33d-8122477ebb41",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "a3308f76-57c3-56a7-acaa-9c505d7fdaa7",
+ "contentPack": 9999,
+ "name": "DissonantWhispers"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/EnduringSting.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/EnduringSting.json
index dfbb2c3a8c..9b5baf4347 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/EnduringSting.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/EnduringSting.json
@@ -37,8 +37,8 @@
"recurrentEffect": "No",
"retargetAfterDeath": false,
"retargetActionType": "Bonus",
- "poolFilterDiceNumber": 0,
- "poolFilterDieType": "D1",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
"trapRangeType": "Triggerer",
"targetConditionName": "",
"targetConditionAsset": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/FindFamiliar.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/FindFamiliar.json
index 4ab31e5981..38e24c8b22 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/FindFamiliar.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/FindFamiliar.json
@@ -97,7 +97,7 @@
"number": 1,
"conditionDefinition": "Definition:ConditionMindControlledByCaster:72691050707821744968bd0595150b86",
"persistOnConcentrationLoss": false,
- "decisionPackage": "Definition:IdleGuard_Default:232428b431ff2414eb8254fb1e9e4cf1",
+ "decisionPackage": null,
"effectProxyDefinitionName": null
},
"hasFilterId": false,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/FizbanPlatinumShield.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/FizbanPlatinumShield.json
index fb25d77704..b389aae08f 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/FizbanPlatinumShield.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/FizbanPlatinumShield.json
@@ -25,11 +25,11 @@
"emissiveBorder": "None",
"emissiveParameter": 1,
"requiresTargetProximity": false,
- "targetProximityDistance": 6,
+ "targetProximityDistance": 30,
"targetExcludeCaster": false,
"canBePlacedOnCharacter": true,
"affectOnlyGround": false,
- "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringMethod": "AllCharacterAndGadgets",
"targetFilteringTag": "No",
"requiresVisibilityForPosition": true,
"inviteOptionalAlly": false,
@@ -47,7 +47,7 @@
"durationParameter": 1,
"endOfEffect": "EndOfTurn",
"hasSavingThrow": false,
- "disableSavingThrowOnAllies": false,
+ "disableSavingThrowOnAllies": true,
"savingThrowAbility": "Dexterity",
"ignoreCover": false,
"grantedConditionOnSave": null,
@@ -122,14 +122,14 @@
"dimAdditionalRange": 6,
"color": {
"$type": "UnityEngine.Color, UnityEngine.CoreModule",
- "r": 1.0,
- "g": 0.9778601,
- "b": 0.78039217,
+ "r": 0.8396226,
+ "g": 0.7766465,
+ "b": 0.5505073,
"a": 1.0
},
"graphicsPrefabReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "3e4cdebecc6e0db469720619529e3dc2",
+ "m_AssetGUID": "fc7cb53da57a8fb40a278d62a885ce58",
"m_SubObjectName": "",
"m_SubObjectType": ""
},
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ForestGuardian.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ForestGuardian.json
index a41ec538c1..78e1c861a9 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ForestGuardian.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/ForestGuardian.json
@@ -48,7 +48,7 @@
"targetSide": "Ally",
"durationType": "Minute",
"durationParameter": 1,
- "endOfEffect": "EndOfSourceTurn",
+ "endOfEffect": "EndOfTurn",
"hasSavingThrow": false,
"disableSavingThrowOnAllies": false,
"savingThrowAbility": "Dexterity",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/Glibness.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/Glibness.json
new file mode 100644
index 0000000000..01a2dc9d57
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/Glibness.json
@@ -0,0 +1,346 @@
+{
+ "$type": "SpellDefinition, Assembly-CSharp",
+ "spellsBundle": false,
+ "subspellsList": [],
+ "compactSubspellsTooltip": false,
+ "implemented": true,
+ "schoolOfMagic": "SchoolTransmutation",
+ "spellLevel": 8,
+ "ritual": false,
+ "uniqueInstance": false,
+ "castingTime": "Action",
+ "reactionContext": "None",
+ "ritualCastingTime": "Action",
+ "requiresConcentration": false,
+ "effectDescription": {
+ "$type": "EffectDescription, Assembly-CSharp",
+ "rangeType": "Self",
+ "rangeParameter": 0,
+ "halfDamageOnAMiss": false,
+ "hitAffinitiesByTargetTag": [],
+ "targetType": "Self",
+ "itemSelectionType": "None",
+ "targetParameter": 1,
+ "targetParameter2": 2,
+ "emissiveBorder": "None",
+ "emissiveParameter": 1,
+ "requiresTargetProximity": false,
+ "targetProximityDistance": 6,
+ "targetExcludeCaster": false,
+ "canBePlacedOnCharacter": true,
+ "affectOnlyGround": false,
+ "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringTag": "No",
+ "requiresVisibilityForPosition": true,
+ "inviteOptionalAlly": false,
+ "slotTypes": [],
+ "recurrentEffect": "No",
+ "retargetAfterDeath": false,
+ "retargetActionType": "Bonus",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
+ "trapRangeType": "Triggerer",
+ "targetConditionName": "",
+ "targetConditionAsset": null,
+ "targetSide": "All",
+ "durationType": "Hour",
+ "durationParameter": 1,
+ "endOfEffect": "EndOfTurn",
+ "hasSavingThrow": false,
+ "disableSavingThrowOnAllies": false,
+ "savingThrowAbility": "Dexterity",
+ "ignoreCover": false,
+ "grantedConditionOnSave": null,
+ "rollSaveOnlyIfRelevantForms": false,
+ "hasShoveRoll": false,
+ "createdByCharacter": true,
+ "difficultyClassComputation": "SpellCastingFeature",
+ "savingThrowDifficultyAbility": "Wisdom",
+ "fixedSavingThrowDifficultyClass": 15,
+ "savingThrowAffinitiesBySense": [],
+ "savingThrowAffinitiesByFamily": [],
+ "damageAffinitiesByFamily": [],
+ "advantageForEnemies": false,
+ "canBeDispersed": false,
+ "hasVelocity": false,
+ "velocityCellsPerRound": 2,
+ "velocityType": "AwayFromSourceOriginalPosition",
+ "restrictedCreatureFamilies": [],
+ "immuneCreatureFamilies": [],
+ "restrictedCharacterSizes": [],
+ "hasLimitedEffectPool": false,
+ "effectPoolAmount": 60,
+ "effectApplication": "All",
+ "effectFormFilters": [],
+ "effectForms": [
+ {
+ "$type": "EffectForm, Assembly-CSharp",
+ "formType": "Condition",
+ "addBonusMode": "None",
+ "applyLevel": "No",
+ "levelType": "ClassLevel",
+ "levelMultiplier": 1,
+ "diceByLevelTable": [],
+ "createdByCharacter": true,
+ "createdByCondition": false,
+ "hasSavingThrow": false,
+ "savingThrowAffinity": "None",
+ "dcModifier": 0,
+ "canSaveToCancel": false,
+ "saveOccurence": "EndOfTurn",
+ "conditionForm": {
+ "$type": "ConditionForm, Assembly-CSharp",
+ "conditionDefinitionName": "ConditionGlibness",
+ "conditionDefinition": "Definition:ConditionGlibness:3182a19d-2d56-5f7a-849b-c2b28c7536b5",
+ "operation": "Add",
+ "conditionsList": [],
+ "applyToSelf": false,
+ "forceOnSelf": false
+ },
+ "hasFilterId": false,
+ "filterId": 0
+ }
+ ],
+ "specialFormsDescription": "",
+ "effectAdvancement": {
+ "$type": "EffectAdvancement, Assembly-CSharp",
+ "effectIncrementMethod": "None",
+ "incrementMultiplier": 1,
+ "additionalTargetsPerIncrement": 0,
+ "additionalSubtargetsPerIncrement": 0,
+ "additionalDicePerIncrement": 0,
+ "additionalSpellLevelPerIncrement": 0,
+ "additionalSummonsPerIncrement": 0,
+ "additionalHPPerIncrement": 0,
+ "additionalTempHPPerIncrement": 0,
+ "additionalTargetCellsPerIncrement": 0,
+ "additionalItemBonus": 0,
+ "additionalWeaponDie": 0,
+ "alteredDuration": "None"
+ },
+ "speedType": "Instant",
+ "speedParameter": 10.0,
+ "offsetImpactTimeBasedOnDistance": false,
+ "offsetImpactTimeBasedOnDistanceFactor": 0.1,
+ "offsetImpactTimePerTarget": 0.0,
+ "effectParticleParameters": {
+ "$type": "EffectParticleParameters, Assembly-CSharp",
+ "casterParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "571a64165c20f514eb4d4e632a93fff4",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterSelfParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "b8e3910dc27fdf743ab63e37bc90ba01",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterQuickSpellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "targetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "440ce6c2017fc654fa1accc32e030c96",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectSubTargetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "zoneParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "beforeImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "impactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticlePerIndex": "",
+ "activeEffectSurfaceParticlePerIndexCount": 0,
+ "emissiveBorderCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "forceApplyZoneParticle": false,
+ "applyEmissionColorOnWeapons": false,
+ "emissionColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "emissionColorFadeInDuration": 0.0,
+ "emissionColorFadeOutDuration": 0.0
+ },
+ "effectAIParameters": {
+ "$type": "EffectAIParameters, Assembly-CSharp",
+ "aoeScoreMultiplier": 1.0,
+ "cooldownForCaster": 0,
+ "cooldownForBattle": 0,
+ "sortingScoreMultiplier": 1.0,
+ "dynamicCooldown": false
+ },
+ "animationMagicEffect": "Animation0",
+ "lightCounterDispellsEffect": false,
+ "hideSavingThrowAnimation": false
+ },
+ "aiParameters": {
+ "$type": "SpellAIParameters, Assembly-CSharp",
+ "learnPriority": "Low",
+ "preparePriority": "Low"
+ },
+ "concentrationAction": "None",
+ "verboseComponent": true,
+ "somaticComponent": false,
+ "materialComponentType": "None",
+ "specificMaterialComponentTag": "Diamond",
+ "specificMaterialComponentCostGp": 100,
+ "specificMaterialComponentConsumed": true,
+ "terminateOnItemUnequip": false,
+ "displayConditionDuration": false,
+ "vocalSpellSemeType": "Buff",
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Spell/&GlibnessTitle",
+ "description": "Spell/&GlibnessDescription",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "b1b3864d-84d0-5132-b2c0-f1144c4bf2eb",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "6fff4ed6-1408-5410-9bb6-16392e1e6b15",
+ "contentPack": 9999,
+ "name": "Glibness"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/GravityFissure.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/GravityFissure.json
new file mode 100644
index 0000000000..dceca18364
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/GravityFissure.json
@@ -0,0 +1,377 @@
+{
+ "$type": "SpellDefinition, Assembly-CSharp",
+ "spellsBundle": false,
+ "subspellsList": [],
+ "compactSubspellsTooltip": false,
+ "implemented": true,
+ "schoolOfMagic": "SchoolEvocation",
+ "spellLevel": 6,
+ "ritual": false,
+ "uniqueInstance": false,
+ "castingTime": "Action",
+ "reactionContext": "None",
+ "ritualCastingTime": "Action",
+ "requiresConcentration": false,
+ "effectDescription": {
+ "$type": "EffectDescription, Assembly-CSharp",
+ "rangeType": "Self",
+ "rangeParameter": 1,
+ "halfDamageOnAMiss": false,
+ "hitAffinitiesByTargetTag": [],
+ "targetType": "Line",
+ "itemSelectionType": "None",
+ "targetParameter": 12,
+ "targetParameter2": 2,
+ "emissiveBorder": "None",
+ "emissiveParameter": 1,
+ "requiresTargetProximity": false,
+ "targetProximityDistance": 6,
+ "targetExcludeCaster": false,
+ "canBePlacedOnCharacter": true,
+ "affectOnlyGround": false,
+ "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringTag": "NotFlying",
+ "requiresVisibilityForPosition": true,
+ "inviteOptionalAlly": false,
+ "slotTypes": [],
+ "recurrentEffect": "OnActivation",
+ "retargetAfterDeath": false,
+ "retargetActionType": "None",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
+ "trapRangeType": "Triggerer",
+ "targetConditionName": "",
+ "targetConditionAsset": null,
+ "targetSide": "All",
+ "durationType": "Round",
+ "durationParameter": 0,
+ "endOfEffect": "EndOfTurn",
+ "hasSavingThrow": true,
+ "disableSavingThrowOnAllies": false,
+ "savingThrowAbility": "Constitution",
+ "ignoreCover": true,
+ "grantedConditionOnSave": null,
+ "rollSaveOnlyIfRelevantForms": false,
+ "hasShoveRoll": false,
+ "createdByCharacter": true,
+ "difficultyClassComputation": "SpellCastingFeature",
+ "savingThrowDifficultyAbility": "Wisdom",
+ "fixedSavingThrowDifficultyClass": 10,
+ "savingThrowAffinitiesBySense": [],
+ "savingThrowAffinitiesByFamily": [],
+ "damageAffinitiesByFamily": [],
+ "advantageForEnemies": false,
+ "canBeDispersed": false,
+ "hasVelocity": false,
+ "velocityCellsPerRound": 2,
+ "velocityType": "AwayFromSourceOriginalPosition",
+ "restrictedCreatureFamilies": [],
+ "immuneCreatureFamilies": [],
+ "restrictedCharacterSizes": [],
+ "hasLimitedEffectPool": false,
+ "effectPoolAmount": 60,
+ "effectApplication": "All",
+ "effectFormFilters": [],
+ "effectForms": [
+ {
+ "$type": "EffectForm, Assembly-CSharp",
+ "formType": "Damage",
+ "addBonusMode": "None",
+ "applyLevel": "No",
+ "levelType": "ClassLevel",
+ "levelMultiplier": 1,
+ "diceByLevelTable": [],
+ "createdByCharacter": true,
+ "createdByCondition": false,
+ "hasSavingThrow": true,
+ "savingThrowAffinity": "HalfDamage",
+ "dcModifier": 0,
+ "canSaveToCancel": false,
+ "saveOccurence": "EndOfTurn",
+ "damageForm": {
+ "$type": "DamageForm, Assembly-CSharp",
+ "versatile": false,
+ "diceNumber": 8,
+ "dieType": "D8",
+ "overrideWithBardicInspirationDie": false,
+ "versatileDieType": "D1",
+ "bonusDamage": 0,
+ "damageType": "DamageForce",
+ "ancestryType": "Sorcerer",
+ "healFromInflictedDamage": "Never",
+ "hitPointsFloor": 0,
+ "forceKillOnZeroHp": false,
+ "specialDeathCondition": null,
+ "ignoreFlyingCharacters": false,
+ "ignoreCriticalDoubleDice": false
+ },
+ "hasFilterId": false,
+ "filterId": 0
+ },
+ {
+ "$type": "EffectForm, Assembly-CSharp",
+ "formType": "Topology",
+ "addBonusMode": "None",
+ "applyLevel": "No",
+ "levelType": "ClassLevel",
+ "levelMultiplier": 1,
+ "diceByLevelTable": [],
+ "createdByCharacter": true,
+ "createdByCondition": false,
+ "hasSavingThrow": false,
+ "savingThrowAffinity": "None",
+ "dcModifier": 0,
+ "canSaveToCancel": false,
+ "saveOccurence": "EndOfTurn",
+ "topologyForm": {
+ "$type": "TopologyForm, Assembly-CSharp",
+ "changeType": "DangerousZone",
+ "impactsFlyingCharacters": false
+ },
+ "hasFilterId": false,
+ "filterId": 0
+ }
+ ],
+ "specialFormsDescription": "",
+ "effectAdvancement": {
+ "$type": "EffectAdvancement, Assembly-CSharp",
+ "effectIncrementMethod": "PerAdditionalSlotLevel",
+ "incrementMultiplier": 1,
+ "additionalTargetsPerIncrement": 0,
+ "additionalSubtargetsPerIncrement": 0,
+ "additionalDicePerIncrement": 1,
+ "additionalSpellLevelPerIncrement": 0,
+ "additionalSummonsPerIncrement": 0,
+ "additionalHPPerIncrement": 0,
+ "additionalTempHPPerIncrement": 0,
+ "additionalTargetCellsPerIncrement": 0,
+ "additionalItemBonus": 0,
+ "additionalWeaponDie": 0,
+ "alteredDuration": "None"
+ },
+ "speedType": "Instant",
+ "speedParameter": 10.0,
+ "offsetImpactTimeBasedOnDistance": false,
+ "offsetImpactTimeBasedOnDistanceFactor": 0.1,
+ "offsetImpactTimePerTarget": 0.0,
+ "effectParticleParameters": {
+ "$type": "EffectParticleParameters, Assembly-CSharp",
+ "casterParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "4cd9d54e34323a640b05b2f1f7a67ff8",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterSelfParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterQuickSpellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "targetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectSubTargetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "zoneParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "beforeImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "impactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "570add77272f276419384de82fce1d15",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "0cf7d6b4dc876b44fbe88623cfeb3959",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "6c17be351f2b9ff4aa1185d493235050",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "078a274c32322044baa5a19b901d5f4f",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "780bc00265f8d9f49bc6db61627acb92",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticlePerIndex": "Earthquake",
+ "activeEffectSurfaceParticlePerIndexCount": 0,
+ "emissiveBorderCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "forceApplyZoneParticle": false,
+ "applyEmissionColorOnWeapons": false,
+ "emissionColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "emissionColorFadeInDuration": 0.0,
+ "emissionColorFadeOutDuration": 0.0
+ },
+ "effectAIParameters": {
+ "$type": "EffectAIParameters, Assembly-CSharp",
+ "aoeScoreMultiplier": 1.0,
+ "cooldownForCaster": 0,
+ "cooldownForBattle": 0,
+ "sortingScoreMultiplier": 1.0,
+ "dynamicCooldown": false
+ },
+ "animationMagicEffect": "Animation0",
+ "lightCounterDispellsEffect": false,
+ "hideSavingThrowAnimation": false
+ },
+ "aiParameters": {
+ "$type": "SpellAIParameters, Assembly-CSharp",
+ "learnPriority": "Low",
+ "preparePriority": "Low"
+ },
+ "concentrationAction": "None",
+ "verboseComponent": true,
+ "somaticComponent": true,
+ "materialComponentType": "Mundane",
+ "specificMaterialComponentTag": "Diamond",
+ "specificMaterialComponentCostGp": 100,
+ "specificMaterialComponentConsumed": true,
+ "terminateOnItemUnequip": false,
+ "displayConditionDuration": false,
+ "vocalSpellSemeType": "Attack",
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Spell/&GravityFissureTitle",
+ "description": "Spell/&GravityFissureDescription",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "543799d2-0a37-5662-8cb5-9ac355c09595",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "e230eac9-00f7-5e9f-86f8-51c2796721cd",
+ "contentPack": 9999,
+ "name": "GravityFissure"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/HolyWeapon.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/HolyWeapon.json
new file mode 100644
index 0000000000..5442771dc7
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/HolyWeapon.json
@@ -0,0 +1,415 @@
+{
+ "$type": "SpellDefinition, Assembly-CSharp",
+ "spellsBundle": false,
+ "subspellsList": [],
+ "compactSubspellsTooltip": false,
+ "implemented": true,
+ "schoolOfMagic": "SchoolEvocation",
+ "spellLevel": 5,
+ "ritual": false,
+ "uniqueInstance": false,
+ "castingTime": "Action",
+ "reactionContext": "None",
+ "ritualCastingTime": "Action",
+ "requiresConcentration": true,
+ "effectDescription": {
+ "$type": "EffectDescription, Assembly-CSharp",
+ "rangeType": "Touch",
+ "rangeParameter": 0,
+ "halfDamageOnAMiss": false,
+ "hitAffinitiesByTargetTag": [],
+ "targetType": "Item",
+ "itemSelectionType": "EquippedNoLightSource",
+ "targetParameter": 1,
+ "targetParameter2": 2,
+ "emissiveBorder": "None",
+ "emissiveParameter": 1,
+ "requiresTargetProximity": false,
+ "targetProximityDistance": 30,
+ "targetExcludeCaster": false,
+ "canBePlacedOnCharacter": true,
+ "affectOnlyGround": false,
+ "targetFilteringMethod": "AllCharacterAndGadgets",
+ "targetFilteringTag": "No",
+ "requiresVisibilityForPosition": true,
+ "inviteOptionalAlly": false,
+ "slotTypes": [],
+ "recurrentEffect": "No",
+ "retargetAfterDeath": false,
+ "retargetActionType": "Bonus",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
+ "trapRangeType": "Triggerer",
+ "targetConditionName": "",
+ "targetConditionAsset": null,
+ "targetSide": "Enemy",
+ "durationType": "Hour",
+ "durationParameter": 1,
+ "endOfEffect": "EndOfTurn",
+ "hasSavingThrow": false,
+ "disableSavingThrowOnAllies": true,
+ "savingThrowAbility": "Dexterity",
+ "ignoreCover": false,
+ "grantedConditionOnSave": null,
+ "rollSaveOnlyIfRelevantForms": false,
+ "hasShoveRoll": false,
+ "createdByCharacter": true,
+ "difficultyClassComputation": "SpellCastingFeature",
+ "savingThrowDifficultyAbility": "Wisdom",
+ "fixedSavingThrowDifficultyClass": 15,
+ "savingThrowAffinitiesBySense": [],
+ "savingThrowAffinitiesByFamily": [],
+ "damageAffinitiesByFamily": [],
+ "advantageForEnemies": false,
+ "canBeDispersed": false,
+ "hasVelocity": false,
+ "velocityCellsPerRound": 2,
+ "velocityType": "AwayFromSourceOriginalPosition",
+ "restrictedCreatureFamilies": [],
+ "immuneCreatureFamilies": [],
+ "restrictedCharacterSizes": [],
+ "hasLimitedEffectPool": false,
+ "effectPoolAmount": 60,
+ "effectApplication": "All",
+ "effectFormFilters": [],
+ "effectForms": [
+ {
+ "$type": "EffectForm, Assembly-CSharp",
+ "formType": "LightSource",
+ "addBonusMode": "None",
+ "applyLevel": "No",
+ "levelType": "ClassLevel",
+ "levelMultiplier": 1,
+ "diceByLevelTable": [],
+ "createdByCharacter": true,
+ "createdByCondition": false,
+ "hasSavingThrow": false,
+ "savingThrowAffinity": "None",
+ "dcModifier": 0,
+ "canSaveToCancel": false,
+ "saveOccurence": "EndOfTurn",
+ "lightSourceForm": {
+ "$type": "LightSourceForm, Assembly-CSharp",
+ "lightSourceType": "Basic",
+ "brightRange": 6,
+ "dimAdditionalRange": 6,
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.8396226,
+ "g": 0.7766465,
+ "b": 0.5505073,
+ "a": 1.0
+ },
+ "graphicsPrefabReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "fc7cb53da57a8fb40a278d62a885ce58",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "applyToSelf": false,
+ "forceOnSelf": false
+ },
+ "hasFilterId": false,
+ "filterId": 0
+ },
+ {
+ "$type": "EffectForm, Assembly-CSharp",
+ "formType": "ItemProperty",
+ "addBonusMode": "None",
+ "applyLevel": "No",
+ "levelType": "ClassLevel",
+ "levelMultiplier": 1,
+ "diceByLevelTable": [],
+ "createdByCharacter": true,
+ "createdByCondition": false,
+ "hasSavingThrow": false,
+ "savingThrowAffinity": "None",
+ "dcModifier": 0,
+ "canSaveToCancel": false,
+ "saveOccurence": "EndOfTurn",
+ "itemPropertyForm": {
+ "$type": "ItemPropertyForm, Assembly-CSharp",
+ "featureBySlotLevel": [
+ {
+ "$type": "FeatureUnlockByLevel, Assembly-CSharp",
+ "featureDefinition": "Definition:AdditionalDamageHolyWeapon:a818b04d-36eb-554a-921b-a4e00c1ac999",
+ "level": 0
+ }
+ ],
+ "usageLimitation": "Unlimited",
+ "useAmount": 0
+ },
+ "hasFilterId": false,
+ "filterId": 0
+ },
+ {
+ "$type": "EffectForm, Assembly-CSharp",
+ "formType": "Condition",
+ "addBonusMode": "None",
+ "applyLevel": "No",
+ "levelType": "ClassLevel",
+ "levelMultiplier": 1,
+ "diceByLevelTable": [],
+ "createdByCharacter": true,
+ "createdByCondition": false,
+ "hasSavingThrow": false,
+ "savingThrowAffinity": "None",
+ "dcModifier": 0,
+ "canSaveToCancel": false,
+ "saveOccurence": "EndOfTurn",
+ "conditionForm": {
+ "$type": "ConditionForm, Assembly-CSharp",
+ "conditionDefinitionName": "ConditionHolyWeapon",
+ "conditionDefinition": "Definition:ConditionHolyWeapon:4abe721f-d87f-519b-a35d-152100b60eb4",
+ "operation": "Add",
+ "conditionsList": [],
+ "applyToSelf": true,
+ "forceOnSelf": false
+ },
+ "hasFilterId": false,
+ "filterId": 0
+ }
+ ],
+ "specialFormsDescription": "",
+ "effectAdvancement": {
+ "$type": "EffectAdvancement, Assembly-CSharp",
+ "effectIncrementMethod": "None",
+ "incrementMultiplier": 1,
+ "additionalTargetsPerIncrement": 0,
+ "additionalSubtargetsPerIncrement": 0,
+ "additionalDicePerIncrement": 0,
+ "additionalSpellLevelPerIncrement": 0,
+ "additionalSummonsPerIncrement": 0,
+ "additionalHPPerIncrement": 0,
+ "additionalTempHPPerIncrement": 0,
+ "additionalTargetCellsPerIncrement": 0,
+ "additionalItemBonus": 0,
+ "additionalWeaponDie": 0,
+ "alteredDuration": "None"
+ },
+ "speedType": "Instant",
+ "speedParameter": 10.0,
+ "offsetImpactTimeBasedOnDistance": false,
+ "offsetImpactTimeBasedOnDistanceFactor": 0.1,
+ "offsetImpactTimePerTarget": 0.0,
+ "effectParticleParameters": {
+ "$type": "EffectParticleParameters, Assembly-CSharp",
+ "casterParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "4abc0a06a6ee59f4cb038a8d983cba4a",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterSelfParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterQuickSpellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "targetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "440ce6c2017fc654fa1accc32e030c96",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectSubTargetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "zoneParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "beforeImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "impactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticlePerIndex": "",
+ "activeEffectSurfaceParticlePerIndexCount": 0,
+ "emissiveBorderCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "forceApplyZoneParticle": false,
+ "applyEmissionColorOnWeapons": false,
+ "emissionColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "emissionColorFadeInDuration": 0.0,
+ "emissionColorFadeOutDuration": 0.0
+ },
+ "effectAIParameters": {
+ "$type": "EffectAIParameters, Assembly-CSharp",
+ "aoeScoreMultiplier": 1.0,
+ "cooldownForCaster": 0,
+ "cooldownForBattle": 0,
+ "sortingScoreMultiplier": 1.0,
+ "dynamicCooldown": false
+ },
+ "animationMagicEffect": "Animation0",
+ "lightCounterDispellsEffect": false,
+ "hideSavingThrowAnimation": false
+ },
+ "aiParameters": {
+ "$type": "SpellAIParameters, Assembly-CSharp",
+ "learnPriority": "Low",
+ "preparePriority": "Low"
+ },
+ "concentrationAction": "None",
+ "verboseComponent": true,
+ "somaticComponent": true,
+ "materialComponentType": "None",
+ "specificMaterialComponentTag": "Diamond",
+ "specificMaterialComponentCostGp": 100,
+ "specificMaterialComponentConsumed": true,
+ "terminateOnItemUnequip": false,
+ "displayConditionDuration": false,
+ "vocalSpellSemeType": "Buff",
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Spell/&HolyWeaponTitle",
+ "description": "Spell/&HolyWeaponDescription",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "816cf7c6-e845-570d-a975-0b7595f0838f",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "ed4a2ccf-c199-5f4c-bfc3-7bc8a584e4ce",
+ "contentPack": 9999,
+ "name": "HolyWeapon"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/Incineration.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/Incineration.json
index 4423ed7119..7a30269407 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/Incineration.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/Incineration.json
@@ -25,11 +25,11 @@
"emissiveBorder": "None",
"emissiveParameter": 1,
"requiresTargetProximity": false,
- "targetProximityDistance": 6,
+ "targetProximityDistance": 30,
"targetExcludeCaster": false,
"canBePlacedOnCharacter": true,
"affectOnlyGround": false,
- "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringMethod": "AllCharacterAndGadgets",
"targetFilteringTag": "No",
"requiresVisibilityForPosition": true,
"inviteOptionalAlly": false,
@@ -45,7 +45,7 @@
"targetSide": "Enemy",
"durationType": "Minute",
"durationParameter": 1,
- "endOfEffect": "StartOfTurn",
+ "endOfEffect": "EndOfTurn",
"hasSavingThrow": true,
"disableSavingThrowOnAllies": false,
"savingThrowAbility": "Dexterity",
@@ -157,14 +157,14 @@
"dimAdditionalRange": 6,
"color": {
"$type": "UnityEngine.Color, UnityEngine.CoreModule",
- "r": 1.0,
- "g": 0.9778601,
- "b": 0.78039217,
+ "r": 0.8396226,
+ "g": 0.7766465,
+ "b": 0.5505073,
"a": 1.0
},
"graphicsPrefabReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "3e4cdebecc6e0db469720619529e3dc2",
+ "m_AssetGUID": "fc7cb53da57a8fb40a278d62a885ce58",
"m_SubObjectName": "",
"m_SubObjectType": ""
},
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/RadiantMotes.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/RadiantMotes.json
index 41451a07af..b3d40b190c 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/RadiantMotes.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/RadiantMotes.json
@@ -29,7 +29,7 @@
"targetExcludeCaster": false,
"canBePlacedOnCharacter": true,
"affectOnlyGround": false,
- "targetFilteringMethod": "AllCharacterAndGadgets",
+ "targetFilteringMethod": "CharacterOnly",
"targetFilteringTag": "No",
"requiresVisibilityForPosition": true,
"inviteOptionalAlly": false,
@@ -37,8 +37,8 @@
"recurrentEffect": "No",
"retargetAfterDeath": false,
"retargetActionType": "Bonus",
- "poolFilterDiceNumber": 0,
- "poolFilterDieType": "D1",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
"trapRangeType": "Triggerer",
"targetConditionName": "",
"targetConditionAsset": null,
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/StarryWisp.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/StarryWisp.json
index 0f7878968e..9ef0255ab3 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/StarryWisp.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/StarryWisp.json
@@ -25,11 +25,11 @@
"emissiveBorder": "None",
"emissiveParameter": 1,
"requiresTargetProximity": false,
- "targetProximityDistance": 6,
+ "targetProximityDistance": 30,
"targetExcludeCaster": false,
"canBePlacedOnCharacter": true,
"affectOnlyGround": false,
- "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringMethod": "AllCharacterAndGadgets",
"targetFilteringTag": "No",
"requiresVisibilityForPosition": true,
"inviteOptionalAlly": false,
@@ -47,7 +47,7 @@
"durationParameter": 1,
"endOfEffect": "EndOfSourceTurn",
"hasSavingThrow": false,
- "disableSavingThrowOnAllies": false,
+ "disableSavingThrowOnAllies": true,
"savingThrowAbility": "Dexterity",
"ignoreCover": false,
"grantedConditionOnSave": null,
@@ -184,14 +184,14 @@
"dimAdditionalRange": 2,
"color": {
"$type": "UnityEngine.Color, UnityEngine.CoreModule",
- "r": 1.0,
- "g": 0.9778601,
- "b": 0.78039217,
+ "r": 0.8396226,
+ "g": 0.7766465,
+ "b": 0.5505073,
"a": 1.0
},
"graphicsPrefabReference": {
"$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
- "m_AssetGUID": "3e4cdebecc6e0db469720619529e3dc2",
+ "m_AssetGUID": "fc7cb53da57a8fb40a278d62a885ce58",
"m_SubObjectName": "",
"m_SubObjectType": ""
},
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/SwiftQuiver.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/SwiftQuiver.json
new file mode 100644
index 0000000000..8b41b7e597
--- /dev/null
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/SwiftQuiver.json
@@ -0,0 +1,346 @@
+{
+ "$type": "SpellDefinition, Assembly-CSharp",
+ "spellsBundle": false,
+ "subspellsList": [],
+ "compactSubspellsTooltip": false,
+ "implemented": true,
+ "schoolOfMagic": "SchoolTransmutation",
+ "spellLevel": 5,
+ "ritual": false,
+ "uniqueInstance": false,
+ "castingTime": "BonusAction",
+ "reactionContext": "None",
+ "ritualCastingTime": "Action",
+ "requiresConcentration": true,
+ "effectDescription": {
+ "$type": "EffectDescription, Assembly-CSharp",
+ "rangeType": "Self",
+ "rangeParameter": 0,
+ "halfDamageOnAMiss": false,
+ "hitAffinitiesByTargetTag": [],
+ "targetType": "Self",
+ "itemSelectionType": "None",
+ "targetParameter": 1,
+ "targetParameter2": 2,
+ "emissiveBorder": "None",
+ "emissiveParameter": 1,
+ "requiresTargetProximity": false,
+ "targetProximityDistance": 6,
+ "targetExcludeCaster": false,
+ "canBePlacedOnCharacter": true,
+ "affectOnlyGround": false,
+ "targetFilteringMethod": "CharacterOnly",
+ "targetFilteringTag": "No",
+ "requiresVisibilityForPosition": true,
+ "inviteOptionalAlly": false,
+ "slotTypes": [],
+ "recurrentEffect": "No",
+ "retargetAfterDeath": false,
+ "retargetActionType": "Bonus",
+ "poolFilterDiceNumber": 5,
+ "poolFilterDieType": "D8",
+ "trapRangeType": "Triggerer",
+ "targetConditionName": "",
+ "targetConditionAsset": null,
+ "targetSide": "Ally",
+ "durationType": "Minute",
+ "durationParameter": 1,
+ "endOfEffect": "EndOfTurn",
+ "hasSavingThrow": false,
+ "disableSavingThrowOnAllies": false,
+ "savingThrowAbility": "Dexterity",
+ "ignoreCover": false,
+ "grantedConditionOnSave": null,
+ "rollSaveOnlyIfRelevantForms": false,
+ "hasShoveRoll": false,
+ "createdByCharacter": true,
+ "difficultyClassComputation": "SpellCastingFeature",
+ "savingThrowDifficultyAbility": "Wisdom",
+ "fixedSavingThrowDifficultyClass": 15,
+ "savingThrowAffinitiesBySense": [],
+ "savingThrowAffinitiesByFamily": [],
+ "damageAffinitiesByFamily": [],
+ "advantageForEnemies": false,
+ "canBeDispersed": false,
+ "hasVelocity": false,
+ "velocityCellsPerRound": 2,
+ "velocityType": "AwayFromSourceOriginalPosition",
+ "restrictedCreatureFamilies": [],
+ "immuneCreatureFamilies": [],
+ "restrictedCharacterSizes": [],
+ "hasLimitedEffectPool": false,
+ "effectPoolAmount": 60,
+ "effectApplication": "All",
+ "effectFormFilters": [],
+ "effectForms": [
+ {
+ "$type": "EffectForm, Assembly-CSharp",
+ "formType": "Condition",
+ "addBonusMode": "None",
+ "applyLevel": "No",
+ "levelType": "ClassLevel",
+ "levelMultiplier": 1,
+ "diceByLevelTable": [],
+ "createdByCharacter": true,
+ "createdByCondition": false,
+ "hasSavingThrow": false,
+ "savingThrowAffinity": "None",
+ "dcModifier": 0,
+ "canSaveToCancel": false,
+ "saveOccurence": "EndOfTurn",
+ "conditionForm": {
+ "$type": "ConditionForm, Assembly-CSharp",
+ "conditionDefinitionName": "ConditionSwiftQuiver",
+ "conditionDefinition": "Definition:ConditionSwiftQuiver:1e981912-4130-58da-9464-ac4a23323337",
+ "operation": "Add",
+ "conditionsList": [],
+ "applyToSelf": false,
+ "forceOnSelf": false
+ },
+ "hasFilterId": false,
+ "filterId": 0
+ }
+ ],
+ "specialFormsDescription": "",
+ "effectAdvancement": {
+ "$type": "EffectAdvancement, Assembly-CSharp",
+ "effectIncrementMethod": "None",
+ "incrementMultiplier": 1,
+ "additionalTargetsPerIncrement": 0,
+ "additionalSubtargetsPerIncrement": 0,
+ "additionalDicePerIncrement": 0,
+ "additionalSpellLevelPerIncrement": 0,
+ "additionalSummonsPerIncrement": 0,
+ "additionalHPPerIncrement": 0,
+ "additionalTempHPPerIncrement": 0,
+ "additionalTargetCellsPerIncrement": 0,
+ "additionalItemBonus": 0,
+ "additionalWeaponDie": 0,
+ "alteredDuration": "None"
+ },
+ "speedType": "Instant",
+ "speedParameter": 10.0,
+ "offsetImpactTimeBasedOnDistance": false,
+ "offsetImpactTimeBasedOnDistanceFactor": 0.1,
+ "offsetImpactTimePerTarget": 0.0,
+ "effectParticleParameters": {
+ "$type": "EffectParticleParameters, Assembly-CSharp",
+ "casterParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "d98f0aac4cd958440a3ebbc9b4a87edc",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterSelfParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "casterQuickSpellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "targetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "effectSubTargetParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "zoneParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "beforeImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "impactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectImpactParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "activeEffectSurfaceParticlePerIndex": "",
+ "activeEffectSurfaceParticlePerIndexCount": 0,
+ "emissiveBorderCellStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderCellEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "emissiveBorderSurfaceEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionStartParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "2da227cea9dca7d41b5d447904eb594c",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "efdfc9a01d8307f4ba69ffa457abd4d3",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "conditionEndParticleReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReference, Unity.Addressables",
+ "m_AssetGUID": "0a30f6db20ec9ce47b58cb2b1cfeb655",
+ "m_SubObjectName": "",
+ "m_SubObjectType": ""
+ },
+ "forceApplyZoneParticle": false,
+ "applyEmissionColorOnWeapons": false,
+ "emissionColor": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 0.0,
+ "g": 0.0,
+ "b": 0.0,
+ "a": 0.0
+ },
+ "emissionColorFadeInDuration": 0.0,
+ "emissionColorFadeOutDuration": 0.0
+ },
+ "effectAIParameters": {
+ "$type": "EffectAIParameters, Assembly-CSharp",
+ "aoeScoreMultiplier": 1.0,
+ "cooldownForCaster": 0,
+ "cooldownForBattle": 0,
+ "sortingScoreMultiplier": 1.0,
+ "dynamicCooldown": false
+ },
+ "animationMagicEffect": "Animation0",
+ "lightCounterDispellsEffect": false,
+ "hideSavingThrowAnimation": false
+ },
+ "aiParameters": {
+ "$type": "SpellAIParameters, Assembly-CSharp",
+ "learnPriority": "Low",
+ "preparePriority": "Low"
+ },
+ "concentrationAction": "None",
+ "verboseComponent": true,
+ "somaticComponent": true,
+ "materialComponentType": "Specific",
+ "specificMaterialComponentTag": "Consumable",
+ "specificMaterialComponentCostGp": 0,
+ "specificMaterialComponentConsumed": false,
+ "terminateOnItemUnequip": false,
+ "displayConditionDuration": false,
+ "vocalSpellSemeType": "Buff",
+ "guiPresentation": {
+ "$type": "GuiPresentation, Assembly-CSharp",
+ "hidden": false,
+ "title": "Spell/&SwiftQuiverTitle",
+ "description": "Spell/&SwiftQuiverDescription",
+ "spriteReference": {
+ "$type": "UnityEngine.AddressableAssets.AssetReferenceSprite, Unity.Addressables",
+ "m_AssetGUID": "6c499066-e227-5a58-b222-867e1da29182",
+ "m_SubObjectName": null,
+ "m_SubObjectType": null
+ },
+ "color": {
+ "$type": "UnityEngine.Color, UnityEngine.CoreModule",
+ "r": 1.0,
+ "g": 1.0,
+ "b": 1.0,
+ "a": 1.0
+ },
+ "symbolChar": "221E",
+ "sortOrder": 0,
+ "unusedInSolastaCOTM": false,
+ "usedInValleyDLC": false
+ },
+ "contentCopyright": "UserContent",
+ "guid": "12962336-42c4-5ddc-8ea1-6092af61fe43",
+ "contentPack": 9999,
+ "name": "SwiftQuiver"
+}
\ No newline at end of file
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/VileBrew.json b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/VileBrew.json
index 525fffc4d5..791a51a73e 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/VileBrew.json
+++ b/Diagnostics/UnfinishedBusinessBlueprints/SpellDefinition/VileBrew.json
@@ -45,7 +45,7 @@
"targetSide": "All",
"durationType": "Minute",
"durationParameter": 1,
- "endOfEffect": "StartOfTurn",
+ "endOfEffect": "EndOfTurn",
"hasSavingThrow": true,
"disableSavingThrowOnAllies": false,
"savingThrowAbility": "Dexterity",
diff --git a/Diagnostics/UnfinishedBusinessBlueprints/Types.txt b/Diagnostics/UnfinishedBusinessBlueprints/Types.txt
index 804c8756cd..3b655bb6b9 100644
--- a/Diagnostics/UnfinishedBusinessBlueprints/Types.txt
+++ b/Diagnostics/UnfinishedBusinessBlueprints/Types.txt
@@ -68,4 +68,5 @@ RestActivityDefinition
SpellDefinition
SpellListDefinition
TA.AI.DecisionDefinition
+TA.AI.DecisionPackageDefinition
WeaponTypeDefinition
diff --git a/Documentation/Spells.md b/Documentation/Spells.md
index 2144380039..ae0a829007 100644
--- a/Documentation/Spells.md
+++ b/Documentation/Spells.md
@@ -1,217 +1,325 @@
# 1. - Acid Claws (S) level 0 Transmutation [UB]
+**[Druid]**
+
Your fingernails sharpen, ready to deliver a corrosive attack. Make a melee spell attack against one creature within 5 ft of you. On a hit, the target takes 1d8 acid damage and has AC lowered by 1 for 1 round (not stacking).
# 2. - Acid Splash (V,S) level 0 Conjuration [SOL]
+**[Artificer, Sorcerer, Wizard]**
+
Launch an acid bolt.
# 3. - Annoying Bee (V,S) level 0 Illusion [SOL]
+**[Druid, Sorcerer, Wizard]**
+
The target sees an illusional bee harassing them and has disadvantage on concentration checks until the start of their next turn.
# 4. - *Blade Ward* © (V,S) level 0 Abjuration [UB]
+**[Bard, Sorcerer, Warlock, Wizard]**
+
You extend your hand and trace a sigil of warding in the air. Until the end of your next turn, you have resistance against bludgeoning, piercing, and slashing damage dealt by weapon attacks.
# 5. - *Booming Blade* © (M,S) level 0 Evocation [UB]
+**[Artificer, Sorcerer, Warlock, Wizard]**
+
You brandish the weapon used in the spell's casting and make a melee attack with it against one creature within 5 ft distance. On a hit, the target suffers the weapon attack's normal effects and then becomes sheathed in booming energy until the start of your next turn. If the target willingly moves 5 ft or more before then, the target takes 1d8 thunder damage, and the spell ends. At 5th level, the melee attack deals an extra 1d8 thunder damage to the target on a hit, and the damage the target takes for moving increases to 2d8. Both damage rolls increase by 1d8 at 11th and 17th levels.
# 6. - Chill Touch (V,S) level 0 Necromancy [SOL]
+**[Sorcerer, Warlock, Wizard]**
+
Deal damage to one enemy and prevent healing for a limited time.
-# 7. - Dancing Lights (V,S) level 0 Evocation [Concentration] [SOL]
+# 7. - *Create Bonfire* © (V,S) level 0 Conjuration [Concentration] [UB]
+
+**[Artificer, Druid, Sorcerer, Warlock, Wizard]**
+
+You create a bonfire on ground that you can see within range. Until the spell ends, the bonfire fills a 5-foot cube. Any creature in the bonfire's space when you cast the spell must succeed on a Dexterity saving throw or take 1d8 fire damage. A creature must also make the saving throw when it enters the bonfire's space or ends its turn there. The spell's damage increases by an additional die at 5th, 11th and 17th level.
+
+# 8. - Dancing Lights (V,S) level 0 Evocation [Concentration] [SOL]
+
+**[Bard, Sorcerer, Wizard]**
Create dancing lights that move at your command.
-# 8. - Dazzle (S) level 0 Illusion [SOL]
+# 9. - Dazzle (S) level 0 Illusion [SOL]
+
+**[Bard, Sorcerer, Warlock, Wizard]**
Lower a target's AC and prevent reaction until the start of its next turn.
-# 9. - Eldritch Blast (V,S) level 0 Evocation [SOL]
+# 10. - Eldritch Blast (V,S) level 0 Evocation [SOL]
+
+**[Warlock]**
Unleash a beam of crackling energy with a ranged spell attack against the target. On a hit, it takes 1d10 force damage.
-# 10. - Fire Bolt (V,S) level 0 Evocation [SOL]
+# 11. - Fire Bolt (V,S) level 0 Evocation [SOL]
+
+**[Artificer, Sorcerer, Wizard]**
Launch a fire bolt.
-# 11. - *Green-Flame Blade* © (M,S) level 0 Evocation [UB]
+# 12. - *Green-Flame Blade* © (M,S) level 0 Evocation [UB]
+
+**[Artificer, Sorcerer, Warlock, Wizard]**
You brandish the weapon used in the spell's casting and make a melee attack with it against one creature within 5 ft distance. On a hit, the target suffers the weapon attack's normal effects, and you can cause green fire to leap from the target to a different creature of your choice that you can see within 5 ft of it. The second creature takes fire damage equal to your spellcasting ability modifier. At 5th level, the melee attack deals an extra 1d8 fire damage to the target on a hit, and the fire damage to the second creature increases to 1d8 + your spellcasting ability modifier. Both damage rolls increase by 1d8 at 11th and 17th levels.
-# 12. - Guidance (V,S) level 0 Divination [Concentration] [SOL]
+# 13. - Guidance (V,S) level 0 Divination [Concentration] [SOL]
+
+**[Artificer, Cleric, Druid]**
Increase an ally's ability checks for a limited time.
-# 13. - *Gust* © (V,S) level 0 Transmutation [UB]
+# 14. - *Gust* © (V,S) level 0 Transmutation [UB]
+
+**[Druid, Sorcerer, Wizard]**
Fire a blast of focused air at your target.
-# 14. - Illuminating Sphere (V,S) level 0 Enchantment [UB]
+# 15. - Illuminating Sphere (V,S) level 0 Enchantment [UB]
-Causes light sources such as torches and mana lamps in the area of effect to light up.
+**[Bard, Sorcerer, Wizard]**
-# 15. - *Infestation* © (V,S) level 0 Conjuration [UB]
+Causes light sources such as torches and mana lamps in the area of effect to light up.
-You cause a cloud of mites, fleas, and other parasites to appear momentarily on one creature you can see within range. The target must succeed on a Constitution saving throw, or it takes 1d6 poison damage and moves 5 ft in a random direction. The spell's damage increases by an additional die at 5th, 11th and 17th level.
+# 16. - *Infestation* © (V,S) level 0 Conjuration [UB]
-# 16. - Light (V) level 0 Evocation [SOL]
+**[Druid, Sorcerer, Warlock, Wizard]**
-An object you can touch emits a powerful light for a limited time.
+You cause a cloud of mites, fleas, and other parasites to appear momentarily on one creature you can see within range. The target must succeed on a Constitution saving throw, or it takes 1d6 poison damage and moves 5 ft in a random direction. The spell's damage increases by an additional die at 5th, 11th and 17th level.
# 17. - Light (V) level 0 Evocation [SOL]
+**[Bard, Cleric, Sorcerer, Wizard]**
+
An object you can touch emits a powerful light for a limited time.
# 18. - *Lightning Lure* © (V) level 0 Evocation [UB]
+**[Artificer, Sorcerer, Warlock, Wizard]**
+
You create a lash of lightning energy that strikes at one creature of your choice that you can see within 15 ft of you. The target must succeed on a Strength saving throw or be pulled up to 10 ft in a straight line toward you and then take 1d8 lightning damage. The spell's damage increases by an additional die at 5th, 11th and 17th level.
# 19. - *Mind Sliver* © (V) level 0 Enchantment [UB]
+**[Sorcerer, Warlock, Wizard]**
+
You drive a disorienting spike of psychic energy into the mind of one creature you can see within range. The target must succeed on an Intelligence saving throw or take 1d6 psychic damage and subtract 1d4 from the next saving throw it makes before the end of your next turn.
# 20. - Minor Lifesteal (V,S) level 0 Necromancy [UB]
+**[Bard, Sorcerer, Warlock, Wizard]**
+
You drain vital energy from a nearby enemy creature. Make a melee spell attack against a creature within 5 ft of you. On a hit, the creature takes 1d6 necrotic damage, and you heal for half the damage dealt (rounded down). This spell has no effect on undead and constructs. The spell's damage increases by an additional die at 5th, 11th and 17th level.
# 21. - Poison Spray (V,S) level 0 Conjuration [SOL]
+**[Artificer, Druid, Sorcerer, Warlock, Wizard]**
+
Fire a poison spray at an enemy you can see, within range.
# 22. - *Primal Savagery* © (S) level 0 Transmutation [UB]
+**[Druid]**
+
You channel primal magic to cause your teeth or fingernails to sharpen, ready to deliver a corrosive attack. Make a melee spell attack against one creature within 5 ft of you. On a hit, the target takes 1d10 acid damage. The spell's damage increases by an additional die at 5th, 11th and 17th level.
# 23. - Produce Flame (V,S) level 0 Conjuration [SOL]
+**[Druid]**
+
Conjures a flickering flame in your hand, which generates light or can be hurled to inflict fire damage.
# 24. - Ray of Frost (V,S) level 0 Evocation [SOL]
+**[Artificer, Sorcerer, Wizard]**
+
Launch a freezing ray at an enemy to damage and slow them.
# 25. - Resistance (V,S) level 0 Abjuration [Concentration] [SOL]
+**[Artificer, Cleric, Druid]**
+
Grant an ally a one-time bonus to saving throws.
# 26. - Sacred Flame (V,S) level 0 Evocation [SOL]
+**[Cleric]**
+
Strike an enemy with radiant damage.
# 27. - *Sapping Sting* © (V,S) level 0 Necromancy [UB]
+**[Wizard]**
+
You sap the vitality of one creature you can see in range. The target must succeed on a Constitution saving throw or take 1d4 necrotic damage and fall prone.
# 28. - Shadow Armor (V,S) level 0 Abjuration [SOL]
+**[Bard, Sorcerer, Warlock, Wizard]**
+
Grants 3 temporary hit points for one minute.
# 29. - Shadow Dagger (V,S) level 0 Illusion [SOL]
+**[Bard, Sorcerer, Warlock, Wizard]**
+
Launches an illusionary dagger that causes psychic damage.
# 30. - Shillelagh (V,S) level 0 Transmutation [SOL]
+**[Druid]**
+
Conjures a magical club whose attacks are magical and use your spellcasting ability instead of strength.
# 31. - Shine (V,S) level 0 Conjuration [SOL]
+**[Cleric, Sorcerer, Wizard]**
+
An enemy you can see becomes luminous for a while.
# 32. - Shocking Grasp (V,S) level 0 Evocation [SOL]
+**[Artificer, Sorcerer, Wizard]**
+
Damage and daze an enemy on a successful touch.
# 33. - Spare the Dying (S) level 0 Necromancy [SOL]
+**[Artificer, Cleric]**
+
Touch a dying ally to stabilize them.
# 34. - Sparkle (V,S) level 0 Enchantment [SOL]
+**[Bard, Cleric, Druid, Sorcerer, Warlock, Wizard]**
+
Target up to three objects that can be illuminated and light them up immediately.
# 35. - *Starry Wisp* © (V,S) level 0 Evocation [UB]
+**[Bard, Druid]**
+
You launch a mote of light at one creature or object within range. Make a ranged spell attack against the target. On a hit, the target takes 1d8 Radiant damage, and until the end of your next turn, it emits Dim Light in a 10-foot radius and can't benefit from the Invisible condition. The spell's damage increases by an additional die at 5th, 11th and 17th level.
# 36. - Sunlit Blade (M,S) level 0 Evocation [UB]
+**[Artificer, Sorcerer, Warlock, Wizard]**
+
You brandish the weapon used in the spell's casting and make a melee attack with it against one creature within 5 ft distance. On a hit, the target suffers the weapon attack's normal effects, and is enveloped in glowing radiant energy, shedding dim light for the turn. Next attack against this creature while it is highlighted is done with advantage. At 5th level, the melee attack deals an extra 1d8 radiant damage to the target. The damage increases by another 1d8 at 11th and 17th levels.
# 37. - *Sword Burst* © (V,S) level 0 Enchantment [UB]
+**[Artificer, Sorcerer, Warlock, Wizard]**
+
You create a momentary circle of spectral blades that sweep around you. All other creatures within 5 ft of you must each succeed on a Dexterity saving throw or take 1d6 force damage.
# 38. - *Thorn Whip* © (V,S) level 0 Transmutation [UB]
+**[Artificer, Druid]**
+
You create a long, whip-like vine covered in thorns that lashes out at your command toward a creature in range. Make a ranged spell attack against the target. If the attack hits, the creature takes 1d6 piercing damage, and you pull the creature up to 10 ft closer to you.
# 39. - *Thunderclap* © (V,S) level 0 Evocation [UB]
+**[Artificer, Bard, Druid, Sorcerer, Warlock, Wizard]**
+
Create a burst of thundering sound, forcing creatures adjacent to you to make a Constitution saving throw or take 1d6 thunder damage. The spell's damage increases by an additional die at 5th, 11th and 17th level.
# 40. - *Toll the Dead* © (V,S) level 0 Necromancy [UB]
+**[Cleric, Warlock, Wizard]**
+
You point at one creature you can see within range, and the sound of a dolorous bell fills the air around it for a moment. The target must succeed on a Wisdom saving throw or take 1d6 necrotic damage. If the target is missing any of its hit points, it instead takes 1d12 necrotic damage.
# 41. - True Strike (S) level 0 Divination [Concentration] [SOL]
+**[Bard, Sorcerer, Warlock, Wizard]**
+
Increases your chance to hit a target you can see, one time.
# 42. - Venomous Spike (V,S) level 0 Enchantment [SOL]
+**[Druid]**
+
A bone spike that pierces and poisons its target.
# 43. - Vicious Mockery (V) level 0 Enchantment [SOL]
+**[Bard]**
+
Unleash a torrent of magically-enhanced insults on a creature you can see. It must make a successful wisdom saving throw, or take psychic damage and have disadvantage on its next attack roll. The effect lasts until the end of its next turn.
# 44. - *Word of Radiance* © (V) level 0 Evocation [UB]
+**[Cleric]**
+
Create a brilliant flash of shimmering light, damaging all enemies around you.
# 45. - Wrack (V,S) level 0 Necromancy [UB]
+**[Cleric]**
+
Unleash a wave of crippling pain at a creature within range. The target must make a Constitution saving throw or take 1d6 necrotic damage, and preventing them from dashing or disengaging.
# 46. - *Absorb Elements* © (S) level 1 Abjuration [UB]
+**[Druid, Ranger, Sorcerer, Wizard]**
+
The spell captures some of the incoming energy, lessening its effect on you and storing it for your next melee attack. You have resistance to the triggering damage type until the start of your next turn. Also, the first time you hit with a melee attack on your next turn, the target takes an extra 1d6 damage of the triggering type, and the spell ends. When you cast this spell using a spell slot of 2nd level or higher, the extra damage increases by 1d6 for each slot level above 1st.
# 47. - Animal Friendship (V,S) level 1 Enchantment [SOL]
+**[Bard, Druid, Ranger]**
+
Choose a beast that you can see within the spell's range. The beast must make a Wisdom saving throw or be charmed for the spell's duration.
# 48. - *Armor of Agathys* © (V,S) level 1 Abjuration [UB]
+**[Warlock]**
+
A protective elemental skin envelops you, covering you and your gear. You gain 5 temporary hit points per spell level for the duration. In addition, if a creature hits you with a melee attack while you have these temporary hit points, the creature takes 5 cold damage per spell level.
# 49. - *Arms of Hadar* © (V,S) level 1 Evocation [UB]
+**[Warlock]**
+
You invoke the power of malevolent forces. Tendrils of dark energy erupt from you and batter all creatures within 10 feet of you. Each creature in that area must make a Strength saving throw. On a failed save, a target takes 2d6 necrotic damage and can't take reactions until the start of your next turn. On a successful save, the creature takes half damage, but suffers no other effect. When you cast this spell using a spell slot of 2nd level or higher, the damage increases by 1d6 for each slot level above 1st.
# 50. - Bane (V,S) level 1 Enchantment [Concentration] [SOL]
+**[Bard, Cleric]**
+
Reduce your enemies' attack and saving throws for a limited time.
# 51. - Bless (V,S) level 1 Enchantment [Concentration] [SOL]
+**[Cleric, Paladin]**
+
Increase your allies' saving throws and attack rolls for a limited time.
# 52. - Burning Hands (V,S) level 1 Evocation [SOL]
+**[Sorcerer, Wizard]**
+
Spray a cone of fire in front of you.
# 53. - Caustic Zap (V,S) level 1 Evocation [UB]
+**[Artificer, Sorcerer, Wizard]**
+
You send a jolt of green energy toward the target momentarily disorientating them as the spell burn some of their armor. The spell targets one enemy with a spell attack and deals 1d4 acid and 1d6 lightning damage and applies the dazzled condition.
# 54. - *Chaos Bolt* © (V,S) level 1 Evocation [UB]
+**[Sorcerer]**
+
Make a ranged spell attack against a target. On a hit, the target takes 2d8 + 1d6 damage. Choose one of the d8s. The number rolled on that die determines the attack's damage type:
1: ◰ Acid 2: ◲ Cold
3: ◳ Fire 4: ◴ Force
@@ -221,858 +329,1298 @@ If you roll the same number on both d8s, you can use your free action to target
# 55. - Charm Person (V,S) level 1 Enchantment [SOL]
+**[Bard, Druid, Sorcerer, Warlock, Wizard]**
+
Makes an ally of an enemy.
# 56. - *Chromatic Orb* © (M,V,S) level 1 Evocation [UB]
+**[Sorcerer, Wizard]**
+
You hurl a 4-inch-diameter sphere of energy at a creature that you can see within range. You choose acid, cold, fire, lightning, poison, or thunder for the type of orb you create, and then make a ranged spell attack against the target. If the attack hits, the creature takes 3d8 damage of the type you chose.
# 57. - Color Spray (V,S) level 1 Illusion [SOL]
+**[Sorcerer, Wizard]**
+
Spray a luminous cone that briefly blinds your enemies. Roll 6d10: the total is how many hit points of creatures this spell can affect.
-# 58. - Comprehend Languages (V,S) level 1 Divination [SOL]
+# 58. - *Command* © (V) level 1 Enchantment [UB]
+
+**[Bard, Cleric, Paladin]**
+
+You speak a one-word command to a creature you can see within range. The target must succeed on a Wisdom saving throw or follow the command on its next turn.
+You can only command creatures you share a language with. Humanoids are considered knowing Common. To command a non-humanoid creature, you must know Draconic for Dragons, Elvish for Fey, Giant for Giants, Infernal for Fiends and Terran for Elementals.
+Cannot target Undead or Surprised creatures.
+
+# 59. - Comprehend Languages (V,S) level 1 Divination [SOL]
+
+**[Bard, Sorcerer, Warlock, Wizard]**
For the duration of the spell, you understand the literal meaning of any spoken words that you hear.
-# 59. - Cure Wounds (V,S) level 1 Evocation [SOL]
+# 60. - Cure Wounds (V,S) level 1 Evocation [SOL]
+
+**[Artificer, Bard, Cleric, Druid, Paladin, Ranger]**
Heal an ally by touch.
-# 60. - Detect Evil and Good (V,S) level 1 Divination [Concentration] [SOL]
+# 61. - Detect Evil and Good (V,S) level 1 Divination [Concentration] [SOL]
+
+**[Cleric, Paladin]**
Detect nearby creatures of evil or good nature.
-# 61. - Detect Magic (V,S) level 1 Divination [Concentration] [SOL]
+# 62. - Detect Magic (V,S) level 1 Divination [Concentration] [SOL]
+
+**[Artificer, Bard, Cleric, Druid, Paladin, Ranger, Sorcerer, Wizard]**
Detect nearby magic objects or creatures.
-# 62. - Detect Poison and Disease (V,S) level 1 Divination [Concentration] [SOL]
+# 63. - Detect Poison and Disease (V,S) level 1 Divination [Concentration] [SOL]
+
+**[Druid]**
TMP For the duration you sense the presence and location of poisonous creatures and diseases within 6 cells of you.
-# 63. - Divine Favor (V,S) level 1 Evocation [Concentration] [SOL]
+# 64. - *Dissonant Whispers* © (V) level 1 Enchantment [UB]
+
+**[Bard]**
+
+You whisper a discordant melody that only one creature of your choice within range can hear, wracking it with terrible pain. The target must make a Wisdom saving throw. On a failed save, it takes 3d6 psychic damage and must immediately use its reaction, if available, to move as far as its speed allows away from you. The creature doesn't move into obviously dangerous ground, such as a fire or a pit. On a successful save, the target takes half as much damage and doesn't have to move away. When you cast this spell using a spell slot of 2nd level or higher, the damage increases by 1d6 for each slot level above 1st.
+
+# 65. - Divine Favor (V,S) level 1 Evocation [Concentration] [SOL]
+
+**[Paladin]**
Gain additional radiant damage for a limited time.
-# 64. - *Earth Tremor* © (V,S) level 1 Evocation [UB]
+# 66. - *Earth Tremor* © (V,S) level 1 Evocation [UB]
+
+**[Bard, Druid, Sorcerer, Wizard]**
You strike the ground and unleash a tremor of seismic force, hurling up earth, rock, and sand.
-# 65. - *Ensnaring Strike* © (V) level 1 Conjuration [Concentration] [UB]
+# 67. - *Ensnaring Strike* © (V) level 1 Conjuration [Concentration] [UB]
+
+**[Ranger]**
The next time you hit a creature with a weapon attack before this spell ends, a writhing mass of thorny vines appears at the point of impact, and the target must succeed on a Strength saving throw or be restrained by the magical vines until the spell ends.While restrained by this spell, the target takes 1d6 piercing damage at the start of each of its turns. A creature restrained by the vines can use its action to make a Strength check against your spell save DC.
-# 66. - Entangle (V,S) level 1 Conjuration [Concentration] [SOL]
+# 68. - Entangle (V,S) level 1 Conjuration [Concentration] [SOL]
+
+**[Druid]**
Creatures in a four-cell square area are restrained if they fail a STR saving throw
-# 67. - Expeditious Retreat (V,S) level 1 Transmutation [Concentration] [SOL]
+# 69. - Expeditious Retreat (V,S) level 1 Transmutation [Concentration] [SOL]
+
+**[Artificer, Sorcerer, Warlock, Wizard]**
Gain movement points and become able to dash as a bonus action for a limited time.
-# 68. - Faerie Fire (V) level 1 Evocation [Concentration] [SOL]
+# 70. - Faerie Fire (V) level 1 Evocation [Concentration] [SOL]
+
+**[Artificer, Bard, Druid]**
Highlight creatures to give advantage to anyone attacking them.
-# 69. - False Life (V,S) level 1 Necromancy [SOL]
+# 71. - False Life (V,S) level 1 Necromancy [SOL]
+
+**[Artificer, Sorcerer, Wizard]**
Gain a few temporary hit points for a limited time.
-# 70. - Feather Fall (V) level 1 Transmutation [SOL]
+# 72. - Feather Fall (V) level 1 Transmutation [SOL]
+
+**[Artificer, Bard, Sorcerer, Wizard]**
Provide a safe landing when you or an ally falls.
-# 71. - *Find Familiar* © (V,S) level 1 Conjuration [UB]
+# 73. - *Find Familiar* © (V,S) level 1 Conjuration [UB]
+
+**[Wizard]**
You gain the service of a familiar. The familiar can use the help action, and you can cast any touch or melee hit spell through the familiar.
-# 72. - Fog Cloud (V,S) level 1 Conjuration [Concentration] [SOL]
+# 74. - Fog Cloud (V,S) level 1 Conjuration [Concentration] [SOL]
+
+**[Druid, Ranger, Sorcerer, Wizard]**
Generate a sphere of thick fog for a limited time. The area is heavily obscured, penalizing creatures inside it that rely on sight.
-# 73. - *Gift of Alacrity* © (V,S) level 1 Divination [UB]
+# 75. - *Gift of Alacrity* © (V,S) level 1 Divination [UB]
+
+**[Wizard]**
You touch a willing creature. For the duration, the target can add 1d8 to its initiative rolls.
-# 74. - Goodberry (V,S) level 1 Transmutation [SOL]
+# 76. - Goodberry (V,S) level 1 Transmutation [SOL]
+
+**[Druid, Ranger]**
Creates 10 berries infused with magic. Eating a berry restores 1 hit point and provides sustenance for a long rest. Berries vanish after a long rest.
-# 75. - Grease (V,S) level 1 Conjuration [SOL]
+# 77. - Grease (V,S) level 1 Conjuration [SOL]
+
+**[Artificer, Wizard]**
Cover an area of 2 x 2 cells with grease. Creatures trying to cross it may fall prone.
-# 76. - Guiding Bolt (V,S) level 1 Evocation [SOL]
+# 78. - Guiding Bolt (V,S) level 1 Evocation [SOL]
+
+**[Cleric]**
Launch a radiant attack against an enemy and make them easy to hit.
-# 77. - *Hail of Thorns* © (V) level 1 Conjuration [Concentration] [UB]
+# 79. - *Hail of Thorns* © (V) level 1 Conjuration [Concentration] [UB]
+
+**[Ranger]**
The next time you hit a creature with a ranged weapon attack before the spell ends, this spell creates a rain of thorns that sprouts from your ranged weapon or ammunition. In addition to the normal effect of the attack, the target of the attack and each creature within 5 feet of it must make a Dexterity saving throw. A creature takes 1d10 piercing damage on a failed save, or half as much damage on a successful one.
-# 78. - Healing Word (V) level 1 Evocation [SOL]
+# 80. - Healing Word (V) level 1 Evocation [SOL]
+
+**[Bard, Cleric, Druid]**
Heal an ally you can see.
-# 79. - Hellish Rebuke (V,S) level 1 Evocation [SOL]
+# 81. - Hellish Rebuke (V,S) level 1 Evocation [SOL]
+
+**[Warlock]**
When you are damaged by a creature within range, you can use your reaction to inflict fire damage back.
-# 80. - Heroism (V,S) level 1 Enchantment [Concentration] [SOL]
+# 82. - Heroism (V,S) level 1 Enchantment [Concentration] [SOL]
+
+**[Bard, Paladin]**
An ally gains temporary hit points and cannot be frightened for a limited time.
-# 81. - Hideous Laughter (V,S) level 1 Enchantment [Concentration] [SOL]
+# 83. - Hideous Laughter (V,S) level 1 Enchantment [Concentration] [SOL]
+
+**[Bard, Wizard]**
Make an enemy helpless with irresistible laughter.
-# 82. - Hunter's Mark (V) level 1 Divination [Concentration] [SOL]
+# 84. - Hunter's Mark (V) level 1 Divination [Concentration] [SOL]
+
+**[Ranger]**
An enemy gets additional damage from you, and you can easily detect it for a limited time.
-# 83. - *Ice Knife* © (S) level 1 Conjuration [UB]
+# 85. - *Ice Knife* © (S) level 1 Conjuration [UB]
+
+**[Druid, Sorcerer, Wizard]**
You create a shard of ice and fling it at one creature within range. Make a ranged spell attack against the target. On a hit, the target takes 1d10 piercing damage. Hit or miss, the shard then explodes. The target and each creature within 5 feet of the point where the ice exploded must succeed on a Dexterity saving throw or take 2d6 cold damage. When you cast this spell using a spell slot of 2nd level or higher, both the cold and piercing damage increase by 1 die for each slot level above 1st.
-# 84. - Identify (M,V,S) level 1 Divination [SOL]
+# 86. - Identify (M,V,S) level 1 Divination [SOL]
+
+**[Artificer, Bard, Wizard]**
Identify the hidden properties of an object.
-# 85. - Inflict Wounds (V,S) level 1 Necromancy [SOL]
+# 87. - Inflict Wounds (V,S) level 1 Necromancy [SOL]
+
+**[Cleric]**
Deal necrotic damage to an enemy you hit.
-# 86. - Jump (V,S) level 1 Transmutation [SOL]
+# 88. - Jump (V,S) level 1 Transmutation [SOL]
+
+**[Artificer, Druid, Ranger, Sorcerer, Wizard]**
Increase an ally's jumping distance.
-# 87. - Jump (V,S) level 1 Transmutation [SOL]
+# 89. - Jump (V,S) level 1 Transmutation [SOL]
+
Increase an ally's jumping distance.
-# 88. - Longstrider (V,S) level 1 Transmutation [SOL]
+# 90. - Longstrider (V,S) level 1 Transmutation [SOL]
+
+**[Artificer, Bard, Druid, Ranger, Wizard]**
Increases an ally's speed by two cells per turn.
-# 89. - Mage Armor (V,S) level 1 Abjuration [SOL]
+# 91. - Mage Armor (V,S) level 1 Abjuration [SOL]
+
+**[Sorcerer, Wizard]**
Provide magical armor to an ally who doesn't wear armor.
-# 90. - Magic Missile (V,S) level 1 Evocation [SOL]
+# 92. - Magic Missile (V,S) level 1 Evocation [SOL]
+
+**[Sorcerer, Wizard]**
Strike one or more enemies with projectiles that can't miss.
-# 91. - *Magnify Gravity* © (V,S) level 1 Transmutation [UB]
+# 93. - *Magnify Gravity* © (V,S) level 1 Transmutation [UB]
+
+**[Wizard]**
Sharply increase gravity in a 10-foot-radius sphere to crush and slow targets.
-# 92. - Malediction (V,S) level 1 Enchantment [Concentration] [SOL]
+# 94. - Malediction (V,S) level 1 Enchantment [Concentration] [SOL]
+
+**[Warlock]**
Until the spell ends, whenever you hit a target with an attack you deal an extra 1d6 magical damage of the same type as the attack's damage.
-# 93. - Mule (V,S) level 1 Transmutation [UB]
+# 95. - Mule (V,S) level 1 Transmutation [UB]
+
+**[Bard, Sorcerer, Warlock, Wizard]**
The recipient of this spell is able to ignore the effects of heavy loads or armor on movement speed. They can also carry slightly more weight.
-# 94. - Protect vs Evil & Good (V,S) level 1 Abjuration [Concentration] [SOL]
+# 96. - Protect vs Evil & Good (V,S) level 1 Abjuration [Concentration] [SOL]
+
+**[Cleric, Paladin, Warlock, Wizard]**
Touch an ally to give them protection from evil or good creatures for a limited time.
-# 95. - Radiant Motes (V,S) level 1 Evocation [UB]
+# 97. - Radiant Motes (V,S) level 1 Evocation [UB]
+
+**[Artificer, Wizard]**
Unleashes a swarm of 4 radiant projectiles that deal 1d4 radiant damage each.
When you cast this spell using a spell slot of 2nd level or higher, the spell creates 1 more projectile for each slot above 1st.
-# 96. - *Sanctuary* © (V,S) level 1 Abjuration [UB]
+# 98. - *Sanctuary* © (V,S) level 1 Abjuration [UB]
+
+**[Artificer, Cleric]**
You ward a creature within range against attack. Until the spell ends, any creature who targets the warded creature with an attack or a harmful spell must first make a Wisdom saving throw. On a failed save, the creature loses the attack or spell. This spell doesn't protect the warded creature from area effects. If the warded creature makes an attack or casts a spell, this spell ends.
-# 97. - *Searing Smite* © (V) level 1 Evocation [Concentration] [UB]
+# 99. - *Searing Smite* © (V) level 1 Evocation [Concentration] [UB]
+
+**[Paladin, Ranger]**
+
+The next time you hit a creature with a melee weapon attack during the spell's duration, your weapon flares with white-hot intensity, and the attack deals an extra 1d6 fire damage to the target and causes the target to ignite in flames. At the start of each of its turns until the spell ends, the target must make a Constitution saving throw. On a failed save, it takes 1d6 fire damage. On a successful save, the spells ends. If the target or a creature within 5 feet of it uses an action to put out the flames, or if some other effect douses the flames (such as the target being submerged in water), the spell ends. When you cast this spell using a spell slot of 2nd level or higher, the extra damage increases by 1d6 for each slot level above 1st.
-On your next hit your weapon flares with white-hot intensity, and the attack deals an extra 1d6 fire damage to the target and causes the target to ignite in flames.
-At the start of each of its turns the target must make a successful Constitution saving throw to stop burning, or take 1d6 fire damage.
-Higher Levels: for each slot level above 1st, the initial extra damage dealt by the attack increases by 1d6.
+# 100. - Shield (V,S) level 1 Abjuration [SOL]
-# 98. - Shield (V,S) level 1 Abjuration [SOL]
+**[Sorcerer, Wizard]**
Increase your AC by 5 just before you would take a hit.
-# 99. - Shield of Faith (V,S) level 1 Abjuration [Concentration] [SOL]
+# 101. - Shield of Faith (V,S) level 1 Abjuration [Concentration] [SOL]
+
+**[Cleric, Paladin]**
Increase an ally's AC by 2 for a limited time.
-# 100. - Sleep (V,S) level 1 Enchantment [SOL]
+# 102. - Sleep (V,S) level 1 Enchantment [SOL]
+
+**[Bard, Sorcerer, Wizard]**
Put a number of creatures to sleep for a limited time. Roll 5d8: the total is how many hit points of creatures this spell can affect.
-# 101. - *Tasha's Caustic Brew* © (V,S) level 1 Evocation [Concentration] [UB]
+# 103. - *Tasha's Caustic Brew* © (V,S) level 1 Evocation [Concentration] [UB]
+
+**[Artificer, Sorcerer, Wizard]**
A stream of acid emanates from you in a line 30 feet long and 5 feet wide in a direction you choose. Each creature in the line must succeed on a Dexterity saving throw or be covered in acid for the spell's duration or until a creature uses its action to scrape or wash the acid off itself or another creature. A creature covered in the acid takes 2d4 acid damage at start of each of its turns. When you cast this spell using a spell slot 2nd level or higher, the damage increases by 2d4 for each slot level above 1st.
-# 102. - *Thunderous Smite* © (V) level 1 Evocation [Concentration] [UB]
+# 104. - *Thunderous Smite* © (V) level 1 Evocation [Concentration] [UB]
-On your next hit your weapon rings with thunder and the attack deals an extra 2d6 thunder damage to the target. Additionally, if the target is a creature, it must succeed on a Strength saving throw or be pushed 10 ft away from you and knocked prone.
+**[Paladin]**
-# 103. - Thunderwave (V,S) level 1 Evocation [SOL]
+The first time you hit with a melee weapon attack during this spell's duration, your weapon rings with thunder that is audible within 300 feet of you, and the attack deals an extra 2d6 thunder damage to the target. Additionally, if the target is a creature, it must succeed on a Strength saving throw or be pushed 10 feet away from you and knocked prone.
+
+# 105. - Thunderwave (V,S) level 1 Evocation [SOL]
+
+**[Bard, Druid, Sorcerer, Wizard]**
Emit a wave of force that causes damage and pushes creatures and objects away.
-# 104. - Tiefling's Hellish Rebuke (V,S) level 1 Evocation [SOL]
+# 106. - Tiefling's Hellish Rebuke (V,S) level 1 Evocation [SOL]
+
When you are damaged by a creature withing range, you can use your reaction to inflict fire damage back at them. This tiefling version of the spell is more powerful than the common one but cannot use a higher level Spell Slot to increase damage.
-# 105. - *Witch Bolt* © (V,S) level 1 Evocation [Concentration] [UB]
+# 107. - *Witch Bolt* © (V,S) level 1 Evocation [Concentration] [UB]
+
+**[Sorcerer, Warlock, Wizard]**
A beam of crackling, blue energy lances out toward a creature within range, forming a sustained arc of lightning between you and the target. Make a ranged spell attack against that creature. On a hit, the target takes 1d12 lightning damage, and on each of your turns for the duration, you can use your action to deal 1d12 lightning damage to the target automatically. The spell ends if you use your action to do anything else. The spell also ends if the target is ever outside the spell's range. When you cast this spell using a spell slot of 2nd level or higher, the damage increases by 1d12 for each slot level above 1st.
-# 106. - *Wrathful Smite* © (V) level 1 Evocation [Concentration] [UB]
+# 108. - *Wrathful Smite* © (V) level 1 Evocation [Concentration] [UB]
+
+**[Paladin]**
+
+The next time you hit with a melee weapon attack during this spell's duration, your attack deals an extra 1d6 psychic damage. Additionally, if the target is a creature, it must make a Wisdom saving throw or be frightened of you until the spell ends. As an action, the creature can make a Wisdom check against your spell save DC to steel its resolve and end this spell.
-Your next hit deals additional 1d6 psychic damage. If target fails WIS saving throw its mind explodes in pain, and it becomes frightened.
+# 109. - *Zephyr Strike* © (V) level 1 Transmutation [Concentration] [UB]
-# 107. - *Zephyr Strike* © (V) level 1 Transmutation [Concentration] [UB]
+**[Ranger]**
You move like the wind. For the duration, your movement doesn't provoke opportunity attacks. Once before the spell ends, you can give yourself advantage on one weapon attack roll on your turn. That attack deals an extra 1d8 force damage on a hit. Whether you hit or miss, your walking speed increases by 30 feet until the end of that turn.
-# 108. - Acid Arrow (V,S) level 2 Evocation [SOL]
+# 110. - Acid Arrow (V,S) level 2 Evocation [SOL]
+
+**[Wizard]**
Launch an acid arrow that deals some damage even if you miss your shot.
-# 109. - *Aganazzar's Scorcher* © (V,S) level 2 Evocation [UB]
+# 111. - *Aganazzar's Scorcher* © (V,S) level 2 Evocation [UB]
+
+**[Sorcerer, Wizard]**
A line of roaring flame 30 feet long and 5 feet wide emanates from you in a direction you choose. Each creature in the line must make a Dexterity saving throw. A creature takes 3d10 fire damage on a failed save, or half as much damage on a successful one. When you cast this spell using a spell slot of 3rd level or higher, the damage increases by 1d10 for each slot level above 2nd.
-# 110. - Aid (V,S) level 2 Abjuration [SOL]
+# 112. - Aid (V,S) level 2 Abjuration [SOL]
+
+**[Artificer, Cleric, Paladin]**
Temporarily increases hit points for up to three allies.
-# 111. - Barkskin (V,S) level 2 Transmutation [Concentration] [SOL]
+# 113. - Barkskin (V,S) level 2 Transmutation [Concentration] [SOL]
+
+**[Druid, Ranger]**
Gives you or an ally you can touch an AC of at least 16.
-# 112. - Blindness (V) level 2 Necromancy [SOL]
+# 114. - Blindness (V) level 2 Necromancy [SOL]
+
+**[Bard, Cleric, Sorcerer, Wizard]**
Blind an enemy for one minute.
-# 113. - Blur (V) level 2 Illusion [Concentration] [SOL]
+# 115. - Blur (V) level 2 Illusion [Concentration] [SOL]
+
+**[Artificer, Sorcerer, Wizard]**
Makes you blurry and harder to hit for up to one minute.
-# 114. - *Borrowed Knowledge* © (V,S) level 2 Divination [UB]
+# 116. - *Borrowed Knowledge* © (V,S) level 2 Divination [UB]
+
+**[Bard, Cleric, Warlock, Wizard]**
You draw on knowledge from spirits of the past. Choose one skill in which you lack proficiency. For 1 hour, you have proficiency in the chosen skill. The spell ends early if you cast it again.
-# 115. - Branding Smite (V) level 2 Evocation [Concentration] [SOL]
+# 117. - Branding Smite (V) level 2 Evocation [Concentration] [SOL]
+
+**[Paladin]**
Your next hit causes additional radiant damage and your target becomes luminous.
-# 116. - Calm Emotions (V,S) level 2 Enchantment [Concentration] [SOL]
+# 118. - Calm Emotions (V,S) level 2 Enchantment [Concentration] [SOL]
+
+**[Bard, Cleric]**
Stops allies from being charmed or frightened and makes hostile humanoids indifferent.
-# 117. - *Cloud of Daggers* © (V,S) level 2 Conjuration [Concentration] [UB]
+# 119. - *Cloud of Daggers* © (V,S) level 2 Conjuration [Concentration] [UB]
+
+**[Bard, Sorcerer, Warlock, Wizard]**
You fill the air with spinning daggers in a cube 5 feet on each side, centered on a point you choose within range. A creature takes 4d4 slashing damage when it enters the spell's area for the first time on a turn or starts its turn there. When you cast this spell using a spell slot of 3rd level or higher, the damage increases by 2d4 for each slot level above 2nd.
-# 118. - Color Burst (V,S) level 2 Illusion [UB]
+# 120. - Color Burst (V,S) level 2 Illusion [UB]
+
+**[Artificer, Sorcerer, Wizard]**
Burst a luminous cube that briefly blinds anyone within 10 ft. 8d10 is how many hit points of creatures this spell can affect.
-# 119. - Conjure Goblinoids (V,S) level 2 Conjuration [Concentration] [UB]
+# 121. - Conjure Goblinoids (V,S) level 2 Conjuration [Concentration] [UB]
+
+**[Druid, Ranger]**
Conjures 2 goblins who obey your orders unless you lose concentration.
-# 120. - Darkness (V) level 2 Evocation [Concentration] [SOL]
+# 122. - Darkness (V) level 2 Evocation [Concentration] [SOL]
+
+**[Sorcerer, Warlock, Wizard]**
Create an area of magical darkness.
-# 121. - Darkvision (V,S) level 2 Transmutation [SOL]
+# 123. - Darkvision (V,S) level 2 Transmutation [SOL]
+
+**[Artificer, Druid, Ranger, Sorcerer, Wizard]**
Grant Darkvision to the target.
-# 122. - Enhance Ability (V,S) level 2 Transmutation [Concentration] [SOL]
+# 124. - Enhance Ability (V,S) level 2 Transmutation [Concentration] [SOL]
+
+**[Artificer, Bard, Cleric, Druid]**
Grant temporary powers to an ally for up to one hour.
-# 123. - Find Traps (V,S) level 2 Evocation [SOL]
+# 125. - Find Traps (V,S) level 2 Evocation [SOL]
+
+**[Cleric, Druid, Ranger]**
Spot mechanical and magical traps, but not natural hazards.
-# 124. - Flame Blade (V,S) level 2 Evocation [Concentration] [SOL]
+# 126. - Flame Blade (V,S) level 2 Evocation [Concentration] [SOL]
+
+**[Druid]**
Evokes a fiery blade for ten minutes that you can wield in battle.
-# 125. - Flaming Sphere (V,S) level 2 Evocation [Concentration] [SOL]
+# 127. - Flaming Sphere (V,S) level 2 Evocation [Concentration] [SOL]
+
+**[Druid, Wizard]**
Summons a movable, burning sphere.
-# 126. - Heat Metal (V,S) level 2 Transmutation [Concentration] [SOL]
+# 128. - Heat Metal (V,S) level 2 Transmutation [Concentration] [SOL]
+
+**[Artificer, Bard, Druid]**
Causes metallic armor worn by a target creature to glow red hot, causing fire damage and disadvantage to attack rolls and ability checks. The damage can be repeated every turn with a bonus action.
-# 127. - Hold Person (V,S) level 2 Enchantment [Concentration] [SOL]
+# 129. - Hold Person (V,S) level 2 Enchantment [Concentration] [SOL]
+
+**[Bard, Cleric, Druid, Sorcerer, Warlock, Wizard]**
Paralyze a humanoid you can see for a limited time.
-# 128. - Invisibility (V,S) level 2 Illusion [Concentration] [SOL]
+# 130. - Invisibility (V,S) level 2 Illusion [Concentration] [SOL]
+
+**[Artificer, Bard, Sorcerer, Warlock, Wizard]**
Make an ally invisible for a limited time.
-# 129. - *Kinetic Jaunt* © (S) level 2 Evocation [Concentration] [UB]
+# 131. - *Kinetic Jaunt* © (S) level 2 Evocation [Concentration] [UB]
+
+**[Artificer, Bard, Sorcerer, Wizard]**
You magically empower your movement with dance like steps, giving yourself the following benefits for the duration:
• Your walking speed increases by 10 feet.
• You don't provoke opportunity attacks.
• You can move through the space of any creature.
-# 130. - Knock (V) level 2 Transmutation [SOL]
+# 132. - Knock (V) level 2 Transmutation [SOL]
+
+**[Bard, Sorcerer, Wizard]**
Magically open locked doors, chests, and the like.
-# 131. - Lesser Restoration (V,S) level 2 Abjuration [SOL]
+# 133. - Lesser Restoration (V,S) level 2 Abjuration [SOL]
+
+**[Artificer, Bard, Cleric, Druid, Paladin, Ranger]**
Remove a detrimental condition from an ally.
-# 132. - Levitate (V,S) level 2 Transmutation [Concentration] [SOL]
+# 134. - Levitate (V,S) level 2 Transmutation [Concentration] [SOL]
+
+**[Artificer, Sorcerer, Wizard]**
Allow a creature to levitate and gain control of its aerial movement for a limited time. Can affect enemies if their size is medium or smaller.
-# 133. - Levitate (V,S) level 2 Transmutation [Concentration] [SOL]
+# 135. - Levitate (V,S) level 2 Transmutation [Concentration] [SOL]
+
Allow a creature to levitate and gain control of its aerial movement for a limited time. Can affect enemies if their size is medium or smaller.
-# 134. - Magic Weapon (V,S) level 2 Transmutation [Concentration] [SOL]
+# 136. - Magic Weapon (V,S) level 2 Transmutation [Concentration] [SOL]
+
+**[Artificer, Paladin, Wizard]**
A nonmagical weapon becomes a +1 weapon for up to one hour.
-# 135. - *Mirror Image* © (V,S) level 2 Illusion [UB]
+# 137. - *Mirror Image* © (V,S) level 2 Illusion [UB]
+
+**[Bard, Sorcerer, Warlock, Wizard]**
Three illusory duplicates of yourself appear in your space. Until the spell ends, each time a creature targets you with an attack, roll a d20 to determine whether the attack instead targets one of your duplicates.
If you have 3 duplicates, you must roll a 6 or higher to change the attack's target to a duplicate. With 2 duplicates, you must roll an 8 or higher. With 1 duplicate, you must roll an 11 or higher.
A duplicate's AC is equal to 10 + your Dexterity modifier. If an attack hits a duplicate, the duplicate is destroyed. A duplicate can be destroyed only by an attack that hits it. It ignores all other damage and effects. The spell ends when all three duplicates are destroyed.
A creature is unaffected by this spell if it is Blinded, or has Blindsight, Truesight or Tremorsense (doesn't apply if you don't touch ground).
-# 136. - Misty Step (V) level 2 Conjuration [SOL]
+# 138. - Misty Step (V) level 2 Conjuration [SOL]
+
+**[Sorcerer, Warlock, Wizard]**
Teleports you to a free cell you can see, no more than 6 cells away.
-# 137. - Moon Beam (V,S) level 2 Evocation [Concentration] [SOL]
+# 139. - Moon Beam (V,S) level 2 Evocation [Concentration] [SOL]
+
+**[Druid]**
Conjures a vertical column of moonlight which causes radiant damage. Shapechangers have disadvantage on the save.
-# 138. - Noxious Spray (V,S) level 2 Evocation [UB]
+# 140. - Noxious Spray (V,S) level 2 Evocation [UB]
+
+**[Druid, Sorcerer, Warlock, Wizard]**
You unleash a spray of noxious gases on a target within range. Make a ranged spell attack. On a hit, the target takes 4d6 poison damage and must succeed on a Constitution saving throw or spend all its next turn retching and heaving, unable to move or take actions. Constructs, elementals and undead are unaffected by this spell. When you cast this spell using a slot of 3rd level or higher, you can target one additional creature for each slot level above 2nd.
-# 139. - Pass Without Trace (V,S) level 2 Abjuration [Concentration] [SOL]
+# 141. - Pass Without Trace (V,S) level 2 Abjuration [Concentration] [SOL]
+
+**[Druid, Ranger]**
Make yourself and up to 5 allies stealthier for one hour.
-# 140. - Petal Storm (V,S) level 2 Conjuration [Concentration] [UB]
+# 142. - Petal Storm (V,S) level 2 Conjuration [Concentration] [UB]
+
+**[Druid]**
Choose an unoccupied 15-foot cube of air that you can see within range. An elemental force of swirling winds appears in the cube and lasts for the spell's duration. The cloud heavily obscures its area. Any creature that enters the storm for the first time on a turn or starts its turn there must make a Strength saving throw. On a failed save, the creature takes 3d4 slashing damage. As a bonus action, you can move the storm up to 30 ft in any direction.
-# 141. - Prayer of Healing (V) level 2 Evocation [SOL]
+# 143. - Prayer of Healing (V) level 2 Evocation [SOL]
+
+**[Cleric]**
Heal multiple allies at the same time.
-# 142. - Protect Threshold (V,S) level 2 Abjuration [UB]
+# 144. - Protect Threshold (V,S) level 2 Abjuration [UB]
+
+**[Cleric, Druid, Paladin]**
Tracing arcane sigils along its boundary, you can ward a doorway, window, or other portal from entry. For the duration, an invisible eldritch creature stalks the warded portal. Any creature that attempts to pass through the portal must make a Wisdom saving throw or take 4d6 psychic damage, or half as much on a successful save.
-# 143. - Protection from Poison (V,S) level 2 Abjuration [SOL]
+# 145. - Protection from Poison (V,S) level 2 Abjuration [SOL]
+
+**[Artificer, Druid, Paladin, Ranger]**
Cures and protects against poison.
-# 144. - Ray of Enfeeblement (V,S) level 2 Necromancy [Concentration] [SOL]
+# 146. - Ray of Enfeeblement (V,S) level 2 Necromancy [Concentration] [SOL]
+
+**[Sorcerer, Warlock, Wizard]**
Weaken an enemy so they deal less damage for one minute.
-# 145. - *Rime's Binding Ice* © (S) level 2 Evocation [UB]
+# 147. - *Rime's Binding Ice* © (S) level 2 Evocation [UB]
+
+**[Sorcerer, Wizard]**
A burst of cold energy emanates from you in a 30-foot cone. Each creature in that area must make a Constitution saving throw. On a failed save, a creature takes 3d8 cold damage and is hindered by ice formations for 1 minute, or until it uses an action to break away the ice. A creature hindered by ice has its speed reduced to 0. On a successful save, a creature takes half as much damage and isn't hindered by ice.
-# 146. - Scorching Ray (V,S) level 2 Evocation [SOL]
+# 148. - Scorching Ray (V,S) level 2 Evocation [SOL]
+
+**[Sorcerer, Wizard]**
Fling rays of fire at one or more enemies.
-# 147. - See Invisibility (V,S) level 2 Divination [SOL]
+# 149. - See Invisibility (V,S) level 2 Divination [SOL]
+
+**[Artificer, Bard, Sorcerer, Wizard]**
You can see invisible creatures.
-# 148. - *Shadow Blade* © (V,S) level 2 Illusion [Concentration] [UB]
+# 150. - *Shadow Blade* © (V,S) level 2 Illusion [Concentration] [UB]
+
+**[Sorcerer, Warlock, Wizard]**
You weave together threads of shadow to create a dagger of solidified gloom in your hand. It deals 2d8 psychic damage on a hit and has the finesse, light, and thrown properties. In addition, when you use it to attack a target that is in dim light or darkness, you make the attack roll with advantage.
-# 149. - Shatter (V,S) level 2 Evocation [SOL]
+# 151. - Shatter (V,S) level 2 Evocation [SOL]
+
+**[Bard, Sorcerer, Warlock, Wizard]**
Triggers a sudden noise that causes Thunder Damage in a 2-cell radius.
-# 150. - Silence (V,S) level 2 Illusion [Concentration] [SOL]
+# 152. - Silence (V,S) level 2 Illusion [Concentration] [SOL]
+
+**[Bard, Cleric, Ranger]**
Creates a sphere four cells in radius, inside which sound cannot exist. Stops thunder damage and prevents spellcasting using verbal components.
-# 151. - *Snilloc's Snowball Storm* © (V,S) level 2 Evocation [UB]
+# 153. - *Snilloc's Snowball Storm* © (V,S) level 2 Evocation [UB]
+
+**[Sorcerer, Wizard]**
A flurry of magic snowballs erupts from a point you choose within range. Each creature in a 3x3 cube centered on that point must make a Dexterity saving throw. A creature takes 3d8 cold damage on a failed save, or half as much damage on a successful one. When you cast this spell using a spell slot of 3rd level or higher, the damage increases by 1d8 for each slot level above 2nd.
-# 152. - Spider Climb (V,S) level 2 Transmutation [Concentration] [SOL]
+# 154. - Spider Climb (V,S) level 2 Transmutation [Concentration] [SOL]
+
+**[Artificer, Sorcerer, Warlock, Wizard]**
Touch an ally to allow them to climb walls like a spider for a limited time.
-# 153. - Spike Growth (V,S) level 2 Transmutation [Concentration] [SOL]
+# 155. - Spike Growth (V,S) level 2 Transmutation [Concentration] [SOL]
+
+**[Druid, Ranger]**
Grows spikes and thorns in the area, making the terrain difficult and causing damage for every cell of movement.
-# 154. - Spiritual Weapon (V,S) level 2 Evocation [SOL]
+# 156. - Spiritual Weapon (V,S) level 2 Evocation [SOL]
+
+**[Cleric]**
Summon a weapon that fights for you.
-# 155. - *Tasha's Mind Whip* © (V) level 2 Enchantment [UB]
+# 157. - *Tasha's Mind Whip* © (V) level 2 Enchantment [UB]
+
+**[Sorcerer, Wizard]**
You psychically lash out at one creature you can see within range. The target must make an Intelligence saving throw. On a failed save, the target takes 3d6 psychic damage, and it can't take a reaction until the end of its next turn. Moreover, on its next turn, it must choose whether it gets a move, an action, or a bonus action; it gets only one of the three. On a successful save, the target takes half as much damage and suffers none of the spell's other effects. When you cast this spell using a spell slot of 3rd level or higher, you can target one additional creature for each slot level above 2nd.
-# 156. - *Warding Bond* © (V,S) level 2 Abjuration [SOL]
+# 158. - *Warding Bond* © (V,S) level 2 Abjuration [SOL]
+
Creates a bond with the target, who gains +1 AC, +1 to saving throws and resistance to all damage, but you share all damage it receives. Lasts for one hour.
-# 157. - *Web* © (V,S) level 2 Conjuration [Concentration] [UB]
+# 159. - *Web* © (V,S) level 2 Conjuration [Concentration] [UB]
+
+**[Artificer, Sorcerer, Wizard]**
You conjure a mass of thick, sticky webbing at a point of your choice within range. The webs fill a 20-foot cube from that point for the duration. The webs are difficult terrain and lightly obscure their area. Each creature that enters them during its turn must make a Dexterity saving throw. On a failed save, the creature is restrained as long as it remains in the webs or until it breaks free. A creature restrained by the webs can use its actions to make a Strength check against your spell save DC. If it succeeds, it is no longer restrained.
-# 158. - *Wither and Bloom* © (V,S) level 2 Necromancy [UB]
+# 160. - *Wither and Bloom* © (V,S) level 2 Necromancy [UB]
+
+**[Druid, Sorcerer, Wizard]**
You invoke both death and life upon a 10-foot-radius sphere centered on an ally. Each enemy in that area must make a Constitution saving throw, taking 2d6 necrotic damage on a failed save, or half as much damage on a successful one. In addition, the target spends and rolls one of its unspent Hit Dice and regain a number of hit points equal to the roll plus your spellcasting ability modifier. When you cast this spell using a spell slot of 3rd level or higher, the damage increases by 1d6 for each slot above 2nd, and the number of Hit Dice that can be spent and added to the healing roll increases by one for each slot above 2nd.
-# 159. - Adder's Fangs (V,S) level 3 Conjuration [UB]
+# 161. - Adder's Fangs (V,S) level 3 Conjuration [UB]
+
+**[Druid, Ranger, Sorcerer, Warlock]**
You create the visage of a massive green snake that appears for an instant before bearing down on your foe. Choose a creature you can see within range. The target must make a constitution saving throw, taking 4d10 poison damage on a failure, or half as much damage on a successful one. A creature that fails its saving throw is also poisoned, and its speed is halved while poisoned by this spell. At the end of each of its turns, a target may make a constitution saving throw, ending the poison on a success. Otherwise, the poison lasts for 1 minute. When you cast this spell using a spell slot of 4th level or higher, you may target an additional creature within range for each slot level above 3rd.
-# 160. - *Ashardalon's Stride* © (V,S) level 3 Transmutation [Concentration] [UB]
+# 162. - *Ashardalon's Stride* © (V,S) level 3 Transmutation [Concentration] [UB]
+
+**[Artificer, Ranger, Sorcerer, Wizard]**
The billowing flames of a dragon blast from your feet, granting you explosive speed. For the duration, your speed increases by 20 feet and moving doesn't provoke opportunity attacks. When you move within 5 feet of a creature, it takes 1d6 fire damage from your trail of heat. A creature can take this damage only once during a turn. When you cast this spell using a spell slot of 4th level or higher, increase your speed by 5 feet for each spell slot level above 3rd. The spell deals an additional 1d6 fire damage for each slot level above 3rd.
-# 161. - *Aura of Vitality* © (V) level 3 Evocation [Concentration] [UB]
+# 163. - *Aura of Vitality* © (V) level 3 Evocation [Concentration] [UB]
+
+**[Cleric, Paladin]**
Healing energy radiates from you in an aura with a 30-foot radius. Until the spell ends, the aura moves with you, centered on you. You can use a bonus action to cause one creature in the aura (including you) to regain 2d6 hit points.
-# 162. - Beacon of Hope (V,S) level 3 Abjuration [Concentration] [SOL]
+# 164. - Beacon of Hope (V,S) level 3 Abjuration [Concentration] [SOL]
+
+**[Cleric]**
Raise hope and vitality.
-# 163. - Bestow Curse (V,S) level 3 Necromancy [Concentration] [SOL]
+# 165. - Bestow Curse (V,S) level 3 Necromancy [Concentration] [SOL]
+
+**[Bard, Cleric, Wizard]**
Curses a creature you can touch.
-# 164. - *Blinding Smite* © (V) level 3 Evocation [Concentration] [UB]
+# 166. - *Blinding Smite* © (V) level 3 Evocation [Concentration] [UB]
+
+**[Paladin]**
+
+The next time you hit a creature with a melee weapon attack during this spell's duration, you weapon flares with a bright light, and the attack deals an extra 3d8 radiant damage to the target. Additionally, the target must succeed on a Constitution saving throw or be blinded until the spell ends. A creature blinded by this spell makes another Constitution saving throw at the end of each of its turns. On a successful save, it is no longer blinded.
-On your next hit your weapon flares with a bright light, and the attack deals an extra 3d8 radiant damage to the target. Additionally, the target must succeed on a Constitution saving throw or be blinded until the spell ends.
-A creature blinded by this spell makes another Constitution saving throw at the end of each of its turns. On a successful save, it is no longer blinded.
+# 167. - Call Lightning (V,S) level 3 Conjuration [Concentration] [SOL]
-# 165. - Call Lightning (V,S) level 3 Conjuration [Concentration] [SOL]
+**[Druid]**
Conjures a storm cloud from which you can call a vertical bolt of lightning to strike targets, dealing 3D10 lightning damage. Another bolt can be repeated every turn by using an action.
-# 166. - Conjure Animal (V,S) level 3 Conjuration [Concentration] [SOL]
+# 168. - Conjure Animal (V,S) level 3 Conjuration [Concentration] [SOL]
+
+**[Druid, Ranger]**
Summon spirits in the form of beasts to help you in battle
-# 167. - Corrupting Bolt (V,S) level 3 Necromancy [UB]
+# 169. - Corrupting Bolt (V,S) level 3 Necromancy [UB]
+
+**[Sorcerer, Warlock, Wizard]**
You can fire a pulse of necrotic energy that causes a creature's body to begin to wither and decay. Make a ranged attack against a creature. On a hit, the target takes 4d8 necrotic damage and must succeed a Constitution saving throw. On a failed saving throw, the next time you or an ally of yours hits the corrupted creature with an attack before the end of your next turn, the creature has vulnerability to all of that attack's damage, and then the corruption ends. When you cast this spell using a spell slot of 4th level or higher, the damage increases by 1d8 for each slot level above 3rd.
-# 168. - Counterspell (S) level 3 Abjuration [SOL]
+# 170. - Counterspell (S) level 3 Abjuration [SOL]
+
+**[Sorcerer, Warlock, Wizard]**
Interrupt an enemy's spellcasting.
-# 169. - Create Food (S) level 3 Conjuration [SOL]
+# 171. - Create Food (S) level 3 Conjuration [SOL]
+
+**[Artificer, Cleric, Paladin]**
Conjure 15 units of food.
-# 170. - *Crusader's Mantle* © (V) level 3 Evocation [Concentration] [UB]
+# 172. - *Crusader's Mantle* © (V) level 3 Evocation [Concentration] [UB]
+
+**[Paladin]**
Surround yourself with a magical aura. Allies within the aura gain a bonus 1d4 radiant damage on their attacks.
-# 171. - Daylight (V,S) level 3 Evocation [SOL]
+# 173. - Daylight (V,S) level 3 Evocation [SOL]
+
+**[Cleric, Druid, Paladin, Ranger, Sorcerer]**
Summon a globe of bright light.
-# 172. - Dispel Magic (V,S) level 3 Abjuration [SOL]
+# 174. - Dispel Magic (V,S) level 3 Abjuration [SOL]
+
+**[Artificer, Bard, Cleric, Druid, Paladin, Sorcerer, Warlock, Wizard]**
End active spells on a creature or object.
-# 173. - *Elemental Weapon* © (V,S) level 3 Transmutation [Concentration] [UB]
+# 175. - *Elemental Weapon* © (V,S) level 3 Transmutation [Concentration] [UB]
+
+**[Artificer, Druid, Paladin, Ranger]**
Imbue a non-magical weapon with elemental magic. It gains a +1 to attack and damage rolls, and it gains 1d4 of the corresponding element's damage. When casting with a 5 or 6 spell slots, the effects increased by one die while casting at a spell slot 7 or higher increases the effects by 2.
-# 174. - Fear (V,S) level 3 Illusion [Concentration] [SOL]
+# 176. - Fear (V,S) level 3 Illusion [Concentration] [SOL]
+
+**[Bard, Sorcerer, Warlock, Wizard]**
Frighten creatures and force them to flee.
-# 175. - Fireball (V,S) level 3 Evocation [SOL]
+# 177. - Fireball (V,S) level 3 Evocation [SOL]
+
+**[Sorcerer, Wizard]**
Launch a fireball that explodes from a point of your choosing.
-# 176. - *Flame Arrows* © (M,V,S) level 3 Transmutation [Concentration] [UB]
+# 178. - *Flame Arrows* © (M,V,S) level 3 Transmutation [Concentration] [UB]
+
+**[Artificer, Druid, Ranger, Sorcerer, Wizard]**
You must be wielding a ranged weapon. When a target is hit by it, the target takes an extra 1d6 fire damage. The spell ends when twelve pieces of ammunition have been drawn from the quiver. When you cast this spell using a spell slot of 4th level or higher, the number of pieces of ammunition you can affect with this spell increases by two for each slot level above 3rd.
-# 177. - Fly (V,S) level 3 Transmutation [Concentration] [SOL]
+# 179. - Fly (V,S) level 3 Transmutation [Concentration] [SOL]
+
+**[Artificer, Sorcerer, Warlock, Wizard]**
An ally you touch gains the ability to fly for a limited time.
-# 178. - Haste (V,S) level 3 Transmutation [Concentration] [SOL]
+# 180. - Haste (V,S) level 3 Transmutation [Concentration] [SOL]
+
+**[Artificer, Sorcerer, Wizard]**
Make an ally faster and more agile, and grant them an additional action for a limited time.
-# 179. - *Hunger of Hadar* © (V,S) level 3 Transmutation [Concentration] [UB]
+# 181. - *Hunger of Hadar* © (V,S) level 3 Transmutation [Concentration] [UB]
+
+**[Warlock]**
You open a gateway to the dark between the stars, a region infested with unknown horrors. A 20-foot-radius sphere of blackness and bitter cold appears, centered on a point with range and lasting for the duration. The area extinguishes light, and creatures within it are blinded. Any creature that starts its turn in the area takes 2d6 cold damage. Any creature that ends its turn in the area must succeed on a Dexterity saving throw or take 2d6 acid damage as milky, otherworldly tentacles rub against it.
-# 180. - Hypnotic Pattern (S) level 3 Illusion [Concentration] [SOL]
+# 182. - Hypnotic Pattern (S) level 3 Illusion [Concentration] [SOL]
+
+**[Bard, Sorcerer, Warlock, Wizard]**
Charms enemies to make them harmless until attacked, but also affects allies in range.
-# 181. - *Intellect Fortress* © (V) level 3 Abjuration [Concentration] [UB]
+# 183. - *Intellect Fortress* © (V) level 3 Abjuration [Concentration] [UB]
+
+**[Artificer, Bard, Sorcerer, Warlock, Wizard]**
For the duration, you or one willing creature you can see within range has resistance to psychic damage, as well as advantage on Intelligence, Wisdom, and Charisma saving throws. When you cast this spell using a spell slot of 4th level or higher, you may target an additional creature within range for each slot level above 3rd.
-# 182. - *Life Transference* © (V,S) level 3 Necromancy [UB]
+# 184. - *Life Transference* © (V,S) level 3 Necromancy [UB]
+
+**[Cleric, Wizard]**
You sacrifice some of your health to mend another creature's injuries. You take 4d8 necrotic damage, and one creature of your choice that you can see within range regains a number of hit points equal to twice the necrotic damage you take. When you cast this spell using a spell s lot of 4th level or higher, the damage increases by 1d8 for each slot level above 3rd.
-# 183. - *Lightning Arrow* © (V,S) level 3 Transmutation [Concentration] [UB]
+# 185. - *Lightning Arrow* © (V,S) level 3 Transmutation [Concentration] [UB]
+
+**[Ranger]**
The next time you make a ranged weapon attack during the spell's duration, the weapon's ammunition, or the weapon itself if it's a thrown weapon, transforms into a bolt of lightning. Make the attack roll as normal. The target takes 3d8 lightning damage on a hit, or half as much damage on a miss. Whether you hit or miss, each creature within 10 feet of the target must make a Dexterity saving throw. Each of these creatures takes 2d8 lightning damage on a failed save, or half as much damage on a successful one. When you cast this spell using a spell slot of 4th level or higher, the damage for both effects of the spell increases by 1d8 for each slot level above 3rd.
-# 184. - Lightning Bolt (V,S) level 3 Evocation [SOL]
+# 186. - Lightning Bolt (V,S) level 3 Evocation [SOL]
+
+**[Sorcerer, Wizard]**
Unleash a stroke of lightning in a direction of your choice, damaging everyone it touches.
-# 185. - Mass Healing Word (V) level 3 Evocation [SOL]
+# 187. - Mass Healing Word (V) level 3 Evocation [SOL]
+
+**[Cleric]**
Instantly heals up to six allies you can see.
-# 186. - Protection from Energy (V,S) level 3 Abjuration [Concentration] [SOL]
+# 188. - Protection from Energy (V,S) level 3 Abjuration [Concentration] [SOL]
+
+**[Artificer, Cleric, Druid, Ranger, Sorcerer, Wizard]**
Touch one willing creature to give them resistance to this damage type.
-# 187. - *Pulse Wave* © (V,S) level 3 Evocation [UB]
+# 189. - *Pulse Wave* © (V,S) level 3 Evocation [UB]
+
+**[Wizard]**
You create intense pressure, unleash it in a 30-foot cone, and decide whether the pressure pulls or pushes creatures and objects. Each creature in that cone must make a Constitution saving throw. A creature takes 6d6 force damage on a failed save, or half as much damage on a successful one. And every creature that fails the save is either pulled 15 feet toward you or pushed 15 feet away from you, depending on the choice you made for the spell. When you cast this spell using a spell slot of 4th level or higher, the damage increases by 1d6 and the distance pulled or pushed increases by 5 feet for each slot level above 3rd.
-# 188. - Remove Curse (V,S) level 3 Abjuration [SOL]
+# 190. - Remove Curse (V,S) level 3 Abjuration [SOL]
+
+**[Cleric, Paladin, Warlock, Wizard]**
Removes all curses affecting the target.
-# 189. - Revivify (M,V,S) level 3 Necromancy [SOL]
+# 191. - Revivify (M,V,S) level 3 Necromancy [SOL]
+
+**[Artificer, Cleric, Paladin]**
Brings one creature back to life, up to 1 minute after death.
-# 190. - Sleet Storm (V,S) level 3 Conjuration [Concentration] [SOL]
+# 192. - Sleet Storm (V,S) level 3 Conjuration [Concentration] [SOL]
+
+**[Druid, Sorcerer, Wizard]**
Creates an area where the ground is slippery, vision is obscured, and concentration is harder.
-# 191. - Slow (V,S) level 3 Transmutation [Concentration] [SOL]
+# 193. - Slow (V,S) level 3 Transmutation [Concentration] [SOL]
+
+**[Sorcerer, Wizard]**
Slows and impairs the actions of up to 6 creatures.
-# 192. - Spirit Guardians (V,S) level 3 Conjuration [Concentration] [SOL]
+# 194. - Spirit Guardians (V,S) level 3 Conjuration [Concentration] [SOL]
+
+**[Cleric]**
Call forth spirits to protect you.
-# 193. - *Spirit Shroud* © (V,S) level 3 Necromancy [Concentration] [UB]
+# 195. - *Spirit Shroud* © (V,S) level 3 Necromancy [Concentration] [UB]
+
+**[Cleric, Paladin, Warlock, Wizard]**
You call forth spirits of the dead, which flit around you for the spell's duration. The spirits are intangible and invulnerable.
Until the spell ends, any attack you make deals 1d8 extra damage when you hit a creature within 10 ft of you. This damage is radiant, necrotic, or cold (your choice when you cast the spell). Any creature that takes this damage can't regain hit points until the start of your next turn.
In addition, any enemy creature within 10ft of you when you cast, or that enters or starts its turn in that range has its movement speed lowered by 10ft until start of its next turn.
When you cast this spell using a spell slot of 4th level or higher, the damage increases by 1d8 for every two slot levels above 3rd.
-# 194. - Stinking Cloud (V,S) level 3 Conjuration [Concentration] [SOL]
+# 196. - Stinking Cloud (V,S) level 3 Conjuration [Concentration] [SOL]
+
+**[Bard, Sorcerer, Wizard]**
Create a cloud of incapacitating, noxious gas.
-# 195. - *Thunder Step* © (V) level 3 Conjuration [UB]
+# 197. - *Thunder Step* © (V) level 3 Conjuration [UB]
+
+**[Sorcerer, Warlock, Wizard]**
You teleport yourself to an unoccupied space you can see within range. Immediately after you disappear, a thunderous boom sounds, and each creature within 10 feet of the space you left must make a Constitution saving throw, taking 3d10 thunder damage on a failed save, or half as much damage on a successful one. You can also teleport one willing ally. When you cast this spell using a spell slot of 4th level or higher, the damage increases by 1d10 for each slot level above 3rd.
-# 196. - Tongues (V) level 3 Divination [SOL]
+# 198. - Tongues (V) level 3 Divination [SOL]
+
+**[Bard, Cleric, Sorcerer, Warlock, Wizard]**
Grants knowledge of all languages for one hour.
-# 197. - Vampiric Touch (V,S) level 3 Necromancy [Concentration] [SOL]
+# 199. - Vampiric Touch (V,S) level 3 Necromancy [Concentration] [SOL]
+
+**[Warlock, Wizard]**
Grants you a life-draining melee attack for one minute.
-# 198. - Wind Wall (V,S) level 3 Evocation [Concentration] [SOL]
+# 200. - Wind Wall (V,S) level 3 Evocation [Concentration] [SOL]
+
+**[Druid, Ranger]**
Create a wall of wind that causes damage, pushes creatures and objects away, and disperses fogs and gases.
-# 199. - Winter's Breath (V,S) level 3 Conjuration [UB]
+# 201. - Winter's Breath (V,S) level 3 Conjuration [UB]
+
+**[Druid, Sorcerer, Wizard]**
Create a blast of cold wind to chill your enemies and knock them prone.
-# 200. - *Aura of Life* © (V) level 4 Abjuration [Concentration] [UB]
+# 202. - *Aura of Life* © (V) level 4 Abjuration [Concentration] [UB]
+
+**[Cleric, Paladin]**
Life-preserving energy radiates from you in an aura with a 30-foot radius. Until the spell ends, the aura moves with you, centered on you. Each non-hostile creature in the aura, including you, has resistance to necrotic damage, and its hit point maximum can't be reduced. In addition, a non-hostile, living creature regains 1 hit point when it starts its turn in the aura with 0 hit points.
-# 201. - *Aura of Purity* © (V) level 4 Abjuration [Concentration] [UB]
+# 203. - *Aura of Purity* © (V) level 4 Abjuration [Concentration] [UB]
+
+**[Cleric, Paladin]**
Purifying energy radiates from you in an aura with a 30-foot radius. Until the spell ends, the aura moves with you, centered on you. Each non-hostile creature in the aura, including you, can't become diseased, has resistance to poison damage, and has advantage on saving throws against effects that cause any of the following conditions: blinded, charmed, deafened, frightened, paralyzed, poisoned, and stunned.
-# 202. - Banishment (V,S) level 4 Abjuration [Concentration] [SOL]
+# 204. - Banishment (V,S) level 4 Abjuration [Concentration] [SOL]
+
+**[Cleric, Paladin, Sorcerer, Warlock, Wizard]**
Banishes a creature as long as you concentrate. The creature can be permanently banished if it is extraplanar.
-# 203. - Black Tentacles (V,S) level 4 Conjuration [Concentration] [SOL]
+# 205. - Black Tentacles (V,S) level 4 Conjuration [Concentration] [SOL]
+
+**[Wizard]**
Conjures black tentacles that restrain and damage creatures within the area of effect.
-# 204. - Blessing of Rime (V,S) level 4 Evocation [UB]
+# 206. - Blessing of Rime (V,S) level 4 Evocation [UB]
+
+**[Bard, Druid, Ranger]**
You summon a chill wind that numbs the pain of your allies. Choose up to three creatures within range. Each creature gains 3d8 temporary hit points for the duration. While a creature has these hit points, if it would make a Constitution saving throw, it gains advantage on the roll. When you cast this spell using a spell slot of 5th level or higher, the temporary hit points increase by 1d8 for each slot level above 4th.
-# 205. - Blight (V,S) level 4 Necromancy [SOL]
+# 207. - Blight (V,S) level 4 Necromancy [SOL]
+
+**[Druid, Sorcerer, Warlock, Wizard]**
Drains life from a creature, causing massive necrotic damage.
-# 206. - Brain Bulwark (V) level 4 Abjuration [UB]
+# 208. - Brain Bulwark (V) level 4 Abjuration [UB]
+
+**[Artificer, Bard, Sorcerer, Warlock, Wizard]**
For the duration, you or one willing creature you can see within range has resistance to psychic damage, as well as Immunity to the Charmed, Frightened, Fear, Mind dominated and Mind controlled conditions.
-# 207. - Confusion (V,S) level 4 Enchantment [Concentration] [SOL]
+# 209. - Confusion (V,S) level 4 Enchantment [Concentration] [SOL]
+
+**[Bard, Druid, Sorcerer, Wizard]**
Creates confusion and erratic behavior in a creature, possibly leading it to attack its allies.
-# 208. - Conjure 4 Elementals (V,S) level 4 Conjuration [Concentration] [SOL]
+# 210. - Conjure 4 Elementals (V,S) level 4 Conjuration [Concentration] [SOL]
+
4 elementals are conjured (CR 1/2).
-# 209. - Conjure Minor Elementals (V,S) level 4 Conjuration [Concentration] [SOL]
+# 211. - Conjure Minor Elementals (V,S) level 4 Conjuration [Concentration] [SOL]
+
+**[Druid, Wizard]**
Conjure elemental creatures under your command, which are dismissed when the spell ends or is broken.
-# 210. - Death Ward (V,S) level 4 Abjuration [SOL]
+# 212. - Death Ward (V,S) level 4 Abjuration [SOL]
+
+**[Cleric, Paladin]**
Protects the creature once against instant death or being reduced to 0 hit points.
-# 211. - Dimension Door (V) level 4 Conjuration [SOL]
+# 213. - Dimension Door (V) level 4 Conjuration [SOL]
+
+**[Bard, Sorcerer, Warlock, Wizard]**
Transfers the caster and a friendly creature to a specified destination.
-# 212. - Dominate Beast (V,S) level 4 Enchantment [Concentration] [SOL]
+# 214. - Dominate Beast (V,S) level 4 Enchantment [Concentration] [SOL]
+
+**[Druid, Sorcerer]**
Grants you control over an enemy beast.
-# 213. - Dreadful Omen (V,S) level 4 Enchantment [SOL]
+# 215. - Dreadful Omen (V,S) level 4 Enchantment [SOL]
+
+**[Bard, Warlock]**
You whisper dreadful words that cause immense mental anguish in your enemies. On a failed wisdom saving throw, they take psychic damage and become frightened until the end of their next turn, moving away from you as much as possible. On a successful save, they take half as much damage and are not frightened.
-# 214. - *Elemental Bane* © (V,S) level 4 Transmutation [Concentration] [UB]
+# 216. - *Elemental Bane* © (V,S) level 4 Transmutation [Concentration] [UB]
+
+**[Artificer, Druid, Warlock, Wizard]**
Choose one creature you can see within range, and choose one of the following damage types: acid, cold, fire, lightning, or thunder. The target must succeed on a Constitution saving throw or be affected by the spell for its duration. The first time each turn the affected target takes non-recurrent damage of the chosen type, the target takes an extra 2d6 damage of that type. Moreover, the target loses any resistance to that damage type until the spell ends. When you cast this spell using a spell slot of 5th level or higher, you can target one additional creature for each slot level above 4th. The creatures must be within 30 feet of each other when you target them.
-# 215. - Fire Shield (V,S) level 4 Evocation [SOL]
+# 217. - Fire Shield (V,S) level 4 Evocation [SOL]
+
+**[Sorcerer, Wizard]**
Grants resistance to fire or cold, and damages creatures attacking the caster with melee attacks.
-# 216. - Freedom of Movement (V,S) level 4 Abjuration [SOL]
+# 218. - Freedom of Movement (V,S) level 4 Abjuration [SOL]
+
+**[Artificer, Bard, Cleric, Druid, Ranger]**
Grants immunity to movement restrictions, as well as being paralyzed or restrained.
-# 217. - Giant Insect (V,S) level 4 Transmutation [Concentration] [SOL]
+# 219. - Giant Insect (V,S) level 4 Transmutation [Concentration] [SOL]
+
+**[Druid]**
Conjures a giant version of a natural insect or arthropod.
-# 218. - *Gravity Sinkhole* © (V,S) level 4 Evocation [UB]
+# 220. - *Gravity Sinkhole* © (V,S) level 4 Evocation [UB]
+
+**[Wizard]**
A 20-foot-radius sphere of crushing force forms at a point you can see within range and tugs at the creatures there. Each creature in the sphere must make a Constitution saving throw. On a failed save, the creature takes 5d10 force damage, and is pulled in a straight line toward the center of the sphere, ending in an unoccupied space as close to the center as possible. On a successful save, the creature takes half as much damage and isn't pulled. When you cast this spell using a spell slot of 5th level or higher, the damage increases by 1d10 for each slot level above 4th.
-# 219. - Greater Invisibility (V,S) level 4 Illusion [Concentration] [SOL]
+# 221. - Greater Invisibility (V,S) level 4 Illusion [Concentration] [SOL]
+
+**[Bard, Sorcerer, Wizard]**
Target becomes invisible for the duration, even when attacking or casting spells.
-# 220. - Guardian of Faith (V) level 4 Conjuration [SOL]
+# 222. - Guardian of Faith (V) level 4 Conjuration [SOL]
+
+**[Cleric]**
Conjures a large spectral guardian that damages approaching enemies.
-# 221. - *Guardian of Nature* © (V) level 4 Transmutation [Concentration] [UB]
+# 223. - *Guardian of Nature* © (V) level 4 Transmutation [Concentration] [UB]
+
+**[Druid, Ranger]**
A nature spirit answers your call and transforms you into a powerful guardian. The transformation lasts until the spell ends. You choose between a Beast or a Tree form.
-# 222. - Ice Storm (V,S) level 4 Evocation [SOL]
+# 224. - Ice Storm (V,S) level 4 Evocation [SOL]
+
+**[Druid, Sorcerer, Wizard]**
Causes bludgeoning and cold damage in the area, and turns the ground into difficult terrain.
-# 223. - Identify Creatures (V,S) level 4 Divination [SOL]
+# 225. - Identify Creatures (V,S) level 4 Divination [SOL]
+
+**[Wizard]**
Reveals full bestiary knowledge for the affected creatures.
-# 224. - Irresistible Performance (V) level 4 Enchantment [UB]
+# 226. - Irresistible Performance (V) level 4 Enchantment [UB]
+
+**[Bard]**
You weave a song into the air, causing those who hear it to applaud its magnificence. All creatures of your choice inside a 30-foot-cube within range must make a Charisma saving throw or be forced to clap and shout until the start of your next turn. A creature that is charmed by you always fails this saving throw. A clapping creature cannot perform any actions that require their hands or mouth but can otherwise act normally. This spell has no effect on creatures that are immune to charm.
-# 225. - *Mordenkainen's Faithful Hound* © (V,S) level 4 Conjuration [UB]
+# 227. - *Mordenkainen's Faithful Hound* © (V,S) level 4 Conjuration [UB]
+
+**[Artificer, Wizard]**
You conjure a phantom watchdog in an unoccupied space that you can see within range, where it remains for the duration. The hound has Darkvision up to 60 ft, Truesight up to 80 ft, is invisible to all creatures except you and can't be harmed. During each of your turns, the hound can attempt to bite one creature within 5 feet of it that is hostile to you as a free action. The hound's attack bonus is equal to your spellcasting ability modifier + your proficiency bonus. On a hit, it deals 4d8 piercing damage.
-# 226. - Phantasmal Killer (V,S) level 4 Illusion [Concentration] [SOL]
+# 228. - Phantasmal Killer (V,S) level 4 Illusion [Concentration] [SOL]
+
+**[Wizard]**
Causes psychic damage to the target creature with each turn, unless a saving throw is successful or the effect ends.
-# 227. - Psionic Blast (V) level 4 Evocation [UB]
+# 229. - Psionic Blast (V) level 4 Evocation [UB]
+
+**[Sorcerer, Warlock, Wizard]**
You unleash a debilitating wave of mental power in a 30-foot cone. Each creature in the area must make an Intelligence saving throw. On a failed save, a target takes 5d8 psychic damage, becomes dazzled and has its movement speed halved until the end of your next turn. On a successful save, a target only takes half as much damage. When you cast this spell using a spell slot of 4th level or higher, the damage increases by 1d8 for each slot level above 4th.
-# 228. - *Raulothim's Psychic Lance* © (V) level 4 Enchantment [UB]
+# 230. - *Raulothim's Psychic Lance* © (V) level 4 Enchantment [UB]
+
+**[Bard, Sorcerer, Warlock, Wizard]**
You unleash a shimmering lance of psychic power from your forehead at a creature that you can see within range. It must succeed on an Intelligence saving throw or take 7d6 psychic damage and be incapacitated until the end of your next turn. On a successful save, the creature takes half damage and isn't incapacitated. At Higher Levels. When you cast this spell using a spell slot of 4th level or higher, the damage increases by 1d6 for each slot level above 4th.
-# 229. - *Sickening Radiance* © (V,S) level 4 Evocation [Concentration] [UB]
+# 231. - *Sickening Radiance* © (V,S) level 4 Evocation [Concentration] [UB]
+
+**[Sorcerer, Warlock, Wizard]**
Dim light spreads within a 30-foot-radius sphere centered on a point you choose within range. The light spreads around corners, and it lasts until the spell ends. When a creature moves into the spell's area for the first time on a turn or starts its turn there, that creature must succeed on a Constitution saving throw or take 4d10 radiant damage, and it suffers one level of exhaustion and emits a dim light in a 5-foot radius. This light makes it impossible for the creature to benefit from being invisible. The light and any levels of exhaustion caused by this spell go away when the spell ends.
-# 230. - *Staggering Smite* © (V) level 4 Evocation [Concentration] [UB]
+# 232. - *Staggering Smite* © (V) level 4 Evocation [Concentration] [UB]
+
+**[Paladin]**
-The next time you hit a creature with a weapon attack during this spell's duration, your weapon pierces both body and mind, and the attack deals an extra 4d6 psychic damage to the target. The target must make a Wisdom saving throw. On a failed save, it has disadvantage on attack rolls and ability checks, and can't take reactions, until the end of its next turn.
+The next time you hit a creature with a melee weapon attack during this spell's duration, your weapon pierces both body and mind, and the attack deals an extra 4d6 psychic damage to the target. The target must make a Wisdom saving throw. On a failed save, it has disadvantage on attack rolls and ability checks, and can't take reactions, until the end of its next turn.
-# 231. - Stoneskin (M,V,S) level 4 Abjuration [Concentration] [SOL]
+# 233. - Stoneskin (M,V,S) level 4 Abjuration [Concentration] [SOL]
+
+**[Artificer, Druid, Ranger, Sorcerer, Wizard]**
Grants resistance to non-magical bludgeoning, slashing, and piercing damage.
-# 232. - *Vitriolic Sphere* © (V,S) level 4 Evocation [UB]
+# 234. - *Vitriolic Sphere* © (V,S) level 4 Evocation [UB]
+
+**[Sorcerer, Wizard]**
You point at a place within range, and a glowing 1-foot ball of emerald acid streaks there and explodes in a 20-foot radius. Each creature in that area must make a Dexterity saving throw. On a failed save, a creature takes 10d4 acid damage and 5d4 acid damage at the end of its next turn. On a successful save, a creature takes half the initial damage and no damage at the end of its next turn. When you cast this spell using a spell slot of 5th level or higher, the initial damage increases by 2d4 for each slot level above 4th.
-# 233. - Wall of Fire (V,S) level 4 Evocation [Concentration] [SOL]
+# 235. - Wall of Fire (V,S) level 4 Evocation [Concentration] [SOL]
+
+**[Druid, Sorcerer, Wizard]**
Create a burning wall that injures creatures in or next to it.
-# 234. - *Banishing Smite* © (V) level 5 Abjuration [Concentration] [UB]
+# 236. - *Banishing Smite* © (V) level 5 Abjuration [Concentration] [UB]
-Your next hit deals additional 5d10 force damage with your weapon. Additionally, if this attack reduces the target to 50 hit points of fewer, you banish it for 1 min.
+**[Paladin]**
-# 235. - *Circle of Power* © (V) level 5 Abjuration [Concentration] [UB]
+The next time you hit a creature with a weapon attack before this spell ends, your weapon crackles with force, and the attack deals an extra 5d10 force damage to the target. Additionally, if this attack reduces the target to 50 hit points of fewer, you banish it. If the target is native to a different plane of existence than the on you're on, the target disappears, returning to its home plane. If the target is native to the plane you're on, the creature vanishes into a harmless demi-plane. While there, the target is incapacitated. It remains there until the spell ends, at which point the target reappears in the space it left or in the nearest unoccupied space if that space is occupied.
+
+# 237. - *Circle of Power* © (V) level 5 Abjuration [Concentration] [UB]
+
+**[Paladin]**
Divine energy radiates from you, distorting and diffusing magical energy within 30 feet of you. Until the spell ends, the sphere moves with you, centered on you. For the duration, each friendly creature in the area, including you, has advantage on saving throws against spells and other magical effects. Additionally, when an affected creature succeeds on a saving throw made against a spell or magical effect that allows it to make a saving throw to take only half damage, it instead takes no damage if it succeeds on the saving throws.
-# 236. - Cloudkill (V,S) level 5 Conjuration [Concentration] [SOL]
+# 238. - Cloudkill (V,S) level 5 Conjuration [Concentration] [SOL]
+
+**[Sorcerer, Wizard]**
Creates an obscuring and poisonous cloud. The cloud moves every round.
-# 237. - Cone of Cold (V,S) level 5 Evocation [SOL]
+# 239. - Cone of Cold (V,S) level 5 Evocation [SOL]
+
+**[Sorcerer, Wizard]**
Inflicts massive cold damage in the cone of effect.
-# 238. - Conjure Elemental (V,S) level 5 Conjuration [Concentration] [SOL]
+# 240. - Conjure Elemental (V,S) level 5 Conjuration [Concentration] [SOL]
+
+**[Druid, Wizard]**
Conjures an elemental of the chosen element that fights alongside you. If you lose concentration, the elemental remains and becomes hostile.
-# 239. - Contagion (V,S) level 5 Necromancy [SOL]
+# 241. - Contagion (V,S) level 5 Necromancy [SOL]
+
+**[Cleric, Druid]**
Hit a creature to inflict a disease from the options.
-# 240. - *Dawn* © (V,S) level 5 Evocation [Concentration] [UB]
+# 242. - *Dawn* © (V,S) level 5 Evocation [Concentration] [UB]
+
+**[Cleric, Wizard]**
The light of dawn shines down on a location you specify within range. Until the spell ends, a 30-foot-radius, 40-foot-high cylinder of bright light glimmers there. This light is sunlight. When the cylinder appears, each creature in it must make a Constitution saving throw, taking 4d10 radiant damage on a failed save, or half as much damage on a successful one. A creature must also make this saving throw whenever it ends its turn in the cylinder. If you're within 60 feet of the cylinder, you can move it up to 60 feet as a bonus action on your turn.
-# 241. - *Destructive Wave* © (V) level 5 Evocation [UB]
+# 243. - *Destructive Wave* © (V) level 5 Evocation [UB]
+
+**[Paladin]**
You strike the ground, creating a burst of divine energy that ripples outward from you. Each creature you choose within 30 feet of you must succeed on a Constitution saving throw or take 5d6 thunder damage, as well as 5d6 radiant or necrotic damage, and be knocked prone. A creature that succeeds on its saving throw takes half as much damage and isn't knocked prone.
-# 242. - Dispel Evil and Good (V,S) level 5 Abjuration [Concentration] [SOL]
+# 244. - Dispel Evil and Good (V,S) level 5 Abjuration [Concentration] [SOL]
+
+**[Cleric, Paladin]**
Celestial, elementals, feys, fiends, and undead have disadvantage on attacks against you. This spell also allows you to cancel hostile enchantments or dismiss extraplanar creatures hit by your attacks once.
-# 243. - Dominate Person (V,S) level 5 Enchantment [Concentration] [SOL]
+# 245. - Dominate Person (V,S) level 5 Enchantment [Concentration] [SOL]
+
+**[Bard, Sorcerer, Wizard]**
Grants you control over an enemy creature.
-# 244. - *Far Step* © (V) level 5 Conjuration [Concentration] [UB]
+# 246. - *Far Step* © (V) level 5 Conjuration [Concentration] [UB]
+
+**[Sorcerer, Warlock, Wizard]**
You teleport up to 60 ft to an unoccupied space you can see. On each of your turns before the spell ends, you can use a bonus action to teleport in this way again.
-# 245. - Flame Strike (V,S) level 5 Evocation [SOL]
+# 247. - Flame Strike (V,S) level 5 Evocation [SOL]
+
+**[Cleric]**
Conjures a burning column of fire and radiance affecting all creatures inside.
-# 246. - Greater Restoration (V,S) level 5 Abjuration [SOL]
+# 248. - Greater Restoration (V,S) level 5 Abjuration [SOL]
+
+**[Artificer, Bard, Cleric, Druid]**
Removes one detrimental condition, such as a charm or curse, or an effect that reduces an ability score or hit points.
-# 247. - Hold Monster (V,S) level 5 Enchantment [Concentration] [SOL]
+# 249. - Hold Monster (V,S) level 5 Enchantment [Concentration] [SOL]
+
+**[Bard, Sorcerer, Warlock, Wizard]**
Paralyzes a creature unless it succeeds a WIS saving throw. No effect on undead.
-# 248. - *Immolation* © (V) level 5 Evocation [Concentration] [UB]
+# 250. - *Holy Weapon* © (V,S) level 5 Evocation [Concentration] [UB]
+
+**[Cleric, Paladin]**
+
+You imbue a weapon you touch with holy power. Until the spell ends, the weapon emits bright light in a 30-foot radius and dim light for an additional 30 feet. In addition, weapon attacks made with it deal an extra 2d8 radiant damage on a hit. If the weapon isn't already a magic weapon, it becomes one for the duration. As a bonus action on your turn, if the weapon is within 30 ft, you can dismiss this spell and cause the weapon to emit a burst of radiance. Each creature of your choice that you can see within 30 feet of the weapon must make a Constitution saving throw. On a failed save, a creature takes 4d8 radiant damage, and it is blinded for 1 minute. On a successful save, a creature takes half as much damage and isn't blinded. At the end of each of its turns, a blinded creature can make a Constitution saving throw, ending the effect on itself on a success.
+
+# 251. - *Immolation* © (V) level 5 Evocation [Concentration] [UB]
+
+**[Sorcerer, Wizard]**
Flames wreathe one creature you can see within range. The target must make a Dexterity saving throw. It takes 8d6 fire damage on a failed save, or half as much damage on a successful one. On a failed save, the target also burns for the spell's duration. The burning target sheds bright light in a 30-foot radius and dim light for an additional 30 feet and takes 8d6 fire damage at the start of each of its turns.
-# 249. - Insect Plague (V,S) level 5 Conjuration [Concentration] [SOL]
+# 252. - Insect Plague (V,S) level 5 Conjuration [Concentration] [SOL]
+
+**[Cleric, Druid, Sorcerer]**
Summons a sphere of biting insects.
-# 250. - Mantle of Thorns (V,S) level 5 Transmutation [Concentration] [UB]
+# 253. - Mantle of Thorns (V,S) level 5 Transmutation [Concentration] [UB]
+
+**[Druid]**
Surround yourself with an aura of thorns. Those that start or walk through take 2d8 piercing damage. This damage scales at higher levels by 1d8 per slot.
-# 251. - Mass Cure Wounds (V,S) level 5 Evocation [SOL]
+# 254. - Mass Cure Wounds (V,S) level 5 Evocation [SOL]
+
+**[Bard, Cleric, Druid]**
Heals up to 6 creatures.
-# 252. - Mind Twist (V,S) level 5 Enchantment [SOL]
+# 255. - Mind Twist (V,S) level 5 Enchantment [SOL]
+
+**[Sorcerer, Warlock, Wizard]**
Causes massive psychic damage to all creatures around you, and incapacitates them if they fail their INT saving throw.
-# 253. - Raise Dead (M,V,S) level 5 Necromancy [SOL]
+# 256. - Raise Dead (M,V,S) level 5 Necromancy [SOL]
+
+**[Bard, Cleric, Paladin]**
Brings one creature back to life, up to 10 days after death.
-# 254. - *Skill Empowerment* © (V,S) level 5 Divination [UB]
+# 257. - *Skill Empowerment* © (V,S) level 5 Divination [UB]
+
+**[Artificer, Bard, Sorcerer, Wizard]**
Your magic deepens a creature's understanding of its own talent. You touch one willing creature and give it expertise in one skill of your choice; until the spell ends, the creature doubles its proficiency bonus for ability checks it makes that use the chosen skill. For 1 hour, you have proficiency in the chosen skill. The spell ends early if you cast it again. You must choose a skill in which the target is proficient and that isn't already benefiting from expertise.
-# 255. - Sonic Boom (V,S) level 5 Evocation [UB]
+# 258. - Sonic Boom (V,S) level 5 Evocation [UB]
+
+**[Sorcerer, Wizard]**
A small orb the same color as the balloon used appears at a point you choose within range then expands with a loud crack into an explosion of force. Each creature in a 30-foot radius must make a Strength saving throw. A target is pushed up to 30 feet away from the center and dealt 6d8 thunder damage on a failed save, or half as much damage and no movement on a successful one.
-# 256. - *Steel Wind Strike* © (M,S) level 5 Conjuration [UB]
+# 259. - *Steel Wind Strike* © (M,S) level 5 Conjuration [UB]
+
+**[Ranger, Wizard]**
You flourish the weapon used in the casting and then vanish to strike like the wind. Choose up to five creatures you can see within range. Make a melee spell attack against each target. On a hit, a target takes 6d10 force damage. You can then teleport to an unoccupied space you can see within 5 feet of one of the targets you hit or missed.
-# 257. - *Synaptic Static* © (V) level 5 Evocation [UB]
+# 260. - *Swift Quiver* © (M,V,S) level 5 Transmutation [Concentration] [UB]
+
+**[Ranger]**
+
+You transmute your quiver so it automatically makes the ammunition leap into your hand when you reach for it. On each of your turns until the spell ends, you can use a bonus action to make two attacks with a ranged weapon.
+
+# 261. - *Synaptic Static* © (V) level 5 Evocation [UB]
+
+**[Bard, Sorcerer, Warlock, Wizard]**
You choose a point within range and cause psychic energy to explode there. Each creature in a 20-foot-radius sphere centered on that point must make an Intelligence saving throw. A target takes 8d6 psychic damage on a failed save, or half as much damage on a successful After a failed save, a target has muddled thoughts for 1 minute. During that time, it rolls a d6 and subtracts the number rolled from all its attack rolls and ability checks. The target can make an Intelligence saving throw at the end of each of its turns, ending the effect on itself on a success.
-# 258. - *Telekinesis* © (V,S) level 5 Transmutation [Concentration] [UB]
+# 262. - *Telekinesis* © (V,S) level 5 Transmutation [Concentration] [UB]
+
+**[Sorcerer, Wizard]**
You can try to move a Huge or smaller creature. Make an ability check with your spellcasting ability contested by the creature's Strength check. If you win the contest, you move the creature up to 30 feet in any direction, but not beyond the range of this spell. Until the end of your next turn, the creature is restrained in your telekinetic grip. On subsequent rounds, you can use your action to attempt to maintain your telekinetic grip on the creature by repeating the contest, or target a new creature, ending the restrained effect on the previously affected creature.
-# 259. - Blade Barrier (V,S) level 6 Evocation [Concentration] [SOL]
+# 263. - Blade Barrier (V,S) level 6 Evocation [Concentration] [SOL]
+
+**[Cleric]**
Conjures a wall of razor sharp blades which causes 6d10 slashing damage to anyone crossing it
-# 260. - Chain Lightning (V,S) level 6 Evocation [SOL]
+# 264. - Chain Lightning (V,S) level 6 Evocation [SOL]
+
+**[Sorcerer, Wizard]**
Target a creature with lightning, which can arc to 3 other targets within 6 cells.
-# 261. - Circle of Death (M,V,S) level 6 Necromancy [SOL]
+# 265. - Circle of Death (M,V,S) level 6 Necromancy [SOL]
+
+**[Sorcerer, Warlock, Wizard]**
A sphere of negative energy causes Necrotic damage from a point you choose
-# 262. - Conjure Fey (V,S) level 6 Conjuration [Concentration] [SOL]
+# 266. - Conjure Fey (V,S) level 6 Conjuration [Concentration] [SOL]
+
+**[Druid, Warlock]**
Conjures a fey creature of challenge rating 1 to 6 to fight alongside you. If you lose concentration, the creature stays but becomes hostile.
-# 263. - Disintegrate (V,S) level 6 Transmutation [SOL]
+# 267. - Disintegrate (V,S) level 6 Transmutation [SOL]
+
+**[Sorcerer, Wizard]**
Causes massive force damage on the target, which can be disintegrated if reduced to 0 hit points
-# 264. - Eyebite (V,S) level 6 Necromancy [Concentration] [SOL]
+# 268. - Eyebite (V,S) level 6 Necromancy [Concentration] [SOL]
+
+**[Bard, Sorcerer, Warlock, Wizard]**
Your eyes gain a specific property which can target a creature each turn
-# 265. - *Fizban's Platinum Shield* © (M,V,S) level 6 Abjuration [Concentration] [UB]
+# 269. - *Fizban's Platinum Shield* © (M,V,S) level 6 Abjuration [Concentration] [UB]
+
+**[Sorcerer, Wizard]**
You create a field of silvery light that surrounds a creature of your choice within range. The field sheds dim light out to 5 feet. While surrounded by the field, a creature gains the following benefits:
• The creature has half cover.
@@ -1080,59 +1628,93 @@ You create a field of silvery light that surrounds a creature of your choice wit
• If the creature is subjected to an effect that allows it to make a Dexterity saving throw to take only half damage, the creature instead takes no damage if it succeeds on the saving throw, and only half damage if it fails.
As a bonus action on subsequent turns, you can move the field to another creature within 60 feet of the field.
-# 266. - Flash Freeze (V,S) level 6 Evocation [UB]
+# 270. - Flash Freeze (V,S) level 6 Evocation [UB]
+
+**[Druid, Sorcerer, Warlock]**
You attempt to encase a creature you can see within range in a prison of solid ice. The target must make a Dexterity saving throw. On a failed save, the target takes 10d6 cold damage and becomes restrained in layers of thick ice. On a successful save, the target takes half as much damage and is not restrained. The spell can only be used on creatures up to large size. To break out, the restrained target can make a Strength check as an action against your spell save DC. On success, the target escapes and is no longer restrained. When you cast this spell using a spell slot of 7th level or higher, the cold damage increases by 2d6 for each slot level above 6th.
-# 267. - Freezing Sphere (V,S) level 6 Evocation [SOL]
+# 271. - Freezing Sphere (V,S) level 6 Evocation [SOL]
+
+**[Wizard]**
Toss a huge ball of cold energy that explodes on impact
-# 268. - Globe Of Invulnerability (V,S) level 6 Abjuration [Concentration] [SOL]
+# 272. - Globe Of Invulnerability (V,S) level 6 Abjuration [Concentration] [SOL]
+
+**[Sorcerer, Wizard]**
A sphere surrounding you prevents any spell up to 5th level to affect anyone inside it.
-# 269. - Harm (V,S) level 6 Necromancy [SOL]
+# 273. - *Gravity Fissure* © (V,S) level 6 Evocation [UB]
+
+**[Wizard]**
+
+You manifest a ravine of gravitational energy in a line originating from you that is 60 feet long, and 5 feet wide. Each creature in that line must make a Constitution saving throw, taking 8d8 force damage on a failed save, or half as much damage on a successful one. Each creature within 10 feet of the line but not in it must succeed on a Constitution saving throw or take 8d8 force damage and be pulled toward the line until the creature is in its area. When you cast this spell using a slot of 7th level or higher, the damage increases by 1d8 for each slot level above 6th.
+
+# 274. - Harm (V,S) level 6 Necromancy [SOL]
+
+**[Cleric]**
Inflicts devastating necrotic damage and reduces the maximum hit points accordingly. Cannot drop the target below 1 hit points
-# 270. - Heal (V,S) level 6 Evocation [SOL]
+# 275. - Heal (V,S) level 6 Evocation [SOL]
+
+**[Cleric, Druid]**
Heals 70 hit points and also removes blindness and diseases
-# 271. - Heroes Feast (M,V,S) level 6 Conjuration [SOL]
+# 276. - Heroes Feast (M,V,S) level 6 Conjuration [SOL]
+
+**[Cleric, Druid]**
Summons a feast which cures most ailments and grants immunity to poisonand being frightened, WIS save advantage, and increased maximum hitpoints
-# 272. - Hilarity (V) level 6 Enchantment [Concentration] [SOL]
+# 277. - Hilarity (V) level 6 Enchantment [Concentration] [SOL]
+
+**[Bard, Wizard]**
Choose one target. They fall down laughing, becoming prone and incapacitated, and take psychic damage until they save at the end of one of their turns, or until the spell ends.
-# 273. - Poison Wave (M,V,S) level 6 Evocation [UB]
+# 278. - Poison Wave (M,V,S) level 6 Evocation [UB]
+
+**[Wizard]**
A poisonous wave erupts from you, engulfing those close by. Each creature within the spell's radius must make a Constitution saving throw, taking 6d10 poison damage on a failure, or half as much damage on a successful one. A creature who fails their saving throw is also poisoned for 1 minute, and can repeat the saving throw at the end of each of its turn. When you cast this spell using a slot of 7th level or higher, the damage increases by 1d10 for each slot level above 6th.
-# 274. - Ring of Blades (M,V,S) level 6 Conjuration [Concentration] [UB]
+# 279. - Ring of Blades (M,V,S) level 6 Conjuration [Concentration] [UB]
+
+**[Wizard]**
You raise both hands as you evoke six transparent blades around you as a bonus action. When you cast this spell, and as a bonus action on each subsequent turn, you can throw one of these blades at a creature within 60 feet from you. Make a ranged spell attack. On a hit, the target takes 4d10 force damage. When you cast this spell using a spell slot of 7th level or higher, the damage of each blade increases by 1d10 for each slot level above 6th.
-# 275. - *Scatter* © (V) level 6 Conjuration [UB]
+# 280. - *Scatter* © (V) level 6 Conjuration [UB]
+
+**[Sorcerer, Warlock, Wizard]**
The air quivers around up to five creatures of your choice that you can see within range. An unwilling creature must succeed on a Wisdom saving throw to resist this spell. You teleport each affected target to an unoccupied space that you can see within 120 feet of you. That space must be on the ground or on a floor.
-# 276. - Shelter from Energy (V,S) level 6 Abjuration [UB]
+# 281. - Shelter from Energy (V,S) level 6 Abjuration [UB]
+
+**[Cleric, Druid, Sorcerer, Wizard]**
Choose one of the following damage types: acid, cold, fire, lightning, necrotic, radiant, or thunder, and then choose up to six willing creatures that you can see within range. For 1 hour, targets have resistance to that damage type. When you cast this spell using a spell slot of 7th level or higher, you may target up to one additional willing creature for each slot level above 6th.
-# 277. - Sunbeam (V,S) level 6 Evocation [Concentration] [SOL]
+# 282. - Sunbeam (V,S) level 6 Evocation [Concentration] [SOL]
+
+**[Druid, Sorcerer, Wizard]**
You conjure a line of radiance which can burn and blind creatures in the line of effect; undead and oozes save with disadvantage. The beam can be retargeted each turn
-# 278. - *Tasha's Otherworldly Guise* © (M,V,S) level 6 Transmutation [Concentration] [UB]
+# 283. - *Tasha's Otherworldly Guise* © (M,V,S) level 6 Transmutation [Concentration] [UB]
+
+**[Sorcerer, Warlock, Wizard]**
Uttering an incantation, you draw on the magic of the Lower Planes or Upper Planes (your choice) to transform yourself.
-# 279. - *Tenser's Transformation* © (V,S) level 6 Transmutation [Concentration] [UB]
+# 284. - *Tenser's Transformation* © (V,S) level 6 Transmutation [Concentration] [UB]
+
+**[Wizard]**
You endow yourself with endurance and martial prowess fueled by magic. Until the spell ends, you can't cast spells, and you gain the following benefits:
• You gain 50 temporary hit points. If any of these remain when the spell ends, they are lost.
@@ -1142,178 +1724,269 @@ You endow yourself with endurance and martial prowess fueled by magic. Until the
• You can attack twice, instead of once, when you take the Attack action on your turn.
Immediately after the spell ends, you must succeed on a DC 15 Constitution saving throw or suffer one level of exhaustion.
-# 280. - True Seeing (V,S) level 6 Divination [SOL]
+# 285. - True Seeing (V,S) level 6 Divination [SOL]
+
+**[Bard, Cleric, Sorcerer, Warlock, Wizard]**
A creature you touch gains True Sight for one hour
-# 281. - Wall of Thorns (V,S) level 6 Conjuration [Concentration] [SOL]
+# 286. - Wall of Thorns (V,S) level 6 Conjuration [Concentration] [SOL]
+
+**[Druid]**
Creates a wall of tough of needle-sharp thorns, that hurts and slows every creature in it.
-# 282. - Arcane Sword (M,V,S) level 7 Evocation [Concentration] [SOL]
+# 287. - Arcane Sword (M,V,S) level 7 Evocation [Concentration] [SOL]
+
+**[Bard, Wizard]**
Summon a weapon that fights for you.
-# 283. - Conjure Celestial (V,S) level 7 Conjuration [Concentration] [SOL]
+# 288. - Conjure Celestial (V,S) level 7 Conjuration [Concentration] [SOL]
+
+**[Cleric]**
Conjures a celestial creature of challenge rating 4 that fights alongside you. If you lose concentration, the creature is dismissed.
-# 284. - *Crown of Stars* © (V,S) level 7 Evocation [UB]
+# 289. - *Crown of Stars* © (V,S) level 7 Evocation [UB]
+
+**[Sorcerer, Warlock, Wizard]**
Seven star-like motes of light appear and orbit your head until the spell ends. You can use a bonus action to send one of the motes streaking toward one creature or object within 120 feet of you. When you do so, make a ranged spell attack. On a hit, the target takes 4d12 radiant damage. Whether you hit or miss, the mote is expended. The spell ends early if you expend the last mote. If you have four or more motes remaining, they shed bright light in a 30-foot radius and dim light for an additional 30 feet. If you have one to three motes remaining, they shed dim light in a 30-foot radius. When you cast this spell using a spell slot of 8th level or higher, the number of motes created increases by two for each slot level above 7th.
-# 285. - Delayed Blast Fireball (V,S) level 7 Evocation [Concentration] [SOL]
+# 290. - Delayed Blast Fireball (V,S) level 7 Evocation [Concentration] [SOL]
+
+**[Sorcerer, Wizard]**
Conjures a ball of fire that grows more powerful with time, detonating when a creature enters its space or when the spell ends.
-# 286. - Divine Word (V) level 7 Evocation [SOL]
+# 291. - Divine Word (V) level 7 Evocation [SOL]
+
+**[Cleric]**
Utter a divine word that inflicts various negative conditions on enemies you can see, based on their HP. Also banishes all celestials, elementals, feys, and fiends if they fail their saving throws.
-# 287. - *Draconic Transformation* © (M,V,S) level 7 Transmutation [Concentration] [UB]
+# 292. - *Draconic Transformation* © (M,V,S) level 7 Transmutation [Concentration] [UB]
+
+**[Druid, Sorcerer, Wizard]**
With a roar, you draw on the magic of dragons to transform yourself, taking on draconic features. You gain the following benefits until the spell ends:
• You have blindsight with a range of 30 feet.
• When you cast this spell, and as a bonus action on subsequent turns for the duration, you can exhale shimmering energy in a 60-foot cone. Each creature in that area must make a Dexterity saving throw, taking 6d8 force damage on a failed save, or half as much damage on a successful one.
• Incorporeal wings sprout from your back, giving you a flying speed of 60 feet.
-# 288. - Finger of Death (V,S) level 7 Necromancy [SOL]
+# 293. - Finger of Death (V,S) level 7 Necromancy [SOL]
+
+**[Sorcerer, Warlock, Wizard]**
Send negative energy coursing through a creature within range.
-# 289. - Fire Storm (V,S) level 7 Evocation [SOL]
+# 294. - Fire Storm (V,S) level 7 Evocation [SOL]
+
+**[Cleric, Druid, Sorcerer]**
Causes a wide wall of roaring flames to burst up wherever you choose within range.
-# 290. - Gravity Slam (V,S) level 7 Transmutation [SOL]
+# 295. - Gravity Slam (V,S) level 7 Transmutation [SOL]
+
+**[Druid, Sorcerer, Warlock, Wizard]**
Increase gravity to slam everyone in a specific area onto the ground.
-# 291. - Prismatic Spray (V,S) level 7 Evocation [SOL]
+# 296. - Prismatic Spray (V,S) level 7 Evocation [SOL]
+
+**[Sorcerer, Wizard]**
Each creature within the cone of effect is randomly affected by one or two (roll 8 on d8) rays with the following effects:
-# 292. - Regenerate (V,S) level 7 Transmutation [SOL]
+# 297. - Regenerate (V,S) level 7 Transmutation [SOL]
+
+**[Bard, Cleric, Druid]**
Touch a creature and stimulate its natural healing ability.
-# 293. - Rescue the Dying (V) level 7 Transmutation [UB]
+# 298. - Rescue the Dying (V) level 7 Transmutation [UB]
+
+**[Cleric, Druid]**
With a word, you call positive energy into the target's body to heal and ward it. The target regains a number of hit points equal to 4d10 + 30. It also gains temporary hit points equal to half that amount and resistance to all damage, both lasting until the end of your next turn. When you cast this spell using a spell slot of 8th level or higher, the healing increases by 2d10 for each slot level above 7th.
-# 294. - Resurrection (M,V,S) level 7 Necromancy [SOL]
+# 299. - Resurrection (M,V,S) level 7 Necromancy [SOL]
+
+**[Bard, Cleric, Druid]**
Brings one creature back to life, up to 100 years after death.
-# 295. - *Reverse Gravity* © (V,S) level 7 Transmutation [Concentration] [UB]
+# 300. - *Reverse Gravity* © (V,S) level 7 Transmutation [Concentration] [UB]
+
+**[Druid, Sorcerer, Wizard]**
This spell reverses gravity in a 50-foot-radius, 100-foot-high cylinder centered on a point within range.
-# 296. - Symbol (V,S) level 7 Abjuration [SOL]
+# 301. - Symbol (V,S) level 7 Abjuration [SOL]
+
+**[Bard, Cleric, Wizard]**
Inscribe a glyph on a surface. When an enemy starts its turn in the area or enters it, the glyph's effect is applied in a sphere with a 12-cell radius.
-# 297. - *Abi-Dalzim's Horrid Wilting* © (V,S) level 8 Necromancy [UB]
+# 302. - *Abi-Dalzim's Horrid Wilting* © (V,S) level 8 Necromancy [UB]
+
+**[Sorcerer, Wizard]**
You draw the moisture from every creature in a 30-foot cube centered on a point you choose within range. Each creature in that area must make a Constitution saving throw. Constructs and undead aren't affected, and plants and ice elementals make this saving throw with disadvantage. A creature takes 10d8 necrotic damage on a failed save, or half as much damage on a successful one.
-# 298. - Divine Blade (V,S) level 8 Evocation [Concentration] [SOL]
+# 303. - Divine Blade (V,S) level 8 Evocation [Concentration] [SOL]
+
+**[Cleric]**
A glowing blade of pure energy springs from your hand. On a hit, the target takes 6d8 radiant damage and must roll a Wisdom saving throw to avoid being stunned until the end of its next turn.
-# 299. - Dominate Monster (V,S) level 8 Enchantment [Concentration] [SOL]
+# 304. - Dominate Monster (V,S) level 8 Enchantment [Concentration] [SOL]
+
+**[Bard, Sorcerer, Warlock, Wizard]**
Grants you control over an enemy creature of any type.
-# 300. - Earthquake (V,S) level 8 Evocation [Concentration] [SOL]
+# 305. - Earthquake (V,S) level 8 Evocation [Concentration] [SOL]
+
+**[Cleric, Druid, Sorcerer]**
You create a seismic disturbance that violently shakes the ground and the creatures standing on it for the duration of the spell.
-# 301. - Feeblemind (V,S) level 8 Enchantment [SOL]
+# 306. - Feeblemind (V,S) level 8 Enchantment [SOL]
+
+**[Bard, Druid, Warlock, Wizard]**
You blast the mind of one creature, attempting to shatter its intellect and personality. The target takes 4d6 psychic damage and must make an Intelligence saving throw. On a failed save, the creature's Intelligence, Charisma and Wisdom scores become 1 and it is unable to cast spells. These effects last for 1 minute.
-# 302. - Holy Aura (V,S) level 8 Abjuration [Concentration] [SOL]
+# 307. - *Glibness* © (V) level 8 Transmutation [UB]
+
+**[Bard, Warlock]**
+
+Until the spell ends, when you make a Charisma check, you can replace the number you roll with a 15.
+
+# 308. - Holy Aura (V,S) level 8 Abjuration [Concentration] [SOL]
+
+**[Cleric]**
Allies within 6 cells of you when you cast Holy Aura gain advantage on all saving throws, and other creatures have disadvantage on attack rolls against them until the spell ends. In addition, when a fiend or an undead hits an affected creature with a melee attack, they must succeed on a Constitution saving throw or be blinded until the spell ends.
-# 303. - Incendiary Cloud (V,S) level 8 Conjuration [Concentration] [SOL]
+# 309. - Incendiary Cloud (V,S) level 8 Conjuration [Concentration] [SOL]
+
+**[Sorcerer, Wizard]**
A cloud of smoke appears in a sphere with a 4-cell radius. The cloud damages each creature inside it, and moves away from you each turn until the end of the spell's duration or until a moderate wind disperses the cloud.
-# 304. - *Maddening Darkness* © (V) level 8 Evocation [Concentration] [UB]
+# 310. - *Maddening Darkness* © (V) level 8 Evocation [Concentration] [UB]
+
+**[Warlock, Wizard]**
Magical darkness spreads from a point you choose within range to fill a 60-foot-radius sphere until the spell ends. Shrieks, gibbering, and mad laughter can be heard within the sphere. On activation, and whenever a creature ends its turn in the sphere, it must make a Wisdom saving throw, taking 6d8 psychic damage on a failed save, or half as much damage on a successful one.
-# 305. - Maze (V,S) level 8 Abjuration [Concentration] [SOL]
+# 311. - Maze (V,S) level 8 Abjuration [Concentration] [SOL]
+
+**[Wizard]**
You banish a creature that you can see within range into a labyrinthine demiplane. The target remains there for the spell's duration or until it escapes the maze.
-# 306. - *Mind Blank* © (V,S) level 8 Transmutation [UB]
+# 312. - *Mind Blank* © (V,S) level 8 Transmutation [UB]
+
+**[Bard, Wizard]**
Until the spell ends, one willing creature you touch is immune to psychic damage, any effect that would sense its emotions or read its thoughts, divination spells, and the charmed condition.
-# 307. - Power Word Stun (V) level 8 Enchantment [SOL]
+# 313. - Power Word Stun (V) level 8 Enchantment [SOL]
+
+**[Bard, Sorcerer, Warlock, Wizard]**
Overwhelm the mind of a creature that has 150 hit points or fewer, leaving it stunned.
-# 308. - Soul Expulsion (V,S) level 8 Necromancy [UB]
+# 314. - Soul Expulsion (V,S) level 8 Necromancy [UB]
+
+**[Cleric, Sorcerer, Wizard]**
You blast a foe's soul with magical power, causing it to glow with otherwordly light. Choose one creature that you can see within range, which must make a Charisma saving throw. On a failed saving throw, the target takes 11d8 necrotic damage and is stunned until the start of your next turn. On a successful saving throw, the target takes half damage and isn't stunned. Each enemy other than the target that is within 60 feet of the target must make a Wisdom saving throw. On a failed save, a creature takes 7d8 radiant damage and has disadvantage on attack rolls until the end of your next turn. On a successful saving throw a creature takes half damage and nothing else. When this spell targets undead, the spell ignores any resistance or immunity to necrotic damage, and the target has disadvantage on the saving throw. When you cast this spell using a spell slot of 9th level, both the necrotic damage and radiant damage increase by 2d8.
-# 309. - Spell Ward (V,S) level 8 Abjuration [Concentration] [SOL]
+# 315. - Spell Ward (V,S) level 8 Abjuration [Concentration] [SOL]
+
+**[Cleric, Wizard]**
Creates a mobile globe that is impenetrable to enemy spells cast from outside it.
-# 310. - Sunburst (V,S) level 8 Evocation [SOL]
+# 316. - Sunburst (V,S) level 8 Evocation [SOL]
+
+**[Druid, Sorcerer, Wizard]**
Brilliant sunlight blazes in a sphere with a 12-cell radius. Each creature that fails a Constitution saving throw takes radiant damage and is blinded for 1 minute. Any darkness created by a spell in the area is dispelled.
-# 311. - Thunderstorm (V,S) level 8 Transmutation [SOL]
+# 317. - Thunderstorm (V,S) level 8 Transmutation [SOL]
+
+**[Cleric, Druid, Wizard]**
You create a blast of thunder in a sphere that causes thunder and lightning damage to everyone, and can blind or stun those who fail a CON saving throw.
-# 312. - Wild Shapes (V,S) level 8 Transmutation [Concentration] [SOL]
+# 318. - Wild Shapes (V,S) level 8 Transmutation [Concentration] [SOL]
+
Turns other creatures in to beasts for one day.
-# 313. - *Foresight* © (V,S) level 9 Transmutation [UB]
+# 319. - *Foresight* © (V,S) level 9 Transmutation [UB]
+
+**[Bard, Druid, Warlock, Wizard]**
You touch a willing creature and bestow a limited ability to see into the immediate future. For the duration, the target can't be surprised and has advantage on attack rolls, ability checks, and saving throws. Additionally, other creatures have disadvantage on attack rolls against the target for the duration.
-# 314. - *Invulnerability* © (M,V,S) level 9 Abjuration [Concentration] [UB]
+# 320. - *Invulnerability* © (M,V,S) level 9 Abjuration [Concentration] [UB]
+
+**[Wizard]**
You are immune to all damage until the spell ends.
-# 315. - *Mass Heal* © (V,S) level 9 Transmutation [UB]
+# 321. - *Mass Heal* © (V,S) level 9 Transmutation [UB]
+
+**[Cleric]**
A flood of healing energy flows from you into injured creatures around you. You restore 120 hit points each to 6 creatures that you can see within range. Creatures healed by this spell are also cured of all diseases and any effect making them blinded or deafened. This spell has no effect on undead or constructs.
-# 316. - *Meteor Swarm* © (V,S) level 9 Transmutation [UB]
+# 322. - *Meteor Swarm* © (V,S) level 9 Transmutation [UB]
+
+**[Sorcerer, Wizard]**
Blazing orbs of fire plummet to the ground at a single point you can see within range. Each creature in a 40-foot-radius sphere centered on the point you choose must make a Dexterity saving throw. The sphere spreads around corners. A creature takes 20d6 fire damage and 20d6 bludgeoning damage on a failed save, or half as much damage on a successful one. A creature in the area of more than one fiery burst is affected only once.
-# 317. - *Power Word Heal* © (V,S) level 9 Enchantment [UB]
+# 323. - *Power Word Heal* © (V,S) level 9 Enchantment [UB]
+
+**[Bard, Cleric]**
A wave of healing energy washes over the creature you touch. The target regains all its hit points. If the creature is charmed, frightened, paralyzed, or stunned, the condition ends. If the creature is prone, it can use its reaction to stand up. This spell has no effect on undead or constructs.
-# 318. - *Power Word Kill* © (V,S) level 9 Transmutation [UB]
+# 324. - *Power Word Kill* © (V,S) level 9 Transmutation [UB]
+
+**[Bard, Sorcerer, Warlock, Wizard]**
You utter a word of power that can compel one creature you can see within range to die instantly. If the creature you choose has 100 hit points or fewer, it dies. Otherwise, the spell has no effect.
-# 319. - *Psychic Scream* © (S) level 9 Enchantment [UB]
+# 325. - *Psychic Scream* © (S) level 9 Enchantment [UB]
+
+**[Bard, Sorcerer, Warlock, Wizard]**
You unleash the power of your mind to blast the intellect of up to ten creatures of your choice that you can see within range. Each target must make an Intelligence saving throw. On a failed save, a target takes 14d6 psychic damage and is stunned for 1 minute. On a successful save, a target takes half as much damage and isn't stunned. A stunned target can make an Intelligence saving throw at the end of each of its turns. On a successful save, the stunning effect ends.
-# 320. - *Shapechange* © (M,V,S) level 9 Transmutation [Concentration] [UB]
+# 326. - *Shapechange* © (M,V,S) level 9 Transmutation [Concentration] [UB]
+
+**[Druid, Wizard]**
You assume the form of a different creature for the duration. The new form can be of any creature with a challenge rating equal to your level or lower.
-# 321. - *Time Stop* © (V) level 9 Transmutation [UB]
+# 327. - *Time Stop* © (V) level 9 Transmutation [UB]
+
+**[Sorcerer, Wizard]**
You briefly stop the flow of time for everyone but yourself. No time passes for other creatures, while you take 1d4+1 turns in a row, during which you can use actions and move as normal. This spell ends if one of the actions you use during this period, or any effects that you create during this period, affects a creature other than you.
-# 322. - *Weird* © (V,S) level 9 Illusion [Concentration] [UB]
+# 328. - *Weird* © (V,S) level 9 Illusion [Concentration] [UB]
+
+**[Warlock, Wizard]**
Drawing on the deepest fears of a group of creatures, you create illusory creatures in their minds, visible only to them. Each enemy in a 30-foot-radius sphere centered on a point of your choice within range must make a Wisdom saving throw. On a failed save, a creature becomes frightened for the duration. The illusion calls on the creature's deepest fears, manifesting its worst nightmares as an implacable threat. At the end of each of the frightened creature's turns, it must succeed on a Wisdom saving throw or take 4d10 psychic damage. On a successful save, the spell ends for that creature.
diff --git a/Media/GravityFissure.png b/Media/GravityFissure.png
deleted file mode 100644
index 09a5a089a9..0000000000
Binary files a/Media/GravityFissure.png and /dev/null differ
diff --git a/Media/MagicStone.png b/Media/MagicStone.png
new file mode 100644
index 0000000000..b26132595e
Binary files /dev/null and b/Media/MagicStone.png differ
diff --git a/SolastaUnfinishedBusiness/Actions/CharacterActionDoNothing.cs b/SolastaUnfinishedBusiness/Actions/CharacterActionDoNothing.cs
index 8e7a823609..5665dcf933 100644
--- a/SolastaUnfinishedBusiness/Actions/CharacterActionDoNothing.cs
+++ b/SolastaUnfinishedBusiness/Actions/CharacterActionDoNothing.cs
@@ -10,6 +10,6 @@ public class CharacterActionDoNothing(CharacterActionParams actionParams) : Char
{
public override IEnumerator ExecuteImpl()
{
- yield return null;
+ yield break;
}
}
diff --git a/SolastaUnfinishedBusiness/Actions/CharacterActionWildlingFeralAgility.cs b/SolastaUnfinishedBusiness/Actions/CharacterActionWildlingFeralAgility.cs
index 02ffd40c97..f23c9026d5 100644
--- a/SolastaUnfinishedBusiness/Actions/CharacterActionWildlingFeralAgility.cs
+++ b/SolastaUnfinishedBusiness/Actions/CharacterActionWildlingFeralAgility.cs
@@ -45,7 +45,5 @@ public override IEnumerator ExecuteImpl()
0,
0,
0);
-
- yield return null;
}
}
diff --git a/SolastaUnfinishedBusiness/Actions/CharacterActionWildshapeSwapAttackToggle.cs b/SolastaUnfinishedBusiness/Actions/CharacterActionWildshapeSwapAttackToggle.cs
index e61430d5e6..388409d37b 100644
--- a/SolastaUnfinishedBusiness/Actions/CharacterActionWildshapeSwapAttackToggle.cs
+++ b/SolastaUnfinishedBusiness/Actions/CharacterActionWildshapeSwapAttackToggle.cs
@@ -26,7 +26,7 @@ public override IEnumerator ExecuteImpl()
var gameLocationCharacter = GameLocationCharacter.GetFromActor(rulesetCharacter);
- if (gameLocationCharacter == null || gameLocationCharacter.HasAttackedSinceLastTurn)
+ if (gameLocationCharacter is not { HasAttackedSinceLastTurn: false })
{
yield break;
}
@@ -35,7 +35,5 @@ public override IEnumerator ExecuteImpl()
(monsterDef.AttackIterations[1], monsterDef.AttackIterations[0]);
monster.RefreshAttackModes();
-
- yield return null;
}
}
diff --git a/SolastaUnfinishedBusiness/Api/DatabaseHelper-RELEASE.cs b/SolastaUnfinishedBusiness/Api/DatabaseHelper-RELEASE.cs
index 1151c55f7a..3aac386d9b 100644
--- a/SolastaUnfinishedBusiness/Api/DatabaseHelper-RELEASE.cs
+++ b/SolastaUnfinishedBusiness/Api/DatabaseHelper-RELEASE.cs
@@ -30,7 +30,9 @@ internal static class ActionDefinitions
internal static ActionDefinition CastMain { get; } = GetDefinition("CastMain");
internal static ActionDefinition CastBonus { get; } = GetDefinition("CastBonus");
internal static ActionDefinition CastInvocation { get; } = GetDefinition("CastInvocation");
+ internal static ActionDefinition CastNoCost { get; } = GetDefinition("CastNoCost");
internal static ActionDefinition DashBonus { get; } = GetDefinition("DashBonus");
+ internal static ActionDefinition DropProne { get; } = GetDefinition("DropProne");
internal static ActionDefinition ReapplyEffect { get; } = GetDefinition("ReapplyEffect");
internal static ActionDefinition SpiritRage { get; } = GetDefinition("SpiritRage");
@@ -130,9 +132,21 @@ internal static class CharacterFamilyDefinitions
internal static CharacterFamilyDefinition Construct { get; } =
GetDefinition("Construct");
+ internal static CharacterFamilyDefinition Dragon { get; } =
+ GetDefinition("Dragon");
+
internal static CharacterFamilyDefinition Elemental { get; } =
GetDefinition("Elemental");
+ internal static CharacterFamilyDefinition Fey { get; } =
+ GetDefinition("Fey");
+
+ internal static CharacterFamilyDefinition Fiend { get; } =
+ GetDefinition("Fiend");
+
+ internal static CharacterFamilyDefinition Giant { get; } =
+ GetDefinition("Giant");
+
internal static CharacterFamilyDefinition Humanoid { get; } =
GetDefinition("Humanoid");
@@ -291,6 +305,45 @@ internal static class CharacterSubclassDefinitions
internal static class ConditionDefinitions
{
+ internal static ConditionDefinition ConditionDashing { get; } =
+ GetDefinition("ConditionDashing");
+
+ internal static ConditionDefinition ConditionDashingAdditional { get; } =
+ GetDefinition("ConditionDashingAdditional");
+
+ internal static ConditionDefinition ConditionDashingAdditionalSwiftBlade { get; } =
+ GetDefinition("ConditionDashingAdditionalSwiftBlade");
+
+ internal static ConditionDefinition ConditionDashingBonus { get; } =
+ GetDefinition("ConditionDashingBonus");
+
+ internal static ConditionDefinition ConditionDashingBonusAdditional { get; } =
+ GetDefinition("ConditionDashingBonusAdditional");
+
+ internal static ConditionDefinition ConditionDashingBonusStepOfTheWind { get; } =
+ GetDefinition("ConditionDashingBonusStepOfTheWind");
+
+ internal static ConditionDefinition ConditionDashingBonusSwiftBlade { get; } =
+ GetDefinition("ConditionDashingBonusSwiftBlade");
+
+ internal static ConditionDefinition ConditionDashingBonusSwiftSteps { get; } =
+ GetDefinition("ConditionDashingBonusSwiftSteps");
+
+ internal static ConditionDefinition ConditionDashingExpeditiousRetreat { get; } =
+ GetDefinition("ConditionDashingExpeditiousRetreat");
+
+ internal static ConditionDefinition ConditionDashingExpeditiousRetreatSwiftBlade { get; } =
+ GetDefinition("ConditionDashingExpeditiousRetreatSwiftBlade");
+
+ internal static ConditionDefinition ConditionDashingSwiftBlade { get; } =
+ GetDefinition("ConditionDashingSwiftBlade");
+
+ internal static ConditionDefinition ConditionMonkFlurryOfBlowsUnarmedStrikeBonus { get; } =
+ GetDefinition("ConditionMonkFlurryOfBlowsUnarmedStrikeBonus");
+
+ internal static ConditionDefinition ConditionDomainMischiefBorrowedLuck { get; } =
+ GetDefinition("ConditionDomainMischiefBorrowedLuck");
+
internal static ConditionDefinition ConditionSurged { get; } =
GetDefinition("ConditionSurged");
@@ -456,9 +509,6 @@ internal static class ConditionDefinitions
internal static ConditionDefinition ConditionFrightenedPhantasmalKiller { get; } =
GetDefinition("ConditionFrightenedPhantasmalKiller");
- internal static ConditionDefinition ConditionGrappledRestrainedRemorhaz { get; } =
- GetDefinition("ConditionGrappledRestrainedRemorhaz");
-
internal static ConditionDefinition ConditionGuided { get; } =
GetDefinition("ConditionGuided");
@@ -639,9 +689,6 @@ internal static class ConditionDefinitions
internal static ConditionDefinition ConditionRestrainedByMagicalArrow { get; } =
GetDefinition("ConditionRestrainedByMagicalArrow");
- internal static ConditionDefinition ConditionRestrainedByWeb { get; } =
- GetDefinition("ConditionRestrainedByWeb");
-
internal static ConditionDefinition ConditionRestrictedInsideMagicCircle { get; } =
GetDefinition("ConditionRestrictedInsideMagicCircle");
@@ -672,9 +719,6 @@ internal static class ConditionDefinitions
internal static ConditionDefinition ConditionSorcererChildRiftDeflection { get; } =
GetDefinition("ConditionSorcererChildRiftDeflection");
- internal static ConditionDefinition ConditionSpellbladeArcaneEscape { get; } =
- GetDefinition("ConditionSpellbladeArcaneEscape");
-
internal static ConditionDefinition ConditionSpiritGuardians { get; } =
GetDefinition("ConditionSpiritGuardians");
@@ -742,6 +786,9 @@ internal static class DeityDefinitions
internal static class EffectProxyDefinitions
{
+ internal static EffectProxyDefinition ProxyWallOfFire_Line { get; } =
+ GetDefinition("ProxyWallOfFire_Line");
+
internal static EffectProxyDefinition ProxyIndomitableLight { get; } =
GetDefinition("ProxyIndomitableLight");
@@ -766,7 +813,6 @@ internal static class EffectProxyDefinitions
internal static EffectProxyDefinition ProxyInsectPlague { get; } =
GetDefinition("ProxyInsectPlague");
-
internal static EffectProxyDefinition ProxySpikeGrowth { get; } =
GetDefinition("ProxySpikeGrowth");
@@ -929,6 +975,9 @@ internal static FeatureDefinitionAbilityCheckAffinity
internal static class FeatureDefinitionActionAffinitys
{
+ internal static FeatureDefinitionActionAffinity ActionAffinityMartialCommanderCoordinatedDefense { get; } =
+ GetDefinition("ActionAffinityMartialCommanderCoordinatedDefense");
+
internal static FeatureDefinitionActionAffinity ActionAffinityAggressive { get; } =
GetDefinition("ActionAffinityAggressive");
@@ -1589,6 +1638,9 @@ internal static class FeatureDefinitionMagicAffinitys
internal static class FeatureDefinitionMovementAffinitys
{
+ internal static FeatureDefinitionMovementAffinity MovementAffinityConditionDashing { get; } =
+ GetDefinition("MovementAffinityConditionDashing");
+
internal static FeatureDefinitionMovementAffinity MovementAffinityBarbarianFastMovement { get; } =
GetDefinition("MovementAffinityBarbarianFastMovement");
@@ -1718,6 +1770,12 @@ internal static class FeatureDefinitionPointPools
internal static class FeatureDefinitionPowers
{
+ internal static FeatureDefinitionPower PowerWindGuidingWinds { get; } =
+ GetDefinition("PowerWindGuidingWinds");
+
+ internal static FeatureDefinitionPower PowerBardTraditionVerbalOnslaught { get; } =
+ GetDefinition("PowerBardTraditionVerbalOnslaught");
+
internal static FeatureDefinitionPower PowerIncubus_Drain { get; } =
GetDefinition("PowerIncubus_Drain");
@@ -1796,9 +1854,6 @@ internal static class FeatureDefinitionPowers
internal static FeatureDefinitionPower PowerDefilerDarkness { get; } =
GetDefinition("PowerDefilerDarkness");
- internal static FeatureDefinitionPower PowerDefilerMistyFormEscape { get; } =
- GetDefinition("PowerDefilerMistyFormEscape");
-
internal static FeatureDefinitionPower PowerDruidCircleBalanceBalanceOfPower { get; } =
GetDefinition("PowerDruidCircleBalanceBalanceOfPower");
@@ -2468,11 +2523,6 @@ internal static class FightingStyleDefinitions
internal static class FormationDefinitions
{
internal static FormationDefinition Column2 { get; } = GetDefinition("Column2");
-
- internal static FormationDefinition SingleCreature { get; } =
- GetDefinition("SingleCreature");
-
- internal static FormationDefinition Squad4 { get; } = GetDefinition("Squad4");
}
internal static class GadgetBlueprints
@@ -3587,6 +3637,7 @@ internal static class SpellDefinitions
internal static SpellDefinition DelayedBlastFireball { get; } =
GetDefinition("DelayedBlastFireball");
+ internal static SpellDefinition Earthquake { get; } = GetDefinition("Earthquake");
internal static SpellDefinition AcidArrow { get; } = GetDefinition("AcidArrow");
internal static SpellDefinition AcidSplash { get; } = GetDefinition("AcidSplash");
internal static SpellDefinition Aid { get; } = GetDefinition("Aid");
@@ -3771,6 +3822,8 @@ internal static class SpellDefinitions
internal static SpellDefinition PrayerOfHealing { get; } = GetDefinition("PrayerOfHealing");
internal static SpellDefinition PrismaticSpray { get; } = GetDefinition("PrismaticSpray");
internal static SpellDefinition ProduceFlame { get; } = GetDefinition("ProduceFlame");
+ internal static SpellDefinition ProduceFlameHold { get; } = GetDefinition("ProduceFlameHold");
+
internal static SpellDefinition ProduceFlameHurl { get; } = GetDefinition("ProduceFlameHurl");
internal static SpellDefinition ProtectionFromEnergy { get; } =
@@ -3903,8 +3956,7 @@ internal static class DecisionPackageDefinitions
internal static DecisionPackageDefinition DefaultMeleeWithBackupRangeDecisions { get; } =
GetDefinition("DefaultMeleeWithBackupRangeDecisions");
- internal static DecisionPackageDefinition DefaultSupportCasterWithBackupAttacksDecisions { get; } =
- GetDefinition("DefaultSupportCasterWithBackupAttacksDecisions");
+ internal static DecisionPackageDefinition Fear { get; } = GetDefinition("Fear");
internal static DecisionPackageDefinition IdleGuard_Default { get; } =
GetDefinition("IdleGuard_Default");
diff --git a/SolastaUnfinishedBusiness/Api/GameExtensions/CharacterActionExtensions.cs b/SolastaUnfinishedBusiness/Api/GameExtensions/CharacterActionExtensions.cs
index 6338c1382e..10387d3b2f 100644
--- a/SolastaUnfinishedBusiness/Api/GameExtensions/CharacterActionExtensions.cs
+++ b/SolastaUnfinishedBusiness/Api/GameExtensions/CharacterActionExtensions.cs
@@ -1,13 +1,26 @@
-using System;
-using static RuleDefinitions;
-
-namespace SolastaUnfinishedBusiness.Api.GameExtensions;
+namespace SolastaUnfinishedBusiness.Api.GameExtensions;
internal static class CharacterActionExtensions
{
internal const string ShouldKeepConcentration = "ActionShouldKeepConcentration";
- // ReSharper disable once InconsistentNaming
+ internal static string FormatTitle(this CharacterAction action)
+ {
+ var magicEffect = action.actionParams.RulesetEffect;
+
+ return magicEffect == null
+ ? Gui.Localize("Action/&AttackTitle")
+ : magicEffect.SourceDefinition.FormatTitle();
+ }
+
+ internal static bool ShouldKeepConcentrationOnPowerUseOrSpend(RulesetCharacter character)
+ {
+ var glc = GameLocationCharacter.GetFromActor(character);
+
+ return glc != null && glc.UsedSpecialFeatures.ContainsKey(ShouldKeepConcentration);
+ }
+
+#if false
internal static int GetSaveDC(this CharacterAction action)
{
var actionParams = action.actionParams;
@@ -55,20 +68,5 @@ internal static int GetSaveDC(this CharacterAction action)
return saveDc;
}
-
- internal static string FormatTitle(this CharacterAction action)
- {
- var magicEffect = action.actionParams.RulesetEffect;
-
- return magicEffect == null
- ? Gui.Localize("Action/&AttackTitle")
- : magicEffect.SourceDefinition.FormatTitle();
- }
-
- internal static bool ShouldKeepConcentrationOnPowerUseOrSpend(RulesetCharacter character)
- {
- var glc = GameLocationCharacter.GetFromActor(character);
-
- return glc != null && glc.UsedSpecialFeatures.ContainsKey(ShouldKeepConcentration);
- }
+#endif
}
diff --git a/SolastaUnfinishedBusiness/Api/GameExtensions/EnumExtensions.cs b/SolastaUnfinishedBusiness/Api/GameExtensions/EnumExtensions.cs
index be7171b530..18a61c5ea6 100644
--- a/SolastaUnfinishedBusiness/Api/GameExtensions/EnumExtensions.cs
+++ b/SolastaUnfinishedBusiness/Api/GameExtensions/EnumExtensions.cs
@@ -135,7 +135,10 @@ public enum ExtraConditionInterruption
AfterWasAttackedNotBySource,
AttacksWithWeaponOrUnarmed,
SourceRageStop,
- UsesBonusAction
+ UsesBonusAction,
+ AttacksWithMeleeAndDamages,
+ SpendPower,
+ SpendPowerExecuted
}
internal enum ExtraMotionType
@@ -150,7 +153,8 @@ internal enum ExtraMotionType
// Telekinesis,
// RallyKindred,
// PushRandomDirection,
- CustomSwap = 9000
+ CustomSwap = 9000,
+ PushDown = 9001
}
internal enum ExtraPowerAttackHitComputation
diff --git a/SolastaUnfinishedBusiness/Api/GameExtensions/GameLocationCharacterExtensions.cs b/SolastaUnfinishedBusiness/Api/GameExtensions/GameLocationCharacterExtensions.cs
index 7bc7aeef45..de8ae5a884 100644
--- a/SolastaUnfinishedBusiness/Api/GameExtensions/GameLocationCharacterExtensions.cs
+++ b/SolastaUnfinishedBusiness/Api/GameExtensions/GameLocationCharacterExtensions.cs
@@ -19,7 +19,7 @@ namespace SolastaUnfinishedBusiness.Api.GameExtensions;
public static class GameLocationCharacterExtensions
{
- private static List GetActionModifiers(int count)
+ internal static List GetActionModifiers(int count)
{
var actionModifiers = new List();
@@ -75,9 +75,7 @@ internal static void MyExecuteActionDodge(this GameLocationCharacter character)
}
internal static void MyExecuteActionPowerNoCost(
- this GameLocationCharacter character,
- RulesetUsablePower usablePower,
- params GameLocationCharacter[] targets)
+ this GameLocationCharacter character, RulesetUsablePower usablePower, params GameLocationCharacter[] targets)
{
var actionModifiers = GetActionModifiers(targets.Length);
var actionService = ServiceRepository.GetService();
@@ -88,16 +86,15 @@ internal static void MyExecuteActionPowerNoCost(
ActionModifiers = actionModifiers,
RulesetEffect = implementationService.InstantiateEffectPower(rulesetCharacter, usablePower, false),
UsablePower = usablePower,
- targetCharacters = [.. targets]
+ targetCharacters = [.. targets],
+ SkipAnimationsAndVFX = true
};
actionService.ExecuteAction(actionParams, null, true);
}
internal static void MyExecuteActionSpendPower(
- this GameLocationCharacter character,
- RulesetUsablePower usablePower,
- params GameLocationCharacter[] targets)
+ this GameLocationCharacter character, RulesetUsablePower usablePower, params GameLocationCharacter[] targets)
{
var actionService = ServiceRepository.GetService();
var implementationService = ServiceRepository.GetService();
@@ -107,26 +104,50 @@ internal static void MyExecuteActionSpendPower(
StringParameter = usablePower.PowerDefinition.Name,
RulesetEffect = implementationService.InstantiateEffectPower(rulesetCharacter, usablePower, false),
UsablePower = usablePower,
- targetCharacters = [.. targets]
+ targetCharacters = [.. targets],
+ SkipAnimationsAndVFX = true
};
actionService.ExecuteInstantSingleAction(actionParams);
}
- internal static void MyExecuteActionStabilizeAndStandUp(
- this GameLocationCharacter character, int hitPoints, IMagicEffect magicEffect = null)
+ internal static void MyExecuteActionStabilizeAndStandUp(this GameLocationCharacter character, int hitPoints)
{
var actionService = ServiceRepository.GetService();
var rulesetCharacter = character.RulesetCharacter;
rulesetCharacter.StabilizeAndGainHitPoints(hitPoints);
- if (magicEffect != null)
+ actionService.ExecuteInstantSingleAction(new CharacterActionParams(character, Id.StandUp));
+ }
+
+ internal static void MyExecuteActionTacticalMove(this GameLocationCharacter character, int3 position)
+ {
+ var actionManager = ServiceRepository.GetService() as GameLocationActionManager;
+
+ if (!actionManager)
{
- EffectHelpers.StartVisualEffect(character, character, magicEffect, EffectHelpers.EffectType.Caster);
+ return;
}
- actionService.ExecuteInstantSingleAction(new CharacterActionParams(character, Id.StandUp));
+ var actionParams = new CharacterActionParams(
+ character, Id.TacticalMove, MoveStance.Run, position, LocationDefinitions.Orientation.North)
+ {
+ BoolParameter3 = false, BoolParameter5 = false
+ };
+
+ actionManager!.actionChainByCharacter.TryGetValue(character, out var actionChainSlot);
+
+ var collection = actionChainSlot?.actionQueue;
+
+ if (collection is { Count: > 0 } &&
+ collection[0].action is CharacterActionMoveStepWalk)
+ {
+ actionParams.BoolParameter2 = true;
+ }
+
+ actionManager.ExecuteActionChain(
+ new CharacterActionChainParams(actionParams.ActingCharacter, actionParams), null, false);
}
//
@@ -282,7 +303,8 @@ internal static IEnumerator MyReactToSpendPower(
StringParameter2 = stringParameter2,
RulesetEffect =
implementationService.InstantiateEffectPower(character.RulesetCharacter, usablePower, false),
- UsablePower = usablePower
+ UsablePower = usablePower,
+ SkipAnimationsAndVFX = true
};
actionService.ReactToSpendPower(actionParams);
@@ -301,6 +323,7 @@ internal static IEnumerator MyReactToSpendPowerBundle(
List targets,
GameLocationCharacter waiter,
string stringParameter,
+ string stringParameter2 = "",
Action reactionValidated = null,
Action reactionNotValidated = null,
GameLocationBattleManager battleManager = null)
@@ -320,26 +343,20 @@ internal static IEnumerator MyReactToSpendPowerBundle(
var actionParams = new CharacterActionParams(character, Id.SpendPower)
{
StringParameter = stringParameter,
+ StringParameter2 = stringParameter2,
ActionModifiers = actionModifiers,
RulesetEffect =
implementationService.InstantiateEffectPower(character.RulesetCharacter, usablePower, false),
UsablePower = usablePower,
- targetCharacters = targets
+ targetCharacters = targets,
+ SkipAnimationsAndVFX = true
};
- var reactionRequest = new ReactionRequestSpendBundlePower(actionParams);
+ var reactionRequest = new ReactionRequestSpendBundlePower(
+ actionParams, reactionValidated, reactionNotValidated);
actionManager.AddInterruptRequest(reactionRequest);
yield return battleManager.WaitForReactions(waiter, actionManager, count);
-
- if (actionParams.ReactionValidated)
- {
- reactionValidated?.Invoke(reactionRequest);
- }
- else
- {
- reactionNotValidated?.Invoke(reactionRequest);
- }
}
internal static IEnumerator MyReactToUsePower(
@@ -786,7 +803,7 @@ internal static void HandleMonkMartialArts(this GameLocationCharacter instance)
var usablePower = PowerProvider.Get(FeatureDefinitionPowers.PowerMonkMartialArts, rulesetCharacter);
- instance.MyExecuteActionSpendPower(usablePower);
+ instance.MyExecuteActionSpendPower(usablePower, instance);
}
internal static int GetAllowedMainAttacks(this GameLocationCharacter instance)
diff --git a/SolastaUnfinishedBusiness/Api/GameExtensions/RulesetActorExtensions.cs b/SolastaUnfinishedBusiness/Api/GameExtensions/RulesetActorExtensions.cs
index d74d4e95f3..3a86bce35d 100644
--- a/SolastaUnfinishedBusiness/Api/GameExtensions/RulesetActorExtensions.cs
+++ b/SolastaUnfinishedBusiness/Api/GameExtensions/RulesetActorExtensions.cs
@@ -2,12 +2,183 @@
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
+using SolastaUnfinishedBusiness.Interfaces;
+using SolastaUnfinishedBusiness.Subclasses;
using static RuleDefinitions;
namespace SolastaUnfinishedBusiness.Api.GameExtensions;
internal static class RulesetActorExtensions
{
+ #region Saving Throw Handlers
+
+ private static void OnRollSavingThrowOath(
+ RulesetCharacter caster,
+ RulesetActor target,
+ BaseDefinition sourceDefinition,
+ string selfConditionName,
+ ConditionDefinition conditionDefinitionEnemy)
+ {
+ if (caster == null ||
+ caster.Side == target.Side ||
+ !caster.HasConditionOfCategoryAndType(AttributeDefinitions.TagEffect, selfConditionName))
+ {
+ return;
+ }
+
+ if (sourceDefinition is not SpellDefinition { castingTime: ActivationTime.Action } &&
+ sourceDefinition is not FeatureDefinitionPower { RechargeRate: RechargeRate.ChannelDivinity } &&
+ !caster.ConditionsByCategory
+ .SelectMany(x => x.Value)
+ .Any(x => x.Name.Contains("Smite")))
+ {
+ return;
+ }
+
+ var gameLocationCaster = GameLocationCharacter.GetFromActor(caster);
+ var gameLocationTarget = GameLocationCharacter.GetFromActor(target);
+
+ if (gameLocationCaster == null ||
+ gameLocationTarget == null ||
+ !gameLocationCaster.IsWithinRange(gameLocationTarget, 2))
+ {
+ return;
+ }
+
+ target.InflictCondition(
+ conditionDefinitionEnemy.Name,
+ DurationType.Round,
+ 0,
+ TurnOccurenceType.StartOfTurn,
+ AttributeDefinitions.TagEffect,
+ caster.guid,
+ caster.CurrentFaction.Name,
+ 1,
+ conditionDefinitionEnemy.Name,
+ 0,
+ 0,
+ 0);
+ }
+
+ // keep a tab on last SaveDC / SaveBonusAndRollModifier / SavingThrowAbility
+ internal static int SaveDC { get; private set; }
+ internal static int SaveBonusAndRollModifier { get; private set; }
+ internal static string SavingThrowAbility { get; private set; }
+
+ internal static void MyRollSavingThrow(
+ this RulesetActor rulesetActorTarget,
+ RulesetCharacter rulesetActorCaster,
+ int saveBonus,
+ string abilityScoreName,
+ BaseDefinition sourceDefinition,
+ List modifierTrends,
+ List advantageTrends,
+ int rollModifier,
+ int saveDC,
+ bool hasHitVisual,
+ ref RollOutcome outcome,
+ ref int outcomeDelta,
+ List effectForms)
+ {
+ //PATCH: supports Oath of Ancients / Oath of Dread
+ OnRollSavingThrowOath(rulesetActorCaster, rulesetActorTarget, sourceDefinition,
+ OathOfAncients.ConditionElderChampionName,
+ OathOfAncients.ConditionElderChampionEnemy);
+ OnRollSavingThrowOath(rulesetActorCaster, rulesetActorTarget, sourceDefinition,
+ OathOfDread.ConditionAspectOfDreadName,
+ OathOfDread.ConditionAspectOfDreadEnemy);
+
+ var rulesetCharacterTarget = rulesetActorTarget as RulesetCharacter;
+
+ //BEGIN PATCH
+ if (rulesetCharacterTarget != null)
+ {
+ //PATCH: supports Path of The Savagery
+ PathOfTheSavagery.OnRollSavingThrowFuriousDefense(rulesetCharacterTarget, ref abilityScoreName);
+
+ //PATCH: supports `OnSavingThrowInitiated` interface
+ foreach (var rollSavingThrowInitiated in rulesetCharacterTarget
+ .GetSubFeaturesByType())
+ {
+ rollSavingThrowInitiated.OnSavingThrowInitiated(
+ rulesetActorCaster,
+ rulesetActorTarget,
+ ref saveBonus,
+ ref abilityScoreName,
+ sourceDefinition,
+ modifierTrends,
+ advantageTrends,
+ ref rollModifier,
+ ref saveDC,
+ ref hasHitVisual,
+ outcome,
+ outcomeDelta,
+ effectForms);
+ }
+ }
+ //END PATCH
+
+ // keep a tab on last SaveDC / SaveBonusAndRollModifier / SavingThrowAbility
+ SaveDC = saveDC;
+ SaveBonusAndRollModifier = saveBonus + rollModifier;
+ SavingThrowAbility = abilityScoreName;
+
+ var saveRoll = rulesetActorTarget.RollDie(
+ DieType.D20, RollContext.SavingThrow, false, ComputeAdvantage(advantageTrends),
+ out var firstRoll, out var secondRoll);
+
+ var totalRoll = saveRoll + saveBonus + rollModifier;
+ outcomeDelta = totalRoll - saveDC;
+ outcome = totalRoll < saveDC ? RollOutcome.Failure : RollOutcome.Success;
+
+ foreach (var modifierTrend in modifierTrends)
+ {
+ if (modifierTrend.dieFlag == TrendInfoDieFlag.None ||
+ modifierTrend is not { value: > 0, dieType: > DieType.D1 })
+ {
+ continue;
+ }
+
+ var additionalSaveDieRolled = rulesetActorTarget.AdditionalSaveDieRolled;
+
+ additionalSaveDieRolled?.Invoke(rulesetActorTarget, modifierTrend);
+ }
+
+ rulesetActorTarget.SaveRolled?.Invoke(rulesetActorTarget, abilityScoreName, sourceDefinition, outcome, saveDC,
+ totalRoll,
+ saveRoll, firstRoll, secondRoll, saveBonus + rollModifier, modifierTrends, advantageTrends, hasHitVisual);
+
+ rulesetActorTarget.ProcessConditionsMatchingInterruption(ConditionInterruption.SavingThrow);
+
+ //BEGIN PATCH
+ if (rulesetCharacterTarget == null)
+ {
+ return;
+ }
+
+ //PATCH: supports `IRollSavingThrowFinished` interface
+ foreach (var rollSavingThrowFinished in rulesetCharacterTarget.GetSubFeaturesByType())
+ {
+ rollSavingThrowFinished.OnSavingThrowFinished(
+ rulesetActorCaster,
+ rulesetActorTarget,
+ saveBonus,
+ abilityScoreName,
+ sourceDefinition,
+ modifierTrends,
+ advantageTrends,
+ rollModifier,
+ saveDC,
+ hasHitVisual,
+ ref outcome,
+ ref outcomeDelta,
+ effectForms);
+ }
+ //END PATCH
+ }
+
+ #endregion
+
internal static void ModifyAttributeAndMax(this RulesetActor hero, string attributeName, int amount)
{
var attribute = hero.GetAttribute(attributeName);
@@ -110,7 +281,7 @@ public static IEnumerable FlattenFeatureList([NotNull] IEnume
return features.SelectMany(f =>
f is FeatureDefinitionFeatureSet set
? FlattenFeatureList(set.FeatureSet)
- : new List { f });
+ : [f]);
}
[NotNull]
@@ -124,7 +295,9 @@ internal static List GetSubFeaturesByType([CanBeNull] this RulesetActor ac
if (actor != null)
{
- list.AddRange(actor.AllConditions.SelectMany(x => x.ConditionDefinition.GetAllSubFeaturesOfType()));
+ list.AddRange(actor.ConditionsByCategory
+ .SelectMany(x => x.Value)
+ .SelectMany(x => x.ConditionDefinition.GetAllSubFeaturesOfType()));
}
return list;
@@ -141,7 +314,8 @@ internal static bool HasSubFeatureOfType([CanBeNull] this RulesetActor actor,
return true;
}
- return actor?.AllConditions
+ return actor?.ConditionsByCategory
+ .SelectMany(x => x.Value)
.SelectMany(x => x.ConditionDefinition.GetAllSubFeaturesOfType())
.FirstOrDefault() != null;
}
diff --git a/SolastaUnfinishedBusiness/Api/GameExtensions/RulesetCharacterExtensions.cs b/SolastaUnfinishedBusiness/Api/GameExtensions/RulesetCharacterExtensions.cs
index b4240df485..81c4d73bfd 100644
--- a/SolastaUnfinishedBusiness/Api/GameExtensions/RulesetCharacterExtensions.cs
+++ b/SolastaUnfinishedBusiness/Api/GameExtensions/RulesetCharacterExtensions.cs
@@ -536,7 +536,8 @@ internal static bool IsMyFavoriteEnemy(this RulesetCharacter me, RulesetCharacte
internal static bool RemoveAllConditionsOfType(this RulesetCharacter character, params string[] types)
{
//should we return number of removed conditions, instead of whether we removed any?
- var conditions = character?.AllConditions
+ var conditions = character?.ConditionsByCategoryAndType
+ .SelectMany(x => x.Value)
.Where(c => types.Contains(c.conditionDefinition.Name))
.ToList();
@@ -580,7 +581,8 @@ internal static RulesetCharacterHero GetOriginalHero(this RulesetCharacter chara
internal static bool HasTemporaryConditionOfType(this RulesetCharacter character, string conditionName)
{
- return character.AllConditions
+ return character.ConditionsByCategory
+ .SelectMany(x => x.Value)
.Any(condition => condition.ConditionDefinition.IsSubtypeOf(conditionName) &&
condition.DurationType != DurationType.Permanent);
}
diff --git a/SolastaUnfinishedBusiness/Api/Helpers/EffectHelpers.cs b/SolastaUnfinishedBusiness/Api/Helpers/EffectHelpers.cs
index 72aa7eb0cb..653e26f2bd 100644
--- a/SolastaUnfinishedBusiness/Api/Helpers/EffectHelpers.cs
+++ b/SolastaUnfinishedBusiness/Api/Helpers/EffectHelpers.cs
@@ -20,6 +20,12 @@ internal static void StartVisualEffect(
IMagicEffect magicEffect,
EffectType effectType = EffectType.Impact)
{
+ // be safe on multiplayer sessions as depending on flow, SFX can break them
+ if (Global.IsMultiplayer)
+ {
+ return;
+ }
+
var prefab = effectType switch
{
EffectType.Caster => magicEffect.EffectDescription.EffectParticleParameters.CasterParticle,
diff --git a/SolastaUnfinishedBusiness/Api/Infrastructure/RulesetConditionCustom.cs b/SolastaUnfinishedBusiness/Api/Infrastructure/RulesetConditionCustom.cs
index 3578ccd851..3ad8609e11 100644
--- a/SolastaUnfinishedBusiness/Api/Infrastructure/RulesetConditionCustom.cs
+++ b/SolastaUnfinishedBusiness/Api/Infrastructure/RulesetConditionCustom.cs
@@ -94,13 +94,11 @@ protected static T GetFromPoolAndCopyOriginalRulesetCondition(RulesetCondition r
return customCondition;
}
- public static bool GetCustomConditionFromCharacter(
- RulesetCharacter rulesetCharacter,
- out T supportCondition)
+ public static bool GetCustomConditionFromCharacter(RulesetActor rulesetActor, out T supportCondition)
{
// Main.Info($"Category is {Category}, Definition is {BindingDefinition.Name}");
supportCondition =
- rulesetCharacter.TryGetConditionOfCategoryAndType(Category, BindingDefinition.Name,
+ rulesetActor.TryGetConditionOfCategoryAndType(Category, BindingDefinition.Name,
out var rulesetCondition)
? rulesetCondition as T
: null;
diff --git a/SolastaUnfinishedBusiness/Api/LanguageExtensions/Int3Extensions.cs b/SolastaUnfinishedBusiness/Api/LanguageExtensions/Int3Extensions.cs
new file mode 100644
index 0000000000..d0480662ed
--- /dev/null
+++ b/SolastaUnfinishedBusiness/Api/LanguageExtensions/Int3Extensions.cs
@@ -0,0 +1,14 @@
+#if DEBUG
+using System;
+using TA;
+
+namespace SolastaUnfinishedBusiness.Api.LanguageExtensions;
+
+public static class Int3Extensions
+{
+ public static int Manhattan(this int3 self)
+ {
+ return Math.Max(Math.Abs(self.x), Math.Max(Math.Abs(self.y), Math.Abs(self.z)));
+ }
+}
+#endif
diff --git a/SolastaUnfinishedBusiness/Api/LanguageExtensions/Vector3Extensions.cs b/SolastaUnfinishedBusiness/Api/LanguageExtensions/Vector3Extensions.cs
new file mode 100644
index 0000000000..363c8f53f8
--- /dev/null
+++ b/SolastaUnfinishedBusiness/Api/LanguageExtensions/Vector3Extensions.cs
@@ -0,0 +1,12 @@
+using System;
+using UnityEngine;
+
+namespace SolastaUnfinishedBusiness.Api.LanguageExtensions;
+
+public static class Vector3Extensions
+{
+ public static float Manhattan(this Vector3 self)
+ {
+ return Math.Max(Math.Abs(self.x), Math.Max(Math.Abs(self.y), Math.Abs(self.z)));
+ }
+}
diff --git a/SolastaUnfinishedBusiness/Api/ModKit/Utility/ModSettings.cs b/SolastaUnfinishedBusiness/Api/ModKit/Utility/ModSettings.cs
index 571daca0f7..4f70ba5226 100644
--- a/SolastaUnfinishedBusiness/Api/ModKit/Utility/ModSettings.cs
+++ b/SolastaUnfinishedBusiness/Api/ModKit/Utility/ModSettings.cs
@@ -16,7 +16,7 @@ internal static class ModSettings
public static void SaveSettings(this ModEntry modEntry, string fileName, T settings)
{
var userConfigFolder = modEntry.Path + "UserSettings";
- Directory.CreateDirectory(userConfigFolder);
+ Main.EnsureFolderExists(userConfigFolder);
var userPath = $"{userConfigFolder}{Path.DirectorySeparatorChar}{fileName}";
File.WriteAllText(userPath, JsonConvert.SerializeObject(settings, Formatting.Indented));
}
@@ -26,7 +26,7 @@ public static void LoadSettings(this ModEntry modEntry, string fileName, ref
{
var assembly = Assembly.GetExecutingAssembly();
var userConfigFolder = modEntry.Path + "UserSettings";
- Directory.CreateDirectory(userConfigFolder);
+ Main.EnsureFolderExists(userConfigFolder);
var userPath = $"{userConfigFolder}{Path.DirectorySeparatorChar}{fileName}";
try
{
diff --git a/SolastaUnfinishedBusiness/Behaviors/AddExtraAttack.cs b/SolastaUnfinishedBusiness/Behaviors/AddExtraAttack.cs
index 0137fbdcd0..0b677ce045 100644
--- a/SolastaUnfinishedBusiness/Behaviors/AddExtraAttack.cs
+++ b/SolastaUnfinishedBusiness/Behaviors/AddExtraAttack.cs
@@ -239,25 +239,11 @@ protected override List GetAttackModes([NotNull] RulesetChara
return null;
}
- var result = new List();
-
- AddItemAttack(result, EquipmentDefinitions.SlotTypeMainHand, hero);
- AddItemAttack(result, EquipmentDefinitions.SlotTypeOffHand, hero);
-
- return result;
- }
-
- private void AddItemAttack(
- // ReSharper disable once SuggestBaseTypeForParameter
- List attackModes,
- [NotNull] string slot,
- [NotNull] RulesetCharacterHero hero)
- {
- var item = hero.CharacterInventory.InventorySlotsByName[slot].EquipedItem;
+ var item = hero.CharacterInventory.InventorySlotsByName[EquipmentDefinitions.SlotTypeMainHand].EquipedItem;
if (item == null || !_weaponValidator.Invoke(null, item, hero))
{
- return;
+ return null;
}
var strikeDefinition = item.ItemDefinition;
@@ -267,7 +253,7 @@ private void AddItemAttack(
strikeDefinition.WeaponDescription,
ValidatorsCharacter.IsFreeOffhand(hero),
true,
- slot,
+ EquipmentDefinitions.SlotTypeMainHand,
hero.attackModifiers,
hero.FeaturesOrigin,
item
@@ -278,7 +264,7 @@ private void AddItemAttack(
attackMode.Thrown = ValidatorsWeapon.HasAnyWeaponTag(item.ItemDefinition, TagsDefinitions.WeaponTagThrown);
attackMode.AttackTags.Remove(TagsDefinitions.WeaponTagMelee);
- attackModes.Add(attackMode);
+ return [attackMode];
}
}
@@ -423,7 +409,7 @@ protected override List GetAttackModes([NotNull] RulesetChara
var offHandItem = hero.GetOffhandWeapon();
if (offHandItem == null ||
- !ValidatorsWeapon.IsShield(offHandItem))
+ !ValidatorsWeapon.IsShield(offHandItem.ItemDefinition))
{
return null;
}
diff --git a/SolastaUnfinishedBusiness/Behaviors/CustomSituationalContext.cs b/SolastaUnfinishedBusiness/Behaviors/CustomSituationalContext.cs
index 18fd304503..a374933ecf 100644
--- a/SolastaUnfinishedBusiness/Behaviors/CustomSituationalContext.cs
+++ b/SolastaUnfinishedBusiness/Behaviors/CustomSituationalContext.cs
@@ -60,16 +60,22 @@ internal static bool IsContextValid(
ExtraSituationalContext.IsNotConditionSource =>
// this is required whenever there is a SetMyAttackAdvantage (Taunted, Illuminating Strike, Honed Bear)
- contextParams.target.Guid != contextParams.source.AllConditions.FirstOrDefault(x =>
- x.ConditionDefinition == contextParams.condition)?.SourceGuid &&
+ contextParams.target.Guid != contextParams.source.ConditionsByCategory
+ .SelectMany(x => x.Value)
+ .FirstOrDefault(x =>
+ x.ConditionDefinition == contextParams.condition)?.SourceGuid &&
// this is required whenever there is a SetAttackOnMeAdvantage (Press the Advantage, Gambit Blind)
- contextParams.source.Guid != contextParams.target.AllConditions.FirstOrDefault(x =>
- x.ConditionDefinition == contextParams.condition)?.SourceGuid,
+ contextParams.source.Guid != contextParams.target.ConditionsByCategory
+ .SelectMany(x => x.Value)
+ .FirstOrDefault(x =>
+ x.ConditionDefinition == contextParams.condition)?.SourceGuid,
ExtraSituationalContext.IsNotConditionSourceNotRanged =>
// this is required whenever there is a SetMyAttackAdvantage (Wolf Leadership)
- contextParams.source.Guid != contextParams.source.AllConditions.FirstOrDefault(x =>
- x.ConditionDefinition == contextParams.condition)?.SourceGuid &&
+ contextParams.source.Guid != contextParams.source.ConditionsByCategory
+ .SelectMany(x => x.Value)
+ .FirstOrDefault(x =>
+ x.ConditionDefinition == contextParams.condition)?.SourceGuid &&
!contextParams.rangedAttack,
ExtraSituationalContext.TargetIsFavoriteEnemy =>
diff --git a/SolastaUnfinishedBusiness/Behaviors/ForcePushOrDragFromEffectPoint.cs b/SolastaUnfinishedBusiness/Behaviors/ForcePushOrDragFromEffectPoint.cs
index 2e9942664b..b99c9c5a30 100644
--- a/SolastaUnfinishedBusiness/Behaviors/ForcePushOrDragFromEffectPoint.cs
+++ b/SolastaUnfinishedBusiness/Behaviors/ForcePushOrDragFromEffectPoint.cs
@@ -1,6 +1,7 @@
using System.Collections.Generic;
using SolastaUnfinishedBusiness.Api.GameExtensions;
using TA;
+using static MotionForm;
namespace SolastaUnfinishedBusiness.Behaviors;
@@ -30,8 +31,8 @@ internal static int SetPositionAndApplyForms(
{
var positions = action.ActionParams.Positions;
- if (positions.Count != 0 &&
- formsParams.activeEffect.SourceDefinition.HasSubFeatureOfType())
+ var sourceDefinition = formsParams.activeEffect.SourceDefinition;
+ if (positions.Count != 0 && sourceDefinition.HasSubFeatureOfType())
{
formsParams.position = positions[0];
}
@@ -60,10 +61,28 @@ public static bool TryPushFromEffectTargetPoint(
return true;
}
- var position = formsParams.position;
- var active = source.HasSubFeatureOfType();
+ int3 position;
+ if (source.HasSubFeatureOfType())
+ {
+ position = formsParams.position;
+ }
+ else if (effectForm.MotionForm?.Type == (MotionType)ExtraMotionType.PushDown)
+ {
+ var locationTarget = GameLocationCharacter.GetFromActor(formsParams.targetCharacter);
+ if (locationTarget == null)
+ {
+ //Do nothing, maybe log error?
+ return false;
+ }
+
+ position = locationTarget.locationPosition + new int3(0, 10, 0);
+ }
+ else
+ {
+ return true;
+ }
- if (!active || position == int3.zero)
+ if (position == int3.zero)
{
return true;
}
@@ -79,8 +98,9 @@ formsParams.saveOutcome is not
var motionForm = effectForm.MotionForm;
- if (motionForm.Type != MotionForm.MotionType.PushFromOrigin
- && motionForm.Type != MotionForm.MotionType.DragToOrigin)
+ if (motionForm.Type is not MotionType.PushFromOrigin
+ and not MotionType.DragToOrigin
+ and not (MotionType)ExtraMotionType.PushDown)
{
return true;
}
@@ -98,7 +118,7 @@ formsParams.saveOutcome is not
return false;
}
- var reverse = motionForm.Type == MotionForm.MotionType.DragToOrigin;
+ var reverse = motionForm.Type == MotionType.DragToOrigin;
if (!ServiceRepository.GetService()
.ComputePushDestination(position, target, motionForm.Distance, reverse,
diff --git a/SolastaUnfinishedBusiness/Behaviors/Specific/AttackAfterMagicEffect.cs b/SolastaUnfinishedBusiness/Behaviors/Specific/AttackAfterMagicEffect.cs
index 3187ddf48e..060504be13 100644
--- a/SolastaUnfinishedBusiness/Behaviors/Specific/AttackAfterMagicEffect.cs
+++ b/SolastaUnfinishedBusiness/Behaviors/Specific/AttackAfterMagicEffect.cs
@@ -115,13 +115,9 @@ internal static List PerformAttackAfterUse(CharacterActio
attackMode.AddAttackTagAsNeeded(AttackAfterMagicEffectTag);
}
- // this is required to support reaction scenarios where AttackMain won't work
- var actionId = attackMode.ActionType == ActionDefinitions.ActionType.Main
- ? ActionDefinitions.Id.AttackMain
- : ActionDefinitions.Id.AttackFree;
-
+ // always use free attack
var attackActionParams =
- new CharacterActionParams(caster, actionId) { AttackMode = attackMode };
+ new CharacterActionParams(caster, ActionDefinitions.Id.AttackFree) { AttackMode = attackMode };
attackActionParams.TargetCharacters.Add(targets[0]);
attackActionParams.ActionModifiers.Add(new ActionModifier());
diff --git a/SolastaUnfinishedBusiness/Behaviors/VerticalPushPullMotion.cs b/SolastaUnfinishedBusiness/Behaviors/VerticalPushPullMotion.cs
new file mode 100644
index 0000000000..60ac298be0
--- /dev/null
+++ b/SolastaUnfinishedBusiness/Behaviors/VerticalPushPullMotion.cs
@@ -0,0 +1,202 @@
+using System.Linq;
+using SolastaUnfinishedBusiness.Api.LanguageExtensions;
+using TA;
+using UnityEngine;
+using static CellFlags;
+
+namespace SolastaUnfinishedBusiness.Behaviors;
+
+internal static class VerticalPushPullMotion
+{
+ private const double Epsilon = 0.015;
+ private const double StepHigh = 0.4 - Epsilon;
+ private const double StepLow = 0.1 - Epsilon;
+
+ public static bool ComputePushDestination(
+ Vector3 sourceCenter,
+ GameLocationCharacter target,
+ int distance,
+ bool reverse,
+ IGameLocationPositioningService positioningService,
+ ref int3 destination,
+ ref Vector3 direction)
+ {
+ var targetCenter = new Vector3();
+ positioningService.ComputeGravityCenterPosition(target, ref targetCenter);
+ direction = targetCenter - sourceCenter;
+ if (reverse)
+ {
+ direction = -direction;
+ var b = ((int)direction.Manhattan()) - 1;
+ distance = distance <= 0 ? b : Mathf.Min(distance, b);
+ }
+ else
+ {
+ distance = Mathf.Max(1, distance);
+ }
+
+ direction = direction.normalized;
+ destination = target.LocationPosition;
+ var position = target.LocationPosition;
+ var delta = new Vector3();
+ var result = false;
+
+ for (var index = 0; index < distance; ++index)
+ {
+ delta += direction;
+
+ var sides = Step(delta, StepHigh);
+ if (sides == int3.zero)
+ {
+ sides = Step(delta, StepLow);
+ }
+
+ var flag = sides != int3.zero;
+
+ if (flag)
+ {
+ var canMoveThroughWalls = target.CanMoveInSituation(RulesetCharacter.MotionRange.ThroughWalls);
+ var size = target.SizeParameters;
+
+ var slide = Slide(sides, delta, position, canMoveThroughWalls, size, positioningService);
+
+ flag = slide != int3.zero;
+ position += slide;
+
+ //zero delta based on full motion
+ delta.x = sides.x == 0 ? delta.x : 0;
+ delta.y = sides.y == 0 ? delta.y : 0;
+ delta.z = sides.z == 0 ? delta.z : 0;
+ }
+
+ if (flag && positioningService.CanPlaceCharacter(target, position, CellHelpers.PlacementMode.Station))
+ {
+ destination = position;
+ result = true;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ //TODO: remove after testing
+#if DEBUG
+ var applied = (target.LocationPosition - destination).Manhattan();
+ var dir = reverse ? "Pull" : "Push";
+ Main.Log(
+ $"{dir}:{distance}\u25ce [{target.Name}] moved: {applied}\u25ce, source: {sourceCenter}, target: {targetCenter}, destination: {destination}",
+ true);
+#endif
+
+ return result;
+ }
+
+ private static int3 Slide(int3 sides, Vector3 delta, int3 position, bool canMoveThroughWalls,
+ RulesetActor.SizeParameters size, IGameLocationPositioningService positioningService)
+ {
+ if (CheckDirections(sides, position, canMoveThroughWalls, size, positioningService))
+ {
+ return sides;
+ }
+
+ //TODO: should this have a setting, or always allow sliding?
+ //Full motion didn't succeed, try sliding
+ //try zeroing each direction and pick passing one with shortest zeroed delta
+
+ var d = float.MaxValue;
+ var slide = int3.zero;
+ int3 tmp;
+
+ //Try zeroing X axis
+ if (sides.x != 0 && delta.x < d)
+ {
+ tmp = new int3(0, sides.y, sides.z);
+ if (tmp != int3.zero && CheckDirections(tmp, position, canMoveThroughWalls, size, positioningService))
+ {
+ d = delta.x;
+ slide = tmp;
+ }
+ }
+
+ //Try zeroing Y axis
+ if (sides.y != 0 && delta.y < d)
+ {
+ tmp = new int3(sides.x, 0, sides.z);
+ if (tmp != int3.zero && CheckDirections(tmp, position, canMoveThroughWalls, size, positioningService))
+ {
+ d = delta.y;
+ slide = tmp;
+ }
+ }
+
+ //Try zeroing Z axis
+ if (sides.z != 0 && delta.z < d)
+ {
+ tmp = new int3(sides.x, sides.y, 0);
+ if (tmp != int3.zero && CheckDirections(tmp, position, canMoveThroughWalls, size, positioningService))
+ {
+ d = delta.z;
+ slide = tmp;
+ }
+ }
+
+ //We either got successful slide, or no way to try double slide with Y=0
+ if (slide != int3.zero || sides.x == 0 || sides.z == 0)
+ {
+ return slide;
+ }
+
+ //Last attempt: zero on Y and one of X/Z axis
+
+ //Try zeroing X and Y axis
+ if (delta.x < d)
+ {
+ tmp = new int3(0, 0, sides.z);
+ if (CheckDirections(tmp, position, canMoveThroughWalls, size, positioningService))
+ {
+ d = delta.x;
+ slide = tmp;
+ }
+ }
+
+ //Try zeroing Y and Z axis
+ if (delta.z >= d)
+ {
+ return slide;
+ }
+
+ tmp = new int3(sides.x, 0, 0);
+ if (!CheckDirections(tmp, position, canMoveThroughWalls, size, positioningService))
+ {
+ return slide;
+ }
+
+#pragma warning disable IDE0059
+ // ReSharper disable once RedundantAssignment
+ d = delta.z;
+#pragma warning restore IDE0059
+ slide = tmp;
+
+ return slide;
+ }
+
+ private static bool CheckDirections(int3 sides, int3 position, bool canMoveThroughWalls,
+ RulesetActor.SizeParameters size, IGameLocationPositioningService positioning)
+ {
+ var surfaceSides = DirectionToAllSurfaceSides(sides);
+
+ return AllSides
+ .Where(side => (side & surfaceSides) != Side.None)
+ .All(side => positioning.CanCharacterMoveThroughSide(size, position, side, canMoveThroughWalls));
+ }
+
+ private static int3 Step(Vector3 delta, double tolerance)
+ {
+ return new int3(
+ (int)Mathf.Sign(delta.x) * (Mathf.Abs(delta.x) < tolerance ? 0 : 1),
+ (int)Mathf.Sign(delta.y) * (Mathf.Abs(delta.y) < tolerance ? 0 : 1),
+ (int)Mathf.Sign(delta.z) * (Mathf.Abs(delta.z) < tolerance ? 0 : 1)
+ );
+ }
+}
diff --git a/SolastaUnfinishedBusiness/Builders/ConditionDefinitionBuilder.cs b/SolastaUnfinishedBusiness/Builders/ConditionDefinitionBuilder.cs
index b621d2ec40..e51f6248bf 100644
--- a/SolastaUnfinishedBusiness/Builders/ConditionDefinitionBuilder.cs
+++ b/SolastaUnfinishedBusiness/Builders/ConditionDefinitionBuilder.cs
@@ -2,8 +2,10 @@
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
+using SolastaUnfinishedBusiness.Api;
using SolastaUnfinishedBusiness.Api.GameExtensions;
using SolastaUnfinishedBusiness.Api.LanguageExtensions;
+using TA.AI;
using UnityEngine.AddressableAssets;
using static RuleDefinitions;
@@ -26,12 +28,10 @@ internal class ConditionDefinitionBuilder
{
private static void SetEmptyParticleReferencesWhereNull(ConditionDefinition definition)
{
- var assetReference = new AssetReference();
-
- definition.conditionStartParticleReference ??= assetReference;
- definition.conditionParticleReference ??= assetReference;
- definition.conditionEndParticleReference ??= assetReference;
- definition.characterShaderReference ??= assetReference;
+ definition.conditionStartParticleReference ??= new AssetReference();
+ definition.conditionParticleReference ??= new AssetReference();
+ definition.conditionEndParticleReference ??= new AssetReference();
+ definition.characterShaderReference ??= new AssetReference();
}
protected override void Initialise()
@@ -46,6 +46,21 @@ internal ConditionDefinitionBuilder AllowMultipleInstances()
return this;
}
+ internal ConditionDefinitionBuilder SetBrain(
+ DecisionPackageDefinition battlePackage,
+ bool addBehavior = false,
+ bool forceBehavior = false,
+ bool fearSource = false)
+ {
+ Definition.battlePackage = battlePackage;
+ Definition.explorationPackage = DatabaseHelper.DecisionPackageDefinitions.IdleGuard_Default;
+ Definition.addBehavior = addBehavior;
+ Definition.forceBehavior = forceBehavior;
+ Definition.fearSource = fearSource;
+
+ return this;
+ }
+
internal ConditionDefinitionBuilder SetCancellingConditions(params ConditionDefinition[] values)
{
Definition.cancellingConditions.SetRange(values);
diff --git a/SolastaUnfinishedBusiness/Builders/DecisionDefinitionBuilder.cs b/SolastaUnfinishedBusiness/Builders/DecisionDefinitionBuilder.cs
index 4d80babba3..a37a503246 100644
--- a/SolastaUnfinishedBusiness/Builders/DecisionDefinitionBuilder.cs
+++ b/SolastaUnfinishedBusiness/Builders/DecisionDefinitionBuilder.cs
@@ -15,6 +15,7 @@ internal DecisionDefinitionBuilder SetDecisionDescription(
string stringParameter = "",
string stringSecParameter = "",
bool boolParameter = false,
+ bool boolSecParameter = false,
float floatParameter = 0,
int enumParameter = 0)
{
@@ -26,6 +27,7 @@ internal DecisionDefinitionBuilder SetDecisionDescription(
stringParameter = stringParameter,
stringSecParameter = stringSecParameter,
boolParameter = boolParameter,
+ boolSecParameter = boolSecParameter,
floatParameter = floatParameter,
enumParameter = enumParameter
};
diff --git a/SolastaUnfinishedBusiness/Builders/DecisionPackageDefinitionBuilder.cs b/SolastaUnfinishedBusiness/Builders/DecisionPackageDefinitionBuilder.cs
new file mode 100644
index 0000000000..41a96033ec
--- /dev/null
+++ b/SolastaUnfinishedBusiness/Builders/DecisionPackageDefinitionBuilder.cs
@@ -0,0 +1,68 @@
+using System;
+using JetBrains.Annotations;
+using SolastaUnfinishedBusiness.Api.LanguageExtensions;
+using TA.AI;
+
+namespace SolastaUnfinishedBusiness.Builders;
+
+[UsedImplicitly]
+internal class DecisionPackageDefinitionBuilder
+ : DefinitionBuilder
+{
+#if false
+ internal DecisionPackageDefinitionBuilder AddWeightedDecisions(
+ params WeightedDecisionDescription[] weightedDecisionDescription)
+ {
+ Definition.Package.WeightedDecisions.AddRange(weightedDecisionDescription);
+
+ return this;
+ }
+#endif
+
+ internal DecisionPackageDefinitionBuilder SetWeightedDecisions(
+ params WeightedDecisionDescription[] weightedDecisionDescription)
+ {
+ Definition.Package.WeightedDecisions.SetRange(weightedDecisionDescription);
+
+ return this;
+ }
+
+#if false
+ internal DecisionPackageDefinitionBuilder CopyWeightedDecisions(
+ DecisionPackageDefinition decisionPackageDefinition, params int[] indexes)
+ {
+ var weightedDecisions = decisionPackageDefinition.Package.WeightedDecisions;
+
+ if (indexes.Length == 0)
+ {
+ Definition.Package.WeightedDecisions.SetRange(weightedDecisions
+ .Select(d => d.DeepCopy()));
+ }
+ else
+ {
+ foreach (var index in indexes)
+ {
+ if (index < weightedDecisions.Count)
+ {
+ Definition.Package.WeightedDecisions.Add(weightedDecisions[index]);
+ }
+ }
+ }
+
+ return this;
+ }
+#endif
+
+ #region Constructors
+
+ protected DecisionPackageDefinitionBuilder(string name, Guid namespaceGuid) : base(name, namespaceGuid)
+ {
+ }
+
+ protected DecisionPackageDefinitionBuilder(DecisionPackageDefinition original, string name, Guid namespaceGuid)
+ : base(original, name, namespaceGuid)
+ {
+ }
+
+ #endregion
+}
diff --git a/SolastaUnfinishedBusiness/Builders/EffectDescriptionBuilder.cs b/SolastaUnfinishedBusiness/Builders/EffectDescriptionBuilder.cs
index 85748d0620..69a15321ec 100644
--- a/SolastaUnfinishedBusiness/Builders/EffectDescriptionBuilder.cs
+++ b/SolastaUnfinishedBusiness/Builders/EffectDescriptionBuilder.cs
@@ -101,6 +101,37 @@ internal EffectDescriptionBuilder SetCasterEffectParameters(
return this;
}
+ internal EffectDescriptionBuilder SetConditionEffectParameters(ConditionDefinition conditionDefinition)
+ {
+ return SetConditionEffectParameters(
+ conditionDefinition.conditionStartParticleReference,
+ conditionDefinition.conditionParticleReference,
+ conditionDefinition.conditionEndParticleReference);
+ }
+
+ internal EffectDescriptionBuilder SetConditionEffectParameters(IMagicEffect magicEffect)
+ {
+ return SetConditionEffectParameters(
+ magicEffect.EffectDescription.EffectParticleParameters.conditionStartParticleReference,
+ magicEffect.EffectDescription.EffectParticleParameters.conditionParticleReference,
+ magicEffect.EffectDescription.EffectParticleParameters.conditionEndParticleReference);
+ }
+
+ internal EffectDescriptionBuilder SetConditionEffectParameters(
+ AssetReference conditionStartParticleReference = null,
+ AssetReference conditionParticleReference = null,
+ AssetReference conditionEndParticleReference = null)
+ {
+ conditionStartParticleReference ??= new AssetReference();
+ conditionParticleReference ??= new AssetReference();
+ conditionEndParticleReference ??= new AssetReference();
+
+ _effect.effectParticleParameters.conditionStartParticleReference = conditionStartParticleReference;
+ _effect.effectParticleParameters.conditionParticleReference = conditionParticleReference;
+ _effect.effectParticleParameters.conditionEndParticleReference = conditionEndParticleReference;
+ return this;
+ }
+
internal EffectDescriptionBuilder SetEffectEffectParameters(IMagicEffect reference)
{
return SetEffectEffectParameters(reference.EffectDescription.EffectParticleParameters.effectParticleReference);
@@ -211,6 +242,7 @@ internal EffectDescriptionBuilder ExcludeCaster()
return this;
}
+#if false
internal EffectDescriptionBuilder SetTargetFiltering(
TargetFilteringMethod targetFilteringMethod,
TargetFilteringTag targetFilteringTag = TargetFilteringTag.No,
@@ -223,6 +255,7 @@ internal EffectDescriptionBuilder SetTargetFiltering(
_effect.poolFilterDieType = poolFilterDieType;
return this;
}
+#endif
internal EffectDescriptionBuilder SetRecurrentEffect(RecurrentEffect recurrentEffect)
{
@@ -299,10 +332,18 @@ internal EffectDescriptionBuilder InviteOptionalAlly(bool value = true)
}
#endif
- internal EffectDescriptionBuilder SetSpeed(SpeedType speedType, float speedParameter = 0f)
+ internal EffectDescriptionBuilder SetSpeedAndImpactOffset(
+ SpeedType speedType,
+ float speedParameter = 0f,
+ bool offsetImpactTimeBasedOnDistance = false,
+ float offsetImpactTimeBasedOnDistanceFactor = 0.1f,
+ float offsetImpactTimePerTarget = 0.0f)
{
_effect.speedType = speedType;
_effect.speedParameter = speedParameter;
+ _effect.offsetImpactTimeBasedOnDistance = offsetImpactTimeBasedOnDistance;
+ _effect.offsetImpactTimeBasedOnDistanceFactor = offsetImpactTimeBasedOnDistanceFactor;
+ _effect.offsetImpactTimePerTarget = offsetImpactTimePerTarget;
return this;
}
@@ -323,15 +364,4 @@ internal EffectDescriptionBuilder AddEffectForms(params EffectForm[] effectForms
_effect.EffectForms.AddRange(effectForms);
return this;
}
-
- internal EffectDescriptionBuilder SetupImpactOffsets(
- bool offsetImpactTimeBasedOnDistance = false,
- float offsetImpactTimeBasedOnDistanceFactor = 0.1f,
- float offsetImpactTimePerTarget = 0.0f)
- {
- _effect.offsetImpactTimeBasedOnDistance = offsetImpactTimeBasedOnDistance;
- _effect.offsetImpactTimeBasedOnDistanceFactor = offsetImpactTimeBasedOnDistanceFactor;
- _effect.offsetImpactTimePerTarget = offsetImpactTimePerTarget;
- return this;
- }
}
diff --git a/SolastaUnfinishedBusiness/Builders/EffectFormBuilder.cs b/SolastaUnfinishedBusiness/Builders/EffectFormBuilder.cs
index 541cd7127f..4d6d51cfe3 100644
--- a/SolastaUnfinishedBusiness/Builders/EffectFormBuilder.cs
+++ b/SolastaUnfinishedBusiness/Builders/EffectFormBuilder.cs
@@ -452,7 +452,7 @@ internal EffectFormBuilder SetSummonCreatureForm(
monsterDefinitionName = monsterDefinitionName,
conditionDefinition = DatabaseHelper.ConditionDefinitions.ConditionMindControlledByCaster,
persistOnConcentrationLoss = false,
- decisionPackage = DatabaseHelper.DecisionPackageDefinitions.IdleGuard_Default,
+ decisionPackage = null,
effectProxyDefinitionName = null
};
diff --git a/SolastaUnfinishedBusiness/Builders/GuiPresentationBuilder.cs b/SolastaUnfinishedBusiness/Builders/GuiPresentationBuilder.cs
index 48da7de118..80a2e2a02b 100644
--- a/SolastaUnfinishedBusiness/Builders/GuiPresentationBuilder.cs
+++ b/SolastaUnfinishedBusiness/Builders/GuiPresentationBuilder.cs
@@ -336,4 +336,19 @@ internal static TBuilder SetGuiPresentationNoContent(this TBuilder bui
: GuiPresentationBuilder.NoContent);
return builder;
}
+
+ internal static TBuilder SetSortOrder(this TBuilder builder, BaseDefinition definition)
+ where TBuilder : IDefinitionBuilder
+ {
+ return builder.SetSortOrder(definition.GuiPresentation.SortOrder);
+ }
+
+ internal static TBuilder SetSortOrder(this TBuilder builder, int sortOrder)
+ where TBuilder : IDefinitionBuilder
+ {
+ var gui = builder.GetGuiPresentation();
+ gui.sortOrder = sortOrder;
+
+ return builder;
+ }
}
diff --git a/SolastaUnfinishedBusiness/Builders/MonsterDefinitionBuilder.cs b/SolastaUnfinishedBusiness/Builders/MonsterDefinitionBuilder.cs
index 19be801199..af98fab3f7 100644
--- a/SolastaUnfinishedBusiness/Builders/MonsterDefinitionBuilder.cs
+++ b/SolastaUnfinishedBusiness/Builders/MonsterDefinitionBuilder.cs
@@ -2,7 +2,6 @@
using System.Linq;
using JetBrains.Annotations;
using SolastaUnfinishedBusiness.Api.LanguageExtensions;
-using TA.AI;
using static RuleDefinitions;
using static BestiaryDefinitions;
@@ -69,11 +68,13 @@ public MonsterDefinitionBuilder NoExperienceGain()
return this;
}
+#if false
internal MonsterDefinitionBuilder SetDefaultBattleDecisionPackage(DecisionPackageDefinition decisionPackage)
{
Definition.defaultBattleDecisionPackage = decisionPackage;
return this;
}
+#endif
internal MonsterDefinitionBuilder SetDefaultFaction(FactionDefinition faction)
{
diff --git a/SolastaUnfinishedBusiness/ChangelogHistory.txt b/SolastaUnfinishedBusiness/ChangelogHistory.txt
index 497a1eb308..a866d25266 100644
--- a/SolastaUnfinishedBusiness/ChangelogHistory.txt
+++ b/SolastaUnfinishedBusiness/ChangelogHistory.txt
@@ -1,8 +1,52 @@
+1.5.97.30:
+
+- added Character > General 'Add the Fall Prone action to all playable races'
+- added Character > Rules > 'Allow allies to perceive Ranger GloomStalker when in natural darkness'
+- added Character > Rules > 'Enable push and pull motion effects to also work on up/down axis'
+- added Create Bonfire, Command, Dissonant Whispers, Holy Weapon, Swift Quiver, Gravity Fissure, and Glibness spells
+- added Interface > Dungeon Maker > 'Enable variable placeholders on descriptions'
+- added Interface > Game UI > 'Enable CTRL click-drag to bypass quest items checks on drop'
+- fixed Ashardalon's Stride spell doing multiple damages to same target on same round
+- fixed auto powers displaying on action bar under others group [VANILLA]
+- fixed Barbarian Sundering Blow interaction with Call Lightning
+- fixed Bardic Inspiration, Indomitable Resistances, and Legendary Resistances save logic
+- fixed Bend Luck, Flash of Genius, Inspiring Protection, Shield Master, and Weal/Woe reaction consumption
+- fixed Circle of the Cosmos woe ability checks reaction not triggering
+- fixed Counter Spell not rolling charisma attribute checks
+- fixed Demonic Influence adding all location enemies to battle [VANILLA]
+- fixed Dwarven Fortitude, and Magical Guidance consuming a reaction
+- fixed Exploiter feat not checking for reactions from 2nd target onwards
+- fixed Green-Flame Blade cantrip adding extra damage to subsequent attacks on same turn
+- fixed Lucky, and Mage Slayer feats double consumption
+- fixed Martial Commander coordinated defense to require an attack first [VANILLA]
+- fixed medium creatures with height 5ft+ being considered only 1 tile taller [VANILLA]
+- fixed Party Editor to register/unregister powers from feats
+- fixed Path of the Wild Magic retribution, and Patron Archfey misty step reacting against allies
+- fixed Power Attack feat not triggering on unarmed attacks
+- fixed Quickened interaction with melee attack cantrips
+- fixed Rescue the Dying spell reacting on enemy death
+- fixed save by location not offering saves for campaigns you don't have, and disabling buttons if there are no saves
+- fixed Transmuted metamagic only changing first target damage type with AoE spells
+- fixed Wrathful Smite to do a wisdom ability check against caster DC
+- improved combat log so players can see when characters use dash action [VANILLA]
+- improved hero positioning on party spawning with parties bigger than 4
+- improved location gadgets to trigger "try alter save outcome" reactions [VANILLA]
+- improved Maneuvering Attack, and Martial Warlord strategic repositioning to use a run stance
+- improved mod UI to ensure all settings required to be in sync on MP sessions are now under Gameplay
+- improved Sorcerer Wild Magic tides of chaos, Conversion Slots, and Shorthand versatilities to react on ability checks
+- improved victory modal export behavior to allow heroes not in pool to be exported [VANILLA]
+
+KNOWN ISSUES:
+
+- Artillerist Force Ballista tiny cannon doesn't force disadvantage if attack is within 5 ft
+- Chaos Bolt spell damage will be of wrong type under multiplayer if twinned and one bolt misses [won't fix]
+
1.5.97.29:
- fixed cantrips **CRASH** if not a melee cantrip and hero has replace attack with cantrips
- fixed Bait and Switch maneuver incorrectly changing AC with an add. +1
- fixed Bardic Inspiration attribute checks to use modifiers instead of adding to roll
+- fixed character spell selection panel scrolling if last spell group has more spells than it can fit in view
- fixed Circle of the Cosmos weal/woe double consumption
- fixed Circle of the Wildfire cauterizing flames heal from half to full hit points cap
- fixed College of Elegance evasive footwork incorrectly changing AC with an add. +1
@@ -23,11 +67,6 @@
- fixed Sorcerer Wild Magic tides of chaos double consumption
- fixed Wizard Dead Master undead chains incorrectly changing AC with an add. +1
-KNOWN ISSUES:
-
-- Artillerist Force Ballista tiny cannon doesn't force disadvantage if attack is within 5 ft
-- Chaos Bolt spell damage will be of wrong type under multiplayer if twinned and one bolt misses [won't fix]
-
1.5.97.28:
- added 'Allow Unarmed Attack with main action for character if a Monk or has Handwraps or Gauntlet equipped' setting
diff --git a/SolastaUnfinishedBusiness/Classes/InventorClass.cs b/SolastaUnfinishedBusiness/Classes/InventorClass.cs
index 1f604c4766..985c57ca0e 100644
--- a/SolastaUnfinishedBusiness/Classes/InventorClass.cs
+++ b/SolastaUnfinishedBusiness/Classes/InventorClass.cs
@@ -2,6 +2,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
+using JetBrains.Annotations;
using SolastaUnfinishedBusiness.Api.GameExtensions;
using SolastaUnfinishedBusiness.Api.Helpers;
using SolastaUnfinishedBusiness.Api.LanguageExtensions;
@@ -16,6 +17,7 @@
using SolastaUnfinishedBusiness.Properties;
using SolastaUnfinishedBusiness.Subclasses.Builders;
using SolastaUnfinishedBusiness.Validators;
+using static ActionDefinitions;
using static RuleDefinitions;
using static SolastaUnfinishedBusiness.Api.DatabaseHelper;
using static SolastaUnfinishedBusiness.Api.DatabaseHelper.CharacterClassDefinitions;
@@ -593,7 +595,7 @@ private static FeatureDefinitionFeatureSet BuildRitualCasting()
FeatureDefinitionActionAffinityBuilder
.Create("ActionAffinityInventorRituals")
.SetGuiPresentationNoContent(true)
- .SetAuthorizedActions(ActionDefinitions.Id.CastRitual)
+ .SetAuthorizedActions(Id.CastRitual)
.AddToDB())
.AddToDB();
}
@@ -922,14 +924,13 @@ void ReactionValidated()
{
var hitPoints = rulesetCharacter.GetClassLevel(Class);
- defender.MyExecuteActionStabilizeAndStandUp(
- hitPoints, FeatureDefinitionPowers.PowerPatronTimekeeperTimeShift);
+ defender.MyExecuteActionStabilizeAndStandUp(hitPoints);
}
}
public void OnSavingThrowInitiated(
- RulesetCharacter caster,
- RulesetCharacter defender,
+ RulesetActor rulesetActorCaster,
+ RulesetActor rulesetActorDefender,
ref int saveBonus,
ref string abilityScoreName,
BaseDefinition sourceDefinition,
@@ -942,8 +943,14 @@ public void OnSavingThrowInitiated(
int outcomeDelta,
List effectForms)
{
+ if (rulesetActorDefender is not RulesetCharacter rulesetCharacter)
+ {
+ return;
+ }
+
var attunedItems =
- defender.CharacterInventory?.items?.Count(x => x.AttunedToCharacter == defender.Name) ?? 0;
+ rulesetCharacter.CharacterInventory?.items?.Count(x => x.AttunedToCharacter == rulesetCharacter.Name) ??
+ 0;
rollModifier += attunedItems;
modifierTrends.Add(
@@ -998,9 +1005,10 @@ public IEnumerator OnTryAlterAttributeCheck(
yield break;
}
+ // any reaction within an attribute check flow must use the yielder as waiter
yield return helper.MyReactToSpendPower(
usablePower,
- defender,
+ helper,
"InventorFlashOfGeniusCheck",
"SpendPowerInventorFlashOfGeniusCheckDescription".Formatted(
Category.Reaction, defender.Name, helper.Name),
@@ -1011,6 +1019,8 @@ public IEnumerator OnTryAlterAttributeCheck(
void ReactionValidated()
{
+ helper.SpendActionType(ActionType.Reaction);
+
var abilityCheckModifier = abilityCheckData.AbilityCheckActionModifier;
abilityCheckModifier.AbilityCheckModifierTrends.Add(
@@ -1039,13 +1049,11 @@ void ReactionValidated()
public IEnumerator OnTryAlterOutcomeSavingThrow(
GameLocationBattleManager battleManager,
- CharacterAction action,
GameLocationCharacter attacker,
GameLocationCharacter defender,
GameLocationCharacter helper,
- ActionModifier saveModifier,
- bool hasHitVisual,
- bool hasBorrowedLuck)
+ SavingThrowData savingThrowData,
+ bool hasHitVisual)
{
var rulesetDefender = defender.RulesetActor;
@@ -1064,21 +1072,21 @@ public IEnumerator OnTryAlterOutcomeSavingThrow(
var intelligence = rulesetHelper.TryGetAttributeValue(AttributeDefinitions.Intelligence);
var bonus = Math.Max(AttributeDefinitions.ComputeAbilityScoreModifier(intelligence), 1);
- if (!action.RolledSaveThrow ||
- action.SaveOutcome != RollOutcome.Failure ||
+ if (savingThrowData.SaveOutcome != RollOutcome.Failure ||
+ savingThrowData.SaveOutcomeDelta + bonus < 0 ||
!helper.CanReact() ||
!helper.CanPerceiveTarget(defender) ||
- rulesetHelper.GetRemainingUsesOfPower(usablePower) == 0 ||
- action.SaveOutcomeDelta + bonus < 0)
+ rulesetHelper.GetRemainingUsesOfPower(usablePower) == 0)
{
yield break;
}
+ // any reaction within a saving flow must use the yielder as waiter
yield return helper.MyReactToSpendPower(
usablePower,
- attacker,
+ helper,
"InventorFlashOfGenius",
- FormatReactionDescription(action, attacker, defender, helper),
+ FormatReactionDescription(savingThrowData.Title, attacker, defender, helper),
ReactionValidated,
battleManager);
@@ -1086,14 +1094,13 @@ public IEnumerator OnTryAlterOutcomeSavingThrow(
void ReactionValidated()
{
- action.SaveOutcomeDelta += bonus;
+ helper.SpendActionType(ActionType.Reaction);
- if (action.SaveOutcomeDelta >= 0)
- {
- action.SaveOutcome = RollOutcome.Success;
- }
+ savingThrowData.SaveOutcomeDelta += bonus;
+ savingThrowData.SaveOutcome =
+ savingThrowData.SaveOutcomeDelta >= 0 ? RollOutcome.Success : RollOutcome.Failure;
- var extra = action.SaveOutcomeDelta >= 0
+ var extra = savingThrowData.SaveOutcomeDelta >= 0
? (ConsoleStyleDuplet.ParameterType.Positive, "Feedback/&RollCheckSuccessTitle")
: (ConsoleStyleDuplet.ParameterType.Negative, "Feedback/&RollCheckFailureTitle");
@@ -1109,14 +1116,14 @@ void ReactionValidated()
}
private static string FormatReactionDescription(
- CharacterAction action,
- GameLocationCharacter attacker,
+ string sourceTitle,
+ [CanBeNull] GameLocationCharacter attacker,
GameLocationCharacter defender,
GameLocationCharacter helper)
{
var text = defender == helper ? "Self" : "Ally";
return $"SpendPowerInventorFlashOfGeniusReactDescription{text}"
- .Formatted(Category.Reaction, defender.Name, attacker.Name, action.FormatTitle());
+ .Formatted(Category.Reaction, defender.Name, attacker?.Name ?? ReactionRequestCustom.EnvTitle, sourceTitle);
}
}
diff --git a/SolastaUnfinishedBusiness/CustomUI/ReactionRequestCustom.cs b/SolastaUnfinishedBusiness/CustomUI/ReactionRequestCustom.cs
index 29c4d35b9a..b45507bd76 100644
--- a/SolastaUnfinishedBusiness/CustomUI/ReactionRequestCustom.cs
+++ b/SolastaUnfinishedBusiness/CustomUI/ReactionRequestCustom.cs
@@ -1,4 +1,6 @@
-using SolastaUnfinishedBusiness.Interfaces;
+using System;
+using JetBrains.Annotations;
+using SolastaUnfinishedBusiness.Interfaces;
namespace SolastaUnfinishedBusiness.CustomUI;
@@ -7,8 +9,27 @@ public interface IReactionRequestWithResource
ICustomReactionResource Resource { get; }
}
+public interface IReactionRequestWithCallbacks // where T : ReactionRequest
+{
+ [CanBeNull] public Action ReactionValidated { get; }
+
+ [CanBeNull] public Action ReactionNotValidated { get; }
+}
+
+public static class ReactionRequestCallback
+{
+ [CanBeNull]
+ public static Action Transform([CanBeNull] Action callback) where T : ReactionRequest
+ {
+ if (callback == null) { return null; }
+
+ return request => callback((T)request);
+ }
+}
+
public class ReactionRequestCustom : ReactionRequest, IReactionRequestWithResource
{
+ internal static readonly string EnvTitle = Gui.Localize("Screen/&EditorLocationEnvironmentTitle");
private readonly string _type;
internal ReactionRequestCustom(string type, CharacterActionParams reactionParams)
diff --git a/SolastaUnfinishedBusiness/CustomUI/ReactionRequestSpendBundlePower.cs b/SolastaUnfinishedBusiness/CustomUI/ReactionRequestSpendBundlePower.cs
index bfc39e5a9a..433065dd5b 100644
--- a/SolastaUnfinishedBusiness/CustomUI/ReactionRequestSpendBundlePower.cs
+++ b/SolastaUnfinishedBusiness/CustomUI/ReactionRequestSpendBundlePower.cs
@@ -1,4 +1,5 @@
-using System.Linq;
+using System;
+using System.Linq;
using JetBrains.Annotations;
using SolastaUnfinishedBusiness.Api.GameExtensions;
using SolastaUnfinishedBusiness.Behaviors;
@@ -8,7 +9,8 @@
namespace SolastaUnfinishedBusiness.CustomUI;
-internal sealed class ReactionRequestSpendBundlePower : ReactionRequest, IReactionRequestWithResource
+internal sealed class ReactionRequestSpendBundlePower : ReactionRequest, IReactionRequestWithResource,
+ IReactionRequestWithCallbacks
{
internal const string Name = "ReactionSpendPowerBundle";
private readonly GuiCharacter _guiCharacter;
@@ -16,9 +18,14 @@ internal sealed class ReactionRequestSpendBundlePower : ReactionRequest, IReacti
private readonly ActionModifier _modifier;
private readonly GameLocationCharacter _target;
- internal ReactionRequestSpendBundlePower([NotNull] CharacterActionParams reactionParams)
+ internal ReactionRequestSpendBundlePower([NotNull] CharacterActionParams reactionParams,
+ Action reactionValidated = null,
+ Action reactionNotValidated = null)
: base(Name, reactionParams)
{
+ ReactionValidated = ReactionRequestCallback.Transform(reactionValidated);
+ ReactionNotValidated = ReactionRequestCallback.Transform(reactionNotValidated);
+
_target = reactionParams.TargetCharacters[0];
_modifier = reactionParams.ActionModifiers.ElementAtOrDefault(0) ?? new ActionModifier();
_guiCharacter = new GuiCharacter(reactionParams.ActingCharacter);
@@ -50,6 +57,9 @@ public override int SelectedSubOption
ServiceRepository.GetService().ValidCharacters.Contains(_target) &&
_target.RulesetCharacter is { IsDeadOrDyingOrUnconscious: false };
+ public Action ReactionValidated { get; }
+ public Action ReactionNotValidated { get; }
+
public ICustomReactionResource Resource { get; set; }
private void BuildSuboptions()
@@ -179,7 +189,9 @@ public override string FormatDescription()
{
var format = $"Reaction/&ReactionSpendPowerBundle{ReactionParams.StringParameter}Description";
- return Gui.Format(format, _guiCharacter.Name);
+ return string.IsNullOrEmpty(reactionParams.StringParameter2)
+ ? Gui.Format(format, _guiCharacter.Name)
+ : reactionParams.StringParameter2;
}
public override string FormatReactTitle()
diff --git a/SolastaUnfinishedBusiness/CustomUI/ReactionRequestSpendPowerCustom.cs b/SolastaUnfinishedBusiness/CustomUI/ReactionRequestSpendPowerCustom.cs
index ef91132aea..adaade2ba0 100644
--- a/SolastaUnfinishedBusiness/CustomUI/ReactionRequestSpendPowerCustom.cs
+++ b/SolastaUnfinishedBusiness/CustomUI/ReactionRequestSpendPowerCustom.cs
@@ -5,8 +5,8 @@ public class ReactionRequestSpendPowerCustom(CharacterActionParams reactionParam
{
public override string FormatDescription()
{
- return string.IsNullOrEmpty(reactionParams.stringParameter2)
+ return string.IsNullOrEmpty(reactionParams.StringParameter2)
? base.FormatDescription()
- : reactionParams.stringParameter2;
+ : reactionParams.StringParameter2;
}
}
diff --git a/SolastaUnfinishedBusiness/CustomUI/ReactionRequestUsePowerCustom.cs b/SolastaUnfinishedBusiness/CustomUI/ReactionRequestUsePowerCustom.cs
index 01360d6faa..0c88e0f752 100644
--- a/SolastaUnfinishedBusiness/CustomUI/ReactionRequestUsePowerCustom.cs
+++ b/SolastaUnfinishedBusiness/CustomUI/ReactionRequestUsePowerCustom.cs
@@ -31,8 +31,8 @@ public ReactionRequestUsePowerCustom(
public override string FormatDescription()
{
- return string.IsNullOrEmpty(reactionParams.stringParameter2)
+ return string.IsNullOrEmpty(reactionParams.StringParameter2)
? base.FormatDescription()
- : reactionParams.stringParameter2;
+ : reactionParams.StringParameter2;
}
}
diff --git a/SolastaUnfinishedBusiness/DataMiner/BlueprintExporter.cs b/SolastaUnfinishedBusiness/DataMiner/BlueprintExporter.cs
index a60faff1fe..df8702af66 100644
--- a/SolastaUnfinishedBusiness/DataMiner/BlueprintExporter.cs
+++ b/SolastaUnfinishedBusiness/DataMiner/BlueprintExporter.cs
@@ -33,14 +33,6 @@ private static BlueprintExporter Exporter
}
}
- private static void EnsureFolderExists(string path)
- {
- if (!Directory.Exists(path))
- {
- Directory.CreateDirectory(path);
- }
- }
-
private static void SetExport(int exportId, Coroutine coroutine, float percentageComplete)
{
CurrentExports[exportId].Coroutine = coroutine;
@@ -93,7 +85,7 @@ private static IEnumerator ExportMany(
yield return null;
- EnsureFolderExists(path);
+ Main.EnsureFolderExists(path);
// Types.txt
using (var sw = new StreamWriter($"{path}/Types.txt"))
@@ -135,7 +127,7 @@ private static IEnumerator ExportMany(
var folderName = $"{path}/{definitionType}";
var fullname = $"{folderName}/{filename}";
- EnsureFolderExists(folderName);
+ Main.EnsureFolderExists(folderName);
if (fullname.Length > MaxPathLength)
{
diff --git a/SolastaUnfinishedBusiness/DataViewer/BlueprintLoader.cs b/SolastaUnfinishedBusiness/DataViewer/BlueprintLoader.cs
index d1abefa05e..3b9d69b475 100644
--- a/SolastaUnfinishedBusiness/DataViewer/BlueprintLoader.cs
+++ b/SolastaUnfinishedBusiness/DataViewer/BlueprintLoader.cs
@@ -53,8 +53,8 @@ private IEnumerator LoadBlueprints()
// iterate over all DBs / BPs and collect them
var blueprints = new List();
- foreach (IEnumerable db in databases.Values.OrderBy(db =>
- db.GetType().GetGenericArguments()[0].Name))
+ foreach (var db in databases.Values.OrderBy(db =>
+ db.GetType().GetGenericArguments()[0].Name).Cast>())
{
yield return null;
diff --git a/SolastaUnfinishedBusiness/Displays/CharacterDisplay.cs b/SolastaUnfinishedBusiness/Displays/CharacterDisplay.cs
index d12fc11cfe..07f3adfece 100644
--- a/SolastaUnfinishedBusiness/Displays/CharacterDisplay.cs
+++ b/SolastaUnfinishedBusiness/Displays/CharacterDisplay.cs
@@ -50,6 +50,13 @@ internal static void DisplayCharacter()
UI.Label();
UI.Label();
+ toggle = Main.Settings.AddFallProneActionToAllRaces;
+ if (UI.Toggle(Gui.Localize("ModUi/&AddFallProneActionToAllRaces"), ref toggle, UI.AutoWidth()))
+ {
+ Main.Settings.AddFallProneActionToAllRaces = toggle;
+ CharacterContext.SwitchProneAction();
+ }
+
toggle = Main.Settings.AddHelpActionToAllRaces;
if (UI.Toggle(Gui.Localize("ModUi/&AddHelpActionToAllRaces"), ref toggle, UI.AutoWidth()))
{
diff --git a/SolastaUnfinishedBusiness/Displays/DungeonMakerDisplay.cs b/SolastaUnfinishedBusiness/Displays/DungeonMakerDisplay.cs
index 1e73f7ed90..98a07d9500 100644
--- a/SolastaUnfinishedBusiness/Displays/DungeonMakerDisplay.cs
+++ b/SolastaUnfinishedBusiness/Displays/DungeonMakerDisplay.cs
@@ -109,6 +109,12 @@ internal static void DisplayDungeonMaker()
Main.Settings.UnleashNpcAsEnemy = toggle;
}
+ toggle = Main.Settings.EnableVariablePlaceholdersOnTexts;
+ if (UI.Toggle(Gui.Localize("ModUi/&EnableVariablePlaceholdersOnTexts"), ref toggle))
+ {
+ Main.Settings.EnableVariablePlaceholdersOnTexts = toggle;
+ }
+
toggle = Main.Settings.EnableDungeonMakerModdedContent;
if (UI.Toggle(Gui.Localize("ModUi/&EnableDungeonMakerModdedContent"), ref toggle))
{
diff --git a/SolastaUnfinishedBusiness/Displays/EncountersDisplay.cs b/SolastaUnfinishedBusiness/Displays/EncountersDisplay.cs
index 23e0f0fea4..c6b3f3b95b 100644
--- a/SolastaUnfinishedBusiness/Displays/EncountersDisplay.cs
+++ b/SolastaUnfinishedBusiness/Displays/EncountersDisplay.cs
@@ -13,11 +13,11 @@ internal static class EncountersDisplay
private static bool _showAttributes;
- private static readonly Dictionary CurrentFeaturesMonster = new();
+ private static readonly Dictionary CurrentFeaturesMonster = [];
- private static readonly Dictionary CurrentAttacksMonster = new();
+ private static readonly Dictionary CurrentAttacksMonster = [];
- private static readonly Dictionary CurrentItemsHeroes = new();
+ private static readonly Dictionary CurrentItemsHeroes = [];
private static void DisplayHeroStats([NotNull] RulesetCharacterHero hero, string actionText, Action action)
{
diff --git a/SolastaUnfinishedBusiness/Displays/GameUiDisplay.cs b/SolastaUnfinishedBusiness/Displays/GameUiDisplay.cs
index 605c9213b7..f3961e01ae 100644
--- a/SolastaUnfinishedBusiness/Displays/GameUiDisplay.cs
+++ b/SolastaUnfinishedBusiness/Displays/GameUiDisplay.cs
@@ -2,121 +2,11 @@
using SolastaUnfinishedBusiness.Api.ModKit;
using SolastaUnfinishedBusiness.CustomUI;
using SolastaUnfinishedBusiness.Models;
-using UnityEngine;
namespace SolastaUnfinishedBusiness.Displays;
internal static class GameUiDisplay
{
- private static bool _selectedForSwap;
- private static int _selectedX, _selectedY;
- private static readonly string[] SetNames = ["1", "2", "3", "4", "5"];
-
- private static void DisplayFormationGrid()
- {
- var selectedSet = Main.Settings.FormationGridSelectedSet;
-
- using (UI.HorizontalScope())
- {
- UI.ActionButton(Gui.Localize("ModUi/&FormationResetAllSets"), () =>
- {
- _selectedForSwap = false;
- GameUiContext.ResetAllFormationGrids();
- },
- UI.Width(110f));
-
- if (UI.SelectionGrid(ref selectedSet, SetNames, SetNames.Length, SetNames.Length, UI.Width(165f)))
- {
- _selectedForSwap = false;
- Main.Settings.FormationGridSelectedSet = selectedSet;
- GameUiContext.FillDefinitionFromFormationGrid();
- }
-
- UI.Label(Gui.Localize("ModUi/&FormationHelp1"));
- }
-
- UI.Label();
-
- for (var y = 0; y < GameUiContext.GridSize; y++)
- {
- using (UI.HorizontalScope())
- {
- // first line
- if (y == 0)
- {
- UI.ActionButton(Gui.Localize("ModUi/&FormationResetThisSet"), () =>
- {
- _selectedForSwap = false;
- GameUiContext.ResetFormationGrid(Main.Settings.FormationGridSelectedSet);
- },
- UI.Width(110f));
- }
- else
- {
- UI.Label("", UI.Width(110f));
- }
-
- for (var x = 0; x < GameUiContext.GridSize; x++)
- {
- var saveColor = GUI.color;
- string label;
-
- if (Main.Settings.FormationGridSets[selectedSet][y][x] == 1)
- {
- // yep 256 not 255 for a light contrast
- GUI.color = new Color(0x1E / 256f, 0x81 / 256f, 0xB0 / 256f);
- label = "@";
- }
- else
- {
- label = "..";
- }
-
- if (_selectedForSwap && _selectedX == x && _selectedY == y)
- {
- label = $"{label}";
- }
-
- UI.ActionButton(label, () =>
- {
- // ReSharper disable once InlineTemporaryVariable
- // ReSharper disable once AccessToModifiedClosure
- var localX = x;
- // ReSharper disable once InlineTemporaryVariable
- // ReSharper disable once AccessToModifiedClosure
- var localY = y;
-
- if (_selectedForSwap)
- {
- (Main.Settings.FormationGridSets[selectedSet][localY][localX],
- Main.Settings.FormationGridSets[selectedSet][_selectedY][_selectedX]) = (
- Main.Settings.FormationGridSets[selectedSet][_selectedY][_selectedX],
- Main.Settings.FormationGridSets[selectedSet][localY][localX]);
-
- GameUiContext.FillDefinitionFromFormationGrid();
-
- _selectedForSwap = false;
- }
- else
- {
- _selectedX = localX;
- _selectedY = localY;
- _selectedForSwap = true;
- }
- }, UI.Width(30f));
-
- GUI.color = saveColor;
- }
-
- // first line
- if (y <= 1)
- {
- UI.Label(Gui.Localize("ModUi/&FormationHelp" + (y + 2)));
- }
- }
- }
- }
-
internal static void DisplayGameUi()
{
#region Campaign
@@ -368,23 +258,6 @@ internal static void DisplayGameUi()
#endregion
- #region Formation
-
- UI.Label();
- UI.Label(Gui.Localize("ModUi/&Formation"));
- UI.Label();
-
- if (Global.IsMultiplayer)
- {
- UI.Label(Gui.Localize("ModUi/&FormationError"));
- }
- else
- {
- DisplayFormationGrid();
- }
-
- #endregion
-
#region Input
UI.Label();
@@ -492,13 +365,6 @@ internal static void DisplayGameUi()
UI.Label();
- toggle = Main.Settings.EnableInvisibleCrownOfTheMagister;
- if (UI.Toggle(Gui.Localize("ModUi/&EnableInvisibleCrownOfTheMagister"), ref toggle, UI.AutoWidth()))
- {
- Main.Settings.EnableInvisibleCrownOfTheMagister = toggle;
- GameUiContext.SwitchCrownOfTheMagister();
- }
-
toggle = Main.Settings.DontDisplayHelmets;
if (UI.Toggle(Gui.Localize("ModUi/&DontDisplayHelmets"), ref toggle, UI.AutoWidth()))
{
@@ -506,6 +372,19 @@ internal static void DisplayGameUi()
ItemCraftingMerchantContext.SwitchSetBeltOfDwarvenKindBeardChances();
}
+ toggle = Main.Settings.EnableCtrlClickDragToBypassQuestItemsOnDrop;
+ if (UI.Toggle(Gui.Localize("ModUi/&EnableCtrlClickDragToBypassQuestItemsOnDrop"), ref toggle, UI.AutoWidth()))
+ {
+ Main.Settings.EnableCtrlClickDragToBypassQuestItemsOnDrop = toggle;
+ }
+
+ toggle = Main.Settings.EnableInvisibleCrownOfTheMagister;
+ if (UI.Toggle(Gui.Localize("ModUi/&EnableInvisibleCrownOfTheMagister"), ref toggle, UI.AutoWidth()))
+ {
+ Main.Settings.EnableInvisibleCrownOfTheMagister = toggle;
+ GameUiContext.SwitchCrownOfTheMagister();
+ }
+
UI.Label();
toggle = Main.Settings.ShowCraftingRecipeInDetailedTooltips;
diff --git a/SolastaUnfinishedBusiness/Displays/PartyEditor.cs b/SolastaUnfinishedBusiness/Displays/PartyEditor.cs
index 761a55b71b..a132f2ed89 100644
--- a/SolastaUnfinishedBusiness/Displays/PartyEditor.cs
+++ b/SolastaUnfinishedBusiness/Displays/PartyEditor.cs
@@ -307,6 +307,13 @@ ToolTypeDefinition tool when chr.TrainedToolTypes.Contains(tool) => () =>
{
chr.TrainFeats([feat]);
+ foreach (var power in feat.Features.OfType())
+ {
+ var usablePower = new RulesetUsablePower(power, null, null);
+
+ chr.UsablePowers.Add(usablePower);
+ }
+
LevelUpContext.RecursiveGrantCustomFeatures(
chr, AttributeDefinitions.TagFeat, feat.Features);
}
@@ -316,6 +323,17 @@ ToolTypeDefinition tool when chr.TrainedToolTypes.Contains(tool) => () =>
{
chr.TrainedFeats.Remove(feat);
+ foreach (var power in feat.Features.OfType())
+ {
+ var usablePower =
+ chr.UsablePowers.FirstOrDefault(p => p.PowerDefinition == power);
+
+ if (usablePower != null)
+ {
+ chr.UsablePowers.Remove(usablePower);
+ }
+ }
+
LevelUpContext.RecursiveRemoveCustomFeatures(
chr, AttributeDefinitions.TagFeat, feat.Features);
}
diff --git a/SolastaUnfinishedBusiness/Displays/RulesDisplay.cs b/SolastaUnfinishedBusiness/Displays/RulesDisplay.cs
index 55db1cd95d..5c3f78035e 100644
--- a/SolastaUnfinishedBusiness/Displays/RulesDisplay.cs
+++ b/SolastaUnfinishedBusiness/Displays/RulesDisplay.cs
@@ -207,6 +207,15 @@ internal static void DisplayRules()
Main.Settings.EnableSorcererQuickenedAction = toggle;
}
+ if (Main.Settings.EnableSorcererQuickenedAction)
+ {
+ toggle = Main.Settings.HideQuickenedActionWhenMetamagicOff;
+ if (UI.Toggle(Gui.Localize("ModUi/&HideQuickenedActionWhenMetamagicOff"), ref toggle, UI.AutoWidth()))
+ {
+ Main.Settings.HideQuickenedActionWhenMetamagicOff = toggle;
+ }
+ }
+
UI.Label();
toggle = Main.Settings.KeepInvisibilityWhenUsingItems;
@@ -476,6 +485,13 @@ internal static void DisplayRules()
UI.Label();
+ toggle = Main.Settings.AllowAlliesToPerceiveRangerGloomStalkerInNaturalDarkness;
+ if (UI.Toggle(Gui.Localize("ModUi/&AllowAlliesToPerceiveRangerGloomStalkerInNaturalDarkness"), ref toggle,
+ UI.AutoWidth()))
+ {
+ Main.Settings.AllowAlliesToPerceiveRangerGloomStalkerInNaturalDarkness = toggle;
+ }
+
toggle = Main.Settings.ChangeDragonbornElementalBreathUsages;
if (UI.Toggle(Gui.Localize("ModUi/&ChangeDragonbornElementalBreathUsages"), ref toggle, UI.AutoWidth()))
{
@@ -531,6 +547,23 @@ internal static void DisplayRules()
Main.Settings.EnableHigherGroundRules = toggle;
}
+ toggle = Main.Settings.EnablePullPushOnVerticalDirection;
+ if (UI.Toggle(Gui.Localize("ModUi/&EnablePullPushOnVerticalDirection"), ref toggle, UI.AutoWidth()))
+ {
+ Main.Settings.EnablePullPushOnVerticalDirection = toggle;
+ SrdAndHouseRulesContext.ToggleGravitySlamModification();
+ }
+
+ if (Main.Settings.EnablePullPushOnVerticalDirection)
+ {
+ toggle = Main.Settings.ModifyGravitySlam;
+ if (UI.Toggle(Gui.Localize("ModUi/&ModifyGravitySlam"), ref toggle, UI.AutoWidth()))
+ {
+ Main.Settings.ModifyGravitySlam = toggle;
+ SrdAndHouseRulesContext.ToggleGravitySlamModification();
+ }
+ }
+
toggle = Main.Settings.EnableTeleportToRemoveRestrained;
if (UI.Toggle(Gui.Localize("ModUi/&EnableTeleportToRemoveRestrained"), ref toggle, UI.AutoWidth()))
{
diff --git a/SolastaUnfinishedBusiness/Displays/ToolsDisplay.cs b/SolastaUnfinishedBusiness/Displays/ToolsDisplay.cs
index 0fde12258e..6f3f265d52 100644
--- a/SolastaUnfinishedBusiness/Displays/ToolsDisplay.cs
+++ b/SolastaUnfinishedBusiness/Displays/ToolsDisplay.cs
@@ -2,6 +2,7 @@
using System.Diagnostics;
using SolastaUnfinishedBusiness.Api.ModKit;
using SolastaUnfinishedBusiness.Models;
+using UnityEngine;
namespace SolastaUnfinishedBusiness.Displays;
@@ -9,9 +10,118 @@ internal static class ToolsDisplay
{
internal const float DefaultFastTimeModifier = 1.5f;
+ private static bool _selectedForSwap;
+ private static int _selectedX, _selectedY;
+ private static readonly string[] SetNames = ["1", "2", "3", "4", "5"];
+
private static string ExportFileName { get; set; } =
ServiceRepository.GetService().GetUserName();
+ private static void DisplayFormationGrid()
+ {
+ var selectedSet = Main.Settings.FormationGridSelectedSet;
+
+ using (UI.HorizontalScope())
+ {
+ UI.ActionButton(Gui.Localize("ModUi/&FormationResetAllSets"), () =>
+ {
+ _selectedForSwap = false;
+ GameUiContext.ResetAllFormationGrids();
+ },
+ UI.Width(110f));
+
+ if (UI.SelectionGrid(ref selectedSet, SetNames, SetNames.Length, SetNames.Length, UI.Width(165f)))
+ {
+ _selectedForSwap = false;
+ Main.Settings.FormationGridSelectedSet = selectedSet;
+ GameUiContext.FillDefinitionFromFormationGrid();
+ }
+
+ UI.Label(Gui.Localize("ModUi/&FormationHelp1"));
+ }
+
+ UI.Label();
+
+ for (var y = 0; y < GameUiContext.GridSize; y++)
+ {
+ using (UI.HorizontalScope())
+ {
+ // first line
+ if (y == 0)
+ {
+ UI.ActionButton(Gui.Localize("ModUi/&FormationResetThisSet"), () =>
+ {
+ _selectedForSwap = false;
+ GameUiContext.ResetFormationGrid(Main.Settings.FormationGridSelectedSet);
+ },
+ UI.Width(110f));
+ }
+ else
+ {
+ UI.Label("", UI.Width(110f));
+ }
+
+ for (var x = 0; x < GameUiContext.GridSize; x++)
+ {
+ var saveColor = GUI.color;
+ string label;
+
+ if (Main.Settings.FormationGridSets[selectedSet][y][x] == 1)
+ {
+ // yep 256 not 255 for a light contrast
+ GUI.color = new Color(0x1E / 256f, 0x81 / 256f, 0xB0 / 256f);
+ label = "@";
+ }
+ else
+ {
+ label = "..";
+ }
+
+ if (_selectedForSwap && _selectedX == x && _selectedY == y)
+ {
+ label = $"{label}";
+ }
+
+ UI.ActionButton(label, () =>
+ {
+ // ReSharper disable once InlineTemporaryVariable
+ // ReSharper disable once AccessToModifiedClosure
+ var localX = x;
+ // ReSharper disable once InlineTemporaryVariable
+ // ReSharper disable once AccessToModifiedClosure
+ var localY = y;
+
+ if (_selectedForSwap)
+ {
+ (Main.Settings.FormationGridSets[selectedSet][localY][localX],
+ Main.Settings.FormationGridSets[selectedSet][_selectedY][_selectedX]) = (
+ Main.Settings.FormationGridSets[selectedSet][_selectedY][_selectedX],
+ Main.Settings.FormationGridSets[selectedSet][localY][localX]);
+
+ GameUiContext.FillDefinitionFromFormationGrid();
+
+ _selectedForSwap = false;
+ }
+ else
+ {
+ _selectedX = localX;
+ _selectedY = localY;
+ _selectedForSwap = true;
+ }
+ }, UI.Width(30f));
+
+ GUI.color = saveColor;
+ }
+
+ // first line
+ if (y <= 1)
+ {
+ UI.Label(Gui.Localize("ModUi/&FormationHelp" + (y + 2)));
+ }
+ }
+ }
+ }
+
internal static void DisplayTools()
{
DisplayGeneral();
@@ -163,6 +273,23 @@ private static void DisplayAdventure()
Main.Settings.FasterTimeModifier = floatValue;
}
+ #region Formation
+
+ UI.Label();
+ UI.Label(Gui.Localize("ModUi/&Formation"));
+ UI.Label();
+
+ if (Global.IsMultiplayer)
+ {
+ UI.Label(Gui.Localize("ModUi/&FormationError"));
+ }
+ else
+ {
+ DisplayFormationGrid();
+ }
+
+ #endregion
+
#if false
UI.Label();
diff --git a/SolastaUnfinishedBusiness/Displays/_ModUi.cs b/SolastaUnfinishedBusiness/Displays/_ModUi.cs
index c4467cc5e7..a1bcdd0d63 100644
--- a/SolastaUnfinishedBusiness/Displays/_ModUi.cs
+++ b/SolastaUnfinishedBusiness/Displays/_ModUi.cs
@@ -60,9 +60,12 @@ internal static class ModUi
"CollegeOfGuts",
"CollegeOfLife",
"CollegeOfValiance",
+ "CommandSpell",
+ "CreateBonfire",
"CrownOfStars",
"CrusadersMantle",
"Dawn",
+ "DissonantWhispers",
"DivineWrath",
"DomainNature",
"DomainTempest",
@@ -151,9 +154,12 @@ internal static class ModUi
"FlameArrows",
"Foresight",
"ForestGuardian",
+ "Glibness",
"GiftOfAlacrity",
+ "GravityFissure",
"GravitySinkhole",
"HeroicInfusion",
+ "HolyWeapon",
"HungerOfTheVoid",
"IceBlade",
"Incineration",
@@ -190,6 +196,7 @@ internal static class ModUi
"LightningArrow",
"LightningLure",
"MaddeningDarkness",
+ "MagicStone",
"MagnifyGravity",
"MartialArcaneArcher",
"MartialForceKnight",
@@ -263,6 +270,7 @@ internal static class ModUi
"StarryWisp",
"SteelWhirlwind",
"StrikeWithTheWind",
+ "SwiftQuiver",
"SwordStorm",
"SynapticStatic",
"Telekinesis",
diff --git a/SolastaUnfinishedBusiness/Feats/ArmorFeats.cs b/SolastaUnfinishedBusiness/Feats/ArmorFeats.cs
index b1d34cba06..cef425cc8e 100644
--- a/SolastaUnfinishedBusiness/Feats/ArmorFeats.cs
+++ b/SolastaUnfinishedBusiness/Feats/ArmorFeats.cs
@@ -8,6 +8,7 @@
using SolastaUnfinishedBusiness.Builders.Features;
using SolastaUnfinishedBusiness.Interfaces;
using SolastaUnfinishedBusiness.Validators;
+using static ActionDefinitions;
using static RuleDefinitions;
using static EquipmentDefinitions;
using static SolastaUnfinishedBusiness.Api.DatabaseHelper.FeatDefinitions;
@@ -91,6 +92,9 @@ internal static void CreateFeats([NotNull] List feats)
featMediumArmorDex,
featMediumArmorStr);
+ featGroupMediumArmor.armorProficiencyPrerequisite = true;
+ featGroupMediumArmor.armorProficiencyCategory = LightArmorCategory;
+
GroupFeats.FeatGroupDefenseCombat.AddFeats(featShieldTechniques);
GroupFeats.MakeGroup("FeatGroupArmor", null,
@@ -117,7 +121,7 @@ private static FeatDefinition BuildFeatShieldTechniques()
var actionAffinityShieldTechniques = FeatureDefinitionActionAffinityBuilder
.Create($"ActionAffinity{Name}")
.SetGuiPresentationNoContent(true)
- .SetAuthorizedActions(ActionDefinitions.Id.ShoveBonus)
+ .SetAuthorizedActions(Id.ShoveBonus)
.AddCustomSubFeatures(
new ValidateDefinitionApplication(ValidatorsCharacter.HasShield, ValidatorsCharacter.HasAttacked))
.AddToDB();
@@ -185,6 +189,8 @@ public IEnumerator OnMagicEffectBeforeHitConfirmedOnMe(
void ReactionValidated()
{
+ defender.SpendActionType(ActionType.Reaction);
+
actionModifier.DefenderDamageMultiplier *= 0.5f;
rulesetDefender.DamageHalved(rulesetDefender, powerShieldTechniques);
@@ -208,8 +214,8 @@ void ReactionValidated()
// add +2 on DEX savings
public void OnSavingThrowInitiated(
- RulesetCharacter caster,
- RulesetCharacter defender,
+ RulesetActor rulesetActorCaster,
+ RulesetActor rulesetActorDefender,
ref int saveBonus,
ref string abilityScoreName,
BaseDefinition sourceDefinition,
@@ -222,7 +228,9 @@ public void OnSavingThrowInitiated(
int outcomeDelta,
List effectForms)
{
- if (abilityScoreName != AttributeDefinitions.Dexterity || !defender.IsWearingShield())
+ if (abilityScoreName != AttributeDefinitions.Dexterity ||
+ rulesetActorDefender is not RulesetCharacter rulesetCharacterDefender ||
+ !rulesetCharacterDefender.IsWearingShield())
{
return;
}
diff --git a/SolastaUnfinishedBusiness/Feats/ClassFeats.cs b/SolastaUnfinishedBusiness/Feats/ClassFeats.cs
index 3c29f75632..5bff83a7c9 100644
--- a/SolastaUnfinishedBusiness/Feats/ClassFeats.cs
+++ b/SolastaUnfinishedBusiness/Feats/ClassFeats.cs
@@ -374,7 +374,9 @@ public IEnumerator OnMagicEffectFinishedByMeOrAlly(
var effectDescription = action.actionParams.RulesetEffect.EffectDescription;
if (effectDescription.RangeType is not (RangeType.MeleeHit or RangeType.RangeHit) ||
- effectDescription.TargetParameter != 1)
+ effectDescription.TargetParameter != 1 ||
+ action.Countered ||
+ action is CharacterActionCastSpell { ExecutionFailed: true })
{
yield break;
}
@@ -407,14 +409,19 @@ private static IEnumerator HandleReaction(
{
if (attackRollOutcome is not (RollOutcome.Success or RollOutcome.CriticalSuccess) ||
attacker == helper ||
- helper.IsMyTurn() ||
- !helper.CanReact())
+ helper.IsMyTurn())
{
yield break;
}
+ // ReSharper disable once ForeachCanBePartlyConvertedToQueryUsingAnotherGetEnumerator
foreach (var defender in targets)
{
+ if (!helper.CanReact())
+ {
+ yield break;
+ }
+
var (opportunityAttackMode, actionModifier) =
helper.GetFirstMeleeModeThatCanAttack(defender, battleManager);
@@ -492,7 +499,10 @@ public IEnumerator OnActionFinishedByMe(CharacterAction action)
}
var rulesetCondition =
- rulesetCharacterMonster.AllConditions.FirstOrDefault(x => x.SourceGuid == TemporaryHitPointsGuid);
+ rulesetCharacterMonster.ConditionsByCategory
+ .SelectMany(x => x.Value)
+ .FirstOrDefault(x =>
+ x.SourceGuid == TemporaryHitPointsGuid);
if (rulesetCondition != null)
{
diff --git a/SolastaUnfinishedBusiness/Feats/MeleeCombatFeats.cs b/SolastaUnfinishedBusiness/Feats/MeleeCombatFeats.cs
index f575e4ca6e..bbc17ebfe5 100644
--- a/SolastaUnfinishedBusiness/Feats/MeleeCombatFeats.cs
+++ b/SolastaUnfinishedBusiness/Feats/MeleeCombatFeats.cs
@@ -628,7 +628,7 @@ public IEnumerator OnPhysicalAttackBeforeHitConfirmedOnEnemy(
[defender],
attacker,
powerPool.Name,
- ReactionValidated,
+ reactionValidated: ReactionValidated,
battleManager: battleManager);
yield break;
@@ -1705,13 +1705,8 @@ private sealed class ModifyWeaponAttackModeFeatPowerAttack(FeatDefinition featDe
public void ModifyAttackMode(RulesetCharacter character, RulesetAttackMode attackMode)
{
- if (attackMode?.SourceObject is not RulesetItem rulesetItem)
- {
- return;
- }
-
// don't use IsMelee(attackMode) in IModifyWeaponAttackMode as it will always fail
- if (!ValidatorsWeapon.IsMelee(rulesetItem) &&
+ if (!ValidatorsWeapon.IsMelee(attackMode.SourceObject as RulesetItem) &&
!ValidatorsWeapon.IsUnarmed(attackMode))
{
return;
@@ -1721,8 +1716,8 @@ public void ModifyAttackMode(RulesetCharacter character, RulesetAttackMode attac
var toDamage = ToHit + proficiency;
attackMode.ToHitBonus -= ToHit;
- attackMode.ToHitBonusTrends.Add(new TrendInfo(-ToHit, FeatureSourceType.Feat, featDefinition.Name,
- featDefinition));
+ attackMode.ToHitBonusTrends.Add(
+ new TrendInfo(-ToHit, FeatureSourceType.Feat, featDefinition.Name, featDefinition));
var damage = attackMode.EffectDescription?.FindFirstDamageForm();
@@ -1732,8 +1727,8 @@ public void ModifyAttackMode(RulesetCharacter character, RulesetAttackMode attac
}
damage.BonusDamage += toDamage;
- damage.DamageBonusTrends.Add(new TrendInfo(toDamage, FeatureSourceType.Feat, featDefinition.Name,
- featDefinition));
+ damage.DamageBonusTrends.Add(
+ new TrendInfo(toDamage, FeatureSourceType.Feat, featDefinition.Name, featDefinition));
}
}
diff --git a/SolastaUnfinishedBusiness/Feats/OtherFeats.cs b/SolastaUnfinishedBusiness/Feats/OtherFeats.cs
index 1c1e681fa7..a22f7a287e 100644
--- a/SolastaUnfinishedBusiness/Feats/OtherFeats.cs
+++ b/SolastaUnfinishedBusiness/Feats/OtherFeats.cs
@@ -712,7 +712,8 @@ public IEnumerator OnPowerOrSpellFinishedByMe(CharacterActionMagicEffect action,
attacker.BurnOneMainAttack();
- var abilityCheckData = new AbilityCheckData { AbilityCheckActionModifier = new ActionModifier() };
+ var abilityCheckData =
+ new AbilityCheckData { AbilityCheckActionModifier = new ActionModifier(), Action = action };
yield return ResolveContest(attacker, defender, abilityCheckData);
@@ -1066,8 +1067,8 @@ private sealed class CustomBehaviorDungeonDelver(
ConditionDefinition conditionResistance) : IRollSavingThrowInitiated
{
public void OnSavingThrowInitiated(
- RulesetCharacter caster,
- RulesetCharacter defender,
+ RulesetActor rulesetActorCaster,
+ RulesetActor rulesetActorDefender,
ref int saveBonus,
ref string abilityScoreName,
BaseDefinition sourceDefinition,
@@ -1080,7 +1081,12 @@ public void OnSavingThrowInitiated(
int outcomeDelta,
List effectForms)
{
- if (caster is RulesetCharacterHero or RulesetCharacterMonster)
+ if (rulesetActorDefender is not RulesetCharacter rulesetCharacterDefender)
+ {
+ return;
+ }
+
+ if (rulesetActorCaster is RulesetCharacterHero or RulesetCharacterMonster)
{
return;
}
@@ -1088,14 +1094,14 @@ public void OnSavingThrowInitiated(
advantageTrends.Add(
new TrendInfo(1, FeatureSourceType.Condition, conditionResistance.Name, conditionResistance));
- defender.InflictCondition(
+ rulesetCharacterDefender.InflictCondition(
conditionResistance.Name,
DurationType.Round,
0,
TurnOccurenceType.EndOfTurn,
AttributeDefinitions.TagEffect,
- defender.guid,
- defender.CurrentFaction.Name,
+ rulesetCharacterDefender.guid,
+ rulesetCharacterDefender.CurrentFaction.Name,
1,
conditionResistance.Name,
0,
@@ -1163,16 +1169,16 @@ public IEnumerator OnPowerOrSpellFinishedByMe(CharacterActionMagicEffect action,
var actingCharacter = action.ActingCharacter;
var rulesetCharacter = actingCharacter.RulesetCharacter;
var actionModifier = new ActionModifier();
-
- rulesetCharacter.ComputeBaseAbilityCheckBonus(
- AttributeDefinitions.Dexterity, actionModifier.AbilityCheckModifierTrends, SkillDefinitions.Acrobatics);
-
- actingCharacter.ComputeAbilityCheckActionModifier(
- AttributeDefinitions.Dexterity, SkillDefinitions.Acrobatics, actionModifier);
-
var abilityCheckRoll = actingCharacter.RollAbilityCheck(
- AttributeDefinitions.Dexterity, SkillDefinitions.Acrobatics, 15,
- AdvantageType.None, actionModifier, false, -1, out var rollOutcome, out var successDelta, true);
+ AttributeDefinitions.Dexterity,
+ SkillDefinitions.Acrobatics,
+ 15,
+ AdvantageType.None,
+ actionModifier,
+ false, -1,
+ out var rollOutcome,
+ out var successDelta,
+ true);
//PATCH: support for Bardic Inspiration roll off battle and ITryAlterOutcomeAttributeCheck
var abilityCheckData = new AbilityCheckData
@@ -1180,7 +1186,8 @@ public IEnumerator OnPowerOrSpellFinishedByMe(CharacterActionMagicEffect action,
AbilityCheckRoll = abilityCheckRoll,
AbilityCheckRollOutcome = rollOutcome,
AbilityCheckSuccessDelta = successDelta,
- AbilityCheckActionModifier = actionModifier
+ AbilityCheckActionModifier = actionModifier,
+ Action = action
};
yield return TryAlterOutcomeAttributeCheck
@@ -1849,11 +1856,6 @@ private static FeatDefinition BuildHealer()
EffectDescriptionBuilder
.Create()
.SetTargetingData(Side.Ally, RangeType.Touch, 0, TargetType.IndividualsUnique)
- .SetTargetFiltering(
- TargetFilteringMethod.CharacterOnly,
- TargetFilteringTag.No,
- 5,
- DieType.D8)
.SetRequiredCondition(ConditionDefinitions.ConditionDead)
.SetEffectForms(
EffectFormBuilder
@@ -1939,37 +1941,9 @@ private static FeatDefinition BuildFeatLucky()
return feat;
}
- private sealed class CustomBehaviorLucky(
- // ReSharper disable once SuggestBaseTypeForParameterInConstructor
- FeatureDefinitionPower powerLucky)
- : ITryAlterOutcomeAttack, ITryAlterOutcomeAttributeCheck, ITryAlterOutcomeSavingThrow, IRollSavingThrowFinished
+ private sealed class CustomBehaviorLucky(FeatureDefinitionPower powerLucky)
+ : ITryAlterOutcomeAttack, ITryAlterOutcomeAttributeCheck, ITryAlterOutcomeSavingThrow
{
- private const string LuckyModifierTag = "LuckyModifierTag";
- private const string LuckySaveTag = "LuckySaveTag";
-
- public void OnSavingThrowFinished(
- RulesetCharacter rulesetCaster,
- RulesetCharacter rulesetDefender,
- int saveBonus,
- string abilityScoreName,
- BaseDefinition sourceDefinition,
- List modifierTrends,
- List advantageTrends,
- int rollModifier,
- int saveDC,
- bool hasHitVisual,
- ref RollOutcome outcome,
- ref int outcomeDelta,
- List effectForms)
- {
- var caster = GameLocationCharacter.GetFromActor(rulesetCaster);
-
- caster.UsedSpecialFeatures.TryAdd(LuckyModifierTag, 0);
- caster.UsedSpecialFeatures.TryAdd(LuckySaveTag, 0);
- caster.UsedSpecialFeatures[LuckyModifierTag] = saveBonus + rollModifier;
- caster.UsedSpecialFeatures[LuckySaveTag] = saveDC;
- }
-
public int HandlerPriority => -10;
public IEnumerator OnTryAlterOutcomeAttack(
@@ -2007,6 +1981,7 @@ public IEnumerator OnTryAlterOutcomeAttack(
yield break;
}
+ // any reaction within an attack flow must use the attacker as waiter
yield return helper.MyReactToSpendPower(
usablePower,
attacker,
@@ -2018,6 +1993,8 @@ public IEnumerator OnTryAlterOutcomeAttack(
void ReactionValidated()
{
+ usablePower.Consume();
+
var dieRoll = rulesetHelper.RollDie(DieType.D20, RollContext.None, false, AdvantageType.None, out _,
out _);
var previousRoll = action.AttackRoll;
@@ -2090,9 +2067,10 @@ abilityCheckData.AbilityCheckRollOutcome is not (RollOutcome.Failure or RollOutc
yield break;
}
+ // any reaction within an attribute check flow must use the yielder as waiter
yield return helper.MyReactToSpendPower(
usablePower,
- defender,
+ helper,
"LuckyCheck",
reactionValidated: ReactionValidated,
battleManager: battleManager);
@@ -2101,6 +2079,8 @@ abilityCheckData.AbilityCheckRollOutcome is not (RollOutcome.Failure or RollOutc
void ReactionValidated()
{
+ usablePower.Consume();
+
var dieRoll = rulesetHelper.RollDie(DieType.D20, RollContext.None, false, AdvantageType.None, out _,
out _);
var previousRoll = abilityCheckData.AbilityCheckRoll;
@@ -2140,41 +2120,44 @@ void ReactionValidated()
public IEnumerator OnTryAlterOutcomeSavingThrow(
GameLocationBattleManager battleManager,
- CharacterAction action,
GameLocationCharacter attacker,
GameLocationCharacter defender,
GameLocationCharacter helper,
- ActionModifier saveModifier,
- bool hasHitVisual,
- bool hasBorrowedLuck)
+ SavingThrowData savingThrowData,
+ bool hasHitVisual)
{
var rulesetHelper = helper.RulesetCharacter;
var usablePower = PowerProvider.Get(powerLucky, rulesetHelper);
- if (!action.RolledSaveThrow ||
- action.SaveOutcome != RollOutcome.Failure ||
+ if (savingThrowData.SaveOutcome != RollOutcome.Failure ||
helper != defender ||
- rulesetHelper.GetRemainingUsesOfPower(usablePower) == 0 ||
- !defender.UsedSpecialFeatures.TryGetValue(LuckyModifierTag, out var modifier) ||
- !defender.UsedSpecialFeatures.TryGetValue(LuckySaveTag, out var saveDC))
+ rulesetHelper.GetRemainingUsesOfPower(usablePower) == 0)
{
yield break;
}
+ // any reaction within a saving flow must use the yielder as waiter
yield return helper.MyReactToSpendPower(
usablePower,
- attacker,
+ helper,
"LuckySaving",
- reactionValidated: ReactionValidated,
- battleManager: battleManager);
+ "SpendPowerLuckySavingDescription".Formatted(
+ Category.Reaction, attacker?.Name ?? ReactionRequestCustom.EnvTitle, savingThrowData.Title),
+ ReactionValidated,
+ battleManager);
yield break;
void ReactionValidated()
{
+ usablePower.Consume();
+
var dieRoll = rulesetHelper.RollDie(DieType.D20, RollContext.None, false, AdvantageType.None, out _,
out _);
- var savingRoll = action.SaveOutcomeDelta - modifier + saveDC;
+
+ var saveDC = savingThrowData.SaveDC;
+ var rollModifier = savingThrowData.SaveBonusAndRollModifier;
+ var savingRoll = savingThrowData.SaveOutcomeDelta - rollModifier + saveDC;
if (dieRoll <= savingRoll)
{
@@ -2190,8 +2173,9 @@ void ReactionValidated()
return;
}
- action.SaveOutcomeDelta += dieRoll - savingRoll;
- action.SaveOutcome = action.SaveOutcomeDelta >= 0 ? RollOutcome.Success : RollOutcome.Failure;
+ savingThrowData.SaveOutcomeDelta += dieRoll - savingRoll;
+ savingThrowData.SaveOutcome =
+ savingThrowData.SaveOutcomeDelta >= 0 ? RollOutcome.Success : RollOutcome.Failure;
rulesetHelper.LogCharacterActivatesAbility(
"Feat/&FeatLuckyTitle",
@@ -2310,35 +2294,31 @@ public IEnumerator OnPhysicalAttackBeforeHitConfirmedOnEnemy(
public IEnumerator OnTryAlterOutcomeSavingThrow(
GameLocationBattleManager battleManager,
- CharacterAction action,
GameLocationCharacter attacker,
GameLocationCharacter defender,
GameLocationCharacter helper,
- ActionModifier actionModifier,
- bool hasHitVisual,
- bool hasBorrowedLuck)
+ SavingThrowData savingThrowData,
+ bool hasHitVisual)
{
var rulesetHelper = helper.RulesetCharacter;
var usablePower = PowerProvider.Get(PowerMageSlayerSaving, rulesetHelper);
- var effectDescription = action.ActionParams.AttackMode?.EffectDescription ??
- action.ActionParams.RulesetEffect?.EffectDescription;
-
- if (helper != defender ||
- !action.RolledSaveThrow ||
- action.SaveOutcome != RollOutcome.Failure ||
+ if (savingThrowData.SaveOutcome != RollOutcome.Failure ||
+ helper != defender ||
rulesetHelper.GetRemainingUsesOfPower(usablePower) == 0 ||
- effectDescription?.savingThrowAbility is not
+ savingThrowData.SavingThrowAbility is not
(AttributeDefinitions.Intelligence or AttributeDefinitions.Wisdom or AttributeDefinitions.Charisma))
{
yield break;
}
+ // any reaction within a saving flow must use the yielder as waiter
yield return defender.MyReactToSpendPower(
usablePower,
- attacker,
+ defender,
"MageSlayer",
- "SpendPowerMageSlayerDescription".Formatted(Category.Reaction, attacker.Name),
+ "SpendPowerMageSlayerDescription".Formatted(
+ Category.Reaction, attacker?.Name ?? ReactionRequestCustom.EnvTitle, savingThrowData.Title),
ReactionValidated,
battleManager);
@@ -2346,8 +2326,10 @@ public IEnumerator OnTryAlterOutcomeSavingThrow(
void ReactionValidated()
{
- action.SaveOutcomeDelta = 0;
- action.SaveOutcome = RollOutcome.Success;
+ usablePower.Consume();
+
+ savingThrowData.SaveOutcomeDelta = 0;
+ savingThrowData.SaveOutcome = RollOutcome.Success;
}
}
@@ -2415,7 +2397,6 @@ private static FeatDefinition BuildMobile()
.SetSilent(Silent.WhenAddedOrRemoved)
.AddToDB()))
.AddToDB())
- .SetAbilityScorePrerequisite(AttributeDefinitions.Dexterity, 13)
.AddToDB();
}
@@ -2511,7 +2492,6 @@ public bool CanIgnoreAoOOnSelf(RulesetCharacter defender, RulesetCharacter attac
.Create()
.SetDurationData(DurationType.Minute, 1)
.SetTargetingData(Side.Enemy, RangeType.Distance, 1, TargetType.IndividualsUnique)
- .ExcludeCaster()
.SetSavingThrowData(false,
AttributeDefinitions.Constitution, false,
EffectDifficultyClassComputation.AbilityScoreAndProficiency,
@@ -2546,7 +2526,7 @@ private static IEnumerator PoisonTarget(GameLocationCharacter me, GameLocationCh
var usablePower = PowerProvider.Get(PowerFeatPoisonousSkin, rulesetMe);
- me.MyExecuteActionPowerNoCost(usablePower, target);
+ me.MyExecuteActionSpendPower(usablePower, target);
}
//Poison character that shoves me
@@ -2809,18 +2789,14 @@ private static FeatDefinition BuildMerciless()
.Create()
.SetTargetingData(Side.Enemy, RangeType.Touch, 0, TargetType.IndividualsUnique)
.SetDurationData(DurationType.Round, 1, TurnOccurenceType.EndOfSourceTurn)
- .SetSavingThrowData(
- false,
- AttributeDefinitions.Wisdom,
- true,
- EffectDifficultyClassComputation.AbilityScoreAndProficiency,
- AttributeDefinitions.Strength, 8)
+ .SetSavingThrowData(false, AttributeDefinitions.Wisdom, true,
+ EffectDifficultyClassComputation.AbilityScoreAndProficiency, AttributeDefinitions.Strength, 8)
.SetEffectForms(
EffectFormBuilder
.Create()
- .SetConditionForm(ConditionDefinitions.ConditionFrightened,
- ConditionForm.ConditionOperation.Add)
.HasSavingThrow(EffectSavingThrowType.Negates)
+ .SetConditionForm(
+ ConditionDefinitions.ConditionFrightened, ConditionForm.ConditionOperation.Add)
.Build())
.Build())
.AddToDB();
@@ -2871,7 +2847,7 @@ public IEnumerator HandleReducedToZeroHpByMe(
withinRange: distance)
.ToArray();
- attacker.MyExecuteActionPowerNoCost(usablePower, targets);
+ attacker.MyExecuteActionSpendPower(usablePower, targets);
}
public IEnumerator OnPhysicalAttackBeforeHitConfirmedOnEnemy(
diff --git a/SolastaUnfinishedBusiness/Feats/RaceFeats.cs b/SolastaUnfinishedBusiness/Feats/RaceFeats.cs
index a5711e8658..e377b28ec1 100644
--- a/SolastaUnfinishedBusiness/Feats/RaceFeats.cs
+++ b/SolastaUnfinishedBusiness/Feats/RaceFeats.cs
@@ -613,37 +613,9 @@ private static FeatDefinitionWithPrerequisites BuildFeatBountifulLuck()
return feat;
}
- private sealed class CustomBehaviorBountifulLuck(
- // ReSharper disable once SuggestBaseTypeForParameterInConstructor
- ConditionDefinition conditionBountifulLuck)
- : ITryAlterOutcomeAttack, ITryAlterOutcomeAttributeCheck, ITryAlterOutcomeSavingThrow, IRollSavingThrowFinished
+ private sealed class CustomBehaviorBountifulLuck(ConditionDefinition conditionBountifulLuck)
+ : ITryAlterOutcomeAttack, ITryAlterOutcomeAttributeCheck, ITryAlterOutcomeSavingThrow
{
- private const string BountifulLuckModifierTag = "BountifulLuckModifierTag";
- private const string BountifulLuckSaveTag = "BountifulLuckSaveTag";
-
- public void OnSavingThrowFinished(
- RulesetCharacter rulesetCaster,
- RulesetCharacter rulesetDefender,
- int saveBonus,
- string abilityScoreName,
- BaseDefinition sourceDefinition,
- List modifierTrends,
- List advantageTrends,
- int rollModifier,
- int saveDC,
- bool hasHitVisual,
- ref RollOutcome outcome,
- ref int outcomeDelta,
- List effectForms)
- {
- var caster = GameLocationCharacter.GetFromActor(rulesetCaster);
-
- caster.UsedSpecialFeatures.TryAdd(BountifulLuckModifierTag, 0);
- caster.UsedSpecialFeatures.TryAdd(BountifulLuckSaveTag, 0);
- caster.UsedSpecialFeatures[BountifulLuckModifierTag] = saveBonus + rollModifier;
- caster.UsedSpecialFeatures[BountifulLuckSaveTag] = saveDC;
- }
-
public int HandlerPriority => -10;
public IEnumerator OnTryAlterOutcomeAttack(
@@ -666,6 +638,7 @@ public IEnumerator OnTryAlterOutcomeAttack(
yield break;
}
+ // any reaction within an attack flow must use the attacker as waiter
yield return helper.MyReactToDoNothing(
ExtraActionId.DoNothingReaction,
attacker,
@@ -750,9 +723,10 @@ abilityCheckData.AbilityCheckRollOutcome is not (RollOutcome.Failure or RollOutc
yield break;
}
+ // any reaction within an attribute check flow must use the yielder as waiter
yield return helper.MyReactToDoNothing(
ExtraActionId.DoNothingReaction,
- defender,
+ helper,
"BountifulLuckCheck",
"CustomReactionBountifulLuckCheckDescription".Formatted(Category.Reaction, defender.Name, helper.Name),
ReactionValidated,
@@ -816,40 +790,39 @@ void ReactionValidated()
public IEnumerator OnTryAlterOutcomeSavingThrow(
GameLocationBattleManager battleManager,
- CharacterAction action,
GameLocationCharacter attacker,
GameLocationCharacter defender,
GameLocationCharacter helper,
- ActionModifier saveModifier,
- bool hasHitVisual,
- bool hasBorrowedLuck)
+ SavingThrowData savingThrowData,
+ bool hasHitVisual)
{
- if (!action.RolledSaveThrow ||
- action.SaveOutcome != RollOutcome.Failure ||
+ if (savingThrowData.SaveOutcome != RollOutcome.Failure ||
helper == defender ||
helper.IsOppositeSide(defender.Side) ||
!helper.CanReact() ||
!helper.IsWithinRange(defender, 6) ||
- !helper.CanPerceiveTarget(defender) ||
- !defender.UsedSpecialFeatures.TryGetValue(BountifulLuckModifierTag, out var modifier) ||
- !defender.UsedSpecialFeatures.TryGetValue(BountifulLuckSaveTag, out var saveDC))
+ !helper.CanPerceiveTarget(defender))
{
yield break;
}
- var savingRoll = action.SaveOutcomeDelta - modifier + saveDC;
+ var saveDC = savingThrowData.SaveDC;
+ var rollModifier = savingThrowData.SaveBonusAndRollModifier;
+ var savingRoll = savingThrowData.SaveOutcomeDelta - rollModifier + saveDC;
if (savingRoll != 1)
{
yield break;
}
+ // any reaction within a saving flow must use the yielder as waiter
yield return helper.MyReactToDoNothing(
ExtraActionId.DoNothingReaction,
- attacker,
+ helper,
"BountifulLuckSaving",
- "CustomReactionBountifulLuckSavingDescription".Formatted(Category.Reaction, defender.Name,
- attacker.Name, helper.Name),
+ "CustomReactionBountifulLuckSavingDescription".Formatted(
+ Category.Reaction, defender.Name, attacker?.Name ?? ReactionRequestCustom.EnvTitle,
+ savingThrowData.Title),
ReactionValidated,
battleManager: battleManager);
@@ -875,8 +848,9 @@ void ReactionValidated()
return;
}
- action.SaveOutcomeDelta += dieRoll - savingRoll;
- action.SaveOutcome = action.SaveOutcomeDelta >= 0 ? RollOutcome.Success : RollOutcome.Failure;
+ savingThrowData.SaveOutcomeDelta += dieRoll - savingRoll;
+ savingThrowData.SaveOutcome =
+ savingThrowData.SaveOutcomeDelta >= 0 ? RollOutcome.Success : RollOutcome.Failure;
rulesetHelper.InflictCondition(
conditionBountifulLuck.Name,
@@ -1149,8 +1123,9 @@ public IEnumerator OnActionFinishedByMe(CharacterAction characterAction)
yield break;
}
+ // any reaction within a ByMe trigger should use the acting character as waiter
yield return attacker.MyReactToDoNothing(
- ExtraActionId.DoNothingReaction,
+ ExtraActionId.DoNothingFree,
attacker,
"DwarvenFortitude",
"CustomReactionDwarvenFortitudeDescription".Formatted(Category.Reaction),
@@ -1228,7 +1203,7 @@ private static FeatDefinition BuildFlamesOfPhlegethos(List feats
.AddToDB();
var lightSourceForm =
- FaerieFire.EffectDescription.GetFirstFormOfType(EffectForm.EffectFormType.LightSource);
+ Light.EffectDescription.GetFirstFormOfType(EffectForm.EffectFormType.LightSource);
var power = FeatureDefinitionPowerBuilder
.Create($"Power{Name}")
@@ -1236,7 +1211,7 @@ private static FeatDefinition BuildFlamesOfPhlegethos(List feats
.SetUsesFixed(ActivationTime.NoCost)
.SetEffectDescription(
EffectDescriptionBuilder
- .Create()
+ .Create(Light)
.SetDurationData(DurationType.Round, 1)
.SetTargetingData(Side.Ally, RangeType.Self, 0, TargetType.Self)
.SetEffectForms(
@@ -1294,7 +1269,9 @@ public IEnumerator OnMagicEffectFinishedByMe(
List targets)
{
if (!action.ActionParams.activeEffect.EffectDescription.EffectForms.Any(x =>
- x.FormType == EffectForm.EffectFormType.Damage && x.DamageForm.DamageType is DamageTypeFire))
+ x.FormType == EffectForm.EffectFormType.Damage && x.DamageForm.DamageType is DamageTypeFire) ||
+ action.Countered ||
+ action is CharacterActionCastSpell { ExecutionFailed: true })
{
yield break;
}
@@ -1302,6 +1279,7 @@ public IEnumerator OnMagicEffectFinishedByMe(
var rulesetCharacter = attacker.RulesetCharacter;
var usablePower = PowerProvider.Get(power, rulesetCharacter);
+ // any reaction within a ByMe trigger should use the acting character as waiter
yield return attacker.MyReactToUsePower(
ActionDefinitions.Id.PowerNoCost,
usablePower,
@@ -1392,6 +1370,7 @@ public IEnumerator OnActionFinishedByMe(CharacterAction action)
}
actingCharacter.UsedTacticalMoves = usedTacticalMoves;
+ actingCharacter.UsedTacticalMovesChanged?.Invoke(actingCharacter);
actingCharacter.UsedSpecialFeatures.Remove(UsedTacticalMoves);
}
@@ -1449,6 +1428,7 @@ public IEnumerator OnPowerOrSpellFinishedByMe(CharacterActionMagicEffect action,
actingCharacter.UsedSpecialFeatures.TryAdd(UsedTacticalMoves, actingCharacter.UsedTacticalMoves);
actingCharacter.UsedTacticalMoves = 0;
+ actingCharacter.UsedTacticalMovesChanged?.Invoke(actingCharacter);
ServiceRepository.GetService().ExecuteAction(_actionParams, null, true);
yield break;
@@ -1490,12 +1470,14 @@ internal static IEnumerator ExecuteImpl(CharacterActionCharge characterActionCha
ActionDefinitions.Id.TacticalMove,
ActionDefinitions.MoveStance.Charge,
destination, orientation) { AttackMode = characterActionCharge.ActionParams.AttackMode };
+
var characterActionMoveStepWalk = new CharacterActionMoveStepWalk(chargeActionParams, actionID, path);
+
var attackActionParams = new CharacterActionParams(
characterActionCharge.ActingCharacter, ActionDefinitions.Id.AttackFree,
characterActionCharge.ActionParams.AttackMode, characterActionCharge.ActionParams.TargetCharacters[0],
- characterActionCharge.ActionParams
- .ActionModifiers[0]); // { BoolParameter = true, BoolParameter2 = true };
+ characterActionCharge.ActionParams.ActionModifiers[0]);
+
var characterActionAttack = new CharacterActionAttack(attackActionParams);
characterActionCharge.ResultingActions.Add(characterActionMoveStepWalk);
@@ -1843,6 +1825,7 @@ public IEnumerator OnTryAlterOutcomeAttack(
yield break;
}
+ // any reaction within an attack flow must use the attacker as waiter
yield return attacker.MyReactToDoNothing(
ExtraActionId.DoNothingReaction,
attacker,
diff --git a/SolastaUnfinishedBusiness/FightingStyles/Interception.cs b/SolastaUnfinishedBusiness/FightingStyles/Interception.cs
index f69719ff31..ee846b1b85 100644
--- a/SolastaUnfinishedBusiness/FightingStyles/Interception.cs
+++ b/SolastaUnfinishedBusiness/FightingStyles/Interception.cs
@@ -42,8 +42,11 @@ internal sealed class Interception : AbstractFightingStyle
.Create($"ReduceDamage{Name}")
.SetGuiPresentation(Name, Category.FightingStyle)
.SetAlwaysActiveReducedDamage(
- (_, defender) => defender.RulesetActor.AllConditions.FirstOrDefault(
- x => x.ConditionDefinition.Name == $"Condition{Name}")!.Amount)
+ (_, defender) =>
+ defender.RulesetActor.ConditionsByCategory
+ .SelectMany(x => x.Value)
+ .FirstOrDefault(
+ x => x.ConditionDefinition.Name == $"Condition{Name}")!.Amount)
.AddToDB())
.AddToDB()))
.AddToDB())
diff --git a/SolastaUnfinishedBusiness/FightingStyles/Torchbearer.cs b/SolastaUnfinishedBusiness/FightingStyles/Torchbearer.cs
index 4828ee0031..b2c8745042 100644
--- a/SolastaUnfinishedBusiness/FightingStyles/Torchbearer.cs
+++ b/SolastaUnfinishedBusiness/FightingStyles/Torchbearer.cs
@@ -23,13 +23,13 @@ internal sealed class Torchbearer : AbstractFightingStyle
.SetEffectDescription(
EffectDescriptionBuilder
.Create()
- .SetDurationData(DurationType.Minute, 1, TurnOccurenceType.StartOfTurn)
+ .SetDurationData(DurationType.Minute, 1)
.SetTargetingData(Side.Enemy, RangeType.Touch, 0, TargetType.IndividualsUnique)
.SetSavingThrowData(
false,
AttributeDefinitions.Dexterity,
false,
- EffectDifficultyClassComputation.FixedValue,
+ EffectDifficultyClassComputation.AbilityScoreAndProficiency,
AttributeDefinitions.Dexterity,
8)
.SetParticleEffectParameters(SpellDefinitions.FireBolt)
diff --git a/SolastaUnfinishedBusiness/Info.json b/SolastaUnfinishedBusiness/Info.json
index 5dafd70004..3ff9903980 100644
--- a/SolastaUnfinishedBusiness/Info.json
+++ b/SolastaUnfinishedBusiness/Info.json
@@ -1,7 +1,7 @@
{
"Id": "SolastaUnfinishedBusiness",
"DisplayName": "[Un] Finished Business",
- "Version": "1.5.97.29",
+ "Version": "1.5.97.30",
"GameVersion": "1.5.97",
"ManagerVersion": "0.24.0",
"AssemblyName": "SolastaUnfinishedBusiness.dll",
diff --git a/SolastaUnfinishedBusiness/Interfaces/IRollSavingThrowFinished.cs b/SolastaUnfinishedBusiness/Interfaces/IRollSavingThrowFinished.cs
index ad8a9a3536..e7984e8847 100644
--- a/SolastaUnfinishedBusiness/Interfaces/IRollSavingThrowFinished.cs
+++ b/SolastaUnfinishedBusiness/Interfaces/IRollSavingThrowFinished.cs
@@ -8,8 +8,8 @@ public interface IRollSavingThrowFinished
{
[UsedImplicitly]
public void OnSavingThrowFinished(
- RulesetCharacter caster,
- RulesetCharacter defender,
+ RulesetActor rulesetActorCaster,
+ RulesetActor rulesetActorDefender,
int saveBonus,
string abilityScoreName,
BaseDefinition sourceDefinition,
diff --git a/SolastaUnfinishedBusiness/Interfaces/IRollSavingThrowInitiated.cs b/SolastaUnfinishedBusiness/Interfaces/IRollSavingThrowInitiated.cs
index 69cd44da99..5ee4b6c4b2 100644
--- a/SolastaUnfinishedBusiness/Interfaces/IRollSavingThrowInitiated.cs
+++ b/SolastaUnfinishedBusiness/Interfaces/IRollSavingThrowInitiated.cs
@@ -8,8 +8,8 @@ public interface IRollSavingThrowInitiated
{
[UsedImplicitly]
public void OnSavingThrowInitiated(
- RulesetCharacter caster,
- RulesetCharacter defender,
+ RulesetActor rulesetActorCaster,
+ RulesetActor rulesetActorDefender,
ref int saveBonus,
ref string abilityScoreName,
BaseDefinition sourceDefinition,
diff --git a/SolastaUnfinishedBusiness/Interfaces/ITryAlterOutcomeAttributeCheck.cs b/SolastaUnfinishedBusiness/Interfaces/ITryAlterOutcomeAttributeCheck.cs
index a268eb1e29..e15dd3c96c 100644
--- a/SolastaUnfinishedBusiness/Interfaces/ITryAlterOutcomeAttributeCheck.cs
+++ b/SolastaUnfinishedBusiness/Interfaces/ITryAlterOutcomeAttributeCheck.cs
@@ -26,6 +26,7 @@ public sealed class AbilityCheckData
public RollOutcome AbilityCheckRollOutcome { get; set; }
public int AbilityCheckSuccessDelta { get; set; }
public ActionModifier AbilityCheckActionModifier { get; set; }
+ public CharacterAction Action { get; set; }
}
internal static class TryAlterOutcomeAttributeCheck
@@ -57,8 +58,8 @@ public static IEnumerator ResolveRolls(
contextFieldActor |= 64;
}
- actor.ComputeAbilityCheckActionModifier(AttributeDefinitions.Strength, SkillDefinitions.Athletics,
- actionModifierActorStrength, contextFieldActor);
+ actor.ComputeAbilityCheckActionModifier(
+ AttributeDefinitions.Strength, SkillDefinitions.Athletics, actionModifierActorStrength, contextFieldActor);
var contextFieldOpponent = 1;
@@ -321,11 +322,12 @@ internal static IEnumerator HandleITryAlterOutcomeAttributeCheck(
GameLocationCharacter actingCharacter,
AbilityCheckData abilityCheckData)
{
- yield return HandleBardicRollOnFailure(actingCharacter, abilityCheckData);
-
- var actionService = ServiceRepository.GetService();
var battleManager = ServiceRepository.GetService()
as GameLocationBattleManager;
+
+ yield return HandleBardicRollOnFailure(battleManager, actingCharacter, abilityCheckData);
+
+ var actionService = ServiceRepository.GetService();
var locationCharacterService = ServiceRepository.GetService();
var contenders =
Gui.Battle?.AllContenders ??
@@ -355,33 +357,28 @@ internal static IEnumerator HandleITryAlterOutcomeAttributeCheck(
}
private static IEnumerator HandleBardicRollOnFailure(
- GameLocationCharacter actingCharacter, AbilityCheckData abilityCheckData)
+ GameLocationBattleManager battleManager,
+ GameLocationCharacter actingCharacter,
+ AbilityCheckData abilityCheckData)
{
var actionService = ServiceRepository.GetService();
- var battleManager = ServiceRepository.GetService()
- as GameLocationBattleManager;
if (abilityCheckData.AbilityCheckRollOutcome != RollOutcome.Failure)
{
yield break;
}
- battleManager!.GetBestParametersForBardicDieRoll(
+ battleManager.GetBestParametersForBardicDieRoll(
actingCharacter,
out var bestDie,
- out _,
+ out var bestModifier,
out var sourceCondition,
out var forceMaxRoll,
out var advantage);
if (bestDie <= DieType.D1 ||
- actingCharacter.RulesetCharacter == null)
- {
- yield break;
- }
-
- // Is the die enough to overcome the failure?
- if (DiceMaxValue[(int)bestDie] < Mathf.Abs(abilityCheckData.AbilityCheckSuccessDelta))
+ actingCharacter.RulesetCharacter == null ||
+ DiceMaxValue[(int)bestDie] < Mathf.Abs(abilityCheckData.AbilityCheckSuccessDelta))
{
yield break;
}
@@ -407,6 +404,14 @@ private static IEnumerator HandleBardicRollOnFailure(
abilityCheckData.AbilityCheckSuccessDelta += roll;
+ var action = abilityCheckData.Action;
+
+ if (action != null)
+ {
+ action.BardicDieType = bestDie;
+ action.FeatureName = bestModifier.Name;
+ }
+
var actionModifier = abilityCheckData.AbilityCheckActionModifier;
if (actionModifier != null)
diff --git a/SolastaUnfinishedBusiness/Interfaces/ITryAlterOutcomeSavingThrow.cs b/SolastaUnfinishedBusiness/Interfaces/ITryAlterOutcomeSavingThrow.cs
index 25bc3388cf..f02e8d1732 100644
--- a/SolastaUnfinishedBusiness/Interfaces/ITryAlterOutcomeSavingThrow.cs
+++ b/SolastaUnfinishedBusiness/Interfaces/ITryAlterOutcomeSavingThrow.cs
@@ -2,6 +2,10 @@
using System.Linq;
using JetBrains.Annotations;
using SolastaUnfinishedBusiness.Api.GameExtensions;
+using UnityEngine;
+using static RuleDefinitions;
+using static SolastaUnfinishedBusiness.Api.DatabaseHelper.ConditionDefinitions;
+using static SolastaUnfinishedBusiness.Api.DatabaseHelper.FeatureDefinitionPowers;
namespace SolastaUnfinishedBusiness.Interfaces;
@@ -9,25 +13,74 @@ public interface ITryAlterOutcomeSavingThrow
{
IEnumerator OnTryAlterOutcomeSavingThrow(
GameLocationBattleManager battleManager,
- CharacterAction action,
- GameLocationCharacter attacker,
+ [CanBeNull] GameLocationCharacter attacker,
GameLocationCharacter defender,
GameLocationCharacter helper,
- ActionModifier actionModifier,
- bool hasHitVisual,
- [UsedImplicitly] bool hasBorrowedLuck);
+ SavingThrowData savingThrowData,
+ bool hasHitVisual);
+}
+
+public sealed class SavingThrowData
+{
+ public RollOutcome SaveOutcome { get; set; }
+ public int SaveOutcomeDelta { get; set; }
+ public ActionModifier SaveActionModifier { get; set; }
+ public string SavingThrowAbility { get; set; }
+ public int SaveDC { get; set; }
+ public int SaveBonusAndRollModifier { get; set; }
+ public BaseDefinition SourceDefinition { get; set; }
+ public EffectDescription EffectDescription { get; set; }
+ public string Title { get; set; }
+ [CanBeNull] public CharacterAction Action { get; set; }
}
internal static class TryAlterOutcomeSavingThrow
{
- internal static IEnumerable Handler(
+ internal static IEnumerator Handler(
+ GameLocationBattleManager battleManager,
+ [CanBeNull] GameLocationCharacter attacker,
+ GameLocationCharacter defender,
+ SavingThrowData savingThrowData,
+ bool hasBorrowedLuck,
+ EffectDescription effectDescription)
+ {
+ // Legendary Resistance or Indomitable?
+ if (savingThrowData.SaveOutcome == RollOutcome.Failure)
+ {
+ yield return HandleFailedSavingThrow(
+ battleManager, attacker, defender, savingThrowData, false, hasBorrowedLuck);
+
+ if (savingThrowData.Action != null)
+ {
+ savingThrowData.Action.SaveOutcome = savingThrowData.SaveOutcome;
+ savingThrowData.Action.SaveOutcomeDelta = savingThrowData.SaveOutcomeDelta;
+ }
+ }
+
+ //PATCH: support for `ITryAlterOutcomeSavingThrow`
+ foreach (var tryAlterOutcomeSavingThrow in TryAlterOutcomeSavingThrowHandler(
+ battleManager, attacker, defender, savingThrowData, false))
+ {
+ yield return tryAlterOutcomeSavingThrow;
+
+ if (savingThrowData.Action == null)
+ {
+ continue;
+ }
+
+ savingThrowData.Action.SaveOutcome = savingThrowData.SaveOutcome;
+ savingThrowData.Action.SaveOutcomeDelta = savingThrowData.SaveOutcomeDelta;
+ }
+
+ defender.RulesetActor.GrantConditionOnSavingThrowOutcome(effectDescription, savingThrowData.SaveOutcome, true);
+ }
+
+ private static IEnumerable TryAlterOutcomeSavingThrowHandler(
GameLocationBattleManager battleManager,
- CharacterAction action,
GameLocationCharacter attacker,
GameLocationCharacter defender,
- ActionModifier actionModifier,
- bool hasHitVisual,
- bool hasBorrowedLuck)
+ SavingThrowData savingThrowData,
+ bool hasHitVisual)
{
var locationCharacterService = ServiceRepository.GetService();
var contenders =
@@ -42,8 +95,236 @@ internal static IEnumerable Handler(
.GetSubFeaturesByType())
{
yield return feature.OnTryAlterOutcomeSavingThrow(
- battleManager, action, attacker, defender, unit, actionModifier, hasHitVisual, hasBorrowedLuck);
+ battleManager, attacker, defender, unit, savingThrowData, hasHitVisual);
+ }
+ }
+ }
+
+ internal static void TryRerollSavingThrow(
+ [CanBeNull] GameLocationCharacter attacker,
+ GameLocationCharacter defender,
+ SavingThrowData savingThrowData,
+ bool hasHitVisual)
+ {
+ var action = savingThrowData.Action;
+ var saveOutcome = RollOutcome.Neutral;
+ var saveOutcomeDelta = 0;
+
+ // save comes from a gadget
+ if (action == null)
+ {
+ var actionModifier = new ActionModifier();
+ var implementationService = ServiceRepository.GetService();
+
+ implementationService.TryRollSavingThrow(
+ null,
+ Side.Enemy,
+ defender.RulesetActor,
+ actionModifier,
+ false,
+ true,
+ savingThrowData.SavingThrowAbility,
+ savingThrowData.SaveDC,
+ false,
+ false,
+ false,
+ FeatureSourceType.Base,
+ [],
+ null,
+ null,
+ string.Empty,
+ savingThrowData.SourceDefinition,
+ string.Empty,
+ null,
+ out saveOutcome,
+ out saveOutcomeDelta);
+ }
+ else
+ {
+ // should never happen
+ if (attacker == null)
+ {
+ return;
}
+
+ if (action.ActionParams.AttackMode != null)
+ {
+ action.ActionParams.AttackMode.TryRollSavingThrow(
+ attacker.RulesetCharacter,
+ defender.RulesetActor,
+ savingThrowData.SaveActionModifier,
+ action.ActionParams.AttackMode.EffectDescription.EffectForms,
+ out saveOutcome, out saveOutcomeDelta);
+ }
+ else
+ {
+ action.ActionParams.RulesetEffect?.TryRollSavingThrow(
+ attacker.RulesetCharacter,
+ attacker.Side,
+ defender.RulesetActor,
+ savingThrowData.SaveActionModifier,
+ action.ActionParams.RulesetEffect.EffectDescription.EffectForms, hasHitVisual,
+ out saveOutcome, out saveOutcomeDelta);
+ }
+ }
+
+ savingThrowData.SaveOutcomeDelta = saveOutcomeDelta;
+ savingThrowData.SaveOutcome = saveOutcome;
+ }
+
+ private static IEnumerator HandleFailedSavingThrow(
+ GameLocationBattleManager battleManager,
+ [CanBeNull] GameLocationCharacter attacker,
+ GameLocationCharacter defender,
+ SavingThrowData savingThrowData,
+ bool hasHitVisual,
+ bool hasBorrowedLuck)
+ {
+ var actionService = ServiceRepository.GetService();
+ CharacterActionParams reactionParams;
+ int count;
+
+ if (defender.HasLegendaryResistances &&
+ defender.Side == Side.Enemy)
+ {
+ reactionParams = new CharacterActionParams(defender, ActionDefinitions.Id.UseLegendaryResistance);
+ count = actionService.PendingReactionRequestGroups.Count;
+ actionService.ReactToLegendaryResistSavingThrow(reactionParams);
+
+ yield return battleManager.WaitForReactions(defender, actionService, count);
+
+ if (reactionParams.ReactionValidated)
+ {
+ savingThrowData.SaveOutcomeDelta = 0;
+ savingThrowData.SaveOutcome = RollOutcome.Success;
+ }
+ }
+
+ if (savingThrowData.SaveOutcome == RollOutcome.Failure &&
+ defender.HasIndomitableResistances)
+ {
+ reactionParams = new CharacterActionParams(defender, ActionDefinitions.Id.UseIndomitableResistance);
+ count = actionService.PendingReactionRequestGroups.Count;
+ actionService.ReactToIndomitableResistSavingThrow(reactionParams);
+
+ yield return battleManager.WaitForReactions(defender, actionService, count);
+
+ if (reactionParams.ReactionValidated)
+ {
+ TryRerollSavingThrow(attacker, defender, savingThrowData, hasHitVisual);
+ }
+ }
+
+ if (savingThrowData.SaveOutcome == RollOutcome.Failure &&
+ defender.CanBorrowLuck() &&
+ !hasBorrowedLuck &&
+ ComputeAdvantage(savingThrowData.SaveActionModifier.SavingThrowAdvantageTrends) !=
+ AdvantageType.Disadvantage)
+ {
+ reactionParams = new CharacterActionParams(defender, ActionDefinitions.Id.BorrowLuck);
+ count = actionService.PendingReactionRequestGroups.Count;
+ actionService.ReactToBorrowLuck(reactionParams);
+
+ yield return battleManager.WaitForReactions(defender, actionService, count);
+
+ if (reactionParams.ReactionValidated)
+ {
+ TryRerollSavingThrow(attacker, defender, savingThrowData, hasHitVisual);
+
+ if (savingThrowData.SaveOutcome == RollOutcome.Success)
+ {
+ defender.RulesetCharacter.AddConditionOfCategory(
+ AttributeDefinitions.TagCombat,
+ RulesetCondition.CreateActiveCondition(
+ defender.Guid,
+ ConditionDomainMischiefBorrowedLuck,
+ DurationType.Dispelled,
+ 0,
+ TurnOccurenceType.StartOfTurn,
+ defender.Guid,
+ defender.RulesetCharacter.CurrentFaction.Name));
+ }
+ }
+ }
+
+ if (savingThrowData.SaveOutcome == RollOutcome.Failure &&
+ defender.CanUseDiamondSoul())
+ {
+ reactionParams = new CharacterActionParams(defender, ActionDefinitions.Id.DiamondSoul);
+ count = actionService.PendingReactionRequestGroups.Count;
+ actionService.ReactToDiamondSoul(reactionParams);
+
+ yield return battleManager.WaitForReactions(defender, actionService, count);
+
+ if (reactionParams.ReactionValidated)
+ {
+ TryRerollSavingThrow(attacker, defender, savingThrowData, hasHitVisual);
+ }
+ }
+
+ if (savingThrowData.SaveOutcome != RollOutcome.Failure)
+ {
+ yield break;
+ }
+
+ battleManager.GetBestParametersForBardicDieRoll(
+ defender,
+ out var bestDie,
+ out var bestModifier,
+ out var sourceCondition,
+ out var forceMaxRoll,
+ out var advantage);
+
+ if (bestDie <= DieType.D1 ||
+ defender.RulesetCharacter == null ||
+ DiceMaxValue[(int)bestDie] < Mathf.Abs(savingThrowData.SaveOutcomeDelta))
+ {
+ yield break;
+ }
+
+ reactionParams =
+ new CharacterActionParams(defender, ActionDefinitions.Id.UseBardicInspiration)
+ {
+ IntParameter = (int)bestDie, IntParameter2 = (int)BardicInspirationUsageType.SavingThrow
+ };
+
+ var previousReactionCount = actionService.PendingReactionRequestGroups.Count;
+
+ actionService.ReactToUseBardicInspiration(reactionParams);
+
+ yield return battleManager.WaitForReactions(defender, actionService, previousReactionCount);
+
+ if (!reactionParams.ReactionValidated)
+ {
+ yield break;
+ }
+
+ var roll = defender.RulesetCharacter.RollBardicInspirationDie(
+ sourceCondition, savingThrowData.SaveOutcomeDelta, forceMaxRoll, advantage);
+
+ savingThrowData.SaveOutcomeDelta += roll;
+
+ var action = savingThrowData.Action;
+
+ if (action != null)
+ {
+ action.BardicDieType = bestDie;
+ action.FeatureName = bestModifier.Name;
+ }
+
+ var actionModifier = savingThrowData.SaveActionModifier;
+
+ if (actionModifier != null)
+ {
+ actionModifier.SavingThrowModifier += roll;
+ actionModifier.SavingThrowModifierTrends.Add(new TrendInfo(
+ roll, FeatureSourceType.CharacterFeature, PowerBardGiveBardicInspiration.Name, null));
+ }
+
+ // change roll to success if appropriate
+ if (savingThrowData.SaveOutcomeDelta >= 0)
+ {
+ savingThrowData.SaveOutcome = RollOutcome.Success;
}
}
}
diff --git a/SolastaUnfinishedBusiness/Main.cs b/SolastaUnfinishedBusiness/Main.cs
index 0612e02ce7..e192ddd52d 100644
--- a/SolastaUnfinishedBusiness/Main.cs
+++ b/SolastaUnfinishedBusiness/Main.cs
@@ -61,6 +61,14 @@ internal static void Info(string msg)
ModEntry.Logger.Log(msg);
}
+ internal static void EnsureFolderExists(string path)
+ {
+ if (!Directory.Exists(path))
+ {
+ Directory.CreateDirectory(path);
+ }
+ }
+
[UsedImplicitly]
internal static bool Load([NotNull] UnityModManager.ModEntry modEntry)
{
@@ -86,6 +94,11 @@ internal static bool Load([NotNull] UnityModManager.ModEntry modEntry)
return false;
}
+ EnsureFolderExists(SettingsFolder);
+ DocumentationContext.EnsureFolderExists();
+ PortraitsContext.EnsureFolderExists();
+ SaveByLocationContext.EnsureFoldersExist();
+
try
{
Mod = new ModManager();
@@ -123,11 +136,6 @@ internal static bool Load([NotNull] UnityModManager.ModEntry modEntry)
internal static void LoadSettingFilenames()
{
- if (!Directory.Exists(SettingsFolder))
- {
- Directory.CreateDirectory(SettingsFolder);
- }
-
SettingsFiles = Directory.GetFiles(SettingsFolder)
.Where(x => x.EndsWith(".xml"))
.Select(Path.GetFileNameWithoutExtension)
diff --git a/SolastaUnfinishedBusiness/Models/AiContext.cs b/SolastaUnfinishedBusiness/Models/AiContext.cs
index 7a2331886d..f67d0264e3 100644
--- a/SolastaUnfinishedBusiness/Models/AiContext.cs
+++ b/SolastaUnfinishedBusiness/Models/AiContext.cs
@@ -1,105 +1,152 @@
-using System.Collections.Generic;
+using System;
using System.Linq;
using SolastaUnfinishedBusiness.Api;
+using SolastaUnfinishedBusiness.Api.GameExtensions;
using SolastaUnfinishedBusiness.Builders;
using TA.AI;
+using TA.AI.Activities;
using TA.AI.Considerations;
using UnityEngine;
+using Object = UnityEngine.Object;
namespace SolastaUnfinishedBusiness.Models;
internal static class AiContext
{
- internal const string DoNothing = "1";
- internal const string DoStrengthCheckCasterDC = "2";
-
- internal static readonly List DoNothingConditions =
- ["ConditionNoxiousSpray", "ConditionVileBrew", "ConditionGrappledRestrainedIceBound"];
+ internal static ActivityScorerDefinition CreateActivityScorer(
+ DecisionDefinition baseDecision, string name,
+ bool overwriteConsiderations = false,
+ params WeightedConsiderationDescription[] considerations)
+ {
+ var result = Object.Instantiate(baseDecision.Decision.scorer);
- internal static readonly List DoStrengthCheckCasterDCConditions =
- [
- "ConditionFlashFreeze", "ConditionGrappledRestrainedEnsnared",
- "ConditionGrappledRestrainedSpellWeb", "ConditionRestrainedByEntangle"
- ];
+ result.name = name;
+ result.scorer = new ActivityScorer();
- internal static void Load()
- {
- // order matters as same weight
- // this code needs a refactoring. meanwhile check:
- // - CharacterActionPanelPatcher SelectBreakFreeMode and add condition there if spell also aims allies
- foreach (var condition in DoNothingConditions)
+ if (!overwriteConsiderations)
{
- BuildDecisionBreakFreeFromCondition(condition, DoNothing);
+ // ReSharper disable once ForeachCanBePartlyConvertedToQueryUsingAnotherGetEnumerator
+ foreach (var weightedConsideration in baseDecision.Decision.scorer.scorer.WeightedConsiderations)
+ {
+ var sourceDescription = weightedConsideration.Consideration;
+ var targetDescription = new ConsiderationDescription
+ {
+ considerationType = sourceDescription.considerationType,
+ curve = sourceDescription.curve,
+ boolParameter = sourceDescription.boolParameter,
+ boolSecParameter = sourceDescription.boolSecParameter,
+ boolTerParameter = sourceDescription.boolTerParameter,
+ byteParameter = sourceDescription.byteParameter,
+ intParameter = sourceDescription.intParameter,
+ floatParameter = sourceDescription.floatParameter,
+ stringParameter = sourceDescription.stringParameter
+ };
+
+ var weightedConsiderationDescription = new WeightedConsiderationDescription(
+ CreateConsiderationDefinition(weightedConsideration.ConsiderationDefinition.name,
+ targetDescription),
+ weightedConsideration.weight);
+
+ result.Scorer.WeightedConsiderations.Add(weightedConsiderationDescription);
+ }
}
- foreach (var condition in DoStrengthCheckCasterDCConditions)
- {
- BuildDecisionBreakFreeFromCondition(condition, DoStrengthCheckCasterDC);
- }
+ result.Scorer.WeightedConsiderations.AddRange(considerations);
+
+ return result;
}
- // boolParameter false won't do any ability check
- private static void BuildDecisionBreakFreeFromCondition(string conditionName, string action)
+ private static ConsiderationDefinition CreateConsiderationDefinition(
+ string name, ConsiderationDescription consideration)
{
- //TODO: create proper builders
-
- // create considerations copies
-
- var baseDecision = DatabaseHelper.GetDefinition("BreakConcentration_FlyingInMelee");
- var considerationHasCondition = baseDecision.Decision.Scorer.considerations.FirstOrDefault(x =>
- x.consideration.name == "HasConditionFlying");
- var considerationMainActionNotFullyConsumed = baseDecision.Decision.Scorer.considerations.FirstOrDefault(x =>
- x.consideration.name == "MainActionNotFullyConsumed");
-
- if (considerationHasCondition == null || considerationMainActionNotFullyConsumed == null)
- {
- Main.Error("fetching considerations at BuildDecisionBreakFreeFromCondition");
-
- return;
- }
-
- var considerationHasConditionBreakFree = new WeightedConsiderationDescription
- {
- consideration = Object.Instantiate(considerationHasCondition.consideration),
- weight = considerationHasCondition.weight
- };
+ var result = ScriptableObject.CreateInstance();
- considerationHasConditionBreakFree.consideration.name = $"Has{conditionName}";
- considerationHasConditionBreakFree.consideration.consideration = new ConsiderationDescription
- {
- considerationType = nameof(HasCondition),
- curve = considerationHasCondition.consideration.consideration.curve,
- boolParameter = considerationHasCondition.consideration.consideration.boolParameter,
- intParameter = considerationHasCondition.consideration.consideration.intParameter,
- floatParameter = considerationHasCondition.consideration.consideration.floatParameter,
- stringParameter = conditionName
- };
+ result.name = name;
+ result.consideration = consideration;
- // create scorer copy
+ return result;
+ }
- var scorer = Object.Instantiate(baseDecision.Decision.scorer);
+ private static WeightedConsiderationDescription GetWeightedConsiderationDescriptionByDecisionAndConsideration(
+ DecisionDefinition decisionDefinition, string considerationType)
+ {
+ return decisionDefinition.Decision.Scorer.WeightedConsiderations
+ .FirstOrDefault(y => y.ConsiderationDefinition.Consideration.considerationType == considerationType)
+ ?? throw new Exception();
+ }
- scorer.name = "BreakFree";
- scorer.scorer.considerations = [considerationHasConditionBreakFree, considerationMainActionNotFullyConsumed];
+ internal static DecisionPackageDefinition BuildDecisionPackageBreakFree(string conditionName)
+ {
+ var baseDecision = DatabaseHelper.GetDefinition("BreakConcentration_FlyingInMelee");
- // create and assign decision definition to all decision packages
+ var wcdHasCondition = GetWeightedConsiderationDescriptionByDecisionAndConsideration(
+ baseDecision, "HasCondition");
+
+ var hasConditionBreakFree = new WeightedConsiderationDescription(
+ CreateConsiderationDefinition(
+ $"Has{conditionName}",
+ new ConsiderationDescription
+ {
+ considerationType = nameof(HasCondition),
+ curve = wcdHasCondition.Consideration.curve,
+ stringParameter = conditionName,
+ boolParameter = true,
+ intParameter = 2,
+ floatParameter = 2f
+ }), 1f);
+
+ var wcdActionTypeStatus = GetWeightedConsiderationDescriptionByDecisionAndConsideration(
+ baseDecision, "ActionTypeStatus");
+
+ var mainActionNotFullyConsumed = new WeightedConsiderationDescription(
+ CreateConsiderationDefinition(
+ "MainActionNotFullyConsumed",
+ new ConsiderationDescription
+ {
+ considerationType = nameof(ActionTypeStatus),
+ curve = wcdActionTypeStatus.Consideration.curve,
+ boolParameter = true,
+ floatParameter = 1f
+ }), 1f);
+
+ var scorerBreakFree = CreateActivityScorer(baseDecision, $"BreakFree{conditionName}", true,
+ hasConditionBreakFree,
+ mainActionNotFullyConsumed);
var decisionBreakFree = DecisionDefinitionBuilder
.Create($"DecisionBreakFree{conditionName}")
.SetGuiPresentationNoContent(true)
.SetDecisionDescription(
- "if restrained and can use main action, try to break free",
- "BreakFree",
- scorer,
- action,
+ $"if restrained from {conditionName}, and can use main action, try to break free",
+ nameof(BreakFree),
+ scorerBreakFree,
enumParameter: 1,
floatParameter: 3f)
.AddToDB();
- foreach (var decisionPackageDefinition in DatabaseRepository.GetDatabase())
- {
- decisionPackageDefinition.package.weightedDecisions.Add(
- new WeightedDecisionDescription(decisionBreakFree, 1, 0, false));
- }
+ // use weight 2f to ensure scenarios that don't prevent enemies from take actions to still consider this
+ var packageBreakFree = DecisionPackageDefinitionBuilder
+ .Create($"BreakFreeAbilityCheck{conditionName}")
+ .SetGuiPresentationNoContent(true)
+ .SetWeightedDecisions(new WeightedDecisionDescription { decision = decisionBreakFree, weight = 2f })
+ .AddToDB();
+
+ return packageBreakFree;
+ }
+
+ internal static RulesetCondition GetRestrainingCondition(RulesetCharacter rulesetCharacter)
+ {
+ return rulesetCharacter
+ .GetFeaturesByType()
+ .Where(actionAffinity => actionAffinity.AuthorizedActions.Contains(ActionDefinitions.Id.BreakFree))
+ .Select(rulesetCharacter.FindFirstConditionHoldingFeature)
+ .FirstOrDefault(rulesetCondition => rulesetCondition != null);
+ }
+
+ internal enum BreakFreeType
+ {
+ DoNoCheckAndRemoveCondition = 10,
+ DoStrengthCheckAgainstCasterDC = 20,
+ DoWisdomCheckAgainstCasterDC = 30
}
}
diff --git a/SolastaUnfinishedBusiness/Models/BootContext.cs b/SolastaUnfinishedBusiness/Models/BootContext.cs
index 29213cf063..206e5bc637 100644
--- a/SolastaUnfinishedBusiness/Models/BootContext.cs
+++ b/SolastaUnfinishedBusiness/Models/BootContext.cs
@@ -27,7 +27,6 @@ internal static void Startup()
DiagnosticsContext.CacheTaDefinitions();
// Load Portraits, Translations and Resources Locator after
- PortraitsContext.Load();
TranslatorContext.Load();
ResourceLocatorContext.Load();
@@ -44,9 +43,6 @@ internal static void Startup()
// Custom Conditions must load as early as possible
CustomConditionsContext.Load();
- // AI Context
- AiContext.Load();
-
//
// custom stuff that can be loaded in any order
//
diff --git a/SolastaUnfinishedBusiness/Models/CharacterContext.cs b/SolastaUnfinishedBusiness/Models/CharacterContext.cs
index d1d6a7fa00..9b475df961 100644
--- a/SolastaUnfinishedBusiness/Models/CharacterContext.cs
+++ b/SolastaUnfinishedBusiness/Models/CharacterContext.cs
@@ -219,6 +219,7 @@ internal static void LateLoad()
SwitchFighterLevelToIndomitableSavingReroll();
SwitchFighterWeaponSpecialization();
SwitchFirstLevelTotalFeats();
+ SwitchProneAction();
SwitchHelpPower();
SwitchMonkAbundantKi();
SwitchMonkFightingStyle();
@@ -353,6 +354,7 @@ private static void LoadSorcererQuickened()
.Create(CastBonus, "CastQuickened")
.SetGuiPresentation(
"Rules/&MetamagicOptionQuickenedSpellTitle", "Action/&CastQuickenedDescription", CastMain)
+ .SetSortOrder(CastBonus)
.SetActionId(ExtraActionId.CastQuickened)
.AddToDB();
@@ -737,6 +739,14 @@ internal static void SwitchHelpPower()
}
}
+ internal static void SwitchProneAction()
+ {
+ DropProne.actionType = ActionDefinitions.ActionType.NoCost;
+ DropProne.formType = Main.Settings.AddFallProneActionToAllRaces
+ ? ActionDefinitions.ActionFormType.Small
+ : ActionDefinitions.ActionFormType.Invisible;
+ }
+
internal static void SwitchDarknessPerceptive()
{
var races = new List
@@ -1208,7 +1218,7 @@ public IEnumerator OnTryAlterAttributeCheck(
}
yield return helper.MyReactToDoNothing(
- ExtraActionId.DoNothingReaction,
+ ExtraActionId.DoNothingFree,
defender,
"MagicalGuidanceCheck",
"CustomReactionMagicalGuidanceCheckDescription"
@@ -1281,8 +1291,8 @@ public IEnumerator ComputeValidPositions(CursorLocationSelectPosition cursorLoca
private sealed class RollSavingThrowInitiatedIndomitableSaving : IRollSavingThrowInitiated
{
public void OnSavingThrowInitiated(
- RulesetCharacter caster,
- RulesetCharacter defender,
+ RulesetActor rulesetActorCaster,
+ RulesetActor rulesetActorDefender,
ref int saveBonus,
ref string abilityScoreName,
BaseDefinition sourceDefinition,
@@ -1295,7 +1305,12 @@ public void OnSavingThrowInitiated(
int outcomeDelta,
List effectForms)
{
- var classLevel = defender.GetClassLevel(Fighter);
+ if (rulesetActorDefender is not RulesetCharacterHero rulesetCharacterDefender)
+ {
+ return;
+ }
+
+ var classLevel = rulesetCharacterDefender.GetClassLevel(Fighter);
rollModifier += classLevel;
modifierTrends.Add(
diff --git a/SolastaUnfinishedBusiness/Models/CharacterUAContext.cs b/SolastaUnfinishedBusiness/Models/CharacterUAContext.cs
index 2657f8de81..36064c6d93 100644
--- a/SolastaUnfinishedBusiness/Models/CharacterUAContext.cs
+++ b/SolastaUnfinishedBusiness/Models/CharacterUAContext.cs
@@ -359,7 +359,7 @@ public IEnumerator OnPhysicalAttackBeforeHitConfirmedOnEnemy(
[defender],
attacker,
powerBarbarianBrutalStrike.Name,
- ReactionValidated,
+ reactionValidated: ReactionValidated,
battleManager: battleManager);
yield break;
@@ -413,10 +413,7 @@ public IEnumerator OnPhysicalAttackFinishedByMe(GameLocationBattleManager battle
}
private static void InflictCondition(
- RulesetCharacter rulesetAttacker,
- // ReSharper disable once SuggestBaseTypeForParameter
- RulesetCharacter rulesetDefender,
- string conditionName)
+ RulesetCharacter rulesetAttacker, RulesetCharacter rulesetDefender, string conditionName)
{
rulesetDefender.InflictCondition(
conditionName,
@@ -448,8 +445,11 @@ public IEnumerator OnMagicEffectAttackInitiatedOnMe(
bool checkMagicalAttackDamage)
{
var damageType = activeEffect.EffectDescription.FindFirstDamageForm()?.DamageType;
+ var rulesetAttacker = attacker.RulesetCharacter;
- if (damageType == null)
+ if (damageType == null ||
+ rulesetAttacker == null ||
+ rulesetAttacker is RulesetCharacterEffectProxy)
{
yield break;
}
@@ -466,8 +466,11 @@ public IEnumerator OnPhysicalAttackInitiatedOnMe(
RulesetAttackMode attackMode)
{
var damageType = attackMode.EffectDescription.FindFirstDamageForm()?.DamageType;
+ var rulesetAttacker = attacker.RulesetCharacter;
- if (damageType == null)
+ if (damageType == null ||
+ rulesetAttacker == null ||
+ rulesetAttacker is RulesetCharacterEffectProxy)
{
yield break;
}
@@ -509,7 +512,7 @@ private void AddBonusAttackAndDamageRoll(
TurnOccurenceType.EndOfTurn,
AttributeDefinitions.TagEffect,
rulesetAttacker.guid,
- rulesetAttacker.CurrentFaction.Name,
+ FactionDefinitions.Party.Name,
1,
conditionSunderingBlowAlly.Name,
0,
@@ -676,8 +679,8 @@ internal static void SwitchBarbarianFightingStyle()
.SetEffectDescription(
EffectDescriptionBuilder
.Create()
- .SetTargetingData(Side.Ally, RangeType.Self, 0, TargetType.Self)
.SetDurationData(DurationType.Minute, 1)
+ .SetTargetingData(Side.Ally, RangeType.Self, 0, TargetType.Self)
.SetEffectForms(
EffectFormBuilder
.Create()
@@ -1218,8 +1221,8 @@ private static void BuildRogueCunningStrike()
.SetEffectDescription(
EffectDescriptionBuilder
.Create()
- .SetTargetingData(Side.Enemy, RangeType.Distance, 6, TargetType.IndividualsUnique)
.SetDurationData(DurationType.Round, 1)
+ .SetTargetingData(Side.Enemy, RangeType.Distance, 6, TargetType.IndividualsUnique)
.SetSavingThrowData(false, AttributeDefinitions.Dexterity, false,
EffectDifficultyClassComputation.AbilityScoreAndProficiency, AttributeDefinitions.Dexterity, 8)
.SetEffectForms(
@@ -1242,8 +1245,8 @@ private static void BuildRogueCunningStrike()
.SetEffectDescription(
EffectDescriptionBuilder
.Create()
- .SetTargetingData(Side.Enemy, RangeType.Distance, 6, TargetType.IndividualsUnique)
.SetDurationData(DurationType.Minute, 1)
+ .SetTargetingData(Side.Enemy, RangeType.Distance, 6, TargetType.IndividualsUnique)
.SetSavingThrowData(false, AttributeDefinitions.Constitution, false,
EffectDifficultyClassComputation.AbilityScoreAndProficiency, AttributeDefinitions.Dexterity, 8)
.SetEffectForms(
@@ -1341,8 +1344,8 @@ private static void BuildRogueCunningStrike()
.SetEffectDescription(
EffectDescriptionBuilder
.Create()
- .SetTargetingData(Side.Enemy, RangeType.Distance, 6, TargetType.IndividualsUnique)
.SetDurationData(DurationType.Round, 1)
+ .SetTargetingData(Side.Enemy, RangeType.Distance, 6, TargetType.IndividualsUnique)
.SetSavingThrowData(false, AttributeDefinitions.Constitution, false,
EffectDifficultyClassComputation.AbilityScoreAndProficiency, AttributeDefinitions.Dexterity, 8)
.SetEffectForms(
@@ -1381,8 +1384,8 @@ private static void BuildRogueCunningStrike()
.SetEffectDescription(
EffectDescriptionBuilder
.Create()
- .SetTargetingData(Side.Enemy, RangeType.Distance, 6, TargetType.IndividualsUnique)
.SetDurationData(DurationType.Minute, 1)
+ .SetTargetingData(Side.Enemy, RangeType.Distance, 6, TargetType.IndividualsUnique)
.SetSavingThrowData(false, AttributeDefinitions.Constitution, false,
EffectDifficultyClassComputation.AbilityScoreAndProficiency, AttributeDefinitions.Dexterity, 8)
.SetEffectForms(
@@ -1404,8 +1407,8 @@ private static void BuildRogueCunningStrike()
.SetEffectDescription(
EffectDescriptionBuilder
.Create()
- .SetTargetingData(Side.Enemy, RangeType.Distance, 6, TargetType.IndividualsUnique)
.SetDurationData(DurationType.Round, 1)
+ .SetTargetingData(Side.Enemy, RangeType.Distance, 6, TargetType.IndividualsUnique)
.SetSavingThrowData(false, AttributeDefinitions.Dexterity, false,
EffectDifficultyClassComputation.AbilityScoreAndProficiency, AttributeDefinitions.Dexterity, 8)
.SetEffectForms(
@@ -1516,7 +1519,7 @@ public IEnumerator OnPhysicalAttackBeforeHitConfirmedOnEnemy(
[defender],
attacker,
powerRogueCunningStrike.Name,
- ReactionValidated,
+ reactionValidated: ReactionValidated,
battleManager: battleManager);
yield break;
@@ -1578,13 +1581,8 @@ private IEnumerator HandleWithdraw(CharacterAction action, GameLocationCharacter
yield return GameUiContext.SelectPosition(action, powerWithdraw);
var rulesetAttacker = attacker.RulesetCharacter;
- var targetPosition = action.ActionParams.Positions[0];
- var distance = int3.Distance(attacker.LocationPosition, targetPosition);
- var actionParams =
- new CharacterActionParams(attacker, ActionDefinitions.Id.TacticalMove)
- {
- Positions = { targetPosition }
- };
+ var position = action.ActionParams.Positions[0];
+ var distance = int3.Distance(attacker.LocationPosition, position);
attacker.UsedTacticalMoves -= (int)distance;
@@ -1593,6 +1591,8 @@ private IEnumerator HandleWithdraw(CharacterAction action, GameLocationCharacter
attacker.UsedTacticalMoves = 0;
}
+ attacker.UsedTacticalMovesChanged?.Invoke(attacker);
+
rulesetAttacker.InflictCondition(
ConditionDisengaging,
DurationType.Round,
@@ -1608,7 +1608,7 @@ private IEnumerator HandleWithdraw(CharacterAction action, GameLocationCharacter
0,
0);
- ServiceRepository.GetService().ExecuteAction(actionParams, null, true);
+ attacker.MyExecuteActionTacticalMove(position);
}
private IEnumerator HandleKnockOut(GameLocationCharacter attacker, GameLocationCharacter defender)
@@ -1623,7 +1623,7 @@ private IEnumerator HandleKnockOut(GameLocationCharacter attacker, GameLocationC
var rulesetAttacker = attacker.RulesetCharacter;
var usablePower = PowerProvider.Get(powerKnockOutApply, rulesetAttacker);
- attacker.MyExecuteActionPowerNoCost(usablePower, defender);
+ attacker.MyExecuteActionSpendPower(usablePower, defender);
}
}
diff --git a/SolastaUnfinishedBusiness/Models/CustomActionIdContext.cs b/SolastaUnfinishedBusiness/Models/CustomActionIdContext.cs
index 3bf257d7ae..3cbba90d63 100644
--- a/SolastaUnfinishedBusiness/Models/CustomActionIdContext.cs
+++ b/SolastaUnfinishedBusiness/Models/CustomActionIdContext.cs
@@ -114,6 +114,7 @@ private static void BuildCustomInvocationActions()
{
ActionDefinitionBuilder
.Create(CastInvocation, "CastInvocationBonus")
+ .SetSortOrder(CastBonus.GuiPresentation.sortOrder + 2)
.SetActionId(ExtraActionId.CastInvocationBonus)
.SetActionType(ActionType.Bonus)
.SetActionScope(ActionScope.Battle)
@@ -121,6 +122,7 @@ private static void BuildCustomInvocationActions()
ActionDefinitionBuilder
.Create(CastInvocation, "CastInvocationNoCost")
+ .SetSortOrder(CastNoCost.GuiPresentation.sortOrder + 2)
.SetActionId(ExtraActionId.CastInvocationNoCost)
.SetActionType(ActionType.NoCost)
.SetActionScope(ActionScope.Battle)
@@ -128,7 +130,8 @@ private static void BuildCustomInvocationActions()
ActionDefinitionBuilder
.Create(CastInvocation, "CastPlaneMagicMain")
- .SetGuiPresentation("CastPlaneMagic", Category.Action, Sprites.ActionPlaneMagic, 10)
+ .SetGuiPresentation("CastPlaneMagic", Category.Action, Sprites.ActionPlaneMagic)
+ .SetSortOrder(CastMain.GuiPresentation.sortOrder + 1)
.SetActionId(ExtraActionId.CastPlaneMagicMain)
.SetActionType(ActionType.Main)
.SetActionScope(ActionScope.All)
@@ -136,7 +139,8 @@ private static void BuildCustomInvocationActions()
ActionDefinitionBuilder
.Create(CastInvocation, "CastPlaneMagicBonus")
- .SetGuiPresentation("CastPlaneMagic", Category.Action, Sprites.ActionPlaneMagic, 41)
+ .SetGuiPresentation("CastPlaneMagic", Category.Action, Sprites.ActionPlaneMagic)
+ .SetSortOrder(CastBonus.GuiPresentation.sortOrder + 1)
.SetActionId(ExtraActionId.CastPlaneMagicBonus)
.SetActionType(ActionType.Bonus)
.SetActionScope(ActionScope.Battle)
@@ -680,7 +684,7 @@ private static ActionStatus CanUseActionQuickened(GameLocationCharacter glc, Act
// more or less in order of cost
if (hero == null ||
!hero.TrainedMetamagicOptions.Contains(quickenedSpell) ||
- !glc.IsActionOnGoing(Id.MetamagicToggle) ||
+ (Main.Settings.HideQuickenedActionWhenMetamagicOff && !glc.IsActionOnGoing(Id.MetamagicToggle)) ||
glc.GetActionTypeStatus(ActionType.Bonus) != ActionStatus.Available ||
!glc.RulesetCharacter.CanCastSpellOfActionType(ActionType.Main, glc.CanOnlyUseCantrips))
{
diff --git a/SolastaUnfinishedBusiness/Models/CustomConditionsContext.cs b/SolastaUnfinishedBusiness/Models/CustomConditionsContext.cs
index 75f7a8c514..1165d321ad 100644
--- a/SolastaUnfinishedBusiness/Models/CustomConditionsContext.cs
+++ b/SolastaUnfinishedBusiness/Models/CustomConditionsContext.cs
@@ -325,10 +325,11 @@ public void OnConditionAdded(RulesetCharacter target, RulesetCondition rulesetCo
}
else
{
- var conditions = target.allConditionsForEnumeration;
-
- foreach (var condition in conditions
- .Where(condition => condition.ConditionDefinition.IsSubtypeOf("ConditionFlying")))
+ // need ToList to avoid enumerator issues with RemoveCondition
+ foreach (var condition in target.ConditionsByCategory
+ .SelectMany(x => x.Value)
+ .Where(condition => condition.ConditionDefinition.IsSubtypeOf("ConditionFlying"))
+ .ToList())
{
//We are not interested in permanent effects
if (condition.DurationType == DurationType.Permanent)
@@ -522,16 +523,18 @@ public IEnumerator OnActionFinishedByMe(CharacterAction characterAction)
var actingCharacter = characterAction.ActingCharacter;
var rulesetCharacter = actingCharacter.RulesetCharacter;
- foreach (var rulesetCondition in rulesetCharacter.AllConditions
+ // need ToList to avoid enumerator issues with RemoveCondition
+ foreach (var rulesetCondition in rulesetCharacter.ConditionsByCategory
+ .SelectMany(x => x.Value)
.Where(x => x.ConditionDefinition.Name == Taunted.Name)
- .ToList()
.Select(a => new { a, rulesetCaster = EffectHelpers.GetCharacterByGuid(a.SourceGuid) })
.Where(t => t.rulesetCaster != null)
.Select(b => new { b, caster = GameLocationCharacter.GetFromActor(b.rulesetCaster) })
.Where(t =>
// ruleset amount carries the max range for the condition
t.caster != null && !t.caster.IsWithinRange(actingCharacter, t.b.a.Amount))
- .Select(c => c.b.a))
+ .Select(c => c.b.a)
+ .ToList())
{
rulesetCharacter.RemoveCondition(rulesetCondition);
}
diff --git a/SolastaUnfinishedBusiness/Models/DiagnosticsContext.cs b/SolastaUnfinishedBusiness/Models/DiagnosticsContext.cs
index c5546aafee..0acf8af6bc 100644
--- a/SolastaUnfinishedBusiness/Models/DiagnosticsContext.cs
+++ b/SolastaUnfinishedBusiness/Models/DiagnosticsContext.cs
@@ -138,19 +138,11 @@ private static string GetDiagnosticsFolder()
{
var path = Path.Combine(ProjectFolder ?? GameFolder, "Diagnostics");
- EnsureFolderExists(path);
+ Main.EnsureFolderExists(path);
return path;
}
- private static void EnsureFolderExists([NotNull] string path)
- {
- if (!Directory.Exists(path))
- {
- Directory.CreateDirectory(path);
- }
- }
-
private const string OfficialBpFolder = "OfficialBlueprints";
private const string UnfinishedBusinessBpFolder = "UnfinishedBusinessBlueprints";
@@ -199,7 +191,7 @@ private static void CreateDefinitionDiagnostics([CanBeNull] BaseDefinition[] bas
return;
}
- EnsureFolderExists(DiagnosticsFolder);
+ Main.EnsureFolderExists(DiagnosticsFolder);
/////////////////////////////////////////////////////////////////////////////////////////////////
// Write all definitions with no GUI presentation to file
diff --git a/SolastaUnfinishedBusiness/Models/DmProEditorContext.cs b/SolastaUnfinishedBusiness/Models/DmProEditorContext.cs
index 112432c2d3..9cd659338d 100644
--- a/SolastaUnfinishedBusiness/Models/DmProEditorContext.cs
+++ b/SolastaUnfinishedBusiness/Models/DmProEditorContext.cs
@@ -38,7 +38,7 @@ internal static void BackupAndDelete([NotNull] string path, [NotNull] UserConten
var backupDirectory = Path.Combine(Main.ModFolder, BackupFolder);
- Directory.CreateDirectory(backupDirectory);
+ Main.EnsureFolderExists(backupDirectory);
var title = userContent.Title;
var compliantTitle = IOHelper.GetOsCompliantFilename(title);
diff --git a/SolastaUnfinishedBusiness/Models/DocumentationContext.cs b/SolastaUnfinishedBusiness/Models/DocumentationContext.cs
index d26f345039..13fdf0c464 100644
--- a/SolastaUnfinishedBusiness/Models/DocumentationContext.cs
+++ b/SolastaUnfinishedBusiness/Models/DocumentationContext.cs
@@ -5,32 +5,28 @@
using System.Text;
using JetBrains.Annotations;
using SolastaUnfinishedBusiness.Api.LanguageExtensions;
+using SolastaUnfinishedBusiness.Classes;
using SolastaUnfinishedBusiness.Displays;
+using static SolastaUnfinishedBusiness.Api.DatabaseHelper.CharacterClassDefinitions;
+using static SolastaUnfinishedBusiness.Api.DatabaseHelper.SpellListDefinitions;
namespace SolastaUnfinishedBusiness.Models;
internal static class DocumentationContext
{
- internal static void DumpDocumentation()
+ internal static void EnsureFolderExists()
{
- if (!Directory.Exists($"{Main.ModFolder}/Documentation"))
- {
- Directory.CreateDirectory($"{Main.ModFolder}/Documentation");
- }
-
- if (!Directory.Exists($"{Main.ModFolder}/Documentation/Monsters"))
- {
- Directory.CreateDirectory($"{Main.ModFolder}/Documentation/Monsters");
- }
+ Main.EnsureFolderExists($"{Main.ModFolder}/Documentation");
+ Main.EnsureFolderExists($"{Main.ModFolder}/Documentation/Monsters");
+ }
+ internal static void DumpDocumentation()
+ {
foreach (var characterFamilyDefinition in DatabaseRepository.GetDatabase()
- .Where(x => x.Name != "Giant_Rugan" && x.Name != "Ooze"))
+ .Where(x =>
+ x.Name is not ("Giant_Rugan" or "Ooze") &&
+ x.ContentPack != CeContentPackContext.CeContentPack))
{
- if (characterFamilyDefinition.ContentPack == CeContentPackContext.CeContentPack)
- {
- continue;
- }
-
DumpMonsters($"SolastaMonsters{characterFamilyDefinition.Name}",
x => x.CharacterFamily == characterFamilyDefinition.Name && x.DefaultFaction == "HostileMonsters");
}
@@ -40,9 +36,21 @@ internal static void DumpDocumentation()
DumpRaces("Races", x => vanillaRaces.Contains(x) || RacesContext.Races.Contains(x));
DumpRaces("Subraces", x => !vanillaRaces.Contains(x) && !RacesContext.Races.Contains(x));
+
DumpClasses(string.Empty, _ => true);
DumpSubclasses(string.Empty, GetModdedSubclasses().Union(GetVanillaSubclasses()));
+ DumpOthers("Spells",
+ x =>
+ (x.ContentPack == CeContentPackContext.CeContentPack &&
+ SpellsContext.Spells.Contains(x)) ||
+ (x.ContentPack != CeContentPackContext.CeContentPack &&
+ !SpellsContext.SpellsChildMaster.ContainsKey(x) &&
+ x.implemented &&
+ !x.Name.Contains("Invocation") &&
+ !x.Name.EndsWith("NoFocus") &&
+ !x.Name.EndsWith("_B")));
+
DumpOthers("Backgrounds",
_ => true);
DumpOthers("Feats",
@@ -56,16 +64,8 @@ internal static void DumpDocumentation()
x =>
InvocationsContext.Invocations.Contains(x) ||
x.ContentPack != CeContentPackContext.CeContentPack);
- DumpOthers("Spells",
- x =>
- (x.ContentPack == CeContentPackContext.CeContentPack &&
- SpellsContext.Spells.Contains(x)) ||
- (x.ContentPack != CeContentPackContext.CeContentPack &&
- !SpellsContext.SpellsChildMaster.ContainsKey(x) &&
- x.implemented &&
- !x.Name.Contains("Invocation") &&
- !x.Name.EndsWith("_B")));
- DumpOthers("Items", x => x.IsArmor || x.IsWeapon);
+ DumpOthers("Items",
+ x => x.IsArmor || x.IsWeapon);
DumpOthers("Metamagic",
x =>
MetamagicContext.Metamagic.Contains(x) ||
@@ -111,6 +111,32 @@ private static string LazyManStripXml(string input)
.Replace("", string.Empty);
}
+ private static void DumpFeatureUnlockByLevel(StringBuilder outString, List featureUnlocks)
+ {
+ var level = 0;
+
+ foreach (var featureUnlockByLevel in featureUnlocks
+ .Where(x => !x.FeatureDefinition.GuiPresentation.hidden)
+ .OrderBy(x => x.level))
+ {
+ if (level != featureUnlockByLevel.level)
+ {
+ outString.AppendLine();
+ outString.AppendLine($"## Level {featureUnlockByLevel.level}");
+ outString.AppendLine();
+ level = featureUnlockByLevel.level;
+ }
+
+ var featureDefinition = featureUnlockByLevel.FeatureDefinition;
+ var description = LazyManStripXml(featureDefinition.FormatDescription());
+
+ outString.AppendLine($"* {featureDefinition.FormatTitle()}");
+ outString.AppendLine();
+ outString.AppendLine(description);
+ outString.AppendLine();
+ }
+ }
+
private static void DumpClasses(string groupName, Func filter)
{
var outString = new StringBuilder();
@@ -125,28 +151,7 @@ private static void DumpClasses(string groupName, Func fil
outString.AppendLine(LazyManStripXml(klass.FormatDescription()));
outString.AppendLine();
- var level = 0;
-
- foreach (var featureUnlockByLevel in klass.FeatureUnlocks
- .Where(x => !x.FeatureDefinition.GuiPresentation.hidden)
- .OrderBy(x => x.level))
- {
- if (level != featureUnlockByLevel.level)
- {
- outString.AppendLine();
- outString.AppendLine($"## Level {featureUnlockByLevel.level}");
- outString.AppendLine();
- level = featureUnlockByLevel.level;
- }
-
- var featureDefinition = featureUnlockByLevel.FeatureDefinition;
- var description = LazyManStripXml(featureDefinition.FormatDescription());
-
- outString.AppendLine($"* {featureDefinition.FormatTitle()}");
- outString.AppendLine();
- outString.AppendLine(description);
- outString.AppendLine();
- }
+ DumpFeatureUnlockByLevel(outString, klass.FeatureUnlocks);
outString.AppendLine();
outString.AppendLine();
@@ -235,28 +240,7 @@ private static void DumpSubclasses(
outString.AppendLine(LazyManStripXml(subclass.FormatDescription()));
outString.AppendLine();
- var level = 0;
-
- foreach (var featureUnlockByLevel in subclass.FeatureUnlocks
- .Where(x => !x.FeatureDefinition.GuiPresentation.hidden)
- .OrderBy(x => x.level))
- {
- if (level != featureUnlockByLevel.level)
- {
- outString.AppendLine();
- outString.AppendLine($"### Level {featureUnlockByLevel.level}");
- outString.AppendLine();
- level = featureUnlockByLevel.level;
- }
-
- var featureDefinition = featureUnlockByLevel.FeatureDefinition;
- var description = LazyManStripXml(featureDefinition.FormatDescription());
-
- outString.AppendLine($"* {featureDefinition.FormatTitle()}");
- outString.AppendLine();
- outString.AppendLine(description);
- outString.AppendLine();
- }
+ DumpFeatureUnlockByLevel(outString, subclass.FeatureUnlocks);
outString.AppendLine();
outString.AppendLine();
@@ -287,28 +271,7 @@ private static void DumpRaces(string groupName, Func filte
outString.AppendLine(LazyManStripXml(race.FormatDescription()));
outString.AppendLine();
- var level = 0;
-
- foreach (var featureUnlockByLevel in race.FeatureUnlocks
- .Where(x => !x.FeatureDefinition.GuiPresentation.hidden)
- .OrderBy(x => x.level))
- {
- if (level != featureUnlockByLevel.level)
- {
- outString.AppendLine();
- outString.AppendLine($"## Level {featureUnlockByLevel.level}");
- outString.AppendLine();
- level = featureUnlockByLevel.level;
- }
-
- var featureDefinition = featureUnlockByLevel.FeatureDefinition;
- var description = LazyManStripXml(featureDefinition.FormatDescription());
-
- outString.AppendLine($"* {featureDefinition.FormatTitle()}");
- outString.AppendLine();
- outString.AppendLine(description);
- outString.AppendLine();
- }
+ DumpFeatureUnlockByLevel(outString, race.FeatureUnlocks);
outString.AppendLine();
outString.AppendLine();
@@ -318,6 +281,36 @@ private static void DumpRaces(string groupName, Func filte
sw.WriteLine(outString.ToString());
}
+ private static readonly Dictionary SpellListClassMap =
+ new()
+ {
+ { InventorClass.SpellList, InventorClass.Class },
+ { SpellListBard, Bard },
+ { SpellListCleric, Cleric },
+ { SpellListDruid, Druid },
+ { SpellListPaladin, Paladin },
+ { SpellListRanger, Ranger },
+ { SpellListSorcerer, Sorcerer },
+ { SpellListWarlock, Warlock },
+ { SpellListWizard, Wizard }
+ };
+
+ private static string GetClassesWhichCanCastSpell(SpellDefinition spell)
+ {
+ var result = SpellListClassMap
+ .OrderBy(kvp => kvp.Value.FormatTitle())
+ .Where(kvp =>
+ kvp.Key.SpellsByLevel
+ .SelectMany(x => x.Spells)
+ .Contains(spell) ||
+ SpellsContext.SpellListContextTab[kvp.Key].SuggestedSpells.Contains(spell))
+ .Aggregate(string.Empty, (current, kvp) => current + kvp.Value.FormatTitle() + ", ");
+
+ return result == string.Empty
+ ? string.Empty
+ : "**[" + result.Substring(0, result.Length - 2) + "]**" + Environment.NewLine;
+ }
+
private static void DumpOthers(string groupName, Func filter) where T : BaseDefinition
{
var outString = new StringBuilder();
@@ -367,6 +360,8 @@ x is SpellDefinition spellDefinition
{
title += " [" + Gui.Format("Tooltip/&TagConcentrationTitle") + "]";
}
+
+ description = GetClassesWhichCanCastSpell(spellDefinition) + Environment.NewLine + description;
}
outString.AppendLine($"# {counter++}. - {title} {GetTag(featureDefinition)}");
@@ -399,8 +394,7 @@ private static string GetMonsterBlock([NotNull] MonsterDefinition monsterDefinit
{
var outString = new StringBuilder();
- outString.AppendLine(
- $"# {counter++}. - {monsterDefinition.FormatTitle()}");
+ outString.AppendLine($"# {counter++}. - {monsterDefinition.FormatTitle()}");
outString.AppendLine();
var description = LazyManStripXml(monsterDefinition.FormatDescription());
diff --git a/SolastaUnfinishedBusiness/Models/EncounterSpawnContext.cs b/SolastaUnfinishedBusiness/Models/EncounterSpawnContext.cs
index c72688d017..2b0a9f0478 100644
--- a/SolastaUnfinishedBusiness/Models/EncounterSpawnContext.cs
+++ b/SolastaUnfinishedBusiness/Models/EncounterSpawnContext.cs
@@ -114,21 +114,28 @@ internal static void ConfirmStageEncounter()
null,
null);
}
- else if (Gui.GameLocation &&
- Gui.GameLocation.LocationDefinition &&
- Gui.GameLocation.LocationDefinition.IsUserLocation)
+
+ if (!Gui.GameLocation)
{
- var position = GetEncounterPosition();
+ return;
+ }
- Gui.GuiService.ShowMessage(
- MessageModal.Severity.Attention2,
- "Message/&SpawnCustomEncounterTitle",
- Gui.Format("Message/&SpawnCustomEncounterDescription", position.x.ToString(),
- position.x.ToString()),
- "Message/&MessageYesTitle", "Message/&MessageNoTitle",
- () => StageEncounter(position),
- null);
+ if (!Gui.GameLocation.LocationDefinition ||
+ !Gui.GameLocation.LocationDefinition.IsUserLocation)
+ {
+ return;
}
+
+ var position = GetEncounterPosition();
+
+ Gui.GuiService.ShowMessage(
+ MessageModal.Severity.Attention2,
+ "Message/&SpawnCustomEncounterTitle",
+ Gui.Format("Message/&SpawnCustomEncounterDescription", position.x.ToString(),
+ position.x.ToString()),
+ "Message/&MessageYesTitle", "Message/&MessageNoTitle",
+ () => StageEncounter(position),
+ null);
}
private static int3 GetEncounterPosition()
@@ -168,9 +175,7 @@ private static void StageEncounter(int3 position)
GameLocationBehaviourPackage.BattleStartBehaviorType.DoNotRaiseAlarm,
DecisionPackageDefinition = IdleGuard_Default,
EncounterId = EncounterId++,
- FormationDefinition = EncounterCharacters.Count > 1
- ? DatabaseHelper.FormationDefinitions.Squad4
- : DatabaseHelper.FormationDefinitions.SingleCreature
+ FormationDefinition = DatabaseHelper.FormationDefinitions.Column2
})))
{
gameLocationCharacter.CollectExistingLightSources(true);
diff --git a/SolastaUnfinishedBusiness/Models/FixesContext.cs b/SolastaUnfinishedBusiness/Models/FixesContext.cs
index 8db3278ba8..25e05a0746 100644
--- a/SolastaUnfinishedBusiness/Models/FixesContext.cs
+++ b/SolastaUnfinishedBusiness/Models/FixesContext.cs
@@ -12,6 +12,7 @@
using SolastaUnfinishedBusiness.Interfaces;
using SolastaUnfinishedBusiness.Subclasses;
using SolastaUnfinishedBusiness.Validators;
+using TA.AI;
using UnityEngine;
using static AttributeDefinitions;
using static EquipmentDefinitions;
@@ -39,6 +40,9 @@ namespace SolastaUnfinishedBusiness.Models;
internal static class FixesContext
{
+ internal static readonly DecisionDefinition DecisionMoveAfraid =
+ DatabaseRepository.GetDatabase().GetElement("Move_Afraid");
+
internal static void Load()
{
InitMagicAffinitiesAndCastSpells();
@@ -47,6 +51,12 @@ internal static void Load()
internal static void LateLoad()
{
+ // fix demonic influence duration and combat log (conditions with ForcedBehavior should have special duration)
+ ConditionDefinitions.ConditionUnderDemonicInfluence.specialDuration = true;
+ ConditionDefinitions.ConditionUnderDemonicInfluence.durationType = DurationType.Hour;
+ ConditionDefinitions.ConditionUnderDemonicInfluence.durationParameter = 1;
+ ConditionDefinitions.ConditionUnderDemonicInfluence.possessive = true;
+
AddAdditionalActionTitles();
ExtendCharmImmunityToDemonicInfluence();
FixAdditionalDamageRestrictions();
@@ -56,6 +66,7 @@ internal static void LateLoad()
FixBlackDragonLegendaryActions();
FixColorTables();
FixCriticalThresholdModifiers();
+ FixDecisionMoveAfraid();
FixDivineBlade();
FixDragonBreathPowerSavingAttribute();
FixEagerForBattleTexts();
@@ -63,6 +74,7 @@ internal static void LateLoad()
FixGorillaWildShapeRocksToUnlimited();
FixLanguagesPointPoolsToIncludeAllLanguages();
FixMartialArtsProgression();
+ FixMartialCommanderCoordinatedDefense();
FixMountaineerBonusShoveRestrictions();
FixMummyDreadfulGlareSavingAttribute();
FixPowerDragonbornBreathWeaponDiceProgression();
@@ -76,6 +88,7 @@ internal static void LateLoad()
FixTwinnedMetamagic();
FixUncannyDodgeForRoguishDuelist();
FixPaladinAurasDisplayOnActionBar();
+ ReportDashing();
// fix Dazzled attribute modifier UI previously displaying Daaaaal on attribute modifier
AttributeModifierDazzled.GuiPresentation.title = "Feature/&AttributeModifierDazzledTitle";
@@ -318,7 +331,6 @@ private static void FixAdditionalDamageRestrictions()
));
AdditionalDamageBrandingSmite.attackModeOnly = true;
- AdditionalDamageBrandingSmite.requiredProperty = RestrictedContextRequiredProperty.MeleeWeapon;
AdditionalDamageRangerSwiftBladeBattleFocus.attackModeOnly = true;
AdditionalDamageRangerSwiftBladeBattleFocus.requiredProperty = RestrictedContextRequiredProperty.MeleeWeapon;
@@ -343,6 +355,12 @@ private static void FixColorTables()
}
}
+ private static void FixDecisionMoveAfraid()
+ {
+ //BUGFIX: allow actors to move a bit far on move_afraid by lowering consideration weight a bit
+ DecisionMoveAfraid.Decision.scorer.Scorer.WeightedConsiderations[3].weight = 0.95f;
+ }
+
private static void FixDivineBlade()
{
//BUGFIX: allows clerics to actually wield divine blade
@@ -405,6 +423,12 @@ private static void FixMartialArtsProgression()
}
}
+ private static void FixMartialCommanderCoordinatedDefense()
+ {
+ ActionAffinityMartialCommanderCoordinatedDefense.AddCustomSubFeatures(
+ new ValidateDefinitionApplication(ValidatorsCharacter.HasAttacked));
+ }
+
private static void FixMinorMagicEffectsIssues()
{
// fix issues with bad targeting
@@ -628,13 +652,38 @@ private static void FixPaladinAurasDisplayOnActionBar()
{
foreach (var power in DatabaseRepository.GetDatabase()
.Where(x =>
- x.ActivationTime == ActivationTime.PermanentUnlessIncapacitated &&
- (x.Name.StartsWith("PowerOath") || x.Name.StartsWith("PowerPaladin"))))
+ x.ActivationTime is ActivationTime.Permanent or ActivationTime.PermanentUnlessIncapacitated &&
+ (x.Name.StartsWith("PowerDomain") ||
+ x.Name.StartsWith("PowerOath") ||
+ x.Name.StartsWith("PowerPaladin"))))
{
power.AddCustomSubFeatures(ModifyPowerVisibility.Hidden);
}
}
+ private static void ReportDashing()
+ {
+ Report(ConditionDefinitions.ConditionDashing);
+ Report(ConditionDefinitions.ConditionDashingAdditional);
+ Report(ConditionDefinitions.ConditionDashingAdditionalSwiftBlade);
+ Report(ConditionDefinitions.ConditionDashingBonus);
+ Report(ConditionDefinitions.ConditionDashingBonusAdditional);
+ Report(ConditionDefinitions.ConditionDashingBonusStepOfTheWind);
+ Report(ConditionDefinitions.ConditionDashingBonusSwiftBlade);
+ Report(ConditionDefinitions.ConditionDashingBonusSwiftSteps);
+ Report(ConditionDefinitions.ConditionDashingExpeditiousRetreat);
+ Report(ConditionDefinitions.ConditionDashingExpeditiousRetreatSwiftBlade);
+ Report(ConditionDefinitions.ConditionDashingSwiftBlade);
+ return;
+
+ static void Report(ConditionDefinition condition)
+ {
+ condition.GuiPresentation.Title = "Screen/&DashModeTitle";
+ condition.GuiPresentation.hidden = false;
+ condition.silentWhenAdded = false;
+ }
+ }
+
private static void FixAdditionalDamageRogueSneakAttack()
{
AdditionalDamageRogueSneakAttack.AddCustomSubFeatures(
@@ -744,7 +793,7 @@ public IEnumerator OnPhysicalAttackFinishedByMe(
yield break;
}
- attacker.MyExecuteActionPowerNoCost(usablePower, defender);
+ attacker.MyExecuteActionSpendPower(usablePower, defender);
}
public IEnumerator OnPowerOrSpellFinishedByMe(CharacterActionMagicEffect action, BaseDefinition baseDefinition)
diff --git a/SolastaUnfinishedBusiness/Models/Level20SubclassesContext.cs b/SolastaUnfinishedBusiness/Models/Level20SubclassesContext.cs
index e89bb7ed2c..750ce83d3a 100644
--- a/SolastaUnfinishedBusiness/Models/Level20SubclassesContext.cs
+++ b/SolastaUnfinishedBusiness/Models/Level20SubclassesContext.cs
@@ -832,7 +832,7 @@ private static void PaladinLoad()
.SetFeatures(savingThrowAffinityOathOfDevotionHolyNimbus)
.AddToDB();
- var lightSourceForm = FaerieFire.EffectDescription.GetFirstFormOfType(EffectForm.EffectFormType.LightSource);
+ var lightSourceForm = Light.EffectDescription.GetFirstFormOfType(EffectForm.EffectFormType.LightSource);
var powerOathOfDevotionHolyNimbus = FeatureDefinitionPowerBuilder
.Create("PowerOathOfDevotionHolyNimbus")
@@ -840,7 +840,7 @@ private static void PaladinLoad()
.SetUsesFixed(ActivationTime.Action, RechargeRate.LongRest)
.SetEffectDescription(
EffectDescriptionBuilder
- .Create()
+ .Create(Light)
.SetDurationData(DurationType.Minute, 1)
.SetTargetingData(Side.Enemy, RangeType.Self, 0, TargetType.Sphere, 6)
.SetRecurrentEffect(
@@ -1514,8 +1514,7 @@ public IEnumerator OnPowerOrSpellFinishedByMe(CharacterActionMagicEffect action,
var rulesetCharacter = actingCharacter.RulesetCharacter;
var usablePower = PowerProvider.Get(powerFortuneFavorTheBold, rulesetCharacter);
- //TODO: check if MyExecuteActionSpendPower works here
- actingCharacter.MyExecuteActionPowerNoCost(usablePower, actingCharacter);
+ actingCharacter.MyExecuteActionSpendPower(usablePower, actingCharacter);
yield break;
}
@@ -1651,8 +1650,8 @@ public IEnumerator HandleReducedToZeroHpByMeOrAlly(
private sealed class ModifySavingThrowHolyNimbus(FeatureDefinition featureDefinition) : IRollSavingThrowInitiated
{
public void OnSavingThrowInitiated(
- RulesetCharacter caster,
- RulesetCharacter defender,
+ RulesetActor rulesetActorCaster,
+ RulesetActor rulesetActorDefender,
ref int saveBonus,
ref string abilityScoreName,
BaseDefinition sourceDefinition,
@@ -1665,8 +1664,8 @@ public void OnSavingThrowInitiated(
int outcomeDelta,
List effectForms)
{
- if (abilityScoreName == AttributeDefinitions.Wisdom
- && caster is RulesetCharacterMonster { CharacterFamily: "Fiend" or "Undead" })
+ if (abilityScoreName == AttributeDefinitions.Wisdom &&
+ rulesetActorCaster is RulesetCharacterMonster { CharacterFamily: "Fiend" or "Undead" })
{
advantageTrends.Add(
new TrendInfo(1, FeatureSourceType.CharacterFeature, featureDefinition.Name, featureDefinition));
@@ -1753,8 +1752,8 @@ private sealed class RollSavingThrowFinishedManaOverflow(FeatureDefinition featu
: IRollSavingThrowFinished
{
public void OnSavingThrowFinished(
- RulesetCharacter caster,
- RulesetCharacter defender,
+ RulesetActor rulesetActorCaster,
+ RulesetActor rulesetActorDefender,
int saveBonus,
string abilityScoreName,
BaseDefinition sourceDefinition,
@@ -1767,10 +1766,15 @@ public void OnSavingThrowFinished(
ref int outcomeDelta,
List effectForms)
{
- var hero = defender.GetOriginalHero();
+ if (outcome != RollOutcome.Success ||
+ rulesetActorDefender is not RulesetCharacter rulesetCharacter)
+ {
+ return;
+ }
+
+ var hero = rulesetCharacter.GetOriginalHero();
- if (outcome is not (RollOutcome.Success or RollOutcome.CriticalSuccess) ||
- hero == null)
+ if (hero == null)
{
return;
}
diff --git a/SolastaUnfinishedBusiness/Models/LightingAndObscurementContext.cs b/SolastaUnfinishedBusiness/Models/LightingAndObscurementContext.cs
index cb63f7e36c..ff7985ee3b 100644
--- a/SolastaUnfinishedBusiness/Models/LightingAndObscurementContext.cs
+++ b/SolastaUnfinishedBusiness/Models/LightingAndObscurementContext.cs
@@ -234,9 +234,10 @@ private static bool IsBlindNotFromDarkness(RulesetActor actor)
{
return
actor != null &&
- actor.AllConditions
+ actor.ConditionsByCategory
+ .SelectMany(x => x.Value)
.Select(y => y.ConditionDefinition)
- .Any(x => x.IsSubtypeOf(ConditionBlinded.Name) && x != ConditionBlindedByDarkness);
+ .Any(z => z.IsSubtypeOf(ConditionBlinded.Name) && z != ConditionBlindedByDarkness);
}
// improved cell perception routine that takes sight into consideration
diff --git a/SolastaUnfinishedBusiness/Models/PortraitsContext.cs b/SolastaUnfinishedBusiness/Models/PortraitsContext.cs
index dbef1ccb94..bc8634b198 100644
--- a/SolastaUnfinishedBusiness/Models/PortraitsContext.cs
+++ b/SolastaUnfinishedBusiness/Models/PortraitsContext.cs
@@ -17,27 +17,12 @@ public static class PortraitsContext
private static readonly string PersonalFolder = $"{PortraitsFolder}/Personal";
private static readonly string MonstersFolder = $"{PortraitsFolder}/Monsters";
- internal static void Load()
+ internal static void EnsureFolderExists()
{
- if (!Directory.Exists(PortraitsFolder))
- {
- Directory.CreateDirectory(PortraitsFolder);
- }
-
- if (!Directory.Exists(PreGenFolder))
- {
- Directory.CreateDirectory(PreGenFolder);
- }
-
- if (!Directory.Exists(PersonalFolder))
- {
- Directory.CreateDirectory(PersonalFolder);
- }
-
- if (!Directory.Exists(MonstersFolder))
- {
- Directory.CreateDirectory(MonstersFolder);
- }
+ Main.EnsureFolderExists(PortraitsFolder);
+ Main.EnsureFolderExists(PreGenFolder);
+ Main.EnsureFolderExists(PersonalFolder);
+ Main.EnsureFolderExists(MonstersFolder);
}
internal static bool HasCustomPortrait(RulesetCharacter rulesetCharacter)
diff --git a/SolastaUnfinishedBusiness/Models/SaveByLocationContext.cs b/SolastaUnfinishedBusiness/Models/SaveByLocationContext.cs
index 9fcd4f53a7..b0a149c318 100644
--- a/SolastaUnfinishedBusiness/Models/SaveByLocationContext.cs
+++ b/SolastaUnfinishedBusiness/Models/SaveByLocationContext.cs
@@ -17,6 +17,7 @@ internal static class SaveByLocationContext
private const string LocationSaveFolder = @"CE\Location";
private const string CampaignSaveFolder = @"CE\Campaign";
private const string OfficialSaveFolder = @"CE\Official";
+ private const string DefaultName = "Default";
internal static readonly string DefaultSaveGameDirectory =
Path.Combine(TacticalAdventuresApplication.GameDirectory, "Saves");
@@ -30,132 +31,53 @@ internal static class SaveByLocationContext
private static readonly string OfficialSaveGameDirectory =
Path.Combine(DefaultSaveGameDirectory, OfficialSaveFolder);
- private static List _allOfficialCampaigns;
- private static List _allUserLocations;
- private static List _allUserCampaigns;
-
internal static CustomDropDown Dropdown { get; private set; }
- internal static bool UseLightEnumeration { get; private set; }
-
- private static IEnumerable AllOfficialCampaigns
+ internal static void EnsureFoldersExist()
{
- get
- {
- if (_allOfficialCampaigns != null)
- {
- return _allOfficialCampaigns;
- }
-
- _allOfficialCampaigns = [];
-
- var allElements = DatabaseRepository.GetDatabase().GetAllElements();
-
- foreach (var campaign in allElements)
- {
- if (campaign.GuiPresentation.Hidden || campaign.IsUserCampaign || campaign.EditorOnly)
- {
- continue;
- }
-
- _allOfficialCampaigns.Add(campaign);
- }
-
- return _allOfficialCampaigns;
- }
+ Main.EnsureFolderExists(OfficialSaveGameDirectory);
+ Main.EnsureFolderExists(LocationSaveGameDirectory);
+ Main.EnsureFolderExists(CampaignSaveGameDirectory);
}
- private static IEnumerable AllUserLocations
+ private static List GetAllSavePlaces()
{
- get
- {
- if (_allUserLocations != null)
- {
- return _allUserLocations;
- }
-
- var userLocationPoolService =
- (UserLocationPoolManager)ServiceRepository.GetService();
-
- if (!userLocationPoolService.Enumerated)
- {
- UseLightEnumeration = true;
- userLocationPoolService.EnumeratePool(out _, []);
- userLocationPoolService.enumerated = false;
- UseLightEnumeration = false;
- }
-
- _allUserLocations = userLocationPoolService.AllLocations;
-
- return _allUserLocations;
- }
+ // Find the most recently touched save file and select the correct location/campaign for that save
+ return EnumerateDirectories(LocationSaveGameDirectory, LocationType.UserLocation)
+ .Concat(EnumerateDirectories(CampaignSaveGameDirectory, LocationType.CustomCampaign))
+ .Concat(EnumerateDirectories(OfficialSaveGameDirectory, LocationType.StandardCampaign))
+ .Append(MostRecentFile(DefaultSaveGameDirectory, LocationType.Default))
+ .Where(d => d.Available)
+ .ToList();
}
- private static IEnumerable AllUserCampaigns
+ internal static SavePlace GetMostRecentPlace()
{
- get
- {
- if (_allUserCampaigns != null)
- {
- return _allUserCampaigns;
- }
-
- var userCampaignPoolService =
- (UserCampaignPoolManager)ServiceRepository.GetService();
-
- if (!userCampaignPoolService.Enumerated)
- {
- UseLightEnumeration = true;
- userCampaignPoolService.EnumeratePool(out _, []);
- userCampaignPoolService.enumerated = false;
- UseLightEnumeration = false;
- }
-
- _allUserCampaigns = userCampaignPoolService.AllCampaigns;
+ return GetAllSavePlaces()
+ .Where(d => d.Date.HasValue)
+ .OrderByDescending(d => d.Date.Value)
+ .FirstOrDefault()
+ ?? SavePlace.Default();
+ }
- return _allUserCampaigns;
- }
+ private static IEnumerable EnumerateDirectories(string where, LocationType type)
+ {
+ return Directory.EnumerateDirectories(where)
+ .Select(dir => MostRecentFile(dir, type));
}
- internal static (string, LocationType) GetMostRecent()
+ private static SavePlace MostRecentFile(string dir, LocationType type)
{
- // Find the most recently touched save file and select the correct location/campaign for that save
- var mostRecent = Directory.EnumerateDirectories(LocationSaveGameDirectory)
- .Select(d =>
- (
- d,
- Directory.EnumerateFiles(d, "*.sav").Max(f => (DateTime?)File.GetLastWriteTimeUtc(f)),
- LocationType.UserLocation
- ))
- .Concat(
- Directory.EnumerateDirectories(CampaignSaveGameDirectory)
- .Select(d =>
- (
- d,
- Directory.EnumerateFiles(d, "*.sav").Max(f => (DateTime?)File.GetLastWriteTimeUtc(f)),
- LocationType.CustomCampaign
- ))
- .Concat(
- Directory.EnumerateDirectories(OfficialSaveGameDirectory)
- .Select(d =>
- (
- d,
- Directory.EnumerateFiles(d, "*.sav").Max(f => (DateTime?)File.GetLastWriteTimeUtc(f)),
- LocationType.StandardCampaign
- ))
- .Concat(
- Enumerable.Repeat(
- (
- DefaultSaveGameDirectory,
- Directory.EnumerateFiles(DefaultSaveGameDirectory, "*.sav")
- .Max(f => (DateTime?)File.GetLastWriteTimeUtc(f)),
- LocationType.Default
- ), 1))))
- .Where(d => d.Item2.HasValue)
- .OrderByDescending(d => d.Item2)
- .FirstOrDefault();
-
- return (mostRecent.Item1 ?? DefaultSaveGameDirectory, mostRecent.Item3);
+ var files = Directory.EnumerateFiles(dir, "*.sav").ToList();
+ var place = new SavePlace
+ {
+ Name = type == LocationType.Default ? DefaultName : Path.GetFileName(dir),
+ Path = dir,
+ Count = files.Count,
+ Date = files.Max(f => (DateTime?)File.GetLastWriteTimeUtc(f)),
+ Type = type
+ };
+ return place;
}
internal static void LateLoad()
@@ -165,52 +87,11 @@ internal static void LateLoad()
return;
}
- // Ensure folders exist
- Directory.CreateDirectory(OfficialSaveGameDirectory);
- Directory.CreateDirectory(LocationSaveGameDirectory);
- Directory.CreateDirectory(CampaignSaveGameDirectory);
-
// Find the most recently touched save file and select the correct location/campaign for that save
- var (path, locationType) = GetMostRecent();
+ var place = GetMostRecentPlace();
ServiceRepositoryEx.GetOrCreateService()
- .SetCampaignLocation(locationType, Path.GetFileName(path));
- }
-
- private static int SaveFileCount(LocationType locationType, string folder)
- {
- switch (locationType)
- {
- case LocationType.UserLocation:
- {
- var saveFolder = Path.Combine(LocationSaveGameDirectory, folder);
-
- return Directory.Exists(saveFolder) ? Directory.EnumerateFiles(saveFolder, "*.sav").Count() : 0;
- }
- case LocationType.CustomCampaign:
- {
- var saveFolder = Path.Combine(CampaignSaveGameDirectory, folder);
-
- return Directory.Exists(saveFolder) ? Directory.EnumerateFiles(saveFolder, "*.sav").Count() : 0;
- }
- case LocationType.StandardCampaign:
- {
- var saveFolder = Path.Combine(OfficialSaveGameDirectory, folder);
-
- return Directory.Exists(saveFolder) ? Directory.EnumerateFiles(saveFolder, "*.sav").Count() : 0;
- }
- case LocationType.Default:
- {
- var saveFolder = DefaultSaveGameDirectory;
-
- return Directory.Exists(saveFolder) ? Directory.EnumerateFiles(saveFolder, "*.sav").Count() : 0;
- }
- default:
- Main.Error($"Unknown LocationType: {locationType}");
- break;
- }
-
- return 0;
+ .SetCampaignLocation(place.Type, place.Name);
}
internal static void LoadPanelOnBeginShowSaveByLocationBehavior(LoadPanel panel)
@@ -224,42 +105,11 @@ internal static void LoadPanelOnBeginShowSaveByLocationBehavior(LoadPanel panel)
// populate the dropdown
guiDropdown.ClearOptions();
-
- var officialCampaigns = AllOfficialCampaigns
- .Select(c => new
- {
- LocationType = LocationType.StandardCampaign, Title = Gui.Localize(c.GuiPresentation.Title)
- })
- .OrderBy(c => c.Title)
- .ToList();
-
- // add them together - each block sorted - can we have separators?
- var userContentList =
- AllUserCampaigns
- .Select(l => new { LocationType = LocationType.CustomCampaign, l.Title })
- .OrderBy(l => l.Title)
- .Concat(AllUserLocations
- .Select(l => new { LocationType = LocationType.UserLocation, l.Title })
- .OrderBy(l => l.Title))
- .ToList();
-
guiDropdown.AddOptions(
- Enumerable.Repeat(new { LocationType = LocationType.Default, Title = "Default" }, 1)
- .Union(officialCampaigns)
- .Union(userContentList)
- .Select(opt => new
- {
- opt.LocationType, opt.Title, SaveFileCount = SaveFileCount(opt.LocationType, opt.Title)
- })
- .Select(opt => new LocationOptionData
- {
- LocationType = opt.LocationType,
- text = GetTitle(opt.LocationType, opt.Title),
- CampaignOrLocation = opt.Title,
- TooltipContent = $"{opt.SaveFileCount} save{(opt.SaveFileCount == 1 ? "" : "s")}",
- ShowInDropdown = opt.SaveFileCount > 0 || opt.LocationType is LocationType.Default
- })
- .Where(opt => opt.ShowInDropdown) // Only show locations that have saves
+ GetAllSavePlaces()
+ .Where(p => p.Available)
+ .OrderBy(p => p)
+ .Select(LocationOptionData.Create)
.Cast()
.ToList());
@@ -271,7 +121,7 @@ internal static void LoadPanelOnBeginShowSaveByLocationBehavior(LoadPanel panel)
var option = guiDropdown.Options
.Cast()
- .Select((o, i) => new { o.CampaignOrLocation, o.LocationType, Index = i })
+ .Select((o, i) => new { CampaignOrLocation = o.Title, o.LocationType, Index = i })
.Where(opt => opt.LocationType == selectedCampaign.LocationType)
.FirstOrDefault(o => o.CampaignOrLocation == selectedCampaign.CampaignOrLocationName);
@@ -295,24 +145,6 @@ internal static void LoadPanelOnBeginShowSaveByLocationBehavior(LoadPanel panel)
return;
- string GetTitle(LocationType locationType, string title)
- {
- switch (locationType)
- {
- default:
- Main.Error($"Unknown LocationType: {locationType}");
- return title.Red();
- case LocationType.Default:
- return title;
- case LocationType.StandardCampaign:
- return title;
- case LocationType.CustomCampaign:
- return title.Khaki();
- case LocationType.UserLocation:
- return title.Orange();
- }
- }
-
void ValueChanged([NotNull] TMP_Dropdown.OptionData selected)
{
// update selected campaign
@@ -325,7 +157,7 @@ void ValueChanged([NotNull] TMP_Dropdown.OptionData selected)
// ReSharper disable once InvocationIsSkipped
Main.Log(
- $"ValueChanged: selected={locationData.LocationType}, {locationData.text}, {locationData.CampaignOrLocation}");
+ $"ValueChanged: selected={locationData.LocationType}, {locationData.text}, {locationData.Title}");
selectedCampaignService.SetCampaignLocation(locationData);
@@ -379,9 +211,37 @@ CustomDropDown CreateOrActivateDropdown()
internal sealed class LocationOptionData : GuiDropdown.OptionDataAdvanced
{
- internal string CampaignOrLocation { get; set; }
- internal LocationType LocationType { get; set; }
- internal bool ShowInDropdown { get; set; }
+ internal string Title { get; private set; }
+ internal LocationType LocationType { get; private set; }
+
+ internal static LocationOptionData Create(SavePlace place)
+ {
+ return new LocationOptionData
+ {
+ LocationType = place.Type,
+ text = GetTitle(place.Type, place.Name),
+ Title = place.Name,
+ TooltipContent = $"{place.Count} save{(place.Count == 1 ? "" : "s")}"
+ };
+ }
+
+ private static string GetTitle(LocationType locationType, string title)
+ {
+ switch (locationType)
+ {
+ case LocationType.Default:
+ return title;
+ case LocationType.StandardCampaign:
+ return title;
+ case LocationType.CustomCampaign:
+ return title.Khaki();
+ case LocationType.UserLocation:
+ return title.Orange();
+ default:
+ Main.Error($"Unknown LocationType: {locationType}");
+ return title.Red();
+ }
+ }
}
internal static class ServiceRepositoryEx
@@ -403,23 +263,15 @@ internal static class ServiceRepositoryEx
}
}
- private interface ISelectedCampaignService : IService
- {
- // string CampaignOrLocationName { get; }
- // LocationType LocationType { get; }
- // string SaveGameDirectory { get; }
- // void SetCampaignLocation(string campaign, string location);
- }
-
internal enum LocationType
{
Default,
StandardCampaign,
- UserLocation,
- CustomCampaign
+ CustomCampaign,
+ UserLocation
}
- internal sealed class SelectedCampaignService : ISelectedCampaignService
+ internal sealed class SelectedCampaignService : IService
{
internal string CampaignOrLocationName { get; private set; }
internal string SaveGameDirectory { get; private set; }
@@ -427,7 +279,7 @@ internal sealed class SelectedCampaignService : ISelectedCampaignService
internal void SetCampaignLocation([NotNull] LocationOptionData selected)
{
- SetCampaignLocation(selected.LocationType, selected.CampaignOrLocation);
+ SetCampaignLocation(selected.LocationType, selected.Title);
}
internal void SetCampaignLocation(LocationType type, string name)
@@ -452,4 +304,33 @@ internal void SetCampaignLocation(LocationType type, string name)
$"SelectedCampaignService: Type='{LocationType}', Name='{CampaignOrLocationName}', Folder='{SaveGameDirectory}'");
}
}
+
+ internal class SavePlace : IComparable
+ {
+ public int Count;
+ public DateTime? Date;
+ public string Name;
+ public string Path;
+ public LocationType Type;
+
+ public bool Available => Count > 0 || Type is LocationType.Default;
+
+ public int CompareTo(SavePlace other)
+ {
+ if (other == null) { return -1; }
+
+ var type = Type.CompareTo(other.Type);
+ return type != 0
+ ? type
+ : String.Compare(Name, other.Name, StringComparison.Ordinal);
+ }
+
+ public static SavePlace Default()
+ {
+ return new SavePlace
+ {
+ Path = DefaultSaveGameDirectory, Count = 0, Date = null, Type = LocationType.Default
+ };
+ }
+ }
}
diff --git a/SolastaUnfinishedBusiness/Models/SharedSpellsContext.cs b/SolastaUnfinishedBusiness/Models/SharedSpellsContext.cs
index 8a35707d91..259c105d18 100644
--- a/SolastaUnfinishedBusiness/Models/SharedSpellsContext.cs
+++ b/SolastaUnfinishedBusiness/Models/SharedSpellsContext.cs
@@ -351,80 +351,80 @@ internal int GetCasterLevel()
internal static readonly List InitiateCastingSlots =
[
- new SlotsByLevelDuplet { Slots = [1], Level = 01 },
- new SlotsByLevelDuplet { Slots = [1], Level = 02 },
- new SlotsByLevelDuplet { Slots = [1], Level = 03 },
- new SlotsByLevelDuplet { Slots = [1], Level = 04 },
- new SlotsByLevelDuplet { Slots = [1], Level = 05 },
- new SlotsByLevelDuplet { Slots = [1], Level = 06 },
- new SlotsByLevelDuplet { Slots = [1], Level = 07 },
- new SlotsByLevelDuplet { Slots = [1], Level = 08 },
- new SlotsByLevelDuplet { Slots = [1], Level = 09 },
- new SlotsByLevelDuplet { Slots = [1], Level = 10 },
- new SlotsByLevelDuplet { Slots = [1], Level = 11 },
- new SlotsByLevelDuplet { Slots = [1], Level = 12 },
- new SlotsByLevelDuplet { Slots = [1], Level = 13 },
- new SlotsByLevelDuplet { Slots = [1], Level = 14 },
- new SlotsByLevelDuplet { Slots = [1], Level = 15 },
- new SlotsByLevelDuplet { Slots = [1], Level = 16 },
- new SlotsByLevelDuplet { Slots = [1], Level = 17 },
- new SlotsByLevelDuplet { Slots = [1], Level = 18 },
- new SlotsByLevelDuplet { Slots = [1], Level = 19 },
- new SlotsByLevelDuplet { Slots = [1], Level = 20 }
+ new() { Slots = [1], Level = 01 },
+ new() { Slots = [1], Level = 02 },
+ new() { Slots = [1], Level = 03 },
+ new() { Slots = [1], Level = 04 },
+ new() { Slots = [1], Level = 05 },
+ new() { Slots = [1], Level = 06 },
+ new() { Slots = [1], Level = 07 },
+ new() { Slots = [1], Level = 08 },
+ new() { Slots = [1], Level = 09 },
+ new() { Slots = [1], Level = 10 },
+ new() { Slots = [1], Level = 11 },
+ new() { Slots = [1], Level = 12 },
+ new() { Slots = [1], Level = 13 },
+ new() { Slots = [1], Level = 14 },
+ new() { Slots = [1], Level = 15 },
+ new() { Slots = [1], Level = 16 },
+ new() { Slots = [1], Level = 17 },
+ new() { Slots = [1], Level = 18 },
+ new() { Slots = [1], Level = 19 },
+ new() { Slots = [1], Level = 20 }
];
internal static readonly List RaceCastingSlots =
[
- new SlotsByLevelDuplet { Slots = [0, 0], Level = 01 },
- new SlotsByLevelDuplet { Slots = [0, 0], Level = 02 },
- new SlotsByLevelDuplet { Slots = [1, 0], Level = 03 },
- new SlotsByLevelDuplet { Slots = [1, 0], Level = 04 },
- new SlotsByLevelDuplet { Slots = [1, 1], Level = 05 },
- new SlotsByLevelDuplet { Slots = [1, 1], Level = 06 },
- new SlotsByLevelDuplet { Slots = [1, 1], Level = 07 },
- new SlotsByLevelDuplet { Slots = [1, 1], Level = 08 },
- new SlotsByLevelDuplet { Slots = [1, 1], Level = 09 },
- new SlotsByLevelDuplet { Slots = [1, 1], Level = 10 },
- new SlotsByLevelDuplet { Slots = [1, 1], Level = 11 },
- new SlotsByLevelDuplet { Slots = [1, 1], Level = 12 },
- new SlotsByLevelDuplet { Slots = [1, 1], Level = 13 },
- new SlotsByLevelDuplet { Slots = [1, 1], Level = 14 },
- new SlotsByLevelDuplet { Slots = [1, 1], Level = 15 },
- new SlotsByLevelDuplet { Slots = [1, 1], Level = 16 },
- new SlotsByLevelDuplet { Slots = [1, 1], Level = 17 },
- new SlotsByLevelDuplet { Slots = [1, 1], Level = 18 },
- new SlotsByLevelDuplet { Slots = [1, 1], Level = 19 },
- new SlotsByLevelDuplet { Slots = [1, 1], Level = 20 }
+ new() { Slots = [0, 0], Level = 01 },
+ new() { Slots = [0, 0], Level = 02 },
+ new() { Slots = [1, 0], Level = 03 },
+ new() { Slots = [1, 0], Level = 04 },
+ new() { Slots = [1, 1], Level = 05 },
+ new() { Slots = [1, 1], Level = 06 },
+ new() { Slots = [1, 1], Level = 07 },
+ new() { Slots = [1, 1], Level = 08 },
+ new() { Slots = [1, 1], Level = 09 },
+ new() { Slots = [1, 1], Level = 10 },
+ new() { Slots = [1, 1], Level = 11 },
+ new() { Slots = [1, 1], Level = 12 },
+ new() { Slots = [1, 1], Level = 13 },
+ new() { Slots = [1, 1], Level = 14 },
+ new() { Slots = [1, 1], Level = 15 },
+ new() { Slots = [1, 1], Level = 16 },
+ new() { Slots = [1, 1], Level = 17 },
+ new() { Slots = [1, 1], Level = 18 },
+ new() { Slots = [1, 1], Level = 19 },
+ new() { Slots = [1, 1], Level = 20 }
];
internal static readonly List RaceEmptyCastingSlots =
[
- new SlotsByLevelDuplet { Slots = [0], Level = 01 },
- new SlotsByLevelDuplet { Slots = [0], Level = 02 },
- new SlotsByLevelDuplet { Slots = [0], Level = 03 },
- new SlotsByLevelDuplet { Slots = [0], Level = 04 },
- new SlotsByLevelDuplet { Slots = [0], Level = 05 },
- new SlotsByLevelDuplet { Slots = [0], Level = 06 },
- new SlotsByLevelDuplet { Slots = [0], Level = 07 },
- new SlotsByLevelDuplet { Slots = [0], Level = 08 },
- new SlotsByLevelDuplet { Slots = [0], Level = 09 },
- new SlotsByLevelDuplet { Slots = [0], Level = 10 },
- new SlotsByLevelDuplet { Slots = [0], Level = 11 },
- new SlotsByLevelDuplet { Slots = [0], Level = 12 },
- new SlotsByLevelDuplet { Slots = [0], Level = 13 },
- new SlotsByLevelDuplet { Slots = [0], Level = 14 },
- new SlotsByLevelDuplet { Slots = [0], Level = 15 },
- new SlotsByLevelDuplet { Slots = [0], Level = 16 },
- new SlotsByLevelDuplet { Slots = [0], Level = 17 },
- new SlotsByLevelDuplet { Slots = [0], Level = 18 },
- new SlotsByLevelDuplet { Slots = [0], Level = 19 },
- new SlotsByLevelDuplet { Slots = [0], Level = 20 }
+ new() { Slots = [0], Level = 01 },
+ new() { Slots = [0], Level = 02 },
+ new() { Slots = [0], Level = 03 },
+ new() { Slots = [0], Level = 04 },
+ new() { Slots = [0], Level = 05 },
+ new() { Slots = [0], Level = 06 },
+ new() { Slots = [0], Level = 07 },
+ new() { Slots = [0], Level = 08 },
+ new() { Slots = [0], Level = 09 },
+ new() { Slots = [0], Level = 10 },
+ new() { Slots = [0], Level = 11 },
+ new() { Slots = [0], Level = 12 },
+ new() { Slots = [0], Level = 13 },
+ new() { Slots = [0], Level = 14 },
+ new() { Slots = [0], Level = 15 },
+ new() { Slots = [0], Level = 16 },
+ new() { Slots = [0], Level = 17 },
+ new() { Slots = [0], Level = 18 },
+ new() { Slots = [0], Level = 19 },
+ new() { Slots = [0], Level = 20 }
];
// game uses IndexOf(0) on these sub lists reason why the last 0 there
private static readonly List WarlockCastingSlots =
[
- new SlotsByLevelDuplet
+ new()
{
Slots =
[
@@ -438,7 +438,7 @@ internal int GetCasterLevel()
Level = 01
},
- new SlotsByLevelDuplet
+ new()
{
Slots =
[
@@ -452,7 +452,7 @@ internal int GetCasterLevel()
Level = 02
},
- new SlotsByLevelDuplet
+ new()
{
Slots =
[
@@ -466,7 +466,7 @@ internal int GetCasterLevel()
Level = 03
},
- new SlotsByLevelDuplet
+ new()
{
Slots =
[
@@ -480,7 +480,7 @@ internal int GetCasterLevel()
Level = 04
},
- new SlotsByLevelDuplet
+ new()
{
Slots =
[
@@ -494,7 +494,7 @@ internal int GetCasterLevel()
Level = 05
},
- new SlotsByLevelDuplet
+ new()
{
Slots =
[
@@ -508,7 +508,7 @@ internal int GetCasterLevel()
Level = 06
},
- new SlotsByLevelDuplet
+ new()
{
Slots =
[
@@ -522,7 +522,7 @@ internal int GetCasterLevel()
Level = 07
},
- new SlotsByLevelDuplet
+ new()
{
Slots =
[
@@ -536,7 +536,7 @@ internal int GetCasterLevel()
Level = 08
},
- new SlotsByLevelDuplet
+ new()
{
Slots =
[
@@ -550,7 +550,7 @@ internal int GetCasterLevel()
Level = 09
},
- new SlotsByLevelDuplet
+ new()
{
Slots =
[
@@ -564,7 +564,7 @@ internal int GetCasterLevel()
Level = 10
},
- new SlotsByLevelDuplet
+ new()
{
Slots =
[
@@ -578,7 +578,7 @@ internal int GetCasterLevel()
Level = 11
},
- new SlotsByLevelDuplet
+ new()
{
Slots =
[
@@ -592,7 +592,7 @@ internal int GetCasterLevel()
Level = 12
},
- new SlotsByLevelDuplet
+ new()
{
Slots =
[
@@ -606,7 +606,7 @@ internal int GetCasterLevel()
Level = 13
},
- new SlotsByLevelDuplet
+ new()
{
Slots =
[
@@ -620,7 +620,7 @@ internal int GetCasterLevel()
Level = 14
},
- new SlotsByLevelDuplet
+ new()
{
Slots =
[
@@ -634,7 +634,7 @@ internal int GetCasterLevel()
Level = 15
},
- new SlotsByLevelDuplet
+ new()
{
Slots =
[
@@ -648,7 +648,7 @@ internal int GetCasterLevel()
Level = 16
},
- new SlotsByLevelDuplet
+ new()
{
Slots =
[
@@ -662,7 +662,7 @@ internal int GetCasterLevel()
Level = 17
},
- new SlotsByLevelDuplet
+ new()
{
Slots =
[
@@ -676,7 +676,7 @@ internal int GetCasterLevel()
Level = 18
},
- new SlotsByLevelDuplet
+ new()
{
Slots =
[
@@ -690,7 +690,7 @@ internal int GetCasterLevel()
Level = 19
},
- new SlotsByLevelDuplet
+ new()
{
Slots =
[
diff --git a/SolastaUnfinishedBusiness/Models/SpellPointsContext.cs b/SolastaUnfinishedBusiness/Models/SpellPointsContext.cs
index 9a2b4dba7e..b347c6ae81 100644
--- a/SolastaUnfinishedBusiness/Models/SpellPointsContext.cs
+++ b/SolastaUnfinishedBusiness/Models/SpellPointsContext.cs
@@ -253,9 +253,11 @@ void ConsumeSlot(int slot)
internal static void ConvertAdditionalSlotsIntoSpellPointsBeforeRefreshSpellRepertoire(RulesetCharacterHero hero)
{
var usablePower = PowerProvider.Get(PowerSpellPoints, hero);
- var activeConditions = hero.AllConditions.ToList();
- foreach (var activeCondition in activeConditions)
+ // need ToList to avoid enumerator issues with RemoveCondition
+ foreach (var activeCondition in hero.ConditionsByCategory
+ .SelectMany(x => x.Value)
+ .ToList())
{
var removeCondition = false;
diff --git a/SolastaUnfinishedBusiness/Models/SpellsContext.cs b/SolastaUnfinishedBusiness/Models/SpellsContext.cs
index a69157d550..301bf8a670 100644
--- a/SolastaUnfinishedBusiness/Models/SpellsContext.cs
+++ b/SolastaUnfinishedBusiness/Models/SpellsContext.cs
@@ -241,13 +241,14 @@ internal static void LateLoad()
RegisterSpell(BuildBoomingBlade(), 0, SpellListSorcerer, SpellListWarlock, SpellListWizard,
spellListInventorClass);
RegisterSpell(BurstOfRadiance, 0, SpellListCleric);
- // RegisterSpell(BuildEgoShock(), 0, SpellListBard, SpellListSorcerer, SpellListWarlock, SpellListWizard);
+ RegisterSpell(BuildCreateBonfire(), 0, SpellListDruid, SpellListSorcerer, SpellListWarlock, SpellListWizard,
+ spellListInventorClass);
RegisterSpell(EnduringSting, 0, SpellListWizard);
- // RegisterSpell(BuildForceStrike(), 0, SpellListSorcerer, SpellListWarlock, SpellListWizard, spellListInventorClass);
RegisterSpell(BuildIlluminatingSphere(), 0, SpellListBard, SpellListSorcerer, SpellListWizard);
RegisterSpell(BuildInfestation(), 0, SpellListDruid, SpellListSorcerer, SpellListWarlock, SpellListWizard);
RegisterSpell(BuildLightningLure(), 0, SpellListSorcerer, SpellListWarlock, SpellListWizard,
spellListInventorClass);
+ //RegisterSpell(BuildMagicStone(), 0, SpellListDruid, SpellListWarlock, spellListInventorClass);
RegisterSpell(BuildMindSpike(), 0, SpellListSorcerer, SpellListWarlock, SpellListWizard);
RegisterSpell(BuildMinorLifesteal(), 0, SpellListBard, SpellListSorcerer, SpellListWarlock, SpellListWizard);
RegisterSpell(BuildPrimalSavagery(), 0, SpellListDruid);
@@ -266,8 +267,10 @@ internal static void LateLoad()
// 1st level
RegisterSpell(CausticZap, 0, SpellListSorcerer, SpellListWizard, spellListInventorClass);
+ RegisterSpell(BuildCommand(), 0, SpellListBard, SpellListPaladin, SpellListCleric);
RegisterSpell(BuildChaosBolt(), 0, SpellListSorcerer);
RegisterSpell(BuildChromaticOrb(), 0, SpellListSorcerer, SpellListWizard);
+ RegisterSpell(BuildDissonantWhispers(), 0, SpellListBard);
RegisterSpell(EarthTremor, 0, SpellListBard, SpellListDruid, SpellListSorcerer, SpellListWizard);
RegisterSpell(EnsnaringStrike, 0, SpellListRanger);
RegisterSpell(ElementalInfusion, 0, SpellListDruid, SpellListRanger, SpellListSorcerer, SpellListWizard);
@@ -355,16 +358,19 @@ internal static void LateLoad()
RegisterSpell(BuildEmpoweredKnowledge(), 0, SpellListBard, SpellListSorcerer, SpellListWizard,
spellListInventorClass);
RegisterSpell(FarStep, 0, SpellListSorcerer, SpellListWarlock, SpellListWizard);
+ RegisterSpell(BuildHolyWeapon(), 0, SpellListCleric, SpellListPaladin);
RegisterSpell(BuildIncineration(), 0, SpellListSorcerer, SpellListWizard);
RegisterSpell(MantleOfThorns, 0, SpellListDruid);
RegisterSpell(SteelWhirlwind, 0, SpellListRanger, SpellListWizard);
RegisterSpell(SonicBoom, 0, SpellListSorcerer, SpellListWizard);
+ RegisterSpell(BuildSwiftQuiver(), 0, SpellListRanger);
RegisterSpell(BuildSynapticStatic(), 0, SpellListBard, SpellListSorcerer, SpellListWarlock, SpellListWizard);
RegisterSpell(Telekinesis, 0, SpellListSorcerer, SpellListWizard);
// 6th level
- RegisterSpell(BuildHeroicInfusion(), 0, SpellListWizard);
RegisterSpell(BuildFlashFreeze(), 0, SpellListDruid, SpellListSorcerer, SpellListWarlock);
+ RegisterSpell(BuildGravityFissure(), 0, SpellListWizard);
+ RegisterSpell(BuildHeroicInfusion(), 0, SpellListWizard);
RegisterSpell(BuildMysticalCloak(), 0, SpellListSorcerer, SpellListWarlock, SpellListWizard);
RegisterSpell(BuildPoisonWave(), 0, SpellListWizard);
RegisterSpell(BuildFizbanPlatinumShield(), 0, SpellListSorcerer, SpellListWizard);
@@ -380,6 +386,7 @@ internal static void LateLoad()
// 8th level
RegisterSpell(BuildAbiDalzimHorridWilting(), 0, SpellListSorcerer, SpellListWizard);
+ RegisterSpell(BuildGlibness(), 0, SpellListBard, SpellListWarlock);
RegisterSpell(BuildMindBlank(), 0, SpellListBard, SpellListWizard);
RegisterSpell(MaddeningDarkness, 0, SpellListWarlock, SpellListWizard);
RegisterSpell(BuildSoulExpulsion(), 0, SpellListCleric, SpellListSorcerer, SpellListWizard);
diff --git a/SolastaUnfinishedBusiness/Models/SrdAndHouseRulesContext.cs b/SolastaUnfinishedBusiness/Models/SrdAndHouseRulesContext.cs
index 7c4bde8cc1..7883c796a1 100644
--- a/SolastaUnfinishedBusiness/Models/SrdAndHouseRulesContext.cs
+++ b/SolastaUnfinishedBusiness/Models/SrdAndHouseRulesContext.cs
@@ -7,6 +7,7 @@
using SolastaUnfinishedBusiness.Builders.Features;
using SolastaUnfinishedBusiness.Interfaces;
using SolastaUnfinishedBusiness.Validators;
+using TA.AI;
using static ActionDefinitions;
using static RuleDefinitions;
using static SolastaUnfinishedBusiness.Api.DatabaseHelper;
@@ -73,6 +74,9 @@ internal static class SrdAndHouseRulesContext
.SetForbiddenActions(Id.AttackOpportunity)
.AddToDB();
+ private static readonly DecisionPackageDefinition DecisionPackageRestrained =
+ AiContext.BuildDecisionPackageBreakFree(ConditionRestrainedByEntangle.Name);
+
private static SpellDefinition ConjureElementalInvisibleStalker { get; set; }
internal static void LateLoad()
@@ -104,6 +108,7 @@ internal static void LateLoad()
SwitchUniversalSylvanArmorAndLightbringer();
SwitchUseHeightOneCylinderEffect();
NoTwinnedBladeCantrips();
+ ModifyGravitySlam();
}
private static void LoadSenseNormalVisionRangeMultiplier()
@@ -397,12 +402,16 @@ internal static void SwitchFilterOnHideousLaughter()
internal static void SwitchRecurringEffectOnEntangle()
{
+ // Remove recurring effect on Entangle (as per SRD, any creature is only affected at cast time)
if (Main.Settings.RemoveRecurringEffectOnEntangle)
{
- // Remove recurring effect on Entangle (as per SRD, any creature is only affected at cast time)
Entangle.effectDescription.recurrentEffect = RecurrentEffect.OnActivation;
Entangle.effectDescription.EffectForms[2].canSaveToCancel = false;
ConditionRestrainedByEntangle.Features.Add(FeatureDefinitionActionAffinitys.ActionAffinityGrappled);
+ ConditionRestrainedByEntangle.amountOrigin = ConditionDefinition.OriginOfAmount.Fixed;
+ ConditionRestrainedByEntangle.baseAmount = (int)AiContext.BreakFreeType.DoStrengthCheckAgainstCasterDC;
+ ConditionRestrainedByEntangle.addBehavior = true;
+ ConditionRestrainedByEntangle.battlePackage = DecisionPackageRestrained;
}
else
{
@@ -410,6 +419,10 @@ internal static void SwitchRecurringEffectOnEntangle()
RecurrentEffect.OnActivation | RecurrentEffect.OnTurnEnd | RecurrentEffect.OnEnter;
Entangle.effectDescription.EffectForms[2].canSaveToCancel = true;
ConditionRestrainedByEntangle.Features.Remove(FeatureDefinitionActionAffinitys.ActionAffinityGrappled);
+ ConditionRestrainedByEntangle.amountOrigin = ConditionDefinition.OriginOfAmount.None;
+ ConditionRestrainedByEntangle.baseAmount = 0;
+ ConditionRestrainedByEntangle.addBehavior = false;
+ ConditionRestrainedByEntangle.battlePackage = null;
}
}
@@ -1003,4 +1016,37 @@ internal sealed class NoTwinned
public static NoTwinned Mark { get; } = new();
}
+
+ #region Gravity Slam
+
+ private static EffectDescription _gravitySlamVanilla;
+ private static EffectDescription _gravitySlamModified;
+
+ private static void ModifyGravitySlam()
+ {
+ _gravitySlamVanilla = GravitySlam.EffectDescription;
+
+ _gravitySlamModified = EffectDescriptionBuilder.Create(_gravitySlamVanilla)
+ .SetTargetingData(Side.All, RangeType.Distance, 20, TargetType.Cylinder, 4, 10)
+ .AddEffectForms(EffectFormBuilder.MotionForm(ExtraMotionType.PushDown, 10))
+ .Build();
+
+ ToggleGravitySlamModification();
+ }
+
+ internal static void ToggleGravitySlamModification()
+ {
+ if (Main.Settings.EnablePullPushOnVerticalDirection && Main.Settings.ModifyGravitySlam)
+ {
+ GravitySlam.effectDescription = _gravitySlamModified;
+ }
+ else
+ {
+ GravitySlam.effectDescription = _gravitySlamVanilla;
+ }
+
+ Global.RefreshControlledCharacter();
+ }
+
+ #endregion
}
diff --git a/SolastaUnfinishedBusiness/Models/ToolsContext.cs b/SolastaUnfinishedBusiness/Models/ToolsContext.cs
index 0d6c458961..1012074c9c 100644
--- a/SolastaUnfinishedBusiness/Models/ToolsContext.cs
+++ b/SolastaUnfinishedBusiness/Models/ToolsContext.cs
@@ -272,24 +272,26 @@ private static void FinalizeRespec([NotNull] RulesetCharacterHero oldHero,
private static void TransferConditionsOfCategory(RulesetActor oldHero, RulesetActor newHero, string category)
{
- if (!oldHero.conditionsByCategory.TryGetValue(category, out var conditions))
+ if (!oldHero.ConditionsByCategory.TryGetValue(category, out var conditions))
{
return;
}
newHero.AddConditionCategoryAsNeeded(category);
- newHero.conditionsByCategory[category].AddRange(conditions);
- newHero.allConditions.AddRange(conditions);
+ newHero.AllConditions.AddRange(conditions);
+ newHero.ConditionsByCategory[category].AddRange(conditions);
}
private static void CleanupOldHeroConditions(RulesetCharacterHero oldHero, RulesetCharacterHero newHero)
{
//Unregister all conditions that are not present in new hero
- oldHero.allConditions
- .Where(c => !newHero.AllConditions.Contains(c))
+ oldHero.ConditionsByCategory
+ .SelectMany(x => x.Value)
+ .Where(c => !newHero.ConditionsByCategory.SelectMany(x => x.Value).Contains(c))
+ .ToList()
.Do(c => c.Unregister());
- oldHero.allConditions.Clear();
- oldHero.conditionsByCategory.Clear();
+ oldHero.AllConditions.Clear();
+ oldHero.ConditionsByCategory.Clear();
}
private static void CopyInventoryOver([NotNull] RulesetCharacter oldHero, int3 position)
diff --git a/SolastaUnfinishedBusiness/Models/TranslatorContext.cs b/SolastaUnfinishedBusiness/Models/TranslatorContext.cs
index 07dd1647f7..00247aef8b 100644
--- a/SolastaUnfinishedBusiness/Models/TranslatorContext.cs
+++ b/SolastaUnfinishedBusiness/Models/TranslatorContext.cs
@@ -648,10 +648,10 @@ private static IEnumerator TranslateUserCampaignRoutine(string languageCode, [No
foreach (var functor in userDialogState.functors)
{
- functor.stringParameter = functor.type switch
+ functor.StringParameter = functor.type switch
{
- "SetLocationStatus" => Translate(functor.stringParameter, languageCode),
- _ => functor.stringParameter
+ "SetLocationStatus" => Translate(functor.StringParameter, languageCode),
+ _ => functor.StringParameter
};
}
}
@@ -693,7 +693,7 @@ private static IEnumerator TranslateUserCampaignRoutine(string languageCode, [No
if (outStart.type == "SetLocationStatus")
{
- outStart.stringParameter = Translate(outStart.stringParameter, languageCode);
+ outStart.StringParameter = Translate(outStart.StringParameter, languageCode);
}
}
@@ -703,12 +703,12 @@ private static IEnumerator TranslateUserCampaignRoutine(string languageCode, [No
outcome.DescriptionText = Translate(outcome.DescriptionText, languageCode);
// magicSkySword : Only place parameters can be translated
- outcome.validatorDescription.stringParameter = outcome.validatorDescription.type switch
+ outcome.validatorDescription.StringParameter = outcome.validatorDescription.type switch
{
QuestDefinitions.QuestValidatorType.EnterLocation
or QuestDefinitions.QuestValidatorType.LeaveLocation => Translate(
- outcome.validatorDescription.stringParameter, languageCode),
- _ => outcome.validatorDescription.stringParameter
+ outcome.validatorDescription.StringParameter, languageCode),
+ _ => outcome.validatorDescription.StringParameter
};
}
}
diff --git a/SolastaUnfinishedBusiness/Patches/Activities/ActivitiesBreakFreePatcher.cs b/SolastaUnfinishedBusiness/Patches/Activities/ActivitiesBreakFreePatcher.cs
new file mode 100644
index 0000000000..633ee468d3
--- /dev/null
+++ b/SolastaUnfinishedBusiness/Patches/Activities/ActivitiesBreakFreePatcher.cs
@@ -0,0 +1,127 @@
+using System.Collections;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using HarmonyLib;
+using JetBrains.Annotations;
+using SolastaUnfinishedBusiness.Api.Helpers;
+using SolastaUnfinishedBusiness.Interfaces;
+using SolastaUnfinishedBusiness.Models;
+using TA.AI.Activities;
+using static RuleDefinitions;
+
+namespace SolastaUnfinishedBusiness.Patches.Activities;
+
+[UsedImplicitly]
+public static class BreakFreePatcher
+{
+ [HarmonyPatch(typeof(BreakFree), nameof(BreakFree.ExecuteImpl))]
+ [SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Patch")]
+ [UsedImplicitly]
+ public static class BreakFree_Patch
+ {
+ [UsedImplicitly]
+ public static IEnumerator Postfix([NotNull] IEnumerator values, AiLocationCharacter character)
+ {
+ var gameLocationCharacter = character.GameLocationCharacter;
+ var rulesetCharacter = gameLocationCharacter.RulesetCharacter;
+ var restrainingCondition = AiContext.GetRestrainingCondition(rulesetCharacter);
+
+ if (restrainingCondition == null)
+ {
+ while (values.MoveNext())
+ {
+ yield return values.Current;
+ }
+
+ yield break;
+ }
+
+ var action = (AiContext.BreakFreeType)restrainingCondition.Amount;
+ var success = true;
+
+ switch (action)
+ {
+ case AiContext.BreakFreeType.DoNoCheckAndRemoveCondition:
+ break;
+
+ case AiContext.BreakFreeType.DoStrengthCheckAgainstCasterDC:
+ yield return RollAttributeCheck(AttributeDefinitions.Strength);
+ break;
+
+ case AiContext.BreakFreeType.DoWisdomCheckAgainstCasterDC:
+ yield return RollAttributeCheck(AttributeDefinitions.Wisdom);
+ break;
+
+ default:
+ while (values.MoveNext())
+ {
+ yield return values.Current;
+ }
+
+ yield break;
+ }
+
+ if (success)
+ {
+ rulesetCharacter.RemoveCondition(restrainingCondition);
+ }
+
+ gameLocationCharacter.SpendActionType(ActionDefinitions.ActionType.Main);
+ rulesetCharacter.BreakFreeExecuted?.Invoke(rulesetCharacter, success);
+
+ yield break;
+
+ IEnumerator RollAttributeCheck(string attributeName)
+ {
+ var checkDC = 10;
+ var sourceGuid = restrainingCondition!.SourceGuid;
+
+ if (RulesetEntity.TryGetEntity(sourceGuid, out RulesetCharacterHero rulesetCharacterHero))
+ {
+ checkDC = rulesetCharacterHero.SpellRepertoires
+ .Select(x => x.SaveDC)
+ .Max();
+ }
+
+ rulesetCharacter.LogCharacterActivatesAbility(
+ string.Empty,
+ "Feedback/&BreakFreeAttempt",
+ extra:
+ [
+ (ConsoleStyleDuplet.ParameterType.Negative,
+ restrainingCondition.ConditionDefinition.FormatTitle())
+ ]);
+
+ var actionModifier = new ActionModifier();
+ var abilityCheckRoll = gameLocationCharacter.RollAbilityCheck(
+ attributeName,
+ string.Empty,
+ checkDC,
+ AdvantageType.None,
+ actionModifier,
+ false,
+ -1,
+ out var rollOutcome,
+ out var successDelta,
+ true);
+
+ //PATCH: support for Bardic Inspiration roll off battle and ITryAlterOutcomeAttributeCheck
+ var abilityCheckData = new AbilityCheckData
+ {
+ AbilityCheckRoll = abilityCheckRoll,
+ AbilityCheckRollOutcome = rollOutcome,
+ AbilityCheckSuccessDelta = successDelta,
+ AbilityCheckActionModifier = actionModifier,
+ Action = null
+ };
+
+ yield return TryAlterOutcomeAttributeCheck
+ .HandleITryAlterOutcomeAttributeCheck(gameLocationCharacter, abilityCheckData);
+
+ success = abilityCheckData.AbilityCheckRollOutcome
+ is RollOutcome.Success
+ or RollOutcome.CriticalSuccess;
+ }
+ }
+ }
+}
diff --git a/SolastaUnfinishedBusiness/Patches/ActivitiesBreakFreePatcher.cs b/SolastaUnfinishedBusiness/Patches/ActivitiesBreakFreePatcher.cs
deleted file mode 100644
index f9004637e4..0000000000
--- a/SolastaUnfinishedBusiness/Patches/ActivitiesBreakFreePatcher.cs
+++ /dev/null
@@ -1,122 +0,0 @@
-using System.Collections;
-using System.Diagnostics.CodeAnalysis;
-using System.Linq;
-using HarmonyLib;
-using JetBrains.Annotations;
-using SolastaUnfinishedBusiness.Api.GameExtensions;
-using SolastaUnfinishedBusiness.Interfaces;
-using SolastaUnfinishedBusiness.Models;
-using TA.AI;
-using TA.AI.Activities;
-using static RuleDefinitions;
-
-namespace SolastaUnfinishedBusiness.Patches;
-
-[UsedImplicitly]
-public static class ActivitiesBreakFreePatcher
-{
- [HarmonyPatch(typeof(BreakFree), nameof(BreakFree.ExecuteImpl))]
- [SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Patch")]
- [UsedImplicitly]
- public static class BreakFree_Patch
- {
- [UsedImplicitly]
- public static IEnumerator Postfix(
- [NotNull] IEnumerator values,
- [NotNull] BreakFree __instance,
- AiLocationCharacter character,
- DecisionDefinition decisionDefinition)
- {
- RulesetCondition restrainingCondition = null;
-
- var gameLocationCharacter = character.GameLocationCharacter;
- var rulesetCharacter = gameLocationCharacter.RulesetCharacter;
-
- if (rulesetCharacter == null)
- {
- yield break;
- }
-
- foreach (var definitionActionAffinity in rulesetCharacter
- .GetFeaturesByType()
- .Where(x => x.AuthorizedActions.Contains(ActionDefinitions.Id.BreakFree)))
- {
- restrainingCondition = rulesetCharacter.FindFirstConditionHoldingFeature(definitionActionAffinity);
- }
-
- if (restrainingCondition == null)
- {
- yield break;
- }
-
- var success = true;
-
- // no ability check
- switch (decisionDefinition.Decision.stringParameter)
- {
- case AiContext.DoNothing:
- rulesetCharacter.RemoveCondition(restrainingCondition);
- break;
-
- case AiContext.DoStrengthCheckCasterDC:
- var checkDC = 10;
- var sourceGuid = restrainingCondition.SourceGuid;
-
- if (RulesetEntity.TryGetEntity(sourceGuid, out RulesetCharacterHero rulesetCharacterHero))
- {
- checkDC = rulesetCharacterHero.SpellRepertoires
- .Select(x => x.SaveDC)
- .Max();
- }
-
- var actionModifier = new ActionModifier();
-
- rulesetCharacter.ComputeBaseAbilityCheckBonus(
- AttributeDefinitions.Strength, actionModifier.AbilityCheckModifierTrends, string.Empty);
- gameLocationCharacter.ComputeAbilityCheckActionModifier(
- AttributeDefinitions.Strength, string.Empty, actionModifier);
-
- var abilityCheckRoll = gameLocationCharacter.RollAbilityCheck(
- AttributeDefinitions.Strength, string.Empty, checkDC, AdvantageType.None, actionModifier,
- false, -1, out var rollOutcome, out var successDelta, true);
-
- //PATCH: support for Bardic Inspiration roll off battle and ITryAlterOutcomeAttributeCheck
- var abilityCheckData = new AbilityCheckData
- {
- AbilityCheckRoll = abilityCheckRoll,
- AbilityCheckRollOutcome = rollOutcome,
- AbilityCheckSuccessDelta = successDelta,
- AbilityCheckActionModifier = actionModifier
- };
-
- yield return TryAlterOutcomeAttributeCheck
- .HandleITryAlterOutcomeAttributeCheck(gameLocationCharacter, abilityCheckData);
-
- success = abilityCheckData.AbilityCheckRollOutcome
- is RollOutcome.Success
- or RollOutcome.CriticalSuccess;
-
- if (success)
- {
- rulesetCharacter.RemoveCondition(restrainingCondition);
- }
-
- break;
-
- default:
- while (values.MoveNext())
- {
- yield return values.Current;
- }
-
- yield break;
- }
-
- gameLocationCharacter.SpendActionType(ActionDefinitions.ActionType.Main);
-
- var breakFreeExecuted = rulesetCharacter.BreakFreeExecuted;
-
- breakFreeExecuted?.Invoke(rulesetCharacter, success);
- }
- }
-}
diff --git a/SolastaUnfinishedBusiness/Patches/AiLocationManagerPatcher.cs b/SolastaUnfinishedBusiness/Patches/AiLocationManagerPatcher.cs
index f99fd12492..8328f27592 100644
--- a/SolastaUnfinishedBusiness/Patches/AiLocationManagerPatcher.cs
+++ b/SolastaUnfinishedBusiness/Patches/AiLocationManagerPatcher.cs
@@ -14,6 +14,12 @@ namespace SolastaUnfinishedBusiness.Patches;
[UsedImplicitly]
public static class AiLocationManagerPatcher
{
+ //TODO: move to separate class?
+ private static T CreateDelegate(this MethodInfo method) where T : Delegate
+ {
+ return (T)Delegate.CreateDelegate(typeof(T), method);
+ }
+
//PATCH: support for Circle of the Wildfire cauterizing flames
[HarmonyPatch(typeof(AiLocationManager), nameof(AiLocationManager.ProcessBattleTurn))]
[SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Patch")]
@@ -44,43 +50,65 @@ public static void Postfix(AiLocationManager __instance)
Assembly.GetExecutingAssembly().GetTypes()
.Where(t => t.IsSubclassOf(typeof(ActivityBase))))
{
- __instance.activitiesMap.TryAdd(type.ToString().Split('.').Last(), type);
+ var name = type.ToString().Split('.').Last();
+ __instance.activitiesMap.AddOrReplace(name, type);
foreach (var method in type.GetMethods(BindingFlags.Static | BindingFlags.Public))
{
var parameters = method.GetParameters();
if (method.ReturnType == typeof(ContextType))
{
- __instance.activityContextsMap.TryAdd(
- type.ToString().Split('.').Last(),
- (AiLocationDefinitions.GetContextTypeHandler)Delegate.CreateDelegate(
- typeof(AiLocationDefinitions.GetContextTypeHandler), method));
+ __instance.activityContextsMap.AddOrReplace(name,
+ method.CreateDelegate());
}
- else if (method.ReturnType == typeof(void) &&
- parameters.Length == 2 &&
- parameters[0].ParameterType.GetElementType() == typeof(ActionDefinitions.Id) &&
- parameters[1].ParameterType.GetElementType() == typeof(ActionDefinitions.Id))
+ else if (method.ReturnType == typeof(void)
+ && parameters.Length == 2
+ && parameters[0].ParameterType.GetElementType() == typeof(ActionDefinitions.Id)
+ && parameters[1].ParameterType.GetElementType() == typeof(ActionDefinitions.Id))
{
- __instance.activityActionIdsMap.TryAdd(
- type.ToString().Split('.').Last(),
- (AiLocationDefinitions.GetActionIdHandler)Delegate.CreateDelegate(
- typeof(AiLocationDefinitions.GetActionIdHandler), method));
+ __instance.activityActionIdsMap.AddOrReplace(name,
+ method.CreateDelegate());
}
- else if (method.ReturnType == typeof(bool) &&
- parameters.Length == 2 && parameters[0].ParameterType.GetElementType() ==
- typeof(GameLocationCharacter))
+ else if (method.ReturnType == typeof(bool)
+ && parameters.Length == 2
+ && parameters[0].ParameterType.GetElementType() == typeof(GameLocationCharacter))
{
- __instance.activityShouldBeSkippedMap.TryAdd(
- type.ToString().Split('.').Last(),
- (AiLocationDefinitions.ShouldBeSkippedHandler)Delegate.CreateDelegate(
- typeof(AiLocationDefinitions.ShouldBeSkippedHandler), method));
+ __instance.activityShouldBeSkippedMap.AddOrReplace(name,
+ method.CreateDelegate());
}
else if (method.ReturnType == typeof(bool) && parameters.Length == 0)
{
- __instance.activityUsesMovementContextsMap.TryAdd(
- type.ToString().Split('.').Last(),
- (AiLocationDefinitions.UsesMovementContextsHandler)Delegate.CreateDelegate(
- typeof(AiLocationDefinitions.UsesMovementContextsHandler), method));
+ __instance.activityUsesMovementContextsMap.AddOrReplace(name,
+ method.CreateDelegate());
+ }
+ }
+ }
+ }
+ }
+
+ [HarmonyPatch(typeof(AiLocationManager), nameof(AiLocationManager.BuildConsiderationsMap))]
+ [SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Patch")]
+ [UsedImplicitly]
+ public static class BuildConsiderationsMap_Patch
+ {
+ [UsedImplicitly]
+ public static void Postfix(AiLocationManager __instance)
+ {
+ foreach (var type in Assembly.GetExecutingAssembly().GetTypes()
+ .Where(t => t.IsSubclassOf(typeof(ConsiderationBase))))
+ {
+ var name = type.ToString().Split('.').Last();
+ foreach (var method in type.GetMethods(BindingFlags.Static | BindingFlags.Public))
+ {
+ if (method.ReturnType == typeof(IEnumerator))
+ {
+ __instance.considerationsWithAllocMap.AddOrReplace(name,
+ method.CreateDelegate());
+ }
+ else if (method.ReturnType == typeof(void))
+ {
+ __instance.considerationsMap.AddOrReplace(name,
+ method.CreateDelegate());
}
}
}
diff --git a/SolastaUnfinishedBusiness/Patches/BrainPatcher.cs b/SolastaUnfinishedBusiness/Patches/BrainPatcher.cs
new file mode 100644
index 0000000000..7599d9ecef
--- /dev/null
+++ b/SolastaUnfinishedBusiness/Patches/BrainPatcher.cs
@@ -0,0 +1,56 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using HarmonyLib;
+using JetBrains.Annotations;
+using TA.AI;
+
+namespace SolastaUnfinishedBusiness.Patches;
+
+[UsedImplicitly]
+public static class BrainPatcher
+{
+ //BUGFIX: potential null exception on vanilla code
+ [HarmonyPatch(typeof(Brain), nameof(Brain.UpdateContextElementsIfNecessary))]
+ [SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Patch")]
+ [UsedImplicitly]
+ public static class UpdateContextElementsIfNecessary_Patch
+ {
+ [UsedImplicitly]
+ public static bool Prefix(out IEnumerator __result, Brain __instance, ContextType contextType)
+ {
+ __result = UpdateContextElementsIfNecessary(__instance, contextType);
+
+ return false;
+ }
+
+ private static IEnumerator UpdateContextElementsIfNecessary(Brain brain, ContextType contextType)
+ {
+ List decisionContexts = [];
+
+ //BEGIN PATCH
+ //moved this off the IF block to ensure ELSE block won't fail if contexts doesn't have context type
+ //END PATCH
+
+ brain.contexts.TryAdd(contextType, decisionContexts);
+
+ if (!brain.contextUpToDateStatus.TryGetValue(contextType, out var isUpToDate))
+ {
+ brain.contextUpToDateStatus.Add(contextType, true);
+ }
+
+ decisionContexts = brain.contexts[contextType];
+
+ if (isUpToDate)
+ {
+ yield break;
+ }
+
+ decisionContexts.Clear();
+
+ yield return brain.BuildContextElements(contextType, decisionContexts);
+
+ brain.contextUpToDateStatus[contextType] = true;
+ }
+ }
+}
diff --git a/SolastaUnfinishedBusiness/Patches/CharacterActionAttackPatcher.cs b/SolastaUnfinishedBusiness/Patches/CharacterActionAttackPatcher.cs
index 9213571213..5424d6a524 100644
--- a/SolastaUnfinishedBusiness/Patches/CharacterActionAttackPatcher.cs
+++ b/SolastaUnfinishedBusiness/Patches/CharacterActionAttackPatcher.cs
@@ -1,10 +1,12 @@
using System.Collections;
+using System.Collections.Generic;
using System.Linq;
using HarmonyLib;
using JetBrains.Annotations;
using SolastaUnfinishedBusiness.Api.GameExtensions;
using SolastaUnfinishedBusiness.Behaviors.Specific;
using SolastaUnfinishedBusiness.Interfaces;
+using SolastaUnfinishedBusiness.Spells;
using UnityEngine;
using static RuleDefinitions;
using Coroutine = TA.Coroutine;
@@ -47,6 +49,14 @@ internal static IEnumerator ExecuteImpl(CharacterActionAttack __instance)
var itemService = ServiceRepository.GetService();
var positioningService = ServiceRepository.GetService();
+ //BEGIN PATCH
+ //support Swift Quiver spell interaction with Flurry of Blows
+ if (attackMode.AttackTags.Contains(SpellBuilders.SwiftQuiverAttackTag))
+ {
+ actingCharacter.UsedSpecialFeatures.TryAdd(SpellBuilders.SwiftQuiverAttackTag, 0);
+ }
+ //END PATCH
+
// Check action params
var canAttackMain =
actingCharacter.GetActionStatus(
@@ -475,30 +485,39 @@ internal static IEnumerator ExecuteImpl(CharacterActionAttack __instance)
// These bool information must be store as a class member, as it is passed to HandleFailedSavingThrow
__instance.RolledSaveThrow = attackMode.TryRollSavingThrow(
- rulesetCharacter, target.RulesetActor, attackModifier,
- __instance.actualEffectForms, out var saveOutcome, out var saveOutcomeDelta);
+ rulesetCharacter,
+ target.RulesetActor,
+ attackModifier,
+ __instance.actualEffectForms,
+ out var saveOutcome,
+ out var saveOutcomeDelta);
+
__instance.SaveOutcome = saveOutcome;
__instance.SaveOutcomeDelta = saveOutcomeDelta;
if (__instance.RolledSaveThrow)
{
- target.RulesetActor?.GrantConditionOnSavingThrowOutcome(
- attackMode.EffectDescription, saveOutcome, true);
-
- // Legendary Resistance or Indomitable?
- if (__instance.SaveOutcome == RollOutcome.Failure)
+ var savingThrowData = new SavingThrowData
{
- yield return battleManager.HandleFailedSavingThrow(
- __instance, actingCharacter, target, attackModifier, false, hasBorrowedLuck);
- }
-
- //PATCH: support for `ITryAlterOutcomeSavingThrow`
- foreach (var tryAlterOutcomeSavingThrow in TryAlterOutcomeSavingThrow.Handler(
- battleManager, __instance, actingCharacter, target, attackModifier, false,
- hasBorrowedLuck))
- {
- yield return tryAlterOutcomeSavingThrow;
- }
+ SaveActionModifier = attackModifier,
+ SaveOutcome = __instance.SaveOutcome,
+ SaveOutcomeDelta = __instance.SaveOutcomeDelta,
+ SaveDC = RulesetActorExtensions.SaveDC,
+ SaveBonusAndRollModifier = RulesetActorExtensions.SaveBonusAndRollModifier,
+ SavingThrowAbility = RulesetActorExtensions.SavingThrowAbility,
+ SourceDefinition = null,
+ EffectDescription = attackMode.EffectDescription,
+ Title = __instance.FormatTitle(),
+ Action = __instance
+ };
+
+ yield return TryAlterOutcomeSavingThrow.Handler(
+ battleManager,
+ actingCharacter,
+ target,
+ savingThrowData,
+ hasBorrowedLuck,
+ attackMode.EffectDescription);
}
// Check for resulting actions, if any of them is a CharacterSpendPower w/ a Motion effect form, don't wait for hit animation
@@ -715,6 +734,13 @@ internal static IEnumerator ExecuteImpl(CharacterActionAttack __instance)
yield return GuardianAura.ProcessOnCharacterAttackHitFinished(
battleManager, actingCharacter, target, attackMode, null, damageReceived);
+ //PATCH: supports smite spell scenarios
+ if (attackHasDamaged && !rangeAttack)
+ {
+ rulesetCharacter.ProcessConditionsMatchingInterruption(
+ (ConditionInterruption)ExtraConditionInterruption.AttacksWithMeleeAndDamages, damageReceived);
+ }
+
// END PATCH
if (attackHasDamaged)
@@ -829,13 +855,13 @@ internal static IEnumerator ExecuteImpl(CharacterActionAttack __instance)
rulesetDefender.matchingInterruption = true;
rulesetDefender.matchingInterruptionConditions.Clear();
- foreach (var rulesetCondition in rulesetDefender.conditionsByCategory
- .SelectMany(keyValuePair => keyValuePair.Value
- .Where(rulesetCondition =>
- rulesetCondition.ConditionDefinition.HasSpecialInterruptionOfType(
- (ConditionInterruption)ExtraConditionInterruption
- .AfterWasAttackedNotBySource) &&
- rulesetCondition.SourceGuid != actingCharacter.Guid)))
+ foreach (var rulesetCondition in rulesetDefender.ConditionsByCategory
+ .SelectMany(x => x.Value)
+ .Where(rulesetCondition =>
+ rulesetCondition.ConditionDefinition.HasSpecialInterruptionOfType(
+ (ConditionInterruption)ExtraConditionInterruption
+ .AfterWasAttackedNotBySource) &&
+ rulesetCondition.SourceGuid != actingCharacter.Guid))
{
rulesetDefender.matchingInterruptionConditions.Add(rulesetCondition);
}
diff --git a/SolastaUnfinishedBusiness/Patches/CharacterActionBreakFreePatcher.cs b/SolastaUnfinishedBusiness/Patches/CharacterActionBreakFreePatcher.cs
index c63013bd16..c484b6be1c 100644
--- a/SolastaUnfinishedBusiness/Patches/CharacterActionBreakFreePatcher.cs
+++ b/SolastaUnfinishedBusiness/Patches/CharacterActionBreakFreePatcher.cs
@@ -3,6 +3,7 @@
using System.Linq;
using HarmonyLib;
using JetBrains.Annotations;
+using SolastaUnfinishedBusiness.Api.Helpers;
using SolastaUnfinishedBusiness.Interfaces;
using SolastaUnfinishedBusiness.Models;
using static RuleDefinitions;
@@ -28,86 +29,81 @@ public static bool Prefix(ref IEnumerator __result, CharacterActionBreakFree __i
private static IEnumerator Process(CharacterActionBreakFree __instance)
{
- RulesetCondition restrainingCondition = null;
-
- __instance.ActingCharacter.RulesetCharacter.EnumerateFeaturesToBrowse(
- __instance.ActingCharacter.RulesetCharacter.FeaturesToBrowse);
-
- foreach (var definitionActionAffinity in __instance.ActingCharacter.RulesetCharacter.FeaturesToBrowse
- .Cast()
- .Where(definitionActionAffinity => definitionActionAffinity.AuthorizedActions
- .Contains(__instance.ActionId)))
- {
- restrainingCondition = __instance.ActingCharacter.RulesetCharacter
- .FindFirstConditionHoldingFeature(definitionActionAffinity);
- }
+ var rulesetCharacter = __instance.ActingCharacter.RulesetCharacter;
+ var restrainingCondition = AiContext.GetRestrainingCondition(rulesetCharacter);
if (restrainingCondition == null)
{
yield break;
}
+ var sourceGuid = restrainingCondition.SourceGuid;
+ var action = (AiContext.BreakFreeType)restrainingCondition?.Amount;
var actionModifier = new ActionModifier();
-
- var abilityScoreName =
- __instance.ActionParams.BreakFreeMode == ActionDefinitions.BreakFreeMode.Athletics
- ? AttributeDefinitions.Strength
- : AttributeDefinitions.Dexterity;
-
- var proficiencyName = __instance.ActionParams.BreakFreeMode == ActionDefinitions.BreakFreeMode.Athletics
- ? SkillDefinitions.Athletics
- : SkillDefinitions.Acrobatics;
-
var checkDC = 10;
- var sourceGuid = restrainingCondition.SourceGuid;
- var conditionName = restrainingCondition.ConditionDefinition.Name;
+ string abilityScoreName;
+ string proficiencyName;
- if (AiContext.DoNothingConditions.Contains(conditionName))
+ switch (action)
{
- __instance.ActingCharacter.RulesetCharacter.RemoveCondition(restrainingCondition);
- yield break;
- }
+ case AiContext.BreakFreeType.DoNoCheckAndRemoveCondition:
+ __instance.ActingCharacter.RulesetCharacter.RemoveCondition(restrainingCondition);
+ yield break;
- if (AiContext.DoStrengthCheckCasterDCConditions.Contains(conditionName))
- {
- if (RulesetEntity.TryGetEntity(sourceGuid, out RulesetCharacterHero rulesetCharacterHero))
+ case AiContext.BreakFreeType.DoStrengthCheckAgainstCasterDC:
{
- checkDC = rulesetCharacterHero.SpellRepertoires
- .Select(x => x.SaveDC)
- .Max();
+ CalculateDC(AttributeDefinitions.Strength);
+ break;
}
-
- proficiencyName = string.Empty;
- }
- else
- {
- if (restrainingCondition.HasSaveOverride)
+ case AiContext.BreakFreeType.DoWisdomCheckAgainstCasterDC:
{
- checkDC = restrainingCondition.SaveOverrideDC;
+ CalculateDC(AttributeDefinitions.Wisdom);
+ break;
}
- else
+ default:
{
- if (RulesetEntity.TryGetEntity(sourceGuid, out RulesetEffect entity1))
+ abilityScoreName =
+ __instance.ActionParams.BreakFreeMode == ActionDefinitions.BreakFreeMode.Athletics
+ ? AttributeDefinitions.Strength
+ : AttributeDefinitions.Dexterity;
+
+ proficiencyName = __instance.ActionParams.BreakFreeMode == ActionDefinitions.BreakFreeMode.Athletics
+ ? SkillDefinitions.Athletics
+ : SkillDefinitions.Acrobatics;
+
+ if (restrainingCondition!.HasSaveOverride)
{
- checkDC = entity1.SaveDC;
+ checkDC = restrainingCondition.SaveOverrideDC;
}
- else if (RulesetEntity.TryGetEntity(sourceGuid, out RulesetCharacterMonster entity2))
+ else
{
- checkDC = 10 + AttributeDefinitions
- .ComputeAbilityScoreModifier(entity2.GetAttribute(AttributeDefinitions.Strength)
- .CurrentValue);
+ if (RulesetEntity.TryGetEntity(sourceGuid, out RulesetEffect entity1))
+ {
+ checkDC = entity1.SaveDC;
+ }
+ else if (RulesetEntity.TryGetEntity(sourceGuid, out RulesetCharacterMonster entity2))
+ {
+ checkDC = 10 + AttributeDefinitions
+ .ComputeAbilityScoreModifier(entity2.GetAttribute(AttributeDefinitions.Strength)
+ .CurrentValue);
+ }
}
+
+ break;
}
}
- __instance.ActingCharacter.RulesetCharacter.ComputeBaseAbilityCheckBonus(
- abilityScoreName, actionModifier.AbilityCheckModifierTrends, proficiencyName);
- __instance.ActingCharacter.ComputeAbilityCheckActionModifier(
- abilityScoreName, proficiencyName, actionModifier);
-
var abilityCheckRoll = __instance.ActingCharacter.RollAbilityCheck(
- abilityScoreName, proficiencyName, checkDC, AdvantageType.None, actionModifier, false,
- -1, out var rollOutcome, out var successDelta, true);
+ abilityScoreName,
+ proficiencyName,
+ checkDC,
+ AdvantageType.None,
+ actionModifier,
+ false,
+ -1,
+ out var rollOutcome,
+ out var successDelta,
+ true);
//PATCH: support for Bardic Inspiration roll off battle and ITryAlterOutcomeAttributeCheck
var abilityCheckData = new AbilityCheckData
@@ -115,7 +111,8 @@ private static IEnumerator Process(CharacterActionBreakFree __instance)
AbilityCheckRoll = abilityCheckRoll,
AbilityCheckRollOutcome = rollOutcome,
AbilityCheckSuccessDelta = successDelta,
- AbilityCheckActionModifier = actionModifier
+ AbilityCheckActionModifier = actionModifier,
+ Action = __instance
};
yield return TryAlterOutcomeAttributeCheck
@@ -135,6 +132,30 @@ private static IEnumerator Process(CharacterActionBreakFree __instance)
var breakFreeExecuted = __instance.ActingCharacter.RulesetCharacter.BreakFreeExecuted;
breakFreeExecuted?.Invoke(__instance.ActingCharacter.RulesetCharacter, success);
+
+ yield break;
+
+ void CalculateDC(string newAbilityScoreName)
+ {
+ if (RulesetEntity.TryGetEntity(sourceGuid, out RulesetCharacterHero rulesetCharacterHero))
+ {
+ checkDC = rulesetCharacterHero.SpellRepertoires
+ .Select(x => x.SaveDC)
+ .Max();
+ }
+
+ rulesetCharacter.LogCharacterActivatesAbility(
+ string.Empty,
+ "Feedback/&BreakFreeAttempt",
+ extra:
+ [
+ (ConsoleStyleDuplet.ParameterType.Negative,
+ restrainingCondition.ConditionDefinition.FormatTitle())
+ ]);
+
+ abilityScoreName = newAbilityScoreName;
+ proficiencyName = string.Empty;
+ }
}
}
}
diff --git a/SolastaUnfinishedBusiness/Patches/CharacterActionCastSpellPatcher.cs b/SolastaUnfinishedBusiness/Patches/CharacterActionCastSpellPatcher.cs
index 1f76086728..bb8181cbd1 100644
--- a/SolastaUnfinishedBusiness/Patches/CharacterActionCastSpellPatcher.cs
+++ b/SolastaUnfinishedBusiness/Patches/CharacterActionCastSpellPatcher.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
@@ -11,6 +12,7 @@
using SolastaUnfinishedBusiness.Behaviors;
using SolastaUnfinishedBusiness.Interfaces;
using SolastaUnfinishedBusiness.Models;
+using static RuleDefinitions;
namespace SolastaUnfinishedBusiness.Patches;
@@ -139,4 +141,140 @@ public static bool Prefix([NotNull] CharacterActionCastSpell __instance)
return false;
}
}
+
+ //PATCH: allow check reactions on cast spell regardless of success / failure
+ [HarmonyPatch(typeof(CharacterActionCastSpell), nameof(CharacterActionCastSpell.CounterEffectAction))]
+ [SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Patch")]
+ [UsedImplicitly]
+ public static class CounterEffectAction_Patch
+ {
+ [UsedImplicitly]
+ public static bool Prefix(ref IEnumerator __result, CharacterActionCastSpell __instance,
+ CharacterAction counterAction)
+ {
+ __result = Process(__instance, counterAction);
+
+ return false;
+ }
+
+ private static IEnumerator Process(
+ CharacterActionCastSpell characterActionCastSpell,
+ CharacterAction counterAction)
+ {
+ var targetAction = characterActionCastSpell.ActionParams.TargetAction;
+
+ if (targetAction == null)
+ {
+ yield break;
+ }
+
+ var actingCharacter = characterActionCastSpell.ActingCharacter;
+ var rulesetCharacter = actingCharacter.RulesetCharacter;
+ var actionParams = characterActionCastSpell.ActionParams;
+ var targetActionParams = targetAction.ActionParams;
+ var counteredSpell = targetActionParams.RulesetEffect as RulesetEffectSpell;
+ var counteredSpellDefinition = counteredSpell!.SpellDefinition;
+ var slotLevel = counteredSpell.SlotLevel;
+ var actionModifier = actionParams.ActionModifiers[0];
+
+ foreach (var counterForm in actionParams.RulesetEffect.EffectDescription.EffectForms
+ .Where(effectForm => effectForm.FormType == EffectForm.EffectFormType.Counter)
+ .Select(effectForm => effectForm.CounterForm))
+ {
+ if (counterForm.AutomaticSpellLevel + characterActionCastSpell.addSpellLevel >= slotLevel)
+ {
+ targetAction.Countered = true;
+ }
+ else if (counterForm.CheckBaseDC != 0)
+ {
+ var checkDC = counterForm.CheckBaseDC + slotLevel;
+
+ rulesetCharacter
+ .EnumerateFeaturesToBrowse(rulesetCharacter.FeaturesToBrowse);
+
+ foreach (var featureDefinition in rulesetCharacter.FeaturesToBrowse)
+ {
+ var definitionMagicAffinity = (FeatureDefinitionMagicAffinity)featureDefinition;
+
+ if (definitionMagicAffinity.CounterspellAffinity == AdvantageType.None)
+ {
+ continue;
+ }
+
+ var advTrend = definitionMagicAffinity.CounterspellAffinity == AdvantageType.Advantage
+ ? 1
+ : -1;
+
+ actionModifier.AbilityCheckAdvantageTrends.Add(new TrendInfo(
+ advTrend, FeatureSourceType.CharacterFeature, definitionMagicAffinity.Name, null));
+ }
+
+ if (counteredSpell.CounterAffinity != AdvantageType.None)
+ {
+ var advTrend = counteredSpell.CounterAffinity == AdvantageType.Advantage
+ ? 1
+ : -1;
+
+ actionModifier.AbilityCheckAdvantageTrends.Add(new TrendInfo(
+ advTrend, FeatureSourceType.CharacterFeature, counteredSpell.CounterAffinityOrigin, null));
+ }
+
+ var proficiencyName = string.Empty;
+
+ if (counterForm.AddProficiencyBonus)
+ {
+ proficiencyName = "ForcedProficiency";
+ }
+
+ var abilityCheckRoll = actingCharacter.RollAbilityCheck(
+ characterActionCastSpell.activeSpell.SpellRepertoire.SpellCastingAbility,
+ proficiencyName,
+ checkDC,
+ AdvantageType.None,
+ actionModifier,
+ false,
+ 0,
+ out var outcome,
+ out var successDelta,
+ true);
+
+ var abilityCheckData = new AbilityCheckData
+ {
+ AbilityCheckRoll = abilityCheckRoll,
+ AbilityCheckRollOutcome = outcome,
+ AbilityCheckSuccessDelta = successDelta,
+ AbilityCheckActionModifier = actionModifier,
+ Action = characterActionCastSpell
+ };
+
+ yield return TryAlterOutcomeAttributeCheck
+ .HandleITryAlterOutcomeAttributeCheck(actingCharacter, abilityCheckData);
+
+ characterActionCastSpell.AbilityCheckRoll = abilityCheckData.AbilityCheckRoll;
+ characterActionCastSpell.AbilityCheckRollOutcome = abilityCheckData.AbilityCheckRollOutcome;
+ characterActionCastSpell.AbilityCheckSuccessDelta = abilityCheckData.AbilityCheckSuccessDelta;
+
+ if (counterAction.AbilityCheckRollOutcome == RollOutcome.Success)
+ {
+ targetAction.Countered = true;
+ }
+ }
+
+ if (!targetAction.Countered ||
+ rulesetCharacter.SpellCounter == null)
+ {
+ continue;
+ }
+
+ var unknown = string.IsNullOrEmpty(counteredSpell.IdentifiedBy);
+
+ characterActionCastSpell.ActingCharacter.RulesetCharacter.SpellCounter(
+ rulesetCharacter,
+ targetAction.ActingCharacter.RulesetCharacter,
+ counteredSpellDefinition,
+ targetAction.Countered,
+ unknown);
+ }
+ }
+ }
}
diff --git a/SolastaUnfinishedBusiness/Patches/CharacterActionItemFormPatcher.cs b/SolastaUnfinishedBusiness/Patches/CharacterActionItemFormPatcher.cs
index 61eff6b62c..b31d508fd6 100644
--- a/SolastaUnfinishedBusiness/Patches/CharacterActionItemFormPatcher.cs
+++ b/SolastaUnfinishedBusiness/Patches/CharacterActionItemFormPatcher.cs
@@ -4,11 +4,9 @@
using SolastaUnfinishedBusiness.Api.GameExtensions;
using SolastaUnfinishedBusiness.Interfaces;
using SolastaUnfinishedBusiness.Models;
-using SolastaUnfinishedBusiness.Validators;
using TA.AddressableAssets;
using TMPro;
using UnityEngine;
-using static SolastaUnfinishedBusiness.Api.DatabaseHelper.WeaponTypeDefinitions;
namespace SolastaUnfinishedBusiness.Patches;
@@ -25,15 +23,22 @@ public static void Postfix(CharacterActionItemForm __instance)
{
//PATCH: make caption on small form wrap, instead of truncating
//TODO: do we need a setting to control this?
- if (__instance.highSlotNumber == null)
+ TMP_Text tmpText;
+ if (__instance.highSlotNumber == null && (tmpText = __instance.captionLabel.tmpText) != null)
{
- var tmpText = __instance.captionLabel.tmpText;
-
tmpText.enableWordWrapping = true;
tmpText.alignment = TextAlignmentOptions.Bottom;
tmpText.overflowMode = TextOverflowModes.Overflow;
}
+ //PATCH: disable word wrapping for attack number
+ //useful when you have Spell Points enabled and have 100+ of them, not noticeable otherwise
+ var attacks = __instance.attacksNumberValue;
+ if (attacks != null && (tmpText = attacks.tmpText) != null)
+ {
+ tmpText.enableWordWrapping = false;
+ }
+
//PATCH: Get dynamic properties from forced attack
if (__instance.guiCharacterAction.forcedAttackMode == null)
{
@@ -51,12 +56,13 @@ public static void Postfix(CharacterActionItemForm __instance)
[UsedImplicitly]
public static class Refresh_Patch
{
+ internal const string HideAttacksNumberOnActionPanel = "HideAttacksNumberOnActionPanel";
+
[UsedImplicitly]
public static void Postfix(CharacterActionItemForm __instance)
{
//PATCH: supports Way of Zen Archery flurry of arrows to not display max attack numbers on action button
- if (__instance.currentAttackMode.ActionType == ActionDefinitions.ActionType.Bonus &&
- ValidatorsWeapon.IsOfWeaponType(LongbowType, ShortbowType)(__instance.currentAttackMode, null, null))
+ if (__instance.currentAttackMode.AttackTags.Contains(HideAttacksNumberOnActionPanel))
{
__instance.attacksNumberGroup.gameObject.SetActive(false);
}
diff --git a/SolastaUnfinishedBusiness/Patches/CharacterActionMagicEffectPatcher.cs b/SolastaUnfinishedBusiness/Patches/CharacterActionMagicEffectPatcher.cs
index 8fcab7b565..a146537c1f 100644
--- a/SolastaUnfinishedBusiness/Patches/CharacterActionMagicEffectPatcher.cs
+++ b/SolastaUnfinishedBusiness/Patches/CharacterActionMagicEffectPatcher.cs
@@ -21,6 +21,9 @@ namespace SolastaUnfinishedBusiness.Patches;
[UsedImplicitly]
public static class CharacterActionMagicEffectPatcher
{
+ internal static readonly List CoveredFloorPositions = [];
+ internal static readonly List AffectedFloorPositions = [];
+
[HarmonyPatch(typeof(CharacterActionMagicEffect), nameof(CharacterActionMagicEffect.MagicEffectExecuteOnPositions))]
[UsedImplicitly]
public static class MagicEffectExecuteOnPositions_Patch
@@ -577,6 +580,9 @@ private static IEnumerator ExecuteImpl(CharacterActionMagicEffect __instance)
actionParams.HasMagneticTargeting,
actingCharacter,
coveredPositions,
+ CoveredFloorPositions,
+ null,
+ AffectedFloorPositions,
groundOnly: effectDescription.AffectOnlyGround);
}
@@ -897,6 +903,18 @@ private static IEnumerator ExecuteImpl(CharacterActionMagicEffect __instance)
magicEffectFinishedByMe.OnMagicEffectFinishedByMe(__instance, actingCharacter, targets);
}
+ //PATCH: supports `IMagicEffectFinishedByMe` on metamagic
+ if (hero != null)
+ {
+ foreach (var magicEffectFinishedByMe in hero.TrainedMetamagicOptions
+ .SelectMany(metamagic =>
+ metamagic.GetAllSubFeaturesOfType()))
+ {
+ yield return
+ magicEffectFinishedByMe.OnMagicEffectFinishedByMe(__instance, actingCharacter, targets);
+ }
+ }
+
//PATCH: support for `IMagicEffectFinishedOnMe`
foreach (var target in targets)
{
@@ -951,7 +969,7 @@ private static IEnumerator ExecuteImpl(CharacterActionMagicEffect __instance)
else
{
ServiceRepository.GetService()
- .ExecuteAction(actionParam, null, false);
+ .ExecuteAction(actionParam, null, true);
}
}
}
@@ -988,7 +1006,7 @@ private static IEnumerator ExecuteMagicAttack(
CharacterActionMagicEffect __instance,
RulesetEffect rulesetEffect,
GameLocationCharacter target,
- ActionModifier attackModifier,
+ ActionModifier actionModifier,
List actualEffectForms,
bool firstTarget,
bool checkMagicalAttackDamage)
@@ -1031,7 +1049,7 @@ private static IEnumerator ExecuteMagicAttack(
rulesetEffect,
actingCharacter,
target,
- attackModifier,
+ actionModifier,
firstTarget,
checkMagicalAttackDamage);
}
@@ -1045,10 +1063,10 @@ private static IEnumerator ExecuteMagicAttack(
rulesetEffect,
rulesetTarget,
rulesetEffect.GetEffectSource(),
- attackModifier.AttacktoHitTrends,
- attackModifier.AttackAdvantageTrends,
+ actionModifier.AttacktoHitTrends,
+ actionModifier.AttackAdvantageTrends,
false,
- attackModifier.AttackRollModifier,
+ actionModifier.AttackRollModifier,
out var outcome,
out var successDelta,
-1,
@@ -1060,7 +1078,7 @@ private static IEnumerator ExecuteMagicAttack(
if (__instance.AttackRollOutcome == RollOutcome.Failure)
{
yield return battleManager.HandleBardicInspirationForAttack(
- __instance, actingCharacter, target, attackModifier);
+ __instance, actingCharacter, target, actionModifier);
// BEGIN PATCH
@@ -1078,7 +1096,7 @@ private static IEnumerator ExecuteMagicAttack(
//PATCH: support for `ITryAlterOutcomeAttack`
foreach (var tryAlterOutcomeAttack in TryAlterOutcomeAttack.HandlerNegativePriority(
- battleManager, __instance, actingCharacter, target, attackModifier, null,
+ battleManager, __instance, actingCharacter, target, actionModifier, null,
rulesetEffect))
{
yield return tryAlterOutcomeAttack;
@@ -1097,7 +1115,7 @@ private static IEnumerator ExecuteMagicAttack(
target,
null,
rulesetEffect,
- attackModifier,
+ actionModifier,
__instance.AttackRoll,
__instance.AttackSuccessDelta,
effectDescription.RangeType == RangeType.RangeHit);
@@ -1105,7 +1123,7 @@ private static IEnumerator ExecuteMagicAttack(
//PATCH: support for `ITryAlterOutcomeAttack`
foreach (var tryAlterOutcomeAttack in TryAlterOutcomeAttack.HandlerNonNegativePriority(
- battleManager, __instance, actingCharacter, target, attackModifier, null,
+ battleManager, __instance, actingCharacter, target, actionModifier, null,
rulesetEffect))
{
yield return tryAlterOutcomeAttack;
@@ -1117,10 +1135,10 @@ private static IEnumerator ExecuteMagicAttack(
rulesetEffect,
rulesetTarget,
rulesetEffect.GetEffectSource(),
- attackModifier.AttacktoHitTrends,
- attackModifier.AttackAdvantageTrends,
+ actionModifier.AttacktoHitTrends,
+ actionModifier.AttackAdvantageTrends,
false,
- attackModifier.AttackRollModifier,
+ actionModifier.AttackRollModifier,
out outcome,
out successDelta,
__instance.AttackRoll,
@@ -1138,7 +1156,7 @@ private static IEnumerator ExecuteMagicAttack(
__instance,
actingCharacter,
target,
- attackModifier,
+ actionModifier,
rulesetEffect,
actualEffectForms,
firstTarget,
@@ -1152,9 +1170,9 @@ private static IEnumerator ExecuteMagicAttack(
rulesetEffect,
rulesetTarget,
rulesetEffect.GetEffectSource(),
- attackModifier.AttacktoHitTrends,
- attackModifier.AttackAdvantageTrends,
- false, attackModifier.AttackRollModifier,
+ actionModifier.AttacktoHitTrends,
+ actionModifier.AttackAdvantageTrends,
+ false, actionModifier.AttackRollModifier,
out outcome,
out successDelta,
__instance.AttackRoll,
@@ -1176,7 +1194,7 @@ private static IEnumerator ExecuteMagicAttack(
__instance,
actingCharacter,
target,
- attackModifier,
+ actionModifier,
rulesetEffect,
actualEffectForms,
firstTarget,
@@ -1194,41 +1212,45 @@ private static IEnumerator ExecuteMagicAttack(
if (rulesetEffect.EffectDescription.RecurrentEffect == RecurrentEffect.No ||
(rulesetEffect.EffectDescription.RecurrentEffect & RecurrentEffect.OnActivation) != 0)
{
+ // Saving throw?
var hasBorrowedLuck = rulesetTarget.HasConditionOfTypeOrSubType(ConditionBorrowedLuck);
__instance.RolledSaveThrow = rulesetEffect.TryRollSavingThrow(
actingCharacter.RulesetCharacter,
actingCharacter.Side,
rulesetTarget,
- attackModifier,
+ actionModifier,
actualEffectForms,
hasSavingThrowAnimation,
out var saveOutcome,
out var saveOutcomeDelta);
+
__instance.SaveOutcome = saveOutcome;
__instance.SaveOutcomeDelta = saveOutcomeDelta;
- rulesetTarget.GrantConditionOnSavingThrowOutcome(
- rulesetEffect.EffectDescription, saveOutcome, false);
-
- // Legendary Resistance or Indomitable?
- if (__instance.RolledSaveThrow && __instance.SaveOutcome == RollOutcome.Failure)
+ if (__instance.RolledSaveThrow)
{
- yield return battleManager.HandleFailedSavingThrow(
- __instance,
+ var savingThrowData = new SavingThrowData
+ {
+ SaveActionModifier = actionModifier,
+ SaveOutcome = __instance.SaveOutcome,
+ SaveOutcomeDelta = __instance.SaveOutcomeDelta,
+ SaveDC = RulesetActorExtensions.SaveDC,
+ SaveBonusAndRollModifier = RulesetActorExtensions.SaveBonusAndRollModifier,
+ SavingThrowAbility = RulesetActorExtensions.SavingThrowAbility,
+ SourceDefinition = null,
+ EffectDescription = rulesetEffect.EffectDescription,
+ Title = __instance.FormatTitle(),
+ Action = __instance
+ };
+
+ yield return TryAlterOutcomeSavingThrow.Handler(
+ battleManager,
actingCharacter,
target,
- attackModifier,
- !needToRollDie,
- hasBorrowedLuck);
- }
-
- //PATCH: support for `ITryAlterOutcomeSavingThrow`
- foreach (var tryAlterOutcomeSavingThrow in TryAlterOutcomeSavingThrow.Handler(
- battleManager, __instance, actingCharacter, target, attackModifier, false,
- hasBorrowedLuck))
- {
- yield return tryAlterOutcomeSavingThrow;
+ savingThrowData,
+ hasBorrowedLuck,
+ rulesetEffect.EffectDescription);
}
}
}
@@ -1241,13 +1263,13 @@ private static IEnumerator ExecuteMagicAttack(
rulesetTarget.matchingInterruption = true;
rulesetTarget.matchingInterruptionConditions.Clear();
- foreach (var rulesetCondition in rulesetTarget.conditionsByCategory
- .SelectMany(keyValuePair => keyValuePair.Value
- .Where(rulesetCondition =>
- rulesetCondition.ConditionDefinition.HasSpecialInterruptionOfType(
- (ConditionInterruption)ExtraConditionInterruption
- .AfterWasAttackedNotBySource) &&
- rulesetCondition.SourceGuid != actingCharacter.Guid)))
+ foreach (var rulesetCondition in rulesetTarget.ConditionsByCategory
+ .SelectMany(x => x.Value)
+ .Where(rulesetCondition =>
+ rulesetCondition.ConditionDefinition.HasSpecialInterruptionOfType(
+ (ConditionInterruption)ExtraConditionInterruption
+ .AfterWasAttackedNotBySource) &&
+ rulesetCondition.SourceGuid != actingCharacter.Guid))
{
rulesetTarget.matchingInterruptionConditions.Add(rulesetCondition);
}
@@ -1283,7 +1305,8 @@ private static IEnumerator ExecuteMagicAttack(
yield break;
}
- var abilityCheckData = new AbilityCheckData { AbilityCheckActionModifier = new ActionModifier() };
+ var abilityCheckData =
+ new AbilityCheckData { AbilityCheckActionModifier = new ActionModifier(), Action = __instance };
yield return TryAlterOutcomeAttributeCheck.ResolveRolls(
actingCharacter, target, ActionDefinitions.Id.Shove, abilityCheckData);
diff --git a/SolastaUnfinishedBusiness/Patches/CharacterActionMoveStepClimbPatcher.cs b/SolastaUnfinishedBusiness/Patches/CharacterActionMoveStepClimbPatcher.cs
new file mode 100644
index 0000000000..89261681f8
--- /dev/null
+++ b/SolastaUnfinishedBusiness/Patches/CharacterActionMoveStepClimbPatcher.cs
@@ -0,0 +1,315 @@
+using System;
+using System.Collections;
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using HarmonyLib;
+using JetBrains.Annotations;
+using SolastaUnfinishedBusiness.Interfaces;
+using UnityEngine;
+using Coroutine = TA.Coroutine;
+
+namespace SolastaUnfinishedBusiness.Patches;
+
+[UsedImplicitly]
+public static class CharacterActionMoveStepClimbPatcher
+{
+ //PATCH: allow check reactions on climb checks regardless of success / failure
+ [HarmonyPatch(typeof(CharacterActionMoveStepClimb), nameof(CharacterActionMoveStepClimb.ExecuteImpl))]
+ [SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Patch")]
+ [UsedImplicitly]
+ public static class ExecuteImpl_Patch
+ {
+ [UsedImplicitly]
+ public static bool Prefix(ref IEnumerator __result, CharacterActionMoveStepClimb __instance)
+ {
+ __result = Process(__instance);
+
+ return false;
+ }
+
+ private static IEnumerator Process(CharacterActionMoveStepClimb action)
+ {
+ var actingCharacter = action.ActingCharacter;
+ var actionModifier = action.ActionParams.ActionModifiers[0];
+ var battleService = ServiceRepository.GetService();
+ var positioningService = ServiceRepository.GetService();
+ var actionService = ServiceRepository.GetService();
+
+ yield return CharacterActionStandUp.StandUp(actingCharacter, true);
+
+ var moveCost = 0;
+
+ if (action.ActionId == ActionDefinitions.Id.TacticalMove)
+ {
+ moveCost += action.MovePath.Sum(pathStep => pathStep.moveCost);
+ }
+
+ if (moveCost == 0 && action.dc > 0)
+ {
+ moveCost = CharacterActionMoveStepClimb.ComputeClimbingCost(
+ actingCharacter, action.startPosition, action.landingPosition);
+ }
+
+ yield return action.WaitForCanMove(action.landingPosition, actingCharacter.Orientation, moveCost);
+
+ if (action.CanMove)
+ {
+ if (actingCharacter.LocationPosition == action.startPosition)
+ {
+ var fastClimber = false;
+ var flag = actingCharacter.CanMoveInSituation(RulesetCharacter.MotionRange.ExpertClimber);
+
+ // ReSharper disable once ForeachCanBePartlyConvertedToQueryUsingAnotherGetEnumerator
+ foreach (var movementModifier in action.ActionParams.ActingCharacter.RulesetCharacter
+ .GetMovementModifiers())
+ {
+ if ((movementModifier as IMovementAffinityProvider).FastClimber)
+ {
+ fastClimber = true;
+ }
+ }
+
+ var num1 = action.dc > 0 ? 1 : 0;
+ var failed = false;
+ var criticalFail = false;
+ var offset = action.landingPosition - action.startPosition;
+ var num2 = Mathf.Abs(offset.y);
+
+ if (num1 != 0 &&
+ !flag &&
+ num2 > 1 &&
+ !action.easyClimb &&
+ !actingCharacter.RulesetCharacter.MoveModes.ContainsKey(1))
+ {
+ const RuleDefinitions.AdvantageType BASE_AFFINITY = RuleDefinitions.AdvantageType.None;
+
+ var abilityCheckRoll = actingCharacter.RollAbilityCheck(
+ AttributeDefinitions.Strength,
+ SkillDefinitions.Athletics,
+ action.dc,
+ BASE_AFFINITY,
+ actionModifier,
+ false,
+ -1,
+ out var outcome,
+ out var successDelta,
+ true);
+
+ var abilityCheckData = new AbilityCheckData
+ {
+ AbilityCheckRoll = abilityCheckRoll,
+ AbilityCheckRollOutcome = outcome,
+ AbilityCheckSuccessDelta = successDelta,
+ AbilityCheckActionModifier = actionModifier,
+ Action = action
+ };
+
+ yield return TryAlterOutcomeAttributeCheck
+ .HandleITryAlterOutcomeAttributeCheck(actingCharacter, abilityCheckData);
+
+ action.AbilityCheckRoll = abilityCheckData.AbilityCheckRoll;
+ action.AbilityCheckRollOutcome = abilityCheckData.AbilityCheckRollOutcome;
+ action.AbilityCheckSuccessDelta = abilityCheckData.AbilityCheckSuccessDelta;
+
+ if (action.AbilityCheckRollOutcome == RuleDefinitions.RollOutcome.Failure)
+ {
+ failed = true;
+ criticalFail = outcome == RuleDefinitions.RollOutcome.CriticalFailure;
+ }
+ }
+
+ var climbingDirection = action.landingPosition.y > action.startPosition.y ? 1f : -1f;
+ var failAltitude = 0;
+ var orientation = offset.x != 0 || offset.z != 0
+ ? climbingDirection <= 0.0
+ ? positioningService.GetLocationOrientationFromTo(
+ action.landingPosition, action.startPosition)
+ : positioningService.GetLocationOrientationFromTo(
+ action.startPosition, action.landingPosition)
+ : actingCharacter.Orientation;
+ var canMove = true;
+
+ actingCharacter.TurnTowards(orientation);
+
+ yield return actingCharacter.EventSystem.UpdateMotionsAndWaitForEvent(
+ GameLocationCharacterEventSystem.Event.RotationEnd);
+
+ if (action.ActionId == ActionDefinitions.Id.TacticalMove)
+ {
+ yield return battleService.HandleCharacterMoveStart(
+ actingCharacter, action.landingPosition);
+ }
+
+ if (!actingCharacter.CanContinueMoving(action.ActionId))
+ {
+ action.MovePath.Clear();
+ action.Abort(CharacterAction.InterruptionType.Failed);
+ }
+ else
+ {
+ if (failed)
+ {
+ var num3 = climbingDirection > 0.0
+ ? action.landingPosition.y - 1
+ : action.startPosition.y - 1;
+ var min = climbingDirection > 0.0
+ ? action.startPosition.y + 1
+ : action.landingPosition.y + 1;
+ failAltitude = min != num3
+ ? criticalFail ? num3 : RandomExtensions.RangeInclusive(min, num3 - 1, true)
+ : num3;
+ }
+
+ var climbPosition = climbingDirection <= 0.0 ? action.landingPosition : action.startPosition;
+
+ actingCharacter.Climbing = true;
+
+ if (action.abortASAP && battleService.IsBattleInProgress)
+ {
+ action.abortASAP = false;
+ }
+
+ var y = action.startPosition.y + (int)climbingDirection;
+ while (Math.Abs(y - (action.landingPosition.y + (double)climbingDirection)) > 0 &&
+ !action.abortASAP)
+ {
+ var time = 0.0f;
+
+ climbPosition.y = y;
+
+ for (canMove = positioningService.CanPlaceCharacter(
+ actingCharacter, climbPosition, CellHelpers.PlacementMode.OnTheMove);
+ !canMove && time < 2.0;
+ canMove = positioningService.CanPlaceCharacter(actingCharacter, climbPosition,
+ CellHelpers.PlacementMode.OnTheMove))
+ {
+ actingCharacter.StopMoving(orientation);
+
+ yield return Coroutine.WaitForSeconds(0.2f);
+
+ time += 0.2f;
+ }
+
+ if (canMove)
+ {
+ var lastMove = y == action.landingPosition.y;
+
+ if (lastMove)
+ {
+ climbPosition = action.landingPosition;
+ }
+
+ actingCharacter.StartClimbTo(
+ climbPosition, orientation, climbingDirection, lastMove, fastClimber);
+
+ yield return actingCharacter.EventSystem.UpdateMotionsAndWaitForEvent(
+ GameLocationCharacterEventSystem.Event.MovementStepEnd);
+
+ if (failed && y == failAltitude)
+ {
+ if (battleService.HasBattleStarted)
+ {
+ actingCharacter.UsedTacticalMoves += moveCost;
+ }
+
+ action.Abort(CharacterAction.InterruptionType.Failed);
+ actingCharacter.Climbing = false;
+ actingCharacter.FinishMoveTo(climbPosition, orientation);
+
+ yield break;
+ }
+
+ actingCharacter.FinishMoveTo(climbPosition, orientation);
+ y += climbingDirection > 0.0 ? 1 : -1;
+
+ if (action.abortASAP && battleService.IsBattleInProgress)
+ {
+ action.abortASAP = false;
+ }
+
+ if (action.abortASAP &&
+ !actingCharacter.RulesetCharacter.IsDeadOrDyingOrUnconscious &&
+ GameLocationCharacter.IsValidCharacter(actingCharacter))
+ {
+ var wait = true;
+ var timeout = 1f;
+ while (wait)
+ {
+ if (actionService.CanMovementQueuedActionProceed(actingCharacter,
+ PathfindingNode.InformationFlag.Climbing, out var result))
+ {
+ wait = false;
+
+ if (result)
+ {
+ continue;
+ }
+
+ actionService.CancelMovementWarmUp(actingCharacter);
+ action.abortASAP = false;
+ }
+ else
+ {
+ yield return Coroutine.WaitForSeconds(0.1f);
+ timeout -= 0.1f;
+
+ if (timeout > 0)
+ {
+ continue;
+ }
+
+ actionService.CancelMovementWarmUp(actingCharacter);
+ wait = false;
+ action.abortASAP = false;
+ }
+ }
+ }
+
+ if (action.abortASAP && battleService.IsBattleInProgress)
+ {
+ action.abortASAP = false;
+ }
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (canMove && !failed && action.landingPosition == actingCharacter.LocationPosition)
+ {
+ action.abortASAP = false;
+
+ if (battleService.HasBattleStarted)
+ {
+ actingCharacter.UsedTacticalMoves += moveCost;
+ }
+
+ actingCharacter.SignalClimbFinished(
+ action.startPosition, action.landingPosition, action.easyClimb);
+ actingCharacter.FinishMoveTo(action.landingPosition, orientation);
+ }
+
+ if (action.ActionId == ActionDefinitions.Id.TacticalMove)
+ {
+ yield return battleService.HandleCharacterMoveEnd(actingCharacter);
+ }
+ }
+ }
+ }
+ else
+ {
+ action.MovePath.Clear();
+ action.Abort(CharacterAction.InterruptionType.Failed);
+ }
+
+ if (!action.abortASAP)
+ {
+ actingCharacter.Climbing = false;
+ actingCharacter.CheckCharacterFooting(false);
+ }
+
+ action.CheckAndProcessMovementFinished();
+ }
+ }
+}
diff --git a/SolastaUnfinishedBusiness/Patches/CharacterActionMoveStepJumpPatcher.cs b/SolastaUnfinishedBusiness/Patches/CharacterActionMoveStepJumpPatcher.cs
new file mode 100644
index 0000000000..53644945e7
--- /dev/null
+++ b/SolastaUnfinishedBusiness/Patches/CharacterActionMoveStepJumpPatcher.cs
@@ -0,0 +1,107 @@
+using System.Collections;
+using System.Diagnostics.CodeAnalysis;
+using HarmonyLib;
+using JetBrains.Annotations;
+using SolastaUnfinishedBusiness.Interfaces;
+
+namespace SolastaUnfinishedBusiness.Patches;
+
+[UsedImplicitly]
+public static class CharacterActionMoveStepJumpPatcher
+{
+ //PATCH: allow check reactions on jump checks regardless of success / failure
+ [HarmonyPatch(typeof(CharacterActionMoveStepJump), nameof(CharacterActionMoveStepJump.RollChecksIfNecessary))]
+ [SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Patch")]
+ [UsedImplicitly]
+ public static class RollChecksIfNecessary_Patch
+ {
+ [UsedImplicitly]
+ public static bool Prefix(ref IEnumerator __result, CharacterActionMoveStepJump __instance)
+ {
+ __result = Process(__instance);
+
+ return false;
+ }
+
+ private static IEnumerator Process(CharacterActionMoveStepJump action)
+ {
+ var actingCharacter = action.ActingCharacter;
+ var actionModifier = action.ActionParams.ActionModifiers[0];
+
+ if (CharacterActionMoveStepJump.NeedsAcrobaticsCheck(action.landingPosition))
+ {
+ const int CHECK_DC = 10;
+ const RuleDefinitions.AdvantageType BASE_AFFINITY = RuleDefinitions.AdvantageType.None;
+
+ var abilityCheckRoll = actingCharacter.RollAbilityCheck(
+ AttributeDefinitions.Dexterity,
+ SkillDefinitions.Acrobatics,
+ CHECK_DC,
+ BASE_AFFINITY,
+ actionModifier,
+ false,
+ -1,
+ out var outcome,
+ out var successDelta,
+ true);
+
+ var abilityCheckData = new AbilityCheckData
+ {
+ AbilityCheckRoll = abilityCheckRoll,
+ AbilityCheckRollOutcome = outcome,
+ AbilityCheckSuccessDelta = successDelta,
+ AbilityCheckActionModifier = actionModifier,
+ Action = action
+ };
+
+ yield return TryAlterOutcomeAttributeCheck
+ .HandleITryAlterOutcomeAttributeCheck(actingCharacter, abilityCheckData);
+
+ action.AbilityCheckRoll = abilityCheckData.AbilityCheckRoll;
+ action.AbilityCheckRollOutcome = abilityCheckData.AbilityCheckRollOutcome;
+ action.AbilityCheckSuccessDelta = abilityCheckData.AbilityCheckSuccessDelta;
+ }
+
+ if (action.AbilityCheckRollOutcome != RuleDefinitions.RollOutcome.Failure &&
+ CharacterActionMoveStepJump.NeedsAthleticsCheck(action.ActingCharacter, action.jumpPosition,
+ action.landingPosition))
+ {
+ const int CHECK_DC = 15;
+ const RuleDefinitions.AdvantageType BASE_AFFINITY = RuleDefinitions.AdvantageType.None;
+
+ var abilityCheckRoll = action.ActingCharacter.RollAbilityCheck(
+ AttributeDefinitions.Strength,
+ SkillDefinitions.Athletics,
+ CHECK_DC,
+ BASE_AFFINITY,
+ action.ActionParams.ActionModifiers[0],
+ false,
+ -1,
+ out var outcome,
+ out var successDelta,
+ true);
+
+ var abilityCheckData = new AbilityCheckData
+ {
+ AbilityCheckRoll = abilityCheckRoll,
+ AbilityCheckRollOutcome = outcome,
+ AbilityCheckSuccessDelta = successDelta,
+ AbilityCheckActionModifier = actionModifier,
+ Action = action
+ };
+
+ yield return TryAlterOutcomeAttributeCheck
+ .HandleITryAlterOutcomeAttributeCheck(actingCharacter, abilityCheckData);
+
+ action.AbilityCheckRoll = abilityCheckData.AbilityCheckRoll;
+ action.AbilityCheckRollOutcome = abilityCheckData.AbilityCheckRollOutcome;
+ action.AbilityCheckSuccessDelta = abilityCheckData.AbilityCheckSuccessDelta;
+ }
+ else if (CharacterActionMoveStepJump.AutomaticPenalty(
+ action.ActingCharacter, action.jumpPosition, action.landingPosition))
+ {
+ action.AbilityCheckRollOutcome = RuleDefinitions.RollOutcome.Failure;
+ }
+ }
+ }
+}
diff --git a/SolastaUnfinishedBusiness/Patches/CharacterActionPanelPatcher.cs b/SolastaUnfinishedBusiness/Patches/CharacterActionPanelPatcher.cs
index 2dd4b37bff..fee3c0d45a 100644
--- a/SolastaUnfinishedBusiness/Patches/CharacterActionPanelPatcher.cs
+++ b/SolastaUnfinishedBusiness/Patches/CharacterActionPanelPatcher.cs
@@ -292,25 +292,11 @@ public static class SelectBreakFreeMode_Patch
public static bool Prefix(CharacterActionPanel __instance)
{
var rulesetCharacter = __instance.GuiCharacter.RulesetCharacter;
+ var restrainingCondition = AiContext.GetRestrainingCondition(rulesetCharacter);
- RulesetCondition restrainingCondition = null;
-
- rulesetCharacter.EnumerateFeaturesToBrowse(
- rulesetCharacter.FeaturesToBrowse);
-
- foreach (var definitionActionAffinity in rulesetCharacter.FeaturesToBrowse
- .Cast()
- .Where(definitionActionAffinity => definitionActionAffinity.AuthorizedActions
- .Contains(ActionDefinitions.Id.BreakFree)))
- {
- restrainingCondition = rulesetCharacter.FindFirstConditionHoldingFeature(definitionActionAffinity);
- }
-
- if (restrainingCondition?.ConditionDefinition.Name is not
- ("ConditionVileBrew" or
- "ConditionGrappledRestrainedIceBound" or
- "ConditionGrappledRestrainedSpellWeb" or
- "ConditionRestrainedByEntangle"))
+ // if not a modded strength check condition let vanilla handle
+ // this works as so far there is no way an ally should be forced to do a DoWisdomCheckAgainstCasterDC
+ if (restrainingCondition?.Amount != (int)AiContext.BreakFreeType.DoStrengthCheckAgainstCasterDC)
{
return true;
}
diff --git a/SolastaUnfinishedBusiness/Patches/CharacterActionPatcher.cs b/SolastaUnfinishedBusiness/Patches/CharacterActionPatcher.cs
index bbfe811371..c8183e5ce5 100644
--- a/SolastaUnfinishedBusiness/Patches/CharacterActionPatcher.cs
+++ b/SolastaUnfinishedBusiness/Patches/CharacterActionPatcher.cs
@@ -239,11 +239,11 @@ public static IEnumerator Postfix(IEnumerator values, CharacterAction __instance
}
}
- //PATCH: support for Circle of the Wildfire cauterizing flames
if (__instance is CharacterActionShove)
{
foreach (var targetCharacter in __instance.ActionParams.TargetCharacters)
{
+ //PATCH: support for Circle of the Wildfire cauterizing flames
yield return CircleOfTheWildfire.HandleCauterizingFlamesBehavior(targetCharacter);
}
}
diff --git a/SolastaUnfinishedBusiness/Patches/CharacterActionRecklessPatcher.cs b/SolastaUnfinishedBusiness/Patches/CharacterActionRecklessPatcher.cs
index 3c86aaf100..cba09a5f5a 100644
--- a/SolastaUnfinishedBusiness/Patches/CharacterActionRecklessPatcher.cs
+++ b/SolastaUnfinishedBusiness/Patches/CharacterActionRecklessPatcher.cs
@@ -62,8 +62,6 @@ private static IEnumerator Process(
action.ActingCharacter.RulesetCharacter.AddConditionOfCategory(
AttributeDefinitions.TagCombat, activeCondition2);
-
- yield return null;
}
}
}
diff --git a/SolastaUnfinishedBusiness/Patches/CharacterActionShovePatcher.cs b/SolastaUnfinishedBusiness/Patches/CharacterActionShovePatcher.cs
index fe79efe423..c7d2f3fc16 100644
--- a/SolastaUnfinishedBusiness/Patches/CharacterActionShovePatcher.cs
+++ b/SolastaUnfinishedBusiness/Patches/CharacterActionShovePatcher.cs
@@ -31,7 +31,10 @@ private static IEnumerator Execute(CharacterActionShove characterActionShove)
var isTopple = characterActionShove.ActionParams.BoolParameter;
var isSameSide = actingCharacter.Side == target.Side;
var isIncapacitated = target.RulesetCharacter.IsIncapacitated;
- var abilityCheckData = new AbilityCheckData { AbilityCheckActionModifier = new ActionModifier() };
+ var abilityCheckData = new AbilityCheckData
+ {
+ AbilityCheckActionModifier = new ActionModifier(), Action = characterActionShove
+ };
//BEGIN PATCH
// original code
diff --git a/SolastaUnfinishedBusiness/Patches/CharacterActionSpendPowerPatcher.cs b/SolastaUnfinishedBusiness/Patches/CharacterActionSpendPowerPatcher.cs
index d9d0ae9dfd..628f7174bf 100644
--- a/SolastaUnfinishedBusiness/Patches/CharacterActionSpendPowerPatcher.cs
+++ b/SolastaUnfinishedBusiness/Patches/CharacterActionSpendPowerPatcher.cs
@@ -110,11 +110,14 @@ private static IEnumerator ExecuteImpl(CharacterActionSpendPower __instance)
// END PATCH
}
- else
+ else if (activePower != null)
{
actingCharacter.RulesetCharacter.UseDevicePower(activePower.OriginItem, activePower.PowerDefinition);
}
+ actingCharacter.RulesetCharacter.ProcessConditionsMatchingInterruption(
+ (RuleDefinitions.ConditionInterruption)ExtraConditionInterruption.SpendPower);
+
for (var i = 0; i < targets.Count; i++)
{
var target = targets[i];
@@ -126,13 +129,15 @@ private static IEnumerator ExecuteImpl(CharacterActionSpendPower __instance)
if (activePower != null)
{
__instance.RolledSaveThrow = activePower.TryRollSavingThrow(
- actingCharacter.RulesetCharacter, actingCharacter.Side,
+ actingCharacter.RulesetCharacter,
+ actingCharacter.Side,
target.RulesetActor,
actionModifier,
activePower.EffectDescription.EffectForms,
false,
out var saveOutcome,
out var saveOutcomeDelta);
+
__instance.SaveOutcome = saveOutcome;
__instance.SaveOutcomeDelta = saveOutcomeDelta;
@@ -141,20 +146,27 @@ private static IEnumerator ExecuteImpl(CharacterActionSpendPower __instance)
if (__instance.RolledSaveThrow)
{
- // Legendary Resistance or Indomitable?
- if (__instance.SaveOutcome == RuleDefinitions.RollOutcome.Failure)
- {
- yield return battleManager.HandleFailedSavingThrow(
- __instance, actingCharacter, target, actionModifier, false, hasBorrowedLuck);
- }
-
- //PATCH: support for `ITryAlterOutcomeSavingThrow`
- foreach (var tryAlterOutcomeSavingThrow in TryAlterOutcomeSavingThrow.Handler(
- battleManager, __instance, actingCharacter, target, actionModifier, false,
- hasBorrowedLuck))
+ var savingThrowData = new SavingThrowData
{
- yield return tryAlterOutcomeSavingThrow;
- }
+ SaveActionModifier = actionModifier,
+ SaveOutcome = __instance.SaveOutcome,
+ SaveOutcomeDelta = __instance.SaveOutcomeDelta,
+ SaveDC = RulesetActorExtensions.SaveDC,
+ SaveBonusAndRollModifier = RulesetActorExtensions.SaveBonusAndRollModifier,
+ SavingThrowAbility = RulesetActorExtensions.SavingThrowAbility,
+ SourceDefinition = null,
+ EffectDescription = rulesetEffect.EffectDescription,
+ Title = __instance.FormatTitle(),
+ Action = __instance
+ };
+
+ yield return TryAlterOutcomeSavingThrow.Handler(
+ battleManager,
+ actingCharacter,
+ target,
+ savingThrowData,
+ hasBorrowedLuck,
+ rulesetEffect.EffectDescription);
}
// Apply the forms of the power
@@ -232,6 +244,16 @@ private static IEnumerator ExecuteImpl(CharacterActionSpendPower __instance)
var targetCurrentHitPoints = target.RulesetCharacter.CurrentHitPoints;
//END BUGFIX
+ //BEGIN PATCH
+ var positions = __instance.ActionParams.Positions;
+
+ var sourceDefinition = activePower.SourceDefinition;
+ if (positions.Count != 0 && sourceDefinition.HasSubFeatureOfType())
+ {
+ applyFormsParams.position = positions[0];
+ }
+ // END PATCH
+
implementationService.ApplyEffectForms(
effectForms,
applyFormsParams,
@@ -343,9 +365,10 @@ private static IEnumerator ExecuteImpl(CharacterActionSpendPower __instance)
}
}
- __instance.PersistantEffectAction();
+ actingCharacter.RulesetCharacter.ProcessConditionsMatchingInterruption(
+ (RuleDefinitions.ConditionInterruption)ExtraConditionInterruption.SpendPowerExecuted);
- yield return null;
+ __instance.PersistantEffectAction();
}
}
}
diff --git a/SolastaUnfinishedBusiness/Patches/CharacterActionUsePowerPatcher.cs b/SolastaUnfinishedBusiness/Patches/CharacterActionUsePowerPatcher.cs
index aa0d42f9a2..c958c9c7d5 100644
--- a/SolastaUnfinishedBusiness/Patches/CharacterActionUsePowerPatcher.cs
+++ b/SolastaUnfinishedBusiness/Patches/CharacterActionUsePowerPatcher.cs
@@ -1,10 +1,12 @@
-using System.Diagnostics.CodeAnalysis;
+using System.Collections;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using HarmonyLib;
using JetBrains.Annotations;
using SolastaUnfinishedBusiness.Api.GameExtensions;
using SolastaUnfinishedBusiness.Behaviors;
using SolastaUnfinishedBusiness.Interfaces;
+using static RuleDefinitions;
namespace SolastaUnfinishedBusiness.Patches;
@@ -129,4 +131,155 @@ private static void CalculateExtraChargeUsage(
.ItemUsed?.Invoke(usableDevice.ItemDefinition.Name);
}
}
+
+ //PATCH: allow check reactions on cast spell regardless of success / failure
+ [HarmonyPatch(typeof(CharacterActionUsePower), nameof(CharacterActionUsePower.CounterEffectAction))]
+ [SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Patch")]
+ [UsedImplicitly]
+ public static class CounterEffectAction_Patch
+ {
+ [UsedImplicitly]
+ public static bool Prefix(
+ ref IEnumerator __result, CharacterActionUsePower __instance, CharacterAction counterAction)
+ {
+ __result = Process(__instance, counterAction);
+
+ return false;
+ }
+
+ private static IEnumerator Process(CharacterActionUsePower actionUsePower, CharacterAction counterAction)
+ {
+ if (actionUsePower.ActionParams.TargetAction == null)
+ {
+ yield break;
+ }
+
+ var actingCharacter = actionUsePower.ActingCharacter;
+ var rulesetCharacter = actingCharacter.RulesetCharacter;
+ var actionParams = actionUsePower.ActionParams.TargetAction.ActionParams;
+ var actionModifier = actionParams.ActionModifiers[0];
+
+ foreach (var effectForm in actionParams.RulesetEffect.EffectDescription.EffectForms)
+ {
+ if (effectForm.FormType != EffectForm.EffectFormType.Counter)
+ {
+ continue;
+ }
+
+ var counterForm = effectForm.CounterForm;
+ var counteredSpell = actionParams.TargetAction.ActionParams.RulesetEffect as RulesetEffectSpell;
+ var counteredSpellDefinition = counteredSpell!.SpellDefinition;
+ var slotLevel = counteredSpell.SlotLevel;
+
+ if (counterForm.AutomaticSpellLevel >= slotLevel)
+ {
+ actionUsePower.ActionParams.TargetAction.Countered = true;
+ }
+ else if (counterForm.CheckBaseDC != 0)
+ {
+ var checkDC = counterForm.CheckBaseDC + slotLevel;
+
+ rulesetCharacter
+ .EnumerateFeaturesToBrowse(rulesetCharacter.FeaturesToBrowse);
+
+ foreach (var featureDefinition in rulesetCharacter.FeaturesToBrowse)
+ {
+ var definitionMagicAffinity = (FeatureDefinitionMagicAffinity)featureDefinition;
+
+ if (definitionMagicAffinity.CounterspellAffinity == AdvantageType.None)
+ {
+ continue;
+ }
+
+ var advTrend = definitionMagicAffinity.CounterspellAffinity == AdvantageType.Advantage
+ ? 1
+ : -1;
+
+ actionModifier.AbilityCheckAdvantageTrends.Add(new TrendInfo(
+ advTrend, FeatureSourceType.CharacterFeature, definitionMagicAffinity.Name, null));
+ }
+
+ if (counteredSpell.CounterAffinity != AdvantageType.None)
+ {
+ var advTrend = counteredSpell.CounterAffinity == AdvantageType.Advantage
+ ? 1
+ : -1;
+
+ actionModifier.AbilityCheckAdvantageTrends
+ .Add(new TrendInfo(advTrend,
+ FeatureSourceType.CharacterFeature,
+ counteredSpell.CounterAffinityOrigin, null));
+ }
+
+ var abilityScoreName = AttributeDefinitions.Charisma;
+
+ foreach (var spellRepertoire in rulesetCharacter.SpellRepertoires
+ .Where(repertoire =>
+ repertoire.SpellCastingFeature.SpellCastingOrigin
+ is FeatureDefinitionCastSpell.CastingOrigin.Class
+ or FeatureDefinitionCastSpell.CastingOrigin.Subclass))
+ {
+ abilityScoreName = spellRepertoire.SpellCastingFeature.SpellcastingAbility;
+
+ break;
+ }
+
+ var proficiencyName = string.Empty;
+
+ if (counterForm.AddProficiencyBonus)
+ {
+ proficiencyName = "ForcedProficiency";
+ }
+
+ var abilityCheckRoll = actingCharacter.RollAbilityCheck(
+ abilityScoreName,
+ proficiencyName,
+ checkDC,
+ AdvantageType.None,
+ actionModifier,
+ false,
+ 0,
+ out var outcome,
+ out var successDelta,
+ true);
+
+ var abilityCheckData = new AbilityCheckData
+ {
+ AbilityCheckRoll = abilityCheckRoll,
+ AbilityCheckRollOutcome = outcome,
+ AbilityCheckSuccessDelta = successDelta,
+ AbilityCheckActionModifier = actionModifier,
+ Action = actionUsePower
+ };
+
+ yield return TryAlterOutcomeAttributeCheck
+ .HandleITryAlterOutcomeAttributeCheck(actingCharacter, abilityCheckData);
+
+ actionUsePower.AbilityCheckRoll = abilityCheckData.AbilityCheckRoll;
+ actionUsePower.AbilityCheckRollOutcome = abilityCheckData.AbilityCheckRollOutcome;
+ actionUsePower.AbilityCheckSuccessDelta = abilityCheckData.AbilityCheckSuccessDelta;
+
+ if (counterAction.AbilityCheckRollOutcome == RollOutcome.Success)
+ {
+ actionUsePower.ActionParams.TargetAction.Countered = true;
+ }
+ }
+
+ if (!actionParams.TargetAction.Countered ||
+ rulesetCharacter.SpellCounter == null)
+ {
+ continue;
+ }
+
+ var unknown = string.IsNullOrEmpty(counteredSpell.IdentifiedBy);
+
+ rulesetCharacter.SpellCounter(
+ rulesetCharacter,
+ actionUsePower.ActionParams.TargetAction.ActingCharacter.RulesetCharacter,
+ counteredSpellDefinition,
+ actionUsePower.ActionParams.TargetAction.Countered,
+ unknown);
+ }
+ }
+ }
}
diff --git a/SolastaUnfinishedBusiness/Patches/CharacterStageSpellSelectionPanelPatcher.cs b/SolastaUnfinishedBusiness/Patches/CharacterStageSpellSelectionPanelPatcher.cs
index 552c8dfa35..6ca2958d8a 100644
--- a/SolastaUnfinishedBusiness/Patches/CharacterStageSpellSelectionPanelPatcher.cs
+++ b/SolastaUnfinishedBusiness/Patches/CharacterStageSpellSelectionPanelPatcher.cs
@@ -7,6 +7,7 @@
using SolastaUnfinishedBusiness.Api.Helpers;
using SolastaUnfinishedBusiness.Models;
using UnityEngine;
+using UnityEngine.UI;
namespace SolastaUnfinishedBusiness.Patches;
@@ -47,5 +48,29 @@ public static IEnumerable Transpiler([NotNull] IEnumerable().rect.width;
+ var spacing = levelTable.GetComponent().spacing;
+ var totalWidth = 0f;
+ var lastWidth = 0f;
+ for (var i = 0; i < levelTable.childCount; ++i)
+ {
+ var child = levelTable.GetChild(i);
+ if (!child.gameObject.activeSelf) { continue; }
+
+ lastWidth = child.GetComponent().rect.width + spacing;
+ totalWidth += lastWidth;
+ }
+
+ levelTable.sizeDelta = new Vector2(
+ //totalWidth + (viewWidth - lastWidth), //original, adds just enough space to last level to make it fit
+ //but there's problem if there's more spells that can fit - do not add space then, as it is not needed
+ totalWidth + Math.Max(viewWidth - lastWidth, 0),
+ levelTable.sizeDelta.y);
+ }
}
}
diff --git a/SolastaUnfinishedBusiness/Patches/Considerations/ConsiderationsInfluenceEnemyProximityPatcher.cs b/SolastaUnfinishedBusiness/Patches/Considerations/ConsiderationsInfluenceEnemyProximityPatcher.cs
new file mode 100644
index 0000000000..5234d54009
--- /dev/null
+++ b/SolastaUnfinishedBusiness/Patches/Considerations/ConsiderationsInfluenceEnemyProximityPatcher.cs
@@ -0,0 +1,80 @@
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using HarmonyLib;
+using JetBrains.Annotations;
+using TA.AI;
+using TA.AI.Considerations;
+using UnityEngine;
+
+namespace SolastaUnfinishedBusiness.Patches.Considerations;
+
+[UsedImplicitly]
+public static class InfluenceEnemyProximityPatcher
+{
+ //PATCH: allows this influence to be reverted if enemy has StringParameter condition name
+ //used on Command Spell, approach command
+ [HarmonyPatch(typeof(InfluenceEnemyProximity), nameof(InfluenceEnemyProximity.Score))]
+ [SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Patch")]
+ [UsedImplicitly]
+ public static class Score_Patch
+ {
+ [UsedImplicitly]
+ public static bool Prefix(
+ DecisionContext context,
+ ConsiderationDescription consideration,
+ DecisionParameters parameters,
+ ScoringResult scoringResult)
+ {
+ Score(context, consideration, parameters, scoringResult);
+
+ return false;
+ }
+
+ // mainly vanilla code except for BEGIN/END blocks
+ private static void Score(
+ DecisionContext context,
+ ConsiderationDescription consideration,
+ DecisionParameters parameters,
+ ScoringResult scoringResult)
+ {
+ var character = parameters.character.GameLocationCharacter;
+ var rulesetCharacter = character.RulesetCharacter;
+ var denominator = consideration.IntParameter > 0 ? consideration.IntParameter : 1;
+ var floatParameter = consideration.FloatParameter;
+ var position = consideration.BoolParameter ? context.position : character.LocationPosition;
+ var numerator = 0.0f;
+
+ var approachSourceGuid = rulesetCharacter.ConditionsByCategory
+ .SelectMany(x => x.Value)
+ .FirstOrDefault(x =>
+ x.ConditionDefinition.Name == consideration.StringParameter)?.SourceGuid ?? 0;
+
+ // ReSharper disable once ForeachCanBePartlyConvertedToQueryUsingAnotherGetEnumerator
+ foreach (var enemy in parameters.situationalInformation.RelevantEnemies)
+ {
+ if (!AiLocationDefinitions.IsRelevantTargetForCharacter(
+ character, enemy, parameters.situationalInformation.HasRelevantPerceivedTarget))
+ {
+ continue;
+ }
+
+ var distance =
+ parameters.situationalInformation.PositioningService
+ .ComputeDistanceBetweenCharactersApproximatingSize(
+ parameters.character.GameLocationCharacter, position, enemy, enemy.LocationPosition);
+
+ //BEGIN PATCH
+ if (enemy.Guid == approachSourceGuid)
+ {
+ numerator += Mathf.Lerp(0.0f, 1f, Mathf.Clamp(distance / floatParameter, 0.0f, 1f));
+ continue;
+ }
+ //END PATCH
+
+ numerator += Mathf.Lerp(1f, 0.0f, Mathf.Clamp(distance / floatParameter, 0.0f, 1f));
+ }
+
+ scoringResult.Score = numerator / denominator;
+ }
+ }
+}
diff --git a/SolastaUnfinishedBusiness/Patches/Considerations/ConsiderationsInfluenceFearSourceProximityPatcher.cs b/SolastaUnfinishedBusiness/Patches/Considerations/ConsiderationsInfluenceFearSourceProximityPatcher.cs
new file mode 100644
index 0000000000..064499f3c0
--- /dev/null
+++ b/SolastaUnfinishedBusiness/Patches/Considerations/ConsiderationsInfluenceFearSourceProximityPatcher.cs
@@ -0,0 +1,115 @@
+using System.Diagnostics.CodeAnalysis;
+using System.Linq;
+using HarmonyLib;
+using JetBrains.Annotations;
+using TA.AI;
+using TA.AI.Considerations;
+using UnityEngine;
+
+namespace SolastaUnfinishedBusiness.Patches.Considerations;
+
+[UsedImplicitly]
+public static class InfluenceFearSourceProximityPatcher
+{
+ //PATCH: allows this influence to be reverted if enemy has StringParameter condition name
+ //used on Command Spell, approach command
+ [HarmonyPatch(typeof(InfluenceFearSourceProximity), nameof(InfluenceFearSourceProximity.Score))]
+ [SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Patch")]
+ [UsedImplicitly]
+ public static class Score_Patch
+ {
+ [UsedImplicitly]
+ public static bool Prefix(
+ DecisionContext context,
+ ConsiderationDescription consideration,
+ DecisionParameters parameters,
+ ScoringResult scoringResult)
+ {
+ Score(context, consideration, parameters, scoringResult);
+
+ return false;
+ }
+
+ // mainly vanilla code except for BEGIN/END blocks
+ private static void Score(
+ DecisionContext context,
+ ConsiderationDescription consideration,
+ DecisionParameters parameters,
+ ScoringResult scoringResult)
+ {
+ var character = parameters.character.GameLocationCharacter;
+ var rulesetCharacter = character.RulesetCharacter;
+ var denominator = consideration.IntParameter > 0 ? consideration.IntParameter : 1;
+ var floatParameter = consideration.FloatParameter;
+ var position = consideration.BoolParameter ? context.position : character.LocationPosition;
+ var numerator = 0.0f;
+
+ // prefer enumerate first to save some cycles
+ rulesetCharacter.GetAllConditions(rulesetCharacter.AllConditionsForEnumeration);
+
+ var approachSourceGuid = rulesetCharacter.AllConditionsForEnumeration
+ .FirstOrDefault(x =>
+ x.ConditionDefinition.Name == consideration.StringParameter)?.SourceGuid ?? 0;
+
+ foreach (var rulesetCondition in rulesetCharacter.AllConditionsForEnumeration
+ .Where(rulesetCondition =>
+ rulesetCondition.ConditionDefinition.ForceBehavior &&
+ rulesetCondition.ConditionDefinition.FearSource))
+ {
+ // ReSharper disable once ForeachCanBePartlyConvertedToQueryUsingAnotherGetEnumerator
+ foreach (var relevantEnemy in parameters.situationalInformation.RelevantEnemies)
+ {
+ if (relevantEnemy.Guid != rulesetCondition.SourceGuid)
+ {
+ continue;
+ }
+
+ var distance =
+ parameters.situationalInformation.PositioningService
+ .ComputeDistanceBetweenCharactersApproximatingSize(
+ parameters.character.GameLocationCharacter, position,
+ relevantEnemy, relevantEnemy.LocationPosition);
+
+ //BEGIN PATCH
+ if (relevantEnemy.Guid == approachSourceGuid)
+ {
+ numerator += Mathf.Lerp(0.0f, 1f, Mathf.Clamp(distance / floatParameter, 0.0f, 1f));
+ break;
+ }
+ //END PATCH
+
+ numerator += Mathf.Lerp(1f, 0.0f, Mathf.Clamp(distance / floatParameter, 0.0f, 1f));
+ break;
+ }
+
+ // ReSharper disable once ForeachCanBePartlyConvertedToQueryUsingAnotherGetEnumerator
+ foreach (var relevantAlly in parameters.situationalInformation.RelevantAllies)
+ {
+ if (relevantAlly.Guid != rulesetCondition.SourceGuid)
+ {
+ continue;
+ }
+
+ var distance =
+ parameters.situationalInformation.PositioningService
+ .ComputeDistanceBetweenCharactersApproximatingSize(
+ parameters.character.GameLocationCharacter, position, relevantAlly,
+ relevantAlly.LocationPosition);
+
+ //BEGIN PATCH
+ if (relevantAlly.Guid == approachSourceGuid)
+ {
+ numerator += Mathf.Lerp(0.0f, 1f, Mathf.Clamp(distance / floatParameter, 0.0f, 1f));
+ break;
+ }
+ //END PATCH
+
+ numerator += Mathf.Lerp(1f, 0.0f, Mathf.Clamp(distance / floatParameter, 0.0f, 1f));
+ break;
+ }
+ }
+
+ scoringResult.Score = numerator / denominator;
+ }
+ }
+}
diff --git a/SolastaUnfinishedBusiness/Patches/CursorLocationSelectTargetPatcher.cs b/SolastaUnfinishedBusiness/Patches/CursorLocationSelectTargetPatcher.cs
index ae2137f57f..7d8e18fc45 100644
--- a/SolastaUnfinishedBusiness/Patches/CursorLocationSelectTargetPatcher.cs
+++ b/SolastaUnfinishedBusiness/Patches/CursorLocationSelectTargetPatcher.cs
@@ -80,9 +80,11 @@ rulesetEffectSpell.EffectDescription.RangeType is not (RangeType.Touch or RangeT
.FirstOrDefault(x =>
x.RulesetCharacter is RulesetCharacterMonster rulesetCharacterMonster &&
rulesetCharacterMonster.MonsterDefinition.Name == OwlFamiliar &&
- rulesetCharacterMonster.AllConditions.Exists(y =>
- y.ConditionDefinition == ConditionDefinitions.ConditionConjuredCreature &&
- y.SourceGuid == actingCharacter.Guid));
+ rulesetCharacterMonster.ConditionsByCategory
+ .SelectMany(x => x.Value)
+ .Exists(y =>
+ y.ConditionDefinition == ConditionDefinitions.ConditionConjuredCreature &&
+ y.SourceGuid == actingCharacter.Guid));
var canAttack = familiar != null && familiar.IsWithinRange(target, 1);
diff --git a/SolastaUnfinishedBusiness/Patches/FunctorEnvironmentEffectPatcher.cs b/SolastaUnfinishedBusiness/Patches/FunctorEnvironmentEffectPatcher.cs
new file mode 100644
index 0000000000..50b8673085
--- /dev/null
+++ b/SolastaUnfinishedBusiness/Patches/FunctorEnvironmentEffectPatcher.cs
@@ -0,0 +1,338 @@
+using System.Collections;
+using System.Diagnostics.CodeAnalysis;
+using HarmonyLib;
+using JetBrains.Annotations;
+using SolastaUnfinishedBusiness.Api.GameExtensions;
+using SolastaUnfinishedBusiness.Interfaces;
+using TA;
+using UnityEngine;
+
+namespace SolastaUnfinishedBusiness.Patches;
+
+[UsedImplicitly]
+public class FunctorEnvironmentEffectPatcher
+{
+ //BUGFIX: vanilla only offers Bardic Inspiration during combat. This fixes that.
+ //code is vanilla, cleaned up by Rider, except for BEGIN / END patch block
+ [HarmonyPatch(typeof(FunctorEnvironmentEffect), nameof(FunctorEnvironmentEffect.Execute))]
+ [SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Patch")]
+ [UsedImplicitly]
+ public static class SelectCharacters_Patch
+ {
+ [UsedImplicitly]
+ public static bool Prefix(
+ out IEnumerator __result,
+ FunctorParametersDescription functorParameters)
+ {
+ __result = Execute(functorParameters);
+
+ return false;
+ }
+
+ private static IEnumerator TriggerEnvironmentEffectPosition(
+ GameLocationEnvironmentManager environmentManager,
+ GameLocationCharacter triggerer,
+ EnvironmentEffectDefinition environmentEffectDefinition,
+ int3 position,
+ int savingThrowDCOverride,
+ int addDice,
+ GameGadget sourceGadget,
+ bool isGlobalEnvironmentEffect)
+ {
+ var effectEnvironment = ServiceRepository.GetService()
+ .InstantiateEffectEnvironment(triggerer?.RulesetCharacter, environmentEffectDefinition,
+ savingThrowDCOverride, addDice, false, new BoxInt(),
+ triggerer?.LocationPosition ?? position, sourceGadget.UniqueNameId,
+ isGlobalEnvironmentEffect);
+ if (effectEnvironment.EffectDescription.TargetType == RuleDefinitions.TargetType.KindredSpirit)
+ {
+ Trace.LogError("Trying to trigger an effect targeting only the kindred spirit, not yet implemented!");
+ }
+ else
+ {
+ var origin = new Vector3();
+
+ environmentManager.affectedCharacters.Clear();
+
+ if (effectEnvironment.EffectDescription.TargetType == RuleDefinitions.TargetType.Self)
+ {
+ environmentManager.affectedCharacters.Add(triggerer);
+ origin = ServiceRepository.GetService()
+ .GetWorldPositionFromGridPosition(position);
+ }
+ else if (effectEnvironment.EffectDescription.IsAoE)
+ {
+ var fromGridPosition = ServiceRepository.GetService()
+ .GetWorldPositionFromGridPosition(triggerer?.LocationPosition ?? position);
+ var direction = new Vector3();
+ var shapeType = effectEnvironment.EffectDescription.ShapeType;
+ var service = ServiceRepository.GetService();
+
+ service.ComputeTargetingParameters(
+ fromGridPosition,
+ null,
+ new int3(), shapeType,
+ effectEnvironment.EffectDescription.RangeType,
+ ref origin, ref direction);
+ service.ComputeTargetsOfAreaOfEffect(
+ origin,
+ direction,
+ new Vector3(),
+ shapeType,
+ RuleDefinitions.Side.Neutral,
+ environmentEffectDefinition.EffectDescription,
+ effectEnvironment.ComputeTargetParameter(),
+ effectEnvironment.ComputeTargetParameter2(),
+ environmentManager.affectedCharacters,
+ false,
+ groundOnly: effectEnvironment.EffectDescription.AffectOnlyGround);
+ }
+
+ environmentManager.EnvironmentEffectTriggered?.Invoke(effectEnvironment, origin);
+
+ yield return TriggerEnvironmentEffect(environmentManager, effectEnvironment);
+ }
+ }
+
+ private static IEnumerator TriggerEnvironmentEffectBox(
+ GameLocationEnvironmentManager environmentManager,
+ GameLocationCharacter triggerer,
+ EnvironmentEffectDefinition environmentEffectDefinition,
+ BoxInt boxTargetArea,
+ int savingThrowOverride,
+ int addDice,
+ GameGadget sourceGadget,
+ bool isGlobalEnvironmentEffect)
+ {
+ var effectEnvironment = ServiceRepository.GetService()
+ .InstantiateEffectEnvironment(triggerer?.RulesetCharacter, environmentEffectDefinition,
+ savingThrowOverride, addDice, true, boxTargetArea, new int3(), sourceGadget.UniqueNameId,
+ isGlobalEnvironmentEffect);
+
+ environmentManager.affectedCharacters.Clear();
+
+ ServiceRepository.GetService().ComputeTargetsOfAreaOfEffect(
+ boxTargetArea,
+ RuleDefinitions.Side.Neutral,
+ environmentEffectDefinition.EffectDescription,
+ effectEnvironment.ComputeTargetParameter(),
+ effectEnvironment.ComputeTargetParameter2(),
+ environmentManager.affectedCharacters);
+
+ var origin = boxTargetArea.Center - new Vector3(0.0f, boxTargetArea.Size.y / 2f, 0.0f);
+
+ environmentManager.EnvironmentEffectTriggered?.Invoke(effectEnvironment, origin);
+
+ yield return TriggerEnvironmentEffect(environmentManager, effectEnvironment);
+ }
+
+ private static IEnumerator TriggerEnvironmentEffect(
+ GameLocationEnvironmentManager environmentManager,
+ RulesetEffectEnvironment activeEnvironmentEffect)
+ {
+ var service = ServiceRepository.GetService();
+
+ service.ClearDamageFormsByIndex();
+
+ for (var index = 0; index < environmentManager.affectedCharacters.Count; ++index)
+ {
+ var affectedCharacter = environmentManager.affectedCharacters[index];
+ var recurrentEffect = activeEnvironmentEffect.EffectDescription.RecurrentEffect;
+
+ if (recurrentEffect == RuleDefinitions.RecurrentEffect.No ||
+ (recurrentEffect & RuleDefinitions.RecurrentEffect.OnActivation) !=
+ RuleDefinitions.RecurrentEffect.No)
+ {
+ var actionModifier = new ActionModifier();
+ var rolledSaveThrow = activeEnvironmentEffect.TryRollSavingThrow(
+ null,
+ RuleDefinitions.Side.Neutral,
+ affectedCharacter.RulesetActor,
+ actionModifier,
+ activeEnvironmentEffect.EffectDescription.EffectForms,
+ true,
+ out var saveOutcome,
+ out var saveOutcomeDelta);
+
+ if (rolledSaveThrow)
+ {
+ var battleManager = ServiceRepository.GetService()
+ as GameLocationBattleManager;
+ var hasBorrowedLuck = affectedCharacter.RulesetActor.HasConditionOfTypeOrSubType(
+ RuleDefinitions.ConditionBorrowedLuck);
+ var savingThrowData = new SavingThrowData
+ {
+ SaveActionModifier = actionModifier,
+ SaveOutcome = saveOutcome,
+ SaveOutcomeDelta = saveOutcomeDelta,
+ SaveDC = RulesetActorExtensions.SaveDC,
+ SaveBonusAndRollModifier = RulesetActorExtensions.SaveBonusAndRollModifier,
+ SavingThrowAbility = RulesetActorExtensions.SavingThrowAbility,
+ SourceDefinition = activeEnvironmentEffect.SourceDefinition,
+ EffectDescription = activeEnvironmentEffect.EffectDescription,
+ Title = activeEnvironmentEffect.SourceDefinition.FormatTitle(),
+ Action = null
+ };
+
+ yield return TryAlterOutcomeSavingThrow.Handler(
+ battleManager,
+ null,
+ affectedCharacter,
+ savingThrowData,
+ hasBorrowedLuck,
+ activeEnvironmentEffect.EffectDescription);
+ }
+
+ var formsParams = new RulesetImplementationDefinitions.ApplyFormsParams();
+
+ formsParams.FillSourceAndTarget(null, affectedCharacter.RulesetActor);
+ formsParams.FillFromActiveEffect(activeEnvironmentEffect);
+ formsParams.FillSpecialParameters(
+ rolledSaveThrow, activeEnvironmentEffect.AddDice, 0, 0, 0,
+ actionModifier, saveOutcome, saveOutcomeDelta, false, index,
+ environmentManager.affectedCharacters.Count, null);
+ formsParams.effectSourceType = RuleDefinitions.EffectSourceType.Environment;
+ service.ApplyEffectForms(
+ activeEnvironmentEffect.EffectDescription.EffectForms,
+ formsParams,
+ null,
+ out _,
+ out _,
+ effectApplication: activeEnvironmentEffect.EffectDescription.EffectApplication,
+ filters: activeEnvironmentEffect.EffectDescription.EffectFormFilters);
+ }
+
+ environmentManager.EnvironmentEffectImpactTriggered?.Invoke(activeEnvironmentEffect, affectedCharacter);
+ }
+
+ if (activeEnvironmentEffect.IsOnGoing())
+ {
+ activeEnvironmentEffect.RemainingRounds = RuleDefinitions.ComputeRoundsDuration(
+ activeEnvironmentEffect.EffectDescription.DurationType,
+ activeEnvironmentEffect.EffectDescription.DurationParameter);
+ activeEnvironmentEffect.TerminatedSelf += environmentManager.ActiveEnvironmentEffectTerminatedSelf;
+ environmentManager.activeEnvironmentEffects.Add(activeEnvironmentEffect);
+ environmentManager.activeEnvironmentEffects.Sort((effectA, effectB) =>
+ -(effectA.SourceDefinition is EnvironmentEffectDefinition sourceDefinition1
+ ? sourceDefinition1.Priority
+ : 0).CompareTo(effectB.SourceDefinition is EnvironmentEffectDefinition sourceDefinition2
+ ? sourceDefinition2.Priority
+ : 0));
+ environmentManager.RegisterGlobalActiveEffect(activeEnvironmentEffect);
+ }
+ else
+ {
+ activeEnvironmentEffect.Terminate(false);
+ }
+
+ service.ClearDamageFormsByIndex();
+ }
+
+ private static IEnumerator Execute(
+ FunctorParametersDescription functorParameters)
+ {
+ GameLocationCharacter actingCharacter = null;
+
+ if (functorParameters.ActingCharacters.Count > 0)
+ {
+ actingCharacter = functorParameters.ActingCharacters[0];
+ }
+
+ var environmentManager =
+ ServiceRepository.GetService() as GameLocationEnvironmentManager;
+
+ if (!environmentManager)
+ {
+ Trace.LogError("Missing environmentService in FunctorEnvironmentEffect");
+ }
+ else
+ {
+ var positioningService = ServiceRepository.GetService();
+ var rulesetImplementationService = ServiceRepository.GetService();
+
+ while (rulesetImplementationService.IsApplyingEffects())
+ {
+ yield return null;
+ }
+
+ if (functorParameters.IsGlobalEnvironmentEffect)
+ {
+ yield return TriggerEnvironmentEffectPosition(
+ environmentManager,
+ actingCharacter,
+ functorParameters.EnvironmentEffectDefinition,
+ int3.zero,
+ functorParameters.SavingThrowOverride,
+ functorParameters.AddDice,
+ functorParameters.SourceGadget.GameGadget,
+ functorParameters.IsGlobalEnvironmentEffect);
+ }
+
+ if (functorParameters.BoxColliders.Count > 0)
+ {
+ foreach (var t in functorParameters.BoxColliders)
+ {
+ if (!t)
+ {
+ continue;
+ }
+
+ var min = t.bounds.min;
+ var max = t.bounds.max;
+
+ yield return TriggerEnvironmentEffectBox(
+ environmentManager,
+ actingCharacter,
+ functorParameters.EnvironmentEffectDefinition,
+ new BoxInt(
+ new int3(
+ Mathf.RoundToInt(min.x),
+ Mathf.RoundToInt(min.y),
+ Mathf.RoundToInt(min.z)),
+ new int3(
+ Mathf.RoundToInt(max.x) - 1,
+ Mathf.RoundToInt(max.y) - 1,
+ Mathf.RoundToInt(max.z) - 1)),
+ functorParameters.SavingThrowOverride,
+ functorParameters.AddDice,
+ functorParameters.SourceGadget.GameGadget,
+ functorParameters.IsGlobalEnvironmentEffect);
+ }
+ }
+
+ if (functorParameters.Nodes.Count > 0)
+ {
+ // ReSharper disable once ForeachCanBePartlyConvertedToQueryUsingAnotherGetEnumerator
+ foreach (var t in functorParameters.Nodes)
+ {
+ if (t)
+ {
+ yield return TriggerEnvironmentEffectPosition(
+ environmentManager,
+ actingCharacter,
+ functorParameters.EnvironmentEffectDefinition,
+ positioningService.GetGridPositionFromWorldPosition(t.transform),
+ functorParameters.SavingThrowOverride,
+ functorParameters.AddDice,
+ functorParameters.SourceGadget.GameGadget,
+ functorParameters.IsGlobalEnvironmentEffect);
+ }
+ }
+ }
+
+ if (functorParameters.Nodes.Empty() && functorParameters.BoxColliders.Empty())
+ {
+ yield return TriggerEnvironmentEffectPosition(
+ environmentManager,
+ actingCharacter,
+ functorParameters.EnvironmentEffectDefinition,
+ positioningService.GetGridPositionFromWorldPosition(functorParameters.SourceGadget.transform),
+ functorParameters.SavingThrowOverride,
+ functorParameters.AddDice,
+ functorParameters.SourceGadget.GameGadget,
+ functorParameters.IsGlobalEnvironmentEffect);
+ }
+ }
+ }
+ }
+}
diff --git a/SolastaUnfinishedBusiness/Patches/FunctorPatcher.cs b/SolastaUnfinishedBusiness/Patches/FunctorPatcher.cs
index 615c7b6496..543a1a3856 100644
--- a/SolastaUnfinishedBusiness/Patches/FunctorPatcher.cs
+++ b/SolastaUnfinishedBusiness/Patches/FunctorPatcher.cs
@@ -42,11 +42,12 @@ public static void Postfix(
continue;
}
- if (!rulesetCharacter.ConditionsByCategory.Values.Select(rulesetConditions => rulesetConditions
- .Where(x => x.ConditionDefinition ==
- DatabaseHelper.ConditionDefinitions.ConditionConjuredCreature)
- .Any(x => characterService.PartyCharacters.Any(y =>
- y.RulesetCharacter.Guid == x.SourceGuid))).Any(found => found))
+ if (!rulesetCharacter.ConditionsByCategory
+ .SelectMany(x => x.Value)
+ .Where(x =>
+ x.ConditionDefinition == DatabaseHelper.ConditionDefinitions.ConditionConjuredCreature)
+ .Any(x => characterService.PartyCharacters
+ .Any(y => y.RulesetCharacter.Guid == x.SourceGuid)))
{
continue;
}
diff --git a/SolastaUnfinishedBusiness/Patches/FunctorSetGadgetConditionByAbilityCheckPatcher.cs b/SolastaUnfinishedBusiness/Patches/FunctorSetGadgetConditionByAbilityCheckPatcher.cs
index 909ba36ed3..91461dba14 100644
--- a/SolastaUnfinishedBusiness/Patches/FunctorSetGadgetConditionByAbilityCheckPatcher.cs
+++ b/SolastaUnfinishedBusiness/Patches/FunctorSetGadgetConditionByAbilityCheckPatcher.cs
@@ -173,7 +173,8 @@ private static IEnumerator ExecuteCheckOnCharacter(
AbilityCheckRoll = abilityCheckRoll,
AbilityCheckRollOutcome = rollOutcome,
AbilityCheckSuccessDelta = successDelta,
- AbilityCheckActionModifier = actionModifier
+ AbilityCheckActionModifier = actionModifier,
+ Action = null
};
yield return TryAlterOutcomeAttributeCheck
diff --git a/SolastaUnfinishedBusiness/Patches/FunctorSetGadgetConditionBySavingThrowPatcher.cs b/SolastaUnfinishedBusiness/Patches/FunctorSetGadgetConditionBySavingThrowPatcher.cs
index baaa30b09c..43db339378 100644
--- a/SolastaUnfinishedBusiness/Patches/FunctorSetGadgetConditionBySavingThrowPatcher.cs
+++ b/SolastaUnfinishedBusiness/Patches/FunctorSetGadgetConditionBySavingThrowPatcher.cs
@@ -1,12 +1,11 @@
-#if false
-using System;
+using System;
using System.Collections;
-using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using HarmonyLib;
using JetBrains.Annotations;
+using SolastaUnfinishedBusiness.Api.GameExtensions;
+using SolastaUnfinishedBusiness.Builders;
using SolastaUnfinishedBusiness.Interfaces;
-using UnityEngine;
namespace SolastaUnfinishedBusiness.Patches;
@@ -21,6 +20,10 @@ public static class FunctorSetGadgetConditionBySavingThrowPatcher
[UsedImplicitly]
public static class SelectCharacters_Patch
{
+ private static readonly EffectDescription EmptyEffectDescription = EffectDescriptionBuilder
+ .Create()
+ .Build();
+
[UsedImplicitly]
public static bool Prefix(
out IEnumerator __result,
@@ -58,12 +61,10 @@ private static IEnumerator ExecuteSaveOnCharacter(
var actionModifier = new ActionModifier();
var implementationService = ServiceRepository.GetService();
- var effectFormList = new List();
var rulesetCharacter = actingCharacter.RulesetCharacter;
var abilityScoreName = functorParameters.AbilityCheck.AbilityScoreName;
var gadgetDefinition = functorParameters.GadgetDefinition;
-
- implementationService.TryRollSavingThrow(
+ var rolledSavingThrow = implementationService.TryRollSavingThrow(
null,
RuleDefinitions.Side.Enemy,
rulesetCharacter,
@@ -76,99 +77,69 @@ private static IEnumerator ExecuteSaveOnCharacter(
false,
false,
RuleDefinitions.FeatureSourceType.Base,
- effectFormList,
+ EmptyEffectDescription.EffectForms,
null,
null,
string.Empty,
gadgetDefinition,
string.Empty,
null,
- out var outcome,
+ out var saveOutcome,
out var saveOutcomeDelta);
var worldGadget = !functorParameters.BoolParameter
? functorParameters.TargetGadget
: functorParameters.SourceGadget;
- var battleManager = ServiceRepository.GetService()
- as GameLocationBattleManager;
-
- if (outcome == RuleDefinitions.RollOutcome.Failure)
+ if (rolledSavingThrow)
{
- battleManager!.GetBestParametersForBardicDieRoll(
- actingCharacter,
- out var bestDie,
- out _,
- out var sourceCondition,
- out var forceMaxRoll,
- out var advantage);
-
- if (bestDie > RuleDefinitions.DieType.D1 &&
- actingCharacter.RulesetCharacter != null)
+ var battleManager = ServiceRepository.GetService()
+ as GameLocationBattleManager;
+ var hasBorrowedLuck =
+ rulesetCharacter.HasConditionOfTypeOrSubType(RuleDefinitions.ConditionBorrowedLuck);
+ var savingThrowData = new SavingThrowData
{
- // Is the die enough to overcome the failure?
- if (RuleDefinitions.DiceMaxValue[(int)bestDie] >= Mathf.Abs(saveOutcomeDelta))
- {
- var reactionParams =
- new CharacterActionParams(actingCharacter,
- ActionDefinitions.Id.UseBardicInspiration)
- {
- IntParameter = (int)bestDie,
- IntParameter2 = (int)RuleDefinitions.BardicInspirationUsageType.SavingThrow
- };
-
- var actionService = ServiceRepository.GetService();
- var previousReactionCount = actionService.PendingReactionRequestGroups.Count;
-
- actionService.ReactToUseBardicInspiration(reactionParams);
-
- yield return battleManager.WaitForReactions(actingCharacter, actionService,
- previousReactionCount);
-
- if (reactionParams.ReactionValidated)
- {
- // Now we have a shot at succeeding on the ability check
- var roll = actingCharacter.RulesetCharacter.RollBardicInspirationDie(
- sourceCondition, saveOutcomeDelta, forceMaxRoll, advantage);
-
- if (roll >= Mathf.Abs(saveOutcomeDelta))
- {
- // The roll is now a success!
- outcome = RuleDefinitions.RollOutcome.Success;
- }
- }
- }
- }
+ SaveActionModifier = actionModifier,
+ SaveOutcome = saveOutcome,
+ SaveOutcomeDelta = saveOutcomeDelta,
+ SaveDC = RulesetActorExtensions.SaveDC,
+ SaveBonusAndRollModifier = RulesetActorExtensions.SaveBonusAndRollModifier,
+ SavingThrowAbility = RulesetActorExtensions.SavingThrowAbility,
+ SourceDefinition = gadgetDefinition,
+ EffectDescription = EmptyEffectDescription,
+ Title = gadgetDefinition.FormatTitle(),
+ Action = null
+ };
+
+ yield return TryAlterOutcomeSavingThrow.Handler(
+ battleManager,
+ null,
+ actingCharacter,
+ savingThrowData,
+ hasBorrowedLuck,
+ EmptyEffectDescription);
}
- //PATCH: support for `ITryAlterOutcomeAttributeCheck`
- // foreach (var tryAlterOutcomeSavingThrow in TryAlterOutcomeSavingThrow.Handler(
- // battleManager, null, actingCharacter, null, new ActionModifier(), true, false))
- // {
- // yield return tryAlterOutcomeSavingThrow;
- // }
-
- //END PATCH
-
- if (outcome is RuleDefinitions.RollOutcome.Success or RuleDefinitions.RollOutcome.CriticalSuccess)
+ if (saveOutcome == RuleDefinitions.RollOutcome.Success)
{
- var conditionIndex = Array.IndexOf(worldGadget.ConditionChoices(),
- functorParameters.TargetConditionState.name);
- worldGadget.GameGadget.SetCondition(conditionIndex, functorParameters.TargetConditionState.state,
+ var conditionIndex = Array.IndexOf(
+ worldGadget.ConditionChoices(), functorParameters.TargetConditionState.name);
+
+ worldGadget.GameGadget.SetCondition(
+ conditionIndex,
+ functorParameters.TargetConditionState.state,
functorParameters.ActingCharacters);
- yield break;
}
-
- // ReSharper disable once InvertIf
- if (functorParameters.HasAlternateTargetConditionState)
+ else if (functorParameters.HasAlternateTargetConditionState)
{
- var conditionIndex = Array.IndexOf(worldGadget.ConditionChoices(),
- functorParameters.AlternateTargetConditionState.name);
- worldGadget.GameGadget.SetCondition(conditionIndex,
+ var conditionIndex = Array.IndexOf(
+ worldGadget.ConditionChoices(), functorParameters.AlternateTargetConditionState.name);
+
+ worldGadget.GameGadget.SetCondition(
+ conditionIndex,
functorParameters.AlternateTargetConditionState.state,
functorParameters.ActingCharacters);
}
}
}
}
-#endif
diff --git a/SolastaUnfinishedBusiness/Patches/GameLocationBattleManagerPatcher.cs b/SolastaUnfinishedBusiness/Patches/GameLocationBattleManagerPatcher.cs
index 4a8a49c760..e2ec78e2be 100644
--- a/SolastaUnfinishedBusiness/Patches/GameLocationBattleManagerPatcher.cs
+++ b/SolastaUnfinishedBusiness/Patches/GameLocationBattleManagerPatcher.cs
@@ -239,7 +239,8 @@ public static IEnumerator Process(
AbilityCheckRoll = action.AbilityCheckRoll,
AbilityCheckRollOutcome = action.AbilityCheckRollOutcome,
AbilityCheckSuccessDelta = action.AbilityCheckSuccessDelta,
- AbilityCheckActionModifier = actionModifier
+ AbilityCheckActionModifier = actionModifier,
+ Action = action
};
yield return TryAlterOutcomeAttributeCheck.HandleITryAlterOutcomeAttributeCheck(checker, abilityCheckData);
diff --git a/SolastaUnfinishedBusiness/Patches/GameLocationCharacterManagerPatcher.cs b/SolastaUnfinishedBusiness/Patches/GameLocationCharacterManagerPatcher.cs
index 977cda519b..7cd419dc1b 100644
--- a/SolastaUnfinishedBusiness/Patches/GameLocationCharacterManagerPatcher.cs
+++ b/SolastaUnfinishedBusiness/Patches/GameLocationCharacterManagerPatcher.cs
@@ -14,6 +14,38 @@ namespace SolastaUnfinishedBusiness.Patches;
[UsedImplicitly]
public static class GameLocationCharacterManagerPatcher
{
+ //BUGFIX: fix demonic influence getting all enemies agro on a custom map
+ [HarmonyPatch(typeof(GameLocationCharacterManager), nameof(GameLocationCharacterManager.CreateCharacter))]
+ [SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Patch")]
+ [UsedImplicitly]
+ public static class SpawnParty_Patch
+ {
+ [UsedImplicitly]
+ public static void Prefix(Side side, ref GameLocationBehaviourPackage behaviourPackage)
+ {
+ if (side == Side.Ally)
+ {
+ behaviourPackage ??= new GameLocationBehaviourPackage
+ {
+ BattleStartBehavior = GameLocationBehaviourPackage.BattleStartBehaviorType.DoNotRaiseAlarm
+ };
+ }
+ }
+ }
+
+ //PATCH: Fire monsters should emit light
+ [HarmonyPatch(typeof(GameLocationCharacterManager), nameof(GameLocationCharacterManager.RevealCharacter))]
+ [SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Patch")]
+ [UsedImplicitly]
+ public static class RevealCharacter_Patch
+ {
+ [UsedImplicitly]
+ public static void Postfix(GameLocationCharacter character)
+ {
+ SrdAndHouseRulesContext.AddLightSourceIfNeeded(character);
+ }
+ }
+
[HarmonyPatch(typeof(GameLocationCharacterManager),
nameof(GameLocationCharacterManager.CreateAndBindEffectProxy))]
[SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Patch")]
@@ -224,27 +256,6 @@ private static void CreateAndBindEffectProxy(
}
}
- //PATCH: recalculates additional party members positions (PARTYSIZE)
- [HarmonyPatch(typeof(GameLocationCharacterManager),
- nameof(GameLocationCharacterManager.UnlockCharactersForLoading))]
- [SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Patch")]
- [UsedImplicitly]
- public static class UnlockCharactersForLoading_Patch
- {
- [UsedImplicitly]
- public static void Prefix([NotNull] GameLocationCharacterManager __instance)
- {
- var partyCharacters = __instance.PartyCharacters;
-
- for (var idx = ToolsContext.GamePartySize; idx < partyCharacters.Count; idx++)
- {
- var position = partyCharacters[idx % ToolsContext.GamePartySize].LocationPosition;
-
- partyCharacters[idx].LocationPosition = new int3(position.x, position.y, position.z);
- }
- }
- }
-
[HarmonyPatch(typeof(GameLocationCharacterManager), nameof(GameLocationCharacterManager.LoseWildShapeAndRefund))]
[SuppressMessage("Minor Code Smell", "S101:Types should be named in PascalCase", Justification = "Patch")]
[UsedImplicitly]
diff --git a/SolastaUnfinishedBusiness/Patches/GameLocationCharacterPatcher.cs b/SolastaUnfinishedBusiness/Patches/GameLocationCharacterPatcher.cs
index a32908ca7a..83bd6e17bc 100644
--- a/SolastaUnfinishedBusiness/Patches/GameLocationCharacterPatcher.cs
+++ b/SolastaUnfinishedBusiness/Patches/GameLocationCharacterPatcher.cs
@@ -13,6 +13,7 @@
using SolastaUnfinishedBusiness.CustomUI;
using SolastaUnfinishedBusiness.Interfaces;
using SolastaUnfinishedBusiness.Models;
+using SolastaUnfinishedBusiness.Spells;
using SolastaUnfinishedBusiness.Validators;
using TA;
using UnityEngine;
@@ -374,6 +375,17 @@ or ActionDefinitions.Id.FlurryOfBlowsUnendingStrikes &&
__result = ActionDefinitions.ActionStatus.Available;
}
+ //PATCH: support Swift Quiver spell interaction with Flurry of Blows
+ if (actionId
+ is ActionDefinitions.Id.FlurryOfBlows
+ or ActionDefinitions.Id.FlurryOfBlowsSwiftSteps
+ or ActionDefinitions.Id.FlurryOfBlowsUnendingStrikes &&
+ __instance.UsedSpecialFeatures.ContainsKey(SpellBuilders.SwiftQuiverAttackTag) &&
+ __result == ActionDefinitions.ActionStatus.Available)
+ {
+ __result = ActionDefinitions.ActionStatus.CannotPerform;
+ }
+
var traditionFreedomLevel =
__instance.RulesetCharacter.GetSubclassLevel(DatabaseHelper.CharacterClassDefinitions.Monk,
"TraditionFreedom");
diff --git a/SolastaUnfinishedBusiness/Patches/GameLocationEnvironmentManagerPatcher.cs b/SolastaUnfinishedBusiness/Patches/GameLocationEnvironmentManagerPatcher.cs
index 15c1983fc1..f154aebad4 100644
--- a/SolastaUnfinishedBusiness/Patches/GameLocationEnvironmentManagerPatcher.cs
+++ b/SolastaUnfinishedBusiness/Patches/GameLocationEnvironmentManagerPatcher.cs
@@ -8,6 +8,8 @@
using SolastaUnfinishedBusiness.Api.GameExtensions;
using SolastaUnfinishedBusiness.Api.Helpers;
using SolastaUnfinishedBusiness.Behaviors;
+using TA;
+using UnityEngine;
using static RuleDefinitions;
namespace SolastaUnfinishedBusiness.Patches;
@@ -89,4 +91,51 @@ public static IEnumerable Transpiler([NotNull] IEnumerable Transpiler([NotNull] IEnumerable