Skip to content

Commit b085a66

Browse files
authored
Merge pull request #7934 from NBKelly/forced-encounter-fix
Forced encounter fix
2 parents 83f35be + 6612b52 commit b085a66

File tree

5 files changed

+84
-9
lines changed

5 files changed

+84
-9
lines changed

src/clj/game/cards/hardware.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1154,7 +1154,7 @@
11541154
{:events [{:event :subroutines-broken
11551155
:optional
11561156
{:req (req
1157-
(let [pred (every-pred :all-subs-broken :outermost :during-run)]
1157+
(let [pred (every-pred :all-subs-broken :outermost :during-run :on-attacked-server)]
11581158
(and (pred context)
11591159
(get-card state (:ice context))
11601160
(first-event? state side :subroutines-broken #(pred (first %))))))

src/clj/game/core/ice.clj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,8 +185,7 @@
185185
(defn all-subs-broken?
186186
[ice]
187187
(let [subroutines (:subroutines ice)]
188-
(and (seq subroutines)
189-
(every? :broken subroutines))))
188+
(every? :broken subroutines)))
190189

191190
(defn any-subs-broken-by-card?
192191
[ice card]
@@ -539,6 +538,7 @@
539538
[state ice broken-subs breaker]
540539
{:outermost (when-let [server-ice (:ices (card->server state ice))] (same-card? ice (last server-ice)))
541540
:during-run (some? (:run @state))
541+
:on-attacked-server (= (get-in @state [:run :server]) [(second (:zone ice))])
542542
:all-subs-broken (all-subs-broken? ice)
543543
:broken-subs broken-subs
544544
;; enough info to backtrack and find breakers without bloating the gamestate

src/clj/game/core/runs.clj

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
[game.core.engine :refer [checkpoint end-of-phase-checkpoint register-pending-event pay queue-event resolve-ability trigger-event trigger-event-simult]]
1111
[game.core.flags :refer [can-run? cards-can-prevent? clear-run-register! get-prevent-list prevent-jack-out]]
1212
[game.core.gaining :refer [gain-credits]]
13-
[game.core.ice :refer [active-ice? get-current-ice get-run-ices update-ice-strength reset-all-ice reset-all-subs! set-current-ice]]
13+
[game.core.ice :refer [active-ice? break-subs-event-context get-current-ice get-run-ices update-ice-strength reset-all-ice reset-all-subs! set-current-ice]]
1414
[game.core.mark :refer [is-mark?]]
1515
[game.core.payment :refer [build-cost-string build-spend-msg can-pay? merge-costs ->c]]
1616
[game.core.prompts :refer [clear-run-prompts clear-wait-prompt show-run-prompts show-prompt show-wait-prompt]]
@@ -334,10 +334,19 @@
334334
(checkpoint state side eid)))))})
335335

336336
(defn encounter-ice
337+
;; note: as far as I can tell, this deliberately leaves on open eid (the run eid).
338+
;; Attempting to change that breaks a very large number of tests, so I'm leaving this
339+
;; note here to remind me when I look at this later. -nbk, 2025
340+
;;
341+
;; TODO: rewrite forced encounter to use it's own version of encounter-ice,
342+
;; then we can close the eids on this. Right now, closing the eids breaks
343+
;; forced encounters and nothing else.
337344
[state side eid ice]
338345
(swap! state update :encounters conj {:eid eid
339346
:ice ice})
340347
(check-auto-no-action state)
348+
;; step 6.9.3a: The encounter begins. Conditions relating to the Runner encountering
349+
;; this ice are met (this is on-encounter effects, etc)
341350
(let [on-encounter (:on-encounter (card-def ice))
342351
applied-encounters (get-effects state nil :gain-encounter-ability ice)
343352
all-encounters (map #(preventable-encounter-abi % ice) (remove nil? (conj applied-encounters on-encounter)))]
@@ -349,8 +358,18 @@
349358
(make-eid state)
350359
{:cancel-fn (fn [state]
351360
(should-end-encounter? state side ice))})
352-
(when (should-end-encounter? state side ice)
353-
(encounter-ends state side eid)))))
361+
(if (should-end-encounter? state side ice)
362+
(encounter-ends state side eid)
363+
;; step 6.9.3b: if there are no subroutines on the ice,
364+
;; the runner is considered to have broken all the subroutines on this ice.
365+
;; This should fire an event, so it can get picked up with cards like hippo
366+
;; or knifed.
367+
(when-let [c-ice (get-current-ice state)]
368+
(when (and (same-card? c-ice ice) (zero? (count (:subroutines c-ice))))
369+
(wait-for
370+
(trigger-event-simult state side :subroutines-broken nil (break-subs-event-context state c-ice [] (get-in @state [:runner :basic-action-card])))
371+
(when (should-end-encounter? state side ice)
372+
(encounter-ends state side eid)))))))))
354373

355374
(defmethod start-next-phase :encounter-ice
356375
[state side _]
@@ -375,9 +394,11 @@
375394
(if (and (not (:run @state))
376395
(empty? (:encounters @state)))
377396
(forced-encounter-cleanup state :runner eid)
378-
(do (when (and new-state (= new-state (get-in @state [:run :phase])))
379-
(set-phase state old-state))
380-
(effect-completed state side eid)))))))
397+
(do
398+
(when (and new-state (= new-state (get-in @state [:run :phase])))
399+
(set-phase state old-state))
400+
(set-current-ice state)
401+
(effect-completed state side eid)))))))
381402

382403
(defmethod continue :encounter-ice
383404
[state side _]

test/clj/game/cards/hardware_test.clj

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2678,6 +2678,30 @@
26782678
(click-prompt state :runner "End the run")
26792679
(is (no-prompt? state :runner) "No Hippo prompt on later ice")))
26802680

2681+
(deftest hippo-interaction-with-konjin
2682+
(do-game
2683+
(new-game {:corp {:hand ["Ice Wall" "Konjin"]}
2684+
:runner {:hand ["Hippo" "Eater"] :credits 15}})
2685+
(play-from-hand state :corp "Ice Wall" "HQ")
2686+
(play-from-hand state :corp "Konjin" "R&D")
2687+
(rez state :corp (get-ice state :hq 0))
2688+
(rez state :corp (get-ice state :rd 0))
2689+
(take-credits state :corp)
2690+
(play-from-hand state :runner "Hippo")
2691+
(play-from-hand state :runner "Eater")
2692+
(run-on state :rd)
2693+
(run-continue state :encounter-ice)
2694+
(is (= "Choose an amount to spend for Konjin" (:msg (prompt-map :corp))) "Psi Game")
2695+
(click-prompt state :corp "0 [Credits]")
2696+
(click-prompt state :runner "1 [Credits]")
2697+
(is (= "Choose a piece of ice" (:msg (prompt-map :corp))) "Prompt to choose Ice")
2698+
(click-card state :corp "Ice Wall")
2699+
(auto-pump-and-break state (get-program state 0))
2700+
(is (no-prompt? state :runner) "Not prompted to use hippo (we're not on the attacked server)")
2701+
(run-continue state :encounter-ice)
2702+
(click-prompt state :runner "Yes")
2703+
(is (= "Konjin" (-> (get-corp) :discard first :title)) "Trashed konjin with hippo (you have 'broken all subs' when the encounter phase ends)")))
2704+
26812705
(deftest hippocampic-mechanocytes
26822706
;; Hippocampic Mechanocytes
26832707
(do-game

test/clj/game/cards/ice_test.clj

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4398,6 +4398,36 @@
43984398
(fire-subs state (refresh iw))
43994399
(is (not (:run @state)) "The run should have ended"))))
44004400

4401+
(deftest konjin-target-ice-gets-trashed
4402+
;; Return to encountering Konjin after forced encounter
4403+
(do-game
4404+
(new-game {:corp {:hand ["Ice Wall" "Konjin"]}
4405+
:runner {:hand ["Arruaceiras Crew"]}})
4406+
(play-from-hand state :corp "Ice Wall" "HQ")
4407+
(play-from-hand state :corp "Konjin" "R&D")
4408+
(take-credits state :corp)
4409+
(play-from-hand state :runner "Arruaceiras Crew")
4410+
(let [konjin (get-ice state :rd 0)
4411+
iw (get-ice state :hq 0)]
4412+
(rez state :corp konjin)
4413+
(rez state :corp iw)
4414+
(run-on state :rd)
4415+
(run-continue state)
4416+
(is (= (refresh konjin) (core/get-current-ice state)) "The runner should be encountering Konjin")
4417+
(is (= "Choose an amount to spend for Konjin" (:msg (prompt-map :corp))) "Psi Game")
4418+
(click-prompt state :corp "0 [Credits]")
4419+
(click-prompt state :runner "1 [Credits]")
4420+
(is (= "Choose a piece of ice" (:msg (prompt-map :corp))) "Prompt to choose Ice")
4421+
(click-card state :corp iw)
4422+
(is (= (refresh iw) (core/get-current-ice state)) "The runner should be encountering Ice Wall")
4423+
(card-ability state :runner (get-resource state 0) 0)
4424+
(card-ability state :runner (get-resource state 0) 1)
4425+
(is (= "Ice Wall" (-> (get-corp) :discard first :title)) "Trashed ice wall")
4426+
(run-continue state :encounter-ice)
4427+
(is (= (refresh konjin) (core/get-current-ice state)) "The runner should be back to encountering Konjin")
4428+
(is (no-prompt? state :runner) "No repeat psi prompt")
4429+
(is (no-prompt? state :corp) "No repeat psi prompt"))))
4430+
44014431
(deftest lockdown
44024432
;; Lockdown - Prevent Runner from drawing cards for the rest of the turn
44034433
(do-game

0 commit comments

Comments
 (0)