From e12c6bcc259a7858f29f84e76fb97b500a6e2f14 Mon Sep 17 00:00:00 2001 From: Zukero Date: Wed, 24 Apr 2019 00:45:57 +0200 Subject: [PATCH] Overhaul of the droplist's drop chance editor, planning to use it for the random requirement type' chance too. --- .../model/gamedata/Droplist.java | 8 +- .../rpg/atcontentstudio/ui/AboutEditor.java | 8 +- .../gpl/rpg/atcontentstudio/ui/Editor.java | 132 ++++++++++++++++++ .../ui/gamedataeditors/DroplistEditor.java | 10 +- 4 files changed, 147 insertions(+), 11 deletions(-) diff --git a/src/com/gpl/rpg/atcontentstudio/model/gamedata/Droplist.java b/src/com/gpl/rpg/atcontentstudio/model/gamedata/Droplist.java index 2059cbc..b83dea5 100644 --- a/src/com/gpl/rpg/atcontentstudio/model/gamedata/Droplist.java +++ b/src/com/gpl/rpg/atcontentstudio/model/gamedata/Droplist.java @@ -36,7 +36,7 @@ public class Droplist extends JSONElement { public static class DroppedItem { //Available from parsed state; public String item_id = null; - public Double chance = null; + public String chance = null; public Integer quantity_min = null; public Integer quantity_max = null; @@ -114,7 +114,8 @@ public class Droplist extends JSONElement { Map droppedItemJson = (Map)droppedItemJsonObj; DroppedItem droppedItem = new DroppedItem(); droppedItem.item_id = (String) droppedItemJson.get("itemID"); - if (droppedItemJson.get("chance") != null) droppedItem.chance = JSONElement.parseChance(droppedItemJson.get("chance").toString()); + //if (droppedItemJson.get("chance") != null) droppedItem.chance = JSONElement.parseChance(droppedItemJson.get("chance").toString()); + droppedItem.chance = (String) droppedItemJson.get("chance"); Map droppedItemQtyJson = (Map) droppedItemJson.get("quantity"); if (droppedItemQtyJson != null) { droppedItem.quantity_min = JSONElement.getInteger((Number) droppedItemQtyJson.get("min")); @@ -217,7 +218,8 @@ public class Droplist extends JSONElement { } else if (droppedItem.item_id != null) { droppedItemJson.put("itemID", droppedItem.item_id); } - if (droppedItem.chance != null) droppedItemJson.put("chance", JSONElement.printJsonChance(droppedItem.chance)); + //if (droppedItem.chance != null) droppedItemJson.put("chance", JSONElement.printJsonChance(droppedItem.chance)); + if (droppedItem.chance != null) droppedItemJson.put("chance", droppedItem.chance); if (droppedItem.quantity_min != null || droppedItem.quantity_max != null) { Map quantityJson = new LinkedHashMap(); droppedItemJson.put("quantity", quantityJson); diff --git a/src/com/gpl/rpg/atcontentstudio/ui/AboutEditor.java b/src/com/gpl/rpg/atcontentstudio/ui/AboutEditor.java index ab6de8d..de1ced3 100644 --- a/src/com/gpl/rpg/atcontentstudio/ui/AboutEditor.java +++ b/src/com/gpl/rpg/atcontentstudio/ui/AboutEditor.java @@ -26,7 +26,9 @@ public class AboutEditor extends Editor { private static final long serialVersionUID = 6230549148222457139L; public static final String WELCOME_STRING = - "" + + "" + + "" + + "" + "" + "" + "
Welcome to "+ATContentStudio.APP_NAME+" "+ATContentStudio.APP_VERSION+"
" + @@ -51,7 +53,7 @@ public class AboutEditor extends Editor { "
" + "Contributors:
" + "Quentin Delvallet
" + - "Žižkin
" + + "Žižkin
" + "
" + "This project uses the following libraries:
" + "JSON.simple by Yidong Fang & Chris Nokleberg.
" + @@ -79,7 +81,7 @@ public class AboutEditor extends Editor { "jsoup by Jonathan Hedley
" + "License: MIT License
" + "
" + - "A slightly modified version of General PO Parser by Balázs Tóth
" + + "A slightly modified version of General PO Parser by Bal�zs T�th
" + "License: GPL v3
" + "
" + "A slightly modified version of Minify.java by Charles Bihis
" + diff --git a/src/com/gpl/rpg/atcontentstudio/ui/Editor.java b/src/com/gpl/rpg/atcontentstudio/ui/Editor.java index edb5912..093dd93 100644 --- a/src/com/gpl/rpg/atcontentstudio/ui/Editor.java +++ b/src/com/gpl/rpg/atcontentstudio/ui/Editor.java @@ -348,6 +348,138 @@ public abstract class Editor extends JPanel implements ProjectElementListener { return spinner; } + + private static final String percent = "%"; + private static final String ratio = "x/y"; + public static JComponent addChanceField(JPanel pane, String label, String initialValue, String defaultValue, boolean editable, final FieldUpdateListener listener) { + int defaultChance = 1; + int defaultMaxChance = 100; + if (defaultValue != null) { + if (defaultValue.contains("/")) { + int c = defaultValue.indexOf('/'); + try { defaultChance = Integer.parseInt(defaultValue.substring(0, c)); } catch (NumberFormatException nfe) {}; + try { defaultMaxChance = Integer.parseInt(defaultValue.substring(c+1)); } catch (NumberFormatException nfe) {}; + } else { + try { defaultChance = Integer.parseInt(defaultValue); } catch (NumberFormatException nfe) {}; + } + } + + boolean currentFormIsRatio = true; + int chance = defaultChance; + int maxChance = defaultMaxChance; + if (initialValue != null) { + if (initialValue.contains("/")) { + int c = initialValue.indexOf('/'); + try { chance = Integer.parseInt(initialValue.substring(0, c)); } catch (NumberFormatException nfe) {}; + try { maxChance = Integer.parseInt(initialValue.substring(c+1)); } catch (NumberFormatException nfe) {}; + } else { + try { + chance = Integer.parseInt(initialValue); + currentFormIsRatio = false; + } catch (NumberFormatException nfe) {}; + } + } + + final JPanel tfPane = new JPanel(); + tfPane.setLayout(new JideBoxLayout(tfPane, JideBoxLayout.LINE_AXIS, 6)); + JLabel tfLabel = new JLabel(label); + tfPane.add(tfLabel, JideBoxLayout.FIX); + + final JComboBox entryTypeBox = new JComboBox(new String[] {percent, ratio}); + if (currentFormIsRatio) { + entryTypeBox.setSelectedItem(ratio); + } else { + entryTypeBox.setSelectedItem(percent); + } + entryTypeBox.setEnabled(editable); + tfPane.add(entryTypeBox, JideBoxLayout.FIX); + /////////////////////////////////////////////////////////////////////////////////////////////////// make sure "chance" is between 1 and 100. If lower than 1 get 1. If higher than 100, get chance/maxChance * 100... Then do the same with defaultChance, in case no value exist. + final SpinnerNumberModel percentModel = new SpinnerNumberModel(initialValue != null ? ((chance > 1 ? chance : 1) < 100 ? chance : (chance * 100 / maxChance)) : ((defaultChance > 1 ? defaultChance : 1) < 100 ? defaultChance : (defaultChance * 100 / defaultMaxChance)) , 1, 100, 1); + final SpinnerNumberModel ratioChanceModel = new SpinnerNumberModel(initialValue != null ? chance : defaultChance, 1, Integer.MAX_VALUE, 1); + + final JSpinner chanceSpinner = new JSpinner(currentFormIsRatio ? ratioChanceModel : percentModel); + if (!currentFormIsRatio) ((JSpinner.DefaultEditor)chanceSpinner.getEditor()).getTextField().setHorizontalAlignment(JTextField.LEFT); + chanceSpinner.setEnabled(editable); + ((DefaultFormatter)((NumberEditor)chanceSpinner.getEditor()).getTextField().getFormatter()).setCommitsOnValidEdit(true); + tfPane.add(chanceSpinner, JideBoxLayout.FLEXIBLE); + + final JLabel ratioLabel = new JLabel("/"); + tfPane.add(ratioLabel, JideBoxLayout.FIX); + + final JSpinner maxChanceSpinner = new JSpinner(new SpinnerNumberModel(initialValue != null ? maxChance : defaultMaxChance, 1, Integer.MAX_VALUE, 1)); + ((JSpinner.DefaultEditor)maxChanceSpinner.getEditor()).getTextField().setHorizontalAlignment(JTextField.LEFT); + maxChanceSpinner.setEnabled(editable); + ((DefaultFormatter)((NumberEditor)maxChanceSpinner.getEditor()).getTextField().getFormatter()).setCommitsOnValidEdit(true); + tfPane.add(maxChanceSpinner, JideBoxLayout.FLEXIBLE); + + if (!currentFormIsRatio) { + ratioLabel.setVisible(false); + maxChanceSpinner.setVisible(false); + tfPane.revalidate(); + tfPane.repaint(); + } + + final JButton nullify = new JButton(new ImageIcon(DefaultIcons.getNullifyIcon())); + tfPane.add(nullify, JideBoxLayout.FIX); + nullify.setEnabled(editable); + pane.add(tfPane, JideBoxLayout.FIX); + + entryTypeBox.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (entryTypeBox.getSelectedItem() == percent) { + int chance = ((Integer)chanceSpinner.getValue()); + int maxChance = ((Integer)maxChanceSpinner.getValue()); + chance *= 100; + chance /= maxChance; + chance = Math.max(0, Math.min(100, chance)); + chanceSpinner.setModel(percentModel); + chanceSpinner.setValue(chance); + ((JSpinner.DefaultEditor)chanceSpinner.getEditor()).getTextField().setHorizontalAlignment(JTextField.LEFT); + ratioLabel.setVisible(false); + maxChanceSpinner.setVisible(false); + tfPane.revalidate(); + tfPane.repaint(); + listener.valueChanged(chanceSpinner, chanceSpinner.getValue().toString()); + } else if (entryTypeBox.getSelectedItem() == ratio) { + int chance = ((Integer)chanceSpinner.getValue()); + chanceSpinner.setModel(ratioChanceModel); + chanceSpinner.setValue(chance); + maxChanceSpinner.setValue(100); + ratioLabel.setVisible(true); + maxChanceSpinner.setVisible(true); + tfPane.revalidate(); + tfPane.repaint(); + listener.valueChanged(chanceSpinner, chanceSpinner.getValue().toString() + "/" + maxChanceSpinner.getValue().toString()); + } + } + }); + chanceSpinner.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + if (entryTypeBox.getSelectedItem() == percent) { + listener.valueChanged(chanceSpinner, chanceSpinner.getValue().toString()); + } else if (entryTypeBox.getSelectedItem() == ratio) { + listener.valueChanged(chanceSpinner, chanceSpinner.getValue().toString() + "/" + maxChanceSpinner.getValue().toString()); + } + } + }); + maxChanceSpinner.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + listener.valueChanged(chanceSpinner, chanceSpinner.getValue().toString() + "/" + maxChanceSpinner.getValue().toString()); + } + }); + nullify.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + chanceSpinner.setValue(1); + listener.valueChanged(chanceSpinner, null); + } + }); + return chanceSpinner; + } + // public static JSpinner addDoubleField(JPanel pane, String label, Double initialValue, boolean editable) { // return addDoubleField(pane, label, initialValue, editable, nullListener); // } diff --git a/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/DroplistEditor.java b/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/DroplistEditor.java index e9d3c08..71b87fb 100644 --- a/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/DroplistEditor.java +++ b/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/DroplistEditor.java @@ -50,7 +50,7 @@ public class DroplistEditor extends JSONElementEditor { private DroppedItemsListModel droppedItemsListModel; private JSpinner qtyMinField; private JSpinner qtyMaxField; - private JSpinner chanceField; + private JComponent chanceField; public DroplistEditor(Droplist droplist) { super(droplist, droplist.getDesc(), droplist.getIcon()); @@ -142,7 +142,7 @@ public class DroplistEditor extends JSONElementEditor { itemCombo = addItemBox(pane, proj, "Item: ", di.item, writable, listener); qtyMinField = addIntegerField(pane, "Quantity min: ", di.quantity_min, false, writable, listener); qtyMaxField = addIntegerField(pane, "Quantity max: ", di.quantity_max, false, writable, listener); - chanceField = addDoubleField(pane, "Chance: ", di.chance, writable, listener); + chanceField = addChanceField(pane, "Chance: ", di.chance, "100", writable, listener);//addDoubleField(pane, "Chance: ", di.chance, writable, listener); } pane.revalidate(); pane.repaint(); @@ -221,9 +221,9 @@ public class DroplistEditor extends JSONElementEditor { Droplist.DroppedItem di = (Droplist.DroppedItem)value; if (di.item != null) { label.setIcon(new ImageIcon(di.item.getIcon())); - label.setText(di.chance+"% to get "+di.quantity_min+"-"+di.quantity_max+" "+di.item.getDesc()); + label.setText(di.chance+(di.chance.contains("/") ? "" : "%")+" to get "+di.quantity_min+"-"+di.quantity_max+" "+di.item.getDesc()); } else if (!isNull(di)) { - label.setText(di.chance+"% to get "+di.quantity_min+"-"+di.quantity_max+" "+di.item_id); + label.setText(di.chance+(di.chance.contains("/") ? "" : "%")+" to get "+di.quantity_min+"-"+di.quantity_max+" "+di.item_id); } else { label.setText("New, undefined, dropped item."); } @@ -283,7 +283,7 @@ public class DroplistEditor extends JSONElementEditor { selectedItem.quantity_max = (Integer) value; droppedItemsListModel.itemChanged(selectedItem); } else if (source == chanceField) { - selectedItem.chance = (Double) value; + selectedItem.chance = (String) value; droppedItemsListModel.itemChanged(selectedItem); }