Skip to content

Commit

Permalink
Merge pull request #7833 from heyshiloh/nr-7821-multi-subtypes
Browse files Browse the repository at this point in the history
Issue 7821: check multi subtypes card helper function
  • Loading branch information
NoahTheDuke authored Oct 29, 2024
2 parents 0e62a29 + 7393175 commit 4a87bcd
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 40 deletions.
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 @@ -2363,9 +2362,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"]))))))

0 comments on commit 4a87bcd

Please sign in to comment.