Code Sketch


Bixuu ShadowfallEternalCurseEvent8
By: Mhalsakant School
Category: Programming
import java.awt.{BasicStroke, BorderLayout, Color, Dimension, Font, Graphics, Graphics2D, GradientPaint, RenderingHints}
import java.awt.event.{ActionEvent, ActionListener, KeyAdapter, KeyEvent, MouseAdapter, MouseEvent}
import javax.swing.{JButton, JFrame, JLabel, JPanel, JTextField, SwingConstants, Timer, WindowConstants}
import scala.collection.mutable.ArrayBuffer

object ShadowfallEternalCurseEvent8 {
  def main(args: Array[String]): Unit = {
    javax.swing.SwingUtilities.invokeLater(new Runnable {
      def run(): Unit = openGame()
    })
  }

  def openGame(): Unit = {
    val frame = new JFrame("INFINITY REALMS SEASON 08 - SHADOWFALL: ETERNAL CURSE")
    frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE)
    frame.setResizable(false)
    val login = new ShadowfallLoginPanel((playerName: String) => {
      val game = new ShadowfallGamePanel(playerName)
      frame.setContentPane(game)
      frame.pack()
      frame.setLocationRelativeTo(null)
      game.requestFocusInWindow()
      game.startGame()
    })
    frame.setContentPane(login)
    frame.pack()
    frame.setLocationRelativeTo(null)
    frame.setVisible(true)
  }
}

class ShadowfallLoginPanel(onStart: String => Unit) extends JPanel {
  setPreferredSize(new Dimension(960, 680))
  setLayout(null)
  setBackground(new Color(12, 10, 27))

  val title = new JLabel("SHADOWFALL", SwingConstants.CENTER)
  title.setFont(new Font("Serif", Font.BOLD, 50))
  title.setForeground(new Color(224, 211, 255))
  title.setBounds(180, 105, 600, 70)
  add(title)

  val subtitle = new JLabel("ETERNAL CURSE  |  INFINITY REALMS SEASON 08", SwingConstants.CENTER)
  subtitle.setFont(new Font("SansSerif", Font.BOLD, 18))
  subtitle.setForeground(new Color(168, 142, 220))
  subtitle.setBounds(150, 180, 660, 35)
  add(subtitle)

  val story = new JLabel("Explore the haunted realms, collect Moon Sigils and break the Eternal Curse.", SwingConstants.CENTER)
  story.setFont(new Font("SansSerif", Font.PLAIN, 16))
  story.setForeground(new Color(206, 198, 225))
  story.setBounds(100, 240, 760, 32)
  add(story)

  val nameLabel = new JLabel("ENTER YOUR EXPLORER NAME", SwingConstants.CENTER)
  nameLabel.setFont(new Font("SansSerif", Font.BOLD, 16))
  nameLabel.setForeground(new Color(204, 188, 242))
  nameLabel.setBounds(300, 330, 360, 30)
  add(nameLabel)

  val nameField = new JTextField("Explorer")
  nameField.setFont(new Font("SansSerif", Font.PLAIN, 20))
  nameField.setHorizontalAlignment(SwingConstants.CENTER)
  nameField.setBounds(330, 370, 300, 42)
  add(nameField)

  val startButton = new JButton("ENTER THE SHADOW REALM")
  startButton.setFont(new Font("SansSerif", Font.BOLD, 16))
  startButton.setForeground(Color.WHITE)
  startButton.setBackground(new Color(94, 62, 145))
  startButton.setFocusPainted(false)
  startButton.setBounds(330, 440, 300, 48)
  startButton.addActionListener(new ActionListener {
    def actionPerformed(e: ActionEvent): Unit = {
      var chosen = nameField.getText.trim
      if (chosen.length == 0) chosen = "Explorer"
      onStart(chosen)
    }
  })
  add(startButton)

  val controls = new JLabel("WASD / ARROWS: MOVE     SPACE: DASH     F: LANTERN PULSE     Q: AURA     E: INTERACT", SwingConstants.CENTER)
  controls.setFont(new Font("SansSerif", Font.PLAIN, 12))
  controls.setForeground(new Color(151, 139, 179))
  controls.setBounds(60, 585, 840, 25)
  add(controls)

  val hint = new JLabel("Offline adventure  -  Progress stays in this game session", SwingConstants.CENTER)
  hint.setFont(new Font("SansSerif", Font.PLAIN, 12))
  hint.setForeground(new Color(112, 104, 139))
  hint.setBounds(200, 615, 560, 22)
  add(hint)

  override def paintComponent(g: Graphics): Unit = {
    super.paintComponent(g)
    val g2 = g.asInstanceOf[Graphics2D]
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
    g2.setPaint(new GradientPaint(0, 0, new Color(9, 8, 24), 0, getHeight, new Color(47, 25, 70)))
    g2.fillRect(0, 0, getWidth, getHeight)
    var i = 0
    while (i < 65) {
      val x = (i * 149 + 31) % getWidth
      val y = (i * 83 + 19) % getHeight
      g2.setColor(new Color(182, 160, 230, 90))
      g2.fillOval(x, y, 2 + (i % 3), 2 + (i % 3))
      i += 1
    }
    g2.setColor(new Color(100, 74, 144, 80))
    g2.fillOval(350, 5, 260, 260)
    g2.setColor(new Color(15, 11, 31))
    g2.fillOval(405, 5, 260, 260)
  }

}

class ShadowfallGamePanel(val playerName: String) extends JPanel {
  setPreferredSize(new Dimension(960, 680))
  setBackground(new Color(16, 13, 30))
  setFocusable(true)

  class Sigil(val x: Int, val y: Int, var collected: Boolean)
  class Wisp(var x: Double, var y: Double, var stunnedTicks: Int)

  val realmNames = Array("THE FORGOTTEN VILLAGE", "WHISPERING BLACKWOOD", "THE ETERNAL CITADEL")
  val realmSubtitles = Array("Find the lost village moon sigils", "Follow the lanterns through the cursed forest", "Face the Warden and open the final gate")
  val realmColors = Array(new Color(67, 83, 130), new Color(72, 46, 112), new Color(112, 52, 105))
  val keys = scala.collection.mutable.Set[Int]()
  val wisps = ArrayBuffer[Wisp]()
  var sigils = ArrayBuffer[Sigil]()
  var realm = 0
  var playerX = 95.0
  var playerY = 380.0
  var playerLives = 3
  var score = 0
  var totalSigils = 0
  var curseMeter = 0.0
  var paused = false
  var gameOver = false
  var victory = false
  var tick = 0
  var dashTicks = 0
  var dashCooldown = 0
  var pulseCooldown = 0
  var auraTicks = 0
  var auraCooldown = 0
  var invulnerableTicks = 0
  var message = "Find 4 Moon Sigils to unlock the realm gate."
  var mouseTargetX = -1.0
  var mouseTargetY = -1.0
  var bossHealth = 3
  var bossStunnedTicks = 0
  var bossX = 785.0
  var bossY = 355.0
  var bossDefeated = false
  var gameTimer: Timer = null

  loadRealm()

  def startGame(): Unit = {
    if (gameTimer == null) {
      gameTimer = new Timer(25, new ActionListener {
        def actionPerformed(e: ActionEvent): Unit = updateGame()
      })
      gameTimer.start()
    }
    requestFocusInWindow()
  }

  def stopGame(): Unit = {
    if (gameTimer != null) gameTimer.stop()
  }

  def loadRealm(): Unit = {
    playerX = 95.0
    playerY = 380.0
    mouseTargetX = -1.0
    mouseTargetY = -1.0
    sigils.clear()
    sigils += new Sigil(235, 210, false)
    sigils += new Sigil(405, 500, false)
    sigils += new Sigil(590, 220, false)
    sigils += new Sigil(735, 505, false)
    wisps.clear()
    wisps += new Wisp(370.0, 330.0, 0)
    wisps += new Wisp(650.0, 420.0, 0)
    if (realm > 0) wisps += new Wisp(520.0, 545.0, 0)
    bossHealth = 3
    bossStunnedTicks = 0
    bossX = 785.0
    bossY = 355.0
    bossDefeated = false
    curseMeter = 0.0
    message = realmSubtitles(realm)
  }

  def currentSigils(): Int = sigils.count(s => s.collected)

  def updateGame(): Unit = {
    if (paused || gameOver || victory) {
      repaint()
      return
    }
    tick += 1
    if (dashTicks > 0) dashTicks -= 1
    if (dashCooldown > 0) dashCooldown -= 1
    if (pulseCooldown > 0) pulseCooldown -= 1
    if (auraTicks > 0) auraTicks -= 1
    if (auraCooldown > 0) auraCooldown -= 1
    if (invulnerableTicks > 0) invulnerableTicks -= 1
    if (bossStunnedTicks > 0) bossStunnedTicks -= 1

    val baseSpeed = 2.35 + Math.min(0.9, totalSigils * 0.045)
    val speed = if (dashTicks > 0) baseSpeed * 2.8 else baseSpeed
    var dx = 0.0
    var dy = 0.0
    if (keys.contains(KeyEvent.VK_A) || keys.contains(KeyEvent.VK_LEFT)) dx -= 1.0
    if (keys.contains(KeyEvent.VK_D) || keys.contains(KeyEvent.VK_RIGHT)) dx += 1.0
    if (keys.contains(KeyEvent.VK_W) || keys.contains(KeyEvent.VK_UP)) dy -= 1.0
    if (keys.contains(KeyEvent.VK_S) || keys.contains(KeyEvent.VK_DOWN)) dy += 1.0
    if (dx != 0.0 || dy != 0.0) {
      val length = Math.sqrt(dx * dx + dy * dy)
      playerX += (dx / length) * speed
      playerY += (dy / length) * speed
      mouseTargetX = -1.0
      mouseTargetY = -1.0
    } else if (mouseTargetX >= 0.0) {
      val tx = mouseTargetX - playerX
      val ty = mouseTargetY - playerY
      val distance = Math.sqrt(tx * tx + ty * ty)
      if (distance < 6.0) {
        mouseTargetX = -1.0
        mouseTargetY = -1.0
      } else {
        playerX += tx / distance * speed
        playerY += ty / distance * speed
      }
    }
    playerX = Math.max(55.0, Math.min(905.0, playerX))
    playerY = Math.max(145.0, Math.min(625.0, playerY))

    sigils.foreach { s =>
      if (!s.collected && distance(playerX, playerY, s.x, s.y) < 27.0) {
        s.collected = true
        totalSigils += 1
        score += 150
        curseMeter = Math.max(0.0, curseMeter - 12.0)
        message = "Moon Sigil collected! Your light grows stronger."
      }
    }

    wisps.foreach { w =>
      if (w.stunnedTicks > 0) w.stunnedTicks -= 1
      else {
        val vx = playerX - w.x
        val vy = playerY - w.y
        val d = Math.sqrt(vx * vx + vy * vy)
        if (d > 1.0) {
          val wispSpeed = 0.58 + realm * 0.12
          w.x += vx / d * wispSpeed
          w.y += vy / d * wispSpeed
        }
        if (d < 25.0 && invulnerableTicks == 0 && auraTicks == 0) {
          playerLives -= 1
          curseMeter = Math.min(100.0, curseMeter + 18.0)
          invulnerableTicks = 95
          playerX = 95.0
          playerY = 380.0
          message = "A Shadow Wisp touched you! Return to the lantern path."
          if (playerLives <= 0) gameOver = true
        }
      }
    }

    if (realm == 2 && currentSigils() >= 4 && !bossDefeated) {
      if (bossStunnedTicks == 0) {
        val vx = playerX - bossX
        val vy = playerY - bossY
        val d = Math.sqrt(vx * vx + vy * vy)
        if (d > 1.0) {
          bossX += vx / d * 0.72
          bossY += vy / d * 0.72
        }
        if (d < 33.0 && invulnerableTicks == 0 && auraTicks == 0) {
          playerLives -= 1
          invulnerableTicks = 105
          curseMeter = Math.min(100.0, curseMeter + 25.0)
          playerX = 95.0
          playerY = 380.0
          message = "The Eternal Warden pushed you back! Use Lantern Pulse."
          if (playerLives <= 0) gameOver = true
        }
      }
    }

    curseMeter = Math.min(100.0, curseMeter + 0.018)
    if (curseMeter >= 100.0) {
      curseMeter = 45.0
      if (invulnerableTicks == 0) {
        playerLives -= 1
        invulnerableTicks = 90
        playerX = 95.0
        playerY = 380.0
        message = "Eternal Curse surge! The lantern sent you back to Base."
        if (playerLives <= 0) gameOver = true
      }
    }
    repaint()
  }

  def distance(x1: Double, y1: Double, x2: Double, y2: Double): Double = {
    val dx = x1 - x2
    val dy = y1 - y2
    Math.sqrt(dx * dx + dy * dy)
  }

  def activateDash(): Unit = {
    if (!paused && dashCooldown == 0 && !gameOver && !victory) {
      dashTicks = 9
      dashCooldown = 65
      message = "Moon Dash activated!"
    }
  }

  def lanternPulse(): Unit = {
    if (!paused && pulseCooldown == 0 && !gameOver && !victory) {
      pulseCooldown = 78
      wisps.foreach { w =>
        if (distance(playerX, playerY, w.x, w.y) < 190.0) w.stunnedTicks = 110
      }
      if (realm == 2 && currentSigils() >= 4 && !bossDefeated && distance(playerX, playerY, bossX, bossY) < 205.0) {
        bossHealth -= 1
        bossStunnedTicks = 95
        score += 250
        message = "Lantern Pulse struck the Eternal Warden!"
        if (bossHealth <= 0) {
          bossDefeated = true
          score += 1000
          message = "The Eternal Warden is defeated! Reach the final Moon Gate."
        }
      } else {
        message = "Lantern Pulse! Nearby Shadow Wisps are stunned."
      }
    }
  }

  def activateAura(): Unit = {
    if (!paused && auraCooldown == 0 && !gameOver && !victory) {
      auraTicks = 100
      auraCooldown = 240
      message = "Moon Aura protects you for a short time."
    }
  }

  def interact(): Unit = {
    if (gameOver || victory || paused) return
    if (distance(playerX, playerY, 95.0, 380.0) < 72.0) {
      curseMeter = Math.max(0.0, curseMeter - 8.0)
      message = "Safe at Lantern Base. The curse is fading."
      return
    }
    if (currentSigils() < 4) {
      message = "The Moon Gate is sealed. Collect all 4 Moon Sigils first."
      return
    }
    if (realm == 2 && !bossDefeated) {
      message = "The Eternal Warden guards the final gate. Use F near it!"
      return
    }
    if (distance(playerX, playerY, 865.0, 380.0) < 85.0) {
      if (realm < 2) {
        realm += 1
        loadRealm()
      } else {
        victory = true
        message = "The Eternal Curse has been broken!"
      }
    } else {
      message = "Find the glowing Moon Gate on the right side of the realm."
    }
  }

  def returnToBase(): Unit = {
    playerX = 95.0
    playerY = 380.0
    mouseTargetX = -1.0
    mouseTargetY = -1.0
    curseMeter = Math.max(0.0, curseMeter - 16.0)
    message = "Returned to Lantern Base."
  }

  def restartGame(): Unit = {
    realm = 0
    playerLives = 3
    score = 0
    totalSigils = 0
    curseMeter = 0.0
    paused = false
    gameOver = false
    victory = false
    tick = 0
    dashCooldown = 0
    pulseCooldown = 0
    auraCooldown = 0
    invulnerableTicks = 0
    loadRealm()
    requestFocusInWindow()
  }

  addKeyListener(new KeyAdapter {
    override def keyPressed(e: KeyEvent): Unit = {
      val code = e.getKeyCode
      if (!keys.contains(code)) {
        if (code == KeyEvent.VK_SPACE) activateDash()
        if (code == KeyEvent.VK_F) lanternPulse()
        if (code == KeyEvent.VK_Q) activateAura()
        if (code == KeyEvent.VK_E) interact()
        if (code == KeyEvent.VK_B) returnToBase()
        if (code == KeyEvent.VK_P) paused = !paused
        if (code == KeyEvent.VK_R && (gameOver || victory)) restartGame()
      }
      keys += code
    }
    override def keyReleased(e: KeyEvent): Unit = keys -= e.getKeyCode
  })

  addMouseListener(new MouseAdapter {
    override def mousePressed(e: MouseEvent): Unit = {
      requestFocusInWindow()
      if (!paused && !gameOver && !victory && e.getY > 115) {
        mouseTargetX = e.getX.toDouble
        mouseTargetY = e.getY.toDouble
      }
    }
  })

  def drawText(g: Graphics2D, text: String, x: Int, y: Int, size: Int, color: Color): Unit = {
    g.setFont(new Font("SansSerif", Font.BOLD, size))
    g.setColor(color)
    g.drawString(text, x, y)
  }

  override def paintComponent(graphics: Graphics): Unit = {
    super.paintComponent(graphics)
    val g = graphics.asInstanceOf[Graphics2D]
    g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
    val sky = realmColors(realm)
    g.setPaint(new GradientPaint(0, 0, new Color(9, 8, 22), 0, getHeight, sky.darker().darker()))
    g.fillRect(0, 0, getWidth, getHeight)

    var i = 0
    while (i < 90) {
      val sx = (i * 137 + 29) % 960
      val sy = (i * 79 + 17) % 680
      g.setColor(new Color(210, 198, 255, 90))
      g.fillOval(sx, sy, 2, 2)
      i += 1
    }

    g.setColor(new Color(176, 157, 221, 45))
    g.fillOval(695, 55, 170, 170)
    g.setColor(new Color(26, 19, 43))
    g.fillOval(735, 42, 170, 170)

    g.setColor(new Color(10, 9, 22, 190))
    g.fillRect(0, 0, 960, 112)
    drawText(g, "SHADOWFALL: ETERNAL CURSE", 24, 36, 23, new Color(232, 220, 255))
    drawText(g, playerName + "   |   " + realmNames(realm), 25, 67, 14, new Color(190, 173, 226))
    drawText(g, "SCORE " + score + "    SIGILS " + totalSigils + "/12    LIVES " + playerLives, 25, 94, 13, new Color(238, 218, 176))

    // Haunted landscape and silhouettes
    g.setColor(new Color(11, 10, 25, 175))
    g.fillOval(-90, 470, 360, 210)
    g.fillOval(200, 495, 360, 190)
    g.fillOval(550, 465, 490, 220)
    var tree = 0
    while (tree < 8) {
      val tx = 160 + tree * 105
      g.setColor(new Color(17, 13, 31))
      g.fillRect(tx, 300 + (tree % 3) * 26, 13, 245)
      g.fillOval(tx - 48, 255 + (tree % 2) * 38, 110, 100)
      tree += 1
    }

    // Lantern Base
    g.setColor(new Color(40, 28, 63))
    g.fillRoundRect(48, 340, 95, 80, 18, 18)
    g.setColor(new Color(241, 201, 122))
    g.setStroke(new BasicStroke(3.0f))
    g.drawRoundRect(48, 340, 95, 80, 18, 18)
    g.fillOval(82, 365, 27, 27)
    drawText(g, "BASE", 69, 438, 12, new Color(246, 220, 166))

    // Sigils
    sigils.foreach { s =>
      if (!s.collected) {
        g.setColor(new Color(184, 157, 255, 55))
        g.fillOval(s.x - 23, s.y - 23, 46, 46)
        g.setColor(new Color(222, 205, 255))
        val px = Array(s.x, s.x + 13, s.x, s.x - 13)
        val py = Array(s.y - 18, s.y, s.y + 18, s.y)
        g.fillPolygon(px, py, 4)
        g.setColor(new Color(255, 239, 196))
        g.fillOval(s.x - 4, s.y - 4, 8, 8)
      }
    }

    // Moon Gate
    val gateOpen = currentSigils() >= 4 && (realm < 2 || bossDefeated)
    g.setColor(new Color(148, 105, 210, 55))
    g.fillOval(820, 295, 90, 165)
    g.setStroke(new BasicStroke(8.0f))
    g.setColor(if (gateOpen) new Color(181, 235, 205) else new Color(113, 92, 145))
    g.drawOval(835, 305, 62, 140)
    drawText(g, "MOON GATE", 816, 470, 11, new Color(218, 207, 240))

    // Shadow Wisps
    wisps.foreach { w =>
      val alpha = if (w.stunnedTicks > 0) 100 else 220
      g.setColor(new Color(151, 113, 205, alpha))
      g.fillOval(w.x.toInt - 17, w.y.toInt - 17, 34, 34)
      g.setColor(new Color(226, 216, 255, alpha))
      g.fillOval(w.x.toInt - 8, w.y.toInt - 6, 5, 6)
      g.fillOval(w.x.toInt + 4, w.y.toInt - 6, 5, 6)
      if (w.stunnedTicks > 0) drawText(g, "Z", w.x.toInt + 12, w.y.toInt - 18, 12, Color.WHITE)
    }

    // Eternal Warden in the final realm
    if (realm == 2 && currentSigils() >= 4 && !bossDefeated) {
      g.setColor(new Color(170, 66, 120, 65))
      g.fillOval(bossX.toInt - 42, bossY.toInt - 42, 84, 84)
      g.setColor(new Color(85, 45, 105))
      g.fillOval(bossX.toInt - 28, bossY.toInt - 34, 56, 68)
      g.setColor(new Color(255, 205, 155))
      g.fillOval(bossX.toInt - 13, bossY.toInt - 9, 7, 7)
      g.fillOval(bossX.toInt + 7, bossY.toInt - 9, 7, 7)
      drawText(g, "WARDEN " + bossHealth + "/3", bossX.toInt - 36, bossY.toInt - 42, 12, new Color(255, 215, 220))
    }

    // Player
    if (invulnerableTicks == 0 || (tick / 5) % 2 == 0) {
      if (auraTicks > 0) {
        g.setColor(new Color(255, 226, 155, 75))
        g.fillOval(playerX.toInt - 27, playerY.toInt - 27, 54, 54)
        g.setColor(new Color(255, 229, 169))
        g.drawOval(playerX.toInt - 27, playerY.toInt - 27, 54, 54)
      }
      g.setColor(new Color(204, 185, 244))
      g.fillOval(playerX.toInt - 12, playerY.toInt - 17, 24, 24)
      g.setColor(new Color(66, 49, 101))
      g.fillRoundRect(playerX.toInt - 13, playerY.toInt - 2, 26, 29, 10, 10)
      g.setColor(new Color(246, 218, 168))
      g.fillOval(playerX.toInt - 4, playerY.toInt - 9, 3, 3)
      g.fillOval(playerX.toInt + 3, playerY.toInt - 9, 3, 3)
    }

    // Curse meter and status
    g.setColor(new Color(28, 21, 43))
    g.fillRoundRect(650, 18, 280, 18, 9, 9)
    g.setColor(if (curseMeter < 55.0) new Color(150, 105, 202) else new Color(223, 105, 132))
    g.fillRoundRect(650, 18, (curseMeter * 2.8).toInt, 18, 9, 9)
    drawText(g, "ETERNAL CURSE", 650, 53, 12, new Color(217, 204, 235))
    drawText(g, "DASH " + (if (dashCooldown == 0) "READY" else "..."), 650, 75, 11, new Color(205, 190, 230))
    drawText(g, "PULSE " + (if (pulseCooldown == 0) "READY" else "..."), 785, 75, 11, new Color(205, 190, 230))

    g.setColor(new Color(8, 7, 18, 210))
    g.fillRoundRect(170, 625, 620, 38, 12, 12)
    drawText(g, message, 185, 649, 13, new Color(235, 220, 255))
    drawText(g, "WASD/ARROWS MOVE  |  SPACE DASH  |  F LANTERN PULSE  |  Q AURA  |  E GATE  |  B BASE  |  P PAUSE", 70, 602, 11, new Color(201, 190, 220))

    if (paused || gameOver || victory) {
      g.setColor(new Color(5, 4, 13, 210))
      g.fillRect(0, 0, getWidth, getHeight)
      if (paused) {
        drawText(g, "PAUSED", 390, 300, 42, Color.WHITE)
        drawText(g, "Press P to continue", 370, 345, 18, new Color(208, 195, 235))
      } else if (gameOver) {
        drawText(g, "THE CURSE HAS WON", 270, 285, 36, new Color(241, 194, 215))
        drawText(g, "Press R to restart the expedition", 300, 335, 18, Color.WHITE)
      } else {
        drawText(g, "ETERNAL CURSE BROKEN!", 245, 285, 36, new Color(225, 221, 255))
        drawText(g, "All realms are free. Score: " + score, 340, 335, 18, Color.WHITE)
        drawText(g, "Press R to play again", 365, 370, 16, new Color(206, 195, 235))
      }
    }
  }
}

// Start the game when the complete Kojo script is run.
ShadowfallEternalCurseEvent8.main(Array[String]())