diff --git a/src/clj/game/cards/hardware.clj b/src/clj/game/cards/hardware.clj index 6cc9ab442c..6443f28cd0 100644 --- a/src/clj/game/cards/hardware.clj +++ b/src/clj/game/cards/hardware.clj @@ -1091,6 +1091,33 @@ :effect (effect (damage-prevent :brain 1) (damage-prevent :net 1))}]}) + "Mu Safecracker" + {:implementation "Stealth credit restriction not enforced" + :events [{:event :successful-run + :optional + {:req (req (and (= target :hq) + (some #(has-subtype? % "Stealth") + (all-active-installed state :runner)))) + :prompt "Pay 1 [Credits] to access 1 additional card?" + :yes-ability + {:async true + :cost [:credit 1] + :msg "access 1 additional card from HQ" + :effect (effect (access-bonus :hq 1) + (effect-completed eid))}}} + {:event :successful-run + :optional + {:req (req (and (= target :rd) + (some #(has-subtype? % "Stealth") + (all-active-installed state :runner)))) + :prompt "Pay 2 [Credits] to access 1 additional card?" + :yes-ability + {:async true + :cost [:credit 2] + :msg "access 1 additional card from R&D" + :effect (effect (access-bonus :rd 1) + (effect-completed eid))}}}]} + "Muresh Bodysuit" {:events [{:event :pre-damage :once :per-turn :once-key :muresh-bodysuit diff --git a/src/clj/game/cards/operations.clj b/src/clj/game/cards/operations.clj index 38ad8e667e..3707cf2db7 100644 --- a/src/clj/game/cards/operations.clj +++ b/src/clj/game/cards/operations.clj @@ -1332,7 +1332,8 @@ (:break ability)))) :value true}] :events [{:event :corp-turn-begins - :effect (effect (trash card nil))}]} + :effect (effect (trash card {:unpreventable true}) + (update-all-ice))}]} "O₂ Shortage" {:async true diff --git a/src/clj/game/cards/resources.clj b/src/clj/game/cards/resources.clj index a1249fc2ad..d904b3f52a 100644 --- a/src/clj/game/cards/resources.clj +++ b/src/clj/game/cards/resources.clj @@ -852,6 +852,16 @@ (unregister-events state side card))}])))}] :events [{:event :post-runner-turn-ends}]} + "DreamNet" + {:events [{:event :successful-run + :async true + :req (req (first-event? state :runner :successful-run)) + :effect (req (wait-for (draw state :runner 1 nil) + (when (or (<= 2 (:link (:runner @state))) + (has-subtype? (:identity (:runner @state)) "Digital")) + (gain-credits state :runner 1)) + (effect-completed state side eid)))}]} + "Drug Dealer" {:flags {:runner-phase-12 (req (some #(card-flag? % :drip-economy true) (all-active-installed state :runner)))} :abilities [{:label "Lose 1 [Credits] (start of turn)" diff --git a/test/clj/game_test/cards/hardware.clj b/test/clj/game_test/cards/hardware.clj index 96f160c79f..875cc8805b 100644 --- a/test/clj/game_test/cards/hardware.clj +++ b/test/clj/game_test/cards/hardware.clj @@ -1863,6 +1863,70 @@ (click-prompt state :runner "Yes")) ;Aeneas (is (= (+ num-creds 2) (:credit (get-runner))) "Runner has gained 2 from Aeneas")))))) +(deftest mu-safecracker + ;; MU Safecracker + (testing "No available stealth credits" + (testing "Access HQ" + (do-game + (new-game {:corp {:deck [(qty "Hedge Fund" 5)] + :hand [(qty "Hedge Fund" 2)]} + :runner {:hand ["Mu Safecracker"]}}) + (take-credits state :corp) + (play-from-hand state :runner "Mu Safecracker") + (run-empty-server state "HQ") + (click-prompt state :runner "No action") + (is (not (:run @state)) "Run has ended with no prompt"))) + (testing "Access R&D" + (do-game + (new-game {:corp {:deck [(qty "Hedge Fund" 5)] + :hand [(qty "Hedge Fund" 2)]} + :runner {:hand ["Mu Safecracker"]}}) + (take-credits state :corp) + (play-from-hand state :runner "Mu Safecracker") + (run-empty-server state "R&D") + (click-prompt state :runner "No action") + (is (not (:run @state)) "Run has ended with no prompt")))) + (testing "Available stealth credits" + (testing "Access HQ" + (do-game + (new-game {:corp {:deck [(qty "Hedge Fund" 5)] + :hand [(qty "Hedge Fund" 2)]} + :runner {:hand ["Mu Safecracker" "Ghost Runner"]}}) + (take-credits state :corp) + (play-from-hand state :runner "Ghost Runner") + (play-from-hand state :runner "Mu Safecracker") + (run-empty-server state "HQ") + (is (= "Pay 1 [Credits] to access 1 additional card?" + (:msg (prompt-map :runner))) + "Runner has the Mu Safecracker prompt") + (click-prompt state :runner "Yes") + (click-card state :runner "Ghost Runner") + (click-prompt state :runner "Card from hand") + (click-prompt state :runner "No action") + (click-prompt state :runner "Card from hand") + (click-prompt state :runner "No action") + (is (not (:run @state)) "Run has ended"))) + (testing "Access R&D" + (do-game + (new-game {:corp {:deck [(qty "Hedge Fund" 5)] + :hand [(qty "Hedge Fund" 2)]} + :runner {:hand ["Mu Safecracker" "Ghost Runner"]}}) + (take-credits state :corp) + (play-from-hand state :runner "Ghost Runner") + (play-from-hand state :runner "Mu Safecracker") + (run-empty-server state "R&D") + (is (= "Pay 2 [Credits] to access 1 additional card?" + (:msg (prompt-map :runner))) + "Runner has the Mu Safecracker prompt") + (click-prompt state :runner "Yes") + (click-card state :runner "Ghost Runner") + (click-card state :runner "Ghost Runner") + (click-prompt state :runner "Card from deck") + (click-prompt state :runner "No action") + (click-prompt state :runner "Card from deck") + (click-prompt state :runner "No action") + (is (not (:run @state)) "Run has ended"))))) + (deftest net-ready-eyes ;; Net-Ready Eyes (testing "Basic test" diff --git a/test/clj/game_test/cards/resources.clj b/test/clj/game_test/cards/resources.clj index e8e2ee967b..b1ceb3773e 100644 --- a/test/clj/game_test/cards/resources.clj +++ b/test/clj/game_test/cards/resources.clj @@ -1109,6 +1109,67 @@ (play-from-hand state :corp "Hedge Fund") (is (= 11 (:credit (get-corp))) "Corp has 11c"))) +(deftest dreamnet + ;; DreamNet + (testing "Draw 1 card on first successful run" + (do-game + (new-game {:runner {:deck [(qty "Sure Gamble" 5)] + :hand ["DreamNet"]}}) + (take-credits state :corp) + (play-from-hand state :runner "DreamNet") + (is (empty? (:hand (get-runner))) "Runner has 0 cards in hand") + (changes-val-macro + 1 (count (:hand (get-runner))) + "Runner has drawn 1 card on successful run" + (run-empty-server state :archives)))) + (testing "Don't draw anything on runs after the first" + (do-game + (new-game {:runner {:deck [(qty "Sure Gamble" 5)] + :hand ["DreamNet"]}}) + (take-credits state :corp) + (play-from-hand state :runner "DreamNet") + (is (empty? (:hand (get-runner))) "Runner has 0 cards in hand") + (run-empty-server state :archives) + (is (= 1 (count (:hand (get-runner)))) "Runner has drawn 1 card on successful run") + (changes-val-macro + 0 (count (:hand (get-runner))) + "Runner has not drawn additional cards" + (run-empty-server state :archives)))) + (testing "Don't draw anything on unsuccessful run" + (do-game + (new-game {:runner {:deck [(qty "Sure Gamble" 5)] + :hand ["DreamNet"]}}) + (take-credits state :corp) + (play-from-hand state :runner "DreamNet") + (changes-val-macro + 0 (count (:hand (get-runner))) + "Runner still has 0 cards in hand" + (run-on state :archives) + (run-jack-out state)))) + (testing "Gain 1 credit on successful run" + (testing "with 2 link" + (do-game + (new-game {:runner {:id "Sunny Lebeau: Security Specialist" + :deck [(qty "Sure Gamble" 5)] + :hand ["DreamNet"]}}) + (take-credits state :corp) + (play-from-hand state :runner "DreamNet") + (changes-val-macro + 1 (:credit (get-runner)) + "Runner gains 1 credit for having 2 link" + (run-empty-server state :archives)))) + (testing "with Digital subtype" + (do-game + (new-game {:runner {:id "Apex: Invasive Predator" + :deck [(qty "Sure Gamble" 5)] + :hand ["DreamNet"]}}) + (take-credits state :corp) + (play-from-hand state :runner "DreamNet") + (changes-val-macro + 1 (:credit (get-runner)) + "Runner gains 1 credit for having Digital subtype" + (run-empty-server state :archives)))))) + (deftest dummy-box ;; Dummy Box - trash a card from hand to prevent corp trashing installed card (testing "Basic test"