| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- package org.leumasjaffe.charsheet.view.level;
- import javax.swing.JPanel;
- import org.jdesktop.swingx.VerticalLayout;
- import org.leumasjaffe.charsheet.model.magic.DDSpell;
- import org.leumasjaffe.charsheet.model.observable.BoolGate;
- import org.leumasjaffe.charsheet.model.observable.IntValue;
- import org.leumasjaffe.charsheet.view.magic.SelectSpellsPanel;
- import org.leumasjaffe.charsheet.view.magic.SelectSpellsPanel.Info;
- import org.leumasjaffe.observer.ObservableListener;
- import org.leumasjaffe.observer.ObserverDispatch;
- import lombok.AccessLevel;
- import lombok.Getter;
- import lombok.experimental.FieldDefaults;
- import lombok.experimental.NonFinal;
- import java.awt.GridBagLayout;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Collections;
- import java.util.LinkedHashSet;
- import java.util.List;
- import java.util.Map;
- import java.util.TreeMap;
- import javax.swing.JScrollPane;
- import java.awt.GridBagConstraints;
- @SuppressWarnings("serial")
- @FieldDefaults(level=AccessLevel.PUBLIC, makeFinal=true)
- class LevelUpSpellPanel extends JPanel {
- public static interface SpellPicker {
- public List<List<Integer>> getSpellCounts(SelectSpellsPanel.Info info);
- public Collection<DDSpell> getAvailableSpells(SelectSpellsPanel.Info info, int i);
- }
- public static enum SpellPickType implements SpellPicker {
- LEARN {
- @Override
- public List<List<Integer>> getSpellCounts(SelectSpellsPanel.Info info) {
- return info.dclass.getProto().getSpells().get().getKnown();
- }
- @Override
- public Collection<DDSpell> getAvailableSpells(Info info, int i) {
- Collection<DDSpell> spells = new ArrayList<>(info.dclass.getProto().getSpellList(i));
- spells.removeAll(info.dclass.getSpellBook().get().spellsKnownAtLevel(i));
- return spells;
- }
- }, PREPARE {
- @Override
- public List<List<Integer>> getSpellCounts(SelectSpellsPanel.Info info) {
- // TODO: Bonus spells for high ability scores
- return info.dclass.getProto().getSpells().get().getPerDay();
- }
- @Override
- public Collection<DDSpell> getAvailableSpells(Info info, int i) {
- return info.dclass.getSpellBook().get().spellsKnownAtLevel(i);
- }
- };
- }
- int[] ready = {0};
- @NonFinal int spellLevelsGrown = 0;
- int oldHighestSpellLevel, newHighestSpellLevel, toLevel;
- SpellPicker pick;
- SelectSpellsPanel.Info info;
- @Getter List<SelectSpellsPanel> panels;
- ObservableListener<LevelUpSpellPanel, BoolGate> allReady;
- public LevelUpSpellPanel(SpellPicker pick, SelectSpellsPanel.Info info,
- BoolGate.Handle readyCount) {
- this.pick = pick;
- this.info = info;
- this.toLevel = info.dclass.getLevel().value();
- newHighestSpellLevel = info.dclass.getHighestSpellLevel(toLevel);
- oldHighestSpellLevel = info.dclass.getHighestSpellLevel(toLevel-1);
- GridBagLayout gridBagLayout = new GridBagLayout();
- gridBagLayout.columnWidths = new int[]{0, 0};
- gridBagLayout.rowHeights = new int[]{0, 0};
- gridBagLayout.columnWeights = new double[]{1.0, Double.MIN_VALUE};
- gridBagLayout.rowWeights = new double[]{1.0, Double.MIN_VALUE};
- setLayout(gridBagLayout);
- JScrollPane scrollPane = new JScrollPane();
- GridBagConstraints gbc_scrollPane = new GridBagConstraints();
- gbc_scrollPane.fill = GridBagConstraints.BOTH;
- gbc_scrollPane.gridx = 0;
- gbc_scrollPane.gridy = 0;
- add(scrollPane, gbc_scrollPane);
- JPanel panel = new JPanel(new VerticalLayout(5));
- scrollPane.setViewportView(panel);
- panels = new ArrayList<>();
- final IntValue val = getSharedAllowedSlots(info);
- final Map<Integer, Integer> spells = getNewSpells(val);
- final int sharedSlots = val.value();
- BoolGate gate = new BoolGate(newHighestSpellLevel);
- for (int i = 0; i < newHighestSpellLevel; ++i) {
- if (spells.get(i) < 0) { gate.set(i, true); panels.add(null); continue; }
- ++spellLevelsGrown;
- SelectSpellsPanel lvl = new SelectSpellsPanel(info, gate.handle(i), i,
- new LinkedHashSet<>(), Math.max(spells.get(i), sharedSlots),
- pick.getAvailableSpells(info, i),
- pick != SpellPickType.LEARN, val);
- panels.add(lvl);
- panel.add(lvl);
- }
- allReady = new ObservableListener<>(this, (c, v) -> {
- readyCount.set(this, v.all());
- });
- allReady.setObserved(gate);
- }
-
- private Map<Integer, Integer> getNewSpells(IntValue sharedSpellCountLimit) {
- final Map<Integer, Integer> map = new TreeMap<>();
- final List<List<Integer>> spellList = pick.getSpellCounts(info);
- final List<Integer> spellsAtPreviousLevel = toLevel == 1 ? Collections.emptyList() :
- spellList.get(toLevel-2);
- final List<Integer> spellsAtCurrentLevel = spellList.get(toLevel-1);
- for (int i = 0; i < newHighestSpellLevel; ++i) {
- map.put(i, diff(spellsAtCurrentLevel, spellsAtPreviousLevel, i,
- isNewSpellCircle(i)));
- }
- if (!map.isEmpty()) sharedSpellCountLimit.value(-1);
- return map;
- }
- private IntValue getSharedAllowedSlots(Info info) {
- return info.dclass.getSpellBook().get().getSharedAllowedSlots();
- }
- private boolean isNewSpellCircle(int i) {
- return i == (newHighestSpellLevel - 1) && oldHighestSpellLevel != newHighestSpellLevel;
- }
- private int diff(List<Integer> current, List<Integer> previous, int level, boolean newSpellLevel) {
- if (current.size() <= level) return 0;
- else if (newSpellLevel || previous.size() <= level) return current.get(level);
- else return current.get(level) - previous.get(level);
- }
- @Override
- public void removeNotify() {
- ObserverDispatch.unsubscribeAll(allReady);
- }
- }
|