Skip to content

Commit

Permalink
Merge pull request #7739 from NBKelly/revealing
Browse files Browse the repository at this point in the history
Add a function to simplify revealing cards
  • Loading branch information
NoahTheDuke authored Oct 10, 2024
2 parents 527cd4a + d734064 commit 4134374
Show file tree
Hide file tree
Showing 10 changed files with 101 additions and 110 deletions.
30 changes: 11 additions & 19 deletions src/clj/game/cards/events.clj
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
[game.core.play-instants :refer [play-instant]]
[game.core.prompts :refer [cancellable clear-wait-prompt]]
[game.core.props :refer [add-counter add-icon add-prop remove-icon]]
[game.core.revealing :refer [reveal]]
[game.core.revealing :refer [reveal reveal-loud]]
[game.core.rezzing :refer [derez get-rez-cost rez]]
[game.core.runs :refer [bypass-ice can-run-server? gain-next-run-credits get-runnable-zones
make-run prevent-access successful-run-replace-breach
Expand Down Expand Up @@ -471,18 +471,15 @@
:this-card-run true
:mandatory true
:ability
{:msg "reveal 3 random cards from HQ"
:req (req (<= 1 (count (:hand corp))))
{:req (req (<= 1 (count (:hand corp))))
:async true
:effect (req (let [chosen-cards (take 3 (shuffle (:hand corp)))]
(system-msg
state side
(str "reveals " (enumerate-str (map :title chosen-cards))
" from HQ"))
(continue-ability
state side
(move-ab chosen-cards (min 2 (count chosen-cards)))
card nil)))}})]}))
(wait-for
(reveal-loud state side card nil chosen-cards)
(continue-ability
state side
(move-ab chosen-cards (min 2 (count chosen-cards)))
card nil))))}})]}))

(defcard "By Any Means"
{:on-play
Expand Down Expand Up @@ -638,8 +635,7 @@
:choices ["OK"]}
card nil))
(do
(wait-for (reveal state side target)
(system-msg state :corp (str "reveals " (:title target) " from HQ"))
(wait-for (reveal-loud state side card {:forced true} target)
(continue-ability
state :runner
{:msg "gain [Click] and draw 1 card"
Expand Down Expand Up @@ -1254,12 +1250,8 @@
:effect (req (let [cards-to-reveal (take 2 (shuffle (:hand corp)))
cards-to-trash (filter #(is-type? % target) cards-to-reveal)
credits (* 4 (count cards-to-trash))]
(system-msg state side
(str "uses " (:title card) " to reveal "
(enumerate-str (map :title cards-to-reveal))
" from HQ"))
(wait-for
(reveal state side cards-to-reveal)
(reveal-loud state side card nil cards-to-reveal)
(if (pos? credits)
(do (system-msg
state side
Expand Down Expand Up @@ -1408,7 +1400,7 @@
(defcard "Executive Wiretaps"
{:on-play
{:msg (msg "reveal " (enumerate-str (sort (map :title (:hand corp)))) " from HQ")
:change-in-game-state (req (seq (:deck corp)))
:change-in-game-state (req (seq (:hand corp)))
:async true
:effect (effect (reveal eid (:hand corp)))}})

Expand Down
26 changes: 5 additions & 21 deletions src/clj/game/cards/ice.clj
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
[game.core.prompts :refer [cancellable clear-wait-prompt]]
[game.core.props :refer [add-counter add-icon add-prop remove-icon]]
[game.core.purging :refer [purge]]
[game.core.revealing :refer [reveal]]
[game.core.revealing :refer [reveal reveal-loud]]
[game.core.rezzing :refer [derez get-rez-cost rez]]
[game.core.runs :refer [bypass-ice encounter-ends end-run
force-ice-encounter get-current-encounter prevent-access
Expand Down Expand Up @@ -1867,30 +1867,14 @@
:max (req 3)}
:async true
:effect (req (wait-for
(reveal state side targets)
(reveal-loud state side card {:and-then ", and shuffle [them] into R&D"} targets)
(doseq [c targets]
(move state :corp c :deck))
(shuffle! state :corp :deck)
(effect-completed state :corp eid)))
:cancel-effect (effect (shuffle! :deck)
(effect-completed eid))
:msg (msg
"reveal "
(enumerate-str
(filter identity
[(when-let [h (->> targets
(filter in-hand?)
(map :title)
not-empty)]
(str (enumerate-str h)
" from HQ"))
(when-let [d (->> targets
(filter in-discard?)
(map :title)
not-empty)]
(str (enumerate-str d)
" from Archives"))]))
" and shuffle them into R&D")}
:cancel-effect (effect (system-msg (str "uses " (:title card) " to shuffle R&D"))
(shuffle! :deck)
(effect-completed eid))}
draw-reveal-shuffle {:async true
:label "Draw cards, reveal and shuffle agendas"
:waiting-prompt true
Expand Down
88 changes: 35 additions & 53 deletions src/clj/game/cards/operations.clj
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
[game.core.prompts :refer [cancellable clear-wait-prompt show-wait-prompt]]
[game.core.props :refer [add-counter add-prop]]
[game.core.purging :refer [purge]]
[game.core.revealing :refer [reveal]]
[game.core.revealing :refer [reveal reveal-loud]]
[game.core.rezzing :refer [derez rez]]
[game.core.runs :refer [end-run make-run]]
[game.core.say :refer [system-msg]]
Expand Down Expand Up @@ -267,6 +267,7 @@
(defcard "Attitude Adjustment"
{:on-play
{:async true
:msg (msg "draw 2 cards")
:effect
(req (wait-for
(draw state side 2)
Expand All @@ -280,30 +281,17 @@
(in-discard? %)))}
:async true
:show-discard true
:effect
(req (wait-for
(reveal state side targets)
(wait-for
(gain-credits state side (* 2 (count targets)))
(doseq [c targets]
(move state :corp c :deck))
(shuffle! state :corp :deck)
(let [from-hq (map :title (filter in-hand? targets))
from-archives (map :title (filter in-discard? targets))]
(system-msg
state side
(str "uses " (:title card) " to reveal "
(enumerate-str
(filter identity
[(when (not-empty from-hq)
(str (enumerate-str from-hq)
" from HQ"))
(when (not-empty from-archives)
(str (enumerate-str from-archives)
" from Archives"))]))
", shuffle them into R&D and gain "
(* 2 (count targets)) " [Credits]")))
(effect-completed state side eid))))}
:effect (req (let [to-gain (* 2 (count targets))]
(wait-for
(reveal-loud state side card
{:and-then (str ", gain " to-gain " [Credits], and shuffle [them] into R&D")}
targets)
(wait-for
(gain-credits state side to-gain)
(doseq [c targets]
(move state :corp c :deck))
(shuffle! state :corp :deck)
(effect-completed state side eid)))))}
card nil)))}})

(defcard "Audacity"
Expand Down Expand Up @@ -483,50 +471,44 @@
:effect (effect (damage eid :meat 7 {:card card}))}})

(defcard "Bring Them Home"
(letfn [(hide-away [cards]
{:msg (msg "place " (enumerate-str (map :title cards))
" from the grip to the top of the stack")
:async true
:effect (req (doseq [c (shuffle cards)]
(move state :runner c :deck {:front true}))
(continue-ability
state side
{:optional
{:prompt "Shuffle 1 random card from the grip into the stack?"
:req (req (threat-level 3 state))
:waiting-prompt true
:yes-ability
{:cost [(->c :credit 2)]
:req (req (seq (:hand runner)))
:effect (req (let [target-card (first (shuffle (:hand runner)))]
(wait-for
(reveal state side target-card)
(system-msg state side (str "shuffles " (:title target-card) " into the stack"))
(move state :runner target-card :deck)
(shuffle! state :runner :deck))))}}}
card nil))})]
(let [threat-abi
{:optional
{:prompt "Shuffle 1 random card from the grip into the stack?"
:req (req (threat-level 3 state))
:waiting-prompt true
:yes-ability
{:cost [(->c :credit 2)]
:req (req (seq (:hand runner)))
:effect (req (let [target-card (first (shuffle (:hand runner)))]
(wait-for
(reveal-loud state side card {:and-then " and shuffle it into the Stack"} target-card)
(move state :runner target-card :deck)
(shuffle! state :runner :deck))))}}}]
{:on-play
{:async true
:req (req (or (last-turn? state :runner :trashed-card)
(last-turn? state :runner :stole-agenda)))
:effect (req
(let [chosen-cards (take 2 (shuffle (:hand runner)))]
(continue-ability
state side
(hide-away chosen-cards)
card nil)))}}))
(wait-for
(reveal-loud state side card {:and-then " and place [them] on the top of the stack (in a random order)"} chosen-cards)
(doseq [c (shuffle chosen-cards)]
(move state :runner c :deck {:front true}))
(continue-ability
state side
threat-abi
card nil))))}}))

(defcard "Building Blocks"
{:on-play
{:prompt "Choose a Barrier to install and rez"
:choices {:card #(and (corp? %)
(has-subtype? % "Barrier")
(in-hand? %))}
:msg (msg "reveal " (:title target))
:async true
:change-in-game-state (req (seq (:hand corp)))
:effect (req (wait-for
(reveal state side target)
(reveal-loud state side card nil target)
(corp-install state side eid target nil {:ignore-all-cost true
:msg-keys {:install-source card
:display-origin true}
Expand Down
23 changes: 16 additions & 7 deletions src/clj/game/cards/resources.clj
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
[game.core.play-instants :refer [play-instant]]
[game.core.prompts :refer [cancellable]]
[game.core.props :refer [add-counter add-icon remove-icon]]
[game.core.revealing :refer [reveal]]
[game.core.revealing :refer [reveal reveal-loud]]
[game.core.rezzing :refer [derez rez]]
[game.core.runs :refer [active-encounter? bypass-ice can-run-server? get-runnable-zones
gain-run-credits get-current-encounter
Expand Down Expand Up @@ -303,12 +303,21 @@
:events [(trash-on-empty :power)]
:abilities [{:cost [(->c :power 1)]
:keep-menu-open :while-power-tokens-left
:msg "look at the top card of Stack"
:optional
{:prompt (msg "Add " (:title (first (:deck runner))) " to bottom of Stack?")
:yes-ability
{:msg "add the top card of Stack to the bottom"
:effect (req (move state side (first (:deck runner)) :deck))}}}]})
:msg "reveal the top card of Stack"
:req (req (seq (:deck runner)))
:async true
:effect (req
(let [top-card (first (:deck runner))]
(wait-for
(reveal-loud state side card nil top-card)
(continue-ability
state side
{:optional
{:prompt (msg "Add " (:title top-card) " to bottom of Stack?")
:yes-ability
{:msg (str "move " (:title top-card) " to the bottom of the Stack")
:effect (req (move state side (first (:deck runner)) :deck))}}}
card nil))))}]})

(defcard "Armitage Codebusting"
{:data {:counter {:credit 12}}
Expand Down
2 changes: 1 addition & 1 deletion src/clj/game/core/installing.clj
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@
(= (:previous-zone card) [:set-aside])
"among the set-aside cards"
:else
(str "the " (name-zone :runner (:previous-zone card)))))
(name-zone :runner (:previous-zone card))))
"")
pre-lhs (when (every? (complement string/blank?) [cost-str prepend-cost-str])
(str prepend-cost-str ", and then "))
Expand Down
26 changes: 25 additions & 1 deletion src/clj/game/core/revealing.clj
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
(ns game.core.revealing
(:require
[game.core.engine :refer [trigger-event-sync]]))
[clojure.string :as string]
[game.core.engine :refer [trigger-event-sync]]
[game.core.say :refer [system-msg]]
[game.core.servers :refer [name-zone]]
[game.utils :refer [enumerate-str]]
[jinteki.utils :refer [other-side]]))

(defn reveal-hand
"Reveals a side's hand to opponent and spectators."
Expand All @@ -16,3 +21,22 @@
"Trigger the event for revealing one or more cards."
[state side eid & targets]
(apply trigger-event-sync state side eid (if (= :corp side) :corp-reveal :runner-reveal) (flatten targets)))

(defn reveal-loud
"Trigger the event for revealing one or more cards, and also handle the log printout"
[state side eid card {:keys [forced and-then] :as args} & targets]
(let [cards-by-zone (group-by #(select-keys % [:side :zone]) (flatten targets))
strs (map #(str (enumerate-str (map :title (get cards-by-zone %)))
" from " (name-zone (:side %) (:zone %)))
(keys cards-by-zone))
;; it's awkward to template a string that could refer to one or many
;; like "add it to the top of the stack" vs "add them to the top of the stack"
;; so I'm choosing to match the tokens [it] and [them] for this purpose
plural-repr (if (< 1 (count (flatten targets))) "them" "it")
follow-up (when and-then (string/replace and-then #"(\[it\])|(\[them\])" plural-repr))]
(if forced
(system-msg state (other-side side) (str "uses " (:title card) " to force the "
(string/capitalize (name side)) " to reveal "
(enumerate-str strs) follow-up))
(system-msg state side (str "uses " (:title card) " to reveal " (enumerate-str strs) follow-up)))
(reveal state side eid targets)))
6 changes: 3 additions & 3 deletions src/clj/game/core/servers.clj
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@
:else side)
zone (if (keyword? zone) [zone] (vec zone))]
(cond
(= zone [:hand]) (if (= side "Runner") "Grip" "HQ")
(= zone [:discard]) (if (= side "Runner") "Heap" "Archives")
(= zone [:deck]) (if (= side "Runner") "Stack" "R&D")
(= zone [:hand]) (if (= side "Runner") "the Grip" "HQ")
(= zone [:discard]) (if (= side "Runner") "the Heap" "Archives")
(= zone [:deck]) (if (= side "Runner") "the Stack" "R&D")
(= zone [:set-aside]) "set-aside cards"
(= (take 1 zone) [:rig]) "Rig"
(= (take 2 zone) [:servers :hq]) "the root of HQ"
Expand Down
2 changes: 1 addition & 1 deletion test/clj/game/cards/events_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -836,7 +836,7 @@
:runner {:hand ["Burner"]}})
(take-credits state :corp)
(play-run-event state "Burner" :hq)
(is (last-log-contains? state "reveals Hedge Fund, Hedge Fund, and Hedge Fund from HQ"))
(is (last-log-contains? state "reveal Hedge Fund, Hedge Fund, and Hedge Fund from HQ"))
(is (changed? [(count (:deck (get-corp))) 2
(count (:hand (get-corp))) -2]
(click-prompt state :runner "Hedge Fund")
Expand Down
6 changes: 3 additions & 3 deletions test/clj/game/cards/ice_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2846,7 +2846,7 @@
(let [hand (:hand (get-corp))
gate (get-ice state :hq 0)
log-str (str "Corp uses Gatekeeper to reveal.+"
" from HQ and shuffle them into R&D")]
" from HQ, and shuffle them into R&D")]
(run-on state "HQ")
(rez state :corp gate)
(run-continue state)
Expand All @@ -2868,7 +2868,7 @@
(let [discard (:discard (get-corp))
gate (get-ice state :hq 0)
log-str (str "Corp uses Gatekeeper to reveal.+"
" from Archives and shuffle them into R&D")]
" from Archives, and shuffle them into R&D")]
(run-on state "HQ")
(rez state :corp gate)
(run-continue state)
Expand All @@ -2893,7 +2893,7 @@
discard (:discard (get-corp))
gate (get-ice state :hq 0)
log-str (str "Corp uses Gatekeeper to reveal.+ from HQ "
"and .+ from Archives and shuffle them into R&D")]
"and .+ from Archives, and shuffle them into R&D")]
(run-on state "HQ")
(rez state :corp gate)
(run-continue state)
Expand Down
Loading

0 comments on commit 4134374

Please sign in to comment.