Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add better damage prevention messages #4309

Merged
merged 6 commits into from
Jul 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/clj/game/cards/hardware.clj
Original file line number Diff line number Diff line change
Expand Up @@ -611,7 +611,9 @@
{:in-play [:memory 1]
:interactions {:prevent [{:type #{:net :brain :meat}
:req (req true)}]}
:abilities [{:msg (msg "prevent 1 damage, trashing a facedown " (:title target))
:abilities [{:msg (msg "prevent 1 damage, trashing "
(when (facedown? target) "a facedown ")
(:title target))
:choices {:req #(and (runner? %) (installed? %))}
:priority 50
:effect (effect (trash target {:unpreventable true})
Expand Down
24 changes: 22 additions & 2 deletions src/clj/game/core/rules.clj
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,30 @@
[state side dtype n]
(swap! state update-in [:damage :damage-bonus dtype] (fnil #(+ % n) 0)))

(defn- damage-prevent-update-prompt
"Look at the current runner prompt and (if a damage prevention prompt), update message."
[state side dtype n]
(if-let [oldprompt (first (get-in @state [side :prompt]))]
(if-let [match (re-matches #"^Prevent any of the (\d+) (\w+) damage\?.*" (:msg oldprompt))]
(let [dnumber (str->int (second match))
promptdtype (case (nth match 2)
"net" :net
"brain" :brain
"meat" :meat)
prevented (get-in @state [:damage :damage-prevent promptdtype] 0)
newprompt (assoc oldprompt :msg (str "Prevent any of the " dnumber " " (name promptdtype) " damage? (" prevented "/" dnumber " prevented)"))
update-fn #(cons newprompt (rest %))
done-update-fn #(rest %)]
(if (>= prevented dnumber)
(do ((:effect oldprompt) nil)
(swap! state update-in [side :prompt] done-update-fn))
(swap! state update-in [side :prompt] update-fn))))))

(defn damage-prevent
"Registers a prevention of n damage to the next damage application of the given type."
"Registers a prevention of n damage to the next damage application of the given type. Afterwards update current prevention prompt, if found."
[state side dtype n]
(swap! state update-in [:damage :damage-prevent dtype] (fnil #(+ % n) 0)))
(swap! state update-in [:damage :damage-prevent dtype] (fnil #(+ % n) 0))
(damage-prevent-update-prompt state side dtype n))

(defn damage-defer
"Registers n damage of the given type to be deferred until later. (Chronos Protocol.)"
Expand Down
1 change: 0 additions & 1 deletion test/clj/game_test/cards/agendas.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2463,7 +2463,6 @@
(is (= 2 (count (:discard (get-runner)))))
(card-subroutine state :corp viktor 0)
(card-ability state :runner ff 1) ;; Prevent the brain damage this time
(click-prompt state :runner "Done")
(is (= 3 (count (:discard (get-runner)))) "Feedback filter trashed, didn't take another net damage")
(is (= 1 (:brain-damage (get-runner)))))))

Expand Down
1 change: 0 additions & 1 deletion test/clj/game_test/cards/assets.clj
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,6 @@
(let [filter (get-hardware state 0)]
(is (= 2 (count (:prompt (get-runner)))) "Runner has a single damage prevention prompt")
(card-ability state :runner filter 0)
(click-prompt state :runner "Done")
(is (zero? (count (:discard (get-runner)))) "Runner prevented damage")
(is (= 2 (count (:prompt (get-runner)))) "Runner has a next damage prevention prompt")
(click-prompt state :runner "Done")
Expand Down
5 changes: 1 addition & 4 deletions test/clj/game_test/cards/events.clj
Original file line number Diff line number Diff line change
Expand Up @@ -1867,7 +1867,6 @@
(letfn [(prevent-snare [existing-dmg]
(click-prompt state :corp "Yes")
(card-ability state :runner (get-program state 0) 1)
(click-prompt state :runner "Done")
(is (= (inc existing-dmg) (count (:discard (get-runner)))) "Damage from Snare! prevented")
(click-prompt state :runner (-> (prompt-map :runner) :choices first))
(when (-> (prompt-map :runner) :choices first)
Expand All @@ -1879,8 +1878,7 @@
(allow-pad [existing-dmg]
(click-prompt state :runner (-> (prompt-map :runner) :choices first))
(card-ability state :runner (get-program state 0) 1)
(is (= (inc existing-dmg) (count (:discard (get-runner)))) "Runner prevented damage from Hostile Inf")
(click-prompt state :runner "Done"))]
(is (= (inc existing-dmg) (count (:discard (get-runner)))) "Runner prevented damage from Hostile Inf"))]
(if (= :waiting (-> (get-runner) :prompt first :prompt-type)) ; hit the snare
;; prevent the damage
(do (prevent-snare (count (:discard (get-runner))))
Expand Down Expand Up @@ -2501,7 +2499,6 @@
(take-credits state :runner)
(play-and-score state "Show of Force")
(card-ability state :runner (-> (get-resource state 0) :hosted first) 1)
(click-prompt state :runner "Done")
(is (zero? (count-tags state)) "Runner should avoid all meat damage")
(is (= 1 (-> (get-runner) :discard count)) "Runner should have 1 card in Heap"))))

Expand Down
16 changes: 12 additions & 4 deletions test/clj/game_test/cards/hardware.clj
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,6 @@
(core/rez state :corp dm)
(card-subroutine state :corp dm 0)
(card-ability state :runner ff 0)
(click-prompt state :runner "Done")
(is (= 3 (count (:hand (get-runner)))) "1 net damage prevented")
(is (= 4 (:credit (get-runner))))
(run-successful state)
Expand Down Expand Up @@ -678,16 +677,26 @@
(core/rez state :corp pup)
(core/rez state :corp nk)
(card-subroutine state :corp (refresh pup) 0)
(is (= (-> (get-runner) :prompt first :msg)
"Prevent any of the 1 net damage?")
"Damage prevention message correct.")
(card-ability state :runner hb 0)
(click-card state :runner cache)
(click-prompt state :runner "Done")
(is (= 1 (count (:discard (get-runner)))) "Prevented 1 net damage")
(is (= 2 (count (:hand (get-runner)))))
(is (second-last-log-contains? state "Runner uses Heartbeat to prevent 1 damage, trashing Cache\\.") "Prompt correct")
(card-subroutine state :corp (refresh nk) 0)
(is (= (-> (get-runner) :prompt first :msg)
"Prevent any of the 3 net damage?")
"Damage prevention message correct.")
(card-ability state :runner hb 0)
(click-card state :runner hbdown)
(is (= (-> (get-runner) :prompt first :msg)
"Prevent any of the 3 net damage? (1/3 prevented)")
"Damage prevention message correct.")
(click-prompt state :runner "Done")
(is (= 4 (count (:discard (get-runner)))) "Prevented 1 of 3 net damage; used facedown card"))))
(is (= 4 (count (:discard (get-runner)))) "Prevented 1 of 3 net damage; used facedown card")
(is (last-n-log-contains? state 2 "Runner uses Heartbeat to prevent 1 damage, trashing a facedown Heartbeat\\.") "Prompt correct"))))

(deftest hijacked-router
;; Hijacked Router
Expand Down Expand Up @@ -1453,7 +1462,6 @@
(card-ability state :runner plas 0)
(card-ability state :runner plas 0)
(card-ability state :runner plas 0)
(click-prompt state :runner "Done")
(is (= 1 (count (:hand (get-runner)))) "All meat damage prevented")
(is (empty? (get-hardware state)) "Plascrete depleted and trashed"))))

Expand Down
1 change: 0 additions & 1 deletion test/clj/game_test/cards/identities.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2116,7 +2116,6 @@
(click-prompt state :corp "2 [Credits]")
(click-prompt state :runner "0 [Credits]")
(card-ability state :runner ff 0)
(click-prompt state :runner "Done")
(is (zero? (:credit (get-runner))) "Runner has no more credits left")
(is (= 1 (count (:hand (get-runner)))) "Prevented 1 net damage")
(is (empty? (:discard (get-runner))) "No cards discarded")
Expand Down
2 changes: 0 additions & 2 deletions test/clj/game_test/cards/programs.clj
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,6 @@
(click-prompt state :runner "Pay 5 [Credits] to trash")
(let [dx (get-program state 0)]
(card-ability state :runner dx 1)
(click-prompt state :runner "Done")
(is (= 2 (count (:hand (get-runner)))) "Deus X prevented one Hostile net damage"))))
(testing "vs Multiple sources of net damage"
(do-game
Expand All @@ -634,7 +633,6 @@
(run-empty-server state "Server 1")
(let [dx (get-program state 0)]
(card-ability state :runner dx 1)
(click-prompt state :runner "Done")
(click-prompt state :runner "Pay to steal")
(is (= 3 (count (:hand (get-runner)))) "Deus X prevented net damage from accessing Fetal AI, but not from Personal Evolution")
(is (= 1 (count (:scored (get-runner)))) "Fetal AI stolen")))))
Expand Down
1 change: 0 additions & 1 deletion test/clj/game_test/cards/upgrades.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2164,7 +2164,6 @@
(core/rez state :corp tori)
(card-subroutine state :corp pup 0)
(card-ability state :runner nshld 0)
(click-prompt state :runner "Done")
(is (empty? (:discard (get-runner))) "1 net damage prevented")
(card-subroutine state :corp pup 0)
(click-prompt state :runner "Done") ; decline to prevent
Expand Down
1 change: 0 additions & 1 deletion test/clj/game_test/engine/scenarios.clj
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
fg (first (:hosted (refresh apt)))]
(card-ability state :runner ns 0)
(is (= 5 (:credit (get-runner))) "Runner paid 1c to survive Neural EMP")
(click-prompt state :runner "Done")
(play-from-hand state :corp "SEA Source")
(click-prompt state :corp "3") ; boost trace to 6
(click-prompt state :runner "0")
Expand Down
19 changes: 19 additions & 0 deletions test/clj/game_test/utils.clj
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,11 @@
(some? (re-find (re-pattern content)
(-> @state :log butlast last :text))))

(defn last-n-log-contains?
[state n content]
(some? (re-find (re-pattern content)
(:text (nth (-> @state :log reverse) n)))))

(defmethod assert-expr 'last-log-contains?
[msg form]
`(let [state# ~(nth form 1)
Expand All @@ -131,6 +136,20 @@
:message ~msg})
found#))

(defmethod assert-expr 'last-n-log-contains?
[msg form]
`(let [state# ~(nth form 1)
n# ~(nth form 2)
content# ~(nth form 3)
log# (:text (nth (-> @state# :log reverse) n#))
found# ~form]
(do-report
{:type (if found# :pass :fail)
:actual log#
:expected content#
:message ~msg})
found#))

(defmethod assert-expr 'prompt-is-type?
[msg form]
`(let [state# ~(nth form 1)
Expand Down