Connected the battle engine to the UI. Beginning to make messages appear in the UI

This commit is contained in:
James Daly 2019-06-13 22:22:57 -04:00
parent 2805bbf1c7
commit 0b52e91a3d
11 changed files with 109 additions and 61 deletions

View File

@ -40,7 +40,7 @@ class Game extends Application {
val url = getClass.getResource("battle/battle.fxml") val url = getClass.getResource("battle/battle.fxml")
val loader = new FXMLLoader(url) val loader = new FXMLLoader(url)
val root: Parent = loader.load() val root: Parent = loader.load()
val controller = loader.getController[BattleUI]() implicit val controller = loader.getController[BattleUI]()
val scene: Scene = new Scene(root) val scene: Scene = new Scene(root)
implicit val rng = new scala.util.Random() implicit val rng = new scala.util.Random()

View File

@ -2,11 +2,12 @@ package fmon.battle
import scala.util.Random import scala.util.Random
import fmon.battle.msg._
import fmon.stat._ import fmon.stat._
import fmon.stat.Statistic._ import fmon.stat.Statistic._
import fmon.util.Fraction import fmon.util.Fraction
class BattleEngine(val player: Party, val enemy: Party)(implicit val rng: Random) { class BattleEngine(val player: Party, val enemy: Party)(implicit val reader: SignalConsumer, val rng: Random) extends SignalConsumer {
def play() = { def play() = {
println(player.lead.level) println(player.lead.level)
@ -15,8 +16,6 @@ class BattleEngine(val player: Party, val enemy: Party)(implicit val rng: Random
} }
} }
def playTurn(): Unit = { def playTurn(): Unit = {
val playerAction = player.pollAction(enemy) val playerAction = player.pollAction(enemy)
playTurn(playerAction) playTurn(playerAction)
@ -36,7 +35,7 @@ class BattleEngine(val player: Party, val enemy: Party)(implicit val rng: Random
val replace = player.pollReplacement(enemy) val replace = player.pollReplacement(enemy)
player.switchIn(replace) player.switchIn(replace)
} else { } else {
println(s"${player.trainer} has lost!") this ! Message(s"${player.trainer} has lost!")
} }
} }
if (!enemy.lead.isAlive) { if (!enemy.lead.isAlive) {
@ -47,9 +46,6 @@ class BattleEngine(val player: Party, val enemy: Party)(implicit val rng: Random
println(s"${enemy.trainer} has lost!") println(s"${enemy.trainer} has lost!")
} }
} }
println(s"${player.lead}(${player.lead.hp}/${player.lead(Hp)})")
println(s"${enemy.lead}(${enemy.lead.hp}/${enemy.lead(Hp)})")
} }
def useMove(action: Action) = { def useMove(action: Action) = {
@ -62,4 +58,8 @@ class BattleEngine(val player: Party, val enemy: Party)(implicit val rng: Random
} }
} }
} }
def !(msg: Signal) = {
reader ! msg
}
} }

View File

@ -10,10 +10,11 @@ import scalafx.scene.Parent
import scalafx.scene.control._ import scalafx.scene.control._
import scalafx.scene.layout._ import scalafx.scene.layout._
import fmon.battle.msg._
import fmon.stat._ import fmon.stat._
import fmon.stat.Statistic._ import fmon.stat.Statistic._
class BattleUI { class BattleUI extends SignalConsumer {
@FXML var usName: jfxsc.Label = _ @FXML var usName: jfxsc.Label = _
@FXML var usLv: jfxsc.Label = _ @FXML var usLv: jfxsc.Label = _
@FXML var usHealth: jfxsc.Label = _ @FXML var usHealth: jfxsc.Label = _
@ -23,32 +24,50 @@ class BattleUI {
@FXML var themHealth: jfxsc.Label = _ @FXML var themHealth: jfxsc.Label = _
@FXML var themHealthBar: jfxsc.ProgressBar = _ @FXML var themHealthBar: jfxsc.ProgressBar = _
@FXML var buttonPane: javafx.scene.layout.VBox = _ @FXML var buttonPane: javafx.scene.layout.VBox = _
@FXML var messages: jfxsc.TextArea = _
private var engine: BattleEngine = _ private var engine: BattleEngine = _
def setEngine(engine: BattleEngine): Unit = { def setEngine(engine: BattleEngine): Unit = {
this.engine = engine
updateUI()
}
def updateUI(): Unit = {
val player = engine.player.lead val player = engine.player.lead
usName.text = player.name usName.text = player.name
usLv.text = s"Lv. ${player.level}" usLv.text = s"Lv. ${player.level}"
usHealth.text = s"${player.hp}/${player.maxhp}" usHealth.text = s"${player.hp}/${player.maxhp}"
usHealthBar.progress = player.hp / player.maxhp usHealthBar.progress = player.hp.toDouble / player.maxhp
val enemy = engine.enemy.lead val enemy = engine.enemy.lead
themName.text = enemy.name themName.text = enemy.name
themLv.text = s"Lv. ${enemy.level}" themLv.text = s"Lv. ${enemy.level}"
themHealth.text = s"${enemy.hp}/${enemy.maxhp}" themHealth.text = s"${enemy.hp}/${enemy.maxhp}"
themHealthBar.progress = enemy.hp / enemy.maxhp themHealthBar.progress = enemy.hp.toDouble / enemy.maxhp
val buttons = player.base.moves.map(move => loadMoveButton(move)) val buttons = player.base.moves.map(move => loadMoveButton(move))
buttonPane.children = buttons buttonPane.children = buttons
} }
def onMove(move: Move): Unit = {
val action = Action(engine.player.lead, move, engine.enemy.lead)
engine.playTurn(action)
updateUI()
}
def !(msg: Signal): Unit = {
msg match {
case Message(text) => messages.text = s"${messages.text()}${text}\n"
}
}
private def loadMoveButton(move: Move): Button = { private def loadMoveButton(move: Move): Button = {
val fxmlLoader = new FXMLLoader(getClass.getResource("moveButton.fxml")) val fxmlLoader = new FXMLLoader(getClass.getResource("moveButton.fxml"))
fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory()) fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory())
val button = fxmlLoader.load[jfxsc.Button]() val button = fxmlLoader.load[jfxsc.Button]()
val controller = fxmlLoader.getController[MoveButton]() val controller = fxmlLoader.getController[MoveButton]()
controller.setup(move) controller.setup(move, onMove)
button button
} }
} }

View File

@ -13,15 +13,16 @@ class MoveButton {
@FXML var moveName: jfxsc.Label = _ @FXML var moveName: jfxsc.Label = _
@FXML var moveUses: jfxsc.Label = _ @FXML var moveUses: jfxsc.Label = _
private var move: Move = _ private var move: Move = _
private var callback: Move => Unit = _
def setup(mv: Move): Unit = { def setup(mv: Move, callback: Move => Unit): Unit = {
move = mv move = mv
moveName.text = mv.name moveName.text = mv.name
moveUses.text = s"${move.pp}/${move.pp}" moveUses.text = s"${move.pp}/${move.pp}"
this.callback = callback
} }
def moveActivate(): Unit = { def moveActivate(): Unit = {
println("We should take a turn here") callback(move)
println(s"${moveBtn.width}")
} }
} }

View File

@ -7,6 +7,7 @@
<?import javafx.scene.control.ProgressBar?> <?import javafx.scene.control.ProgressBar?>
<?import javafx.scene.control.ScrollPane?> <?import javafx.scene.control.ScrollPane?>
<?import javafx.scene.control.SeparatorMenuItem?> <?import javafx.scene.control.SeparatorMenuItem?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.image.Image?> <?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?> <?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?> <?import javafx.scene.layout.AnchorPane?>
@ -132,11 +133,12 @@
</Label> </Label>
</children> </children>
</GridPane> </GridPane>
<ScrollPane hbarPolicy="NEVER" layoutX="616.0" layoutY="344.0" prefHeight="200.0" prefWidth="200.0"> <ScrollPane hbarPolicy="NEVER" layoutX="32.0" layoutY="29.0" prefHeight="200.0" prefWidth="200.0">
<content> <content>
<VBox fx:id="buttonPane" /> <VBox fx:id="buttonPane" />
</content> </content>
</ScrollPane> </ScrollPane>
<TextArea fx:id="messages" layoutX="440.0" layoutY="449.0" prefHeight="112.0" prefWidth="399.0" />
</children> </children>
</AnchorPane> </AnchorPane>
</children> </children>

View File

@ -0,0 +1,11 @@
package fmon.battle.msg
trait SignalConsumer {
def !(msg: Signal): Unit
}
trait Signal
case class Message(val text: String) extends Signal {
}

View File

@ -5,6 +5,7 @@ import scala.tools.reflect.ToolBox
import scala.io.Source import scala.io.Source
import scala.util.Random import scala.util.Random
import fmon.battle.msg.SignalConsumer
import fmon.util._ import fmon.util._
abstract class Ability extends Effect { abstract class Ability extends Effect {
@ -13,9 +14,10 @@ abstract class Ability extends Effect {
def effectType = EffectType.AbilityEffect def effectType = EffectType.AbilityEffect
def onAfterDamage(source: Monster, move: MoveTurn, mon: Monster, dmg: Int)(implicit rng: Random) = onAfterDamageImp(this, source, move, mon, dmg, rng) def onAfterDamage(source: Monster, move: MoveTurn, mon: Monster, dmg: Int)(implicit reader: SignalConsumer, rng: Random) =
onAfterDamageImp(this, source, move, mon, dmg, reader, rng)
protected val onAfterDamageImp: (Ability, Monster, MoveTurn, Monster, Int, Random) => Unit protected val onAfterDamageImp: (Ability, Monster, MoveTurn, Monster, Int, SignalConsumer, Random) => Unit
override def toString = name override def toString = name
} }
@ -50,6 +52,7 @@ object Ability {
private val header = """ private val header = """
|import scala.util.Random |import scala.util.Random
|import fmon.battle.msg._
|import fmon.stat._ |import fmon.stat._
|import fmon.stat.MoveType._ |import fmon.stat.MoveType._
|import fmon.stat.Statistic._ |import fmon.stat.Statistic._
@ -57,20 +60,21 @@ object Ability {
""" """
private val helper = """ private val helper = """
implicit val gen = rng implicit val gen = rng
implicit val signalConsumer = reader
def trigger { def trigger {
print(s"[${mon}'s ${self}]") reader ! Message(s"[${mon}'s ${self}]")
} }
def effect = EffectSource(mon, self) def effect = EffectSource(mon, self)
""" """
def compileOnAfterDamage(code: String): (Ability, Monster, MoveTurn, Monster, Int, Random) => Unit = { def compileOnAfterDamage(code: String): (Ability, Monster, MoveTurn, Monster, Int, SignalConsumer, Random) => Unit = {
if (code == null) { if (code == null) {
(_, _, _, _, _, _) => () (_, _, _, _, _, _, _) => ()
} else { } else {
val tree = tb.parse( val tree = tb.parse(
s""" s"""
|$header |$header
|def onAfterDamage(self: Ability, source: Monster, move: MoveTurn, mon: Monster, damage: Int, rng: Random): Unit = { |def onAfterDamage(self: Ability, source: Monster, move: MoveTurn, mon: Monster, damage: Int, reader: SignalConsumer, rng: Random): Unit = {
| $helper | $helper
| $code | $code
|} |}
@ -79,7 +83,7 @@ object Ability {
val f = tb.compile(tree) val f = tb.compile(tree)
val wrapper = f() val wrapper = f()
implicit val c = code implicit val c = code
wrapper.asInstanceOf[(Ability, Monster, MoveTurn, Monster, Int, Random) => Unit] wrapper.asInstanceOf[(Ability, Monster, MoveTurn, Monster, Int, SignalConsumer, Random) => Unit]
} }
} }
} }

View File

@ -2,6 +2,7 @@ package fmon.stat
import scala.util._ import scala.util._
import fmon.battle.msg._
import fmon.util._ import fmon.util._
import Monster._ import Monster._
@ -45,7 +46,7 @@ class Monster(val base : StorageMon) {
status = None status = None
} }
def addStatus(s : Status, source: EffectSource)(implicit rng: Random) = { def addStatus(s : Status, source: EffectSource)(implicit reader: SignalConsumer, rng: Random) = {
if (s.effectType == EffectType.Volatile && !volatile.exists(_.name == s.name)) { if (s.effectType == EffectType.Volatile && !volatile.exists(_.name == s.name)) {
volatile +:= s volatile +:= s
s.onStart(this, source) s.onStart(this, source)

View File

@ -9,6 +9,7 @@ import scala.io.Source
import scala.util.Random import scala.util.Random
import Statistic._ import Statistic._
import fmon.battle.msg.{Message, SignalConsumer}
import fmon.util._ import fmon.util._
object MoveType extends Enumeration { object MoveType extends Enumeration {
@ -28,7 +29,7 @@ trait MoveTurn extends Effect {
def prior: Int def prior: Int
def target: Target def target: Target
def category: MoveType def category: MoveType
def useMove(user: Monster, target: Monster)(implicit rng: Random): Unit def useMove(user: Monster, target: Monster)(implicit reader: SignalConsumer, rng: Random): Unit
} }
class SwitchOut(val party: Party, val replacement: Monster) extends MoveTurn { class SwitchOut(val party: Party, val replacement: Monster) extends MoveTurn {
@ -38,10 +39,10 @@ class SwitchOut(val party: Party, val replacement: Monster) extends MoveTurn {
def target = Target.Self def target = Target.Self
def category = MoveType.Other def category = MoveType.Other
def useMove(user: Monster, target: Monster)(implicit rng: Random): Unit = { def useMove(user: Monster, target: Monster)(implicit reader: SignalConsumer, rng: Random): Unit = {
println(s"${party.trainer} withdrew $user!") reader ! Message(s"${party.trainer} withdrew $user!")
party.switchIn(replacement) party.switchIn(replacement)
println(s"${party.trainer} sent out $replacement") reader ! Message(s"${party.trainer} sent out $replacement")
} }
override def toString: String = s"Swap -> $replacement" override def toString: String = s"Swap -> $replacement"
@ -72,34 +73,34 @@ abstract class Move extends MoveTurn {
// zPower, zMoveEffect, zMoveBoost // zPower, zMoveEffect, zMoveBoost
override def useMove(user: Monster, target: Monster)(implicit rng: Random) = { override def useMove(user: Monster, target: Monster)(implicit reader: SignalConsumer, rng: Random) = {
println(s"$user used $name.") reader ! Message(s"$user used $name.")
if (attackRoll(user, target)) { if (attackRoll(user, target)) {
if (pow > 0 || powCallback != null) { if (pow > 0 || powCallback != null) {
val dmg = damageRoll(user, target) val dmg = damageRoll(user, target)
val actualDmg = target.takeDamage(dmg) val actualDmg = target.takeDamage(dmg)
if (dmg == actualDmg) { if (dmg == actualDmg) {
println(s"$target takes $actualDmg damage!") reader ! Message(s"$target takes $actualDmg damage!")
} else { } else {
println(s"$target takes $actualDmg (+${dmg - actualDmg} overkill) damage!") reader ! Message(s"$target takes $actualDmg (+${dmg - actualDmg} overkill) damage!")
} }
if (drain > 0.frac) { if (drain > 0.frac) {
val healing = Math.max(drain * actualDmg, 1) val healing = Math.max(drain * actualDmg, 1)
user.recoverDamage(healing) user.recoverDamage(healing)
println(s"$user recovered $healing damage.") reader ! Message(s"$user recovered $healing damage.")
} else if (drain < 0.frac) { } else if (drain < 0.frac) {
val recoil = Math.max(-drain * actualDmg, 1) val recoil = Math.max(-drain * actualDmg, 1)
user.takeDamage(recoil) user.takeDamage(recoil)
println(s"$user took $recoil damage from recoil!") reader ! Message(s"$user took $recoil damage from recoil!")
} }
target.base.ability.onAfterDamage(user, this, target, actualDmg) target.base.ability.onAfterDamage(user, this, target, actualDmg)
if (!user.isAlive) { if (!user.isAlive) {
println(s"$user fainted!") reader ! Message(s"$user fainted!")
} }
if (!target.isAlive) { if (!target.isAlive) {
println(s"$target fainted!") reader ! Message(s"$target fainted!")
} }
} }
applyBoosts(target, boosts, user) applyBoosts(target, boosts, user)
@ -116,11 +117,11 @@ abstract class Move extends MoveTurn {
// TODO : Multiparty // TODO : Multiparty
} else { } else {
println("Missed!") reader ! Message("Missed!")
} }
} }
def attackRoll(user: Monster, target: Monster)(implicit rng: Random) = { def attackRoll(user: Monster, target: Monster)(implicit reader: SignalConsumer, rng: Random) = {
if (accuracy == 0) { if (accuracy == 0) {
true true
} else { } else {
@ -131,7 +132,7 @@ abstract class Move extends MoveTurn {
} }
} }
def damageRoll(user: Monster, target: Monster)(implicit rng: Random) = { def damageRoll(user: Monster, target: Monster)(implicit reader: SignalConsumer, rng: Random) = {
val atkStat = if (category == MoveType.Physical) PAtk else MAtk val atkStat = if (category == MoveType.Physical) PAtk else MAtk
val defStat = if (category == MoveType.Physical) PDef else MDef val defStat = if (category == MoveType.Physical) PDef else MDef
// TODO : Fixed damage // TODO : Fixed damage
@ -140,34 +141,34 @@ abstract class Move extends MoveTurn {
val effectiveness = target.effectiveness(element) val effectiveness = target.effectiveness(element)
val multiplier = effectiveness * critMultiplier(user, target) val multiplier = effectiveness * critMultiplier(user, target)
if (effectiveness > 1.0) { if (effectiveness > 1.0) {
println("It's super effective!") reader ! Message("It's super effective!")
} else if (effectiveness < 1.0) { } else if (effectiveness < 1.0) {
println("It's not very effective.") reader ! Message("It's not very effective.")
} }
val maxDmg = (baseDmg * multiplier).toInt val maxDmg = (baseDmg * multiplier).toInt
val minDmg = (17 \\ 20) * maxDmg val minDmg = (17 \\ 20) * maxDmg
rng.nextInt(minDmg, maxDmg) rng.nextInt(minDmg, maxDmg)
} }
def critMultiplier(user: Monster, target: Monster)(implicit rng: Random) = { def critMultiplier(user: Monster, target: Monster)(implicit reader: SignalConsumer, rng: Random) = {
// Percentage chance is different from Pokemon // Percentage chance is different from Pokemon
val stage = crit val stage = crit
val chance = (1 << stage) \\ 16 // Doubles per stage val chance = (1 << stage) \\ 16 // Doubles per stage
if (rng.chance(chance)) { if (rng.chance(chance)) {
println("A critical hit!") reader ! Message("A critical hit!")
1.5 1.5
} else { } else {
1.0 1.0
} }
} }
def applyEffect(target: Monster, source: Monster, effect: Secondary)(implicit rng: Random) { def applyEffect(target: Monster, source: Monster, effect: Secondary)(implicit reader: SignalConsumer, rng: Random) {
applyBoosts(target, effect.boosts, source) applyBoosts(target, effect.boosts, source)
applyStatus(target, source, effect.status) applyStatus(target, source, effect.status)
applyStatus(target, source, effect.volatile) applyStatus(target, source, effect.volatile)
} }
def applyStatus(target: Monster, user: Monster, status: StatusTemplate)(implicit rng: Random) { def applyStatus(target: Monster, user: Monster, status: StatusTemplate)(implicit reader: SignalConsumer, rng: Random) {
if (target.isAlive && status != null) { if (target.isAlive && status != null) {
target.addStatus(status.build, EffectSource(user, this)) target.addStatus(status.build, EffectSource(user, this))
} }

View File

@ -7,6 +7,7 @@ import scala.util.Random
import scala.io.Source import scala.io.Source
import fmon.battle.msg._
import fmon.util._ import fmon.util._
import EffectType.Volatile import EffectType.Volatile
@ -47,11 +48,11 @@ class Status(template: StatusTemplate) extends Effect {
def name = template.name def name = template.name
// val id // val id
def effectType = template.effectType def effectType = template.effectType
def onStart(mon: Monster, source: EffectSource)(implicit rng: Random) = template.onStart(this, mon, source, rng) def onStart(mon: Monster, source: EffectSource)(implicit reader: SignalConsumer, rng: Random) = template.onStart(this, mon, source, reader, rng)
def onEnd(mon: Monster) = template.onEnd(this, mon) def onEnd(mon: Monster) = template.onEnd(this, mon)
def onModifyStat(mon: Monster, stat: Stat) = template.onModifyStat(this, mon, stat) def onModifyStat(mon: Monster, stat: Stat) = template.onModifyStat(this, mon, stat)
// val onBeforeMovePriority : Int // val onBeforeMovePriority : Int
def onBeforeMove(mon: Monster, move: MoveTurn, target: Monster)(implicit rng: Random) = template.onBeforeMove(this, mon, move, target, rng) def onBeforeMove(mon: Monster, move: MoveTurn, target: Monster)(implicit reader: SignalConsumer, rng: Random) = template.onBeforeMove(this, mon, move, target, reader, rng)
// val onModifyMove // val onModifyMove
// val onHit // val onHit
def onResidualOrder = template.onResidualOrder def onResidualOrder = template.onResidualOrder
@ -68,11 +69,11 @@ abstract class StatusTemplate {
val name: String val name: String
// val id // val id
val effectType: EffectType val effectType: EffectType
val onStart: (Status, Monster, EffectSource, Random) => Unit val onStart: (Status, Monster, EffectSource, SignalConsumer, Random) => Unit
val onEnd: (Status, Monster) => Unit val onEnd: (Status, Monster) => Unit
val onModifyStat: (Status, Monster, Stat) => Fraction val onModifyStat: (Status, Monster, Stat) => Fraction
// val onBeforeMovePriority : Int // val onBeforeMovePriority : Int
val onBeforeMove: (Status, Monster, MoveTurn, Monster, Random) => Boolean val onBeforeMove: (Status, Monster, MoveTurn, Monster, SignalConsumer, Random) => Boolean
// val onModifyMove // val onModifyMove
// val onHit // val onHit
val onResidualOrder: Int val onResidualOrder: Int
@ -122,27 +123,34 @@ object Status {
private val tb = runtimeMirror(getClass.getClassLoader).mkToolBox() private val tb = runtimeMirror(getClass.getClassLoader).mkToolBox()
private val header = """ private val header = """
import scala.util.Random import scala.util.Random
import fmon.battle.msg._
import fmon.stat._ import fmon.stat._
import fmon.stat.MoveType._ import fmon.stat.MoveType._
import fmon.stat.Statistic._ import fmon.stat.Statistic._
import fmon.util._ import fmon.util._
""" """
private val helpers = """
def msg(text: String): Unit = {
reader ! Message(text)
}
"""
def compileOnStart(code: String): (Status, Monster, EffectSource, Random ) => Unit = { def compileOnStart(code: String): (Status, Monster, EffectSource, SignalConsumer, Random ) => Unit = {
if (code == null) { if (code == null) {
(_, _, _, _) => () (_, _, _, _, _) => ()
} else { } else {
val tree = tb.parse( val tree = tb.parse(
s""" s"""
|$header |$header
|def onStart(self:Status, mon: Monster, source: EffectSource, rng: Random) = { |def onStart(self:Status, mon: Monster, source: EffectSource, reader: SignalConsumer, rng: Random) = {
| $helpers
| $code | $code
|} |}
|onStart _ |onStart _
""".stripMargin) """.stripMargin)
val f = tb.compile(tree) val f = tb.compile(tree)
val wrapper = f() val wrapper = f()
wrapper.asInstanceOf[(Status, Monster, EffectSource, Random) => Unit] wrapper.asInstanceOf[(Status, Monster, EffectSource, SignalConsumer, Random) => Unit]
} }
} }
@ -164,14 +172,15 @@ object Status {
} }
} }
def compileOnBeforeMove(code: String): (Status, Monster, MoveTurn, Monster, Random) => Boolean = { def compileOnBeforeMove(code: String): (Status, Monster, MoveTurn, Monster, SignalConsumer, Random) => Boolean = {
if (code == null) { if (code == null) {
(_, _, _, _, _) => true (_, _, _, _, _, _) => true
} else { } else {
val tree = tb.parse( val tree = tb.parse(
s""" s"""
$header $header
def onBeforeMove(self: Status, mon: Monster, move: MoveTurn, target: Monster, rng: Random): Boolean = { def onBeforeMove(self: Status, mon: Monster, move: MoveTurn, target: Monster, reader: SignalConsumer, rng: Random): Boolean = {
$helpers
$code $code
} }
onBeforeMove _ onBeforeMove _
@ -179,7 +188,7 @@ object Status {
val f = tb.compile(tree) val f = tb.compile(tree)
val wrapper = f() val wrapper = f()
wrapper.asInstanceOf[(Status, Monster, MoveTurn, Monster, Random) => Boolean] wrapper.asInstanceOf[(Status, Monster, MoveTurn, Monster, SignalConsumer, Random) => Boolean]
} }
} }

View File

@ -13,7 +13,7 @@ brn:
if (!source.isMove) { if (!source.isMove) {
print(s"[${source.mon}'s ${source.effect}]") print(s"[${source.mon}'s ${source.effect}]")
} }
println(s"${mon} was burned!") msg(s"${mon} was burned!")
/* /*
if (sourceEffect && sourceEffect.id === 'flameorb') { if (sourceEffect && sourceEffect.id === 'flameorb') {
target.status = Status('brn', '[from] 'item': Flame Orb'); target.status = Status('brn', '[from] 'item': Flame Orb');
@ -45,7 +45,7 @@ confusion:
val maxDmg = (2 * mon.level / 5 + 2) * 40 * mon(PAtk) / (mon(PDef) * 50) + 2 val maxDmg = (2 * mon.level / 5 + 2) * 40 * mon(PAtk) / (mon(PDef) * 50) + 2
val minDmg = (17 \\ 20) * maxDmg val minDmg = (17 \\ 20) * maxDmg
val dmg = rng.nextInt(minDmg, maxDmg) val dmg = rng.nextInt(minDmg, maxDmg)
println(s"${mon} hurt itself in its confusion.") msg(s"${mon} hurt itself in its confusion.")
mon.takeDamage(dmg) mon.takeDamage(dmg)
false false
} else { } else {
@ -65,7 +65,7 @@ confusion:
onBeforeMovePriority: 3 onBeforeMovePriority: 3
onEnd: println(s"${mon} snapped out of its confusion.") onEnd: println(s"${mon} snapped out of its confusion.")
onStart: |- onStart: |-
println(s"${mon} was confused!") msg(s"${mon} was confused!")
/* /*
if (sourceEffect && sourceEffect.id === 'lockedmove') { if (sourceEffect && sourceEffect.id === 'lockedmove') {
this.add('-start', target, 'confusion', '[fatigue]'); this.add('-start', target, 'confusion', '[fatigue]');
@ -102,7 +102,7 @@ par:
onBeforeMovePriority: 1 onBeforeMovePriority: 1
onBeforeMove: | onBeforeMove: |
if (rng.chance(1, 4)) { if (rng.chance(1, 4)) {
println(s"${mon} is fully paralyzed!") msg(s"${mon} is fully paralyzed!")
false false
} else { } else {
true true