Skip to content

Commit

Permalink
Merge pull request #7826 from NBKelly/fix-install-and-discard-bad-beh…
Browse files Browse the repository at this point in the history
…aviour

Fix install and discard bad behaviour
  • Loading branch information
NoahTheDuke authored Oct 29, 2024
2 parents 3540203 + 7e4b402 commit eb00a55
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 7 deletions.
2 changes: 2 additions & 0 deletions src/clj/game/core/actions.clj
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,10 @@
from-str (card-str state c)
s (if (#{"HQ" "R&D" "Archives"} server) :corp :runner)]
;; allow moving from play-area always, otherwise only when same side, and to valid zone
;; here!
(when (and (not= src server)
(same-side? s (:side card))
(not= :select (get-in @state [side :prompt-state :prompt-type]))
(or (= last-zone :play-area)
(same-side? side (:side card))))
(let [move-card-to (partial move state s c)
Expand Down
7 changes: 6 additions & 1 deletion src/clj/game/core/hosting.clj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
[game.core.initializing :refer [card-init]]
[game.core.memory :refer [init-mu-cost]]
[game.core.update :refer [update! update-hosted!]]
[game.utils :refer [remove-once]]))
[game.utils :refer [remove-once same-card?]]))

(defn remove-from-host
"Removes a card from its host."
Expand All @@ -18,6 +18,11 @@
(when-let [hosted-lost (:hosted-lost (card-def host-card))]
(hosted-lost state side (make-eid state) (get-card state host-card) (dissoc card :host)))))

(defn has-ancestor?
"Determines if the target is an ancestor of the given card (a card is its own ancestor)"
[card target]
(when (and card target) (or (same-card? card target) (has-ancestor? (:host card) target))))

(defn host
"Host the target onto the card."
([state side card target] (host state side card target nil))
Expand Down
21 changes: 15 additions & 6 deletions src/clj/game/core/installing.clj
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
[game.core.engine :refer [checkpoint register-pending-event pay queue-event register-events trigger-event-simult unregister-events]]
[game.core.effects :refer [is-disabled-reg? register-static-abilities unregister-static-abilities update-disabled-cards]]
[game.core.flags :refer [turn-flag? zone-locked?]]
[game.core.hosting :refer [host]]
[game.core.hosting :refer [has-ancestor? host]]
[game.core.ice :refer [update-breaker-strength]]
[game.core.initializing :refer [ability-init card-init corp-ability-init runner-ability-init]]
[game.core.memory :refer [expected-mu sufficient-mu? update-mu]]
[game.core.memory :refer [available-mu expected-mu sufficient-mu? update-mu]]
[game.core.moving :refer [move trash trash-cards]]
[game.core.payment :refer [build-spend-msg can-pay? merge-costs ->c value]]
[game.core.props :refer [add-prop]]
Expand Down Expand Up @@ -519,8 +519,9 @@
true))))

(defn runner-install-pay
[state side eid card {:keys [no-mu facedown] :as args}]
(let [costs (runner-install-cost state side (assoc card :facedown facedown) (dissoc args :cached-costs))]
[state side eid card {:keys [no-mu facedown host-card] :as args}]
(let [costs (runner-install-cost state side (assoc card :facedown facedown) (dissoc args :cached-costs))
available-mem (available-mu state)]
(if-not (runner-can-pay-and-install? state side eid card (assoc args :cached-costs costs))
(effect-completed state side eid)
(if (and (program? card)
Expand All @@ -529,14 +530,22 @@
(continue-ability
state side
{:prompt (format "Insufficient MU to install %s. Trash installed programs?" (:title card))
:choices {:max (count (all-installed-runner-type state :program))
:choices {:max (count (filter #(and (program? %) (not (has-ancestor? % host-card))) (all-installed state :runner)))
:card #(and (installed? %)
;; note: rules team says we can't create illegal gamestates by
;; trashing a host when installing a card. If they ever change it,
;; then be aware that the engine will hang when trying to do this
;; without these guards. - nbkelly, oct 2024
(not (has-ancestor? % host-card))
(program? %))}
:async true
:effect (req (wait-for (trash-cards state side (make-eid state eid) targets {:unpreventable true})
(update-mu state)
(runner-install-pay state side eid card args)))
:cancel-effect (effect (effect-completed eid))}
:cancel-effect (req (update-mu state)
(if (= available-mem (available-mu state))
(effect-completed state side eid)
(runner-install-pay state side eid card args)))}
card nil)
(let [played-card (move state side (assoc card :facedown facedown) :play-area {:suppress-event true})]
(wait-for (pay state side (make-eid state eid) card costs)
Expand Down

0 comments on commit eb00a55

Please sign in to comment.