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

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