Skip to content

Commit 8334ed4

Browse files
authored
Merge pull request #7973 from NBKelly/prevention-rework
Prevention system reworked
2 parents 23bb952 + 9b69594 commit 8334ed4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2106
-1685
lines changed

src/clj/game/cards/agendas.clj

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
in-scored? installed? operation? program? resource? rezzed? runner? upgrade?]]
1616
[game.core.card-defs :refer [card-def]]
1717
[game.core.cost-fns :refer [rez-cost install-cost]]
18-
[game.core.damage :refer [damage damage-bonus]]
18+
[game.core.damage :refer [damage]]
1919
[game.core.def-helpers :refer [corp-recur defcard do-net-damage
2020
offer-jack-out reorder-choice take-credits get-x-fn]]
2121
[game.core.drawing :refer [draw draw-up-to]]
@@ -38,12 +38,13 @@
3838
trash trash-cards]]
3939
[game.core.optional :refer [get-autoresolve set-autoresolve]]
4040
[game.core.payment :refer [can-pay? ->c]]
41+
[game.core.prevention :refer [damage-boost preventable? prevent-jack-out]]
4142
[game.core.prompts :refer [cancellable clear-wait-prompt show-wait-prompt]]
4243
[game.core.props :refer [add-counter add-prop]]
4344
[game.core.purging :refer [purge]]
4445
[game.core.revealing :refer [reveal]]
4546
[game.core.rezzing :refer [derez rez]]
46-
[game.core.runs :refer [end-run force-ice-encounter jack-out-prevent]]
47+
[game.core.runs :refer [end-run force-ice-encounter]]
4748
[game.core.say :refer [system-msg]]
4849
[game.core.servers :refer [is-remote? target-server zone->name]]
4950
[game.core.shuffling :refer [shuffle! shuffle-into-deck
@@ -1201,12 +1202,20 @@
12011202
{:on-score {:silent (req true)
12021203
:async true
12031204
:effect (effect (add-counter eid card :power 2 nil))}
1204-
:interactions {:prevent [{:type #{:jack-out}
1205-
:req (req (pos? (get-counters card :power)))}]}
1206-
:abilities [{:req (req (:run @state))
1207-
:cost [(->c :power 1)]
1208-
:msg "prevent the Runner from jacking out"
1209-
:effect (effect (jack-out-prevent))}]})
1205+
:prevention [{:prevents :jack-out
1206+
:type :ability
1207+
:ability {:cost [(->c :power 1)]
1208+
:msg "prevent the runner from jacking out for the remainder of this run"
1209+
:condition :active
1210+
:async true
1211+
:req (req (preventable? context))
1212+
:effect (req (wait-for (prevent-jack-out state side)
1213+
(register-lingering-effect
1214+
state side card
1215+
{:type :cannot-jack-out
1216+
:value true
1217+
:duration :end-of-run})
1218+
(effect-completed state side eid)))}}]})
12101219

12111220
(defcard "License Acquisition"
12121221
{:on-score {:interactive (req true)
@@ -2236,11 +2245,19 @@
22362245
:effect (effect (gain-tags eid 1))}})
22372246

22382247
(defcard "The Cleaners"
2239-
{:events [{:event :pre-damage
2240-
:req (req (and (= :meat (:type context))
2241-
(= :corp side)))
2242-
:msg "do 1 additional meat damage"
2243-
:effect (effect (damage-bonus :meat 1))}]})
2248+
{:prevention [{:prevents :pre-damage
2249+
:type :event
2250+
:max-uses 1
2251+
:mandatory true
2252+
:ability {:async true
2253+
:condition :active
2254+
:req (req
2255+
(and (= :meat (:type context))
2256+
(not= :all (:prevented context))
2257+
(= :corp (:source-player context))
2258+
(not (:unboostable context))))
2259+
:msg "increase the pending meat damage by 1"
2260+
:effect (req (damage-boost state side eid 1))}}]})
22442261

22452262
(defcard "The Future is Now"
22462263
{:on-score {:interactive (req true)

src/clj/game/cards/assets.clj

Lines changed: 54 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
[game.core.actions :refer [score]]
88
[game.core.agendas :refer [update-all-advancement-requirements
99
update-all-agenda-points]]
10-
[game.core.bad-publicity :refer [bad-publicity-prevent gain-bad-publicity
11-
lose-bad-publicity]]
10+
[game.core.bad-publicity :refer [gain-bad-publicity lose-bad-publicity]]
1211
[game.core.board :refer [all-active-installed all-installed all-installed-runner-type get-remotes
1312
installable-servers]]
1413
[game.core.card :refer [agenda? asset? can-be-advanced? corp? event? corp-installable-type?
@@ -18,7 +17,7 @@
1817
operation? program? resource? rezzed? runner? upgrade?]]
1918
[game.core.card-defs :refer [card-def]]
2019
[game.core.checkpoint :refer [fake-checkpoint]]
21-
[game.core.damage :refer [damage damage-prevent]]
20+
[game.core.damage :refer [damage]]
2221
[game.core.def-helpers :refer [corp-recur corp-rez-toast defcard
2322
reorder-choice spend-credits take-credits trash-on-empty get-x-fn with-revealed-hand]]
2423
[game.core.drawing :refer [draw first-time-draw-bonus max-draw
@@ -27,7 +26,6 @@
2726
[game.core.eid :refer [complete-with-result effect-completed is-basic-advance-action? make-eid get-ability-targets]]
2827
[game.core.engine :refer [not-used-once? pay register-events resolve-ability trigger-event-sync]]
2928
[game.core.events :refer [first-event? no-event? turn-events event-count]]
30-
[game.core.expose :refer [expose-prevent]]
3129
[game.core.flags :refer [lock-zone prevent-current
3230
prevent-draw
3331
register-turn-flag! release-zone]]
@@ -46,6 +44,7 @@
4644
[game.core.play-instants :refer [play-instant]]
4745
[game.core.prompts :refer [cancellable]]
4846
[game.core.props :refer [add-counter add-icon add-prop remove-icon set-prop]]
47+
[game.core.prevention :refer [damage-name preventable? prevent-bad-publicity prevent-damage prevent-expose]]
4948
[game.core.revealing :refer [reveal]]
5049
[game.core.rezzing :refer [can-pay-to-rez? derez rez]]
5150
[game.core.runs :refer [end-run]]
@@ -445,11 +444,15 @@
445444
(damage state side eid :meat 1 {:card card}))))}})
446445

447446
(defcard "Broadcast Square"
448-
{:events [{:event :pre-bad-publicity
449-
:async true
450-
:trace {:base 3
451-
:successful {:msg "prevents all bad publicity"
452-
:effect (effect (bad-publicity-prevent Integer/MAX_VALUE))}}}]})
447+
{:prevention [{:prevents :bad-publicity
448+
:type :event
449+
:max-uses 1
450+
:mandatory true
451+
:ability {:req (req (preventable? context))
452+
:trace {:base 3
453+
:successful {:msg "prevent all bad publicity"
454+
:async true
455+
:effect (req (prevent-bad-publicity state side eid :all))}}}}]})
453456

454457
(defcard "C.I. Fund"
455458
{:derezzed-events [corp-rez-toast]
@@ -1707,16 +1710,13 @@
17071710
{:derezzed-events [corp-rez-toast]
17081711
:events [(assoc ability :event :corp-turn-begins)]
17091712
:data {:counter {:credit 8}}
1710-
:abilities [(set-autoresolve :auto-reshuffle "Marilyn Campaign shuffling itself back into R&D")]
1711-
:on-trash {:interactive (req true)
1712-
:optional
1713-
{:waiting-prompt true
1714-
:prompt (msg "Shuffle " (:title card) " into R&D?")
1715-
:autoresolve (get-autoresolve :auto-reshuffle)
1716-
:player :corp
1717-
:yes-ability {:msg "shuffle itself back into R&D"
1718-
:effect (effect (move :corp card :deck)
1719-
(shuffle! :corp :deck))}}}}))
1713+
:prevention [{:prevents :trash
1714+
:type :event
1715+
:label "Shuffle Marilyn Campaign into R&D"
1716+
:max-uses 1
1717+
:ability {:msg "shuffle itself into R&D instead of moving it to Archives"
1718+
:req (req (some #(same-card? % card) (map :card (get-in @state [:prevent :trash :remaining]))))
1719+
:effect (req (swap! state update-in [:prevent :trash :remaining] (fn [ctx] (mapv #(if (same-card? card (:card %)) (assoc % :destination :deck :shuffle-rd true) %) ctx))))}}]}))
17201720

17211721
(defcard "Mark Yale"
17221722
{:events [{:event :agenda-counter-spent
@@ -2208,16 +2208,18 @@
22082208
card nil)))}]}))
22092209

22102210
(defcard "Prāna Condenser"
2211-
{:interactions {:prevent [{:type #{:net}
2212-
:req (req (= :corp (:side target)))}]}
2213-
:abilities [{:label "Prevent 1 net damage to place power counter on Prāna Condenser"
2214-
:msg "prevent 1 net damage, place 1 power counter, and gain 3 [Credits]"
2215-
:async true
2216-
:req (req true)
2217-
:effect (req (damage-prevent state :corp :net 1)
2218-
(wait-for (add-counter state side card :power 1 nil)
2219-
(gain-credits state :corp eid 3)))}
2220-
{:action true
2211+
{:prevention [{:prevents :damage
2212+
:type :event
2213+
:max-uses 1
2214+
:ability {:async true
2215+
:msg "prevent 1 net damage, place 1 counter on itself, and gain 3 [Credits]"
2216+
:req (req (and (= :net (:type context))
2217+
(= :corp (:source-player context))
2218+
(preventable? context)))
2219+
:effect (req (wait-for (prevent-damage state side 1)
2220+
(wait-for (add-counter state side card :power 1 {:suppress-checkpoint true})
2221+
(gain-credits state side eid 3))))}}]
2222+
:abilities [{:action true
22212223
:msg (msg "deal " (get-counters card :power) " net damage")
22222224
:label "deal net damage"
22232225
:cost [(->c :click 2) (->c :trash-can)]
@@ -2712,9 +2714,9 @@
27122714
:no-ability {:effect (effect (system-msg (str "declines to use " (:title card))))}
27132715
:yes-ability {:async true
27142716
:cost [(->c :credit 4)]
2715-
:msg "do 3 net damage and give the Runner 1 tag"
2716-
:effect (req (wait-for (damage state side :net 3 {:card card})
2717-
(gain-tags state :corp eid 1)))}}}})
2717+
:msg "give the Runner 1 tag and do 3 net damage"
2718+
:effect (req (wait-for (gain-tags state :corp 1 {:suppress-checkpoint true})
2719+
(damage state side eid :net 3 {:card card})))}}}})
27182720

27192721
(defcard "Space Camp"
27202722
{:flags {:rd-reveal (req true)}
@@ -3281,27 +3283,34 @@
32813283
(rez state side eid (last (:hosted (get-card state card))) {:cost-bonus -2})))}]})
32823284

32833285
(defcard "Zaibatsu Loyalty"
3284-
{:interactions {:prevent [{:type #{:expose}
3285-
:req (req true)}]}
3286-
:derezzed-events [{:event :pre-expose
3286+
{:prevention [{:prevents :expose
3287+
:type :ability
3288+
:label "1 [Credit]: Zaibatsu Loyalty"
3289+
:ability {:cost [(->c :credit 1)]
3290+
:req (req (preventable? context))
3291+
:msg "prevent a card from being exposed"
3292+
:async true
3293+
:effect (req (prevent-expose state side eid card))}}
3294+
{:prevents :expose
3295+
:type :ability
3296+
:label "[trash]: Zaibatsu Loyalty"
3297+
:ability {:cost [(->c :trash-can)]
3298+
:req (req (preventable? context))
3299+
:msg "prevent a card from being exposed"
3300+
:async true
3301+
:effect (req (prevent-expose state side eid card))}}]
3302+
:derezzed-events [{:event :expose-interrupt
32873303
:async true
3288-
:effect (req (let [etarget target]
3304+
:effect (req (let [ctx context]
32893305
(continue-ability
32903306
state side
32913307
{:optional
32923308
{:req (req (not (rezzed? card)))
32933309
:player :corp
3294-
:prompt (msg "The Runner is about to expose " (:title etarget) ". Rez Zaibatsu Loyalty?")
3310+
:prompt (msg "The Runner is about to expose " (enumerate-str (map #(card-str state % {:visible true}) (:cards ctx))) ". Rez Zaibatsu Loyalty?")
32953311
:yes-ability {:async true
32963312
:effect (effect (rez eid card))}}}
3297-
card nil)))}]
3298-
:abilities [{:msg "prevent 1 card from being exposed"
3299-
:cost [(->c :credit 1)]
3300-
:effect (effect (expose-prevent 1))}
3301-
{:msg "prevent 1 card from being exposed"
3302-
:label "Prevent 1 card from being exposed"
3303-
:cost [(->c :trash-can)]
3304-
:effect (effect (expose-prevent 1))}]})
3313+
card nil)))}]})
33053314

33063315
(defcard "Zealous Judge"
33073316
{:rez-req (req tagged)

0 commit comments

Comments
 (0)