Chaofan
2017-05-07 d398aa713da9885a85b7eccff267942608087f37
promo cards
3 files added
28 files modified
532 ■■■■ changed files
app/src/main/resources/cards.txt 22 ●●●● patch | view | raw | blame | history
app/src/main/resources/flags/46.png patch | view | raw | blame | history
app/src/main/resources/flags/47.png patch | view | raw | blame | history
app/src/main/resources/flags/ccw.png patch | view | raw | blame | history
app/src/main/scala/me/herbix/ts/client/ClientAgent.scala 8 ●●●●● patch | view | raw | blame | history
app/src/main/scala/me/herbix/ts/client/ClientLocal.scala 8 ●●●●● patch | view | raw | blame | history
app/src/main/scala/me/herbix/ts/client/HelpDialog.scala 4 ●●●● patch | view | raw | blame | history
app/src/main/scala/me/herbix/ts/client/MultiplePlayerFrame.scala 6 ●●●● patch | view | raw | blame | history
app/src/main/scala/me/herbix/ts/client/NetHandlerClient.scala 4 ●●●● patch | view | raw | blame | history
app/src/main/scala/me/herbix/ts/client/NewRoomDialog.scala 18 ●●●● patch | view | raw | blame | history
app/src/main/scala/me/herbix/ts/client/SinglePlayerFrame.scala 12 ●●●●● patch | view | raw | blame | history
app/src/main/scala/me/herbix/ts/ui/ControlUI.scala 31 ●●●● patch | view | raw | blame | history
app/src/main/scala/me/herbix/ts/ui/WorldMapUI.scala 4 ●●●● patch | view | raw | blame | history
app/src/main/scala/me/herbix/ts/util/Lang.scala 23 ●●●●● patch | view | raw | blame | history
app/src/main/scala/me/herbix/ts/util/Resource.scala 33 ●●●●● patch | view | raw | blame | history
common/src/main/scala/me/herbix/ts/logic/Flags.scala 3 ●●●●● patch | view | raw | blame | history
common/src/main/scala/me/herbix/ts/logic/Game.scala 106 ●●●● patch | view | raw | blame | history
common/src/main/scala/me/herbix/ts/logic/State.scala 1 ●●●● patch | view | raw | blame | history
common/src/main/scala/me/herbix/ts/logic/WorldMap.scala 18 ●●●●● patch | view | raw | blame | history
common/src/main/scala/me/herbix/ts/logic/card/Card.scala 3 ●●●●● patch | view | raw | blame | history
common/src/main/scala/me/herbix/ts/logic/card/CardMultiStep.scala 3 ●●●● patch | view | raw | blame | history
common/src/main/scala/me/herbix/ts/logic/card/Cards.scala 23 ●●●● patch | view | raw | blame | history
common/src/main/scala/me/herbix/ts/logic/card/PromoCards.scala 130 ●●●●● patch | view | raw | blame | history
common/src/main/scala/me/herbix/ts/logic/chinesecivilwar/CCWFlags.scala 1 ●●●● patch | view | raw | blame | history
common/src/main/scala/me/herbix/ts/logic/chinesecivilwar/GameChineseCivilWar.scala 1 ●●●● patch | view | raw | blame | history
common/src/main/scala/me/herbix/ts/logic/latewar/GameLateWar.scala 11 ●●●●● patch | view | raw | blame | history
common/src/main/scala/me/herbix/ts/logic/turnzero/Crisis.scala 5 ●●●● patch | view | raw | blame | history
common/src/main/scala/me/herbix/ts/logic/turnzero/GameTurnZero.scala 16 ●●●●● patch | view | raw | blame | history
common/src/main/scala/me/herbix/ts/logic/turnzero/TZFlags.scala 2 ●●●●● patch | view | raw | blame | history
common/src/main/scala/me/herbix/ts/logic/turnzero/TZWorldMap.scala 3 ●●●● patch | view | raw | blame | history
common/src/main/scala/me/herbix/ts/util/ConditionBuilder.scala 33 ●●●●● patch | view | raw | blame | history
app/src/main/resources/cards.txt
@@ -55,7 +55,7 @@
[9 star start=245]
越南起义
在越南增加2点苏联影响力。
在本回合内,苏联如果将行动力全和在东南亚,则可以行动力+1。
在本回合内,苏联如果将行动力全部用在东南亚,则可以行动力+1。
[10 star start=260]
封锁
@@ -549,39 +549,39 @@
美国在沙特阿拉伯增加2点影响力。
不可作为事件打出“穆斯林革命”。
[151 promote1 start=251]
[151 promo1 start=251]
不结盟运动
选择印度,非洲,东南亚,中东,南美中的一个双方都有2以上影响力的国家,去掉双方的所有影响力。然后从牌堆顶翻出4张牌放入弃牌堆(如有必要可洗牌)。
[152 promote1 star start=252]
[152 promo1 star start=252]
扎伊尔总统蒙博托
扎伊尔的稳定度永久变为3,美国在扎伊尔增加2点影响力。
[153 promote1 star start=258]
[153 promo1 star start=258]
柏林墙
在东德增加2点苏联影响力。
如果苏联在大空竞赛落后或等于美国,则前进一格。
[154 promote1 star start=264]
阻止核战的人
[154 promo1 star start=264]
避免核战的人
只有在核战等级为2时才能发动事件,设置核战等级为4或5。
[155 promote2 start=215]
[155 promo2 start=215 nuclear=USSR]
克里姆林流感
美国使用这张牌的行动力行动。
苏联下个行动轮必须要打出一张计分牌,如果没有计分牌,则跳过下个行动轮。
[156 promote2 star start=252]
第一声雷
[156 promo2 star start=252 nuclear=afterPlay]
苏联首枚原子弹
将此牌和一张美国相关的牌同时打出,那张牌不发动事件并进入弃牌堆。
当此牌被作为事件或是行动打出时,核战等级恶化1级。
[157 promote2 start=278]
[157 promo2 start=278]
谁失去了中国
若苏联持有中国牌,则设置美国的军事行动为0。
如果中国内战生效,则此牌不可作事件打出。
[158 promote2 star start=261]
[158 promo2 star start=261]
“不要再等翻译了”
如果美国军事行动落后,则美国增加2VP。
app/src/main/resources/flags/46.png

app/src/main/resources/flags/47.png
app/src/main/resources/flags/ccw.png
app/src/main/scala/me/herbix/ts/client/ClientAgent.scala
@@ -18,6 +18,8 @@
  var extraInfluence = 0
  var hasOptional = false
  var hasPromo1 = false
  var hasPromo2 = false
  var drawWinner = Faction.Neutral
  var gameVariant = GameVariant.Standard
@@ -45,6 +47,8 @@
    extraInfluence = NewRoomDialog.slider.getValue
    drawWinner = if (NewRoomDialog.us.isSelected) Faction.US else Faction.USSR
    hasOptional = NewRoomDialog.optional.isSelected
    hasPromo1 = NewRoomDialog.promo1.isSelected
    hasPromo2 = NewRoomDialog.promo2.isSelected
    gameVariant = NewRoomDialog.variant.getSelectedItem.asInstanceOf[GameVariantDelegate].gameVariant
  } else {
    System.exit(0)
@@ -66,10 +70,14 @@
  game1.extraInfluence = extraInfluence
  game1.drawGameWinner = drawWinner
  game1.optionalCards = hasOptional
  game1.promo1Cards = hasPromo1
  game1.promo2Cards = hasPromo2
  game2.extraInfluence = extraInfluence
  game2.drawGameWinner = drawWinner
  game2.optionalCards = hasOptional
  game2.promo1Cards = hasPromo1
  game2.promo2Cards = hasPromo2
  game1.anotherGame = game2
  game2.anotherGame = game1
app/src/main/scala/me/herbix/ts/client/ClientLocal.scala
@@ -17,6 +17,8 @@
  var extraInfluence = 0
  var hasOptional = false
  var hasPromo1 = false
  var hasPromo2 = false
  var drawWinner = Faction.Neutral
  var gameVariant = GameVariant.Standard
@@ -48,6 +50,8 @@
    extraInfluence = NewRoomDialog.slider.getValue
    drawWinner = if (NewRoomDialog.us.isSelected) Faction.US else Faction.USSR
    hasOptional = NewRoomDialog.optional.isSelected
    hasPromo1 = NewRoomDialog.promo1.isSelected
    hasPromo2 = NewRoomDialog.promo2.isSelected
    gameVariant = NewRoomDialog.variant.getSelectedItem.asInstanceOf[GameVariantDelegate].gameVariant
  } else {
    System.exit(0)
@@ -68,10 +72,14 @@
  game1.extraInfluence = extraInfluence
  game1.drawGameWinner = drawWinner
  game1.optionalCards = hasOptional
  game1.promo1Cards = hasPromo1
  game1.promo2Cards = hasPromo2
  game2.extraInfluence = extraInfluence
  game2.drawGameWinner = drawWinner
  game2.optionalCards = hasOptional
  game2.promo1Cards = hasPromo1
  game2.promo2Cards = hasPromo2
  game1.anotherGame = game2
  game2.anotherGame = game1
app/src/main/scala/me/herbix/ts/client/HelpDialog.scala
@@ -7,7 +7,7 @@
import me.herbix.ts.logic.Faction
import me.herbix.ts.logic.Faction.Faction
import me.herbix.ts.logic.{Game, Faction}
import me.herbix.ts.logic.card.{CardInstant, Card, Cards}
import me.herbix.ts.logic.card.{PromoCards, CardInstant, Card, Cards}
import me.herbix.ts.logic.turnzero.TZCards
import me.herbix.ts.util.{InfoItem, CardInfo, Lang, Resource}
@@ -61,7 +61,7 @@
  helpListModel.addElement(new ListItem("=========标准版卡牌列表========="))
  (1 to 110).map(Cards.fromId).foreach(card => helpListModel.addElement(new ListItem(card)))
  helpListModel.addElement(new ListItem("===========扩展牌列表==========="))
  (1 to 8).map(i => new DummyCard(i + Cards.PromoteOffset)).foreach(card => helpListModel.addElement(new ListItem(card)))
  (1 to 8).map(i => new DummyCard(i + PromoCards.Offset)).foreach(card => helpListModel.addElement(new ListItem(card)))
  helpListModel.addElement(new ListItem("========第零回合卡牌列表========"))
  (1 to 12).map(x => TZCards.fromId(x + TZCards.IdInc)).foreach(card => helpListModel.addElement(new ListItem(card)))
app/src/main/scala/me/herbix/ts/client/MultiplePlayerFrame.scala
@@ -29,6 +29,8 @@
  var extraInfluence = 0
  var hasOptional = false
  var hasPromo1 = false
  var hasPromo2 = false
  var drawWinner = Faction.Neutral
  var gameVariant = GameVariant.Standard
@@ -123,6 +125,8 @@
        extraInfluence = NewRoomDialog.slider.getValue
        drawWinner = if (NewRoomDialog.us.isSelected) Faction.US else Faction.USSR
        hasOptional = NewRoomDialog.optional.isSelected
        hasPromo1 = NewRoomDialog.promo1.isSelected
        hasPromo2 = NewRoomDialog.promo2.isSelected
        gameVariant = NewRoomDialog.variant.getSelectedItem.asInstanceOf[GameVariantDelegate].gameVariant
        showInfo()
      }
@@ -134,7 +138,7 @@
      s"游戏变体:${new GameVariantDelegate(gameVariant)}<br/>" +
      s"苏联让点:$extraInfluence<br/>" +
      s"平局胜者:${Lang.getFactionName(drawWinner)}<br/>" +
      s"可选牌: ${if (hasOptional) "有" else "无"}<br/>" +
      s"额外牌: ${if (hasOptional) "可选 " else ""}${if (hasPromo1) "扩展1 " else ""}${if (hasPromo2) "扩展2 " else ""}<br/>" +
      "</body></html>"
    )
  }
app/src/main/scala/me/herbix/ts/client/NetHandlerClient.scala
@@ -208,6 +208,8 @@
    MultiplePlayerFrame.extraInfluence = roomIn.readInt()
    MultiplePlayerFrame.drawWinner = Faction(roomIn.readInt())
    MultiplePlayerFrame.hasOptional = roomIn.readBoolean()
    MultiplePlayerFrame.hasPromo1 = roomIn.readBoolean()
    MultiplePlayerFrame.hasPromo2 = roomIn.readBoolean()
    MultiplePlayerFrame.gameVariant = GameVariant(roomIn.readInt())
    MultiplePlayerFrame.showInfo()
  }
@@ -246,6 +248,8 @@
    roomOut.writeInt(MultiplePlayerFrame.extraInfluence)
    roomOut.writeInt(MultiplePlayerFrame.drawWinner.id)
    roomOut.writeBoolean(MultiplePlayerFrame.hasOptional)
    roomOut.writeBoolean(MultiplePlayerFrame.hasPromo1)
    roomOut.writeBoolean(MultiplePlayerFrame.hasPromo2)
    roomOut.writeInt(MultiplePlayerFrame.gameVariant.id)
    roomOut.flush()
  }
app/src/main/scala/me/herbix/ts/client/NewRoomDialog.scala
@@ -22,16 +22,18 @@
  val panel = new JPanel
  panel.setLayout(null)
  panel.setPreferredSize(new Dimension(400, 240))
  panel.setPreferredSize(new Dimension(400, 320))
  add(panel)
  panel.add(label("游戏变体", 50, 30, 50, 20))
  panel.add(label("苏联让点", 50, 70, 50, 20))
  panel.add(label("平局胜者", 50, 110, 50, 20))
  panel.add(label("可选牌", 50, 150, 50, 20))
  panel.add(label("扩展牌1", 50, 190, 50, 20))
  panel.add(label("扩展牌2", 50, 230, 50, 20))
  val done = new JButton("完成")
  done.setLocation(150, 190)
  done.setLocation(150, 270)
  done.setSize(100, 30)
  panel.add(done)
@@ -76,6 +78,18 @@
  optional.setSelected(true)
  panel.add(optional)
  val promo1 = new JCheckBox()
  promo1.setLocation(120, 190)
  promo1.setSize(50, 20)
  promo1.setSelected(true)
  panel.add(promo1)
  val promo2 = new JCheckBox()
  promo2.setLocation(120, 230)
  promo2.setSize(50, 20)
  promo2.setSelected(true)
  panel.add(promo2)
  pack()
  setLocationRelativeTo(getOwner)
app/src/main/scala/me/herbix/ts/client/SinglePlayerFrame.scala
@@ -18,6 +18,8 @@
  var extraInfluence = 0
  var hasOptional = true
  var hasPromo1 = true
  var hasPromo2 = true
  var drawWinner = Faction.US
  var gameVariant = GameVariant.Standard
@@ -123,7 +125,7 @@
      s"游戏变体:${new GameVariantDelegate(gameVariant)}<br/>" +
      s"苏联让点:$extraInfluence<br/>" +
      s"平局胜者:${Lang.getFactionName(drawWinner)}<br/>" +
      s"可选牌: ${if (hasOptional) "有" else "无"}<br/>" +
      s"额外牌: ${if (hasOptional) "可选 " else ""}${if (hasPromo1) "扩展1 " else ""}${if (hasPromo2) "扩展2 " else ""}<br/>" +
      "</body></html>"
    )
  }
@@ -135,6 +137,8 @@
        extraInfluence = NewRoomDialog.slider.getValue
        drawWinner = if (NewRoomDialog.us.isSelected) Faction.US else Faction.USSR
        hasOptional = NewRoomDialog.optional.isSelected
        hasPromo1 = NewRoomDialog.promo1.isSelected
        hasPromo2 = NewRoomDialog.promo2.isSelected
        gameVariant = NewRoomDialog.variant.getSelectedItem.asInstanceOf[GameVariantDelegate].gameVariant
        showInfo()
      }
@@ -153,11 +157,15 @@
    game1.extraInfluence = extraInfluence
    game1.drawGameWinner = drawWinner
    game1.optionalCards = hasOptional
    game1.promo1Cards = hasPromo1
    game1.promo2Cards = hasPromo2
    game1.playerId = 0
    game2.extraInfluence = extraInfluence
    game2.drawGameWinner = drawWinner
    game2.optionalCards = hasOptional
    game2.promo1Cards = hasPromo1
    game2.promo2Cards = hasPromo2
    game2.playerId = 1
    game1.anotherGame = game2
@@ -204,6 +212,8 @@
      game3.extraInfluence = extraInfluence
      game3.drawGameWinner = drawWinner
      game3.optionalCards = hasOptional
      game3.promo1Cards = hasPromo1
      game3.promo2Cards = hasPromo2
      game3.playerId = 2
      game3.isSpectator = true
app/src/main/scala/me/herbix/ts/ui/ControlUI.scala
@@ -12,6 +12,7 @@
import me.herbix.ts.logic.turnzero.{TZFlags, GameTurnZero, TZState}
import me.herbix.ts.util._
import scala.collection.immutable.Range.Inclusive
import scala.collection.mutable
import scala.List
@@ -40,7 +41,7 @@
    val GameOver = Value
    // Special
    val Summit = Value
    val StopWorry = Value
    val Defcon = Value
    val GrainSales = Value
  }
@@ -65,7 +66,7 @@
  val uiGameOver = new ControlSubUIText(this, Array("", "", Lang.gameOver, "", Lang.winnerIs))
  // Special
  val uiSummit = new ControlSubUISummit(this)
  val uiStopWorry = new ControlSubUIHowILearnStopWorry(this)
  val uiDefcon = new ControlSubUIDefcon(this)
  val uiGrainSales = new ControlSubUIGrainSales(this)
  var operationListeners: List[Operation => Unit] = List()
@@ -88,7 +89,7 @@
  addUI(uiGameOver, GameOver)
  // Special
  addUI(uiSummit, Summit)
  addUI(uiStopWorry, StopWorry)
  addUI(uiDefcon, Defcon)
  addUI(uiGrainSales, GrainSales)
  updateState()
@@ -122,17 +123,18 @@
        case State.selectHeadlineCard | State.selectHeadlineCard2 => Lang.selectHeadline
        case State.discardHeldCard => Lang.discardHeldCard
        case State.quagmireDiscard => Lang.selectQuagmireDiscard
        case State.quagmirePlayScoringCard => Lang.selectQuagmireScoringCard
        case State.quagmirePlayScoringCard => Lang.selectScoringCard
        case State.cardOperationRealignment => Lang.operationRealignment
        case State.cardOperationCoup => Lang.operationCoup
        case State.cubaMissileRemove => Lang.cardTips(Card040CubaMissile.id)(0)
        case State.selectTake8Rounds => Lang.take8rounds
        case State.kremlinFluPlayScoringCard => Lang.selectScoringCard
        case State.EventStates(_) =>
          val card = game.currentCard
          val step = card.asInstanceOf[CardMultiStep].getStep(game)
          Lang.cardTips(card.id)(step - 1)
        case TZState.chooseStateCraft => Lang.chooseStateCarft
        case TZState.solveFlags => Lang.turnZeroFlagInfo(game.asInstanceOf[GameTurnZero].currentSolvingFlag.id)
        case TZState.solveFlags => Lang.turnZeroFlagInfo(game.asInstanceOf[GameTurnZero].currentSolvingFlag.id - TZFlags.FlagIdOffset)
        case _ => ""
      }
    } catch {
@@ -174,7 +176,7 @@
      case oh: OperationIntValueHint =>
        game.currentCard match {
          case Card045Summit => showSubUI(Summit)
          case Card046HowILearnStopWorry => showSubUI(StopWorry)
          case Card046HowILearnStopWorry | CardP04Stanislav => defconUI(oh.min, oh.max)
        }
      case oh: OperationSelectCardsHint =>
        selectMultipleCardsUI(tip);
@@ -278,6 +280,11 @@
  def selectRegionUI() = {
    showSubUI(SelectRegion)
  }
  def defconUI(min: Int, max: Int) = {
    showSubUI(Defcon)
    uiDefcon.setRange(min, max)
  }
  def gameOverUI(): Unit = {
@@ -591,9 +598,9 @@
      val cardProperties = CardInfo.info(card.id).properties
      if (cardProperties.contains("nuclear")) {
        val nuclear = cardProperties("nuclear")
        if (nuclear == "true" || nuclear == parent.game.playerFaction.toString) {
        if (nuclear == "true" || nuclear == "afterPlay" || nuclear == parent.game.playerFaction.toString) {
          buttonEvent.setIcon(Resource.nuclearIcon)
          if (oppositeEvent) {
          if (oppositeEvent || nuclear == "afterPlay") {
            buttonOperation.setIcon(Resource.nuclearIcon)
          }
        }
@@ -842,11 +849,17 @@
  }
}
class ControlSubUIHowILearnStopWorry(parent: ControlUI)
class ControlSubUIDefcon(parent: ControlUI)
  extends ControlSubUIText(parent, Array("", "", Lang.cardTips(Card046HowILearnStopWorry.id)(0))) {
  val buttons = (1 to 5).map(i => addButton(i.toString, 5 + (5 - i) * 38, 120, 38, 30) -> i).toMap
  def setRange(min: Int, max: Int) = {
    buttons.foreach(_._1.setEnabled(false))
    val range = min to max
    buttons.filter(e => range.contains(e._2)).foreach(_._1.setEnabled(true))
  }
  override def actionPerformed(e: ActionEvent): Unit = {
    val v = buttons(e.getSource.asInstanceOf[JButton])
    val op = new OperationIntValue(parent.game.playerId, parent.game.playerFaction, v)
app/src/main/scala/me/herbix/ts/ui/WorldMapUI.scala
@@ -261,6 +261,10 @@
      g.drawImage(battlefieldTaiwan, 2209, 712, null)
    }
    if (game.theWorldMap.countries("Zaire").stability == 3) {
      g.drawImage(stability3Zaire, 1209, 1010, null)
    }
    if (game.flags.hasFlag(TZFlags.usGoesFirst)) {
      drawTurnTokenUSFirst(g)
    } else {
app/src/main/scala/me/herbix/ts/util/Lang.scala
@@ -93,7 +93,7 @@
  val take8rounds = "是否要进行8个行动轮"
  val selectQuagmireDiscard = "请弃一张2以上行动力的牌"
  val selectQuagmireScoringCard = "请打出一张计分牌"
  val selectScoringCard = "请打出一张计分牌"
  val thisTurnFlag = "回合结束时标记失效。"
  val duringSetupFlag = "此标记在开局时生效。"
@@ -319,7 +319,7 @@
  addFlagInfo("核战等级限制(欧洲)", "双方不能在欧洲调整阵营或发动政变。")
  addFlagInfo("核战等级限制(亚洲)", "双方不能在亚洲调整阵营或发动政变。")
  addFlagInfo("核战等级限制(中东)", "双方不能在中东调整阵营或发动政变。")
  addFlagInfo("越南起义", "在本回合内,苏联如果将行动力全和在东南亚,则可以行动力+1。")
  addFlagInfo("越南起义", "在本回合内,苏联如果将行动力全部用在东南亚,则可以行动力+1。")
  addFlagInfo("戴高乐领导法国", "取消“北大西洋公约组织”对法国的效果,苏联可在法国调整阵营或发动政变。")
  addFlagInfo("遏制政策", "勃列日涅夫主义", "遏制政策/勃列日涅夫主义", "本回合%s打出的所有行动牌行动力+1(上限为4)。")
  addFlagInfo("美日共同防卫协定", "苏联不能在日本进行政变或调整阵营。")
@@ -372,6 +372,10 @@
      "打出“困境”时,此标记失效。")
  addFlagInfo("尤里和萨曼莎", "本回合剩下的行动轮内,每当美国发动政变,苏联就得1VP。")
  addFlagInfo("出售预警机给沙特", "不可作为事件打出“穆斯林革命”。")
  addFlagInfo("扎伊尔总统蒙博托", "扎伊尔的稳定度变为3。")
  addFlagInfo("克里姆林流感", "下个行动轮必须要打出一张计分牌,如果没有计分牌,则跳过下个行动轮。")
  addFlagInfo("中国内战",
      "双方不持有“中国牌”。\n" +
      "“文化大革命”,“台湾决议”不可作为事件打出。\n" +
@@ -386,7 +390,7 @@
  addFlagInfo("西欧盟军奋进", "“封锁”无效。")
  addFlagInfo("联合政府领导英国", "“社会主义政府”在第1~2回合无效。")
  addFlagInfo("保守党领导英国", "“苏伊士运河危机”无效。")
  addFlagInfo("以色列的危机", "苏联开局时在中东增加2点影响力(每个国家最多1点)")
  addFlagInfo("以色列的危机", "苏联开局时在中东增加2点影响力(每个国家最多1点).")
  addFlagInfo("美国速援蒋介石", "台湾成为战场国。")
  addFlagInfo("识局势的日本", "核战等级不可小于2,美国无视核战等级限制。")
@@ -440,6 +444,9 @@
  cardTips += Card107Che.id -> Array("请政变%1$s个国家(行动力%2$s)", "请政变%1$s个国家(行动力%2$s)")
  cardTips += Card108OurManInTehran.id -> Array("请弃掉任意张牌")
  cardTips += CardTZ02NationalistChina.id -> Array("请在亚洲放置%s影响力")
  cardTips += CardP01NonAlignMovement.id -> Array("请选择%s个国家移除影响力")
  cardTips += CardP04Stanislav.id -> Array("请改变核战等级")
  cardTips += CardP06FirstLightning.id -> Array("请选择要打出的牌")
  val spaceInfo = new Array[(String, String)](11)
  spaceInfo(0) = ("遥望天空",
@@ -514,11 +521,11 @@
  }
  val turnZeroFlagInfo = mutable.Map[Int, String](
    51 -> "请在东欧放置%s点影响力",
    47 -> "请在欧洲放置%s点影响力",
    55 -> "请在中东放置%s点影响力",
    48 -> "请选择要加入起始手牌的牌",
    49 -> "请选择要加入起始手牌的牌"
    1 -> "请在欧洲放置%s点影响力",
    2 -> "请选择要加入起始手牌的牌",
    3 -> "请选择要加入起始手牌的牌",
    5 -> "请在东欧放置%s点影响力",
    9 -> "请在中东放置%s点影响力"
  )
}
app/src/main/scala/me/herbix/ts/util/Resource.scala
@@ -5,7 +5,7 @@
import javax.swing.ImageIcon
import me.herbix.ts.logic.Faction._
import me.herbix.ts.logic.card.Cards
import me.herbix.ts.logic.card.{PromoCards, Cards}
import me.herbix.ts.logic.chinesecivilwar.CCWFlags
import me.herbix.ts.logic.turnzero.{TZCards, TZFlags}
import me.herbix.ts.logic.{Faction, Flags, FlagsTrait}
@@ -21,7 +21,7 @@
    .map(i => (i, ImageIO.read(getClass.getResourceAsStream(f"/cards/$i%03d.png"))))
    .toMap ++
      (1 to 8)
    .map(i => (i + Cards.PromoteOffset, ImageIO.read(getClass.getResourceAsStream(f"/cards/p$i%02d.png"))))
    .map(i => (i + PromoCards.Offset, ImageIO.read(getClass.getResourceAsStream(f"/cards/p$i%02d.png"))))
    .toMap ++
      (1 to 12)
    .map(i => (i + TZCards.IdInc, ImageIO.read(getClass.getResourceAsStream(f"/turnzero/cards/$i%02d.png"))))
@@ -38,20 +38,26 @@
  CCWFlags.init()
  TZFlags.init()
  val flag = (0 to FlagsTrait.flagId).map(i => {
    val (dir, id) =
      if (i > 46) {
        ("turnzero/flags", i - 47)
      } else {
        ("flags", i)
      }
    val in = getClass.getResourceAsStream(f"/$dir/$id%02d.png")
    if (in != null) {
    if (i == CCWFlags.FlagIdOffset + 1) {
      val in = getClass.getResourceAsStream(f"/flags/ccw.png")
      val img = ImageIO.read(in)
      (i, Map(US -> img, USSR -> img, Neutral -> img))
    } else {
      val inA = getClass.getResourceAsStream(f"/$dir/$id%02dA.png")
      val inS = getClass.getResourceAsStream(f"/$dir/$id%02dS.png")
      (i, Map(US -> ImageIO.read(inA), USSR -> ImageIO.read(inS)))
      val (dir, id) =
        if (i > TZFlags.FlagIdOffset) {
          ("turnzero/flags", i - TZFlags.FlagIdOffset - 1)
        } else {
          ("flags", i)
        }
      val in = getClass.getResourceAsStream(f"/$dir/$id%02d.png")
      if (in != null) {
        val img = ImageIO.read(in)
        (i, Map(US -> img, USSR -> img, Neutral -> img))
      } else {
        val inA = getClass.getResourceAsStream(f"/$dir/$id%02dA.png")
        val inS = getClass.getResourceAsStream(f"/$dir/$id%02dS.png")
        (i, Map(US -> ImageIO.read(inA), USSR -> ImageIO.read(inS)))
      }
    }
  }).toMap
@@ -77,6 +83,7 @@
  val chineseCivilWarBg = ImageIO.read(getClass.getResourceAsStream("/other/ccw-bg.png"))
  val battlefieldTaiwan = ImageIO.read(getClass.getResourceAsStream("/turnzero/other/battlefield-taiwan.png"))
  val stability3Zaire = ImageIO.read(getClass.getResourceAsStream("/other/3-stability-zaire.png"))
  val textFont = new Font(Lang.heiti, 0, 16)
  val textFont2 = new Font(Lang.lishu, 0, 32)
common/src/main/scala/me/herbix/ts/logic/Flags.scala
@@ -174,4 +174,7 @@
  val NORAD = new Flag(Always, true)
  val Samantha = new Flag(ThisTurn, true)
  val AwacsSale = new Flag(Always, true)
  val Mobutu = new Flag(Always, true)
  val KremlinFlu = new Flag(Always, false)
}
common/src/main/scala/me/herbix/ts/logic/Game.scala
@@ -27,6 +27,8 @@
  // config
  var extraInfluence = 0
  var optionalCards = true
  var promo1Cards = false
  var promo2Cards = false
  var drawGameWinner = US
  lazy val gameVariant = GameVariant.Standard
  
@@ -163,6 +165,7 @@
      case State.quagmirePlayScoringCard => nextStateQuagmireScoringCard(input)
      case State.noradInfluence => nextStateNORADInfluence(input)
      case State.cubaMissileRemove => nextStateCubaMissileRemove(input)
      case State.kremlinFluPlayScoringCard => nextStateKremlinFluScoringCard(input)
      case State.EventStates(n) => nextStateCardEvent(input)
    }
    checkFlags()
@@ -326,6 +329,7 @@
  }
  protected def initGame(): Unit = {
    theWorldMap.reset()
    initGameExceptChinaCard()
    handAdd(USSR, theCards.chinaCard)
@@ -333,10 +337,7 @@
  }
  def initGameExceptChinaCard(): Unit = {
    deckJoin(theCards.earlyWarSet)
    if (optionalCards) {
      deckJoin(theCards.earlyWarOptionalSet)
    }
    joinEarlyWarSet()
    pickGameStartHands(8)
@@ -345,6 +346,39 @@
    operatingPlayer = USSR
    stateStack.push(putStartUSSR)
  }
  def joinEarlyWarSet(): Unit = {
    deckJoin(theCards.earlyWarSet)
    if (optionalCards) {
      deckJoin(theCards.earlyWarOptionalSet)
    }
    if (promo2Cards) {
      deckJoin(theCards.earlyWarPromo2Set)
    }
  }
  def joinMidWarSet(): Unit = {
    deckJoin(theCards.midWarSet)
    if (optionalCards) {
      deckJoin(theCards.midWarOptionalSet)
    }
    if (promo1Cards) {
      deckJoin(theCards.midWarPromo1Set)
    }
    if (promo2Cards) {
      deckJoin(theCards.midWarPromo2Set)
    }
  }
  def joinLateWarSet(): Unit = {
    deckJoin(theCards.lateWarSet)
    if (optionalCards) {
      deckJoin(theCards.lateWarOptionalSet)
    }
    if (promo1Cards) {
      deckJoin(theCards.lateWarPromo1Set)
    }
  }
  def pickGameStartHands(count: Int): Unit = {
@@ -430,7 +464,9 @@
  }
  def nextActionState: State = {
    if (flags.hasFlag(phasingPlayer, Flags.QuagmireBearTrap)) {
    if (flags.hasFlag(phasingPlayer, Flags.KremlinFlu)) {
      kremlinFluPlayScoringCard
    } else if (flags.hasFlag(phasingPlayer, Flags.QuagmireBearTrap)) {
      val scoringCardCount = hand(phasingPlayer).count(!_.canHeld(this))
      if (hand(phasingPlayer).exists(card => card.canHeld(this) && card.canPlay(this, phasingPlayer)) &&
        scoringCardCount < turnRoundCount + 1 - round) {
@@ -549,21 +585,23 @@
  }
  def beginFirstRound(): Unit = {
    round = 1
    phasingPlayer = USSR
    operatingPlayer = phasingPlayer
    round = 0
    phasingPlayer = US
    nextRound()
    stateStack.push(nextActionState)
    flags.setFlagData(US, Flags.NORAD, defcon)
    recordHistory(new HistoryTurnRound(turn, round, phasingPlayer))
  }
  @tailrec
  private def nextRound(): Boolean = {
  final def nextRound(): Boolean = {
    increaseRoundCounter()
    operatingPlayer = phasingPlayer
    if (hand(phasingPlayer).canPlayCardCount(this, phasingPlayer) == 0 && !isAfterFinalRound) {
      if (flags.hasFlag(phasingPlayer, Flags.KremlinFlu)) {
        removeFlag(phasingPlayer, Flags.KremlinFlu)
      }
      nextRound()
    } else {
      if (!isAfterFinalRound) {
@@ -643,7 +681,7 @@
  def setDefcon(newVal: Int): Unit = {
    val oldVal = defcon
    defcon = newVal
    defcon = Math.min(5, Math.max(1, newVal))
    recordHistory(new HistoryDefcon(oldVal, defcon))
    checkDefcon()
    if (defcon > 2) {
@@ -703,15 +741,9 @@
    recordHistory(new HistoryTurnRound(turn, -1, Neutral))
    if (turn == 4) {
      deckJoin(theCards.midWarSet)
      if (optionalCards) {
        deckJoin(theCards.midWarOptionalSet)
      }
      joinMidWarSet()
    } else if (turn == 8) {
      deckJoin(theCards.lateWarSet)
      if (optionalCards) {
        deckJoin(theCards.lateWarOptionalSet)
      }
      joinLateWarSet()
    }
    val usHandCount = hand(US).cardCount
@@ -980,9 +1012,6 @@
    if (defcon <= 1) {
      defcon = 1
      gameOver(Faction.getOpposite(phasingPlayer))
    }
    if (defcon > 5) {
      defcon = 5
    }
    if (defcon <= 4) addFlag(Neutral, Flags.Defcon4Penalty) else removeFlag(Neutral, Flags.Defcon4Penalty)
    if (defcon <= 3) addFlag(Neutral, Flags.Defcon3Penalty) else removeFlag(Neutral, Flags.Defcon3Penalty)
@@ -1303,6 +1332,30 @@
    }
  }
  def nextStateKremlinFluScoringCard(input: Operation) = {
    val op = input.asInstanceOf[OperationSelectCard]
    val card = op.card.get
    handRemove(op.faction, card)
    discardCard(card, op.faction)
    recordHistory(new HistoryCardAction(op.faction, card, Action.Event, false))
    removeFlag(phasingPlayer, Flags.KremlinFlu)
    currentCard = card
    operatingPlayerChange(operatingPlayer)
    currentCardChange(currentCard)
    stateStack.pop()
    stateStack.push(cardE)
    recordHistory(new HistoryEvent(operatingPlayer, currentCard))
    stateStack.push(cardEvent)
    stateStack.push(cardEventStart)
    currentCard.nextState(this, operatingPlayer, null)
  }
  def checkFlags(): Unit = {
    for ((faction, set) <- flags.flagSets) {
      for (flag <- set) {
@@ -1459,6 +1512,13 @@
        } else {
          OperationHint.NOP
        }
      case State.kremlinFluPlayScoringCard =>
        if (operatingPlayer == playerFaction) {
          OperationHint(classOf[OperationSelectCard], false, (game, card) =>
            card.canPlay(this, playerFaction) && !card.canHeld(this))
        } else {
          OperationHint.NOP
        }
      case EventStates(_) =>
        if (operatingPlayer == playerFaction) {
          currentCard.getOperationHint(this)
common/src/main/scala/me/herbix/ts/logic/State.scala
@@ -20,6 +20,7 @@
  val quagmireDiscard, quagmirePlayScoringCard = Value
  val noradInfluence = Value
  val cubaMissileRemove = Value
  val kremlinFluPlayScoringCard = Value
  val end = Value
  object cardEventStep {
common/src/main/scala/me/herbix/ts/logic/WorldMap.scala
@@ -1,6 +1,7 @@
package me.herbix.ts.logic
import me.herbix.ts.logic.Region.{Region, _}
import me.herbix.ts.logic.turnzero.TZWorldMap._
import scala.collection.mutable
@@ -168,7 +169,22 @@
  addCountry(new Country("Botswana", 2, false, Africa), Set("Angola", "Zimbabwe"))
  addCountry(new Country("South Africa", 3, true, Africa), Set("Angola", "Botswana"))
  val normalCountries = countries.filter(e => !e._2.regions(Special))
  val normalZaire = countries("Zaire")
  val highStabilityZaire = new Country(normalZaire.id, "Zaire", 3, true, Set(Africa))
  def replaceWithHighStabilityZaire(): Unit = {
    removeCountry(normalZaire)
    addCountry(highStabilityZaire, Set("Angola", "Cameroon", "Zimbabwe"))
  }
  def reset(): Unit = {
    if (countries("Zaire") eq highStabilityZaire) {
      removeCountry(highStabilityZaire)
      addCountry(normalZaire, Set("Angola", "Cameroon", "Zimbabwe"))
    }
  }
  def normalCountries = countries.filter(e => !e._2.regions(Special))
  val ussrStandardStart = Map(
    countries("Syria") -> 1,
common/src/main/scala/me/herbix/ts/logic/card/Card.scala
@@ -18,6 +18,9 @@
  }
  def canEvent(game: Game, faction: Faction) = true
  def canPlay(game: Game, faction: Faction): Boolean = {
    if (game.flags.hasFlag(faction, Flags.KremlinFlu)) {
      return !canHeld(game)
    }
    if (game.flags.hasFlag(faction, Flags.QuagmireBearTrap)) {
      return !canHeld(game) ||
        ((game.modifyOp(faction, op) >= 2 && canDiscard(game, faction)) &&
common/src/main/scala/me/herbix/ts/logic/card/CardMultiStep.scala
@@ -3,10 +3,9 @@
import me.herbix.ts.logic.Faction.Faction
import me.herbix.ts.logic.State._
import me.herbix.ts.logic._
import me.herbix.ts.util.{OperationHint, CardCondition, CountryCondition, InfluenceCondition}
import me.herbix.ts.util.{CardCondition, CountryCondition, InfluenceCondition, OperationHint}
import scala.collection.mutable
import scala.reflect.ClassTag
/**
  * Created by Chaofan on 2016/7/23.
common/src/main/scala/me/herbix/ts/logic/card/Cards.scala
@@ -8,7 +8,6 @@
object Cards extends CardsTrait
trait CardsTrait {
  val PromoteOffset = 150
  protected val cardMap = mutable.Map[Int, Card]()
@@ -132,6 +131,15 @@
  addCard(Card109YuriAndSamantha)
  addCard(Card110AwacsSale)
  addCard(CardP01NonAlignMovement)
  addCard(CardP02Mobutu)
  addCard(CardP03BerlinWall)
  addCard(CardP04Stanislav)
  addCard(CardP05KremlinFlu)
  addCard(CardP06FirstLightning)
  addCard(CardP07WhoLostChina)
  addCard(CardP08DoNotWaitForTheTranslation)
  def fromId(id: Int): Card = cardMap.getOrElse(id, null)
  def earlyWarSet = cardMap.filter(e => (e._1 > 0 && e._1 <= 35 && e._1 != 6) || e._1 == 103).values
@@ -142,23 +150,30 @@
  def lateWarOptionalSet = cardMap.filter(e => e._1 > 108 && e._1 <= 110).values
  def chinaCard = cardMap(6)
  def promo1Set = cardMap.filter(e => e._1 >= PromoCards.Offset + 1 && e._1 <= PromoCards.Offset + 4).values
  def promo2Set = cardMap.filter(e => e._1 >= PromoCards.Offset + 5 && e._1 <= PromoCards.Offset + 8).values
  def midWarPromo1Set = promo1Set.filter(isMidWarCard)
  def lateWarPromo1Set = promo1Set.filter(isLateWarCard)
  def earlyWarPromo2Set = promo2Set.filter(isEarlyWarCard)
  def midWarPromo2Set = promo2Set.filter(isMidWarCard)
  def allCards = cardMap.values
  def isEarlyWarCard(card: Card): Boolean = {
    val i = card.id
    val j = i - PromoteOffset
    val j = i - PromoCards.Offset
    i <= 35 || (i >= 103 && i <= 106) || (j >= 5 && j <= 7)
  }
  def isMidWarCard(card: Card): Boolean = {
    val i = card.id
    val j = i - PromoteOffset
    val j = i - PromoCards.Offset
    (i >= 36 && i <= 81) || (i >= 107 && i <= 108) || (j >= 1 && j <= 3) || j == 8
  }
  def isLateWarCard(card: Card): Boolean = {
    val i = card.id
    val j = i - PromoteOffset
    val j = i - PromoCards.Offset
    (i >= 82 && i <= 102) || (i >= 109 && i <= 110) || j == 4
  }
common/src/main/scala/me/herbix/ts/logic/card/PromoCards.scala
New file
@@ -0,0 +1,130 @@
package me.herbix.ts.logic.card
import me.herbix.ts.logic.Faction.{Faction, _}
import me.herbix.ts.logic.Region._
import me.herbix.ts.logic.State._
import me.herbix.ts.logic._
import me.herbix.ts.logic.chinesecivilwar.CCWFlags
import me.herbix.ts.util.ConditionBuilder._
import me.herbix.ts.util.{HistoryCardAction, OperationHint}
/**
  * Created by Chaofan on 2017/4/22.
  */
object CardP01NonAlignMovement extends CardMultiStep(1 + PromoCards.Offset, 1, Neutral, false) {
  @step1(cardEventSelectCountry, 1, false,
    selectCountry.withName("India").or.inRegion(Africa, SouthEastAsia, MidEast, SouthAmerica)
      .influenceMoreOrEqual(US, 2).influenceMoreOrEqual(USSR, 2))
  def removeInfluence(game: Game, input: Operation): Unit = {
    val countries = input.asInstanceOf[OperationSelectCountry].detail
    game.modifyInfluence(US, false, countries.map(c => (c, game.influence(c, US))).toMap)
    game.modifyInfluence(USSR, false, countries.map(c => (c, game.influence(c, USSR))).toMap)
    for (i <- 1 to 4) {
      game.discardCard(game.pickCardFromDeck(), game.operatingPlayer, true, true)
    }
  }
}
object CardP02Mobutu extends CardInstant(2 + PromoCards.Offset, 2, US, true) {
  override def instantEvent(game: Game, faction: Faction): Boolean = {
    game.theWorldMap.replaceWithHighStabilityZaire()
    game.addFlag(Neutral, Flags.Mobutu)
    game.modifyInfluence(US, true, Map(game.theWorldMap.countries("Zaire") -> 2))
    true
  }
}
object CardP03BerlinWall extends CardInstant(3 + PromoCards.Offset, 2, USSR, true) {
  override def instantEvent(game: Game, faction: Faction): Boolean = {
    game.modifyInfluence(USSR, true, Map(game.theWorldMap.countries("E.Germany") -> 2))
    if (game.space(USSR).level <= game.space(US).level) {
      game.increaseSpace(USSR, 1)
    }
    true
  }
}
object CardP04Stanislav extends CardMultiStep(4 + PromoCards.Offset, 3, Neutral, true) {
  override def canEvent(game: Game, faction: Faction) = game.defcon == 2
  @step1(cardEventSpecial)
  def setDefconAndMilitary(game: Game, input: Operation): Unit = {
    game.setDefcon(input.asInstanceOf[OperationIntValue].value)
  }
  override def getSpecialOperationHint(game: Game): OperationHint = OperationHint(classOf[OperationIntValue], 4, 5)
}
object CardP05KremlinFlu extends CardMultiStep(5 + PromoCards.Offset, 2, US, false) {
  @prepare
  def addFlag(game: Game): Unit = {
    game.addFlag(USSR, Flags.KremlinFlu)
  }
  @step1(cardEventOperation)
  def operationDone(game: Game): Unit = {
    /* do nothing */
  }
}
object CardP06FirstLightning extends CardMultiStep(6 + PromoCards.Offset, 2, USSR, true) {
  class CardP06FirstLightningDummy(tmpop: Int) extends Card(6 + PromoCards.Offset, op, Neutral, false) {
    override val op = tmpop
    override def modifyOp(game: Game, faction: Faction, originalOp: Int): Int = op
    override def nextState(game: Game, faction: Faction, input: Operation): Unit =
      CardP06FirstLightning.nextState(game, faction, input)
  }
  object CardP06FirstLightningDummy {
    val map = (0 to 4).map(i => i -> new CardP06FirstLightningDummy(i)).toMap
    def apply(op: Int) = map(op)
  }
  //override def canEvent(game: Game, faction: Faction) = game.hand(USSR).exists(_.faction == US)
  @step1(cardEventSelectCardOrCancel, selectCard.isOppositeCard)
  def selectOpponentCard(game: Game, faction: Faction, input: Operation): Int = {
    if (input.asInstanceOf[OperationSelectCard].card.isEmpty) {
      3
    } else {
      val card = input.asInstanceOf[OperationSelectCard].card.get
      val op = game.modifyOp(faction, card.op)
      game.handRemove(faction, card)
      game.recordHistory(new HistoryCardAction(faction, card, Action.Operation, false))
      game.discardCard(card, faction, true)
      game.currentCardChange(CardP06FirstLightningDummy(op))
      2
    }
  }
  @step2(cardEventOperation)
  def operationDone(game: Game, input: Operation): Unit = {
    game.currentCard.afterPlay(game, faction)
    game.currentCardRollBack()
  }
  override def afterPlay(game: Game, faction: Faction): Unit = {
    game.setDefcon(game.defcon - 1)
  }
}
object CardP07WhoLostChina extends CardInstant(7 + PromoCards.Offset, 1, USSR, false) {
  override def canEvent(game: Game, faction: Faction) = !game.flags.hasFlag(CCWFlags.ChineseCivilWar)
  override def instantEvent(game: Game, faction: Faction): Boolean = {
    if (game.hand(USSR).has(game.theCards.chinaCard)) {
      game.setMilitary(US, 0)
    }
    true
  }
}
object CardP08DoNotWaitForTheTranslation extends CardInstant(8 + PromoCards.Offset, 3, US, true) {
  override def instantEvent(game: Game, faction: Faction): Boolean = {
    if (game.military(US) < game.military(USSR)) {
      game.addVp(US, 2)
    }
    true
  }
}
object PromoCards {
  val Offset = 150
}
common/src/main/scala/me/herbix/ts/logic/chinesecivilwar/CCWFlags.scala
@@ -6,5 +6,6 @@
  * Created by Chaofan on 2017/4/3.
  */
object CCWFlags extends FlagsTrait {
  val FlagIdOffset = FlagsTrait.flagId
  val ChineseCivilWar = new Flag(FlagType.Always, false)
}
common/src/main/scala/me/herbix/ts/logic/chinesecivilwar/GameChineseCivilWar.scala
@@ -13,6 +13,7 @@
  lazy override val gameVariant = GameVariant.ChineseCivilWar
  override protected def initGame(): Unit = {
    theWorldMap.reset()
    initGameExceptChinaCard()
    addFlag(Neutral, CCWFlags.ChineseCivilWar)
  }
common/src/main/scala/me/herbix/ts/logic/latewar/GameLateWar.scala
@@ -14,6 +14,8 @@
  lazy override val gameVariant = GameVariant.LateWar
  override def initGame() = {
    theWorldMap.reset()
    turn = 8
    setDefcon(4)
    space(USSR) = SpaceLevel.Orbit
@@ -36,6 +38,15 @@
      deckJoin(theCards.midWarOptionalSet.filter(!theCards.isCardStarred(_)))
      deckJoin(theCards.lateWarOptionalSet)
    }
    if (promo1Cards) {
      deckAdd(CardP01NonAlignMovement)
      deckAdd(CardP02Mobutu)
      deckAdd(CardP04Stanislav)
    }
    if (promo2Cards) {
      deckAdd(CardP05KremlinFlu)
      deckAdd(CardP07WhoLostChina)
    }
    deckAdd(Card044BearTrap)
    deckAdd(Card065CampDavidAccords)
    deckAdd(Card068JohnPaulII)
common/src/main/scala/me/herbix/ts/logic/turnzero/Crisis.scala
@@ -11,6 +11,7 @@
  */
abstract class Crisis(val id: Int) {
  Crisis.byId(id) = this
  println(Crisis.byId)
  def effect(value: Int, game: GameTurnZero): Unit =
    value match {
      case 1 => effect1(game)
@@ -27,13 +28,15 @@
}
object Crisis {
  def byId = mutable.Map[Int, Crisis]()
  val byId = mutable.Map[Int, Crisis]()
  def fromId(id: Int): Crisis = {
    Crisis.byId(id)
  }
  val setA = Set(CrisisYaltaAndPotsdam, CrisisVEDay, Crisis1945UKElection)
  val setB = Set(CrisisIsrael, CrisisChineseCivilWar, CrisisVJDay)
  System.out.println(byId)
}
object CrisisYaltaAndPotsdam extends Crisis(0) {
common/src/main/scala/me/herbix/ts/logic/turnzero/GameTurnZero.scala
@@ -180,10 +180,7 @@
    deckPrepared = true
    deckJoin(theCards.earlyWarSet)
    if (optionalCards) {
      deckJoin(theCards.earlyWarOptionalSet)
    }
    joinEarlyWarSet()
    pickGameStartHands(8)
@@ -242,14 +239,13 @@
  }
  override def beginFirstRound(): Unit = {
    round = 1
    phasingPlayer = if (flags.hasFlag(TZFlags.usGoesFirst)) US else USSR
    operatingPlayer = phasingPlayer
    round = 0
    phasingPlayer = if (!flags.hasFlag(TZFlags.usGoesFirst)) US else USSR
    nextRound()
    stateStack.push(nextActionState)
    flags.setFlagData(US, Flags.NORAD, defcon)
    recordHistory(new HistoryTurnRound(turn, round, phasingPlayer))
  }
  override def increaseRoundCounter(): Unit = {
@@ -311,7 +307,7 @@
                ConditionBuilder.influence.inRegion(Region.EastEurope).build, true, true, false)
            case TZFlags.ussrMidEastPlus2 =>
              OperationHint(classOf[OperationModifyInfluence], 2, true, USSR,
                ConditionBuilder.influence.inRegion(Region.MidEast).max(2).build, true, true, false)
                ConditionBuilder.influence.inRegion(Region.MidEast).max(1).build, true, true, false)
            case TZFlags.ussrVietnamOrArab =>
              OperationHint(classOf[OperationSelectCard], true, (game, card) => true)
            case TZFlags.usMarshall =>
common/src/main/scala/me/herbix/ts/logic/turnzero/TZFlags.scala
@@ -8,6 +8,8 @@
  */
object TZFlags extends FlagsTrait {
  val FlagIdOffset = FlagsTrait.flagId
  // Yalta & Potsdam
  val ussrEuropePlus1 = new Flag(DuringSetup, true)
  val ussrVietnamOrArab = new Flag(DuringSetup, true)
common/src/main/scala/me/herbix/ts/logic/turnzero/TZWorldMap.scala
@@ -15,7 +15,8 @@
    addCountry(battlefieldTaiwan, Set("Japan", "S.Korea"))
  }
  def reset(): Unit = {
  override def reset(): Unit = {
    super.reset()
    if (countries("Taiwan") eq battlefieldTaiwan) {
      removeCountry(battlefieldTaiwan)
      addCountry(normalTaiwan, Set("Japan", "S.Korea"))
common/src/main/scala/me/herbix/ts/util/ConditionBuilder.scala
@@ -12,16 +12,34 @@
  def influence = new InfluenceCondition(List.empty)
  def selectCard = new CardCondition(List.empty)
  def selectCountry = new CountryCondition(List.empty)
  val orInfluence: (Game, Map[Country, Int]) => Boolean = (_, _) => throw new NotImplementedError
  val orCountry: (Game, Set[Country]) => Boolean = (_, _) => throw new NotImplementedError
  val orCard: (Game, Card) => Boolean = (_, _) => throw new NotImplementedError
  val orSet: Set[(Game, _ <: AnyRef) => Boolean] = Set(orInfluence, orCard, orCountry)
}
class Condition[T](val items: List[(Game, T) => Boolean]) {
  private def toMethodImpl(game: Game, param: T): Boolean = {
    var lastCondition = true
    var followOr = false
    for (item <- items) {
      if (!item(game, param)) {
        return false
      if (!ConditionBuilder.orSet.contains(item)) {
        if (followOr) {
          lastCondition ||= item(game, param)
        } else {
          if (!lastCondition) {
            return false
          }
          lastCondition = item(game, param)
        }
        followOr = false
      } else {
        followOr = true
      }
    }
    true
    lastCondition
  }
  def build: (Game, T) => Boolean = toMethodImpl
@@ -62,6 +80,8 @@
  def inRegionShownInCardData = new InfluenceCondition(items :+
    ((game: Game, detail: Map[Country, Int]) => detail.forall(_._1.regions(game.currentCardData.asInstanceOf[Region]))))
  def or = new InfluenceCondition(items :+ ConditionBuilder.orInfluence)
  def all = this
}
@@ -93,6 +113,8 @@
  def canEvent = new CardCondition(items :+
    ((game: Game, card: Card) => card.canEvent(game, game.operatingPlayer)))
  def or = new CardCondition(items :+ ConditionBuilder.orCard)
  def all = this
}
@@ -122,6 +144,11 @@
  def notBattlefield = new CountryCondition(items :+
    ((game: Game, detail: Set[Country]) => detail.forall(!_.isBattlefield)))
  def influenceMoreOrEqual(faction: Faction, count: Int) = new CountryCondition(items :+
    ((game: Game, detail: Set[Country]) => detail.forall(c => game.influence(c, faction) >= count)))
  def or = new CountryCondition(items :+ ConditionBuilder.orCountry)
  def all = this
}