Added the ability for statuses to have data (like duration) and the sleep and toxic status effects
This commit is contained in:
parent
40553d36b9
commit
34cd67c36f
@ -14,13 +14,12 @@ case class Prop(url : Seq[String])
|
|||||||
|
|
||||||
object Game {
|
object Game {
|
||||||
def main(args : Array[String]): Unit = {
|
def main(args : Array[String]): Unit = {
|
||||||
println(Element("Water").effect)
|
|
||||||
println(Status("psn"))
|
|
||||||
implicit val rng = new scala.util.Random()
|
implicit val rng = new scala.util.Random()
|
||||||
val form1 = Form("Diabolo")
|
val form1 = Form("Diabolo")
|
||||||
val form2 = Form("Chanilla")
|
val form2 = Form("Chanilla")
|
||||||
val movepool1 = IndexedSeq(Move("Ice Beam"))
|
val movepool1 = IndexedSeq(Move("Aqua Jet"))
|
||||||
val movepool2 = IndexedSeq(Move("Scald"))
|
val movepool2 = IndexedSeq(Move("Thunder Wave"))
|
||||||
val p1 = TrainerID("Jaeda", Gender.Female, 0)
|
val p1 = TrainerID("Jaeda", Gender.Female, 0)
|
||||||
val p2 = TrainerID("Wild Monster", Gender.Male, 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())
|
val party1 = new Party(p1, new MonsterPtr(new Monster(new StorageMon("Allied Mon", 500, Gene.randomGene(null, form1), form1, Statistic.emptyEvs, movepool1))), IndexedSeq())
|
||||||
|
@ -51,7 +51,7 @@ class BattleEngine(val player: Party, val enemy: Party)(implicit val rng: Random
|
|||||||
val move = action.move
|
val move = action.move
|
||||||
val target = action.target
|
val target = action.target
|
||||||
if (user.isAlive) {
|
if (user.isAlive) {
|
||||||
if (user.status.forall(_.onBeforeMove(user, move, target, rng))) {
|
if (user.status.forall(_.onBeforeMove(user, move, target))) {
|
||||||
move.useMove(user, target)
|
move.useMove(user, target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ abstract class Move extends MoveTurn {
|
|||||||
val target: Target
|
val target: Target
|
||||||
val boosts: Map[Stat, Int]
|
val boosts: Map[Stat, Int]
|
||||||
val crit: Int
|
val crit: Int
|
||||||
val status: Status
|
val status: StatusTemplate
|
||||||
val drain: Fraction
|
val drain: Fraction
|
||||||
val selfEffect: Secondary
|
val selfEffect: Secondary
|
||||||
val secondary: 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)
|
applyBoosts(target, effect.boosts)
|
||||||
applyStatus(target, effect.status)
|
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.isAlive && status != null) {
|
||||||
if (target.status == None) {
|
if (target.status == None) {
|
||||||
// apply status
|
// apply status
|
||||||
target.status = Some(status)
|
val s = status.build
|
||||||
status.onStart(target)
|
target.status = Some(s)
|
||||||
|
s.onStart(target)
|
||||||
} else {
|
} else {
|
||||||
println("But it failed!")
|
println("But it failed!")
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package fmon.stat
|
|||||||
abstract class Secondary {
|
abstract class Secondary {
|
||||||
val chance : Int
|
val chance : Int
|
||||||
val boosts : Map[Stat, Int]
|
val boosts : Map[Stat, Int]
|
||||||
val status : Status
|
val status : StatusTemplate
|
||||||
// val volatileStatus
|
// val volatileStatus
|
||||||
//val onHit :
|
//val onHit :
|
||||||
// val self
|
// val self
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package fmon.stat
|
package fmon.stat
|
||||||
|
|
||||||
|
import scala.collection.mutable.{Map => MutMap}
|
||||||
import scala.reflect.runtime.universe._
|
import scala.reflect.runtime.universe._
|
||||||
import scala.tools.reflect.ToolBox
|
import scala.tools.reflect.ToolBox
|
||||||
import scala.util.Random
|
import scala.util.Random
|
||||||
@ -8,21 +9,44 @@ import scala.io.Source
|
|||||||
|
|
||||||
import fmon.util._
|
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 name: String
|
||||||
// val id
|
// val id
|
||||||
// val effectType
|
// val effectType
|
||||||
val onStart: Monster => Unit
|
val onStart: (Status, Monster, Random) => Unit
|
||||||
val onEnd: Monster => Unit
|
val onEnd: (Status, Monster) => Unit
|
||||||
val onModifyStat: (Monster, Stat) => Fraction
|
val onModifyStat: (Status, Monster, Stat) => Fraction
|
||||||
// val onBeforeMovePriority : Int
|
// val onBeforeMovePriority : Int
|
||||||
val onBeforeMove: (Monster, MoveTurn, Monster, Random) => Boolean
|
val onBeforeMove: (Status, Monster, MoveTurn, Monster, Random) => Boolean
|
||||||
// val onModifyMove
|
// val onModifyMove
|
||||||
// val onHit
|
// val onHit
|
||||||
val onResidualOrder: Int
|
val onResidualOrder: Int
|
||||||
val onResidual: Monster => Unit
|
val onResidual: (Status, Monster) => Unit
|
||||||
// val onSwitchIn
|
// val onSwitchIn
|
||||||
|
|
||||||
|
def build = new Status(this)
|
||||||
|
|
||||||
override def toString = name
|
override def toString = name
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,10 +60,10 @@ case class StatusToken(
|
|||||||
val onResidual: String) {
|
val onResidual: String) {
|
||||||
def instantiate() = {
|
def instantiate() = {
|
||||||
val self = this
|
val self = this
|
||||||
new Status {
|
new StatusTemplate {
|
||||||
val name = self.name
|
val name = self.name
|
||||||
val onStart = Status.compileOnStart(self.onStart)
|
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 onBeforeMove = Status.compileOnBeforeMove(self.onBeforeMove)
|
||||||
val onModifyStat = Status.compileOnModifyStat(self.onModifyStat)
|
val onModifyStat = Status.compileOnModifyStat(self.onModifyStat)
|
||||||
val onResidualOrder = self.onResidualOrder
|
val onResidualOrder = self.onResidualOrder
|
||||||
@ -49,7 +73,7 @@ case class StatusToken(
|
|||||||
}
|
}
|
||||||
|
|
||||||
object Status {
|
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
|
val tokens = YamlHelper.extractSeq[StatusToken](Source.fromInputStream(Move.getClass.getResourceAsStream("data/statuses.yaml"))).map(t => (t.name, t)).toMap
|
||||||
|
|
||||||
def apply(name: String) = {
|
def apply(name: String) = {
|
||||||
@ -61,74 +85,97 @@ object Status {
|
|||||||
|
|
||||||
private val tb = runtimeMirror(getClass.getClassLoader).mkToolBox()
|
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) {
|
if (code == null) {
|
||||||
_ => ()
|
(_, _, _) => ()
|
||||||
} else {
|
} else {
|
||||||
val tree = tb.parse(
|
val tree = tb.parse(
|
||||||
s"""
|
s"""
|
||||||
|
|import scala.util.Random
|
||||||
|import fmon.stat._
|
|import fmon.stat._
|
||||||
|import fmon.stat.Statistic._
|
|import fmon.stat.Statistic._
|
||||||
|def onStart(mon : Monster) = {
|
|import fmon.util._
|
||||||
|
|def onStart(self:Status, mon: Monster, rng: Random) = {
|
||||||
| $code
|
| $code
|
||||||
|}
|
|}
|
||||||
|onStart _
|
|onStart _
|
||||||
""".stripMargin)
|
""".stripMargin)
|
||||||
val f = tb.compile(tree)
|
val f = tb.compile(tree)
|
||||||
val wrapper = f()
|
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) {
|
if (code == null) {
|
||||||
(_, _, _, _) => true
|
(_, _, _, _, _) => true
|
||||||
} else {
|
} else {
|
||||||
val tree = tb.parse(
|
val tree = tb.parse(
|
||||||
s"""
|
s"""
|
||||||
import scala.util.Random
|
import scala.util.Random
|
||||||
import fmon.stat._
|
import fmon.stat._
|
||||||
import fmon.stat.Statistic._
|
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
|
$code
|
||||||
}
|
}
|
||||||
onBeforeMove _
|
onBeforeMove _
|
||||||
""")
|
""")
|
||||||
val f = tb.compile(tree)
|
val f = tb.compile(tree)
|
||||||
val wrapper = f()
|
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) {
|
if (code == null) {
|
||||||
(_, _) => 1.frac
|
(_, _, _) => 1.frac
|
||||||
} else {
|
} else {
|
||||||
val tree = tb.parse(
|
val tree = tb.parse(
|
||||||
s"""
|
s"""
|
||||||
import fmon.stat._
|
import fmon.stat._
|
||||||
import fmon.stat.Statistic._
|
import fmon.stat.Statistic._
|
||||||
import fmon.util._
|
import fmon.util._
|
||||||
def onModifyStat(mon: Monster, stat: Stat): Fraction = {
|
def onModifyStat(self: Status, mon: Monster, stat: Stat): Fraction = {
|
||||||
$code
|
$code
|
||||||
}
|
}
|
||||||
onModifyStat _
|
onModifyStat _
|
||||||
""")
|
""")
|
||||||
val f = tb.compile(tree)
|
val f = tb.compile(tree)
|
||||||
val wrapper = f()
|
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) {
|
if (code == null) {
|
||||||
_ => ()
|
(_, _) => ()
|
||||||
} else {
|
} else {
|
||||||
val tree = tb.parse(
|
val tree = tb.parse(
|
||||||
s"""
|
s"""
|
||||||
|import fmon.stat._
|
|import fmon.stat._
|
||||||
|import fmon.stat.Statistic._
|
|import fmon.stat.Statistic._
|
||||||
|def onResidual(mon : Monster) = {
|
|import fmon.util._
|
||||||
|
|def onResidual(self: Status, mon: Monster) = {
|
||||||
| $code
|
| $code
|
||||||
|}
|
|}
|
||||||
|onResidual _
|
|onResidual _
|
||||||
@ -136,7 +183,7 @@ object Status {
|
|||||||
val f = tb.compile(tree)
|
val f = tb.compile(tree)
|
||||||
val wrapper = f()
|
val wrapper = f()
|
||||||
|
|
||||||
wrapper.asInstanceOf[Monster => Unit]
|
wrapper.asInstanceOf[(Status, Monster) => Unit]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -278,6 +278,28 @@
|
|||||||
zMovePower: 100
|
zMovePower: 100
|
||||||
contestType: "Tough"
|
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
|
- name: Tackle
|
||||||
num: 33
|
num: 33
|
||||||
accuracy: 100
|
accuracy: 100
|
||||||
|
@ -60,6 +60,8 @@
|
|||||||
num: 0
|
num: 0
|
||||||
effectType: 'Status'
|
effectType: 'Status'
|
||||||
onStart: |
|
onStart: |
|
||||||
|
println(s"${mon} fell asleep!")
|
||||||
|
/*
|
||||||
if (sourceEffect && sourceEffect.effectType === 'Ability') {
|
if (sourceEffect && sourceEffect.effectType === 'Ability') {
|
||||||
this.add('-status', target, 'slp', '[from] ability: ' + sourceEffect.name, '[of] ' + source);
|
this.add('-status', target, 'slp', '[from] ability: ' + sourceEffect.name, '[of] ' + source);
|
||||||
} else if (sourceEffect && sourceEffect.effectType === 'Move') {
|
} else if (sourceEffect && sourceEffect.effectType === 'Move') {
|
||||||
@ -67,30 +69,27 @@
|
|||||||
} else {
|
} else {
|
||||||
this.add('-status', target, 'slp');
|
this.add('-status', target, 'slp');
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
// 1-3 turns
|
// 1-3 turns
|
||||||
this.effectData.startTime = this.random(2, 5);
|
self.intData("startTime") = rng.nextInt(2, 5)
|
||||||
this.effectData.time = this.effectData.startTime;
|
self.intData("time") = self.intData("startTime")
|
||||||
onEnd: |
|
onEnd: |
|
||||||
println(s"${mon} woke up!")
|
println(s"${mon} woke up!")
|
||||||
onBeforeMovePriority: 10
|
onBeforeMovePriority: 10
|
||||||
onBeforeMove: |
|
onBeforeMove: |
|
||||||
/*
|
/*
|
||||||
if (pokemon.hasAbility('earlybird')) {
|
if (mon.hasAbility('earlybird')) {
|
||||||
pokemon.statusData.time--;
|
this.intData.time--;
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
pokemon.statusData.time--;
|
self.intData("time") -= 1;
|
||||||
if (pokemon.statusData.time <= 0) {
|
if (self.intData("time") <= 0) {
|
||||||
pokemon.cureStatus();
|
mon.cureStatus();
|
||||||
return;
|
true
|
||||||
|
} else {
|
||||||
|
println(s"${mon} is fast asleep.")
|
||||||
|
!move.flags("sleepUsable")
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
this.add('cant', pokemon, 'slp');
|
|
||||||
if (move.sleepUsable) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
return false;
|
|
||||||
|
|
||||||
- name: 'frz'
|
- name: 'frz'
|
||||||
effectType: Status
|
effectType: Status
|
||||||
@ -153,19 +152,22 @@
|
|||||||
num: 0
|
num: 0
|
||||||
effectType: 'Status'
|
effectType: 'Status'
|
||||||
onStart: |
|
onStart: |
|
||||||
this.effectData.stage = 0;
|
println(s"${mon} was baddly poisoned!")
|
||||||
|
self.intData("stage") = 0;
|
||||||
|
/*
|
||||||
if (sourceEffect && sourceEffect.id === 'toxicorb') {
|
if (sourceEffect && sourceEffect.id === 'toxicorb') {
|
||||||
this.add('-status', target, 'tox', '[from] item: Toxic Orb');
|
this.add('-status', target, 'tox', '[from] item: Toxic Orb');
|
||||||
} else if (sourceEffect && sourceEffect.effectType === 'Ability') {
|
} else if (sourceEffect && sourceEffect.effectType === 'Ability') {
|
||||||
this.add('-status', target, 'tox', '[from] ability: ' + sourceEffect.name, '[of] ' + source);
|
this.add('-status', target, 'tox', '[from] ability: ' + sourceEffect.name, '[of] ' + source);
|
||||||
} else {
|
} else {
|
||||||
this.add('-status', target, 'tox');
|
this.add('-status', target, 'tox');
|
||||||
}
|
}*/
|
||||||
onSwitchIn: |
|
onSwitchIn: |
|
||||||
this.effectData.stage = 0;
|
this.effectData.stage = 0;
|
||||||
onResidualOrder: 9
|
onResidualOrder: 9
|
||||||
onResidual: |
|
onResidual: |
|
||||||
if (this.effectData.stage < 15) {
|
if (self.intData("stage") < 15) {
|
||||||
this.effectData.stage++;
|
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!")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user