* Hope of Ghirapur - Fixed a problem with check if current object has daone the damage.

This commit is contained in:
LevelX2 2017-09-23 19:16:21 +02:00
parent 4285aced97
commit 0714ae39dc
3 changed files with 30 additions and 16 deletions

View file

@ -33,6 +33,7 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject; import mage.MageObject;
import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost; import mage.abilities.costs.common.SacrificeSourceCost;
@ -49,6 +50,8 @@ import mage.game.Game;
import mage.game.events.DamagedPlayerEvent; import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType; import mage.game.events.GameEvent.EventType;
import mage.game.stack.StackAbility;
import mage.game.stack.StackObject;
import mage.players.Player; import mage.players.Player;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
import mage.watchers.Watcher; import mage.watchers.Watcher;
@ -115,7 +118,7 @@ class HopeOfGhirapurCantCastEffect extends ContinuousRuleModifyingEffectImpl {
@Override @Override
public String getInfoMessage(Ability source, GameEvent event, Game game) { public String getInfoMessage(Ability source, GameEvent event, Game game) {
MageObject mageObject = game.getObject(source.getSourceId()); MageObject mageObject = source.getSourceObject(game);
if (mageObject != null) { if (mageObject != null) {
return "You can't cast noncreature spells this turn (you were dealt damage by " + mageObject.getLogName() + ')'; return "You can't cast noncreature spells this turn (you were dealt damage by " + mageObject.getLogName() + ')';
} }
@ -153,7 +156,7 @@ class HopeOfGhirapurPlayerLostLifePredicate implements ObjectSourcePlayerPredica
} }
HopeOfGhirapurCombatDamageWatcher watcher = (HopeOfGhirapurCombatDamageWatcher) game.getState().getWatchers().get(HopeOfGhirapurCombatDamageWatcher.class.getSimpleName()); HopeOfGhirapurCombatDamageWatcher watcher = (HopeOfGhirapurCombatDamageWatcher) game.getState().getWatchers().get(HopeOfGhirapurCombatDamageWatcher.class.getSimpleName());
if (watcher != null) { if (watcher != null) {
return watcher.playerGotCombatDamage(input.getSourceId(), input.getObject().getId()); return watcher.playerGotCombatDamage(input.getSourceId(), input.getObject().getId(), game);
} }
return false; return false;
} }
@ -161,7 +164,7 @@ class HopeOfGhirapurPlayerLostLifePredicate implements ObjectSourcePlayerPredica
class HopeOfGhirapurCombatDamageWatcher extends Watcher { class HopeOfGhirapurCombatDamageWatcher extends Watcher {
private final HashMap<UUID, Set<UUID>> combatDamagedPlayers = new HashMap<>(); private final HashMap<MageObjectReference, Set<UUID>> combatDamagedPlayers = new HashMap<>();
public HopeOfGhirapurCombatDamageWatcher() { public HopeOfGhirapurCombatDamageWatcher() {
super(HopeOfGhirapurCombatDamageWatcher.class.getSimpleName(), WatcherScope.GAME); super(HopeOfGhirapurCombatDamageWatcher.class.getSimpleName(), WatcherScope.GAME);
@ -169,10 +172,10 @@ class HopeOfGhirapurCombatDamageWatcher extends Watcher {
public HopeOfGhirapurCombatDamageWatcher(final HopeOfGhirapurCombatDamageWatcher watcher) { public HopeOfGhirapurCombatDamageWatcher(final HopeOfGhirapurCombatDamageWatcher watcher) {
super(watcher); super(watcher);
for (UUID damagerId : watcher.combatDamagedPlayers.keySet()) { for (MageObjectReference damager : watcher.combatDamagedPlayers.keySet()) {
Set<UUID> players = new HashSet<>(); Set<UUID> players = new HashSet<>();
players.addAll(watcher.combatDamagedPlayers.get(damagerId)); players.addAll(watcher.combatDamagedPlayers.get(damager));
this.combatDamagedPlayers.put(damagerId, players); this.combatDamagedPlayers.put(damager, players);
} }
} }
@ -184,13 +187,13 @@ class HopeOfGhirapurCombatDamageWatcher extends Watcher {
@Override @Override
public void watch(GameEvent event, Game game) { public void watch(GameEvent event, Game game) {
if (event.getType() == EventType.DAMAGED_PLAYER && ((DamagedPlayerEvent) event).isCombatDamage()) { if (event.getType() == EventType.DAMAGED_PLAYER && ((DamagedPlayerEvent) event).isCombatDamage()) {
UUID damagerId = event.getSourceId(); MageObjectReference damager = new MageObjectReference(event.getSourceId(), game);
Set<UUID> players; Set<UUID> players;
if (combatDamagedPlayers.containsKey(damagerId)) { if (combatDamagedPlayers.containsKey(damager)) {
players = combatDamagedPlayers.get(damagerId); players = combatDamagedPlayers.get(damager);
} else { } else {
players = new HashSet<>(); players = new HashSet<>();
combatDamagedPlayers.put(damagerId, players); combatDamagedPlayers.put(damager, players);
} }
players.add(event.getTargetId()); players.add(event.getTargetId());
} }
@ -204,9 +207,17 @@ class HopeOfGhirapurCombatDamageWatcher extends Watcher {
* @param playerId * @param playerId
* @return * @return
*/ */
public boolean playerGotCombatDamage(UUID objectId, UUID playerId) { public boolean playerGotCombatDamage(UUID objectId, UUID playerId, Game game) {
if (combatDamagedPlayers.containsKey(objectId)) { StackObject stackObject = game.getState().getStack().getStackObject(objectId);
return combatDamagedPlayers.get(objectId).contains(playerId); MageObjectReference mor;
if (stackObject != null && stackObject instanceof StackAbility) {
// This is neccessary because the source object was sacrificed as cost and the correct zone change counter for target calid check can only be get from stack
mor = new MageObjectReference(objectId, ((StackAbility) stackObject).getSourceObjectZoneChangeCounter(), game);
} else {
mor = new MageObjectReference(objectId, game);
}
if (combatDamagedPlayers.containsKey(mor)) {
return combatDamagedPlayers.get(mor).contains(playerId);
} }
return false; return false;
} }

View file

@ -35,16 +35,19 @@ public class HopeOfGhirapurTest extends CardTestPlayerBase {
// from the battlefield and returned back. // from the battlefield and returned back.
@Test @Test
public void testWhenHopeOfGhirapurWasRemovedAndReturnedBack() { public void testWhenHopeOfGhirapurWasRemovedAndReturnedBack() {
// Flying
// Sacrifice Hope of Ghirapur: Until your next turn, target player who was dealt combat damage by Hope of Ghirapur this turn can't cast noncreature spells.
addCard(Zone.BATTLEFIELD, playerA, "Hope of Ghirapur"); addCard(Zone.BATTLEFIELD, playerA, "Hope of Ghirapur");
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1); addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
// Exile target creature you control, then return that card to the battlefield under your control.
addCard(Zone.HAND, playerA, "Cloudshift"); addCard(Zone.HAND, playerA, "Cloudshift");
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1); addCard(Zone.BATTLEFIELD, playerB, "Mountain", 1);
addCard(Zone.HAND, playerB, "Shock"); addCard(Zone.HAND, playerB, "Shock");
attack(1, playerA, "Hope of Ghirapur"); attack(1, playerA, "Hope of Ghirapur");
castSpell(1, PhaseStep.END_COMBAT, playerA, "Cloudshift", "Hope of Ghirapur"); castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Cloudshift", "Hope of Ghirapur");
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "Sacrifice", playerB); activateAbility(1, PhaseStep.END_TURN, playerA, "Sacrifice", playerB);
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Shock", playerA); castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Shock", playerA);

View file

@ -537,7 +537,7 @@ public class StackAbility extends StackObjImpl implements Ability {
@Override @Override
public int getSourceObjectZoneChangeCounter() { public int getSourceObjectZoneChangeCounter() {
throw new UnsupportedOperationException("Not supported."); return ability.getSourceObjectZoneChangeCounter();
} }
@Override @Override