Messages will now play when an ability triggers
This commit is contained in:
parent
d2ee6debf8
commit
bebbf469db
@ -7,13 +7,15 @@ import scala.util.Random
|
|||||||
|
|
||||||
import fmon.util._
|
import fmon.util._
|
||||||
|
|
||||||
abstract class Ability {
|
abstract class Ability extends Effect {
|
||||||
val name: String
|
val name: String
|
||||||
val desc: String
|
val desc: String
|
||||||
|
|
||||||
def onAfterDamage(source: Monster, move: MoveTurn, mon: Monster, dmg: Int)(implicit rng: Random) = onAfterDamageImp(source, move, mon, dmg, rng)
|
def effectType = EffectType.AbilityEffect
|
||||||
|
|
||||||
protected val onAfterDamageImp: (Monster, MoveTurn, Monster, Int, Random) => Unit
|
def onAfterDamage(source: Monster, move: MoveTurn, mon: Monster, dmg: Int)(implicit rng: Random) = onAfterDamageImp(this, source, move, mon, dmg, rng)
|
||||||
|
|
||||||
|
protected val onAfterDamageImp: (Ability, Monster, MoveTurn, Monster, Int, Random) => Unit
|
||||||
|
|
||||||
override def toString = name
|
override def toString = name
|
||||||
}
|
}
|
||||||
@ -53,16 +55,23 @@ object Ability {
|
|||||||
|import fmon.stat.Statistic._
|
|import fmon.stat.Statistic._
|
||||||
|import fmon.util._
|
|import fmon.util._
|
||||||
"""
|
"""
|
||||||
|
private val helper = """
|
||||||
|
implicit val gen = rng
|
||||||
|
def trigger {
|
||||||
|
print(s"[${mon}'s ${self}]")
|
||||||
|
}
|
||||||
|
def effect = EffectSource(mon, self)
|
||||||
|
"""
|
||||||
|
|
||||||
def compileOnAfterDamage(code: String): (Monster, MoveTurn, Monster, Int, Random) => Unit = {
|
def compileOnAfterDamage(code: String): (Ability, Monster, MoveTurn, Monster, Int, Random) => Unit = {
|
||||||
if (code == null) {
|
if (code == null) {
|
||||||
(_, _, _, _, _) => ()
|
(_, _, _, _, _, _) => ()
|
||||||
} else {
|
} else {
|
||||||
val tree = tb.parse(
|
val tree = tb.parse(
|
||||||
s"""
|
s"""
|
||||||
|$header
|
|$header
|
||||||
|def onAfterDamage(source: Monster, move: MoveTurn, mon: Monster, damage: Int, rng: Random): Unit = {
|
|def onAfterDamage(self: Ability, source: Monster, move: MoveTurn, mon: Monster, damage: Int, rng: Random): Unit = {
|
||||||
| implicit val gen = rng
|
| $helper
|
||||||
| $code
|
| $code
|
||||||
|}
|
|}
|
||||||
|onAfterDamage _
|
|onAfterDamage _
|
||||||
@ -70,7 +79,7 @@ object Ability {
|
|||||||
val f = tb.compile(tree)
|
val f = tb.compile(tree)
|
||||||
val wrapper = f()
|
val wrapper = f()
|
||||||
implicit val c = code
|
implicit val c = code
|
||||||
wrapper.asInstanceOf[(Monster, MoveTurn, Monster, Int, Random) => Unit]
|
wrapper.asInstanceOf[(Ability, Monster, MoveTurn, Monster, Int, Random) => Unit]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -44,13 +44,13 @@ class Monster(val base : StorageMon) {
|
|||||||
status = None
|
status = None
|
||||||
}
|
}
|
||||||
|
|
||||||
def +=(s : Status)(implicit rng: Random) = {
|
def addStatus(s : Status, source: EffectSource)(implicit rng: Random) = {
|
||||||
if (s.effectType == EffectType.Volatile && !volatile.exists(_.name == s.name)) {
|
if (s.effectType == EffectType.Volatile && !volatile.exists(_.name == s.name)) {
|
||||||
volatile +:= s
|
volatile +:= s
|
||||||
s.onStart(this)
|
s.onStart(this, source)
|
||||||
} else if (s.effectType == EffectType.NonVolatile && status == None) {
|
} else if (s.effectType == EffectType.NonVolatile && status == None) {
|
||||||
status = Some(s)
|
status = Some(s)
|
||||||
s.onStart(this)
|
s.onStart(this, source)
|
||||||
} else {
|
} else {
|
||||||
println("But it failed!")
|
println("But it failed!")
|
||||||
}
|
}
|
||||||
@ -65,7 +65,7 @@ class Monster(val base : StorageMon) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def applyBoost(s : Stat, boost : Int) {
|
def applyBoost(s : Stat, boost : Int, effect: EffectSource) {
|
||||||
val modified = boosts.getOrElse(s, 0) + boost
|
val modified = boosts.getOrElse(s, 0) + boost
|
||||||
boosts = boosts.updated(s, Math.min(MaxBoost, Math.max(-MaxBoost, modified)))
|
boosts = boosts.updated(s, Math.min(MaxBoost, Math.max(-MaxBoost, modified)))
|
||||||
if (boost > 0) {
|
if (boost > 0) {
|
||||||
|
@ -21,8 +21,9 @@ object Target extends Enumeration {
|
|||||||
}
|
}
|
||||||
class TargetType extends TypeReference[Target.type]
|
class TargetType extends TypeReference[Target.type]
|
||||||
|
|
||||||
trait MoveTurn {
|
trait MoveTurn extends Effect {
|
||||||
def name: String
|
def name: String
|
||||||
|
def effectType = EffectType.MoveEffect
|
||||||
def flags: Set[String]
|
def flags: Set[String]
|
||||||
def prior: Int
|
def prior: Int
|
||||||
def target: Target
|
def target: Target
|
||||||
@ -101,16 +102,16 @@ abstract class Move extends MoveTurn {
|
|||||||
println(s"$target fainted!")
|
println(s"$target fainted!")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
applyBoosts(target, boosts)
|
applyBoosts(target, boosts, user)
|
||||||
applyStatus(target, status)
|
applyStatus(target, user, status)
|
||||||
if (effect != null) {
|
if (effect != null) {
|
||||||
applyEffect(target, effect)
|
applyEffect(target, user, effect)
|
||||||
}
|
}
|
||||||
if (selfEffect != null) {
|
if (selfEffect != null) {
|
||||||
applyEffect(user, selfEffect)
|
applyEffect(user, user, selfEffect)
|
||||||
}
|
}
|
||||||
if (secondary != null && rng.chance(secondary.chance.%%)) {
|
if (secondary != null && rng.chance(secondary.chance.%%)) {
|
||||||
applyEffect(target, secondary)
|
applyEffect(target, user, secondary)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO : Multiparty
|
// TODO : Multiparty
|
||||||
@ -160,24 +161,23 @@ abstract class Move extends MoveTurn {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def applyEffect(target: Monster, effect: Secondary)(implicit rng: Random) {
|
def applyEffect(target: Monster, source: Monster, effect: Secondary)(implicit rng: Random) {
|
||||||
applyBoosts(target, effect.boosts)
|
applyBoosts(target, effect.boosts, source)
|
||||||
applyStatus(target, effect.status)
|
applyStatus(target, source, effect.status)
|
||||||
applyStatus(target, effect.volatile)
|
applyStatus(target, source, effect.volatile)
|
||||||
}
|
}
|
||||||
|
|
||||||
def applyStatus(target: Monster, status: StatusTemplate)(implicit rng: Random) {
|
def applyStatus(target: Monster, user: Monster, status: StatusTemplate)(implicit rng: Random) {
|
||||||
if (target.isAlive && status != null) {
|
if (target.isAlive && status != null) {
|
||||||
target += status.build
|
target.addStatus(status.build, EffectSource(user, this))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def applyBoosts(target: Monster, boosts: Map[Stat, Int]) {
|
def applyBoosts(target: Monster, boosts: Map[Stat, Int], source: Monster) {
|
||||||
if (target.isAlive) {
|
if (target.isAlive) {
|
||||||
boosts.foreach {
|
boosts.foreach {
|
||||||
case (s, b) => {
|
case (s, b) => {
|
||||||
target.applyBoost(s, b)
|
target.applyBoost(s, b, EffectSource(source, this))
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,9 +12,12 @@ import EffectType.Volatile
|
|||||||
|
|
||||||
object EffectType extends Enumeration {
|
object EffectType extends Enumeration {
|
||||||
|
|
||||||
val NonVolatile, Volatile, Field, Weather = Value
|
val NonVolatile, Volatile, AbilityEffect, MoveEffect, ItemEffect, Field, Weather = Value
|
||||||
|
|
||||||
def parse(s : String, default : EffectType) = s match {
|
def parse(s : String, default : EffectType) = s match {
|
||||||
|
case "ability" => AbilityEffect
|
||||||
|
case "item" => ItemEffect
|
||||||
|
case "move" => MoveEffect
|
||||||
case "status" => NonVolatile
|
case "status" => NonVolatile
|
||||||
case "volatile" => Volatile
|
case "volatile" => Volatile
|
||||||
case "weather" => Weather
|
case "weather" => Weather
|
||||||
@ -22,11 +25,29 @@ object EffectType extends Enumeration {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class Status(template: StatusTemplate) {
|
trait Effect {
|
||||||
|
def name: String
|
||||||
|
def effectType: EffectType
|
||||||
|
|
||||||
|
def isItem = effectType == EffectType.ItemEffect
|
||||||
|
def isMove = effectType == EffectType.MoveEffect
|
||||||
|
def isAbility = effectType == EffectType.AbilityEffect
|
||||||
|
}
|
||||||
|
|
||||||
|
case class EffectSource(mon: Monster, effect: Effect) {
|
||||||
|
def isItem = effect.isItem
|
||||||
|
def isMove = effect.isMove
|
||||||
|
def isAbility = effect.isAbility
|
||||||
|
|
||||||
|
def triggerMsg = s"[${mon}'s ${effect}]"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Status(template: StatusTemplate) extends Effect {
|
||||||
def name = template.name
|
def name = template.name
|
||||||
// val id
|
// val id
|
||||||
def effectType = template.effectType
|
def effectType = template.effectType
|
||||||
def onStart(mon: Monster)(implicit rng: Random) = template.onStart(this, mon, rng)
|
def onStart(mon: Monster, source: EffectSource)(implicit rng: Random) = template.onStart(this, mon, source, rng)
|
||||||
def onEnd(mon: Monster) = template.onEnd(this, mon)
|
def onEnd(mon: Monster) = template.onEnd(this, mon)
|
||||||
def onModifyStat(mon: Monster, stat: Stat) = template.onModifyStat(this, mon, stat)
|
def onModifyStat(mon: Monster, stat: Stat) = template.onModifyStat(this, mon, stat)
|
||||||
// val onBeforeMovePriority : Int
|
// val onBeforeMovePriority : Int
|
||||||
@ -47,7 +68,7 @@ abstract class StatusTemplate {
|
|||||||
val name: String
|
val name: String
|
||||||
// val id
|
// val id
|
||||||
val effectType: EffectType
|
val effectType: EffectType
|
||||||
val onStart: (Status, Monster, Random) => Unit
|
val onStart: (Status, Monster, EffectSource, Random) => Unit
|
||||||
val onEnd: (Status, Monster) => Unit
|
val onEnd: (Status, Monster) => Unit
|
||||||
val onModifyStat: (Status, Monster, Stat) => Fraction
|
val onModifyStat: (Status, Monster, Stat) => Fraction
|
||||||
// val onBeforeMovePriority : Int
|
// val onBeforeMovePriority : Int
|
||||||
@ -91,7 +112,7 @@ object Status {
|
|||||||
private var statuses = Map[String, StatusTemplate]()
|
private var statuses = Map[String, StatusTemplate]()
|
||||||
val tokens = YamlHelper.extractMap[StatusToken](Source.fromInputStream(Status.getClass.getResourceAsStream("data/statuses.yaml")))
|
val tokens = YamlHelper.extractMap[StatusToken](Source.fromInputStream(Status.getClass.getResourceAsStream("data/statuses.yaml")))
|
||||||
|
|
||||||
def apply(name: String) = {
|
def apply(name: String): StatusTemplate = {
|
||||||
if (!statuses.contains(name)) {
|
if (!statuses.contains(name)) {
|
||||||
statuses = statuses.updated(name, tokens(name).instantiate())
|
statuses = statuses.updated(name, tokens(name).instantiate())
|
||||||
}
|
}
|
||||||
@ -107,21 +128,21 @@ object Status {
|
|||||||
import fmon.util._
|
import fmon.util._
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def compileOnStart(code: String): (Status, Monster /*, source, source effect */, Random ) => Unit = {
|
def compileOnStart(code: String): (Status, Monster, EffectSource, Random ) => Unit = {
|
||||||
if (code == null) {
|
if (code == null) {
|
||||||
(_, _, _) => ()
|
(_, _, _, _) => ()
|
||||||
} else {
|
} else {
|
||||||
val tree = tb.parse(
|
val tree = tb.parse(
|
||||||
s"""
|
s"""
|
||||||
|$header
|
|$header
|
||||||
|def onStart(self:Status, mon: Monster, rng: Random) = {
|
|def onStart(self:Status, mon: Monster, source: EffectSource, 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[(Status, Monster, Random) => Unit]
|
wrapper.asInstanceOf[(Status, Monster, EffectSource, Random) => Unit]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@ aftermath:
|
|||||||
num: 106
|
num: 106
|
||||||
onAfterDamage: |-
|
onAfterDamage: |-
|
||||||
if ((source != null) && (source != mon) && (move != null) && move.flags("contact") && !mon.isAlive) {
|
if ((source != null) && (source != mon) && (move != null) && move.flags("contact") && !mon.isAlive) {
|
||||||
|
trigger
|
||||||
println(s"$source is damaged in the aftermath!")
|
println(s"$source is damaged in the aftermath!")
|
||||||
source.takeDamage(source(Hp) / 4);
|
source.takeDamage(source(Hp) / 4);
|
||||||
}
|
}
|
||||||
@ -30,7 +31,7 @@ flamebody:
|
|||||||
onAfterDamage: |-
|
onAfterDamage: |-
|
||||||
if (move != null && move.flags("contact")) {
|
if (move != null && move.flags("contact")) {
|
||||||
if (rng.chance(3, 10)) {
|
if (rng.chance(3, 10)) {
|
||||||
source += Status("brn");
|
source.addStatus(Status("brn"), EffectSource(mon, self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rating: 2
|
rating: 2
|
||||||
@ -42,9 +43,8 @@ gooey:
|
|||||||
num: 183
|
num: 183
|
||||||
onAfterDamage: |-
|
onAfterDamage: |-
|
||||||
if (move != null && move.flags("contact")) {
|
if (move != null && move.flags("contact")) {
|
||||||
//this.add('-ability', target, 'Gooey');
|
trigger
|
||||||
source.applyBoost(Speed, -1)
|
source.applyBoost(Speed, -1, effect)
|
||||||
//this.boost({'spe': -1}, source, target, null, true);
|
|
||||||
}
|
}
|
||||||
rating: 2.5
|
rating: 2.5
|
||||||
shortDesc: Pokemon making contact with this Pokemon have their Speed lowered by
|
shortDesc: Pokemon making contact with this Pokemon have their Speed lowered by
|
||||||
@ -58,6 +58,7 @@ innardsout:
|
|||||||
num: 215
|
num: 215
|
||||||
onAfterDamage: |-
|
onAfterDamage: |-
|
||||||
if (source != null && source != mon && move != null /* && move.effectType === 'Move'*/ && !mon.isAlive) {
|
if (source != null && source != mon && move != null /* && move.effectType === 'Move'*/ && !mon.isAlive) {
|
||||||
|
trigger
|
||||||
println(s"$source is damaged in the aftermath!")
|
println(s"$source is damaged in the aftermath!")
|
||||||
source.takeDamage(damage)//, source, target);
|
source.takeDamage(damage)//, source, target);
|
||||||
}
|
}
|
||||||
@ -74,6 +75,7 @@ ironbarbs:
|
|||||||
num: 160
|
num: 160
|
||||||
onAfterDamage: |-
|
onAfterDamage: |-
|
||||||
if (source != null && source != mon && move != null && move.flags("contact")) {
|
if (source != null && source != mon && move != null && move.flags("contact")) {
|
||||||
|
trigger
|
||||||
println(s"Pointed barbs dug into $source!")
|
println(s"Pointed barbs dug into $source!")
|
||||||
source.takeDamage(source(Hp) / 8)//, source, target)
|
source.takeDamage(source(Hp) / 8)//, source, target)
|
||||||
}
|
}
|
||||||
@ -88,7 +90,7 @@ poisonpoint:
|
|||||||
onAfterDamage: |-
|
onAfterDamage: |-
|
||||||
if (move != null && move.flags("contact")) {
|
if (move != null && move.flags("contact")) {
|
||||||
if (rng.chance(3, 10)) {
|
if (rng.chance(3, 10)) {
|
||||||
source += Status("psn")
|
source.addStatus(Status("psn"), EffectSource(mon, self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rating: 2
|
rating: 2
|
||||||
@ -102,6 +104,7 @@ roughskin:
|
|||||||
num: 24
|
num: 24
|
||||||
onAfterDamage: |-
|
onAfterDamage: |-
|
||||||
if (source != null && source != mon && move != null && move.flags("contact")) {
|
if (source != null && source != mon && move != null && move.flags("contact")) {
|
||||||
|
trigger
|
||||||
println(s"$source is damaged by rough skin!")
|
println(s"$source is damaged by rough skin!")
|
||||||
source.takeDamage(source(Hp) / 8)//, source, target)
|
source.takeDamage(source(Hp) / 8)//, source, target)
|
||||||
}
|
}
|
||||||
@ -115,6 +118,7 @@ stamina:
|
|||||||
num: 192
|
num: 192
|
||||||
onAfterDamage: |-
|
onAfterDamage: |-
|
||||||
if (move != null /*&& effect.effectType == 'Move' && effect.id != 'confused'*/) {
|
if (move != null /*&& effect.effectType == 'Move' && effect.id != 'confused'*/) {
|
||||||
|
trigger
|
||||||
mon.applyBoost(PDef, +1)
|
mon.applyBoost(PDef, +1)
|
||||||
}
|
}
|
||||||
rating: 3
|
rating: 3
|
||||||
@ -127,7 +131,7 @@ static:
|
|||||||
onAfterDamage: |-
|
onAfterDamage: |-
|
||||||
if (move != null && move.flags("contact")) {
|
if (move != null && move.flags("contact")) {
|
||||||
if (rng.chance(3, 10)) {
|
if (rng.chance(3, 10)) {
|
||||||
source += Status("par");
|
source.addStatus(Status("par"), EffectSource(mon, self))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rating: 2
|
rating: 2
|
||||||
@ -139,8 +143,9 @@ tanglinghair:
|
|||||||
num: 221
|
num: 221
|
||||||
onAfterDamage: |-
|
onAfterDamage: |-
|
||||||
if (move != null && move.flags("contact")) {
|
if (move != null && move.flags("contact")) {
|
||||||
this.add('-ability', target, 'Tangling Hair');
|
//this.add('-ability', target, 'Tangling Hair');
|
||||||
source.applyBoost(Speed, -1)
|
trigger
|
||||||
|
source.applyBoost(Speed, -1, effect)
|
||||||
//this.boost({'spe': -1}, source, target, null, true);
|
//this.boost({'spe': -1}, source, target, null, true);
|
||||||
}
|
}
|
||||||
rating: 2.5
|
rating: 2.5
|
||||||
@ -156,7 +161,9 @@ weakarmor:
|
|||||||
onAfterDamage: |-
|
onAfterDamage: |-
|
||||||
if (move.category == Physical) {
|
if (move.category == Physical) {
|
||||||
//this.boost({'def': -1, 'spe': 2}, target, target);
|
//this.boost({'def': -1, 'spe': 2}, target, target);
|
||||||
|
trigger
|
||||||
mon.applyBoost(PDef, -1)
|
mon.applyBoost(PDef, -1)
|
||||||
|
trigger
|
||||||
mon.applyBoost(Speed, +2)
|
mon.applyBoost(Speed, +2)
|
||||||
}
|
}
|
||||||
rating: 1
|
rating: 1
|
||||||
|
@ -10,6 +10,9 @@ brn:
|
|||||||
1.frac
|
1.frac
|
||||||
}
|
}
|
||||||
onStart: |
|
onStart: |
|
||||||
|
if (!source.isMove) {
|
||||||
|
print(s"[${source.mon}'s ${source.effect}]")
|
||||||
|
}
|
||||||
println(s"${mon} was burned!")
|
println(s"${mon} was burned!")
|
||||||
/*
|
/*
|
||||||
if (sourceEffect && sourceEffect.id === 'flameorb') {
|
if (sourceEffect && sourceEffect.id === 'flameorb') {
|
||||||
@ -77,6 +80,9 @@ par:
|
|||||||
num: 0
|
num: 0
|
||||||
effectType: 'Status'
|
effectType: 'Status'
|
||||||
onStart: |
|
onStart: |
|
||||||
|
if (!source.isMove) {
|
||||||
|
print(s"[${source.mon}'s ${source.effect}]")
|
||||||
|
}
|
||||||
println(s"${mon} was paralyzed!")
|
println(s"${mon} was paralyzed!")
|
||||||
/*
|
/*
|
||||||
if (sourceEffect && sourceEffect.effectType === 'Ability') {
|
if (sourceEffect && sourceEffect.effectType === 'Ability') {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user