Skip to content

Commit

Permalink
Merge pull request #4262 from lostgeek/pay-credits-prompt
Browse files Browse the repository at this point in the history
Implement Recurring and Placed Credits
  • Loading branch information
NoahTheDuke authored Jun 10, 2019
2 parents 99108f3 + 23a91b5 commit 9125ac8
Show file tree
Hide file tree
Showing 31 changed files with 1,557 additions and 559 deletions.
84 changes: 80 additions & 4 deletions src/clj/game/cards.clj
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,9 @@
The ability triggered returns either {:number n :msg msg} on completed effect, or :cancel on a cancel.
n is the number of virus counters selected, msg is the msg string of all the cards and the virus counters taken from each.
If called with no arguments, allows user to select as many counters as they like until 'Cancel' is pressed."
([] (pick-virus-counters-to-spend (hash-map) 0 nil))
([target-count] (pick-virus-counters-to-spend (hash-map) 0 target-count))
([selected-cards counter-count target-count]
([] (pick-virus-counters-to-spend nil (hash-map) 0))
([target-count] (pick-virus-counters-to-spend target-count (hash-map) 0 ))
([target-count selected-cards counter-count]
{:async true
:prompt (str "Select a card with virus counters ("
counter-count (when (and target-count (pos? target-count))
Expand All @@ -190,7 +190,7 @@
counter-count (inc counter-count)]
(if (or (not target-count) (< counter-count target-count))
(continue-ability state side
(pick-virus-counters-to-spend selected-cards counter-count target-count)
(pick-virus-counters-to-spend target-count selected-cards counter-count)
card nil)
(let [msg (join ", " (map #(let [{:keys [card number]} %
title (:title card)]
Expand All @@ -207,6 +207,82 @@
(vals selected-cards)))]
(effect-completed state side (make-result eid {:number counter-count :msg msg})))))}))

(defn pick-credit-providing-cards
"Similar to pick-virus-counters-to-spend. Works on :recurring and normal credits."
([provider-func outereid] (pick-credit-providing-cards provider-func outereid nil (hash-map) 0))
([provider-func outereid target-count] (pick-credit-providing-cards provider-func outereid target-count (hash-map) 0))
([provider-func outereid target-count selected-cards counter-count]
(let [pay-rest
(req (if (<= (- target-count counter-count) (get-in @state [side :credit]))
(let [remainder (- target-count counter-count)
remainder-str (when (pos? remainder)
(str remainder " [Credits]"))
card-strs (when (pos? (count selected-cards))
(str (join ", " (map #(let [{:keys [card number]} %
title (:title card)]
(str number " [Credits] from " title))
(vals selected-cards)))))
message (str card-strs
(when (and card-strs remainder-str)
" and ")
remainder-str
(when (and card-strs remainder-str)
" from their credit pool"))]
(deduct state side [:credit remainder])
(swap! state update-in [:stats side :spent :credit] (fnil + 0) target-count)
(when-let [card (some #(when (has-subtype? (:card %) "Stealth") (:card %)) (vals selected-cards))]
(trigger-event state side :spent-stealth-credit card))
(effect-completed state side (make-result eid {:number counter-count :msg message})))
(continue-ability
state side
(pick-credit-providing-cards provider-func eid target-count selected-cards counter-count)
card nil)))]
(let [provider-cards (provider-func)]
(if (or (not (pos? target-count)) ; there is a limit
(>= counter-count target-count) ; paid everything
(zero? (count provider-cards))) ; no more additional credit sources found
{:async true
:effect pay-rest}
{:async true
:prompt (str "Select a credit providing card ("
counter-count (when (and target-count (pos? target-count))
(str " of " target-count))
" credits)")
:choices {:req #(in-coll? (map :cid provider-cards) (:cid %))}
:effect (req (let [pay-credits-type (-> target card-def :interactions :pay-credits :type)
pay-credits-custom (when (= :custom pay-credits-type)
(-> target card-def :interactions :pay-credits :custom))
custom-ability (when (= :custom pay-credits-type)
{:async true :effect pay-credits-custom})
gained-credits (case pay-credits-type
:recurring
(do (add-prop state side target :rec-counter -1) 1)
:credit
(do (add-counter state side target :credit -1) 1)
; Custom credits will be handled separately later
0)
selected-cards (update selected-cards (:cid target)
;; Store card reference and number of counters picked
;; Overwrite card reference each time
#(assoc % :card target :number (inc (:number % 0))))
counter-count (+ counter-count gained-credits)]
(if (= :custom pay-credits-type)
; custom functions should be a 5-arg fn that returns an ability that provides the number of credits as async-result
(let [neweid (make-eid state outereid)
providing-card target]
(wait-for (resolve-ability state side neweid custom-ability providing-card [card])
(continue-ability state side
(pick-credit-providing-cards provider-func eid target-count
(update selected-cards (:cid providing-card)
;; correct credit count
#(assoc % :card target :number (+ (:number % 0) (dec async-result))))
(+ counter-count async-result))
card targets)))
(continue-ability state side
(pick-credit-providing-cards provider-func eid target-count selected-cards counter-count)
card nil))))
:cancel-effect pay-rest})))))

(defn never?
"Returns true if is argument is :never."
[x]
Expand Down
23 changes: 18 additions & 5 deletions src/clj/game/cards/assets.clj
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,10 @@
:effect (effect (damage eid :meat 2 {:card card}))}}}

"Dedicated Server"
{:recurring 2}
{:recurring 2
:interactions {:pay-credits {:req (req (and (= :rez (:source-type eid))
(ice? target)))
:type :recurring}}}

"Director Haas"
{:in-play [:click-per-turn 1]
Expand Down Expand Up @@ -1168,7 +1171,9 @@
:effect (effect (damage :corp eid :meat 1 {:card card}))}}}

"Mumba Temple"
{:recurring 2}
{:recurring 2
:interactions {:pay-credits {:req (req (= :rez (:source-type eid)))
:type :recurring}}}

"Mumbad City Hall"
{:abilities [{:label "Search R&D for an Alliance card"
Expand Down Expand Up @@ -1290,7 +1295,9 @@

"Net Police"
{:recurring (effect (set-prop card :rec-counter (:link runner)))
:effect (effect (set-prop card :rec-counter (:link runner)))}
:effect (effect (set-prop card :rec-counter (:link runner)))
:interactions {:pay-credits {:req (req (= :trace (:source-type eid)))
:type :recurring}}}

"Neurostasis"
(advance-ambush 3 {:req (req (pos? (get-counters (get-card state card) :advancement)))
Expand Down Expand Up @@ -1461,7 +1468,9 @@
(continue-ability state side (pdhelper agendas 0) card nil)))}}})

"Primary Transmission Dish"
{:recurring 3}
{:recurring 3
:interactions {:pay-credits {:req (req (= :trace (:source-type eid)))
:type :recurring}}}

"Private Contracts"
{:effect (effect (add-counter card :credit 14))
Expand Down Expand Up @@ -2014,7 +2023,11 @@
:leave-play (req (swap! state assoc-in [:runner :register :cannot-play-current] false))}

"The Root"
{:recurring 3}
{:recurring 3
:interactions {:pay-credits {:req (req (or (= :advance (:source-type eid))
(= :corp-install (:source-type eid))
(= :rez (:source-type eid))))
:type :recurring}}}

"Thomas Haas"
{:advanceable :always
Expand Down
33 changes: 21 additions & 12 deletions src/clj/game/cards/events.clj
Original file line number Diff line number Diff line change
Expand Up @@ -317,11 +317,14 @@
:choices (req runnable-servers)
:effect (req (let [c (move state side (assoc card :zone '(:discard)) :play-area {:force true})]
(card-init state side c {:resolve-effect false})
(update! state side (assoc (get-card state c) :cold-read-active true))
(make-run state side (make-eid state) target
{:end-run {:async true
:effect (effect (trash c)
(continue-ability end-effect card nil))}}
c)))})
:effect (effect (trash card)
(continue-ability end-effect nil nil))}}
(assoc c :cold-read-active true))))
:interactions {:pay-credits {:req (req (:cold-read-active card))
:type :recurring}}})

"Compile"
(letfn [(compile-fn [where]
Expand Down Expand Up @@ -390,7 +393,7 @@
:effect (req (let [c target
cost (:cost c)
title (:title c)]
(if (can-pay? state :corp nil :credit cost)
(if (can-pay? state :corp eid card nil :credit cost)
(do (show-wait-prompt state :runner "Corp to decide whether or not to prevent the trash")
(continue-ability
state :corp
Expand Down Expand Up @@ -930,7 +933,7 @@
state side
{:prompt "Install a program?"
:choices (conj (vec (sort-by :title (filter #(and (is-type? % "Program")
(can-pay? state side nil
(can-pay? state side eid card nil
(modified-install-cost state side % [:credit -5])))
topten))) "No install")
:async true
Expand Down Expand Up @@ -1541,7 +1544,7 @@
{:player :corp
:async true
:prompt "Pay 5 [Credits] or take 1 Bad Publicity?"
:choices (concat (when (can-pay? state :corp "Mining Accident" :credit 5)
:choices (concat (when (can-pay? state :corp eid card "Mining Accident" :credit 5)
["Pay 5 [Credits]"])
["Take 1 Bad Publicity"])
:effect (req (clear-wait-prompt state :runner)
Expand Down Expand Up @@ -1588,7 +1591,9 @@
:effect (effect (install-cost-bonus [:credit -3]) (runner-install target))}

"Net Celebrity"
{:recurring 1}
{:recurring 1
:interactions {:pay-credits {:req (req (:run @state))
:type :recurring}}}

"Networking"
{:msg "remove 1 tag"
Expand Down Expand Up @@ -1893,17 +1898,17 @@
(installed? %))}
:effect (req (move state side target :hand)
(effect-completed state side (make-result eid (:cost target))))}
put-down (fn [st si bonus]
put-down (fn [st si eid card bonus]
{:async true
:prompt "Select a program or piece of hardware to install"
:choices {:req #(and (valid-target? %)
(can-pay? st si nil (modified-install-cost st si % [:credit (- bonus)])))}
(can-pay? st si eid card nil (modified-install-cost st si % [:credit (- bonus)])))}
:effect (effect (install-cost-bonus [:credit (- bonus)])
(runner-install eid target nil))})]
{:req (req (some valid-target? (all-installed state :runner)))
:effect (req (wait-for (resolve-ability state side pick-up card nil)
(continue-ability state side
(put-down state side async-result)
(put-down state side eid card async-result)
card nil)))})

"Reshape"
Expand Down Expand Up @@ -2037,15 +2042,19 @@
{:prompt "Select an installed program to trash"
:choices {:req #(and (is-type? % "Program")
(installed? %))}
:effect (req (let [trashed target tcost (- (:cost trashed)) st state si side]
:effect (req (let [trashed target tcost (- (:cost trashed))
st state
si side
e eid
c card]
(trash state side trashed)
(resolve-ability
state side
{:prompt "Select a program to install from your Grip or Heap"
:show-discard true
:choices {:req #(and (is-type? % "Program")
(#{[:hand] [:discard]} (:zone %))
(can-pay? st si nil (modified-install-cost st si % [:credit tcost])))}
(can-pay? st si e c nil (modified-install-cost st si % [:credit tcost])))}
:effect (effect (install-cost-bonus [:credit (- (:cost trashed))])
(runner-install target))
:msg (msg "trash " (:title trashed) " and install " (:title target))} card nil)))}
Expand Down
Loading

0 comments on commit 9125ac8

Please sign in to comment.