Card-Forge / Card-Forge/forge

Deck editor drops the DeckGroup model when a deck is loaded into a limited pool

Open
#11,900 0 comments 0 reactions 1 assignee Claimed by @leriomaggio View on GitHub
Deck Editor Desktop
Dominant language
Java
Stars
2.7k
Forks
1.1k
Avg merge
1d 1h
Merged PRs (30d)
158

Description

**Describe the bug**

In the local draft, sealed and Winston deck editors, pressing New, Open or Import
replaces the editor's `DeckGroup` model with a bare `Deck`. The AI decks in the group
are lost from the model. Nothing fails at the time and the editor still looks correct,
so the problem only surfaces later on the save path, which then holds a `Deck` where
its `IStorage` expects a group.

The cause is the last line of `DeckController.loadDeck`:

this.setModel((T) currentDeck, isStored);

`currentDeck` comes from `view.getHumanDeck()`. `Deck.getHumanDeck()` returns `this`,
so for a `Deck` model this stores the model back over itself and is harmless.
`DeckGroup.getHumanDeck()` returns the group's human deck, so for a `DeckGroup` model
it stores the wrong object.

`T` is `DeckGroup` for the local draft, sealed and Winston editors and `Deck` for
network event decks, so only the local limited editors are affected. Constructed is
unaffected.

**To Reproduce**

Steps to reproduce the behavior:
1. Open a Draft Deck Editor
2. Move a few cards into the maindeck
3. Click New. The deck empties and the pool returns to the sideboard, which is the
expected behaviour and looks correct
4. Click Save
5. You get a `ClassCastException`

```
java.lang.ClassCastException: class forge.deck.Deck cannot be cast to class forge.deck.DeckGroup (forge.deck.Deck and forge.deck.DeckGroup are in unnamed module of loader 'app')
at forge.util.storage.StorageReaderFolder.getItemKey(StorageReaderFolder.java:128)
at forge.util.storage.StorageImmediatelySerialized.add(StorageImmediatelySerialized.java:70)
at forge.screens.deckeditor.controllers.DeckController.save(DeckController.java:330)
at forge.screens.deckeditor.controllers.DeckController.saveAs(DeckController.java:352)
at forge.screens.deckeditor.SEditorIO.saveDeck(SEditorIO.java:58)
at forge.toolbox.FLabel._doMouseAction(FLabel.java:315)
at forge.toolbox.FLabel$6.onLeftClick(FLabel.java:353)
at forge.toolbox.FMouseAdapter.mouseReleased(FMouseAdapter.java:246)
at java.desktop/java.awt.AWTEventMulticaster.mouseReleased(AWTEventMulticaster.java:298)
at java.desktop/java.awt.Component.processMouseEvent(Component.java:6621)
at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3398)
at java.desktop/java.awt.Component.processEvent(Component.java:6386)
at java.desktop/java.awt.Container.processEvent(Container.java:2266)
at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4996)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4828)
at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948)
at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4575)
at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516)
at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310)
at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780)
at java.desktop/java.awt.Component.dispatchEvent(Component.java:4828)
at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:775)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:98)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:747)
at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:400)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:744)
at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

```

**Expected behavior**

New, Open and Import change the contents of the deck being edited. They should not
change which object the editor is editing. After any of them, the model should still
be the `DeckGroup` it was, with its AI decks intact, and saving should write a well
formed deck group.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.