Merged some conflicts with the new damage animations

This commit is contained in:
James Daly
2019-06-17 22:23:22 -04:00
19 changed files with 609 additions and 80 deletions

View File

@@ -10,6 +10,8 @@ import scala.util.Random
import Statistic._
import fmon.battle.msg._
import fmon._
import fmon.battle.msg.{Message, SignalConsumer}
import fmon.util._
object MoveType extends Enumeration {
@@ -53,7 +55,8 @@ abstract class Move extends MoveTurn {
val desc: String
val category: MoveType
val pow: Int
val powCallback: (Monster, Move, Monster) => Int
val powCallback: (Monster, Move, Monster, SignalConsumer, Random) => Int
val damageCallback: (Monster, Move, Monster, SignalConsumer, Random) => Int
val prior: Int
val accuracy: Int
val pp: Int
@@ -76,7 +79,7 @@ abstract class Move extends MoveTurn {
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) {
if (pow > 0 || powCallback != null || damageCallback != null) {
val dmg = damageRoll(user, target)
val actualDmg = target.takeDamage(dmg)
if (dmg == actualDmg) {
@@ -136,21 +139,24 @@ abstract class Move extends MoveTurn {
}
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
val actualPow = if (powCallback != null) powCallback(user, this, target) else pow
val baseDmg = (2 * user.level / 5 + 2) * actualPow * user(atkStat) / (target(defStat) * 50) + 2
val effectiveness = target.effectiveness(element)
val multiplier = effectiveness * critMultiplier(user, target)
if (effectiveness > 1.0) {
reader ! Message("It's super effective!")
} else if (effectiveness < 1.0) {
reader ! Message("It's not very effective.")
if (damageCallback != null) {
damageCallback(user, this, target, reader, rng)
} else {
val atkStat = if (category == MoveType.Physical) PAtk else MAtk
val defStat = if (category == MoveType.Physical) PDef else MDef
val actualPow = if (powCallback != null) powCallback(user, this, target, reader, rng) else pow
val baseDmg = (2 * user.level / 5 + 2) * actualPow * user(atkStat) / (target(defStat) * 50) + 2
val effectiveness = target.effectiveness(element)
val multiplier = effectiveness * critMultiplier(user, target) * stabMultiplier(user)
if (effectiveness > 1.0) {
reader ! Message("It's super effective!")
} else if (effectiveness < 1.0) {
reader ! Message("It's not very effective.")
}
val maxDmg = (baseDmg * multiplier).toInt
val minDmg = (17 \\ 20) * maxDmg
rng.nextInt(minDmg, maxDmg)
}
val maxDmg = (baseDmg * multiplier).toInt
val minDmg = (17 \\ 20) * maxDmg
rng.nextInt(minDmg, maxDmg)
}
def critMultiplier(user: Monster, target: Monster)(implicit reader: SignalConsumer, rng: Random) = {
@@ -159,7 +165,15 @@ abstract class Move extends MoveTurn {
val chance = (1 << stage) \\ 16 // Doubles per stage
if (rng.chance(chance)) {
reader ! Message("A critical hit!")
1.5
Config.crit
} else {
1.0
}
}
def stabMultiplier(user: Monster) = {
if (user.elements.contains(element)) {
Config.stab
} else {
1.0
}
@@ -198,6 +212,7 @@ case class MoveToken(
@JsonScalaEnumeration(classOf[MoveTypeType]) val category: MoveType,
val basePower: Option[Int],
val basePowerCallback: String,
val damage: String,
val priority: Int,
val accuracy: Option[Int],
val pp: Int,
@@ -222,6 +237,7 @@ case class MoveToken(
val category = token.category
val pow = token.basePower.getOrElse(0)
val powCallback = Move.compilePowCallback(token.basePowerCallback)
val damageCallback = Move.compileDamageCallback(token.damage)
val prior = token.priority
val pp = token.pp
val element = Element(token.`type`)
@@ -250,14 +266,17 @@ object Move {
moves(name)
}
def compilePowCallback(code: String): (Monster, Move, Monster) => Int = {
def compilePowCallback(code: String): (Monster, Move, Monster, SignalConsumer, Random) => Int = {
if (code != null) {
val tb = runtimeMirror(getClass.getClassLoader).mkToolBox()
val tree = tb.parse(
s"""
|import scala.util.Random
|import fmon._
|import fmon.battle.msg._
|import fmon.stat._
|import fmon.stat.Statistic._
|def callback(user : Monster, move: Move, target : Monster): Int = {
|def callback(user : Monster, move: Move, target : Monster, reader: SignalConsumer, rng: Random): Int = {
| $code
|}
|callback _
@@ -265,10 +284,14 @@ object Move {
val f = tb.compile(tree)
val wrapper = f()
wrapper.asInstanceOf[(Monster, Move, Monster) => Int]
wrapper.asInstanceOf[(Monster, Move, Monster, SignalConsumer, Random) => Int]
} else {
null
}
}
def compileDamageCallback(code: String): (Monster, Move, Monster, SignalConsumer, Random) => Int = {
compilePowCallback(code)
}
}