ソースを参照

Fix item sale and purchase:
- Use actualValue instead of base value
- Can't sell off equipped item
- Signal sell option when count changes (purchase)
- Bind purchase to DDInventory::getWealth
Fix signal for selling last item
Make money observable
Add current liquid wealth to the player's Inventory tab

Sam Jaffe 8 年 前
コミット
76e19631ce

+ 5 - 2
src/main/lombok/org/leumasjaffe/charsheet/model/inventory/Money.java

@@ -1,14 +1,17 @@
 package org.leumasjaffe.charsheet.model.inventory;
 
+import org.leumasjaffe.observer.Observable;
+
 import lombok.AccessLevel;
 import lombok.AllArgsConstructor;
 import lombok.Data;
+import lombok.EqualsAndHashCode;
 import lombok.experimental.FieldDefaults;
 
 @AllArgsConstructor
-@Data
+@Data @EqualsAndHashCode(callSuper=false)
 @FieldDefaults(level=AccessLevel.PRIVATE)
-public class Money implements Comparable<Money> {
+public class Money extends Observable implements Comparable<Money> {
 	int pp, gp, sp, cp;
 	
 	public Money assign(final Money other) {

+ 158 - 5
src/main/lombok/org/leumasjaffe/charsheet/view/inventory/InventoryPanel.java

@@ -10,6 +10,7 @@ import javax.swing.border.MatteBorder;
 import org.jdesktop.swingx.VerticalLayout;
 import org.leumasjaffe.charsheet.model.DDCharacter;
 import org.leumasjaffe.charsheet.model.inventory.DDInventory;
+import org.leumasjaffe.charsheet.model.inventory.Money;
 import org.leumasjaffe.observer.ObservableListener;
 import org.leumasjaffe.observer.ObserverDispatch;
 
@@ -20,6 +21,10 @@ import java.awt.Color;
 import java.awt.Font;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.Dimension;
+
+import javax.swing.JTextField;
 
 @FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
 public class InventoryPanel extends JPanel {
@@ -29,21 +34,160 @@ public class InventoryPanel extends JPanel {
 	private static final long serialVersionUID = 1L;
 	JComponent inventory;
 	ObservableListener<InventoryPanel, DDInventory> inventoryObserver;
+	ObservableListener<JTextField, Money> moneyObserver;
+	private JTextField txtPp;
+	private JTextField txtGp;
+	private JTextField txtSp;
+	private JTextField txtCp;
 	
 	public InventoryPanel() {
 		GridBagLayout gridBagLayout = new GridBagLayout();
 		gridBagLayout.columnWidths = new int[]{0};
-		gridBagLayout.rowHeights = new int[]{0};
-		gridBagLayout.columnWeights = new double[]{Double.MIN_VALUE};
-		gridBagLayout.rowWeights = new double[]{Double.MIN_VALUE};
+		gridBagLayout.rowHeights = new int[]{0, 0};
+		gridBagLayout.columnWeights = new double[]{1.0};
+		gridBagLayout.rowWeights = new double[]{0.0, Double.MIN_VALUE};
 		setLayout(gridBagLayout);
 		
+		JPanel panel = new JPanel();
+		panel.setPreferredSize(new Dimension(280, 30));
+		GridBagConstraints gbc_panel = new GridBagConstraints();
+		gbc_panel.insets = new Insets(0, 0, 5, 0);
+		gbc_panel.fill = GridBagConstraints.BOTH;
+		gbc_panel.gridx = 0;
+		gbc_panel.gridy = 0;
+		add(panel, gbc_panel);
+		GridBagLayout gbl_panel = new GridBagLayout();
+		gbl_panel.columnWidths = new int[]{100, 0, 0};
+		gbl_panel.rowHeights = new int[]{0, 0};
+		gbl_panel.columnWeights = new double[]{0.0, 1.0, Double.MIN_VALUE};
+		gbl_panel.rowWeights = new double[]{1.0, Double.MIN_VALUE};
+		panel.setLayout(gbl_panel);
+		
+		JLabel lblMoney = new JLabel("Money");
+		lblMoney.setOpaque(true);
+		lblMoney.setHorizontalAlignment(SwingConstants.CENTER);
+		lblMoney.setForeground(Color.WHITE);
+		lblMoney.setFont(new Font("Tahoma", Font.BOLD, 20));
+		lblMoney.setBorder(new MatteBorder(0, 0, 1, 0, (Color) Color.WHITE));
+		lblMoney.setBackground(Color.BLACK);
+		GridBagConstraints gbc_lblMoney = new GridBagConstraints();
+		gbc_lblMoney.fill = GridBagConstraints.BOTH;
+		gbc_lblMoney.insets = new Insets(0, 0, 0, 1);
+		gbc_lblMoney.gridx = 0;
+		gbc_lblMoney.gridy = 0;
+		panel.add(lblMoney, gbc_lblMoney);
+		
+		JPanel panel_1 = new JPanel();
+		GridBagConstraints gbc_panel_1 = new GridBagConstraints();
+		gbc_panel_1.fill = GridBagConstraints.BOTH;
+		gbc_panel_1.insets = new Insets(0, 0, 1, 0);
+		gbc_panel_1.gridx = 1;
+		gbc_panel_1.gridy = 0;
+		panel.add(panel_1, gbc_panel_1);
+		GridBagLayout gbl_panel_1 = new GridBagLayout();
+		gbl_panel_1.columnWidths = new int[]{0, 0, 0, 0, 0};
+		gbl_panel_1.rowHeights = new int[]{0};
+		gbl_panel_1.columnWeights = new double[]{1.0, 1.0, 1.0, 1.0, Double.MIN_VALUE};
+		gbl_panel_1.rowWeights = new double[]{Double.MIN_VALUE};
+		panel_1.setLayout(gbl_panel_1);
+		
+		JLabel lblPp = new JLabel("pp");
+		GridBagConstraints gbc_lblPp = new GridBagConstraints();
+		gbc_lblPp.fill = GridBagConstraints.HORIZONTAL;
+		gbc_lblPp.insets = new Insets(0, 0, 0, 1);
+		gbc_lblPp.gridx = 0;
+		gbc_lblPp.gridy = 0;
+		panel_1.add(lblPp, gbc_lblPp);
+		lblPp.setOpaque(true);
+		lblPp.setHorizontalAlignment(SwingConstants.CENTER);
+		lblPp.setForeground(Color.WHITE);
+		lblPp.setFont(new Font("Tahoma", Font.BOLD, 8));
+		lblPp.setBackground(Color.BLACK);
+		
+		JLabel lblGp = new JLabel("gp");
+		GridBagConstraints gbc_lblGp = new GridBagConstraints();
+		gbc_lblGp.fill = GridBagConstraints.HORIZONTAL;
+		gbc_lblGp.insets = new Insets(0, 0, 0, 1);
+		gbc_lblGp.gridx = 1;
+		gbc_lblGp.gridy = 0;
+		panel_1.add(lblGp, gbc_lblGp);
+		lblGp.setOpaque(true);
+		lblGp.setHorizontalAlignment(SwingConstants.CENTER);
+		lblGp.setForeground(Color.WHITE);
+		lblGp.setFont(new Font("Tahoma", Font.BOLD, 8));
+		lblGp.setBackground(Color.BLACK);
+		
+		JLabel lblSp = new JLabel("sp");
+		GridBagConstraints gbc_lblSp = new GridBagConstraints();
+		gbc_lblSp.fill = GridBagConstraints.HORIZONTAL;
+		gbc_lblSp.insets = new Insets(0, 0, 0, 1);
+		gbc_lblSp.gridx = 2;
+		gbc_lblSp.gridy = 0;
+		panel_1.add(lblSp, gbc_lblSp);
+		lblSp.setOpaque(true);
+		lblSp.setHorizontalAlignment(SwingConstants.CENTER);
+		lblSp.setForeground(Color.WHITE);
+		lblSp.setFont(new Font("Tahoma", Font.BOLD, 8));
+		lblSp.setBackground(Color.BLACK);
+		
+		JLabel lblCp = new JLabel("cp");
+		GridBagConstraints gbc_lblCp = new GridBagConstraints();
+		gbc_lblCp.insets = new Insets(0, 0, 0, 1);
+		gbc_lblCp.fill = GridBagConstraints.HORIZONTAL;
+		gbc_lblCp.gridx = 3;
+		gbc_lblCp.gridy = 0;
+		panel_1.add(lblCp, gbc_lblCp);
+		lblCp.setOpaque(true);
+		lblCp.setHorizontalAlignment(SwingConstants.CENTER);
+		lblCp.setForeground(Color.WHITE);
+		lblCp.setFont(new Font("Tahoma", Font.BOLD, 8));
+		lblCp.setBackground(Color.BLACK);
+		
+		txtPp = new JTextField();
+		GridBagConstraints gbc_txtPP = new GridBagConstraints();
+		gbc_txtPP.fill = GridBagConstraints.HORIZONTAL;
+		gbc_txtPP.insets = new Insets(0, 0, 0, 0);
+		gbc_txtPP.gridx = 0;
+		gbc_txtPP.gridy = 1;
+		panel_1.add(txtPp, gbc_txtPP);
+		txtPp.setEditable(false);
+		txtPp.setColumns(5);
+		
+		txtGp = new JTextField();
+		GridBagConstraints gbc_txtGP = new GridBagConstraints();
+		gbc_txtGP.fill = GridBagConstraints.HORIZONTAL;
+		gbc_txtGP.insets = new Insets(0, 0, 0, 0);
+		gbc_txtGP.gridx = 1;
+		gbc_txtGP.gridy = 1;
+		panel_1.add(txtGp, gbc_txtGP);
+		txtGp.setEditable(false);
+		txtGp.setColumns(5);
+		
+		txtSp = new JTextField();
+		GridBagConstraints gbc_txtSP = new GridBagConstraints();
+		gbc_txtSP.fill = GridBagConstraints.HORIZONTAL;
+		gbc_txtSP.insets = new Insets(0, 0, 0, 0);
+		gbc_txtSP.gridx = 2;
+		gbc_txtSP.gridy = 1;
+		panel_1.add(txtSp, gbc_txtSP);
+		txtSp.setEditable(false);
+		txtSp.setColumns(5);
+		
+		txtCp = new JTextField();
+		GridBagConstraints gbc_txtCP = new GridBagConstraints();
+		gbc_txtCP.fill = GridBagConstraints.HORIZONTAL;
+		gbc_txtCP.gridx = 3;
+		gbc_txtCP.gridy = 1;
+		panel_1.add(txtCp, gbc_txtCP);
+		txtCp.setEditable(false);
+		txtCp.setColumns(5);
+		
 		JScrollPane scrollPane = new JScrollPane();
 		scrollPane.setOpaque(false);
 		GridBagConstraints gbc_scrollPane_1 = new GridBagConstraints();
 		gbc_scrollPane_1.fill = GridBagConstraints.BOTH;
 		gbc_scrollPane_1.gridx = 0;
-		gbc_scrollPane_1.gridy = 0;
+		gbc_scrollPane_1.gridy = 1;
 		add(scrollPane, gbc_scrollPane_1);
 		
 		JLabel lblInventory = new JLabel("Inventory");
@@ -60,8 +204,16 @@ public class InventoryPanel extends JPanel {
 		scrollPane.setViewportView(inventory);
 		inventory.setLayout(new VerticalLayout(5));
 		
-		inventoryObserver = new ObservableListener<>(this, 
+		inventoryObserver = new ObservableListener<>(this,
 				(self, inv) -> self.updateModel(inv) );
+		
+		moneyObserver = new ObservableListener<>(txtPp, 
+				($, money) -> {
+					txtPp.setText("" + money.getPp());
+					txtGp.setText("" + money.getGp());
+					txtSp.setText("" + money.getSp());
+					txtCp.setText("" + money.getCp());
+				});
 	}
 
 	private void updateModel(DDInventory inv) {
@@ -71,6 +223,7 @@ public class InventoryPanel extends JPanel {
 
 	public void setModel(DDCharacter model) {
 		inventoryObserver.setObserved(model.getInventory());
+		moneyObserver.setObserved(model.getInventory().getWealth());
 	}
 	
 	@Override

+ 10 - 7
src/main/lombok/org/leumasjaffe/charsheet/view/inventory/ItemInfoMenu.java

@@ -28,10 +28,10 @@ class ItemInfoMenu extends JPopupMenu {
 	private static final long serialVersionUID = 1L;
 	
 	IndirectObservableListener<JMenuItem, IntValue> sellListener, equipListener = null;
-	ObservableListener<JMenuItem, DDInventory> buyListener;
+	ObservableListener<JMenuItem, Money> buyListener;
 
 	public ItemInfoMenu(final DDInventory inv, final DDItem item) {
-		final int rawValue = item.getValue().asCopper();
+		final int rawValue = item.getActualValue().asCopper();
 		final BuySellAction doTxn = new BuySellAction(inv, item);
 		final BuySellDialogHelper dlg = new BuySellDialogHelper(item.getFullName());
 
@@ -46,22 +46,24 @@ class ItemInfoMenu extends JPopupMenu {
 
 		JMenuItem mntmBuy = new JMenuItem("Purchase");
 		mntmBuy.addActionListener(e -> {
-			doTxn.applyTransaction(dlg.getNumUnits("Purchase", rawValue, inv.getWealth().asCopper() / rawValue), rawValue);
+			doTxn.applyTransaction(dlg.getNumUnits("Purchase", rawValue, rawValue == 0 ? 100 : 
+				inv.getWealth().asCopper() / rawValue), rawValue);
 		});
 		buyListener = new ObservableListener<>(mntmBuy, (c, v) -> {
-			c.setEnabled(inv.getWealth().asCopper() >= item.getValue().asCopper());
+			c.setEnabled(v.asCopper() >= item.getActualValue().asCopper());
 		});
-		buyListener.setObserved(inv);
+		buyListener.setObserved(inv.getWealth());
 		add(mntmBuy);
 
 		JMenuItem mntmSell = new JMenuItem("Sell");	
 		mntmSell.addActionListener(e -> {
-			doTxn.applyTransaction(-dlg.getNumUnits("Sell", rawValue / 2, item.getCount().value()), rawValue / 2);
+			doTxn.applyTransaction(-dlg.getNumUnits("Sell", rawValue / 2, 
+					item.getCount().value() - item.getCountEquipped().value()), rawValue / 2);
 		});
 		sellListener = new IndirectObservableListener<>(mntmSell, (c, v) -> {
 			c.setEnabled(item.getUnequippedCount() > 0);
 		});
-		sellListener.setObserved(item.getCount(), item.getCountEquipped());
+		sellListener.setObserved(item.getCount(), item.getCount(), item.getCountEquipped());
 		add(mntmSell);
 
 		if (item.getSlot() != EquipmentSlot.NONE) {
@@ -109,6 +111,7 @@ class ItemInfoMenu extends JPopupMenu {
 			final Money wealth = inv.getWealth();
 			wealth.assign(wealth.difference(Money.fromCopper(selected * txnPrice)));
 			ObserverDispatch.notifySubscribers(item.getCount(), null);
+			ObserverDispatch.notifySubscribers(wealth, null);
 		}
 	}
 }

+ 1 - 1
src/main/lombok/org/leumasjaffe/charsheet/view/inventory/ItemPanel.java

@@ -152,7 +152,7 @@ public class ItemPanel extends JPanel {
 				comp.repaint();
 			}
 		});
-		countListener.setObserved(item.getCount(), item.getCountEquipped());
+		countListener.setObserved(item.getCount(), item.getCount(), item.getCountEquipped());
 		addMouseListener(new PopClickListener(new ItemInfoMenu(inv, item)));
 	}