Added moves with a cooldown
This commit is contained in:
parent
a475126a3f
commit
908069f2bc
@ -29,8 +29,8 @@ class Game extends Application {
|
||||
implicit val rng = new scala.util.Random()
|
||||
val form1 = Form("Diabolo")
|
||||
val form2 = Form("Chanilla")
|
||||
val movepool1 = IndexedSeq(Move("eruption"), Move("willowisp"), Move("thunderbolt"), Move("thunderwave"), Move("facade"))
|
||||
val movepool2 = IndexedSeq(Move("flail"))
|
||||
val movepool1 = IndexedSeq(Move("eruption"), Move("willowisp"), Move("thunderbolt"), Move("thunderwave"), Move("blastburn"))
|
||||
val movepool2 = IndexedSeq(Move("blastburn"))
|
||||
val p1 = TrainerID("Jaeda", Gender.Female, 0)
|
||||
val p2 = TrainerID("Wild Monster", Gender.Male, 0)
|
||||
val party1 = new Party(p1, new MonsterPtr(Monster.generate("Allied Mon", p1, 500, form1, movepool1)), IndexedSeq())
|
||||
|
@ -18,10 +18,17 @@ class BattleEngine(val player: Party, val enemy: Party)(implicit val reader: Sig
|
||||
|
||||
def playTurn(): Unit = {
|
||||
val playerAction = player.pollAction(enemy)
|
||||
playTurn(playerAction)
|
||||
playTurnImp(playerAction)
|
||||
}
|
||||
|
||||
def playTurn(playerAction: Action): Unit = {
|
||||
playTurnImp(playerAction)
|
||||
while (player.lead.isLocked) {
|
||||
playTurn()
|
||||
}
|
||||
}
|
||||
|
||||
def playTurnImp(playerAction: Action): Unit = {
|
||||
val enemyAction = enemy.pollAction(player)
|
||||
|
||||
val actions = Seq(playerAction, enemyAction)
|
||||
|
@ -39,7 +39,9 @@ class BattleUI extends SignalConsumer {
|
||||
}
|
||||
|
||||
def onMove(move: Move): Unit = {
|
||||
val action = Action(engine.player.lead, move, engine.enemy.lead)
|
||||
implicit val rng = engine.rng
|
||||
implicit val reader = engine
|
||||
val action = Action(engine.player.lead, move, engine.player.pollTarget(move, engine.player.lead, engine.enemy))
|
||||
engine.playTurn(action)
|
||||
updateUI()
|
||||
}
|
||||
|
@ -2,3 +2,4 @@ title: FakeMon Engine Demo
|
||||
crit: 1.5
|
||||
stab: 1.5
|
||||
maxBoost: 6
|
||||
newday: 02:00
|
@ -82,6 +82,10 @@ class Monster(val base : StorageMon) {
|
||||
elements.foldLeft(1.0)((m, e) => m * (element --> e))
|
||||
}
|
||||
|
||||
def isLocked(implicit reader: SignalConsumer, rng: Random): Boolean = {
|
||||
statuses.exists(_.onLockMove(this).isDefined)
|
||||
}
|
||||
|
||||
private def computeStat(s : Stat) : Int = {
|
||||
val num = 2 * base.form.baseStats(s) + base.gene.ivs(s) + base.evs(s) / 4
|
||||
val frac = num * level / 100
|
||||
|
@ -4,15 +4,33 @@ import scala.util.Random
|
||||
|
||||
import fmon._
|
||||
import fmon.battle.Action
|
||||
import fmon.battle.msg.SignalConsumer
|
||||
import fmon.stat.Target._
|
||||
|
||||
class Party(val trainer: TrainerID, val lead: MonsterPtr, var sideboard: IndexedSeq[Monster]) {
|
||||
def pollAction(them: Party)(implicit rng: Random): Action = {
|
||||
if (hasBackup && shouldSwitch(them)) {
|
||||
def pollAction(them: Party)(implicit reader: SignalConsumer, rng: Random): Action = {
|
||||
if (lead.isLocked) {
|
||||
val moveNames = lead.statuses.flatMap(s => s.onLockMove(lead)).distinct
|
||||
moveNames match {
|
||||
case Seq(moveName) => {
|
||||
// Use locked move
|
||||
val move = Move(moveName)
|
||||
// TODO : remember target
|
||||
val target = pollTarget(move, lead, them)
|
||||
Action(lead, move, target)
|
||||
}
|
||||
case _ => {
|
||||
// Struggle
|
||||
val move = Move("struggle")
|
||||
val target = pollTarget(move, lead, them)
|
||||
Action(lead, move, target)
|
||||
}
|
||||
}
|
||||
} else if (hasBackup && shouldSwitch(them)) {
|
||||
val sub = pollReplacement(them: Party)
|
||||
val move = new SwitchOut(this, sub)
|
||||
Action(lead, move, lead)
|
||||
} else {
|
||||
} else{
|
||||
val move = pollMove
|
||||
val target = pollTarget(move, lead, them)
|
||||
Action(lead, move, target)
|
||||
|
@ -59,6 +59,7 @@ class Status(template: StatusTemplate) extends Effect {
|
||||
def onResidualOrder = template.onResidualOrder
|
||||
def onResidual(mon: Monster)(implicit reader: SignalConsumer, rng: Random) = template.onResidual(this, mon, reader, rng)
|
||||
// val onSwitchIn
|
||||
def onLockMove(mon: Monster)(implicit reader: SignalConsumer, rng: Random) = template.onLockMove(this, mon, reader, rng)
|
||||
|
||||
val intData: MutMap[String, Int] = MutMap[String, Int]()
|
||||
val stringData = MutMap[String, String]()
|
||||
@ -80,6 +81,7 @@ abstract class StatusTemplate {
|
||||
val onResidualOrder: Int
|
||||
val onResidual: (Status, Monster, SignalConsumer, Random) => Unit
|
||||
// val onSwitchIn
|
||||
val onLockMove: (Status, Monster, SignalConsumer, Random) => Option[String]
|
||||
|
||||
def build = new Status(this)
|
||||
|
||||
@ -94,7 +96,8 @@ case class StatusToken(
|
||||
val onBeforeMove: String,
|
||||
val onModifyStat: String,
|
||||
val onResidualOrder: Int,
|
||||
val onResidual: String) {
|
||||
val onResidual: String,
|
||||
val onLockMove: String) {
|
||||
def instantiate() = {
|
||||
val self = this
|
||||
new StatusTemplate {
|
||||
@ -106,6 +109,7 @@ case class StatusToken(
|
||||
val onModifyStat = Status.compileOnModifyStat(self.onModifyStat)
|
||||
val onResidualOrder = self.onResidualOrder
|
||||
val onResidual = Status.compileOnResidual(self.onResidual)
|
||||
val onLockMove = Status.compileOnLockMove(self.onLockMove)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -132,6 +136,8 @@ object Status {
|
||||
import fmon.util.Fraction
|
||||
"""
|
||||
private val helpers = """
|
||||
implicit val dice = rng
|
||||
implicit val consumer = reader
|
||||
def msg(text: String): Unit = {
|
||||
reader ! Message(text)
|
||||
}
|
||||
@ -232,4 +238,25 @@ object Status {
|
||||
wrapper.asInstanceOf[(Status, Monster, SignalConsumer, Random) => Unit]
|
||||
}
|
||||
}
|
||||
|
||||
def compileOnLockMove(code: String): (Status, Monster, SignalConsumer, Random) => Option[String] = {
|
||||
if (code == null) {
|
||||
(_, _, _, _) => None
|
||||
} else {
|
||||
val tree = tb.parse(
|
||||
s"""
|
||||
|$header
|
||||
|def onLockMove(self: Status, mon: Monster, reader: SignalConsumer, rng: Random) = {
|
||||
| $helpers
|
||||
| val result = {$code}
|
||||
| Some(result)
|
||||
|}
|
||||
|onLockMove _
|
||||
""".stripMargin)
|
||||
val f = tb.compile(tree)
|
||||
val wrapper = f()
|
||||
|
||||
wrapper.asInstanceOf[(Status, Monster, SignalConsumer, Random) => Option[String]]
|
||||
}
|
||||
}
|
||||
}
|
@ -462,6 +462,29 @@ bite:
|
||||
target: Normal
|
||||
type: Dark
|
||||
zMovePower: 120
|
||||
blastburn:
|
||||
accuracy: 90
|
||||
basePower: 150
|
||||
category: Special
|
||||
contestType: Beautiful
|
||||
desc: If this move is successful, the user must recharge on the following turn and
|
||||
cannot make a move.
|
||||
flags:
|
||||
mirror: 1
|
||||
protect: 1
|
||||
recharge: 1
|
||||
id: blastburn
|
||||
name: Blast Burn
|
||||
num: 307
|
||||
pp: 5
|
||||
priority: 0
|
||||
secondary: null
|
||||
self:
|
||||
volatileStatus: mustrecharge
|
||||
shortDesc: User cannot move next turn.
|
||||
target: Normal
|
||||
type: Fire
|
||||
zMovePower: 200
|
||||
blazekick:
|
||||
accuracy: 90
|
||||
basePower: 85
|
||||
@ -2528,6 +2551,30 @@ forcepalm:
|
||||
target: Normal
|
||||
type: Fighting
|
||||
zMovePower: 120
|
||||
frenzyplant:
|
||||
accuracy: 90
|
||||
basePower: 150
|
||||
category: Special
|
||||
contestType: Cool
|
||||
desc: If this move is successful, the user must recharge on the following turn and
|
||||
cannot select a move.
|
||||
flags:
|
||||
mirror: 1
|
||||
nonsky: 1
|
||||
protect: 1
|
||||
recharge: 1
|
||||
id: frenzyplant
|
||||
name: Frenzy Plant
|
||||
num: 338
|
||||
pp: 5
|
||||
priority: 0
|
||||
secondary: null
|
||||
self:
|
||||
volatileStatus: mustrecharge
|
||||
shortDesc: User cannot move next turn.
|
||||
target: Normal
|
||||
type: Grass
|
||||
zMovePower: 200
|
||||
frostbreath:
|
||||
accuracy: 90
|
||||
basePower: 60
|
||||
@ -2574,6 +2621,30 @@ gigadrain:
|
||||
target: Normal
|
||||
type: Grass
|
||||
zMovePower: 140
|
||||
gigaimpact:
|
||||
accuracy: 90
|
||||
basePower: 150
|
||||
category: Physical
|
||||
contestType: Tough
|
||||
desc: If this move is successful, the user must recharge on the following turn and
|
||||
cannot select a move.
|
||||
flags:
|
||||
contact: 1
|
||||
mirror: 1
|
||||
protect: 1
|
||||
recharge: 1
|
||||
id: gigaimpact
|
||||
name: Giga Impact
|
||||
num: 416
|
||||
pp: 5
|
||||
priority: 0
|
||||
secondary: null
|
||||
self:
|
||||
volatileStatus: mustrecharge
|
||||
shortDesc: User cannot move next turn.
|
||||
target: Normal
|
||||
type: Normal
|
||||
zMovePower: 200
|
||||
glaciate:
|
||||
accuracy: 95
|
||||
basePower: 65
|
||||
@ -3000,6 +3071,29 @@ howl:
|
||||
type: Normal
|
||||
zMoveBoost:
|
||||
PAtk: 1
|
||||
hydrocannon:
|
||||
accuracy: 90
|
||||
basePower: 150
|
||||
category: Special
|
||||
contestType: Beautiful
|
||||
desc: If this move is successful, the user must recharge on the following turn and
|
||||
cannot select a move.
|
||||
flags:
|
||||
mirror: 1
|
||||
protect: 1
|
||||
recharge: 1
|
||||
id: hydrocannon
|
||||
name: Hydro Cannon
|
||||
num: 308
|
||||
pp: 5
|
||||
priority: 0
|
||||
secondary: null
|
||||
self:
|
||||
volatileStatus: mustrecharge
|
||||
shortDesc: User cannot move next turn.
|
||||
target: Normal
|
||||
type: Water
|
||||
zMovePower: 200
|
||||
hydropump:
|
||||
accuracy: 80
|
||||
basePower: 110
|
||||
@ -3019,6 +3113,29 @@ hydropump:
|
||||
target: Normal
|
||||
type: Water
|
||||
zMovePower: 185
|
||||
hyperbeam:
|
||||
accuracy: 90
|
||||
basePower: 150
|
||||
category: Special
|
||||
contestType: Cool
|
||||
desc: If this move is successful, the user must recharge on the following turn and
|
||||
cannot select a move.
|
||||
flags:
|
||||
mirror: 1
|
||||
protect: 1
|
||||
recharge: 1
|
||||
id: hyperbeam
|
||||
name: Hyper Beam
|
||||
num: 63
|
||||
pp: 5
|
||||
priority: 0
|
||||
secondary: null
|
||||
self:
|
||||
volatileStatus: mustrecharge
|
||||
shortDesc: User cannot move next turn.
|
||||
target: Normal
|
||||
type: Normal
|
||||
zMovePower: 200
|
||||
hyperfang:
|
||||
accuracy: 90
|
||||
basePower: 80
|
||||
@ -4801,6 +4918,29 @@ precipiceblades:
|
||||
target: AllAdjacentFoes
|
||||
type: Ground
|
||||
zMovePower: 190
|
||||
prismaticlaser:
|
||||
accuracy: 100
|
||||
basePower: 160
|
||||
category: Special
|
||||
contestType: Cool
|
||||
desc: If this move is successful, the user must recharge on the following turn and
|
||||
cannot select a move.
|
||||
flags:
|
||||
mirror: 1
|
||||
protect: 1
|
||||
recharge: 1
|
||||
id: prismaticlaser
|
||||
name: Prismatic Laser
|
||||
num: 711
|
||||
pp: 10
|
||||
priority: 0
|
||||
secondary: null
|
||||
self:
|
||||
volatileStatus: mustrecharge
|
||||
shortDesc: User cannot move next turn.
|
||||
target: Normal
|
||||
type: Psychic
|
||||
zMovePower: 200
|
||||
psybeam:
|
||||
accuracy: 100
|
||||
basePower: 65
|
||||
@ -4999,6 +5139,48 @@ razorshell:
|
||||
target: Normal
|
||||
type: Water
|
||||
zMovePower: 140
|
||||
recharge:
|
||||
accuracy: 100
|
||||
basePower: 0
|
||||
category: Support
|
||||
contestType: Tough
|
||||
flags:
|
||||
contact: 1
|
||||
mirror: 1
|
||||
protect: 1
|
||||
id: recharge
|
||||
name: Recharge
|
||||
num: 10
|
||||
pp: 40
|
||||
priority: 0
|
||||
secondary: null
|
||||
shortDesc: Placeholder move for when recharging.
|
||||
target: Normal
|
||||
type: Normal
|
||||
zMovePower: 100
|
||||
roaroftime:
|
||||
accuracy: 90
|
||||
basePower: 150
|
||||
category: Special
|
||||
contestType: Beautiful
|
||||
desc: If this move is successful, the user must recharge on the following turn and
|
||||
cannot select a move.
|
||||
flags:
|
||||
mirror: 1
|
||||
protect: 1
|
||||
recharge: 1
|
||||
id: roaroftime
|
||||
name: Roar of Time
|
||||
num: 459
|
||||
pp: 5
|
||||
priority: 0
|
||||
secondary: null
|
||||
self:
|
||||
volatileStatus: mustrecharge
|
||||
shortDesc: User cannot move next turn.
|
||||
target: Normal
|
||||
type: Dragon
|
||||
zMovePower: 200
|
||||
rockclimb:
|
||||
accuracy: 85
|
||||
basePower: 90
|
||||
@ -5127,6 +5309,30 @@ rocktomb:
|
||||
target: Normal
|
||||
type: Rock
|
||||
zMovePower: 120
|
||||
rockwrecker:
|
||||
accuracy: 90
|
||||
basePower: 150
|
||||
category: Physical
|
||||
contestType: Tough
|
||||
desc: If this move is successful, the user must recharge on the following turn and
|
||||
cannot select a move.
|
||||
flags:
|
||||
bullet: 1
|
||||
mirror: 1
|
||||
protect: 1
|
||||
recharge: 1
|
||||
id: rockwrecker
|
||||
name: Rock Wrecker
|
||||
num: 439
|
||||
pp: 5
|
||||
priority: 0
|
||||
secondary: null
|
||||
self:
|
||||
volatileStatus: mustrecharge
|
||||
shortDesc: User cannot move next turn.
|
||||
target: Normal
|
||||
type: Rock
|
||||
zMovePower: 200
|
||||
rollingkick:
|
||||
accuracy: 85
|
||||
basePower: 60
|
||||
|
@ -41,16 +41,6 @@ confusion:
|
||||
true
|
||||
}
|
||||
}
|
||||
/*
|
||||
this.activeTarget = mon;
|
||||
let damage = this.getDamage(mon, mon, 40);
|
||||
if (typeof damage !== 'number') throw new Error('Confusion damage not dealt');
|
||||
mon.takeDamage(damage, mon, mon, /** @type {ActiveMove} */ ({
|
||||
'id': 'confused',
|
||||
'effectType': 'Move',
|
||||
'type': '???'
|
||||
}));
|
||||
*/
|
||||
onBeforeMovePriority: 3
|
||||
onEnd: msg(s"${mon} snapped out of its confusion.")
|
||||
onStart: |-
|
||||
@ -95,11 +85,6 @@ slp:
|
||||
msg(s"${mon} woke up!")
|
||||
onBeforeMovePriority: 10
|
||||
onBeforeMove: |
|
||||
/*
|
||||
if (mon.hasAbility('earlybird')) {
|
||||
this.intData.time--;
|
||||
}
|
||||
*/
|
||||
self.intData("time") -= 1;
|
||||
if (self.intData("time") <= 0) {
|
||||
mon.cureStatus();
|
||||
@ -149,6 +134,21 @@ frz:
|
||||
mon.cureStatus()
|
||||
}
|
||||
|
||||
mustrecharge:
|
||||
duration: 2
|
||||
id: mustrecharge
|
||||
name: mustrecharge
|
||||
num: 0
|
||||
onBeforeMove: |-
|
||||
msg(s"${mon} must recharge!")
|
||||
mon -= self
|
||||
//mon.removeVolatile('mustrecharge');
|
||||
//mon.removeVolatile('truant');
|
||||
false
|
||||
onBeforeMovePriority: 11
|
||||
onLockMove: |
|
||||
"recharge"
|
||||
|
||||
psn:
|
||||
name: 'psn'
|
||||
id: 'psn'
|
||||
|
Loading…
x
Reference in New Issue
Block a user