diff --git a/FakeMon/src/fmon/Game.scala b/FakeMon/src/fmon/Game.scala index aa61187..3064738 100644 --- a/FakeMon/src/fmon/Game.scala +++ b/FakeMon/src/fmon/Game.scala @@ -14,13 +14,12 @@ case class Prop(url : Seq[String]) object Game { def main(args : Array[String]): Unit = { - println(Element("Water").effect) - println(Status("psn")) + implicit val rng = new scala.util.Random() val form1 = Form("Diabolo") val form2 = Form("Chanilla") - val movepool1 = IndexedSeq(Move("Ice Beam")) - val movepool2 = IndexedSeq(Move("Scald")) + val movepool1 = IndexedSeq(Move("Aqua Jet")) + val movepool2 = IndexedSeq(Move("Thunder Wave")) val p1 = TrainerID("Jaeda", Gender.Female, 0) val p2 = TrainerID("Wild Monster", Gender.Male, 0) val party1 = new Party(p1, new MonsterPtr(new Monster(new StorageMon("Allied Mon", 500, Gene.randomGene(null, form1), form1, Statistic.emptyEvs, movepool1))), IndexedSeq()) diff --git a/FakeMon/src/fmon/battle/BattleEngine.scala b/FakeMon/src/fmon/battle/BattleEngine.scala index 579c16e..0ae5985 100644 --- a/FakeMon/src/fmon/battle/BattleEngine.scala +++ b/FakeMon/src/fmon/battle/BattleEngine.scala @@ -51,7 +51,7 @@ class BattleEngine(val player: Party, val enemy: Party)(implicit val rng: Random val move = action.move val target = action.target if (user.isAlive) { - if (user.status.forall(_.onBeforeMove(user, move, target, rng))) { + if (user.status.forall(_.onBeforeMove(user, move, target))) { move.useMove(user, target) } } diff --git a/FakeMon/src/fmon/stat/Move.scala b/FakeMon/src/fmon/stat/Move.scala index bc3493e..c4a312f 100644 --- a/FakeMon/src/fmon/stat/Move.scala +++ b/FakeMon/src/fmon/stat/Move.scala @@ -58,7 +58,7 @@ abstract class Move extends MoveTurn { val target: Target val boosts: Map[Stat, Int] val crit: Int - val status: Status + val status: StatusTemplate val drain: Fraction val selfEffect: Secondary val secondary: Secondary @@ -152,17 +152,18 @@ abstract class Move extends MoveTurn { } } - def applyEffect(target: Monster, effect: Secondary) { + def applyEffect(target: Monster, effect: Secondary)(implicit rng: Random) { applyBoosts(target, effect.boosts) applyStatus(target, effect.status) } - def applyStatus(target: Monster, status: Status) { + def applyStatus(target: Monster, status: StatusTemplate)(implicit rng: Random) { if (target.isAlive && status != null) { if (target.status == None) { // apply status - target.status = Some(status) - status.onStart(target) + val s = status.build + target.status = Some(s) + s.onStart(target) } else { println("But it failed!") } diff --git a/FakeMon/src/fmon/stat/Secondary.scala b/FakeMon/src/fmon/stat/Secondary.scala index 4a1f212..150f969 100644 --- a/FakeMon/src/fmon/stat/Secondary.scala +++ b/FakeMon/src/fmon/stat/Secondary.scala @@ -3,7 +3,7 @@ package fmon.stat abstract class Secondary { val chance : Int val boosts : Map[Stat, Int] - val status : Status + val status : StatusTemplate // val volatileStatus //val onHit : // val self diff --git a/FakeMon/src/fmon/stat/Status.scala b/FakeMon/src/fmon/stat/Status.scala index b4002f6..213175e 100644 --- a/FakeMon/src/fmon/stat/Status.scala +++ b/FakeMon/src/fmon/stat/Status.scala @@ -1,5 +1,6 @@ package fmon.stat +import scala.collection.mutable.{Map => MutMap} import scala.reflect.runtime.universe._ import scala.tools.reflect.ToolBox import scala.util.Random @@ -8,21 +9,44 @@ import scala.io.Source import fmon.util._ -abstract class Status { +class Status(template: StatusTemplate) { + def name = template.name + // val id + // val effectType + def onStart(mon: Monster)(implicit rng: Random) = template.onStart(this, mon, rng) + def onEnd(mon: Monster) = template.onEnd(this, mon) + def onModifyStat(mon: Monster, stat: Stat) = template.onModifyStat(this, mon, stat) + // val onBeforeMovePriority : Int + def onBeforeMove(mon: Monster, move: MoveTurn, target: Monster)(implicit rng: Random) = template.onBeforeMove(this, mon, move, target, rng) + // val onModifyMove + // val onHit + def onResidualOrder = template.onResidualOrder + def onResidual(mon: Monster) = template.onResidual(this, mon) + // val onSwitchIn + + val intData: MutMap[String, Int] = MutMap[String, Int]() + val stringData = MutMap[String, String]() + + override def toString = name +} + +abstract class StatusTemplate { val name: String // val id // val effectType - val onStart: Monster => Unit - val onEnd: Monster => Unit - val onModifyStat: (Monster, Stat) => Fraction + val onStart: (Status, Monster, Random) => Unit + val onEnd: (Status, Monster) => Unit + val onModifyStat: (Status, Monster, Stat) => Fraction // val onBeforeMovePriority : Int - val onBeforeMove: (Monster, MoveTurn, Monster, Random) => Boolean + val onBeforeMove: (Status, Monster, MoveTurn, Monster, Random) => Boolean // val onModifyMove // val onHit val onResidualOrder: Int - val onResidual: Monster => Unit + val onResidual: (Status, Monster) => Unit // val onSwitchIn + def build = new Status(this) + override def toString = name } @@ -36,10 +60,10 @@ case class StatusToken( val onResidual: String) { def instantiate() = { val self = this - new Status { + new StatusTemplate { val name = self.name val onStart = Status.compileOnStart(self.onStart) - val onEnd = Status.compileOnStart(self.onEnd) + val onEnd = Status.compileOnEnd(self.onEnd) val onBeforeMove = Status.compileOnBeforeMove(self.onBeforeMove) val onModifyStat = Status.compileOnModifyStat(self.onModifyStat) val onResidualOrder = self.onResidualOrder @@ -49,7 +73,7 @@ case class StatusToken( } object Status { - private var statuses = Map[String, Status]() + private var statuses = Map[String, StatusTemplate]() val tokens = YamlHelper.extractSeq[StatusToken](Source.fromInputStream(Move.getClass.getResourceAsStream("data/statuses.yaml"))).map(t => (t.name, t)).toMap def apply(name: String) = { @@ -61,74 +85,97 @@ object Status { private val tb = runtimeMirror(getClass.getClassLoader).mkToolBox() - def compileOnStart(code: String): (Monster /*, source, source effect */ ) => Unit = { + def compileOnStart(code: String): (Status, Monster /*, source, source effect */, Random ) => Unit = { if (code == null) { - _ => () + (_, _, _) => () } else { val tree = tb.parse( s""" + |import scala.util.Random |import fmon.stat._ |import fmon.stat.Statistic._ - |def onStart(mon : Monster) = { + |import fmon.util._ + |def onStart(self:Status, mon: Monster, rng: Random) = { | $code |} |onStart _ """.stripMargin) val f = tb.compile(tree) val wrapper = f() - wrapper.asInstanceOf[Monster => Unit] + wrapper.asInstanceOf[(Status, Monster, Random) => Unit] + } + } + + def compileOnEnd(code: String): (Status, Monster) => Unit = { + if (code == null) { + (_, _) => () + } else { + val tree = tb.parse( + s""" + |import fmon.stat._ + |import fmon.stat.Statistic._ + |import fmon.util._ + |def onStart(self:Status, mon: Monster) = { + | $code + |} + |onStart _ + """.stripMargin) + val f = tb.compile(tree) + val wrapper = f() + wrapper.asInstanceOf[(Status, Monster) => Unit] } } - def compileOnBeforeMove(code: String): (Monster, MoveTurn, Monster, Random) => Boolean = { + def compileOnBeforeMove(code: String): (Status, Monster, MoveTurn, Monster, Random) => Boolean = { if (code == null) { - (_, _, _, _) => true + (_, _, _, _, _) => true } else { val tree = tb.parse( s""" import scala.util.Random import fmon.stat._ import fmon.stat.Statistic._ - def onBeforeMove(mon: Monster, move: MoveTurn, target: Monster, rng: Random): Boolean = { + def onBeforeMove(self: Status, mon: Monster, move: MoveTurn, target: Monster, rng: Random): Boolean = { $code } onBeforeMove _ """) val f = tb.compile(tree) val wrapper = f() - wrapper.asInstanceOf[(Monster, MoveTurn, Monster, Random) => Boolean] + wrapper.asInstanceOf[(Status, Monster, MoveTurn, Monster, Random) => Boolean] } } - def compileOnModifyStat(code: String): (Monster, Stat) => Fraction = { + def compileOnModifyStat(code: String): (Status, Monster, Stat) => Fraction = { if (code == null) { - (_, _) => 1.frac + (_, _, _) => 1.frac } else { val tree = tb.parse( s""" import fmon.stat._ import fmon.stat.Statistic._ import fmon.util._ - def onModifyStat(mon: Monster, stat: Stat): Fraction = { + def onModifyStat(self: Status, mon: Monster, stat: Stat): Fraction = { $code } onModifyStat _ """) val f = tb.compile(tree) val wrapper = f() - wrapper.asInstanceOf[(Monster, Stat) => Fraction] + wrapper.asInstanceOf[(Status, Monster, Stat) => Fraction] } } - def compileOnResidual(code: String): Monster => Unit = { + def compileOnResidual(code: String): (Status, Monster) => Unit = { if (code == null) { - _ => () + (_, _) => () } else { val tree = tb.parse( s""" |import fmon.stat._ |import fmon.stat.Statistic._ - |def onResidual(mon : Monster) = { + |import fmon.util._ + |def onResidual(self: Status, mon: Monster) = { | $code |} |onResidual _ @@ -136,7 +183,7 @@ object Status { val f = tb.compile(tree) val wrapper = f() - wrapper.asInstanceOf[Monster => Unit] + wrapper.asInstanceOf[(Status, Monster) => Unit] } } } \ No newline at end of file diff --git a/FakeMon/src/fmon/stat/data/moves.yaml b/FakeMon/src/fmon/stat/data/moves.yaml index a8d2fcc..3dea64e 100644 --- a/FakeMon/src/fmon/stat/data/moves.yaml +++ b/FakeMon/src/fmon/stat/data/moves.yaml @@ -278,6 +278,28 @@ zMovePower: 100 contestType: "Tough" +- name: Spore + accuracy: 100 + basePower: 0 + category: Status + contestType: Beautiful + flags: + mirror: 1 + powder: 1 + protect: 1 + reflectable: 1 + id: spore + isViable: true + num: 147 + pp: 15 + priority: 0 + secondary: null + shortDesc: Causes the target to fall asleep. + status: slp + target: Normal + type: Grass + zMoveEffect: clearnegativeboost + - name: Tackle num: 33 accuracy: 100 diff --git a/FakeMon/src/fmon/stat/data/statuses.yaml b/FakeMon/src/fmon/stat/data/statuses.yaml index f58eacc..a320d98 100644 --- a/FakeMon/src/fmon/stat/data/statuses.yaml +++ b/FakeMon/src/fmon/stat/data/statuses.yaml @@ -60,6 +60,8 @@ num: 0 effectType: 'Status' onStart: | + println(s"${mon} fell asleep!") + /* if (sourceEffect && sourceEffect.effectType === 'Ability') { this.add('-status', target, 'slp', '[from] ability: ' + sourceEffect.name, '[of] ' + source); } else if (sourceEffect && sourceEffect.effectType === 'Move') { @@ -67,30 +69,27 @@ } else { this.add('-status', target, 'slp'); } + */ // 1-3 turns - this.effectData.startTime = this.random(2, 5); - this.effectData.time = this.effectData.startTime; + self.intData("startTime") = rng.nextInt(2, 5) + self.intData("time") = self.intData("startTime") onEnd: | println(s"${mon} woke up!") onBeforeMovePriority: 10 onBeforeMove: | /* - if (pokemon.hasAbility('earlybird')) { - pokemon.statusData.time--; + if (mon.hasAbility('earlybird')) { + this.intData.time--; } */ - pokemon.statusData.time--; - if (pokemon.statusData.time <= 0) { - pokemon.cureStatus(); - return; + self.intData("time") -= 1; + if (self.intData("time") <= 0) { + mon.cureStatus(); + true + } else { + println(s"${mon} is fast asleep.") + !move.flags("sleepUsable") } - /* - this.add('cant', pokemon, 'slp'); - if (move.sleepUsable) { - return; - } - */ - return false; - name: 'frz' effectType: Status @@ -153,19 +152,22 @@ num: 0 effectType: 'Status' onStart: | - this.effectData.stage = 0; + println(s"${mon} was baddly poisoned!") + self.intData("stage") = 0; + /* if (sourceEffect && sourceEffect.id === 'toxicorb') { this.add('-status', target, 'tox', '[from] item: Toxic Orb'); } else if (sourceEffect && sourceEffect.effectType === 'Ability') { this.add('-status', target, 'tox', '[from] ability: ' + sourceEffect.name, '[of] ' + source); } else { this.add('-status', target, 'tox'); - } + }*/ onSwitchIn: | this.effectData.stage = 0; onResidualOrder: 9 onResidual: | - if (this.effectData.stage < 15) { - this.effectData.stage++; + if (self.intData("stage") < 15) { + self.intData("stage") += 1 } - this.damage(this.clampIntRange(pokemon.maxhp / 16, 1) * this.effectData.stage); + mon.takeDamage(self.intData("stage") \\ 16 * mon(Hp)); + println(s"${mon} was damaged by poison!")