Added support for abilities including a bunch of abilities that have effects the the monster is hit. Better monster generation support has been added.
This commit is contained in:
parent
ce81ab2079
commit
ad6780362b
@ -18,13 +18,13 @@ object Game {
|
||||
implicit val rng = new scala.util.Random()
|
||||
val form1 = Form("Diabolo")
|
||||
val form2 = Form("Chanilla")
|
||||
val movepool1 = IndexedSeq(Move("Confuse Ray"))
|
||||
val movepool2 = IndexedSeq(Move("Headbutt"))
|
||||
val movepool1 = IndexedSeq(Move("electroball"), Move("thunderwave"))
|
||||
val movepool2 = IndexedSeq(Move("headbutt"))
|
||||
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())
|
||||
val party2 = new Party(p2, new MonsterPtr(new Monster(new StorageMon("Wild Mon", 500, Gene.randomGene(null, form2), form2, Statistic.emptyEvs, movepool2))), IndexedSeq(
|
||||
new Monster(new StorageMon("Sideboard Mon", 500, Gene.randomGene(null, form2), form2, Statistic.emptyEvs, movepool2))
|
||||
val party1 = new Party(p1, new MonsterPtr(Monster.generate("Allied Mon", p1, 500, form1, movepool1)), IndexedSeq())
|
||||
val party2 = new Party(p2, new MonsterPtr(Monster.generate("Wild Mon", p2, 500, form2, movepool2)), IndexedSeq(
|
||||
Monster.generate("Sideboard Mon", p2, 500, form2, movepool2)
|
||||
))
|
||||
println(form1.xpCurve)
|
||||
val engine = new BattleEngine(party1, party2)
|
||||
|
76
FakeMon/src/fmon/stat/Ability.scala
Normal file
76
FakeMon/src/fmon/stat/Ability.scala
Normal file
@ -0,0 +1,76 @@
|
||||
package fmon.stat
|
||||
|
||||
import scala.reflect.runtime.universe._
|
||||
import scala.tools.reflect.ToolBox
|
||||
import scala.io.Source
|
||||
import scala.util.Random
|
||||
|
||||
import fmon.util._
|
||||
|
||||
abstract class Ability {
|
||||
val name: String
|
||||
val desc: String
|
||||
|
||||
def onAfterDamage(source: Monster, move: MoveTurn, mon: Monster, dmg: Int)(implicit rng: Random) = onAfterDamageImp(source, move, mon, dmg, rng)
|
||||
|
||||
protected val onAfterDamageImp: (Monster, MoveTurn, Monster, Int, Random) => Unit
|
||||
|
||||
override def toString = name
|
||||
}
|
||||
|
||||
class AbilityToken(
|
||||
val name: String,
|
||||
val shortDesc: String,
|
||||
val onAfterDamage: String
|
||||
) {
|
||||
|
||||
def instantiate(): Ability = {
|
||||
val self = this
|
||||
new Ability {
|
||||
val name = self.name
|
||||
val desc = self.shortDesc
|
||||
val onAfterDamageImp = Ability.compileOnAfterDamage(self.onAfterDamage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object Ability {
|
||||
private var abilities = Map[String, Ability]()
|
||||
val tokens = YamlHelper.extractMap[AbilityToken](Source.fromInputStream(Ability.getClass.getResourceAsStream("data/abilities.yaml")))
|
||||
private val tb = runtimeMirror(getClass.getClassLoader).mkToolBox()
|
||||
|
||||
def apply(name: String) = {
|
||||
if (!abilities.contains(name)) {
|
||||
abilities = abilities.updated(name, tokens(name).instantiate())
|
||||
}
|
||||
abilities(name)
|
||||
}
|
||||
|
||||
private val header = """
|
||||
|import scala.util.Random
|
||||
|import fmon.stat._
|
||||
|import fmon.stat.MoveType._
|
||||
|import fmon.stat.Statistic._
|
||||
|import fmon.util._
|
||||
"""
|
||||
|
||||
def compileOnAfterDamage(code: String): (Monster, MoveTurn, Monster, Int, Random) => Unit = {
|
||||
if (code == null) {
|
||||
(_, _, _, _, _) => ()
|
||||
} else {
|
||||
val tree = tb.parse(
|
||||
s"""
|
||||
|$header
|
||||
|def onAfterDamage(source: Monster, move: MoveTurn, mon: Monster, damage: Int, rng: Random): Unit = {
|
||||
| implicit val gen = rng
|
||||
| $code
|
||||
|}
|
||||
|onAfterDamage _
|
||||
""".stripMargin)
|
||||
val f = tb.compile(tree)
|
||||
val wrapper = f()
|
||||
implicit val c = code
|
||||
wrapper.asInstanceOf[(Monster, MoveTurn, Monster, Int, Random) => Unit]
|
||||
}
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@ abstract class Form {
|
||||
val baseStats : Map[Stat, Int]
|
||||
// val appearance // animation
|
||||
// moves
|
||||
// abilities
|
||||
val abilities : IndexedSeq[Ability]
|
||||
val xpCurve : XpCurve
|
||||
val catchRate : Int
|
||||
// val color
|
||||
@ -30,6 +30,7 @@ abstract class Form {
|
||||
case class FormToken(
|
||||
val name : String,
|
||||
val desc : String,
|
||||
val abilities : IndexedSeq[String],
|
||||
val elements : IndexedSeq[String],
|
||||
val baseStats : Map[String, Int],
|
||||
@JsonScalaEnumeration(classOf[XpCurveType]) val xpCurve : XpCurve,
|
||||
@ -43,6 +44,7 @@ case class FormToken(
|
||||
val desc = self.desc
|
||||
val elements = self.elements.map(Element(_))
|
||||
val baseStats = self.baseStats.map{ case (s, i) => (Statistic(s), i)}
|
||||
val abilities = self.abilities.map(Ability(_))
|
||||
val xpCurve = self.xpCurve
|
||||
val catchRate = self.catchRate
|
||||
}
|
||||
|
@ -68,6 +68,11 @@ class Monster(val base : StorageMon) {
|
||||
def applyBoost(s : Stat, boost : Int) {
|
||||
val modified = boosts.getOrElse(s, 0) + boost
|
||||
boosts = boosts.updated(s, Math.min(MaxBoost, Math.max(-MaxBoost, modified)))
|
||||
if (boost > 0) {
|
||||
println(s"$this's $s rose!")
|
||||
} else if (boost < 0) {
|
||||
println(s"$this's $s fell!")
|
||||
}
|
||||
}
|
||||
|
||||
def effectiveness(element : Element) : Double = {
|
||||
@ -88,7 +93,11 @@ class Monster(val base : StorageMon) {
|
||||
object Monster {
|
||||
final val MaxBoost = 6
|
||||
|
||||
def build(trainer : TrainerID, form : Form)(implicit rng : Random) = {
|
||||
|
||||
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()
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
package fmon.stat
|
||||
|
||||
class MonsterPtr(var mon : Monster) {
|
||||
|
||||
override def toString : String = mon.toString()
|
||||
}
|
@ -12,7 +12,7 @@ import Statistic._
|
||||
import fmon.util._
|
||||
|
||||
object MoveType extends Enumeration {
|
||||
val Physical, Special, Status = Value
|
||||
val Physical, Special, Support, Other = Value
|
||||
}
|
||||
class MoveTypeType extends TypeReference[MoveType.type]
|
||||
|
||||
@ -26,6 +26,7 @@ trait MoveTurn {
|
||||
def flags: Set[String]
|
||||
def prior: Int
|
||||
def target: Target
|
||||
def category: MoveType
|
||||
def useMove(user: Monster, target: Monster)(implicit rng: Random): Unit
|
||||
}
|
||||
|
||||
@ -34,6 +35,7 @@ class SwitchOut(val party: Party, val replacement: Monster) extends MoveTurn {
|
||||
def flags = Set()
|
||||
def prior = +6
|
||||
def target = Target.Self
|
||||
def category = MoveType.Other
|
||||
|
||||
def useMove(user: Monster, target: Monster)(implicit rng: Random): Unit = {
|
||||
println(s"${party.trainer} withdrew $user!")
|
||||
@ -47,7 +49,7 @@ class SwitchOut(val party: Party, val replacement: Monster) extends MoveTurn {
|
||||
abstract class Move extends MoveTurn {
|
||||
val name: String
|
||||
val desc: String
|
||||
val mvType: MoveType
|
||||
val category: MoveType
|
||||
val pow: Int
|
||||
val powCallback: (Monster, Monster) => Int
|
||||
val prior: Int
|
||||
@ -89,6 +91,9 @@ abstract class Move extends MoveTurn {
|
||||
user.takeDamage(recoil)
|
||||
println(s"$user took $recoil damage from recoil!")
|
||||
}
|
||||
|
||||
target.base.ability.onAfterDamage(user, this, target, actualDmg)
|
||||
|
||||
if (!user.isAlive) {
|
||||
println(s"$user fainted!")
|
||||
}
|
||||
@ -126,8 +131,8 @@ abstract class Move extends MoveTurn {
|
||||
}
|
||||
|
||||
def damageRoll(user: Monster, target: Monster)(implicit rng: Random) = {
|
||||
val atkStat = if (mvType == MoveType.Physical) PAtk else MAtk
|
||||
val defStat = if (mvType == MoveType.Physical) PDef else MDef
|
||||
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, target) else pow
|
||||
val baseDmg = (2 * user.level / 5 + 2) * actualPow * user(atkStat) / (target(defStat) * 50) + 2
|
||||
@ -172,11 +177,7 @@ abstract class Move extends MoveTurn {
|
||||
boosts.foreach {
|
||||
case (s, b) => {
|
||||
target.applyBoost(s, b)
|
||||
if (b > 0) {
|
||||
println(s"$target's $s rose!")
|
||||
} else if (b < 0) {
|
||||
println(s"$target's $s fell!")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -214,7 +215,7 @@ case class MoveToken(
|
||||
new Move {
|
||||
val name = token.name
|
||||
val desc = token.shortDesc
|
||||
val mvType = category
|
||||
val category = token.category
|
||||
val pow = token.basePower.getOrElse(0)
|
||||
val powCallback = Move.compilePowCallback(token.basePowerCallback)
|
||||
val prior = token.priority
|
||||
@ -236,7 +237,7 @@ case class MoveToken(
|
||||
|
||||
object Move {
|
||||
private var moves = Map[String, Move]()
|
||||
val tokens = YamlHelper.extractSeq[MoveToken](Source.fromInputStream(Move.getClass.getResourceAsStream("data/moves.yaml"))).map(t => (t.name, t)).toMap
|
||||
val tokens = YamlHelper.extractMap[MoveToken](Source.fromInputStream(Move.getClass.getResourceAsStream("data/moves.yaml")))
|
||||
|
||||
def apply(name: String): Move = {
|
||||
if (!moves.contains(name)) {
|
||||
@ -250,8 +251,8 @@ object Move {
|
||||
val tb = runtimeMirror(getClass.getClassLoader).mkToolBox()
|
||||
val tree = tb.parse(
|
||||
s"""
|
||||
|import mon.stat.Monster
|
||||
|import mon.stat.Statistic._
|
||||
|import fmon.stat.Monster
|
||||
|import fmon.stat.Statistic._
|
||||
|def callback(user : Monster, target : Monster): Int = {
|
||||
| $code
|
||||
|}
|
||||
|
@ -99,6 +99,13 @@ object Status {
|
||||
}
|
||||
|
||||
private val tb = runtimeMirror(getClass.getClassLoader).mkToolBox()
|
||||
private val header = """
|
||||
import scala.util.Random
|
||||
import fmon.stat._
|
||||
import fmon.stat.MoveType._
|
||||
import fmon.stat.Statistic._
|
||||
import fmon.util._
|
||||
"""
|
||||
|
||||
def compileOnStart(code: String): (Status, Monster /*, source, source effect */, Random ) => Unit = {
|
||||
if (code == null) {
|
||||
@ -106,10 +113,7 @@ object Status {
|
||||
} else {
|
||||
val tree = tb.parse(
|
||||
s"""
|
||||
|import scala.util.Random
|
||||
|import fmon.stat._
|
||||
|import fmon.stat.Statistic._
|
||||
|import fmon.util._
|
||||
|$header
|
||||
|def onStart(self:Status, mon: Monster, rng: Random) = {
|
||||
| $code
|
||||
|}
|
||||
@ -127,13 +131,11 @@ object Status {
|
||||
} else {
|
||||
val tree = tb.parse(
|
||||
s"""
|
||||
|import fmon.stat._
|
||||
|import fmon.stat.Statistic._
|
||||
|import fmon.util._
|
||||
|$header
|
||||
|def onStart(self:Status, mon: Monster) = {
|
||||
| $code
|
||||
|}
|
||||
|onStart _
|
||||
onStart _
|
||||
""".stripMargin)
|
||||
val f = tb.compile(tree)
|
||||
val wrapper = f()
|
||||
@ -147,15 +149,13 @@ object Status {
|
||||
} else {
|
||||
val tree = tb.parse(
|
||||
s"""
|
||||
import scala.util.Random
|
||||
import fmon.stat._
|
||||
import fmon.stat.Statistic._
|
||||
import fmon.util._
|
||||
$header
|
||||
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[(Status, Monster, MoveTurn, Monster, Random) => Boolean]
|
||||
@ -168,9 +168,7 @@ object Status {
|
||||
} else {
|
||||
val tree = tb.parse(
|
||||
s"""
|
||||
import fmon.stat._
|
||||
import fmon.stat.Statistic._
|
||||
import fmon.util._
|
||||
$header
|
||||
def onModifyStat(self: Status, mon: Monster, stat: Stat): Fraction = {
|
||||
$code
|
||||
}
|
||||
@ -188,9 +186,7 @@ object Status {
|
||||
} else {
|
||||
val tree = tb.parse(
|
||||
s"""
|
||||
|import fmon.stat._
|
||||
|import fmon.stat.Statistic._
|
||||
|import fmon.util._
|
||||
|$header
|
||||
|def onResidual(self: Status, mon: Monster) = {
|
||||
| $code
|
||||
|}
|
||||
|
@ -1,5 +1,16 @@
|
||||
package fmon.stat
|
||||
|
||||
class StorageMon(val nickname : String, val xp: Int, val gene : Gene, val form : Form, val evs : Map[Stat, Int], val moves : IndexedSeq[Move]) {
|
||||
import scala.util.Random
|
||||
|
||||
import fmon.util._
|
||||
|
||||
class StorageMon(val nickname : String, val xp: Int, val gene : Gene, val form : Form, val evs : Map[Stat, Int], val moves : IndexedSeq[Move], val ability: Ability) {
|
||||
def level = form.xpCurve(xp)
|
||||
}
|
||||
|
||||
object StorageMon {
|
||||
def generate(nickname: String, ot: TrainerID, xp: Int, form: Form, moves: IndexedSeq[Move])(implicit rng: Random) = {
|
||||
val gene = Gene.randomGene(ot, form)
|
||||
new StorageMon(nickname, xp, gene, form, Statistic.emptyEvs, moves, rng.pick(form.abilities))
|
||||
}
|
||||
}
|
164
FakeMon/src/fmon/stat/data/abilities.yaml
Normal file
164
FakeMon/src/fmon/stat/data/abilities.yaml
Normal file
@ -0,0 +1,164 @@
|
||||
noability:
|
||||
id: noability
|
||||
isNonstandard: Past
|
||||
name: No Ability
|
||||
num: 0
|
||||
rating: 0.1
|
||||
shortDesc: Does nothing.
|
||||
|
||||
aftermath:
|
||||
desc: If this Pokemon is knocked out with a contact move, that move's user loses
|
||||
1/4 of its maximum HP, rounded down. If any active Pokemon has the Damp Ability,
|
||||
this effect is prevented.
|
||||
id: aftermath
|
||||
name: Aftermath
|
||||
num: 106
|
||||
onAfterDamage: |-
|
||||
if ((source != null) && (source != mon) && (move != null) && move.flags("contact") && !mon.isAlive) {
|
||||
println(s"$source is damaged in the aftermath!")
|
||||
source.takeDamage(source(Hp) / 4);
|
||||
}
|
||||
onAfterDamageOrder: 1
|
||||
rating: 2.5
|
||||
shortDesc: If this Pokemon is KOed with a contact move, that move's user loses 1/4
|
||||
its max HP.
|
||||
|
||||
flamebody:
|
||||
id: flamebody
|
||||
name: Flame Body
|
||||
num: 49
|
||||
onAfterDamage: |-
|
||||
if (move != null && move.flags("contact")) {
|
||||
if (rng.chance(3, 10)) {
|
||||
source += Status("brn");
|
||||
}
|
||||
}
|
||||
rating: 2
|
||||
shortDesc: 30% chance a Pokemon making contact with this Pokemon will be burned.
|
||||
|
||||
gooey:
|
||||
id: gooey
|
||||
name: Gooey
|
||||
num: 183
|
||||
onAfterDamage: |-
|
||||
if (move != null && move.flags("contact")) {
|
||||
//this.add('-ability', target, 'Gooey');
|
||||
source.applyBoost(Speed, -1)
|
||||
//this.boost({'spe': -1}, source, target, null, true);
|
||||
}
|
||||
rating: 2.5
|
||||
shortDesc: Pokemon making contact with this Pokemon have their Speed lowered by
|
||||
1 stage.
|
||||
|
||||
innardsout:
|
||||
desc: If this Pokemon is knocked out with a move, that move's user loses HP equal
|
||||
to the amount of damage inflicted on this Pokemon.
|
||||
id: innardsout
|
||||
name: Innards Out
|
||||
num: 215
|
||||
onAfterDamage: |-
|
||||
if (source != null && source != mon && move != null /* && move.effectType === 'Move'*/ && !mon.isAlive) {
|
||||
println(s"$source is damaged in the aftermath!")
|
||||
source.takeDamage(damage)//, source, target);
|
||||
}
|
||||
onAfterDamageOrder: 1
|
||||
rating: 2.5
|
||||
shortDesc: If this Pokemon is KOed with a move, that move's user loses an equal
|
||||
amount of HP.
|
||||
|
||||
ironbarbs:
|
||||
desc: Pokemon making contact with this Pokemon lose 1/8 of their maximum HP, rounded
|
||||
down.
|
||||
id: ironbarbs
|
||||
name: Iron Barbs
|
||||
num: 160
|
||||
onAfterDamage: |-
|
||||
if (source != null && source != mon && move != null && move.flags("contact")) {
|
||||
println(s"Pointed barbs dug into $source!")
|
||||
source.takeDamage(source(Hp) / 8)//, source, target)
|
||||
}
|
||||
onAfterDamageOrder: 1
|
||||
rating: 3
|
||||
shortDesc: Pokemon making contact with this Pokemon lose 1/8 of their max HP.
|
||||
|
||||
poisonpoint:
|
||||
id: poisonpoint
|
||||
name: Poison Point
|
||||
num: 38
|
||||
onAfterDamage: |-
|
||||
if (move != null && move.flags("contact")) {
|
||||
if (rng.chance(3, 10)) {
|
||||
source += Status("psn")
|
||||
}
|
||||
}
|
||||
rating: 2
|
||||
shortDesc: 30% chance a Pokemon making contact with this Pokemon will be poisoned.
|
||||
|
||||
roughskin:
|
||||
desc: Pokemon making contact with this Pokemon lose 1/8 of their maximum HP, rounded
|
||||
down.
|
||||
id: roughskin
|
||||
name: Rough Skin
|
||||
num: 24
|
||||
onAfterDamage: |-
|
||||
if (source != null && source != mon && move != null && move.flags("contact")) {
|
||||
println(s"$source is damaged by rough skin!")
|
||||
source.takeDamage(source(Hp) / 8)//, source, target)
|
||||
}
|
||||
onAfterDamageOrder: 1
|
||||
rating: 3
|
||||
shortDesc: Pokemon making contact with this Pokemon lose 1/8 of their max HP.
|
||||
|
||||
stamina:
|
||||
id: stamina
|
||||
name: Stamina
|
||||
num: 192
|
||||
onAfterDamage: |-
|
||||
if (move != null /*&& effect.effectType == 'Move' && effect.id != 'confused'*/) {
|
||||
mon.applyBoost(PDef, +1)
|
||||
}
|
||||
rating: 3
|
||||
shortDesc: This Pokemon's Defense is raised by 1 stage after it is damaged by a move.
|
||||
|
||||
static:
|
||||
id: static
|
||||
name: Static
|
||||
num: 9
|
||||
onAfterDamage: |-
|
||||
if (move != null && move.flags("contact")) {
|
||||
if (rng.chance(3, 10)) {
|
||||
source += Status("par");
|
||||
}
|
||||
}
|
||||
rating: 2
|
||||
shortDesc: 30% chance a Pokemon making contact with this Pokemon will be paralyzed.
|
||||
|
||||
tanglinghair:
|
||||
id: tanglinghair
|
||||
name: Tangling Hair
|
||||
num: 221
|
||||
onAfterDamage: |-
|
||||
if (move != null && move.flags("contact")) {
|
||||
this.add('-ability', target, 'Tangling Hair');
|
||||
source.applyBoost(Speed, -1)
|
||||
//this.boost({'spe': -1}, source, target, null, true);
|
||||
}
|
||||
rating: 2.5
|
||||
shortDesc: Pokemon making contact with this Pokemon have their Speed lowered by
|
||||
1 stage.
|
||||
|
||||
weakarmor:
|
||||
desc: If a physical attack hits this Pokemon, its Defense is lowered by 1 stage
|
||||
and its Speed is raised by 2 stages.
|
||||
id: weakarmor
|
||||
name: Weak Armor
|
||||
num: 133
|
||||
onAfterDamage: |-
|
||||
if (move.category == Physical) {
|
||||
//this.boost({'def': -1, 'spe': 2}, target, target);
|
||||
mon.applyBoost(PDef, -1)
|
||||
mon.applyBoost(Speed, +2)
|
||||
}
|
||||
rating: 1
|
||||
shortDesc: If a physical attack hits this Pokemon, Defense is lowered by 1, Speed
|
||||
is raised by 2.
|
@ -2,6 +2,8 @@
|
||||
desc: A vanilla chameleon.
|
||||
elements:
|
||||
- Normal
|
||||
abilities:
|
||||
- noability
|
||||
baseStats:
|
||||
hp: 60
|
||||
patk: 70
|
||||
@ -16,6 +18,9 @@
|
||||
elements:
|
||||
- Electric
|
||||
- Fire
|
||||
abilities:
|
||||
- flamebody
|
||||
- static
|
||||
baseStats:
|
||||
hp: 40
|
||||
patk: 110
|
||||
|
@ -1,4 +1,5 @@
|
||||
- name: "Absorb"
|
||||
absorb:
|
||||
name: "Absorb"
|
||||
num: 71
|
||||
accuracy: 100
|
||||
basePower: 20
|
||||
@ -19,7 +20,8 @@
|
||||
zMovePower: 100
|
||||
contestType: "Clever"
|
||||
|
||||
- name: Aqua Jet
|
||||
aquajet:
|
||||
name: Aqua Jet
|
||||
num: 453
|
||||
accuracy: 100
|
||||
basePower: 40
|
||||
@ -41,11 +43,12 @@
|
||||
zMovePower: 100
|
||||
contestType: Cool
|
||||
|
||||
- name: "Bulk Up"
|
||||
bulkup:
|
||||
name: "Bulk Up"
|
||||
num: 339
|
||||
accuracy: 0
|
||||
basePower: 0
|
||||
category: "Status"
|
||||
category: Support
|
||||
desc: "Raises the user's Attack and Defense by 1 stage."
|
||||
shortDesc: "Raises the user's Attack and Defense by 1."
|
||||
id: "bulkup"
|
||||
@ -64,11 +67,12 @@
|
||||
patk: 1
|
||||
contestType: "Cool"
|
||||
|
||||
- name: Charm
|
||||
charm:
|
||||
name: Charm
|
||||
num: 204
|
||||
accuracy: 100
|
||||
basePower: 0
|
||||
category: Status
|
||||
category: Support
|
||||
desc: Lowers the target's Attack by 2 stages.
|
||||
shortDesc: Lowers the target's Attack by 2.
|
||||
id: charm
|
||||
@ -88,7 +92,8 @@
|
||||
pdef: 1
|
||||
contestType: Cute
|
||||
|
||||
- name: "Close Combat"
|
||||
closecombat:
|
||||
name: "Close Combat"
|
||||
num: 370
|
||||
accuracy: 100
|
||||
basePower: 120
|
||||
@ -113,10 +118,11 @@
|
||||
zMovePower: 190
|
||||
contestType: "Tough"
|
||||
|
||||
- name: Confuse Ray
|
||||
confuseray:
|
||||
name: Confuse Ray
|
||||
accuracy: 100
|
||||
basePower: 0
|
||||
category: Status
|
||||
category: Support
|
||||
contestType: Clever
|
||||
desc: Causes the target to become confused.
|
||||
flags:
|
||||
@ -135,7 +141,8 @@
|
||||
zMoveBoost:
|
||||
MAtk: 1
|
||||
|
||||
- name: Electro Ball
|
||||
electroball:
|
||||
name: Electro Ball
|
||||
num: 486
|
||||
accuracy: 100
|
||||
basePower: 0
|
||||
@ -169,7 +176,8 @@
|
||||
zMovePower: 160
|
||||
contestType: "Cool"
|
||||
|
||||
- name: "Frost Breath"
|
||||
frostbreath:
|
||||
name: "Frost Breath"
|
||||
num: 524
|
||||
accuracy: 90
|
||||
basePower: 60
|
||||
@ -187,7 +195,8 @@
|
||||
zMovePower: 120
|
||||
contestType: "Beautiful"
|
||||
|
||||
- name: Headbutt
|
||||
headbutt:
|
||||
name: Headbutt
|
||||
accuracy: 100
|
||||
basePower: 70
|
||||
category: Physical
|
||||
@ -209,7 +218,8 @@
|
||||
type: Normal
|
||||
zMovePower: 140
|
||||
|
||||
- name: Ice Beam
|
||||
icebeam:
|
||||
name: Ice Beam
|
||||
accuracy: 100
|
||||
basePower: 90
|
||||
category: Special
|
||||
@ -231,11 +241,12 @@
|
||||
type: Ice
|
||||
zMovePower: 175
|
||||
|
||||
- name: "Poison Gas"
|
||||
poisongas:
|
||||
name: "Poison Gas"
|
||||
num: 139
|
||||
accuracy: 90
|
||||
basePower: 0
|
||||
category: "Status"
|
||||
category: Support
|
||||
desc: "Poisons the target."
|
||||
shortDesc: "Poisons the foe(s)."
|
||||
id: "poisongas"
|
||||
@ -253,7 +264,8 @@
|
||||
def: 1
|
||||
contestType: "Clever"
|
||||
|
||||
- name: "Poison Sting"
|
||||
poisonsting:
|
||||
name: "Poison Sting"
|
||||
num: 40
|
||||
accuracy: 100
|
||||
basePower: 15
|
||||
@ -274,7 +286,8 @@
|
||||
zMovePower: 100
|
||||
contestType: "Clever"
|
||||
|
||||
- name: Scald
|
||||
scald:
|
||||
name: Scald
|
||||
accuracy: 100
|
||||
basePower: 80
|
||||
category: Special
|
||||
@ -298,7 +311,8 @@
|
||||
type: Water
|
||||
zMovePower: 160
|
||||
|
||||
- name: "Snarl"
|
||||
snarl:
|
||||
name: "Snarl"
|
||||
num: 555
|
||||
accuracy: 95
|
||||
basePower: 55
|
||||
@ -322,10 +336,11 @@
|
||||
zMovePower: 100
|
||||
contestType: "Tough"
|
||||
|
||||
- name: Spore
|
||||
spore:
|
||||
name: Spore
|
||||
accuracy: 100
|
||||
basePower: 0
|
||||
category: Status
|
||||
category: Support
|
||||
contestType: Beautiful
|
||||
flags:
|
||||
mirror: 1
|
||||
@ -344,7 +359,8 @@
|
||||
type: Grass
|
||||
zMoveEffect: clearnegativeboost
|
||||
|
||||
- name: Tackle
|
||||
tackle:
|
||||
name: Tackle
|
||||
num: 33
|
||||
accuracy: 100
|
||||
basePower: 40
|
||||
@ -363,10 +379,11 @@
|
||||
zMovePower: 100
|
||||
contestType: Tough
|
||||
|
||||
- name: Thunder Wave
|
||||
thunderwave:
|
||||
name: Thunder Wave
|
||||
accuracy: 90
|
||||
basePower: 0
|
||||
category: Status
|
||||
category: Support
|
||||
contestType: Cool
|
||||
desc: Paralyzes the target. This move does not ignore type immunity.
|
||||
flags:
|
||||
@ -387,7 +404,8 @@
|
||||
zMoveBoost:
|
||||
MDef: 1
|
||||
|
||||
- name: "Volt Tackle"
|
||||
volttackle:
|
||||
name: "Volt Tackle"
|
||||
num: 344
|
||||
accuracy: 100
|
||||
basePower: 120
|
||||
@ -408,10 +426,11 @@
|
||||
zMovePower: 190
|
||||
contestType: "Cool"
|
||||
|
||||
- name: Will-O-Wisp
|
||||
willowisp:
|
||||
name: Will-O-Wisp
|
||||
accuracy: 85
|
||||
basePower: 0
|
||||
category: Status
|
||||
category: Support
|
||||
contestType: Beautiful
|
||||
desc: Burns the target.
|
||||
flags:
|
||||
|
@ -20,5 +20,6 @@ package object stat {
|
||||
|
||||
implicit val formats = DefaultFormats + new EnumNameSerializer(MoveType) + new EnumNameSerializer(Gender)
|
||||
implicit def rngDice(rng : Random) = new Dice(rng)
|
||||
implicit def ptrToMonster(ptr : MonsterPtr) : Monster = ptr.mon
|
||||
implicit def ptrToMonster(ptr : MonsterPtr) : Monster = ptr.mon
|
||||
implicit def templateToStatus(status: StatusTemplate): Status = status.build
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user