fakemon/FakeMon/src/fmon/stat/Monster.scala

104 lines
2.9 KiB
Scala

package fmon.stat
import scala.util._
import fmon._
import fmon.battle.msg._
import fmon.util._
import Monster._
import Statistic._
class Monster(val base : StorageMon) {
def level = base.level
val stats = Statistic.buildMap(computeStat)
var boosts = Statistic.buildMap(_ => 0)
var hp = stats(Hp)
def maxhp = stats(Hp)
var status : Option[Status] = None
var volatile = Seq[Status]()
def isAlive = hp > 0
def apply(s : Stat) = {
val mod = boosts.getOrElse(s, 0)
val mult = if (mod > 0) Fraction(2 + mod, 2) else Fraction(2, 2 - mod)
status.foldLeft(1.frac)((m, sts) => m * sts.onModifyStat(this, s)) * mult * stats(s)
}
def elements = base.form.elements
def takeDamage(dmg : Int) : Int = {
val actualDmg = Math.min(hp, dmg)
hp -= actualDmg
actualDmg
}
def recoverDamage(healing : Int) {
hp = Math.min(stats(Hp), hp + healing)
}
def statuses = volatile ++ status
def cureStatus()(implicit reader: SignalConsumer, rng: Random) {
status.map(_.onEnd(this))
status = None
}
def addStatus(s : Status, source: EffectSource)(implicit reader: SignalConsumer, rng: Random) = {
if (s.effectType == EffectType.Volatile && !volatile.exists(_.name == s.name)) {
volatile +:= s
s.onStart(this, source)
} else if (s.effectType == EffectType.NonVolatile && status == None) {
status = Some(s)
s.onStart(this, source)
} else {
reader ! Message("But it failed!")
}
}
def -=(s : Status)(implicit reader: SignalConsumer, rng: Random) = {
if (s.effectType == EffectType.Volatile) {
s.onEnd(this)
volatile = volatile.filterNot(_.name == s.name)
} else {
cureStatus()
}
}
def applyBoost(s : Stat, boost : Int, effect: EffectSource)(implicit reader: SignalConsumer, rng: Random) {
val modified = boosts.getOrElse(s, 0) + boost
boosts = boosts.updated(s, Math.min(Config.maxBoost, Math.max(-Config.maxBoost, modified)))
if (boost > 0) {
reader ! Message(s"$this's $s rose!")
} else if (boost < 0) {
reader ! Message(s"$this's $s fell!")
}
}
def effectiveness(element : Element) : Double = {
elements.foldLeft(1.0)((m, e) => m * (element --> e))
}
private def computeStat(s : Stat) : Int = {
val num = 2 * base.form.baseStats(s) + base.gene.ivs(s) + base.evs(s) / 4
val frac = num * level / 100
val score = if(s == Hp) frac + 10 + level else frac + 5
(score * base.gene.nature(s)).toInt
}
def name = if (base.nickname != null) base.nickname else base.form.name
override def toString = name
}
object Monster {
def generate(nickname: String, ot: TrainerID, xp: Int, form: Form, moves: IndexedSeq[Move])(implicit rng: Random) = {
new Monster(StorageMon.generate(nickname, ot, xp, form, moves))
}
}
class MonsterPtr(var mon : Monster) {
override def toString : String = mon.toString()
}