diff --git a/resources/public/image/black/cursed-star.svg b/resources/public/image/black/cursed-star.svg
new file mode 100644
index 000000000..a4bb31cc4
--- /dev/null
+++ b/resources/public/image/black/cursed-star.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/resources/public/image/cursed-star.svg b/resources/public/image/cursed-star.svg
new file mode 100644
index 000000000..7fc86fb82
--- /dev/null
+++ b/resources/public/image/cursed-star.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/src/clj/orcpub/routes.clj b/src/clj/orcpub/routes.clj
index 7c5cd6d12..4dd1a334f 100644
--- a/src/clj/orcpub/routes.clj
+++ b/src/clj/orcpub/routes.clj
@@ -934,6 +934,7 @@
[route-map/dnd-e5-class-builder-page-route]
[route-map/dnd-e5-language-builder-page-route]
[route-map/dnd-e5-invocation-builder-page-route]
+ [route-map/dnd-e5-boon-builder-page-route]
[route-map/dnd-e5-feat-builder-page-route]
[route-map/dnd-e5-item-list-page-route]
[route-map/dnd-e5-item-page-route :key ":key"]
diff --git a/src/cljc/orcpub/dnd/e5/classes.cljc b/src/cljc/orcpub/dnd/e5/classes.cljc
index 9276bdc87..d3889fd6b 100644
--- a/src/cljc/orcpub/dnd/e5/classes.cljc
+++ b/src/cljc/orcpub/dnd/e5/classes.cljc
@@ -26,6 +26,8 @@
(spec/def ::homebrew-invocation (spec/keys :req-un [::name ::key ::option-pack]))
+(spec/def ::homebrew-boon (spec/keys :req-un [::name ::key ::option-pack]))
+
(defn class-level [levels class-kw]
(get-in levels [class-kw :class-level]))
@@ -2604,7 +2606,17 @@
melee-weapons-xform
weapons)})]}))
-(defn pact-boon-options [spell-lists spells-map]
+(defn pact-boon-options [plugin-boons spell-lists spells-map]
+ (concat
+ (map
+ (fn [{:keys [name description edit-event]}]
+ (t/option-cfg
+ {:name name
+ :modifiers [(mod5e/trait-cfg
+ {:name (str "Pact Boon: " name)
+ :description description})]
+ :edit-event edit-event}))
+ plugin-boons)
[(t/option-cfg
{:name "Pact of the Chain"
:modifiers [(mod5e/spells-known 1 :find-familiar ::char5e/cha "Warlock")
@@ -2639,7 +2651,7 @@
:modifiers [(mod5e/trait-cfg
{:name opt5e/pact-of-the-tome-name
:page 108
- :summary "you have a spellbook with 3 extra cantrips"})]})])
+ :summary "you have a spellbook with 3 extra cantrips"})]})]))
(defn eldritch-invocation-options [plugin-invocations spell-lists spells-map]
@@ -2952,7 +2964,7 @@ long rest."})
false
"uses Mystic Arcanum")}))
-(defn warlock-option [spell-lists spells-map plugin-subclasses-map language-map weapon-map invocations]
+(defn warlock-option [spell-lists spells-map plugin-subclasses-map language-map weapon-map invocations boons]
(opt5e/class-option
spell-lists
spells-map
@@ -3004,7 +3016,7 @@ long rest."})
3 {:selections [(t/selection-cfg
{:name "Pact Boon"
:tags #{:class}
- :options (pact-boon-options spell-lists spells-map)})]}
+ :options (pact-boon-options boons spell-lists spells-map)})]}
5 {:selections [(eldritch-invocation-selection invocations spell-lists spells-map)]}
7 {:selections [(eldritch-invocation-selection invocations spell-lists spells-map)]}
9 {:selections [(eldritch-invocation-selection invocations spell-lists spells-map)]}
diff --git a/src/cljc/orcpub/route_map.cljc b/src/cljc/orcpub/route_map.cljc
index 032352b05..9ba0b7f83 100644
--- a/src/cljc/orcpub/route_map.cljc
+++ b/src/cljc/orcpub/route_map.cljc
@@ -42,6 +42,7 @@
(def dnd-e5-class-builder-page-route :class-builder-5e-page)
(def dnd-e5-language-builder-page-route :language-builder-5e-page)
(def dnd-e5-invocation-builder-page-route :invocation-builder-5e-page)
+(def dnd-e5-boon-builder-page-route :boon-builder-5e-page)
(def dnd-e5-feat-builder-page-route :feat-builder-5e-page)
(def dnd-e5-selection-builder-page-route :selection-builder-5e-page)
@@ -71,6 +72,7 @@
dnd-e5-class-builder-page-route
dnd-e5-language-builder-page-route
dnd-e5-invocation-builder-page-route
+ dnd-e5-boon-builder-page-route
dnd-e5-selection-builder-page-route})
(def dnd-e5-my-encounters-route :my-content-5e-page)
@@ -175,6 +177,7 @@
"class-builder" dnd-e5-class-builder-page-route
"language-builder" dnd-e5-language-builder-page-route
"invocation-builder" dnd-e5-invocation-builder-page-route
+ "boon-builder" dnd-e5-boon-builder-page-route
"feat-builder" dnd-e5-feat-builder-page-route
"spell-builder" dnd-e5-spell-builder-page-route
"selection-builder" dnd-e5-selection-builder-page-route
diff --git a/src/cljs/orcpub/dnd/e5/db.cljs b/src/cljs/orcpub/dnd/e5/db.cljs
index d83385520..100df7c1a 100644
--- a/src/cljs/orcpub/dnd/e5/db.cljs
+++ b/src/cljs/orcpub/dnd/e5/db.cljs
@@ -35,6 +35,7 @@
(def local-storage-background-key "background")
(def local-storage-language-key "language")
(def local-storage-invocation-key "invocation")
+(def local-storage-boon-key "boon")
(def local-storage-selection-key "selection")
(def local-storage-feat-key "feat")
(def local-storage-race-key "race")
@@ -89,6 +90,8 @@
(def default-invocation {})
+(def default-boon {})
+
(def default-selection {:options []})
@@ -130,6 +133,7 @@
::bg5e/builder-item default-background
::langs5e/builder-item default-language
::class5e/invocation-builder-item default-invocation
+ ::class5e/boon-builder-item default-boon
::selections5e/builder-item default-selection
::feats5e/builder-item default-feat
::race5e/builder-item default-race
@@ -187,6 +191,10 @@
(if js/window.localStorage
(set-item local-storage-invocation-key (str invocation))))
+(defn boon->local-store [boon]
+ (if js/window.localStorage
+ (set-item local-storage-boon-key (str boon))))
+
(defn selection->local-store [selection]
(if js/window.localStorage
(set-item local-storage-selection-key (str selection))))
diff --git a/src/cljs/orcpub/dnd/e5/events.cljs b/src/cljs/orcpub/dnd/e5/events.cljs
index 1873c43fa..4d7f1e651 100644
--- a/src/cljs/orcpub/dnd/e5/events.cljs
+++ b/src/cljs/orcpub/dnd/e5/events.cljs
@@ -38,6 +38,7 @@
background->local-store
language->local-store
invocation->local-store
+ boon->local-store
selection->local-store
feat->local-store
race->local-store
@@ -54,6 +55,7 @@
default-background
default-language
default-invocation
+ default-boon
default-selection
default-feat
default-race
@@ -107,6 +109,8 @@
(def invocation->local-store-interceptor (after invocation->local-store))
+(def boon->local-store-interceptor (after boon->local-store))
+
(def selection->local-store-interceptor (after selection->local-store))
(def feat->local-store-interceptor (after feat->local-store))
@@ -156,6 +160,9 @@
(def invocation-interceptors [(path ::class5e/invocation-builder-item)
invocation->local-store-interceptor])
+(def boon-interceptors [(path ::class5e/boon-builder-item)
+ boon->local-store-interceptor])
+
(def selection-interceptors [(path ::selections5e/builder-item)
selection->local-store-interceptor])
@@ -503,6 +510,14 @@
::e5/invocations
"You must specify 'Name', 'Option Source Name'")
+(reg-save-homebrew
+ "Boon"
+ ::class5e/save-boon
+ ::class5e/boon-builder-item
+ ::class5e/homebrew-boon
+ ::e5/boons
+ "You must specify 'Name', 'Option Source Name'")
+
(reg-save-homebrew
"Selection"
::selections5e/save-selection
@@ -581,6 +596,10 @@
::class5e/delete-invocation
::e5/invocations)
+(reg-delete-homebrew
+ ::class5e/delete-boon
+ ::e5/boons)
+
(reg-delete-homebrew
::selections5e/delete-selection
::e5/selections)
@@ -1700,6 +1719,11 @@
::class5e/set-invocation
routes/dnd-e5-invocation-builder-page-route)
+(reg-edit-homebrew
+ ::class5e/edit-boon
+ ::class5e/set-boon
+ routes/dnd-e5-boon-builder-page-route)
+
(reg-edit-homebrew
::selections5e/edit-selection
::selections5e/set-selection
@@ -2540,6 +2564,12 @@
(fn [invocation [_ prop-key prop-value]]
(assoc invocation prop-key prop-value)))
+(reg-event-db
+ ::class5e/set-boon-prop
+ boon-interceptors
+ (fn [boon [_ prop-key prop-value]]
+ (assoc boon prop-key prop-value)))
+
(reg-event-db
::selections5e/set-selection-prop
selection-interceptors
@@ -3241,6 +3271,12 @@
(fn [_ [_ invocation]]
invocation))
+(reg-event-db
+ ::class5e/set-boon
+ boon-interceptors
+ (fn [_ [_ boon]]
+ boon))
+
(reg-event-db
::selections5e/set-selection
selection-interceptors
@@ -3326,6 +3362,12 @@
{:dispatch [::class5e/set-invocation
default-invocation]}))
+(reg-event-fx
+ ::class5e/reset-boon
+ (fn [_ _]
+ {:dispatch [::class5e/set-boon
+ default-boon]}))
+
(reg-event-fx
::selections5e/reset-selection
(fn [_ _]
@@ -3584,6 +3626,12 @@
default-selection
routes/dnd-e5-selection-builder-page-route)
+(reg-new-homebrew
+ ::class5e/new-boon
+ ::class5e/set-boon
+ default-boon
+ routes/dnd-e5-boon-builder-page-route)
+
(reg-new-homebrew
::feats5e/new-feat
::feats5e/set-feat
diff --git a/src/cljs/orcpub/dnd/e5/spell_subs.cljs b/src/cljs/orcpub/dnd/e5/spell_subs.cljs
index 4f6acd1c2..ff91bcf1d 100644
--- a/src/cljs/orcpub/dnd/e5/spell_subs.cljs
+++ b/src/cljs/orcpub/dnd/e5/spell_subs.cljs
@@ -437,6 +437,12 @@
(fn [plugins _]
(apply concat (map (comp vals ::e5/invocations) plugins))))
+(reg-sub
+ ::classes5e/plugin-boons
+ :<- [::e5/plugin-vals]
+ (fn [plugins _]
+ (mapcat #(-> % ::e5/boons vals) plugins)))
+
(def acolyte-bg
{:name "Acolyte"
:help "Your life has been devoted to serving a god or gods."
@@ -854,7 +860,7 @@
tiefling-option-cfg]))))))
-(defn base-class-options [spell-lists spells-map plugin-subclasses-map language-map weapons-map invocations]
+(defn base-class-options [spell-lists spells-map plugin-subclasses-map language-map weapons-map invocations boons]
[(classes5e/barbarian-option spell-lists spells-map plugin-subclasses-map language-map weapons-map)
(classes5e/bard-option spell-lists spells-map plugin-subclasses-map language-map weapons-map)
(classes5e/cleric-option spell-lists spells-map plugin-subclasses-map language-map weapons-map)
@@ -865,7 +871,7 @@
(classes5e/ranger-option spell-lists spells-map plugin-subclasses-map language-map weapons-map)
(classes5e/rogue-option spell-lists spells-map plugin-subclasses-map language-map weapons-map)
(classes5e/sorcerer-option spell-lists spells-map plugin-subclasses-map language-map weapons-map)
- (classes5e/warlock-option spell-lists spells-map plugin-subclasses-map language-map weapons-map invocations)
+ (classes5e/warlock-option spell-lists spells-map plugin-subclasses-map language-map weapons-map invocations boons)
(classes5e/wizard-option spell-lists spells-map plugin-subclasses-map language-map weapons-map)])
(reg-sub
@@ -876,8 +882,9 @@
:<- [::langs5e/language-map]
:<- [::classes5e/plugin-classes]
:<- [::classes5e/invocations]
+ :<- [::classes5e/boons]
:<- [::mi5e/custom-and-standard-weapons-map]
- (fn [[spell-lists spells-map plugin-subclasses-map language-map plugin-classes invocations weapons-map] _]
+ (fn [[spell-lists spells-map plugin-subclasses-map language-map plugin-classes invocations boons weapons-map] _]
(vec
(into
(sorted-set-by #(compare (::t/key %1) (::t/key %2)))
@@ -893,7 +900,7 @@
weapons-map
plugin-class))
plugin-classes))
- (base-class-options spell-lists spells-map plugin-subclasses-map language-map weapons-map invocations))))))
+ (base-class-options spell-lists spells-map plugin-subclasses-map language-map weapons-map invocations boons))))))
(reg-sub
::classes5e/class-map
@@ -937,6 +944,15 @@
(assoc invocation :edit-event [::classes5e/edit-invocation invocation]))
plugin-invocations)))
+(reg-sub
+ ::classes5e/boons
+ :<- [::classes5e/plugin-boons]
+ (fn [plugin-boons]
+ (map
+ (fn [boon]
+ (assoc boon :edit-event [::classes5e/edit-boon boon]))
+ plugin-boons)))
+
(reg-sub
::spells5e/plugin-spells
:<- [::e5/plugin-vals]
@@ -1216,6 +1232,11 @@
(fn [db _]
(::classes5e/invocation-builder-item db)))
+(reg-sub
+ ::classes5e/boon-builder-item
+ (fn [db _]
+ (::classes5e/boon-builder-item db)))
+
(reg-sub
::classes5e/builder-item
(fn [db _]
diff --git a/src/cljs/orcpub/dnd/e5/views.cljs b/src/cljs/orcpub/dnd/e5/views.cljs
index b35a25a8d..1ee61619a 100644
--- a/src/cljs/orcpub/dnd/e5/views.cljs
+++ b/src/cljs/orcpub/dnd/e5/views.cljs
@@ -531,6 +531,8 @@
:route routes/dnd-e5-subclass-builder-page-route}
{:name "Eldritch Invocation Builder"
:route routes/dnd-e5-invocation-builder-page-route}
+ {:name "Pact Boon Builder"
+ :route routes/dnd-e5-boon-builder-page-route}
{:name "Selection Builder"
:route routes/dnd-e5-selection-builder-page-route}]]]]]]))
@@ -4073,6 +4075,9 @@
(defn invocation-input-field [title prop invocation & [class-names]]
(builder-input-field title prop invocation ::classes/set-invocation-prop class-names))
+(defn boon-input-field [title prop boon & [class-names]]
+ (builder-input-field title prop boon ::classes/set-boon-prop class-names))
+
(defn selection-input-field [title prop selection & [class-names]]
(builder-input-field title prop selection ::selections/set-selection-prop class-names))
@@ -6088,6 +6093,27 @@
{:value (get language :description)
:on-change #(dispatch [::langs/set-language-prop :description %])}]]]))
+(defn boon-builder []
+ (let [boon @(subscribe [::classes/boon-builder-item])]
+ [:div.p-20.main-text-color
+ [:div.flex.w-100-p.flex-wrap
+ [boon-input-field
+ "Name"
+ :name
+ boon
+ "m-b-20"]
+ [boon-input-field
+ option-source-name-label
+ :option-pack
+ boon
+ "m-l-5 m-b-20"]]
+ [:div.w-100-p
+ [:div.f-s-24.f-w-b
+ "Description"]
+ [textarea-field
+ {:value (get boon :description)
+ :on-change #(dispatch [::classes/set-boon-prop :description %])}]]]))
+
(defn invocation-builder []
(let [invocation @(subscribe [::classes/invocation-builder-item])]
[:div.p-20.main-text-color
@@ -7168,6 +7194,17 @@
::classes/edit-invocation
::classes/delete-invocation])
+(defn my-boons [name plugin]
+ [my-content-type
+ name
+ plugin
+ "pact boon"
+ ::e5/boons
+ "cursed-star"
+ ::classes/new-boon
+ ::classes/edit-boon
+ ::classes/delete-boon])
+
(defn my-feats [name plugin]
[my-content-type
name
@@ -7226,6 +7263,7 @@
[my-classes name plugin]
[my-subclasses name plugin]
[my-invocations name plugin]
+ [my-boons name plugin]
[my-feats name plugin]
[my-languages name plugin]
[my-selections name plugin]]])])))
@@ -7354,6 +7392,9 @@
(defn invocation-builder-page []
(builder-page "Eldritch Invocation" ::classes/reset-invocation ::classes/save-invocation invocation-builder))
+(defn boon-builder-page []
+ (builder-page "Pact Boon" ::classes/reset-boon ::classes/save-boon boon-builder))
+
(defn selection-builder-page []
(builder-page "Selection" ::selections/reset-selection ::selections/save-selection selection-builder [title-with-help "Selection Builder" selection-help]))
diff --git a/web/cljs/orcpub/core.cljs b/web/cljs/orcpub/core.cljs
index 632724bf4..43568d3f7 100644
--- a/web/cljs/orcpub/core.cljs
+++ b/web/cljs/orcpub/core.cljs
@@ -46,6 +46,7 @@
routes/dnd-e5-feat-builder-page-route views/feat-builder-page
routes/dnd-e5-language-builder-page-route views/language-builder-page
routes/dnd-e5-invocation-builder-page-route views/invocation-builder-page
+ routes/dnd-e5-boon-builder-page-route views/boon-builder-page
routes/dnd-e5-selection-builder-page-route views/selection-builder-page
routes/dnd-e5-item-list-page-route views/item-list
routes/dnd-e5-char-page-route views/character-page