Messages will now play when an ability triggers

This commit is contained in:
James Daly 2019-06-06 17:37:32 -04:00
parent d2ee6debf8
commit bebbf469db
6 changed files with 87 additions and 44 deletions

View File

@ -7,13 +7,15 @@ import scala.util.Random
import fmon.util._
abstract class Ability {
abstract class Ability extends Effect {
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)
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
}
@ -53,16 +55,23 @@ object Ability {
|import fmon.stat.Statistic._
|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) {
(_, _, _, _, _) => ()
(_, _, _, _, _, _) => ()
} else {
val tree = tb.parse(
s"""
|$header
|def onAfterDamage(source: Monster, move: MoveTurn, mon: Monster, damage: Int, rng: Random): Unit = {
| implicit val gen = rng
|def onAfterDamage(self: Ability, source: Monster, move: MoveTurn, mon: Monster, damage: Int, rng: Random): Unit = {
| $helper
| $code
|}
|onAfterDamage _
@ -70,7 +79,7 @@ object Ability {
val f = tb.compile(tree)
val wrapper = f()
implicit val c = code
wrapper.asInstanceOf[(Monster, MoveTurn, Monster, Int, Random) => Unit]
wrapper.asInstanceOf[(Ability, Monster, MoveTurn, Monster, Int, Random) => Unit]
}
}
}

View File

@ -44,13 +44,13 @@ class Monster(val base : StorageMon) {
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)) {
volatile +:= s
s.onStart(this)
s.onStart(this, source)
} else if (s.effectType == EffectType.NonVolatile && status == None) {
status = Some(s)
s.onStart(this)
s.onStart(this, source)
} else {
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
boosts = boosts.updated(s, Math.min(MaxBoost, Math.max(-MaxBoost, modified)))
if (boost > 0) {

View File

@ -21,8 +21,9 @@ object Target extends Enumeration {
}
class TargetType extends TypeReference[Target.type]
trait MoveTurn {
trait MoveTurn extends Effect {
def name: String
def effectType = EffectType.MoveEffect
def flags: Set[String]
def prior: Int
def target: Target
@ -101,16 +102,16 @@ abstract class Move extends MoveTurn {
println(s"$target fainted!")
}
}
applyBoosts(target, boosts)
applyStatus(target, status)
applyBoosts(target, boosts, user)
applyStatus(target, user, status)
if (effect != null) {
applyEffect(target, effect)
applyEffect(target, user, effect)
}
if (selfEffect != null) {
applyEffect(user, selfEffect)
applyEffect(user, user, selfEffect)
}
if (secondary != null && rng.chance(secondary.chance.%%)) {
applyEffect(target, secondary)
applyEffect(target, user, secondary)
}
// TODO : Multiparty
@ -160,24 +161,23 @@ abstract class Move extends MoveTurn {
}
}
def applyEffect(target: Monster, effect: Secondary)(implicit rng: Random) {
applyBoosts(target, effect.boosts)
applyStatus(target, effect.status)
applyStatus(target, effect.volatile)
def applyEffect(target: Monster, source: Monster, effect: Secondary)(implicit rng: Random) {
applyBoosts(target, effect.boosts, source)
applyStatus(target, source, effect.status)
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) {
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) {
boosts.foreach {
case (s, b) => {
target.applyBoost(s, b)
target.applyBoost(s, b, EffectSource(source, this))
}
}
}

View File

@ -12,9 +12,12 @@ import EffectType.Volatile
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 {
case "ability" => AbilityEffect
case "item" => ItemEffect
case "move" => MoveEffect
case "status" => NonVolatile
case "volatile" => Volatile
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
// val id
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 onModifyStat(mon: Monster, stat: Stat) = template.onModifyStat(this, mon, stat)
// val onBeforeMovePriority : Int
@ -47,7 +68,7 @@ abstract class StatusTemplate {
val name: String
// val id
val effectType: EffectType
val onStart: (Status, Monster, Random) => Unit
val onStart: (Status, Monster, EffectSource, Random) => Unit
val onEnd: (Status, Monster) => Unit
val onModifyStat: (Status, Monster, Stat) => Fraction
// val onBeforeMovePriority : Int
@ -91,7 +112,7 @@ object Status {
private var statuses = Map[String, StatusTemplate]()
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)) {
statuses = statuses.updated(name, tokens(name).instantiate())
}
@ -107,21 +128,21 @@ object Status {
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) {
(_, _, _) => ()
(_, _, _, _) => ()
} else {
val tree = tb.parse(
s"""
|$header
|def onStart(self:Status, mon: Monster, rng: Random) = {
|def onStart(self:Status, mon: Monster, source: EffectSource, rng: Random) = {
| $code
|}
|onStart _
""".stripMargin)
val f = tb.compile(tree)
val wrapper = f()
wrapper.asInstanceOf[(Status, Monster, Random) => Unit]
wrapper.asInstanceOf[(Status, Monster, EffectSource, Random) => Unit]
}
}

View File

@ -15,6 +15,7 @@ aftermath:
num: 106
onAfterDamage: |-
if ((source != null) && (source != mon) && (move != null) && move.flags("contact") && !mon.isAlive) {
trigger
println(s"$source is damaged in the aftermath!")
source.takeDamage(source(Hp) / 4);
}
@ -30,7 +31,7 @@ flamebody:
onAfterDamage: |-
if (move != null && move.flags("contact")) {
if (rng.chance(3, 10)) {
source += Status("brn");
source.addStatus(Status("brn"), EffectSource(mon, self))
}
}
rating: 2
@ -42,9 +43,8 @@ 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);
trigger
source.applyBoost(Speed, -1, effect)
}
rating: 2.5
shortDesc: Pokemon making contact with this Pokemon have their Speed lowered by
@ -58,6 +58,7 @@ innardsout:
num: 215
onAfterDamage: |-
if (source != null && source != mon && move != null /* && move.effectType === 'Move'*/ && !mon.isAlive) {
trigger
println(s"$source is damaged in the aftermath!")
source.takeDamage(damage)//, source, target);
}
@ -74,6 +75,7 @@ ironbarbs:
num: 160
onAfterDamage: |-
if (source != null && source != mon && move != null && move.flags("contact")) {
trigger
println(s"Pointed barbs dug into $source!")
source.takeDamage(source(Hp) / 8)//, source, target)
}
@ -88,7 +90,7 @@ poisonpoint:
onAfterDamage: |-
if (move != null && move.flags("contact")) {
if (rng.chance(3, 10)) {
source += Status("psn")
source.addStatus(Status("psn"), EffectSource(mon, self))
}
}
rating: 2
@ -102,6 +104,7 @@ roughskin:
num: 24
onAfterDamage: |-
if (source != null && source != mon && move != null && move.flags("contact")) {
trigger
println(s"$source is damaged by rough skin!")
source.takeDamage(source(Hp) / 8)//, source, target)
}
@ -115,6 +118,7 @@ stamina:
num: 192
onAfterDamage: |-
if (move != null /*&& effect.effectType == 'Move' && effect.id != 'confused'*/) {
trigger
mon.applyBoost(PDef, +1)
}
rating: 3
@ -127,7 +131,7 @@ static:
onAfterDamage: |-
if (move != null && move.flags("contact")) {
if (rng.chance(3, 10)) {
source += Status("par");
source.addStatus(Status("par"), EffectSource(mon, self))
}
}
rating: 2
@ -139,8 +143,9 @@ tanglinghair:
num: 221
onAfterDamage: |-
if (move != null && move.flags("contact")) {
this.add('-ability', target, 'Tangling Hair');
source.applyBoost(Speed, -1)
//this.add('-ability', target, 'Tangling Hair');
trigger
source.applyBoost(Speed, -1, effect)
//this.boost({'spe': -1}, source, target, null, true);
}
rating: 2.5
@ -156,7 +161,9 @@ weakarmor:
onAfterDamage: |-
if (move.category == Physical) {
//this.boost({'def': -1, 'spe': 2}, target, target);
trigger
mon.applyBoost(PDef, -1)
trigger
mon.applyBoost(Speed, +2)
}
rating: 1

View File

@ -10,6 +10,9 @@ brn:
1.frac
}
onStart: |
if (!source.isMove) {
print(s"[${source.mon}'s ${source.effect}]")
}
println(s"${mon} was burned!")
/*
if (sourceEffect && sourceEffect.id === 'flameorb') {
@ -77,6 +80,9 @@ par:
num: 0
effectType: 'Status'
onStart: |
if (!source.isMove) {
print(s"[${source.mon}'s ${source.effect}]")
}
println(s"${mon} was paralyzed!")
/*
if (sourceEffect && sourceEffect.effectType === 'Ability') {