Re: Help implementing a card
51 new ULG cards
High Quality Resources for Collectible Card Games and Home of the CCGHQ Team
https://www.slightlymagic.net/forum/
https://www.slightlymagic.net/forum/viewtopic.php?f=116&t=5451
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.fifthedition;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DestroyAllEffect;
import mage.cards.CardImpl;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
/**
*
* @author jeffwadsworth
*/
public class NevinyrralsDisk extends CardImpl<NevinyrralsDisk> {
private final static FilterPermanent filter = new FilterPermanent("artifacts, creatures, and enchantments");
static {
filter.add(new CardTypePredicate(CardType.ARTIFACT));
filter.add(new CardTypePredicate(CardType.CREATURE));
filter.add(new CardTypePredicate(CardType.ENCHANTMENT));
}
public NevinyrralsDisk(UUID ownerId) {
super(ownerId, 391, "Nevinyrral's Disk", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{4}");
this.expansionSetCode = "5ED";
// Nevinyrral's Disk enters the battlefield tapped.
this.addAbility(new EntersBattlefieldTappedAbility());
// {1}, {tap}: Destroy all artifacts, creatures, and enchantments.
SimpleActivatedAbility ability = new SimpleActivatedAbility(Constants.Zone.BATTLEFIELD, new DestroyAllEffect(filter), new ManaCostsImpl("{1}"));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
}
public NevinyrralsDisk(final NevinyrralsDisk card) {
super(card);
}
@Override
public NevinyrralsDisk copy() {
return new NevinyrralsDisk(this);
}
}
filter.add(Predicates.or(
new CardTypePredicate(CardType.ARTIFACT),
new CardTypePredicate(CardType.CREATURE),
new CardTypePredicate(CardType.ENCHANTMENT)));/*
/**
*
* @author jeffwadsworth
*/
public class Abomination extends CardImpl<Abomination> {
public Abomination(UUID ownerId) {
super(ownerId, 1, "Abomination", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{B}{B}");
this.expansionSetCode = "4TH";
this.subtype.add("Horror");
/*this.subtype.add("Knight");*/
this.color.setBlack(true);
this.power = new MageInt(2);
this.toughness = new MageInt(6);
// Whenever Abomination blocks or becomes blocked by a green or white creature, destroy that creature at end of combat.
this.addAbility(new AbominationTriggeredAbility());
}
public Abomination(final Abomination card) {
super(card);
}
@Override
public Abomination copy() {
return new Abomination(this);
}
}
class AbominationTriggeredAbility extends TriggeredAbilityImpl<AbominationTriggeredAbility> {
AbominationTriggeredAbility() {
super(Zone.BATTLEFIELD, new AbominationEffect());
}
AbominationTriggeredAbility(final AbominationTriggeredAbility ability) {
super(ability);
}
@Override
public AbominationTriggeredAbility copy() {
return new AbominationTriggeredAbility(this);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.BLOCKER_DECLARED) {
Permanent blocker = game.getPermanent(event.getSourceId());
Permanent abomination = game.getPermanent(sourceId);
if (blocker != null && blocker != abomination && blocker.getColor().isWhite()) {
return true;
}
if (blocker != null && blocker != abomination && blocker.getColor().isGreen()) {
return true;
}
else {
/*return true;*/
}
return false;
}
return false;
}
@Override
public String getRule() {
return "Whenever {this} blocks or becomes blocked by a green or white creature, destroy that creature at end of combat..";
}
}
class AbominationEffect extends OneShotEffect<AbominationEffect> {
AbominationEffect() {
super(Outcome.Detriment);
staticText = "Destroy that creature at the end of combat";
}
AbominationEffect(final AbominationEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability event) {
Permanent permanent = game.getPermanent(event.getSourceId());
if (permanent != null) {
AtTheEndOfCombatDelayedTriggeredAbility delayedAbility = new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect());
delayedAbility.setSourceId(event.getSourceId());
delayedAbility.setControllerId(event.getControllerId());
delayedAbility.getEffects().get(0).setTargetPointer(new FixedTarget(event.getSourceId()));
game.addDelayedTriggeredAbility(delayedAbility);
return true;
}
return false;
}
@Override
public AbominationEffect copy() {
return new AbominationEffect(this);
}
}
You are quite correct. Thanks.LevelX wrote:jeffwadsworth wrote:Does anyone see an issue with this card? It does not destroy the filtered cards.
You have to use the "Predicates.or". The way it's implemented now means AND.
- Code: Select all
filter.add(Predicates.or(
new CardTypePredicate(CardType.ARTIFACT),
new CardTypePredicate(CardType.CREATURE),
new CardTypePredicate(CardType.ENCHANTMENT)));
I see a logic issue with Arrogant Bloodlord. I will fix them both.cbt33 wrote:Abomination originally from Arrogant Bloodlord.
Any good?
- Code: Select all
/*
/**
*
* @author jeffwadsworth
*/
public class Abomination extends CardImpl<Abomination> {
public Abomination(UUID ownerId) {
super(ownerId, 1, "Abomination", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{3}{B}{B}");
this.expansionSetCode = "4TH";
this.subtype.add("Horror");
/*this.subtype.add("Knight");*/
this.color.setBlack(true);
this.power = new MageInt(2);
this.toughness = new MageInt(6);
// Whenever Abomination blocks or becomes blocked by a green or white creature, destroy that creature at end of combat.
this.addAbility(new AbominationTriggeredAbility());
}
public Abomination(final Abomination card) {
super(card);
}
@Override
public Abomination copy() {
return new Abomination(this);
}
}
class AbominationTriggeredAbility extends TriggeredAbilityImpl<AbominationTriggeredAbility> {
AbominationTriggeredAbility() {
super(Zone.BATTLEFIELD, new AbominationEffect());
}
AbominationTriggeredAbility(final AbominationTriggeredAbility ability) {
super(ability);
}
@Override
public AbominationTriggeredAbility copy() {
return new AbominationTriggeredAbility(this);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.BLOCKER_DECLARED) {
Permanent blocker = game.getPermanent(event.getSourceId());
Permanent abomination = game.getPermanent(sourceId);
if (blocker != null && blocker != abomination && blocker.getColor().isWhite()) {
return true;
}
if (blocker != null && blocker != abomination && blocker.getColor().isGreen()) {
return true;
}
else {
/*return true;*/
}
return false;
}
return false;
}
@Override
public String getRule() {
return "Whenever {this} blocks or becomes blocked by a green or white creature, destroy that creature at end of combat..";
}
}
class AbominationEffect extends OneShotEffect<AbominationEffect> {
AbominationEffect() {
super(Outcome.Detriment);
staticText = "Destroy that creature at the end of combat";
}
AbominationEffect(final AbominationEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability event) {
Permanent permanent = game.getPermanent(event.getSourceId());
if (permanent != null) {
AtTheEndOfCombatDelayedTriggeredAbility delayedAbility = new AtTheEndOfCombatDelayedTriggeredAbility(new DestroyTargetEffect());
delayedAbility.setSourceId(event.getSourceId());
delayedAbility.setControllerId(event.getControllerId());
delayedAbility.getEffects().get(0).setTargetPointer(new FixedTarget(event.getSourceId()));
game.addDelayedTriggeredAbility(delayedAbility);
return true;
}
return false;
}
@Override
public AbominationEffect copy() {
return new AbominationEffect(this);
}
}
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.shadowmoor;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author jeffwadsworth
*/
public class IncrementalBlight extends CardImpl<IncrementalBlight> {
public IncrementalBlight(UUID ownerId) {
super(ownerId, 70, "Incremental Blight", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{B}");
this.expansionSetCode = "SHM";
this.color.setBlack(true);
// Put a -1/-1 counter on target creature, two -1/-1 counters on another target creature, and three -1/-1 counters on a third target creature.
this.getSpellAbility().addTarget(new TargetOtherCreaturePermanent());
this.getSpellAbility().addEffect(new IncrementalBlightEffect());
}
public IncrementalBlight(final IncrementalBlight card) {
super(card);
}
@Override
public IncrementalBlight copy() {
return new IncrementalBlight(this);
}
}
class TargetOtherCreaturePermanent extends TargetCreaturePermanent {
public TargetOtherCreaturePermanent() {
super(3, true);
}
public TargetOtherCreaturePermanent(final TargetOtherCreaturePermanent target) {
super(target);
}
@Override
public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) {
if (source.getTargets().get(0).getTargets().contains(id)) {
return false;
}
return super.canTarget(controllerId, id, source, game);
}
@Override
public TargetOtherCreaturePermanent copy() {
return new TargetOtherCreaturePermanent(this);
}
}
class IncrementalBlightEffect extends OneShotEffect<IncrementalBlightEffect> {
public IncrementalBlightEffect() {
super(Constants.Outcome.Detriment);
staticText = "Put a -1/-1 counter on target creature, two -1/-1 counters on another target creature, and three -1/-1 counters on a third target creature";
}
public IncrementalBlightEffect(final IncrementalBlightEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent target1 = game.getPermanent(source.getTargets().get(0).getTargets().get(0));
Permanent target2 = game.getPermanent(source.getTargets().get(0).getTargets().get(1));
Permanent target3 = game.getPermanent(source.getTargets().get(0).getTargets().get(2));
if (target1 != null) {
System.out.println("The first target is " + target1.getName());
target1.addCounters(CounterType.M1M1.createInstance(), game);
}
if (target2 != null) {
System.out.println("The second target is " + target2.getName());
target2.addCounters(CounterType.M1M1.createInstance(2), game);
}
if (target3 != null) {
System.out.println("The third target is " + target3.getName());
target3.addCounters(CounterType.M1M1.createInstance(3), game);
}
return true;
}
@Override
public IncrementalBlightEffect copy() {
return new IncrementalBlightEffect(this);
}
}
package mage.sets.shadowmoor;
import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Outcome;
import mage.Constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.Target;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author LevelX2
*/
public class IncrementalBlight extends CardImpl<IncrementalBlight> {
public IncrementalBlight(UUID ownerId) {
super(ownerId, 70, "Incremental Blight", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{3}{B}{B}");
this.expansionSetCode = "SHM";
this.color.setBlack(true);
// Put a -1/-1 counter on target creature, two -1/-1 counters on another target creature, and three -1/-1 counters on a third target creature.
this.getSpellAbility().addEffect(new IncrementalBlightEffect());
Target target = new TargetCreaturePermanent(3,3);
target.setRequired(true);
this.getSpellAbility().addTarget(target);
}
public IncrementalBlight(final IncrementalBlight card) {
super(card);
}
@Override
public IncrementalBlight copy() {
return new IncrementalBlight(this);
}
}
class IncrementalBlightEffect extends OneShotEffect<IncrementalBlightEffect> {
public IncrementalBlightEffect() {
super(Outcome.UnboostCreature);
this.staticText = "Put a -1/-1 counter on target creature, two -1/-1 counters on another target creature, and three -1/-1 counters on a third target creature";
}
public IncrementalBlightEffect(final IncrementalBlightEffect effect) {
super(effect);
}
@Override
public IncrementalBlightEffect copy() {
return new IncrementalBlightEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
int i = 0;
for (UUID targetId : getTargetPointer().getTargets(game, source)) {
i++;
Permanent creature = game.getPermanent(targetId);
if (creature != null) {
creature.addCounters(CounterType.M1M1.createInstance(i), game);
}
}
return false;
}
}
public class AegisOfHonor extends CardImpl<AegisOfHonor>{
public AegisOfHonor(ownerId UUID){
super(ownerId, 1, "Aegis of Honor", Rarity.RARE, new CardType[]{Cardtype.ENCHANTMENT}, "{W}");
this.ExpansionSetCode = "ODY";
this.color.setWhite(true);
// {1} The next time The next time an instant or sorcery spell would deal damage to you this
//turn, that spell deals that damage to its controller instead.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new AegisOfHonorEffect(), ManaCostsImpl("1")));
}
public AegisOfHonor(final AegisOfHonor card) {
super(card);
}
@Override
public AegisOfHonor copy() {
return new AegisOfHonor(this);
}
class AegisOfHonorEffect extends RedirectionEffect<AegisOfHonorEffect> {
public AegisOfHonorEffect() {
super(Duration.EndOfTurn);
staticText = "The next time The next time an instant or sorcery spell would deal "
+ "damage to you this turn, that spell deals that damage to its controller "
+ "instead.";
}
@Override
public AegisOfHonorEffect copy() {
return new AegisOfHonorEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType().equals(GameEvent.EventType.DAMAGE_PLAYER)) {
//if event.getSourceID.getCardType.equals.or(CardType.INSTANT, CardType.SORCERY) {
// if (getSourceID() != getPlayer(ID)){ <-Needed?
Card sourceCard = game.getCard(source.getSourceID());
if (sourceCard != null && (sourceCard.getCardType().contains(CardType.INSTANT) || sourceCard.getCardType().contains(CardType.SORCERY))); {
return true;
}
return true;
}
return true;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
DamageEvent damageEvent = (DamageEvent)event;
Player sourcePlayer = game.getPlayer(source.getSourceId());
this.used = true;
sourcePlayer.damage(damageEvent.getAmount(), damageSource.getSourceId(), game, damageEvent.isPreventable(), event.getAppliedEffects());
}
RedirectionEffect was not made yet to be used in cards. I changed it to be usable. See the newly commited card Shield Dancer.cbt33 wrote:For Aegis of Honor:
With RedirectionEffect, do you need to use replaceEffect() or does the permanent.damage part never occur because of the applies member function stipulating the event as player damage?
Card sourceCard = game.getCard(source.getSourceID());Yes you have to add acbt33 wrote:Should an extra if statement go into the applies m.f. to make sure it only redirects when other spells damage the player not when the player's spells damage the opponent?
event.getTargetId().equals(source.getControllerId())To locally play a game you need to run the mage server, of course.cbt33 wrote:Is it correct that you need to run the Mage.Server module in Netbeans along with a regular client to test new cards?
Yes, both. First build the complete project (Mage Root). Then run the Mage Server and Mage Client, connect to the Server, start a Game.cbt33 wrote:If so do you need to build or run mage.server?
Seems like you didn't build all parts of the project. As said use right mouse button menu on MAGE Root project and choose "Clean and build". That will build all projects and this has to executed without an error. If here an error is shown, please let me know what error is shown.cbt33 wrote:Build takes a very long time but I can't get run to work, I get this error:
Failed to execute goal on project mage-server: Could not resolve dependencies for project org.mage:mage-server:jar:1.1.0: The following artifacts could not be resolved: org.mage:mage-sets:jar:1.1.0...(the rest triggers spam filter) was cached in the local repository, resolution will not be reattempted until the update interval of jboss-public-repository has elapsed or updates are forced [Help 1]
Defining proxy can have some relevance because some java libs must be downloaded by maven.cbt33 wrote:I'm using school internet and a school computer which may or may not use a proxy if that has any relevance. I can also get mage.server.console to work somehow, just not server or client with which i get the same error.
It's like this:cbt33 wrote:Thanks. So then when you test a card, you compile it individually, put the class file into Mage.Sets.target.classes.mage.sets, then run the server and client.