Merge google-code.
commit
f3ae0c14fb
7
Makefile
7
Makefile
|
@ -110,7 +110,10 @@ cards/existing_tokens_%.txt: $(wildcard release/Magarena/scripts/*.txt)
|
|||
cards/existing_%.txt: cards/existing_scripts_%.txt cards/existing_tokens_%.txt
|
||||
join -v1 -t"|" <(sort $(word 1,$^)) <(sort $(word 2,$^)) > $@
|
||||
|
||||
%_full.txt: scripts/extract_candidates.awk %.txt cards/mtg-data.txt
|
||||
cards/groovy.txt:
|
||||
grep -ho "name=.*" `grep requires_groovy_code -lr release/Magarena/scripts` | sed 's/name=//' | sort > $@
|
||||
|
||||
%_full.txt: scripts/extract_candidates.awk %.txt cards/groovy.txt cards/mtg-data.txt
|
||||
awk -f $^ | sed 's/\t/\n/g' > $@
|
||||
|
||||
cards/candidates_full.txt: scripts/extract_candidates.awk cards/scored_by_dec.tsv cards/unimplementable.tsv cards/mtg-data.txt
|
||||
|
@ -635,4 +638,4 @@ common_actions:
|
|||
|
||||
src/magic/MurmurHash3.java:
|
||||
curl https://raw.github.com/infinispan/infinispan/master/commons/src/main/java/org/infinispan/commons/hash/MurmurHash3.java > $@
|
||||
patch $@ MurmurHash3.diff
|
||||
patch $@ src/magic/MurmurHash3.diff
|
||||
|
|
129
MurmurHash3.diff
129
MurmurHash3.diff
|
@ -1,129 +0,0 @@
|
|||
--- MurmurHash3.java 2013-10-29 22:40:32.510685131 +0800
|
||||
+++ src/magic/MurmurHash3.java 2013-10-29 22:42:12.150687043 +0800
|
||||
@@ -1,11 +1,4 @@
|
||||
-package org.infinispan.commons.hash;
|
||||
-
|
||||
-import net.jcip.annotations.Immutable;
|
||||
-import net.jcip.annotations.ThreadSafe;
|
||||
-
|
||||
-import org.infinispan.commons.marshall.exts.NoStateExternalizer;
|
||||
-import org.infinispan.commons.util.Util;
|
||||
-import org.infinispan.commons.marshall.Ids;
|
||||
+package magic;
|
||||
|
||||
import java.io.ObjectInput;
|
||||
import java.nio.charset.Charset;
|
||||
@@ -25,9 +18,7 @@
|
||||
* @see <a href="http://en.wikipedia.org/wiki/MurmurHash">MurmurHash entry on Wikipedia</a>
|
||||
* @since 5.0
|
||||
*/
|
||||
-@ThreadSafe
|
||||
-@Immutable
|
||||
-public class MurmurHash3 implements Hash {
|
||||
+public class MurmurHash3 {
|
||||
private static final Charset UTF8 = Charset.forName("UTF-8");
|
||||
|
||||
static class State {
|
||||
@@ -92,6 +83,7 @@
|
||||
* @param seed random value
|
||||
* @return 128 bit hashed key, in an array containing two longs
|
||||
*/
|
||||
+ @SuppressWarnings("fallthrough")
|
||||
public static long[] MurmurHash3_x64_128(final byte[] key, final int seed) {
|
||||
State state = new State();
|
||||
|
||||
@@ -154,6 +146,7 @@
|
||||
* @param seed random value
|
||||
* @return 64 bit hashed key
|
||||
*/
|
||||
+ @SuppressWarnings("fallthrough")
|
||||
public static long MurmurHash3_x64_64(final byte[] key, final int seed) {
|
||||
// Exactly the same as MurmurHash3_x64_128, except it only returns state.h1
|
||||
State state = new State();
|
||||
@@ -244,7 +237,7 @@
|
||||
bmix(state);
|
||||
}
|
||||
|
||||
- long tail = key[key.length - 1];
|
||||
+ final long tail = key.length > 0 ? key[key.length - 1] : 0;
|
||||
|
||||
// Key length is odd
|
||||
if ((key.length & 1) == 1) {
|
||||
@@ -290,7 +283,7 @@
|
||||
bmix(state);
|
||||
}
|
||||
|
||||
- long tail = key[key.length - 1];
|
||||
+ final long tail = key.length > 0 ? key[key.length - 1] : 0;
|
||||
|
||||
if (key.length % 2 != 0) {
|
||||
state.k1 ^= tail;
|
||||
@@ -322,7 +315,7 @@
|
||||
return (int) (MurmurHash3_x64_64(key, seed) >>> 32);
|
||||
}
|
||||
|
||||
- @Override
|
||||
+
|
||||
public int hash(byte[] payload) {
|
||||
return MurmurHash3_x64_32(payload, 9001);
|
||||
}
|
||||
@@ -333,11 +326,11 @@
|
||||
* @param payload a byte array to hash
|
||||
* @return a hash code for the byte array
|
||||
*/
|
||||
- public static int hash(long[] payload) {
|
||||
- return MurmurHash3_x64_32(payload, 9001);
|
||||
+ public static long hash(long[] payload) {
|
||||
+ return MurmurHash3_x64_64(payload, 9001);
|
||||
}
|
||||
|
||||
- @Override
|
||||
+
|
||||
public int hash(int hashcode) {
|
||||
// Obtained by inlining MurmurHash3_x64_32(byte[], 9001) and removing all the unused code
|
||||
// (since we know the input is always 4 bytes and we only need 4 bytes of output)
|
||||
@@ -375,44 +368,4 @@
|
||||
|
||||
return (int) (state.h1 >>> 32);
|
||||
}
|
||||
-
|
||||
- @Override
|
||||
- public int hash(Object o) {
|
||||
- if (o instanceof byte[])
|
||||
- return hash((byte[]) o);
|
||||
- else if (o instanceof long[])
|
||||
- return hash((long[]) o);
|
||||
- else if (o instanceof String)
|
||||
- return hash(((String) o).getBytes(UTF8));
|
||||
- else
|
||||
- return hash(o.hashCode());
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public boolean equals(Object other) {
|
||||
- return other != null && other.getClass() == getClass();
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public String toString() {
|
||||
- return "MurmurHash3";
|
||||
- }
|
||||
-
|
||||
- public static class Externalizer extends NoStateExternalizer<MurmurHash3> {
|
||||
- @Override
|
||||
- @SuppressWarnings("unchecked")
|
||||
- public Set<Class<? extends MurmurHash3>> getTypeClasses() {
|
||||
- return Util.<Class<? extends MurmurHash3>>asSet(MurmurHash3.class);
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public MurmurHash3 readObject(ObjectInput input) {
|
||||
- return new MurmurHash3();
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public Integer getId() {
|
||||
- return Ids.MURMURHASH_3;
|
||||
- }
|
||||
- }
|
||||
}
|
|
@ -188,13 +188,8 @@ Fact or Fiction separate into piles
|
|||
Simic Growth Chamber mana pool
|
||||
Golgari Rot Farm mana pool
|
||||
Nykthos, Shrine to Nyx mana pool
|
||||
Temple of Deceit scry 1
|
||||
Magma Jet scry 2
|
||||
Temple of Silence scry 1
|
||||
Omenspeaker scry 2
|
||||
Temple of Abandon scry 1
|
||||
Read the Bones scry 2
|
||||
Dissolve scry 1
|
||||
Xenagos, the Reveler mana pool
|
||||
Temple of Triumph scry 1
|
||||
Condescend scry 2
|
||||
|
|
|
|
@ -1,23 +0,0 @@
|
|||
[
|
||||
new MagicSpellCardEvent() {
|
||||
@Override
|
||||
public MagicEvent getEvent(final MagicCardOnStack cardOnStack,final MagicPayedCost payedCost) {
|
||||
return new MagicEvent(
|
||||
cardOnStack,
|
||||
MagicTargetChoice.POS_TARGET_CREATURE,
|
||||
MagicFlyingTargetPicker.create(),
|
||||
this,
|
||||
"Target creature\$ gets +3/+3 and gains flying until end of turn."
|
||||
);
|
||||
}
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
event.processTargetPermanent(game,new MagicPermanentAction() {
|
||||
public void doAction(final MagicPermanent creature) {
|
||||
game.doAction(new MagicChangeTurnPTAction(creature,3,3));
|
||||
game.doAction(new MagicGainAbilityAction(creature,MagicAbility.Flying));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
|
@ -5,5 +5,5 @@ value=2.727
|
|||
rarity=C
|
||||
type=Sorcery
|
||||
cost={2}{W}
|
||||
effect=Target creature gets +3/+3 and gains flying until end of turn.
|
||||
timing=pump
|
||||
requires_groovy_code
|
||||
|
|
|
@ -7,5 +7,5 @@ type=Creature
|
|||
subtype=Insect
|
||||
cost={1}{B}{R}
|
||||
pt=1/1
|
||||
timing=main
|
||||
ability=pay {T},Sacrifice a land: Destroy target land.
|
||||
timing=main
|
||||
|
|
|
@ -5,5 +5,5 @@ value=4.256
|
|||
rarity=U
|
||||
type=Sorcery
|
||||
cost={3}{W}
|
||||
effect=Return target creature card from your graveyard to the battlefield.
|
||||
timing=main
|
||||
requires_groovy_code=Zombify
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
[
|
||||
new MagicSpellCardEvent() {
|
||||
@Override
|
||||
public MagicEvent getEvent(final MagicCardOnStack cardOnStack,final MagicPayedCost payedCost) {
|
||||
return new MagicEvent(
|
||||
cardOnStack,
|
||||
MagicTargetChoice.POS_TARGET_CREATURE,
|
||||
MagicPumpTargetPicker.create(),
|
||||
this,
|
||||
"Target creature\$ gets +4/+2 and gains trample until end of turn."
|
||||
);
|
||||
}
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
event.processTargetPermanent(game,new MagicPermanentAction() {
|
||||
public void doAction(final MagicPermanent creature) {
|
||||
game.doAction(new MagicChangeTurnPTAction(creature,4,2));
|
||||
game.doAction(new MagicGainAbilityAction(creature,MagicAbility.Trample));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
|
@ -5,5 +5,5 @@ value=2.786
|
|||
rarity=C
|
||||
type=Instant
|
||||
cost={R}{G}
|
||||
effect=Target creature gets +4/+2 and gains trample until end of turn.
|
||||
timing=pump
|
||||
requires_groovy_code
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name=Dark Depths
|
||||
url=http://magiccards.info/csp/en/145.html
|
||||
image=http://magiccards.info/scans/en/csp/145.jpg
|
||||
url=http://magiccards.info/cs/en/145.html
|
||||
image=http://magiccards.info/scans/en/cs/145.jpg
|
||||
value=2.500
|
||||
rarity=R
|
||||
type=Legendary,Snow,Land
|
||||
|
|
|
@ -7,5 +7,5 @@ type=Creature
|
|||
subtype=Human,Wizard
|
||||
cost={2}{U}
|
||||
pt=1/1
|
||||
timing=main
|
||||
ability=pay {T}: Counter target spell unless its controller pays {1}.
|
||||
timing=main
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
[
|
||||
new MagicWhenDiesTrigger() {
|
||||
@Override
|
||||
public MagicEvent executeTrigger(final MagicGame game, final MagicPermanent permanent, final MagicMoveCardAction data) {
|
||||
final MagicTargetChoice targetChoice = new MagicTargetChoice(
|
||||
new MagicTargetFilter.MagicCMCCardFilter(
|
||||
MagicTargetFilter.TARGET_CREATURE_CARD_FROM_GRAVEYARD,
|
||||
MagicTargetFilter.Operator.LESS_THAN_OR_EQUAL,
|
||||
2
|
||||
),
|
||||
MagicTargetHint.None,
|
||||
"target creature card from your graveyard)"
|
||||
);
|
||||
return new MagicEvent(
|
||||
permanent,
|
||||
targetChoice,
|
||||
MagicGraveyardTargetPicker.PutOntoBattlefield,
|
||||
this,
|
||||
"PN returns target creature card\$ with " +
|
||||
"converted mana cost 2 or less " +
|
||||
"from his or her graveyard to the battlefield."
|
||||
);
|
||||
}
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
event.processTargetCard(game,new MagicCardAction() {
|
||||
public void doAction(final MagicCard card) {
|
||||
game.doAction(new MagicReanimateAction(
|
||||
card,
|
||||
event.getPlayer()
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
|
@ -7,5 +7,5 @@ type=Creature
|
|||
subtype=Vampire
|
||||
cost={3}{B}
|
||||
pt=3/2
|
||||
ability=dies effect Return target creature card with converted mana cost 2 or less from your graveyard to the battlefield.
|
||||
timing=main
|
||||
requires_groovy_code
|
||||
|
|
|
@ -7,5 +7,5 @@ type=Creature
|
|||
subtype=Dwarf
|
||||
cost={1}{R}
|
||||
pt=1/2
|
||||
timing=main
|
||||
ability=pay {2}{R},{T}: Destroy target nonbasic land.
|
||||
timing=main
|
||||
|
|
|
@ -5,5 +5,5 @@ value=4.133
|
|||
rarity=U
|
||||
type=Sorcery
|
||||
cost={3}{W}
|
||||
effect=Return target creature card from your graveyard to the battlefield.
|
||||
timing=main
|
||||
requires_groovy_code=Zombify
|
||||
|
|
|
@ -7,5 +7,5 @@ type=Creature
|
|||
subtype=Bird
|
||||
cost={W/U}
|
||||
pt=1/1
|
||||
timing=main
|
||||
ability=flying;pay {S}: Counter target instant or sorcery spell unless its controller pays {1}.
|
||||
timing=main
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
[
|
||||
new MagicWhenComesIntoPlayTrigger() {
|
||||
@Override
|
||||
public MagicEvent executeTrigger(
|
||||
final MagicGame game,
|
||||
final MagicPermanent permanent,
|
||||
final MagicPayedCost payedCost) {
|
||||
return new MagicEvent(
|
||||
permanent,
|
||||
MagicTargetChoice.TARGET_CREATURE_CARD_FROM_GRAVEYARD,
|
||||
MagicGraveyardTargetPicker.PutOntoBattlefield,
|
||||
this,
|
||||
"Return target creature card\$ from " +
|
||||
"your graveyard to the battlefield."
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
event.processTargetCard(game,new MagicCardAction() {
|
||||
public void doAction(final MagicCard targetCard) {
|
||||
game.doAction(new MagicReanimateAction(
|
||||
targetCard,
|
||||
event.getPlayer()
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
|
@ -7,6 +7,6 @@ type=Creature
|
|||
subtype=Angel,Spirit
|
||||
cost={3}{W}{W}
|
||||
pt=2/2
|
||||
ability=flying;protection from black;echo {3}{W}{W}
|
||||
ability=flying;protection from black;echo {3}{W}{W};\
|
||||
enters effect Return target creature card from your graveyard to the battlefield.
|
||||
timing=main
|
||||
requires_groovy_code
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
[
|
||||
new MagicSpellCardEvent() {
|
||||
@Override
|
||||
public MagicEvent getEvent(final MagicCardOnStack cardOnStack,final MagicPayedCost payedCost) {
|
||||
return new MagicEvent(
|
||||
cardOnStack,
|
||||
MagicTargetChoice.POS_TARGET_CREATURE,
|
||||
MagicFirstStrikeTargetPicker.create(),
|
||||
this,
|
||||
"Target creature\$ gets +1/+0 and gains first strike until end of turn."
|
||||
);
|
||||
}
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
event.processTargetPermanent(game,new MagicPermanentAction() {
|
||||
public void doAction(final MagicPermanent creature) {
|
||||
game.doAction(new MagicChangeTurnPTAction(creature,1,0));
|
||||
game.doAction(new MagicGainAbilityAction(creature,MagicAbility.FirstStrike));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
|
@ -5,5 +5,5 @@ value=2.265
|
|||
rarity=C
|
||||
type=Instant
|
||||
cost={R}
|
||||
effect=Target creature gets +1/+0 and gains first strike until end of turn.
|
||||
timing=pump
|
||||
requires_groovy_code
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
[
|
||||
new MagicSpellCardEvent() {
|
||||
@Override
|
||||
public MagicEvent getEvent(final MagicCardOnStack cardOnStack,final MagicPayedCost payedCost) {
|
||||
return new MagicEvent(
|
||||
cardOnStack,
|
||||
MagicTargetChoice.POS_TARGET_CREATURE,
|
||||
MagicFlyingTargetPicker.create(),
|
||||
this,
|
||||
"Target creature\$ gets +2/+2 and gains flying until end of turn."
|
||||
);
|
||||
}
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
event.processTargetPermanent(game,new MagicPermanentAction() {
|
||||
public void doAction(final MagicPermanent creature) {
|
||||
game.doAction(new MagicChangeTurnPTAction(creature,2,2));
|
||||
game.doAction(new MagicGainAbilityAction(creature,MagicAbility.Flying));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
|
@ -5,5 +5,5 @@ value=2.932
|
|||
rarity=C
|
||||
type=Instant
|
||||
cost={1}{W}
|
||||
effect=Target creature gets +2/+2 and gains flying until end of turn.
|
||||
timing=pump
|
||||
requires_groovy_code
|
||||
|
|
|
@ -1,25 +1,4 @@
|
|||
[
|
||||
new MagicSpellCardEvent() {
|
||||
@Override
|
||||
public MagicEvent getEvent(final MagicCardOnStack cardOnStack,final MagicPayedCost payedCost) {
|
||||
return new MagicEvent(
|
||||
cardOnStack,
|
||||
MagicTargetChoice.TARGET_CREATURE_YOU_CONTROL,
|
||||
MagicShroudTargetPicker.create(),
|
||||
this,
|
||||
"Target creature\$ you control gets +0/+1 and gains hexproof until end of turn."
|
||||
);
|
||||
}
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
event.processTargetPermanent(game,new MagicPermanentAction() {
|
||||
public void doAction(final MagicPermanent creature) {
|
||||
game.doAction(new MagicChangeTurnPTAction(creature, 0, 1));
|
||||
game.doAction(new MagicGainAbilityAction(creature, MagicAbility.Hexproof));
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
new MagicOverloadActivation(MagicTiming.Pump) {
|
||||
@Override
|
||||
public Iterable<MagicEvent> getCostEvent(final MagicCard source) {
|
||||
|
|
|
@ -5,5 +5,6 @@ value=3.325
|
|||
rarity=C
|
||||
type=Instant
|
||||
cost={U}
|
||||
effect=Target creature you control gets +0/+1 and gains hexproof until end of turn.
|
||||
timing=pump
|
||||
requires_groovy_code
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
[
|
||||
new MagicSpellCardEvent() {
|
||||
@Override
|
||||
public MagicEvent getEvent(final MagicCardOnStack cardOnStack,final MagicPayedCost payedCost) {
|
||||
return new MagicEvent(
|
||||
cardOnStack,
|
||||
MagicTargetChoice.POS_TARGET_CREATURE,
|
||||
MagicLifelinkTargetPicker.create(),
|
||||
this,
|
||||
"Target creature\$ gets +2/+2 and gains lifelink until end of turn."
|
||||
);
|
||||
}
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
event.processTargetPermanent(game,new MagicPermanentAction() {
|
||||
public void doAction(final MagicPermanent creature) {
|
||||
game.doAction(new MagicChangeTurnPTAction(creature,2,2));
|
||||
game.doAction(new MagicGainAbilityAction(creature,MagicAbility.Lifelink));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
|
@ -5,5 +5,5 @@ value=3.438
|
|||
rarity=C
|
||||
type=Instant
|
||||
cost={1}{W}
|
||||
effect=Target creature gets +2/+2 and gains lifelink until end of turn.
|
||||
timing=pump
|
||||
requires_groovy_code
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
[
|
||||
new MagicSpellCardEvent() {
|
||||
@Override
|
||||
public MagicEvent getEvent(final MagicCardOnStack cardOnStack,final MagicPayedCost payedCost) {
|
||||
return new MagicEvent(
|
||||
cardOnStack,
|
||||
MagicTargetChoice.TARGET_PERMANENT_CARD_FROM_GRAVEYARD,
|
||||
MagicGraveyardTargetPicker.PutOntoBattlefield,
|
||||
this,
|
||||
"Return target permanent card\$ from your graveyard to the battlefield."
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
event.processTargetCard(game,new MagicCardAction() {
|
||||
public void doAction(final MagicCard targetCard) {
|
||||
game.doAction(new MagicReanimateAction(
|
||||
targetCard,
|
||||
event.getPlayer()
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
|
@ -5,5 +5,5 @@ value=4.092
|
|||
rarity=R
|
||||
type=Sorcery
|
||||
cost={3}{W}{B}
|
||||
effect=Return target permanent card from your graveyard to the battlefield.
|
||||
timing=main
|
||||
requires_groovy_code
|
||||
|
|
|
@ -5,5 +5,5 @@ value=4.057
|
|||
rarity=U
|
||||
type=Sorcery
|
||||
cost={2}{W}{W}
|
||||
effect=Return target creature card from your graveyard to the battlefield.
|
||||
timing=main
|
||||
requires_groovy_code=Zombify
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
[
|
||||
new MagicAtUpkeepTrigger() {
|
||||
@Override
|
||||
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final MagicPlayer upkeepPlayer) {
|
||||
return permanent.isController(upkeepPlayer) ?
|
||||
new MagicEvent(
|
||||
permanent,
|
||||
new MagicMayChoice(
|
||||
MagicTargetChoice.TARGET_CREATURE_CARD_FROM_GRAVEYARD
|
||||
),
|
||||
MagicGraveyardTargetPicker.PutOntoBattlefield,
|
||||
this,
|
||||
"PN may\$ return target creature card\$ from " +
|
||||
"his or her graveyard to the battlefield."
|
||||
):
|
||||
MagicEvent.NONE;
|
||||
}
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
if (event.isYes()) {
|
||||
event.processTargetCard(game,new MagicCardAction() {
|
||||
public void doAction(final MagicCard card) {
|
||||
game.doAction(new MagicReanimateAction(
|
||||
card,
|
||||
event.getPlayer()
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
|
@ -7,6 +7,6 @@ type=Legendary,Creature
|
|||
subtype=Angel
|
||||
cost={6}{W}{W}{W}
|
||||
pt=4/6
|
||||
ability=flying
|
||||
ability=flying;\
|
||||
your upkeep effect PN may return target creature card from your graveyard to the battlefield.
|
||||
timing=main
|
||||
requires_groovy_code
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
[
|
||||
new MagicWhenComesIntoPlayTrigger() {
|
||||
@Override
|
||||
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent, final MagicPayedCost payedCost) {
|
||||
return new MagicEvent(
|
||||
permanent,
|
||||
new MagicMayChoice(
|
||||
MagicTargetChoice.TARGET_ARTIFACT_CARD_FROM_GRAVEYARD,
|
||||
),
|
||||
MagicGraveyardTargetPicker.PutOntoBattlefield,
|
||||
this,
|
||||
"PN may\$ return target artifact card\$ from your graveyard to the battlefield."
|
||||
);
|
||||
}
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
if (event.isYes()) {
|
||||
event.processTargetCard(game,new MagicCardAction() {
|
||||
public void doAction(final MagicCard card) {
|
||||
game.doAction(new MagicReanimateAction(
|
||||
card,
|
||||
event.getPlayer()
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
|
@ -7,6 +7,6 @@ type=Legendary,Artifact,Creature
|
|||
subtype=Sphinx
|
||||
cost={3}{W}{U}{B}
|
||||
pt=5/5
|
||||
ability=flying
|
||||
ability=flying;\
|
||||
enters effect PN may return target artifact card from your graveyard to the battlefield.
|
||||
timing=main
|
||||
requires_groovy_code
|
||||
|
|
|
@ -1,29 +1,4 @@
|
|||
[
|
||||
new MagicAtUpkeepTrigger() {
|
||||
@Override
|
||||
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final MagicPlayer upkeepPlayer) {
|
||||
return permanent.isController(upkeepPlayer) ?
|
||||
new MagicEvent(
|
||||
permanent,
|
||||
MagicTargetChoice.TARGET_CREATURE_CARD_FROM_GRAVEYARD,
|
||||
MagicGraveyardTargetPicker.PutOntoBattlefield,
|
||||
this,
|
||||
"Return target creature card\$ from your graveyard to the battlefield."
|
||||
):
|
||||
MagicEvent.NONE;
|
||||
}
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
event.processTargetCard(game,new MagicCardAction() {
|
||||
public void doAction(final MagicCard card) {
|
||||
game.doAction(new MagicReanimateAction(
|
||||
card,
|
||||
event.getPlayer()
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
new MagicAtUpkeepTrigger() {
|
||||
@Override
|
||||
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final MagicPlayer upkeepPlayer) {
|
||||
|
|
|
@ -7,6 +7,7 @@ type=Legendary,Creature
|
|||
subtype=Praetor
|
||||
cost={5}{B}{B}
|
||||
pt=6/6
|
||||
ability=swampwalk
|
||||
timing=smain
|
||||
ability=swampwalk;\
|
||||
your upkeep effect Return target creature card from your graveyard to the battlefield.
|
||||
timing=main
|
||||
requires_groovy_code
|
||||
|
|
|
@ -1,35 +0,0 @@
|
|||
[
|
||||
new MagicPermanentActivation(
|
||||
new MagicActivationHints(MagicTiming.Pump),
|
||||
"Pump"
|
||||
) {
|
||||
|
||||
@Override
|
||||
public Iterable<MagicEvent> getCostEvent(final MagicPermanent source) {
|
||||
return [
|
||||
new MagicTapEvent(source), new MagicPayManaCostEvent(source, "{R}{G}")
|
||||
];
|
||||
}
|
||||
|
||||
@Override
|
||||
public MagicEvent getPermanentEvent(final MagicPermanent source,final MagicPayedCost payedCost) {
|
||||
return new MagicEvent(
|
||||
source,
|
||||
MagicTargetChoice.POS_TARGET_CREATURE,
|
||||
MagicPumpTargetPicker.create(),
|
||||
this,
|
||||
"Target creature\$ gets +1/+1 and gains trample until end of turn."
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
event.processTargetPermanent(game,new MagicPermanentAction() {
|
||||
public void doAction(final MagicPermanent creature) {
|
||||
game.doAction(new MagicChangeTurnPTAction(creature,1,1));
|
||||
game.doAction(new MagicGainAbilityAction(creature,MagicAbility.Trample));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
|
@ -4,6 +4,6 @@ image=http://magiccards.info/scans/en/gp/163.jpg
|
|||
value=4.182
|
||||
rarity=U
|
||||
type=Land
|
||||
ability=tap add mana {1}
|
||||
ability=tap add mana {1};\
|
||||
pay {R}{G}, {T}: Target creature gets +1/+1 and gains trample until end of turn.
|
||||
timing=land
|
||||
requires_groovy_code
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
[
|
||||
new MagicSpellCardEvent() {
|
||||
@Override
|
||||
public MagicEvent getEvent(final MagicCardOnStack cardOnStack, final MagicPayedCost payedCost) {
|
||||
return new MagicEvent(
|
||||
cardOnStack,
|
||||
MagicTargetChoice.POS_TARGET_CREATURE,
|
||||
MagicFirstStrikeTargetPicker.create(),
|
||||
this,
|
||||
"Target creature\$ gets +2/+0 and gains " +
|
||||
"first strike until end of turn."
|
||||
);
|
||||
}
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
event.processTargetPermanent(game,new MagicPermanentAction() {
|
||||
public void doAction(final MagicPermanent creature) {
|
||||
game.doAction(new MagicChangeTurnPTAction(creature,2,0));
|
||||
game.doAction(new MagicGainAbilityAction(
|
||||
creature,
|
||||
MagicAbility.FirstStrike
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
|
@ -5,5 +5,5 @@ value=2.512
|
|||
rarity=C
|
||||
type=Instant
|
||||
cost={1}{W}
|
||||
effect=Target creature gets +2/+0 and gains first strike until end of turn.
|
||||
timing=pump
|
||||
requires_groovy_code
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
[
|
||||
new MagicSpellCardEvent() {
|
||||
@Override
|
||||
public MagicEvent getEvent(final MagicCardOnStack cardOnStack,final MagicPayedCost payedCost) {
|
||||
return new MagicEvent(
|
||||
cardOnStack,
|
||||
MagicTargetChoice.POS_TARGET_CREATURE,
|
||||
MagicFirstStrikeTargetPicker.create(),
|
||||
this,
|
||||
"Target creature\$ gets +3/+0 and gains first strike until end of turn."
|
||||
);
|
||||
}
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
event.processTargetPermanent(game,new MagicPermanentAction() {
|
||||
public void doAction(final MagicPermanent creature) {
|
||||
game.doAction(new MagicChangeTurnPTAction(creature,3,0));
|
||||
game.doAction(new MagicGainAbilityAction(creature,MagicAbility.FirstStrike));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
|
@ -5,5 +5,5 @@ value=2.238
|
|||
rarity=C
|
||||
type=Instant
|
||||
cost={2}{R}
|
||||
effect=Target creature gets +3/+0 and gains first strike until end of turn.
|
||||
timing=pump
|
||||
requires_groovy_code
|
||||
|
|
|
@ -0,0 +1,26 @@
|
|||
[
|
||||
new MagicSpellCardEvent() {
|
||||
@Override
|
||||
public MagicEvent getEvent(final MagicCardOnStack cardOnStack,final MagicPayedCost payedCost) {
|
||||
return new MagicEvent(
|
||||
cardOnStack,
|
||||
MagicTargetChoice.NEG_TARGET_CREATURE_OR_PLAYER,
|
||||
new MagicDamageTargetPicker(1),
|
||||
this,
|
||||
"SN deals 1 damage to target creature or player\$. " +
|
||||
"Scry 1."
|
||||
);
|
||||
}
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
event.processTargetPermanent(game, {
|
||||
final MagicPermanent target ->
|
||||
game.doAction(new MagicDealDamageAction(
|
||||
new MagicDamage(event.getSource(),target,2)
|
||||
));
|
||||
game.doAction(new MagicGainAbilityAction(target, MagicAbility.CannotBlock));
|
||||
game.addEvent(new MagicScryEvent(event));
|
||||
} as MagicPermanentAction);
|
||||
}
|
||||
}
|
||||
]
|
|
@ -0,0 +1,10 @@
|
|||
name=Spark Jolt
|
||||
url=http://magiccards.info/ths/en/140.html
|
||||
image=http://magiccards.info/scans/en/ths/140.jpg
|
||||
value=4.641
|
||||
removal=1
|
||||
rarity=C
|
||||
type=Instant
|
||||
cost={R}
|
||||
timing=removal
|
||||
requires_groovy_code
|
|
@ -1,38 +0,0 @@
|
|||
def action = {
|
||||
final MagicGame game, final MagicEvent event ->
|
||||
event.processTargetCard(game,new MagicCardAction() {
|
||||
public void doAction(final MagicCard card) {
|
||||
game.doAction(new MagicReanimateAction(
|
||||
card,
|
||||
event.getPlayer()
|
||||
));
|
||||
}
|
||||
});
|
||||
} as MagicEventAction
|
||||
|
||||
def event = {
|
||||
final MagicPermanent permanent ->
|
||||
return new MagicEvent(
|
||||
permanent,
|
||||
MagicTargetChoice.TARGET_PERMANENT_CARD_CMC_LEQ_3_FROM_GRAVEYARD,
|
||||
MagicGraveyardTargetPicker.PutOntoBattlefield,
|
||||
action,
|
||||
"Return target permanent card\$ with converted mana cost 3 or less " +
|
||||
"from your graveyard to the battlefield."
|
||||
);
|
||||
}
|
||||
|
||||
[
|
||||
new MagicWhenComesIntoPlayTrigger() {
|
||||
@Override
|
||||
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent, final MagicPayedCost payedCost) {
|
||||
return event(permanent);
|
||||
}
|
||||
},
|
||||
new MagicWhenAttacksTrigger() {
|
||||
@Override
|
||||
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent,final MagicPermanent attacker) {
|
||||
return (permanent==attacker) ? event(permanent) : MagicEvent.NONE;
|
||||
}
|
||||
}
|
||||
]
|
|
@ -7,6 +7,7 @@ type=Creature
|
|||
subtype=Giant
|
||||
cost={4}{W}{W}
|
||||
pt=6/6
|
||||
ability=vigilance
|
||||
timing=fmain
|
||||
requires_groovy_code
|
||||
ability=vigilance;\
|
||||
enters effect PN may return target permanent card with converted mana cost 3 or less from your graveyard to the battlefield.;\
|
||||
attacks effect PN may return target permanent card with converted mana cost 3 or less from your graveyard to the battlefield.
|
||||
timing=main
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
act.card,
|
||||
new MagicMayChoice(),
|
||||
this,
|
||||
"PN may return SN to your hand."
|
||||
"PN may\$ return SN to your hand."
|
||||
):
|
||||
MagicEvent.NONE
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
[
|
||||
new MagicWhenComesIntoPlayTrigger() {
|
||||
@Override
|
||||
public MagicEvent executeTrigger(final MagicGame game,final MagicPermanent permanent, final MagicPayedCost payedCost) {
|
||||
return new MagicEvent(
|
||||
permanent,
|
||||
this,
|
||||
"Look at the top card of your library. You may put that card on the bottom of your library."
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
game.addEvent(new MagicScryEvent(event));
|
||||
}
|
||||
}
|
||||
]
|
|
@ -0,0 +1,11 @@
|
|||
name=Temple of Silence
|
||||
url=http://magiccards.info/ths/en/227.html
|
||||
image=http://magiccards.info/scans/en/ths/227.jpg
|
||||
value=3.792
|
||||
rarity=R
|
||||
type=Land
|
||||
mana=w3b3
|
||||
ability=tap add mana {W} or {B};\
|
||||
enters tapped
|
||||
timing=tapland
|
||||
requires_groovy_code
|
|
@ -1,23 +0,0 @@
|
|||
[
|
||||
new MagicSpellCardEvent() {
|
||||
@Override
|
||||
public MagicEvent getEvent(final MagicCardOnStack cardOnStack,final MagicPayedCost payedCost) {
|
||||
return new MagicEvent(
|
||||
cardOnStack,
|
||||
MagicTargetChoice.POS_TARGET_CREATURE,
|
||||
MagicFirstStrikeTargetPicker.create(),
|
||||
this,
|
||||
"Target creature\$ gets +2/+0 and gains first strike until end of turn."
|
||||
);
|
||||
}
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
event.processTargetPermanent(game,new MagicPermanentAction() {
|
||||
public void doAction(final MagicPermanent creature) {
|
||||
game.doAction(new MagicChangeTurnPTAction(creature,2,0));
|
||||
game.doAction(new MagicGainAbilityAction(creature,MagicAbility.FirstStrike));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
|
@ -5,5 +5,5 @@ value=3.139
|
|||
rarity=C
|
||||
type=Instant
|
||||
cost={1}{R}
|
||||
effect=Target creature gets +2/+0 and gains first strike until end of turn.
|
||||
timing=pump
|
||||
requires_groovy_code
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
[
|
||||
new MagicSpellCardEvent() {
|
||||
@Override
|
||||
public MagicEvent getEvent(final MagicCardOnStack cardOnStack, final MagicPayedCost payedCost) {
|
||||
return new MagicEvent(
|
||||
cardOnStack,
|
||||
MagicTargetChoice.POS_TARGET_CREATURE,
|
||||
MagicPumpTargetPicker.create(),
|
||||
this,
|
||||
"Target creature\$ gets +3/+0 and " +
|
||||
"gains haste until end of turn."
|
||||
);
|
||||
}
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
event.processTargetPermanent(game,new MagicPermanentAction() {
|
||||
public void doAction(final MagicPermanent creature) {
|
||||
game.doAction(new MagicChangeTurnPTAction(creature,3,0));
|
||||
game.doAction(new MagicGainAbilityAction(creature,MagicAbility.Haste));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
|
@ -5,5 +5,5 @@ value=2.220
|
|||
rarity=C
|
||||
type=Instant
|
||||
cost={1}{R}
|
||||
effect=Target creature gets +3/+0 and gains haste until end of turn.
|
||||
timing=fmain
|
||||
requires_groovy_code
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
[
|
||||
new MagicSpellCardEvent() {
|
||||
@Override
|
||||
public MagicEvent getEvent(final MagicCardOnStack cardOnStack, final MagicPayedCost payedCost) {
|
||||
return new MagicEvent(
|
||||
cardOnStack,
|
||||
MagicTargetChoice.POS_TARGET_CREATURE,
|
||||
MagicFirstStrikeTargetPicker.create(),
|
||||
this,
|
||||
"Target creature\$ gets +2/+2 and " +
|
||||
"gains first strike until end of turn."
|
||||
);
|
||||
}
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
event.processTargetPermanent(game,new MagicPermanentAction() {
|
||||
public void doAction(final MagicPermanent creature) {
|
||||
game.doAction(new MagicChangeTurnPTAction(creature,2,2));
|
||||
game.doAction(new MagicGainAbilityAction(
|
||||
creature,
|
||||
MagicAbility.FirstStrike
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
|
@ -5,5 +5,5 @@ value=2.705
|
|||
rarity=C
|
||||
type=Instant
|
||||
cost={1}{W}
|
||||
effect=Target creature gets +2/+2 and gains first strike until end of turn.
|
||||
timing=pump
|
||||
requires_groovy_code
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
[
|
||||
new MagicSpellCardEvent() {
|
||||
@Override
|
||||
public MagicEvent getEvent(final MagicCardOnStack cardOnStack,final MagicPayedCost payedCost) {
|
||||
return new MagicEvent(
|
||||
cardOnStack,
|
||||
MagicTargetChoice.TARGET_CREATURE_CARD_FROM_GRAVEYARD,
|
||||
MagicGraveyardTargetPicker.PutOntoBattlefield,
|
||||
this,
|
||||
"Return target creature card\$ from your graveyard to the battlefield."
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
event.processTargetCard(game,new MagicCardAction() {
|
||||
public void doAction(final MagicCard targetCard) {
|
||||
game.doAction(new MagicReanimateAction(
|
||||
targetCard,
|
||||
event.getPlayer()
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
]
|
|
@ -5,5 +5,5 @@ value=4.330
|
|||
rarity=U
|
||||
type=Sorcery
|
||||
cost={3}{B}
|
||||
effect=Return target creature card from your graveyard to the battlefield.
|
||||
timing=main
|
||||
requires_groovy_code
|
||||
|
|
|
@ -34,6 +34,11 @@ FILENAME ~ /unimplementable/ {
|
|||
next
|
||||
}
|
||||
|
||||
FILENAME ~ /groovy/ {
|
||||
comment[$1] = "groovy"
|
||||
next
|
||||
}
|
||||
|
||||
{
|
||||
if (NF == 1) {
|
||||
score[$1] = 1
|
||||
|
|
|
@ -0,0 +1,331 @@
|
|||
--- MurmurHash3.java 2013-11-02 09:43:10.120309279 +0800
|
||||
+++ src/magic/MurmurHash3.java 2013-11-02 09:46:15.064312827 +0800
|
||||
@@ -1,11 +1,4 @@
|
||||
-package org.infinispan.commons.hash;
|
||||
-
|
||||
-import net.jcip.annotations.Immutable;
|
||||
-import net.jcip.annotations.ThreadSafe;
|
||||
-
|
||||
-import org.infinispan.commons.marshall.exts.NoStateExternalizer;
|
||||
-import org.infinispan.commons.util.Util;
|
||||
-import org.infinispan.commons.marshall.Ids;
|
||||
+package magic;
|
||||
|
||||
import java.io.ObjectInput;
|
||||
import java.nio.charset.Charset;
|
||||
@@ -25,9 +18,7 @@
|
||||
* @see <a href="http://en.wikipedia.org/wiki/MurmurHash">MurmurHash entry on Wikipedia</a>
|
||||
* @since 5.0
|
||||
*/
|
||||
-@ThreadSafe
|
||||
-@Immutable
|
||||
-public class MurmurHash3 implements Hash {
|
||||
+public class MurmurHash3 {
|
||||
private static final Charset UTF8 = Charset.forName("UTF-8");
|
||||
|
||||
static class State {
|
||||
@@ -92,143 +83,7 @@
|
||||
* @param seed random value
|
||||
* @return 128 bit hashed key, in an array containing two longs
|
||||
*/
|
||||
- public static long[] MurmurHash3_x64_128(final byte[] key, final int seed) {
|
||||
- State state = new State();
|
||||
-
|
||||
- state.h1 = 0x9368e53c2f6af274L ^ seed;
|
||||
- state.h2 = 0x586dcd208f7cd3fdL ^ seed;
|
||||
-
|
||||
- state.c1 = 0x87c37b91114253d5L;
|
||||
- state.c2 = 0x4cf5ad432745937fL;
|
||||
-
|
||||
- for (int i = 0; i < key.length / 16; i++) {
|
||||
- state.k1 = getblock(key, i * 2 * 8);
|
||||
- state.k2 = getblock(key, (i * 2 + 1) * 8);
|
||||
-
|
||||
- bmix(state);
|
||||
- }
|
||||
-
|
||||
- state.k1 = 0;
|
||||
- state.k2 = 0;
|
||||
-
|
||||
- int tail = (key.length >>> 4) << 4;
|
||||
-
|
||||
- switch (key.length & 15) {
|
||||
- case 15: state.k2 ^= (long) key[tail + 14] << 48;
|
||||
- case 14: state.k2 ^= (long) key[tail + 13] << 40;
|
||||
- case 13: state.k2 ^= (long) key[tail + 12] << 32;
|
||||
- case 12: state.k2 ^= (long) key[tail + 11] << 24;
|
||||
- case 11: state.k2 ^= (long) key[tail + 10] << 16;
|
||||
- case 10: state.k2 ^= (long) key[tail + 9] << 8;
|
||||
- case 9: state.k2 ^= key[tail + 8];
|
||||
-
|
||||
- case 8: state.k1 ^= (long) key[tail + 7] << 56;
|
||||
- case 7: state.k1 ^= (long) key[tail + 6] << 48;
|
||||
- case 6: state.k1 ^= (long) key[tail + 5] << 40;
|
||||
- case 5: state.k1 ^= (long) key[tail + 4] << 32;
|
||||
- case 4: state.k1 ^= (long) key[tail + 3] << 24;
|
||||
- case 3: state.k1 ^= (long) key[tail + 2] << 16;
|
||||
- case 2: state.k1 ^= (long) key[tail + 1] << 8;
|
||||
- case 1: state.k1 ^= key[tail + 0];
|
||||
- bmix(state);
|
||||
- }
|
||||
-
|
||||
- state.h2 ^= key.length;
|
||||
-
|
||||
- state.h1 += state.h2;
|
||||
- state.h2 += state.h1;
|
||||
-
|
||||
- state.h1 = fmix(state.h1);
|
||||
- state.h2 = fmix(state.h2);
|
||||
-
|
||||
- state.h1 += state.h2;
|
||||
- state.h2 += state.h1;
|
||||
-
|
||||
- return new long[] { state.h1, state.h2 };
|
||||
- }
|
||||
-
|
||||
- /**
|
||||
- * Hash a value using the x64 64 bit variant of MurmurHash3
|
||||
- *
|
||||
- * @param key value to hash
|
||||
- * @param seed random value
|
||||
- * @return 64 bit hashed key
|
||||
- */
|
||||
- public static long MurmurHash3_x64_64(final byte[] key, final int seed) {
|
||||
- // Exactly the same as MurmurHash3_x64_128, except it only returns state.h1
|
||||
- State state = new State();
|
||||
-
|
||||
- state.h1 = 0x9368e53c2f6af274L ^ seed;
|
||||
- state.h2 = 0x586dcd208f7cd3fdL ^ seed;
|
||||
-
|
||||
- state.c1 = 0x87c37b91114253d5L;
|
||||
- state.c2 = 0x4cf5ad432745937fL;
|
||||
-
|
||||
- for (int i = 0; i < key.length / 16; i++) {
|
||||
- state.k1 = getblock(key, i * 2 * 8);
|
||||
- state.k2 = getblock(key, (i * 2 + 1) * 8);
|
||||
-
|
||||
- bmix(state);
|
||||
- }
|
||||
-
|
||||
- state.k1 = 0;
|
||||
- state.k2 = 0;
|
||||
-
|
||||
- int tail = (key.length >>> 4) << 4;
|
||||
-
|
||||
- switch (key.length & 15) {
|
||||
- case 15: state.k2 ^= (long) key[tail + 14] << 48;
|
||||
- case 14: state.k2 ^= (long) key[tail + 13] << 40;
|
||||
- case 13: state.k2 ^= (long) key[tail + 12] << 32;
|
||||
- case 12: state.k2 ^= (long) key[tail + 11] << 24;
|
||||
- case 11: state.k2 ^= (long) key[tail + 10] << 16;
|
||||
- case 10: state.k2 ^= (long) key[tail + 9] << 8;
|
||||
- case 9: state.k2 ^= key[tail + 8];
|
||||
-
|
||||
- case 8: state.k1 ^= (long) key[tail + 7] << 56;
|
||||
- case 7: state.k1 ^= (long) key[tail + 6] << 48;
|
||||
- case 6: state.k1 ^= (long) key[tail + 5] << 40;
|
||||
- case 5: state.k1 ^= (long) key[tail + 4] << 32;
|
||||
- case 4: state.k1 ^= (long) key[tail + 3] << 24;
|
||||
- case 3: state.k1 ^= (long) key[tail + 2] << 16;
|
||||
- case 2: state.k1 ^= (long) key[tail + 1] << 8;
|
||||
- case 1: state.k1 ^= key[tail + 0];
|
||||
- bmix(state);
|
||||
- }
|
||||
-
|
||||
- state.h2 ^= key.length;
|
||||
-
|
||||
- state.h1 += state.h2;
|
||||
- state.h2 += state.h1;
|
||||
-
|
||||
- state.h1 = fmix(state.h1);
|
||||
- state.h2 = fmix(state.h2);
|
||||
-
|
||||
- state.h1 += state.h2;
|
||||
- state.h2 += state.h1;
|
||||
-
|
||||
- return state.h1;
|
||||
- }
|
||||
-
|
||||
- /**
|
||||
- * Hash a value using the x64 32 bit variant of MurmurHash3
|
||||
- *
|
||||
- * @param key value to hash
|
||||
- * @param seed random value
|
||||
- * @return 32 bit hashed key
|
||||
- */
|
||||
- public static int MurmurHash3_x64_32(final byte[] key, final int seed) {
|
||||
- return (int) (MurmurHash3_x64_64(key, seed) >>> 32);
|
||||
- }
|
||||
-
|
||||
- /**
|
||||
- * Hash a value using the x64 128 bit variant of MurmurHash3
|
||||
- *
|
||||
- * @param key value to hash
|
||||
- * @param seed random value
|
||||
- * @return 128 bit hashed key, in an array containing two longs
|
||||
- */
|
||||
- public static long[] MurmurHash3_x64_128(final long[] key, final int seed) {
|
||||
+ private static State MurmurHash3_x64_128(final long[] key, final int seed) {
|
||||
State state = new State();
|
||||
|
||||
state.h1 = 0x9368e53c2f6af274L ^ seed;
|
||||
@@ -244,7 +99,7 @@
|
||||
bmix(state);
|
||||
}
|
||||
|
||||
- long tail = key[key.length - 1];
|
||||
+ final long tail = key.length > 0 ? key[key.length - 1] : 0;
|
||||
|
||||
// Key length is odd
|
||||
if ((key.length & 1) == 1) {
|
||||
@@ -263,7 +118,7 @@
|
||||
state.h1 += state.h2;
|
||||
state.h2 += state.h1;
|
||||
|
||||
- return new long[] { state.h1, state.h2 };
|
||||
+ return state;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -275,40 +130,7 @@
|
||||
*/
|
||||
public static long MurmurHash3_x64_64(final long[] key, final int seed) {
|
||||
// Exactly the same as MurmurHash3_x64_128, except it only returns state.h1
|
||||
- State state = new State();
|
||||
-
|
||||
- state.h1 = 0x9368e53c2f6af274L ^ seed;
|
||||
- state.h2 = 0x586dcd208f7cd3fdL ^ seed;
|
||||
-
|
||||
- state.c1 = 0x87c37b91114253d5L;
|
||||
- state.c2 = 0x4cf5ad432745937fL;
|
||||
-
|
||||
- for (int i = 0; i < key.length / 2; i++) {
|
||||
- state.k1 = key[i * 2];
|
||||
- state.k2 = key[i * 2 + 1];
|
||||
-
|
||||
- bmix(state);
|
||||
- }
|
||||
-
|
||||
- long tail = key[key.length - 1];
|
||||
-
|
||||
- if (key.length % 2 != 0) {
|
||||
- state.k1 ^= tail;
|
||||
- bmix(state);
|
||||
- }
|
||||
-
|
||||
- state.h2 ^= key.length * 8;
|
||||
-
|
||||
- state.h1 += state.h2;
|
||||
- state.h2 += state.h1;
|
||||
-
|
||||
- state.h1 = fmix(state.h1);
|
||||
- state.h2 = fmix(state.h2);
|
||||
-
|
||||
- state.h1 += state.h2;
|
||||
- state.h2 += state.h1;
|
||||
-
|
||||
- return state.h1;
|
||||
+ return MurmurHash3_x64_128(key, seed).h1;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -322,97 +144,13 @@
|
||||
return (int) (MurmurHash3_x64_64(key, seed) >>> 32);
|
||||
}
|
||||
|
||||
- @Override
|
||||
- public int hash(byte[] payload) {
|
||||
- return MurmurHash3_x64_32(payload, 9001);
|
||||
- }
|
||||
-
|
||||
/**
|
||||
* Hashes a byte array efficiently.
|
||||
*
|
||||
* @param payload a byte array to hash
|
||||
* @return a hash code for the byte array
|
||||
*/
|
||||
- public static int hash(long[] payload) {
|
||||
- return MurmurHash3_x64_32(payload, 9001);
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public int hash(int hashcode) {
|
||||
- // Obtained by inlining MurmurHash3_x64_32(byte[], 9001) and removing all the unused code
|
||||
- // (since we know the input is always 4 bytes and we only need 4 bytes of output)
|
||||
- byte b0 = (byte) hashcode;
|
||||
- byte b1 = (byte) (hashcode >>> 8);
|
||||
- byte b2 = (byte) (hashcode >>> 16);
|
||||
- byte b3 = (byte) (hashcode >>> 24);
|
||||
- State state = new State();
|
||||
-
|
||||
- state.h1 = 0x9368e53c2f6af274L ^ 9001;
|
||||
- state.h2 = 0x586dcd208f7cd3fdL ^ 9001;
|
||||
-
|
||||
- state.c1 = 0x87c37b91114253d5L;
|
||||
- state.c2 = 0x4cf5ad432745937fL;
|
||||
-
|
||||
- state.k1 = 0;
|
||||
- state.k2 = 0;
|
||||
-
|
||||
- state.k1 ^= (long) b3 << 24;
|
||||
- state.k1 ^= (long) b2 << 16;
|
||||
- state.k1 ^= (long) b1 << 8;
|
||||
- state.k1 ^= b0;
|
||||
- bmix(state);
|
||||
-
|
||||
- state.h2 ^= 4;
|
||||
-
|
||||
- state.h1 += state.h2;
|
||||
- state.h2 += state.h1;
|
||||
-
|
||||
- state.h1 = fmix(state.h1);
|
||||
- state.h2 = fmix(state.h2);
|
||||
-
|
||||
- state.h1 += state.h2;
|
||||
- state.h2 += state.h1;
|
||||
-
|
||||
- return (int) (state.h1 >>> 32);
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public int hash(Object o) {
|
||||
- if (o instanceof byte[])
|
||||
- return hash((byte[]) o);
|
||||
- else if (o instanceof long[])
|
||||
- return hash((long[]) o);
|
||||
- else if (o instanceof String)
|
||||
- return hash(((String) o).getBytes(UTF8));
|
||||
- else
|
||||
- return hash(o.hashCode());
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public boolean equals(Object other) {
|
||||
- return other != null && other.getClass() == getClass();
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public String toString() {
|
||||
- return "MurmurHash3";
|
||||
- }
|
||||
-
|
||||
- public static class Externalizer extends NoStateExternalizer<MurmurHash3> {
|
||||
- @Override
|
||||
- @SuppressWarnings("unchecked")
|
||||
- public Set<Class<? extends MurmurHash3>> getTypeClasses() {
|
||||
- return Util.<Class<? extends MurmurHash3>>asSet(MurmurHash3.class);
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public MurmurHash3 readObject(ObjectInput input) {
|
||||
- return new MurmurHash3();
|
||||
- }
|
||||
-
|
||||
- @Override
|
||||
- public Integer getId() {
|
||||
- return Ids.MURMURHASH_3;
|
||||
- }
|
||||
+ public static long hash(long[] payload) {
|
||||
+ return MurmurHash3_x64_64(payload, 9001);
|
||||
}
|
||||
}
|
|
@ -83,145 +83,7 @@ public class MurmurHash3 {
|
|||
* @param seed random value
|
||||
* @return 128 bit hashed key, in an array containing two longs
|
||||
*/
|
||||
@SuppressWarnings("fallthrough")
|
||||
public static long[] MurmurHash3_x64_128(final byte[] key, final int seed) {
|
||||
State state = new State();
|
||||
|
||||
state.h1 = 0x9368e53c2f6af274L ^ seed;
|
||||
state.h2 = 0x586dcd208f7cd3fdL ^ seed;
|
||||
|
||||
state.c1 = 0x87c37b91114253d5L;
|
||||
state.c2 = 0x4cf5ad432745937fL;
|
||||
|
||||
for (int i = 0; i < key.length / 16; i++) {
|
||||
state.k1 = getblock(key, i * 2 * 8);
|
||||
state.k2 = getblock(key, (i * 2 + 1) * 8);
|
||||
|
||||
bmix(state);
|
||||
}
|
||||
|
||||
state.k1 = 0;
|
||||
state.k2 = 0;
|
||||
|
||||
int tail = (key.length >>> 4) << 4;
|
||||
|
||||
switch (key.length & 15) {
|
||||
case 15: state.k2 ^= (long) key[tail + 14] << 48;
|
||||
case 14: state.k2 ^= (long) key[tail + 13] << 40;
|
||||
case 13: state.k2 ^= (long) key[tail + 12] << 32;
|
||||
case 12: state.k2 ^= (long) key[tail + 11] << 24;
|
||||
case 11: state.k2 ^= (long) key[tail + 10] << 16;
|
||||
case 10: state.k2 ^= (long) key[tail + 9] << 8;
|
||||
case 9: state.k2 ^= key[tail + 8];
|
||||
|
||||
case 8: state.k1 ^= (long) key[tail + 7] << 56;
|
||||
case 7: state.k1 ^= (long) key[tail + 6] << 48;
|
||||
case 6: state.k1 ^= (long) key[tail + 5] << 40;
|
||||
case 5: state.k1 ^= (long) key[tail + 4] << 32;
|
||||
case 4: state.k1 ^= (long) key[tail + 3] << 24;
|
||||
case 3: state.k1 ^= (long) key[tail + 2] << 16;
|
||||
case 2: state.k1 ^= (long) key[tail + 1] << 8;
|
||||
case 1: state.k1 ^= key[tail + 0];
|
||||
bmix(state);
|
||||
}
|
||||
|
||||
state.h2 ^= key.length;
|
||||
|
||||
state.h1 += state.h2;
|
||||
state.h2 += state.h1;
|
||||
|
||||
state.h1 = fmix(state.h1);
|
||||
state.h2 = fmix(state.h2);
|
||||
|
||||
state.h1 += state.h2;
|
||||
state.h2 += state.h1;
|
||||
|
||||
return new long[] { state.h1, state.h2 };
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash a value using the x64 64 bit variant of MurmurHash3
|
||||
*
|
||||
* @param key value to hash
|
||||
* @param seed random value
|
||||
* @return 64 bit hashed key
|
||||
*/
|
||||
@SuppressWarnings("fallthrough")
|
||||
public static long MurmurHash3_x64_64(final byte[] key, final int seed) {
|
||||
// Exactly the same as MurmurHash3_x64_128, except it only returns state.h1
|
||||
State state = new State();
|
||||
|
||||
state.h1 = 0x9368e53c2f6af274L ^ seed;
|
||||
state.h2 = 0x586dcd208f7cd3fdL ^ seed;
|
||||
|
||||
state.c1 = 0x87c37b91114253d5L;
|
||||
state.c2 = 0x4cf5ad432745937fL;
|
||||
|
||||
for (int i = 0; i < key.length / 16; i++) {
|
||||
state.k1 = getblock(key, i * 2 * 8);
|
||||
state.k2 = getblock(key, (i * 2 + 1) * 8);
|
||||
|
||||
bmix(state);
|
||||
}
|
||||
|
||||
state.k1 = 0;
|
||||
state.k2 = 0;
|
||||
|
||||
int tail = (key.length >>> 4) << 4;
|
||||
|
||||
switch (key.length & 15) {
|
||||
case 15: state.k2 ^= (long) key[tail + 14] << 48;
|
||||
case 14: state.k2 ^= (long) key[tail + 13] << 40;
|
||||
case 13: state.k2 ^= (long) key[tail + 12] << 32;
|
||||
case 12: state.k2 ^= (long) key[tail + 11] << 24;
|
||||
case 11: state.k2 ^= (long) key[tail + 10] << 16;
|
||||
case 10: state.k2 ^= (long) key[tail + 9] << 8;
|
||||
case 9: state.k2 ^= key[tail + 8];
|
||||
|
||||
case 8: state.k1 ^= (long) key[tail + 7] << 56;
|
||||
case 7: state.k1 ^= (long) key[tail + 6] << 48;
|
||||
case 6: state.k1 ^= (long) key[tail + 5] << 40;
|
||||
case 5: state.k1 ^= (long) key[tail + 4] << 32;
|
||||
case 4: state.k1 ^= (long) key[tail + 3] << 24;
|
||||
case 3: state.k1 ^= (long) key[tail + 2] << 16;
|
||||
case 2: state.k1 ^= (long) key[tail + 1] << 8;
|
||||
case 1: state.k1 ^= key[tail + 0];
|
||||
bmix(state);
|
||||
}
|
||||
|
||||
state.h2 ^= key.length;
|
||||
|
||||
state.h1 += state.h2;
|
||||
state.h2 += state.h1;
|
||||
|
||||
state.h1 = fmix(state.h1);
|
||||
state.h2 = fmix(state.h2);
|
||||
|
||||
state.h1 += state.h2;
|
||||
state.h2 += state.h1;
|
||||
|
||||
return state.h1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash a value using the x64 32 bit variant of MurmurHash3
|
||||
*
|
||||
* @param key value to hash
|
||||
* @param seed random value
|
||||
* @return 32 bit hashed key
|
||||
*/
|
||||
public static int MurmurHash3_x64_32(final byte[] key, final int seed) {
|
||||
return (int) (MurmurHash3_x64_64(key, seed) >>> 32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hash a value using the x64 128 bit variant of MurmurHash3
|
||||
*
|
||||
* @param key value to hash
|
||||
* @param seed random value
|
||||
* @return 128 bit hashed key, in an array containing two longs
|
||||
*/
|
||||
public static long[] MurmurHash3_x64_128(final long[] key, final int seed) {
|
||||
private static State MurmurHash3_x64_128(final long[] key, final int seed) {
|
||||
State state = new State();
|
||||
|
||||
state.h1 = 0x9368e53c2f6af274L ^ seed;
|
||||
|
@ -256,7 +118,7 @@ public class MurmurHash3 {
|
|||
state.h1 += state.h2;
|
||||
state.h2 += state.h1;
|
||||
|
||||
return new long[] { state.h1, state.h2 };
|
||||
return state;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -268,40 +130,7 @@ public class MurmurHash3 {
|
|||
*/
|
||||
public static long MurmurHash3_x64_64(final long[] key, final int seed) {
|
||||
// Exactly the same as MurmurHash3_x64_128, except it only returns state.h1
|
||||
State state = new State();
|
||||
|
||||
state.h1 = 0x9368e53c2f6af274L ^ seed;
|
||||
state.h2 = 0x586dcd208f7cd3fdL ^ seed;
|
||||
|
||||
state.c1 = 0x87c37b91114253d5L;
|
||||
state.c2 = 0x4cf5ad432745937fL;
|
||||
|
||||
for (int i = 0; i < key.length / 2; i++) {
|
||||
state.k1 = key[i * 2];
|
||||
state.k2 = key[i * 2 + 1];
|
||||
|
||||
bmix(state);
|
||||
}
|
||||
|
||||
final long tail = key.length > 0 ? key[key.length - 1] : 0;
|
||||
|
||||
if (key.length % 2 != 0) {
|
||||
state.k1 ^= tail;
|
||||
bmix(state);
|
||||
}
|
||||
|
||||
state.h2 ^= key.length * 8;
|
||||
|
||||
state.h1 += state.h2;
|
||||
state.h2 += state.h1;
|
||||
|
||||
state.h1 = fmix(state.h1);
|
||||
state.h2 = fmix(state.h2);
|
||||
|
||||
state.h1 += state.h2;
|
||||
state.h2 += state.h1;
|
||||
|
||||
return state.h1;
|
||||
return MurmurHash3_x64_128(key, seed).h1;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -315,11 +144,6 @@ public class MurmurHash3 {
|
|||
return (int) (MurmurHash3_x64_64(key, seed) >>> 32);
|
||||
}
|
||||
|
||||
|
||||
public int hash(byte[] payload) {
|
||||
return MurmurHash3_x64_32(payload, 9001);
|
||||
}
|
||||
|
||||
/**
|
||||
* Hashes a byte array efficiently.
|
||||
*
|
||||
|
@ -329,43 +153,4 @@ public class MurmurHash3 {
|
|||
public static long hash(long[] payload) {
|
||||
return MurmurHash3_x64_64(payload, 9001);
|
||||
}
|
||||
|
||||
|
||||
public int hash(int hashcode) {
|
||||
// Obtained by inlining MurmurHash3_x64_32(byte[], 9001) and removing all the unused code
|
||||
// (since we know the input is always 4 bytes and we only need 4 bytes of output)
|
||||
byte b0 = (byte) hashcode;
|
||||
byte b1 = (byte) (hashcode >>> 8);
|
||||
byte b2 = (byte) (hashcode >>> 16);
|
||||
byte b3 = (byte) (hashcode >>> 24);
|
||||
State state = new State();
|
||||
|
||||
state.h1 = 0x9368e53c2f6af274L ^ 9001;
|
||||
state.h2 = 0x586dcd208f7cd3fdL ^ 9001;
|
||||
|
||||
state.c1 = 0x87c37b91114253d5L;
|
||||
state.c2 = 0x4cf5ad432745937fL;
|
||||
|
||||
state.k1 = 0;
|
||||
state.k2 = 0;
|
||||
|
||||
state.k1 ^= (long) b3 << 24;
|
||||
state.k1 ^= (long) b2 << 16;
|
||||
state.k1 ^= (long) b1 << 8;
|
||||
state.k1 ^= b0;
|
||||
bmix(state);
|
||||
|
||||
state.h2 ^= 4;
|
||||
|
||||
state.h1 += state.h2;
|
||||
state.h2 += state.h1;
|
||||
|
||||
state.h1 = fmix(state.h1);
|
||||
state.h2 = fmix(state.h2);
|
||||
|
||||
state.h1 += state.h2;
|
||||
state.h2 += state.h1;
|
||||
|
||||
return (int) (state.h1 >>> 32);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,6 +72,12 @@ public class MagicCardList extends ArrayList<MagicCard> implements MagicCopyable
|
|||
return card;
|
||||
}
|
||||
|
||||
public MagicCard removeCardAtBottom() {
|
||||
final MagicCard card=get(0);
|
||||
remove(0);
|
||||
return card;
|
||||
}
|
||||
|
||||
public int removeCard(final MagicCard card) {
|
||||
final int index=indexOf(card);
|
||||
if (index >= 0) {
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
package magic.model.action;
|
||||
|
||||
import magic.model.MagicCard;
|
||||
import magic.model.MagicCardList;
|
||||
import magic.model.MagicGame;
|
||||
import magic.model.MagicPlayer;
|
||||
|
||||
public class MagicScryAction extends MagicAction {
|
||||
|
||||
private final MagicPlayer player;
|
||||
private MagicCard card;
|
||||
|
||||
public MagicScryAction(final MagicPlayer aPlayer) {
|
||||
player = aPlayer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doAction(final MagicGame game) {
|
||||
card = player.getLibrary().removeCardAtTop();
|
||||
player.getLibrary().addToBottom(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void undoAction(final MagicGame game) {
|
||||
player.getLibrary().removeCardAtBottom();
|
||||
player.getLibrary().addToTop(card);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package magic.model.choice;
|
||||
|
||||
import magic.data.GeneralConfig;
|
||||
import magic.model.MagicGame;
|
||||
import magic.model.MagicCard;
|
||||
import magic.model.MagicCardList;
|
||||
import magic.model.MagicPlayer;
|
||||
import magic.model.MagicSource;
|
||||
import magic.model.event.MagicEvent;
|
||||
import magic.ui.GameController;
|
||||
import magic.ui.UndoClickedException;
|
||||
import magic.ui.choice.MayChoicePanel;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
public class MagicScryChoice extends MagicMayChoice {
|
||||
public MagicScryChoice() {
|
||||
super("Put this card on the bottom of your library?");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] getPlayerChoiceResults(
|
||||
final GameController controller,
|
||||
final MagicGame game,
|
||||
final MagicPlayer player,
|
||||
final MagicSource source) throws UndoClickedException {
|
||||
|
||||
final Object[] choiceResults=new Object[1];
|
||||
choiceResults[0]=NO_CHOICE;
|
||||
|
||||
final MagicCard topCard = player.getLibrary().getCardAtTop();
|
||||
if (topCard == MagicCard.NONE) {
|
||||
return choiceResults;
|
||||
}
|
||||
|
||||
final MagicCardList cards = new MagicCardList();
|
||||
cards.add(topCard);
|
||||
controller.showCards(cards);
|
||||
|
||||
controller.disableActionButton(false);
|
||||
final MayChoicePanel choicePanel = controller.waitForInput(new Callable<MayChoicePanel>() {
|
||||
public MayChoicePanel call() {
|
||||
return new MayChoicePanel(controller,source,getDescription());
|
||||
}
|
||||
});
|
||||
|
||||
controller.showCards(new MagicCardList());
|
||||
|
||||
if (choicePanel.isYesClicked()) {
|
||||
choiceResults[0]=YES_CHOICE;
|
||||
}
|
||||
|
||||
return choiceResults;
|
||||
}
|
||||
}
|
|
@ -37,6 +37,7 @@ import magic.model.action.MagicGainAbilityAction;
|
|||
import magic.model.action.MagicMillLibraryAction;
|
||||
import magic.model.action.MagicRemoveCardAction;
|
||||
import magic.model.action.MagicMoveCardAction;
|
||||
import magic.model.action.MagicReanimateAction;
|
||||
import magic.model.stack.MagicCardOnStack;
|
||||
import magic.model.target.MagicTarget;
|
||||
import magic.model.target.MagicTargetFilter;
|
||||
|
@ -382,6 +383,66 @@ public enum MagicRuleEventAction {
|
|||
};
|
||||
}
|
||||
},
|
||||
GainPumpChosen(
|
||||
"(?<choice>[^\\.]*) gets (?<pt>[0-9+]+/[0-9+]+) and gains (?<ability>[^\\.]*) until end of turn.",
|
||||
MagicTargetHint.Positive
|
||||
) {
|
||||
public MagicEventAction getAction(final String rule) {
|
||||
final Matcher matcher = matched(rule);
|
||||
final MagicAbility ability = MagicAbility.getAbility(matcher.group("ability"));
|
||||
final String[] pt = matcher.group("pt").replace("+","").split("/");
|
||||
final int power = Integer.parseInt(pt[0]);
|
||||
final int toughness = Integer.parseInt(pt[1]);
|
||||
return new MagicEventAction() {
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
event.processTargetPermanent(game,new MagicPermanentAction() {
|
||||
public void doAction(final MagicPermanent creature) {
|
||||
game.doAction(new MagicChangeTurnPTAction(creature,power,toughness));
|
||||
game.doAction(new MagicGainAbilityAction(creature,ability));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
public MagicTiming getTiming(final String rule) {
|
||||
final Matcher matcher = matched(rule);
|
||||
final MagicAbility ability = MagicAbility.getAbility(matcher.group("ability"));
|
||||
switch (ability) {
|
||||
case Haste:
|
||||
case Vigilance:
|
||||
return MagicTiming.FirstMain;
|
||||
case FirstStrike:
|
||||
case DoubleStrike:
|
||||
return MagicTiming.Block;
|
||||
default:
|
||||
return MagicTiming.Pump;
|
||||
}
|
||||
}
|
||||
public MagicTargetPicker<?> getPicker(final String rule) {
|
||||
final Matcher matcher = matched(rule);
|
||||
final MagicAbility ability = MagicAbility.getAbility(matcher.group("ability"));
|
||||
switch (ability) {
|
||||
case Deathtouch:
|
||||
return MagicDeathtouchTargetPicker.getInstance();
|
||||
case Lifelink:
|
||||
return MagicLifelinkTargetPicker.create();
|
||||
case FirstStrike:
|
||||
case DoubleStrike:
|
||||
return MagicFirstStrikeTargetPicker.create();
|
||||
case Haste:
|
||||
return MagicHasteTargetPicker.create();
|
||||
case Indestructible:
|
||||
return MagicIndestructibleTargetPicker.create();
|
||||
case Trample:
|
||||
return MagicTrampleTargetPicker.create();
|
||||
case Flying:
|
||||
return MagicFlyingTargetPicker.create();
|
||||
default:
|
||||
return MagicPumpTargetPicker.create();
|
||||
}
|
||||
}
|
||||
},
|
||||
PumpGroup(
|
||||
"(?<group>[^\\.]*) get (?<pt>[0-9+]+/[0-9+]+) until end of turn.",
|
||||
MagicTiming.Pump,
|
||||
|
@ -749,6 +810,26 @@ public enum MagicRuleEventAction {
|
|||
}
|
||||
}
|
||||
),
|
||||
Reanimate(
|
||||
"return (?<choice>[^\\.]*) to the battlefield.",
|
||||
MagicTargetHint.None,
|
||||
MagicGraveyardTargetPicker.PutOntoBattlefield,
|
||||
MagicTiming.Pump,
|
||||
"Return",
|
||||
new MagicEventAction() {
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
event.processTargetCard(game,new MagicCardAction() {
|
||||
public void doAction(final MagicCard card) {
|
||||
game.doAction(new MagicReanimateAction(
|
||||
card,
|
||||
event.getPlayer()
|
||||
));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
),
|
||||
Tap(
|
||||
"tap (?<choice>[^\\.]*).",
|
||||
MagicTargetHint.Negative,
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
package magic.model.event;
|
||||
|
||||
import magic.model.MagicGame;
|
||||
import magic.model.MagicPlayer;
|
||||
import magic.model.MagicSource;
|
||||
import magic.model.MagicLocationType;
|
||||
import magic.model.MagicPermanent;
|
||||
import magic.model.MagicCard;
|
||||
import magic.model.choice.MagicScryChoice;
|
||||
import magic.model.action.MagicScryAction;
|
||||
|
||||
public class MagicScryEvent extends MagicEvent {
|
||||
|
||||
public MagicScryEvent(final MagicEvent event) {
|
||||
this(event.getSource(), event.getPlayer());
|
||||
}
|
||||
|
||||
public MagicScryEvent(final MagicSource source, final MagicPlayer player) {
|
||||
super(
|
||||
source,
|
||||
player,
|
||||
new MagicScryChoice(),
|
||||
EventAction,
|
||||
""
|
||||
);
|
||||
}
|
||||
|
||||
private static final MagicEventAction EventAction = new MagicEventAction() {
|
||||
@Override
|
||||
public void executeEvent(final MagicGame game, final MagicEvent event) {
|
||||
if (event.isYes()) {
|
||||
final MagicPlayer p = event.getPlayer();
|
||||
game.logAppendMessage(p, p + " moves a card from top of his or her library to the bottom.");
|
||||
game.doAction(new MagicScryAction(p));
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
|
@ -908,6 +908,15 @@ public interface MagicTargetFilter<T extends MagicTarget> {
|
|||
}
|
||||
};
|
||||
|
||||
MagicCardFilterImpl TARGET_CREATURE_CARD_CMC_LEQ_2_FROM_GRAVEYARD=new MagicCardFilterImpl() {
|
||||
public boolean accept(final MagicGame game,final MagicPlayer player,final MagicCard target) {
|
||||
return target.getConvertedCost() <= 2 && target.hasType(MagicType.Creature);
|
||||
}
|
||||
public boolean acceptType(final MagicTargetType targetType) {
|
||||
return targetType==MagicTargetType.Graveyard;
|
||||
}
|
||||
};
|
||||
|
||||
MagicPermanentFilterImpl TARGET_NONLAND_PERMANENT_CMC_LEQ_3 = new MagicTargetFilter.MagicCMCPermanentFilter(
|
||||
MagicTargetFilter.TARGET_NONLAND_PERMANENT,
|
||||
MagicTargetFilter.Operator.LESS_THAN_OR_EQUAL,
|
||||
|
|
|
@ -144,6 +144,7 @@ public class MagicTargetFilterFactory {
|
|||
single.put("non-Vampire creature you control", TARGET_NON_VAMPIRE_YOU_CONTROL);
|
||||
single.put("permanent card from your graveyard", TARGET_PERMANENT_CARD_FROM_GRAVEYARD);
|
||||
single.put("permanent card with converted mana cost 3 or less from your graveyard", TARGET_PERMANENT_CARD_CMC_LEQ_3_FROM_GRAVEYARD);
|
||||
single.put("creature card with converted mana cost 2 or less from your graveyard", TARGET_CREATURE_CARD_CMC_LEQ_2_FROM_GRAVEYARD);
|
||||
single.put("unblocked attacking creature you control", UNBLOCKED_ATTACKING_CREATURE_YOU_CONTROL);
|
||||
single.put("attacking creature you control", TARGET_ATTACKING_CREATURE_YOU_CONTROL);
|
||||
single.put("Vampire, Werewolf, or Zombie", TARGET_VAMPIRE_WEREWOLF_OR_ZOMBIE);
|
||||
|
|
|
@ -29,11 +29,12 @@ class TestPlaneswalker extends TestGameBuilder {
|
|||
|
||||
P.setLife(20);
|
||||
addToLibrary(P, "Plains", 10);
|
||||
createPermanent(game,P,"Rupture Spire",false,8);
|
||||
createPermanent(game,P,"Rupture Spire",false,10);
|
||||
createPermanent(game,P,"Grizzly Bears",false,1);
|
||||
addToHand(P, "Ajani, Caller of the Pride", 1);
|
||||
addToHand(P, "Sarkhan Vol", 1);
|
||||
addToHand(P, "Tamiyo, the Moon Sage", 1);
|
||||
addToHand(P, "Burst Lightning", 1);
|
||||
addToHand(P, "Elspeth Tirel", 1);
|
||||
addToHand(P, "Venser, the Sojourner", 1);
|
||||
addToHand(P, "Vraska the Unseen", 1);
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
package magic.test;
|
||||
|
||||
import magic.model.MagicDuel;
|
||||
import magic.model.MagicGame;
|
||||
import magic.model.MagicPlayer;
|
||||
import magic.model.MagicPlayerDefinition;
|
||||
import magic.model.MagicPlayerProfile;
|
||||
import magic.model.phase.MagicMainPhase;
|
||||
|
||||
class TestScry extends TestGameBuilder {
|
||||
public MagicGame getGame() {
|
||||
final MagicDuel duel=new MagicDuel();
|
||||
duel.setDifficulty(6);
|
||||
|
||||
final MagicPlayerProfile profile=new MagicPlayerProfile("bgruw");
|
||||
final MagicPlayerDefinition player1=new MagicPlayerDefinition("Player",false,profile,15);
|
||||
final MagicPlayerDefinition player2=new MagicPlayerDefinition("Computer",true,profile,14);
|
||||
duel.setPlayers(new MagicPlayerDefinition[]{player1,player2});
|
||||
duel.setStartPlayer(0);
|
||||
|
||||
final MagicGame game=duel.nextGame(true);
|
||||
game.setPhase(MagicMainPhase.getFirstInstance());
|
||||
final MagicPlayer player=game.getPlayer(0);
|
||||
final MagicPlayer opponent=game.getPlayer(1);
|
||||
|
||||
MagicPlayer P = player;
|
||||
|
||||
P.setLife(6);
|
||||
addToLibrary(P, "Forest", 20);
|
||||
addToLibrary(P, "Island", 20);
|
||||
addToLibrary(P, "Entreat the Angels", 20);
|
||||
addToLibrary(P, "Sliver Overlord", 1);
|
||||
addToGraveyard(P, "Ink-Eyes, Servant of Oni", 3);
|
||||
createPermanent(game,P, "Rupture Spire", false, 10);
|
||||
addToHand(P, "Spark Jolt", 1);
|
||||
addToHand(P, "Temple of Silence", 1);
|
||||
|
||||
P = opponent;
|
||||
|
||||
P.setLife(6);
|
||||
addToLibrary(P, "Mountain", 20);
|
||||
createPermanent(game,P,"Rupture Spire",false,9);
|
||||
createPermanent(game,P, "Grizzly Bears", false, 1);
|
||||
addToHand(P, "Trained Jackal", 1);
|
||||
addToGraveyard(P, "Ink-Eyes, Servant of Oni", 1);
|
||||
|
||||
return game;
|
||||
}
|
||||
}
|
|
@ -475,8 +475,12 @@ public class GameController implements ILogBookListener {
|
|||
} else {
|
||||
game.gotoLastUndoPoint();
|
||||
}
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
gamePanel.getLogBookViewer().update();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void haltGame() {
|
||||
running.set(false);
|
||||
|
|
Loading…
Reference in New Issue