From 2c9f08fce443d57a70e886242ec391d89e450a7b Mon Sep 17 00:00:00 2001
From: Benjamin Auder <benjamin.auder@somewhere>
Date: Sat, 20 Mar 2021 18:00:30 +0100
Subject: [PATCH] Teleport2 (no king repositioning) + do not relay some
 challenges

---
 client/src/translations/en.js                 |  3 +-
 client/src/translations/es.js                 |  3 +-
 client/src/translations/fr.js                 |  3 +-
 .../rules/{Teleport => Teleport1}/en.pug      |  2 +
 .../rules/{Teleport => Teleport1}/es.pug      |  3 +-
 .../rules/{Teleport => Teleport1}/fr.pug      |  2 +
 .../src/translations/rules/Teleport2/en.pug   |  7 +++
 .../src/translations/rules/Teleport2/es.pug   |  8 +++
 .../src/translations/rules/Teleport2/fr.pug   |  8 +++
 client/src/translations/variants/en.pug       |  3 +-
 client/src/translations/variants/es.pug       |  3 +-
 client/src/translations/variants/fr.pug       |  3 +-
 .../variants/{Teleport.js => Teleport1.js}    |  2 +-
 client/src/variants/Teleport2.js              | 57 +++++++++++++++++++
 server/db/populate.sql                        |  3 +-
 server/sockets.js                             | 17 ++++--
 16 files changed, 114 insertions(+), 13 deletions(-)
 rename client/src/translations/rules/{Teleport => Teleport1}/en.pug (99%)
 rename client/src/translations/rules/{Teleport => Teleport1}/es.pug (94%)
 rename client/src/translations/rules/{Teleport => Teleport1}/fr.pug (99%)
 create mode 100644 client/src/translations/rules/Teleport2/en.pug
 create mode 100644 client/src/translations/rules/Teleport2/es.pug
 create mode 100644 client/src/translations/rules/Teleport2/fr.pug
 rename client/src/variants/{Teleport.js => Teleport1.js} (99%)
 create mode 100644 client/src/variants/Teleport2.js

diff --git a/client/src/translations/en.js b/client/src/translations/en.js
index e3f361c7..e93b434b 100644
--- a/client/src/translations/en.js
+++ b/client/src/translations/en.js
@@ -299,7 +299,8 @@ export const translations = {
   "Reach the last rank (v2)": "Reach the last rank (v2)",
   "Rearrange enemy pieces": "Rearrange enemy pieces",
   "Replace pieces": "Replace pieces",
-  "Reposition pieces": "Reposition pieces",
+  "Reposition pieces (v1)": "Reposition pieces (v1)",
+  "Reposition pieces (v2)": "Reposition pieces (v2)",
   "Reuse pieces": "Reuse pieces",
   "Reverse captures": "Reverse captures",
   "Roll the dice": "Roll the dice",
diff --git a/client/src/translations/es.js b/client/src/translations/es.js
index 3869b5de..d776b26a 100644
--- a/client/src/translations/es.js
+++ b/client/src/translations/es.js
@@ -299,7 +299,8 @@ export const translations = {
   "Reach the last rank (v2)": "Llegar a la última fila (v2)",
   "Rearrange enemy pieces": "Reorganizar piezas opuestas",
   "Replace pieces": "Reemplazar piezas",
-  "Reposition pieces": "Reposicionar las piezas",
+  "Reposition pieces (v1)": "Reposicionar las piezas (v1)",
+  "Reposition pieces (v2)": "Reposicionar las piezas (v2)",
   "Reuse pieces": "Reutilizar piezas",
   "Reverse captures": "Capturas invertidas",
   "Roll the dice": "Tirar los dados",
diff --git a/client/src/translations/fr.js b/client/src/translations/fr.js
index e75273a5..4752d917 100644
--- a/client/src/translations/fr.js
+++ b/client/src/translations/fr.js
@@ -299,7 +299,8 @@ export const translations = {
   "Reach the last rank (v2)": "Atteignez la dernière rangée (v2)",
   "Rearrange enemy pieces": "Réorganisez les pièces adverses",
   "Replace pieces": "Remplacer les pièces",
-  "Reposition pieces": "Replacer les pièces",
+  "Reposition pieces (v1)": "Replacer les pièces (v1)",
+  "Reposition pieces (v2)": "Replacer les pièces (v2)",
   "Reuse pieces": "Réutiliser les pièces",
   "Reverse captures": "Captures inversées",
   "Roll the dice": "Lancez le dé",
diff --git a/client/src/translations/rules/Teleport/en.pug b/client/src/translations/rules/Teleport1/en.pug
similarity index 99%
rename from client/src/translations/rules/Teleport/en.pug
rename to client/src/translations/rules/Teleport1/en.pug
index 0d1442f0..a3fd07c3 100644
--- a/client/src/translations/rules/Teleport/en.pug
+++ b/client/src/translations/rules/Teleport1/en.pug
@@ -7,6 +7,8 @@ p.
   A king may remain under check while the move isn't complete.
   A repositioned piece can give checkmate.
   A pawn cannot be placed on the last rank.
+
+p.
   A king can reposition a piece or be repositioned,
   possibly to escape from a check.
 
diff --git a/client/src/translations/rules/Teleport/es.pug b/client/src/translations/rules/Teleport1/es.pug
similarity index 94%
rename from client/src/translations/rules/Teleport/es.pug
rename to client/src/translations/rules/Teleport1/es.pug
index 8b7f5a9a..e7671245 100644
--- a/client/src/translations/rules/Teleport/es.pug
+++ b/client/src/translations/rules/Teleport1/es.pug
@@ -8,7 +8,8 @@ p.
   Un rey puede quedarse en jaque durante esta acción.
   Una pieza movida en el tablero puede dar jaque mate.
   Un peón no se puede mover a la última fila.
-  Un rey puede moverse y ser movido, incluso para evitar jaques.
+
+p Un rey puede moverse y ser movido, incluso para evitar jaques.
 
 figure.diagram-container
   .diagram.diag12
diff --git a/client/src/translations/rules/Teleport/fr.pug b/client/src/translations/rules/Teleport1/fr.pug
similarity index 99%
rename from client/src/translations/rules/Teleport/fr.pug
rename to client/src/translations/rules/Teleport1/fr.pug
index 0d191e45..c1d09a77 100644
--- a/client/src/translations/rules/Teleport/fr.pug
+++ b/client/src/translations/rules/Teleport1/fr.pug
@@ -8,6 +8,8 @@ p.
   en échec durant cette action.
   Une pièce déplacée sur l'échiquier peut mater.
   Un pion ne peut pas être déplacé en dernière rangée.
+
+p.
   Un roi peut déplacer et être déplacé,
   y compris pour se soustraire à un échec.
 
diff --git a/client/src/translations/rules/Teleport2/en.pug b/client/src/translations/rules/Teleport2/en.pug
new file mode 100644
index 00000000..7f31849b
--- /dev/null
+++ b/client/src/translations/rules/Teleport2/en.pug
@@ -0,0 +1,7 @@
+p.boxed.
+  You can capture your pieces to teleport them instead of a regular move.
+
+p
+  a(href="/#/variants/Teleport1") Teleport1
+  | , but the king cannot be repositioned.
+  | This removes some unusual defensive options.
diff --git a/client/src/translations/rules/Teleport2/es.pug b/client/src/translations/rules/Teleport2/es.pug
new file mode 100644
index 00000000..cdad5ae9
--- /dev/null
+++ b/client/src/translations/rules/Teleport2/es.pug
@@ -0,0 +1,8 @@
+p.boxed.
+  Puedes capturar tus piezas para teletransportarlas en lugar de jugar
+  un movimiento normal.
+
+p
+  a(href="/#/variants/Teleport1") Teleport1
+  | , pero el rey no se puede reposicionar.
+  | Esto evita algunas posibilidades defensivas inusuales.
diff --git a/client/src/translations/rules/Teleport2/fr.pug b/client/src/translations/rules/Teleport2/fr.pug
new file mode 100644
index 00000000..4eb9ddc0
--- /dev/null
+++ b/client/src/translations/rules/Teleport2/fr.pug
@@ -0,0 +1,8 @@
+p.boxed.
+  Vous pouvez capturer vos pièces pour les téléporter au lieu de jouer
+  un coup normal.
+
+p
+  a(href="/#/variants/Teleport1") Teleport1
+  | , mais le roi ne peut pas être repositionné.
+  | Cela empêche quelques possibilités défensives inhabituelles.
diff --git a/client/src/translations/variants/en.pug b/client/src/translations/variants/en.pug
index 15a8aa5e..a6e5bd8d 100644
--- a/client/src/translations/variants/en.pug
+++ b/client/src/translations/variants/en.pug
@@ -324,7 +324,8 @@ p Pieces can be dropped on the board, either immediately or later in the game.
     "Rampage",
     "Recycle",
     "Shogun",
-    "Teleport"
+    "Teleport1",
+    "Teleport2"
   ]
 ul
   for v in varlist
diff --git a/client/src/translations/variants/es.pug b/client/src/translations/variants/es.pug
index cc855000..2db4ef95 100644
--- a/client/src/translations/variants/es.pug
+++ b/client/src/translations/variants/es.pug
@@ -333,7 +333,8 @@ p.
     "Rampage",
     "Recycle",
     "Shogun",
-    "Teleport"
+    "Teleport1",
+    "Teleport2"
   ]
 ul
   for v in varlist
diff --git a/client/src/translations/variants/fr.pug b/client/src/translations/variants/fr.pug
index f23512ea..ba52eca5 100644
--- a/client/src/translations/variants/fr.pug
+++ b/client/src/translations/variants/fr.pug
@@ -332,7 +332,8 @@ p.
     "Rampage",
     "Recycle",
     "Shogun",
-    "Teleport"
+    "Teleport1",
+    "Teleport2"
   ]
 ul
   for v in varlist
diff --git a/client/src/variants/Teleport.js b/client/src/variants/Teleport1.js
similarity index 99%
rename from client/src/variants/Teleport.js
rename to client/src/variants/Teleport1.js
index cbf6a786..faa503ac 100644
--- a/client/src/variants/Teleport.js
+++ b/client/src/variants/Teleport1.js
@@ -201,7 +201,7 @@ export class TeleportRules extends ChessRules {
       this.kingPos[move.vanish[1].c] = [-1, -1];
     else if (move.appear[0].p == V.KING)
       this.kingPos[move.appear[0].c] = [move.appear[0].x, move.appear[0].y];
-    this.updateCastleFlags(move);
+    if (move.vanish.length > 0) this.updateCastleFlags(move);
   }
 
   // NOTE: no need to update if castleFlags already off
diff --git a/client/src/variants/Teleport2.js b/client/src/variants/Teleport2.js
new file mode 100644
index 00000000..4e0fe23a
--- /dev/null
+++ b/client/src/variants/Teleport2.js
@@ -0,0 +1,57 @@
+import { Teleport1Rules } from "@/variants/Teleport1";
+
+export class Teleport2Rules extends Teleport1Rules {
+
+  canTake([x1, y1], [x2, y2]) {
+    // Cannot teleport king:
+    return (this.subTurn == 1 && this.getPiece(x2, y2) != V.KING);
+  }
+
+  underCheck(color) {
+    // Standard method:
+    return this.isAttacked(this.kingPos[color], V.GetOppCol(color));
+  }
+
+  postPlay(move) {
+    if (move.vaish.length > 0) {
+      // Standard method:
+      if (move.appear[0].p == V.KING)
+        this.kingPos[move.appear[0].c] = [move.appear[0].x, move.appear[0].y];
+      this.updateCastleFlags(move);
+    }
+  }
+
+  updateCastleFlags(move) {
+    // Standard method: TODO = find a better way... (not rewriting)
+    const c = color || V.GetOppCol(this.turn);
+    const firstRank = (c == "w" ? V.size.x - 1 : 0);
+    const oppCol = this.turn;
+    const oppFirstRank = V.size.x - 1 - firstRank;
+    if (piece == V.KING && move.appear.length > 0)
+      this.castleFlags[c] = [V.size.y, V.size.y];
+    else if (
+      move.start.x == firstRank &&
+      this.castleFlags[c].includes(move.start.y)
+    ) {
+      const flagIdx = (move.start.y == this.castleFlags[c][0] ? 0 : 1);
+      this.castleFlags[c][flagIdx] = V.size.y;
+    }
+    if (
+      move.end.x == oppFirstRank &&
+      this.castleFlags[oppCol].includes(move.end.y)
+    ) {
+      const flagIdx = (move.end.y == this.castleFlags[oppCol][0] ? 0 : 1);
+      this.castleFlags[oppCol][flagIdx] = V.size.y;
+    }
+  }
+
+  postUndo(move) {
+    if (move.vanish.length > 0) {
+      // Standard method:
+      const c = this.getColor(move.start.x, move.start.y);
+      if (this.getPiece(move.start.x, move.start.y) == V.KING)
+        this.kingPos[c] = [move.start.x, move.start.y];
+    }
+  }
+
+};
diff --git a/server/db/populate.sql b/server/db/populate.sql
index f9722f67..f0c87ed8 100644
--- a/server/db/populate.sql
+++ b/server/db/populate.sql
@@ -161,7 +161,8 @@ insert or ignore into Variants (name, description) values
   ('Switching', 'Exchange pieces'' positions'),
   ('Synochess', 'Dynasty versus Kingdom'),
   ('Takenmake', 'Prolongated captures'),
-  ('Teleport', 'Reposition pieces'),
+  ('Teleport (v1)', 'Reposition pieces (v1)'),
+  ('Teleport (v2)', 'Reposition pieces (v2)'),
   ('Tencubed', 'Four new pieces'),
   ('Threechecks', 'Give three checks'),
   ('Titan', 'Extra bishops and knights'),
diff --git a/server/sockets.js b/server/sockets.js
index 88cc2f24..4a61f685 100644
--- a/server/sockets.js
+++ b/server/sockets.js
@@ -219,10 +219,19 @@ module.exports = function(wss) {
           // "newgame" message can provide a page (corr Game --> Hall)
           notifyRoom(
             obj.page || page, obj.code, {data: obj.data}, obj.excluded);
-          if (!!discordChannel && obj.code == "newchallenge") {
-            discordChannel.send("New challenge: **" +
-              obj.data.vname +
-              "** [" + obj.data.cadence + "]");
+          if (
+            obj.code == "newchallenge" &&
+            !obj.data.to && //filter out targeted challenges
+            obj.data.cadence.indexOf('d') < 0 //and correspondance games
+          ) {
+            const challMsg = (
+              "New challenge: **" + obj.data.vname + "** " +
+              "[" + obj.data.cadence + "]"
+            );
+            if (!!discordChannel) discordChannel.send(challMsg);
+            else
+              // Log when running locally (dev, debug):
+              console.log(challMsg);
           }
           break;
 
-- 
2.44.0