diff --git a/lib/magic/abilities/static/power_and_toughness_modification.rb b/lib/magic/abilities/static/power_and_toughness_modification.rb index c71344c..9beb988 100644 --- a/lib/magic/abilities/static/power_and_toughness_modification.rb +++ b/lib/magic/abilities/static/power_and_toughness_modification.rb @@ -3,12 +3,20 @@ module Abilities module Static class PowerAndToughnessModification < StaticAbility attr_reader :source, :power, :toughness, :applicable_targets - def initialize(source:, power:, toughness:, applicable_targets:) + + def self.modify(power:, toughness:) + define_method(:power) { power } if power + define_method(:toughness) { toughness } if toughness + end + + def self.other_creatures(creature_type) + define_method(:applicable_targets) do + source.controller.creatures.by_type(creature_type) - [source] + end + end + + def initialize(source:) @source = source - @power = power - @toughness = toughness - @applicable_targets = applicable_targets - @applied_to = [] end def applies_to?(target) diff --git a/lib/magic/cards/canopy_tactician.rb b/lib/magic/cards/canopy_tactician.rb new file mode 100644 index 0000000..6bfb905 --- /dev/null +++ b/lib/magic/cards/canopy_tactician.rb @@ -0,0 +1,27 @@ +module Magic + module Cards + CanopyTactician = Creature("Canopy Tactician") do + cost generic: 3, green: 1 + creature_type "Elf Warrior" + power 3 + toughness 3 + end + + class CanopyTactician < Creature + class PowerAndToughnessModification < Abilities::Static::PowerAndToughnessModification + modify power: 1, toughness: 1 + other_creatures "Elf" + end + + def static_abilities = [PowerAndToughnessModification] + + class ManaAbility < Magic::TapManaAbility + def resolve! + source.controller.add_mana(green: 3) + end + end + + def activated_abilities = [ManaAbility] + end + end +end diff --git a/lib/magic/cards/crown_of_skemfar.rb b/lib/magic/cards/crown_of_skemfar.rb new file mode 100644 index 0000000..0012d24 --- /dev/null +++ b/lib/magic/cards/crown_of_skemfar.rb @@ -0,0 +1,49 @@ +module Magic + module Cards + class CrownOfSkemfar < Aura + card_name "Crown of Skemfar" + cost "{2}{G}{G}" + + def target_choices + battlefield.creatures + end + + def elves + battlefield.controlled_by(owner).by_type("Elf").count + end + + def power_modification + elves + end + + def toughness_modification + elves + end + + def keyword_grants + [Keywords::REACH] + end + + class ReturnFromGraveyard < Magic::ActivatedAbility + def costs = [Costs::Mana.new(generic: 2, green: 1)] + + def resolve! + source.controller.graveyard.remove(source) + source.controller.hand.add(source) + end + end + + def can_activate_ability?(ability) + return true unless ability.is_a?(ReturnFromGraveyard) + + return true if self.zone == controller.graveyard + + false + end + + def activated_abilities + [ReturnFromGraveyard.new(source: self)] + end + end + end +end diff --git a/lib/magic/cards/elvish_archdruid.rb b/lib/magic/cards/elvish_archdruid.rb index e1445d5..64c019e 100644 --- a/lib/magic/cards/elvish_archdruid.rb +++ b/lib/magic/cards/elvish_archdruid.rb @@ -5,23 +5,12 @@ module Cards toughness 2 cost generic: 1, green: 2 creature_type "Elf Druid" + end + class ElvishArchdruid < Creature class PowerAndToughnessModification < Abilities::Static::PowerAndToughnessModification - def initialize(source:) - @source = source - end - - def power - 1 - end - - def toughness - 1 - end - - def applicable_targets - source.controller.creatures.by_type("Elf") - [source] - end + modify power: 1, toughness: 1 + other_creatures "Elf" end class ManaAbility < Magic::TapManaAbility diff --git a/spec/cards/canopy_tactician_spec.rb b/spec/cards/canopy_tactician_spec.rb new file mode 100644 index 0000000..b29b661 --- /dev/null +++ b/spec/cards/canopy_tactician_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper' + +RSpec.describe Magic::Cards::CanopyTactician do + include_context "two player game" + + subject! { ResolvePermanent("Canopy Tactician", owner: p1) } + let!(:lathril) { ResolvePermanent("Lathril, Blade Of The Elves", owner: p1) } + + context "static ability" do + it "gives lathril +1/+1" do + expect(lathril.power).to eq(3) + expect(lathril.toughness).to eq(4) + end + + it "does not give itself the boost" do + expect(subject.power).to eq(3) + expect(subject.toughness).to eq(3) + end + end + + context "mana ability" do + def activate_ability + p1.activate_ability(ability: subject.activated_abilities.first) + end + + it "adds 3 green mana" do + activate_ability + expect(p1.mana_pool[:green]).to eq(3) + end + end +end diff --git a/spec/cards/crown_of_skemfar_spec.rb b/spec/cards/crown_of_skemfar_spec.rb new file mode 100644 index 0000000..a529dd2 --- /dev/null +++ b/spec/cards/crown_of_skemfar_spec.rb @@ -0,0 +1,43 @@ +require "spec_helper" + +RSpec.describe Magic::Cards::CrownOfSkemfar do + include_context "two player game" + + subject(:crown_of_skemfar) { Card("Crown Of Skemfar") } + + let!(:wood_elves) { ResolvePermanent("Wood Elves") } + + it "attaches to a creature" do + p1.add_mana(green: 4) + action = cast_action(player: p1, card: subject) + .pay_mana(green: 2, generic: { green: 2 }) + .targeting(wood_elves) + game.take_action(action) + game.stack.resolve! + expect(wood_elves.power).to eq(2) + expect(wood_elves.toughness).to eq(2) + expect(wood_elves.has_keyword?(Magic::Cards::Keywords::REACH)).to eq(true) + + expect(p1.permanents.by_name("Crown of Skemfar").count).to eq(1) + end + + context "return from graveyard to hand" do + let(:crown_of_skemfar) { Card("Crown Of Skemfar") } + + before do + p1.graveyard.add(crown_of_skemfar) + end + + it "returns to hand" do + ability = crown_of_skemfar.activated_abilities.first + p1.add_mana(green: 3) + p1.activate_ability(ability: ability) do + _1.pay_mana(generic: { green: 2 }, green: 1) + end + + game.tick! + + expect(p1.hand).to include(crown_of_skemfar) + end + end +end