From 577e96b62d9a3beda061f91eb79dd9355fb868ef Mon Sep 17 00:00:00 2001 From: NB Kelly Date: Wed, 20 Mar 2024 07:52:06 +1300 Subject: [PATCH 01/20] descent charges credit on expend --- src/clj/game/cards/ice.clj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/clj/game/cards/ice.clj b/src/clj/game/cards/ice.clj index 5a24472501..0312b7615d 100644 --- a/src/clj/game/cards/ice.clj +++ b/src/clj/game/cards/ice.clj @@ -2005,6 +2005,7 @@ (let [shuffle-ab {:label "Draw 1 card and shuffle 2 agendas in HQ and/or Archives into R&D" :msg "draw 1 card" + :cost [:credit 1] :effect (req (wait-for (draw state side 1) From b48a9cd32c39f6339c8c8e015a8cf278a44eaf4e Mon Sep 17 00:00:00 2001 From: NB Kelly Date: Wed, 20 Mar 2024 07:57:27 +1300 Subject: [PATCH 02/20] juli marked as once per turn --- src/clj/game/cards/resources.clj | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/clj/game/cards/resources.clj b/src/clj/game/cards/resources.clj index 4c96afcba8..9f4f36b873 100644 --- a/src/clj/game/cards/resources.clj +++ b/src/clj/game/cards/resources.clj @@ -1832,7 +1832,12 @@ {:data {:counter {:power 4}} :events [(trash-on-empty :power) {:event :runner-spent-click + :once :per-turn :req (req (let [all-cards (get-all-cards state)] + ;; TODO - assert this works when (e.g.) using the last click on lib-acc + ;; and having it trashed (all-cards wont find it) + ;; also asset that the first-event? fn actually works right... + ;; -nbk, mar '24 (and (resource? (find-cid (first target) all-cards)) (first-event? state side :runner-spent-click #(resource? From 5f4a8e050f823eab311a9cf0b45687635e5f51d1 Mon Sep 17 00:00:00 2001 From: NB Kelly Date: Wed, 20 Mar 2024 08:02:37 +1300 Subject: [PATCH 03/20] valentina only triggers when the runner removes tags --- src/clj/game/cards/resources.clj | 1 + 1 file changed, 1 insertion(+) diff --git a/src/clj/game/cards/resources.clj b/src/clj/game/cards/resources.clj index 9f4f36b873..2ec0d366aa 100644 --- a/src/clj/game/cards/resources.clj +++ b/src/clj/game/cards/resources.clj @@ -3701,6 +3701,7 @@ " to " (decapitalize target)))) :else (effect-completed state side eid)))} :events [{:event :runner-lose-tag + :req (req (= :runner (second targets))) :player :runner :msg "gain 1 [Credits]" :async true From 7fab5afe39c2e88c0fc7e287908a68c1a1f57853 Mon Sep 17 00:00:00 2001 From: NB Kelly Date: Wed, 20 Mar 2024 08:07:49 +1300 Subject: [PATCH 04/20] amaneunsis end of the line interaction fixed --- src/clj/game/cards/hardware.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clj/game/cards/hardware.clj b/src/clj/game/cards/hardware.clj index d87a8687c6..410510f60a 100644 --- a/src/clj/game/cards/hardware.clj +++ b/src/clj/game/cards/hardware.clj @@ -180,8 +180,8 @@ (defcard "Amanuensis" {:static-abilities [(mu+ 1)] :events [{:event :runner-lose-tag - :req (req (= :runner side)) :optional {:prompt "Remove 1 power counter to draw 2 cards?" + :req (req (= :runner (second targets))) :yes-ability {:cost [:power 1] :msg "draw 2 cards" :async true From af047ca3fcdec786feb4902b6d9fe3d280dfd9c6 Mon Sep 17 00:00:00 2001 From: NB Kelly Date: Thu, 21 Mar 2024 21:57:08 +1300 Subject: [PATCH 05/20] fixes for kingmaking, cloud eater --- src/clj/game/cards/agendas.clj | 7 ++++--- src/clj/game/cards/ice.clj | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/clj/game/cards/agendas.clj b/src/clj/game/cards/agendas.clj index a79ca98c27..f4c6904ca7 100644 --- a/src/clj/game/cards/agendas.clj +++ b/src/clj/game/cards/agendas.clj @@ -18,7 +18,7 @@ [game.core.damage :refer [damage damage-bonus]] [game.core.def-helpers :refer [corp-recur defcard do-net-damage offer-jack-out reorder-choice get-x-fn]] - [game.core.drawing :refer [draw]] + [game.core.drawing :refer [draw draw-up-to]] [game.core.effects :refer [register-lingering-effect]] [game.core.eid :refer [effect-completed make-eid]] [game.core.engine :refer [pay register-events resolve-ability @@ -1129,10 +1129,11 @@ (update-all-agenda-points state) (check-win-by-agenda state side) (effect-completed state side eid)) - :cancel-effect (effect (system-msg (str "declines to use " (:title card))))}] + :cancel-effect (effect (system-msg (str "declines to use " (:title card))) + (effect-completed eid))}] {:on-score {:async true :effect (req (wait-for - (draw state side 3) + (draw-up-to state side card 3) (continue-ability state side add-abi card nil)))}})) (defcard "Labyrinthine Servers" diff --git a/src/clj/game/cards/ice.clj b/src/clj/game/cards/ice.clj index 0312b7615d..4f05017713 100644 --- a/src/clj/game/cards/ice.clj +++ b/src/clj/game/cards/ice.clj @@ -1199,18 +1199,18 @@ :events [{:event :end-of-encounter :req (req (and (= :this-turn (:rezzed card)) (same-card? (:ice context) card))) - :msg "force the Runner to choose a subroutine to resolve" + :msg "force the Runner to choose an effect" :effect (effect (continue-ability {:prompt "Choose one" :player :runner - :choices (req [(when (seq (all-installed-runner state)) "Corp trashes 1 Runner card") + :choices (req ["Corp trashes 1 Runner card" (when-not (forced-to-avoid-tags? state side) "Take 2 tags") (when (can-pay? state :runner eid card nil :net 3) "Suffer 3 net damage")]) :async true :effect (req (continue-ability - state :runner + state (if (= target "Corp trashes 1 Runner card") :corp :runner) (cond (= target "Corp trashes 1 Runner card") trash-installed-sub From 4e2afb8cc10560f152e57e48916a2937b977e8e4 Mon Sep 17 00:00:00 2001 From: NB Kelly Date: Fri, 22 Mar 2024 07:48:07 +1300 Subject: [PATCH 06/20] duration on lightning lab --- src/clj/game/cards/agendas.clj | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/clj/game/cards/agendas.clj b/src/clj/game/cards/agendas.clj index f4c6904ca7..7fe456f298 100644 --- a/src/clj/game/cards/agendas.clj +++ b/src/clj/game/cards/agendas.clj @@ -1164,6 +1164,8 @@ {:event :runner-turn-ends :req (req (seq (filter #(= (:zone %) [:servers zone :ices]) (all-active-installed state :corp)))) + :duration :end-of-turn + :unregister-once-resolved true :effect (req (let [derez-count (min 2 (count (filter #(= (:zone %) [:servers zone :ices]) (all-active-installed state :corp))))] From b6d8d4c4341f4c5ba63ea20941041043f248844f Mon Sep 17 00:00:00 2001 From: NB Kelly Date: Fri, 22 Mar 2024 08:10:05 +1300 Subject: [PATCH 07/20] kingmaking tests --- test/clj/game/cards/agendas_test.clj | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/clj/game/cards/agendas_test.clj b/test/clj/game/cards/agendas_test.clj index cfc2b78344..73e115c219 100644 --- a/test/clj/game/cards/agendas_test.clj +++ b/test/clj/game/cards/agendas_test.clj @@ -2132,12 +2132,26 @@ (count (:hand (get-corp))) 1 (:agenda-point (get-corp)) 3] (play-and-score state "Kingmaking") + (click-prompt state :corp "3") (click-card state :corp "Project Atlas") (is (not (no-prompt? state :corp)) "Couldn't choose 2-points agenda") (click-card state :corp "House of Knives")) "Corp drew 3 cards (2 of which moved to the score area)") (is (zero? (get-counters (get-scored state :runner 1) :agenda)) "House of Knives should have 0 agenda counters"))) +(deftest kingmaking-draw-n + (dotimes [n 4] + (do-game + (new-game {:corp {:hand ["Kingmaking" "Hedge Fund"] + :deck ["House of Knives" "Project Atlas" "Hedge Fund"]}}) + (is (changed? [(count (:deck (get-corp))) (- n) + (count (:hand (get-corp))) (- n 1)] + (play-and-score state "Kingmaking") + (click-prompt state :corp (str n)) + (click-prompt state :corp "Done")) + (str "Corp drew " n " cards"))))) + + (deftest license-acquisition ;; License Acquisition (do-game From b434ed34aa399311e900df50765e0109ee713566 Mon Sep 17 00:00:00 2001 From: NB Kelly Date: Fri, 22 Mar 2024 18:46:23 +1300 Subject: [PATCH 08/20] lightning lab cleanup, test --- src/clj/game/cards/agendas.clj | 1 - test/clj/game/cards/agendas_test.clj | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/clj/game/cards/agendas.clj b/src/clj/game/cards/agendas.clj index 7fe456f298..ea12801e9c 100644 --- a/src/clj/game/cards/agendas.clj +++ b/src/clj/game/cards/agendas.clj @@ -1165,7 +1165,6 @@ :req (req (seq (filter #(= (:zone %) [:servers zone :ices]) (all-active-installed state :corp)))) :duration :end-of-turn - :unregister-once-resolved true :effect (req (let [derez-count (min 2 (count (filter #(= (:zone %) [:servers zone :ices]) (all-active-installed state :corp))))] diff --git a/test/clj/game/cards/agendas_test.clj b/test/clj/game/cards/agendas_test.clj index 73e115c219..ebca97c919 100644 --- a/test/clj/game/cards/agendas_test.clj +++ b/test/clj/game/cards/agendas_test.clj @@ -2216,7 +2216,10 @@ (click-card state :corp rime) (is (not (rezzed? (refresh archer)))) (is (not (rezzed? (refresh rime)))) - (is (rezzed? (refresh bloop)))))) + (is (rezzed? (refresh bloop))) + (take-credits state :corp) + (take-credits state :runner) + (is (no-prompt? state :corp) "no repeat prompt")))) (deftest longevity-serum-basic-behavior ;; Basic behavior From 341d2e1730a6688b0cd6f34c6134c8ddea222d54 Mon Sep 17 00:00:00 2001 From: NB Kelly Date: Fri, 22 Mar 2024 19:37:01 +1300 Subject: [PATCH 09/20] cupellation disables cards (and only prompts on hq) --- src/clj/game/cards/programs.clj | 17 +++++++++++------ test/clj/game/cards/programs_test.clj | 15 +++++++++++++++ 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/clj/game/cards/programs.clj b/src/clj/game/cards/programs.clj index 9d33a8a6d8..86a5371774 100644 --- a/src/clj/game/cards/programs.clj +++ b/src/clj/game/cards/programs.clj @@ -29,6 +29,7 @@ [game.core.flags :refer [can-host? can-trash? card-flag? lock-zone release-zone zone-locked?]] [game.core.gaining :refer [gain-clicks gain-credits lose-credits]] [game.core.hosting :refer [host]] + [game.core.identities :refer [disable-card enable-card]] [game.core.ice :refer [all-subs-broken-by-card? all-subs-broken? any-subs-broken-by-card? auto-icebreaker break-sub break-subroutine! break-subroutines-msg breaker-strength-bonus dont-resolve-subroutine! @@ -1044,12 +1045,13 @@ :sorted)) :cost [:credit 1] :msg (msg "host " (:title target) " on itself") - :effect (req (host state side (assoc card :seen true) target) + :effect (req (disable-card state side (get-card state target)) + (host state side (assoc card :seen true) target) (effect-completed state side eid))} {:event :breach-server :async true - :optional {:req (req (= :hq target) - (seq (filter corp? (:hosted card)))) + :optional {:req (req (and (= :hq target) + (seq (filter corp? (:hosted card))))) :prompt "Trash this program to access 2 additional cards from HQ?" :yes-ability {:async true :effect (effect (access-bonus :hq 2) @@ -1062,9 +1064,12 @@ :cost [:credit 1] :msg (msg "host " (:title target) " on itself") :async true - :effect (req (host state side (assoc card :seen true) target) - (swap! state dissoc :access) - (effect-completed state side eid))}}}) + :effect (req + (disable-card state side (get-card state target)) + (host state side (assoc card :seen true) + (get-card state target)) + (swap! state dissoc :access) + (effect-completed state side eid))}}}) (defcard "Curupira" (auto-icebreaker {:abilities [(break-sub 1 1 "Barrier") diff --git a/test/clj/game/cards/programs_test.clj b/test/clj/game/cards/programs_test.clj index 087f72a699..b8223bde83 100644 --- a/test/clj/game/cards/programs_test.clj +++ b/test/clj/game/cards/programs_test.clj @@ -2042,6 +2042,21 @@ (dotimes [_ 3] (click-prompt state :runner "No action"))) "Cupellation and its hosted card are trashed")))) +(deftest cupellation-disables-cards + (do-game + (new-game {:runner {:hand ["Cupellation"]} + :corp {:hand ["Marilyn Campaign"]}}) + (play-from-hand state :corp "Marilyn Campaign" "New remote") + (rez state :corp (get-content state :remote1 0)) + (take-credits state :corp) + (play-from-hand state :runner "Cupellation") + (is (= 8 (get-counters (get-content state :remote1 0) :credit)) "Marilyn Campaign should start with 8 credits") + (run-on state "Server 1") + (run-continue state) + (click-prompt state :runner "[Cupellation] 1 [Credits]: Host a card") + (take-credits state :runner) + (is (= 8 (get-counters (first (:hosted (get-program state 0))) :credit))))) + (deftest curupira (do-game (new-game {:runner {:hand ["Curupira"] From c08302b80ba9e12cbb5ee089b46ac101a8f78e9e Mon Sep 17 00:00:00 2001 From: NB Kelly Date: Fri, 22 Mar 2024 21:17:17 +1300 Subject: [PATCH 10/20] asyncs right to help out nuvem --- src/clj/game/cards/agendas.clj | 2 +- src/clj/game/cards/ice.clj | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/clj/game/cards/agendas.clj b/src/clj/game/cards/agendas.clj index ea12801e9c..f9147ee5f0 100644 --- a/src/clj/game/cards/agendas.clj +++ b/src/clj/game/cards/agendas.clj @@ -732,7 +732,7 @@ (corp-installable-type? %))} :msg "install and rez 1 card from HQ, paying 5 [Credits] less" :async true - :effect (req (corp-install state side (make-eid state eid) target nil + :effect (req (corp-install state side eid target nil {:install-state :rezzed :combined-credit-discount 5}))} score-abi {:interactive (req true) diff --git a/src/clj/game/cards/ice.clj b/src/clj/game/cards/ice.clj index 4f05017713..4d1c11e494 100644 --- a/src/clj/game/cards/ice.clj +++ b/src/clj/game/cards/ice.clj @@ -2005,6 +2005,7 @@ (let [shuffle-ab {:label "Draw 1 card and shuffle 2 agendas in HQ and/or Archives into R&D" :msg "draw 1 card" + :async true :cost [:credit 1] :effect (req (wait-for From cc9dac793a4dc4350611265425f05e743cdc2579 Mon Sep 17 00:00:00 2001 From: NB Kelly Date: Fri, 22 Mar 2024 21:58:14 +1300 Subject: [PATCH 11/20] priv access actually works properly --- src/clj/game/cards/events.clj | 53 ++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/src/clj/game/cards/events.clj b/src/clj/game/cards/events.clj index 09adfcde5f..96efbbc53e 100644 --- a/src/clj/game/cards/events.clj +++ b/src/clj/game/cards/events.clj @@ -20,7 +20,7 @@ [game.core.effects :refer [register-lingering-effect]] [game.core.eid :refer [complete-with-result effect-completed make-eid make-result]] - [game.core.engine :refer [not-used-once? pay register-events + [game.core.engine :refer [not-used-once? pay register-events register-pending-event resolve-ability trigger-event trigger-event-simult unregister-events unregister-floating-events]] [game.core.events :refer [first-event? first-run-event? run-events @@ -2854,13 +2854,13 @@ {:prompt "Choose a program to install" :waiting-prompt true :async true - :req (req (and (not (zone-locked? state :runner :discard)) - (not (install-locked? state side)) - (threat-level 3 state))) + :req (req (and + (not (get-in card [:special :maybe-a-bonus-tag])) + (not (zone-locked? state :runner :discard)) + (not (install-locked? state side)) + (threat-level 3 state))) :interactive (req true) :ability-name "Privileged Access (program)" - :once :per-run - :once-key :install-program-from-heap :choices (req (concat (->> (:discard runner) (filter @@ -2872,20 +2872,23 @@ (seq)) ["Done"])) :effect (req (if (= target "Done") - (effect-completed state side eid) - (wait-for (runner-install state side (make-eid state (assoc eid :source card :source-type :runner-install)) target) - (system-msg state side (str "uses " (:title card) " to install " (:title target) " from the heap")) - (effect-completed state side eid))))} + (effect-completed state side eid) + (do (update! state side (assoc-in card [:special :maybe-a-bonus-tag] true)) + (wait-for + (runner-install state side (make-eid state (assoc eid :source card :source-type :runner-install)) target) + (update! state side (dissoc-in card [:special :maybe-a-bonus-tag])) + (system-msg state side (str "uses " (:title card) " to install " (:title target) " from the heap")) + (effect-completed state side eid)))))} install-resource-from-heap {:prompt "Choose a resource to install, paying 2 [Credits] less" :waiting-prompt true - :req (req (and (not (zone-locked? state :runner :discard)) + :req (req (and + (not (get-in card [:special :maybe-a-bonus-tag])) + (not (zone-locked? state :runner :discard)) (not (install-locked? state side)))) :async true :interactive (req true) :ability-name "Privileged Access (resource)" - :once :per-run - :once-key :install-resource-from-heap :choices (req (concat (->> (:discard runner) (filter @@ -2898,24 +2901,30 @@ ["Done"])) :effect (req (if (= target "Done") (effect-completed state side eid) - (wait-for (runner-install state side (make-eid state (assoc eid :source card :source-type :runner-install)) target {:cost-bonus -2}) - (system-msg state side (str "uses " (:title card) " to install " (:title target) " from the heap, paying 2 [Credits] less")) - (effect-completed state side eid))))}] + (do (update! state side (assoc-in card [:special :maybe-a-bonus-tag] true)) + (wait-for + (runner-install state side (make-eid state (assoc eid :source card :source-type :runner-install)) target {:cost-bonus -2}) + (update! state side (dissoc-in card [:special :maybe-a-bonus-tag])) + (system-msg state side (str "uses " (:title card) " to install " (:title target) " from the heap, paying 2 [Credits] less")) + (effect-completed state side eid)))))}] {:makes-run true :on-play {:req (req (and archives-runnable (not tagged))) :async true :effect (effect (make-run eid :archives card))} - :events [(assoc install-resource-from-heap - :event :runner-gain-tag) - (assoc install-program-from-heap - :event :runner-gain-tag) - (successful-run-replace-breach + :events [(successful-run-replace-breach {:target-server :archives :this-card-run true :mandatory true :ability {:async true :msg "take 1 tag" - :effect (effect (gain-tags :runner eid 1))}})]})) + :effect (req + (register-pending-event state :runner-gain-tag + card install-resource-from-heap) + (register-pending-event state :runner-gain-tag + card install-program-from-heap) + (wait-for (gain-tags state :runner 1) + (unregister-events state side card) + (effect-completed state side eid)))}})]})) (defcard "Process Automation" {:on-play From 40e010cb26e8893a6106259f5d4b4844c3bfca43 Mon Sep 17 00:00:00 2001 From: NB Kelly Date: Sat, 23 Mar 2024 08:03:57 +1300 Subject: [PATCH 12/20] tests for valentina/amen --- test/clj/game/cards/hardware_test.clj | 14 ++++++++++++++ test/clj/game/cards/resources_test.clj | 12 ++++++++++++ 2 files changed, 26 insertions(+) diff --git a/test/clj/game/cards/hardware_test.clj b/test/clj/game/cards/hardware_test.clj index 539c6acce7..6569eb4181 100644 --- a/test/clj/game/cards/hardware_test.clj +++ b/test/clj/game/cards/hardware_test.clj @@ -183,6 +183,20 @@ (click-prompt state :runner "Yes")) "Spend a power counter when removing a tag to draw 2 cards"))) +(deftest amanuensis-corp-spend-tag + (do-game + (new-game {:runner {:hand ["Amanuensis"] + :deck [(qty "Sure Gamble" 2)]} + :corp {:hand ["End of the Line"]}}) + (take-credits state :corp) + (gain-tags state :runner 1) + (play-from-hand state :runner "Amanuensis") + (is (changed? [(get-counters (get-hardware state 0) :power) 1] + (take-credits state :runner)) + "Amanuensis gains a power counter at end of turn") + (play-from-hand state :corp "End of the Line") + (is (no-prompt? state :runner) "No runner prompt for amen"))) + (deftest aniccam-trash-trash-before-and-after-install-does-not-trigger ;; Aniccam (doseq [first-side [:corp :runner] diff --git a/test/clj/game/cards/resources_test.clj b/test/clj/game/cards/resources_test.clj index 1e661f24ef..313a350a5f 100644 --- a/test/clj/game/cards/resources_test.clj +++ b/test/clj/game/cards/resources_test.clj @@ -7118,6 +7118,18 @@ (click-prompt state :runner "Gain 2 [Credits]")) "Threat 3: Runner can gain 2 credits when installing Valentina"))) +(deftest valentina-ferreira-carvalho-op-tag + (do-game + (new-game {:runner {:hand ["Valentina Ferreira Carvalho"]} + :corp {:hand ["End of the Line"]}}) + (take-credits state :corp) + (play-from-hand state :runner "Valentina Ferreira Carvalho") + (gain-tags state :runner 1) + (take-credits state :runner) + (is (changed? [(:credit (get-runner)) 0] + (play-from-hand state :corp "End of the Line")) + "Runner does NOT gain a credit from EOTL"))) + (deftest verbal-plasticity ;; Verbal Plasticity (do-game From 771725e2b074f326b4c61f84a6ec2316eaef3552 Mon Sep 17 00:00:00 2001 From: NB Kelly Date: Sat, 23 Mar 2024 08:19:25 +1300 Subject: [PATCH 13/20] isaac linger prompt fixed --- src/clj/game/cards/upgrades.clj | 22 +++++++++------------- test/clj/game/cards/upgrades_test.clj | 3 ++- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/clj/game/cards/upgrades.clj b/src/clj/game/cards/upgrades.clj index 7270719d6c..1674e42475 100644 --- a/src/clj/game/cards/upgrades.clj +++ b/src/clj/game/cards/upgrades.clj @@ -77,7 +77,8 @@ (conj (server->zone state target) :content))] (unregister-events state side card) (register-default-events state side c) - (continue-ability state side callback c nil)))}}})) + (wait-for (resolve-ability state side callback c nil) + (effect-completed state side eid))))}}})) ;; Card definitions @@ -897,18 +898,13 @@ (zero? (get-counters % :advancement)) (same-server? card %)) (all-installed-corp state))) - :async true - :effect - (effect - (continue-ability - {:prompt "Choose a piece of ice protecting this server to place 1 advancement counter on" - :waiting-prompt true - :choices {:card #(and (ice? %) - (zero? (get-counters % :advancement)) - (same-server? % card))} - :msg (msg "place 1 advancement counter on " (card-str state target)) - :effect (effect (add-prop target :advance-counter 1 {:placed true}))} - card nil))}] + :prompt "Choose a piece of ice protecting this server to place 1 advancement counter on" + :waiting-prompt true + :choices {:req (req (and (ice? target) + (zero? (get-counters target :advancement)) + (same-server? target card)))} + :msg (msg "place 1 advancement counter on " (card-str state target)) + :effect (effect (add-prop target :advance-counter 1 {:placed true}))}] {:static-abilities [{:type :ice-strength :req (req (and (ice? target) (= (card->server state card) (card->server state target)))) diff --git a/test/clj/game/cards/upgrades_test.clj b/test/clj/game/cards/upgrades_test.clj index 0825c26f9b..b9fa681a4a 100644 --- a/test/clj/game/cards/upgrades_test.clj +++ b/test/clj/game/cards/upgrades_test.clj @@ -1914,7 +1914,8 @@ (is (changed? [(get-strength (refresh tithe)) 2 (get-counters (refresh tithe) :advancement) 1] (click-card state :corp tithe)) - "Tithe got +2 strength and 1 advancement counter")))) + "Tithe got +2 strength and 1 advancement counter") + (is (no-prompt? state :runner) "No lingering prompt")))) (deftest jinja-city-grid-single-draws ;; Single draws From 76969318e1ee0c1d41d6c10cfc88b8509596a77f Mon Sep 17 00:00:00 2001 From: NB Kelly Date: Sat, 23 Mar 2024 08:23:01 +1300 Subject: [PATCH 14/20] Window of Opportunity optional --- src/clj/game/cards/events.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/clj/game/cards/events.clj b/src/clj/game/cards/events.clj index 96efbbc53e..14d9415633 100644 --- a/src/clj/game/cards/events.clj +++ b/src/clj/game/cards/events.clj @@ -4140,7 +4140,7 @@ (if (seq targets-in-the-grip) {:prompt "Choose 1 program or piece of hardware" :waiting-prompt true - :choices (req targets-in-the-grip) + :choices (req (cancellable targets-in-the-grip)) :async true :effect (effect (runner-install (assoc eid :source card :source-type :runner-install) target)) :msg (msg "install " (:title target) " from the grip")} From d4391ea38390d1459a0962596010740b44182005 Mon Sep 17 00:00:00 2001 From: NB Kelly Date: Sat, 23 Mar 2024 14:04:42 +1300 Subject: [PATCH 15/20] no auto-break for pressure spikle --- src/clj/game/cards/programs.clj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/clj/game/cards/programs.clj b/src/clj/game/cards/programs.clj index 86a5371774..c9f00c7889 100644 --- a/src/clj/game/cards/programs.clj +++ b/src/clj/game/cards/programs.clj @@ -2746,10 +2746,10 @@ :effect (effect (add-counter :runner card :virus 2))}]}) (defcard "Pressure Spike" - (auto-icebreaker {:implementation "Once per run restriction not enforced" - :abilities [(break-sub 1 1 "Barrier") - (strength-pump 2 3) - (strength-pump 2 9 :end-of-encounter {:req (req (threat-level 4 state))})]})) + {:implementation "Once per run restriction not enforced. Auto-breaking disabled for this card." + :abilities [(break-sub 1 1 "Barrier") + (strength-pump 2 3) + (strength-pump 2 9 :end-of-encounter {:req (req (threat-level 4 state))})]}_) (defcard "Progenitor" {:abilities [{:label "Install and host a virus program" From 16dfcdf394c42b2e26a2a367a6ef72a9636d1d14 Mon Sep 17 00:00:00 2001 From: NB Kelly Date: Sat, 23 Mar 2024 14:16:34 +1300 Subject: [PATCH 16/20] no auto-break for boi-tata --- src/clj/game/cards/programs.clj | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/clj/game/cards/programs.clj b/src/clj/game/cards/programs.clj index c9f00c7889..eb29892675 100644 --- a/src/clj/game/cards/programs.clj +++ b/src/clj/game/cards/programs.clj @@ -685,11 +685,11 @@ (letfn [(was-a-runner-card? [target] (runner? (:card (first target))))] - (auto-icebreaker {:implementation "Effect only applies for printed abilities" - :abilities [(break-sub 1 2 "Sentry" (cond-breaker :runner-trash was-a-runner-card?)) - (break-sub 2 2 "Sentry") - (strength-pump 2 3 :end-of-encounter (cond-breaker :runner-trash was-a-runner-card?)) - (strength-pump 3 3)]}))) + {:implementation "Effect only applies for printed abilities" + :abilities [(break-sub 1 2 "Sentry" (cond-breaker :runner-trash was-a-runner-card?)) + (break-sub 2 2 "Sentry") + (strength-pump 2 3 :end-of-encounter (cond-breaker :runner-trash was-a-runner-card?)) + (strength-pump 3 3)]})) (defcard "Botulus" {:implementation "[Erratum] Program: Virus - Trojan" @@ -2749,7 +2749,7 @@ {:implementation "Once per run restriction not enforced. Auto-breaking disabled for this card." :abilities [(break-sub 1 1 "Barrier") (strength-pump 2 3) - (strength-pump 2 9 :end-of-encounter {:req (req (threat-level 4 state))})]}_) + (strength-pump 2 9 :end-of-encounter {:req (req (threat-level 4 state))})]}) (defcard "Progenitor" {:abilities [{:label "Install and host a virus program" From a03a90d9087dcaa468355262c4a5fda04aa13f36 Mon Sep 17 00:00:00 2001 From: NB Kelly Date: Sat, 23 Mar 2024 14:27:20 +1300 Subject: [PATCH 17/20] cloud eater test fixed --- test/clj/game/cards/ice_test.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/clj/game/cards/ice_test.clj b/test/clj/game/cards/ice_test.clj index d7cc402b7d..3e60e63c00 100644 --- a/test/clj/game/cards/ice_test.clj +++ b/test/clj/game/cards/ice_test.clj @@ -1577,7 +1577,7 @@ (card-subroutine state :corp (refresh ce) 2)) "Runner suffered 3 net damage") (run-continue state :movement) - (is (= 1 (count (prompt-buttons :runner))) "Runner doesn't have the option to suffer net damage or trash installed cards") + (is (= 2 (count (prompt-buttons :runner))) "Runner doesn't have the option to suffer net damage") (is (changed? [(count-tags state) 2] (click-prompt state :runner "Take 2 tags")) "Runner got 2 tags") From b45243a41118a647a9368c0edc5307700537c840 Mon Sep 17 00:00:00 2001 From: NB Kelly Date: Sat, 23 Mar 2024 14:47:46 +1300 Subject: [PATCH 18/20] clean up sisyphus, make forced ice encounters considerate of run phase --- src/clj/game/cards/agendas.clj | 53 +++++++++++++++++----------------- src/clj/game/core/runs.clj | 23 +++++++++++---- 2 files changed, 43 insertions(+), 33 deletions(-) diff --git a/src/clj/game/cards/agendas.clj b/src/clj/game/cards/agendas.clj index f9147ee5f0..95423cee4c 100644 --- a/src/clj/game/cards/agendas.clj +++ b/src/clj/game/cards/agendas.clj @@ -1922,33 +1922,32 @@ :effect (effect (damage eid :meat 2 {:card card}))}}) (defcard "Sisyphus Protocol" - {:events [{:event :pass-ice - :req (req (and (rezzed? (:ice context)) - (or (has-subtype? (:ice context) "Code Gate") - (has-subtype? (:ice context) "Sentry")) - (first-event? state side :pass-ice - (fn [targets] - (let [context (first targets)] - (and (rezzed? (:ice context)) - (or (has-subtype? (:ice context) "Code Gate") - (has-subtype? (:ice context) "Sentry")))))))) - :prompt (msg "Make the runner encounter " (:title (:ice context)) " again?") - :choices (req [(when (can-pay? state :corp (assoc eid :source card :source-type :ability) card nil [:credit 1]) "Pay 1 [Credit]") - (when (can-pay? state :corp (assoc eid :source card :source-type :ability) card nil [:trash-from-hand 1]) "Trash 1 card from HQ") - "Done"]) - :async true - :effect (req (if (= target "Done") - (effect-completed state side eid) - (let [enc-ice current-ice] - (continue-ability - state side - (assoc {:msg (msg "make the runner encounter " (card-str state enc-ice) " again") - :async true - :effect (req (force-ice-encounter state side eid enc-ice))} - :cost (if (= target "Pay 1 [Credit]") - [:credit 1] - [:trash-from-hand 1])) - card nil))))}]}) + (letfn [(rezzed-gate-or-sentry [context] + (and (rezzed? (:ice context)) + (or (has-subtype? (:ice context) "Code Gate") + (has-subtype? (:ice context) "Sentry"))))] + {:events [{:event :pass-ice + :req (req (and (rezzed-gate-or-sentry context) + (first-event? state side :pass-ice + #(rezzed-gate-or-sentry (first %))))) + :prompt (msg "Make the runner encounter " (:title (:ice context)) " again?") + :choices (req [(when (can-pay? state :corp (assoc eid :source card :source-type :ability) card nil [:credit 1]) "Pay 1 [Credit]") + (when (can-pay? state :corp (assoc eid :source card :source-type :ability) card nil [:trash-from-hand 1]) "Trash 1 card from HQ") + "Done"]) + :async true + :effect (req (if (= target "Done") + (effect-completed state side eid) + (let [enc-ice current-ice] + (continue-ability + state side + (assoc {:msg (msg "make the runner encounter " (card-str state enc-ice) " again") + :async true + :effect (req + (force-ice-encounter state side eid enc-ice))} + :cost (if (= target "Pay 1 [Credit]") + [:credit 1] + [:trash-from-hand 1])) + card nil))))}]})) (defcard "Slash and Burn Agriculture" {:expend {:req (req (some #(can-be-advanced? %) (all-installed state :corp))) diff --git a/src/clj/game/core/runs.clj b/src/clj/game/core/runs.clj index 6b0b464b2e..66ef2bb340 100644 --- a/src/clj/game/core/runs.clj +++ b/src/clj/game/core/runs.clj @@ -350,12 +350,23 @@ ;; clears the broken subs out of the prompt, otherwise they can get stuck with some cards (reset-all-subs! state (get-card state ice)) (show-run-prompts state (str "encountering " (:title ice)) ice) - (wait-for (encounter-ice state side (make-eid state eid) ice) - (clear-run-prompts state) - (if (and (not (:run @state)) - (empty? (:encounters @state))) - (forced-encounter-cleanup state :runner eid) - (effect-completed state side eid)))) + ;; do we need to mess with the run state + (let [old-state (get-in @state [:run :phase]) + new-state (if (= :movement old-state) + :encounter-ice + old-state)] + (system-msg state side old-state) + (system-msg state side new-state) + (set-phase state new-state) + (wait-for (encounter-ice state side (make-eid state eid) ice) + ;; reset the state if needed + (when (= new-state (get-in @state [:run :phase])) + (set-phase state old-state)) + (clear-run-prompts state) + (if (and (not (:run @state)) + (empty? (:encounters @state))) + (forced-encounter-cleanup state :runner eid) + (effect-completed state side eid))))) (defmethod continue :encounter-ice [state side _] From 9553c6459cbc5f49842dc7fface437dc27545d2f Mon Sep 17 00:00:00 2001 From: NB Kelly Date: Sat, 23 Mar 2024 15:06:50 +1300 Subject: [PATCH 19/20] fixed sysphus again (and other tests), boi-tata test is pending --- src/clj/game/cards/agendas.clj | 2 +- src/clj/game/core/runs.clj | 39 +++++++++++++-------------- test/clj/game/cards/programs_test.clj | 2 +- 3 files changed, 20 insertions(+), 23 deletions(-) diff --git a/src/clj/game/cards/agendas.clj b/src/clj/game/cards/agendas.clj index 95423cee4c..47ad0d652c 100644 --- a/src/clj/game/cards/agendas.clj +++ b/src/clj/game/cards/agendas.clj @@ -1943,7 +1943,7 @@ (assoc {:msg (msg "make the runner encounter " (card-str state enc-ice) " again") :async true :effect (req - (force-ice-encounter state side eid enc-ice))} + (force-ice-encounter state side eid enc-ice :encounter-ice))} :cost (if (= target "Pay 1 [Credit]") [:credit 1] [:trash-from-hand 1])) diff --git a/src/clj/game/core/runs.clj b/src/clj/game/core/runs.clj index 66ef2bb340..be9e9d95af 100644 --- a/src/clj/game/core/runs.clj +++ b/src/clj/game/core/runs.clj @@ -346,27 +346,24 @@ (encounter-ice state side eid ice))) (defn force-ice-encounter - [state side eid ice] - ;; clears the broken subs out of the prompt, otherwise they can get stuck with some cards - (reset-all-subs! state (get-card state ice)) - (show-run-prompts state (str "encountering " (:title ice)) ice) - ;; do we need to mess with the run state - (let [old-state (get-in @state [:run :phase]) - new-state (if (= :movement old-state) - :encounter-ice - old-state)] - (system-msg state side old-state) - (system-msg state side new-state) - (set-phase state new-state) - (wait-for (encounter-ice state side (make-eid state eid) ice) - ;; reset the state if needed - (when (= new-state (get-in @state [:run :phase])) - (set-phase state old-state)) - (clear-run-prompts state) - (if (and (not (:run @state)) - (empty? (:encounters @state))) - (forced-encounter-cleanup state :runner eid) - (effect-completed state side eid))))) + ([state side eid ice] (force-ice-encounter state side eid ice nil)) + ([state side eid ice new-state] + ;; clears the broken subs out of the prompt, otherwise they can get stuck with some cards + (reset-all-subs! state (get-card state ice)) + (show-run-prompts state (str "encountering " (:title ice)) ice) + ;; do we need to mess with the run state + (let [old-state (get-in @state [:run :phase])] + (when new-state + (set-phase state new-state)) + (wait-for (encounter-ice state side (make-eid state eid) ice) + ;; reset the state if needed + (clear-run-prompts state) + (if (and (not (:run @state)) + (empty? (:encounters @state))) + (forced-encounter-cleanup state :runner eid) + (do (when (and new-state (= new-state (get-in @state [:run :phase]))) + (set-phase state old-state)) + (effect-completed state side eid))))))) (defmethod continue :encounter-ice [state side _] diff --git a/test/clj/game/cards/programs_test.clj b/test/clj/game/cards/programs_test.clj index b8223bde83..e4722de5cd 100644 --- a/test/clj/game/cards/programs_test.clj +++ b/test/clj/game/cards/programs_test.clj @@ -891,7 +891,7 @@ (run-continue state) (is (no-prompt? state :runner) "Black Orchestra prompt did not come up"))) -(deftest boi-tata +(deftest ^:kaocha/pending boi-tata (do-game (new-game {:corp {:credits 6 :deck ["Ansel 1.0"] } :runner {:credits 15 From 86ab6b69bf2e73d1081e8e264372fee626cc6dea Mon Sep 17 00:00:00 2001 From: NB Kelly Date: Sat, 23 Mar 2024 15:12:03 +1300 Subject: [PATCH 20/20] window of op test fix --- test/clj/game/cards/events_test.clj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/clj/game/cards/events_test.clj b/test/clj/game/cards/events_test.clj index 9e97b9d11e..0e04cbbaa7 100644 --- a/test/clj/game/cards/events_test.clj +++ b/test/clj/game/cards/events_test.clj @@ -7422,7 +7422,7 @@ (take-credits state :corp) (play-from-hand state :runner "Window of Opportunity") (click-prompt state :runner "HQ") - (is (= 2 (-> (prompt-map :runner) :choices count)) "Runner has 2 choices") + (is (= 3 (-> (prompt-map :runner) :choices count)) "Runner has 3 choices (done is a choice)") (is (changed? [(:credit (get-runner)) -1] (click-prompt state :runner "Fermenter")) "Runner paid Fermenter install cost")