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

Issue 7821: check multi subtypes card helper function #7833

Merged
merged 3 commits into from
Oct 29, 2024
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
8 changes: 3 additions & 5 deletions src/clj/game/cards/assets.clj
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
installable-servers]]
[game.core.card :refer [agenda? asset? can-be-advanced? corp? event? corp-installable-type?
faceup? fake-identity? get-advancement-requirement
get-agenda-points get-card get-counters get-title get-zone hardware? has-subtype? ice?
identity? in-deck? in-discard? in-hand? in-server? installed? is-type?
get-agenda-points get-card get-counters get-title get-zone hardware? has-subtype?
has-any-subtype? ice? identity? in-deck? in-discard? in-hand? in-server? installed? is-type?
operation? program? resource? rezzed? runner? upgrade?]]
[game.core.card-defs :refer [card-def]]
[game.core.checkpoint :refer [fake-checkpoint]]
Expand Down Expand Up @@ -1063,9 +1063,7 @@
{:abilities [{:action true
:prompt "Choose an Executive, Sysop, or Character to add to HQ"
:msg (msg "reveal " (:title target) ", add it to HQ, and shuffle R&D")
:choices (req (cancellable (filter #(or (has-subtype? % "Executive")
(has-subtype? % "Sysop")
(has-subtype? % "Character"))
:choices (req (cancellable (filter #(has-any-subtype? % ["Executive" "Sysop" "Character"])
(:deck corp))
:sorted))
:cost [(->c :click 1)]
Expand Down
12 changes: 3 additions & 9 deletions src/clj/game/cards/hardware.clj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
[game.core.actions :refer [play-ability]]
[game.core.board :refer [all-active all-active-installed all-installed]]
[game.core.card :refer [corp? event? facedown? get-card get-counters get-title
get-zone hardware? has-subtype? ice? in-deck? in-discard?
get-zone hardware? has-subtype? has-any-subtype? ice? in-deck? in-discard?
in-hand? in-scored? installed? is-type? program? resource? rezzed?
runner? virus-program? faceup?]]
[game.core.card-defs :refer [card-def]]
Expand Down Expand Up @@ -2480,19 +2480,13 @@
(seq (filter
#(and (rezzed? %)
(installed? %)
(or (has-subtype? % "Bioroid")
(has-subtype? % "Clone")
(has-subtype? % "Executive")
(has-subtype? % "Sysop")))
(has-any-subtype? % ["Bioroid" "Clone" "Executive" "Sysop"]))
(all-active-installed state :corp)))))
:label "trash a Bioroid, Clone, Executive or Sysop"
:prompt "Choose a Bioroid, Clone, Executive, or Sysop to trash"
:choices {:card #(and (rezzed? %)
(installed? %)
(or (has-subtype? % "Bioroid")
(has-subtype? % "Clone")
(has-subtype? % "Executive")
(has-subtype? % "Sysop")))}
(has-any-subtype? % ["Bioroid" "Clone" "Executive" "Sysop"]))}
:async true
:msg (msg "trash " (:title target))
:effect (effect (trash eid target {:cause-card card}))}]})
Expand Down
12 changes: 4 additions & 8 deletions src/clj/game/cards/ice.clj
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
get-all-cards get-all-installed server->zone]]
[game.core.card :refer [active? agenda? asset? card-index can-be-advanced?
corp? corp-installable-type? faceup?
get-card get-counters get-zone
hardware? has-subtype? ice? in-discard? in-hand? installed? is-type? operation?
get-card get-counters get-zone hardware?
has-any-subtype? has-subtype? ice? in-discard? in-hand? installed? is-type? operation?
program? protecting-a-central? protecting-archives? protecting-hq? protecting-rd?
resource? rezzed? runner?]]
[game.core.card-defs :refer [card-def]]
Expand Down Expand Up @@ -2003,9 +2003,7 @@
:msg (msg "trash " (:title target))
:choices {:card #(and (installed? %)
(program? %)
(not (has-subtype? % "Decoder"))
(not (has-subtype? % "Fracter"))
(not (has-subtype? % "Killer")))}
(not (has-any-subtype? % ["Decoder" "Fracter" "Killer"])))}
:async true
:effect (effect (clear-wait-prompt :runner)
(trash eid target {:cause :subroutine}))}
Expand Down Expand Up @@ -2038,9 +2036,7 @@
:msg (msg "trash " (:title target))
:choices {:card #(and (installed? %)
(program? %)
(not (has-subtype? % "Decoder"))
(not (has-subtype? % "Fracter"))
(not (has-subtype? % "Killer")))}
(not (has-any-subtype? % ["Decoder" "Fracter" "Killer"])))}
:async true
:effect (effect (trash eid target {:cause :subroutine}))}]})

Expand Down
7 changes: 3 additions & 4 deletions src/clj/game/cards/identities.clj
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
[game.core.card :refer [agenda? asset? can-be-advanced?
corp-installable-type? corp? faceup? get-advancement-requirement
get-agenda-points get-card get-counters get-title get-zone hardware? has-subtype?
ice? in-discard? in-hand? in-play-area? in-rfg? installed? is-type? operation? program?
resource? rezzed? runner? upgrade?]]
has-any-subtype? ice? in-discard? in-hand? in-play-area? in-rfg? installed? is-type?
operation? program? resource? rezzed? runner? upgrade?]]
[game.core.charge :refer [charge-ability]]
[game.core.cost-fns :refer [install-cost play-cost
rez-additional-cost-bonus rez-cost]]
Expand Down Expand Up @@ -417,8 +417,7 @@
;; Effect marks Az's ability as "used" if it has already met it's trigger condition this turn
(letfn [(az-type? [card] (or (hardware? card)
(and (resource? card)
(or (has-subtype? card "Job")
(has-subtype? card "Connection")))))
(has-any-subtype? card ["Job" "Connection"]))))
(not-triggered? [state] (no-event? state :runner :runner-install #(az-type? (:card (first %)))))]
{:static-abilities [{:type :install-cost
:req (req (and (az-type? target)
Expand Down
9 changes: 3 additions & 6 deletions src/clj/game/cards/operations.clj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
installable-servers server->zone]]
[game.core.card :refer [active? agenda? asset? can-be-advanced? card-index corp? corp-installable-type?
event? facedown? faceup? get-advancement-requirement
get-card get-counters get-title get-zone hardware? has-subtype? ice? identity?
get-card get-counters get-title get-zone hardware? has-subtype? has-any-subtype? ice? identity?
in-discard? in-hand? installed? is-type? operation? program? resource?
rezzed? runner? upgrade?]]
[game.core.card-defs :refer [card-def]]
Expand Down Expand Up @@ -1065,8 +1065,7 @@
:successful
{:prompt "Choose 1 card to trash"
:choices {:card #(and (installed? %)
(or (has-subtype? % "Virtual")
(has-subtype? % "Link")))}
(has-any-subtype? % ["Virtual" "Link"]))}
:msg (msg "trash " (card-str state target))
:async true
:effect (effect (trash eid target {:cause-card card}))}}}})
Expand Down Expand Up @@ -2364,9 +2363,7 @@
{:on-play
{:prompt "Choose a Sysop, Executive or Clone to trash"
:msg (msg "trash " (:title target) " to remove 2 bad publicity")
:choices {:card #(or (has-subtype? % "Clone")
(has-subtype? % "Executive")
(has-subtype? % "Sysop"))}
:choices {:card #(has-any-subtype? % ["Clone" "Executive" "Sysop"])}
:async true
:effect (req (wait-for
(lose-bad-publicity state side 2)
Expand Down
6 changes: 2 additions & 4 deletions src/clj/game/cards/programs.clj
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
[game.core.card :refer [active? agenda? asset? card-index corp? facedown? faceup?
get-advancement-requirement get-card get-counters
get-nested-host get-title get-zone
hardware? has-subtype? in-hand? in-discard? ice? installed?
hardware? has-subtype? has-any-subtype? in-hand? in-discard? ice? installed?
is-type? program? resource? rezzed? runner?]]
[game.core.card-defs :refer [card-def]]
[game.core.charge :refer [charge-ability]]
Expand Down Expand Up @@ -1921,9 +1921,7 @@

(defcard "Laser Pointer"
{:events [{:event :encounter-ice
:req (req (or (has-subtype? current-ice "AP")
(has-subtype? current-ice "Observer")
(has-subtype? current-ice "Destroyer")))
:req (req (has-any-subtype? current-ice ["AP" "Observer" "Destroyer"]))
:async true
:effect (effect (continue-ability
{:optional
Expand Down
8 changes: 4 additions & 4 deletions src/clj/game/cards/resources.clj
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@
all-installed-runner card->server get-all-cards server->zone]]
[game.core.card :refer [agenda? asset? assoc-host-zones card-index corp? condition-counter?
event? facedown? get-agenda-points get-card get-counters
get-title get-zone hardware? has-subtype? ice? identity? in-discard? in-hand? in-scored?
installed? is-type? program? resource? rezzed? runner? upgrade? virus-program?]]
get-title get-zone hardware? has-subtype? has-any-subtype? ice? identity?
in-discard? in-hand? in-scored? installed? is-type? program? resource? rezzed?
runner? upgrade? virus-program?]]
[game.core.card-defs :refer [card-def]]
[game.core.charge :refer [can-charge charge-ability]]
[game.core.checkpoint :refer [fake-checkpoint]]
Expand Down Expand Up @@ -367,8 +368,7 @@
(req (let [hosted-cards (:hosted (get-card state card))
not-hosted? (fn [c] (not-any? #(= (:title %) (:title c)) hosted-cards))]
(cancellable (filter #(and (not-hosted? %)
(or (has-subtype? % "Virus")
(has-subtype? % "Weapon")))
(has-any-subtype? % ["Virus" "Weapon"]))
(:deck runner)) :sorted)))
:async true
:waiting-prompt true
Expand Down
10 changes: 10 additions & 0 deletions src/cljc/game/core/card.cljc
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,16 @@
[card subtype]
(find-first #(= % subtype) (:subtypes card)))

(defn has-any-subtype?
"Checks if the provided list of subtypes contains any of the subtypes present on the card"
[card subtypes]
(some #(has-subtype? card %) subtypes))

(defn has-all-subtypes?
"Checks if the provided list of subtypes contains any of the subtypes present on the card"
[card subtypes]
(every? #(has-subtype? card %) subtypes))

(defn virus-program?
[card]
(and (program? card)
Expand Down
25 changes: 25 additions & 0 deletions test/clj/game/core/card_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,28 @@
(is (has-subtype? laamb "Icebreaker"))
(is (has-subtype? laamb "Fracter"))
(is (not (has-subtype? stimhack "Mod"))))))

(deftest has-any-subtype?-test
(before-each [contaminate {:subtypes []}
stimhack {:subtypes ["Run"]}
laamb {:subtypes ["Icebreaker" "Fracter"]}]
(testing "one is present returns true"
(is (has-any-subtype? stimhack ["Test" "Two" "Run"])))
(testing "multiple are present but not all returns true"
(is (has-any-subtype? laamb ["Test" "Two" "Icebreaker" "Fracter" "False"])))
(testing "none are present"
(is (not (has-any-subtype? contaminate ["Test" "Two" "Icebreaker" "Fracter" "False"]))))))

(deftest has-all-subtypes?-test
(before-each [contaminate {:subtypes []}
stimhack {:subtypes ["Run"]}
laamb {:subtypes ["Icebreaker" "Fracter"]}]
(testing "Interaction when card has one subtype"
(is (has-all-subtypes? stimhack ["Run"]))
(is (not (has-all-subtypes? stimhack ["Test" "Two" "Run"]))))
(testing "Interaction when card has two subtypes"
(is (has-all-subtypes? laamb ["Icebreaker" "Fracter"]))
(is (has-all-subtypes? laamb ["Icebreaker"]))
(is (not (has-all-subtypes? laamb ["Icebreaker" "Fracter" "Test"]))))
(testing "Interaction when card has no subtypes"
(is (not (has-all-subtypes? contaminate ["Test" "Two" "Icebreaker" "Fracter" "False"]))))))
Loading