Skip to content

Commit

Permalink
Implement remaining Academy Elite ability
Browse files Browse the repository at this point in the history
  • Loading branch information
radar committed Jan 17, 2024
1 parent cbb0874 commit e21997b
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 35 deletions.
18 changes: 17 additions & 1 deletion lib/magic/cards/academy_elite.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,23 @@ def perform
end

def etb_triggers = [ETB]
end

class ActivatedAbility < ActivatedAbility
def costs
[
Costs::Mana.new(generic: 2, blue: 1),
Costs::RemoveCounter.new(source, Counters::Plus1Plus1),
]
end

def resolve!
game.add_effect(Effects::DrawCards.new(source: source, player: source.controller))

game.choices.add(Magic::Choice::Discard.new(player: source.controller))
end
end

def activated_abilities = [ActivatedAbility]
end
end
end
20 changes: 20 additions & 0 deletions lib/magic/costs/remove_counter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module Magic
module Costs
class RemoveCounter
attr_reader :source, :counter_class

def initialize(source, counter_class)
@source = source
@counter_class = counter_class
end

def can_pay?
source.counters.count(counter_class) > 0
end

def finalize!(_player)
source.remove_counter(counter_class)
end
end
end
end
18 changes: 18 additions & 0 deletions lib/magic/events/counter_removed.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module Magic
module Events
class CounterRemoved
attr_reader :permanent, :player, :counter_type, :amount

def initialize(permanent: nil, player: nil, counter_type:, amount:)
@permanent = permanent
@player = player
@counter_type = counter_type
@amount = amount
end

def inspect
"#<Events::CounterRemoved player: #{player&.name}, permanent: #{permanent&.name}, type: #{counter_type}, amount: #{amount}>"
end
end
end
end
19 changes: 19 additions & 0 deletions lib/magic/permanent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,25 @@ def add_counter(counter_type, amount: 1)
game.notify!(counter_added)
end

def remove_counter(counter_type, amount: 1)
removable_counters = @counters.select { |counter| counter.is_a?(counter_type) }.first(amount)
if removable_counters.count < amount
raise "Not enough #{counter_type} counters to remove"
end

events = []
removable_counters.each do |counter|
@counters.delete(counter)
events << Events::CounterRemoved.new(
permanent: self,
counter_type: counter_type,
amount: amount
)
end

game.notify!(events)
end

def target_choices
card.target_choices(self)
end
Expand Down
91 changes: 57 additions & 34 deletions spec/cards/academy_elite_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,55 +3,78 @@
RSpec.describe Magic::Cards::AcademyElite do
include_context "two player game"

subject(:academy_elite) { Card("Academy Elite") }
context "ETB effects" do
subject(:academy_elite) { Card("Academy Elite", owner: p1) }

before do
p1.hand.add(subject)
end

context "when there's a single instant in opponent's graveyard" do
before do
p2.graveyard.add(Card("Shock"))
p1.hand.add(subject)
end

context "when it enters the battlefield" do
it "gets 1 +1/+1 counter" do
p1.add_mana(blue: 4)
p1.cast(card: academy_elite) do
_1.pay_mana(generic: { blue: 3 }, blue: 1)
context "when there's a single instant in opponent's graveyard" do
before do
p2.graveyard.add(Card("Shock"))
end

context "when it enters the battlefield" do
it "gets 1 +1/+1 counter" do
p1.add_mana(blue: 4)
p1.cast(card: academy_elite) do
_1.pay_mana(generic: { blue: 3 }, blue: 1)
end
game.tick!

permanent = p1.permanents.last
expect(permanent.counters.first).to be_a(Magic::Counters::Plus1Plus1)
expect(permanent.power).to eq(1)
expect(permanent.toughness).to eq(1)
end
game.tick!
end
end

permanent = p1.permanents.last
expect(permanent.counters.first).to be_a(Magic::Counters::Plus1Plus1)
expect(permanent.power).to eq(1)
expect(permanent.toughness).to eq(1)
context "when there's an instant and sorcery in opponent's graveyard" do
before do
p2.graveyard.add(Card("Shock"))
p2.graveyard.add(Card("Legion's Judgement"))
end

context "when it enters the battlefield" do
it "gets 2 +1/+1 counters" do
p1.add_mana(blue: 4)
p1.cast(card: academy_elite) do
_1.pay_mana(generic: { blue: 3 }, blue: 1)
end
game.tick!

permanent = p1.permanents.last
expect(permanent.counters.first).to be_a(Magic::Counters::Plus1Plus1)
expect(permanent.power).to eq(2)
expect(permanent.toughness).to eq(2)
end
end
end
end

context "when there's an instant and sorcery in opponent's graveyard" do
context "activated ability" do
let(:academy_elite) { ResolvePermanent("Academy Elite", owner: p1) }

before do
p2.graveyard.add(Card("Shock"))
p2.graveyard.add(Card("Legion's Judgement"))
academy_elite.add_counter(Magic::Counters::Plus1Plus1)
end

context "when it enters the battlefield" do
it "gets 2 +1/+1 counters" do
p1.add_mana(blue: 4)
p1.cast(card: academy_elite) do
_1.pay_mana(generic: { blue: 3 }, blue: 1)
end
game.tick!

permanent = p1.permanents.last
expect(permanent.counters.first).to be_a(Magic::Counters::Plus1Plus1)
expect(permanent.power).to eq(2)
expect(permanent.toughness).to eq(2)
it "removes a +1/+1 counter, draws a card and discards a card" do
expect(p1).to receive(:draw!)

p1.add_mana(blue: 3)
p1.activate_ability(ability: academy_elite.activated_abilities.first) do
_1.pay_mana(generic: { blue: 2 }, blue: 1)
end

expect(academy_elite.counters.count).to eq(0)

choice = game.choices.last
expect(choice).to be_a(Magic::Choice::Discard)
choice.choose(p1.hand.cards.first)
expect(p1.graveyard.cards.count).to eq(1)
end
end

it "activated ability to loot a card"
end

0 comments on commit e21997b

Please sign in to comment.