Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Making actions instance methods on Player for cleaner Ruby syntax #501

Merged
merged 2 commits into from
Jan 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions lib/magic/action.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
module Magic
class Action
attr_reader :player, :game
attr_reader :game, :player

def initialize(player:)
def initialize(game:, player:)
@game = game
@player = player
@game = player.game
end
end
end
25 changes: 16 additions & 9 deletions lib/magic/actions/activate_ability.rb
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
module Magic
module Actions
class ActivateAbility < Action
attr_reader :permanent, :ability, :costs, :requirements, :targets
attr_reader :ability, :costs, :requirements, :targets

def initialize(permanent:, ability:, **args)
@permanent = permanent
@ability = ability.new(source: permanent)
def initialize(ability:, **args)
@ability = ability
@costs = @ability.costs
@requirements = @ability.requirements
@targets = []
super(**args)
end

def inspect
"#<Actions::Actions::ActivateAbility permanent: #{permanent.name}, ability: #{ability.class}>"
"#<Actions::Actions::ActivateAbility source: #{ability.source.name}, ability: #{ability.class}>"
end

def can_be_activated?(player)
Expand All @@ -39,16 +38,20 @@ def targeting(*targets)
end

def pay_mana(payment)
pay(player, :mana, payment)
pay(:mana, payment)
self
end

def pay_tap
pay(player, :tap)
pay(:tap)
end

def pay_multi_tap(targets)
pay(player, :multi_tap, targets)
pay(:multi_tap, targets)
end

def pay_sacrifice(targets)
pay(:sacrifice, targets)
end

def perform
Expand All @@ -63,7 +66,7 @@ def perform
end
end

def pay(player, cost_type, payment = nil)
def pay(cost_type, payment = nil)
cost_type = case cost_type
when :mana
Costs::Mana
Expand All @@ -85,6 +88,10 @@ def pay(player, cost_type, payment = nil)
self
end

def has_cost?(cost_type)
costs.any? { |cost| cost.is_a?(cost_type) }
end

def finalize_costs!(player)
costs.each { |cost| cost.finalize!(player) }
end
Expand Down
6 changes: 3 additions & 3 deletions lib/magic/actions/activate_loyalty_ability.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ module Actions
class ActivateLoyaltyAbility < Action
attr_reader :ability, :planeswalker, :targets, :x_value

def initialize(planeswalker:, ability:, **args)
@planeswalker = planeswalker
@ability = ability.new(planeswalker: planeswalker)
def initialize(ability:, **args)
@planeswalker = ability.planeswalker
@ability = ability
@targets = []
super(**args)
end
Expand Down
8 changes: 7 additions & 1 deletion lib/magic/actions/cast.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ module Actions
class Cast < Action
extend Forwardable

class InvalidTarget < StandardError; end

def_delegators :@card, :enchantment?, :artifact?
attr_reader :card, :targets
def initialize(card:, **args)
Expand Down Expand Up @@ -47,6 +49,10 @@ def mana_cost
end
end

def auto_pay
mana_cost.auto_pay(player)
end

def kicker_cost
card.kicker_cost
end
Expand All @@ -69,7 +75,7 @@ def can_target?(target)

def targeting(*targets)
targets.each do |target|
raise "Invalid target for #{card.name}: #{target}" unless can_target?(target)
raise InvalidTarget, "Invalid target for #{card.name}: #{target}" unless can_target?(target)
end
@targets = targets
self
Expand Down
3 changes: 1 addition & 2 deletions lib/magic/actions/play_land.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ def inspect
end

def can_perform?
return false if player.can_play_lands?
true
player.can_play_lands?
end

def perform
Expand Down
4 changes: 2 additions & 2 deletions lib/magic/cards/animal_sanctuary.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ def costs
end

def resolve!
controller.add_mana(colorless: 1)
controller.add_mana(generic: 1)
end
end

class ActivatedAbility < Magic::ActivatedAbility
def costs
[
Costs::Mana.new(colorless: 2),
Costs::Mana.new(generic: 2),
Costs::Tap.new(source),
]
end
Expand Down
2 changes: 2 additions & 0 deletions lib/magic/cards/celestial_enforcer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ def resolve!(target:)
target.tap!
end
end

def activated_abilities = [ActivatedAbility]
end
end
end
5 changes: 1 addition & 4 deletions lib/magic/cards/fabled_passage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ module Magic
module Cards
class FabledPassage < Land
NAME = "Fabled Passage"
TYPE_LINE = "Land"

def target_choices(receiver)
receiver.controller.library.basic_lands
Expand Down Expand Up @@ -30,9 +29,7 @@ def resolve!
end
end

def activated_abilities
[ActivatedAbility]
end
def activated_abilities = [ActivatedAbility]
end
end
end
2 changes: 1 addition & 1 deletion lib/magic/cards/faiths_fetters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def can_block?
end

def can_activate_ability?(ability)
ability < ManaAbility
ability.is_a?(ManaAbility)
end
end
end
Expand Down
6 changes: 3 additions & 3 deletions lib/magic/cards/idol_of_endurance.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ def target_choices

def resolve!(target:)
source.remove_from_exile(target)
cast_action = Magic::Actions::Cast.new(card: target, player: source.controller)
cast_action.mana_cost = 0
game.take_action(cast_action)
source.controller.cast(card: target) do
_1.mana_cost = 0
end
end
end

Expand Down
2 changes: 2 additions & 0 deletions lib/magic/cards/land.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
module Magic
module Cards
class Land < Card
type "Land"

def play!
move_zone!(game.battlefield)
end
Expand Down
4 changes: 1 addition & 3 deletions lib/magic/cards/shock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ def single_target?
end

def resolve!(_controller, target:)
game.add_effect(Effects::DealDamage.new(source: self, targets: [target], damage: 2))
game.add_effect(Effects::DealDamage.new(source: self, targets: [target], damage: 2))
end
end


end
end
8 changes: 7 additions & 1 deletion lib/magic/costs/mana.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,19 @@ def can_pay?(player)
end

def pay(player, payment)

raise CannotPay unless can_pay?(player)

pay_generic(payment[:generic]) if payment[:generic]
pay_colors(payment.slice(*Magic::Mana::COLORS))
end

def auto_pay(player)
raise CannotPay unless can_pay?(player)

pay_colors(color_costs)
pay_generic(generic: cost[:generic]) if cost[:generic]
end

def finalize!(player)
raise OutstandingBalance if outstanding_balance?
raise Overpayment if overpaid?
Expand Down
27 changes: 27 additions & 0 deletions lib/magic/effects/single_target.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module Magic
module Effects
class SingleTarget < Effect
class InvalidTarget < StandardError; end;

attr_reader :source, :target, :choices

def initialize(source:, target:, choices: source.target_choices)
@target = target
@source = source
@choices = [*choices]
end

def requires_choices?
true
end

def single_choice?
choices.count == 1
end

def no_choice?
choices.count.zero?
end
end
end
end
4 changes: 0 additions & 4 deletions lib/magic/effects/targeted_effect.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ def choices
end
end

def requires_targets?
true
end

def requires_choices?
true
end
Expand Down
2 changes: 1 addition & 1 deletion lib/magic/game.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def initialize(
def add_players(*players)
players.each(&method(:add_player))
end

\
def add_player(player)
@player_count += 1
@players << player
Expand Down
7 changes: 5 additions & 2 deletions lib/magic/permanent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class Permanent
include Types

extend Forwardable
attr_reader :game, :owner, :controller, :card,:types, :delayed_responses, :attachments, :protections, :modifiers, :counters, :keywords, :keyword_grants, :activated_abilities, :exiled_cards, :cannot_untap_next_turn
attr_reader :game, :owner, :controller, :card, :types, :delayed_responses, :attachments, :protections, :modifiers, :counters, :keywords, :keyword_grants, :activated_abilities, :exiled_cards, :cannot_untap_next_turn

def_delegators :@card, :name, :cmc, :mana_value, :colors, :colorless?
def_delegators :@game, :logger
Expand Down Expand Up @@ -49,7 +49,6 @@ def initialize(game:, owner:, card:, token: false, cast: true, kicked: false)
@keywords = card.keywords
@keyword_grants = []
@counters = Counters::Collection.new([])
@activated_abilities = card.activated_abilities
@damage = 0
@protections = Protections.new(card.protections.dup)
@exiled_cards = Magic::CardList.new([])
Expand All @@ -67,6 +66,10 @@ def inspect
"#<Magic::Permanent name:#{card.name} controller:#{controller.name}>"
end

def activated_abilities
@activated_abilities ||= card.activated_abilities.map { |ability| ability.new(source: self) }
end

alias_method :to_s, :inspect

def controller?(other_controller)
Expand Down
5 changes: 2 additions & 3 deletions lib/magic/permanents/planeswalker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def change_loyalty!(change)
@loyalty += change
destroy! if loyalty <= 0
end

def take_damage(source:, damage:)
game.notify!(
Events::DamageDealt.new(
Expand All @@ -24,9 +24,8 @@ def take_damage(source:, damage:)
change_loyalty!(- damage)
end


def loyalty_abilities
card.loyalty_abilities
card.loyalty_abilities.map { |ability| ability.new(planeswalker: self) }
end
end
end
Expand Down
Loading