Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
1e48a1a
first steps on making a prevention framework
NBKelly Feb 23, 2025
76edc43
forger reworked as an interrupt
NBKelly Feb 23, 2025
1b137f6
tag prevention is updated
NBKelly Feb 24, 2025
6ec1846
cleaned up prevents
NBKelly Feb 24, 2025
81c8ddb
allow specify waiting msg
NBKelly Feb 24, 2025
06dbb38
waiting promp, pick printed title if no label
NBKelly Feb 24, 2025
75715d2
fix unit tests for updated card behaviour
NBKelly Feb 24, 2025
6919e25
if there aren't any abilities, ignore the trash icon thing
NBKelly Feb 24, 2025
3c6695e
simplified tags file
NBKelly Feb 24, 2025
bc47a0e
removed dead references to tag-prevent
NBKelly Feb 24, 2025
5d6c3bd
cleanup
NBKelly Feb 24, 2025
ce75489
cleanup/sorting for re-use
NBKelly Feb 24, 2025
8695ca0
bad publicity prevention + more cleanup
NBKelly Feb 24, 2025
06bfaed
half-way through expose handler
NBKelly Feb 24, 2025
654e09d
expose prevention is good to go
NBKelly Feb 24, 2025
0be5874
prevent jack out
NBKelly Feb 25, 2025
90ec901
fix tests
NBKelly Feb 25, 2025
9ebcf8e
preventions for end-the-run effects
NBKelly Feb 25, 2025
7a30040
made one of the functions generic/reusable
NBKelly Feb 25, 2025
29bb16b
more simplification
NBKelly Feb 25, 2025
fe0b416
encounter prevention
NBKelly Feb 25, 2025
8ea4619
klevetnik uses floating disable card system
NBKelly Feb 25, 2025
214169c
started on damage prevention - got the pre-damage stuff out of the wa…
NBKelly Feb 25, 2025
b20140a
damage prevention done (damage doesn't work though)
NBKelly Feb 26, 2025
77ed7c6
damage works again - fixed some naming
NBKelly Feb 26, 2025
7a12908
declining a prevention doesn't count as using it
NBKelly Feb 26, 2025
6091e31
100 unit tests down...
NBKelly Feb 26, 2025
0ef4a8c
all damage tests pass
NBKelly Feb 26, 2025
410b6ec
liza is simultaneous
NBKelly Feb 26, 2025
106caf4
started on trash prevention
NBKelly Feb 26, 2025
c748bbe
all tests pass I think
NBKelly Feb 27, 2025
1f75c42
all conflicts fixed, and all tests pass
NBKelly Feb 27, 2025
73a1dbe
fixed up damage a bit as per discussions with jamie
NBKelly Feb 28, 2025
483c100
snare order reflects the card now
NBKelly Mar 2, 2025
afac03b
checked NoH works as intended with a unit test
NBKelly Mar 2, 2025
c76e6da
corrected logic for cleaners/brainchips
NBKelly Mar 2, 2025
dcd742f
simplified damage, documentation, tests pass
NBKelly Mar 3, 2025
0b11ad5
trash icon checking cleaned up
NBKelly Mar 3, 2025
9b69594
expose simplified
NBKelly Mar 4, 2025
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
43 changes: 30 additions & 13 deletions src/clj/game/cards/agendas.clj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
in-scored? installed? operation? program? resource? rezzed? runner? upgrade?]]
[game.core.card-defs :refer [card-def]]
[game.core.cost-fns :refer [rez-cost install-cost]]
[game.core.damage :refer [damage damage-bonus]]
[game.core.damage :refer [damage]]
[game.core.def-helpers :refer [corp-recur defcard do-net-damage
offer-jack-out reorder-choice take-credits get-x-fn]]
[game.core.drawing :refer [draw draw-up-to]]
Expand All @@ -38,12 +38,13 @@
trash trash-cards]]
[game.core.optional :refer [get-autoresolve set-autoresolve]]
[game.core.payment :refer [can-pay? ->c]]
[game.core.prevention :refer [damage-boost preventable? prevent-jack-out]]
[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.rezzing :refer [derez rez]]
[game.core.runs :refer [end-run force-ice-encounter jack-out-prevent]]
[game.core.runs :refer [end-run force-ice-encounter]]
[game.core.say :refer [system-msg]]
[game.core.servers :refer [is-remote? target-server zone->name]]
[game.core.shuffling :refer [shuffle! shuffle-into-deck
Expand Down Expand Up @@ -1201,12 +1202,20 @@
{:on-score {:silent (req true)
:async true
:effect (effect (add-counter eid card :power 2 nil))}
:interactions {:prevent [{:type #{:jack-out}
:req (req (pos? (get-counters card :power)))}]}
:abilities [{:req (req (:run @state))
:cost [(->c :power 1)]
:msg "prevent the Runner from jacking out"
:effect (effect (jack-out-prevent))}]})
:prevention [{:prevents :jack-out
:type :ability
:ability {:cost [(->c :power 1)]
:msg "prevent the runner from jacking out for the remainder of this run"
:condition :active
:async true
:req (req (preventable? context))
:effect (req (wait-for (prevent-jack-out state side)
(register-lingering-effect
state side card
{:type :cannot-jack-out
:value true
:duration :end-of-run})
(effect-completed state side eid)))}}]})

(defcard "License Acquisition"
{:on-score {:interactive (req true)
Expand Down Expand Up @@ -2236,11 +2245,19 @@
:effect (effect (gain-tags eid 1))}})

(defcard "The Cleaners"
{:events [{:event :pre-damage
:req (req (and (= :meat (:type context))
(= :corp side)))
:msg "do 1 additional meat damage"
:effect (effect (damage-bonus :meat 1))}]})
{:prevention [{:prevents :pre-damage
:type :event
:max-uses 1
:mandatory true
:ability {:async true
:condition :active
:req (req
(and (= :meat (:type context))
(not= :all (:prevented context))
(= :corp (:source-player context))
(not (:unboostable context))))
:msg "increase the pending meat damage by 1"
:effect (req (damage-boost state side eid 1))}}]})

(defcard "The Future is Now"
{:on-score {:interactive (req true)
Expand Down
99 changes: 54 additions & 45 deletions src/clj/game/cards/assets.clj
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
[game.core.actions :refer [score]]
[game.core.agendas :refer [update-all-advancement-requirements
update-all-agenda-points]]
[game.core.bad-publicity :refer [bad-publicity-prevent gain-bad-publicity
lose-bad-publicity]]
[game.core.bad-publicity :refer [gain-bad-publicity lose-bad-publicity]]
[game.core.board :refer [all-active-installed all-installed all-installed-runner-type get-remotes
installable-servers]]
[game.core.card :refer [agenda? asset? can-be-advanced? corp? event? corp-installable-type?
Expand All @@ -18,7 +17,7 @@
operation? program? resource? rezzed? runner? upgrade?]]
[game.core.card-defs :refer [card-def]]
[game.core.checkpoint :refer [fake-checkpoint]]
[game.core.damage :refer [damage damage-prevent]]
[game.core.damage :refer [damage]]
[game.core.def-helpers :refer [corp-recur corp-rez-toast defcard
reorder-choice spend-credits take-credits trash-on-empty get-x-fn with-revealed-hand]]
[game.core.drawing :refer [draw first-time-draw-bonus max-draw
Expand All @@ -27,7 +26,6 @@
[game.core.eid :refer [complete-with-result effect-completed is-basic-advance-action? make-eid get-ability-targets]]
[game.core.engine :refer [not-used-once? pay register-events resolve-ability trigger-event-sync]]
[game.core.events :refer [first-event? no-event? turn-events event-count]]
[game.core.expose :refer [expose-prevent]]
[game.core.flags :refer [lock-zone prevent-current
prevent-draw
register-turn-flag! release-zone]]
Expand All @@ -46,6 +44,7 @@
[game.core.play-instants :refer [play-instant]]
[game.core.prompts :refer [cancellable]]
[game.core.props :refer [add-counter add-icon add-prop remove-icon set-prop]]
[game.core.prevention :refer [damage-name preventable? prevent-bad-publicity prevent-damage prevent-expose]]
[game.core.revealing :refer [reveal]]
[game.core.rezzing :refer [can-pay-to-rez? derez rez]]
[game.core.runs :refer [end-run]]
Expand Down Expand Up @@ -445,11 +444,15 @@
(damage state side eid :meat 1 {:card card}))))}})

(defcard "Broadcast Square"
{:events [{:event :pre-bad-publicity
:async true
:trace {:base 3
:successful {:msg "prevents all bad publicity"
:effect (effect (bad-publicity-prevent Integer/MAX_VALUE))}}}]})
{:prevention [{:prevents :bad-publicity
:type :event
:max-uses 1
:mandatory true
:ability {:req (req (preventable? context))
:trace {:base 3
:successful {:msg "prevent all bad publicity"
:async true
:effect (req (prevent-bad-publicity state side eid :all))}}}}]})

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

(defcard "Mark Yale"
{:events [{:event :agenda-counter-spent
Expand Down Expand Up @@ -2208,16 +2208,18 @@
card nil)))}]}))

(defcard "Prāna Condenser"
{:interactions {:prevent [{:type #{:net}
:req (req (= :corp (:side target)))}]}
:abilities [{:label "Prevent 1 net damage to place power counter on Prāna Condenser"
:msg "prevent 1 net damage, place 1 power counter, and gain 3 [Credits]"
:async true
:req (req true)
:effect (req (damage-prevent state :corp :net 1)
(wait-for (add-counter state side card :power 1 nil)
(gain-credits state :corp eid 3)))}
{:action true
{:prevention [{:prevents :damage
:type :event
:max-uses 1
:ability {:async true
:msg "prevent 1 net damage, place 1 counter on itself, and gain 3 [Credits]"
:req (req (and (= :net (:type context))
(= :corp (:source-player context))
(preventable? context)))
:effect (req (wait-for (prevent-damage state side 1)
(wait-for (add-counter state side card :power 1 {:suppress-checkpoint true})
(gain-credits state side eid 3))))}}]
:abilities [{:action true
:msg (msg "deal " (get-counters card :power) " net damage")
:label "deal net damage"
:cost [(->c :click 2) (->c :trash-can)]
Expand Down Expand Up @@ -2712,9 +2714,9 @@
:no-ability {:effect (effect (system-msg (str "declines to use " (:title card))))}
:yes-ability {:async true
:cost [(->c :credit 4)]
:msg "do 3 net damage and give the Runner 1 tag"
:effect (req (wait-for (damage state side :net 3 {:card card})
(gain-tags state :corp eid 1)))}}}})
:msg "give the Runner 1 tag and do 3 net damage"
:effect (req (wait-for (gain-tags state :corp 1 {:suppress-checkpoint true})
(damage state side eid :net 3 {:card card})))}}}})

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

(defcard "Zaibatsu Loyalty"
{:interactions {:prevent [{:type #{:expose}
:req (req true)}]}
:derezzed-events [{:event :pre-expose
{:prevention [{:prevents :expose
:type :ability
:label "1 [Credit]: Zaibatsu Loyalty"
:ability {:cost [(->c :credit 1)]
:req (req (preventable? context))
:msg "prevent a card from being exposed"
:async true
:effect (req (prevent-expose state side eid card))}}
{:prevents :expose
:type :ability
:label "[trash]: Zaibatsu Loyalty"
:ability {:cost [(->c :trash-can)]
:req (req (preventable? context))
:msg "prevent a card from being exposed"
:async true
:effect (req (prevent-expose state side eid card))}}]
:derezzed-events [{:event :expose-interrupt
:async true
:effect (req (let [etarget target]
:effect (req (let [ctx context]
(continue-ability
state side
{:optional
{:req (req (not (rezzed? card)))
:player :corp
:prompt (msg "The Runner is about to expose " (:title etarget) ". Rez Zaibatsu Loyalty?")
:prompt (msg "The Runner is about to expose " (enumerate-str (map #(card-str state % {:visible true}) (:cards ctx))) ". Rez Zaibatsu Loyalty?")
:yes-ability {:async true
:effect (effect (rez eid card))}}}
card nil)))}]
:abilities [{:msg "prevent 1 card from being exposed"
:cost [(->c :credit 1)]
:effect (effect (expose-prevent 1))}
{:msg "prevent 1 card from being exposed"
:label "Prevent 1 card from being exposed"
:cost [(->c :trash-can)]
:effect (effect (expose-prevent 1))}]})
card nil)))}]})

(defcard "Zealous Judge"
{:rez-req (req tagged)
Expand Down
Loading