Connected the battle engine to the UI. Beginning to make messages appear in the UI
This commit is contained in:
parent
2805bbf1c7
commit
0b52e91a3d
@ -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()
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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}")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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>
|
||||||
|
11
FakeMon/src/fmon/battle/msg/Message.scala
Normal file
11
FakeMon/src/fmon/battle/msg/Message.scala
Normal 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 {
|
||||||
|
|
||||||
|
}
|
@ -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]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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)
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user