Skip to content

[WHO] Implement Osgood, Operation Double #13744

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
125 changes: 125 additions & 0 deletions Mage.Sets/src/mage/cards/o/OsgoodOperationDouble.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package mage.cards.o;

import java.util.UUID;

import mage.ConditionalMana;
import mage.MageInt;
import mage.MageObject;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CastSourceTriggeredAbility;
import mage.abilities.effects.keyword.InvestigateEffect;
import mage.abilities.mana.ConditionalColoredManaAbility;
import mage.abilities.mana.builder.ConditionalManaBuilder;
import mage.constants.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.filter.FilterSpell;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.card.CastFromZonePredicate;
import mage.game.Game;
import mage.game.stack.Spell;
import mage.util.functions.RemoveTypeCopyApplier;

/**
* @author balazskristof
*/
public final class OsgoodOperationDouble extends CardImpl {

private static final FilterSpell filter = new FilterSpell("a spell from anywhere other than your hand");

static {
filter.add(Predicates.not(new CastFromZonePredicate(Zone.HAND)));
}

public OsgoodOperationDouble(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}");

this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.ALIEN);
this.subtype.add(SubType.SHAPESHIFTER);
this.power = new MageInt(2);
this.toughness = new MageInt(2);

// When you cast this spell, create a token that's a copy of it, except it isn't legendary.
this.addAbility(new CastSourceTriggeredAbility(new OsgoodOperationDoubleEffect()));

// {T}: Add {C}. Spend this mana only to cast an artifact spell or activate an ability of an artifact.
this.addAbility(new ConditionalColoredManaAbility(Mana.ColorlessMana(1), new OsgoodOperationDoubleManaBuilder()));

// Paradox -- Whenever you cast a spell from anywhere other than your hand, investigate.
this.addAbility(new SpellCastControllerTriggeredAbility(
new InvestigateEffect(),
filter, false
).setAbilityWord(AbilityWord.PARADOX));
}

private OsgoodOperationDouble(final OsgoodOperationDouble card) {
super(card);
}

@Override
public OsgoodOperationDouble copy() {
return new OsgoodOperationDouble(this);
}
}

class OsgoodOperationDoubleEffect extends OneShotEffect {

OsgoodOperationDoubleEffect() {
super(Outcome.Benefit);
staticText = "create a token that's a copy of it, except it isn't legendary";
}

protected OsgoodOperationDoubleEffect(final OsgoodOperationDoubleEffect effect) {
super(effect);
}

@Override
public boolean apply(Game game, Ability source) {
Spell spell = game.getSpell(source.getSourceId());
if (spell == null) {
return false;
}
spell.createCopyOnStack(game, source, source.getControllerId(), false, 1, new RemoveTypeCopyApplier(SuperType.LEGENDARY));
return true;
}

@Override
public OsgoodOperationDoubleEffect copy() { return new OsgoodOperationDoubleEffect(this); }
}

class OsgoodOperationDoubleManaBuilder extends ConditionalManaBuilder {

@Override
public ConditionalMana build(Object... options) {
return new OsgoodOperationDoubleConditionalMana(this.mana);
}

@Override
public String getRule() {
return "Spend this mana only to cast an artifact spell or activate an ability of an artifact.";
}
}

class OsgoodOperationDoubleConditionalMana extends ConditionalMana {

OsgoodOperationDoubleConditionalMana(Mana mana) {
super(mana);
addCondition(OsgoodOperationDoubleCondition.instance);
}
}

enum OsgoodOperationDoubleCondition implements Condition {
instance;

@Override
public boolean apply(Game game, Ability source) {
MageObject object = game.getObject(source);
return object != null && object.isArtifact(game);
Copy link
Member

@JayDi85 JayDi85 Jun 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you copy or fix code from another card with same ability/effect then must copy/fix all places with same code (even if you don’t understand the original logic). The main idea: same ability/effect must use same implementation code.

IMG_1543

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather not touch this. Cargo Ship and other cards seem to work fine; I can use the mana to activate other activated abilities, like Unearth.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, it’s about allow to activate one time only (activated sets true on activate call).

IMG_1547

I’m not sure why it used or required. Maybe for good playable calculations or some workaround from multiple instances, etc. But it’s better to keep same code.

}
}
8 changes: 4 additions & 4 deletions Mage.Sets/src/mage/sets/DoctorWho.java
Original file line number Diff line number Diff line change
Expand Up @@ -573,10 +573,10 @@ private DoctorWho() {
cards.add(new SetCardInfo("Ominous Cemetery", 189, Rarity.UNCOMMON, mage.cards.o.OminousCemetery.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Ominous Cemetery", 794, Rarity.UNCOMMON, mage.cards.o.OminousCemetery.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("Ood Sphere", 594, Rarity.COMMON, mage.cards.o.OodSphere.class));
//cards.add(new SetCardInfo("Osgood, Operation Double", 191, Rarity.RARE, mage.cards.o.OsgoodOperationDouble.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("Osgood, Operation Double", 367, Rarity.RARE, mage.cards.o.OsgoodOperationDouble.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("Osgood, Operation Double", 796, Rarity.RARE, mage.cards.o.OsgoodOperationDouble.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("Osgood, Operation Double", 958, Rarity.RARE, mage.cards.o.OsgoodOperationDouble.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Osgood, Operation Double", 191, Rarity.RARE, mage.cards.o.OsgoodOperationDouble.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Osgood, Operation Double", 367, Rarity.RARE, mage.cards.o.OsgoodOperationDouble.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Osgood, Operation Double", 796, Rarity.RARE, mage.cards.o.OsgoodOperationDouble.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Osgood, Operation Double", 958, Rarity.RARE, mage.cards.o.OsgoodOperationDouble.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Out of Time", 1058, Rarity.RARE, mage.cards.o.OutOfTime.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Out of Time", 209, Rarity.RARE, mage.cards.o.OutOfTime.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Out of Time", 467, Rarity.RARE, mage.cards.o.OutOfTime.class, NON_FULL_USE_VARIOUS));
Expand Down