Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
ad8d2eb
melies-u image handling
NBKelly Feb 14, 2026
a44a56c
Meleis U: Only the Brightest
NBKelly Feb 14, 2026
621e6d8
Virtual Intelligence, PI
NBKelly Feb 14, 2026
1a8ebeb
remove unused import
NBKelly Feb 15, 2026
295ba13
functional rules change for bad publicity
NBKelly Feb 15, 2026
9ba9173
unit tests updated for the bad publicity rule change
NBKelly Feb 15, 2026
ce3d1e2
Editorial Division, Nihilo Agent, Vulture Fund
NBKelly Feb 15, 2026
50d979c
hiram 0mission svensson
NBKelly Feb 16, 2026
dcd0065
qol for meiles u
NBKelly Feb 16, 2026
23dac31
side doing the damage trashes the cards
NBKelly Feb 17, 2026
81e034a
let them dream, melies city luxury line
NBKelly Feb 18, 2026
4b688d1
startup validation is three 3+pointers nows
NBKelly Feb 18, 2026
6762650
fixed tests
NBKelly Feb 18, 2026
edc7665
less hacky bad pub routing
NBKelly Feb 18, 2026
e086444
stick and poke
NBKelly Feb 18, 2026
4329a80
magistrate revontulet
NBKelly Feb 19, 2026
0e35973
flagship, access updates
NBKelly Feb 19, 2026
13b105b
Merge branch 'master' into vantage-point-spoilers-2
NBKelly Feb 21, 2026
88276c9
Merge branch 'master' of github.com:mtgred/netrunner into vantage-poi…
NBKelly Feb 21, 2026
7edb010
compiles
NBKelly Feb 21, 2026
09f0974
Async
NBKelly Feb 21, 2026
c85c9ce
tailgate, kompromat
NBKelly Feb 21, 2026
efdd9e2
witch hunt test
NBKelly Feb 21, 2026
116f06d
paywall
NBKelly Feb 21, 2026
ee23fa5
bad pub redo now works with unit tests
NBKelly Feb 21, 2026
54bf283
flywheel, event horizon
NBKelly Feb 21, 2026
b90e2a5
stowaway
NBKelly Feb 21, 2026
f063a4d
myoshu and tests
NBKelly Feb 21, 2026
dd03d1a
beta build
NBKelly Feb 22, 2026
db91d80
borrowed goods
NBKelly Feb 22, 2026
4fba084
rules says there will be an upadte to make flagship not silly with cu…
NBKelly Feb 23, 2026
13be4c3
dont prune cards from the set of already accessed cards
NBKelly Feb 23, 2026
df76104
touchstone, rotary
NBKelly Feb 23, 2026
24c5158
knowledge seeker
NBKelly Feb 23, 2026
9bda6ed
Ansel 2.0, baker
NBKelly Feb 23, 2026
f05934b
tocsin, viksek, vertigo
NBKelly Feb 24, 2026
78305e4
unit tests for the ice
NBKelly Feb 24, 2026
fa92c9f
esca
NBKelly Feb 24, 2026
046c862
unleash and tests
NBKelly Feb 24, 2026
e3306de
ezaM and tests
NBKelly Feb 24, 2026
d88fb11
The Red Room and tests
NBKelly Feb 24, 2026
2e08750
show other player discard option for prompts
NBKelly Feb 24, 2026
98bc6bd
Methuselah test
NBKelly Feb 26, 2026
157b1af
hype machine and test
NBKelly Feb 26, 2026
6fe8951
read-write share
NBKelly Feb 26, 2026
20fd10d
grubber and unit etsts
NBKelly Feb 26, 2026
75864f5
support for cards with hosting discounts to work for cost computation
NBKelly Feb 26, 2026
2519f3a
chain reaction and test
NBKelly Feb 26, 2026
97978ad
hackerspace and test, test for class act triggering correctly on host…
NBKelly Feb 26, 2026
9894225
perfect recall and test
NBKelly Feb 26, 2026
52b5ca7
tungsten tailor and tests
NBKelly Feb 27, 2026
55b3613
reverb and tests
NBKelly Feb 27, 2026
6b24596
realloc and tests
NBKelly Feb 27, 2026
5eb84b3
expand run from choices ab
NBKelly Feb 27, 2026
316f1fa
aircheck and take a dive
NBKelly Feb 27, 2026
fb90ccf
label fix for read write
NBKelly Feb 28, 2026
2372454
install-req -> install-req + legal-zones
NBKelly Feb 28, 2026
5bf7ca1
lotus haze and unit tests
NBKelly Feb 28, 2026
97ec8d6
fix hackerspace test
NBKelly Feb 28, 2026
582fad6
cannot lose credits if the effect is live
NBKelly Feb 28, 2026
c3cb1cf
pick-counters, costs updated for effects which restrict spending cred…
NBKelly Feb 28, 2026
10162c5
limit restrictions to runner side
NBKelly Feb 28, 2026
f8175c5
tag vp cards with interactive/silent/automatic
NBKelly Feb 28, 2026
ac15bb4
lethe and tests, and test frameworku pdate for concise run events
NBKelly Feb 28, 2026
894c6c7
sell out and unit test
NBKelly Feb 28, 2026
8076959
nurse hanh and test, access fires archives-flipped event
NBKelly Feb 28, 2026
26d914f
cultivate and unit tests. A little documentation update for test frak…
NBKelly Feb 28, 2026
c41fd0d
fix ordering
NBKelly Feb 28, 2026
991f52f
rework bacpro to allow redo of all three modes
NBKelly Feb 28, 2026
f3b5d85
unit test updates for bacpro
NBKelly Feb 28, 2026
6912b6d
sacrifice zone expansion and tests
NBKelly Feb 28, 2026
c4084cc
luana campos and tests
NBKelly Feb 28, 2026
e2a0785
sipa and tests
NBKelly Mar 1, 2026
8d38a18
support for cannot-forfeit flags
NBKelly Mar 1, 2026
b52d6b5
man in the middle and tests
NBKelly Mar 1, 2026
db1989f
sleipnir and tests
NBKelly Mar 1, 2026
61e82ad
caveat emptor and tests
NBKelly Mar 1, 2026
4b26dbf
lionsmane and tests
NBKelly Mar 1, 2026
806f0e6
caveat emptor and tests
NBKelly Mar 1, 2026
e71ff8d
shackleton grid and tests
NBKelly Mar 1, 2026
f741c97
Merge branch 'master' of github.com:mtgred/netrunner into vantage-poi…
NBKelly Mar 1, 2026
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
261 changes: 214 additions & 47 deletions src/clj/game/cards/agendas.clj

Large diffs are not rendered by default.

70 changes: 69 additions & 1 deletion src/clj/game/cards/assets.clj
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
[game.core.set-aside :refer [swap-set-aside-cards]]
[game.core.shuffling :refer [shuffle! shuffle-into-deck shuffle-my-deck!
shuffle-into-rd-effect]]
[game.core.tags :refer [gain-tags]]
[game.core.tags :refer [gain-tags lose-tags]]
[game.core.threat :refer [threat-level]]
[game.core.to-string :refer [card-str]]
[game.core.toasts :refer [toast]]
Expand Down Expand Up @@ -1071,6 +1071,20 @@
:req (req (installed? target))
:value 1}]})

(defcard "Esca"
{:flags {:rd-reveal (req true)}
:poison true
:on-access {:msg "force the Runner to lose 1 [Credits]"
:async true
:effect (req (wait-for (lose-credits state :runner 1)
(continue-ability
state side
{:req (req tagged)
:msg "do 1 net damage"
:async true
:effect (req (damage state side eid :net 1))}
card nil)))}})

(defcard "Estelle Moon"
{:events [{:event :corp-install
:req (req (and (or (asset? (:card context))
Expand Down Expand Up @@ -1843,6 +1857,41 @@
:effect (req (access-bonus state :runner target -1))}
card targets))}]})

(defcard "Luana Campos"
{:uninstall (req (continue-ability
state side
{:req (req (and (rezzed? (:old-card context))
(pos? (get-counters (:old-card context) :bad-publicity))))
:msg (msg "take " (get-counters (:old-card context) :bad-publicity)
" bad publicity")
:async true
:effect (req
(gain-bad-publicity
state side eid
(get-counters (:old-card context) :bad-publicity)))}
card targets))
:events [{:event :corp-turn-begins
:interactive (req true)
:change-in-game-state {:req (req (pos? (count-bad-pub state))) :silent true}
:optional {:interactive (req true)
:prompt "Host a bad publicity counter to gain 3 [Credits] and draw a card?"
:yes-ability {:msg (msg "gain 3 [Credits] and draw 1 card")
:cost [(->c :host-bad-pub 1)]
:async true
:effect (req (wait-for
(gain-credits state side 3 {:suppress-checkpoint true})
(draw state side eid 1)))}}}]})

(defcard "Magistrate Revontulet"
{:static-abilities [{:type :steal-additional-cost
:req (req (agenda? target))
:value (req [(->c :credit 3)])}]
:events [{:event :agenda-scored
:async true
:interactive (req true)
:msg "force the Runner to lose 3 [Credits]"
:effect (req (lose-credits state :runner eid 3))}]})

(defcard "Malia Z0L0K4"
(let [unmark
(req (when-let [malia-target (get-in card [:special :malia-target])]
Expand Down Expand Up @@ -2240,6 +2289,25 @@
(do (as-agenda state :runner card -1)
(effect-completed state side eid))))}})

(defcard "Nihilo Agent"
{:data {:counter {:power 3}}
:events [(trash-on-empty :power)
{:event :corp-turn-ends
:msg "take 1 bad publicity and give the Runner 1 tag"
:async true
:effect (req (wait-for
(gain-bad-publicity state :corp 1 {:suppress-checkpoint true})
(wait-for
(add-counter state side card :power -1 {:suppress-checkpoint true})
(gain-tags state side eid 1))))}
{:event :corp-turn-begins
:change-in-game-state {:silent true
:req (req (or tagged (pos? (count-bad-pub state))))}
:msg "remove 1 bad publicity and 1 tag"
:async true
:effect (req (wait-for (lose-bad-publicity state :corp 1 {:suppress-checkpoint true})
(lose-tags state side eid 1)))}]})

(defcard "Open Forum"
{:events [{:event :corp-mandatory-draw
:interactive (req true)
Expand Down
155 changes: 155 additions & 0 deletions src/clj/game/cards/events.clj
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,34 @@
:this-card-run true
:ability (drain-credits :runner :corp 5 2 2)})]})

(defcard "Aircheck"
{:makes-run true
:data {:counter {:credit 4}}
:interactions {:pay-credits {:req (req run) :type :credit}}
:static-abilities [{:type :cannot-pay-credits-from-pool
:req (req (= :runner side))
:value true}
{:type :cannot-lose-credits
:req (req (= :runner side))
:value true}]
:on-play (run-server-from-choices-ability
["HQ" "R&D"]
{:events [{:event :run-ends
:unregister-once-resolved true
:req (req (and (:successful context)
this-card-run
(or (= [:hq] (:server context))
(= [:rd] (:server context)))))
:prompt "Choose a remote server to run"
:choices (req (cancellable
(->> runnable-servers
(map unknown->kw)
(filter is-remote?)
(map remote->name))))
:msg (msg "make a run on " target)
:async true
:effect (effect (make-run eid target card))}]})})

(defcard "Always Have a Backup Plan"
{:makes-run true
:on-play {:prompt "Choose a server"
Expand Down Expand Up @@ -264,6 +292,34 @@
(move state :corp c :deck))
(shuffle! state :corp :deck))}})]})

(defcard "Beta Build"
{:makes-run true
:on-play {:async true
:effect (req (wait-for
(resolve-ability
state side
{:prompt "Install a non-virus program"
:choices (req (cancellable (filter #(and (program? %)
(runner-can-install? state side eid % {:no-toast true}))
(:deck runner))))
:async true
:effect (req (wait-for
(runner-install state side target {:ignore-all-cost :true :msg-keys {:display-origin true :source-card card}})
(complete-with-result state side eid async-result)))}
card nil)
(let [installed-card async-result]
(resolve-ability state side eid
(run-any-server-ability {:events [{:event :run-ends
:unregister-once-resolved true
:duration :end-of-run
:interactive (req true)
:automatic :last
:change-in-game-state {:silent true
:req (req (get-card state installed-card))}
:msg (msg "add " (:title installed-card) " to the top of the stack")
:effect (req (move state side installed-card :deck {:front true}))}]})
card nil))))}})

(defcard "Black Hat"
{:on-play
{:trace
Expand Down Expand Up @@ -561,6 +617,39 @@
(cbi-choice from '() (count from) from)))
card nil))}})]}))

(defcard "Chain Reaction"
(let [corp-choice {:player :corp
:prompt "Choose a Runner card to trash"
:async true
:req (req (seq (all-installed state :runner)))
:choices {:card (every-pred runner? installed?)}
:waiting-prompt true
:display-side :corp
:msg (msg "trash " (:title target))
:effect (req (trash state :corp eid target))}
cards-to-trash (fn [state] (min 2 (count (all-installed state :corp))))
runner-choice {:prompt (msg "choose " (quantify (cards-to-trash state) "card") " to trash")
:async true
:choices {:card (every-pred corp? installed?)
:max (req (cards-to-trash state))
:all true}
:waiting-prompt true
:msg (msg "trash " (enumerate-str (map #(card-str state %) targets)))
:effect (req (wait-for (trash-cards state side targets)
(continue-ability
state :corp
corp-choice
card nil)))}]
{:on-play {:async true
:change-in-game-state {:req (req (or (seq (all-installed state :corp))
(seq (all-installed state :runner))))}
:req (req (and (some #{:hq} (:successful-run runner-reg))
(some #{:rd} (:successful-run runner-reg))
(some #{:archives} (:successful-run runner-reg))))
:effect (req (if (seq (all-installed state :corp))
(continue-ability state side runner-choice card nil)
(continue-ability state :corp corp-choice card nil)))}}))

(defcard "Charm Offensive"
(letfn [(trash-x-opt [t]
{:option (str "Trash a rezzed copy of " t)
Expand Down Expand Up @@ -2180,6 +2269,45 @@
(defcard "Knifed"
(cutlery "Barrier"))

(defcard "Kompromat"
(letfn [(iced-servers [state side eid card]
(filter #(-> (get-in @state (cons :corp (server->zone state %))) :ices count pos?)
(zones->sorted-names (get-runnable-zones state side eid card nil))))]
{:makes-run true
:on-play {:async true
:rfg-instead-of-trashing true
:change-in-game-state {:req (req (seq (iced-servers state side eid card)))}
:prompt "Choose an iced server"
:choices (req (iced-servers state side eid card))
:effect (req (make-run state side eid target card))}
:events [{:event :run-ends
:req (req (and this-card-run (:successful context)))
:async true
:interactive (req true)
:effect (req (let [valid-ice (filter #(and (ice? %)
(rezzed? %)
(= (first (:server context)) (second (get-zone %))))
(all-installed state :corp))]
(continue-ability
state side
(if (seq valid-ice)
{:prompt "Derez an ice? (if you click done, you take a bad publicity)"
:player :corp
:waiting-prompt true
:choices {:req (req (some #(same-card? % target) valid-ice))}
:cancel {:display-side :runner
:msg "give the Corp 1 bad publicity"
:async true
:effect (req (gain-bad-publicity state :runner eid 1))}
:msg (msg "derez " (card-str state target))
:display-side :corp
:async true
:effect (req (derez state side eid target {:no-msg true}))}
{:msg "give the Corp 1 bad publicity"
:async true
:effect (req (gain-bad-publicity state :runner eid 1))})
card nil)))}]}))

(defcard "Kraken"
{:on-play
{:req (req (:stole-agenda runner-reg))
Expand Down Expand Up @@ -3459,6 +3587,13 @@
(:label (:ability context)))))
:value (->c :credit 1)}]})

(defcard "Sell Out"
{:on-play {:additional-cost [(->c :resource 1)]
:async true
:msg "gain 4 [Credits] and draw 2 cards"
:effect (req (wait-for (gain-credits state side 4 {:suppress-checkpoint true})
(draw state side eid 2)))}})

(defcard "Shred"
{:on-play (run-any-server-ability)
:makes-run true
Expand Down Expand Up @@ -3761,6 +3896,26 @@
(assoc ability :event :corp-turn-ends)
(assoc ability :event :runner-turn-ends)]}))

(defcard "Tailgate"
{:makes-run true
:on-play (run-server-ability
:hq
{:play-cost-bonus (req (- (count (get-in @state [:corp :servers :hq :ices]))))})
:events [{:event :successful-run
:silent (req true)
:req (req (and (= :hq (target-server context)) this-card-run))
:effect (effect (register-events
card [(breach-access-bonus :hq 2 {:duration :end-of-run})]))}]})

(defcard "Take a Dive"
{:on-play (run-server-from-choices-ability ["HQ" "R&D"] {:rfg-instead-of-trashing true})
:events [{:event :successful-run
:req (req (letfn [(valid-ctx? [[ctx]] (pos? (or (:subroutines-fired ctx) 0)))]
(valid-ctx? [context])))
:msg "force the Corp to take 1 Bad Publicity"
:async true
:effect (req (gain-bad-publicity state :corp eid 1 {:card card}))}]})

(defcard "Test Run"
{:on-play
{:prompt (req (if (not (zone-locked? state :runner :discard))
Expand Down
Loading
Loading