diff --git a/src/clj/game/core/commands.clj b/src/clj/game/core/commands.clj index 2047492446..9ea087fed1 100644 --- a/src/clj/game/core/commands.clj +++ b/src/clj/game/core/commands.clj @@ -37,7 +37,9 @@ [game.macros :refer [continue-ability effect msg req wait-for]] [game.utils :refer [dissoc-in enumerate-str quantify safe-split same-card? same-side? server-card string->num]] - [jinteki.utils :refer [str->int]])) + [jinteki.utils :refer [other-side str->int]])) + +(defmulti lobby-command :command) (defn- constrain-value "Constrain value to [min-value max-value]" @@ -413,6 +415,28 @@ :effect (effect (trash eid target {:unpreventable true}))} nil nil))) +(defn command-swap-sides + [state side] + (swap! state dissoc-in [side :command-info :ignore-swap-sides]) + (if (get-in @state [(other-side side) :command-info :ignore-swap-sides]) + (toast state side "your opponent has indicated that they do not wish to swap sides") + (resolve-ability + state (other-side side) + {:prompt "Your opponent wishes to swap sides" + :waiting-prompt true + :choices ["Accept" "Decline" "Don't ask me again"] + :effect (req (cond + (= target "Decline") + (toast state (other-side side) "your opponent does not wish to swap sides at this time") + (= target "Don't ask me again") + (do (toast state (other-side side) "your opponent does not wish to swap sides") + (swap! state assoc-in [side :command-info :ignore-swap-sides] true)) + (= target "Accept") + (do (system-msg state side "accepts the request to swap sides. Players swap sides") + (lobby-command {:command :swap-sides + :gameid (:gameid @state)}))))} + nil nil))) + (defn parse-command [state text] (let [[command & args] (safe-split text #" ") @@ -566,6 +590,7 @@ (not (ice? c))))} :effect (effect (swap-installed (first targets) (second targets)))} (make-card {:title "/swap-installed command"}) nil)) + "/swap-sides" #(command-swap-sides %1 %2) "/tag" #(swap! %1 assoc-in [%2 :tag :base] (constrain-value value 0 1000)) "/take-core" #(when (= %2 :runner) (damage %1 %2 (make-eid %1) :brain (constrain-value value 0 1000) {:card (make-card {:title "/damage command" :side %2})})) diff --git a/src/clj/game/core/prompts.clj b/src/clj/game/core/prompts.clj index 64b5614989..a8740bc099 100644 --- a/src/clj/game/core/prompts.clj +++ b/src/clj/game/core/prompts.clj @@ -49,7 +49,7 @@ {:eid (select-keys eid [:eid]) :card card :prompt-type :waiting - :msg (str "Waiting for " + :msg (str "Waiting for " (if (true? waiting-prompt) (str (side-str side) " to make a decision") waiting-prompt))})) diff --git a/src/clj/web/game.clj b/src/clj/web/game.clj index fcc805c6fb..4f9501be35 100644 --- a/src/clj/web/game.clj +++ b/src/clj/web/game.clj @@ -5,7 +5,7 @@ [clojure.stacktrace :as stacktrace] [clojure.string :as str] [cond-plus.core :refer [cond+]] - [game.core.commands :refer [parse-command]] + [game.core.commands :as commands :refer [parse-command]] [game.core.diffs :as diffs] [game.core.say :refer [make-system-message]] [game.core.set-up :refer [init-game]] @@ -418,3 +418,42 @@ (app-state/deregister-user! uid) (when ?reply-fn (?reply-fn true)) (lobby/log-delay! timestamp id))) + +(defn switch-side + "Returns a new player map with the player's :side set to a new side" + [player] + (if (= "Corp" (get-in player [:side])) + (assoc player :side "Runner") + (assoc player :side "Corp"))) + +(defn handle-swap-sides-in-prog [lobbies gameid] + (if-let [lobby (get lobbies gameid)] + (do + (-> lobby + ;; note - original-players needs to be updated so that you rejoin the game + ;; on the correct side if you leave/rejoin + (update :original-players #(mapv switch-side %)) + (update :players #(mapv switch-side %)) + (->> (assoc lobbies gameid)))) + lobbies)) + +(defn switch-side-for-lobby + [gameid] + (let [{:keys [state] :as lobby} (app-state/get-lobby gameid) + old-runner (get-in @state [:runner :user]) + old-runner-options (get-in @state [:runner :options])] + (swap! state assoc-in [:runner :user] (get-in @state [:corp :user])) + (swap! state assoc-in [:runner :options] (get-in @state [:corp :options])) + (swap! state assoc-in [:corp :user] old-runner) + (swap! state assoc-in [:corp :options] old-runner-options) + (lobby/lobby-thread + (let [new-app-state (swap! app-state/app-state + update :lobbies + #(-> % + (handle-swap-sides-in-prog gameid))) + lobby? (get-in new-app-state [:lobbies gameid])] + (lobby/send-lobby-state lobby?) + (lobby/broadcast-lobby-list))))) + +(defmethod commands/lobby-command :swap-sides [{:keys [gameid] :as args}] + (switch-side-for-lobby gameid)) diff --git a/src/cljc/jinteki/utils.cljc b/src/cljc/jinteki/utils.cljc index 9f97faad14..492601cb0e 100644 --- a/src/cljc/jinteki/utils.cljc +++ b/src/cljc/jinteki/utils.cljc @@ -288,6 +288,9 @@ {:name "/swap-installed" :usage "/swap-installed" :help "Swap the position of two installed non-ice (Corp only)"} + {:name "/swap-sides" + :usage "/swap-sides" + :help "Request to swap sides with your opponent"} {:name "/tag" :has-args :required :usage "/tag n" diff --git a/src/cljs/nr/gameboard/board.cljs b/src/cljs/nr/gameboard/board.cljs index 35f7fe85e0..96d5abfbbc 100644 --- a/src/cljs/nr/gameboard/board.cljs +++ b/src/cljs/nr/gameboard/board.cljs @@ -1869,8 +1869,7 @@ [:div.button-pane {:on-mouse-over #(card-preview-mouse-over % zoom-channel) :on-mouse-out #(card-preview-mouse-out % zoom-channel)} (cond - (and @prompt-state - (not= "run" @prompt-type)) + (and @prompt-state (not= "run" (get-in @prompt-state [:prompt-type]))) [prompt-div me @prompt-state] (or @run @encounters)