568 lines
20 KiB
CoffeeScript
568 lines
20 KiB
CoffeeScript
require '../helpers'
|
|
|
|
{Battle} = require('../../server/bw/battle')
|
|
{Pokemon} = require('../../server/bw/pokemon')
|
|
{Status, Attachment} = require('../../server/bw/attachment')
|
|
{Conditions} = require '../../shared/conditions'
|
|
{Factory} = require '../factory'
|
|
should = require 'should'
|
|
shared = require '../shared'
|
|
{Protocol} = require '../../shared/protocol'
|
|
|
|
describe 'Mechanics', ->
|
|
describe 'an attack missing', ->
|
|
it 'deals no damage', ->
|
|
shared.create.call this,
|
|
team1: [Factory('Celebi')]
|
|
team2: [Factory('Magikarp')]
|
|
shared.biasRNG.call(this, 'randInt', 'miss', 100)
|
|
move = @battle.getMove('Leaf Storm')
|
|
originalHP = @p2.currentHP
|
|
@battle.performMove(@p1, @battle.getMove('Leaf Storm'))
|
|
@p2.currentHP.should.equal(originalHP)
|
|
|
|
it 'triggers effects dependent on the move missing', ->
|
|
shared.create.call this,
|
|
team1: [Factory('Hitmonlee')]
|
|
team2: [Factory('Magikarp')]
|
|
shared.biasRNG.call(this, 'randInt', 'miss', 100)
|
|
hiJumpKick = @battle.getMove('Hi Jump Kick')
|
|
mock = @sandbox.mock(hiJumpKick).expects('afterMiss').once()
|
|
@battle.performMove(@p1, hiJumpKick)
|
|
mock.verify()
|
|
|
|
it 'does not trigger effects dependent on the move hitting', ->
|
|
shared.create.call this,
|
|
team1: [Factory('Celebi')]
|
|
team2: [Factory('Gyarados')]
|
|
shared.biasRNG.call(this, 'randInt', 'miss', 100)
|
|
hiJumpKick = @battle.getMove('Hi Jump Kick')
|
|
mock = @sandbox.mock(hiJumpKick).expects('afterSuccessfulHit').never()
|
|
@battle.performMove(@p1, hiJumpKick)
|
|
mock.verify()
|
|
|
|
describe 'fainting', ->
|
|
it 'forces a new pokemon to be picked', ->
|
|
shared.create.call this,
|
|
team1: [Factory('Mew'), Factory('Heracross')]
|
|
team2: [Factory('Hitmonchan'), Factory('Heracross')]
|
|
spy = @sandbox.spy(@battle, 'tellPlayer')
|
|
@p2.currentHP = 1
|
|
@controller.makeMove(@id1, 'Psychic')
|
|
@controller.makeMove(@id2, 'Mach Punch')
|
|
spy.calledWith(@id2, Protocol.REQUEST_ACTIONS).should.be.true
|
|
|
|
it 'does not increment the turn count', ->
|
|
shared.create.call this,
|
|
team1: [Factory('Mew'), Factory('Heracross')]
|
|
team2: [Factory('Hitmonchan'), Factory('Heracross')]
|
|
turn = @battle.turn
|
|
@p2.currentHP = 1
|
|
@controller.makeMove(@id1, 'Psychic')
|
|
@controller.makeMove(@id2, 'Mach Punch')
|
|
@battle.turn.should.not.equal turn + 1
|
|
|
|
it 'removes the fainted pokemon from the action priority queue', ->
|
|
shared.create.call this,
|
|
team1: [Factory('Mew'), Factory('Heracross')]
|
|
team2: [Factory('Hitmonchan'), Factory('Heracross')]
|
|
@p1.currentHP = 1
|
|
@p2.currentHP = 1
|
|
@controller.makeMove(@id1, 'Psychic')
|
|
@controller.makeMove(@id2, 'Mach Punch')
|
|
@p1.currentHP.should.be.below 1
|
|
@p2.currentHP.should.equal 1
|
|
action = @battle.getAction(@p1)
|
|
should.not.exist(action)
|
|
|
|
it 'lets the player switch in a new pokemon', ->
|
|
shared.create.call this,
|
|
team1: [Factory('Mew'), Factory('Heracross')]
|
|
team2: [Factory('Hitmonchan'), Factory('Heracross')]
|
|
@p2.currentHP = 1
|
|
@controller.makeMove(@id1, 'Psychic')
|
|
@controller.makeMove(@id2, 'Mach Punch')
|
|
@controller.makeSwitch(@id2, 1)
|
|
@team2.first().species.should.equal 'Heracross'
|
|
|
|
it "occurs when a pokemon faints from passive damage", ->
|
|
shared.create.call(this)
|
|
@p2.currentHP = 1
|
|
@battle.performMove(@p1, @battle.getMove("Leech Seed"))
|
|
spy = @sandbox.spy(@p2, 'faint')
|
|
@battle.endTurn()
|
|
spy.calledOnce.should.be.true
|
|
|
|
it "occurs when a pokemon faints normally", ->
|
|
shared.create.call(this)
|
|
@p2.currentHP = 1
|
|
spy = @sandbox.spy(@p2, 'faint')
|
|
@battle.performMove(@p1, @battle.getMove("Tackle"))
|
|
spy.calledOnce.should.be.true
|
|
|
|
describe 'secondary effect attacks', ->
|
|
it 'can inflict effect on successful hit', ->
|
|
shared.create.call this,
|
|
team1: [Factory('Porygon-Z')]
|
|
team2: [Factory('Porygon-Z')]
|
|
shared.biasRNG.call(this, "next", 'secondary effect', 0) # 100% chance
|
|
@battle.performMove(@p1, @battle.getMove('Flamethrower'))
|
|
@p2.has(Status.Burn).should.be.true
|
|
|
|
describe 'the fang attacks', ->
|
|
it 'can inflict two effects at the same time', ->
|
|
shared.create.call this,
|
|
team1: [Factory('Gyarados')]
|
|
team2: [Factory('Gyarados')]
|
|
shared.biasRNG.call(this, "randInt", "secondary effect", 0) # 100% chance
|
|
shared.biasRNG.call(this, "randInt", "flinch", 0)
|
|
@battle.performMove(@p1, @battle.getMove("Ice Fang"))
|
|
|
|
@p2.has(Attachment.Flinch).should.be.true
|
|
@p2.has(Status.Freeze).should.be.true
|
|
|
|
describe 'a pokemon with technician', ->
|
|
it "doesn't increase damage if the move has bp > 60", ->
|
|
shared.create.call this,
|
|
team1: [Factory('Hitmontop')]
|
|
team2: [Factory('Mew')]
|
|
icePunch = @battle.getMove('Ice Punch')
|
|
icePunch.modifyBasePower(@battle, @p1, @p2).should.equal(0x1000)
|
|
|
|
it "increases damage if the move has bp <= 60", ->
|
|
shared.create.call this,
|
|
team1: [Factory('Hitmontop')]
|
|
team2: [Factory('Shaymin')]
|
|
bulletPunch = @battle.getMove('Bullet Punch')
|
|
bulletPunch.modifyBasePower(@battle, @p1, @p2).should.equal(0x1800)
|
|
|
|
describe 'STAB', ->
|
|
it "gets applied if the move and user share a type", ->
|
|
shared.create.call this,
|
|
team1: [Factory('Heracross')]
|
|
team2: [Factory('Regirock')]
|
|
megahorn = @battle.getMove("Megahorn")
|
|
megahorn.stabModifier(@battle, @p1, @p2).should.equal(0x1800)
|
|
|
|
it "doesn't get applied if the move and user are of different types", ->
|
|
shared.create.call this,
|
|
team1: [Factory('Hitmonchan')]
|
|
team2: [Factory('Mew')]
|
|
icePunch = @battle.getMove("Ice Punch")
|
|
icePunch.stabModifier(@battle, @p1, @p2).should.equal(0x1000)
|
|
|
|
describe 'turn order', ->
|
|
it 'randomly decides winner if pokemon have the same speed and priority', ->
|
|
shared.create.call this,
|
|
team1: [Factory('Mew')]
|
|
team2: [Factory('Mew')]
|
|
spy = @sandbox.spy(@battle, 'determineTurnOrder')
|
|
shared.biasRNG.call(this, "next", "turn order", .6)
|
|
@battle.recordMove(@id1, @battle.getMove('Psychic'))
|
|
@battle.recordMove(@id2, @battle.getMove('Psychic'))
|
|
@battle.determineTurnOrder().map((o) -> o.pokemon).should.eql [ @p2, @p1 ]
|
|
|
|
@battle.pokemonActions = []
|
|
|
|
shared.biasRNG.call(this, "next", "turn order", .4)
|
|
@battle.recordMove(@id1, @battle.getMove('Psychic'))
|
|
@battle.recordMove(@id2, @battle.getMove('Psychic'))
|
|
@battle.determineTurnOrder().map((o) -> o.pokemon).should.eql [ @p1, @p2 ]
|
|
|
|
it 'decides winner by highest priority move', ->
|
|
shared.create.call this,
|
|
team1: [Factory('Hitmonchan')]
|
|
team2: [Factory('Hitmonchan')]
|
|
spy = @sandbox.spy(@battle, 'determineTurnOrder')
|
|
@battle.recordMove(@id1, @battle.getMove('Mach Punch'))
|
|
@battle.recordMove(@id2, @battle.getMove('Psychic'))
|
|
@battle.determineTurnOrder().map((o) -> o.pokemon).should.eql [ @p1, @p2 ]
|
|
|
|
@battle.pokemonActions = []
|
|
|
|
@battle.recordMove(@id1, @battle.getMove('Psychic'))
|
|
@battle.recordMove(@id2, @battle.getMove('Mach Punch'))
|
|
@battle.determineTurnOrder().map((o) -> o.pokemon).should.eql [ @p2, @p1 ]
|
|
|
|
it 'decides winner by speed if priority is equal', ->
|
|
shared.create.call this,
|
|
team1: [Factory('Hitmonchan')]
|
|
team2: [Factory('Hitmonchan', evs: { speed: 4 })]
|
|
@battle.recordMove(@id1, @battle.getMove('ThunderPunch'))
|
|
@battle.recordMove(@id2, @battle.getMove('ThunderPunch'))
|
|
@battle.determineTurnOrder().map((o) -> o.pokemon).should.eql [ @p2, @p1 ]
|
|
|
|
describe 'fainting all the opposing pokemon', ->
|
|
it "doesn't request any more actions from players", ->
|
|
shared.create.call this,
|
|
team1: [Factory('Hitmonchan')]
|
|
team2: [Factory('Mew')]
|
|
@p2.currentHP = 1
|
|
@controller.makeMove(@id1, 'Mach Punch')
|
|
@controller.makeMove(@id2, 'Psychic')
|
|
@battle.requests.should.not.have.property @id1.id
|
|
@battle.requests.should.not.have.property @id2.id
|
|
|
|
it 'ends the battle', ->
|
|
shared.create.call this,
|
|
team1: [Factory('Hitmonchan')]
|
|
team2: [Factory('Mew')]
|
|
@p2.currentHP = 1
|
|
mock = @sandbox.mock(@battle)
|
|
mock.expects('endBattle').once()
|
|
@controller.makeMove(@id1, 'Mach Punch')
|
|
@controller.makeMove(@id2, 'Psychic')
|
|
mock.verify()
|
|
|
|
describe 'a pokemon with a type immunity', ->
|
|
it 'cannot be damaged by a move of that type', ->
|
|
shared.create.call this,
|
|
team1: [Factory('Camerupt')]
|
|
team2: [Factory('Gyarados')]
|
|
@controller.makeMove(@id1, 'Earthquake')
|
|
@controller.makeMove(@id2, 'Dragon Dance')
|
|
|
|
@p2.currentHP.should.equal @p2.stat('hp')
|
|
|
|
describe 'a confused pokemon', ->
|
|
it "has a 50% chance of hurting itself", ->
|
|
shared.create.call(this)
|
|
|
|
shared.biasRNG.call(this, "randInt", 'confusion turns', 1) # always 1 turn
|
|
@p1.attach(Attachment.Confusion, {@battle})
|
|
shared.biasRNG.call(this, "next", 'confusion', 0) # always hits
|
|
|
|
mock = @sandbox.mock(@battle.getMove('Tackle'))
|
|
mock.expects('execute').never()
|
|
|
|
@controller.makeMove(@id1, 'Tackle')
|
|
@controller.makeMove(@id2, 'Splash')
|
|
|
|
mock.verify()
|
|
|
|
@p1.currentHP.should.be.lessThan @p1.stat('hp')
|
|
@p2.currentHP.should.equal @p2.stat('hp')
|
|
|
|
it "deals a minimum of 1 damage", ->
|
|
shared.create.call(this, team1: [Factory("Shuckle", level: 1)])
|
|
|
|
shared.biasRNG.call(this, "randInt", 'confusion turns', 1) # always 1 turn
|
|
@p1.attach(Attachment.Confusion, {@battle})
|
|
shared.biasRNG.call(this, "next", 'confusion', 0) # always hits
|
|
@sandbox.stub(@battle.confusionMove, 'calculateDamage', -> 0)
|
|
|
|
@battle.performMove(@p1, @battle.getMove('Tackle'))
|
|
|
|
@p1.currentHP.should.equal(@p1.stat('hp') - 1)
|
|
|
|
it "snaps out of confusion after a predetermined number of turns", ->
|
|
shared.create.call(this)
|
|
|
|
shared.biasRNG.call(this, "randInt", 'confusion turns', 1) # always 1 turn
|
|
@p1.attach(Attachment.Confusion)
|
|
|
|
@controller.makeMove(@id1, 'Splash')
|
|
@controller.makeMove(@id2, 'Splash')
|
|
|
|
@controller.makeMove(@id1, 'Splash')
|
|
@controller.makeMove(@id2, 'Splash')
|
|
|
|
@p1.has(Attachment.Confusion).should.be.false
|
|
|
|
it "will not crit the confusion recoil", ->
|
|
shared.create.call(this)
|
|
|
|
@p1.attach(Attachment.Confusion)
|
|
shared.biasRNG.call(this, "next", 'confusion', 0) # always recoils
|
|
shared.biasRNG.call(this, 'next', 'ch', 0) # always crits
|
|
|
|
spy = @sandbox.spy(@battle.confusionMove, 'isCriticalHit')
|
|
@controller.makeMove(@id1, 'Tackle')
|
|
@controller.makeMove(@id2, 'Tackle')
|
|
|
|
spy.returned(false).should.be.true
|
|
|
|
it "will not error for not having unusual move properties", ->
|
|
shared.create.call(this, team1: [Factory("Magikarp", ability: "Iron Fist")])
|
|
|
|
@p1.attach(Attachment.Confusion)
|
|
shared.biasRNG.call(this, "next", 'confusion', 0) # always recoils
|
|
|
|
(=>
|
|
@controller.makeMove(@id1, 'Tackle')
|
|
@controller.makeMove(@id2, 'Tackle')
|
|
).should.not.throw()
|
|
|
|
describe 'a frozen pokemon', ->
|
|
it "will not execute moves", ->
|
|
shared.create.call(this)
|
|
@p1.attach(Status.Freeze)
|
|
shared.biasRNG.call(this, "next", 'unfreeze chance', 1) # always stays frozen
|
|
|
|
mock = @sandbox.mock(@battle.getMove('Tackle'))
|
|
mock.expects('execute').never()
|
|
|
|
@controller.makeMove(@id1, 'Tackle')
|
|
@controller.makeMove(@id2, 'Splash')
|
|
|
|
mock.verify()
|
|
|
|
it "has a 20% chance of unfreezing", ->
|
|
shared.create.call(this)
|
|
@p1.attach(Status.Freeze)
|
|
shared.biasRNG.call(this, "next", 'unfreeze chance', 0) # always unfreezes
|
|
|
|
@controller.makeMove(@id1, 'Splash')
|
|
@controller.makeMove(@id2, 'Splash')
|
|
|
|
@p1.has(Status.Freeze).should.be.false
|
|
|
|
it "unfreezes if hit by a fire move", ->
|
|
shared.create.call(this)
|
|
shared.biasRNG.call(this, "next", 'unfreeze chance', 1) # always stays frozen
|
|
@p1.attach(Status.Freeze)
|
|
|
|
@battle.performMove(@p2, @battle.getMove('Flamethrower'))
|
|
@p1.has(Status.Freeze).should.be.false
|
|
|
|
it "does not unfreeze if hit by a non-damaging move", ->
|
|
shared.create.call(this)
|
|
shared.biasRNG.call(this, "next", 'unfreeze chance', 1) # always stays frozen
|
|
@p1.attach(Status.Freeze)
|
|
|
|
@battle.performMove(@p2, @battle.getMove('Will-O-Wisp'))
|
|
@p1.has(Status.Freeze).should.be.true
|
|
|
|
for moveName in ["Sacred Fire", "Flare Blitz", "Flame Wheel", "Fusion Flare", "Scald"]
|
|
it "automatically unfreezes if using #{moveName}", ->
|
|
shared.create.call(this)
|
|
|
|
@p1.attach(Status.Freeze)
|
|
shared.biasRNG.call(this, "next", 'unfreeze chance', 1) # always stays frozen
|
|
|
|
@battle.performMove(@p1, @battle.getMove(moveName))
|
|
@p1.has(Status.Freeze).should.be.false
|
|
|
|
describe "a paralyzed pokemon", ->
|
|
it "has a 25% chance of being fully paralyzed", ->
|
|
shared.create.call(this)
|
|
|
|
@p1.attach(Status.Paralyze)
|
|
shared.biasRNG.call(this, "next", 'paralyze chance', 0) # always stays frozen
|
|
|
|
mock = @sandbox.mock(@battle.getMove('Tackle'))
|
|
mock.expects('execute').never()
|
|
|
|
@controller.makeMove(@id1, 'Tackle')
|
|
@controller.makeMove(@id2, 'Splash')
|
|
|
|
mock.verify()
|
|
|
|
it "has its speed quartered", ->
|
|
shared.create.call(this)
|
|
|
|
speed = @p1.stat('speed')
|
|
@p1.attach(Status.Paralyze)
|
|
|
|
@p1.stat('speed').should.equal Math.floor(speed / 4)
|
|
|
|
describe "a burned pokemon", ->
|
|
it "loses 1/8 of its HP each turn", ->
|
|
shared.create.call(this)
|
|
@p1.attach(Status.Burn)
|
|
hp = @p1.currentHP
|
|
eighth = Math.floor(hp / 8)
|
|
|
|
@battle.endTurn()
|
|
(hp - @p1.currentHP).should.equal(eighth)
|
|
|
|
@battle.endTurn()
|
|
(hp - @p1.currentHP).should.equal(2 * eighth)
|
|
|
|
it "loses 1 minimum HP", ->
|
|
shared.create.call(this, team1: [Factory("Shedinja")])
|
|
@p1.attach(Status.Burn)
|
|
@p1.currentHP.should.equal(1)
|
|
|
|
@battle.endTurn()
|
|
@p1.currentHP.should.equal(0)
|
|
|
|
describe "a sleeping pokemon", ->
|
|
it "sleeps for 1-3 turns", ->
|
|
shared.create.call(this)
|
|
shared.biasRNG.call(this, "randInt", 'sleep turns', 3)
|
|
@p1.attach(Status.Sleep)
|
|
tackle = @battle.getMove('Tackle')
|
|
|
|
for i in [0...3]
|
|
@battle.performMove(@p1, tackle)
|
|
@p1.has(Status.Sleep).should.be.true
|
|
|
|
@battle.performMove(@p1, tackle)
|
|
@p1.has(Status.Sleep).should.be.false
|
|
|
|
it "cannot move while asleep", ->
|
|
shared.create.call(this)
|
|
shared.biasRNG.call(this, "randInt", 'sleep turns', 3)
|
|
@p1.attach(Status.Sleep)
|
|
tackle = @battle.getMove('Tackle')
|
|
|
|
mock = @sandbox.mock(tackle).expects('execute').never()
|
|
for i in [0...3]
|
|
@battle.performMove(@p1, tackle)
|
|
mock.verify()
|
|
tackle.execute.restore()
|
|
|
|
mock = @sandbox.mock(tackle).expects('execute').once()
|
|
@battle.performMove(@p1, tackle)
|
|
mock.verify()
|
|
|
|
it "resets its counter when switching out", ->
|
|
shared.create.call this,
|
|
team1: [ Factory("Magikarp"), Factory("Magikarp") ]
|
|
shared.biasRNG.call(this, "randInt", 'sleep turns', 1)
|
|
@p1.attach(Status.Sleep)
|
|
tackle = @battle.getMove('Tackle')
|
|
|
|
@battle.performMove(@p1, tackle)
|
|
@battle.performSwitch(@team1.first(), 1)
|
|
@battle.performSwitch(@team1.first(), 1)
|
|
@battle.performMove(@team1.first(), tackle)
|
|
@p1.has(Status.Sleep).should.be.true
|
|
|
|
describe "a poisoned pokemon", ->
|
|
it "loses 1/8 of its HP each turn", ->
|
|
shared.create.call(this)
|
|
@p1.attach(Status.Poison)
|
|
hp = @p1.currentHP
|
|
eighth = Math.floor(hp / 8)
|
|
|
|
@battle.endTurn()
|
|
(hp - @p1.currentHP).should.equal(eighth)
|
|
|
|
@battle.endTurn()
|
|
(hp - @p1.currentHP).should.equal(2 * eighth)
|
|
|
|
it "loses 1 minimum HP", ->
|
|
shared.create.call(this, team1: [Factory("Shedinja")])
|
|
@p1.attach(Status.Poison)
|
|
@p1.currentHP.should.equal(1)
|
|
|
|
@battle.endTurn()
|
|
@p1.currentHP.should.equal(0)
|
|
|
|
describe "a badly poisoned pokemon", ->
|
|
it "loses 1/16 of its HP the first turn", ->
|
|
shared.create.call(this)
|
|
@p1.attach(Status.Toxic)
|
|
hp = @p1.currentHP
|
|
|
|
@battle.endTurn()
|
|
(hp - @p1.currentHP).should.equal(hp >> 4)
|
|
|
|
it "loses 1/16 of its max HP, rounded down, times x where x is the number of turns up to 15", ->
|
|
shared.create.call(this)
|
|
@p1.attach(Status.Toxic)
|
|
hp = @p1.currentHP
|
|
fraction = (hp >> 4)
|
|
|
|
for i in [1..16]
|
|
@battle.endTurn()
|
|
hpFraction = Math.min(fraction * i, fraction * 15)
|
|
(hp - @p1.currentHP).should.equal(hpFraction)
|
|
@p1.currentHP = hp
|
|
|
|
it "still increases the counter with poison heal", ->
|
|
shared.create.call(this, team1: [Factory("Magikarp", ability: "Poison Heal")])
|
|
@p1.attach(Status.Toxic)
|
|
hp = @p1.currentHP
|
|
fraction = (hp >> 4)
|
|
turns = 3
|
|
|
|
for i in [1...turns]
|
|
@battle.endTurn()
|
|
|
|
@p1.copyAbility(null)
|
|
@battle.endTurn()
|
|
hpFraction = Math.min(fraction * turns, fraction * 15)
|
|
(hp - @p1.currentHP).should.equal(hpFraction)
|
|
|
|
it "loses 1 minimum HP", ->
|
|
shared.create.call(this, team1: [Factory("Shedinja")])
|
|
@p1.attach(Status.Toxic)
|
|
@p1.currentHP.should.equal(1)
|
|
|
|
@battle.endTurn()
|
|
@p1.currentHP.should.equal(0)
|
|
|
|
it "resets its counter when switching out", ->
|
|
shared.create.call this,
|
|
team1: [ Factory("Magikarp"), Factory("Magikarp") ]
|
|
@p1.attach(Status.Toxic)
|
|
hp = @p1.currentHP
|
|
|
|
@battle.endTurn()
|
|
@battle.performSwitch(@team1.first(), 1)
|
|
@p1.currentHP = hp
|
|
@battle.performSwitch(@team1.first(), 1)
|
|
@battle.endTurn()
|
|
(hp - @p1.currentHP).should.equal(hp >> 4)
|
|
|
|
describe "Pokemon#turnsActive", ->
|
|
it "is 1 on start of battle", ->
|
|
shared.create.call(this)
|
|
@p1.turnsActive.should.equal 1
|
|
|
|
it "is set to 0 when switching", ->
|
|
shared.create.call(this, team1: (Factory("Magikarp") for x in [1..2]))
|
|
@p1.turnsActive = 4
|
|
@team1.switch(@p1, 0)
|
|
@team1.first().turnsActive.should.equal 0
|
|
|
|
it "increases by 1 when a turn ends", ->
|
|
shared.create.call(this)
|
|
@p1.turnsActive.should.equal 1
|
|
|
|
@battle.endTurn()
|
|
@p1.turnsActive.should.equal 2
|
|
|
|
describe "A move with 0 PP", ->
|
|
it "will not execute", ->
|
|
shared.create.call(this)
|
|
move = @p1.moves[0]
|
|
@p1.setPP(move, 0)
|
|
|
|
@sandbox.mock(move).expects('execute').never()
|
|
@sandbox.mock(@p1).expects('beforeMove').never()
|
|
@battle.performMove(@p1, move)
|
|
|
|
describe "A pokemon with no available moves", ->
|
|
it "can struggle", ->
|
|
shared.create.call(this)
|
|
@battle.removeRequest(@id1)
|
|
|
|
# Next turn, @p1 will have no available moves.
|
|
for move in @p1.moves
|
|
@p1.blockMove(move)
|
|
@p1.resetBlocks = ->
|
|
|
|
@p1.validMoves().should.be.empty
|
|
@battle.beginTurn()
|
|
request = @battle.requestFor(@p1)
|
|
should.exist(request)
|
|
request.should.have.property('moves')
|
|
request.moves.should.eql(["Struggle"])
|
|
|
|
describe "Ability activation at the beginning of a battle", ->
|
|
it "considers Abilities that are always active", ->
|
|
shared.create.call this,
|
|
team1: [Factory("Magikarp", ability: "Clear Body")]
|
|
team2: [Factory("Magikarp", ability: "Intimidate")]
|
|
@p1.stages.should.containEql(attack: 0)
|
|
|
|
xit "works the same way regardless of the entry order", ->
|
|
shared.create.call this,
|
|
team1: [Factory("Magikarp", ability: "Intimidate")]
|
|
team2: [Factory("Magikarp", ability: "Clear Body")]
|
|
@p2.stages.should.containEql(attack: 0)
|