From 74afb69f1e0e441d4d98376163f7729a767a293b Mon Sep 17 00:00:00 2001 From: Noah Bogart Date: Wed, 29 Apr 2026 15:47:04 -0400 Subject: [PATCH] Remove effect macro --- .clj-kondo/config.edn | 26 +- project.clj | 2 +- src/clj/game/cards/agendas.clj | 316 +++++++++---------- src/clj/game/cards/assets.clj | 394 ++++++++++++------------ src/clj/game/cards/basic.clj | 14 +- src/clj/game/cards/events.clj | 492 +++++++++++++++--------------- src/clj/game/cards/hardware.clj | 276 ++++++++--------- src/clj/game/cards/ice.clj | 388 +++++++++++------------ src/clj/game/cards/identities.clj | 266 ++++++++-------- src/clj/game/cards/operations.clj | 292 +++++++++--------- src/clj/game/cards/programs.clj | 388 +++++++++++------------ src/clj/game/cards/resources.clj | 414 ++++++++++++------------- src/clj/game/cards/upgrades.clj | 228 +++++++------- src/clj/game/core.clj | 1 - src/clj/game/core/charge.clj | 2 +- src/clj/game/core/commands.clj | 54 ++-- src/clj/game/core/def_helpers.clj | 34 +-- src/clj/game/core/ice.clj | 8 +- src/clj/game/core/installing.clj | 6 +- src/clj/game/core/optional.clj | 6 +- src/clj/game/core/psi.clj | 4 +- src/clj/game/core/rezzing.clj | 6 +- src/clj/game/core/runs.clj | 6 +- src/clj/game/core/trace.clj | 4 +- src/clj/game/macros.clj | 10 - src/clj/tasks/remove_effect.clj | 93 ++++++ src/clj/web/core.clj | 2 +- 27 files changed, 1902 insertions(+), 1830 deletions(-) create mode 100644 src/clj/tasks/remove_effect.clj diff --git a/.clj-kondo/config.edn b/.clj-kondo/config.edn index a2e64d312f..ba000ea509 100644 --- a/.clj-kondo/config.edn +++ b/.clj-kondo/config.edn @@ -8,21 +8,16 @@ runner-reg-last installed remotes servers unprotected runnable-servers hq-runnable rd-runnable archives-runnable tagged this-card-run this-server - corp-currently-drawing runner-currently-drawing]) - (game.macros/effect [state side eid card targets target context - runner corp run run-server run-ices run-position - current-ice corp-reg corp-reg-last runner-reg - runner-reg-last installed remotes servers - unprotected runnable-servers hq-runnable rd-runnable - archives-runnable tagged this-card-run this-server - corp-currently-drawing runner-currently-drawing]) + corp-currently-drawing runner-currently-drawing + this-card-is-run-source]) (game.macros/msg [state side eid card targets target context runner corp run run-server run-ices run-position current-ice corp-reg corp-reg-last runner-reg runner-reg-last installed remotes servers unprotected runnable-servers hq-runnable rd-runnable archives-runnable tagged this-card-run this-server - corp-currently-drawing runner-currently-drawing]) + corp-currently-drawing runner-currently-drawing + this-card-is-run-source]) (game.macros/wait-for [async-result]) (game.test-framework/do-game [state get-corp get-runner get-run refresh hand-size prompt-map prompt-button @@ -34,21 +29,16 @@ runner-reg-last installed remotes servers unprotected runnable-servers hq-runnable rd-runnable archives-runnable tagged this-card-run this-server - corp-currently-drawing runner-currently-drawing]) - (game.core/effect [state side eid card targets target context - runner corp run run-server run-ices run-position - current-ice corp-reg corp-reg-last runner-reg - runner-reg-last installed remotes servers - unprotected runnable-servers hq-runnable rd-runnable - archives-runnable tagged this-card-run this-server - corp-currently-drawing runner-currently-drawing]) + corp-currently-drawing runner-currently-drawing + this-card-is-run-source]) (game.core/msg [state side eid card targets target context runner corp run run-server run-ices run-position current-ice corp-reg corp-reg-last runner-reg runner-reg-last installed remotes servers unprotected runnable-servers hq-runnable rd-runnable archives-runnable tagged this-card-run this-server - corp-currently-drawing runner-currently-drawing]) + corp-currently-drawing runner-currently-drawing + this-card-is-run-source]) (game.core/wait-for [async-result])]} :invalid-arity {:skip-args [game.macros/effect game.macros/wait-for game.core/effect game.core/wait-for]} diff --git a/project.clj b/project.clj index 46aab77eff..ffebc36fd3 100644 --- a/project.clj +++ b/project.clj @@ -18,7 +18,7 @@ :init-ns web.dev :init (go)} - :dependencies [[org.clojure/clojure "1.12.0"] + :dependencies [[org.clojure/clojure "1.12.4"] [org.clojure/clojurescript "1.11.132" :exclusions [org.clojure/google-closure-library org.clojure/data.json diff --git a/src/clj/game/cards/agendas.clj b/src/clj/game/cards/agendas.clj index d760494936..005c48db42 100644 --- a/src/clj/game/cards/agendas.clj +++ b/src/clj/game/cards/agendas.clj @@ -56,7 +56,7 @@ [game.core.toasts :refer [toast]] [game.core.update :refer [update!]] [game.core.winning :refer [check-win-by-agenda]] - [game.macros :refer [continue-ability effect msg req wait-for]] + [game.macros :refer [continue-ability msg req wait-for]] [game.utils :refer :all] [jinteki.utils :refer :all])) @@ -79,7 +79,7 @@ {:on-score {:msg (msg "gain " (count-ice corp) " [Credits]") :interactive (req true) :async true - :effect (effect (gain-credits eid (count-ice corp)))} + :effect (req (gain-credits state side eid (count-ice corp)))} :static-abilities [{:type :ice-strength :req (req (has-subtype? target subtype)) :value 1}]})) @@ -125,9 +125,9 @@ :cost [(->c :click 1)] :msg "shuffle itself into R&D" :label "Shuffle this agenda into R&D" - :effect (effect (move :corp card :deck nil) - (shuffle! :corp :deck) - (update-all-agenda-points))}] + :effect (req (move state :corp card :deck nil) + (shuffle! state :corp :deck) + (update-all-agenda-points state side))}] :flags {:has-abilities-when-stolen true}}) (defcard "Above the Law" @@ -141,7 +141,7 @@ (resource? %))} :msg (msg "trash " (card-str state target)) :async true - :effect (effect (trash eid target {:cause-card card}))}}) + :effect (req (trash state side eid target {:cause-card card}))}}) (defcard "Accelerated Beta Test" (letfn [(abt [choices] @@ -150,8 +150,8 @@ :choices (cancellable (filter ice? choices) :sorted) :cancel {:msg (msg "trash " (quantify (count choices) " card") " from the top of R&D") :async true - :effect (effect (unregister-events card) - (trash-cards eid choices {:unpreventable true :cause-card card}))} + :effect (req (unregister-events state side card) + (trash-cards state side eid choices {:unpreventable true :cause-card card}))} :effect (req (wait-for (corp-install state side target nil {:ignore-all-cost true :install-state :rezzed-no-cost @@ -180,7 +180,7 @@ :effect (req (register-events state side card [{:event :corp-shuffle-deck - :effect (effect (update! (assoc-in card [:special :shuffle-occurred] true)))}]) + :effect (req (update! state side (assoc-in card [:special :shuffle-occurred] true)))}]) (let [choices (take 3 (:deck corp))] (wait-for (resolve-ability state side @@ -231,13 +231,13 @@ [{:event :corp-turn-begins :unregister-once-resolved true :duration :until-corp-turn-begins - :effect (effect (gain-clicks :corp 1))}]))}}}]}) + :effect (req (gain-clicks state :corp 1))}]))}}}]}) (defcard "Ancestral Imager" {:events [{:event :jack-out :msg "do 1 net damage" :async true - :effect (effect (damage eid :net 1 {:card card}))}]}) + :effect (req (damage state side eid :net 1 {:card card}))}]}) (defcard "AR-Enhanced Security" {:events [{:event :runner-trash @@ -248,7 +248,7 @@ (and (valid-ctx? targets) (first-event? state side :runner-trash valid-ctx?)))) :msg "give the Runner a tag" - :effect (effect (gain-tags eid 1))}]}) + :effect (req (gain-tags state side eid 1))}]}) (defcard "Architect Deployment Test" {:on-score (combine-abilities @@ -286,14 +286,14 @@ :req (req run) :label "increase cost to break subroutines or jack out" :msg "make the Runner trash a card from the grip as an additional cost to jack out or break subroutines for the remainder of the run" - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card {:type :break-sub-additional-cost :duration :end-of-run :value (req (repeat (count (:broken-subs (:ability context))) (->c :trash-from-hand 1)))}) (register-lingering-effect - card + state side card {:type :jack-out-additional-cost :duration :end-of-run :value (->c :trash-from-hand 1)}))}]}) @@ -302,7 +302,7 @@ {:on-score {:async true :msg "make the Runner lose 7 [Credits]" - :effect (effect (lose-credits :runner eid 7))}}) + :effect (req (lose-credits state :runner eid 7))}}) (defcard "AstroScript Pilot Program" {:on-score (agenda-counters 1) @@ -315,8 +315,8 @@ :waiting-prompt true :prompt "How many advancement counters do you want to place?" :choices ["0" "1" "2"] - :effect (effect (continue-ability - (let [c (str->int target)] + :effect (req (continue-ability + state side (let [c (str->int target)] {:choices {:req (req (can-be-advanced? state target))} :msg (msg "place " (quantify c "advancement counter") " on " (card-str state target)) @@ -330,7 +330,7 @@ :msg "do 2 meat damage" :automatic :damage :interactive (req true) - :effect (effect (damage eid :meat 2 {:card card}))}}) + :effect (req (damage state side eid :meat 2 {:card card}))}}) (defcard "Bacterial Programming" (letfn [(remove-card [remaining target] @@ -428,14 +428,14 @@ (defcard "The Basalt Spire" {:on-score (agenda-counters 2) :stolen {:async true - :effect (effect (continue-ability (corp-recur) card nil))} + :effect (req (continue-ability state side (corp-recur) card nil))} :flags {:has-abilities-when-stolen true} :abilities [{:label "Choose a card to add to HQ" :cost [(->c :trash-from-deck 1) (->c :agenda 1)] :once :per-turn :msg "add 1 card from Archives to HQ" :async true - :effect (effect (continue-ability (corp-recur) card nil))}]}) + :effect (req (continue-ability state side (corp-recur) card nil))}]}) (defcard "Bellona" {:steal-cost-bonus (req [(->c :credit 5)]) @@ -453,7 +453,7 @@ :yes-ability {:async true :msg "give the Runner a tag for playing a run event" - :effect (effect (gain-tags :corp eid 1))}}} + :effect (req (gain-tags state :corp eid 1))}}} {:event :runner-install :silent true :optional @@ -467,7 +467,7 @@ :yes-ability {:async true :msg "give the Runner a tag for installing an icebreaker" - :effect (effect (gain-tags :corp eid 1))}}}] + :effect (req (gain-tags state :corp eid 1))}}}] :abilities [(set-autoresolve :auto-fire "Better Citizen Program")]}) (defcard "Bifrost Array" @@ -483,7 +483,7 @@ (when-scored? %))} :msg (msg "trigger the \"when scored\" ability of " (:title target)) :async true - :effect (effect (continue-ability (:on-score (card-def target)) target nil))}}}}) + :effect (req (continue-ability state side (:on-score (card-def target)) target nil))}}}}) (defcard "Blood in the Water" {:x-fn (req (count (:hand runner))) @@ -525,9 +525,9 @@ (defcard "Breaking News" {:on-score (give-tags 2) :events (let [event {:unregister-once-resolved true - :req (effect (first-event? :agenda-scored #(same-card? card (:card (first %))))) + :req (req (first-event? state side :agenda-scored #(same-card? card (:card (first %))))) :msg "make the Runner lose 2 tags" - :effect (effect (lose :runner :tag 2))}] + :effect (req (lose state :runner :tag 2))}] [(assoc event :event :corp-turn-ends) (assoc event :event :runner-turn-ends)])}) @@ -542,14 +542,14 @@ :effect (req (wait-for (gain-bad-publicity state :corp 1) (agenda-counters state side card eid)))} :no-ability {:async true - :effect (effect (agenda-counters card eid))}}} + :effect (req (agenda-counters state side card eid))}}} :abilities [{:action true :cost [(->c :click 1) (->c :agenda 1)] :async true :label "Do 2 meat damage" :once :per-turn :msg "do 2 meat damage" - :effect (effect (damage eid :meat 2 {:card card}))}]})) + :effect (req (damage state side eid :meat 2 {:card card}))}]})) (defcard "CFC Excavation Contract" (letfn [(bucks [state] @@ -560,7 +560,7 @@ {:on-score {:async true :msg (msg "gain " (bucks state) " [Credits]") - :effect (effect (gain-credits :corp eid (bucks state)))}})) + :effect (req (gain-credits state :corp eid (bucks state)))}})) (defcard "Character Assassination" {:on-score @@ -570,14 +570,14 @@ :msg (msg "trash " (:title target)) :interactive (req true) :async true - :effect (effect (trash eid target {:unpreventable true :cause-card card}))}}) + :effect (req (trash state side eid target {:unpreventable true :cause-card card}))}}) (defcard "Chronos Project" {:on-score {:req (req (not (zone-locked? state :runner :discard))) :msg "remove all cards in the heap from the game" :interactive (req true) - :effect (effect (move-zone :runner :discard :rfg))}}) + :effect (req (move-zone state :runner :discard :rfg))}}) (defcard "City Works Project" (letfn [(meat-damage [s c] (+ 2 (get-counters (get-card s c) :advancement)))] @@ -585,14 +585,14 @@ :on-access {:req (req installed) :msg (msg "do " (meat-damage state card) " meat damage") :async true - :effect (effect (damage eid :meat (meat-damage state card) {:card card}))}})) + :effect (req (damage state side eid :meat (meat-damage state card) {:card card}))}})) (defcard "Clone Retirement" {:on-score {:msg "remove 1 bad publicity" - :effect (effect (lose-bad-publicity 1)) + :effect (req (lose-bad-publicity state side 1)) :silent true} :stolen {:msg "force the Corp to take 1 bad publicity" - :effect (effect (gain-bad-publicity :corp 1))}}) + :effect (req (gain-bad-publicity state :corp 1))}}) (defcard "Corporate Oversight A" {:on-score @@ -601,22 +601,22 @@ {:prompt "Search R&D for a piece of ice to install protecting a remote server?" :yes-ability {:async true - :effect (effect + :effect (req (continue-ability - (if (not-empty (filter ice? (:deck corp))) + state side (if (not-empty (filter ice? (:deck corp))) {:async true :prompt "Choose a piece of ice" :choices (req (filter ice? (:deck corp))) :effect - (effect + (req (continue-ability - (let [chosen-ice target] + state side (let [chosen-ice target] {:async true :prompt (str "Choose a server to install " (:title chosen-ice) " on") :choices (filter #(not (#{"HQ" "Archives" "R&D"} %)) (installable-servers state chosen-ice)) - :effect (effect (shuffle! :deck) - (corp-install eid chosen-ice target + :effect (req (shuffle! state side :deck) + (corp-install state side eid chosen-ice target {:ignore-all-cost true :install-state :rezzed-no-cost}))}) card nil))} @@ -624,7 +624,7 @@ :choices ["Carry on!"] :prompt-type :bogus :msg "shuffle R&D" - :effect (effect (shuffle! :deck))}) + :effect (req (shuffle! state side :deck))}) card nil))}}}}) (defcard "Corporate Oversight B" @@ -634,22 +634,22 @@ {:prompt "Search R&D for a piece of ice to install protecting a central server?" :yes-ability {:async true - :effect (effect + :effect (req (continue-ability - (if (not-empty (filter ice? (:deck corp))) + state side (if (not-empty (filter ice? (:deck corp))) {:async true :prompt "Choose a piece of ice" :choices (req (filter ice? (:deck corp))) :effect - (effect + (req (continue-ability - (let [chosen-ice target] + state side (let [chosen-ice target] {:async true :prompt (str "Choose a server to install " (:title chosen-ice) " on") :choices (filter #(#{"HQ" "Archives" "R&D"} %) (installable-servers state chosen-ice)) - :effect (effect (shuffle! :deck) - (corp-install eid chosen-ice target + :effect (req (shuffle! state side :deck) + (corp-install state side eid chosen-ice target {:ignore-all-cost true :install-state :rezzed-no-cost}))}) card nil))} @@ -657,7 +657,7 @@ :choices ["Carry on!"] :prompt-type :bogus :msg "shuffle R&D" - :effect (effect (shuffle! :deck))}) + :effect (req (shuffle! state side :deck))}) card nil))}}}}) (defcard "Corporate Sales Team" @@ -686,7 +686,7 @@ :automatic :corp-damage :once :per-turn :msg "do 1 meat damage" - :effect (effect (damage eid :meat 1 {:card card}))}] + :effect (req (damage state side eid :meat 1 {:card card}))}] {:events [(assoc ability :event :corp-turn-begins)] :abilities [ability]})) @@ -695,7 +695,7 @@ {:prompt "Purge virus counters?" :yes-ability {:msg "purge virus counters" :async true - :effect (effect (purge eid))}}} + :effect (req (purge state side eid))}}} :events [{:event :purge :req (req (first-event? state :corp :purge)) :msg "gain 4 [Credits]" @@ -709,12 +709,12 @@ (first-event? state side :successful-run #(= :hq (target-server (first %))))) :not-equal {:async true - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card {:type :corp-choose-hq-access :duration :end-of-run :value true}) - (effect-completed eid))}}}]}) + (effect-completed state side eid))}}}]}) (defcard "Degree Mill" {:steal-cost-bonus (req [(->c :shuffle-installed-to-stack 2)])}) @@ -775,7 +775,7 @@ :cost [(->c :click 3)] :msg "place 1 agenda counter on itself" :async true - :effect (effect (add-agenda-point-counters eid card 1))}]}) + :effect (req (add-agenda-point-counters state side eid card 1))}]}) (defcard "Élivágar Bifurcation" {:on-score @@ -806,9 +806,9 @@ {:on-score (agenda-counters 3) :abilities [{:action true :cost [(->c :click 1) (->c :agenda 1)] - :effect (effect (gain-clicks 2) + :effect (req (gain-clicks state side 2) (register-turn-flag! - card :can-advance + state side card :can-advance (constantly false))) :keep-menu-open :while-agenda-tokens-left :msg "gain [Click][Click]"}]}) @@ -818,7 +818,7 @@ :abilities [{:action true :cost [(->c :click 1) (->c :agenda 1)] :once :per-turn - :effect (effect (gain-clicks 2)) + :effect (req (gain-clicks state side 2)) :msg "gain [Click][Click]"}]}) (defcard "Embedded Reporting" @@ -891,7 +891,7 @@ :once :per-turn :msg (msg "gain " (count-tags state) " [Credits]") :async true - :effect (effect (gain-credits eid (count-tags state)))}]}) + :effect (req (gain-credits state side eid (count-tags state)))}]}) (defcard "Executive Retreat" {:on-score {:async true @@ -932,7 +932,7 @@ :label "runner loses [Click][Click]" :msg "force the Runner to lose [Click][Click]" :cost [(->c :forfeit-self)] - :effect (effect (lose-clicks :runner 2))}] + :effect (req (lose-clicks state :runner 2))}] ;; this even doesn't correlate 1:1 with the card text - ;; this exists so you can avoid needing to click this before the runner clicks a basic action ;; (ie click racing your opponent). @@ -966,7 +966,7 @@ :msg (msg "place 1 advancement counter on " (card-str state target)) :once :per-turn :async true - :effect (effect (add-prop eid target :advance-counter 1 {:placed true}))}]}) + :effect (req (add-prop state side eid target :advance-counter 1 {:placed true}))}]}) (defcard "Flower Sermon" {:on-score (agenda-counters 5) @@ -988,7 +988,7 @@ :corp (msg "add facedown " (:title target) " to the top of R&D")} :choices {:card #(and (in-hand? %) (corp? %))} - :effect (effect (move target :deck {:front true}))} + :effect (req (move state side target :deck {:front true}))} card nil))))}]}) (defcard "Fly on the Wall" @@ -1001,7 +1001,7 @@ (let [ability {:async true :interactive (req true) :msg "do 2 net damage" - :effect (effect (damage eid :net 2 {:card card}))}] + :effect (req (damage state side eid :net 2 {:card card}))}] {:stolen ability :on-score ability})) @@ -1030,7 +1030,7 @@ :msg "gain 3 [Credits]" :async true :keep-menu-open :while-2-clicks-left - :effect (effect (gain-credits eid 3))}]}) + :effect (req (gain-credits state side eid 3))}]}) (defcard "Glenn Station" {:abilities [{:action true @@ -1041,7 +1041,7 @@ :msg "host a card from HQ" :prompt "Choose a card to host" :choices {:card #(and (corp? %) (in-hand? %))} - :effect (effect (host card target {:facedown true}))} + :effect (req (host state side card target {:facedown true}))} {:action true :label "Add a hosted card to HQ" :change-in-game-state {:req (req (not-empty (filter corp? (:hosted card))))} @@ -1055,7 +1055,7 @@ (map :cid) (into #{}))] (hosted-corp-cards (:cid target))))} - :effect (effect (move target :hand))}]}) + :effect (req (move state side target :hand))}]}) (defcard "Global Food Initiative" {:agendapoints-runner (req 2)}) @@ -1071,7 +1071,7 @@ :cost [(->c :click 1)] :async true :keep-menu-open :while-clicks-left - :effect (effect (gain-credits eid 3)) + :effect (req (gain-credits state side eid 3)) :msg "gain 3 [Credits]"}]}) (defcard "Graft" @@ -1089,7 +1089,7 @@ {:on-score {:async true :msg "add up to 3 cards from R&D to HQ" - :effect (effect (continue-ability (graft 1) card nil))}})) + :effect (req (continue-ability state side (graft 1) card nil))}})) (defcard "Greenmail" ;; "When you score this agenda, gain 2{c}. @@ -1106,7 +1106,7 @@ :once :per-turn :choices {:card #(and (corp? %) (in-discard? %))} - :effect (effect (move target :deck)) + :effect (req (move state side target :deck)) :msg (msg "add " (if (:seen target) (:title target) @@ -1142,7 +1142,7 @@ :msg (msg "gain " (:credit runner) " [Credits]") :async true :keep-menu-open :while-agenda-tokens-left - :effect (effect (gain-credits eid (:credit runner)))}]}) + :effect (req (gain-credits state side eid (:credit runner)))}]}) (defcard "Hollywood Renovation" {:install-state :face-up @@ -1158,7 +1158,7 @@ :msg (msg "place " (quantify n "advancement counter") " on " (card-str state target)) :async true - :effect (effect (add-prop :corp eid target :advance-counter n {:placed true}))} + :effect (req (add-prop state :corp eid target :advance-counter n {:placed true}))} card nil)))}]}) (defcard "Hostile Takeover" @@ -1175,7 +1175,7 @@ :req (req (:run @state)) :once :per-run :async true - :effect (effect (damage eid :net 1 {:card card}))}]}) + :effect (req (damage state side eid :net 1 {:card card}))}]}) (defcard "Hybrid Release" {:on-score {:prompt "Choose a facedown card in Archives to install" @@ -1186,7 +1186,7 @@ :choices {:card #(and (corp-installable-type? %) (in-discard? %) (not (faceup? %)))} - :effect (effect (corp-install eid target nil {:msg-keys {:install-source card + :effect (req (corp-install state side eid target nil {:msg-keys {:install-source card :display-origin true}}))}}) (defcard "Hyperloop Extension" @@ -1205,7 +1205,7 @@ {:prompt "Take 1 bad publicity?" :yes-ability {:msg "take 1 bad publicity" :async true - :effect (effect (gain-bad-publicity :corp eid 1))}}} + :effect (req (gain-bad-publicity state :corp eid 1))}}} card nil) (let [n (* 3 (count-bad-pub state))] (system-msg state side (str "uses " (:title card) " to gain " n " [Credits]")) @@ -1215,7 +1215,7 @@ (let [ability {:async true :interactive (req true) :msg "make the Runner gain 4 [Credits]" - :effect (effect (gain-credits :runner eid 4))}] + :effect (req (gain-credits state :runner eid 4))}] {:on-score ability :stolen ability})) @@ -1245,7 +1245,7 @@ (is-remote? (second (get-zone %))))} :msg (msg "place 2 advancement counters on " (card-str state target)) :async true - :effect (effect (add-prop :corp eid target :advance-counter 2 {:placed true}))}]}) + :effect (req (add-prop state :corp eid target :advance-counter 2 {:placed true}))}]}) (defcard "Kimberlite Field" {:on-score @@ -1266,7 +1266,7 @@ (<= (:cost %) target-cost))} :msg (msg "trash " (:title target)) :async true - :effect (effect (trash eid target))} + :effect (req (trash state side eid target))} card nil))))}}) (defcard "Kingmaking" @@ -1352,7 +1352,7 @@ (or (in-hand? %) (in-discard? %)))} :msg (msg "install and rez " (:title target) ", ignoring all costs") :async true - :effect (effect (corp-install eid target nil {:install-state :rezzed-no-cost + :effect (req (corp-install state side eid target nil {:install-state :rezzed-no-cost :msg-keys {:install-source card :display-origin true}}))}}) @@ -1488,7 +1488,7 @@ (effect-completed state side eid))))})] {:on-score {:async true :msg "rearrange any number of ice" - :effect (effect (continue-ability (msr) card nil))}})) + :effect (req (continue-ability state side (msr) card nil))}})) (defcard "Mandatory Upgrades" {:move-zone (req (if (and (in-scored? card) @@ -1507,7 +1507,7 @@ {:on-score {:interactive (req true) :req (req tagged) :async true - :effect (effect (add-agenda-point-counters eid card 1))} + :effect (req (add-agenda-point-counters state side eid card 1))} :agendapoints-corp (req (if (zero? (get-counters card :agenda)) 2 3))}) (defcard "Medical Breakthrough" @@ -1527,7 +1527,7 @@ :req (req (< 1 (count (filter #(= (:title %) "Megaprix Qualifier") (concat (:scored corp) (:scored runner)))))) :async true - :effect (effect (add-agenda-point-counters eid card 1))} + :effect (req (add-agenda-point-counters state side eid card 1))} :agendapoints-corp (req (if (zero? (get-counters card :agenda)) 1 2))}) (defcard "Merger" @@ -1555,13 +1555,13 @@ (defcard "Midnight-3 Arcology" {:on-score {:async true :msg (msg "draw 3 cards and skip [their] discard step this turn") - :effect (effect + :effect (req (register-lingering-effect - card + state side card {:type :skip-discard :duration :end-of-turn :value true}) - (draw :corp eid 3))}}) + (draw state :corp eid 3))}}) (defcard "NAPD Contract" {:steal-cost-bonus (req [(->c :credit 4)]) @@ -1596,8 +1596,8 @@ (when (<= 5 (get-counters (get-card state card) :advancement)) " and rez it, ignoring all costs")) :async true - :effect (effect (corp-install - eid target "New remote" + :effect (req (corp-install + state side eid target "New remote" {:install-state (when (<= 5 (get-counters (get-card state card) :advancement)) :rezzed-no-cost) :msg-keys {:install-source card :display-origin true}}))}}}]}) @@ -1634,9 +1634,9 @@ {:on-score {:async true :effect - (effect + (req (continue-ability - (when (some #(and (rezzed? %) + state side (when (some #(and (rezzed? %) (ice? %) (has-subtype? % "NEXT")) (all-installed state :corp)) @@ -1644,7 +1644,7 @@ {:prompt "Do 1 core damage?" :yes-ability {:msg "do 1 core damage" :async true - :effect (effect (damage eid :brain 1 {:card card}))}}}) + :effect (req (damage state side eid :brain 1 {:card card}))}}}) card nil))}}) (defcard "Nisei MK II" @@ -1653,7 +1653,7 @@ :cost [(->c :agenda 1)] :msg "end the run" :async true - :effect (effect (end-run eid card))}]}) + :effect (req (end-run state side eid card))}]}) (defcard "Oaktown Renovation" {:install-state :face-up @@ -1662,7 +1662,7 @@ :req (req (same-card? card (:card context))) :msg (msg "gain " (if (>= (get-counters (get-card state card) :advancement) 5) "3" "2") " [Credits]") :async true - :effect (effect (gain-credits eid (if (<= 5 (get-counters (get-card state card) :advancement)) 3 2)))}]}) + :effect (req (gain-credits state side eid (if (<= 5 (get-counters (get-card state card) :advancement)) 3 2)))}]}) (defcard "Obokata Protocol" {:steal-cost-bonus (req [(->c :net 4)])}) @@ -1708,9 +1708,9 @@ :req (req (is-scored? state :runner card)) :msg "shuffle itself into R&D" :label "Shuffle this agenda into R&D" - :effect (effect (move :corp card :deck nil) - (shuffle! :corp :deck) - (update-all-agenda-points))}] + :effect (req (move state :corp card :deck nil) + (shuffle! state :corp :deck) + (update-all-agenda-points state side))}] :flags {:has-abilities-when-stolen true}}) (defcard "Orbital Superiority" @@ -1752,7 +1752,7 @@ :req (req (pos? (count (:scored runner)))) :msg (msg "do " (count (:scored runner)) " net damage") :async true - :effect (effect (damage eid :net (count (:scored runner)) {:card card}))}}) + :effect (req (damage state side eid :net (count (:scored runner)) {:card card}))}}) (defcard "Post-Truth Dividend" {:on-score {:optional @@ -1760,9 +1760,9 @@ :yes-ability {:msg "draw 1 card" :async true - :effect (effect (draw eid 1))} + :effect (req (draw state side eid 1))} :no-ability - {:effect (effect (system-msg (str "declines to use " (:title card))))}}}}) + {:effect (req (system-msg state side (str "declines to use " (:title card))))}}}}) (defcard "Posted Bounty" {:on-score {:optional @@ -1779,7 +1779,7 @@ {:on-score {:interactive (req true) :choices {:card (every-pred ice? installed? (complement rezzed?))} :async true - :effect (effect (rez eid target {:ignore-cost :all-costs}))}}) + :effect (req (rez state side eid target {:ignore-cost :all-costs}))}}) (defcard "Private Security Force" {:abilities [{:action true @@ -1787,7 +1787,7 @@ :cost [(->c :click 1)] :keep-menu-open :while-clicks-left :async true - :effect (effect (damage eid :meat 1 {:card card})) + :effect (req (damage state side eid :meat 1 {:card card})) :msg "do 1 meat damage"}]}) (defcard "Profiteering" @@ -1832,8 +1832,8 @@ :msg (msg "add " (:title target) " to HQ from R&D") :choices (req (cancellable (:deck corp) :sorted)) :cancel {:msg "decide they don't want to tutor a card after all"} - :effect (effect (shuffle! :deck) - (move target :hand))}]}) + :effect (req (shuffle! state side :deck) + (move state side target :hand))}]}) (defcard "Project Beale" (project-agenda {:granularity 2}) @@ -1873,8 +1873,8 @@ :keep-menu-open :while-agenda-tokens-left :msg (str "make a piece of ice gain \"[Subroutine] Do 1 net damage\" " "after all its other subroutines for the remainder of the run") - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card (let [t target] {:type :additional-subroutines :duration :end-of-run @@ -1927,8 +1927,8 @@ :keep-menu-open :while-agenda-tokens-left :msg (str "make the approached piece of Bioroid ice gain \"[Subroutine] End the run\"" "after all its other subroutines for the remainder of this run") - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card (let [card-target current-ice] {:type :additional-subroutines :duration :end-of-run @@ -1936,7 +1936,7 @@ :value {:subroutines [{:label "End the run" :msg "end the run" :async true - :effect (effect (end-run eid card))}]}})))}]}) + :effect (req (end-run state side eid card))}]}})))}]}) (defcard "Project Yagi-Uda" (letfn [(choose-swap [to-swap] @@ -1959,7 +1959,7 @@ {:async true :prompt "Choose a card in or protecting the attacked server" :choices {:card #(= (first run-server) (second (get-zone %)))} - :effect (effect (continue-ability (choose-swap target) card nil))})] + :effect (req (continue-ability state side (choose-swap target) card nil))})] (project-agenda {:abilities [{:async true :waiting-prompt true @@ -1967,7 +1967,7 @@ :keep-menu-open false ;; not using :while-agenda-tokens-left as the typical use case is only one token, even if there are multiple :label "swap card in HQ with installed card" :req (req (and run (can-pay? state side eid card nil [(->c :agenda 1)]))) - :effect (effect (continue-ability (choose-card (:server run)) card nil))}]}))) + :effect (req (continue-ability state side (choose-card (:server run)) card nil))}]}))) (defcard "Puppet Master" {:events [{:event :successful-run @@ -1978,12 +1978,12 @@ :choices {:req (req (can-be-advanced? state card))} :msg (msg "place 1 advancement counter on " (card-str state target)) :async true - :effect (effect (add-prop :corp eid target :advance-counter 1 {:placed true}))}]}) + :effect (req (add-prop state :corp eid target :advance-counter 1 {:placed true}))}]}) (defcard "Proprionegation" {:on-score {:silent true :async true - :effect (effect (add-counter eid card :agenda 1))} + :effect (req (add-counter state side eid card :agenda 1))} :abilities [{:req (req (:run @state)) :cost [(->c :agenda 1)] ;; you can't get redirected from a ganked encounter (ie during success) @@ -2021,9 +2021,9 @@ :prompt "Quantum Predictive Model will be added to the Corp's score area" :choices ["OK"] :msg (msg "add itself to [their] score area and gain 1 agenda point") - :effect (effect (move :corp card :scored {:force true}) - (update-all-agenda-points) - (check-win-by-agenda))}}) + :effect (req (move state :corp card :scored {:force true}) + (update-all-agenda-points state side) + (check-win-by-agenda state side))}}) (defcard "Rebranding Team" {:move-zone (req (when (and (in-scored? card) @@ -2122,22 +2122,22 @@ {:prompt "Search R&D for a piece of ice to install protecting a remote server?" :yes-ability {:async true - :effect (effect + :effect (req (continue-ability - (if (not-empty (filter ice? (:deck corp))) + state side (if (not-empty (filter ice? (:deck corp))) {:async true :prompt "Choose a piece of ice" :choices (req (filter ice? (:deck corp))) :cancel shuffle-my-deck! - :effect (effect + :effect (req (continue-ability - (let [chosen-ice target] + state side (let [chosen-ice target] {:async true :prompt (str "Choose a server to install " (:title chosen-ice) " on") :choices (filter #(not (#{"HQ" "Archives" "R&D"} %)) (installable-servers state chosen-ice)) - :effect (effect (shuffle! :deck) - (corp-install eid chosen-ice target + :effect (req (shuffle! state side :deck) + (corp-install state side eid chosen-ice target {:install-state :rezzed-no-rez-cost :msg-keys {:install-source card :display-origin true}}))}) @@ -2146,20 +2146,20 @@ :choices ["Carry on!"] :prompt-type :bogus :msg "shuffle R&D" - :effect (effect (shuffle! :deck))}) + :effect (req (shuffle! state side :deck))}) card nil))}}}}) (defcard "Research Grant" {:on-score {:interactive (req true) :silent (req (empty? (filter #(= (:title %) (:title card)) (all-installed state :corp)))) :async true - :effect (effect (continue-ability - {:prompt (str "Choose another installed copy of " (:title card) " to score") + :effect (req (continue-ability + state side {:prompt (str "Choose another installed copy of " (:title card) " to score") :choices {:card #(= (:title %) (:title card))} :interactive (req true) :async true :req (req (seq (filter #(= (:title %) (:title card)) (all-installed state :corp)))) - :effect (effect (score eid (get-card state target) {:no-req true})) + :effect (req (score state side eid (get-card state target) {:no-req true})) :msg "score another installed copy of itself"} card nil))}}) @@ -2179,7 +2179,7 @@ (first-event? state side :advance #(same-card? card (:card (first %)))))) :msg (msg "gain 3 [Credits]") :async true - :effect (effect (gain-credits eid 3))} + :effect (req (gain-credits state side eid 3))} {:event :successful-run :condition :faceup :optional {:prompt "Do 1 meat damage?" @@ -2201,7 +2201,7 @@ :yes-ability {:msg "do 1 core damage" :async true - :effect (effect (damage eid :brain 1 {:card card}))}}}]}) + :effect (req (damage state side eid :brain 1 {:card card}))}}}]}) (defcard "SDS Drone Deployment" {:steal-cost-bonus (req [(->c :program 1)]) @@ -2213,7 +2213,7 @@ :all true} :msg (msg "trash " (:title target)) :async true - :effect (effect (trash eid target {:cause-card card}))}}) + :effect (req (trash state side eid target {:cause-card card}))}}) (defcard "See How They Run" {:on-score {:interactive (req true) @@ -2226,10 +2226,10 @@ {:msg "start a psi game (do 1 core damage / do 1 net damage)" :psi {:not-equal {:msg "do 1 core damage" :async true - :effect (effect (damage eid :brain 1 {:card card}))} + :effect (req (damage state side eid :brain 1 {:card card}))} :equal {:async true :msg "do 1 net damage" - :effect (effect (damage eid :net 1 {:card card}))}}} + :effect (req (damage state side eid :net 1 {:card card}))}}} card nil)))}}) (defcard "Self-Destruct Chips" @@ -2247,7 +2247,7 @@ (not (rezzed? %)) (installed? %))} :async true - :effect (effect (rez eid target {:ignore-cost :all-costs}))}] + :effect (req (rez state side eid target {:ignore-cost :all-costs}))}] {:on-score ability :stolen ability})) @@ -2272,7 +2272,7 @@ :unregister-once-resolved true :duration :end-of-turn :async true - :effect (effect (derez eid c))}]) + :effect (req (derez state side eid c))}]) (effect-completed state side eid))))}]}) (defcard "Sentinel Defense Program" @@ -2281,7 +2281,7 @@ (= (:damage-type context) :brain))) :msg "do 1 net damage" :async true - :effect (effect (damage eid :net 1 {:card card}))}]}) + :effect (req (damage state side eid :net 1 {:card card}))}]}) (defcard "Sericulture Expansion" (project-agenda {:mode :computed}) @@ -2294,7 +2294,7 @@ (defcard "Show of Force" {:on-score {:async true :msg "do 2 meat damage" - :effect (effect (damage eid :meat 2 {:card card}))}}) + :effect (req (damage state side eid :meat 2 {:card card}))}}) (defcard "Sisyphus Protocol" (letfn [(rezzed-gate-or-sentry [context] @@ -2380,8 +2380,8 @@ {:on-score {:interactive (req true) :async true - :effect (effect (show-wait-prompt (str (side-str (other-side side)) " to trash a card for Standoff")) - (continue-ability :runner (stand :runner) card nil))}})) + :effect (req (show-wait-prompt state side (str (side-str (other-side side)) " to trash a card for Standoff")) + (continue-ability state :runner (stand :runner) card nil))}})) (defcard "Stegodon MK IV" {:events [{:event :run @@ -2410,7 +2410,7 @@ state side :derez (fn [[context]] (some ice? (:cards context)))))) :msg "lower strength of each installed icebreaker by 2"}] - :leave-play (effect (update-all-icebreakers)) + :leave-play (req (update-all-icebreakers state side)) :static-abilities [{:type :breaker-strength :value -2 :req (req (and run @@ -2424,10 +2424,10 @@ (count (filter #(= (:title %) "Sting!") (get-in @state [(other-side side) :scored]))))] {:on-score {:msg (msg "deal " (inc (count-opp-stings state :corp)) " net damage") :async true - :effect (effect (damage eid :net (inc (count-opp-stings state :corp)) {:card card}))} + :effect (req (damage state side eid :net (inc (count-opp-stings state :corp)) {:card card}))} :stolen {:msg (msg "deal " (inc (count-opp-stings state :runner)) " net damage") :async true - :effect (effect (damage eid :net (inc (count-opp-stings state :runner)) {:card card}))}})) + :effect (req (damage state side eid :net (inc (count-opp-stings state :runner)) {:card card}))}})) (defcard "Stoke the Embers" (letfn [(score-abi @@ -2482,7 +2482,7 @@ {:prompt "Draw 2 cards?" :yes-ability {:msg "draw 2 cards" :async true - :effect (effect (draw :corp eid 2))}}}}) + :effect (req (draw state :corp eid 2))}}}}) (defcard "Superior Cyberwalls" (ice-boost-agenda "Barrier")) @@ -2513,8 +2513,8 @@ :choices (req (:deck corp)) :msg "add a card from R&D to HQ and shuffle R&D" :req (req (pos? (count (:deck corp)))) - :effect (effect (shuffle! :deck) - (move target :hand))}}) + :effect (req (shuffle! state side :deck) + (move state side target :hand))}}) (defcard "The Future Perfect" {:flags {:rd-reveal (req true)} @@ -2522,10 +2522,10 @@ :not-equal {:msg "prevent itself from being stolen" :async true - :effect (effect (register-run-flag! - card :can-steal + :effect (req (register-run-flag! + state side card :can-steal (fn [_ _ c] (not (same-card? c card)))) - (effect-completed eid))}}}}) + (effect-completed state side eid))}}}}) (defcard "Timely Public Release" {:on-score (agenda-counters 1) @@ -2539,15 +2539,15 @@ (in-discard? %)))} :async true :msg "install an ice from HQ or Archives" - :effect (effect + :effect (req (continue-ability - (let [chosen-ice target] + state side (let [chosen-ice target] {:prompt "Choose a server" :choices (req (installable-servers state chosen-ice)) :async true - :effect (effect + :effect (req (continue-ability - (let [chosen-server target + state side (let [chosen-server target num-ice (count (get-in (:corp @state) (conj (server->zone state target) :ices)))] {:prompt "Which position to install in? (0 is innermost)" @@ -2571,8 +2571,8 @@ :once :per-turn :req (req run) :msg "prevent this run from becoming successful" - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card {:type :block-successful-run :duration :end-of-run :value true}))}]}) @@ -2589,7 +2589,7 @@ (enumerate-cards (take (adv4? state card) (:deck runner))) " from the stack") "trash no cards from the stack (it is empty)")) - :effect (effect (mill :corp eid :runner (adv4? state card)))}]})) + :effect (req (mill state :corp eid :runner (adv4? state card)))}]})) (defcard "Unorthodox Predictions" {:implementation "Prevention of subroutine breaking is not enforced" @@ -2610,20 +2610,20 @@ (defcard "Veterans Program" {:on-score {:interactive (req true) :msg "remove 2 bad publicity" - :effect (effect (lose-bad-publicity 2))}}) + :effect (req (lose-bad-publicity state side 2))}}) (defcard "Viral Weaponization" {:on-score {:effect - (effect + (req (register-events - card + state side card [{:event (if (= :corp (:active-player @state)) :corp-turn-ends :runner-turn-ends) :unregister-once-resolved true :duration :end-of-turn :msg (msg "do " (count (:hand runner)) " net damage") :async true - :effect (effect (damage eid :net (count (:hand runner)) {:card card}))}]))}}) + :effect (req (damage state side eid :net (count (:hand runner)) {:card card}))}]))}}) (defcard "Voting Machine Initiative" {:on-score (agenda-counters 3) @@ -2635,16 +2635,16 @@ :yes-ability {:msg "make the Runner lose [Click]" :cost [(->c :agenda 1)] - :effect (effect (lose-clicks :runner 1))}}}]}) + :effect (req (lose-clicks state :runner 1))}}}]}) (defcard "Vulcan Coverup" {:on-score {:interactive (req true) :msg "do 2 meat damage" :async true - :effect (effect (damage eid :meat 2 {:card card}))} + :effect (req (damage state side eid :meat 2 {:card card}))} :stolen {:msg "force the Corp to take 1 bad publicity" :async true - :effect (effect (gain-bad-publicity :corp eid 1))}}) + :effect (req (gain-bad-publicity state :corp eid 1))}}) (defcard "Vulnerability Audit" {:flags {:can-score (req (let [result (not= :this-turn (installed? card))] @@ -2662,13 +2662,13 @@ (defcard "Witch Hunt" (let [bp {:msg "take 1 bad publicity" :async true - :effect (effect (gain-bad-publicity :corp eid 1))}] + :effect (req (gain-bad-publicity state :corp eid 1))}] {:stolen bp :on-score bp :events [{:unregister-once-resolved true :event :corp-action-phase-ends :duration :end-of-turn - :req (effect (first-event? :agenda-scored #(same-card? card (:card (first %))))) + :req (req (first-event? state side :agenda-scored #(same-card? card (:card (first %))))) :msg (msg (if tagged "Remove all tags, and then give the Runner 3 tags" "give the Runner 3 tags")) diff --git a/src/clj/game/cards/assets.clj b/src/clj/game/cards/assets.clj index 9fea694741..dfd04f2fa0 100644 --- a/src/clj/game/cards/assets.clj +++ b/src/clj/game/cards/assets.clj @@ -60,7 +60,7 @@ [game.core.toasts :refer [toast]] [game.core.update :refer [update!]] [game.core.winning :refer [check-win-by-agenda win]] - [game.macros :refer [continue-ability effect msg req wait-for]] + [game.macros :refer [continue-ability msg req wait-for]] [game.utils :refer :all] [jinteki.utils :refer :all] [game.core.link :refer [get-link]])) @@ -104,7 +104,7 @@ :once :per-turn :async true :automatic :gain-credits - :effect (effect (gain-credits eid per-turn))}] + :effect (req (gain-credits state side eid per-turn))}] {:derezzed-events [corp-rez-toast] :events [(assoc ability :event :corp-turn-begins)] :abilities [ability]})) @@ -149,7 +149,7 @@ (defcard "Advanced Assembly Lines" {:on-rez {:async true :msg "gain 3 [Credits]" - :effect (effect (gain-credits eid 3))} + :effect (req (gain-credits state side eid 3))} :abilities [{:label "Install a non-agenda card from HQ" :async true :prompt "Choose a non-agenda card to install from HQ" @@ -160,7 +160,7 @@ (in-hand? %) (corp? %))} :cost [(->c :trash-can)] - :effect (effect (corp-install eid target nil {:msg-keys {:install-source card + :effect (req (corp-install state side eid target nil {:msg-keys {:install-source card :display-origin true}}))}]}) (defcard "Aggressive Secretary" @@ -171,15 +171,15 @@ :card (every-pred installed? program?)} :msg (msg "trash " (enumerate-cards targets)) :async true - :effect (effect (trash-cards eid targets {:cause-card card}))})) + :effect (req (trash-cards state side eid targets {:cause-card card}))})) (defcard "Alexa Belsky" {:abilities [{:label "Shuffle all cards in HQ into R&D" :async true :cost [(->c :trash-can)] - :effect (effect + :effect (req (continue-ability - {:waiting-prompt true + state side {:waiting-prompt true :prompt "How many credits do you want to pay?" :choices :credit :player :runner @@ -203,13 +203,13 @@ (defcard "Alix T4LB07" {:events [{:event :corp-install :async true - :effect (effect (add-counter eid card :power 1 nil))}] + :effect (req (add-counter state side eid card :power 1 nil))}] :abilities [{:action true :label "Gain 2 [Credits] for each counter on Alix T4LB07" :cost [(->c :click 1) (->c :trash-can)] :msg (msg "gain " (* 2 (get-counters card :power)) " [Credits]") :async true - :effect (effect (gain-credits eid (* 2 (get-counters card :power))))}]}) + :effect (req (gain-credits state side eid (* 2 (get-counters card :power))))}]}) (defcard "Allele Repression" (letfn [(select-archives-cards [total] @@ -220,7 +220,7 @@ (in-discard? %)) :max total :all true} - :effect (effect (complete-with-result eid targets))}) + :effect (req (complete-with-result state side eid targets))}) (select-hq-cards [total] {:async true :prompt (str "Choose " (quantify total "card") " from HQ") @@ -228,7 +228,7 @@ (in-hand? %)) :max total :all true} - :effect (effect (complete-with-result eid targets))})] + :effect (req (complete-with-result state side eid targets))})] {:advanceable :always :abilities [{:label "Swap 1 card in HQ and Archives for each advancement counter" :cost [(->c :trash-can)] @@ -262,15 +262,15 @@ (runner? %))} :label "add 1 installed card to the grip" :msg (msg "add " (:title target) " to the grip") - :effect (effect (move :runner target :hand))}}}}})] + :effect (req (move state :runner target :hand))}}}}})] {:events [{:event :agenda-scored :interactive (req true) :async true - :effect (effect (continue-ability (senai-ability (:card context)) card nil))} + :effect (req (continue-ability state side (senai-ability (:card context)) card nil))} {:event :agenda-stolen :interactive (req true) :async true - :effect (effect (continue-ability (senai-ability (:card context)) card nil))}] + :effect (req (continue-ability state side (senai-ability (:card context)) card nil))}] :abilities [(set-autoresolve :auto-fire "Amani Senai")]})) (defcard "Anson Rose" @@ -278,7 +278,7 @@ :once :per-turn :msg "place 1 advancement counter on itself" :async true - :effect (effect (add-prop eid card :advance-counter 1 {:placed true}))}] + :effect (req (add-prop state side eid card :advance-counter 1 {:placed true}))}] {:derezzed-events [corp-rez-toast] :flags {:corp-phase-12 (req true)} :events [(assoc ability :event :corp-turn-begins) @@ -354,7 +354,7 @@ :cost [(->c :tag 1)] :msg "end the run" :label "End the run on another server" - :effect (effect (end-run eid card))}]}) + :effect (req (end-run state side eid card))}]}) (defcard "Balanced Coverage" (let [name-abi @@ -383,7 +383,7 @@ " from the top of R&D and gain 2 [Credits]") :effect (req (wait-for (reveal state side (make-eid state eid) top-card) (gain-credits state :corp eid 2)))} - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card) " to reveal the top card of R&D")))}}} + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card) " to reveal the top card of R&D")))}}} card nil) (do (system-msg state side (str "declines to use " (:title card) " to reveal the top card of R&D")) (effect-completed state side eid))))))} @@ -402,7 +402,7 @@ {:abilities [{:action true :cost [(->c :click 1) (->c :trash-can)] :msg "gain [Click][Click]" - :effect (effect (gain-clicks 2))}]}) + :effect (req (gain-clicks state side 2))}]}) (defcard "Behold!" {:flags {:rd-reveal (req true)} @@ -410,7 +410,7 @@ {:req (req (not (in-discard? card))) :waiting-prompt true :prompt (msg "Pay 4 [Credits] to use " (:title card) " ability?") - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card))))} + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card))))} :yes-ability (assoc (give-tags 2) :cost [(->c :credit 4)])}}}) (defcard "Bio-Ethics Association" @@ -420,7 +420,7 @@ :label "Do 1 net damage (start of turn)" :once :per-turn :msg "do 1 net damage" - :effect (effect (damage eid :net 1 {:card card}))}] + :effect (req (damage state side eid :net 1 {:card card}))}] {:derezzed-events [corp-rez-toast] :events [(assoc ability :event :corp-turn-begins)] :abilities [ability]})) @@ -436,12 +436,12 @@ (corp? %))} :cost [(->c :trash-can)] :async true - :effect (effect (corp-install eid target nil {:msg-keys {:install-source card + :effect (req (corp-install state side eid target nil {:msg-keys {:install-source card :display-origin true}}))}]}) (defcard "Blacklist" - {:on-rez {:effect (effect (lock-zone (:cid card) :runner :discard))} - :leave-play (effect (release-zone (:cid card) :runner :discard))}) + {:on-rez {:effect (req (lock-zone state side (:cid card) :runner :discard))} + :leave-play (req (release-zone state side (:cid card) :runner :discard))}) (defcard "Bladderwort" (let [ability {:msg "gain 1 [Credits]" @@ -456,7 +456,7 @@ state side {:msg "do 1 net damage" :async true - :effect (effect (damage eid :net 1 {:card card}))} + :effect (req (damage state side eid :net 1 {:card card}))} card nil) (effect-completed state side eid))))}] {:derezzed-events [corp-rez-toast] @@ -498,7 +498,7 @@ (can-pay? state :corp eid card nil [(->c :credit 4)]))) :waiting-prompt true :prompt (msg "Pay 4 [Credits] to use " (:title card) " ability?") - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card))))} + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card))))} :yes-ability {:async true :cost [(->c :credit 4)] :msg "give the Runner 1 tag and do 3 net damage" @@ -520,7 +520,7 @@ :cost [(->c :credit 2) (->c :trash-can)] :msg (msg "trash it and gain " (get-counters card :credit) " [Credits]") :async true - :effect (effect (gain-credits eid (get-counters card :credit)))}] + :effect (req (gain-credits state side eid (get-counters card :credit)))}] :events [{:event :corp-turn-begins :msg "place 2 [Credits] on itself" :req (req (>= (get-counters card :credit) 6)) @@ -544,14 +544,14 @@ :msg "gain 2 [Credits]" :keep-menu-open :while-clicks-left :async true - :effect (effect (gain-credits eid 2))}]}) + :effect (req (gain-credits state side eid 2))}]}) (defcard "Cerebral Overwriter" (advance-ambush 3 {:async true :waiting-prompt true :req (req (pos? (get-counters (get-card state card) :advancement))) :msg (msg "do " (get-counters (get-card state card) :advancement) " core damage") - :effect (effect (damage eid :brain (get-counters (get-card state card) :advancement) {:card card}))})) + :effect (req (damage state side eid :brain (get-counters (get-card state card) :advancement) {:card card}))})) (defcard "Chairman Hiro" {:static-abilities [(runner-hand-size+ -2)] @@ -595,7 +595,7 @@ (defcard "Chekist Scion" (advance-ambush 0 {:msg (msg "give the Runner " (quantify (inc (get-counters (get-card state card) :advancement)) "tag")) :async true - :effect (effect (gain-tags :corp eid (inc (get-counters (get-card state card) :advancement))))})) + :effect (req (gain-tags state :corp eid (inc (get-counters (get-card state card) :advancement))))})) (defcard "Chief Slee" {:events [{:event :end-of-encounter @@ -609,7 +609,7 @@ :keep-menu-open :while-5-power-tokens-left :async true :msg "do 5 meat damage" - :effect (effect (damage eid :meat 5 {:card card}))}]}) + :effect (req (damage state side eid :meat 5 {:card card}))}]}) (defcard "City Surveillance" {:derezzed-events [corp-rez-toast] @@ -638,9 +638,9 @@ :interactive (req true) :req (req (:corp-phase-12 @state)) :effect - (effect + (req (continue-ability - {:optional + state side {:optional {:prompt (msg "Trash this asset to do " (get-counters card :advancement) " meat damage?") :yes-ability {:async true @@ -734,8 +734,8 @@ :msg (msg "place 1 advancement counter on " (card-str state target)) :async true - :effect (effect - (add-prop eid target + :effect (req + (add-prop state side eid target :advance-counter 1 {:placed true}))} card nil))}) @@ -748,7 +748,7 @@ :once :per-turn :msg "gain 3 [Credits]" :async true - :effect (effect (gain-credits eid 3))}] + :effect (req (gain-credits state side eid 3))}] {:derezzed-events [corp-rez-toast] :events [(assoc ability :event :corp-turn-begins)] :abilities [ability]})) @@ -777,9 +777,9 @@ :choices {:card #(and (ice? %) (get-counters % :advancement))} :async true - :effect (effect + :effect (req (continue-ability - (let [from-ice target] + state side (let [from-ice target] {:prompt "Choose a piece of ice that can be advanced" :choices {:req (req (and (ice? target) (not (same-card? from-ice target)) @@ -802,14 +802,14 @@ :req (req (>= (get-counters card :advancement) 2)) :choices {:card #(has-subtype? % "Connection")} :msg (msg "trash " (:title target)) - :effect (effect (trash eid target {:cause-card card}))} + :effect (req (trash state side eid target {:cause-card card}))} {:action true :label "Do 2 meat damage" :async true :cost [(->c :click 1) (->c :trash-can)] :req (req (>= (get-counters card :advancement) 2)) :msg "do 2 meat damage" - :effect (effect (damage eid :meat 2 {:card card}))}]}) + :effect (req (damage state side eid :meat 2 {:card card}))}]}) (defcard "Corporate Town" (let [ability {:label "Trash a resource" @@ -820,7 +820,7 @@ :msg (msg "trash " (:title target)) :interactive (req true) :req (req (some resource? (all-installed state :runner))) - :effect (effect (trash eid target {:unpreventable true :cause-card card}))}] + :effect (req (trash state side eid target {:unpreventable true :cause-card card}))}] {:derezzed-events [corp-rez-toast] :additional-cost [(->c :forfeit)] :flags {:corp-phase-12 (req (and (rezzed? card) @@ -838,7 +838,7 @@ (first-event? state side :runner-credit-gain valid-ctx?)))) :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits :corp eid 1))}]}) + :effect (req (gain-credits state :corp eid 1))}]}) (defcard "CSR Campaign" (let [ability {:once :per-turn @@ -846,8 +846,8 @@ :label "Draw 1 card (start of turn)" :automatic :draw-cards :interactive (req true) - :effect (effect (continue-ability - {:optional + :effect (req (continue-ability + state side {:optional {:prompt "Draw 1 card?" :autoresolve (get-autoresolve :auto-fire) :yes-ability (draw-abi 1)}} @@ -865,13 +865,13 @@ :req (req (ice? (:card context))) :msg "place 2 [Credits] on itself" :async true - :effect (effect (add-counter :corp eid card :credit 2 nil))}] + :effect (req (add-counter state :corp eid card :credit 2 nil))}] :abilities [{:label "Take all hosted credits" :cost [(->c :trash-can)] :change-in-game-state {:req (req (pos? (get-counters card :credit)))} :msg (msg "gain " (get-counters card :credit) " [Credits]") :async true - :effect (effect (gain-credits eid (get-counters card :credit)))} + :effect (req (gain-credits state side eid (get-counters card :credit)))} {:async true :effect (req (spend-credits state side eid card :credit 1)) :label "Take 1 hosted [Credits] (manual)" @@ -922,14 +922,14 @@ :automatic :gain-credits :msg "gain 3 [Credits]" :async true - :effect (effect (gain-credits :corp eid 3))}] + :effect (req (gain-credits state :corp eid 3))}] {:rez-req (req (= (:active-player @state) :corp)) :events [{:event :successful-run :req (req this-server) :async true - :effect (effect (system-msg :runner (str "gains 2 [Credits] for a successful run " + :effect (req (system-msg state :runner (str "gains 2 [Credits] for a successful run " "on the Daily Quest server")) - (gain-credits :runner eid 2))} + (gain-credits state :runner eid 2))} (assoc ability :event :corp-turn-begins)] :abilities [ability]})) @@ -955,7 +955,7 @@ :keep-menu-open :while-2-clicks-left :msg "place 1 power counter in itself" :async true - :effect (effect (add-counter eid card :power 1 nil))}] + :effect (req (add-counter state side eid card :power 1 nil))}] :static-abilities [{:type :install-cost :req (req (and (runner? target) (not-triggered? state))) @@ -978,7 +978,7 @@ :req (req (= :corp (:active-player @state))) :msg "give the runner a tag" :async true - :effect (effect (gain-tags :corp eid 1))}]}) + :effect (req (gain-tags state :corp eid 1))}]}) (defcard "Drudge Work" {:data {:counter {:power 3}} @@ -1015,7 +1015,7 @@ :once :per-turn :msg (msg "place 1 advancement counter on " (card-str state target)) :async true - :effect (effect (add-prop eid target :advance-counter 1 {:placed true}))}]}) + :effect (req (add-prop state side eid target :advance-counter 1 {:placed true}))}]}) (defcard "Echo Chamber" {:abilities [{:action true @@ -1029,7 +1029,7 @@ (count (get-in (:corp @state) [:servers (last (:server (:run @state))) :ices])))] (installed-access-trigger 3 {:msg (msg "do " (ice-count state) " core damage") :async true - :effect (effect (damage eid :brain (ice-count state) + :effect (req (damage state side eid :brain (ice-count state) {:card card}))}))) (defcard "Eliza's Toybox" @@ -1039,11 +1039,11 @@ :label "Rez a card, ignoring all costs" :choices {:card (every-pred corp? installed? (complement agenda?) (complement rezzed?))} :async true - :effect (effect (rez eid target {:ignore-cost :all-costs :msg-keys {:include-cost-from-eid eid}}))}]}) + :effect (req (rez state side eid target {:ignore-cost :all-costs :msg-keys {:include-cost-from-eid eid}}))}]}) (defcard "Elizabeth Mills" {:on-rez {:msg "remove 1 bad publicity" - :effect (effect (lose-bad-publicity 1))} + :effect (req (lose-bad-publicity state side 1))} :abilities [{:action true :cost [(->c :click 1) (->c :trash-can)] :label "Trash a location and take 1 bad publicity" @@ -1063,7 +1063,7 @@ state side {:msg "take 1 bad publicity" :async true - :effect (effect (gain-bad-publicity eid 1))} + :effect (req (gain-bad-publicity state side eid 1))} card nil)))}]}) (defcard "Encryption Protocol" @@ -1093,7 +1093,7 @@ (is-remote? (second (get-zone (:card context)))))) :msg "place 1 power counter on itself" :async true - :effect (effect (add-counter eid card :power 1 nil))}] + :effect (req (add-counter state side eid card :power 1 nil))}] :abilities [{:label "Draw 1 card and gain 2 [Credits] for each hosted power counter" :cost [(->c :trash-can)] :change-in-game-state {:req (req (pos? (get-counters card :power)))} @@ -1148,15 +1148,15 @@ :cancel (assoc shuffle-my-deck! :cost [(->c :click 1)] :action true) :keep-menu-open :while-clicks-left :label "Search R&D for an Executive, Sysop, or Character" - :effect (effect (move target :hand) - (shuffle! :deck))}]}) + :effect (req (move state side target :hand) + (shuffle! state side :deck))}]}) (defcard "Exposé" {:advanceable :always :abilities [{:label "Remove 1 bad publicity for each advancement counter on Exposé" :msg (msg "remove " (get-counters card :advancement) " bad publicity") :cost [(->c :trash-can)] - :effect (effect (lose-bad-publicity (get-counters card :advancement)))}]}) + :effect (req (lose-bad-publicity state side (get-counters card :advancement)))}]}) (defcard "False Flag" (letfn [(tag-count [false-flag] @@ -1165,7 +1165,7 @@ :on-access {:req (req (pos? (get-counters (get-card state card) :advancement))) :msg (msg "give the runner " (quantify (tag-count (get-card state card)) "tag")) :async true - :effect (effect (gain-tags :corp eid (tag-count (get-card state card))))} + :effect (req (gain-tags state :corp eid (tag-count (get-card state card))))} :abilities [{:action true :cost [(->c :click 1) (->c :advancement 7)] :label "Add this asset to your score area as an agenda worth 3 agenda points" @@ -1178,8 +1178,8 @@ :waiting-prompt true :yes-ability {:msg "draw 1 card" :async true - :effect (effect (draw eid 1))} - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card) " to draw 1 card")))}}} + :effect (req (draw state side eid 1))} + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card) " to draw 1 card")))}}} ability {:once :per-turn :req (req (and (:corp-phase-12 @state) @@ -1189,9 +1189,9 @@ :label "Look at the top 3 cards of R&D (start of turn)" :async true :effect - (effect + (req (continue-ability - {:optional + state side {:optional {:prompt "Look at the top 3 cards of R&D?" :waiting-prompt true :no-ability draw-ab @@ -1228,7 +1228,7 @@ unprotected)) :msg "do 2 net damage" :async true - :effect (effect (damage eid :net 2))}]}) + :effect (req (damage state side eid :net 2))}]}) (defcard "Full Immersion RecStudio" {:can-host (req (and (or (asset? target) (agenda? target)) @@ -1245,7 +1245,7 @@ (corp? %))} :msg "install and host an asset or agenda" :async true - :effect (effect (corp-install eid target card nil))} + :effect (req (corp-install state side eid target card nil))} {:label "Install a previously-installed asset or agenda on this asset (fixes only)" :req (req (< (count (:hosted card)) 2)) :prompt "Choose an installed asset or agenda to host" @@ -1263,7 +1263,7 @@ (some? runner-credits) (not= corp-credits runner-credits)))) :msg "do 1 meat damage" - :effect (effect (damage eid :meat 1 {:card card}))}]}) + :effect (req (damage state side eid :meat 1 {:card card}))}]}) (defcard "Gaslight" (let [search-for-operation {:prompt "Choose an operation to add to HQ" @@ -1288,9 +1288,9 @@ :interactive (req true) :req (req (:corp-phase-12 @state)) :effect - (effect + (req (continue-ability - {:optional + state side {:optional {:prompt "Trash this asset to search R&D for an operation?" :yes-ability {:async true @@ -1307,7 +1307,7 @@ :on-access {:req (req (pos? (get-counters (get-card state card) :advancement))) :msg (msg "do " (get-counters (get-card state card) :advancement) " net damage") :async true - :effect (effect (damage eid :net (get-counters (get-card state card) :advancement) + :effect (req (damage state side eid :net (get-counters (get-card state card) :advancement) {:card card}))} :abilities [{:action true :cost [(->c :click 1) (->c :advancement 3)] @@ -1322,7 +1322,7 @@ (prevent-draw state :runner)))} :events [{:event :runner-turn-begins :silent true - :effect (effect (max-draw :runner 2))}] + :effect (req (max-draw state :runner 2))}] :leave-play (req (swap! state update-in [:runner :register] dissoc :max-draw :cannot-draw))}) (defcard "Ghost Branch" @@ -1330,7 +1330,7 @@ :waiting-prompt true :req (req (pos? (get-counters (get-card state card) :advancement))) :msg (msg "give the Runner " (quantify (get-counters (get-card state card) :advancement) "tag")) - :effect (effect (gain-tags :corp eid (get-counters (get-card state card) :advancement)))})) + :effect (req (gain-tags state :corp eid (get-counters (get-card state card) :advancement)))})) (defcard "GRNDL Refinery" {:advanceable :always @@ -1339,7 +1339,7 @@ :cost [(->c :click 1) (->c :trash-can)] :msg (msg "gain " (* 4 (get-counters card :advancement)) " [Credits]") :async true - :effect (effect (gain-credits eid (* 4 (get-counters card :advancement))))}]}) + :effect (req (gain-credits state side eid (* 4 (get-counters card :advancement))))}]}) (defcard "Haas Arcology AI" {:advanceable :while-unrezzed @@ -1348,7 +1348,7 @@ :once :per-turn :msg "gain [Click][Click]" :cost [(->c :click 1) (->c :advancement 1)] - :effect (effect (gain-clicks 2))}]}) + :effect (req (gain-clicks state side 2))}]}) (defcard "Hearts and Minds" (let [political (assoc (place-advancement-counter true 1) @@ -1362,9 +1362,9 @@ :choices {:card #(and (installed? %) (pos? (get-counters % :advancement)))} :async true - :effect (effect + :effect (req (continue-ability - (let [from-ice target] + state side (let [from-ice target] {:prompt "Choose an installed card you can advance" :choices {:req (req (and (installed? target) (can-be-advanced? state target) @@ -1393,7 +1393,7 @@ :poison true :on-access {:msg "force the Runner to lose 1 [Credits]" :async true - :effect (effect (lose-credits :runner eid 1))}}) + :effect (req (lose-credits state :runner eid 1))}}) (defcard "Hostile Architecture" (letfn [(valid-ctx? @@ -1407,7 +1407,7 @@ :req (req (and (valid-ctx? targets) (first-event? state side :runner-trash valid-ctx?))) :msg "do 2 meat damage" - :effect (effect (damage :corp eid :meat 2 {:card card}))}]})) + :effect (req (damage state :corp eid :meat 2 {:card card}))}]})) (defcard "Hostile Infrastructure" {:events [{:event :runner-trash @@ -1415,7 +1415,7 @@ :once-per-instance false :req (req (corp? (:card target))) :msg "do 1 net damage" - :effect (effect (damage :corp eid :net 1 {:card card}))}]}) + :effect (req (damage state :corp eid :net 1 {:card card}))}]}) (defcard "Humanoid Resources" (let [play-an-instant @@ -1451,7 +1451,7 @@ (first-event? state side :reveal-spent-credits))) :msg (msg "gain " (:corp-credits context) " [Credits]") :async true - :effect (effect (gain-credits :corp eid (:corp-credits context)))}]}) + :effect (req (gain-credits state :corp eid (:corp-credits context)))}]}) (defcard "Ibrahim Salem" (let [trash-ability (fn [card-type] @@ -1462,7 +1462,7 @@ (runner? %) (is-type? % card-type))} :async true - :effect (effect (trash eid target {:cause-card card})) + :effect (req (trash state side eid target {:cause-card card})) :msg (msg "trash " (:title target) " from the grip")})) choose-ability {:label "Trash 1 card in the grip of a named type" :change-in-game-state {:req (req (seq (:hand runner))) :silent true} @@ -1472,7 +1472,7 @@ :choices ["Event" "Hardware" "Program" "Resource"] :msg (msg "choose " target) :async true - :effect (effect (continue-ability (trash-ability target) card nil))}] + :effect (req (continue-ability state side (trash-ability target) card nil))}] {:additional-cost [(->c :forfeit)] :flags {:corp-phase-12 (req (not (is-disabled-reg? state card)))} :derezzed-events [corp-rez-toast] @@ -1511,19 +1511,19 @@ :abilities [ability] :on-trash {:req (req (= side :runner)) :msg "take 1 bad publicity" - :effect (effect (gain-bad-publicity :corp 1))}})) + :effect (req (gain-bad-publicity state :corp 1))}})) (defcard "Indian Union Stock Exchange" {:events [{:event :play-operation :req (req (not= (:faction (:card context)) (:faction (:identity corp)))) :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits eid 1))} + :effect (req (gain-credits state side eid 1))} {:event :rez :req (req (not= (:faction (:card context)) (:faction (:identity corp)))) :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits eid 1))}]}) + :effect (req (gain-credits state side eid 1))}]}) (defcard "Investigator Inez Delgado A" {:events [{:event :agenda-scored @@ -1587,7 +1587,7 @@ :keep-menu-open :while-clicks-left :choices {:card installed?} :msg (msg "move " (card-str state target) " to HQ") - :effect (effect (move target :hand))}]}) + :effect (req (move state side target :hand))}]}) (defcard "IT Department" {:abilities [{:action true @@ -1595,7 +1595,7 @@ :keep-menu-open :while-clicks-left :msg "place 1 power counter on itself" :async true - :effect (effect (add-counter eid card :power 1 nil))} + :effect (req (add-counter state side eid card :power 1 nil))} {:cost [(->c :power 1)] :keep-menu-open :while-power-tokens-left :label "Add strength to a rezzed piece of ice" @@ -1603,14 +1603,14 @@ (rezzed? %))} :req (req (pos? (get-counters card :power))) :msg "add strength to a rezzed piece of ice" - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card (let [it-target target] {:type :ice-strength :duration :end-of-turn :req (req (same-card? target it-target)) :value (req (inc (get-counters card :power)))})) - (update-ice-strength target))}]}) + (update-ice-strength state side target))}]}) (defcard "Jackson Howard" {:abilities [(draw-abi 2 nil {:action true @@ -1619,14 +1619,14 @@ {:label "Shuffle up to 3 cards from Archives into R&D" :cost [(->c :remove-from-game)] :async true - :effect (effect (shuffle-into-rd-effect eid card 3))}]}) + :effect (req (shuffle-into-rd-effect state side eid card 3))}]}) (defcard "Janaína \"JK\" Dumont Kindelán" (let [ability {:label "Place 3 [Credits] on this asset (start of turn)" :once :per-turn :msg "place 3 [Credits] on itself" :async true - :effect (effect (add-counter eid card :credit 3 {:placed true}))}] + :effect (req (add-counter state side eid card :credit 3 {:placed true}))}] {:derezzed-events [corp-rez-toast] :flags {:corp-phase-12 (req true)} :events [(assoc ability :event :corp-turn-begins)] @@ -1646,7 +1646,7 @@ :prompt "Choose 1 card to install" :choices {:card #(and (corp-installable-type? %) (in-hand? %))} - :effect (effect (corp-install eid target nil {:msg-keys {:install-source card + :effect (req (corp-install state side eid target nil {:msg-keys {:install-source card :display-origin true}}))} card nil)))}]})) @@ -1654,8 +1654,8 @@ (let [ability {:label "Gain [Click]" :msg "gain [Click]" :once :per-turn - :effect (effect (gain-clicks 1))} - cleanup (effect (update! (dissoc card :seen-this-turn)))] + :effect (req (gain-clicks state side 1))} + cleanup (req (update! state side (dissoc card :seen-this-turn)))] {:abilities [ability] :leave-play cleanup :events [{:event :corp-spent-click @@ -1685,8 +1685,8 @@ :abilities [{:msg "look at the top card of the stack" :change-in-game-state {:req (req (seq (:deck runner)))} :async true - :effect (effect (continue-ability - {:prompt (req (->> runner :deck first :title (str "The top card of the stack is "))) + :effect (req (continue-ability + state side {:prompt (req (->> runner :deck first :title (str "The top card of the stack is "))) :waiting-prompt true :choices ["OK"]} card nil))} @@ -1694,7 +1694,7 @@ :label "Trash the top card of the stack" :msg (msg "trash " (:title (first (:deck runner))) " from the stack") :cost [(->c :trash-can)] - :effect (effect (mill :corp eid :runner 1))}]}) + :effect (req (mill state :corp eid :runner 1))}]}) (defcard "Kuwinda K4H1U3" {:x-fn (req (get-counters card :power)) @@ -1708,7 +1708,7 @@ :effect (req (wait-for (damage state :runner :brain 1 {:card card}) (trash state side eid card {:cause-card card})))} :unsuccessful - {:effect (effect (add-counter eid card :power 1 nil)) + {:effect (req (add-counter state side eid card :power 1 nil)) :async true :msg "place 1 power counter on itself"}}}]}) @@ -1736,7 +1736,7 @@ :events [{:event :corp-turn-begins :automatic :last ;;so it goes after warm reception :async true - :effect (effect (add-counter eid card :power 1 nil))}]}) + :effect (req (add-counter state side eid card :power 1 nil))}]}) (defcard "Lakshmi Smartfabrics" {:events [{:event :rez @@ -1784,8 +1784,8 @@ :cost [(->c :click 1) (->c :credit 1)] :cancel (assoc shuffle-my-deck! :cost [(->c :credit 1) (->c :click 1)] :action true) :keep-menu-open :while-clicks-left - :effect (effect (move target :hand) - (shuffle! :deck))}]}) + :effect (req (move state side target :hand) + (shuffle! state side :deck))}]}) (defcard "Lily Lockwell" {:on-rez (draw-abi 3) @@ -1950,17 +1950,17 @@ {:events [{:event :agenda-counter-spent :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits eid 1))}] + :effect (req (gain-credits state side eid 1))}] :abilities [{:label "Gain 2 [Credits]" :msg "gain 2 [Credits]" :cost [(->c :trash-can)] :async true - :effect (effect (gain-credits eid 2))} + :effect (req (gain-credits state side eid 2))} {:label "Gain 2 [Credits]" :msg "gain 2 [Credits]" :cost [(->c :any-agenda-counter)] :async true - :effect (effect (gain-credits eid 2))}]}) + :effect (req (gain-credits state side eid 2))}]}) (defcard "Marked Accounts" (let [ability (take-n-credits-start-of-turn 1)] @@ -1969,7 +1969,7 @@ :cost [(->c :click 1)] :msg "store 3 [Credits]" :async true - :effect (effect (add-counter eid card :credit 3 nil))}] + :effect (req (add-counter state side eid card :credit 3 nil))}] :events [(assoc ability :event :corp-turn-begins)]})) (defcard "MCA Austerity Policy" @@ -1982,12 +1982,12 @@ [{:event :runner-turn-begins :unregister-once-resolved true :duration :until-runner-turn-begins - :effect (effect (lose-clicks :runner 1))}]) + :effect (req (lose-clicks state :runner 1))}]) (add-counter state side eid card :power 1 nil))} {:action true :cost [(->c :click 1) (->c :power 3) (->c :trash-can)] :msg "gain 4 [Click]" - :effect (effect (gain-clicks 4))}]}) + :effect (req (gain-clicks state side 4))}]}) (defcard "Melange Mining Corp." {:abilities [(merge (gain-credits-ability 7) @@ -2055,15 +2055,15 @@ {:abilities [{:label "Trash up to 2 cards from HQ. Shuffle up to 2 cards from Archives into R&D" :cost [(->c :remove-from-game)] :async true - :effect (effect (continue-ability - moon-pool-discard-ability + :effect (req (continue-ability + state side moon-pool-discard-ability card nil))}]}))) (defcard "Mr. Stone" {:events [{:event :runner-gain-tag :async true :msg "do 1 meat damage" - :effect (effect (damage :corp eid :meat 1 {:card card}))}]}) + :effect (req (damage state :corp eid :meat 1 {:card card}))}]}) (defcard "Mumba Temple" {:recurring 2 @@ -2102,7 +2102,7 @@ :events [{:event :corp-turn-begins :silent true :async true - :effect (effect (add-prop eid card :advance-counter 1 {:placed true}))}] + :effect (req (add-prop state side eid card :advance-counter 1 {:placed true}))}] :abilities [{:cost [(->c :credit 2)] :keep-menu-open :while-advancement-tokens-left :req (req (and (pos? (get-counters card :advancement)) @@ -2150,7 +2150,7 @@ :once :per-turn :msg "gain 2 [Credits]" :async true - :effect (effect (gain-credits eid 2))}] + :effect (req (gain-credits state side eid 2))}] :on-trash {:optional {:req (req (= :runner side)) :waiting-prompt true @@ -2158,7 +2158,7 @@ :yes-ability {:msg "gain 2 [Credits]" :async true - :effect (effect (gain-credits :corp eid 2))}}}}) + :effect (req (gain-credits state :corp eid 2))}}}}) (defcard "NASX" (let [ability {:msg "gain 1 [Credits]" @@ -2166,7 +2166,7 @@ :label "Gain 1 [Credits] (start of turn)" :once :per-turn :async true - :effect (effect (gain-credits eid 1))}] + :effect (req (gain-credits state side eid 1))}] {:implementation "Manual - click NASX to place power counters on itself" :derezzed-events [corp-rez-toast] :events [(assoc ability :event :corp-turn-begins)] @@ -2175,18 +2175,18 @@ :cost [(->c :credit 1)] :msg "place 1 power counter on itself" :async true - :effect (effect (add-counter eid card :power 1 nil))} + :effect (req (add-counter state side eid card :power 1 nil))} {:label "Place 2 power counters" :cost [(->c :credit 2)] :msg "place 2 power counters on itself" :async true - :effect (effect (add-counter eid card :power 2 nil))} + :effect (req (add-counter state side eid card :power 2 nil))} {:action true :label "Gain 2 [Credits] for each hosted power counter" :cost [(->c :click 1) (->c :trash-can)] :msg (msg "gain " (* 2 (get-counters card :power)) " [Credits]") :async true - :effect (effect (gain-credits eid (* 2 (get-counters card :power))))}]})) + :effect (req (gain-credits state side eid (* 2 (get-counters card :power))))}]})) (defcard "Net Analytics" (let [ability {:optional @@ -2243,7 +2243,7 @@ (letfn [(builder [cost cred] {:cost [(->c :advancement cost) (->c :trash-can)] :async true - :effect (effect (gain-credits eid cred)) + :effect (req (gain-credits state side eid cred)) :label (str "Gain " cred " [Credits]") :msg (str "gain " cred " [Credits]")})] {:advanceable :always @@ -2328,8 +2328,8 @@ :choices {:card #(and (in-hand? %) (corp? %))} :msg "add 1 card from HQ to the top of R&D" - :effect (effect (move target :deck {:front true}) - (effect-completed eid))} + :effect (req (move state side target :deck {:front true}) + (effect-completed state side eid))} card nil)))}]}) (defcard "Otto Campaign" @@ -2458,7 +2458,7 @@ (in-hand? target)))} :msg (msg "score " (:title target)) :async true - :effect (effect (score eid target {:no-req true :ignore-turn true}))})) + :effect (req (score state side eid target {:no-req true :ignore-turn true}))})) (defcard "Plutus" (let [abi {:once :per-turn @@ -2508,7 +2508,7 @@ (remove-from-currently-drawing state side agenda) (continue-ability state side (pdhelper (next agendas)) card nil))))} :no-ability {:async true - :effect (effect (continue-ability (pdhelper (next agendas)) card nil))}}}))] + :effect (req (continue-ability state side (pdhelper (next agendas)) card nil))}}}))] {:events [{:event :corp-draw :async true :effect (req (cond @@ -2544,7 +2544,7 @@ :label "deal net damage" :cost [(->c :click 2) (->c :trash-can)] :async true - :effect (effect (damage eid :net (get-counters card :power) {:card card}))}]}) + :effect (req (damage state side eid :net (get-counters card :power) {:card card}))}]}) (defcard "Primary Transmission Dish" {:recurring 3 @@ -2565,7 +2565,7 @@ :waiting-prompt true :msg (msg "do " (* 2 (get-counters (get-card state card) :advancement)) " net damage") :async true - :effect (effect (damage eid :net (* 2 (get-counters (get-card state card) :advancement)) + :effect (req (damage state side eid :net (* 2 (get-counters (get-card state card) :advancement)) {:card card}))})) (defcard "Psychic Field" @@ -2578,7 +2578,7 @@ {:psi {:not-equal {:msg message :async true - :effect (effect (damage eid :net hand {:card card}))}}} + :effect (req (damage state side eid :net hand {:card card}))}}} card nil)))}] {:on-expose ab :on-access ab})) @@ -2609,12 +2609,12 @@ :events [{:event :corp-turn-begins :req (req (pos? (get-counters card :power))) :async true - :effect (effect (add-counter eid card :power -1 nil))} + :effect (req (add-counter state side eid card :power -1 nil))} {:event :counter-added :req (req (same-card? card (:card context)) (not (pos? (get-counters card :power)))) :msg "add itself to [their] score area as an agenda worth 1 agenda point" - :effect (effect (as-agenda card 1))}]}) + :effect (req (as-agenda state side card 1))}]}) (defcard "Quarantine System" (letfn [(rez-ice [cnt discount] @@ -2655,16 +2655,16 @@ {:once :per-turn :async true :effect - (effect - (lose-clicks :corp 1) + (req + (lose-clicks state :corp 1) (continue-ability - {:prompt "Choose a card in HQ that you just drew to swap for a card of the same type in Archives" + state side {:prompt "Choose a card in HQ that you just drew to swap for a card of the same type in Archives" :choices {:card #(some (fn [c] (same-card? c %)) corp-currently-drawing)} :async true :effect - (effect + (req (continue-ability - (let [set-aside-card target + state side (let [set-aside-card target t (:type set-aside-card)] {:show-discard true :prompt (msg "Choose an " t " in Archives to reveal and swap into HQ for " (:title set-aside-card)) @@ -2689,9 +2689,9 @@ :label "Gain 3 [Credits] and draw 3 cards (start of turn)" :req (req (:corp-phase-12 @state)) :effect - (effect + (req (continue-ability - {:optional + state side {:optional {:prompt "Trash this asset to gain 3 [Credits] and draw 3 cards?" :yes-ability {:async true @@ -2709,14 +2709,14 @@ :abilities [ability]})) (defcard "Reality Threedee" - (let [ability {:effect (effect (gain-credits eid (if tagged 2 1))) + (let [ability {:effect (req (gain-credits state side eid (if tagged 2 1))) :async true :label "Gain credits (start of turn)" :automatic :gain-credits :once :per-turn :msg (msg (if tagged "gain 2 [Credits]" "gain 1 [Credits]"))}] {:on-rez {:msg "take 1 bad publicity" - :effect (effect (gain-bad-publicity :corp 1))} + :effect (req (gain-bad-publicity state :corp 1))} :derezzed-events [corp-rez-toast] :events [(assoc ability :event :corp-turn-begins)] :abilities [ability]})) @@ -2729,9 +2729,9 @@ :interactive (req true) :req (req (:corp-phase-12 @state)) :effect - (effect + (req (continue-ability - {:optional + state side {:optional {:prompt "Trash Reaper Function to do 2 net damage?" :yes-ability {:msg "do 2 net damage" @@ -2750,7 +2750,7 @@ (= :meat (:damage-type context)))) :msg "place 1 advancement counter on itself" :async true - :effect (effect (add-counter eid card :advancement 1 {:placed true}))}] + :effect (req (add-counter state side eid card :advancement 1 {:placed true}))}] :abilities [{:label "Move hosted advancement counters to another card" :cost [(->c :trash-can)] :async true @@ -2763,8 +2763,8 @@ {:async true :prompt "Choose a card that can be advanced" :choices {:req (req (can-be-advanced? state target))} - :effect (effect (system-msg (str "uses " (:title card) " to move " (quantify num-counters "hosted advancement counter") " to " (card-str state target))) - (add-counter eid target :advancement num-counters {:placed true}))} + :effect (req (system-msg state side (str "uses " (:title card) " to move " (quantify num-counters "hosted advancement counter") " to " (card-str state target))) + (add-counter state side eid target :advancement num-counters {:placed true}))} card nil)))}]}) (defcard "Refuge Campaign" @@ -2786,7 +2786,7 @@ :label "Force the Runner to lose 4 [Credits] per advancement" :msg (msg "force the Runner to lose " (min (* 4 (get-counters card :advancement)) (:credit runner)) " [Credits]") :async true - :effect (effect (lose-credits :runner eid (* 4 (get-counters card :advancement))))}]}) + :effect (req (lose-credits state :runner eid (* 4 (get-counters card :advancement))))}]}) (defcard "Rex Campaign" (let [payout-ab {:prompt "Choose one" @@ -2817,7 +2817,7 @@ :req (req (and (corp? (:card target)) (pos? (:click runner)))) :msg "force the runner to lose [Click]" - :effect (effect (lose-clicks :runner 1))}] + :effect (req (lose-clicks state :runner 1))}] {:events [ability] :on-trash ability})) @@ -2844,21 +2844,21 @@ :prompt "Remove 1 bad publicity?" :yes-ability {:msg "remove 1 bad publicity" - :effect (effect (lose-bad-publicity 1))}}} + :effect (req (lose-bad-publicity state side 1))}}} card nil)))}]}) (defcard "Sandburg" - {:on-rez {:effect (effect (update-all-ice))} + {:on-rez {:effect (req (update-all-ice state side))} :static-abilities [{:type :ice-strength :req (req (<= 10 (:credit corp))) :value (req (quot (:credit corp) 5))}] :events [{:event :corp-gain :req (req (= :credit (:type context))) - :effect (effect (update-all-ice))} + :effect (req (update-all-ice state side))} {:event :corp-lose :req (req (= :credit (:type context))) - :effect (effect (update-all-ice))}] - :leave-play (effect (update-all-ice))}) + :effect (req (update-all-ice state side))}] + :leave-play (req (update-all-ice state side))}) (defcard "Sealed Vault" {:abilities [{:label "Store any number of credits" @@ -2876,14 +2876,14 @@ :choices {:counter :credit} :msg (msg "gain " target " [Credits]") :async true - :effect (effect (gain-credits eid target))} + :effect (req (gain-credits state side eid target))} {:label "Move any number of credits to your credit pool" :prompt "How many credits do you want to move?" :choices {:counter :credit} :msg (msg "gain " target " [Credits]") :cost [(->c :trash-can)] :async true - :effect (effect (gain-credits eid target))}]}) + :effect (req (gain-credits state side eid target))}]}) (defcard "Security Subcontract" {:abilities [(merge (gain-credits-ability 4) @@ -2905,11 +2905,11 @@ :choices {:card #(and (corp? %) (in-hand? %))} :msg "add 1 card from HQ to the bottom of R&D" - :effect (effect (move target :deck))} + :effect (req (move state side target :deck))} card nil)))}]}) (defcard "Server Diagnostics" - (let [ability {:effect (effect (gain-credits eid 2)) + (let [ability {:effect (req (gain-credits state side eid 2)) :async true :once :per-turn :automatic :gain-credits @@ -2922,7 +2922,7 @@ :req (req (ice? (:card context))) :async true :msg "trash itself" - :effect (effect (trash eid card {:cause-card card}))}]})) + :effect (req (trash state side eid card {:cause-card card}))}]})) (defcard "Shannon Claire" {:abilities [{:action true @@ -2930,8 +2930,8 @@ :keep-menu-open :while-clicks-left :msg "draw 1 card from the bottom of R&D" ;; TODO - this does not interact with DBS or other draw effects, and it should - :effect (effect (play-sfx "click-card") - (move (last (:deck corp)) :hand))} + :effect (req (play-sfx state side "click-card") + (move state side (last (:deck corp)) :hand))} {:label "Search R&D for an agenda" :prompt "Choose an agenda to add to the bottom of R&D" :msg (msg "reveal " (:title target) " from R&D and add it to the bottom of R&D") @@ -2966,7 +2966,7 @@ :choices {:max (req (get-counters (get-card state card) :advancement)) :card #(and (installed? %) (hardware? %))} - :effect (effect (trash-cards eid targets {:cause-card card}))})) + :effect (req (trash-cards state side eid targets {:cause-card card}))})) (defcard "Shi.Kyū" {:poison true @@ -2980,9 +2980,9 @@ :choices :credit :msg (msg "attempt to do " target " net damage") :async true - :effect (effect + :effect (req (continue-ability - (let [dmg target] + state side (let [dmg target] {:player :runner :prompt "Choose one" :waiting-prompt true @@ -3003,7 +3003,7 @@ :poison true :on-access {:msg "do 1 net damage" :async true - :effect (effect (damage eid :net 1 {:card card}))}}) + :effect (req (damage state side eid :net 1 {:card card}))}}) (defcard "SIU" {:derezzed-events [corp-rez-toast] @@ -3012,8 +3012,8 @@ :req (req (:corp-phase-12 @state)) :async true :cost [(->c :trash-can)] - :effect (effect (continue-ability - {:trace {:base 3 + :effect (req (continue-ability + state side {:trace {:base 3 :label "Trace 3 - Give the Runner 1 tag" :successful (give-tags 1)}} card nil))}]}) @@ -3025,7 +3025,7 @@ (can-pay? state :corp eid card nil [(->c :credit 4)]))) :waiting-prompt true :prompt (msg "Pay 4 [Credits] to use " (:title card) " ability?") - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card))))} + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card))))} :yes-ability {:async true :cost [(->c :credit 4)] :msg "give the Runner 1 tag and do 3 net damage" @@ -3042,16 +3042,16 @@ :prompt "Choose a card to place an advancement counter on" :choices {:req (req (can-be-advanced? state target))} :async true - :effect (effect (add-prop eid target :advance-counter 1 {:placed true}))}}}}) + :effect (req (add-prop state side eid target :advance-counter 1 {:placed true}))}}}}) (defcard "Spin Doctor" {:on-rez {:async true :msg "draw 2 cards" - :effect (effect (draw eid 2))} + :effect (req (draw state side eid 2))} :abilities [{:label "Shuffle up to 2 cards from Archives into R&D" :cost [(->c :remove-from-game)] :async true - :effect (effect (shuffle-into-rd-effect eid card 2))}]}) + :effect (req (shuffle-into-rd-effect state side eid card 2))}]}) (defcard "Storgotic Resonator" {:abilities [{:action true @@ -3060,7 +3060,7 @@ :label "Do 1 net damage" :msg "do 1 net damage" :async true - :effect (effect (damage eid :net 1 {:card card}))}] + :effect (req (damage state side eid :net 1 {:card card}))}] :events [{:event :corp-trash :once-per-instance true :req (req (and (some #(= (:faction (:identity runner)) (:faction (:card %))) targets) @@ -3070,7 +3070,7 @@ (some #(= (:faction (:identity runner)) (:faction (:card %))) targets))))) :msg "place 1 power counter on itself" :async true - :effect (effect (add-counter eid card :power 1 nil))}]}) + :effect (req (add-counter state side eid card :power 1 nil))}]}) (defcard "Student Loans" {:static-abilities [{:type :play-additional-cost @@ -3145,7 +3145,7 @@ #(has-subtype? (:ice (first %)) "AP")))) :msg "do 1 net damage" :async true - :effect (effect (damage eid :net 1 {:card card}))}]}) + :effect (req (damage state side eid :net 1 {:card card}))}]}) (defcard "Team Sponsorship" {:events [{:event :agenda-scored @@ -3157,7 +3157,7 @@ (corp? %) (or (in-hand? %) (in-discard? %)))} - :effect (effect (corp-install eid target nil {:ignore-install-cost true + :effect (req (corp-install state side eid target nil {:ignore-install-cost true :msg-keys {:install-source card :display-origin true}}))}]}) @@ -3199,7 +3199,7 @@ :autoresolve (get-autoresolve :auto-fire) :yes-ability {:msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits :corp eid 1))}}}]})) + :effect (req (gain-credits state :corp eid 1))}}}]})) (defcard "Tenma Line" {:abilities [{:action true @@ -3260,7 +3260,7 @@ :choices {:card #(and (corp-installable-type? %) (or (in-hand? %) (in-discard? %)))} - :effect (effect (corp-install eid target nil {:ignore-install-cost true + :effect (req (corp-install state side eid target nil {:ignore-install-cost true :msg-keys {:install-source card :display-origin true}}))}]}) @@ -3276,14 +3276,14 @@ :msg (msg "gain " (* 2 (get-counters card :advancement)) " [Credits]") :cost [(->c :trash-can)] :async true - :effect (effect (gain-credits eid (* 2 (get-counters card :advancement))))}]}) + :effect (req (gain-credits state side eid (* 2 (get-counters card :advancement))))}]}) (defcard "Tiered Subscription" {:events [{:event :run :req (req (first-event? state side :run)) :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits :corp eid 1))}]}) + :effect (req (gain-credits state :corp eid 1))}]}) (defcard "Toshiyuki Sakai" (advance-ambush @@ -3303,7 +3303,7 @@ {:optional {:prompt "Access the newly installed card?" :yes-ability {:async true - :effect (effect (access-card eid (get-card state moved-target)))}}} + :effect (req (access-card state side eid (get-card state moved-target)))}}} moved-card nil)))})) (defcard "Trieste Model Bioroids" @@ -3312,7 +3312,7 @@ :choices {:card #(and (ice? %) (rezzed? %) (has-subtype? % "Bioroid"))} - :effect (effect (update! (assoc-in (get-card state card) [:special :trieste-target] target)))} + :effect (req (update! state side (assoc-in (get-card state card) [:special :trieste-target] target)))} :static-abilities [{:type :icon :req (req (same-card? target (get-in card [:special :trieste-target]))) :value (req (make-icon "TMB" card))} @@ -3348,7 +3348,7 @@ {:events [{:event :server-created :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits eid 1))}]}) + :effect (req (gain-credits state side eid 1))}]}) (defcard "Ubiquitous Vig" (let [ability {:msg (msg "gain " (get-counters card :advancement) " [Credits]") @@ -3356,7 +3356,7 @@ :automatic :corp-gain-credits :once :per-turn :async true - :effect (effect (gain-credits eid (get-counters card :advancement)))}] + :effect (req (gain-credits state side eid (get-counters card :advancement)))}] {:derezzed-events [corp-rez-toast] :advanceable :always :events [(assoc ability :event :corp-turn-begins)] @@ -3380,7 +3380,7 @@ (defcard "Urtica Cipher" (advance-ambush 0 {:msg (msg "do " (+ 2 (get-counters (get-card state card) :advancement)) " net damage") :async true - :effect (effect (damage eid :net (+ 2 (get-counters (get-card state card) :advancement)) {:card card}))})) + :effect (req (damage state side eid :net (+ 2 (get-counters (get-card state card) :advancement)) {:card card}))})) (defcard "Vaporframe Fabricator" {:on-trash {:req (req (= :runner side)) @@ -3389,14 +3389,14 @@ (in-hand? %) (not (operation? %)))} :effect - (effect + (req (continue-ability - (let [card-to-install target] + state side (let [card-to-install target] {:async true :prompt "Choose a server" :choices (req (remove (set (zone->name (get-zone card))) (installable-servers state card-to-install))) - :effect (effect (corp-install eid card-to-install target {:ignore-all-cost true + :effect (req (corp-install state side eid card-to-install target {:ignore-all-cost true :msg-keys {:install-source card :display-origin true}}))}) card nil))} @@ -3409,7 +3409,7 @@ (in-hand? %) (not (operation? %)))} :msg (msg (corp-install-msg target)) - :effect (effect (corp-install eid target nil {:ignore-all-cost true + :effect (req (corp-install state side eid target nil {:ignore-all-cost true :msg-keys {:install-source card :display-origin true}}))}]}) @@ -3424,7 +3424,7 @@ :async true :msg (msg "trash " (:title target) " from the Grip") :effect (req (trash state side eid target {:cause-card card}))}) - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card))))}}}] + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card))))}}}] {:events [(assoc ability :event :agenda-scored) (assoc ability :event :agenda-stolen)] :abilities [(set-autoresolve :auto-fire "Vera Ivanovna Shuyskaya")]})) @@ -3437,7 +3437,7 @@ (defcard "Wage Workers" (let [payoff {:msg "gain [Click]" :req (req (not (get-in @state [side :register :terminal]))) - :effect (effect (gain-clicks 1))} + :effect (req (gain-clicks state side 1))} relevant-keys (fn [context] {:cid (get-in context [:card :cid]) :idx (:ability-idx context)})] {:events [{:event :action-resolved @@ -3455,10 +3455,10 @@ (defcard "Wall to Wall" (let [all [{:msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits eid 1))} + :effect (req (gain-credits state side eid 1))} {:msg "draw 1 card" :async true - :effect (effect (draw eid 1))} + :effect (req (draw state side eid 1))} {:label "place 1 advancement counter on a piece of ice" :msg {:public (msg "place 1 advancement counter on " (card-str state target)) :corp (msg "place 1 advancement counter on " (card-str state target {:maybe-visible true}))} @@ -3466,10 +3466,10 @@ :async true :choices {:card #(and (ice? %) (installed? %))} - :effect (effect (add-prop eid target :advance-counter 1 {:placed true}))} + :effect (req (add-prop state side eid target :advance-counter 1 {:placed true}))} {:label "add this asset to HQ" :msg "add itself to HQ" - :effect (effect (move card :hand))}] + :effect (req (move state side card :hand))}] choice (fn choice [abis n] (let [choices (concat (mapv make-label abis) ["Done"])] {:prompt "Choose an ability to resolve" @@ -3487,7 +3487,7 @@ :interactive (req true) :label "resolve an ability (start of turn)" :once :per-turn - :effect (effect (continue-ability (choice all (if (< 1 (count (filter asset? (all-active-installed state :corp)))) + :effect (req (continue-ability state side (choice all (if (< 1 (count (filter asset? (all-active-installed state :corp)))) 1 3)) card nil))}] {:derezzed-events [(assoc corp-rez-toast :event :runner-turn-ends)] @@ -3500,7 +3500,7 @@ :value {:position :front :subroutines [{:label "[Warden Fatuma] Force the Runner to lose [Click], if able" :msg "force the Runner to lose [Click], if able" - :effect (effect (lose-clicks :runner 1))}]}}]}) + :effect (req (lose-clicks state :runner 1))}]}}]}) (defcard "Warm Reception" (let [install {:prompt "Choose a card to install" @@ -3553,8 +3553,8 @@ (pos? (count (:discard corp))))) :async true :cost [(->c :trash-from-hand 1)] - :effect (effect (continue-ability - {:waiting-prompt true + :effect (req (continue-ability + state side {:waiting-prompt true :prompt "Choose a card in Archives to add to the bottom of R&D" :show-discard true :choices {:card #(and (in-discard? %) @@ -3562,14 +3562,14 @@ :msg (msg "trash 1 card from HQ and add " (if (:seen target) (:title target) "a card") " from Archives to the bottom of R&D") - :effect (effect (move target :deck))} + :effect (req (move state side target :deck))} card nil))}]}) (defcard "Working Prototype" {:events [{:event :rez :silent true :async true - :effect (effect (add-counter eid card :power 1 nil))}] + :effect (req (add-counter state side eid card :power 1 nil))}] :abilities [{:action true :cost [(->c :click 1) (->c :power 1)] :label "Gain 3 [Credits]" @@ -3636,7 +3636,7 @@ {:req (req (not (rezzed? card))) :prompt (msg "The Runner is about to expose " (enumerate-str (map #(card-str state % {:visible true}) (:cards ctx))) ". Rez Zaibatsu Loyalty?") :yes-ability {:async true - :effect (effect (rez eid card))}}} + :effect (req (rez state side eid card))}}} card nil)))}]}) (defcard "Zealous Judge" @@ -3647,4 +3647,4 @@ :cost [(->c :click 1) (->c :credit 1)] :keep-menu-open :while-clicks-left :msg "give the Runner 1 tag" - :effect (effect (gain-tags eid 1))}]}) + :effect (req (gain-tags state side eid 1))}]}) diff --git a/src/clj/game/cards/basic.clj b/src/clj/game/cards/basic.clj index a8e88861a1..65a197c8b6 100644 --- a/src/clj/game/cards/basic.clj +++ b/src/clj/game/cards/basic.clj @@ -22,7 +22,7 @@ [game.core.say :refer [play-sfx system-msg]] [game.core.tags :refer [lose-tags]] [game.core.to-string :refer [card-str]] - [game.macros :refer [effect msg req wait-for]] + [game.macros :refer [msg req wait-for]] [game.utils :refer :all] [jinteki.utils :refer :all])) ;; Card definitions @@ -94,9 +94,9 @@ :cost [(->c :click 1) (->c :credit 1)] :async true :msg (msg "advance " (card-str state (:card context))) - :effect (effect (update-advancement-requirement (:card context)) - (play-sfx "click-advance") - (add-prop eid (get-card state (:card context)) :advance-counter 1))} + :effect (req (update-advancement-requirement state side (:card context)) + (play-sfx state side "click-advance") + (add-prop state side eid (get-card state (:card context)) :advance-counter 1))} {:action true :label "Trash 1 resource if the Runner is tagged" :cost [(->c :click 1) (->c :credit 2)] @@ -199,12 +199,12 @@ {:action true :label "Run any server" :async true - :effect (effect (make-run eid (:server context) nil {:click-run true}))} + :effect (req (make-run state side eid (:server context) nil {:click-run true}))} {:action true :label "Remove 1 tag" :cost [(->c :click 1) (->c :credit 2)] :msg "remove 1 tag" :req (req tagged) :async true - :effect (effect (play-sfx "click-remove-tag") - (lose-tags eid 1))}]}) + :effect (req (play-sfx state side "click-remove-tag") + (lose-tags state side eid 1))}]}) diff --git a/src/clj/game/cards/events.clj b/src/clj/game/cards/events.clj index c7f809311c..0a90dbdd9e 100644 --- a/src/clj/game/cards/events.clj +++ b/src/clj/game/cards/events.clj @@ -73,7 +73,7 @@ [game.core.toasts :refer [toast]] [game.core.update :refer [update!]] [game.core.virus :refer [get-virus-counters]] - [game.macros :refer [continue-ability effect msg req wait-for]] + [game.macros :refer [continue-ability msg req wait-for]] [game.utils :refer :all] [jinteki.utils :refer :all] [jinteki.validator :refer [legal?]])) @@ -90,7 +90,7 @@ (get-card state (:ice context)) (first-run-event? state side :subroutines-broken #(pred (first %)))))) :msg (msg "trash " (card-str state (:ice context))) - :effect (effect (trash eid (:ice context) {:cause-card card}))}]}) + :effect (req (trash state side eid (:ice context) {:cause-card card}))}]}) ;; Card definitions @@ -128,7 +128,7 @@ (map remote->name)))) :msg (msg "make a run on " target) :async true - :effect (effect (make-run eid target card))}]})}) + :effect (req (make-run state side eid target card))}]})}) (defcard "Always Have a Backup Plan" {:makes-run true @@ -167,15 +167,15 @@ {:on-play {:msg "gain [Click][Click][Click] and suffer 1 core damage" :async true - :effect (effect (gain-clicks 3) - (damage eid :brain 1 {:unpreventable true :card card}))}}) + :effect (req (gain-clicks state side 3) + (damage state side eid :brain 1 {:unpreventable true :card card}))}}) (defcard "Another Day, Another Paycheck" {:events [{:event :agenda-stolen :trace {:base 0 :unsuccessful {:async true - :effect (effect (gain-credits :runner eid (+ (:agenda-point runner) (:agenda-point corp)))) + :effect (req (gain-credits state :runner eid (+ (:agenda-point runner) (:agenda-point corp)))) :msg (msg (str "gain " (+ (:agenda-point runner) (:agenda-point corp)) " [Credits]"))}}}]}) (defcard "Apocalypse" @@ -230,13 +230,13 @@ (defcard "Bahia Bands" (let [all [{:async true - :effect (effect (draw eid 2)) + :effect (req (draw state side eid 2)) :msg "draw 2 cards"} {:msg "install a card from the grip, paying 1 [Credits] less" :async true :req (req (not (install-locked? state side))) - :effect (effect (continue-ability - {:prompt "Choose a card to install" + :effect (req (continue-ability + state side {:prompt "Choose a card to install" :waiting-prompt true :choices {:req (req (and (or (hardware? target) (program? target) @@ -244,14 +244,14 @@ (in-hand*? state target) (runner-can-pay-and-install? state side (assoc eid :source card) target {:cost-bonus -1})))} :async true - :effect (effect (runner-install (assoc eid :source card :source-type :runner-install) target {:cost-bonus -1 + :effect (req (runner-install state side (assoc eid :source card :source-type :runner-install) target {:cost-bonus -1 :msg-keys {:install-source card :display-origin true}}))} card nil))} {:msg "remove 1 tag" :async true - :effect (effect (lose-tags eid 1))} - {:effect (effect (add-counter eid (get-card state card) :credit 4 nil)) + :effect (req (lose-tags state side eid 1))} + {:effect (req (add-counter state side eid (get-card state card) :credit 4 nil)) :async true :msg "place 4 [Credits] for paying trash costs"}] choice (fn choice [abis rem] @@ -324,8 +324,8 @@ {:trace {:base 4 :unsuccessful - {:effect (effect (register-events - card [(breach-access-bonus :rd 2 {:duration :end-of-turn}) + {:effect (req (register-events + state side card [(breach-access-bonus :rd 2 {:duration :end-of-turn}) (breach-access-bonus :hq 2 {:duration :end-of-turn})]))}}}}) (defcard "Blackmail" @@ -336,15 +336,15 @@ :choices (req runnable-servers) :msg "prevent ice from being rezzed during this run" :async true - :effect (effect (register-run-flag! - card + :effect (req (register-run-flag! + state side card :can-rez (fn [state _side card] (if (ice? card) ((constantly false) (toast state :corp "Cannot rez ice on this run due to Blackmail")) true))) - (make-run eid target card))}}) + (make-run state side eid target card))}}) (defcard "Blueberry!™ Diesel" {:on-play {:async true @@ -373,12 +373,12 @@ :change-in-game-state {:req (req (seq (iced-servers state side eid card)))} :prompt "Choose an iced server" :choices (req (iced-servers state side eid card)) - :effect (effect (register-events - card + :effect (req (register-events + state side card [{:event :pass-ice :duration :end-of-run - :effect (effect (update! (update-in (get-card state card) [:special :bravado-passed] (fnil conj #{}) (:cid (:ice context)))))}]) - (make-run eid target (get-card state card)))} + :effect (req (update! state side (update-in (get-card state card) [:special :bravado-passed] (fnil conj #{}) (:cid (:ice context)))))}]) + (make-run state side eid target (get-card state card)))} :events [{:event :run-ends :silent true :msg (msg "gain " @@ -417,9 +417,9 @@ (fn [targets] (let [context (first targets)] (not (rezzed? (:ice context)))))))) - :effect (effect + :effect (req (register-lingering-effect - card + state side card (let [approached-ice (:ice context)] {:type :rez-additional-cost :duration :end-of-run @@ -494,9 +494,9 @@ (defcard "By Any Means" {:on-play {:effect - (effect + (req (register-events - card + state side card [{:event :access :duration :end-of-turn :req (req (and (can-trash? state :runner (:accessed-card context)) @@ -517,7 +517,7 @@ :change-in-game-state {:req (req (some #(and (has-subtype? % "Connection") (resource? %)) (all-active-installed state :runner)))} :async true - :effect (effect (gain-credits eid (count (filter #(and (has-subtype? % "Connection") + :effect (req (gain-credits state side eid (count (filter #(and (has-subtype? % "Connection") (resource? %)) (all-active-installed state :runner)))))}}) @@ -529,7 +529,7 @@ (in-hand*? state target) (runner-can-pay-and-install? state side eid card {:cost-bonus -3})))} :async true - :effect (effect (runner-install (assoc eid :source card :source-type :runner-install) target {:cost-bonus -3 + :effect (req (runner-install state side (assoc eid :source card :source-type :runner-install) target {:cost-bonus -3 :msg-keys {:install-source card :display-origin true}}))}}) @@ -569,10 +569,10 @@ state side {:optional {:prompt (str "Run on " (zone->name marked-server) "?") - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card) " to make a run")))} + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card) " to make a run")))} :yes-ability {:msg (str "make a run on " (zone->name marked-server)) :async true - :effect (effect (make-run eid marked-server card))}}} + :effect (req (make-run state side eid marked-server card))}}} card nil)))))}}) (defcard "CBI Raid" @@ -594,9 +594,9 @@ :prompt "Choose a card to move next onto R&D" :choices remaining :async true - :effect (effect + :effect (req (continue-ability - (let [chosen (cons target chosen)] + state side (let [chosen (cons target chosen)] (if (< (count chosen) n) (cbi-choice (remove-once #(= target %) remaining) chosen n original) (cbi-final chosen original))) @@ -612,9 +612,9 @@ :player :corp :waiting-prompt true :async true - :effect (effect + :effect (req (continue-ability - (let [from (:hand corp)] + state side (let [from (:hand corp)] (when (pos? (count from)) (cbi-choice from '() (count from) from))) card nil))}})]})) @@ -661,7 +661,7 @@ :choices {:card #(and (rezzed? %) (= t (:title %)))} :msg (msg "trash " (card-str state target)) - :effect (effect (trash eid target {:cause-card card}))}})] + :effect (req (trash state side eid target {:cause-card card}))}})] {:makes-run true :on-play (run-server-ability :archives) :events [{:event :breach-server @@ -694,7 +694,7 @@ :choices {:card #(and (rezzed? %) (contains? isec (:title %)))} :msg (msg "trash " (card-str state target)) - :effect (effect (trash eid target {:cause-card card}))} + :effect (req (trash state side eid target {:cause-card card}))} card nil) (effect-completed state side eid))))}]})) @@ -733,7 +733,7 @@ :req (req this-card-run) :msg "gain 6 [Credits]" :async true - :effect (effect (gain-credits :runner eid 6))}]}) + :effect (req (gain-credits state :runner eid 6))}]}) (defcard "Code Siphon" (letfn [(rd-ice [state] @@ -770,7 +770,7 @@ (installed? %))} :msg (msg "trash " (:title target)) :async true - :effect (effect (trash eid target {:unpreventable true + :effect (req (trash state side eid target {:unpreventable true :cause-card card}))}]}) (defcard "Compile" @@ -815,8 +815,8 @@ {:async true :prompt "Choose where to install the program from" :choices (req (if (not (zone-locked? state :runner :discard)) ["Stack" "Heap"] ["Stack"])) - :effect (effect (continue-ability - (compile-fn (if (= "Stack" target) :deck :discard)) + :effect (req (continue-ability + state side (compile-fn (if (= "Stack" target) :deck :discard)) card nil))}}}]})) (defcard "Concerto" @@ -852,14 +852,14 @@ :change-in-game-state {:req (req (some #(zero? (get-virus-counters state %)) (all-installed state :runner)))} :async true - :effect (effect (add-counter :runner eid target :virus 3 nil))}}) + :effect (req (add-counter state :runner eid target :virus 3 nil))}}) (defcard "Corporate \"Grant\"" {:events [{:event :runner-install :req (req (first-event? state side :runner-install)) :msg "force the Corp to lose 1 [Credit]" :async true - :effect (effect (lose-credits :corp eid 1))}]}) + :effect (req (lose-credits state :corp eid 1))}]}) (defcard "Corporate Scandal" {:on-play {:msg "give the Corp 1 additional bad publicity" @@ -904,7 +904,7 @@ (lose-credits state :corp eid cost))} :no-ability {:msg (msg "trash " title " at no cost") :async true - :effect (effect (trash eid (assoc c :seen true) {:cause-card card}))}}} + :effect (req (trash state side eid (assoc c :seen true) {:cause-card card}))}}} card nil) (do (system-msg state side (str "uses " (:title card) " to trash " title " at no cost")) (trash state side eid (assoc c :seen true) nil)))))}]}) @@ -952,38 +952,38 @@ (ice? %) (can-pay? state side eid card nil [(->c :credit (rez-cost state side %))]))} - :effect (effect (rez :corp eid target)) + :effect (req (rez state :corp eid target)) :cancel {:async true - :effect (effect (register-run-flag! - card + :effect (req (register-run-flag! + state side card :can-rez (fn [state _side card] (if (ice? card) ((constantly false) (toast state :corp "Cannot rez ice on this run due to Cyber Threat")) true))) - (make-run eid serv card))}} + (make-run state side eid serv card))}} :no-ability {:async true - :effect (effect (register-run-flag! - card + :effect (req (register-run-flag! + state side card :can-rez (fn [state _side card] (if (ice? card) ((constantly false) (toast state :corp "Cannot rez ice on this run due to Cyber Threat")) true))) - (make-run eid serv card)) + (make-run state side eid serv card)) :msg (msg "make a run on " serv " during which no ice can be rezzed")}}} {:async true - :effect (effect (register-run-flag! - card + :effect (req (register-run-flag! + state side card :can-rez (fn [state _side card] (if (ice? card) ((constantly false) (toast state :corp "Cannot rez ice on this run due to Cyber Threat")) true))) - (make-run eid serv card)) + (make-run state side eid serv card)) :msg (msg "make a run on " serv " during which no ice can be rezzed")}) card nil)))}}) @@ -1004,7 +1004,7 @@ {:additional-cost [(->c :click 3)] :msg "gain 10 [Credits]" :async true - :effect (effect (gain-credits eid 10))}}) + :effect (req (gain-credits state side eid 10))}}) (defcard "Deep Data Mining" {:makes-run true @@ -1013,8 +1013,8 @@ :req (req (and (= :rd (target-server context)) this-card-run)) :silent true - :effect (effect (register-events - card [(breach-access-bonus :rd + :effect (req (register-events + state side card [(breach-access-bonus :rd (max 0 (min 4 (available-mu state))) {:duration :end-of-run})]))}]}) @@ -1066,7 +1066,7 @@ (assoc eid :source card :source-type :ability) card nil [(->c :click 1)])) :no-ability - {:effect (effect (system-msg (str "declines to use " + {:effect (req (system-msg state side (str "declines to use " (:title card) " to access another card")))} :yes-ability @@ -1093,15 +1093,15 @@ :choices (req (cancellable (:discard runner) :sorted)) :msg (msg "add " (:title target) " to [their] Grip") :async true - :effect (effect (move target :hand) + :effect (req (move state side target :hand) (continue-ability - (when (has-subtype? target "Virus") + state side (when (has-subtype? target "Virus") {:prompt "Choose a virus to add to Grip" :change-in-game-state {:silent true :req (req (seq (filter #(has-subtype? % "Virus") (:discard runner))))} :msg (msg "add " (:title target) " to [their] Grip") :choices (req (cancellable (filter #(has-subtype? % "Virus") (:discard runner)) :sorted)) - :effect (effect (move target :hand))}) + :effect (req (move state side target :hand))}) card nil))}}) (defcard "Demolition Run" @@ -1114,17 +1114,17 @@ :req (req (and (can-trash? state :runner target) (not (in-discard? target)))) ;;for if the run gets diverted :async true - :effect (effect (trash eid (assoc target :seen true) {:cause-card card}))}}}) + :effect (req (trash state side eid (assoc target :seen true) {:cause-card card}))}}}) (defcard "Deuces Wild" - (let [all [{:effect (effect (gain-credits eid 3)) + (let [all [{:effect (req (gain-credits state side eid 3)) :async true :msg "gain 3 [Credits]"} {:async true - :effect (effect (draw eid 2)) + :effect (req (draw state side eid 2)) :msg "draw 2 cards"} {:async true - :effect (effect (lose-tags eid 1)) + :effect (req (lose-tags state side eid 1)) :msg "remove 1 tag"} {:prompt "Choose 1 piece of ice to expose" :msg "expose 1 ice and make a run" @@ -1150,7 +1150,7 @@ (effect-completed state side eid)))))})] {:on-play {:async true - :effect (effect (continue-ability (choice all) card nil))}})) + :effect (req (continue-ability state side (choice all) card nil))}})) (defcard "Diana's Hunt" {:makes-run true @@ -1165,7 +1165,7 @@ :async true :choices {:req (req (and (in-hand*? state target) (program? target)))} - :effect (effect (runner-install eid (assoc-in target [:special :diana-installed] true) {:ignore-all-cost true + :effect (req (runner-install state side eid (assoc-in target [:special :diana-installed] true) {:ignore-all-cost true :msg-keys {:install-source card :display-origin true}}))}}} {:event :run-ends @@ -1198,7 +1198,7 @@ {:async true :prompt "Choose a server" :choices (req runnable-servers) - :effect (effect (make-run eid target card))} + :effect (req (make-run state side eid target card))} card nil))} :events [{:event :run-ends :unregister-once-resolved true @@ -1209,8 +1209,8 @@ {:prompt "Shuffle Direct Access into the Stack?" :yes-ability {:msg "shuffle itself into the Stack" - :effect (effect (move (get-card state card) :deck) - (shuffle! :deck))}}} + :effect (req (move state side (get-card state card) :deck) + (shuffle! state side :deck))}}} card nil))}]}) (defcard "Dirty Laundry" @@ -1221,7 +1221,7 @@ this-card-run)) :msg "gain 5 [Credits]" :async true - :effect (effect (gain-credits :runner eid 5))}]}) + :effect (req (gain-credits state :runner eid 5))}]}) (defcard "Diversion of Funds" {:makes-run true @@ -1264,8 +1264,8 @@ :choices (req runnable-servers) :msg (msg "make a run on " target " and gain [Click]") :async true - :effect (effect (gain-clicks 1) - (make-run eid target card))}}) + :effect (req (gain-clicks state side 1) + (make-run state side eid target card))}}) (defcard "Easy Mark" {:on-play (gain-credits-ability 3)}) @@ -1360,7 +1360,7 @@ :msg (msg "trash " (card-str state target)) :async true :cancel {:msg "do nothing"} - :effect (effect (trash eid target {:cause-card card}))}}) + :effect (req (trash state side eid target {:cause-card card}))}}) (defcard "Encore" {:on-play @@ -1391,7 +1391,7 @@ :ability {:async true :msg "rearrange installed ice" - :effect (effect (continue-ability (es) card nil))}})]})) + :effect (req (continue-ability state side (es) card nil))}})]})) (defcard "Eureka!" {:on-play @@ -1408,7 +1408,7 @@ {:optional {:prompt (msg "Install " (:title topcard) "?") :yes-ability {:async true - :effect (effect (runner-install eid topcard {:msg-keys {:display-origin true + :effect (req (runner-install state side eid topcard {:msg-keys {:display-origin true :install-source card} :cost-bonus -10}))} :no-ability {:async true @@ -1438,7 +1438,7 @@ {:msg (msg "reveal " (enumerate-cards (:hand corp) :sorted) " from HQ") :change-in-game-state {:req (req (seq (:hand corp)))} :async true - :effect (effect (reveal eid (:hand corp)))}}) + :effect (req (reveal state side eid (:hand corp)))}}) (defcard "Exploit" {:on-play @@ -1485,8 +1485,8 @@ :change-in-game-state {:req (req (seq (:deck runner)))} :choices (req (take 4 (:deck runner))) :msg "look at the top 4 cards of the stack and add 1 of them to the grip" - :effect (effect (move target :hand) - (shuffle! :deck))}}) + :effect (req (move state side target :hand) + (shuffle! state side :deck))}}) (defcard "Eye for an Eye" {:makes-run true @@ -1497,7 +1497,7 @@ :cost [(->c :trash-from-hand 1)] :msg (msg "trash " (:title target) " from HQ") :async true - :effect (effect (trash eid (assoc target :seen true) {:accessed true :cause-card card}))}} + :effect (req (trash state side eid (assoc target :seen true) {:accessed true :cause-card card}))}} :events [{:event :successful-run :silent true :req (req (and (= :hq (target-server context)) @@ -1517,9 +1517,9 @@ :choices ["Agenda" "Asset" "Upgrade"] :msg (msg "guess " target) :async true - :effect (effect + :effect (req (continue-ability - (let [chosen-type target] + state side (let [chosen-type target] {:choices {:card #(let [topmost (get-nested-host %)] (and (is-remote? (second (get-zone topmost))) (= (last (get-zone topmost)) :content) @@ -1532,7 +1532,7 @@ (= chosen-type (:type target))) {:msg "gain 5 [Credits]" :async true - :effect (effect (gain-credits eid 5))}) + :effect (req (gain-credits state side eid 5))}) card nil)))}) card nil))}}) @@ -1576,7 +1576,7 @@ :effect (req (bypass-ice state) (update! state side (update-in card [:special :bypass-count] (fnil inc 0))))} {:event :successful-run - :effect (effect (prevent-access))}]}) + :effect (req (prevent-access state side))}]}) (defcard "Finality" {:makes-run true @@ -1585,8 +1585,8 @@ :silent true :req (req (and (= :rd (target-server context)) this-card-run)) - :effect (effect (register-events - card [(breach-access-bonus :rd 3 {:duration :end-of-run})]))}]}) + :effect (req (register-events + state side card [(breach-access-bonus :rd 3 {:duration :end-of-run})]))}]}) (defcard "Fisk Investment Seminar" {:on-play @@ -1639,16 +1639,16 @@ {:async true :change-in-game-state {:req (req (seq (:deck runner)))} :effect - (effect + (req (continue-ability - (let [top-ten (take 10 (:deck runner))] + state side (let [top-ten (take 10 (:deck runner))] {:prompt (str "The top cards of the stack are (top->bottom): " (enumerate-cards top-ten)) :choices ["OK"] :async true :effect - (effect + (req (continue-ability - {:prompt "Install a program?" + state side {:prompt "Install a program?" :choices (concat (->> top-ten (filter #(and (program? %) @@ -1701,7 +1701,7 @@ {:msg (msg "draw " (quantify (- (hand-size state :runner) (count (:hand runner))) "card")) :change-in-game-state {:req (req (pos? (- (hand-size state :runner) (count (:hand runner)))))} :async true - :effect (effect (draw eid (- (hand-size state :runner) (count (:hand runner)))))}}) + :effect (req (draw state side eid (- (hand-size state :runner) (count (:hand runner)))))}}) (defcard "Glut Cipher" {:makes-run true @@ -1805,13 +1805,13 @@ bad-zones (keys (filter (complement unrezzed-ice) (get-in @state [:corp :servers])))] (zones->sorted-names (remove (set bad-zones) (get-runnable-zones state side eid card nil))))) :async true - :effect (effect (make-run eid target card))} + :effect (req (make-run state side eid target card))} :events [{:event :run-ends :req (req (and (:successful target) this-card-run)) :msg "gain 12 [Credits]" :async true - :effect (effect (gain-credits :runner eid 12))}]}) + :effect (req (gain-credits state :runner eid 12))}]}) (defcard "Hostage" {:on-play @@ -1821,18 +1821,18 @@ :msg (msg "add " (:title target) " from the stack to the grip and shuffle the stack") :async true :cancel fail-to-find! - :effect (effect (trigger-event :searched-stack) + :effect (req (trigger-event state side :searched-stack) (continue-ability - (let [connection target] + state side (let [connection target] (if (runner-can-pay-and-install? state side (assoc eid :source card) connection) {:optional {:prompt (str "Install " (:title connection) "?") :yes-ability {:async true - :effect (effect (runner-install (assoc eid :source card :source-type :runner-install) connection nil) - (shuffle! :deck))} - :no-ability {:effect (effect (move connection :hand) - (shuffle! :deck))}}} - {:effect (effect (move connection :hand) - (shuffle! :deck))})) + :effect (req (runner-install state side (assoc eid :source card :source-type :runner-install) connection nil) + (shuffle! state side :deck))} + :no-ability {:effect (req (move state side connection :hand) + (shuffle! state side :deck))}}} + {:effect (req (move state side connection :hand) + (shuffle! state side :deck))})) card nil))}}) (defcard "Hot Pursuit" @@ -1850,13 +1850,13 @@ (defcard "I've Had Worse" {:on-play {:async true :change-in-game-state {:req (req (seq (:deck runner)))} - :effect (effect (draw eid 3))} + :effect (req (draw state side eid 3))} :on-trash {:when-inactive true :interactive (req true) :async true :req (req (#{:meat :net} (:cause context))) :msg "draw 3 cards" - :effect (effect (draw :runner eid 3))}}) + :effect (req (draw state :runner eid 3))}}) (defcard "Illumination" (letfn [(install-fn [remaining] @@ -1900,15 +1900,15 @@ (into #{} (map :title (filter rezzed? (all-installed state :corp)))))))) :prompt "Choose a piece of ice in Archives" :choices (req (filter ice? (:discard corp))) - :effect (effect (continue-ability - (let [ice target] + :effect (req (continue-ability + state side (let [ice target] {:async true :prompt (msg "Choose a rezzed copy of " (:title ice) " to trash") :choices {:card #(and (ice? %) (rezzed? %) (same-card? :title % ice))} :msg (msg "trash " (card-str state target)) - :effect (effect (trash eid target {:cause-card card}))}) + :effect (req (trash state side eid target {:cause-card card}))}) card nil))}]}) (defcard "In the Groove" @@ -1953,9 +1953,9 @@ {:msg "rearrange the top 5 cards of R&D" :waiting-prompt true :async true - :effect (effect + :effect (req (continue-ability - (let [from (take 5 (:deck corp))] + state side (let [from (take 5 (:deck corp))] (when (pos? (count from)) (reorder-choice :corp :corp from '() (count from) from))) card nil))}})]}) @@ -1968,7 +1968,7 @@ :ability {:choices {:card #(and (installed? %) (not (rezzed? %)))} :async true - :effect (effect (expose eid [target]))}}])}) + :effect (req (expose state side eid [target]))}}])}) (defcard "Information Sifting" (letfn [(access-pile [cards pile pile-size] @@ -2052,14 +2052,14 @@ :choices (req runnable-servers) :change-in-game-state {:req (req (seq runnable-servers))} :async true - :effect (effect (continue-ability - (let [server target] + :effect (req (continue-ability + state side (let [server target] {:prompt "Choose an icebreaker" :choices {:card #(and (installed? %) (has-subtype? % "Icebreaker"))} :async true - :effect (effect (pump target 2 :end-of-run) - (make-run eid server card))}) + :effect (req (pump state side target 2 :end-of-run) + (make-run state side eid server card))}) card nil))}}) (defcard "Inside Job" @@ -2087,8 +2087,8 @@ (reveal state :runner eid top-4))))}}) (defcard "Interdiction" - (let [ab (effect (register-turn-flag! - card :can-rez + (let [ab (req (register-turn-flag! + state side card :can-rez (fn [state _side card] (if (and (= (:active-player @state) :runner) (not (ice? card))) ((constantly false) @@ -2106,12 +2106,12 @@ ;; passing the same ice multiple times (ie thimblerig) counts. (let [all [{:msg "gain 4 [Credits]" :async true - :effect (effect (gain-credits eid 4))} + :effect (req (gain-credits state side eid 4))} {:msg "install a program from the stack" :async true :req (req (not (install-locked? state side))) - :effect (effect (continue-ability - {:prompt "Choose a program to install" + :effect (req (continue-ability + state side {:prompt "Choose a program to install" :msg (msg (if (= target "Done") "shuffle the stack" (str "install " (:title target) " from the stack"))) @@ -2132,7 +2132,7 @@ :display-origin true}})))} card nil))} {:async true - :effect (effect (continue-ability (charge-ability state side) card nil)) + :effect (req (continue-ability state side (charge-ability state side) card nil)) :msg "charge a card"}] choice (fn choice [abis rem] {:prompt (str "Choose an ability to resolve (" rem " remaining)") @@ -2163,7 +2163,7 @@ {:additional-cost [(->c :resource 1)] :msg "gain 7 [Credits]" :async true - :effect (effect (gain-credits eid 7))}}) + :effect (req (gain-credits state side eid 7))}}) (defcard "Itinerant Protesters" {:on-play {:msg "reduce the Corp's maximum hand size by 1 for each bad publicity"} @@ -2179,9 +2179,9 @@ :msg "draw 1 card" :req (req (and (#{:hq :rd} (target-server context)) this-card-run)) - :effect (effect (register-events - card [(breach-access-bonus (target-server context) 1 {:duration :end-of-run})]) - (draw eid 1))}]}) + :effect (req (register-events + state side card [(breach-access-bonus (target-server context) 1 {:duration :end-of-run})]) + (draw state side eid 1))}]}) (defcard "Joy Ride" {:on-play {:async true @@ -2194,7 +2194,7 @@ :req (req (and (= :rd (target-server context)) this-card-run)) :msg "draw 5 cards" - :effect (effect (draw eid 5))}]}) + :effect (req (draw state side eid 5))}]}) (defcard "Katorga Breakout" {:makes-run true @@ -2207,7 +2207,7 @@ :waiting-prompt true :choices (req (cancellable (:discard runner) :sorted)) :msg (msg "add " (:title target) " to the grip") - :effect (effect (move target :hand))}]}) + :effect (req (move state side target :hand))}]}) (defcard "Khusyuk" (let [access-revealed (fn [revealed] @@ -2217,7 +2217,7 @@ :not-distinct true :choices revealed :req (req (not= (:max-access run) 0)) - :effect (effect (access-card eid target))}) + :effect (req (access-card state side eid target))}) select-install-cost (fn [state] (let [current-values (->> (all-active-installed state :runner) @@ -2232,8 +2232,8 @@ :choices (mapv str (for [x (->> current-values keys last inc (range 1) (#(concat % [99])))] (str x " [Credit]: " (quantify (get current-values x 0) "card")))) - :effect (effect (complete-with-result - eid [(str->int (first (str/split target #" "))) + :effect (req (complete-with-result + state side eid [(str->int (first (str/split target #" "))) (min 6 (str->int (nth (str/split target #" ") 2)))]))})) access-effect {:async true @@ -2252,7 +2252,7 @@ state side (when revealed {:async true - :effect (effect (reveal eid revealed))}) + :effect (req (reveal state side eid revealed))}) card nil) (wait-for (resolve-ability state side (when (and revealed (not (get-only-card-to-access state))) @@ -2319,16 +2319,16 @@ :choices (req servers) :msg (msg "force the Corp to trash a piece of ice protecting " target) :async true - :effect (effect + :effect (req (continue-ability - (let [serv (second (server->zone state target))] + state side (let [serv (second (server->zone state target))] {:player :corp :async true :prompt (msg "Choose a piece of ice in " target " to trash") :choices {:card #(and (ice? %) (= serv (second (get-zone %))))} - :effect (effect (system-msg (str "trashes " (card-str state target))) - (trash :corp eid target {:cause-card card}))}) + :effect (req (system-msg state side (str "trashes " (card-str state target))) + (trash state :corp eid target {:cause-card card}))}) card nil))}}) (defcard "Labor Rights" @@ -2365,8 +2365,8 @@ (shuffle! state :runner :deck) (draw state :runner eid 1))} {:async true - :effect (effect - (do (system-msg state :runner "shuffles the stack and draws 1 card") + :effect (req + (do state side (system-msg state :runner "shuffles the stack and draws 1 card") (shuffle! state :runner :deck) (draw state :runner eid 1)))}) card nil)))))}}) @@ -2412,8 +2412,8 @@ :silent true :req (req (and (= :hq (target-server context)) this-card-run)) - :effect (effect (register-events - card [(breach-access-bonus :hq 2 {:duration :end-of-run})]))}]}) + :effect (req (register-events + state side card [(breach-access-bonus :hq 2 {:duration :end-of-run})]))}]}) (defcard "Leverage" {:on-play @@ -2424,7 +2424,7 @@ :waiting-prompt true :yes-ability {:player :corp :msg "takes 2 bad publicity" - :effect (effect (gain-bad-publicity :corp 2))} + :effect (req (gain-bad-publicity state :corp 2))} :no-ability {:player :runner :msg "is immune to damage until the beginning of the Runner's next turn" :effect (req @@ -2452,8 +2452,8 @@ "shuffle the grip into the stack and draw 5 cards")) :rfg-instead-of-trashing true :async true - :effect (effect (shuffle-into-deck :hand :discard) - (draw eid 5))}}) + :effect (req (shuffle-into-deck state side :hand :discard) + (draw state side eid 5))}}) (defcard "Lie Low" (letfn [(remove-tag-opt [x] @@ -2475,7 +2475,7 @@ {:on-play {:msg "gain 9 [Credits]" :async true - :effect (effect (gain-credits eid 9))}}) + :effect (req (gain-credits state side eid 9))}}) (defcard "Mad Dash" {:makes-run true @@ -2527,7 +2527,7 @@ :change-in-game-state {:req (req (seq (:deck runner)))} :async true :waiting-prompt true - :effect (effect (continue-ability (entrance-trash (take 6 (:deck runner))) card nil))}})) + :effect (req (continue-ability state side (entrance-trash (take 6 (:deck runner))) card nil))}})) (defcard "Marathon" {:makes-run true @@ -2574,7 +2574,7 @@ {:on-play {:async true :change-in-game-state {:silent true :req (req (seq (all-cards-in-hand* state :runner)))} - :effect (effect (continue-ability (mhelper 0) card nil))}})) + :effect (req (continue-ability state side (mhelper 0) card nil))}})) (defcard "Meeting of Minds" (letfn [(credit-gain-abi [type] @@ -2599,10 +2599,10 @@ (continue-ability state side (credit-gain-abi type) card nil))} :msg (msg "add " (:title target) " from the stack to the grip and shuffle the stack") :async true - :effect (effect (trigger-event :searched-stack) - (move target :hand) - (shuffle! :deck) - (continue-ability (credit-gain-abi type) card nil))})] + :effect (req (trigger-event state side :searched-stack) + (move state side target :hand) + (shuffle! state side :deck) + (continue-ability state side (credit-gain-abi type) card nil))})] {:on-play {:prompt "Choose one" :async true :waiting-prompt true @@ -2615,10 +2615,10 @@ :yes-ability {:async true :msg (msg "search the stack for a " (decapitalize choice) " resource") - :effect (effect (continue-ability (tutor-abi choice) card nil))} + :effect (req (continue-ability state side (tutor-abi choice) card nil))} :no-ability {:async true - :effect (effect (continue-ability (credit-gain-abi choice) card nil))}}} + :effect (req (continue-ability state side (credit-gain-abi choice) card nil))}}} card nil)))}})) (defcard "Mining Accident" @@ -2655,15 +2655,15 @@ (= :rd (target-server context)))) :msg "gain 4 [Credits]" :async true - :effect (effect (gain-credits eid 4))} + :effect (req (gain-credits state side eid 4))} {:event :run-ends :interactive (req true) :optional {:req (req (and (:successful target) (not (get-in card [:special :run-again])) (= [:rd] (:server target)))) :prompt "Make another run on R&D?" - :yes-ability {:effect (effect (clear-wait-prompt :corp) - (update! (assoc-in card [:special :run-again] true)))}}}]}) + :yes-ability {:effect (req (clear-wait-prompt state :corp) + (update! state side (assoc-in card [:special :run-again] true)))}}}]}) (defcard "Modded" {:on-play @@ -2674,7 +2674,7 @@ (in-hand*? state target) (runner-can-pay-and-install? state side eid card {:cost-bonus -3})))} :async true - :effect (effect (runner-install (assoc eid :source card :source-type :runner-install) target {:cost-bonus -3 + :effect (req (runner-install state side (assoc eid :source card :source-type :runner-install) target {:cost-bonus -3 :msg-keys {:install-source card :display-origin true}}))}}) @@ -2694,9 +2694,9 @@ :cancel fail-to-find! :msg (msg "add " (:title target) " from the stack to the grip and shuffle the stack") :async true - :effect (effect (trigger-event :searched-stack) + :effect (req (trigger-event state side :searched-stack) (continue-ability - (let [icebreaker target] + state side (let [icebreaker target] (if (and (:successful-run runner-reg) (runner-can-pay-and-install? state side (assoc eid :source card :source-type :runner-install) icebreaker)) {:optional @@ -2733,7 +2733,7 @@ :yes-ability {:cost [(->c :credit 1)] :msg "add itself to the Grip" - :effect (effect (move card :hand))}}} + :effect (req (move state side card :hand))}}} card nil)))}}) (defcard "Notoriety" @@ -2777,7 +2777,7 @@ (let [ashes-run {:prompt "Choose a server" :choices (req runnable-servers) :async true - :effect (effect (make-run eid target card))} + :effect (req (make-run state side eid target card))} ashes-recur (fn ashes-recur [] {:optional {:req (req (not (zone-locked? state :runner :discard))) @@ -2825,7 +2825,7 @@ {:msg "remove all tags" :change-in-game-state {:req (req tagged)} :async true - :effect (effect (lose-tags eid :all))}}) + :effect (req (lose-tags state side eid :all))}}) (defcard "Peace in Our Time" {:on-play @@ -2881,9 +2881,9 @@ (:deck runner)))) :msg (msg "play " (:title target)) :async true - :effect (effect (trigger-event :searched-stack) - (shuffle! :deck) - (play-instant eid target {:no-additional-cost true}))}}) + :effect (req (trigger-event state side :searched-stack) + (shuffle! state side :deck) + (play-instant state side eid target {:no-additional-cost true}))}}) (defcard "Political Graffiti" {:makes-run true @@ -2915,16 +2915,16 @@ (defcard "Populist Rally" {:on-play {:req (req (seq (filter #(has-subtype? % "Seedy") (all-active-installed state :runner)))) :msg (msg "give the Corp 1 fewer [Click] to spend on [corp-pronoun] next turn") - :effect (effect (lose :corp :click-per-turn 1))} + :effect (req (lose state :corp :click-per-turn 1))} :events [{:event :corp-turn-ends :duration :until-corp-turn-ends - :effect (effect (gain :corp :click-per-turn 1))}]}) + :effect (req (gain state :corp :click-per-turn 1))}]}) (defcard "Power Nap" {:on-play {:async true :msg (msg "gain " (+ 2 (count (filter #(has-subtype? % "Double") (:discard runner)))) " [Credits]") - :effect (effect (gain-credits eid (+ 2 (count (filter #(has-subtype? % "Double") + :effect (req (gain-credits state side eid (+ 2 (count (filter #(has-subtype? % "Double") (:discard runner))))))}}) (defcard "Power to the People" @@ -2935,7 +2935,7 @@ :unregister-once-resolved true :msg "gain 7 [Credits]" :async true - :effect (effect (gain-credits eid 7))}]}) + :effect (req (gain-credits state side eid 7))}]}) (defcard "Prey" {:makes-run true @@ -2946,9 +2946,9 @@ (<= (get-strength (:ice context)) (count (all-installed state :runner))))) :async true :effect - (effect + (req (continue-ability - (let [ice (:ice context)] + state side (let [ice (:ice context)] (if (pos? (get-strength ice)) {:optional {:prompt (str "Trash " (quantify (get-strength ice) "installed card") @@ -2958,14 +2958,14 @@ {:async true :cost [(->c :trash-installed (get-strength ice))] :msg (msg "trash " (card-str state ice)) - :effect (effect (trash eid ice {:cause-card card}))}}} + :effect (req (trash state side eid ice {:cause-card card}))}}} {:optional {:prompt (str "Trash " (:title ice) "?") :once :per-run :yes-ability {:async true :msg (msg "trash " (card-str state ice)) - :effect (effect (trash eid ice {:cause-card card}))}}})) + :effect (req (trash state side eid ice {:cause-card card}))}}})) card nil))}]}) (defcard "Privileged Access" @@ -3071,7 +3071,7 @@ :waiting-prompt true :choices choices :async true - :effect (effect (continue-ability :corp (corp-choice (str->int target)) card nil))})] + :effect (req (continue-ability state :corp (corp-choice (str->int target)) card nil))})] {:on-play {:async true :effect (req (let [all-amounts (range (inc (get-in @state [:runner :credit]))) @@ -3102,9 +3102,9 @@ {:choices ["0" "1" "2" "3"] :prompt "How many advancement counters do you want to place?" :async true - :effect (effect + :effect (req (continue-ability - (let [c (str->int target)] + state side (let [c (str->int target)] {:choices {:card #(and (is-remote? (second (get-zone %))) (= (last (get-zone %)) :content) (not (:rezzed %)))} @@ -3131,7 +3131,7 @@ :choices {:card installed?} :msg (msg "access " (:title target)) :async true - :effect (effect (access-card eid target))}}) + :effect (req (access-card state side eid target))}}) (defcard "Raindrops Cut Stone" {:makes-run true @@ -3139,7 +3139,7 @@ :events [{:event :subroutine-fired :req (req (some #(= % :play-area) (:zone card))) :async true - :effect (effect (add-counter eid (get-card state card) :power 1 nil))} + :effect (req (add-counter state side eid (get-card state card) :power 1 nil))} {:event :run-ends :async true :req (req this-card-run) @@ -3215,7 +3215,7 @@ :choices {:max 5 :card #(and (in-discard? %) (runner? %))} - :effect (effect (install-cards eid card targets (map :title targets)))}})]})) + :effect (req (install-cards state side eid card targets (map :title targets)))}})]})) (defcard "Recon" {:makes-run true @@ -3242,7 +3242,7 @@ {:req (req (and (valid-target? target) (in-hand*? state target) (runner-can-pay-and-install? state side (assoc eid :source card) target {:cost-bonus (- bonus)})))} - :effect (effect (runner-install (assoc eid :source card :source-type :runner-install) + :effect (req (runner-install state side (assoc eid :source card :source-type :runner-install) target {:cost-bonus (- bonus) :msg-keys {:install-source card :display-origin true}}))})] @@ -3259,7 +3259,7 @@ {:optional {:prompt "Run a server?" :yes-ability (run-any-server-ability) - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card) " to make a run")))}}})] + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card) " to make a run")))}}})] {:makes-run true :on-play {:async true @@ -3270,8 +3270,8 @@ (corp? %))} :msg (msg "add " (card-str state target) " to HQ") :cancel (opt-run) - :effect (effect (move :corp target :hand) - (continue-ability (opt-run) card nil))}})) + :effect (req (move state :corp target :hand) + (continue-ability state side (opt-run) card nil))}})) (defcard "Reshape" {:on-play @@ -3283,7 +3283,7 @@ :all true} :msg (msg "swap the positions of " (card-str state (first targets)) " and " (card-str state (second targets))) - :effect (effect (swap-ice (first targets) (second targets)))}}) + :effect (req (swap-ice state side (first targets) (second targets)))}}) (defcard "Retrieval Run" {:makes-run true @@ -3309,15 +3309,15 @@ :choices {:card ice?} :msg (msg "make a run and bypass " (card-str state target)) :async true - :effect (effect (register-events - card + :effect (req (register-events + state side card (let [target-ice target] [{:event :encounter-ice :automatic :bypass :req (req (same-card? target-ice (:ice context))) :msg (msg "bypass " (:title (:ice context))) :effect (req (bypass-ice state))}])) - (make-run eid (second (get-zone target)) card))}) + (make-run state side eid (second (get-zone target)) card))}) (corp-choice [choices spent] {:player :corp :waiting-prompt true @@ -3337,7 +3337,7 @@ :prompt "How many credits do you want to spend?" :choices choices :async true - :effect (effect (continue-ability (corp-choice choices (str->int target)) card nil))})] + :effect (req (continue-ability state side (corp-choice choices (str->int target)) card nil))})] {:on-play {:async true :effect (req (let [all-amounts (range (min 3 (inc (get-in @state [:runner :credit])))) @@ -3367,7 +3367,7 @@ :req (req (can-charge state side rig-target)) :yes-ability {:async true - :effect (effect (charge-card eid rig-target)) + :effect (req (charge-card state side eid rig-target)) :msg (msg "charge " (:title rig-target))}}} card nil))))}}) @@ -3410,12 +3410,12 @@ :silent true :req (req (and (= :hq (target-server context)) this-card-run)) - :effect (effect (register-events card + :effect (req (register-events state side card [{:event :candidates-determined :duration :end-of-run :async true :req (req (= :hq (:breached-server context))) - :effect (effect (continue-ability add-cards-from-heap card nil))}]))}]})) + :effect (req (continue-ability state side add-cards-from-heap card nil))}]))}]})) (defcard "Ritual" {:on-play {:async true @@ -3443,8 +3443,8 @@ :change-in-game-state {:req (req (seq runnable-servers))} :choices (req runnable-servers) :async true - :effect (effect (update! (assoc-in card [:special :run-amok] (get-rezzed-cids (all-installed state :corp)))) - (make-run eid target (get-card state card)))} + :effect (req (update! state side (assoc-in card [:special :run-amok] (get-rezzed-cids (all-installed state :corp)))) + (make-run state side eid target (get-card state card)))} :events [{:event :run-ends :req (req this-card-run) :async true @@ -3459,7 +3459,7 @@ :prompt "Choose an ice to trash" :choices {:card #(some (partial same-card? %) diff) :all true} - :effect (effect (trash eid target {:cause-card card}))}) + :effect (req (trash state side eid target {:cause-card card}))}) card nil)))}]})) (defcard "Running Hot" @@ -3467,8 +3467,8 @@ {:msg "gain [Click][Click][Click]" :additional-cost [(->c :brain 1)] :async true - :effect (effect (gain-clicks 3) - (effect-completed eid))}}) + :effect (req (gain-clicks state side 3) + (effect-completed state side eid))}}) (defcard "Running Interference" {:makes-run true @@ -3491,8 +3491,8 @@ :req (req (and (= 2 (count (run-events state side :encounter-ice))) (threat-level 4 state))) :async true - :effect (effect (continue-ability - {:optional {:prompt (msg "Spend [Click] to bypass " + :effect (req (continue-ability + state side {:optional {:prompt (msg "Spend [Click] to bypass " (card-str state current-ice) "?") :waiting-prompt true @@ -3543,7 +3543,7 @@ :msg (msg "trash " (:title trashed) " and install " (:title target) ", lowering the cost by " tcost " [Credits]") - :effect (effect (runner-install (assoc eid :source card :source-type :runner-install) + :effect (req (runner-install state side (assoc eid :source card :source-type :runner-install) target {:cost-bonus (- tcost)}))} card nil))))}}) @@ -3573,15 +3573,15 @@ (defcard "Scrubbed" {:events [{:event :encounter-ice :once :per-turn - :effect (effect + :effect (req (register-lingering-effect - card + state side card (let [target-ice (:ice context)] {:type :ice-strength :duration :end-of-run :req (req (same-card? target target-ice)) :value -2})) - (update-all-ice))}]}) + (update-all-ice state side))}]}) (defcard "Security Leak" {:static-abilities [{:type :card-ability-additional-cost @@ -3645,7 +3645,7 @@ :ability {:async true :msg "trash all cards in the server at no cost" - :effect (effect (trash-cards eid (:content run-server) {:cause-card card}))}})]}) + :effect (req (trash-cards state side eid (:content run-server) {:cause-card card}))}})]}) (defcard "Social Engineering" {:on-play @@ -3655,16 +3655,16 @@ (ice? %))} :change-in-game-state {:req (req (some (every-pred ice? (complement rezzed?)) (all-installed state :corp)))} :msg (msg "select " (card-str state target)) - :effect (effect + :effect (req (register-events - card + state side card (let [ice target] [{:event :rez :duration :end-of-turn :req (req (same-card? (:card context) ice)) :msg (msg "gain " (rez-cost state side (get-card state (:card context))) " [Credits]") :async true - :effect (effect (gain-credits :runner eid (rez-cost state side (get-card state (:card context)))))}])))}}) + :effect (req (gain-credits state :runner eid (rez-cost state side (get-card state (:card context)))))}])))}}) (defcard "Spark of Inspiration" (letfn [(shuffle-back [revealed-cards] @@ -3710,7 +3710,7 @@ (continue-ability state side (shuffle-back revealed-cards) card nil)))] {:on-play {:async true :change-in-game-state {:req (req (seq (:deck runner)))} - :effect (effect (spark-search-fn eid card (:deck runner) []))}})) + :effect (req (spark-search-fn state side eid card (:deck runner) []))}})) (defcard "Spear Phishing" {:makes-run true @@ -3777,20 +3777,20 @@ {:on-play {:async true :msg "draw 3 cards" :change-in-game-state {:req (req (seq (:deck runner)))} - :effect (effect (draw eid 3))} + :effect (req (draw state side eid 3))} :on-trash {:when-inactive true :interactive (req true) :async true :req (req (let [zone (first (:zone (:card context)))] (#{:hand :deck} zone))) - :effect (effect (continue-ability - {:optional {:prompt "Draw 2 cards?" + :effect (req (continue-ability + state side {:optional {:prompt "Draw 2 cards?" :waiting-prompt true :yes-ability {:msg "draw 2 cards" :async true - :effect (effect (draw :runner eid 2))} + :effect (req (draw state :runner eid 2))} :no-ability - {:effect (effect (system-msg (str "declines to use " (:title card))))}}} + {:effect (req (system-msg state side (str "declines to use " (:title card))))}}} card nil))}}) (defcard "Stimhack" @@ -3799,13 +3799,13 @@ :change-in-game-state {:req (req (seq runnable-servers))} :choices (req runnable-servers) :async true - :effect (effect (gain-next-run-credits 9) - (make-run eid target card))} + :effect (req (gain-next-run-credits state side 9) + (make-run state side eid target card))} :events [{:event :run-ends :req (req this-card-run) :msg "take 1 core damage" :async true - :effect (effect (damage eid :brain 1 {:unpreventable true + :effect (req (damage state side eid :brain 1 {:unpreventable true :card card}))}]}) (defcard "Strike Fund" @@ -3818,21 +3818,21 @@ :async true :req (req (let [zone (first (:zone (:card context)))] (#{:hand :deck} zone))) - :effect (effect (continue-ability - {:optional {:prompt "Gain 2 [Credits]?" + :effect (req (continue-ability + state side {:optional {:prompt "Gain 2 [Credits]?" :waiting-prompt true :yes-ability {:msg "gain 2 [Credits]" :async true - :effect (effect (gain-credits :runner eid 2))} + :effect (req (gain-credits state :runner eid 2))} :no-ability - {:effect (effect (system-msg (str "declines to use " (:title card))))}}} + {:effect (req (system-msg state side (str "declines to use " (:title card))))}}} card nil))}}) (defcard "Sure Gamble" {:on-play {:msg "gain 9 [Credits]" :async true - :effect (effect (gain-credits eid 9))}}) + :effect (req (gain-credits state side eid 9))}}) (defcard "Surge" (letfn [(placed-virus-cards [state] @@ -3846,7 +3846,7 @@ :choices {:req (req (some #(same-card? % target) (placed-virus-cards state)))} :msg (msg "place 2 virus counters on " (:title target)) :async true - :effect (effect (add-counter :runner eid target :virus 2 nil))}})) + :effect (req (add-counter state :runner eid target :virus 2 nil))}})) (defcard "SYN Attack" {:on-play @@ -3869,7 +3869,7 @@ :card #(and (in-hand? %) (corp? %))} :async true - :effect (effect (trash-cards :corp eid targets {:unpreventable true + :effect (req (trash-cards state :corp eid targets {:unpreventable true :cause-card card :cause :forced-to-trash}))} card nil)))}}) @@ -3879,11 +3879,11 @@ :req (req (not (first-event? state side :corp-draw))) :msg "force the Corp to lose 1 [Credits]" :async true - :effect (effect (lose-credits :corp eid 1))}]}) + :effect (req (lose-credits state :corp eid 1))}]}) (defcard "System Seizure" (let [ability {:req (req (get-in card [:special :ss-target])) - :effect (effect (update! (dissoc-in card [:special :ss-target])))}] + :effect (req (update! state side (dissoc-in card [:special :ss-target])))}] {:events [{:event :pump-breaker :req (req (or (not (get-in card [:special :ss-target])) (same-card? (:card context) (get-in card [:special :ss-target])))) @@ -3907,8 +3907,8 @@ :events [{:event :successful-run :silent (req true) :req (req (and (= :hq (target-server context)) this-card-run)) - :effect (effect (register-events - card [(breach-access-bonus :hq 2 {:duration :end-of-run})]))}]}) + :effect (req (register-events + state side card [(breach-access-bonus :hq 2 {:duration :end-of-run})]))}]}) (defcard "Take a Dive" {:on-play (run-server-from-choices-ability ["HQ" "R&D"] {:rfg-instead-of-trashing true}) @@ -3929,9 +3929,9 @@ :msg (msg "install a program from the " target) :waiting-prompt true :async true - :effect (effect + :effect (req (continue-ability - (let [where target + state side (let [where target where-key (if (= where "Heap") :discard :deck)] {:prompt "Choose a program to install" :choices (req (cancellable @@ -3953,7 +3953,7 @@ :duration :end-of-turn :req (req (get-in (find-latest state installed-card) [:special :test-run])) :msg (msg "move " (:title installed-card) " to the top of the stack") - :effect (effect (move (find-latest state installed-card) :deck {:front true}))}]) + :effect (req (move state side (find-latest state installed-card) :deck {:front true}))}]) (effect-completed state side eid)) (effect-completed state side eid))))}) card nil))}}) @@ -3965,8 +3965,8 @@ :silent true :req (req (and (= :rd (target-server context)) this-card-run)) - :effect (effect (register-events - card [(breach-access-bonus :rd 2 {:duration :end-of-run})]))}]}) + :effect (req (register-events + state side card [(breach-access-bonus :rd 2 {:duration :end-of-run})]))}]}) (defcard "The Noble Path" {:makes-run true @@ -4004,7 +4004,7 @@ :choices (req runnable-servers) :msg (msg "trash [their] grip and make a run on " target ", preventing all damage") - :effect (effect (make-run eid target card))} + :effect (req (make-run state side eid target card))} card nil)))}}) (defcard "The Price" @@ -4039,21 +4039,21 @@ :msg (msg "prevent the Corp from advancing cards during [their] next turn")} :events [{:event :corp-turn-begins :duration :until-runner-turn-begins - :effect (effect (register-turn-flag! - card :can-advance + :effect (req (register-turn-flag! + state side card :can-advance (constantly false)))}]}) (defcard "Three Steps Ahead" {:on-play - {:effect (effect (register-events - card + {:effect (req (register-events + state side card [{:event :runner-turn-ends :automatic :gain-credits :duration :end-of-turn :unregister-once-resolved true :msg (msg "gain " (* 2 (count (:successful-run runner-reg))) " [Credits]") :async true - :effect (effect (gain-credits eid (* 2 (count (:successful-run runner-reg)))))}]))}}) + :effect (req (gain-credits state side eid (* 2 (count (:successful-run runner-reg)))))}]))}}) (defcard "Tinkering" {:on-play @@ -4091,9 +4091,9 @@ :choices (req (filter hardware? (:deck runner))) :msg (msg "add " (:title target) " from the stack to the Grip and shuffle the stack") - :effect (effect (trigger-event :searched-stack) - (shuffle! :deck) - (move target :hand))} + :effect (req (trigger-event state side :searched-stack) + (shuffle! state side :deck) + (move state side target :hand))} card nil))))}})) (defcard "Traffic Jam" @@ -4144,10 +4144,10 @@ (= (get-in card [:special :run-eid :eid]) (get-in @state [:run :eid :eid])))) :msg "place 2 [Credits] on itself and access 1 additional card from R&D" :async true - :effect (effect + :effect (req (register-events - card [(breach-access-bonus :rd 1 {:duration :end-of-run})]) - (add-counter eid card :credit 2 {:placed true}))} + state side card [(breach-access-bonus :rd 1 {:duration :end-of-run})]) + (add-counter state side eid card :credit 2 {:placed true}))} {:event :run-ends :unregister-once-resolved true :req (req this-card-run) @@ -4159,7 +4159,7 @@ (map remote->name)))) :msg (msg "make a run on " target) :async true - :effect (effect (make-run eid target card))}]}) + :effect (req (make-run state side eid target card))}]}) (defcard "Uninstall" {:on-play @@ -4171,19 +4171,19 @@ (or (hardware? %) (program? %)))} :msg (msg "move " (:title target) " to [their] Grip") - :effect (effect (move target :hand))}}) + :effect (req (move state side target :hand))}}) (defcard "Unscheduled Maintenance" {:events [{:event :corp-install :req (req (ice? (:card context))) - :effect (effect (register-turn-flag! - card :can-install-ice + :effect (req (register-turn-flag! + state side card :can-install-ice (fn [state side card] (if (ice? card) ((constantly false) (toast state :corp "Cannot install ice the rest of this turn due to Unscheduled Maintenance")) true))))}] - :leave-play (effect (clear-turn-flag! card :can-install-ice))}) + :leave-play (req (clear-turn-flag! state side card :can-install-ice))}) (defcard "Vamp" {:makes-run true @@ -4233,7 +4233,7 @@ :duration :end-of-game :req (req (same-card? :title burned-card (:accessed-card context))) :msg (msg (str "remove " (:title burned-card) " from the game")) - :effect (effect (move :corp (:accessed-card context) :rfg))}])] + :effect (req (move state :corp (:accessed-card context) :rfg))}])] {:makes-run true :on-play run-remote-server-ability :events [{:event :pre-access-card @@ -4241,8 +4241,8 @@ (:successful run))) :once :per-run :msg (msg "remove " (:title (:accessed-card context)) " from the game, and watch for other copies of " (:title (:accessed-card context)) " to burn") - :effect (effect (move :corp (:accessed-card context) :rfg) - (register-events card (rfg-card-event (:accessed-card context))))}]})) + :effect (req (move state :corp (:accessed-card context) :rfg) + (register-events state side card (rfg-card-event (:accessed-card context))))}]})) (defcard "White Hat" {:on-play @@ -4299,7 +4299,7 @@ (program? target)) (runner-can-pay-and-install? state side (assoc eid :source card) target)))} :async true - :effect (effect (runner-install (assoc eid :source card :source-type :runner-install) target {:msg-keys {:install-source card + :effect (req (runner-install state side (assoc eid :source card :source-type :runner-install) target {:msg-keys {:install-source card :display-origin true}}))}] {:makes-run true :events [{:event :run diff --git a/src/clj/game/cards/hardware.clj b/src/clj/game/cards/hardware.clj index 0167dfe7e8..a13a84c585 100644 --- a/src/clj/game/cards/hardware.clj +++ b/src/clj/game/cards/hardware.clj @@ -61,7 +61,7 @@ [game.core.update :refer [update!]] [game.core.virus :refer [count-virus-programs]] [game.core.winning :refer [win]] - [game.macros :refer [continue-ability effect msg req wait-for]] + [game.macros :refer [continue-ability msg req wait-for]] [game.utils :refer :all] [jinteki.utils :refer :all] [game.core.set-aside :refer [set-aside get-set-aside]] @@ -90,7 +90,7 @@ (has-subtype? % "Icebreaker") (installed? %))} :msg (msg "host itself on " (card-str state target)) - :effect (effect (host (get-card state target) (get-card state card)))} + :effect (req (host state side (get-card state target) (get-card state card)))} :static-abilities [{:type :gain-subtype :req (req (same-card? target (:host card))) :value "AI"}] @@ -174,7 +174,7 @@ (first-trash? state event-targets?)))) :change-in-game-state {:silent true :req (req (seq (:deck runner)))} :msg "draw 1 card" - :effect (effect (draw :runner eid 1))}] + :effect (req (draw state :runner eid 1))}] {:static-abilities [(mu+ 1)] :events [(assoc ability :event :corp-trash) (assoc ability :event :runner-trash) @@ -198,7 +198,7 @@ :yes-ability {:prompt "Choose a card in Archives" :choices (req (:discard corp)) :msg (msg "remove " (:title target) " from the game") - :effect (effect (move :corp target :rfg))}}} card nil)))}]}) + :effect (req (move state :corp target :rfg))}}} card nil)))}]}) (defcard "Astrolabe" {:static-abilities [(mu+ 1)] @@ -219,15 +219,15 @@ (and (some #{:hand} (:previous-zone (:card context))) (program? (:card context))))))) :msg "gain [Click]" - :effect (effect (gain-clicks 1))} + :effect (req (gain-clicks state side 1))} {:event :unsuccessful-run :async true :msg "trash itself" - :effect (effect (trash eid card {:cause-card card}))}]}) + :effect (req (trash state side eid card {:cause-card card}))}]}) (defcard "Basilar Synthgland 2KVJ" {:on-install {:async true - :effect (effect (damage eid :brain 2 {:card card}))} + :effect (req (damage state side eid :brain 2 {:card card}))} :in-play [:click-per-turn 1]}) (defcard "Blackguard" @@ -251,7 +251,7 @@ " as an additional cost to rez " cname "?") :player :corp :yes-ability {:async true - :effect (effect (rez :corp eid c))} + :effect (req (rez state :corp eid c))} :no-ability {:msg (msg "declines to pay additional costs" " and is not forced to rez " cname)}}} card nil) @@ -325,7 +325,7 @@ :choices (req (cancellable (filter #(runner-can-pay-and-install? state side (assoc eid :source card) %) (:hosted card)))) :msg (msg "install " (:title target)) :async true - :effect (effect (runner-install (assoc eid :source card :source-type :runner-install) target))}]})) + :effect (req (runner-install state side (assoc eid :source card :source-type :runner-install) target))}]})) (defcard "BMI Buffer 2" (let [grip-program-trash? @@ -348,7 +348,7 @@ :choices (req (:hosted card)) :msg (msg "install " (:title target)) :async true - :effect (effect (runner-install (assoc eid :source card :source-type :runner-install) target {:ignore-all-cost true}))}]})) + :effect (req (runner-install state side (assoc eid :source card :source-type :runner-install) target {:ignore-all-cost true}))}]})) (defcard "Bookmark" {:abilities [{:action true @@ -385,7 +385,7 @@ :msg (msg "target " (card-str state target)) :choices {:card #(and (installed? %) (ice? %))} - :effect (effect (update! (assoc-in (get-card state card) [:special :boomerang-target] target)))} + :effect (req (update! state side (assoc-in (get-card state card) [:special :boomerang-target] target)))} :static-abilities [{:type :icon :req (req (same-card? target (get-in card [:special :boomerang-target]))) :while-disabled true @@ -413,10 +413,10 @@ :prompt (msg "Shuffle a copy of " (:title card) " back into the Stack?") :yes-ability {:msg (msg "shuffle a copy of " (:title card) " back into the Stack") - :effect (effect (move (some #(when (= (:title card) (:title %)) %) + :effect (req (move state side (some #(when (= (:title card) (:title %)) %) (:discard runner)) :deck) - (shuffle! :deck))}}}])))}}) + (shuffle! state side :deck))}}}])))}}) {:label "Break 0 subroutines" :cost [(->c :trash-can)] :msg "break 0 subroutines" @@ -440,10 +440,10 @@ :prompt (msg "Shuffle a copy of " (:title card) " back into the Stack?") :yes-ability {:msg (msg "shuffle a copy of " (:title card) " back into the Stack") - :effect (effect (move (some #(when (= (:title card) (:title %)) %) + :effect (req (move state side (some #(when (= (:title card) (:title %)) %) (:discard runner)) :deck) - (shuffle! :deck))}}}])))}]})) + (shuffle! state side :deck))}}}])))}]})) (defcard "Borrowed Goods" {:on-install {:change-in-game-state {:req (req (not tagged)) :silent true} @@ -460,7 +460,7 @@ (defcard "Brain Cage" {:static-abilities [(runner-hand-size+ 3)] :on-install {:async true - :effect (effect (damage eid :brain 1 {:card card}))}}) + :effect (req (damage state side eid :brain 1 {:card card}))}}) (defcard "Brain Chip" {:x-fn (req (max (get-in @state [:runner :agenda-point] 0) 0)) @@ -502,7 +502,7 @@ :choices {:card #(and (runner? %) (in-discard? %))} :msg (msg "add " (:title target) " to the top of the stack") - :effect (effect (move target :deck {:front true}))}]})) + :effect (req (move state side target :deck {:front true}))}]})) (defcard "Capstone" {:abilities [{:action true @@ -555,7 +555,7 @@ :msg (msg "trash " (:title target) " at no cost") :once :per-turn :async true - :effect (effect (trash eid (assoc target :seen true) {:accessed true + :effect (req (trash state side eid (assoc target :seen true) {:accessed true :cause-card card}))}}}) (defcard "Cataloguer" @@ -581,7 +581,7 @@ :msg "breach R&D" :keep-menu-open :while-power-tokens-left :async true - :effect (effect (breach-server eid [:rd] #_{:no-root true}))}] + :effect (req (breach-server state side eid [:rd] #_{:no-root true}))}] {:data {:counter {:power 2}} :abilities [access-ability] :events [(trash-on-empty :power) @@ -632,7 +632,7 @@ (runner-can-pay-and-install? state side (assoc eid :source card) target)))} :cost [(->c :trash-can)] :async true - :effect (effect (runner-install (assoc eid :source card :source-type :runner-install) target {:msg-keys {:install-source card + :effect (req (runner-install state side (assoc eid :source card :source-type :runner-install) target {:msg-keys {:install-source card :display-origin true :include-cost-from-eid eid}}))}]}) @@ -662,8 +662,8 @@ :msg (msg "increase the rez cost of " (card-str state target) " by 2 [Credits] until the end of the turn") :cost [(->c :trash-can)] - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card (let [ice target] {:type :rez-additional-cost :duration :end-of-turn @@ -677,7 +677,7 @@ (first-event? state side :subroutines-broken #(:all-subs-broken (first %))))) :msg "gain 1 [Credits] for breaking all subroutines on a piece of ice" :async true - :effect (effect (gain-credits eid 1))}]}) + :effect (req (gain-credits state side eid 1))}]}) (defcard "Cyberfeeder" {:recurring 1 @@ -714,7 +714,7 @@ :abilities [{:cost [(->c :credit 2)] :label "add 4 strength for the remainder of the run" :req (req run) - :effect (effect (pump (get-card state (:host card)) 4)) + :effect (req (pump state side (get-card state (:host card)) 4)) :msg (msg "pump the strength of " (get-in card [:host :title]) " by 4")}]}) (defcard "Deep Red" @@ -725,7 +725,7 @@ :prompt "Trigger the [Click] ability of the just-installed Caïssa program?" :yes-ability {:async true - :effect (effect (play-ability eid {:card (:card context) + :effect (req (play-ability state side eid {:card (:card context) :ability 0 :ignore-cost true}))}}}]}) @@ -741,7 +741,7 @@ (some #(corp? (:card %)) targets))))) :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits :runner eid 1))}]}) + :effect (req (gain-credits state :runner eid 1))}]}) (defcard "Desperado" {:static-abilities [(mu+ 1)] @@ -750,7 +750,7 @@ :silent true :async true :msg "gain 1 [Credits]" - :effect (effect (gain-credits eid 1))}]}) + :effect (req (gain-credits state side eid 1))}]}) (defcard "Detente" (let [return-cards @@ -802,14 +802,14 @@ :yes-ability {:msg (msg "give -6 strength to " (card-str state (:ice context)) " for the remainder of the run") :cost [(->c :remove-from-game)] - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card (let [ice (:ice context)] {:type :ice-strength :duration :end-of-run :req (req (same-card? target ice)) :value -6})) - (update-all-ice))}}}]}) + (update-all-ice state side))}}}]}) (defcard "Dinosaurus" {:static-abilities [{:type :can-host @@ -843,14 +843,14 @@ :choices (req runnable-servers) :msg (msg "make a run on " target) :makes-run true - :effect (effect (unregister-lingering-effects :end-of-run) - (unregister-floating-events :end-of-run) - (register-once {:once :per-turn} card) - (update-all-icebreakers) - (update-all-ice) - (reset-all-ice) - (clear-wait-prompt :corp) - (make-run eid target (get-card state card)))}}}]}) + :effect (req (unregister-lingering-effects state side :end-of-run) + (unregister-floating-events state side :end-of-run) + (register-once state side {:once :per-turn} card) + (update-all-icebreakers state side) + (update-all-ice state side) + (reset-all-ice state side) + (clear-wait-prompt state :corp) + (make-run state side eid target (get-card state card)))}}}]}) (defcard "Dorm Computer" {:data {:counter {:power 4}} @@ -905,15 +905,15 @@ {:abilities [{:req (req run) :msg "prevent the Corp from rezzing more than 1 piece of ice for the remainder of the run" :cost [(->c :trash-can)] - :effect (effect + :effect (req (register-events - card + state side card [{:event :rez :duration :end-of-run :unregister-once-resolved true :req (req (ice? (:card context))) - :effect (effect (register-run-flag! - card :can-rez + :effect (req (register-run-flag! + state side card :can-rez (fn [state _side card] (if (ice? card) ((constantly false) @@ -928,7 +928,7 @@ :req (req (first-event? state :runner :successful-run)) :msg "place 1 power counter on itself" :async true - :effect (effect (add-counter eid card :power 1))}] + :effect (req (add-counter state side eid card :power 1))}] :abilities [(break-sub [(->c :power 2)] 2 "All")]})) (defcard "Feedback Filter" @@ -1007,21 +1007,21 @@ :msg "jack out" :cost [(->c :trash-can)] :async true - :effect (effect (jack-out eid))} + :effect (req (jack-out state side eid))} {:label "Remove 1 tag" :change-in-game-state {:req (req (pos? (count-real-tags state)))} :req (req (= :runner (:active-player @state))) :msg "remove 1 tag" :cost [(->c :trash-can)] :async true - :effect (effect (lose-tags eid 1))}]}) + :effect (req (lose-tags state side eid 1))}]}) (defcard "Forger" (let [avoid-ab {:msg "avoid 1 tag" :label "Avoid 1 tag" :async true :cost [(->c :trash-can)] - :effect (effect (prevent-tag :runner eid 1))}] + :effect (req (prevent-tag state :runner eid 1))}] {:events [(choose-one-helper {:event :tag-interrupt :req (req (and (pos? (get-in @state [:prevent :tag :remaining])) @@ -1037,7 +1037,7 @@ :cost [(->c :trash-can)] :change-in-game-state {:req (req (pos? (count-real-tags state)))} :async true - :effect (effect (lose-tags eid 1))}]})) + :effect (req (lose-tags state side eid 1))}]})) (defcard "Friday Chip" (let [ability {:msg (msg "move 1 virus counter to " (:title target)) @@ -1061,19 +1061,19 @@ {:prompt (msg "Place a virus counter on " (:title card) "?") :autoresolve (get-autoresolve :auto-fire) :yes-ability {:async true - :effect (effect (system-msg - :runner + :effect (req (system-msg + state :runner (str "uses " (:title card) " to place 1 virus counter on itself")) - (add-counter :runner eid card :virus 1))}}} + (add-counter state :runner eid card :virus 1))}}} mult-ab {:prompt (msg "Place virus counters on " (:title card) "?") :choices {:number (req amt-trashed) :default (req amt-trashed)} :async true - :effect (effect (system-msg :runner + :effect (req (system-msg state :runner (str "uses " (:title card) " to place " (quantify target "virus counter") " on itself")) - (add-counter :runner eid card :virus target))} + (add-counter state :runner eid card :virus target))} ab (if (> amt-trashed 1) mult-ab sing-ab)] (continue-ability state side ab card targets)))}]})) @@ -1248,7 +1248,7 @@ (defcard "Ghosttongue" {:on-install {:async true - :effect (effect (damage eid :brain 1 {:card card}))} + :effect (req (damage state side eid :brain 1 {:card card}))} :static-abilities [{:type :play-cost :req (req (event? target)) :value -1}]}) @@ -1268,7 +1268,7 @@ :interactive (req true) :req (req (has-subtype? (:card context) "Virus")) :async true - :effect (effect (add-counter eid (:card context) :virus 1))}]}) + :effect (req (add-counter state side eid (:card context) :virus 1))}]}) (defcard "Heartbeat" {:static-abilities [(mu+ 1)] @@ -1294,7 +1294,7 @@ (corp? %)) :all true} :msg (msg "add " (card-str state target) " to HQ") - :effect (effect (move :corp target :hand))}] + :effect (req (move state :corp target :hand))}] {:static-abilities [(mu+ 1)] :events [(assoc ab :event :agenda-scored) (assoc ab :event :agenda-stolen)]})) @@ -1303,7 +1303,7 @@ {:events [{:event :server-created :msg "force the Corp to lose 1 [Credits]" :async true - :effect (effect (lose-credits :corp eid 1))} + :effect (req (lose-credits state :corp eid 1))} {:event :successful-run :skippable true :optional @@ -1329,12 +1329,12 @@ {:async true :cost [(->c :remove-from-game)] :msg (msg "trash " (card-str state (:ice context))) - :effect (effect (trash eid (:ice context) {:cause-card card}))}}}]}) + :effect (req (trash state side eid (:ice context) {:cause-card card}))}}}]}) (defcard "Hippocampic Mechanocytes" {:on-install {:async true :msg "suffer 1 meat damage" - :effect (effect (damage eid :meat 1 {:unboostable true :card card}))} + :effect (req (damage state side eid :meat 1 {:unboostable true :card card}))} :data {:counter {:power 2}} :static-abilities [(runner-hand-size+ (req (get-counters card :power)))]}) @@ -1388,14 +1388,14 @@ (no-event? state side :runner-install #(companion? (:card (first %)))))) :msg "gain 1 [Credit]" :async true - :effect (effect (gain-credits :runner eid 1))} + :effect (req (gain-credits state :runner eid 1))} {:event :runner-install :req (req (and (companion? (:card context)) (first-event? state side :runner-install #(companion? (:card (first %)))) (no-event? state side :spent-credits-from-card valid-ctx?))) :msg "gain 1 [Credit]" :async true - :effect (effect (gain-credits :runner eid 1))}]})) + :effect (req (gain-credits state :runner eid 1))}]})) (defcard "Knobkierie" {:static-abilities [(virus-mu+ 3)] @@ -1412,7 +1412,7 @@ (program? %))} :msg (msg "place 1 virus counter on " (:title target)) :async true - :effect (effect (add-counter eid target :virus 1))}}}] + :effect (req (add-counter state side eid target :virus 1))}}}] :abilities [(set-autoresolve :auto-fire "Knobkierie")]}) (defcard "Lemuria Codecracker" @@ -1422,7 +1422,7 @@ :req (req (some #{:hq} (:successful-run runner-reg))) :choices {:card installed?} :label "Expose a card" - :effect (effect (expose eid [target] {:card card}))}]}) + :effect (req (expose state side eid [target] {:card card}))}]}) (defcard "LilyPAD" {:events [{:event :runner-install @@ -1433,7 +1433,7 @@ (first-event? state :runner :runner-install #(program? (:card (first %)))))) :autoresolve (get-autoresolve :auto-fire) :yes-ability (draw-abi 1) - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card))))}}}] + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card))))}}}] :static-abilities [(mu+ 2)] :abilities [(set-autoresolve :auto-fire "LilyPAD")]}) @@ -1446,7 +1446,7 @@ {:events [{:event :runner-install :silent true :req (req (has-subtype? (:card context) "Icebreaker")) - :effect (effect (pump (:card context) 1 :end-of-turn))}]}) + :effect (req (pump state side (:card context) 1 :end-of-turn))}]}) (defcard "Lockpick" {:recurring 1 @@ -1466,9 +1466,9 @@ :yes-ability {:prompt "Choose a card" :msg "add 1 card from the stack to the grip" :choices (req (:deck runner)) - :effect (effect (trigger-event :searched-stack) - (shuffle! :deck) - (move target :hand))}}}]}) + :effect (req (trigger-event state side :searched-stack) + (shuffle! state side :deck) + (move state side target :hand))}}}]}) (defcard "Lucky Charm" {:prevention [{:prevents :end-run @@ -1540,7 +1540,7 @@ {:static-abilities [(mu+ 1) (runner-hand-size+ 3)] :on-install {:async true - :effect (effect (damage eid :brain 1 {:card card}))} + :effect (req (damage state side eid :brain 1 {:card card}))} :events [(assoc (sabotage-ability 1) :event :agenda-scored :interactive (req true))]}) @@ -1561,7 +1561,7 @@ :choices {:req (req (and (in-hand*? state target) (hardware? target) (runner-can-pay-and-install? state side (assoc eid :source card) target {:cost-bonus 1})))} - :effect (effect (runner-install (assoc eid :source card :source-type :runner-install) target {:cost-bonus 1 + :effect (req (runner-install state side (assoc eid :source card :source-type :runner-install) target {:cost-bonus 1 :msg-keys {:display-origin true :install-source card}}))}}} (draw-abi 1 nil {:event :runner-install @@ -1609,8 +1609,8 @@ :yes-ability {:msg "move the card just accessed to the bottom of R&D" :async true - :effect (effect (move :corp (:accessed-card context) :deck) - (gain-tags :runner eid 1))}}}]}) + :effect (req (move state :corp (:accessed-card context) :deck) + (gain-tags state :runner eid 1))}}}]}) (defcard "MemStrips" {:static-abilities [(virus-mu+ 3)]}) @@ -1638,7 +1638,7 @@ :silent true :req (req (= :rd (target-server context))) :async true - :effect (effect (add-counter eid card :power 1))}] + :effect (req (add-counter state side eid card :power 1))}] :abilities [{:action true :async true :cost [(->c :click 1) (->c :power 3)] @@ -1651,12 +1651,12 @@ :skippable true :async true :req (req (= :rd (target-server context))) - :effect (effect (continue-ability - {:prompt "Choose a card and replace 1 spent [Recurring Credits] on it" + :effect (req (continue-ability + state side {:prompt "Choose a card and replace 1 spent [Recurring Credits] on it" :choices {:card #(< (get-counters % :recurring) (:recurring (card-def %) 0))} :msg (msg "replace 1 spent [Recurring Credits] on " (:title target)) :async true - :effect (effect (add-counter eid target :recurring 1))} + :effect (req (add-counter state side eid target :recurring 1))} card nil))}]}) (defcard "Monolith" @@ -1673,7 +1673,7 @@ (continue-ability state side (when (< n 3) (mh (inc n))) card nil)))})] {:static-abilities [(mu+ 3)] :on-install {:async true - :effect (effect (continue-ability (mhelper 1) card nil))} + :effect (req (continue-ability state side (mhelper 1) card nil))} :prevention [{:prevents :damage :type :ability :ability {:async true @@ -1694,8 +1694,8 @@ :yes-ability {:cost [(->c :credit 1 {:stealth 1})] :msg "access 1 additional card from HQ" - :effect (effect (register-events - card [(breach-access-bonus :hq 1 {:duration :end-of-run})]))}}} + :effect (req (register-events + state side card [(breach-access-bonus :hq 1 {:duration :end-of-run})]))}}} {:event :successful-run :skippable true :optional @@ -1706,8 +1706,8 @@ :yes-ability {:cost [(->c :credit 2 {:stealth :all-stealth})] :msg "access 1 additional card from R&D" - :effect (effect (register-events - card [(breach-access-bonus :rd 1 {:duration :end-of-run})]))}}}]}) + :effect (req (register-events + state side card [(breach-access-bonus :rd 1 {:duration :end-of-run})]))}}}]}) (defcard "Muresh Bodysuit" {:prevention [{:prevents :damage @@ -1725,7 +1725,7 @@ (defcard "Net-Ready Eyes" {:on-install {:async true :msg "suffer 2 meat damage" - :effect (effect (damage eid :meat 2 {:unboostable true :card card}))} + :effect (req (damage state side eid :meat 2 {:unboostable true :card card}))} :events [{:event :run :req (req (some #(and (program? %) (has-subtype? % "Icebreaker")) @@ -1733,7 +1733,7 @@ :choices {:card #(and (installed? %) (has-subtype? % "Icebreaker"))} :msg (msg "give " (:title target) " +1 strength") - :effect (effect (pump target 1 :end-of-run))}]}) + :effect (req (pump state side target 1 :end-of-run))}]}) (defcard "NetChip" (letfn [(netchip-count @@ -1766,7 +1766,7 @@ (#{:rd :hq} (target-server (first %))))))) :msg (msg "draw " (quantify (total-cards-accessed target) "card")) :async true - :effect (effect (draw eid (total-cards-accessed target)))}]}) + :effect (req (draw state side eid (total-cards-accessed target)))}]}) (defcard "Omni-drive" {:recurring 1 @@ -1792,7 +1792,7 @@ (defcard "PAN-Weave" {:on-install {:async true :msg "suffer 1 meat damage" - :effect (effect (damage eid :meat 1 {:unboostable true :card card}))} + :effect (req (damage state side eid :meat 1 {:unboostable true :card card}))} :events [{:event :successful-run :automatic :drain-credits :req (req (and @@ -1817,8 +1817,8 @@ (in-hand*? state target) (not (event? target)) (runner-can-pay-and-install? state side eid target {:no-toast true})))} - :effect (effect (runner-install - (assoc eid :source card :source-type :runner-install) + :effect (req (runner-install + state side (assoc eid :source card :source-type :runner-install) target {:msg-keys {:install-source card :display-origin true}}))} gain-credit-ability @@ -1854,17 +1854,17 @@ {:prompt (msg "Add " (:title (first (:deck runner))) " to bottom of the stack?") :yes-ability {:msg "add the top card of the stack to the bottom" - :effect (effect (move :runner (first (:deck runner)) :deck))} + :effect (req (move state :runner (first (:deck runner)) :deck))} :no-ability - {:effect (effect (system-msg "does not add the top card of the the stack to the bottom"))}}} + {:effect (req (system-msg state side "does not add the top card of the the stack to the bottom"))}}} card nil)))} - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card))))}}}] + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card))))}}}] :abilities [(set-autoresolve :auto-fire "Paragon")]}) (defcard "Patchwork" (let [install-word (fn [c] (if (event? c) "play" "install")) patchwork-ability {:once :per-turn - :effect (effect (update! (assoc-in card [:special :patchwork] true)))} + :effect (req (update! state side (assoc-in card [:special :patchwork] true)))} patchwork-manual-prognosis {:cost [(->c :click 1)] :action true :once :per-turn @@ -1985,7 +1985,7 @@ :async true :effect (req (wait-for (draw state :runner 1) (draw state :corp eid 1)))} - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card))))}}}] + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card))))}}}] {:static-abilities [(mu+ 1) (link+ 1)] :events [{:event :pass-ice @@ -2043,7 +2043,7 @@ :prompt (msg "Install " (:title top-card) "?") :yes-ability {:async true - :effect (effect (runner-install (assoc eid :source-type :runner-install) top-card {:msg-keys {:display-origin true + :effect (req (runner-install state side (assoc eid :source-type :runner-install) top-card {:msg-keys {:display-origin true :origin-index 0 :install-source card}}))}}}) card nil)))}]}) @@ -2061,7 +2061,7 @@ :req (req (and (installed? (:card target)) (program? (:card target)))) :msg "trash itself" - :effect (effect (trash eid card {:cause-card card}))}] + :effect (req (trash state side eid card {:cause-card card}))}] [(assoc e :event :runner-trash) (assoc e :event :corp-trash)])}) @@ -2147,7 +2147,7 @@ :req (req (seq (filter faceup? (:discard corp)))) :choices (req (filter faceup? (:discard corp))) :msg (msg "add " (:title target) " to the top of R&D") - :effect (effect (move :corp target :deck {:front true}))}})]}) + :effect (req (move state :corp target :deck {:front true}))}})]}) (defcard "Reflection" {:static-abilities [(mu+ 1) @@ -2174,9 +2174,9 @@ :req (req (hardware-and-in-deck? (:card context) runner)) :yes-ability {:msg (msg "add a copy of " (:title (:card context)) " from the stack to the grip") - :effect (effect (trigger-event :searched-stack) - (shuffle! :deck) - (move (some #(when (= (:title %) (:title (:card context))) %) (:deck runner)) :hand))}}}]})) + :effect (req (trigger-event state side :searched-stack) + (shuffle! state side :deck) + (move state side (some #(when (= (:title %) (:title (:card context))) %) (:deck runner)) :hand))}}}]})) (defcard "Respirocytes" (let [ability {:once :per-turn @@ -2193,11 +2193,11 @@ (effect-completed state side eid)))))} event {:req (req (zero? (count (:hand runner)))) :async true - :effect (effect (continue-ability ability card targets))}] + :effect (req (continue-ability state side ability card targets))}] {:implementation "Only watches trashes, playing events, and installing. Doesn't know about your hand size pre-install." :on-install {:async true :msg "suffer 1 meat damage" - :effect (effect (damage eid :meat 1 {:unboostable true + :effect (req (damage state side eid :meat 1 {:unboostable true :card card}))} :events [(assoc event :event :play-event) (assoc event :event :runner-hand-changed?) @@ -2223,12 +2223,12 @@ :automatic :draw-cards :req (req (empty? (:hand runner))) :async true - :effect (effect (continue-ability ability card nil))} + :effect (req (continue-ability state side ability card nil))} {:event :corp-turn-begins :automatic :draw-cards :req (req (empty? (:hand runner))) :async true - :effect (effect (continue-ability ability card nil))}] + :effect (req (continue-ability state side ability card nil))}] :abilities [ability]})) (defcard "Rotary" @@ -2239,14 +2239,14 @@ :prompt "Tag 1 tag to see an additional card?" :yes-ability {:cost [(->c :gain-tag 1)] :msg (msg "access 1 additional card from " (zone->name (:server context))) - :effect (effect (access-bonus (:server context) 1))}}}] + :effect (req (access-bonus state side (:server context) 1))}}}] :corp-abilities [{:action true :label "Trash Rotary" :async true :cost [(->c :click 1) (->c :credit 2)] :req (req (and tagged (= :corp side))) - :effect (effect (system-msg :corp "spends [Click] and 2 [Credits] to trash Rotary") - (trash :corp eid card {:cause-card card}))}]}) + :effect (req (system-msg state :corp "spends [Click] and 2 [Credits] to trash Rotary") + (trash state :corp eid card {:cause-card card}))}]}) (defcard "Rubicon Switch" {:abilities [{:action true @@ -2277,7 +2277,7 @@ (not (has-subtype? % "Cloud")) (installed? %))} :cost [(->c :trash-can)] - :effect (effect (pump target (get-link state) :end-of-run))} + :effect (req (pump state side target (get-link state) :end-of-run))} {:label "Add [Link] strength to any Cloud icebreakers until the end of the run" :msg (msg "add " (get-link state) " strength to " (count targets) @@ -2336,7 +2336,7 @@ :waiting-prompt true :choices ["HQ" "R&D"] :async true - :effect (effect (continue-ability (implant-fn target (if (= target "HQ") :hq :rd)) card nil))}]})) + :effect (req (continue-ability state side (implant-fn target (if (= target "HQ") :hq :rd)) card nil))}]})) (defcard "Şifr" (letfn [(index-of [pred coll] @@ -2371,15 +2371,15 @@ :once :per-turn :yes-ability {:msg (msg "lower [their] maximum hand size by 1 and reduce the strength of " (:title current-ice) " to 0") - :effect (effect + :effect (req (register-lingering-effect - card + state side card {:type :hand-size :duration :until-runner-turn-begins :req (req (= :runner side)) :value -1}) (register-lingering-effect - :runner card + state :runner card (let [ice current-ice] {:type :ice-strength :duration :end-of-encounter @@ -2418,15 +2418,15 @@ (:discard runner)))} :cost [(->c :trash-can)] :effect - (effect + (req (continue-ability - {:show-discard true + state side {:show-discard true :waiting-prompt true :choices {:req (req (and (in-discard? target) (program? target) (runner-can-pay-and-install? state side (assoc eid :source card) target {:cost-bonus -3})))} :async true - :effect (effect (runner-install (assoc eid :source card :source-type :runner-install) target {:cost-bonus -3 + :effect (req (runner-install state side (assoc eid :source card :source-type :runner-install) target {:cost-bonus -3 :msg-keys {:display-origin true :install-source card :include-cost-from-eid eid}}))} @@ -2434,7 +2434,7 @@ (defcard "Skulljack" {:on-install {:async true - :effect (effect (damage eid :brain 1 {:card card}))} + :effect (req (damage state side eid :brain 1 {:card card}))} :static-abilities [{:type :trash-cost :value -1}]}) @@ -2470,7 +2470,7 @@ (fn [targets] (some #(corp? (:card %)) targets))))) :msg "place 1 power counter on itself" - :effect (effect (add-counter :runner eid card :power 1))}]}) + :effect (req (add-counter state :runner eid card :power 1))}]}) (defcard "Spinal Modem" {:static-abilities [(mu+ 1)] @@ -2479,7 +2479,7 @@ :req (req run) :msg "suffer 1 core damage" :async true - :effect (effect (damage eid :brain 1 {:card card}))}] + :effect (req (damage state side eid :brain 1 {:card card}))}] :interactions {:pay-credits {:req (req (and (= :ability (:source-type eid)) (has-subtype? target "Icebreaker"))) :type :recurring}}}) @@ -2509,8 +2509,8 @@ :msg "look at the top card of R&D" :cost [(->c :trash-can)] :async true - :effect (effect (continue-ability - {:prompt (req (->> corp :deck first :title (str "The top card of R&D is "))) + :effect (req (continue-ability + state side {:prompt (req (->> corp :deck first :title (str "The top card of R&D is "))) :choices ["OK"]} card nil))}]}) @@ -2527,8 +2527,8 @@ :autoresolve (get-autoresolve :auto-fire) :yes-ability {:msg "gain 2 [Credits]" :async true - :effect (effect (gain-credits eid 2))} - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card))))}}}] + :effect (req (gain-credits state side eid 2))} + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card))))}}}] :abilities [(set-autoresolve :auto-fire "Supercorridor")]}) (defcard "Swift" @@ -2537,7 +2537,7 @@ :req (req (and (has-subtype? (:card context) "Run") (first-event? state side :play-event #(has-subtype? (:card (first %)) "Run")))) :msg "gain a [click]" - :effect (effect (gain-clicks 1))}]}) + :effect (req (gain-clicks state side 1))}]}) (defcard "T400 Memory Diamond" {:static-abilities [(mu+ 1) @@ -2563,7 +2563,7 @@ (defcard "The Personal Touch" {:hosting {:card #(and (has-subtype? % "Icebreaker") (installed? %))} - :on-install {:effect (effect (update-breaker-strength (:host card)))} + :on-install {:effect (req (update-breaker-strength state side (:host card)))} :static-abilities [{:type :breaker-strength :req (req (same-card? target (:host card))) :value 1}]}) @@ -2632,8 +2632,8 @@ (continue-ability state side {:msg (msg "reveal " rev-str " from the top of the stack") - :effect (effect (shuffle! :deck) - (system-msg "shuffles the Stack"))} + :effect (req (shuffle! state side :deck) + (system-msg state side "shuffles the Stack"))} card nil) (install-choice state side eid card rev-str first-card nil))))] {:abilities [{:cost [(->c :trash-can)] @@ -2646,7 +2646,7 @@ (some #{:rd} (:successful-run runner-reg)) (some #{:archives} (:successful-run runner-reg)))) :async true - :effect (effect (wiz-search-fn eid card (:deck runner) target "" nil))}]})) + :effect (req (wiz-search-fn state side eid card (:deck runner) target "" nil))}]})) (defcard "Time Bomb" {:data {:counter {:power 1}} @@ -2665,8 +2665,8 @@ (defcard "Titanium Ribs" {:on-install {:async true :msg "suffer 2 meat damage" - :effect (effect (enable-runner-damage-choice) - (damage eid :meat 2 {:unboostable true :card card}))} + :effect (req (enable-runner-damage-choice state side) + (damage state side eid :meat 2 {:unboostable true :card card}))} :leave-play (req (swap! state update :damage dissoc :damage-choose-runner)) :events [{:event :pre-resolve-damage :async true @@ -2678,7 +2678,7 @@ (continue-ability state :runner (if (< (count hand) dmg) - {:effect (effect (chosen-damage :runner hand))} + {:effect (req (chosen-damage state :runner hand))} {:waiting-prompt true :prompt (msg "Choose " (quantify dmg "card") " to trash for the " (name dtype) " damage") :choices {:max dmg @@ -2686,7 +2686,7 @@ :card #(and (in-hand? %) (runner? %))} :msg (msg "trash " (enumerate-cards targets :sorted)) - :effect (effect (chosen-damage :runner targets))}) + :effect (req (chosen-damage state :runner targets))}) card nil)))}]}) (defcard "Top Hat" @@ -2722,16 +2722,16 @@ :interactive (req true) :req (req (seq (:scored corp))) :async true - :effect (effect + :effect (req (continue-ability - (let [stolen (:card context)] + state side (let [stolen (:card context)] {:optional {:prompt (msg "Swap " (:title stolen) " for an agenda in the Corp's score area?") :yes-ability {:prompt (str "Choose a scored Corp agenda to swap with " (:title stolen)) :choices {:card #(in-corp-scored? state side %)} :msg (msg "swap " (:title stolen) " for " (:title target)) - :effect (effect (swap-agendas target stolen))}}}) + :effect (req (swap-agendas state side target stolen))}}}) card targets))}]}) (defcard "Ubax" @@ -2741,7 +2741,7 @@ :label "Draw 1 card (start of turn)" :once :per-turn :async true - :effect (effect (draw eid 1))}] + :effect (req (draw state side eid 1))}] {:static-abilities [(mu+ 1)] :flags {:runner-turn-draw true :runner-phase-12 (req (< 1 (count (filter #(card-flag? % :runner-turn-draw true) @@ -2767,7 +2767,7 @@ (has-any-subtype? % ["Bioroid" "Clone" "Executive" "Sysop"]))} :async true :msg (msg "trash " (:title target)) - :effect (effect (trash eid target {:cause-card card}))}]}) + :effect (req (trash state side eid target {:cause-card card}))}]}) (defcard "Vigil" (let [ability {:req (req (and (:runner-phase-12 @state) @@ -2777,7 +2777,7 @@ :label "Draw 1 card (start of turn)" :once :per-turn :async true - :effect (effect (draw eid 1))}] + :effect (req (draw state side eid 1))}] {:static-abilities [(mu+ 1)] :events [(assoc ability :event :runner-turn-begins)] :abilities [ability]})) @@ -2812,7 +2812,7 @@ (defcard "WAKE Implant v2A-JRJ" {:on-install {:async true :msg "suffer 1 meat damage" - :effect (effect (damage eid :meat 1 {:unboostable true :card card}))} + :effect (req (damage state side eid :meat 1 {:unboostable true :card card}))} :events [{:event :successful-run :async true :req (req (= :hq (target-server context))) @@ -2841,7 +2841,7 @@ :change-in-game-state {:req (req (seq (:deck runner)))} :keep-menu-open :while-clicks-left :msg "draw 1 card from the bottom of the stack" - :effect (effect (move (last (:deck runner)) :hand))}]}) + :effect (req (move state side (last (:deck runner)) :hand))}]}) (defcard "Zamba" {:special {:auto-gain-credits :always} @@ -2858,11 +2858,11 @@ :autoresolve (get-autoresolve :auto-gain-credits) :yes-ability {:msg (msg "gain " (count (:cards context)) " [Credits]") :async true - :effect (effect (gain-credits eid (count (:cards context))))}}}]}) + :effect (req (gain-credits state side eid (count (:cards context))))}}}]}) (defcard "Zenit Chip JZ-2MJ" {:on-install {:async true - :effect (effect (damage eid :brain 1 {:card card}))} + :effect (req (damage state side eid :brain 1 {:card card}))} :events [{:event :successful-run :automatic :draw-cards :async true diff --git a/src/clj/game/cards/ice.clj b/src/clj/game/cards/ice.clj index 8783a192ac..b3378c15fe 100644 --- a/src/clj/game/cards/ice.clj +++ b/src/clj/game/cards/ice.clj @@ -63,7 +63,7 @@ [game.core.to-string :refer [card-str]] [game.core.toasts :refer [toast]] [game.core.update :refer [update!]] - [game.macros :refer [continue-ability effect msg req wait-for]] + [game.macros :refer [continue-ability msg req wait-for]] [game.utils :refer :all] [jinteki.utils :refer :all])) @@ -103,7 +103,7 @@ {:label "End the run" :msg "end the run" :async true - :effect (effect (end-run :corp eid card))}) + :effect (req (end-run state :corp eid card))}) (def end-the-run-if-tagged "ETR subroutine if tagged" @@ -111,12 +111,12 @@ :change-in-game-state {:req (req tagged) :silent true} :msg "end the run" :async true - :effect (effect (end-run :corp eid card))}) + :effect (req (end-run state :corp eid card))}) (def prevent-runs-this-turn {:label "The Runner cannot make another run this turn" :msg "prevent the Runner from making another run" - :effect (effect (register-turn-flag! card :can-run nil))}) + :effect (req (register-turn-flag! state side card :can-run nil))}) (defn- faceup-archives-types "helper for the faceup-archives-count cards" @@ -128,7 +128,7 @@ [qty] {:async true :label (str "You may draw " (quantify qty "card")) - :effect (effect (maybe-draw eid card qty))}) + :effect (req (maybe-draw state side eid card qty))}) (defn draw-up-to-sub "Ability to draw between 0 and n cards" @@ -136,7 +136,7 @@ ([qty args] {:async true :label (str "Draw up to " (quantify qty "card")) - :effect (effect (draw-up-to eid card qty args))})) + :effect (req (draw-up-to state side eid card qty args))})) (defn runner-pays "Ability to pay to avoid a subroutine by paying a resource" @@ -271,7 +271,7 @@ {:label (str "Gain " credits " [Credits]") :msg (str "gain " credits " [Credits]") :async true - :effect (effect (gain-credits eid credits))}) + :effect (req (gain-credits state side eid credits))}) (defn corps-gains-and-runner-loses-credits [gain loss] @@ -303,7 +303,7 @@ {:label "Force the Runner to lose [Click]" :change-in-game-state {:silent true :req (req (pos? (:click runner)))} :msg "force the Runner to lose [Click], if able" - :effect (effect (lose-clicks :runner 1))}) + :effect (req (lose-clicks state :runner 1))}) (defn runner-loses-credits "Runner loses credits effect" @@ -312,7 +312,7 @@ :msg (str "force the Runner to lose " credits " [Credits]") :change-in-game-state {:silent true :req (req (pos? (:credit runner)))} :async true - :effect (effect (lose-credits :runner eid credits))}) + :effect (req (lose-credits state :runner eid credits))}) (def add-runner-card-to-grip "Add 1 installed Runner card to the grip" @@ -323,8 +323,8 @@ :choices {:card #(and (installed? %) (runner? %))} :msg "add 1 installed card to the grip" - :effect (effect (move :runner target :hand true) - (system-msg (str "adds " (:title target) + :effect (req (move state :runner target :hand true) + (system-msg state side (str "adds " (:title target) " to the grip")))}) (def add-program-to-top-of-stack @@ -336,7 +336,7 @@ :req (req (some program? (all-installed state :runner)))} :label "Add installed program to the top of the stack" :msg (msg "add " (:title target) " to the top of the stack") - :effect (effect (move :runner target :deck {:front true}))}) + :effect (req (move state :runner target :deck {:front true}))}) (def trash-program-sub {:prompt "Choose a program to trash" @@ -347,7 +347,7 @@ :choices {:card #(and (installed? %) (program? %))} :async true - :effect (effect (trash eid target {:cause :subroutine}))}) + :effect (req (trash state side eid target {:cause :subroutine}))}) (def runner-trash-program-sub {:prompt "Choose a program to trash" @@ -360,7 +360,7 @@ :choices {:card #(and (installed? %) (program? %))} :async true - :effect (effect (trash eid target {:cause :subroutine}))}) + :effect (req (trash state side eid target {:cause :subroutine}))}) (def trash-hardware-sub @@ -372,7 +372,7 @@ :waiting-prompt true :change-in-game-state {:silent true :req (req (seq (filter hardware? (all-installed state :runner))))} :async true - :effect (effect (trash eid target {:cause :subroutine}))}) + :effect (req (trash state side eid target {:cause :subroutine}))}) (def trash-resource-sub {:prompt "Choose a resource to trash" @@ -383,7 +383,7 @@ :waiting-prompt true :change-in-game-state {:silent true :req (req (seq (filter resource? (all-installed state :runner))))} :async true - :effect (effect (trash eid target {:cause :subroutine}))}) + :effect (req (trash state side eid target {:cause :subroutine}))}) (def trash-installed-sub {:async true @@ -394,7 +394,7 @@ :change-in-game-state {:silent true :req (req (seq (all-installed state :runner)))} :choices {:card #(and (installed? %) (runner? %))} - :effect (effect (trash eid target {:cause :subroutine}))}) + :effect (req (trash state side eid target {:cause :subroutine}))}) (def runner-trash-installed-sub (assoc trash-installed-sub @@ -411,7 +411,7 @@ :choices {:card #(and (corp-installable-type? %) (in-hand? %))} :async true - :effect (effect (corp-install eid target nil (assoc args :msg-keys {:install-source card})))})) + :effect (req (corp-install state side eid target nil (assoc args :msg-keys {:install-source card})))})) (defn install-from-archives-sub ([] (install-from-archives-sub nil)) @@ -423,7 +423,7 @@ :choices {:card #(and (corp-installable-type? %) (in-discard? %))} :async true - :effect (effect (corp-install eid target nil (assoc args :msg-keys {:install-source card + :effect (req (corp-install state side eid target nil (assoc args :msg-keys {:install-source card :display-origin true})))})) (defn install-from-hq-or-archives-sub @@ -437,19 +437,19 @@ (or (in-hand? %) (in-discard? %)))} :async true - :effect (effect (corp-install eid target nil (assoc args :msg-keys {:install-source card + :effect (req (corp-install state side eid target nil (assoc args :msg-keys {:install-source card :display-origin true})))})) (def cannot-steal-or-trash-sub {:label "The Runner cannot steal or trash Corp cards for the remainder of this run" :msg "prevent the Runner from stealing or trashing Corp cards for the remainder of the run" - :effect (effect (register-run-flag! - card :can-steal + :effect (req (register-run-flag! + state side card :can-steal (fn [state _side _card] ((constantly false) (toast state :runner "Cannot steal due to subroutine." "warning")))) (register-run-flag! - card :can-trash + state side card :can-trash (fn [state _side card] ((constantly (not (corp? card))) (toast state :runner "Cannot trash due to subroutine." "warning")))))}) @@ -651,15 +651,15 @@ :change-in-game-state {:silent true :req (req (some #(pred card %) (all-installed state :corp)))} :effect - (effect + (req (continue-ability - {:async true + state side {:async true :prompt "Choose the ice" :choices {:req (req (pred card target)) :all true} - :effect (effect + :effect (req (continue-ability - (let [ice target] + state side (let [ice target] {:async true :prompt "Choose the subroutine" :choices (req (unbroken-subroutines-choice ice)) @@ -679,8 +679,8 @@ (def take-bad-pub ; Bad pub on rez effect {:async true - :effect (effect (system-msg (str "takes 1 bad publicity from " (:title card))) - (gain-bad-publicity :corp eid 1))}) + :effect (req (system-msg state side (str "takes 1 bad publicity from " (:title card))) + (gain-bad-publicity state :corp eid 1))}) ;; Card definitions @@ -705,7 +705,7 @@ :waiting-prompt true :choices (req (remove #(= this %) (installable-servers state nice))) :async true - :effect (effect (corp-install eid nice target {:msg-keys {:install-source card + :effect (req (corp-install state side eid nice target {:msg-keys {:install-source card :display-origin true}}))} card nil)))}}) @@ -718,8 +718,8 @@ :yes-ability {:msg "do 2 net damage" :cost [(->c :trash-from-hand 1)] :async true - :effect (effect (damage eid :net 2 {:card card}))} - :no-ability {:effect (effect (system-msg :corp (str "declines to use " (:title card))))}}} + :effect (req (damage state side eid :net 2 {:card card}))} + :no-ability {:effect (req (system-msg state :corp (str "declines to use " (:title card))))}}} :subroutines [(do-net-damage 1)]}) (defcard "Ansel 1.0" @@ -754,8 +754,8 @@ :yes-ability {:prompt "Select another installed card to trash" :cost [(->c :trash-other-installed 1)] :msg "prevent its printed subroutines being broken this encounter" - :effect (effect (register-lingering-effect - card {:type :cannot-break-subs-on-ice + :effect (req (register-lingering-effect + state side card {:type :cannot-break-subs-on-ice :req (req (same-card? card (:ice context))) :value true :duration :end-of-encounter}))}}})] @@ -776,7 +776,7 @@ {:subroutines [(do-psi {:label "Runner draws 2 cards" :msg "make the Runner draw 2 cards" :async true - :effect (effect (draw :runner eid 2))}) + :effect (req (draw state :runner eid 2))}) (do-net-damage 1) (do-net-damage 1)]}) @@ -858,7 +858,7 @@ :async true :msg "force the Runner to encounter it" :effect (req (force-ice-encounter state side eid card))} - :no-ability {:effect (effect (system-msg :corp (str "declines to use " (:title card))))}}} + :no-ability {:effect (req (system-msg state :corp (str "declines to use " (:title card))))}}} :subroutines [(trace-ability 6 add-runner-card-to-grip)]}) (defcard "Archer" @@ -882,12 +882,12 @@ :choices ["OK"] :req (req (not-empty (:deck corp))) :effect - (effect (continue-ability - {:prompt "Choose a card to install" + (req (continue-ability + state side {:prompt "Choose a card to install" :choices (cancellable (filter corp-installable-type? (take 5 (:deck corp)))) :async true :waiting-prompt true - :effect (effect (corp-install eid target nil {:ignore-all-cost true + :effect (req (corp-install state side eid target nil {:ignore-all-cost true :msg-keys {:install-source card :origin-index (first (positions #{target} (take 5 (:deck corp)))) :display-origin true}}))} @@ -966,7 +966,7 @@ {:on-break-subs {:msg (msg (let [n-subs (count (:broken-subs context))] (str "gain " n-subs " [Credits] from the runner breaking subs"))) :async true - :effect (effect (bailiff-gain-credits eid (count (:broken-subs context))))} + :effect (req (bailiff-gain-credits state side eid (count (:broken-subs context))))} :subroutines [end-the-run]})) (defcard "Ballista" @@ -984,7 +984,7 @@ :unregister-once-resolved true :async true :msg "make the Runner lose 1 tag" - :effect (effect (lose-tags :corp eid 1))}]) + :effect (req (lose-tags state :corp eid 1))}]) (effect-completed state side eid)))}]}) (defcard "Bastion" @@ -1048,7 +1048,7 @@ {:prompt (str "Choose a location to install " (:title target)) :choices (req (remove #(= this %) (installable-servers state nice))) :async true - :effect (effect (corp-install eid nice target {:ignore-all-cost true + :effect (req (corp-install state side eid nice target {:ignore-all-cost true :msg-keys {:install-source card :display-origin true}}))} card nil)))} @@ -1078,7 +1078,7 @@ :async true :req (req this-server run) :cost [(->c :trash-can)] - :effect (effect (end-run eid card))}] + :effect (req (end-run state side eid card))}] :subroutines [{:label "Gain 1 [Credits] for each ice protecting this server" :msg (msg "gain " (count (:ices (card->server state card))) @@ -1096,7 +1096,7 @@ :yes-ability {:cost [(->c :trash-from-hand 1)] :msg "end the run" :async true - :effect (effect (end-run eid card))}}}] + :effect (req (end-run state side eid card))}}}] {:static-abilities [(ice-strength-bonus (req (if (threat-level 4 state) 2 0)))] :subroutines [(do-net-damage 2) discard-card-to-end-the-run-sub @@ -1118,14 +1118,14 @@ :choices {:req (req (and (ice? target) (can-be-advanced? state target)))} :async true - :effect (effect (add-prop eid target :advance-counter 1 {:placed true}))}] + :effect (req (add-prop state side eid target :advance-counter 1 {:placed true}))}] {:abilities [{:action true :label "Move this ice to the outermost position of any server" :cost [(->c :click 1)] :prompt "Choose a server" :choices (req servers) :msg (msg "move itself to the outermost position of " target) - :effect (effect (move card (conj (server->zone state target) :ices)))}] + :effect (req (move state side card (conj (server->zone state target) :ices)))}] :subroutines [sub sub]})) @@ -1170,9 +1170,9 @@ :change-in-game-state {:silent true :req (req (installed? card))} :msg (msg "move itself to the outermost position of " target) :async true - :effect (effect (move card (conj (server->zone state target) :ices)) - (redirect-run target) - (effect-completed eid))})]}) + :effect (req (move state side card (conj (server->zone state target) :ices)) + (redirect-run state side target) + (effect-completed state side eid))})]}) (defcard "Bulwark" (let [sub {:msg "gain 2 [Credits] and end the run" @@ -1183,7 +1183,7 @@ :on-encounter {:req (req (some #(has-subtype? % "AI") (all-active-installed state :runner))) :msg "gain 2 [Credits] if there is an installed AI" :async true - :effect (effect (gain-credits eid 2))} + :effect (req (gain-credits state side eid 2))} :subroutines [runner-trash-program-sub sub sub]})) @@ -1201,7 +1201,7 @@ :async true :change-in-game-state {:silent true :req (req tagged)} :msg (msg "gain " (count-tags state) " [Credits]") - :effect (effect (gain-credits :corp eid (count-tags state)))} + :effect (req (gain-credits state :corp eid (count-tags state)))} end-the-run]}) (defcard "Cell Portal" @@ -1223,14 +1223,14 @@ {:on-rez take-bad-pub :subroutines [(trace-ability 5 {:label "Do 3 meat damage when this run is successful" :msg "do 3 meat damage when this run is successful" - :effect (effect (register-events - card + :effect (req (register-events + state side card [{:event :successful-run :automatic :corp-damage :duration :end-of-run :async true :msg "do 3 meat damage" - :effect (effect (damage eid :meat 3 {:card card}))}]))})]}) + :effect (req (damage state side eid :meat 3 {:card card}))}]))})]}) (defcard "Chetana" {:subroutines [{:msg "make each player gain 2 [Credits]" @@ -1240,13 +1240,13 @@ (do-psi {:label "Do 1 net damage for each card in the grip" :async true :msg (msg "do " (count (get-in @state [:runner :hand])) " net damage") - :effect (effect (damage eid :net (count (get-in @state [:runner :hand])) {:card card}))})]}) + :effect (req (damage state side eid :net (count (get-in @state [:runner :hand])) {:card card}))})]}) (defcard "Chimera" {:on-rez {:prompt "Choose one subtype" :choices ["Barrier" "Code Gate" "Sentry"] :msg (msg "make itself gain " target) - :effect (effect (update! (assoc card :subtype-target target)))} + :effect (req (update! state side (assoc card :subtype-target target)))} :static-abilities [{:type :gain-subtype :req (req (and (same-card? card target) (:subtype-target card))) :value (req (:subtype-target card))}] @@ -1271,7 +1271,7 @@ :req (req (and (same-card? card (:ice context)) (seq (filter #(has-subtype? % "AI") (all-active-installed state :runner))))) :async true - :effect (effect (chiyashi-auto-trash :corp eid (count (:broken-subs context))))}] + :effect (req (chiyashi-auto-trash state :corp eid (count (:broken-subs context))))}] :subroutines [(do-net-damage 2) (do-net-damage 2) end-the-run]})) @@ -1290,8 +1290,8 @@ :req (req this-server) :msg (msg "give +2 strength to the next piece of ice the Runner encounters") :effect - (effect (register-events - card + (req (register-events + state side card [{:event :encounter-ice :duration :end-of-run :unregister-once-resolved true @@ -1331,8 +1331,8 @@ :req (req (and (= :this-turn (:rezzed card)) (same-card? (:ice context) card))) :async true - :effect (effect (continue-ability - {:prompt "Choose one" + :effect (req (continue-ability + state side {:prompt "Choose one" :player :runner :choices (req ["Corp trashes 1 Runner card" (when-not (forced-to-avoid-tags? state side) "Take 2 tags") @@ -1349,7 +1349,7 @@ (= target "Take 2 tags") {:msg (msg "force the Runner to " (decapitalize target)) :async true - :effect (effect (gain-tags :runner eid 2 {:unpreventable true}))} + :effect (req (gain-tags state :runner eid 2 {:unpreventable true}))} (= target "Suffer 3 net damage") {:msg (msg "force the Runner to " (decapitalize target)) :async true @@ -1364,7 +1364,7 @@ (wall-ice [{:label "Give the Runner 1 tag (Give the Runner 2 tags)" :async true :msg (msg "give the Runner " (if (wonder-sub card 3) "2 tags" "1 tag")) - :effect (effect (gain-tags :corp eid (if (wonder-sub card 3) 2 1)))} + :effect (req (gain-tags state :corp eid (if (wonder-sub card 3) 2 1)))} {:label "Trash 1 program (Trash 1 program and 1 resource)" :async true :msg (msg "trash 1 program" (when (wonder-sub card 3) " and 1 resource")) @@ -1382,7 +1382,7 @@ :choices {:card #(and (installed? %) (resource? %))} :async true - :effect (effect (trash eid target {:cause :subroutine}))} + :effect (req (trash state side eid target {:cause :subroutine}))} card nil) (effect-completed state side eid))))}])) @@ -1391,7 +1391,7 @@ :req (req (same-card? (:ice context) card)) :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits :corp eid 1))}] + :effect (req (gain-credits state :corp eid 1))}] :subroutines [{:label "Gain 2 [Credits]. The Runner gains 1 [Credits]" :msg "gain 2 [Credits]. The Runner gains 1 [Credits]" :async true @@ -1412,7 +1412,7 @@ :change-in-game-state {:silent true :req (req (pos? (available-mu state)))} :async true - :effect (effect (damage eid :net (available-mu state) {:card card}))}]}) + :effect (req (damage state side eid :net (available-mu state) {:card card}))}]}) (defcard "Crick" {:subroutines [(install-from-archives-sub)] @@ -1429,11 +1429,11 @@ :events [{:event :trash :req (req (and (not (same-card? card target)) (= (card->server state card) (card->server state target)))) - :effect (effect (update-ice-strength card))} + :effect (req (update-ice-strength state side card))} {:event :corp-install :req (req (and (not (same-card? card (:card context))) (= (card->server state card) (card->server state (:card context))))) - :effect (effect (update-ice-strength card))}]}) + :effect (req (update-ice-strength state side card))}]}) (defcard "Data Hound" (letfn [(dh-trash [cards] @@ -1472,9 +1472,9 @@ (defcard "Data Loop" {:on-encounter {:req (req (pos? (count (:hand runner)))) :async true - :effect (effect + :effect (req (continue-ability - :runner + state :runner (let [n (min 2 (count (:hand runner)))] {:prompt (str "Choose " (quantify n "card") " in the grip to add to the top of the stack (second card targeted will be topmost)") :choices {:max n @@ -1596,7 +1596,7 @@ :req (req (and (has-subtype? (:card context) "Harmonic") (ice? (:card context)))) :async true - :effect (effect (add-counter eid card :power 1 nil))}] + :effect (req (add-counter state side eid card :power 1 nil))}] :static-abilities [{:type :additional-subroutines :req (req (same-card? card target)) :value (req {:subroutines (vec (repeat (get-counters card :power) end-the-run))})}]}) @@ -1627,8 +1627,8 @@ :choices {:card #(and (in-hand? %) (corp? %))} :async true - :effect (effect (move target :deck {:front true}) - (effect-completed eid))} + :effect (req (move state side target :deck {:front true}) + (effect-completed state side eid))} card nil)))} {:label "Do 1 net damage and give the Runner 1 tag" :msg "do 1 net damage and give the Runner 1 tag" @@ -1687,7 +1687,7 @@ (installed? %))} :msg (msg "trash " (:title target)) :async true - :effect (effect (trash eid target {:cause :subroutine}))} + :effect (req (trash state side eid target {:cause :subroutine}))} {:msg "trash all virtual resources" :change-in-game-state {:silent true :req (req (some #(and (has-subtype? % "Virtual") (resource? %)) (all-installed state :runner)))} @@ -1702,7 +1702,7 @@ :change-in-game-state {:silent true :req (req (:hand runner))} :msg (msg "reveal " (enumerate-cards (:hand runner) :sorted) " from the grip") - :effect (effect (reveal eid (:hand runner)))}] + :effect (req (reveal state side eid (:hand runner)))}] {:on-encounter {:prompt "Choose a card type" :choices ["Event" "Hardware" "Program" "Resource"] :msg (msg "name " target) @@ -1741,15 +1741,15 @@ (defcard "Envelopment" {:on-rez {:async true - :effect (effect (add-counter eid card :power 4 nil))} + :effect (req (add-counter state side eid card :power 4 nil))} :events [{:event :corp-turn-begins :req (req (pos? (get-counters card :power))) :async true - :effect (effect (add-counter eid card :power -1 nil))}] + :effect (req (add-counter state side eid card :power -1 nil))}] :subroutines [{:label "Trash this ice" :async true :msg (msg "trash " (:title card)) - :effect (effect (trash eid card {:cause :subroutine}))}] + :effect (req (trash state side eid card {:cause :subroutine}))}] :static-abilities [{:type :additional-subroutines :req (req (same-card? card target)) :value (req {:position :front @@ -1807,13 +1807,13 @@ :effect (req (when-not (= target "Done") (move state side (first (:deck corp)) :deck)))} {:label "Each piece of ice gets +1 strength for the remainder of this run." :msg "give +1 strength to all ice for the remainder of the run" - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card (let [c-ice card] {:type :ice-strength :duration :end-of-run :value 1})) - (update-all-ice))}] + (update-all-ice state side))}] :abilities [{:cost [(->c :click 1)] :action true :label "Swap this ice with another installed ice." @@ -2070,7 +2070,7 @@ n-subs " [Credits] for breaking printed subs"))) :async true - :effect (effect (gf-lose-credits eid (count (filter :printed (:broken-subs context)))))} + :effect (req (gf-lose-credits state side eid (count (filter :printed (:broken-subs context)))))} :subroutines [(end-the-run-unless-runner-pays (->c :credit 3)) (end-the-run-unless-runner-pays (->c :credit 3))]})) @@ -2100,8 +2100,8 @@ {:subroutines [{:req (req run) :label "Reduce Runner's hand size by 2" :msg "reduce the Runner's maximum hand size by 2 until the start of the next Corp turn" - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card {:type :hand-size :duration :until-corp-turn-begins :req (req (= :runner side)) @@ -2131,8 +2131,8 @@ {:cost [(->c :trash-from-hand 1)] :async true :effect - (effect (continue-ability - {:waiting-prompt true + (req (continue-ability + state side {:waiting-prompt true :prompt "Choose an installed Runner card" :async true :choices {:card #(and (installed? %) @@ -2150,7 +2150,7 @@ (register-lingering-effect state side card (prevent-sub-break-by t)) (effect-completed state side eid)))} card nil))} - :no-ability {:effect (effect (system-msg :corp (str "declines to use " (:title card))))}}}})) + :no-ability {:effect (req (system-msg state :corp (str "declines to use " (:title card))))}}}})) (defcard "Hákarl 1.0" {:runner-abilities [(bioroid-break 1 1)] @@ -2187,8 +2187,8 @@ (program? %) (not (has-any-subtype? % ["Decoder" "Fracter" "Killer"])))} :async true - :effect (effect (clear-wait-prompt :runner) - (trash eid target {:cause :subroutine}))} + :effect (req (clear-wait-prompt state :runner) + (trash state side eid target {:cause :subroutine}))} end-the-run] :static-abilities [(ice-strength-bonus (req (- (count (filter #(has-subtype? % "Icebreaker") (all-active-installed state :runner))))))]}) @@ -2201,7 +2201,7 @@ :prompt "Choose a card in the Heap" :choices (req (cancellable (:discard runner) :sorted)) :msg (msg "remove " (:title target) " from the game") - :effect (effect (move :runner target :rfg))} + :effect (req (move state :runner target :rfg))} end-the-run]}) (defcard "Hammer" @@ -2222,7 +2222,7 @@ (resource? target))))} :async true :breakable breakable-fn - :effect (effect (trash eid target {:cause :subroutine}))} + :effect (req (trash state side eid target {:cause :subroutine}))} {:label "Choose a program to trash that is not a decoder, fracter or killer" :change-in-game-state {:silent true :req (req (some #(and (program? %) (not (has-any-subtype? % ["Decoder" "Fracter" "Killer"]))) (all-installed state :runner)))} @@ -2233,7 +2233,7 @@ (program? %) (not (has-any-subtype? % ["Decoder" "Fracter" "Killer"])))} :async true - :effect (effect (trash eid target {:cause :subroutine}))}]})) + :effect (req (trash state side eid target {:cause :subroutine}))}]})) (defcard "Descent" (let [shuffle-ab @@ -2328,7 +2328,7 @@ " on " (card-str state target)) :choices {:req (req (can-be-advanced? state target))} :async true - :effect (effect (add-prop eid target :advance-counter c {:placed true}))} + :effect (req (add-prop state side eid target :advance-counter c {:placed true}))} card nil))) (effect-completed state side eid))))}] :on-access {:async true @@ -2339,7 +2339,7 @@ (defcard "Himitsu-Bako" {:abilities [{:msg "add itself to HQ" :cost [(->c :credit 1)] - :effect (effect (move card :hand))}] + :effect (req (move state side card :hand))}] :subroutines [end-the-run]}) (defcard "Hive" @@ -2355,7 +2355,7 @@ (defcard "Holmegaard" {:subroutines [(trace-ability 4 {:label "Runner cannot access any cards this run" :msg "stop the Runner from accessing any cards this run" - :effect (effect (prevent-access))}) + :effect (req (prevent-access state side))}) {:label "Trash an icebreaker" :prompt "Choose an icebreaker to trash" :msg (msg "trash " (:title target)) @@ -2364,8 +2364,8 @@ :choices {:card #(and (installed? %) (has-subtype? % "Icebreaker"))} :async true - :effect (effect (clear-wait-prompt :runner) - (trash eid target {:cause :subroutine}))}]}) + :effect (req (clear-wait-prompt state :runner) + (trash state side eid target {:cause :subroutine}))}]}) (defcard "Hortum" (letfn [(hort [n] {:prompt "Choose a card to add to HQ" @@ -2389,7 +2389,7 @@ :breakable breakable-fn :msg (msg "gain " (if (wonder-sub card 3) "4" "1") " [Credits]") :async true - :effect (effect (gain-credits :corp eid (if (wonder-sub card 3) 4 1)))} + :effect (req (gain-credits state :corp eid (if (wonder-sub card 3) 4 1)))} {:label "End the run (Search R&D for up to 2 cards and add them to HQ, shuffle R&D, end the run)" :async true :breakable breakable-fn @@ -2460,13 +2460,13 @@ (gain-tags state :runner eid 1)))})] {:subroutines [(otherwise-tag "do 3 net damage" - (effect (damage :runner eid :net 3 {:card card}))) + (req (damage state :runner eid :net 3 {:card card}))) (otherwise-tag "gain 5 [Credits]" - (effect (gain-credits :corp eid 5))) + (req (gain-credits state :corp eid 5))) (otherwise-tag "end the run" - (effect (end-run eid card)))]})) + (req (end-run state side eid card)))]})) (defcard "Ice Wall" (wall-ice [end-the-run])) @@ -2496,14 +2496,14 @@ [{:msg "prevent the Runner from breaking subroutines on the next piece of ice they encounter this run" :change-in-game-state {:silent true :req (req run)} :effect - (effect (register-events - card + (req (register-events + state side card [{:event :encounter-ice :duration :end-of-run :unregister-once-resolved true :msg (msg "prevent the runner from breaking subroutines on " (:title (:ice context))) - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card (let [encountered-ice (:ice context)] {:type :cannot-break-subs-on-ice :duration :end-of-encounter @@ -2533,8 +2533,8 @@ (defcard "Interrupt 0" (let [sub {:label "Make the Runner pay 1 [Credits] to use icebreaker" :msg "make the Runner pay 1 [Credits] to use icebreakers to break subroutines during this run" - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card {:type :break-sub-additional-cost :duration :end-of-run :req (req (and ; The card is an icebreaker @@ -2567,7 +2567,7 @@ (defcard "It's a Trap!" {:on-expose {:msg "do 2 net damage" :async true - :effect (effect (damage eid :net 2 {:card card}))} + :effect (req (damage state side eid :net 2 {:card card}))} :subroutines [(assoc runner-trash-installed-sub :effect (req (wait-for (trash state side target {:cause :subroutine}) (system-msg state :corp (str "uses " (:title card) " to trash itself")) @@ -2617,7 +2617,7 @@ (defcard "Jua" {:on-encounter {:msg "prevent the Runner from installing cards for the rest of the turn" - :effect (effect (register-turn-flag! card :runner-lock-install (constantly true)))} + :effect (req (register-turn-flag! state side card :runner-lock-install (constantly true)))} :subroutines [{:label "Choose 2 installed Runner cards, if able. The Runner must add 1 of those to the top of the Stack" :change-in-game-state {:silent true :req (req (>= (count (all-installed state :runner)) 2))} :async true @@ -2629,8 +2629,8 @@ :msg (msg "add either " (card-str state (first targets)) " or " (card-str state (second targets)) " to the top of the Stack") - :effect (effect (continue-ability - (when (= 2 (count targets)) + :effect (req (continue-ability + state side (when (= 2 (count targets)) {:player :runner :waiting-prompt true :prompt "Choose a card to move to the top of the Stack" @@ -2644,7 +2644,7 @@ :async true :req (req (same-card? (:ice context) card)) :msg "do 1 net damage" - :effect (effect (damage eid :net 1 {:card card}))}] + :effect (req (damage state side eid :net 1 {:card card}))}] :subroutines [end-the-run]}) (defcard "Kamali 1.0" @@ -2735,8 +2735,8 @@ :req (req (and run this-server (seq (all-installed-runner-type state :resource)))) :yes-ability {:async true - :effect (effect (continue-ability on-rez-ability card nil))} - :no-ability {:effect (effect (system-msg :corp (str "declines to use " (:title card))))}}}})) + :effect (req (continue-ability state side on-rez-ability card nil))} + :no-ability {:effect (req (system-msg state :corp (str "declines to use " (:title card))))}}}})) (defcard "Knowledge Seeker" {:events [{:event :end-of-encounter @@ -2806,7 +2806,7 @@ :else target-zone)] (= target-zone (second (get-zone card))))) :msg (msg "trash itself") - :effect (effect (trash :corp eid card {:cause-card card :cause :effect}))}] + :effect (req (trash state :corp eid card {:cause-card card :cause :effect}))}] {:subroutines [(tag-or-pay-credits 3) end-the-run-if-tagged] :events [(assoc trash-self :event :agenda-scored) @@ -2865,19 +2865,19 @@ end-the-run {:msg "make the Runner gain 5 [Credits]" :async true - :effect (effect (gain-credits :runner eid 5))}]}) + :effect (req (gain-credits state :runner eid 5))}]}) (defcard "Lockdown" {:subroutines [{:label "The Runner cannot draw cards for the remainder of this turn" :msg "prevent the Runner from drawing cards" - :effect (effect (prevent-draw))}]}) + :effect (req (prevent-draw state side))}]}) (defcard "Logjam" {:advanceable :always :static-abilities [(ice-strength-bonus (req (get-counters card :advancement)))] :on-rez {:msg (msg "place " (quantify (inc (faceup-archives-types corp)) "advancement counter") " on itself") :async true - :effect (effect (add-prop eid card + :effect (req (add-prop state side eid card :advance-counter (inc (faceup-archives-types corp)) {:placed true}))} @@ -2991,7 +2991,7 @@ card nil))))})] {:on-rez {:async true :waiting-prompt true - :effect (effect (continue-ability (ice-subtype-choice ["Barrier" "Code Gate" "Sentry"]) card nil))} + :effect (req (continue-ability state side (ice-subtype-choice ["Barrier" "Code Gate" "Sentry"]) card nil))} :derez-effect {:effect (req (unregister-effects-for-card state side card #(= :gain-subtype (:type %))))} :static-abilities [{:type :gain-subtype :req (req (and (same-card? card target) (:subtype-target card))) @@ -2999,11 +2999,11 @@ :events [{:event :runner-turn-ends :req (req (rezzed? card)) :async true - :effect (effect (derez :corp eid card))} + :effect (req (derez state :corp eid card))} {:event :corp-turn-ends :req (req (rezzed? card)) :async true - :effect (effect (derez :corp eid card))}] + :effect (req (derez state :corp eid card))}] :subroutines [{:label "(Code Gate) Force the Runner to lose [Click] and 1 [Credit]" :msg "force the Runner to lose [Click] and 1 [Credit]" :change-in-game-state {:silent true @@ -3024,7 +3024,7 @@ :choices {:card #(and (installed? %) (program? %))} :async true - :effect (effect (trash eid target {:cause :subroutine}))} + :effect (req (trash state side eid target {:cause :subroutine}))} {:label "(Barrier) Gain 1 [Credit] and end the run" :msg "gain 1 [Credit] and end the run" :change-in-game-state {:silent true :req (req (has-subtype? card "Barrier"))} @@ -3081,21 +3081,21 @@ {:subroutines [(trace-ability 4 {:label "Purge virus counters" :msg "purge virus counters" :async true - :effect (effect (purge eid))}) + :effect (req (purge state side eid))}) (trace-ability 3 {:label "Trash a virus" :prompt "Choose a virus to trash" :choices {:card #(and (installed? %) (has-subtype? % "Virus"))} :msg (msg "trash " (:title target)) :async true - :effect (effect (clear-wait-prompt :runner) - (trash eid target {:cause :subroutine}))}) + :effect (req (clear-wait-prompt state :runner) + (trash state side eid target {:cause :subroutine}))}) (trace-ability 2 {:label "Remove a virus in the Heap from the game" :req (req (not (zone-locked? state :runner :discard))) :prompt "Choose a virus in the Heap to remove from the game" :choices (req (cancellable (filter #(has-subtype? % "Virus") (:discard runner)) :sorted)) :msg (msg "remove " (:title target) " from the game") - :effect (effect (move :runner target :rfg))}) + :effect (req (move state :runner target :rfg))}) (trace-ability 1 end-the-run)]}) (defcard "Magnet" @@ -3127,9 +3127,9 @@ (defcard "Marker" {:subroutines [{:label "Give next encountered ice \"End the run\"" :msg "give next encountered ice \"[Subroutine] End the run\" after all its other subroutines for the remainder of the run" - :effect (effect + :effect (req (register-events - card + state side card [{:event :encounter-ice :duration :end-of-run :unregister-once-resolved true @@ -3155,7 +3155,7 @@ (defcard "Masvingo" (assoc (hero-to-hero end-the-run) :on-rez {:async true - :effect (effect (add-prop eid card :advance-counter 1 {:placed true}))})) + :effect (req (add-prop state side eid card :advance-counter 1 {:placed true}))})) (defcard "Matrix Analyzer" {:on-encounter (assoc (place-advancement-counter true) :cost [(->c :credit 1)]) @@ -3166,11 +3166,11 @@ :subroutines [{:label "Gain 1 [Credits] (Gain 3 [Credits])" :msg (msg "gain " (if (wonder-sub card 3) 3 1) " [Credits]") :async true - :effect (effect (gain-credits eid (if (wonder-sub card 3) 3 1)))} + :effect (req (gain-credits state side eid (if (wonder-sub card 3) 3 1)))} {:label "Do 1 net damage (Do 3 net damage)" :async true :msg (msg "do " (if (wonder-sub card 3) 3 1) " net damage") - :effect (effect (damage eid :net (if (wonder-sub card 3) 3 1) {:card card}))} + :effect (req (damage state side eid :net (if (wonder-sub card 3) 3 1) {:card card}))} {:label "Give the Runner 1 tag (and end the run)" :async true :msg (msg "give the Runner 1 tag" @@ -3217,9 +3217,9 @@ "Swap 2 pieces of ice") (when (<= 2 (count (remove ice? (all-installed state :corp)))) "Swap 2 non-ice")]) - :effect (effect + :effect (req (continue-ability - (if (= target "Swap 2 pieces of ice") + state side (if (= target "Swap 2 pieces of ice") {:prompt "Choose 2 pieces of ice to swap" :choices {:card #(and (installed? %) (ice? %)) @@ -3248,7 +3248,7 @@ :msg (msg "spend 1 hosted advancement counter from " (:title card) " to force the Runner to lose 3 [Credits]") :effect (req (wait-for (add-prop state :corp card :advance-counter -1 {:placed true}) (lose-credits state :runner eid 3)))} - :no-ability {:effect (effect (system-msg :corp (str "declines to use " (:title card))))}}} + :no-ability {:effect (req (system-msg state :corp (str "declines to use " (:title card))))}}} :subroutines [(runner-loses-credits 3) end-the-run]}) @@ -3297,7 +3297,7 @@ :prompt "Choose a piece of ice to install from HQ" :change-in-game-state {:req (req (seq (:hand corp))) :silent true} :label "install ice from HQ, ignoring all costs" - :effect (effect (corp-install eid target (zone->name (target-server run)) {:ignore-all-cost true + :effect (req (corp-install state side eid target (zone->name (target-server run)) {:ignore-all-cost true :msg-keys {:install-source card :display-origin true}}))}]}) @@ -3324,7 +3324,7 @@ {:prompt "Draw 1 card?" :yes-ability {:async true :msg "draw 1 card" - :effect (effect (draw eid 1))}}} + :effect (req (draw state side eid 1))}}} card nil) (continue-ability state side @@ -3332,8 +3332,8 @@ :choices {:card #(and (in-hand? %) (corp? %))} :msg "shuffle 1 card in HQ into R&D" - :effect (effect (move target :deck) - (shuffle! :deck))} + :effect (req (move state side target :deck) + (shuffle! state side :deck))} card nil)))}]}) (defcard "Mlinzi" @@ -3360,9 +3360,9 @@ (defcard "Mother Goddess" (let [context-mg {:req (req (ice? (:card context))) - :effect (effect (update-all-subtypes))} + :effect (req (update-all-subtypes state side))} mg {:req (req (ice? target)) - :effect (effect (update-all-subtypes))}] + :effect (req (update-all-subtypes state side))}] {:static-abilities [{:type :gain-subtype :req (req (same-card? card target)) :value (req (->> (vals (:servers corp)) @@ -3391,7 +3391,7 @@ :waiting-prompt true :async true :msg (msg (corp-install-msg target)) - :effect (effect (corp-install eid target nil {:ignore-install-cost true}))} + :effect (req (corp-install state side eid target nil {:ignore-install-cost true}))} (rez-an-ice {:cost-bonus -2}) (resolve-another-subroutine #(has-subtype? % "Sentry") @@ -3463,7 +3463,7 @@ :choices {:card #(and (installed? %) (runner? %))} :async true - :effect (effect (trash eid target {:cause :subroutine}))}]}) + :effect (req (trash state side eid target {:cause :subroutine}))}]}) (defcard "NEXT Gold" (letfn [(trash-programs [cnt state side card eid] @@ -3475,7 +3475,7 @@ :subroutines [{:label "Do X net damage" :msg (msg "do " ((get-x-fn) state side eid card targets) " net damage") :async true - :effect (effect (damage eid :net ((get-x-fn) state side eid card targets) {:card card}))} + :effect (req (damage state side eid :net ((get-x-fn) state side eid card targets) {:card card}))} {:label "Trash X programs" :async true :effect (req (trash-programs (min (count (filter program? (all-active-installed state :runner))) @@ -3494,7 +3494,7 @@ :choices {:number (get-x-fn) :default (req 1)} :async true - :effect (effect (draw eid target))} + :effect (req (draw state side eid target))} {:label "Add up to X cards from Archives to HQ" :prompt "Choose cards to add to HQ" :show-discard true @@ -3552,7 +3552,7 @@ :async true :choices {:card ice? :not-self true} - :effect (effect (add-prop eid target :advance-counter counters {:placed true}))}}}) + :effect (req (add-prop state side eid target :advance-counter counters {:placed true}))}}}) (get-card state card) nil)))} :x-fn (req (get-counters card :advancement)) :subroutines [end-the-run @@ -3609,7 +3609,7 @@ :req (req (and (same-card? card (:ice context)) (:all-subs-broken context))) :async true - :effect (effect (trash :corp eid card {:cause-card card :cause :effect}))}] + :effect (req (trash state :corp eid card {:cause-card card :cause :effect}))}] :subroutines [end-the-run]}) (defcard "Paywall" @@ -3654,7 +3654,7 @@ (<= 4 (count (:hand runner))))) :msg "give the Runner 1 tag" :async true - :effect (effect (gain-tags eid 1))}]}) + :effect (req (gain-tags state side eid 1))}]}) (defcard "Ping" {:on-rez (assoc (give-tags 1) :req (req (and run this-server))) @@ -3694,7 +3694,7 @@ :effect (req (wait-for (forfeit state side target) (effect-completed state side (make-result eid 10)))) :cancel {:async true - :effect (effect (effect-completed (make-result eid 0)))}} + :effect (req (effect-completed state side (make-result eid 0)))}} card nil))) :type :custom :while-inactive true}}}) @@ -3704,7 +3704,7 @@ {:rez-sound "pulse" :on-rez {:req (req (and run this-server)) :msg "force the runner to lose [Click]" - :effect (effect (lose-clicks :runner 1))} + :effect (req (lose-clicks state :runner 1))} :subroutines [{:label "Runner loses 1 [Credits] for each rezzed piece of Harmonic ice" :msg (msg "make the runner lose " (harmonic-ice-count corp) " [Credits]") :async true @@ -3750,12 +3750,12 @@ (defcard "Red Tape" {:subroutines [{:label "Give +3 strength to all ice for the remainder of the run" :msg "give +3 strength to all ice for the remainder of the run" - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card {:type :ice-strength :duration :end-of-run :value 3}) - (update-all-ice))}]}) + (update-all-ice state side))}]}) (defcard "Resistor" {:static-abilities [(ice-strength-bonus (req (count-tags state)))] @@ -3771,7 +3771,7 @@ (defcard "Rime" {:implementation "Can be rezzed anytime already" - :on-rez {:effect (effect (update-all-ice))} + :on-rez {:effect (req (update-all-ice state side))} :subroutines [(runner-loses-credits 1)] :static-abilities [{:type :ice-strength :req (req (protecting-same-server? card target)) @@ -3798,8 +3798,8 @@ :change-in-game-state {:silent true :req (req (not-empty (:deck corp)))} :async true :effect - (effect (continue-ability - (let [top-cards (take 3 (:deck corp))] + (req (continue-ability + state side (let [top-cards (take 3 (:deck corp))] {:waiting-prompt true :prompt (str "The top cards of R&D are (top->bottom): " (enumerate-cards top-cards)) :choices ["Arrange cards" "Shuffle R&D"] @@ -3848,7 +3848,7 @@ :prompt "Choose a card type" :choices ["Event" "Hardware" "Program" "Resource"] :msg (msg "choose the card type " target) - :effect (effect (update! (assoc card :card-target target)))} + :effect (req (update! state side (assoc card :card-target target)))} :events [{:event :damage :req (req (and (= (:damage-type context) :net) (= (:cause context) :subroutine) @@ -3871,7 +3871,7 @@ (resolve-extra-damage (count matching-type) eid)))))} {:event :end-of-encounter :req (req (:card-target card)) - :effect (effect (update! (dissoc card :card-target)))}] + :effect (req (update! state side (dissoc card :card-target)))}] :subroutines [sub sub sub]})) @@ -3947,9 +3947,9 @@ (defcard "Sensei" {:subroutines [{:label "Give encountered ice \"End the run\"" :msg "give encountered ice \"[Subroutine] End the run\" after all its other subroutines for the remainder of the run" - :effect (effect + :effect (req (register-lingering-effect - card + state side card {:type :additional-subroutines :duration :end-of-run :req (req (and (rezzed? target) @@ -3995,7 +3995,7 @@ (program? %))} :label "Add 1 installed program to the bottom of the stack" :msg (msg "add " (:title target) " to the bottom of the stack") - :effect (effect (move :runner target :deck))})] + :effect (req (move state :runner target :deck))})] {:subroutines [sub sub (give-tags 1)] @@ -4017,8 +4017,8 @@ :change-in-game-state {:silent true :req (req (seq (:deck corp)))} :async true :waiting-prompt true - :effect (effect (continue-ability - (let [from (take 3 (:deck corp))] + :effect (req (continue-ability + state side (let [from (take 3 (:deck corp))] (when (pos? (count from)) (reorder-choice :corp :runner from '() (count from) from))) card nil))} @@ -4029,7 +4029,7 @@ :msg "keep the Runner from breaching R&D"} :no-ability {:async true :msg "make the Runner breach R&D" - :effect (effect (breach-server :runner eid [:rd] {:no-root true}))}}}]}) + :effect (req (breach-server state :runner eid [:rd] {:no-root true}))}}}]}) (defcard "Sleipnir" {:subroutines [(maybe-draw-sub 1) @@ -4081,7 +4081,7 @@ :subroutines [{:label "Runner loses 3 [Credits]" :msg "force the Runner to lose 3 [Credits]" :async true - :effect (effect (lose-credits :runner eid 3))} + :effect (req (lose-credits state :runner eid 3))} {:label "Gain 3 [Credits]" :async true :effect (req (let [et (effect-type card) @@ -4097,9 +4097,9 @@ (effect-completed state side eid))))} {:label "Place 3 advancement counters" :async true - :effect (effect + :effect (req (continue-ability - (let [et (effect-type card) + state side (let [et (effect-type card) unique-types (top-3-types state card et)] (when (and (= 3 (count (first (get-effects state :corp et card)))) (= 1 unique-types)) @@ -4108,13 +4108,13 @@ :msg (msg "place 3 advancement counters on " (card-str state target)) :async true - :effect (effect (add-prop eid target :advance-counter 3 {:placed true}))})) + :effect (req (add-prop state side eid target :advance-counter 3 {:placed true}))})) card nil))}]})) (defcard "Snoop" {:on-encounter {:msg (msg "reveal " (enumerate-cards (:hand runner) :sorted) " from the grip") :async true - :effect (effect (reveal eid (:hand runner)))} + :effect (req (reveal state side eid (:hand runner)))} :abilities [{:req (req (pos? (get-counters card :power))) :change-in-game-state {:req (req (seq (:hand runner)))} :cost [(->c :power 1)] @@ -4263,14 +4263,14 @@ :choices {:card #(and (installed? %) (program? %) (has-subtype? % "AI"))} - :effect (effect (trash eid target {:cause :subroutine}))} + :effect (req (trash state side eid target {:cause :subroutine}))} (do-net-damage 1)]}) (defcard "SYNC BRE" {:subroutines [(tag-trace 4) (trace-ability 2 {:label "Runner reduces cards accessed by 1 for this run" :msg "reduce cards accessed for this run by 1" - :effect (effect (access-bonus :total -1))})]}) + :effect (req (access-bonus state side :total -1))})]}) (defcard "Syailendra" ;; "You can advance this ice. @@ -4295,7 +4295,7 @@ :choices {:card #(and (in-hand? %) (corp? %))} :msg "add 1 card in HQ to the top of R&D" - :effect (effect (move target :deck {:front true}))}]}) + :effect (req (move state side target :deck {:front true}))}]}) (defcard "Tatu-Bola" {:events [{:event :pass-ice @@ -4337,7 +4337,7 @@ :yes-ability {:prompt "Choose a piece of ice to swap Thimblerig with" :choices {:card ice? :not-self true} - :effect (effect (swap-ice card target)) + :effect (req (swap-ice state side card target)) :msg (msg "swap " (card-str state card) " with " (card-str state target))}}}] {:events [(assoc ability :event :pass-ice) @@ -4349,11 +4349,11 @@ :subroutines [(trace-ability 4 {:label "Do 1 net damage for each Runner tag" :async true :msg (msg "do " (count-tags state) " net damage") - :effect (effect (damage eid :net (count-tags state) {:card card}))}) + :effect (req (damage state side eid :net (count-tags state) {:card card}))}) (trace-ability 4 {:label "Runner loses 1 [Credits] for each tag" :async true :msg (msg "force the Runner to lose " (count-tags state) " [Credits]") - :effect (effect (lose-credits :runner eid (count-tags state)))})]}) + :effect (req (lose-credits state :runner eid (count-tags state)))})]}) (defcard "Tithe" {:subroutines [(do-net-damage 1) @@ -4388,9 +4388,9 @@ (defcard "TL;DR" {:subroutines [{:label "Duplicate each subroutine on a piece of ice" - :effect (effect + :effect (req (register-events - card + state side card [{:event :encounter-ice :duration :end-of-run :unregister-once-resolved true @@ -4408,7 +4408,7 @@ :msg "keep TMI rezzed" :label "Keep TMI rezzed" :unsuccessful {:async true - :effect (effect (derez eid card))}}} + :effect (req (derez state side eid card))}}} :subroutines [end-the-run]}) (defcard "Tocsin" @@ -4500,19 +4500,19 @@ {:prompt (str "Choose a location to install " (:title target)) :choices (req (remove #(= this %) (installable-servers state nice))) :async true - :effect (effect (corp-install eid nice target {:ignore-install-cost true + :effect (req (corp-install state side eid nice target {:ignore-install-cost true :msg-keys {:install-source card :display-origin true}}))} card nil)))} card nil)))} {:label "Give +2 strength to each piece of ice for the remainder of the run" :msg "give +2 strength to each piece of ice for the remainder of the run" - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card {:type :ice-strength :duration :end-of-run :value 2}) - (update-all-ice))}] + (update-all-ice state side))}] :events [{:event :run :req (req (and (first-event? state side :run))) :async true @@ -4622,9 +4622,9 @@ :waiting-prompt true :req (req (and run this-server)) :yes-ability {:async true - :effect (effect (continue-ability on-rez-ability card nil))} + :effect (req (continue-ability state side on-rez-ability card nil))} :no-ability - {:effect (effect (system-msg :corp (str "declines to use " (:title card))))}}}})) + {:effect (req (system-msg state :corp (str "declines to use " (:title card))))}}}})) (defcard "Upayoga" {:subroutines [(do-psi (runner-loses-credits 2)) @@ -4671,13 +4671,13 @@ :req (req (same-card? (:ice context) card)) :change-in-game-state {:silent true :req (req (zero? (:click runner)))} :msg "prevent the Runner from stealing or trashing Corp cards for the remainder of the run" - :effect (effect (register-run-flag! - card :can-steal + :effect (req (register-run-flag! + state side card :can-steal (fn [state _side _card] ((constantly false) (toast state :runner "Cannot steal due to Vertigo." "warning")))) (register-run-flag! - card :can-trash + state side card :can-trash (fn [state _side card] ((constantly (not (corp? card))) (toast state :runner "Cannot trash due to Vertigo." "warning")))))}] @@ -4734,7 +4734,7 @@ (not (contains? (set (:breaker-subtypes printed-sub)) "Decoder")))))) :msg "give the Runner 1 tag" :async true - :effect (effect (gain-tags eid 1))}]}) + :effect (req (gain-tags state side eid 1))}]}) (defcard "Waiver" {:subroutines [(trace-ability @@ -4764,8 +4764,8 @@ :msg "add a card from R&D to HQ" :change-in-game-state {:req (req (seq (:deck corp)))} :choices (req (sort (:deck corp))) - :effect (effect (shuffle! :deck) - (move target :hand))}]}) + :effect (req (shuffle! state side :deck) + (move state side target :hand))}]}) (defcard "Wave" {:on-rez @@ -4780,7 +4780,7 @@ (shuffle! state side :deck) (move state side target :hand) (effect-completed state side eid)))} - :no-ability {:effect (effect (system-msg :corp (str "declines to use " (:title card))))}}} + :no-ability {:effect (req (system-msg state :corp (str "declines to use " (:title card))))}}} :rez-sound "wave" :subroutines [{:label (str "Gain 1 [Credits] for each rezzed piece of Harmonic ice") :msg (msg "gain " (harmonic-ice-count corp) " [Credits]") @@ -4798,7 +4798,7 @@ :display-side :corp :msg (msg "force the Runner to trash " (:title target) " from [their] grip") :async true - :effect (effect (trash :runner eid target {:cause :subroutine}))}]}) + :effect (req (trash state :runner eid target {:cause :subroutine}))}]}) (defcard "Wendigo" (implementation-note @@ -4824,7 +4824,7 @@ :change-in-game-state {:req (req (< (:credit runner) 7)) :silent true} :msg "end the run" :async true - :effect (effect (end-run :corp eid card))}]}) + :effect (req (end-run state :corp eid card))}]}) (defcard "Winchester" {:subroutines [(trace-ability 4 trash-program-sub) @@ -4857,8 +4857,8 @@ :change-in-game-state {:silent true :req (req (seq (:deck corp)))} :optional {:prompt (msg "Move " (:title (first (:deck corp))) " to the bottom of R&D?") :yes-ability {:msg "move the top card of R&D to the bottom" - :effect (effect (move (first (:deck corp)) :deck))} - :no-ability {:effect (effect (system-msg :corp (str "declines to use " (:title card) " to move the top card of R&D to the bottom")))}}} + :effect (req (move state side (first (:deck corp)) :deck))} + :no-ability {:effect (req (system-msg state :corp (str "declines to use " (:title card) " to move the top card of R&D to the bottom")))}}} (do-net-damage 1)]}) (defcard "Zed 1.0" diff --git a/src/clj/game/cards/identities.clj b/src/clj/game/cards/identities.clj index ba67dc6adb..1ab4b728ea 100644 --- a/src/clj/game/cards/identities.clj +++ b/src/clj/game/cards/identities.clj @@ -59,7 +59,7 @@ [game.core.update :refer [update!]] [game.core.virus :refer [number-of-runner-virus-counters]] [game.core.winning :refer [check-win-by-agenda]] - [game.macros :refer [continue-ability effect msg req wait-for]] + [game.macros :refer [continue-ability msg req wait-for]] [game.utils :refer :all] [jinteki.utils :refer :all])) @@ -101,9 +101,9 @@ (not (#{:face-up} (:install-state context))))) :waiting-prompt true :effect - (effect + (req (continue-ability - {:optional + state side {:optional {:prompt "Expose installed card unless the Corp pays 1 [Credits]?" :autoresolve (get-autoresolve :auto-fire) :no-ability {:effect (req (clear-wait-prompt state :corp))} @@ -121,7 +121,7 @@ :player :corp :no-ability {:async true - :effect (effect (expose :runner eid [(:card context)]))} + :effect (req (expose state :runner eid [(:card context)]))} :yes-ability {:async true :effect @@ -160,7 +160,7 @@ :choices (req (conj (vec (filter #(not= original-server %) (get-remote-names state))) "New remote")) :async true - :effect (effect (corp-install eid chosen-card target {:ignore-install-cost true + :effect (req (corp-install state side eid chosen-card target {:ignore-install-cost true :msg-keys {:install-source card :display-origin true}}))} card nil)))} @@ -319,8 +319,8 @@ :psi {:req (req (= :rd (:server context))) :equal {:msg "access 1 additional card" :async true - :effect (effect (access-bonus :rd 1) - (effect-completed eid))}}}]}) + :effect (req (access-bonus state side :rd 1) + (effect-completed state side eid))}}}]}) (defcard "Alice Merchant: Clan Agitator" {:events [{:event :successful-run @@ -338,7 +338,7 @@ (corp? %))} :msg "force the Corp to trash 1 card from HQ" :async true - :effect (effect (trash :corp eid target nil))}]}) + :effect (req (trash state :corp eid target nil))}]}) (defcard "Ampère: Cybernetics For Anyone" ;; No special implementation @@ -348,8 +348,8 @@ {:events [{:event :pre-start-game :req (req (= side :runner)) :async true - :effect (effect (draw eid 4 {:suppress-event true}))}] - :mulligan (effect (draw eid 4 {:suppress-event true}))}) + :effect (req (draw state side eid 4 {:suppress-event true}))}] + :mulligan (req (draw state side eid 4 {:suppress-event true}))}) (defcard "Apex: Invasive Predator" (let [ability {:prompt "Choose a card to install facedown" @@ -361,9 +361,9 @@ :req (req (and (pos? (count (:hand runner))) (:runner-phase-12 @state))) :async true - :effect (effect + :effect (req (runner-install - (assoc eid :source card :source-type :runner-install) + state side (assoc eid :source card :source-type :runner-install) target {:facedown true :msg-keys {:install-source card}}))}] @@ -392,7 +392,7 @@ :req (req (and (= :runner (:side context)) (->> context :payment (map :paid/type) (some #{:trash-can})))) :msg "draw 1 card" - :effect (effect (draw eid 1))}]}) + :effect (req (draw state side eid 1))}]}) (defcard "Arissana Rocha Nahu: Street Artist" {:abilities [{:req (req (and run @@ -443,7 +443,7 @@ (or (is-remote? z) (not (asset? %))) (not (agenda? %)))} :async true - :effect (effect (corp-install eid target (zone->name z) {:msg-keys {:install-source card + :effect (req (corp-install state side eid target (zone->name z) {:msg-keys {:install-source card :display-origin true}}))} card nil)))}]}) @@ -455,8 +455,8 @@ :prompt "Choose a hosted card" :choices (req (cancellable (:hosted card))) :msg "add a hosted card to the grip" - :effect (effect (move target :hand) - (effect-completed eid))}] + :effect (req (move state side target :hand) + (effect-completed state side eid))}] :events [{:event :pre-start-game :req (req (= side :runner)) :async true @@ -508,14 +508,14 @@ #(is-type? (:card (first %)) (:card-target card))) (not (:facedown context)))) :async true - :effect (effect (gain-credits :corp eid 2)) + :effect (req (gain-credits state :corp eid 2)) :msg (msg "gain 2 [Credits] from " (:card-target card))} {:event :play-event :req (req (and (:card-target card) (first-event? state :runner :play-event) (is-type? (:card context) (:card-target card)))) :async true - :effect (effect (gain-credits :corp eid 2)) + :effect (req (gain-credits state :corp eid 2)) :msg (msg "gain 2 [Credits] from " (:card-target card))}]}) (defcard "Barry \"Baz\" Wong: Tri-Maf Veteran" @@ -531,7 +531,7 @@ :choices {:req (req (and (in-hand*? state target) (or (resource? target) (hardware? target)) (runner-can-pay-and-install? state side eid target)))} - :effect (effect (runner-install (assoc eid :source card) target {:msg-keys {:install-source card}}))}]}) + :effect (req (runner-install state side (assoc eid :source card) target {:msg-keys {:install-source card}}))}]}) (defcard "BANGUN: When Disaster Strikes" {:abilities [{:label "Manually turn an agenda faceup" @@ -586,8 +586,8 @@ :silent true} :async true :once :per-turn - :effect (effect (move target :hand) - (gain-credits eid (rez-cost state side target)))}] + :effect (req (move state side target :hand) + (gain-credits state side eid (rez-cost state side target)))}] {:flags {:corp-phase-12 (req (and (not (:disabled card)) (not (is-disabled? state side card)) (not-used-once? state {:once :per-turn} card) @@ -606,14 +606,14 @@ (pos? (get-in runner [:tag :base])))) :msg "remove 1 tag" :async true - :effect (effect (lose-tags eid 1))}]}) + :effect (req (lose-tags state side eid 1))}]}) (defcard "Captain Padma Isbister: Intrepid Explorer" {:events [{:event :run :async true :req (req (and (= (:server target) [:rd]) (first-event? state side :run #(= [:rd] (:server (first %)))))) - :effect (effect (continue-ability (charge-ability state side) card nil))}]}) + :effect (req (continue-ability state side (charge-ability state side) card nil))}]}) (defcard "Cerebral Imaging: Infinite Frontiers" {:static-abilities [(corp-hand-size+ (req (- (:credit corp) 5)))]}) @@ -635,12 +635,12 @@ (defcard "Chronos Protocol: Selective Mind-mapping" {:req (req (empty? (filter #(= :net (:damage-type (first %))) (turn-events state :runner :damage)))) - :effect (effect (enable-corp-damage-choice)) + :effect (req (enable-corp-damage-choice state side)) :leave-play (req (swap! state update-in [:damage] dissoc :damage-choose-corp)) :events [{:event :corp-phase-12 - :effect (effect (enable-corp-damage-choice))} + :effect (req (enable-corp-damage-choice state side))} {:event :runner-phase-12 - :effect (effect (enable-corp-damage-choice))} + :effect (req (enable-corp-damage-choice state side))} {:event :pre-resolve-damage :optional {:req (req (and (= :net (:damage-type context)) @@ -662,7 +662,7 @@ {:static-abilities [(hand-size+ -1)]}) (defcard "Dewi Subrotoputri: Pedagogical Dhalang" - (let [flip-effect {:effect (effect (update! (if (:flipped card) + (let [flip-effect {:effect (req (update! state side (if (:flipped card) (assoc card :flipped false :face :front @@ -700,14 +700,14 @@ (effect-completed state side eid))))}}}] {:events [{:event :pre-first-turn :req (req (= side :runner)) - :effect (effect (update! (assoc card :flipped false :face :front)))} + :effect (req (update! state side (assoc card :flipped false :face :front)))} maybe-flip] :abilities [(assoc flip-effect :label "Manually flip identity" :force-menu true :msg "manually flip [their] identity")]})) (defcard "Earth Station: SEA Headquarters" - (let [flip-effect (effect (update! (if (:flipped card) + (let [flip-effect (req (update! state side (if (:flipped card) (do (system-msg state :corp "flipped [pronoun] identity to Earth Station: SEA Headquarters") (assoc card :flipped false @@ -720,7 +720,7 @@ {:flags {:server-limit 1} :events [{:event :pre-first-turn :req (req (= side :corp)) - :effect (effect (update! (assoc card :flipped false :face :front)))} + :effect (req (update! state side (assoc card :flipped false :face :front)))} {:event :successful-run :req (req (and (= :hq (target-server context)) (:flipped card))) @@ -785,7 +785,7 @@ :choices ["[Edward Kim] Trash"] :async true :msg (msg "trash " (:title c)) - :effect (effect (trash eid c nil))}) + :effect (req (trash state side eid c nil))}) card nil)))}]}) (defcard "Ele \"Smoke\" Scovak: Cynosure of the Net" @@ -817,7 +817,7 @@ :not-distinct true :choices (cancellable (filter #(corp-installable-type? %) top)) :async true - :effect (effect (corp-install eid target nil {:msg-keys {:install-source card + :effect (req (corp-install state side eid target nil {:msg-keys {:install-source card :origin-index (first (keep-indexed #(when (same-card? target %2) %1) top)) :display-origin true}}))} card nil))))}]})) @@ -849,7 +849,7 @@ :req (req (and (program? (:card context)) (some #{:discard} (:previous-zone (:card context))))) :msg "draw 1 card" - :effect (effect (draw eid 1))}]}) + :effect (req (draw state side eid 1))}]}) (defcard "Freedom Khumalo: Crypto-Anarchist" {:interactions @@ -872,7 +872,7 @@ state side {:async true :msg (msg "trash " (:title accessed-card) " at no cost") - :effect (effect (trash eid (assoc accessed-card :seen true) {:accessed true}))} + :effect (req (trash state side eid (assoc accessed-card :seen true) {:accessed true}))} card nil) (wait-for (resolve-ability state side (pick-virus-counters-to-spend play-or-rez) card nil) (if-let [msg (:msg async-result)] @@ -909,12 +909,12 @@ (first-successful-run-on-server? state :hq))) :msg "gain 2 [Credits]" :async true - :effect (effect (gain-credits eid 2))}]}) + :effect (req (gain-credits state side eid 2))}]}) (defcard "Gagarin Deep Space: Expanding the Horizon" {:events [{:event :pre-access-card :req (req (is-remote? (second (get-zone (:accessed-card context))))) - :effect (effect (access-cost-bonus [(->c :credit 1)])) + :effect (req (access-cost-bonus state side [(->c :credit 1)])) :msg "make the Runner spend 1 [Credits] to access"}]}) (defcard "GameNET: Where Dreams are Real" @@ -928,7 +928,7 @@ (:additional-costs eid))))) :async true :msg "gain 1 [Credits]" - :effect (effect (gain-credits :corp eid 1))}] + :effect (req (gain-credits state :corp eid 1))}] {:events [(assoc gamenet-ability :event :runner-credit-loss) (assoc gamenet-ability :event :runner-spent-credits)]})) @@ -948,7 +948,7 @@ :events [{:event :access :req (req (and (agenda? (:accessed-card context)) (pos? (event-count state side :agenda-stolen)))) - :effect (effect (toast :runner "Cannot steal due to Haarpsichord Studios." "warning"))}]}) + :effect (req (toast state :runner "Cannot steal due to Haarpsichord Studios." "warning"))}]}) (defcard "Haas-Bioroid: Architects of Tomorrow" {:events [{:event :pass-ice @@ -977,7 +977,7 @@ :automatic :gain-credits :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits eid 1))}]}) + :effect (req (gain-credits state side eid 1))}]}) (defcard "Haas-Bioroid: Precision Design" {:static-abilities [(corp-hand-size+ 1)] @@ -992,8 +992,8 @@ {:static-abilities [{:type :ice-strength :req (req (has-subtype? target "Bioroid")) :value 1}] - :leave-play (effect (update-all-ice)) - :effect (effect (update-all-ice))}) + :leave-play (req (update-all-ice state side)) + :effect (req (update-all-ice state side))}) (defcard "Harishchandra Ent.: Where You're the Star" (letfn [(format-grip [runner] @@ -1034,8 +1034,8 @@ :async true :waiting-prompt true :effect - (effect (continue-ability - (let [itarget (:card context) + (req (continue-ability + state side (let [itarget (:card context) card-type (:type itarget)] (if (some #(is-type? % (:type itarget)) (all-cards-in-hand* state :runner)) {:optional @@ -1045,7 +1045,7 @@ :choices {:req (req (and (is-type? target card-type) (in-hand*? state target)))} :async true - :effect (effect (runner-install (assoc eid :source card :source-type :runner-install) target {:msg-keys {:install-source card + :effect (req (runner-install state side (assoc eid :source card :source-type :runner-install) target {:msg-keys {:install-source card :display-origin true}}))}}} {:prompt (str "You have no " card-type " to install") :choices ["Carry on!"] @@ -1083,7 +1083,7 @@ :value "Natural"}] :events [{:event :pre-first-turn :req (req (= side :runner)) - :effect (effect (update! (assoc card :flipped false :face :front)))} + :effect (req (update! state side (assoc card :flipped false :face :front)))} {:event :runner-turn-ends :automatic :gain-credits :interactive (req true) @@ -1119,7 +1119,7 @@ (first-event? state side :corp-reveal valid-ctx?)))) :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits eid 1))}] + :effect (req (gain-credits state side eid 1))}] :abilities [{:action true :cost [(->c :click 1)] :label "Reveal the top card of the Stack" @@ -1145,7 +1145,7 @@ :automatic :gain-credits :msg "gain 2 [Credits]" :async true - :effect (effect (gain-credits eid 2))}] + :effect (req (gain-credits state side eid 2))}] {:flags {:drip-economy true} :events [(assoc ability :event :runner-turn-begins)] :abilities [ability]})) @@ -1161,15 +1161,15 @@ :interactive (req true) :msg "give the Runner 1 tag" :async true - :effect (effect (gain-tags :corp eid 1))}] + :effect (req (gain-tags state :corp eid 1))}] [{:event :pre-start-game :effect draft-points-target} (assoc inf :event :agenda-scored) (assoc inf :event :agenda-stolen)])}) (defcard "Issuaq Adaptics: Sustaining Diversity" - {:effect (effect (lose :agenda-point-req (get-counters card :power))) - :leave-play (effect (gain :agenda-point-req (get-counters card :power))) + {:effect (req (lose state side :agenda-point-req (get-counters card :power))) + :leave-play (req (gain state side :agenda-point-req (get-counters card :power))) :static-abilities [{:type :agenda-point-req :req (req (= :corp side)) :value (req (- (get-counters card :power)))}] @@ -1195,23 +1195,23 @@ (first-event? state side :runner-install))) :msg "draw 1 card" :async true - :effect (effect (draw eid 1))}]}) + :effect (req (draw state side eid 1))}]}) (defcard "Jemison Astronautics: Sacrifice. Audacity. Success." {:events [{:event :corp-forfeit-agenda :async true :waiting-prompt true :effect - (effect + (req (continue-ability - (let [p (inc (get-agenda-points (:card context)))] + state side (let [p (inc (get-agenda-points (:card context)))] {:prompt "Choose a card to place advancement counters on" :choices {:card #(and (installed? %) (corp? %))} :msg (msg "place " (quantify p "advancement counter") " on " (card-str state target)) :async true - :effect (effect (add-prop :corp eid target :advance-counter p {:placed true}))}) + :effect (req (add-prop state :corp eid target :advance-counter p {:placed true}))}) card nil))}]}) (defcard "Jesminder Sareen: Girl Behind the Curtain" @@ -1222,15 +1222,15 @@ :async true :req (req (and run (<= (run-event-count state side :tag-interrupt) 1))) :msg "avoid 1 tag" - :effect (effect (prevent-tag :runner eid 1))}]}) + :effect (req (prevent-tag state :runner eid 1))}]}) (defcard "Jinteki Biotech: Life Imagined" {:events [{:event :pre-first-turn :req (req (= side :corp)) :prompt (msg "Choose a copy of " (:title card) " to use this game") :choices ["The Brewery" "The Tank" "The Greenhouse"] - :effect (effect (update! (assoc card :biotech-target target :face :front)) - (system-msg (str "has chosen a copy of " (:title card) " for this game")))}] + :effect (req (update! state side (assoc card :biotech-target target :face :front)) + (system-msg state side (str "has chosen a copy of " (:title card) " for this game")))}] :abilities [{:label "Check chosen flip identity" :effect (req (case (:biotech-target card) "The Brewery" @@ -1267,7 +1267,7 @@ {:prompt "Choose a card that can be advanced" :choices {:req (req (can-be-advanced? state target))} :async true - :effect (effect (add-prop eid target :advance-counter 4 {:placed true}))} + :effect (req (add-prop state side eid target :advance-counter 4 {:placed true}))} card nil)) (do (toast state :corp (str "Unknown Jinteki Biotech: Life Imagined card: " flip) "error") (effect-completed state side eid)))))}]}) @@ -1276,7 +1276,7 @@ (let [ability {:async true :interactive (req true) :msg "do 1 net damage" - :effect (effect (damage eid :net 1 {:card card}))}] + :effect (req (damage state side eid :net 1 {:card card}))}] {:events [(assoc ability :event :agenda-scored) (assoc ability :event :agenda-stolen)]})) @@ -1300,7 +1300,7 @@ :req (req (pos? (count (remove :seen (:discard corp))))) :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits :corp eid 1))}]}) + :effect (req (gain-credits state :corp eid 1))}]}) (defcard "Kabonesa Wu: Netspace Thrillseeker" {:abilities [{:action true @@ -1359,16 +1359,16 @@ (first-event? state :runner :play-event #(has-subtype? (:card (first %)) "Run")))) :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits eid 1))}]}) + :effect (req (gain-credits state side eid 1))}]}) (defcard "Khan: Savvy Skiptracer" {:events [{:event :pass-ice :req (req (first-event? state :runner :pass-ice)) :async true :interactive (req true) - :effect (effect + :effect (req (continue-ability - (when (some #(and (has-subtype? % "Icebreaker") + state side (when (some #(and (has-subtype? % "Icebreaker") (can-pay? state side (assoc eid :source card :source-type :runner-install) % nil [(->c :credit (install-cost state side % {:cost-bonus -1}))])) (:hand runner)) @@ -1379,7 +1379,7 @@ (can-pay? state side (assoc eid :source card :source-type :runner-install) target nil [(->c :credit (install-cost state side target {:cost-bonus -1}))])))} :async true - :effect (effect (runner-install eid target {:cost-bonus -1 + :effect (req (runner-install state side eid target {:cost-bonus -1 :msg-keys {:display-origin true :install-source card}}))}) card nil))}]}) @@ -1400,8 +1400,8 @@ :prompt "Force the Corp to draw 1 card?" :yes-ability {:msg "force the Corp to draw 1 card" :async true - :effect (effect (draw :corp eid 1))} - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card))))}}}] + :effect (req (draw state :corp eid 1))} + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card))))}}}] :abilities [(set-autoresolve :auto-fire "Laramy Fisk: Savvy Investor")]}) (defcard "Lat: Ethical Freelancer" @@ -1409,16 +1409,16 @@ :interactive (req true) :async true :effect - (effect (continue-ability - {:optional {:req (req (= (count (:hand runner)) (count (:hand corp)))) + (req (continue-ability + state side {:optional {:req (req (= (count (:hand runner)) (count (:hand corp)))) :autoresolve (get-autoresolve :auto-fire) :waiting-prompt true :prompt "Draw 1 card?" :yes-ability {:async true :msg "draw 1 card" - :effect (effect (draw :runner eid 1))} + :effect (req (draw state :runner eid 1))} :no-ability - {:effect (effect (system-msg (str "declines to use " (:title card))))}}} + {:effect (req (system-msg state side (str "declines to use " (:title card))))}}} card nil))}] :abilities [(set-autoresolve :auto-fire "Lat: Ethical Freelancer")]}) @@ -1434,7 +1434,7 @@ (installed? %)) (all-installed state :corp)))} :msg (msg "add " (card-str state target) " to HQ") - :effect (effect (move :corp target :hand))}] + :effect (req (move state :corp target :hand))}] {:events [(assoc leela :event :agenda-scored) (assoc leela :event :agenda-stolen)]})) @@ -1466,7 +1466,7 @@ (first-event? state side :rez #(ice? (:card (first %)))))) :msg "gain 2 [Credits]" :async true - :effect (effect (gain-credits :runner eid 2))}]}) + :effect (req (gain-credits state :runner eid 2))}]}) (defcard "Magdalene Keino-Chemutai: Cryptarchitect" {:events [{:event :runner-discard-to-hand-size @@ -1525,11 +1525,11 @@ :events [;; At game start, you're on the front face {:event :pre-first-turn :req (req (= side :corp)) - :effect (effect (update! - (assoc card + :effect (req (update! + state side (assoc card :face :front :melies-target (first (shuffle ["HQ" "R&D" "Archives"])))) - (system-msg "reveals that the three hidden faces of Méliès U: Only the Brightest are: Tenure Floors: Méliès U, Subsurface Labs: Méliès U, and Disposal Grounds: Méliès U"))} + (system-msg state side "reveals that the three hidden faces of Méliès U: Only the Brightest are: Tenure Floors: Méliès U, Subsurface Labs: Méliès U, and Disposal Grounds: Méliès U"))} ;; When your turn ends, you secretly choose a server {:event :corp-turn-ends :prompt "Choose a server" @@ -1549,7 +1549,7 @@ ;; when our turn begins and we are not on the front face, we flip {:event :corp-turn-begins :silent (req true) - :effect (effect (update! (assoc card :face :front)))} + :effect (req (update! state side (assoc card :face :front)))} ;; When the runner makes a successful run on a central ;; while we're on a front face, we flip and maybe do something {:event :successful-run @@ -1575,7 +1575,7 @@ :once :per-turn :msg "add 1 card from Archives to HQ" :async true - :effect (effect (continue-ability (corp-recur) card nil))}}} + :effect (req (continue-ability state side (corp-recur) card nil))}}} card nil) (effect-completed state side eid))))}]})) @@ -1598,7 +1598,7 @@ :async true :effect (req (access-bonus state side breached-server 1 :end-of-access) (effect-completed state side eid))} - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card) " to access 1 additional card")))}}} + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card) " to access 1 additional card")))}}} card nil)))}]}) (defcard "MirrorMorph: Endless Iteration" @@ -1607,9 +1607,9 @@ mm-clear {:prompt "Manually fix Mirrormorph" :msg "manually clear Mirrormorph flags" :label "Manually fix Mirrormorph" - :effect (effect - (update! (assoc-in card [:special :mm-actions] [])) - (update! (assoc-in (get-card state card) [:special :mm-click] false)))} + :effect (req + (update! state side (assoc-in card [:special :mm-actions] [])) + (update! state side (assoc-in (get-card state card) [:special :mm-click] false)))} mm-ability {:prompt "Choose one" :choices ["Gain [Click]" "Gain 1 [Credits]"] :msg (msg (decapitalize target)) @@ -1637,14 +1637,14 @@ (effect-completed state side eid))))} {:event :runner-turn-begins :silent true - :effect (effect - (update! (assoc-in card [:special :mm-actions] [])) - (update! (assoc-in (get-card state card) [:special :mm-click] false)))} + :effect (req + (update! state side (assoc-in card [:special :mm-actions] [])) + (update! state side (assoc-in (get-card state card) [:special :mm-click] false)))} {:event :corp-turn-ends :silent true - :effect (effect - (update! (assoc-in card [:special :mm-actions] [])) - (update! (assoc-in (get-card state card) [:special :mm-click] false)))}] + :effect (req + (update! state side (assoc-in card [:special :mm-actions] [])) + (update! state side (assoc-in (get-card state card) [:special :mm-click] false)))}] :static-abilities [{:type :prevent-paid-ability :req (req (and (get-in card [:special :mm-click]) (let [ctx {:cid (:cid target) @@ -1692,7 +1692,7 @@ :prompt "You have no piece of ice to install" :choices ["Carry on!"] :prompt-type :bogus - :effect (effect (effect-completed eid))} + :effect (req (effect-completed state side eid))} card nil)))}]}) (defcard "MuslihaT: Multifarious Marketeer" @@ -1723,9 +1723,9 @@ (defcard "Nasir Meidan: Cyber Explorer" {:events [{:event :approach-ice :req (req (not (rezzed? (:ice context)))) - :effect (effect + :effect (req (register-events - card + state side card (let [ice (:ice context) cost (rez-cost state side ice)] [{:event :encounter-ice @@ -1777,7 +1777,7 @@ :successful {:msg "give the Runner 1 tag" :async true - :effect (effect (gain-tags :corp eid 1 {:unpreventable true}))}}}}}] + :effect (req (gain-tags state :corp eid 1 {:unpreventable true}))}}}}}] :abilities [(set-autoresolve :auto-fire "NBN: Controlling the Message")]}) (defcard "NBN: Making News" @@ -1807,11 +1807,11 @@ :req (req (first-event? state :corp :server-created)) :async true :msg "draw 1 card" - :effect (effect (draw :corp eid 1))}]}) + :effect (req (draw state :corp eid 1))}]}) (defcard "Nebula Talent Management: Making Stars" (let [flip-effect - {:effect (effect (update! (if (:flipped card) + {:effect (req (update! state side (if (:flipped card) (assoc card :flipped false :face :front @@ -1826,7 +1826,7 @@ :force-menu true)] :events [{:event :pre-first-turn :req (req (= side :corp)) - :effect (effect (update! (assoc card :flipped false :face :front)))} + :effect (req (update! state side (assoc card :flipped false :face :front)))} {:event :corp-turn-ends :req (req (and (not (no-event? state side :play-operation)) (not (:flipped card)))) @@ -1867,7 +1867,7 @@ (or (in-hand? %) (in-discard? %)))} :msg (msg "play a current from " (name-zone "Corp" (get-zone target))) - :effect (effect (play-instant eid target))}}}] + :effect (req (play-instant state side eid target))}}}] {:events [(assoc nasol :event :agenda-scored) (assoc nasol :event :agenda-stolen)]})) @@ -1903,7 +1903,7 @@ (some? (:runner-credits context)))) :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits :corp eid 1))}]}) + :effect (req (gain-credits state :corp eid 1))}]}) (defcard "Noise: Hacker Extraordinaire" {:events [{:async true @@ -1911,7 +1911,7 @@ :interactive (req true) :req (req (has-subtype? (:card context) "Virus")) :msg "force the Corp to trash the top card of R&D" - :effect (effect (mill :corp eid :corp 1))}]}) + :effect (req (mill state :corp eid :corp 1))}]}) (defcard "Null: Whistleblower" {:events [{:event :encounter-ice @@ -1927,15 +1927,15 @@ " from the grip to lower the strength of " (:title current-ice) " by 2 for the remainder of the run") :async true - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card (let [ice current-ice] {:type :ice-strength :duration :end-of-run :req (req (same-card? target ice)) :value -2})) - (update-all-ice) - (trash eid target {:unpreventable true}))}}}]}) + (update-all-ice state side) + (trash state side eid target {:unpreventable true}))}}}]}) (defcard "Nuvem SA: Law of the Land" (let [abi2 {:event :corp-trash @@ -1944,15 +1944,15 @@ (first-event? state side :corp-trash #(= [:deck] (:zone (:card (first %))))))) :msg "gain 2 [Credits]" :async true - :effect (effect (gain-credits :corp eid 2))} + :effect (req (gain-credits state :corp eid 2))} abi1 {:prompt (msg "The top card of R&D is: " (:title (first (:deck corp)))) :async true :msg "look at the top card of R&D" :choices ["OK"] :req (req (seq (:deck corp))) :effect - (effect (continue-ability - {:optional + (req (continue-ability + state side {:optional {:prompt (str "Trash " (:title (first (:deck corp))) "?") :yes-ability {:msg "trash the top card of R&D" @@ -1972,7 +1972,7 @@ :req (req (and (:marked-server target) (first-event? state side :successful-run #(:marked-server (first %))))) :msg "gain [Click]" - :effect (effect (gain-clicks 1))}]}) + :effect (req (gain-clicks state side 1))}]}) (defcard "Ob Superheavy Logistics: Extract. Export. Excel." ;; note - we ensure the card can be installed (asset/upgrade/ice) - condition counters (like patch) @@ -2075,10 +2075,10 @@ (continue-ability state side {:msg "shuffle R&D" - :effect (effect (shuffle! :corp :deck))} + :effect (req (shuffle! state :corp :deck))} card nil)))} :no-ability - {:effect (effect (system-msg (str "declines to use " (:title card))))}}})] + {:effect (req (system-msg state side (str "declines to use " (:title card))))}}})] {:abilities [(choose-one-helper {:label "Always pause at start of turn"} [{:option "Always pause at turn start" @@ -2131,7 +2131,7 @@ :msg "gain 1 [Credits]" :async true :automatic :gain-credits - :effect (effect (gain-credits :corp eid 1))}]}) + :effect (req (gain-credits state :corp eid 1))}]}) (defcard "Poétrï Luxury Brands: All the Rage" (let [remote-choice @@ -2190,7 +2190,7 @@ :choices {:req (req (and (installed? target) (can-be-advanced? state target)))} :msg {:public (msg "place 1 advancement counter on " (card-str state target)) :corp (msg "place 1 advancement counter on " (card-str state target {:maybe-visible true}))} - :effect (effect (add-prop :corp eid target :advance-counter 1 {:placed true}))}]}) + :effect (req (add-prop state :corp eid target :advance-counter 1 {:placed true}))}]}) (defcard "PT Untaian: Life's Building Blocks" {:events [{:event :corp-turn-ends @@ -2244,8 +2244,8 @@ :req (req (first-event? state side :encounter-ice)) :msg (msg "make " (:title (:ice context)) " gain Code Gate until the end of the run") - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card (let [ice (:ice context)] {:type :gain-subtype :duration :end-of-run @@ -2310,7 +2310,7 @@ (corp? %) (in-hand? %))} :msg (msg "install a card in a remote server and place 1 advancement counter on it") - :effect (effect (continue-ability (install-card target) card nil))}] + :effect (req (continue-ability state side (install-card target) card nil))}] :events [{:event :corp-turn-begins :silent true :effect (req (clear-persistent-flag! state side card :can-rez))}]})) @@ -2330,7 +2330,7 @@ (in-hand*? state target) (can-pay? state side (assoc eid :source card :source-type :runner-install) target nil [(->c :credit (install-cost state side target {:cost-bonus -2}))])))} - :effect (effect (runner-install (assoc eid :source card :source-type :runner-install) target {:cost-bonus -2 + :effect (req (runner-install state side (assoc eid :source card :source-type :runner-install) target {:cost-bonus -2 :msg-keys {:display-origin true :install-source card}}))}]}) @@ -2343,7 +2343,7 @@ :show-discard true :choices {:card #(and (corp? %) (in-discard? %))} - :effect (effect (move target :deck {:front true})) + :effect (req (move state side target :deck {:front true})) :msg (msg "add " (if (:seen target) (:title target) "a card") " to the top of R&D")}]}) (defcard "Silhouette: Stealth Operative" @@ -2355,7 +2355,7 @@ (first-successful-run-on-server? state :hq))) :choices {:card #(and (installed? %) (not (rezzed? %)))} - :effect (effect (expose eid [target]))}]}) + :effect (req (expose state side eid [target]))}]}) (defcard "Skorpios Defense Systems: Persuasive Power" (let [set-resolution-mode @@ -2422,7 +2422,7 @@ :req (req (and (has-subtype? (:card context) "Advertisement") (first-event? state :corp :rez #(has-subtype? (:card (first %)) "Advertisement")))) :async true - :effect (effect (lose-credits :runner eid 1)) + :effect (req (lose-credits state :runner eid 1)) :msg "make the Runner lose 1 [Credits]"}]}) (defcard "Sportsmetal: Go Big or Go Home" @@ -2473,7 +2473,7 @@ :msg (msg "place " (quantify agenda-points "advancement counter") " on " (card-str state target)) :async true - :effect (effect (add-prop eid target :advance-counter agenda-points {:placed true}))} + :effect (req (add-prop state side eid target :advance-counter agenda-points {:placed true}))} card nil)))}}}] :abilities [(set-autoresolve :auto-fire "SSO Industries: Fueling Innovation")]})) @@ -2497,8 +2497,8 @@ :card #(and (in-discard? %) (runner? %))} :effect - (effect (continue-ability - (let [c1 (first targets) + (req (continue-ability + state side (let [c1 (first targets) c2 (second targets)] {:waiting-prompt true :prompt "Choose which card to remove from the game" @@ -2623,7 +2623,7 @@ :msg (msg "swap the positions of " (card-str state (first targets)) " and " (card-str state (second targets))) :effect (req (swap-ice state side (first targets) (second targets)))} - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card))))}}}] + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card))))}}}] {:events [(assoc swap-ability :event :agenda-scored) (assoc swap-ability :event :agenda-stolen)]})) @@ -2637,7 +2637,7 @@ :once :per-turn :async true :interactive (req true) - :effect (effect (add-prop eid target :advance-counter 1 {:placed true}))}]}) + :effect (req (add-prop state side eid target :advance-counter 1 {:placed true}))}]}) (defcard "The Catalyst: Convention Breaker" ;; No special implementation @@ -2692,7 +2692,7 @@ {:events [{:event :corp-gain-bad-publicity :msg "gain 3 [Credit]" :async true - :effect (effect (gain-credits eid 3))}]}) + :effect (req (gain-credits state side eid 3))}]}) (defcard "The Professor: Keeper of Knowledge" ;; No special implementation @@ -2713,13 +2713,13 @@ (or (agenda? (:source ctx)) (operation? (:source ctx))))] (and (valid-ctx? targets) (first-event? state side :corp-credit-gain valid-ctx?)))) - :effect (effect (maybe-draw eid card 1))}]}) + :effect (req (maybe-draw state side eid card 1))}]}) (defcard "Thule Subsea: Safety Below" {:events [{:event :agenda-stolen :async true - :effect (effect (continue-ability - {:prompt "Choose one" + :effect (req (continue-ability + state side {:prompt "Choose one" :player :runner :choices (req [(when (can-pay? state :runner eid card nil [(->c :credit 2) (->c :click 1)]) "Pay [Click] and 2 [Credits]") @@ -2768,22 +2768,22 @@ (:label thunderbolt-sub) "\" after its other subroutines") :async true - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card (let [t (:card context)] {:type :additional-subroutines :duration :end-of-run :req (req (and (rezzed? target) (same-card? t target))) :value {:subroutines [thunderbolt-sub]}})) - (pump-ice (:card context) 1 :end-of-run) - (effect-completed eid))}]})) + (pump-ice state side (:card context) 1 :end-of-run) + (effect-completed state side eid))}]})) (defcard "Titan Transnational: Investing In Your Future" {:events [{:event :agenda-scored :msg (msg "place 1 agenda counter on " (:title (:card context))) :async true - :effect (effect (add-counter eid (:card context) :agenda 1 nil))}]}) + :effect (req (add-counter state side eid (:card context) :agenda 1 nil))}]}) (defcard "Topan: Ormas Leader" (letfn [(installable? [state side eid target] @@ -2821,7 +2821,7 @@ :req (req (and (= side :runner) (zero? (count-bad-pub state)))) ;; This doesn't use `gain-bad-publicity` to avoid the event - :effect (effect (gain :corp :bad-publicity 1))}]}) + :effect (req (gain state :corp :bad-publicity 1))}]}) (defcard "Virtual Intelligence, P.I.: \"You Can Call Me Vic\"" {:abilities [{:cost [(->c :click 1) (->c :credit 1)] @@ -2858,14 +2858,14 @@ (and (rezzed? (:ice context)) (pos? (get-counters (:ice context) :advancement)))))))) :msg "do 1 meat damage" - :effect (effect (damage eid :meat 1 {:card card}))}]}) + :effect (req (damage state side eid :meat 1 {:card card}))}]}) (defcard "Weyland Consortium: Building a Better World" {:events [{:event :play-operation :req (req (has-subtype? (:card context) "Transaction")) :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits eid 1))}]}) + :effect (req (gain-credits state side eid 1))}]}) (defcard "Weyland Consortium: Built to Last" {:events [{:event :advance diff --git a/src/clj/game/cards/operations.clj b/src/clj/game/cards/operations.clj index bea68a8c04..85fc44bf12 100644 --- a/src/clj/game/cards/operations.clj +++ b/src/clj/game/cards/operations.clj @@ -57,7 +57,7 @@ [game.core.toasts :refer [toast]] [game.core.update :refer [update!]] [game.core.virus :refer [number-of-virus-counters]] - [game.macros :refer [continue-ability effect msg req wait-for]] + [game.macros :refer [continue-ability msg req wait-for]] [game.utils :refer :all] [jinteki.utils :refer :all])) @@ -72,7 +72,7 @@ (:on-play cardfn)))] (update untrashed :events conj {:event :corp-turn-begins :async true - :effect (effect (trash eid card nil))}))) + :effect (req (trash state side eid card nil))}))) ;; helper for the faceup-archives-count cards (defn- faceup-archives-types [corp] @@ -132,7 +132,7 @@ (is-scored? state :corp %))} :msg (msg "trigger the \"when scored\" ability of " (:title target)) :async true - :effect (effect (continue-ability (:on-score (card-def target)) target nil))} + :effect (req (continue-ability state side (:on-score (card-def target)) target nil))} card nil))}}) (defcard "Accelerated Diagnostics" @@ -230,7 +230,7 @@ {:base-play-cost [(->c :x-credits)] :msg (msg "install and rez " (x-cost-value eid) " Advertisements") :async true - :effect (effect (continue-ability (ab 0 (x-cost-value eid)) card nil))}})) + :effect (req (continue-ability state side (ab 0 (x-cost-value eid)) card nil))}})) (defcard "Aggressive Negotiation" {:on-play (assoc (tutor-abi nil) :req (req (:scored-agenda corp-reg)))}) @@ -241,9 +241,9 @@ :prompt "Choose a server" :choices ["Archives" "R&D" "HQ"] :effect - (effect (show-wait-prompt (str "Runner to decide on running " target)) + (req (show-wait-prompt state side (str "Runner to decide on running " target)) (continue-ability - (let [serv target] + state side (let [serv target] {:optional {:prompt (str "Make a run on " serv "?") :player :runner @@ -257,8 +257,8 @@ :duration :end-of-run}) (make-run state :runner eid serv card))} :no-ability {:msg "add itself to [their] score area as an agenda worth 1 agenda point" - :effect (effect (clear-wait-prompt :corp) - (as-agenda :corp card 1))}}}) + :effect (req (clear-wait-prompt state :corp) + (as-agenda state :corp card 1))}}}) card nil))}}) (defcard "Anonymous Tip" @@ -274,7 +274,7 @@ :req (req (not-empty run-ices)) :msg "deal 2 meat damage" :async true - :effect (effect (damage eid :meat 2 {:card card}))}]})) + :effect (req (damage state side eid :meat 2 {:card card}))}]})) (defcard "Ark Lockdown" {:on-play @@ -302,7 +302,7 @@ state side (when (faceup-agendas corp) {:msg "gain 2 [Credits] for having faceup agendas in Archives" - :effect (effect (gain-credits eid 2)) + :effect (req (gain-credits state side eid 2)) :async true}) card nil))))}})) @@ -399,7 +399,7 @@ (all-installed state :runner)))} :msg (msg "trash " (:title target)) :async true - :effect (effect (trash eid target {:cause-card card}))}}) + :effect (req (trash state side eid target {:cause-card card}))}}) (defcard "Biased Reporting" (letfn [(num-installed [state t] @@ -459,8 +459,8 @@ {:req (req (can-score? state side (get-card state card-to-score))) :prompt (str "Score " (:title card-to-score) "?") :yes-ability {:async true - :effect (effect (score eid (get-card state card-to-score)))} - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card) " to score " (card-str state card-to-score))))}}} + :effect (req (score state side eid (get-card state card-to-score)))} + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card) " to score " (card-str state card-to-score))))}}} card nil))))}}) (defcard "Bigger Picture" @@ -513,7 +513,7 @@ {:req (req (<= 2 (count-tags state))) :msg "do 7 meat damage" :async true - :effect (effect (damage eid :meat 7 {:card card}))}}) + :effect (req (damage state side eid :meat 7 {:card card}))}}) (defcard "Bring Them Home" (let [threat-abi @@ -565,7 +565,7 @@ (let [faux-purge {:choices {:req (req (and (installed? target) (pos? (get-counters target :virus))))} :async true - :effect (effect (add-counter eid target :virus (* -1 (get-counters target :virus)) nil)) + :effect (req (add-counter state side eid target :virus (* -1 (get-counters target :virus)) nil)) :msg (msg "remove all virus counters from " (card-str state target))} kaguya {:choices {:max 2 :req (req (and (corp? target) @@ -605,7 +605,7 @@ :async true :req (req (same-card? (:accessed-card context) (:host card))) :msg "give the Runner 2 tags" - :effect (effect (gain-tags :runner eid 2))}]}) + :effect (req (gain-tags state :runner eid 2))}]}) (defcard "Caveat Emptor" {:on-play (choose-one-helper @@ -732,7 +732,7 @@ :change-in-game-state {:req (req (pos? (:credit runner)))} :msg (msg "force the Runner to lose all " (:credit runner) " [Credits]") :async true - :effect (effect (lose-credits :runner eid :all))}}) + :effect (req (lose-credits state :runner eid :all))}}) (defcard "Commercialization" {:on-play @@ -742,7 +742,7 @@ :choices {:card #(and (ice? %) (installed? %))} :async true - :effect (effect (gain-credits eid (get-counters target :advancement)))}}) + :effect (req (gain-credits state side eid (get-counters target :advancement)))}}) (defcard "Complete Image" (letfn [(name-a-card [] @@ -751,7 +751,7 @@ :choices {:card-title (req (and (runner? target) (not (identity? target))))} :msg (msg "name " target) - :effect (effect (continue-ability (damage-ability) card targets))}) + :effect (req (continue-ability state side (damage-ability) card targets))}) (damage-ability [] {:async true :msg "do 1 net damage" @@ -767,7 +767,7 @@ :on-play {:async true :req (req (and (last-turn? state :runner :successful-run) (<= 3 (:agenda-point runner)))) - :effect (effect (continue-ability (name-a-card) card nil))}})) + :effect (req (continue-ability state side (name-a-card) card nil))}})) (defcard "Consulting Visit" {:on-play @@ -781,9 +781,9 @@ :cancel shuffle-my-deck! :msg (msg "search R&D for " (:title target) " and play it") :async true - :effect (effect (shuffle! :deck) - (system-msg "shuffles [their] deck") - (play-instant eid target nil))}}) + :effect (req (shuffle! state side :deck) + (system-msg state side "shuffles [their] deck") + (play-instant state side eid target nil))}}) (defcard "Corporate Hospitality" {:on-play (combine-abilities (clearance 6 2) (corp-recur))}) @@ -792,15 +792,15 @@ {:on-play {:msg "shuffle all cards in HQ into R&D and draw 5 cards" :async true - :effect (effect (shuffle-into-deck :hand) - (draw eid 5))}}) + :effect (req (shuffle-into-deck state side :hand) + (draw state side eid 5))}}) (defcard "Cyberdex Trial" {:play-sound "virus-purge" :on-play {:msg "purge virus counters" :async true - :effect (effect (purge eid))}}) + :effect (req (purge state side eid))}}) (defcard "Death and Taxes" (let [maybe-gain-credit {:prompt "Gain 1 [Credits]?" @@ -808,7 +808,7 @@ :autoresolve (get-autoresolve :auto-fire) :yes-ability {:msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits :corp eid 1))}}] + :effect (req (gain-credits state :corp eid 1))}}] {:special {:auto-fire :always} :abilities [(set-autoresolve :auto-fire "Death and Taxes")] :events [{:event :runner-install :optional maybe-gain-credit} @@ -909,7 +909,7 @@ {:prompt "Choose a server" :choices (remove #{"HQ" "R&D" "Archives"} (installable-servers state card-to-install)) :async true - :effect (effect (corp-install eid card-to-install target {:msg-keys {:install-source card + :effect (req (corp-install state side eid card-to-install target {:msg-keys {:install-source card :display-origin true}}))}) card nil) (end-effect state side eid card targets))) @@ -919,7 +919,7 @@ (defcard "Distract the Masses" (let [shuffle-two {:async true - :effect (effect (shuffle-into-rd-effect eid card 2))} + :effect (req (shuffle-into-rd-effect state side eid card 2))} trash-from-hq {:async true :prompt "Choose up to 2 cards in HQ to trash" :choices {:max 2 @@ -948,7 +948,7 @@ " [Credits]") :change-in-game-state {:req (req (pos? (number-of-non-empty-remotes state)))} :async true - :effect (effect (gain-credits eid (number-of-non-empty-remotes state)))}})) + :effect (req (gain-credits state side eid (number-of-non-empty-remotes state)))}})) (defcard "Divert Power" {:on-play @@ -990,7 +990,7 @@ :msg (msg "give " (card-str state target {:visible false}) " additional text") :change-in-game-state {:req (req (some ice? (all-installed state :corp)))} :async true - :effect (effect (install-as-condition-counter eid card target))} + :effect (req (install-as-condition-counter state side eid card target))} :events [{:event :encounter-ice :condition :hosted :trace {:base 3 @@ -1003,7 +1003,7 @@ :async true :change-in-game-state {:req (req (>= (:credit runner) 4))} :msg "make the runner lose 4 [Credits]" - :effect (effect (lose-credits :runner eid 4))}}) + :effect (req (lose-credits state :runner eid 4))}}) (defcard "Election Day" {:on-play @@ -1022,7 +1022,7 @@ {:additional-cost [(->c :tag 1)] :msg "do 4 meat damage" :async true - :effect (effect (damage eid :meat 4 {:card card}))}}) + :effect (req (damage state side eid :meat 4 {:card card}))}}) (defcard "Enforced Curfew" {:on-play {:msg "reduce the Runner's maximum hand size by 1"} @@ -1041,7 +1041,7 @@ (or (not= (:faction (:identity runner)) (:faction target)) (= (:faction (:identity runner)) "Neutral"))))} :msg (msg "trash " (:title target)) - :effect (effect (trash eid target {:cause-card card}))}}}}) + :effect (req (trash state side eid target {:cause-card card}))}}}}) (defcard "Enhanced Login Protocol" {:on-play {:msg (str "add an additional cost of [Click]" @@ -1059,14 +1059,14 @@ :prompt "Choose an agenda in the Runner's score area to swap" :choices {:req (req (in-runner-scored? state side target))} :async true - :effect (effect + :effect (req (continue-ability - (let [stolen target] + state side (let [stolen target] {:prompt (msg "Choose a scored agenda to swap for " (:title stolen)) :choices {:req (req (in-corp-scored? state side target))} :msg (msg "swap " (:title target) " for " (:title stolen)) - :effect (effect (swap-agendas target stolen))}) + :effect (req (swap-agendas state side target stolen))}) card nil))}}) (defcard "Extract" @@ -1103,7 +1103,7 @@ :max (get-x-fn) :default (req 1)} :msg (msg "draw " (quantify target "card")) - :effect (effect (draw eid target))} + :effect (req (draw state side eid target))} install-cards (fn install-cards [server n] (when (pos? n) @@ -1123,7 +1123,7 @@ select-server {:async true :prompt "Choose a server" :choices (req (conj (vec (get-remote-names state)) "New remote")) - :effect (effect (continue-ability (install-cards target 1) card nil))}] + :effect (req (continue-ability state side (install-cards target 1) card nil))}] (wait-for (gain-credits state :corp ((get-x-fn) state side eid card targets)) (wait-for (resolve-ability state side draw card nil) (continue-ability state side select-server card nil)))))}}) @@ -1159,7 +1159,7 @@ {:player :corp :async true :msg (msg "make the Runner lose " (count-resources state) " [Credits]") - :effect (effect (lose-credits :runner eid (count-resources state)))}}}})) + :effect (req (lose-credits state :runner eid (count-resources state)))}}}})) (defcard "Flood the Market" (letfn [(full-servers [state] @@ -1233,7 +1233,7 @@ {:on-play {:async true :change-in-game-state {:req (req (seq (:discard corp)))} - :effect (effect (continue-ability (fhelper 1) card nil))} })) + :effect (req (continue-ability state side (fhelper 1) card nil))} })) (defcard "Fully Operational" (letfn [(full-servers [state] @@ -1257,14 +1257,14 @@ {:on-play {:msg (msg "make " (quantify (inc (count (full-servers state))) "gain/draw decision")) :async true - :effect (effect (continue-ability (repeat-choice 1 (inc (count (full-servers state)))) + :effect (req (continue-ability state side (repeat-choice 1 (inc (count (full-servers state)))) card nil))}})) (defcard "Game Changer" {:on-play {:rfg-instead-of-trashing true :change-in-game-state {:req (req (pos? (count (:scored runner))))} - :effect (effect (gain-clicks (count (:scored runner))))}}) + :effect (req (gain-clicks state side (count (:scored runner))))}}) (defcard "Game Over" {:on-play @@ -1367,8 +1367,8 @@ :async true :msg (msg "choose " (card-str state target)) :effect - (effect (continue-ability - {:optional + (req (continue-ability + state side {:optional {:player :runner :waiting-prompt true :prompt "Access the installed card?" @@ -1379,7 +1379,7 @@ (effect-completed state side eid)))} :no-ability {:msg "add itself to the Runner's score area as an agenda worth -1 agenda point" - :effect (effect (as-agenda :runner card -1))}}} + :effect (req (as-agenda state :runner card -1))}}} card targets))}}) (defcard "Hansei Review" @@ -1444,7 +1444,7 @@ (runner? %) (not (has-subtype? % "Virtual")))} :msg "add 1 installed non-virtual card to the grip" - :effect (effect (move :runner target :hand true))}}}}) + :effect (req (move state :runner target :hand true))}}}}) (defcard "Hedge Fund" {:on-play (gain-credits-ability 9)}) @@ -1457,10 +1457,10 @@ :successful {:msg "add a Resource to the top of the Stack" :choices {:card #(and (installed? %) (resource? %))} - :effect (effect (move :runner target :deck {:front true}) - (system-msg (str "adds " (:title target) " to the top of the Stack")))} + :effect (req (move state :runner target :deck {:front true}) + (system-msg state side (str "adds " (:title target) " to the top of the Stack")))} :unsuccessful {:msg "take 1 bad publicity" - :effect (effect (gain-bad-publicity :corp 1))}}}}) + :effect (req (gain-bad-publicity state :corp 1))}}}}) (defcard "Hellion Beta Test" {:on-play @@ -1471,7 +1471,7 @@ :successful (trash-type "non-program" #(or (facedown? %) (not (program? %))) :loud 2 :all) :unsuccessful {:msg "take 1 bad publicity" :async true - :effect (effect (gain-bad-publicity :corp eid 1))}}}}) + :effect (req (gain-bad-publicity state :corp eid 1))}}}}) (defcard "Heritage Committee" {:on-play @@ -1483,7 +1483,7 @@ :choices {:card #(and (corp? %) (in-hand? %))} :msg "draw 3 cards and add 1 card from HQ to the top of R&D" - :effect (effect (move target :deck {:front true}))} + :effect (req (move state side target :deck {:front true}))} card nil)))}}) (defcard "High-Profile Target" @@ -1492,7 +1492,7 @@ {:req (req tagged) :msg (msg "do " (dmg-count state) " meat damage") :async true - :effect (effect (damage eid :meat (dmg-count state) {:card card}))}})) + :effect (req (damage state side eid :meat (dmg-count state) {:card card}))}})) (defcard "Housekeeping" {:events [{:event :runner-install @@ -1504,7 +1504,7 @@ :async true :msg (msg "force the Runner to trash" (:title target) " from the grip") - :effect (effect (trash :runner eid target {:unpreventable true :cause-card card :cause :forced-to-trash}))}]}) + :effect (req (trash state :runner eid target {:unpreventable true :cause-card card :cause :forced-to-trash}))}]}) (defcard "Hunter Seeker" {:on-play (trash-type "card" installed? :loud 1 nil @@ -1515,13 +1515,13 @@ {:on-play {:prompt "Choose a server" :choices (req servers) :msg (msg "choose " target) - :effect (effect (update! (assoc card :card-target target)))} + :effect (req (update! state side (assoc card :card-target target)))} :events [{:event :successful-run :psi {:req (req (= (zone->name (get-in @state [:run :server])) (:card-target card))) :not-equal {:msg "end the run" :async true - :effect (effect (end-run eid card))}}}]})) + :effect (req (end-run state side eid card))}}}]})) (defcard "Hypoxia" {:on-play {:req (req tagged) @@ -1544,7 +1544,7 @@ (or (in-hand? %) (in-discard? %)))} :async true - :effect (effect (corp-install eid target nil {:ignore-install-cost true + :effect (req (corp-install state side eid target nil {:ignore-install-cost true :msg-keys {:install-source card :display-origin true}}))}}) @@ -1568,7 +1568,7 @@ :effect (req (trash-cards state side eid targets {:cause-card card}))}) :unsuccessful {:msg "take 1 bad publicity" :async true - :effect (effect (gain-bad-publicity :corp eid 1))}}}}) + :effect (req (gain-bad-publicity state :corp eid 1))}}}}) (defcard "IP Enforcement" (letfn [(valid-agenda? [state c x] @@ -1694,17 +1694,17 @@ (agenda? (:accessed-card context)))) :successful {:msg "do 1 core damage" :async true - :effect (effect (damage :runner eid :brain 1 {:card card}))}}}] + :effect (req (damage state :runner eid :brain 1 {:card card}))}}}] {:events [(assoc trace-for-brain-damage :event :access :interactive (req (agenda? (:accessed-card context)))) (assoc trace-for-brain-damage :event :agenda-scored)]})) (defcard "Lag Time" - {:on-play {:effect (effect (update-all-ice))} + {:on-play {:effect (req (update-all-ice state side))} :static-abilities [{:type :ice-strength :value 1}] - :leave-play (effect (update-all-ice))}) + :leave-play (req (update-all-ice state side))}) (defcard "Lateral Growth" {:on-play @@ -1719,7 +1719,7 @@ (corp-installable-type? %) (in-hand? %))} :async true - :effect (effect (corp-install eid target nil {:msg-keys {:install-source card + :effect (req (corp-install state side eid target nil {:msg-keys {:install-source card :display-origin true}}))} card nil)))}}) @@ -1741,7 +1741,7 @@ :events [{:event :runner-turn-begins :duration :until-runner-turn-begins :msg "make the Runner lose [Click]" - :effect (effect (lose-clicks :runner 1))}]}) + :effect (req (lose-clicks state :runner 1))}]}) (defcard "Localized Product Line" {:on-play @@ -1749,9 +1749,9 @@ :choices (req (cancellable (:deck corp) :sorted)) :change-in-game-state {:req (req (seq (:deck corp)))} :async true - :effect (effect + :effect (req (continue-ability - (let [title (:title target) + state side (let [title (:title target) copies (filter #(= (:title %) title) (:deck corp))] {:prompt (msg "How many copies of " title " do you want to find?") :choices {:number (req (count copies))} @@ -1780,7 +1780,7 @@ :change-in-game-state {:req (req (pos? (count (filter #(pos? (get-counters % :advancement)) (get-all-installed state)))))} :async true - :effect (effect (gain-credits eid (* 2 (count (filter #(pos? (get-counters % :advancement)) + :effect (req (gain-credits state side eid (* 2 (count (filter #(pos? (get-counters % :advancement)) (get-all-installed state))))))}}) (defcard "MCA Informant" @@ -1791,7 +1791,7 @@ (installed? %))} :msg (msg "host itself on " (card-str state target) ". The Runner has an additional tag") :async true - :effect (effect (install-as-condition-counter eid card target))} + :effect (req (install-as-condition-counter state side eid card target))} :static-abilities [{:type :tags :value 1}] :leave-play (req (system-msg state :corp "trashes MCA Informant")) @@ -1799,9 +1799,9 @@ :label "Trash MCA Informant host" :cost [(->c :click 1) (->c :credit 2)] :async true - :effect (effect (system-msg :runner (str "spends [Click] and 2 [Credits] to trash " + :effect (req (system-msg state :runner (str "spends [Click] and 2 [Credits] to trash " (card-str state (:host card)))) - (trash :runner eid (get-card state (:host card)) {:cause-card (:host card)}))}]}) + (trash state :runner eid (get-card state (:host card)) {:cause-card (:host card)}))}]}) (defcard "Measured Response" {:on-play (choose-one-helper @@ -1840,7 +1840,7 @@ :label "Trace 6 - Give the Runner X tags" :successful {:msg (msg "give the Runner " (quantify (- target (second targets)) "tag")) :async true - :effect (effect (gain-tags eid (- target (second targets))))}}}}) + :effect (req (gain-tags state side eid (- target (second targets))))}}}}) (defcard "Mindscaping" {:on-play @@ -1862,7 +1862,7 @@ (corp? %)) ;; just incase everything gets jinja'd out of hand :all (req (not (zero? (count (:hand corp)))))} - :effect (effect (move target :deck {:front true}))} + :effect (req (move state side target :deck {:front true}))} card nil))))}} {:option "Do 1 net damage per tag (up to 3)" :ability {:async true @@ -2014,14 +2014,14 @@ {:req (req (last-turn? state :runner :made-run)) :msg "do 1 net damage" :async true - :effect (effect (damage eid :net 1 {:card card}))}}) + :effect (req (damage state side eid :net 1 {:card card}))}}) (defcard "Neurospike" {:on-play {:msg (msg "do " (:scored-agenda corp-reg 0) " net damage") :change-in-game-state {:req (req (pos? (:scored-agenda corp-reg 0)))} :async true - :effect (effect (damage eid :net (:scored-agenda corp-reg 0) {:card card}))}}) + :effect (req (damage state side eid :net (:scored-agenda corp-reg 0) {:card card}))}}) (defcard "NEXT Activation Command" (lockdown @@ -2047,7 +2047,7 @@ :no-ability {:msg "gain 5 [Credits]" :async true - :effect (effect (gain-credits eid 5))}}}}) + :effect (req (gain-credits state side eid 5))}}}}) (defcard "O₂ Shortage" {:on-play @@ -2096,7 +2096,7 @@ :req (req (and (same-card? (:ice context) (:host card)) (:all-subs-broken context))) :msg (msg "trash " (card-str state (:ice context))) - :effect (effect (trash :corp eid (:ice context) {:unpreventable true :cause-card card}))}]}) + :effect (req (trash state :corp eid (:ice context) {:unpreventable true :cause-card card}))}]}) (defcard "Patch" {:on-play {:choices {:card #(and (ice? %) @@ -2104,7 +2104,7 @@ :change-in-game-state {:req (req (some (every-pred ice? rezzed?) (all-installed state :corp)))} :msg (msg "give +2 strength to " (card-str state target)) :async true - :effect (effect (install-as-condition-counter eid card target))} + :effect (req (install-as-condition-counter state side eid card target))} :static-abilities [{:type :ice-strength :req (req (same-card? target (:host card))) :value 2}]}) @@ -2114,7 +2114,7 @@ :automatic :gain-credits :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits :corp eid 1))}]}) + :effect (req (gain-credits state :corp eid 1))}]}) (defcard "Peak Efficiency" {:on-play @@ -2124,8 +2124,8 @@ " [Credits]") :change-in-game-state {:req (req (some (every-pred ice? rezzed?) (all-installed state :corp)))} :async true - :effect (effect (gain-credits - eid + :effect (req (gain-credits + state side eid (reduce (fn [c server] (+ c (count (filter (fn [ice] (:rezzed ice)) (:ices server))))) 0 (flatten (seq (:servers corp))))))}}) @@ -2151,13 +2151,13 @@ {:prompt "Choose a server" :choices (remove #{"HQ" "R&D" "Archives"} (installable-servers state card-to-install)) :async true - :effect (effect (corp-install eid card-to-install target nil))}) + :effect (req (corp-install state side eid card-to-install target nil))}) target nil) (effect-completed state side eid)))} card nil)))}] {:on-play {:async true - :effect (effect (continue-ability - (if (>= (count (:hand corp)) 2) + :effect (req (continue-ability + state side (if (>= (count (:hand corp)) 2) {:prompt "Choose a card in HQ to keep private" :choices {:req (req (and (in-hand? target) (corp? target))) @@ -2218,7 +2218,7 @@ (continue-ability state side {:async true - :effect (effect (corp-install eid target-card nil {:msg-keys {:install-source card + :effect (req (corp-install state side eid target-card nil {:msg-keys {:install-source card :display-origin true}}))} card nil))))} card nil) @@ -2257,7 +2257,7 @@ (program? %)) (<= (:cost %) n))} :msg (msg "trash " (:title target)) - :effect (effect (trash eid target {:cause-card card :cause :forced-to-trash}))}) + :effect (req (trash state side eid target {:cause-card card :cause :forced-to-trash}))}) card nil)))}}) (defcard "Precognition" @@ -2266,8 +2266,8 @@ :change-in-game-state {:req (req (seq (:deck corp)))} :waiting-prompt true :async true - :effect (effect (continue-ability - (let [from (take 5 (:deck corp))] + :effect (req (continue-ability + state side (let [from (take 5 (:deck corp))] (when (pos? (count from)) (reorder-choice :corp :runner from '() (count from) from))) @@ -2302,14 +2302,14 @@ {:on-play {:rfg-instead-of-trashing true :change-in-game-state {:req (req (seq (:discard corp)))} :async true - :effect (effect (shuffle-into-rd-effect eid card 3 true))}}) + :effect (req (shuffle-into-rd-effect state side eid card 3 true))}}) (defcard "Priority Construction" (letfn [(install-card [chosen] {:prompt "Choose a remote server" :choices (req (conj (vec (get-remote-names state)) "New remote")) :async true - :effect (effect (corp-install eid chosen target {:ignore-all-cost true + :effect (req (corp-install state side eid chosen target {:ignore-all-cost true :counters {:advance-counter 3} :msg-keys {:install-source card :display-origin true}}))})] @@ -2322,7 +2322,7 @@ :msg "install a piece of ice from HQ and place 3 advancements on it" :cancel {:msg "do nothing"} :async true - :effect (effect (continue-ability (install-card target) card nil))}})) + :effect (req (continue-ability state side (install-card target) card nil))}})) (defcard "Product Recall" {:on-play @@ -2353,7 +2353,7 @@ :waiting-prompt true :choices (req (conj (vec (get-remote-names state)) "New remote")) :async true - :effect (effect (corp-install eid chosen target {:msg-keys {:install-source card + :effect (req (corp-install state side eid chosen target {:msg-keys {:install-source card :origin-index (first (positions #{chosen} (take 5 (:deck corp)))) :display-origin true}}))})] {:on-play @@ -2361,24 +2361,24 @@ :change-in-game-state {:req (req (seq (:deck corp)))} :msg "look at the top 5 cards of R&D" :effect - (effect + (req (continue-ability - (let [top-five (take 5 (:deck corp))] + state side (let [top-five (take 5 (:deck corp))] {:prompt (str "The top cards of R&D are (top->bottom): " (enumerate-cards top-five)) :waiting-prompt true :choices ["OK"] :async true :effect - (effect + (req (continue-ability - {:prompt "Choose an agenda, asset, or upgrade to install" + state side {:prompt "Choose an agenda, asset, or upgrade to install" :waiting-prompt true :async true :choices (cancellable (filter #(and (corp-installable-type? %) (some #{"New remote"} (installable-servers state %))) top-five)) - :effect (effect (continue-ability (install-card target) card nil))} + :effect (req (continue-ability state side (install-card target) card nil))} card nil))}) card nil))}})) @@ -2401,7 +2401,7 @@ :successful {:async true :msg (msg "do " (:stole-agenda runner-reg-last 0) " meat damage") - :effect (effect (damage eid :meat (:stole-agenda runner-reg-last 0) {:card card}))}}}}) + :effect (req (damage state side eid :meat (:stole-agenda runner-reg-last 0) {:card card}))}}}}) (defcard "realloc()" {:on-play {:change-in-game-state {:req (req (seq (filter (every-pred rezzed? ice?) @@ -2506,15 +2506,15 @@ {:base-play-cost [(->c :x-credits)] :msg (msg "search for " (x-cost-value eid) " Sysops") :async true - :effect (effect (continue-ability (rthelp (x-cost-value eid) (x-cost-value eid) []) card nil))}})) + :effect (req (continue-ability state side (rthelp (x-cost-value eid) (x-cost-value eid) []) card nil))}})) (defcard "Red Level Clearance" (let [all [{:msg "gain 2 [Credits]" :async true - :effect (effect (gain-credits eid 2))} + :effect (req (gain-credits state side eid 2))} {:msg "draw 2 cards" :async true - :effect (effect (draw eid 2))} + :effect (req (draw state side eid 2))} (gain-n-clicks 1) {:prompt "Choose a non-agenda to install" :msg "install a non-agenda from hand" @@ -2522,7 +2522,7 @@ (corp-installable-type? %) (in-hand? %))} :async true - :effect (effect (corp-install eid target nil {:msg-keys {:install-source card + :effect (req (corp-install state side eid target nil {:msg-keys {:install-source card :display-origin true}}))}] can-install? (fn [hand] (seq (remove #(or (agenda? %) @@ -2546,7 +2546,7 @@ {:on-play {:waiting-prompt true :async true - :effect (effect (continue-ability (choice all false) card nil))}})) + :effect (req (continue-ability state side (choice all false) card nil))}})) (defcard "Red Planet Couriers" (letfn [(clear-counters [state side eid [c :as installed]] @@ -2626,7 +2626,7 @@ state side (when (facedown? target) {:async true - :effect (effect (reveal eid target))}) + :effect (req (reveal state side eid target))}) card targets) (trash state side eid target {:cause-card card}))))}}) @@ -2642,7 +2642,7 @@ (corp? %) (in-discard? %))} :async true - :effect (effect (corp-install eid target nil {:msg-keys {:install-source card + :effect (req (corp-install state side eid target nil {:msg-keys {:install-source card :display-origin true}}))}}) (defcard "Retribution" @@ -2696,8 +2696,8 @@ :choices {:card #(and (corp? %) (in-hand? %))} :msg "shuffle a card from HQ into R&D" - :effect (effect (move target :deck) - (shuffle! :deck))}}) + :effect (req (move state side target :deck) + (shuffle! state side :deck))}}) (defcard "Riot Suppression" {:on-play @@ -2722,7 +2722,7 @@ :req (req (first-event? state side :play-event)) :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits :corp eid 1))}]}) + :effect (req (gain-credits state :corp eid 1))}]}) (defcard "Rover Algorithm" {:on-play {:choices {:card #(and (ice? %) @@ -2730,7 +2730,7 @@ :change-in-game-state {:req (req (some (every-pred ice? rezzed?) (all-installed state :corp)))} :msg (msg "host itself as a condition counter on " (card-str state target)) :async true - :effect (effect (install-as-condition-counter eid card target))} + :effect (req (install-as-condition-counter state side eid card target))} :static-abilities [{:type :ice-strength :req (req (same-card? target (:host card))) :value (req (get-counters card :power))}] @@ -2739,7 +2739,7 @@ :req (req (same-card? (:ice context) (:host card))) :msg "place 1 power counter on itself" :async true - :effect (effect (add-counter eid card :power 1 nil))}]}) + :effect (req (add-counter state side eid card :power 1 nil))}]}) (defcard "Sacrifice" {:on-play @@ -2800,7 +2800,7 @@ (or (has-subtype? % "Virtual") (has-subtype? % "Chip")))} :msg (msg "remove " (card-str state target) " from game") - :effect (effect (move :runner target :rfg))}}}}) + :effect (req (move state :runner target :rfg))}}}}) (defcard "Scarcity of Resources" {:on-play {:msg "increase the install cost of resources by 2"} @@ -2839,9 +2839,9 @@ :prompt "Choose a piece of ice" :choices (req (filter ice? (:deck corp))) :effect - (effect + (req (continue-ability - (let [chosen-ice target] + state side (let [chosen-ice target] {:async true :prompt "Choose a server" :choices ["Archives" "R&D" "HQ"] @@ -2925,7 +2925,7 @@ {:async true :req (req (<= 2 (count-tags state))) :change-in-game-state {:req (req (something-can-be-advanced? state))} - :effect (effect (continue-ability (ability 4) card nil))}})) + :effect (req (continue-ability state side (ability 4) card nil))}})) (defcard "Shoot the Moon" {:on-play @@ -2964,7 +2964,7 @@ (continue-ability state side {:msg (msg "draw " (quantify n "card")) :async true - :effect (effect (draw eid n))} + :effect (req (draw state side eid n))} card nil))))}}) (defcard "Snatch and Grab" @@ -2977,9 +2977,9 @@ :choices {:card #(has-subtype? % "Connection")} :async true :effect - (effect + (req (continue-ability - (let [c target] + state side (let [c target] {:optional {:player :runner :waiting-prompt true @@ -2988,11 +2988,11 @@ {:async true :msg (msg "take 1 tag to prevent " (:title c) " from being trashed") - :effect (effect (gain-tags :runner eid 1 {:unpreventable true}))} + :effect (req (gain-tags state :runner eid 1 {:unpreventable true}))} :no-ability {:async true :msg (msg "trash " (:title c)) - :effect (effect (trash :corp eid c {:cause-card card}))}}}) + :effect (req (trash state :corp eid c {:cause-card card}))}}}) card nil))}}}}) (defcard "Special Report" @@ -3048,7 +3048,7 @@ {:msg (msg "gain " (* 3 (count (:scored runner))) " [Credits]") :change-in-game-state {:req (req (seq (:scored runner)))} :async true - :effect (effect (gain-credits eid (* 3 (count (:scored runner)))))}}) + :effect (req (gain-credits state side eid (* 3 (count (:scored runner)))))}}) (defcard "Sudden Commandment" (let [play-instant-second {:optional @@ -3057,7 +3057,7 @@ :req (req (threat-level 3 state)) :yes-ability {:cost [(->c :credit 3)] :msg "gain [Click]" - :effect (effect (gain-clicks 1))}}} + :effect (req (gain-clicks state side 1))}}} play-instant-first {:prompt "Choose a non-terminal operation" :choices (req (conj (filter #(and (operation? %) (not (has-subtype? % "Terminal")) @@ -3097,7 +3097,7 @@ :value {:subroutines [{:label "[Sub Boost] End the run" :msg "end the run" :async true - :effect (effect (end-run eid card))}]}}]}) + :effect (req (end-run state side eid card))}]}}]}) (defcard "Subcontract" (letfn [(sc [i sccard] @@ -3115,7 +3115,7 @@ {:req (req tagged) :change-in-game-state {:req (req (seq (:hand corp)))} :async true - :effect (effect (continue-ability (sc 1 card) card nil))}})) + :effect (req (continue-ability state side (sc 1 card) card nil))}})) (defcard "Subliminal Messaging" {:on-play {:msg "gain 1 [Credits]" @@ -3126,7 +3126,7 @@ {:once :per-turn :once-key :subliminal-messaging :msg "gain [Click]" - :effect (effect (gain-clicks :corp 1))} + :effect (req (gain-clicks state :corp 1))} card nil)))} :highlight-in-discard true :events [{:event :corp-phase-12 @@ -3154,7 +3154,7 @@ :msg (msg "advance " (card-str state target) " " (quantify (get-advancement-requirement (cost-target eid :forfeit)) "time")) :async true - :effect (effect (advance-n-times eid card target (get-advancement-requirement (cost-target eid :forfeit))))}})) + :effect (req (advance-n-times state side eid card target (get-advancement-requirement (cost-target eid :forfeit))))}})) (defcard "Successful Demonstration" {:on-play (assoc (gain-credits-ability 7) :req (req (last-turn? state :runner :unsuccessful-run)))}) @@ -3195,7 +3195,7 @@ {:msg (msg "gain " (count (:hand runner)) " [Credits]") :change-in-game-state {:req (req (seq (:hand runner)))} :async true - :effect (effect (gain-credits eid (count (:hand runner))))}}) + :effect (req (gain-credits state side eid (count (:hand runner))))}}) (defcard "SYNC Rerouting" (lockdown @@ -3213,12 +3213,12 @@ (let [gaincr {:req (req (= (:title (:card context)) (:card-target card))) :async true :msg "gain 10 [Credits]" - :effect (effect (gain-credits :corp eid 10))}] + :effect (req (gain-credits state :corp eid 10))}] {:on-play {:prompt "Name a Runner card" :choices {:card-title (req (and (runner? target) (not (identity? target))))} - :effect (effect (update! (assoc card :card-target target)) - (system-msg (str "uses " (:title card) " to name " target)))} + :effect (req (update! state side (assoc card :card-target target)) + (system-msg state side (str "uses " (:title card) " to name " target)))} :events [(assoc gaincr :event :runner-install) (assoc gaincr :event :play-event)]})) @@ -3226,21 +3226,21 @@ (let [trash-all-resources {:msg "trash all resources" :async true - :effect (effect (trash-cards :corp eid (filter resource? (all-active-installed state :runner)) {:cause-card card}))}] + :effect (req (trash-cards state :corp eid (filter resource? (all-active-installed state :runner)) {:cause-card card}))}] {:on-play {:req (req tagged) :change-in-game-state {:req (req (some resource? (all-active-installed state :runner)))} :async true - :effect (effect + :effect (req (continue-ability - (if (pos? (count-bad-pub state)) + state side (if (pos? (count-bad-pub state)) {:optional {:player :runner :prompt "Remove 1 bad publicity to prevent all resources from being trashed?" :yes-ability {:msg "remove 1 bad publicity, preventing all resources from being trashed" :async true - :effect (effect (lose-bad-publicity eid 1))} + :effect (req (lose-bad-publicity state side eid 1))} :no-ability trash-all-resources}} trash-all-resources) card nil))}})) @@ -3253,9 +3253,9 @@ (installed? %))} :rfg-instead-of-trashing true :async true - :effect (effect + :effect (req (continue-ability - (let [chosen target] + state side (let [chosen target] {:player :runner :waiting-prompt true :prompt "Choose one" @@ -3304,7 +3304,7 @@ {:req (req (<= 2 (count-tags state))) :msg "do 2 meat damage" :async true - :effect (effect (damage eid :meat 2 {:card card}))}}) + :effect (req (damage state side eid :meat 2 {:card card}))}}) (defcard "Transparency Initiative" {:static-abilities [{:type :gain-subtype @@ -3328,7 +3328,7 @@ :req (req (same-card? (:host card) (:card context))) :async true :msg "gain 1 [Credit]" - :effect (effect (gain-credits eid 1))}])) + :effect (req (gain-credits state side eid 1))}])) (effect-completed state side eid))))}}) (defcard "Trick of Light" @@ -3338,16 +3338,16 @@ (installed? target)))} :change-in-game-state {:req (req (something-can-be-advanced? state))} :async true - :effect (effect + :effect (req (continue-ability - (let [card-to-advance target] + state side (let [card-to-advance target] {:async true :prompt "Choose another installed card" :choices {:card #(and (not (same-card? card-to-advance %)) (installed? %))} - :effect (effect + :effect (req (continue-ability - (let [source target] + state side (let [source target] {:prompt "How many advancement counters do you want to move?" :choices (take (inc (get-counters source :advancement)) ["0" "1" "2"]) :msg (msg "move " target " advancement counters from " @@ -3377,7 +3377,7 @@ (installed? %) (>= exceed (:cost %)))} :msg (msg "trash " (card-str state target)) - :effect (effect (trash eid target {:cause-card card}))} + :effect (req (trash state side eid target {:cause-card card}))} card nil)))}}}}) (defcard "Trust Operation" @@ -3387,7 +3387,7 @@ (in-discard? %))} :msg (msg "install and rez " (:title target) ", ignoring all costs") :async true - :effect (effect (corp-install eid target nil {:ignore-all-cost true + :effect (req (corp-install state side eid target nil {:ignore-all-cost true :msg-keys {:install-source card :display-origin true} :install-state :rezzed-no-cost}))}] @@ -3443,7 +3443,7 @@ (corp? %) (not (operation? %)))} :async true - :effect (effect (corp-install eid target nil {:msg-keys {:install-source card + :effect (req (corp-install state side eid target nil {:msg-keys {:install-source card :display-origin true}}))} card nil)))}}) @@ -3510,9 +3510,9 @@ (and (resource? %) (not (has-subtype? % "Virtual"))))} :async true - :effect (effect + :effect (req (continue-ability - (let [chosen target + state side (let [chosen target wake card] {:player :runner :waiting-prompt true @@ -3548,10 +3548,10 @@ {:on-play {:msg "remove 2 bad publicity" :change-in-game-state {:req (req (pos? (count-bad-pub state)))} - :effect (effect (lose-bad-publicity 2))}}) + :effect (req (lose-bad-publicity state side 2))}}) (defcard "Your Digital Life" {:on-play {:msg (msg "gain " (count (:hand corp)) " [Credits]") :change-in-game-state {:req (req (seq (:hand corp)))} :async true - :effect (effect (gain-credits :corp eid (count (:hand corp))))}}) + :effect (req (gain-credits state :corp eid (count (:hand corp))))}}) diff --git a/src/clj/game/cards/programs.clj b/src/clj/game/cards/programs.clj index 9510232556..9fa110077d 100644 --- a/src/clj/game/cards/programs.clj +++ b/src/clj/game/cards/programs.clj @@ -63,7 +63,7 @@ [game.core.trace :refer [force-base]] [game.core.update :refer [update!]] [game.core.virus :refer [get-virus-counters]] - [game.macros :refer [continue-ability effect msg req wait-for]] + [game.macros :refer [continue-ability msg req wait-for]] [game.utils :refer :all] [jinteki.utils :refer :all])) @@ -108,9 +108,9 @@ state :runner (assoc eid :source card :source-type :runner-install) card {:no-toast true}))) - :effect (effect + :effect (req (continue-ability - {:req (req (and (not-any? #(and (= title (:title %)) + state side {:req (req (and (not-any? #(and (= title (:title %)) (get-in % [:special :heap-breaker-dont-install])) (all-active-installed state :runner)) (not (get-in @state [:run :register (keyword (str "conspiracy-" title)) (:cid current-ice)])))) @@ -125,7 +125,7 @@ state side (cond (= target "Yes") {:async true - :effect (effect (runner-install :runner (assoc eid :source card :source-type :runner-install) card {:msg-keys {:install-source card :display-origin true}}))} + :effect (req (runner-install state :runner (assoc eid :source card :source-type :runner-install) card {:msg-keys {:install-source card :display-origin true}}))} ;; Add a register to note that the player was already asked about installing, ;; to prevent multiple copies from prompting multiple times. (= target "No") {:effect (req (swap! state assoc-in [:run :register (keyword (str "conspiracy-" title)) (:cid current-ice)] true))} @@ -160,8 +160,8 @@ :msg (msg "increase its strength from " (get-strength card) " to " (+ strength (get-strength card))) :async true - :effect (effect (pump card strength) - (continue-ability (break-sub nil strength subtype {:repeatable false}) (get-card state card) nil)) + :effect (req (pump state side card strength) + (continue-ability state side (break-sub nil strength subtype {:repeatable false}) (get-card state card) nil)) :pump strength})) (def heap-breaker-auto-pump-and-break @@ -272,18 +272,18 @@ (can-pay? state :runner eid card nil [(->c :credit 2)]))) :async true :effect - (effect + (req (continue-ability - {:optional + state side {:optional {:prompt (str "Pay " cost " [Credits] to make " (:title (:ice context)) " gain " ice-type "?") :yes-ability {:cost [(->c :credit cost)] :msg (msg "make " (:title current-ice) " gain " ice-type) - :effect (effect (register-once {:once :per-turn} card) + :effect (req (register-once state side {:once :per-turn} card) (register-lingering-effect - card + state side card (let [ice current-ice] {:type :gain-subtype :duration :end-of-encounter @@ -299,8 +299,8 @@ {:events [{:event :successful-run :silent true :async true - :effect (effect (system-msg (str "places 1 virus counter on " (:title card))) - (add-counter eid card :virus 1 nil))}] + :effect (req (system-msg state side (str "places 1 virus counter on " (:title card))) + (add-counter state side eid card :virus 1 nil))}] :abilities [(break-sub [(->c :any-virus-counter 1)] 1 ice-type) (strength-pump [(->c :any-virus-counter 1)] 1)]})) @@ -382,8 +382,8 @@ :req (req (and (all-subs-broken-by-card? (:ice context) card) (first-event? state side :subroutines-broken #(all-subs-broken-by-card? (:ice (first %)) card)))) :async true - :effect (effect (continue-ability - {:prompt "Choose 1 card in the grip to trash" + :effect (req (continue-ability + state side {:prompt "Choose 1 card in the grip to trash" :waiting-prompt true :async true :choices {:card #(and (in-hand? %) @@ -469,7 +469,7 @@ (all-subs-broken-by-card? (:ice context) card)))))) :msg "make the Corp lose 1 [Credits]" :async true - :effect (effect (lose-credits :corp eid 1))}]})) + :effect (req (lose-credits state :corp eid 1))}]})) (defcard "Analog Dreamers" (let [ability (successful-run-replace-breach @@ -481,8 +481,8 @@ (not (faceup? %)) (zero? (get-counters % :advancement)))} :msg (msg "shuffle " (card-str state target) " into R&D") - :effect (effect (move :corp target :deck) - (shuffle! :corp :deck))}})] + :effect (req (move state :corp target :deck) + (shuffle! state :corp :deck))}})] {:abilities [(run-server-ability :rd {:action true :cost [(->c :click 1)] :events [ability]})]})) @@ -503,14 +503,14 @@ {:on-install {:cost [(->c :x-credits)] :msg (msg "place " (quantify (cost-value eid :x-credits) "power counter") " on itself") :async true - :effect (effect (add-counter eid card :power (cost-value eid :x-credits) nil))} + :effect (req (add-counter state side eid card :power (cost-value eid :x-credits) nil))} :abilities [(break-sub 1 1 "All" {:req (req (= (get-strength current-ice) (get-strength card)))})] :static-abilities [(breaker-strength-bonus (req (get-counters card :power)))]})) (defcard "Au Revoir" {:events [{:event :jack-out :async true - :effect (effect (gain-credits eid 1)) + :effect (req (gain-credits state side eid 1)) :msg "gain 1 [Credits]"}]}) (defcard "Audrey v2" @@ -521,7 +521,7 @@ :once-per-instance true :req (req (:accessed target)) :async true - :effect (effect (add-counter :runner eid card :virus 1 nil)) + :effect (req (add-counter state :runner eid card :virus 1 nil)) :msg "place 1 virus counter on itself"}]})) (defcard "Aumakua" @@ -530,16 +530,16 @@ {:label "Place 1 virus counter" :msg "manually place 1 virus counter on itself" :async true - :effect (effect (add-counter eid card :virus 1 nil))}] + :effect (req (add-counter state side eid card :virus 1 nil))}] :static-abilities [(breaker-strength-bonus (req (get-virus-counters state card)))] :events [{:event :end-breach-server :req (req (not (or (:did-steal target) (:did-trash target)))) :async true - :effect (effect (add-counter eid card :virus 1 nil))} + :effect (req (add-counter state side eid card :virus 1 nil))} {:event :expose :async true - :effect (effect (add-counter eid card :virus (count (:cards context)) nil))}]})) + :effect (req (add-counter state side eid card :virus (count (:cards context)) nil))}]})) (defcard "Aurora" (auto-icebreaker {:abilities [(break-sub 2 1 "Barrier") @@ -590,14 +590,14 @@ :autoresolve (get-autoresolve :auto-place-credit) :prompt (msg "Place 1 credit on " (:title card) "?") :yes-ability {:async true - :effect (effect (add-counter eid card :credit 1 nil))}}}] + :effect (req (add-counter state side eid card :credit 1 nil))}}}] :abilities [{:label "Take all hosted credits" :async true ;; Cannot trash unless there are counters (so game state changes) :req (req (pos? (get-counters card :credit))) :msg (msg "gain " (get-counters card :credit) " [Credits]") :cost [(->c :trash-can)] - :effect (effect (gain-credits eid (get-counters card :credit)))} + :effect (req (gain-credits state side eid (get-counters card :credit)))} (set-autoresolve :auto-place-credit "Bankroll placing credits on itself")]}) (defcard "Banner" @@ -625,7 +625,7 @@ (defcard "Begemot" (auto-icebreaker {:on-install {:async true - :effect (effect (damage eid :brain 1 {:card card}))} + :effect (req (damage state side eid :brain 1 {:card card}))} :abilities [(break-sub 1 0 "Barrier")] :static-abilities [(breaker-strength-bonus (req (:brain-damage runner)))]})) @@ -633,7 +633,7 @@ (auto-icebreaker {:events [{:event :encounter-ice :req (req (has-subtype? (:ice context) "Barrier")) :msg (msg "gain " (count (:subroutines (:ice context))) " strength") - :effect (effect (pump card (count (:subroutines (:ice context)))))}] + :effect (req (pump state side card (count (:subroutines (:ice context)))))}] :abilities [(break-sub 2 2 "Barrier")]})) (defcard "Bishop" @@ -664,7 +664,7 @@ (not-any? (fn [c] (has-subtype? c "Caïssa")) (:hosted %))))} :msg (msg "host itself on " (card-str state target)) - :effect (effect (host target card))} + :effect (req (host state side target card))} card nil)))}] :static-abilities [{:type :ice-strength :req (req (and (= (:cid target) @@ -709,7 +709,7 @@ :data {:counter {:virus 1}} :events [{:event :runner-turn-begins :async true - :effect (effect (add-counter eid card :virus 1 nil))}] + :effect (req (add-counter state side eid card :virus 1 nil))}] :abilities [(break-sub [(->c :virus 1)] 1 "All" {:req (req (same-card? current-ice (:host card)))})]}) @@ -725,7 +725,7 @@ (not (facedown? %)) (not (has-subtype? % "Virus")))} :msg (msg "add " (:title target) " to the top of the stack") - :effect (effect (move (get-card state target) :deck {:front true}))}]})) + :effect (req (move state side (get-card state target) :deck {:front true}))}]})) (defcard "Breach" (central-only (break-sub 2 3 "Barrier") @@ -766,7 +766,7 @@ (first-event? state side :subroutines-broken #(all-subs-broken-by-card? (:ice (first %)) card)))) :msg "gain 2 [Credits]" :async true - :effect (effect (gain-credits :runner eid 2))}]})) + :effect (req (gain-credits state :runner eid 2))}]})) (defcard "Buzzsaw" (auto-icebreaker {:abilities [(break-sub 1 2 "Code Gate") @@ -775,7 +775,7 @@ (defcard "Cache" {:abilities [{:cost [(->c :virus 1)] :async true - :effect (effect (gain-credits eid 1)) + :effect (req (gain-credits state side eid 1)) :keep-menu-open :while-virus-tokens-left :msg "gain 1 [Credits]"}] :data {:counter {:virus 3}}}) @@ -808,17 +808,17 @@ :silent true :req (req (= :rd (target-server context))) :async true - :effect (effect (add-counter eid card :virus 1 nil))}]}) + :effect (req (add-counter state side eid card :virus 1 nil))}]}) (defcard "Chameleon" (auto-icebreaker {:on-install {:prompt "Choose one" :choices ["Barrier" "Code Gate" "Sentry"] :msg (msg "choose " target) - :effect (effect (update! (assoc card :subtype-target target)))} + :effect (req (update! state side (assoc card :subtype-target target)))} :events [{:event :runner-turn-ends :msg "add itself to Grip" :interactive (req true) - :effect (effect (move card :hand))}] + :effect (req (move state side card :hand))}] :abilities [(break-sub 1 1 "All" {:req (req (if-let [subtype (:subtype-target card)] (has-subtype? current-ice subtype) true))})]})) @@ -880,7 +880,7 @@ :req (req (= (:active-player @state) :runner)) :async true :keep-menu-open :while-power-tokens-left - :effect (effect (gain-credits eid 2)) + :effect (req (gain-credits state side eid 2)) :msg "gain 2 [Credits]"}] :data {:counter {:power 2}}}) @@ -889,7 +889,7 @@ :req (req (ice? (:card target))) :msg "draw 1 card" :async true - :effect (effect (draw :runner eid 1))}]}) + :effect (req (draw state :runner eid 1))}]}) (defcard "Conduit" {:events [{:event :run-ends @@ -901,13 +901,13 @@ :prompt (msg "Place 1 virus counter on " (:title card) "?") :yes-ability {:msg "place 1 virus counter on itself" :async true - :effect (effect (add-counter eid card :virus 1 nil))} - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card) " to place 1 virus counter on itself")))}}} + :effect (req (add-counter state side eid card :virus 1 nil))} + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card) " to place 1 virus counter on itself")))}}} {:event :successful-run :req (req (and (= :rd (target-server context)) this-card-run)) - :effect (effect (register-events - card [(breach-access-bonus :rd (max 0 (get-virus-counters state card)) {:duration :end-of-run})]))}] + :effect (req (register-events + state side card [(breach-access-bonus :rd (max 0 (get-virus-counters state card)) {:duration :end-of-run})]))}] :abilities [(run-server-ability :rd {:action true :cost [(->c :click 1)]}) (set-autoresolve :auto-place-counter "Conduit placing virus counters on itself")]}) @@ -920,7 +920,7 @@ :effect (req (let [amt-trashed (count (filter #(corp? (:card %)) targets)) sing-ab {:optional {:prompt (msg "Place 1 virus counter on " (:title card) "?") :autoresolve (get-autoresolve :auto-place-counter) - :yes-ability {:effect (effect (add-counter :runner eid card :virus 1 nil)) + :yes-ability {:effect (req (add-counter state :runner eid card :virus 1 nil)) :async true :msg "place 1 virus counter on itself"}}} mult-ab {:prompt (msg "Place virus counters on " (:title card) "?") @@ -928,7 +928,7 @@ :default (req amt-trashed)} :msg (msg "place " (quantify target "virus counter") " on itself") :async true - :effect (effect (add-counter :runner eid card :virus target nil))} + :effect (req (add-counter state :runner eid card :virus target nil))} ab (if (= 1 amt-trashed) sing-ab mult-ab)] (continue-ability state side ab card targets)))}] :abilities [{:action true @@ -986,9 +986,9 @@ (ice? target) (= (target-server (:run @state)) (second (get-zone target)))))} :async true - :effect (effect + :effect (req (continue-ability - (let [first-ice target] + state side (let [first-ice target] {:prompt "Choose a piece of ice to swap with" :choices {:req (req (and (installed? target) (ice? target) @@ -1013,7 +1013,7 @@ (has-subtype? current-ice "Barrier"))) :keep-menu-open true :msg (msg "give -3 strength to " (:title current-ice)) - :effect (effect (pump-ice current-ice -3)) + :effect (req (pump-ice state side current-ice -3)) :cost [(->c :credit 1 {:stealth :all-stealth})]}]})) (defcard "Cradle" @@ -1045,7 +1045,7 @@ :keep-menu-open :while-clicks-left :msg "place 1 virus counter on itself" :async true - :effect (effect (add-counter eid card :virus 1 nil))}] + :effect (req (add-counter state side eid card :virus 1 nil))}] :events [{:event :end-of-encounter :req (req (any-subs-broken-by-card? (:ice context) card)) :msg (msg (if (can-pay? state side eid card nil [(->c :virus 1)]) @@ -1080,8 +1080,8 @@ (seq (filter corp? (:hosted card))))) :prompt "1 [Credits]: Trash this program to access 2 additional cards from HQ?" :yes-ability {:async true - :effect (effect (access-bonus :hq 2) - (effect-completed eid)) + :effect (req (access-bonus state side :hq 2) + (effect-completed state side eid)) :cost [(->c :credit 1) (->c :trash-can)] :msg "access 2 additional cards from HQ"}}}] :interactions {:access-ability {:label "Host card" @@ -1113,7 +1113,7 @@ :req (req (all-subs-broken-by-card? (:ice context) card)) :msg "place 1 power counter on itself" :async true - :effect (effect (add-counter eid card :power 1 nil))}]})) + :effect (req (add-counter state side eid card :power 1 nil))}]})) (defcard "Customized Secretary" (letfn [(custsec-host [cards] @@ -1153,8 +1153,8 @@ {:on-install {:prompt "Choose a server" :msg (msg "target " target) :choices (req servers) - :effect (effect (update! (assoc card :card-target target)))} - :leave-play (effect (update! (dissoc card :card-target))) + :effect (req (update! state side (assoc card :card-target target)))} + :leave-play (req (update! state side (dissoc card :card-target))) :abilities [(break-sub 1 1 "Code Gate" {:req (req (if (:card-target card) (#{(last (server->zone state (:card-target card)))} (target-server run)) true))}) @@ -1189,7 +1189,7 @@ :msg "place 1 virus counter on itself" :req (req (:runner-phase-12 @state)) :async true - :effect (effect (add-counter eid card :virus 1 nil))}] + :effect (req (add-counter state side eid card :virus 1 nil))}] :static-abilities [(breaker-strength-bonus (get-x-fn))]})) (defcard "Datasucker" @@ -1197,20 +1197,20 @@ :silent true :req (req (is-central? (target-server context))) :async true - :effect (effect (add-counter eid card :virus 1 nil))}] + :effect (req (add-counter state side eid card :virus 1 nil))}] :abilities [{:cost [(->c :virus 1)] :label "Give -1 strength to current piece of ice" :req (req (and (rezzed? current-ice) (get-current-encounter state))) :keep-menu-open :while-virus-tokens-left :msg (msg "give -1 strength to " (:title current-ice)) - :effect (effect (pump-ice current-ice -1))}]}) + :effect (req (pump-ice state side current-ice -1))}]}) (defcard "DaVinci" {:events [{:event :successful-run :silent true :async true - :effect (effect (add-counter eid card :power 1 nil))}] + :effect (req (add-counter state side eid card :power 1 nil))}] :abilities [{:req (req (some #(and (or (hardware? %) (program? %) (resource? %)) @@ -1220,9 +1220,9 @@ :label "install a card from the grip" :cost [(->c :trash-can)] :async true - :effect (effect + :effect (req (continue-ability - {:waiting-prompt true + state side {:waiting-prompt true :prompt "Choose a card to install" :choices {:req (req (and (in-hand*? state target) (or (hardware? target) @@ -1231,8 +1231,8 @@ (<= (install-cost state side target) (get-counters (cost-target eid :trash-can) :power))))} :async true - :effect (effect - (runner-install (assoc eid :source card :source-type :runner-install) + :effect (req + (runner-install state side (assoc eid :source card :source-type :runner-install) target {:ignore-install-cost true :msg-keys {:install-source card :include-cost-from-eid eid @@ -1243,14 +1243,14 @@ {:events [{:event :successful-run :silent true :async true - :effect (effect (add-counter eid card :virus 1 nil)) + :effect (req (add-counter state side eid card :virus 1 nil)) :req (req (= :rd (target-server context)))} {:event :runner-turn-begins :req (req (>= (get-virus-counters state card) 3)) :msg "look at the top card of R&D" :async true - :effect (effect (continue-ability - {:prompt (req (->> corp :deck first :title (str "The top card of R&D is "))) + :effect (req (continue-ability + state side {:prompt (req (->> corp :deck first :title (str "The top card of R&D is "))) :choices ["OK"]} card nil))}]}) @@ -1277,7 +1277,7 @@ :autoresolve (get-autoresolve :auto-fire) :yes-ability {:msg "access 1 additional card from R&D" :cost [(->c :power 1)] - :effect (effect (access-bonus :rd 1))}}}] + :effect (req (access-bonus state side :rd 1))}}}] :abilities [(set-autoresolve :auto-fire "Devadatta Drone")]}) (defcard "Dhegdheer" @@ -1302,7 +1302,7 @@ (defcard "Diwan" {:on-install {:prompt "Choose a server" :choices (req servers) - :effect (effect (update! (assoc card :card-target target)))} + :effect (req (update! state side (assoc card :card-target target)))} :static-abilities [{:type :install-cost :req (req (let [serv (:server (second targets))] (= serv (:card-target card)))) @@ -1376,7 +1376,7 @@ :async true :interactive (req true) :waiting-prompt true - :effect (effect (continue-ability rvl card nil))}]})) + :effect (req (continue-ability state side rvl card nil))}]})) (defcard "Euler" (auto-icebreaker {:abilities [(break-sub 0 1 "Code Gate" {:req (req (= :this-turn (installed? card)))}) @@ -1394,7 +1394,7 @@ :ability {:msg (msg "reveal " (enumerate-cards (:hand corp) :sorted) " from HQ") :async true - :effect (effect (reveal eid (:hand corp)))}})] + :effect (req (reveal state side eid (:hand corp)))}})] {:abilities [(run-server-ability :hq {:action true :cost [(->c :click 1)] :events [ability]})]})) @@ -1406,7 +1406,7 @@ :async true :req (req (any-subs-broken-by-card? (:ice context) card)) :msg (msg "trash " (:title card)) - :effect (effect (trash eid card {:cause :runner-ability + :effect (req (trash state side eid card {:cause :runner-ability :cause-card card}))}]})) (defcard "False Echo" @@ -1446,7 +1446,7 @@ {:label "+X strength for the remainder of the run (using at least 1 stealth [Credits])" :cost [(->c :x-credits 0 {:stealth 1})] :prompt "How many credits do you want to spend?" - :effect (effect (pump card (cost-value eid :x-credits) :end-of-run)) + :effect (req (pump state side card (cost-value eid :x-credits) :end-of-run)) :msg (msg "increase strength by " (cost-value eid :x-credits) " for the remainder of the run")}]}) @@ -1485,15 +1485,15 @@ {:data {:counter {:virus 1}} :events [{:event :runner-turn-begins :async true - :effect (effect (add-counter eid card :virus 1 nil))}] + :effect (req (add-counter state side eid card :virus 1 nil))}] :abilities [{:action true :change-in-game-state {:req (req (pos? (get-virus-counters state card)))} :cost [(->c :click 1) (->c :trash-can)] :label "Gain 2 [Credits] for each hosted virus counter" :msg (msg (str "gain " (* 2 (get-virus-counters state card)) " [Credits]")) :async true - :effect (effect (play-tiered-sfx "click-credit" (* 2 (get-virus-counters state card)) 3) - (gain-credits eid (* 2 (get-virus-counters state card))))}]}) + :effect (req (play-tiered-sfx state side "click-credit" (* 2 (get-virus-counters state card)) 3) + (gain-credits state side eid (* 2 (get-virus-counters state card))))}]}) (defcard "Flashbang" (auto-icebreaker {:abilities [{:label "Derez a Sentry being encountered" @@ -1510,7 +1510,7 @@ :once :per-encounter :async true :req (req (and this-server (same-card? current-ice (:host card)))) - :effect (effect (continue-ability (charge-ability state side) card nil))}]}) + :effect (req (continue-ability state side (charge-ability state side) card nil))}]}) (defcard "Force of Nature" (auto-icebreaker {:abilities [(break-sub 2 2 "Code Gate") @@ -1561,15 +1561,15 @@ {:events [{:event :corp-credit-gain :req (req (= :corp-click-credit (:action context))) :async true - :effect (effect (add-counter :runner eid card :virus 1 nil))} + :effect (req (add-counter state :runner eid card :virus 1 nil))} {:event :corp-click-draw :async true - :effect (effect (add-counter :runner eid card :virus 1 nil))}] + :effect (req (add-counter state :runner eid card :virus 1 nil))}] :abilities [{:action true :cost [(->c :click 1) (->c :trash-can)] :label "Gain credits" :async true - :effect (effect (gain-credits eid (get-virus-counters state card))) + :effect (req (gain-credits state side eid (get-virus-counters state card))) :msg (msg "gain " (get-virus-counters state card) " [Credits]")}]}) (defcard "Gourmand" @@ -1624,7 +1624,7 @@ (corp? (:card target)))) :msg (msg "place 1 virus counter on " (:title card)) :async true - :effect (effect (add-counter :runner eid card :virus 1 nil))}] + :effect (req (add-counter state :runner eid card :virus 1 nil))}] {:events [(assoc e :event :runner-trash) (assoc e :event :corp-trash)] :abilities [{:action true @@ -1633,7 +1633,7 @@ :change-in-game-state {:req (req (seq (:deck corp)))} :keep-menu-open :while-virus-tokens-left :msg "force the Corp to trash the top card of R&D" - :effect (effect (mill :corp eid :corp 1))}]})) + :effect (req (mill state :corp eid :corp 1))}]})) (defcard "GS Sherman M3" (global-sec-breaker "Barrier")) @@ -1673,9 +1673,9 @@ :yes-ability {:prompt "Choose a card in Archives" :choices (req (cancellable (:discard corp) :sorted)) :msg (msg "host " (:title target) " on itself instead of accessing it") - :effect (effect - (update! (assoc-in card [:special :host-available] false)) - (host card target))}}} + :effect (req + (update! state side (assoc-in card [:special :host-available] false)) + (host state side card target))}}} card nil)))} {:event :pre-access-card :req (req (let [target (:accessed-card context)] @@ -1701,14 +1701,14 @@ {:optional {:prompt "Host face-down card on this program instead of accessing it?" :yes-ability {:msg "host a facedown card on itself instead of accessing it" - :effect (effect (update! (assoc-in card [:special :host-available] false)) - (host card target-card))}}} + :effect (req (update! state side (assoc-in card [:special :host-available] false)) + (host state side card target-card))}}} (or is-agenda? is-poison?) {:optional {:prompt (msg "Host " (:title target-card) " on this program instead of accessing it?") :yes-ability {:msg (msg "host " (:title target-card) " on itself instead of accessing it") - :effect (effect (update! (assoc-in card [:special :host-available] false)) - (host card target-card))}}}) + :effect (req (update! state side (assoc-in card [:special :host-available] false)) + (host state side card target-card))}}}) card nil)))} {:event :purge :msg "force the Corp to trash 2 cards from HQ at random, then trash itself" @@ -1728,7 +1728,7 @@ {:events [{:event :successful-run :silent true :async true - :effect (effect (add-counter eid card :virus 1 nil))}] + :effect (req (add-counter state side eid card :virus 1 nil))}] :abilities [{:action true :cost [(->c :click 1) (->c :virus 2)] :keep-menu-open :while-2-virus-tokens-left @@ -1741,7 +1741,7 @@ :prompt "Choose a card to trash" :choices (req (filter corp? (:hand corp))) :async true - :effect (effect (trash eid target {:cause-card card + :effect (req (trash state side eid target {:cause-card card :cause :forced-to-trash}))} card nil))}]}) @@ -1786,15 +1786,15 @@ {:cost [(->c :credit 2)] :msg "place 1 power counter" :async true - :effect (effect (add-counter eid card :power 1 nil))}] + :effect (req (add-counter state side eid card :power 1 nil))}] :static-abilities [(breaker-strength-bonus (req (get-counters card :power)))]})) (defcard "Hyperdriver" {:flags {:runner-phase-12 (req true)} :abilities [{:label "Remove Hyperdriver from the game to gain [Click] [Click] [Click]" :req (req (:runner-phase-12 @state)) - :effect (effect (move card :rfg) - (gain-clicks 3)) + :effect (req (move state side card :rfg) + (gain-clicks state side 3)) :msg "gain [Click][Click][Click]"}]}) (defcard "Ika" @@ -1806,7 +1806,7 @@ (installed? target) (can-host? state target)))} :msg (msg "host itself on " (card-str state target)) - :effect (effect (host target card))} + :effect (req (host state side target card))} (break-sub 1 2 "Sentry") (strength-pump 2 3)]})) @@ -1821,14 +1821,14 @@ :msg (msg "trash " (:title target) " at no cost") :once :per-turn :async true - :effect (effect (trash eid (assoc target :seen true) + :effect (req (trash state side eid (assoc target :seen true) {:accessed true :cause-card card}))}}}) (defcard "Incubator" {:events [{:event :runner-turn-begins :async true - :effect (effect (add-counter eid card :virus 1 nil))}] + :effect (req (add-counter state side eid card :virus 1 nil))}] :abilities [{:action true :cost [(->c :click 1) (->c :trash-can)] :label "move hosted virus counters" @@ -1836,7 +1836,7 @@ :choices {:card #(and (installed? %) (has-subtype? % "Virus"))} :async true - :effect (effect (add-counter eid target :virus (get-counters card :virus) nil))}]}) + :effect (req (add-counter state side eid target :virus (get-counters card :virus) nil))}]}) (defcard "Inti" (auto-icebreaker {:abilities [(break-sub 1 1 "Barrier") @@ -1854,9 +1854,9 @@ (all-subs-broken-by-card? (:ice context) card)))))) :async true :effect - (effect + (req (continue-ability - (let [ice (:ice context)] + state side (let [ice (:ice context)] {:optional {:prompt (str "Swap " (:title ice) " with another ice?") :yes-ability @@ -1866,14 +1866,14 @@ (not (same-card? % ice)))} :msg (msg "swap the positions of " (card-str state ice) " and " (card-str state target)) - :effect (effect (swap-ice (get-card state ice) (get-card state target)))}}}) + :effect (req (swap-ice state side (get-card state ice) (get-card state target)))}}}) card nil))}]})) (defcard "Ixodidae" {:events [{:event :corp-credit-loss :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits :runner eid 1))} + :effect (req (gain-credits state :runner eid 1))} trash-on-purge]}) (defcard "K2CP Turbine" @@ -1881,7 +1881,7 @@ :req (req (and (has-subtype? target "Icebreaker") (not (has-subtype? target "AI")))) :value 2}] - :leave-play (effect (update-all-icebreakers))}) + :leave-play (req (update-all-icebreakers state side))}) (defcard "Keyhole" (let [ability (successful-run-replace-breach @@ -1894,8 +1894,8 @@ :msg (msg "trash " (:title target)) :choices (req (take 3 (:deck corp))) :async true - :effect (effect (shuffle! :corp :deck) - (trash eid (assoc target :seen true) {:cause-card card}))}})] + :effect (req (shuffle! state :corp :deck) + (trash state side eid (assoc target :seen true) {:cause-card card}))}})] {:abilities [(run-server-ability :rd {:action true :cost [(->c :click 1)] :events [ability]})]})) @@ -1929,7 +1929,7 @@ (can-host? state target) (not-any? (fn [c] (has-subtype? c "Caïssa")) (:hosted target)))))} :msg (msg "host itself on " (card-str state target)) - :effect (effect (host target card))} + :effect (req (host state side target card))} card nil)))} (break-sub 2 1 "All" {:req knight-req})]})) @@ -1941,7 +1941,7 @@ :req (req (same-card? (:ice context) (:host card))) :msg "gain 2 [Credits]" :async true - :effect (effect (gain-credits :runner eid 2))}]}) + :effect (req (gain-credits state :runner eid 2))}]}) (defcard "Laamb" (give-ice-subtype 2 "Barrier" @@ -1966,7 +1966,7 @@ {:async true :cost [(->c :power 1) (->c :credit (:cost accessed-card 0) {:stealth :all-stealth})] :msg (msg "trash " (:title accessed-card)) - :effect (effect (trash eid (assoc accessed-card :seen true) {:accessed true}))} + :effect (req (trash state side eid (assoc accessed-card :seen true) {:accessed true}))} card nil)))}} :data {:counter {:power 3}}}) @@ -1976,7 +1976,7 @@ :req (req (= :hq (target-server context))) :msg "force the Corp to lose 1 [Credits]" :async true - :effect (effect (lose-credits :corp eid 1))} + :effect (req (lose-credits state :corp eid 1))} trash-on-purge]}) (defcard "Laser Pointer" @@ -1984,8 +1984,8 @@ :skippable true :req (req (has-any-subtype? current-ice ["AP" "Observer" "Destroyer"])) :async true - :effect (effect (continue-ability - {:optional + :effect (req (continue-ability + state side {:optional {:prompt (msg "Trash this program to bypass " (card-str state current-ice) "?") @@ -2012,7 +2012,7 @@ :req (req (active-encounter? state)) :keep-menu-open :while-virus-tokens-left :msg (msg "give -1 strength to " (:title current-ice)) - :effect (effect (pump-ice current-ice -1))}]}) + :effect (req (pump-ice state side current-ice -1))}]}) (defcard "Leprechaun" {:static-abilities [{:type :can-host @@ -2029,7 +2029,7 @@ trojan {:on-install {:req (req (threat-level 4 state)) :msg "gain 3 strength for the remainder of the turn" - :effect (effect (pump card 3 :end-of-turn))} + :effect (req (pump state side card 3 :end-of-turn))} :abilities [(break-sub 1 1 "Sentry" {:req (req (protecting-same-server? current-ice (:host card)))}) (strength-pump 1 2)]}) @@ -2055,9 +2055,9 @@ :msg (msg "break " (quantify (cost-value eid :x-credits) "subroutine") " on " (card-str state current-ice)) :async true - :effect (effect + :effect (req (continue-ability - (when (pos? (cost-value eid :x-credits)) + state side (when (pos? (cost-value eid :x-credits)) (break-sub nil (cost-value eid :x-credits) "Barrier")) card nil))} (strength-pump 1 2)] @@ -2066,7 +2066,7 @@ (has-subtype? (:ice context) "Code Gate"))) :msg "place 1 power counter on itself" :async true - :effect (effect (add-counter eid card :power 1 nil))}]})) + :effect (req (add-counter state side eid card :power 1 nil))}]})) (defcard "Lustig" (trash-to-bypass (break-sub 1 1 "Sentry") @@ -2077,8 +2077,8 @@ :cost [(->c :click 1)] :keep-menu-open :while-clicks-left :async true - :effect (effect (play-sfx "click-credit-2") - (gain-credits eid 2)) + :effect (req (play-sfx state side "click-credit-2") + (gain-credits state side eid 2)) :msg "gain 2 [Credits]"}]}) (defcard "Makler" @@ -2092,7 +2092,7 @@ (all-subs-broken-by-card? (:ice context) card)))))) :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits :runner eid 1))}]})) + :effect (req (gain-credits state :runner eid 1))}]})) (defcard "Malandragem" {:data {:counter {:power 2}} @@ -2127,13 +2127,13 @@ :cost [(->c :x-credits)] :req (req (:runner-phase-12 @state)) :async true - :effect (effect (add-counter eid card :power (cost-value eid :x-credits) nil)) + :effect (req (add-counter state side eid card :power (cost-value eid :x-credits) nil)) :msg (msg "place " (quantify (cost-value eid :x-credits) "power counter") " on itself")} (break-sub [(->c :power 1)] 1) (strength-pump 2 2)] :events [{:event :runner-turn-ends :silent true - :effect (effect (update! (assoc-in card [:counter :power] 0)))}]})) + :effect (req (update! state side (assoc-in card [:counter :power] 0)))}]})) (defcard "Mantle" {:recurring 1 @@ -2155,9 +2155,9 @@ :req (req (all-subs-broken-by-card? (:ice context) card)) :msg "prevent the first 3 subroutines from resolving on the next encountered ice" :effect - (effect + (req (register-events - card + state side card (let [broken-ice (:ice context)] [{:event :encounter-ice :duration :end-of-run @@ -2178,9 +2178,9 @@ (<= (get-strength current-ice) (get-strength card)))) :msg (msg "break " (quantify (cost-value eid :x-credits) "subroutine") " on " (card-str state current-ice)) - :effect (effect + :effect (req (continue-ability - (when (pos? (cost-value eid :x-credits)) + state side (when (pos? (cost-value eid :x-credits)) (break-sub nil (cost-value eid :x-credits) "All" {:repeatable false})) card nil))} host-abi {:action true @@ -2222,7 +2222,7 @@ :duration :end-of-run :unregister-once-resolved true :async true - :effect (effect (trash eid card {:cause :runner-ability + :effect (req (trash state side eid card {:cause :runner-ability :cause-card card}))}]))}}) (strength-pump 1 1)]})) @@ -2230,18 +2230,18 @@ {:events [{:event :successful-run :req (req (= :rd (target-server context))) :async true - :effect (effect (add-counter eid card :virus 1 nil))} + :effect (req (add-counter state side eid card :virus 1 nil))} {:event :breach-server :automatic :pre-breach :async true :req (req (= :rd (:server context))) - :effect (effect (continue-ability - {:req (req (< 1 (get-virus-counters state card))) + :effect (req (continue-ability + state side {:req (req (< 1 (get-virus-counters state card))) :prompt "How many additional cards from R&D do you want to access?" :choices {:number (req (dec (get-virus-counters state card))) :default (req (dec (get-virus-counters state card)))} :msg (msg "access " (quantify target "additional card") " from R&D") - :effect (effect (access-bonus :rd (max 0 target)))} + :effect (req (access-bonus state side :rd (max 0 target)))} card nil))}]}) (defcard "Mimic" @@ -2253,7 +2253,7 @@ :label "remove X tags" :async true :msg (msg "remove " (quantify (cost-value eid :x-credits) "tag")) - :effect (effect (lose-tags :runner eid (cost-value eid :x-credits)))}]}) + :effect (req (lose-tags state :runner eid (cost-value eid :x-credits)))}]}) (defcard "MKUltra" (let [events (for [event [:run :approach-ice :encounter-ice :pass-ice :run-ends @@ -2351,8 +2351,8 @@ :choices (req ["Grip" "Stack" (when-not (zone-locked? state :runner :discard) "Heap")]) :msg (msg "search the " target " for a non-daemon program to install") - :effect (effect (continue-ability - (muse-abi (if (= "Stack" target) :deck + :effect (req (continue-ability + state side (muse-abi (if (= "Stack" target) :deck (if (= "Grip" target) :hand :discard))) card nil))}})) @@ -2365,7 +2365,7 @@ (let [self-rfg {:msg "remove itself from the game" :once :per-turn ;; prevents self triggering :interactive (req true) - :effect (effect (move card :rfg))}] + :effect (req (move state side card :rfg))}] (auto-icebreaker {:abilities [(break-sub 2 2 "All") (strength-pump 1 1)] @@ -2387,18 +2387,18 @@ {:events [{:event :successful-run :req (req (= :hq (target-server context))) :async true - :effect (effect (add-counter eid card :virus 1 nil))} + :effect (req (add-counter state side eid card :virus 1 nil))} {:event :breach-server :automatic :pre-breach :async true :req (req (= :hq (:server context))) - :effect (effect (continue-ability - {:req (req (< 1 (get-virus-counters state card))) + :effect (req (continue-ability + state side {:req (req (< 1 (get-virus-counters state card))) :prompt "How many additional cards from HQ do you want to access?" :choices {:number (req (dec (get-virus-counters state card))) :default (req (dec (get-virus-counters state card)))} :msg (msg "access " (quantify target "additional card") " from HQ") - :effect (effect (access-bonus :hq (max 0 target)))} + :effect (req (access-bonus state side :hq (max 0 target)))} card nil))}]}) (defcard "Net Shield" @@ -2420,7 +2420,7 @@ :req (req (all-subs-broken-by-card? (:ice context) card)) :msg "place 1 power counter on itself" :async true - :effect (effect (add-counter eid card :power 1 nil))}]})) + :effect (req (add-counter state side eid card :power 1 nil))}]})) (defcard "Nga" {:data {:counter {:power 3}} @@ -2439,10 +2439,10 @@ {:msg "remove 1 hosted power counter to sabotage 1" :async true :cost [(->c :power 1)] - :effect (effect (continue-ability - (sabotage-ability 1) + :effect (req (continue-ability + state side (sabotage-ability 1) card nil))} - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card))))}}}] + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card))))}}}] :abilities [(set-autoresolve :auto-fire "Nga")]}) (defcard "Ninja" @@ -2464,7 +2464,7 @@ :autoresolve (get-autoresolve :auto-fire) :yes-ability {:msg "access 1 additional card from R&D" :cost [(->c :power 1)] - :effect (effect (access-bonus :rd 1))}}}] + :effect (req (access-bonus state side :rd 1))}}}] :abilities [(set-autoresolve :auto-fire "Nyashia")]}) (defcard "Odore" @@ -2489,7 +2489,7 @@ :req (req (and (all-subs-broken-by-card? (:ice context) card) (first-event? state side :subroutines-broken #(all-subs-broken-by-card? (:ice (first %)) card)))) :async true - :effect (effect (continue-ability (charge-ability state side) card nil))}]})) + :effect (req (continue-ability state side (charge-ability state side) card nil))}]})) (defcard "Origami" {:static-abilities [{:type :hand-size @@ -2500,7 +2500,7 @@ (defcard "Overmind" (auto-icebreaker {:on-install {:async true - :effect (effect (add-counter eid card :power (available-mu state) nil))} + :effect (req (add-counter state side eid card :power (available-mu state) nil))} :abilities [(break-sub [(->c :power 1)] 1) (strength-pump 1 1)]})) @@ -2512,16 +2512,16 @@ (ice? %) (rezzed? %))} :async true - :effect (effect + :effect (req (continue-ability - (let [ice target] + state side (let [ice target] {:prompt "Choose one" :choices ["Sentry" "Code Gate" "Barrier"] :msg (msg "spend [Click] and make " (card-str state ice) " gain " target " until the end of the next run this turn") - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card {:type :gain-subtype :duration :end-of-next-run :req (req (same-card? ice target)) @@ -2545,9 +2545,9 @@ (#(disj % "Barrier" "Code Gate" "Sentry")) sort)) :msg (msg "make " (card-str state current-ice) " gain " target) - :effect (effect (register-once {:once :per-turn} card) + :effect (req (register-once state side {:once :per-turn} card) (register-lingering-effect - card + state side card (let [ice current-ice] {:type :gain-subtype :duration :end-of-run @@ -2567,9 +2567,9 @@ :break-req (req (and (active-encounter? state) (has-subtype? current-ice "Barrier"))) :async true - :effect (effect (pump card (cost-value eid :x-credits)) + :effect (req (pump state side card (cost-value eid :x-credits)) (continue-ability - (break-sub nil (cost-value eid :x-credits) "Barrier" {:repeatable false}) + state side (break-sub nil (cost-value eid :x-credits) "Barrier" {:repeatable false}) (get-card state card) nil)) :msg (msg "increase its strength from " (get-strength card) " to " (+ (cost-value eid :x-credits) (get-strength card)))}]] @@ -2663,7 +2663,7 @@ (= target (last (get-in @state (vec (concat [:corp] (:zone target)))))) (is-central? (second (get-zone target)))))} :msg (msg "host itself on " (card-str state target)) - :effect (effect (host target card))}]})) + :effect (req (host state side target card))}]})) (defcard "Peacock" (auto-icebreaker {:abilities [(break-sub 2 1 "Code Gate") @@ -2686,8 +2686,8 @@ :msg (msg "make " (card-str state current-ice) " gain " target " until end of the encounter") - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card (let [ice current-ice] {:type :gain-subtype :duration :end-of-encounter @@ -2712,9 +2712,9 @@ (pos? (count (:deck runner))))) :async true :effect - (effect + (req (continue-ability - (let [fired-subs (count (filter :fired (:subroutines (:ice context))))] + state side (let [fired-subs (count (filter :fired (:subroutines (:ice context))))] {:optional {:prompt (str "Trash the top card of the stack to trash " (quantify fired-subs "card") " from R&D?") :yes-ability @@ -2733,7 +2733,7 @@ :silent true :req (req (= :hq (target-server context))) :async true - :effect (effect (add-counter eid card :virus 1 nil))}] + :effect (req (add-counter state side eid card :virus 1 nil))}] :interactions {:pay-credits {:req (req (= :hq (get-in @state [:run :server 0]))) :type :recurring}}}) @@ -2781,7 +2781,7 @@ :cost [(->c :return-to-hand)]}}} card nil) (effect-completed state side eid)))} - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card))))}}}]}) + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card))))}}}]}) (defcard "Pipeline" (auto-icebreaker {:abilities [(break-sub 1 1 "Sentry") @@ -2792,13 +2792,13 @@ :choices (req servers) :msg (msg "target " target) :req (req (not (:card-target card))) - :effect (effect (update! (assoc card :card-target target)))} + :effect (req (update! state side (assoc card :card-target target)))} :events [{:event :successful-run :req (req (= (zone->name (:server context)) (:card-target (get-card state card)))) :msg "place 2 virus counters on itself" :async true - :effect (effect (add-counter :runner eid card :virus 2 nil))}]}) + :effect (req (add-counter state :runner eid card :virus 2 nil))}]}) (defcard "Pressure Spike" (letfn [(once [card] @@ -2902,7 +2902,7 @@ (first-event? state side :runner-trash (fn [targets] (some #(installed? (:card %)) targets))))) :msg "draw 1 card" - :effect (effect (draw :runner eid 1))}]}) + :effect (req (draw state :runner eid 1))}]}) (defcard "Refractor" (auto-icebreaker @@ -2922,7 +2922,7 @@ :automatic :gain-credits :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits eid 1))}]}) + :effect (req (gain-credits state side eid 1))}]}) (defcard "Rising Tide" (auto-icebreaker @@ -2951,7 +2951,7 @@ (gain-credits state :runner eid 3)))})) card nil)))} {:event :post-access-card - :effect (effect (update! (assoc-in card [:special :rng-guess] nil)))} + :effect (req (update! state side (assoc-in card [:special :rng-guess] nil)))} (let [highest-cost (fn [state card] (or (get-in card [:special :rng-highest]) @@ -2974,7 +2974,7 @@ :yes-ability {:prompt "Guess a number" :choices {:number (req (highest-cost state card))} :msg (msg "guess " target) - :effect (effect (update! (assoc-in card [:special :rng-guess] target)))}}})] + :effect (req (update! state side (assoc-in card [:special :rng-guess] target)))}}})] :abilities [(set-autoresolve :auto-fire "RNG Key")]}) (defcard "Rook" @@ -3004,7 +3004,7 @@ (= (last (get-zone target)) :ices) (not-any? (fn [c] (has-subtype? c "Caïssa")) (:hosted target)))))} :msg (msg "host itself on " (card-str state target)) - :effect (effect (host target card))} + :effect (req (host state side target card))} card nil)))}] :static-abilities [{:type :rez-cost :req (req (and (ice? target) @@ -3017,7 +3017,7 @@ :req (req (same-card? (:card context) (:host card))) :msg "gain 3 [Credits]" :async true - :effect (effect (gain-credits :runner eid 3))} + :effect (req (gain-credits state :runner eid 3))} {:event :derez :req (req (some #(same-card? % (:host card)) (:cards context))) ;; NOTE @@ -3027,7 +3027,7 @@ ;; - Apr 13 '24, nbkelly :msg "gain 3 [Credits]" :async true - :effect (effect (gain-credits :runner eid 3))}]}) + :effect (req (gain-credits state :runner eid 3))}]}) (defcard "Sadyojata" (swap-with-in-hand "Sadyojata" @@ -3071,7 +3071,7 @@ :choices {:req (req (and (program? target) (in-hand*? state target)))} :async true - :effect (effect (runner-install (assoc eid :source card :source-type :runner-install) target {:msg-keys {:install-source card + :effect (req (runner-install state side (assoc eid :source card :source-type :runner-install) target {:msg-keys {:install-source card :display-origin true :include-cost-from-eid eid}}))}]}) @@ -3088,9 +3088,9 @@ {:abilities [{:label "Install a program from the stack" :cost [(->c :trash-can) (->c :credit 2)] :async true - :effect (effect + :effect (req (continue-ability - {:prompt "Choose a program to install" + state side {:prompt "Choose a program to install" :choices (req (concat (->> (:deck runner) (filter @@ -3137,16 +3137,16 @@ (first-event? state side :pass-ice #(some valid-ctx? %))))) :interactive (req true) :async true - :effect (effect + :effect (req (continue-ability - (when-let [ice (get-card state (:ice context))] + state side (when-let [ice (get-card state (:ice context))] {:prompt (str "Swap " (:title ice) " with another ice?") :choices {:card #(and (installed? %) (ice? %) (not (same-card? % ice)))} :msg (msg "swap the positions of " (card-str state ice) " and " (card-str state target)) - :effect (effect (swap-ice ice (get-card state target)))}) + :effect (req (swap-ice state side ice (get-card state target)))}) card nil))}]}) (defcard "Slap Vandal" @@ -3228,7 +3228,7 @@ (defcard "Snowball" (auto-icebreaker {:abilities [(break-sub 1 1 "Barrier" {:additional-ability {:msg "gain +1 strength for the remainder of the run" - :effect (effect (pump card 1 :end-of-run))}}) + :effect (req (pump state side card 1 :end-of-run))}}) (strength-pump 1 1)]})) (defcard "Spike" @@ -3263,7 +3263,7 @@ (if (= 1 (count (filter #{(:title target)} card-titles))) (str "trash " (:title target)) (str "trash " position (:title target))))) - :effect (effect (trash :runner eid (assoc target :seen true) {:cause-card card}))} + :effect (req (trash state :runner eid (assoc target :seen true) {:cause-card card}))} card nil)))}})] {:abilities [(run-server-ability :rd {:action true :cost [(->c :click 1)] @@ -3285,7 +3285,7 @@ {:cost [(->c :credit 2)] :msg "place 1 power counter" :async true - :effect (effect (add-counter eid card :power 1 nil))}] + :effect (req (add-counter state side eid card :power 1 nil))}] :static-abilities [(breaker-strength-bonus (req (get-counters card :power)))]})) (defcard "Sūnya" @@ -3295,7 +3295,7 @@ :req (req (all-subs-broken-by-card? (:ice context) card)) :msg "place 1 power counter on itself" :async true - :effect (effect (add-counter eid card :power 1 nil))}]})) + :effect (req (add-counter state side eid card :power 1 nil))}]})) (defcard "Surfer" (letfn [(surf [state cice] @@ -3316,7 +3316,7 @@ (has-subtype? current-ice "Barrier"))) :label "Swap the piece of Barrier ice currently being encountered with a piece of ice directly before or after it" :async true - :effect (effect (continue-ability (surf state current-ice) card nil))}]})) + :effect (req (continue-ability state side (surf state current-ice) card nil))}]})) (defcard "Surveillance Network Key" {:implementation "Only implemented for click to draw" @@ -3331,8 +3331,8 @@ :once :per-turn :keep-menu-open :while-2-power-tokens-left :msg (msg "access 1 additional card from " name " for the remainder of the run") - :effect (effect (register-events - card [(breach-access-bonus server 1 {:duration :end-of-run})]))})] + :effect (req (register-events + state side card [(breach-access-bonus server 1 {:duration :end-of-run})]))})] {:implementation "Only implemented for click to draw" :abilities [(ttw-ab "R&D" :rd) (ttw-ab "HQ" :hq)] @@ -3352,7 +3352,7 @@ :yes-ability {:msg "place 1 power counter on itself" :async true - :effect (effect (add-counter eid card :power 1 nil))}}}] + :effect (req (add-counter state side eid card :power 1 nil))}}}] :abilities [{:req (req (get-current-encounter state)) :cost [(->c :power 2)] :label "Give non-AI icebreaker +3 strength" @@ -3362,7 +3362,7 @@ (installed? %))} :keep-menu-open :while-power-tokens-left :msg (msg "give +3 strength to " (:title target)) - :effect (effect (pump target 3))} + :effect (req (pump state side target 3))} (set-autoresolve :auto-place-counter "Takobi placing power counters on itself")]}) (defcard "Tapwrm" @@ -3372,7 +3372,7 @@ :once :per-turn :req (req (:runner-phase-12 @state)) :async true - :effect (effect (gain-credits eid (quot (:credit corp) 5)))}] + :effect (req (gain-credits state side eid (quot (:credit corp) 5)))}] {:req (req (some #{:hq :rd :archives} (:successful-run runner-reg))) :flags {:drip-economy true} :abilities [ability] @@ -3388,7 +3388,7 @@ :choices (req servers) :msg (msg "target " target) :req (req (not (:card-target card))) - :effect (effect (update! (assoc card :card-target target)))} + :effect (req (update! state side (assoc card :card-target target)))} prevent-sub {:event :pre-resolve-subroutine :duration :end-of-run :unregister-once-resolved true @@ -3402,12 +3402,12 @@ {:req (req (some #(= (:card-target card) %) runnable-servers))} :msg (msg "make a run on " (:card-target card) ". Prevent the first subroutine that would resolve from resolving") :async true - :effect (effect (register-events card [prevent-sub]) - (make-run eid (:card-target card) card))}] + :effect (req (register-events state side card [prevent-sub]) + (make-run state side eid (:card-target card) card))}] :events [(assoc ability :event :runner-turn-begins) {:event :runner-turn-ends :silent true - :effect (effect (update! (dissoc card :card-target)))}]})) + :effect (req (update! state side (dissoc card :card-target)))}]})) (defcard "Tranquilizer" trojan @@ -3437,15 +3437,15 @@ (defcard "Trope" {:events [{:event :runner-turn-begins :async true - :effect (effect (add-counter eid card :power 1 nil))}] + :effect (req (add-counter state side eid card :power 1 nil))}] :abilities [{:action true :req (req (not (zone-locked? state :runner :discard))) :label "shuffle cards from heap into stack" :async true :effect - (effect + (req (continue-ability - {:cost [(->c :click 1) (->c :remove-from-game)] + state side {:cost [(->c :click 1) (->c :remove-from-game)] :label "Reshuffle cards from heap into stack" :show-discard true :choices {:max (min (get-counters card :power) (count (:discard runner))) @@ -3503,7 +3503,7 @@ :req (req (any-subs-broken-by-card? (:ice context) card)) :msg "give the Corp 2 [Credits]" :async true - :effect (effect (gain-credits :corp eid 2))}]})) + :effect (req (gain-credits state :corp eid 2))}]})) (defcard "Umbrella" (let [corp-draw {:optional {:prompt "Draw 1 card?" @@ -3559,12 +3559,12 @@ :autoresolve (get-autoresolve :auto-place-counters) :prompt (msg "Place 1 power counter on " (:title card) "?") :yes-ability {:async true - :effect (effect (add-counter eid card :power 1 nil))}}}] + :effect (req (add-counter state side eid card :power 1 nil))}}}] :abilities [{:action true :cost [(->c :click 1) (->c :power 3)] :once :per-turn :msg "gain [Click][Click]" - :effect (effect (gain-clicks 2))} + :effect (req (gain-clicks state side 2))} (set-autoresolve :auto-place-counters "Upya placing counters on itself")]}) (defcard "Utae" @@ -3584,9 +3584,9 @@ (has-subtype? current-ice "Code Gate"))) :msg (msg "break " (quantify (cost-value eid :x-credits) "subroutine") " on " (card-str state current-ice)) - :effect (effect + :effect (req (continue-ability - (when (pos? (cost-value eid :x-credits)) + state side (when (pos? (cost-value eid :x-credits)) (break-sub nil (cost-value eid :x-credits) "Code Gate")) card nil))} (break-sub 1 1 "Code Gate" {:label "Break 1 Code Gate subroutine (Virtual restriction)" @@ -3679,7 +3679,7 @@ :req (req (and (active-encounter? state) (<= (get-strength current-ice) (get-strength card)))) :msg (msg "give -1 strength to " (:title current-ice)) - :effect (effect (pump-ice current-ice -1))} + :effect (req (pump-ice state side current-ice -1))} (strength-pump 1 1)]})) (defcard "Yog.0" diff --git a/src/clj/game/cards/resources.clj b/src/clj/game/cards/resources.clj index cc5bc332e4..00469fadc9 100644 --- a/src/clj/game/cards/resources.clj +++ b/src/clj/game/cards/resources.clj @@ -83,7 +83,7 @@ [game.core.update :refer [update!]] [game.core.virus :refer [get-virus-counters number-of-runner-virus-counters]] [game.core.winning :refer [check-win-by-agenda]] - [game.macros :refer [continue-ability effect msg req wait-for]] + [game.macros :refer [continue-ability msg req wait-for]] [game.utils :refer :all] [jinteki.utils :refer :all] [jinteki.validator :refer [legal?]] @@ -104,7 +104,7 @@ {:target-server target-server :ability {:async true - :effect (effect (runner-install eid card {:ignore-all-cost true + :effect (req (runner-install state side eid card {:ignore-all-cost true :msg-keys {:display-origin true :install-source card}}))}}) :location :hand) @@ -115,14 +115,14 @@ :ability {:async true :req (req (in-hand*? state card)) - :effect (effect (runner-install eid card {:ignore-all-cost true + :effect (req (runner-install state side eid card {:ignore-all-cost true :msg-keys {:display-origin true :install-source card}}))}}) :location :hosted)] :abilities [{:async true :cost [(->c :trash-can)] :msg message - :effect (effect (effect-fn eid card targets))}]}) + :effect (req (effect-fn state side eid card targets))}]}) (defn- move-virus-counter [state side eid from to count] @@ -145,7 +145,7 @@ :req (req (<= 3 (get-counters (get-card state card) :credit))) :interactive (req true) :async true - :effect (effect (continue-ability turn-ends-ability card targets))}] + :effect (req (continue-ability state side turn-ends-ability card targets))}] :abilities [ability]})) (defn trash-when-tagged @@ -228,7 +228,7 @@ (and (= 2 click-losses) (has-flag? state side :persistent :genetics-trigger-twice))))) :msg "gain [Click]" - :effect (effect (gain-clicks :runner 1))}]}) + :effect (req (gain-clicks state :runner 1))}]}) (defcard "Aeneas Informant" {:events [{:event :post-access-card @@ -241,7 +241,7 @@ (when-not (installed? (:accessed-card context)) (str " and reveal " (:title (:accessed-card context)))))) :async true - :effect (effect (gain-credits eid 1))}}}] + :effect (req (gain-credits state side eid 1))}}}] :abilities [(set-autoresolve :auto-fire "Aeneas Informant")]}) (defcard "Aesop's Pawnshop" @@ -266,8 +266,8 @@ (defcard "Akshara Sareen" {:in-play [:click-per-turn 1] :on-install {:msg "give each player 1 additional [Click] to spend during their turn" - :effect (effect (gain :corp :click-per-turn 1))} - :leave-play (effect (lose :corp :click-per-turn 1))}) + :effect (req (gain state :corp :click-per-turn 1))} + :leave-play (req (lose state :corp :click-per-turn 1))}) (defcard "Algo Trading" {:flags {:runner-phase-12 (req (pos? (:credit runner)))} @@ -296,7 +296,7 @@ (defcard "All-nighter" {:abilities [{:action true :cost [(->c :click 1) (->c :trash-can)] - :effect (effect (gain-clicks 2)) + :effect (req (gain-clicks state side 2)) :msg "gain [Click][Click]"}]}) (defcard "Always Be Running" @@ -367,9 +367,9 @@ :choices (req (cancellable (filter #(not (event? %)) (:deck runner)) :sorted)) :cancel (assoc fail-to-find! :cost [(->c :forfeit)]) :async true - :effect (effect (trigger-event :searched-stack) - (shuffle! :deck) - (runner-install eid target {:msg-keys {:install-source card + :effect (req (trigger-event state side :searched-stack) + (shuffle! state side :deck) + (runner-install state side eid target {:msg-keys {:install-source card :include-cost-from-eid eid :display-origin true}}))}]}) @@ -379,13 +379,13 @@ :once :per-turn :label "Give encountered ice -2 strength" :msg (msg "give " (card-str state current-ice) " -2 strength for the remainder of the encounter") - :effect (effect (pump-ice current-ice -2 :end-of-encounter))} + :effect (req (pump-ice state side current-ice -2 :end-of-encounter))} {:label "Trash encountered ice" :async true :req (req (and (active-encounter? state) (not (pos? (ice-strength state side current-ice))))) :cost [(->c :credit 2) (->c :trash-can)] - :effect (effect (trash eid current-ice {:cause-card card})) + :effect (req (trash state side eid current-ice {:cause-card card})) :msg (msg "trash " (card-str state current-ice))}]}) (defcard "Asmund Pudlat" @@ -448,9 +448,9 @@ :req (req (and (virus-program? (:card context)) (first-event? state side :runner-install #(virus-program? (:card (first %)))))) :async true - :effect (effect + :effect (req (continue-ability - (sabotage-ability 1) + state side (sabotage-ability 1) card nil))}]}) (defcard "Backstitching" @@ -512,7 +512,7 @@ :prompt (msg "Choose a copy of " (:title card) " to use") :choices {:card #(and (installed? %) (= (:title %) (:title card)))} - :effect (effect (continue-ability (select-credits-ability target) target nil))} + :effect (req (continue-ability state side (select-credits-ability target) target nil))} card nil) (continue-ability state side (select-credits-ability card) card nil))))}})]}) @@ -526,8 +526,8 @@ :async true :req (req (and (hardware? (:card context)) (= [:hand] (:previous-zone (:card context))))) - :effect (effect (continue-ability - (let [hw (:title (:card context))] + :effect (req (continue-ability + state side (let [hw (:title (:card context))] {:optional {:req (req (some #(when (= (:title %) hw) %) (all-cards-in-hand* state :runner))) :prompt (msg "Install another copy of " hw "?") @@ -544,7 +544,7 @@ :events [{:event :runner-turn-begins :automatic :lose-clicks :msg "lose [Click]" - :effect (effect (lose-clicks 1))}]}) + :effect (req (lose-clicks state side 1))}]}) (defcard "Beatriz Friere Gonzalez" {:abilities [(run-server-ability @@ -636,8 +636,8 @@ :req (req (seq (:hand runner))) :choices {:card #(and (in-hand? %) (runner? %))} - :effect (effect (move target :deck) - (shuffle! :deck))} + :effect (req (move state side target :deck) + (shuffle! state side :deck))} card nil)))}]}) (defcard "Bloo Moose" @@ -650,8 +650,8 @@ (runner? %))} :msg (msg "remove " (:title target) " from the game and gain 2 [Credits]") :async true - :effect (effect (move target :rfg) - (gain-credits eid 2))}] + :effect (req (move state side target :rfg) + (gain-credits state side eid 2))}] {:flags {:runner-phase-12 (req (not (zone-locked? state :runner :discard)))} :events [(assoc ability :event :runner-turn-begins @@ -724,9 +724,9 @@ :change-in-game-state {:req (req (seq runnable-servers))} :async true :effect - (effect + (req (register-events - card + state side card [{:event :approach-ice :unregister-once-resolved true :duration :end-of-run @@ -758,7 +758,7 @@ (do (system-msg state :runner (str "can't afford to pay to bypass " (:title ice))) (effect-completed state side eid))))))}}}]) - (make-run eid target card))}]}) + (make-run state side eid target card))}]}) (defcard "Chatterjee University" {:abilities [{:action true @@ -817,7 +817,7 @@ :req (req tagged) :unsuccessful {:msg "remove 1 tag" :async true - :effect (effect (lose-tags :runner eid 1))}}}]}) + :effect (req (lose-tags state :runner eid 1))}}}]}) (defcard "Clan Vengeance" {:events [{:event :damage @@ -831,7 +831,7 @@ :cost [(->c :trash-can)] :msg (msg "trash " (quantify (min (get-counters card :power) (count (:hand corp))) "card") " from HQ") - :effect (effect (trash-cards eid (take (min (get-counters card :power) (count (:hand corp))) + :effect (req (trash-cards state side eid (take (min (get-counters card :power) (count (:hand corp))) (shuffle (:hand corp))) {:cause-card card}))}]}) (defcard "Climactic Showdown" @@ -858,7 +858,7 @@ :req (req (#{:hq :rd} (:server context))) :once :per-turn :msg (msg "access 2 additional cards from " (zone->name target)) - :effect (effect (access-bonus :runner (:server context) 2))}]))}})] + :effect (req (access-bonus state :runner (:server context) 2))}]))}})] {:events [{:event :runner-turn-begins :async true :interactive (req true) @@ -872,8 +872,8 @@ :msg (msg "choose " (zone->name (unknown->kw target)) " and remove itself from the game") :async true - :effect (effect (continue-ability - :corp + :effect (req (continue-ability + state :corp (trash-or-bonus (rest (server->zone state target))) card nil))} {:msg "remove itself from the game"}) @@ -885,7 +885,7 @@ :req (req (ice? (:card context))) :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits :runner eid 1))}] + :effect (req (gain-credits state :runner eid 1))}] :interactions {:pay-credits {:req (req (= :trace (:source-type eid))) :type :recurring}}}) @@ -906,7 +906,7 @@ {:events [{:event :corp-click-draw :msg (msg "force the Corp to reveal that they drew " (:title (:card context))) :async true - :effect (effect (reveal eid (:card context)))}]}) + :effect (req (reveal state side eid (:card context)))}]}) (defcard "Councilman" {:events [{:event :rez @@ -917,9 +917,9 @@ [(->c :credit (rez-cost state :corp (:card context)))]))) :async true :effect - (effect + (req (continue-ability - {:optional + state side {:optional {:waiting-prompt true :prompt (msg "Trash " (:title card) " and pay " (rez-cost state :corp (:card context)) " [Credits] to derez " (:title (:card context)) "?") @@ -959,7 +959,7 @@ :waiting-prompt true :choices {:number (req tags) :default (req tags)} - :effect (effect (access-n-cards eid (:server run) target))} + :effect (req (access-n-cards state side eid (:server run) target))} card nil))} card targets) ;; Can't pay, don't access cards @@ -1017,14 +1017,14 @@ :async true :location :discard :req (req (runner-can-install? state side eid card nil)) - :effect (effect + :effect (req (continue-ability - {:optional + state side {:optional {:req (req (and (<= 3 (count (:successful-run runner-reg))) (not (get-in @state [:runner :register :crowdfunding-prompt])))) :prompt "Install Crowdfunding from the Heap?" :yes-ability {:async true - :effect (effect (runner-install :runner eid card {:ignore-all-cost true + :effect (req (runner-install state :runner eid card {:ignore-all-cost true :msg-keys {:install-source card :display-origin true}}))} ;; Add a register to note that the player was already asked about installing, @@ -1051,9 +1051,9 @@ (:deck runner)) :sorted)) :cost [(->c :click 1) (->c :virus 3) (->c :trash-can)] :cancel (assoc fail-to-find! :cost [(->c :click 1) (->c :virus 3) (->c :trash-can)] :action true) - :effect (effect (trigger-event :searched-stack) - (shuffle! :deck) - (runner-install (assoc eid :source card :source-type :runner-install) target {:msg-keys {:install-source card + :effect (req (trigger-event state side :searched-stack) + (shuffle! state side :deck) + (runner-install state side (assoc eid :source card :source-type :runner-install) target {:msg-keys {:install-source card :display-origin true}}))} (set-autoresolve :auto-place-counter "Crypt placing virus counters on itself")]}) @@ -1063,7 +1063,7 @@ :silent true :req (req (and (has-subtype? (:card context) "Icebreaker") (not (has-subtype? (:card context) "AI")))) - :effect (effect (pump (:card context) 2 :end-of-turn))}]}) + :effect (req (pump state side (:card context) 2 :end-of-turn))}]}) (defcard "Dadiana Chacon" (letfn [(trash-effect [] {:async true @@ -1089,11 +1089,11 @@ :interactive (req true) :async true :effect - (effect (continue-ability - {:msg "gain 1 [Credits]" + (req (continue-ability + state side {:msg "gain 1 [Credits]" :req (req (< (get-in @state [:runner :credit]) 6)) :async true - :effect (effect (gain-credits :runner eid 1))} + :effect (req (gain-credits state :runner eid 1))} card nil))}]})) (defcard "Daily Casts" @@ -1114,7 +1114,7 @@ (defcard "Daeg, First Net-Cat" (let [ability {:async true :interactive (req true) - :effect (effect (continue-ability (charge-ability state side) card nil))}] + :effect (req (continue-ability state side (charge-ability state side) card nil))}] {:events [(assoc ability :event :agenda-scored) (assoc ability :event :agenda-stolen)]})) @@ -1122,8 +1122,8 @@ {:abilities [{:action true :cost [(->c :click 1) (->c :forfeit)] :async true - :effect (effect (play-sfx "click-credit-3") - (gain-credits eid 9)) + :effect (req (play-sfx state side "click-credit-3") + (gain-credits state side eid 9)) :msg "gain 9 [Credits]"}]}) (defcard "Data Folding" @@ -1134,7 +1134,7 @@ :req (req (and (<= 2 (available-mu state)) (:runner-phase-12 @state))) :async true - :effect (effect (gain-credits eid 1))}] + :effect (req (gain-credits state side eid 1))}] {:flags {:drip-economy true} :abilities [ability] :events [(assoc ability :event :runner-turn-begins)]})) @@ -1153,9 +1153,9 @@ (defcard "DDoS" {:abilities [{:msg "prevent the corp from rezzing the outermost piece of ice during a run on any server this turn" :cost [(->c :trash-can)] - :effect (effect + :effect (req (register-turn-flag! - card :can-rez + state side card :can-rez (fn [state _ card] (let [idx (card-index state card)] (if (and (ice? card) @@ -1224,7 +1224,7 @@ :cost [(->c :click 1) (->c :power 3)] :prompt "Choose a card to add to grip" :choices (req (eligible-cards runner)) - :effect (effect (move target :hand)) + :effect (req (move state side target :hand)) :msg (msg "add " (:title target) " from the heap to the grip")} {:label "Place 1 power counter" :once :per-turn @@ -1243,7 +1243,7 @@ (first-event? state side side-trash prog-or-hw))) :msg "place 1 power counter on itself" :async true - :effect (effect (add-counter eid card :power 1))})] + :effect (req (add-counter state side eid card :power 1))})] [(trash-event :corp-trash) (trash-event :runner-trash)])})) @@ -1276,7 +1276,7 @@ ;; Clean-up (effect-completed state side eid)))}] {:on-install {:async true - :effect (effect (continue-ability fenris-effect card nil))} + :effect (req (continue-ability state side fenris-effect card nil))} ;; TODO - make this work ;; Handle Dr. Lovegood / Malia :disable {:effect (req (doseq [hosted (:hosted card)] @@ -1345,14 +1345,14 @@ :req (req (:runner-phase-12 @state)) :once :per-turn :async true - :effect (effect (lose-credits eid 1))}] + :effect (req (lose-credits state side eid 1))}] :events [{:event :corp-turn-begins :automatic :draw-cards :msg (msg "draw " (if (zero? (count (get-in @state [:runner :deck]))) "no cards (the stack is empty)" "1 card")) :async true - :effect (effect (draw :runner eid 1))} + :effect (req (draw state :runner eid 1))} {:event :runner-turn-begins :automatic :lose-credits :msg (msg "lose " (if (zero? (get-in @state [:runner :credit])) @@ -1360,7 +1360,7 @@ "1 [Credits]")) :once :per-turn :async true - :effect (effect (lose-credits eid 1))}]}) + :effect (req (lose-credits state side eid 1))}]}) (defcard "Duggar's" {:abilities [(draw-abi 10 nil {:action true @@ -1395,7 +1395,7 @@ :abilities [ability]})) (defcard "Eden Shard" - (shard-constructor "Eden Shard" :rd "force the Corp to draw 2 cards" (effect (draw :corp eid 2)))) + (shard-constructor "Eden Shard" :rd "force the Corp to draw 2 cards" (req (draw state :corp eid 2)))) (defcard "Emptied Mind" (let [ability {:req (req (zero? (count (:hand runner)))) @@ -1403,7 +1403,7 @@ :msg "gain [Click]" :label "Gain [Click] (start of turn)" :once :per-turn - :effect (effect (gain-clicks 1))}] + :effect (req (gain-clicks state side 1))}] {:events [(assoc ability :event :runner-turn-begins)] :abilities [ability]})) @@ -1449,7 +1449,7 @@ (= :rd (:server context)) (= :archives (first (:server run))))) :msg "access 1 additional card" - :effect (effect (access-bonus :rd 1))}] + :effect (req (access-bonus state side :rd 1))}] :abilities [(run-server-ability :archives {:cost [(->c :gain-tag 1) (->c :click 1)] @@ -1471,7 +1471,7 @@ :msg "gain 2 [Credits]" :cost [(->c :trash-can)] :async true - :effect (effect (gain-credits eid 2))}]})) + :effect (req (gain-credits state side eid 2))}]})) (defcard "Fan Site" {:events [{:event :agenda-scored @@ -1523,7 +1523,7 @@ (agenda? (:accessed-card context)))) :interactive (req true) :async true - :effect (effect (continue-ability (host-agenda? (:accessed-card context)) card nil))}] + :effect (req (continue-ability state side (host-agenda? (:accessed-card context)) card nil))}] :abilities [{:action true :cost [(->c :click 2)] :label "Add hosted agenda to your score area" @@ -1609,8 +1609,8 @@ (defcard "Gene Conditioning Shoppe" {:on-install {:msg "make Genetics trigger a second time each turn" - :effect (effect (register-persistent-flag! card :genetics-trigger-twice (constantly true)))} - :leave-play (effect (clear-persistent-flag! card :genetics-trigger-twice))}) + :effect (req (register-persistent-flag! state side card :genetics-trigger-twice (constantly true)))} + :leave-play (req (clear-persistent-flag! state side card :genetics-trigger-twice))}) (defcard "Ghost Runner" {:data {:counter {:credit 3}} @@ -1635,7 +1635,7 @@ {:msg "lose [Click] and look at the top card of R&D" :prompt (req (->> corp :deck first :title (str "The top card of R&D is "))) :choices ["OK"] - :effect (effect (lose-clicks 1))}}}] + :effect (req (lose-clicks state side 1))}}}] {:req (req (< 1 (get-link state))) :flags {:runner-phase-12 (req true)} :abilities [ability (set-autoresolve :auto-fire "Globalsec Security Clearance")] @@ -1651,10 +1651,10 @@ :effect (req (let [ab (if (:successful-run runner-reg) {:msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits eid 1))} + :effect (req (gain-credits state side eid 1))} {:msg "trash Grifter" :async true - :effect (effect (trash eid card {:cause :runner-ability :cause-card card}))})] + :effect (req (trash state side eid card {:cause :runner-ability :cause-card card}))})] (continue-ability state side ab card targets)))}]}) (defcard "Guru Davinder" @@ -1700,7 +1700,7 @@ (defcard "Hades Shard" (shard-constructor "Hades Shard" :archives "breach Archives" - (effect (breach-server eid [:archives] {:no-root true})))) + (req (breach-server state side eid [:archives] {:no-root true})))) (defcard "Hannah \"Wheels\" Pilintra" {:abilities [{:action true @@ -1730,14 +1730,14 @@ (same-card? card (:source-card context)))) :async true :msg "take 1 tag" - :effect (effect (gain-tags :runner eid 1))}]) + :effect (req (gain-tags state :runner eid 1))}]) (make-run state side eid target card))} {:action true :cost [(->c :click 1) (->c :trash-can)] :async true :label "Gain [Click][Click]. Remove 1 tag" - :effect (effect (gain-clicks 2) - (lose-tags eid 1)) + :effect (req (gain-clicks state side 2) + (lose-tags state side eid 1)) :msg "gain [Click][Click] and remove 1 tag"}]}) (defcard "Hard at Work" @@ -1745,8 +1745,8 @@ :automatic :lose-clicks :once :per-turn :async true - :effect (effect (lose-clicks 1) - (gain-credits eid 2))}] + :effect (req (lose-clicks state side 1) + (gain-credits state side eid 2))}] {:flags {:drip-economy true} :events [(assoc ability :event :runner-turn-begins)] :abilities [ability]})) @@ -1761,11 +1761,11 @@ {:events [{:event :agenda-scored :msg (msg "gain " (get-agenda-points (:card context)) " [Credits]") :async true - :effect (effect (gain-credits :runner eid (get-agenda-points (:card context))))} + :effect (req (gain-credits state :runner eid (get-agenda-points (:card context))))} {:event :agenda-stolen :msg (msg "gain " (get-agenda-points (:card context)) " [Credits]") :async true - :effect (effect (gain-credits :runner eid (get-agenda-points (:card context))))}]}) + :effect (req (gain-credits state :runner eid (get-agenda-points (:card context))))}]}) (defcard "Hunting Grounds" {:prevention [{:prevents :encounter @@ -1788,14 +1788,14 @@ :msg "install the top 3 cards of the stack facedown" :change-in-game-state {:req (req (seq (:deck runner)))} :cost [(->c :trash-can)] - :effect (effect (continue-ability (ri (take 3 (:deck runner))) card nil))})]}) + :effect (req (continue-ability state side (ri (take 3 (:deck runner))) card nil))})]}) (defcard "Ice Analyzer" {:implementation "Credit use restriction is not enforced" :events [{:event :rez :req (req (ice? (:card context))) :async true - :effect (effect (add-counter :runner eid card :credit 1))}] + :effect (req (add-counter state :runner eid card :credit 1))}] :abilities [{:async true :effect (req (spend-credits state side eid card :credit 1)) :msg "take 1 hosted [Credits] to install programs"}] @@ -1835,7 +1835,7 @@ :abilities [{:action true :cost [(->c :click 4) (->c :trash-can)] :msg "give the Corp 1 bad publicity" - :effect (effect (gain-bad-publicity :corp 1))}]}) + :effect (req (gain-bad-publicity state :corp 1))}]}) (defcard "Investigator Inez Delgado" {:abilities [{:msg (msg "add itself to [their] score area as an agenda worth 0 agenda points") @@ -1903,7 +1903,7 @@ :events [{:event :runner-turn-begins :silent true :async true - :effect (effect (add-counter :runner eid card :credit 1))} + :effect (req (add-counter state :runner eid card :credit 1))} ;; TODO (NoahTheDuke, Oct 2020): ;; This is an async ability and it's getting called in `move`, which is sync. ;; This won't work long-term, but it's the best solution at the moment. @@ -1966,12 +1966,12 @@ :interactive (req true) :msg "draw 1 card" :async true - :effect (effect (draw eid 1))} + :effect (req (draw state side eid 1))} {:event :unsuccessful-run :req (req (first-event? state side :unsuccessful-run)) :async true :msg "take 1 tag" - :effect (effect (gain-tags :runner eid 1))}]}) + :effect (req (gain-tags state :runner eid 1))}]}) (defcard "Joshua B." (let [ability {:msg "gain [Click]" @@ -1991,8 +1991,8 @@ :once :per-turn :yes-ability ability :no-ability - {:effect (effect (system-msg (str "declines to use " (:title card) " to gain [Click]")) - (update! (assoc-in card [:special :joshua-b] false)))}}}] + {:effect (req (system-msg state side (str "declines to use " (:title card) " to gain [Click]")) + (update! state side (assoc-in card [:special :joshua-b] false)))}}}] :abilities [ability]})) (defcard "Juli Moreira Lee" @@ -2026,7 +2026,7 @@ :yes-ability {:msg "place 1 power counter on itself" :async true :effect (req (add-counter state side eid card :power 1 {:placed true}))} - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card))))}}} + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card))))}}} {:event :counter-added :req (req (<= 4 (get-counters (get-card state card) :power))) :msg "add itself to [their] score area as an agenda worth 1 agenda point" @@ -2039,7 +2039,7 @@ :msg "store 3 [Credits]" :once :per-turn :async true - :effect (effect (add-counter eid card :credit 3))} + :effect (req (add-counter state side eid card :credit 3))} (take-all-credits-ability {:action true :cost [(->c :click 1)] @@ -2051,7 +2051,7 @@ (= (:side context) :runner))) :msg "gain 2 [Credits]" :async true - :effect (effect (gain-credits eid 2))}]}) + :effect (req (gain-credits state side eid 2))}]}) (defcard "\"Knickknack\" O'Brian" {:events [{:async true @@ -2093,13 +2093,13 @@ :async true :effect (req (wait-for (mill state :runner :runner 1) (draw state :runner eid 1)))} - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card))))}}}] + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card))))}}}] :abilities [(set-autoresolve :auto-fire "Lago Paranoá Shelter")]}) (defcard "Laguna Velasco District" {:events [{:event :runner-click-draw :msg "draw 1 additional card" - :effect (effect (click-draw-bonus 1))}]}) + :effect (req (click-draw-bonus state side 1))}]}) (defcard "Levy Advanced Research Lab" (letfn [(lab-keep [cards] @@ -2161,8 +2161,8 @@ :label "Add liberated Chela to your score area" :async true :effect - (effect (continue-ability - (if (seq (:scored corp)) + (req (continue-ability + state side (if (seq (:scored corp)) {:optional {:waiting-prompt true :prompt (msg "Forfeit an agenda to prevent " (:title card) " from being added to Runner's score area?") @@ -2178,9 +2178,9 @@ (effect-completed state side eid)))} :no-ability {:msg "add itself to [their] score area as an agenda worth 2 points" - :effect (effect (as-agenda :runner card 2))}}} + :effect (req (as-agenda state :runner card 2))}}} {:msg "add itself to [their] score area as an agenda worth 2 points" - :effect (effect (as-agenda :runner card 2))}) + :effect (req (as-agenda state :runner card 2))}) card nil))}]}) (defcard "Light the Fire!" @@ -2190,7 +2190,7 @@ :async true :req (req (and run (is-remote? (:server run)))) - :effect (effect (trash-cards eid (:content run-server))) + :effect (req (trash-cards state side eid (:content run-server))) :msg "trash all cards in the server for no cost"} disable-card-effect {:type :disable-card @@ -2207,10 +2207,10 @@ :msg (msg "make a run on " target " during which cards in the root of the attacked server lose all abilities") :makes-run true :async true - :effect (effect - (register-events card [successful-run-event]) - (register-lingering-effect card disable-card-effect) - (make-run eid target card))}]})) + :effect (req + (register-events state side card [successful-run-event]) + (register-lingering-effect state side card disable-card-effect) + (make-run state side eid target card))}]})) (defcard "Logic Bomb" {:abilities [{:label "Bypass the encountered ice" @@ -2236,7 +2236,7 @@ :choices {:req (req (and (program? target) (not (has-subtype? target "Virus")) (in-hand*? state target)))} - :effect (effect (runner-install eid target {:host-card card :ignore-install-cost true + :effect (req (runner-install state side eid target {:host-card card :ignore-install-cost true :msg-keys {:install-source card :include-cost-from-eid eid :display-origin true}}))} @@ -2247,11 +2247,11 @@ :change-in-game-state {:req (req (seq (:hosted (get-card state card))))} :choices {:req (req (same-card? card (:host target)))} :msg (msg "add " (:title target) " to [their] Grip") - :effect (effect (move target :hand))}] + :effect (req (move state side target :hand))}] :events [{:event :runner-turn-ends :interactive (req true) :async true - :effect (effect (trash-cards eid (filter program? (:hosted card)) {:cause-card card}))}]}) + :effect (req (trash-cards state side eid (filter program? (:hosted card)) {:cause-card card}))}]}) (defcard "Manuel Lattes de Moura" {:static-abilities [{:type :basic-ability-additional-trash-cost @@ -2264,7 +2264,7 @@ :req (req (and tagged (#{:hq :rd} (:server context)))) :msg (msg "access 1 additional card from " (zone->name (:server context))) - :effect (effect (access-bonus (:server context) 1))}]}) + :effect (req (access-bonus state side (:server context) 1))}]}) (defcard "\"Pretty\" Mary da Silva" {:implementation "only works after other abilities increasing the number of accesses have resolved" @@ -2283,7 +2283,7 @@ {:prompt "Access 1 additional card?" :yes-ability {:msg "access 1 additional card" - :effect (effect (access-bonus :rd 1))}}}) + :effect (req (access-bonus state side :rd 1))}}}) card nil)))}]}) (defcard "Maxwell James" @@ -2350,7 +2350,7 @@ :prompt "Choose 1 card to add to the bottom of the Stack" :choices {:req (req (some #(same-card? target %) runner-currently-drawing))} :msg "add 1 card to the bottom of the Stack" - :effect (effect (move target :deck))}]) + :effect (req (move state side target :deck))}]) (play-sfx state side "click-card-2") (wait-for (draw state side 2) (unregister-events state side card) @@ -2368,14 +2368,14 @@ :async true :effect (req (derez state :corp (assoc eid :source card) target))} :uninstall - (effect + (req (continue-ability - {:player :corp + state side {:player :corp :waiting-prompt true :prompt "Choose a card to rez, ignoring the rez cost" :choices {:card (complement rezzed?)} :async true - :effect (effect (rez eid target {:ignore-cost :rez-cost :no-msg true}))} + :effect (req (rez state side eid target {:ignore-cost :rez-cost :no-msg true}))} card nil)) :abilities [(draw-abi 1 nil {:cost [(->c :trash-can)]})]}) @@ -2485,7 +2485,7 @@ :events [{:event :agenda-stolen :async true :msg "trash itself" - :effect (effect (trash eid card {:cause :runner-ability :cause-card card}))}]})) + :effect (req (trash state side eid card {:cause :runner-ability :cause-card card}))}]})) (defcard "Nurse Hạnh" {:events [{:event :archives-flipped @@ -2499,13 +2499,13 @@ :msg "gain 3 [Credits]" :cost [(->c :trash-can)] :async true - :effect (effect (gain-credits eid 3))} + :effect (req (gain-credits state side eid 3))} {:label "Remove 1 tag" :msg "remove 1 tag" :change-in-game-state {:req (req tagged)} :cost [(->c :trash-can)] :async true - :effect (effect (lose-tags :runner eid 1))}]}) + :effect (req (lose-tags state :runner eid 1))}]}) (defcard "No One Home" {:prevention [{:prevents :damage @@ -2553,7 +2553,7 @@ :events [{:event :runner-install :req (req (same-card? card (:host (:card context)))) :async true - :effect (effect (draw eid 1))}]}) + :effect (req (draw state side eid 1))}]}) (defcard "Officer Frank" {:abilities [{:cost [(->c :credit 1) (->c :trash-can)] @@ -2561,7 +2561,7 @@ :change-in-game-state {:req (req (seq (:hand corp)))} :msg "force the Corp to trash 2 random cards from HQ" :async true - :effect (effect (trash-cards :corp eid (take 2 (shuffle (:hand corp))) {:cause-card card}))}]}) + :effect (req (trash-cards state :corp eid (take 2 (shuffle (:hand corp))) {:cause-card card}))}]}) (defcard "Open Market" (let [ability {:once :per-turn @@ -2610,9 +2610,9 @@ :req (req (zero? (:credit runner))) :once :per-turn :async true - :effect (effect (gain-credits eid 1))}] + :effect (req (gain-credits state side eid 1))}] {:on-install {:async true - :effect (effect (continue-ability ability card nil))} + :effect (req (continue-ability state side ability card nil))} :events [(assoc ability :event :runner-credit-loss) (assoc ability :event :runner-spent-credits)]})) @@ -2629,15 +2629,15 @@ :autoresolve (get-autoresolve :auto-fire) :yes-ability {:msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits :runner eid 1))}}}] + :effect (req (gain-credits state :runner eid 1))}}}] :abilities [(set-autoresolve :auto-fire "PAD Tap")] :corp-abilities [{:action true :label "Trash PAD Tap" :async true :cost [(->c :click 1) (->c :credit 3)] :req (req (= :corp side)) - :effect (effect (system-msg :corp "spends [Click] and 3 [Credits] to trash PAD Tap") - (trash :corp eid card {:cause-card card}))}]}) + :effect (req (system-msg state :corp "spends [Click] and 3 [Credits] to trash PAD Tap") + (trash state :corp eid card {:cause-card card}))}]}) (defcard "Paige Piper" (letfn [(pphelper [title cards] @@ -2660,8 +2660,8 @@ :interactive (req true) :req (req (first-event? state side :runner-install)) :async true - :effect (effect (continue-ability - (pphelper (:title (:card context)) + :effect (req (continue-ability + state side (pphelper (:title (:card context)) (filterv #(= (:title %) (:title (:card context))) (:deck runner))) card nil))}]})) @@ -2678,7 +2678,7 @@ (runner? %))} :msg (msg "trash " (:title target)) :async true - :effect (effect (trash eid target {:cause :runner-ability :cause-card card}))} + :effect (req (trash state side eid target {:cause :runner-ability :cause-card card}))} ;; companion-builder: ability {:req (req (pos? (get-counters (get-card state card) :credit))) :msg "take 1 [Credits]" @@ -2724,7 +2724,7 @@ (:card-target card))))))))) {:event :runner-turn-ends :silent true - :effect (effect (update! (dissoc (get-card state card) :card-target)))}]})) + :effect (req (update! state side (dissoc (get-card state card) :card-target)))}]})) (defcard "Paule's Café" {:abilities [{:action true @@ -2814,9 +2814,9 @@ :label "Remove power counters from a hosted card" :choices {:card #(:host %)} :req (req (seq (:hosted card))) - :effect (effect + :effect (req (continue-ability - (let [paydowntarget target + state side (let [paydowntarget target num-counters (get-counters (get-card state paydowntarget) :power)] {:async true :prompt "How many power counters do you want to remove?" @@ -2844,20 +2844,20 @@ :fake-cost [(->c :trash-can)] :label "Trash a rezzed card" :effect - (effect + (req (continue-ability ;; TODO: Convert this to a cost - {:prompt "Choose a rezzed card with a trash cost" + state side {:prompt "Choose a rezzed card with a trash cost" :choices {:card #(and (:trash %) (rezzed? %) (can-pay? state side (assoc eid :source card :source-type :ability) card nil [(->c :credit (trash-cost state :runner %))]))} :async true - :effect (effect + :effect (req (continue-ability - {:async true + state side {:async true :msg (msg "trash " (card-str state target)) :cost [(->c :credit (trash-cost state :runner target)) (->c :trash-can)] - :effect (effect (trash eid target {:cause-card card}))} + :effect (req (trash state side eid target {:cause-card card}))} card targets))} card nil))}]}) @@ -2865,7 +2865,7 @@ {:events [{:event :initialize-trace :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits :runner eid 1))}]}) + :effect (req (gain-credits state :runner eid 1))}]}) (defcard "Professional Contacts" {:abilities [{:action true @@ -2887,7 +2887,7 @@ :yes-ability {:msg (msg "gain " (total-cards-accessed target :deck) " [Credits]") :async true - :effect (effect (gain-credits :runner eid (total-cards-accessed target :deck)))}}}] + :effect (req (gain-credits state :runner eid (total-cards-accessed target :deck)))}}}] :abilities [(set-autoresolve :auto-fire "Psych Mike")]}) (defcard "Public Sympathy" @@ -2907,7 +2907,7 @@ :choices {:card installed?} :async true :cost [(->c :trash-can)] - :effect (effect (expose eid [target]))}]}) + :effect (req (expose state side eid [target]))}]}) (defcard "Reclaim" {:abilities @@ -2924,9 +2924,9 @@ (:discard runner))) :cost [(->c :click 1) (->c :trash-can) (->c :trash-from-hand 1)] :effect - (effect + (req (continue-ability - {:async true + state side {:async true :prompt "Choose a card to install" :choices (req (vec (sort-by :title @@ -2969,7 +2969,7 @@ :msg (msg "make a run on " target) :makes-run true :async true - :effect (effect (make-run eid target card))}]}) + :effect (req (make-run state side eid target card))}]}) (defcard "Rent Rioters" {:abilities [{:action true @@ -2997,8 +2997,8 @@ {:on-install {:async true :msg "look at the top 5 cards of the stack" :waiting-prompt true - :effect (effect (continue-ability - (let [from (take 5 (:deck runner))] + :effect (req (continue-ability + state side (let [from (take 5 (:deck runner))] (when (pos? (count from)) (reorder-choice :runner :corp from '() (count from) from))) card nil))} @@ -3019,9 +3019,9 @@ :async true :cost [(->c :click 1) (->c :rfg-program 1)] :effect - (effect + (req (continue-ability - {:async true + state side {:async true :prompt "Choose a non-virus program to install" :choices (req (concat (->> (:deck runner) @@ -3119,7 +3119,7 @@ :msg (msg "force the Corp to trash the top " (quantify (get-turn-damage state :runner) "card") " of R&D") - :effect (effect (mill :corp eid :corp (get-turn-damage state :runner)))}}}]}) + :effect (req (mill state :corp eid :corp (get-turn-damage state :runner)))}}}]}) ;; TODO - limit selection to what runner can play (defcard "Same Old Thing" @@ -3135,7 +3135,7 @@ :choices {:req (req (and (event? target) (in-discard? target) (can-play-instant? state side eid target {:base-cost [(->c :click 2)]})))} - :effect (effect (play-instant eid target))}]}) + :effect (req (play-instant state side eid target))}]}) (defcard "Scrubber" {:recurring 2 @@ -3161,7 +3161,7 @@ :ability {:msg "gain 2 [Credits]" :async true - :effect (effect (gain-credits eid 2))}}) + :effect (req (gain-credits state side eid 2))}}) :req (req (when-let [card (get-card state card)] (and (= (zone->name (:server context)) (:card-target card)) (first-event? state side :successful-run @@ -3171,7 +3171,7 @@ (:card-target card))))))))) {:event :runner-turn-ends :silent true - :effect (effect (update! (dissoc card :card-target)))}] + :effect (req (update! state side (dissoc card :card-target)))}] :abilities [ability]})) (defcard "Shadow Team" @@ -3239,9 +3239,9 @@ :yes-ability {:async true :effect - (effect + (req (continue-ability - (let [passed-ice (:ice context)] + state side (let [passed-ice (:ice context)] {:async true :prompt "Choose a piece of ice protecting a central server at the same position" :choices {:req (req (and (ice? target) @@ -3266,7 +3266,7 @@ :async true :interactive (req true) :msg "trash the top card of R&D" - :effect (effect (mill :corp eid :corp 1))}]}) + :effect (req (mill state :corp eid :corp 1))}]}) (defcard "Starlight Crusade Funding" {:on-install {:msg "ignore additional costs on Double events" @@ -3317,7 +3317,7 @@ :req (req (can-charge state side)) :cost [(->c :trash-can)] :async true - :effect (effect (continue-ability (charge-ability state side) card nil))}]}) + :effect (req (continue-ability state side (charge-ability state side) card nil))}]}) (defcard "Street Magic" (letfn [(runner-break [unbroken-subs] @@ -3343,7 +3343,7 @@ :async true :msg (msg "choose the order the unbroken subroutines on " (:title current-ice) " resolve") - :effect (effect (continue-ability (runner-break (unbroken-subroutines-choice current-ice)) card nil))}]})) + :effect (req (continue-ability state side (runner-break (unbroken-subroutines-choice current-ice)) card nil))}]})) (defcard "Street Peddler" {:on-install {:interactive (req (some #(card-flag? % :runner-install-draw true) (all-active state :runner))) @@ -3390,21 +3390,21 @@ :req (req (genetics-trigger? state side :runner-click-draw)) :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits eid 1))}]}) + :effect (req (gain-credits state side eid 1))}]}) (defcard "Synthetic Blood" {:events [{:event :damage :req (req (genetics-trigger? state side :damage)) :msg "draw 1 card" :async true - :effect (effect (draw :runner eid 1))}]}) + :effect (req (draw state :runner eid 1))}]}) (defcard "Tallie Perrault" {:abilities [{:label "Draw 1 card for each bad publicity the Corp has" :async true :cost [(->c :trash-can)] :change-in-game-state {:req (req (pos? (count-bad-pub state)))} - :effect (effect (draw eid (count-bad-pub state))) + :effect (req (draw state side eid (count-bad-pub state))) :msg (msg "draw " (quantify (count-bad-pub state) "card"))}] :events [{:event :play-operation :optional @@ -3414,8 +3414,8 @@ :prompt "Give the Corp 1 bad publicity and take 1 tag?" :yes-ability {:msg "give the Corp 1 bad publicity and take 1 tag" :async true - :effect (effect (gain-bad-publicity :corp 1 {:suppress-checkpoint true}) - (gain-tags :runner eid 1))}}}]}) + :effect (req (gain-bad-publicity state :corp 1 {:suppress-checkpoint true}) + (gain-tags state :runner eid 1))}}}]}) (defcard "Tech Trader" {:events [{:event :costs-paid @@ -3424,7 +3424,7 @@ :req (req (and (= :runner (:side context)) (->> context :payment (map :paid/type) (some #{:trash-can})))) :msg "gain 1 [Credits]" - :effect (effect (gain-credits eid 1))}]}) + :effect (req (gain-credits state side eid 1))}]}) (defcard "Technical Writer" {:events [{:event :runner-install @@ -3434,7 +3434,7 @@ (not (:facedown? context)))) :msg "place 1 [Credits] on itself" :async true - :effect (effect (add-counter :runner eid card :credit 1))}] + :effect (req (add-counter state :runner eid card :credit 1))}] :abilities [{:action true :cost [(->c :click 1) (->c :trash-can)] :label "Take all hosted credits" @@ -3455,19 +3455,19 @@ :label "Place 1 power counter" :msg "place 1 power counter on itself" :async true - :effect (effect (add-counter eid card :power 1))} + :effect (req (add-counter state side eid card :power 1))} {:label "Gain [Click]" :cost [(->c :power 1)] :req (req (= (:active-player @state) :runner)) :msg "gain [Click]" :once :per-turn - :effect (effect (gain-clicks 1))}]}) + :effect (req (gain-clicks state side 1))}]}) (defcard "Temüjin Contract" {:data {:counter {:credit 20}} :on-install {:prompt "Choose a server" :choices (req servers) :msg (msg "target " target) - :effect (effect (update! (assoc card :card-target target)))} + :effect (req (update! state side (assoc card :card-target target)))} :events [(trash-on-empty :credit) {:event :successful-run :automatic :gain-credits @@ -3484,8 +3484,8 @@ :req (req (or (has-subtype? (:card context) "Initiative") (has-subtype? (:card context) "Security"))) :unsuccessful - {:effect (effect (gain-bad-publicity :corp 1) - (system-msg :corp (str "takes 1 bad publicity")))}}}]}) + {:effect (req (gain-bad-publicity state :corp 1) + (system-msg state :corp (str "takes 1 bad publicity")))}}}]}) (defcard "The Artist" {:abilities [{:action true @@ -3495,8 +3495,8 @@ :once :per-turn :once-key :artist-credits :async true - :effect (effect (play-sfx "click-credit-2") - (gain-credits eid 2))} + :effect (req (play-sfx state side "click-credit-2") + (gain-credits state side eid 2))} {:action true :cost [(->c :click 1)] :label "Install a program or piece of hardware" @@ -3513,7 +3513,7 @@ :once :per-turn :once-key :artist-install :async true - :effect (effect (runner-install (assoc eid :source card :source-type :runner-install) + :effect (req (runner-install state side (assoc eid :source card :source-type :runner-install) target {:msg-keys {:install-source card :display-source true} :cost-bonus -1}))}]}) @@ -3564,8 +3564,8 @@ (check-win-by-agenda state side) (effect-completed state side eid)) (add-counter state side eid card :power 1)))}] - :on-trash {:effect (effect (check-win-by-agenda))} - :leave-play (effect (check-win-by-agenda))}) + :on-trash {:effect (req (check-win-by-agenda state side))} + :leave-play (req (check-win-by-agenda state side))}) (defcard "The Class Act" (let [draw-ability {:req (req (= :this-turn (installed? card))) @@ -3573,7 +3573,7 @@ :interactive (req true) :automatic :pre-draw-cards ;; queue this before smaller draws :msg "draw 4 cards" - :effect (effect (draw :runner eid 4))}] + :effect (req (draw state :runner eid 4))}] {:events [(assoc draw-ability :event :corp-turn-ends) (assoc draw-ability :event :runner-turn-ends) {:event :pre-runner-draw @@ -3606,7 +3606,7 @@ :choices {:card #(and (has-subtype? % "Icebreaker") (installed? %))} :cost [(->c :trash-can)] - :effect (effect (pump target 2 :end-of-turn))}]}) + :effect (req (pump state side target 2 :end-of-turn))}]}) (defcard "The Masque A" {:abilities [{:action true @@ -3616,18 +3616,18 @@ :choices (req runnable-servers) :msg (msg "make a run on " target " and gain [click]") :async true - :effect (effect - (gain-clicks :runner 1) + :effect (req + (gain-clicks state :runner 1) (register-events - card + state side card [{:event :successful-run :automatic :draw-cards :unregister-once-resolved true :duration :end-of-run :async true :msg "draw 1 card" - :effect (effect (draw :runner eid 1))}]) - (make-run eid target card))}]}) + :effect (req (draw state :runner eid 1))}]) + (make-run state side eid target card))}]}) (defcard "The Masque B" {:implementation "Successful run condition not implemented" @@ -3638,8 +3638,8 @@ :choices (req runnable-servers) :msg (msg "make a run on " target " and gain [click]") :async true - :effect (effect (gain-clicks 1) - (make-run eid target card))}]}) + :effect (req (gain-clicks state side 1) + (make-run state side eid target card))}]}) (defcard "The Nihilist" (let [corp-choice {:player :corp @@ -3674,7 +3674,7 @@ :msg "place 2 virus counters on itself" :req (req (has-subtype? (:card context) "Virus")) :async true - :effect (effect (add-counter eid card :virus 2))}]})) + :effect (req (add-counter state side eid card :virus 2))}]})) (defcard "The Shadow Net" (letfn [(events [runner] (filter #(and (event? %) (not (has-subtype? % "Priority"))) (:discard runner)))] @@ -3687,7 +3687,7 @@ :prompt "Choose an event to play" :msg (msg "play " (:title target) " from the heap, ignoring all costs") :choices (req (cancellable (events runner) :sorted)) - :effect (effect (play-instant eid target {:ignore-cost true}))}]})) + :effect (req (play-instant state side eid target {:ignore-cost true}))}]})) (defcard "The Source" {:static-abilities [{:type :advancement-requirement @@ -3696,10 +3696,10 @@ :value (req (->c :credit 3))}] :events [{:event :agenda-scored :async true - :effect (effect (trash eid card {:cause :runner-ability :cause-card card}))} + :effect (req (trash state side eid card {:cause :runner-ability :cause-card card}))} {:event :agenda-stolen :async true - :effect (effect (trash eid card {:cause :runner-ability :cause-card card}))}]}) + :effect (req (trash state side eid card {:cause :runner-ability :cause-card card}))}]}) (defcard "The Supplier" (let [ability {:label "Install a hosted card (start of turn)" @@ -3737,7 +3737,7 @@ :choices {:card #(and (or (hardware? %) (resource? %)) (in-hand? %))} - :effect (effect (host card target)) + :effect (req (host state side card target)) :msg (msg "install and host " (:title target))} ability] ; A card installed by The Supplier is ineligible to receive the turn-begins event for this turn. @@ -3747,7 +3747,7 @@ {:event :runner-turn-ends :silent true :req (req (:supplier-installed card)) - :effect (effect (update! (dissoc card :supplier-installed)))}]})) + :effect (req (update! state side (dissoc card :supplier-installed)))}]})) (defcard "The Turning Wheel" (letfn [(ttw-ab [name server] @@ -3756,8 +3756,8 @@ :req (req run) :keep-menu-open :while-2-power-tokens-left :msg (msg "access 1 additional card from " name " for the remainder of the run") - :effect (effect (register-events - card [(breach-access-bonus server 1 {:duration :end-of-run})]))}) + :effect (req (register-events + state side card [(breach-access-bonus server 1 {:duration :end-of-run})]))}) (ttw-bounce [name server] {:action true :label (str "Shortcut: Bounce " name) @@ -3808,8 +3808,8 @@ :msg (msg "access " (quantify target "additional card") " from " (zone->name target-server)) :async true - :effect (effect (access-bonus target-server (max 0 target)) - (add-counter :runner eid card :power (- target) {:placed true}))} + :effect (req (access-bonus state side target-server (max 0 target)) + (add-counter state :runner eid card :power (- target) {:placed true}))} card nil)))}]}) (defcard "Theophilius Bagbiter" @@ -3830,7 +3830,7 @@ (in-hand? target) (not (event? target)) (runner-can-pay-and-install? state side (assoc eid :source card) target {:cost-bonus -1})))} - :effect (effect (runner-install (assoc eid + :effect (req (runner-install state side (assoc eid :source card :source-type :runner-install) target {:cost-bonus -1 @@ -3851,10 +3851,10 @@ :msg "gain 2 [Credits]" :once :per-turn :async true - :effect (effect (play-sfx "click-credit-2") - (gain-credits eid 2))}] + :effect (req (play-sfx state side "click-credit-2") + (gain-credits state side eid 2))}] :on-trash {:async true - :effect (effect (damage eid :meat 3 {:unboostable true :card card}))}}) + :effect (req (damage state side eid :meat 3 {:unboostable true :card card}))}}) (defcard "Trickster Taka" (companion-builder @@ -3907,9 +3907,9 @@ :req (req (and (matches-server (:ice target) card state side) (first-event? state side :encounter-ice #(matches-server (:ice (first %)) card state side)))) - :effect (effect + :effect (req (register-events - card + state side card (let [target-ice (:ice context)] [{:event :pre-resolve-subroutine :duration :end-of-encounter @@ -3920,7 +3920,7 @@ (effect-completed state side eid))}])))} {:event :runner-turn-ends :silent true - :effect (effect (update! (dissoc card :card-target)))}] + :effect (req (update! state side (dissoc card :card-target)))}] :abilities [ability]})) (defcard "Tyson Observatory" @@ -3935,9 +3935,9 @@ :msg "shuffle the stack") :keep-menu-open :while-2-clicks-left :change-in-game-state {:req (req (seq (:deck runner)))} - :effect (effect (trigger-event :searched-stack) - (shuffle! :deck) - (move target :hand))}]}) + :effect (req (trigger-event state side :searched-stack) + (shuffle! state side :deck) + (move state side target :hand))}]}) (defcard "Underdome Irregulars" {:events [{:event :runner-action-phase-ends @@ -4005,7 +4005,7 @@ (defcard "Utopia Shard" (shard-constructor "Utopia Shard" :hq "force the Corp to discard 2 cards from HQ at random" - (effect (trash-cards :corp eid (take 2 (shuffle (:hand corp))) {:cause-card card})))) + (req (trash-cards state :corp eid (take 2 (shuffle (:hand corp))) {:cause-card card})))) (defcard "Valentina Ferreira Carvalho" {:on-install {:prompt "Choose one" @@ -4035,12 +4035,12 @@ {:events [{:event :runner-click-draw :req (req (genetics-trigger? state side :runner-click-draw)) :msg "draw 1 additional card" - :effect (effect (click-draw-bonus 1))}]}) + :effect (req (click-draw-bonus state side 1))}]}) (defcard "Virus Breeding Ground" {:events [{:event :runner-turn-begins :async true - :effect (effect (add-counter eid card :virus 1))}] + :effect (req (add-counter state side eid card :virus 1))}] :abilities [{:action true :cost [(->c :click 1)] :label "move hosted virus counter" @@ -4067,7 +4067,7 @@ (first-event? state side :runner-trash valid-ctx?)))) :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits eid 1))}]}) + :effect (req (gain-credits state side eid 1))}]}) (defcard "Whistleblower" {:events [{:event :successful-run @@ -4080,19 +4080,19 @@ :prompt "Name an agenda" :choices {:card-title (req (and (corp? target) (agenda? target)))} - :effect (effect (system-msg (str "trashes " (:title card) + :effect (req (system-msg state side (str "trashes " (:title card) " to use " (:title card) " to name " (:title target))) (register-events - card + state side card (let [named-agenda target] [{:event :access :duration :end-of-run :unregister-once-resolved true :async true :req (req (= (:title (:accessed-card context)) named-agenda)) - :effect (effect (steal eid (:accessed-card context)))}])) - (trash eid card {:unpreventable true :cause-card card}))}}}] + :effect (req (steal state side eid (:accessed-card context)))}])) + (trash state side eid card {:unpreventable true :cause-card card}))}}}] :abilities [(set-autoresolve :auto-fire "Whistleblower")]}) (defcard "Wireless Net Pavilion" @@ -4119,10 +4119,10 @@ :prompt (msg "Draw " (:title (first (:deck corp))) "?") :yes-ability {:async true - :effect (effect (system-msg (str "draws " (:title (first (:deck corp))))) - (draw eid 1))} + :effect (req (system-msg state side (str "draws " (:title (first (:deck corp))))) + (draw state side eid 1))} :no-ability - {:effect (effect (system-msg (str "declines to use " (:title card))))}}} + {:effect (req (system-msg state side (str "declines to use " (:title card))))}}} card nil)))}] {:events [(assoc ability :event :runner-turn-begins)] :abilities [ability]})) @@ -4170,6 +4170,6 @@ {:events [{:event :runner-turn-begins :automatic :gain-credits :async true - :effect (effect (add-counter eid card :credit 1))}] + :effect (req (add-counter state side eid card :credit 1))}] :abilities [(take-all-credits-ability {:action true :cost [(->c :click 1)]})]})) diff --git a/src/clj/game/cards/upgrades.clj b/src/clj/game/cards/upgrades.clj index 3f9ea280e6..cc8b4f3ed8 100644 --- a/src/clj/game/cards/upgrades.clj +++ b/src/clj/game/cards/upgrades.clj @@ -53,7 +53,7 @@ [game.core.to-string :refer [card-str]] [game.core.toasts :refer [toast]] [game.core.update :refer [update!]] - [game.macros :refer [continue-ability effect msg req wait-for]] + [game.macros :refer [continue-ability msg req wait-for]] [game.utils :refer :all] [jinteki.utils :refer :all])) @@ -94,15 +94,15 @@ :psi {:req (req this-server) :not-equal {:msg (msg "prevent the Runner from accessing cards other than " (:title card)) :async true - :effect (effect (set-only-card-to-access card) - (effect-completed eid))} + :effect (req (set-only-card-to-access state side card) + (effect-completed state side eid))} :equal {:msg (msg "prevent the Runner from accessing " (:title card)) :async true - :effect (effect (register-run-flag! - card :can-access + :effect (req (register-run-flag! + state side card :can-access ;; prevent access of advanced card (fn [_ _ target] (not (same-card? target card)))) - (effect-completed eid))}}}]}) + (effect-completed state side eid))}}}]}) (defcard "Akitaro Watanabe" {:static-abilities [{:type :rez-cost @@ -121,8 +121,8 @@ {:events [ability] :on-trash {:req (req (and run (= :runner side))) - :effect (effect (register-events - card + :effect (req (register-events + state side card [(assoc ability :req (req (= (second (:previous-zone card)) (first (:server context)))) :duration :end-of-run)]))}})) @@ -136,23 +136,23 @@ (:card context) {:cost-bonus -3}))) :prompt "Rez ice with rez cost lowered by 3?" :yes-ability {:async true - :effect (effect (rez eid (:card context) {:cost-bonus -3}))}}}]}) + :effect (req (rez state side eid (:card context) {:cost-bonus -3}))}}}]}) (defcard "Angelique Garza Correa" {:expend {:req (req (threat-level 3 state)) :cost [(->c :credit 1)] :msg "do 1 meat damage" :async true - :effect (effect (damage eid :meat 1 {:card card}))} + :effect (req (damage state side eid :meat 1 {:card card}))} :on-access {:optional {:req (req (rezzed? card)) :waiting-prompt true :prompt (msg "Pay 2 [Credits] to use " (:title card) " ability?") - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card))))} + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card))))} :yes-ability {:async true :cost [(->c :credit 2)] :msg "do 2 meat damage" - :effect (effect (damage eid :meat 2 {:card card}))}}}}) + :effect (req (damage state side eid :meat 2 {:card card}))}}}}) (defcard "Anoetic Void" {:events [{:event :approach-server @@ -195,7 +195,7 @@ :req (req this-server) :successful {:msg "prevent the Runner from accessing cards other than Ash 2X3ZB9CY" - :effect (effect (set-only-card-to-access card))}}}]}) + :effect (req (set-only-card-to-access state side card))}}}]}) (defcard "Awakening Center" {:can-host (req (ice? target)) @@ -233,11 +233,11 @@ :duration :end-of-run :async true :req (req (get-card state ice)) - :effect (effect (trash eid (get-card state ice) {:cause-card card}))}]) + :effect (req (trash state side eid (get-card state ice) {:cause-card card}))}]) (system-msg state side (str "uses " (:title card) " to force the Runner to encounter " (card-str state ice))) (force-ice-encounter state side eid ice))))} :no-ability - {:effect (effect (system-msg (str "declines to use " (:title card))))}}}]}) + {:effect (req (system-msg state side (str "declines to use " (:title card))))}}}]}) (defcard "Bamboo Dome" {:install-req (req (filter #{"R&D"} targets)) @@ -258,9 +258,9 @@ :choices (take 3 (:deck corp)) :not-distinct true :msg "add 1 of the revealed cards to HQ" - :effect (effect (move target :hand) + :effect (req (move state side target :hand) (continue-ability - (let [from (take 2 (get-in @state [:corp :deck]))] + state side (let [from (take 2 (get-in @state [:corp :deck]))] (when (pos? (count from)) (reorder-choice :corp :runner from '() (count from) from))) card nil))} @@ -270,8 +270,8 @@ {:on-trash {:req (req (and (= :runner side) (:run @state))) - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card {:type :steal-additional-cost :duration :end-of-run :req (req (or (= (get-zone target) (:previous-zone card)) @@ -292,7 +292,7 @@ :unsuccessful {:async true :msg "trash itself" - :effect (effect (trash eid card {:cause-card card}))}}}]}) + :effect (req (trash state side eid card {:cause-card card}))}}}]}) (defcard "Bio Vault" {:install-req (req (remove #{"HQ" "R&D" "Archives"} targets)) @@ -302,7 +302,7 @@ :msg "end the run" :async true :cost [(->c :advancement 2) (->c :trash-can)] - :effect (effect (end-run eid card))}]}) + :effect (req (end-run state side eid card))}]}) (defcard "Black Level Clearance" {:events [{:event :successful-run @@ -373,7 +373,7 @@ :choices (req (cancellable (filter #(and (operation? %) (has-subtype? % "Transaction")) (:discard corp)) :sorted)) :async true - :effect (effect (play-instant eid (-> target + :effect (req (play-instant state side eid (-> target (assoc :rfg-instead-of-trashing true) (assoc-in [:special :rfg-when-trashed] true)) {:no-additional-cost true @@ -384,13 +384,13 @@ :abilities [{:label "Place 1 advancement counter on a card in this server" :async true :fake-cost [(->c :trash-can)] - :effect (effect (continue-ability - {:prompt "Choose a card in this server" + :effect (req (continue-ability + state side {:prompt "Choose a card in this server" :choices {:card #(in-same-server? % card)} :async true :msg (msg "place an advancement counter on " (card-str state target)) :cost [(->c :trash-can)] - :effect (effect (add-prop eid target :advance-counter 1 {:placed true}))} + :effect (req (add-prop state side eid target :advance-counter 1 {:placed true}))} card nil))}]}) (defcard "Caprice Nisei" @@ -398,7 +398,7 @@ :psi {:req (req this-server) :not-equal {:msg "end the run" :async true - :effect (effect (end-run eid card))}}}]}) + :effect (req (end-run state side eid card))}}}]}) (defcard "Cayambe Grid" (let [ability {:interactive (req (->> (all-installed state :corp) @@ -409,9 +409,9 @@ :label "place 1 advancement counter (start of turn)" :async true :effect - (effect + (req (continue-ability - (when (->> (all-installed state :corp) + state side (when (->> (all-installed state :corp) (filter #(and (ice? %) (same-server? card %))) count @@ -421,7 +421,7 @@ (same-server? % card))} :msg (msg "place 1 advancement counter on " (card-str state target)) :async true - :effect (effect (add-prop eid target :advance-counter 1 {:placed true}))}) + :effect (req (add-prop state side eid target :advance-counter 1 {:placed true}))}) card nil))}] {:events [(assoc ability :event :corp-turn-begins) {:event :approach-server @@ -429,9 +429,9 @@ :req (req this-server) :async true :effect - (effect + (req (continue-ability - (let [cost (->> (get-run-ices state) + state side (let [cost (->> (get-run-ices state) (filter #(pos? (get-counters % :advancement))) count (* 2))] @@ -488,13 +488,13 @@ :req (req (pos? (get-counters card :power))) :msg "remove all hosted power counters" :async true - :effect (effect (add-counter eid card :power (- (get-counters card :power)) nil))}] + :effect (req (add-counter state side eid card :power (- (get-counters card :power)) nil))}] :abilities [{:action true :cost [(->c :click 1)] :keep-menu-open :while-clicks-left :msg "place 1 power counter on itself" :async true - :effect (effect (add-counter eid card :power 1 nil))}]}) + :effect (req (add-counter state side eid card :power 1 nil))}]}) (defcard "Corporate Troubleshooter" {:abilities [{:label "Add strength to a rezzed piece of ice protecting this server" @@ -505,7 +505,7 @@ (protecting-same-server? card target)))} :msg (msg "add " (cost-value eid :x-credits) " strength to " (:title target)) - :effect (effect (pump-ice target (cost-value eid :x-credits) :end-of-turn))}]}) + :effect (req (pump-ice state side target (cost-value eid :x-credits) :end-of-turn))}]}) (defcard "Crisium Grid" {:static-abilities [{:type :block-successful-run @@ -515,7 +515,7 @@ (defcard "Cyberdex Virus Suite" (let [resolve-purge {:msg "purge virus counters" :async true - :effect (effect (purge eid))}] + :effect (req (purge state side eid))}] {:flags {:rd-reveal (req true)} :poison true :on-access {:async true @@ -532,7 +532,7 @@ :msg "purge virus counters" :cost [(->c :trash-can)] :async true - :effect (effect (purge eid))}]})) + :effect (req (purge state side eid))}]})) (defcard "Daniela Jorge Inácio" (let [steal-cost {:type :steal-additional-cost @@ -586,7 +586,7 @@ :msg (msg "swap " (card-str state to-swap) " with " (card-str state target)) :async true - :effect (effect (swap-cards-async eid to-swap target))}) + :effect (req (swap-cards-async state side eid to-swap target))}) ability {:optional {:waiting-prompt true @@ -597,8 +597,8 @@ :choices {:req (req (and (installed? target) (in-same-server? card target))) :not-self true} - :effect (effect (continue-ability (choose-swap target) card nil))} - :no-ability {:effect (effect (clear-wait-prompt :runner))}}}] + :effect (req (continue-ability state side (choose-swap target) card nil))} + :no-ability {:effect (req (clear-wait-prompt state :runner))}}}] {:events [{:event :approach-server :interactive (req true) :req (req this-server) @@ -637,9 +637,9 @@ (in-hand? %))} :async true :msg "add a card to the bottom of R&D" - :effect (effect (move target :deck) + :effect (req (move state side target :deck) (continue-ability - (when (< i n) + state side (when (< i n) (dhq (inc i) n)) card nil))})] {:flags {:rd-reveal (req true)} @@ -649,8 +649,8 @@ :yes-ability {:async true :msg "add cards in HQ to the bottom of R&D" - :effect (effect (continue-ability - (dhq 1 (count (:hand corp))) + :effect (req (continue-ability + state side (dhq 1 (count (:hand corp))) card nil))}}}})) (defcard "Djupstad Grid" @@ -658,7 +658,7 @@ :req (req (= (:previous-zone (:card context)) (get-zone card))) :interactive (req true) :async true - :effect (effect (damage eid :brain 1 {:card card}))}]}) + :effect (req (damage state side eid :brain 1 {:card card}))}]}) (defcard "Drone Screen" {:events [{:event :run @@ -668,18 +668,18 @@ :successful {:msg "do 1 meat damage" :async true - :effect (effect (damage eid :meat 1 {:card card + :effect (req (damage state side eid :meat 1 {:card card :unpreventable true}))}}}]}) (defcard "Embolus" (let [maybe-gain-counter {:once :per-turn :async true :label "Place 1 power counter (start of turn)" - :effect (effect + :effect (req (continue-ability - {:optional + state side {:optional {:prompt (msg "Pay 1 [Credit] to place 1 power counter on " (:title card) "?") - :yes-ability {:effect (effect (add-counter eid card :power 1 nil)) + :yes-ability {:effect (req (add-counter state side eid card :power 1 nil)) :async true :cost [(->c :credit 1)] :msg "place 1 power counter on itself"}}} @@ -688,14 +688,14 @@ :cost [(->c :power 1)] :msg "end the run" :async true - :effect (effect (end-run eid card))}] + :effect (req (end-run state side eid card))}] {:derezzed-events [(assoc corp-rez-toast :event :runner-turn-ends)] :events [(assoc maybe-gain-counter :event :corp-turn-begins) {:event :successful-run :req (req (pos? (get-counters card :power))) :msg "remove 1 power counter from itself" :async true - :effect (effect (add-counter eid card :power -1 nil))}] + :effect (req (add-counter state side eid card :power -1 nil))}] :abilities [maybe-gain-counter etr]})) @@ -713,7 +713,7 @@ :automatic :gain-credits :label "Gain 1 [Credits] (start of turn)" :async true - :effect (effect (gain-credits eid 1))}] + :effect (req (gain-credits state side eid 1))}] {:derezzed-events [(assoc corp-rez-toast :event :runner-turn-ends)] :events [(assoc ability :event :corp-turn-begins)] :abilities [ability]})) @@ -771,7 +771,7 @@ (str "trash " (enumerate-cards (take 2 deck)) " from the stack") "trash no cards from the stack (it is empty)"))) :async true - :effect (effect (mill :corp eid :runner 2))}]}) + :effect (req (mill state :corp eid :runner 2))}]}) (defcard "Ganked!" {:flags {:rd-reveal (req true)} @@ -808,7 +808,7 @@ :msg "trash itself" :effect (req (trash state side eid (assoc card :seen true) {:unpreventable true :cause-card card}))}) card nil))} - :no-ability {:effect (effect (system-msg (str "declines to use " (:title card))))}}}}) + :no-ability {:effect (req (system-msg state side (str "declines to use " (:title card))))}}}}) (defcard "Georgia Emelyov" {:events [{:event :unsuccessful-run @@ -816,12 +816,12 @@ (second (get-zone card)))) :async true :msg "do 1 net damage" - :effect (effect (damage eid :net 1 {:card card}))}] + :effect (req (damage state side eid :net 1 {:card card}))}] :abilities [{:cost [(->c :credit 2)] :label "Move to another server" :async true - :effect (effect (continue-ability - {:prompt "Choose a server" + :effect (req (continue-ability + state side {:prompt "Choose a server" :choices (server-list state) :msg (msg "move to " target) :effect (req (let [c (move state side card @@ -835,9 +835,9 @@ :interactive (req true) :async true :req (req this-server) - :effect (effect + :effect (req (continue-ability - (let [credit-cost (* 2 (count (:scored runner)))] + state side (let [credit-cost (* 2 (count (:scored runner)))] {:player :runner :async true :waiting-prompt true @@ -861,7 +861,7 @@ :msg (msg "force the Runner to lose all " (:credit runner) " [Credits]") :once :per-run :async true - :effect (effect (lose-credits :runner eid :all))}]}) + :effect (req (lose-credits state :runner eid :all))}]}) (defcard "Helheim Servers" {:abilities [{:label "All ice protecting this server has +2 strength until the end of the run" @@ -870,13 +870,13 @@ run (pos? (count (:hand corp))))) :cost [(->c :trash-from-hand 1)] - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card {:type :ice-strength :duration :end-of-run :req (req (protecting-same-server? card target)) :value 2}) - (update-all-ice)) + (update-all-ice state side)) :keep-menu-open :while-cards-in-hand}]}) (defcard "Henry Phillips" @@ -889,7 +889,7 @@ :req (req (and this-server tagged)) :msg (msg "gain " (* 2 (count (:broken-subs context))) " [Credits]") :async true - :effect (effect (hp-gain-credits :corp eid (count (:broken-subs context))))}]})) + :effect (req (hp-gain-credits state :corp eid (count (:broken-subs context))))}]})) (defcard "Hired Help" (let [prompt-to-trash-agenda-or-etr @@ -936,7 +936,7 @@ :choices {:req (req (in-same-server? card target))} :msg (msg "place an advancement token on " (card-str state target)) :cost [(->c :trash-can)] - :effect (effect (add-prop eid target :advance-counter 1 {:placed true}))}]}) + :effect (req (add-prop state side eid target :advance-counter 1 {:placed true}))}]}) (defcard "Increased Drop Rates" {:flags {:rd-reveal (req true)} @@ -986,7 +986,7 @@ (same-server? target card)))} :msg (msg "place 1 advancement counter on " (card-str state target)) :async true - :effect (effect (add-prop eid target :advance-counter 1 {:placed true}))}] + :effect (req (add-prop state side eid target :advance-counter 1 {:placed true}))}] {:static-abilities [{:type :ice-strength :req (req (and (ice? target) (= (card->server state card) (card->server state target)))) @@ -1018,15 +1018,15 @@ {:async true :prompt (str "Choose a server to install " (:title ice)) :choices (conj (mapv #(-> % :zone second zone->name) grids) "None") - :effect (effect (continue-ability (install-ice ice ices grids target) card nil))})) + :effect (req (continue-ability state side (install-ice ice ices grids target) card nil))})) (choose-ice [ices grids] (when (seq ices) {:async true :prompt "Choose an ice to reveal and install" :choices (conj (mapv :title ices) "None") :effect - (effect (continue-ability - (when-not (= "None" target) + (req (continue-ability + state side (when-not (= "None" target) (choose-grid (some #(when (= target (:title %)) %) ices) ices grids)) card nil))}))] {:events [{:event :corp-draw @@ -1085,7 +1085,7 @@ (program? %))} :cost [(->c :tag 1) (->c :trash-can)] :async true - :effect (effect (trash eid target {:cause-card card}))}]}) + :effect (req (trash state side eid target {:cause-card card}))}]}) (defcard "Khondi Plaza" {:x-fn (req (count (get-remotes state))) @@ -1102,7 +1102,7 @@ :choices {:req (req (and (installed? target) (in-same-server? card target)))} :async true - :effect (effect (add-prop eid target :advance-counter 1 {:placed true}))}] + :effect (req (add-prop state side eid target :advance-counter 1 {:placed true}))}] {:legal-zones (req (remove #{"HQ" "R&D" "Archives"} targets)) :derezzed-events [corp-rez-toast] :flags {:corp-phase-12 (req true)} @@ -1218,9 +1218,9 @@ (rezzed? %)) :all true} :async true - :effect (effect + :effect (req (continue-ability - (let [ice target] + state side (let [ice target] {:prompt "Choose a subroutine" :choices (req (unbroken-subroutines-choice ice)) :msg (msg "resolve the subroutine (\"[subroutine] " @@ -1235,7 +1235,7 @@ :req (req (and this-server (seq (filter :broken (:subroutines (:ice context)))))) :msg "force the Runner to lose [Click]" - :effect (effect (lose-clicks :runner 1))}]}) + :effect (req (lose-clicks state :runner 1))}]}) (defcard "Mavirus" (let [resolve-purge {:msg (msg "purge virus counters") @@ -1270,7 +1270,7 @@ :msg "purge virus counters" :cost [(->c :trash-can)] :async true - :effect (effect (purge eid))}]})) + :effect (req (purge state side eid))}]})) (defcard "Mercia B4LL4RD" {:events [{:event :corp-action-phase-ends @@ -1362,7 +1362,7 @@ ;; Adding a msg to print the ability's cost :msg "force the Runner to suffer a core damage or lose all remaining [Click]" :effect - (effect (continue-ability {:player :runner + (req (continue-ability state side {:player :runner :prompt "Choose one" :waiting-prompt true :choices (req ["Suffer 1 core damage" @@ -1383,15 +1383,15 @@ :req (req (and this-server (<= 2 (count run-ices)))) :async true :effect - (effect + (req (continue-ability - (let [passed-ice (:ice context)] + state side (let [passed-ice (:ice context)] {:prompt (msg "Choose a piece of ice to swap with " (:title target)) :choices {:req (req (and (installed? target) (ice? target) (= (target-server run) (second (get-zone target))) (not (same-card? target passed-ice))))} - :effect (effect (swap-ice target passed-ice))}) + :effect (req (swap-ice state side target passed-ice))}) card nil))}]}) (defcard "Mumbad Virtual Tour" @@ -1500,7 +1500,7 @@ (only-ev state side :advancement-placed :advance card)))) :msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits eid 1))}] + :effect (req (gain-credits state side eid 1))}] {:events [(assoc ng :event :advance) (assoc ng :event :advancement-placed)]})) @@ -1519,14 +1519,14 @@ {:async true :msg "look at the top 5 cards of R&D" :effect - (effect + (req (continue-ability - {:async true + state side {:async true :prompt "Choose a card in R&D" :choices (take 5 (:deck corp)) - :effect (effect + :effect (req (continue-ability - (when-let [rdc target] + state side (when-let [rdc target] {:prompt "Choose a card in HQ" :choices {:card in-hand?} :msg "swap a card from the top 5 of R&D with a card in HQ" @@ -1548,7 +1548,7 @@ (map first (turn-events state side :advance))))))) :msg (msg "place 1 additional advancement counter on " (card-str state (:card context))) :async true - :effect (effect (add-prop :corp eid (:card context) :advance-counter 1 {:placed true}))}]}) + :effect (req (add-prop state :corp eid (:card context) :advance-counter 1 {:placed true}))}]}) (defcard "Off the Grid" {:install-req (req (remove #{"HQ" "R&D" "Archives"} targets)) @@ -1565,8 +1565,8 @@ {:on-trash {:req (req (and (= :runner side) (:run @state))) - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card {:type :cannot-steal :duration :end-of-run :req (req (and (not-any? #(= (:title target) (:title %)) @@ -1602,9 +1602,9 @@ (total-available-credits state :corp eid card)))} :async true :effect - (effect + (req (continue-ability - (let [n target] + state side (let [n target] (assoc (give-tags n) :cost [(->c :credit n)])) card nil))}] {:on-trash {:silent (req true) @@ -1682,14 +1682,14 @@ :on-access {:req (req (not (in-discard? card))) :msg "gain 2 [Credits]" :async true - :effect (effect (gain-credits :corp eid 2))}}) + :effect (req (gain-credits state :corp eid 2))}}) (defcard "Red Herrings" {:on-trash {:req (req (and (= :runner side) (:run @state))) - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card {:type :steal-additional-cost :duration :end-of-run :req (req (or (= (get-zone target) (:previous-zone card)) @@ -1710,7 +1710,7 @@ (is-central? (:server context)))) :msg "remove 1 hosted power counter" :async true - :effect (effect (add-counter eid card :power -1 nil))}] + :effect (req (add-counter state side eid card :power -1 nil))}] :on-rez {:waiting-prompt true :prompt "How many credits do you want to pay?" :choices (req (map str (range (inc (min 4 (get-in @state [:corp :credit])))))) @@ -1742,7 +1742,7 @@ :cost [(->c :trash-can)] :msg "do 1 core damage" :async true - :effect (effect (damage eid :brain 1 {:card card}))}]}) + :effect (req (damage state side eid :brain 1 {:card card}))}]}) (defcard "SanSan City Grid" {:static-abilities [{:type :advancement-requirement @@ -1756,7 +1756,7 @@ :events [{:event :corp-install :req (req (and (ice? (:card context)) (protecting-same-server? card (:card context)))) - :effect (effect (set-prop (:card context) :extra-advance-counter 1))}] + :effect (req (set-prop state side (:card context) :extra-advance-counter 1))}] :leave-play (req (doseq [c (:ices (card->server state card))] (update! state side (dissoc c :extra-advance-counter))) (update-all-ice state side))}) @@ -1777,7 +1777,7 @@ :successful {:async true :msg "do 3 net damage" - :effect (effect (damage eid :net 3 {:card card}))}}} + :effect (req (damage state side eid :net 3 {:card card}))}}} card nil))))}]}) (defcard "Shackleton Grid" @@ -1801,7 +1801,7 @@ :msg "place 3 [Credits]" :once :per-turn :async true - :effect (effect (add-counter eid card :credit 3 nil))} + :effect (req (add-counter state side eid card :credit 3 nil))} (take-all-credits-ability {:cost [(->c :click 1)] :action true :once :per-turn})]}) @@ -1811,10 +1811,10 @@ :msg "prevent cards being installed until the end of the run" :req (req (and this-server run)) :cost [(->c :trash-can)] - :effect (effect (register-run-flag! card :corp-lock-install (constantly true)) - (register-run-flag! card :runner-lock-install (constantly true)) - (toast :runner "Cannot install until the end of the run") - (toast :corp "Cannot install until the end of the run"))}]}) + :effect (req (register-run-flag! state side card :corp-lock-install (constantly true)) + (register-run-flag! state side card :runner-lock-install (constantly true)) + (toast state :runner "Cannot install until the end of the run") + (toast state :corp "Cannot install until the end of the run"))}]}) (defcard "Simone Diego" {:recurring 2 @@ -1828,8 +1828,8 @@ {:on-trash {:req (req (and (= :runner side) (:run @state))) - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card {:type :steal-additional-cost :duration :end-of-run :req (req (or (= (get-zone target) (:previous-zone card)) @@ -1861,7 +1861,7 @@ (installed? target) (can-pay-to-rez? state side (assoc eid :source card) target {:cost-bonus -2})))} :async true - :effect (effect (rez eid target {:cost-bonus -2}))}}}]}) + :effect (req (rez state side eid target {:cost-bonus -2}))}}}]}) (defcard "Tempus" {:flags {:rd-reveal (req true)} @@ -1963,7 +1963,7 @@ (ice? (:card context)))) :successful {:msg "gain 1 [Credits]" :async true - :effect (effect (gain-credits eid 1))}}}]}) + :effect (req (gain-credits state side eid 1))}}}]}) (defcard "Tranquility Home Grid" {:legal-zones (req (remove #{"HQ" "R&D" "Archives"} targets)) @@ -2006,8 +2006,8 @@ (assoc ability :event :agenda-scored)] :on-trash {:req (req (and run (= :runner side))) - :effect (effect (register-events - card + :effect (req (register-events + state side card [(-> ability (assoc :event :agenda-stolen :duration :end-of-run) (assoc-in [:optional :req] (req (= (:previous-zone card) (:previous-zone (:card context))))))]))}})) @@ -2031,8 +2031,8 @@ {:events [{:event :subroutines-broken :req (req (and this-server (:all-subs-broken context))) :msg "reduce the Runner's maximum hand size by 1 until the start of the next Corp turn" - :effect (effect (register-lingering-effect - card + :effect (req (register-lingering-effect + state side card {:type :hand-size :duration :until-corp-turn-begins :req (req (= :runner side)) @@ -2051,7 +2051,7 @@ (can-be-advanced? state target) (in-same-server? card target)))} :async true - :effect (effect (add-prop eid target :advance-counter 2 {:placed true}))}]}) + :effect (req (add-prop state side eid target :advance-counter 2 {:placed true}))}]}) (defcard "Vovô Ozetti" {:static-abilities [{:type :rez-cost @@ -2085,8 +2085,8 @@ (quantify n "installed card") (when (not (pos? n)) "but there are no installed cards to trash")))) - :effect (effect (continue-ability - (let [n (min 2 (count (all-installed state :runner)))] + :effect (req (continue-ability + state side (let [n (min 2 (count (all-installed state :runner)))] (when (pos? n) (wt n))) card nil))}}})] @@ -2101,7 +2101,7 @@ (= (second warroid-zone) (second target-zone))))) targets)) - :effect (effect (continue-ability (ability) card nil))}]})) + :effect (req (continue-ability state side (ability) card nil))}]})) (defcard "Will-o'-the-Wisp" {:implementation "Doesn't restrict icebreaker selection" @@ -2131,7 +2131,7 @@ :interactive (req true) :req (req (valid-target-fn context card)) :msg "gain 2 [Credits]" - :effect (effect (gain-credits eid 2))} + :effect (req (gain-credits state side eid 2))} {:event :corp-trash :interactive (req true) :once-per-instance false @@ -2148,7 +2148,7 @@ (valid-target-fn context card)))) :async true :msg "gain 2 [Credits]" - :effect (effect (gain-credits eid 2))}]})) + :effect (req (gain-credits state side eid 2))}]})) (defcard "ZATO City Grid" {:legal-zones (req (remove #{"HQ" "R&D" "Archives"} targets)) diff --git a/src/clj/game/core.clj b/src/clj/game/core.clj index a57a594201..61cd472dcf 100644 --- a/src/clj/game/core.clj +++ b/src/clj/game/core.clj @@ -828,7 +828,6 @@ (expose-vars [game.macros continue-ability - effect msg req wait-for diff --git a/src/clj/game/core/charge.clj b/src/clj/game/core/charge.clj index 787f6411d7..048b96a231 100644 --- a/src/clj/game/core/charge.clj +++ b/src/clj/game/core/charge.clj @@ -4,7 +4,7 @@ [game.core.card :refer :all] [game.core.eid :refer [effect-completed]] [game.core.say :refer [system-msg]] - [game.macros :refer [req msg effect]] + [game.macros :refer [req msg]] [game.core.props :refer [add-counter]])) (defn can-charge diff --git a/src/clj/game/core/commands.clj b/src/clj/game/core/commands.clj index 3f2ba0eb6f..f4c5eaa3a2 100644 --- a/src/clj/game/core/commands.clj +++ b/src/clj/game/core/commands.clj @@ -35,7 +35,7 @@ [game.core.trace :refer [init-trace]] [game.core.update :refer [update!]] [game.core.winning :refer [clear-win]] - [game.macros :refer [continue-ability effect msg req wait-for]] + [game.macros :refer [continue-ability msg req wait-for]] [game.utils :refer [dissoc-in enumerate-str quantify safe-split same-card? same-side? server-card string->num]] [jinteki.utils :refer [other-side str->int]])) @@ -56,7 +56,7 @@ (defn command-adv-counter [state side value] (let [value (constrain-value value 0 1000)] (resolve-ability state side - {:effect (effect (set-adv-counter target value)) + {:effect (req (set-adv-counter state side target value)) :choices {:card (fn [t] (same-side? (:side t) side))}} (make-card {:title "/adv-counter command"}) nil))) @@ -119,7 +119,7 @@ :choices {:card #(and (runner? %) (in-hand? %))} :async true - :effect (effect (runner-install (make-eid state eid) target {:facedown true}))} + :effect (req (runner-install state side (make-eid state eid) target {:facedown true}))} (make-card {:title "/faceup command"}) nil)) (defn command-counter [state side args] @@ -145,8 +145,8 @@ (if advance (command-adv-counter state side value) (resolve-ability state side - {:effect (effect (update! (assoc-in target [:counter counter-type] value)) - (system-msg (str "sets " (name counter-type) " counters to " value " on " + {:effect (req (update! state side (assoc-in target [:counter counter-type] value)) + (system-msg state side (str "sets " (name counter-type) " counters to " value " on " (card-str state target)))) :choices {:card (fn [t] (same-side? (:side t) side))}} (make-card {:title "/counter command"}) nil))))) @@ -256,7 +256,7 @@ "Toggles :uniqueness of the selected card" [state side] (resolve-ability state side - {:effect (effect (set-prop target :uniqueness (not (:uniqueness target)))) + {:effect (req (set-prop state side target :uniqueness (not (:uniqueness target)))) :msg (msg "make " (card-str state target) (when (:uniqueness target) " not") ;it was unique before " unique") @@ -303,22 +303,22 @@ :choices {:card #(and (ice? %) (#{[:hand]} (:zone %)))} :async true - :effect (effect + :effect (req (continue-ability - (let [chosen-ice target] + state side (let [chosen-ice target] {:prompt "Choose a server" :choices (req servers) :async true - :effect (effect + :effect (req (continue-ability - (let [chosen-server target + state side (let [chosen-server target num-ice (count (get-in (:corp @state) (conj (server->zone state target) :ices)))] {:prompt "Which position to install in? (0 is innermost)" :choices (vec (reverse (map str (range (inc num-ice))))) :async true - :effect (effect (corp-install - (make-eid state eid) + :effect (req (corp-install + state side (make-eid state eid) chosen-ice chosen-server {:no-install-cost true :index (str->int target)}))}) @@ -352,7 +352,7 @@ (in-hand? target))))} :msg (msg "score " (card-str state target {:visible true}) ", ignoring all restrictions") :async true - :effect (effect (score eid target {:no-req true :ignore-turn true}))} + :effect (req (score state side eid target {:no-req true :ignore-turn true}))} (make-card {:title "the '/score' command"}) nil))) (defn command-summon @@ -409,14 +409,14 @@ :choices {:card #(and (f %) (installed? %))} :async true - :effect (effect + :effect (req (continue-ability - (let [h1 target] + state side (let [h1 target] {:prompt "Choose the card to host the first card" :choices {:card #(and (f %) (installed? %) (not (same-card? % h1)))} - :effect (effect (host target h1 nil))}) + :effect (req (host state side target h1 nil))}) nil nil))} nil nil))) @@ -429,7 +429,7 @@ :waiting-prompt true :choices {:card #(rezzed? %)} :async true - :effect (effect (derez eid target {:no-event true}))} + :effect (req (derez state side eid target {:no-event true}))} nil nil))) (defn command-trash @@ -441,7 +441,7 @@ :waiting-prompt true :choices {:card #(f %)} :async true - :effect (effect (trash eid target {:unpreventable true}))} + :effect (req (trash state side eid target {:unpreventable true}))} nil nil))) (defn command-swap-sides @@ -492,7 +492,7 @@ "/bp" #(swap! %1 assoc-in [%2 :bad-publicity :base] (constrain-value value -1000 1000)) "/bug" command-bug-report "/card-info" #(resolve-ability %1 %2 - {:effect (effect (system-msg (str "shows card-info of " + {:effect (req (system-msg state side (str "shows card-info of " (card-str state target) ": " (get-card state target)))) :choices {:card (fn [t] (same-side? (:side t) %2))}} @@ -556,7 +556,7 @@ "/move-bottom" #(resolve-ability %1 %2 {:prompt "Choose a card in hand to put on the bottom of your deck" :waiting-prompt true - :effect (effect (move target :deck)) + :effect (req (move state side target :deck)) :choices {:card (fn [t] (and (same-side? (:side t) %2) (in-hand? t)))}} (make-card {:title "/move-bottom command"}) nil) @@ -585,16 +585,16 @@ (resolve-ability %1 %2 {:choices {:card (fn [t] (same-side? (:side t) %2))} :async true - :effect (effect (rez eid target {:ignore-cost :all-costs :force true}))} + :effect (req (rez state side eid target {:ignore-cost :all-costs :force true}))} (make-card {:title "/rez command"}) nil)) "/rez-all" #(when (= %2 :corp) (command-rezall %1 %2)) "/rez-free" #(when (= %2 :corp) (resolve-ability %1 %2 {:choices {:card (fn [t] (same-side? (:side t) %2))} :async true - :effect (effect (disable-card target) - (rez eid target {:ignore-cost :all-costs :force true}) - (enable-card (get-card state target)))} + :effect (req (disable-card state side target) + (rez state side eid target {:ignore-cost :all-costs :force true}) + (enable-card state side (get-card state target)))} (make-card {:title "/rez command"}) nil)) "/rfg" #(resolve-ability %1 %2 {:prompt "Choose a card" @@ -609,7 +609,7 @@ "/set-mark" #(command-set-mark %1 %2 args) "/score" command-score "/show-hand" #(resolve-ability %1 %2 - {:effect (effect (system-msg (str + {:effect (req (system-msg state side (str (if (= :corp %2) "shows cards from HQ: " "shows cards from the grip: ") @@ -625,7 +625,7 @@ :all true :card (fn [c] (and (installed? c) (ice? c)))} - :effect (effect (swap-ice (first targets) (second targets)))} + :effect (req (swap-ice state side (first targets) (second targets)))} (make-card {:title "/swap-ice command"}) nil)) "/swap-installed" #(when (= %2 :corp) (resolve-ability @@ -637,7 +637,7 @@ :card (fn [c] (and (installed? c) (corp? c) (not (ice? c))))} - :effect (effect (swap-installed (first targets) (second targets)))} + :effect (req (swap-installed state side (first targets) (second targets)))} (make-card {:title "/swap-installed command"}) nil)) "/swap-sides" #(command-swap-sides %1 %2) "/tag" #(swap! %1 assoc-in [%2 :tag :base] (constrain-value value 0 1000)) diff --git a/src/clj/game/core/def_helpers.clj b/src/clj/game/core/def_helpers.clj index 20f3cff6ae..2dd2fa0675 100644 --- a/src/clj/game/core/def_helpers.clj +++ b/src/clj/game/core/def_helpers.clj @@ -28,7 +28,7 @@ [game.core.to-string :refer [card-str]] [game.core.toasts :refer [toast]] [game.core.tags :refer [gain-tags]] - [game.macros :refer [continue-ability effect msg req wait-for]] + [game.macros :refer [continue-ability msg req wait-for]] [game.utils :refer [enumerate-cards remove-once same-card? server-card to-keyword quantify]] [jinteki.utils :refer [faction-label other-side]])) @@ -131,7 +131,7 @@ (:req args) (req (= server (:server context)))) :msg msg - :effect (effect (access-bonus :runner server bonus))})) + :effect (req (access-bonus state :runner server bonus))})) (defn do-net-damage "Do specified amount of net-damage." @@ -139,7 +139,7 @@ {:label (str "Do " dmg " net damage") :async true :msg (str "do " dmg " net damage") - :effect (effect (damage eid :net dmg {:card card}))}) + :effect (req (damage state side eid :net dmg {:card card}))}) (defn do-meat-damage "Do specified amount of meat damage." @@ -147,7 +147,7 @@ {:label (str "Do " dmg " meat damage") :async true :msg (str "do " dmg " meat damage") - :effect (effect (damage eid :meat dmg {:card card}))}) + :effect (req (damage state side eid :meat dmg {:card card}))}) (defn do-brain-damage "Do specified amount of core damage." @@ -155,7 +155,7 @@ {:label (str "Do " dmg " core damage") :async true :msg (str "do " dmg " core damage") - :effect (effect (damage eid :brain dmg {:card card}))}) + :effect (req (damage state side eid :brain dmg {:card card}))}) (defn rfg-on-empty "Used in :event maps for effects like Malandragem" @@ -164,8 +164,8 @@ :req (req (and (same-card? card (:card context)) (not (get-in card [:special :skipped-loading])) (not (pos? (get-counters card counter-type))))) - :effect (effect (system-msg (str "removes " (:title card) " from the game")) - (move card :rfg))}) + :effect (req (system-msg state side (str "removes " (:title card) " from the game")) + (move state side card :rfg))}) (defn trash-on-empty "Used in :event maps for effects like Daily Casts" @@ -175,8 +175,8 @@ (not (get-in card [:special :skipped-loading])) (not (pos? (get-counters card counter-type))))) :async true - :effect (effect (system-msg (str "trashes " (:title card))) - (trash eid card {:unpreventable true :source-card card}))}) + :effect (req (system-msg state side (str "trashes " (:title card))) + (trash state side eid card {:unpreventable true :source-card card}))}) (defn pick-tiered-sfx [base upper-limit n] @@ -216,7 +216,7 @@ :msg (str "give the Runner " (quantify n "tag")) :interactive (req true) :async true - :effect (effect (gain-tags :corp eid n))}) + :effect (req (gain-tags state :corp eid n))}) (defn run-server-ability "Runs a target server, if possible. " @@ -258,7 +258,7 @@ :choices (req (filter #(can-run-server? state %) remotes)) :label "Run a remote server" :msg (msg "make a run on " target) - :effect (effect (make-run eid target card))}) + :effect (req (make-run state side eid target card))}) (def run-central-server-ability {:prompt "Choose a central server" @@ -267,7 +267,7 @@ :async true :label "Run a central server" :msg (msg "make a run on " target) - :effect (effect (make-run eid target card))}) + :effect (req (make-run state side eid target card))}) (defn run-server-from-choices-ability ([choices] (run-server-from-choices-ability choices nil)) @@ -419,9 +419,9 @@ :prompt "Jack out?" :waiting-prompt true :yes-ability {:async true - :effect (effect (system-msg :runner (str "uses " (:title card) " to jack out")) - (jack-out eid))} - :no-ability {:effect (effect (system-msg :runner (str "uses " (:title card) " to continue the run")))}}})) + :effect (req (system-msg state :runner (str "uses " (:title card) " to jack out")) + (jack-out state side eid))} + :no-ability {:effect (req (system-msg state :runner (str "uses " (:title card) " to continue the run")))}}})) (defn get-x-fn [] (fn get-x-fn-inner @@ -518,7 +518,7 @@ (pred %))} :msg {:public (msg "add " (card-str state target {:visible (faceup? target)}) " to HQ") :corp (msg "add " (card-str state target {:maybe-visible true}) " to HQ")} - :effect (effect (move :corp target :hand))})) + :effect (req (move state :corp target :hand))})) (defn tutor-abi "Tutor a card. Optionally, pass a restriction, which is a 1-fn the cards must pass" @@ -633,7 +633,7 @@ :msg {:public (msg "place " (quantify qty "advancement counter") " on " (card-str state target)) :corp (msg "place " (quantify qty "advancement counter") " on " (card-str state target {:maybe-visible true}))} :async true - :effect (effect (add-prop eid target :advance-counter qty {:placed true}))}))) + :effect (req (add-prop state side eid target :advance-counter qty {:placed true}))}))) (defn look-at-the-top [looking-side deck-side qty] diff --git a/src/clj/game/core/ice.clj b/src/clj/game/core/ice.clj index 5c7121c254..a01b2e2371 100644 --- a/src/clj/game/core/ice.clj +++ b/src/clj/game/core/ice.clj @@ -10,7 +10,7 @@ [game.core.payment :refer [build-cost-label can-pay? merge-costs ->c stealth-value]] [game.core.say :refer [system-msg]] [game.core.update :refer [update!]] - [game.macros :refer [req effect msg continue-ability wait-for]] + [game.macros :refer [req msg continue-ability wait-for]] [game.utils :refer [same-card? pluralize quantify remove-once]] [jinteki.utils :refer [make-label]] [clojure.string :as string] @@ -683,8 +683,8 @@ (str " " (string/join " or " (sort subtypes)))) (pluralize " subroutine" n) (add-stealth-to-label cost)))) - :effect (effect (continue-ability - (let [n (if (fn? n) + :effect (req (continue-ability + state side (let [n (if (fn? n) (n state side eid card nil) n)] (when (can-pay? state side eid @@ -728,7 +728,7 @@ card) (get-strength card)) duration-string) - :effect (effect (pump card + :effect (req (pump state side card (get-pump-strength state side (assoc args :pump strength) diff --git a/src/clj/game/core/installing.clj b/src/clj/game/core/installing.clj index 462e6d83d0..730821c21c 100644 --- a/src/clj/game/core/installing.clj +++ b/src/clj/game/core/installing.clj @@ -27,7 +27,7 @@ [game.core.to-string :refer [card-str]] [game.core.toasts :refer [toast]] [game.core.update :refer [update!]] - [game.macros :refer [continue-ability effect req wait-for]] + [game.macros :refer [continue-ability req wait-for]] [game.utils :refer [dissoc-in enumerate-str in-coll? same-card? to-keyword quantify]] [medley.core :refer [find-first]])) @@ -427,7 +427,7 @@ {:prompt (str "Choose a location to install " (:title card)) :choices (installable-servers state card) :async true - :effect (effect (corp-install eid card target args))} + :effect (req (corp-install state side eid card target args))} card nil) ;; A card was selected as the server; recurse, with the :host-card parameter set. (and (map? server) @@ -786,7 +786,7 @@ {:choices hosting :prompt (str "Choose a card to host " (:title card) " on") :async true - :effect (effect (runner-install-pay eid card (assoc args :host-card target)))} + :effect (req (runner-install-pay state side eid card (assoc args :host-card target)))} card nil) (if-let [potential-hosts (runner-can-host state side eid card args)] (runner-host-choice state side eid card potential-hosts args) diff --git a/src/clj/game/core/optional.clj b/src/clj/game/core/optional.clj index 2ffaef5023..a68fc878d0 100644 --- a/src/clj/game/core/optional.clj +++ b/src/clj/game/core/optional.clj @@ -7,7 +7,7 @@ [game.core.prompts :refer [show-prompt]] [game.core.toasts :refer [toast]] [game.core.update :refer [update!]] - [game.macros :refer [effect req wait-for]] + [game.macros :refer [req wait-for]] [clojure.string :as string])) (defn optional-ability @@ -75,8 +75,8 @@ :label (str "Toggle auto-resolve on " ability-name) :prompt (str "Set auto-resolve on " ability-name " to:") :choices ["Always" "Never" "Ask"] - :effect (effect (update! (assoc-in card [:special toggle-kw] (keyword (string/lower-case target)))) - (toast (str "From now on, " ability-name " will " + :effect (req (update! state side (assoc-in card [:special toggle-kw] (keyword (string/lower-case target)))) + (toast state side (str "From now on, " ability-name " will " ({:always "always" :never "never" :ask "ask whether it should"} (get-in (get-card state card) [:special toggle-kw])) " resolve.") "info"))}) diff --git a/src/clj/game/core/psi.clj b/src/clj/game/core/psi.clj index 16790ec3c1..23a90c9d25 100644 --- a/src/clj/game/core/psi.clj +++ b/src/clj/game/core/psi.clj @@ -7,7 +7,7 @@ [game.core.flags :refer [any-flag-fn?]] [game.core.prompts :refer [clear-wait-prompt show-prompt-with-dice show-wait-prompt]] [game.core.say :refer [system-msg]] - [game.macros :refer [continue-ability effect wait-for]] + [game.macros :refer [continue-ability req wait-for]] [jinteki.utils :refer [str->int]] [clojure.string :as string] [game.core.payment :refer [->c]])) @@ -71,7 +71,7 @@ (-> ability (dissoc :psi :once :req) (assoc :async true - :effect (effect (psi-game eid card psi targets)))) + :effect (req (psi-game state side eid card psi targets)))) card targets) (effect-completed state side eid))) diff --git a/src/clj/game/core/rezzing.clj b/src/clj/game/core/rezzing.clj index 947c212a39..f8757eeb4d 100644 --- a/src/clj/game/core/rezzing.clj +++ b/src/clj/game/core/rezzing.clj @@ -17,7 +17,7 @@ [game.core.toasts :refer [toast]] [game.core.to-string :refer [card-str]] [game.core.update :refer [update!]] - [game.macros :refer [continue-ability effect wait-for]] + [game.macros :refer [continue-ability req wait-for]] [game.utils :refer [enumerate-str to-keyword]])) (defn get-rez-cost @@ -157,10 +157,10 @@ {:optional {:prompt "Pay the alternative Rez cost?" :yes-ability {:async true - :effect (effect (rez eid card (merge args {:ignore-cost true + :effect (req (rez state side eid card (merge args {:ignore-cost true :alternative-cost alternative-cost})))} :no-ability {:async true - :effect (effect (rez eid card (merge args {:declined-alternative-cost true})))}}} + :effect (req (rez state side eid card (merge args {:declined-alternative-cost true})))}}} card nil) (complete-rez state side eid card args)) (effect-completed state side eid))))) diff --git a/src/clj/game/core/runs.clj b/src/clj/game/core/runs.clj index 2f57ca02bc..d505cfb6e3 100644 --- a/src/clj/game/core/runs.clj +++ b/src/clj/game/core/runs.clj @@ -20,7 +20,7 @@ [game.core.subtypes :refer [update-all-subtypes]] [game.core.to-string :refer [card-str]] [game.core.update :refer [update!]] - [game.macros :refer [continue-ability effect req wait-for]] + [game.macros :refer [continue-ability req wait-for]] [game.utils :refer [dissoc-in same-card?]] [jinteki.utils :refer [count-bad-pub other-side]] [clojure.stacktrace :refer [print-stack-trace]] @@ -670,8 +670,8 @@ {:prompt (str "You are prevented from breaching " (zone->name server) " this run.") :choices ["OK"] :async true - :effect (effect (system-msg :runner (str "is prevented from breaching " (zone->name server) " this run.")) - (handle-end-run eid))} + :effect (req (system-msg state :runner (str "is prevented from breaching " (zone->name server) " this run.")) + (handle-end-run state side eid))} nil nil) ;; Any number of replace-breach effects diff --git a/src/clj/game/core/trace.clj b/src/clj/game/core/trace.clj index 9c9f40cc65..c17b8296a9 100644 --- a/src/clj/game/core/trace.clj +++ b/src/clj/game/core/trace.clj @@ -7,7 +7,7 @@ [game.core.link :refer [get-link]] [game.core.prompts :refer [clear-wait-prompt show-trace-prompt show-wait-prompt]] [game.core.say :refer [system-msg system-say]] - [game.macros :refer [continue-ability effect wait-for]] + [game.macros :refer [continue-ability req wait-for]] [game.core.payment :refer [->c]])) (defn- determine-initiator @@ -175,7 +175,7 @@ (-> ability (dissoc :trace :req) (assoc :async true - :effect (effect (init-trace eid card trace)))) + :effect (req (init-trace state side eid card trace)))) card targets) (effect-completed state side eid))) diff --git a/src/clj/game/macros.clj b/src/clj/game/macros.clj index 597e557b4c..98ab556f9f 100644 --- a/src/clj/game/macros.clj +++ b/src/clj/game/macros.clj @@ -70,13 +70,6 @@ :when (contains? forms x)] (get forms x)))) -(defn- effect-state-handler - [expr] - (for [body expr] - (if (#{:runner :corp} (second body)) - (concat [(first body) 'state (second body)] (drop 2 body)) - (concat [(first body) 'state 'side] (rest body))))) - (defmacro req [& expr] (let [needed-locals (find-undefined-locals expr) nls (emit-only needed-locals)] @@ -86,9 +79,6 @@ (let [~@nls] ~@expr)))) -(defmacro effect [& expr] - `(req ~@(effect-state-handler expr))) - (defmacro msg [& expr] `(req (str ~@expr))) diff --git a/src/clj/tasks/remove_effect.clj b/src/clj/tasks/remove_effect.clj new file mode 100644 index 0000000000..0b32c32659 --- /dev/null +++ b/src/clj/tasks/remove_effect.clj @@ -0,0 +1,93 @@ +(ns tasks.remove-effect + (:require + [clojure.java.io :as io] + [rewrite-clj.node :as n] + [rewrite-clj.zip :as z] + [clojure.string :as str])) + +(def cutlery + (-> " +(defcard + {:abilities [{:action true + :cost [(->c :click 1)] + :effect (effect (move :corp card :deck nil) + (shuffle! :corp :deck) + (update-all-agenda-points))}] + :flags {:has-abilities-when-stolen true}}) +" + (z/of-string) + (z/up))) + +(defn add-state-side + [zloc] + (if (z/list? zloc) + (let [zloc (z/down zloc)] + (if-let [zloc (z/right zloc)] + (if (and (n/keyword-node? (z/node zloc)) + (#{:corp :runner} (z/sexpr zloc))) + (-> zloc + (z/insert-left 'state) + (z/up)) + (-> zloc + (z/insert-left 'state) + (z/insert-left 'side) + (z/up))) + (-> zloc + (z/insert-right 'side) + (z/insert-right 'state) + (z/up)))) + zloc)) + +(defn edit-body-form [zloc] + (let [zloc (if (z/whitespace-or-comment? zloc) + zloc + (add-state-side zloc))] + (if-let [zloc (z/right* zloc)] + (recur zloc) + (z/up zloc)))) + +(defn replace-effect + [zloc] + (-> zloc + (z/down) + (z/replace 'req) + (z/up))) + +(defn update-call + [zloc] + (-> zloc + (replace-effect) + (z/down) + (edit-body-form))) + +(comment + (-> cutlery + (z/prewalk effect-zloc? update-call) + (z/string) + (println))) + +(defn effect-zloc? [zloc] + (and (z/list? zloc) + (= "effect" + (-> zloc z/down z/string)))) + +(defn rewrite-file [zloc] + (z/prewalk zloc + effect-zloc? + (fn [zloc] + (update-call zloc)))) + +(defn process-file [file] + (->> (z/of-file file) + (z/up) + (rewrite-file) + (z/root-string) + (spit file))) + +(comment + (doseq [file (sort (file-seq (io/file "src/clj/game"))) + :when (.isFile file) + :when (not (str/includes? (str file) "macros"))] + (prn (str file)) + (process-file file)) + ) diff --git a/src/clj/web/core.clj b/src/clj/web/core.clj index d977d75f74..b20c61888a 100644 --- a/src/clj/web/core.clj +++ b/src/clj/web/core.clj @@ -4,7 +4,7 @@ [web.system :refer [start stop]] [taoensso.timbre :as timbre] [web.logs :refer [timbre-init!]]) - (:gen-class :main true)) + (:gen-class)) (defn -main [& _args] (let [system (start)