Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Recurring and Placed Credits #4262

Merged
merged 44 commits into from
Jun 10, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
f83bc2b
First approach to implementing a credits prompt
lostgeek May 30, 2019
14baef0
Change to make-eid to reuse fields from old eid
lostgeek May 30, 2019
935a996
pay-credits working with recurring credits
lostgeek May 30, 2019
ab2e911
Structure of :interactions :pay-credits changed
lostgeek Jun 1, 2019
7439330
pick-credit-providing-cards now calling provider-func only once
lostgeek Jun 1, 2019
d96b699
Comparing :cid instead of whole cards
lostgeek Jun 1, 2019
5846ee4
Fixed order of args on pick-virus-counters-to-spend
lostgeek Jun 1, 2019
cd43714
pay-credits now works on paid-abilities
lostgeek Jun 1, 2019
7f95a68
After using pay-credits, rest will now be paid from credit pool
lostgeek Jun 1, 2019
e761a42
I accidentally a verb
lostgeek Jun 1, 2019
5be62e7
Added pay-credits prompts to a bunch of cards
lostgeek Jun 1, 2019
71711f4
pay-credits on playing Events (and Operations)
lostgeek Jun 1, 2019
a17bd01
Reverted eid change in move
lostgeek Jun 1, 2019
c7fa595
Added pay-credits for removing tags
lostgeek Jun 1, 2019
6d95403
Trim whitespace on remove tag message
lostgeek Jun 1, 2019
8db6dd5
Added effect-completed for remove-tag
lostgeek Jun 2, 2019
32c1ed3
Refactor and speed up pick-credit-providing-cards
NoahTheDuke Jun 3, 2019
7b6f089
Merge pull request #1 from NoahTheDuke/lostgeek-pay-credits-prompt
lostgeek Jun 4, 2019
9650c9d
Implemented Noahs comments
lostgeek Jun 4, 2019
45c4381
Added pay-credits prompt to rezzing cards
lostgeek Jun 4, 2019
6fef990
Swapped The Root with Off the Grid to avoid pay-credits prompt
lostgeek Jun 4, 2019
027e3ce
Removed test-refresh...
lostgeek Jun 4, 2019
c48cf98
Added pay-credits prompt to installing corp cards
lostgeek Jun 4, 2019
4bce666
Added pay-credits prompt to advancing cards
lostgeek Jun 5, 2019
2084354
Added pay-credits to Trickster Taka and Cold Read
lostgeek Jun 5, 2019
2abc341
Implemented pay-credits prompt for Flame-out
lostgeek Jun 5, 2019
3e1acd0
Removed unnecessary do
lostgeek Jun 5, 2019
4778e80
Implement pay-credits prompts for trashing accessed cards
NoahTheDuke Jun 6, 2019
534ad1c
Implement pay-credit prompts for traces
NoahTheDuke Jun 6, 2019
ef4a8da
Added pay-credits prompt to Patchwork. Reworked :custom functions
lostgeek Jun 8, 2019
4256ba1
Merge branch 'pay-credits-prompt' into lostgeek-pay-credits-prompt
lostgeek Jun 8, 2019
5592046
Merge pull request #2 from NoahTheDuke/lostgeek-pay-credits-prompt
lostgeek Jun 8, 2019
2a48ca4
Fixed bugs introduced in the merge...
lostgeek Jun 8, 2019
02a8dab
play-ability now works correctly with can-pay?
lostgeek Jun 8, 2019
3889041
Tests for pay-credits prompts on installing cards as Runner and Steal…
lostgeek Jun 8, 2019
231a201
Tests for pay-credits prompts on paid abilities on icebreakers and cr…
lostgeek Jun 9, 2019
2385781
Tests for pay-credits prompt on playing events and removing tags
lostgeek Jun 9, 2019
d9e0005
Tests for pay-credits prompt on rezzing cards. Fixed
lostgeek Jun 9, 2019
51637cd
Fixed previous tests that used `changes-credits`
lostgeek Jun 9, 2019
5777e51
Tests for pay-credits prompts on installing and advancing Corp cards
lostgeek Jun 9, 2019
608e874
Fixed Thunder Art Gallery + Sahasrara + pay-credits interaction
lostgeek Jun 9, 2019
5ed94de
Clean up custom pay-credit effects, cold read
NoahTheDuke Jun 9, 2019
d06167a
Merge pull request #3 from NoahTheDuke/lostgeek-pay-credits-prompt
lostgeek Jun 9, 2019
23a91b5
Net Mercur now shows pay-credits prompt during runs and traces
lostgeek Jun 9, 2019
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
36 changes: 36 additions & 0 deletions src/clj/game/cards.clj
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,42 @@
(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] (pick-credit-providing-cards (hash-map) 0 nil provider-func))
([target-count provider-func] (pick-credit-providing-cards (hash-map) 0 target-count provider-func))
([selected-cards counter-count target-count provider-func]
lostgeek marked this conversation as resolved.
Show resolved Hide resolved
{:async true
:prompt (str "Select a card with recurring credits ("
counter-count (when (and target-count (pos? target-count))
(str " of " target-count))
" credits)")
:choices {:req #(and (< 0 (get-counters % :recurring)) (.contains (provider-func) %))}
lostgeek marked this conversation as resolved.
Show resolved Hide resolved
:effect (req (add-counter state :runner target :recurring -1)
lostgeek marked this conversation as resolved.
Show resolved Hide resolved
(let [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 (inc counter-count)]
(if (or (not target-count) (< counter-count target-count))
(continue-ability state side
(pick-credit-providing-cards selected-cards counter-count target-count provider-func)
card nil)
(let [msg (join ", " (map #(let [{:keys [card number]} %
title (:title card)]
(str (quantify number "recurring credit") " from " title))
(vals selected-cards)))]
(effect-completed state side (make-result eid {:number counter-count :msg msg}))))))
:cancel-effect (if target-count
(req (doseq [{:keys [card number]} (vals selected-cards)]
(add-counter state :runner (get-card state card) :recurring number))
(effect-completed state side (make-result eid :cancel)))
(req (let [msg (join ", " (map #(let [{:keys [card number]} %
title (:title card)]
(str (quantify number "recurring credit") " from " title))
(vals selected-cards)))]
(effect-completed state side (make-result eid {:number counter-count :msg msg})))))}))

(defn never?
"Returns true if is argument is :never."
[x]
Expand Down
3 changes: 2 additions & 1 deletion src/clj/game/cards/programs.clj
Original file line number Diff line number Diff line change
Expand Up @@ -1970,7 +1970,8 @@
:msg "break 1 Code Gate or Barrier subroutine"}])

"Sahasrara"
{:recurring 2}
{:recurring 2
:interactions {:pay-credits (req (and (< 0 (get-counters card :recurring)) (program? target)))}}

"Saker"
(auto-icebreaker ["Barrier"]
Expand Down
3 changes: 2 additions & 1 deletion src/clj/game/core/actions.clj
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
(when-let [card (get-card state card)]
(case (:type card)
("Event" "Operation") (play-instant state side card {:extra-cost [:click 1]})
("Hardware" "Resource" "Program") (runner-install state side (make-eid state) card {:extra-cost [:click 1]})
("Hardware" "Resource" "Program") (runner-install state side (make-eid state {:source :action
:source-type :runner-install}) card {:extra-cost [:click 1]})
("ICE" "Upgrade" "Asset" "Agenda") (corp-install state side card server {:extra-cost [:click 1] :action :corp-click-install}))
(trigger-event state side :play card)))

Expand Down
28 changes: 25 additions & 3 deletions src/clj/game/core/costs.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

(declare forfeit prompt! toast damage mill installed? is-type? is-scored? system-msg
facedown? make-result unknown->kw discard-from-hand card-str trash trash-cards
complete-with-result all-installed-runner-type)
complete-with-result all-installed-runner-type pick-credit-providing-cards)

(defn deduct
"Deduct the value from the player's attribute."
Expand Down Expand Up @@ -264,6 +264,25 @@
(str "trashes " (quantify amount "card") " randomly from "
(if (= :corp side) "HQ" "the grip"))))))

(defn pay-credits
[state side eid card amount]
(case (:source-type eid)
:runner-install
(letfn [(provider-func []
(filter #((or (-> % card-def :interactions :pay-credits) (req false)) state side eid % [card]) (all-active-installed state :runner)))]
lostgeek marked this conversation as resolved.
Show resolved Hide resolved
(if (< 0 (count (provider-func)))
(wait-for (resolve-ability state side (pick-credit-providing-cards amount provider-func) card nil)
(swap! state update-in [:stats side :spent :credit] (fnil + 0) amount)
(complete-with-result state side eid (:msg async-result)))
(do
(swap! state update-in [:stats side :spent :credit] (fnil + 0) amount)
(complete-with-result state side eid (deduct state side [:credit amount])))))

;; Default
(do
(swap! state update-in [:stats side :spent :credit] (fnil + 0) amount)
(complete-with-result state side eid (deduct state side [:credit amount])))))

(defn- cost-handler
"Calls the relevant function for a cost depending on the keyword passed in"
([state side card action costs cost] (cost-handler state side (make-eid state) card action costs cost))
Expand Down Expand Up @@ -309,6 +328,9 @@
;; Shuffle installed runner cards into the stack (eg Degree Mill)
:shuffle-installed-to-stack (pay-shuffle-installed-to-stack state side eid card amount)

;; Pay credits
:credit (pay-credits state side eid card amount)

;; Else
(do
(swap! state update-in [:stats side :spent cost-type] (fnil + 0) amount)
Expand All @@ -332,7 +354,7 @@
[state side eid costs card action msgs]
(if (empty? costs)
(effect-completed state side (make-result eid msgs))
(wait-for (cost-handler state side card action costs (first costs))
(wait-for (cost-handler state side (make-eid state eid) card action costs (first costs))
(pay-sync-next state side eid (next costs) card action (conj msgs async-result)))))

(defn pay-sync
Expand All @@ -341,7 +363,7 @@
(let [raw-costs (not-empty (remove map? args))
action (not-empty (filter map? args))]
(if-let [costs (apply can-pay? state side (:title card) raw-costs)]
(wait-for (pay-sync-next state side costs card action [])
(wait-for (pay-sync-next state side (make-eid state eid) costs card action [])
(complete-with-result state side eid (->> async-result
(filter some?)
(join " and "))))
Expand Down
75 changes: 39 additions & 36 deletions src/clj/game/core/installing.clj
Original file line number Diff line number Diff line change
Expand Up @@ -406,8 +406,10 @@
(defn runner-install
"Installs specified runner card if able
Params include extra-cost, no-cost, host-card, facedown and custom-message."
([state side card] (runner-install state side (make-eid state) card nil))
([state side card params] (runner-install state side (make-eid state) card params))
([state side card] (runner-install state side (make-eid state {:source nil
:source-type :runner-install}) card nil))
([state side card params] (runner-install state side (make-eid state {:source nil
:source-type :runner-install}) card params))
([state side eid card {:keys [host-card facedown no-mu no-msg] :as params}]
(if (and (empty? (get-in @state [side :locked (-> card :zone first)]))
(not (install-locked? state :runner)))
Expand All @@ -421,37 +423,38 @@
(wait-for (trigger-event-simult state side :pre-install nil card facedown)
(let [cost (runner-get-cost state side card params)]
(if (runner-can-install? state side card facedown)
(if-let [cost-str (pay state side card cost)]
(let [c (if host-card
(host state side host-card card)
(move state side card
[:rig (if facedown :facedown (to-keyword (:type card)))]))
c (assoc c :installed :this-turn :new true)
installed-card (if facedown
(do (update! state side c)
(find-latest state c))
(card-init state side c {:resolve-effect false
:init-data true}))]
(when-not no-msg
(runner-install-message state side (:title card) cost-str params))

(play-sfx state side "install-runner")
(when (and (is-type? card "Program")
(not facedown)
(not no-mu))
;; Use up mu from program not installed facedown
(use-mu state (:memoryunits card))
(toast-check-mu state))
(handle-virus-counter-flag state side installed-card)
(when (and (not facedown) (is-type? card "Resource"))
(swap! state assoc-in [:runner :register :installed-resource] true))
(when (and (not facedown) (has-subtype? c "Icebreaker"))
(update-breaker-strength state side c))
(trigger-event-simult state side eid :runner-install
(when-not facedown
{:card-ability (card-as-handler installed-card)})
installed-card))
(effect-completed state side eid))
(effect-completed state side eid)))
(clear-install-cost-bonus state side)))
(effect-completed state side eid))))
(wait-for (pay-sync state side (make-eid state eid) card cost)
(if-let [cost-str async-result]
(let [c (if host-card
(host state side host-card card)
(move state side card
[:rig (if facedown :facedown (to-keyword (:type card)))]))
c (assoc c :installed :this-turn :new true)
installed-card (if facedown
(do (update! state side c)
(find-latest state c))
(card-init state side c {:resolve-effect false
:init-data true}))]
(when-not no-msg
(runner-install-message state side (:title card) cost-str params))

(play-sfx state side "install-runner")
(when (and (is-type? card "Program")
(not facedown)
(not no-mu))
;; Use up mu from program not installed facedown
(use-mu state (:memoryunits card))
(toast-check-mu state))
(handle-virus-counter-flag state side installed-card)
(when (and (not facedown) (is-type? card "Resource"))
(swap! state assoc-in [:runner :register :installed-resource] true))
(when (and (not facedown) (has-subtype? c "Icebreaker"))
(update-breaker-strength state side c))
(trigger-event-simult state side eid :runner-install
(when-not facedown
{:card-ability (card-as-handler installed-card)})
installed-card))
(effect-completed state side eid)))
(effect-completed state side eid)))
(clear-install-cost-bonus state side)))
(effect-completed state side eid))))