Bloodrager#
Leshy Bloodrager barbarian, critfisher build
Feats: 1. Extended Reach, 2. Bloodrager Dedication, 4. Rising Blood Magic, 6. Siphon Magic, 10. Hematocritical, 12. Surging Blood Magic, 18. Exultant Blood Magic
Spells: cantrips ignition or live wire, electric arc; 1st Sure Strike; 2nd Brine Dragon Bile; 3rd Haste or Blazing Bolt or Breathe Fire or Fireball or Organsight (signature)
Equipment: Rooting Flaming Greatpick or Greatsword, (Greater) Phantasmal Doorknob
import xarray
import pathfinder2e_stats as pf2
level = 14
spell_slot_rank = (
pf2.level2rank(level, dedication=True) - 1
) # max - 1, recoverable with Siphon Magic
use_hematocritical = level >= 10
use_rooting_rune = level >= 7 # clumsy 1 on a crit
use_flaming_rune = level >= 10
use_sword = False # off-guard to ranged spells on a crit
use_greater_phantasmal_doorknob = level >= 10 # off-guard to ranged spells on a crit
Attack bonus progrssion#
Weapon vs. spell vs. Organsight Medicine checks
atk_bonus = xarray.Dataset(
{
"weapon": pf2.tables.SIMPLE_PC.weapon_attack_bonus.barbarian.sum("component"),
"spell": pf2.tables.SIMPLE_PC.spell_attack_bonus.barbarian.sum("component"),
"organsight": (
pf2.tables.PC.ability_bonus.boosts.sel(initial=1, drop=True)
+ pf2.tables.PC.skill_proficiency.others.sel(priority=1, drop=True)
+ pf2.tables.PC.skill_item_bonus.medicine
+ pf2.tables.PC.level
+ 2 # Circumstance
),
}
)
atk_bonus.to_pandas()
| weapon | spell | organsight | |
|---|---|---|---|
| level | |||
| 1 | 7 | 6 | 6 |
| 2 | 9 | 7 | 7 |
| 3 | 10 | 8 | 11 |
| 4 | 11 | 9 | 12 |
| 5 | 14 | 11 | 14 |
| 6 | 15 | 12 | 15 |
| 7 | 16 | 13 | 18 |
| 8 | 17 | 14 | 19 |
| 9 | 18 | 15 | 21 |
| 10 | 21 | 16 | 23 |
| 11 | 22 | 17 | 24 |
| 12 | 23 | 20 | 25 |
| 13 | 26 | 21 | 26 |
| 14 | 27 | 22 | 27 |
| 15 | 28 | 24 | 31 |
| 16 | 30 | 25 | 32 |
| 17 | 32 | 26 | 33 |
| 18 | 33 | 29 | 35 |
| 19 | 34 | 30 | 36 |
| 20 | 36 | 31 | 37 |
Let’s select 3 standard targets:#
level -2 henchman, all defenses are low
at-level monster, all defenses are moderate
level +2 boss, all defenses are high
rank = pf2.level2rank(level)
defenses = pf2.tables.SIMPLE_NPC[["AC", "saving_throws", "recall_knowledge"]].sel(
level=level
)
AC = defenses.AC
saves = defenses.saving_throws
defenses.to_array("kind").to_pandas()
| challenge | Weak | Matched | Boss |
|---|---|---|---|
| kind | |||
| AC | 30 | 35 | 39 |
| saving_throws | 19 | 25 | 30 |
| recall_knowledge | 30 | 32 | 37 |
Build damage profiles for weapon and spells#
STR = (
pf2.tables.PC.ability_bonus.boosts.sel(initial=4) + pf2.tables.PC.ability_bonus.apex
)
weapon_specialization = pf2.tables.PC.weapon_specialization.barbarian
rage_weapon = pf2.tables.PC.rage.bloodrager_weapon
weapon_dmg_bonus = (STR + weapon_specialization + rage_weapon).sel(level=level).item()
rage_bleed = pf2.tables.PC.rage.bloodrager_bleed.sel(level=level).item()
weapon_dice = pf2.tables.PC.weapon_dice.striking_rune.sel(level=level).item()
if use_sword:
# Greatsword with extended reach
weapon = pf2.armory.swords.greatsword(weapon_dice, weapon_dmg_bonus).reduce_die()
else:
# Greatpick with extended reach
weapon = pf2.armory.picks.greatpick(weapon_dice, weapon_dmg_bonus).reduce_die()
if level >= 5:
weapon += pf2.armory.picks.critical_specialization(2)
if use_flaming_rune:
weapon += pf2.armory.runes.flaming()
weapon += pf2.Damage("bleed", 0, 0, rage_bleed, persistent=True)
weapon
Success 3d8+12 piercing plus 1d6 fire plus 2 persistent bleed
def rage_spell(
level: int, type_: str, *, persistent: bool = False, drained: int = 2
) -> dict[pf2.DoS, list[pf2.Damage]]:
raw = pf2.tables.PC.rage.bloodrager_spells.sel(level=level, drained=drained).item()
d = pf2.Damage(type_, 0, 0, raw, persistent=persistent)
return {
pf2.DoS.critical_success: [d.copy(multiplier=2)],
pf2.DoS.success: [d],
pf2.DoS.failure: [d],
}
ignition_melee = pf2.armory.cantrips.ignition(rank, melee=True) + rage_spell(
level, "fire"
)
ignition_melee
Success 8d6+7 fire
Failure 7 fire
ignition_ranged = pf2.armory.cantrips.ignition(rank, melee=False) + rage_spell(
level, "fire"
)
ignition_ranged
Success 8d4+7 fire
Failure 7 fire
live_wire = pf2.armory.cantrips.live_wire(rank) + rage_spell(level, "electricity")
live_wire
Success 4d4 slashing plus 4d4+7 electricity
Failure 4d4+7 electricity
electric_arc = pf2.armory.cantrips.electric_arc(rank)
electric_arc
breathe_fire = pf2.armory.spells.breathe_fire(spell_slot_rank)
breathe_fire
brine_dragon_bile = pf2.armory.spells.brine_dragon_bile(spell_slot_rank) + rage_spell(
level, "acid", persistent=True
)
brine_dragon_bile
Success 4d6+7 persistent acid
Failure 7 persistent acid
blazing_bolt_1action = pf2.armory.spells.blazing_bolt(
spell_slot_rank, actions=1
) + rage_spell(level, "fire")
blazing_bolt_1action
Success 4d6+7 fire
Failure 7 fire
blazing_bolt_3actions = pf2.armory.spells.blazing_bolt(
spell_slot_rank, actions=3
) + rage_spell(level, "fire")
blazing_bolt_3actions
Success 8d6+7 fire
Failure 7 fire
organsight = pf2.armory.spells.organsight(spell_slot_rank)
organsight
Attack routine#
Strike (with flank) -> Hematocritical if crit -> spell, or
(if hasted) Sure Strike -> Strike (with flank) -> Hematocritical -> spell
Spell is one of:
Ignition (melee with flank)
Ignition (ranged due to reach)
Live Wire
Electric Arc (1-2 targets)
Breathe Fire / Fireball
Blazing Bolt (1-2-3 actions)
(out of round) Brine Dragon Bile
Spells from slots are at maximum rank -1, so that they can be cycled with Syphon Magic.
sure_strike = xarray.DataArray(
[False, True, False],
dims=["Sure Strike"],
coords={"Sure Strike": ["Normal", "Sure Strike", "Only on melee crit"]},
)
Dimensions
challengeandsure strikerepresent a what-if analysis. Roll dice only once and compare the results against different situations.For AoE spells with a saving throw (Electric Arc, Breathe Fire) roll damage only once, but roll saving throw individually for every target.
For Blazing Bolt, roll both attack and damage individually for every target.
pf2.set_config(
check_independent_dims=["AoE_target", "BB_target"],
check_dependent_dims=["challenge", "Sure Strike"],
damage_independent_dims=["BB_target"],
damage_dependent_dims=["challenge", "Sure Strike", "AoE_target"],
)
strike = pf2.damage(
pf2.check(
bonus=atk_bonus.weapon.sel(level=level).item(),
DC=AC - 2,
fortune=sure_strike,
),
weapon,
)
What are the chances of a critical hit on the initial weapon strike?#
melee_crit = strike.outcome == pf2.DoS.critical_success
melee_crit.loc[{"Sure Strike": "Only on melee crit"}] = True
melee_crit.mean("roll").round(3).to_pandas() * 100.0
| challenge | Weak | Matched | Boss |
|---|---|---|---|
| Sure Strike | |||
| Normal | 50.1 | 25.1 | 5.0 |
| Sure Strike | 75.1 | 43.8 | 9.8 |
| Only on melee crit | 100.0 | 100.0 | 100.0 |
The conditions of the next spell change depending on the strike and equipment#
If the strike was critical, we can use Hematocritical
If the weapon was rooting, the target is now Clumsy 1
If the weapon was a sword, th target is now off-guard even if not flanked
hematocritical = melee_crit if use_hematocritical else xarray.DataArray(False)
clumsy = melee_crit if use_rooting_rune else xarray.DataArray(0)
ranged_off_guard = (
2 * melee_crit
if (use_sword or use_greater_phantasmal_doorknob)
else xarray.DataArray(0)
)
Roll damage for the spells#
ignition_melee_dmg = pf2.damage(
pf2.check(
atk_bonus.spell.sel(level=level) - 5,
DC=AC - 2 - clumsy,
fortune=hematocritical,
),
ignition_melee,
)
ignition_ranged_dmg = pf2.damage(
pf2.check(
atk_bonus.spell.sel(level=level) - 5,
DC=AC - clumsy - ranged_off_guard,
fortune=hematocritical,
),
ignition_ranged,
)
live_wire_dmg = pf2.damage(
pf2.check(
atk_bonus.spell.sel(level=level) - 5,
DC=AC - clumsy - ranged_off_guard,
fortune=hematocritical,
),
live_wire,
)
AoE_target = xarray.DataArray(
[1, 0, 0],
dims=["AoE_target"],
coords={"AoE_target": ["Strike target", "target 2", "target 3"]},
)
electric_arc_dmg = pf2.damage(
pf2.check(
saves - AoE_target[:2] * clumsy,
DC=atk_bonus.spell.sel(level=level) + 10,
misfortune=hematocritical,
),
electric_arc,
).rename({"AoE_target": "target"}) # Align with Blazing Bolt target later
breathe_fire_dmg = pf2.damage(
pf2.check(
saves - AoE_target * clumsy,
DC=atk_bonus.spell.sel(level=level) + 10,
misfortune=hematocritical,
),
breathe_fire,
).rename({"AoE_target": "target"})
We need to use a different dimension from before because
the above AoEs have dependent damage rolls (roll only once for all targets),
whereas Blazing Bolt is independent (roll separately for each target).
See set_config above.
bb_target = AoE_target.rename({"AoE_target": "BB_target"})
blazing_bolt_check = pf2.check(
atk_bonus.spell.sel(level=level) - 5,
DC=AC - (clumsy + ranged_off_guard) * bb_target,
fortune=hematocritical,
)
blazing_bolt_1action_dmg = pf2.damage(
blazing_bolt_check,
blazing_bolt_1action,
).isel(BB_target=0, drop=True)
blazing_bolt_23actions_dmg = pf2.damage(
blazing_bolt_check,
blazing_bolt_3actions,
).rename({"BB_target": "target"})
Also show:#
A second iterative strike
a standalone 3-actions Blazing Bolt
an out-of-round Brine Dragon Bile
additional damage from Organsight, applied to the initial and iterative Strike on each round
strike2 = pf2.damage(
pf2.check(
bonus=atk_bonus.spell.sel(level=level).item() - 5,
DC=AC - 2 - clumsy,
),
weapon,
)
blazing_bolt_23actions_noMAP_dmg = pf2.damage(
pf2.check(
atk_bonus.spell.sel(level=level),
DC=AC,
independent_dims={"BB_target": 3},
),
blazing_bolt_3actions,
).rename({"BB_target": "target"})
brine_dragon_bile_dmg = pf2.damage(
pf2.check(
atk_bonus.spell.sel(level=level),
DC=AC,
),
brine_dragon_bile,
)
organsight_check = pf2.check(
atk_bonus.organsight.sel(level=level),
DC=defenses.recall_knowledge,
)
organsight_check["recall_knowledge_outcome"] = organsight_check.outcome
organsight_check["strike_outcome"] = xarray.concat(
[
strike.outcome,
xarray.where(
strike.outcome >= pf2.DoS.success,
pf2.DoS.no_roll,
strike2.outcome,
),
],
dim="strike",
)
organsight_check["outcome"] = xarray.where(
organsight_check.outcome >= pf2.DoS.success,
xarray.where(
organsight_check.strike_outcome >= pf2.DoS.success,
organsight_check.strike_outcome,
pf2.DoS.no_roll,
),
pf2.DoS.no_roll,
)
organsight_check.coords["strike"] = ["initial", "iterative"]
# "Only on melee crit" makes no sense here
organsight_check = organsight_check.isel({"Sure Strike": slice(2)})
organsight_dmg = pf2.damage(
organsight_check,
organsight,
independent_dims=["strike"],
)
Mean damage for every action#
rows = {
"Weapon Strike (flanked)": strike,
"Iterative Weapon Strike (flanked) (MAP-5)": strike2,
"Organsight (first strike)": organsight_dmg.isel(strike=0, drop=True),
"Organsight (iterative strike)": organsight_dmg.isel(strike=1, drop=True),
"Ignition (melee, flanked) (MAP-5)": ignition_melee_dmg,
"Ignition (ranged) (MAP-5)": ignition_ranged_dmg,
"Live Wire (MAP-5)": live_wire_dmg,
"Electric Arc (1 target)": electric_arc_dmg.isel(target=slice(1)),
"Electric Arc (2 targets)": electric_arc_dmg,
"Breathe Fire (1 target)": breathe_fire_dmg.isel(target=slice(1)),
"Breathe Fire (2 targets)": breathe_fire_dmg.isel(target=slice(2)),
"Breathe Fire (3 targets)": breathe_fire_dmg,
"Blazing Bolt > (MAP-5)": blazing_bolt_1action_dmg,
"Blazing Bolt >> (MAP-5)": blazing_bolt_23actions_dmg.isel(target=slice(2)),
"Blazing Bolt >>> (MAP-5)": blazing_bolt_23actions_dmg,
"Blazing Bolt >>> (standalone)": blazing_bolt_23actions_noMAP_dmg,
"Brine Dragon Bile (standalone)": brine_dragon_bile_dmg,
}
damages = []
for dmg in rows.values():
dmg = dmg.total_damage.mean("roll")
if "target" in dmg.dims:
dmg = dmg.sum("target")
damages.append(dmg)
total_damage = xarray.concat(damages, dim="activity", join="outer", coords="minimal")
total_damage.coords["activity"] = list(rows)
total_damage.loc[
{"activity": total_damage.activity[0], "Sure Strike": "Only on melee crit"}
] = float("nan")
total_damage.loc[
{"activity": total_damage.activity[-2:], "Sure Strike": "Only on melee crit"}
] = float("nan")
total_damage.loc[
{"activity": total_damage.activity[-3:], "Sure Strike": "Sure Strike"}
] = float("nan")
total_damage.stack(col=["challenge", "Sure Strike"]).to_pandas().round(1)
| challenge | Weak | Matched | Boss | ||||||
|---|---|---|---|---|---|---|---|---|---|
| Sure Strike | Normal | Only on melee crit | Sure Strike | Normal | Only on melee crit | Sure Strike | Normal | Only on melee crit | Sure Strike |
| activity | |||||||||
| Weapon Strike (flanked) | 65.7 | NaN | 84.4 | 42.1 | NaN | 61.1 | 21.8 | NaN | 33.3 |
| Iterative Weapon Strike (flanked) (MAP-5) | 20.9 | 21.7 | 21.3 | 12.1 | 13.4 | 12.4 | 5.2 | 6.7 | 5.2 |
| Organsight (first strike) | 22.8 | NaN | 27.5 | 14.0 | NaN | 19.3 | 5.8 | NaN | 8.6 |
| Organsight (iterative strike) | 0.4 | NaN | 0.0 | 1.1 | NaN | 0.2 | 0.4 | NaN | 0.2 |
| Ignition (melee, flanked) (MAP-5) | 32.2 | 38.7 | 35.5 | 20.2 | 30.3 | 22.7 | 10.3 | 20.3 | 10.9 |
| Ignition (ranged) (MAP-5) | 23.5 | 29.8 | 26.6 | 13.8 | 23.5 | 16.2 | 4.4 | 16.2 | 4.9 |
| Live Wire (MAP-5) | 25.3 | 29.6 | 27.4 | 17.0 | 25.7 | 19.2 | 7.9 | 20.1 | 8.5 |
| Electric Arc (1 target) | 22.2 | 26.0 | 24.1 | 13.3 | 17.4 | 14.3 | 7.2 | 12.1 | 7.4 |
| Electric Arc (2 targets) | 43.4 | 49.9 | 46.7 | 26.3 | 34.0 | 28.2 | 14.2 | 22.9 | 14.7 |
| Breathe Fire (1 target) | 31.0 | 36.3 | 33.6 | 18.6 | 24.4 | 20.0 | 10.0 | 17.0 | 10.4 |
| Breathe Fire (2 targets) | 60.6 | 69.6 | 65.1 | 36.9 | 47.6 | 39.6 | 20.0 | 32.0 | 20.6 |
| Breathe Fire (3 targets) | 90.2 | 103.0 | 96.6 | 55.3 | 70.7 | 59.1 | 29.9 | 47.1 | 30.7 |
| Blazing Bolt > (MAP-5) | 16.3 | 20.1 | 18.2 | 9.4 | 15.7 | 10.9 | 3.8 | 10.2 | 4.1 |
| Blazing Bolt >> (MAP-5) | 49.2 | 60.8 | 55.0 | 25.5 | 41.2 | 29.4 | 9.0 | 21.4 | 9.6 |
| Blazing Bolt >>> (MAP-5) | 72.8 | 89.0 | NaN | 37.4 | 58.3 | NaN | 13.3 | 28.6 | NaN |
| Blazing Bolt >>> (standalone) | 90.3 | NaN | NaN | 56.7 | NaN | NaN | 35.8 | NaN | NaN |
| Brine Dragon Bile (standalone) | 41.4 | NaN | NaN | 27.7 | NaN | NaN | 18.4 | NaN | NaN |
Outcome probability for the initial Strike#
(
pf2.outcome_counts(strike)
.isel({"Sure Strike": slice(2)})
.stack(col=["challenge", "Sure Strike"])
.to_pandas()
.round(3)
* 100.0
)
| challenge | Weak | Matched | Boss | |||
|---|---|---|---|---|---|---|
| Sure Strike | Normal | Sure Strike | Normal | Sure Strike | Normal | Sure Strike |
| outcome | ||||||
| Critical success | 50.1 | 75.1 | 25.1 | 43.8 | 5.0 | 9.8 |
| Success | 44.8 | 24.6 | 49.9 | 50.1 | 50.0 | 70.1 |
| Failure | 5.1 | 0.2 | 19.9 | 5.9 | 39.9 | 19.9 |
| Critical failure | 0.0 | 0.0 | 5.1 | 0.2 | 5.1 | 0.2 |
Outcome probability for the iterative Strike#
(
pf2.outcome_counts(strike2)
.stack(col=["challenge", "Sure Strike"])
.to_pandas()
.round(3)
* 100.0
)
| challenge | Weak | Matched | Boss | ||||||
|---|---|---|---|---|---|---|---|---|---|
| Sure Strike | Normal | Sure Strike | Only on melee crit | Normal | Sure Strike | Only on melee crit | Normal | Sure Strike | Only on melee crit |
| outcome | |||||||||
| Critical success | 5.0 | 5.0 | 5.0 | 5.0 | 5.0 | 5.0 | 5.0 | 5.0 | 5.0 |
| Success | 47.3 | 48.7 | 49.9 | 21.1 | 22.1 | 24.9 | 0.2 | 0.5 | 5.0 |
| Failure | 42.6 | 41.3 | 40.1 | 45.2 | 45.2 | 45.1 | 44.9 | 44.9 | 44.9 |
| Critical failure | 5.0 | 5.0 | 5.0 | 28.7 | 27.8 | 25.0 | 49.9 | 49.6 | 45.1 |
Outcome probability for Ignition (melee)#
(
pf2.outcome_counts(ignition_melee_dmg)
.stack(col=["challenge", "Sure Strike"])
.to_pandas()
.round(3)
* 100.0
)
| challenge | Weak | Matched | Boss | ||||||
|---|---|---|---|---|---|---|---|---|---|
| Sure Strike | Normal | Sure Strike | Only on melee crit | Normal | Sure Strike | Only on melee crit | Normal | Sure Strike | Only on melee crit |
| outcome | |||||||||
| Critical success | 7.4 | 8.6 | 9.8 | 6.2 | 7.2 | 9.8 | 5.3 | 5.6 | 9.8 |
| Success | 57.5 | 63.7 | 69.9 | 25.4 | 29.3 | 41.3 | 0.5 | 0.9 | 9.2 |
| Failure | 32.5 | 26.3 | 20.1 | 44.4 | 44.0 | 42.6 | 45.7 | 46.3 | 60.7 |
| Critical failure | 2.5 | 1.3 | 0.2 | 24.0 | 19.6 | 6.3 | 48.5 | 47.2 | 20.3 |
Outcome probability for Electric Arc / Breathe Fire / Fireball#
(
pf2.outcome_counts(electric_arc_dmg)
.stack(row=["target", "outcome"])
.stack(col=["challenge", "Sure Strike"])
.to_pandas()
.round(3)
* 100.0
)
| challenge | Weak | Matched | Boss | |||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Sure Strike | Normal | Sure Strike | Only on melee crit | Normal | Sure Strike | Only on melee crit | Normal | Sure Strike | Only on melee crit | |
| target | outcome | |||||||||
| Strike target | Critical success | 2.6 | 1.4 | 0.2 | 15.8 | 12.3 | 2.2 | 43.6 | 42.2 | 16.1 |
| Success | 23.6 | 17.8 | 12.1 | 47.2 | 45.4 | 40.0 | 50.6 | 51.4 | 64.8 | |
| Failure | 48.1 | 49.8 | 51.5 | 30.7 | 35.0 | 47.8 | 0.5 | 0.9 | 9.2 | |
| Critical failure | 25.7 | 31.0 | 36.2 | 6.3 | 7.2 | 9.9 | 5.3 | 5.6 | 9.9 | |
| target 2 | Critical success | 2.6 | 1.5 | 0.3 | 15.8 | 12.9 | 3.9 | 43.9 | 42.8 | 20.3 |
| Success | 25.5 | 20.7 | 15.9 | 49.0 | 48.0 | 45.0 | 50.9 | 51.8 | 69.9 | |
| Failure | 50.4 | 53.1 | 55.9 | 29.0 | 32.1 | 41.3 | 0.0 | 0.0 | 0.0 | |
| Critical failure | 21.4 | 24.7 | 28.0 | 6.2 | 7.1 | 9.8 | 5.2 | 5.5 | 9.8 | |
Outcome probability for Organsight#
Recall Knowledege#
(
pf2.outcome_counts(organsight_dmg.recall_knowledge_outcome).to_pandas().T.round(3)
* 100.0
)
| challenge | Weak | Matched | Boss |
|---|---|---|---|
| outcome | |||
| Critical success | 39.9 | 29.8 | 5.0 |
| Success | 50.0 | 50.1 | 49.9 |
| Failure | 5.0 | 15.0 | 40.0 |
| Critical failure | 5.1 | 5.1 | 5.1 |
Triggering Strike#
The iterative strike is “no roll” whenever the initial strike connects, as the damage from Organsight can only be discharged once per round.
(
pf2.outcome_counts(organsight_dmg.strike_outcome)
.stack(row=["strike", "outcome"])
.stack(col=["challenge", "Sure Strike"])
.to_pandas()
.round(3)
* 100.0
)
| challenge | Weak | Matched | Boss | ||||
|---|---|---|---|---|---|---|---|
| Sure Strike | Normal | Sure Strike | Normal | Sure Strike | Normal | Sure Strike | |
| strike | outcome | ||||||
| initial | Critical success | 50.1 | 75.1 | 25.1 | 43.8 | 5.0 | 9.8 |
| Success | 44.8 | 24.6 | 49.9 | 50.1 | 50.0 | 70.1 | |
| Failure | 5.1 | 0.2 | 19.9 | 5.9 | 39.9 | 19.9 | |
| Critical failure | 0.0 | 0.0 | 5.1 | 0.2 | 5.1 | 0.2 | |
| No roll | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | |
| iterative | Critical success | 0.3 | 0.0 | 1.3 | 0.3 | 2.3 | 1.0 |
| Success | 2.3 | 0.1 | 5.0 | 1.2 | 0.0 | 0.0 | |
| Failure | 2.3 | 0.1 | 11.3 | 2.8 | 20.4 | 9.1 | |
| Critical failure | 0.2 | 0.0 | 7.4 | 1.8 | 22.3 | 10.0 | |
| No roll | 94.9 | 99.8 | 75.0 | 93.9 | 55.0 | 79.8 | |
Combined chance to apply Organsight#
(
pf2.outcome_counts(organsight_dmg)
.stack(row=["strike", "outcome"])
.stack(col=["challenge", "Sure Strike"])
.to_pandas()
.round(3)
* 100.0
)
| challenge | Weak | Matched | Boss | ||||
|---|---|---|---|---|---|---|---|
| Sure Strike | Normal | Sure Strike | Normal | Sure Strike | Normal | Sure Strike | |
| strike | outcome | ||||||
| initial | Critical success | 45.0 | 67.6 | 20.0 | 34.9 | 2.8 | 5.3 |
| Success | 40.3 | 22.1 | 40.0 | 40.2 | 27.4 | 38.5 | |
| No roll | 14.7 | 10.3 | 40.1 | 24.9 | 69.8 | 56.2 | |
| iterative | Critical success | 0.2 | 0.0 | 1.0 | 0.2 | 1.2 | 0.6 |
| Success | 2.1 | 0.1 | 4.0 | 0.9 | 0.0 | 0.0 | |
| No roll | 97.7 | 99.9 | 95.0 | 98.8 | 98.8 | 99.4 | |