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