{ "cells": [ { "cell_type": "markdown", "id": "e8c77db2-aeeb-4a56-b352-ba1821f95d7e", "metadata": {}, "source": [ "# Barrow's Edge\n", "\n", "How reliable is the healing provided by the Exemplar's {prd_ikons}`Barrow's Edge <2>`?\n", "Let's test it with a {prd_weapons}`Greatpick <378>`." ] }, { "cell_type": "code", "execution_count": null, "id": "dbb6c2c7-ce7c-4152-9e40-4e1cecf4688a", "metadata": {}, "outputs": [], "source": [ "# Install in JupyterLite\n", "%pip install -q pathfinder2e-stats\n", "\n", "import matplotlib as mpl # noqa: F401 # Needed by JupyterLite\n", "import xarray\n", "\n", "import pathfinder2e_stats as pf2" ] }, { "cell_type": "code", "execution_count": null, "id": "50ac4967-4e15-441c-98db-ceb57a3d8699", "metadata": {}, "outputs": [], "source": [ "level = 4\n", "half_health_enemy = True" ] }, { "cell_type": "code", "execution_count": null, "id": "c6d91a8d-7106-4b43-ab40-a1e591a60552", "metadata": {}, "outputs": [], "source": [ "atk = (\n", " pf2.tables.SIMPLE_PC.weapon_attack_bonus.exemplar.sum(\"component\")\n", " .sel(level=level)\n", " .item()\n", ")\n", "atk" ] }, { "cell_type": "code", "execution_count": null, "id": "2e534b4b-8ebd-42ec-a641-805327fc2d61", "metadata": {}, "outputs": [], "source": [ "weapon_dice = pf2.tables.PC.weapon_dice.striking_rune.sel(level=level).item()\n", "damage_bonus = (\n", " (\n", " pf2.tables.PC.ability_bonus.boosts.sel(initial=4)\n", " + pf2.tables.PC.weapon_specialization.exemplar\n", " )\n", " .sel(level=level)\n", " .item()\n", ")\n", "\n", "immanence = 3 if half_health_enemy else 1\n", "weapon = (\n", " pf2.armory.pathfinder.melee.greatpick(weapon_dice, damage_bonus)\n", " + pf2.armory.runes.auto(level=level)\n", " + pf2.Damage(\"spirit\", 0, 0, immanence * weapon_dice)\n", ")\n", "weapon" ] }, { "cell_type": "code", "execution_count": null, "id": "55077600-4926-4215-87d9-4c518e4969b5", "metadata": {}, "outputs": [], "source": [ "AC = pf2.tables.SIMPLE_NPC.AC.sel(level=level)\n", "AC.display()" ] }, { "cell_type": "markdown", "id": "6ce4acb5-7132-40d5-afb0-25b1d68944b1", "metadata": {}, "source": [ "Let's compare hitting an enemy without any buffs/debuffs vs. when they're flanked, grabbed, or prone:" ] }, { "cell_type": "code", "execution_count": null, "id": "baf68048-1a36-4c4d-b79e-3ec8218e63c3", "metadata": {}, "outputs": [], "source": [ "off_guard = xarray.DataArray(\n", " [0, -2], dims=\"off-guard\", coords={\"off-guard\": [False, True]}\n", ")" ] }, { "cell_type": "markdown", "id": "789dd97f-a50b-4863-bfde-43ae51bcfbef", "metadata": {}, "source": [ "Both the challenge of the enemy and the off-guard conditions are what-if analyses:\n", "let's roll our Strike only once and compare the output against all of them." ] }, { "cell_type": "code", "execution_count": null, "id": "34757d79-dfc5-4c51-8b0a-c060fcf5496f", "metadata": {}, "outputs": [], "source": [ "pf2.set_config(\n", " check_dependent_dims=[\"challenge\", \"off-guard\"],\n", " damage_dependent_dims=[\"challenge\", \"off-guard\"],\n", ")" ] }, { "cell_type": "markdown", "id": "e29233ea-745f-4436-8724-fc16e656f6cc", "metadata": {}, "source": [ "Let's Strike the enemy! On a hit or critical hit, we will Spark Transcendence to heal ourselves." ] }, { "cell_type": "code", "execution_count": null, "id": "ecd1730b-4ba7-420c-b3d5-394a04c379bd", "metadata": {}, "outputs": [], "source": [ "atk_roll = pf2.check(atk, DC=AC + off_guard)\n", "dmg_roll = pf2.damage(atk_roll, weapon)\n", "barrows_edge_heal = dmg_roll.total_damage // 2\n", "pf2.outcome_counts(atk_roll).display()" ] }, { "cell_type": "markdown", "id": "d7179912-d154-46b6-96b4-7acd198e8d54", "metadata": {}, "source": [ "## Damage distribution" ] }, { "cell_type": "code", "execution_count": null, "id": "189a8ae3-734a-4b83-92ab-7b89ac6f508e", "metadata": {}, "outputs": [], "source": [ "barrows_edge_heal.display()" ] }, { "cell_type": "code", "execution_count": null, "id": "d5689b9c-d2fe-40ab-8f58-e8304bc2b416", "metadata": {}, "outputs": [], "source": [ "total_heal = barrows_edge_heal.stack(col=[\"challenge\", \"off-guard\"])\n", "means = total_heal.mean(\"roll\").to_pandas()\n", "stds = total_heal.std(\"roll\").to_pandas()\n", "_ = means.plot.barh(xerr=stds)" ] }, { "cell_type": "code", "execution_count": null, "id": "76877ba3-be46-49f1-bb93-73070a8e09f9", "metadata": { "scrolled": true }, "outputs": [], "source": [ "bins = barrows_edge_heal.max().item() + 1\n", "_ = (\n", " barrows_edge_heal.stack(col=[\"challenge\", \"off-guard\"])\n", " .to_pandas()\n", " .hist(bins=bins, figsize=(10, 10))\n", ")" ] }, { "cell_type": "markdown", "id": "96cb9839-837a-4905-b93b-41a685f40591", "metadata": {}, "source": [ "## Conclusions\n", "Barrow's Edge provides a solid health drip when fighting against extras, effectively allowing the Exemplar to take on an entire army and just keep going indefinitely.\n", "However, both its reliability and mean effect drastically drop when tanking a boss - which is also what hits the hardest. So you should consider complementing it with {prd_ikons}`Scar of the Survivor <13>` or be backed by a dedicated healer." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.7" } }, "nbformat": 4, "nbformat_minor": 5 }