Lithoform Engine error copying clue card draw ability
In beta, pay 2 to sacrifice a clue, hold priority try to copy the ability with Lithoform Engine, results in an error and rollback
Game exception occurred: java.lang.NullPointerException
Server version: 1.4.52-V1-beta3 (build: 2022-09-17 05:55)
mage.view.StackAbilityView.updateTargets(StackAbilityView.java:157)
mage.view.StackAbilityView.(StackAbilityView.java:79)
mage.view.GameView.(GameView.java:94)
mage.server.game.GameSessionPlayer.prepareGameView(GameSessionPlayer.java:211)
mage.server.game.GameSessionPlayer.getGameView(GameSessionPlayer.java:198)
mage.server.game.GameSessionPlayer.lambda$playMana$6(GameSessionPlayer.java:97)
java.util.Optional.ifPresent(Optional.java:159)
mage.server.game.GameSessionPlayer.playMana(GameSessionPlayer.java:96)
mage.server.game.GameController.lambda$playMana$21(GameController.java:862)
mage.server.game.GameController.perform(GameController.java:988)
mage.server.game.GameController.perform(GameController.java:981)
mage.server.game.GameController.playMana(GameController.java:862)
mage.server.game.GameController.lambda$init$3aa0d15c$2(GameController.java:198)
mage.game.events.EventDispatcher.fireEvent(EventDispatcher.java:28)
mage.game.events.PlayerQueryEventSource.playMana(PlayerQueryEventSource.java:80)
mage.game.GameImpl.firePlayManaEvent(GameImpl.java:2696)
mage.player.human.HumanPlayer.playManaHandling(HumanPlayer.java:1389)
mage.player.human.HumanPlayer.playMana(HumanPlayer.java:1371)
mage.abilities.costs.mana.ManaCostsImpl.pay(ManaCostsImpl.java:138)
mage.abilities.AbilityImpl.activate(AbilityImpl.java:404)
mage.abilities.ActivatedAbilityImpl.activate(ActivatedAbilityImpl.java:253)
mage.players.PlayerImpl.playAbility(PlayerImpl.java:1371)
mage.players.PlayerImpl.activateAbility(PlayerImpl.java:1497)
mage.player.human.HumanPlayer.activateAbility(HumanPlayer.java:2127)
mage.player.human.HumanPlayer.activateAbility(HumanPlayer.java:2150)
mage.player.human.HumanPlayer.priority(HumanPlayer.java:1228)
mage.game.GameImpl.playPriority(GameImpl.java:1539)
mage.game.turn.Step.priority(Step.java:61)
mage.game.turn.Phase.playStep(Phase.java:184)
mage.game.turn.Phase.play(Phase.java:89)
mage.game.turn.Turn.play(Turn.java:132)
mage.game.GameImpl.playTurn(GameImpl.java:1055)
mage.game.GameImpl.play(GameImpl.java:965)
mage.game.GameImpl.start(GameImpl.java:941)
mage.server.game.GameWorker.call(GameWorker.java:34)
java.util.concurrent.FutureTask.run(FutureTask.java:266)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
java.lang.Thread.run(Thread.java:748)
This doesn't happen in 1.4.50V2, so it's a regression.
Lithoform Engine - (Gatherer) (Scryfall) (EDHREC)
{4}
Legendary Artifact
{2}, {T}: Copy target activated or triggered ability you control. You may choose new targets for the copy.
{3}, {T}: Copy target instant or sorcery spell you control. You may choose new targets for the copy.
{4}, {T}: Copy target permanent spell you control. (The copy becomes a token.)
Line 157 is:
https://github.com/magefree/mage/blob/9084180937f7f7a7ad8f42d615b59633202a426b/Mage.Common/src/main/java/mage/view/StackAbilityView.java#L157
I have a feeling it's game.getCard
which is returning null since the clue is gone, so .getIdName()
will cause the NPE.
Why are CardView
and StackAbilityView
using different logic here? I can see displaying a different message depending on whether the target StackObject
is a spell or an ability, but this displays different messages depending on whether the thing doing the targetting is a spell or an ability.
In my tree I changed the StackAbilityView
code to match the CardView
code and now it doesn't crash and it looks like this when you mouse over the ability on the stack:
![Screenshot_20220923_163902](https://user-images.githubusercontent.com/9252545/192053337-ce6f6f43-c2b7-4e2e-95a6-45eb9e816574.png)
Does this look like what you intended? @jeffwadsworth It matches the log message, which also includes the text of the targeted ability rather than the name of its source object.
That looks great to me. I can't find the original user request for targets to show up on the stackobjects, but I think it was a useful request.
Does the current testing suite support catching a bug like this?