diff --git a/Controller/ArrayField.java b/Controller/ArrayField.java
index b96d58f..eb3f10b 100644
--- a/Controller/ArrayField.java
+++ b/Controller/ArrayField.java
@@ -7,6 +7,8 @@
*/
public enum ArrayField {
// ITEM
+ weaponID1, weaponID2, weaponInventorySlot, weaponGem1Value, weaponGem2Value, weaponGem3Value, weaponGem1Index, weaponGem2Index, weaponGem3Index, weaponNumGemSlots, // weapons
+
// gemID1 -> gemID for name, gemID2 -> gemID for description
gemID1, gemUnk1, gemInventorySlot, gemUnk2, gemValue, gemRank, gemUnk3, gemID2, // gems
diff --git a/Controller/SaveField.java b/Controller/SaveField.java
index 9c91793..42d1dcf 100644
--- a/Controller/SaveField.java
+++ b/Controller/SaveField.java
@@ -39,6 +39,7 @@ public enum SaveField {
// ITEM
money,
+ weaponArray,
gemArray,
// WTHR
diff --git a/Controller/SaveFileController.java b/Controller/SaveFileController.java
index a2e2237..2f3e3b5 100644
--- a/Controller/SaveFileController.java
+++ b/Controller/SaveFileController.java
@@ -55,7 +55,6 @@ public void viewEventOccurred(ViewEvent e) {
loadArrayValue(e.getSaveField(), e.getIndex(), e.getArrayField());
this.gettingArrayData = false;
break;
- // TODO: may be able to combine SET_DATA and SET_ARRAY_DATA
case SET_DATA: // sends value of field in gui to save in model
SaveField saveField = e.getSaveField();
Data data = (Data) SaveFile.DataMap.get(saveField);
@@ -97,13 +96,14 @@ public void viewEventOccurred(ViewEvent e) {
try {
saveFile.setData(data, convertedValue);
+ if (arrName == SaveField.weaponArray) handleWeaponTable(colName, index, value);
} catch (IllegalArgumentException e1) {
e1.printStackTrace();
}
catch (NullPointerException e2) {
System.out.print("Reloading saved value: ");
}
-
+
// Determine whether to set/clear StaticElements
boolean isIndexNull = saveFile.isArrayIndexNull(arr, index);
if (isIndexNull) { // clear StaticElements
@@ -119,6 +119,71 @@ public void viewEventOccurred(ViewEvent e) {
viewEventOccurred(new ViewEvent(this, ViewEvent.EventType.GET_ARRAY_DATA, null, arrName, colName, index, null));
break;
+ case SET_COPY_ARRAY_DATA:
+ // copy origin -> dest, and reload dest to show in View
+ SaveField originArrName = e.getSaveField(), destArrName = e.getDestSaveField();
+ Array originArr = (Array) SaveFile.DataMap.get(originArrName), destArr = (Array) SaveFile.DataMap.get(destArrName);;
+ ArrayField originCol = e.getArrayField(), destCol = e.getDestArrayField();
+ int originIndex = e.getIndex(), destIndex = e.getDestIndex();
+
+ // Get Data obj for both arrays
+ Data originData = originArr.get(originIndex, originCol);
+ Data destData = destArr.get(destIndex, destCol);
+
+ saveFile.copyBytes(originData, destData);
+
+ // reload destination element to show in View
+ viewEventOccurred(new ViewEvent(this, ViewEvent.EventType.GET_ARRAY_DATA, null, destArrName, destCol, destIndex, null));
+
+ break;
+ }
+ }
+
+ // Handles the quirky behavior of the weapon table, from the side affect of hiding weaponGemxValue from View
+ private void handleWeaponTable(ArrayField colName, int index, String value) throws NumberFormatException {
+ switch (colName) {
+ // When weaponGemIndex updates -> update weaponGemValue to gem at new index
+ case weaponGem1Index:
+ if (Integer.parseInt(value) < gui.ITEMPanel.getGemTableNumRows()) viewEventOccurred(new ViewEvent(this, SaveField.gemArray, ArrayField.gemUnk2, Integer.parseInt(value), SaveField.weaponArray, ArrayField.weaponGem1Value, index));
+ else viewEventOccurred(new ViewEvent(this, ViewEvent.EventType.SET_ARRAY_DATA, null, SaveField.weaponArray, ArrayField.weaponGem1Value, index, "0")); // If the index into the gemArray is out-of-bounds
+ break;
+ case weaponGem2Index:
+ if (Integer.parseInt(value) < gui.ITEMPanel.getGemTableNumRows()) viewEventOccurred(new ViewEvent(this, SaveField.gemArray, ArrayField.gemUnk2, Integer.parseInt(value), SaveField.weaponArray, ArrayField.weaponGem2Value, index));
+ else viewEventOccurred(new ViewEvent(this, ViewEvent.EventType.SET_ARRAY_DATA, null, SaveField.weaponArray, ArrayField.weaponGem2Value, index, "0")); // If the index into the gemArray is out-of-bounds
+ break;
+ case weaponGem3Index:
+ if (Integer.parseInt(value) < gui.ITEMPanel.getGemTableNumRows()) viewEventOccurred(new ViewEvent(this, SaveField.gemArray, ArrayField.gemUnk2, Integer.parseInt(value), SaveField.weaponArray, ArrayField.weaponGem3Value, index));
+ else viewEventOccurred(new ViewEvent(this, ViewEvent.EventType.SET_ARRAY_DATA, null, SaveField.weaponArray, ArrayField.weaponGem3Value, index, "0")); // If the index into the gemArray is out-of-bounds
+ break;
+
+ // When gemUnk2/gemValue/gemRank/gemUnk3/gemID2 updates -> if any weapons have the same index, update weaponGemValue
+ case gemUnk2:
+ case gemValue:
+ case gemRank:
+ case gemUnk3:
+ case gemID2:
+ for (int i = 0; i < gui.ITEMPanel.getWeaponTableNumRows(); i++) {
+ if (saveFile.isArrayIndexNull(SaveField.weaponArray, i)) continue; // ignore null weapon rows
+
+ int gemIndexFromWeapon = (int) saveFile.getArrayAt(SaveField.weaponArray, i, ArrayField.weaponGem1Index);
+ if (gemIndexFromWeapon == index) viewEventOccurred(new ViewEvent(this, SaveField.gemArray, ArrayField.gemUnk2, index, SaveField.weaponArray, ArrayField.weaponGem1Value, i));
+
+ gemIndexFromWeapon = (int) saveFile.getArrayAt(SaveField.weaponArray, i, ArrayField.weaponGem2Index);
+ if (gemIndexFromWeapon == index) viewEventOccurred(new ViewEvent(this, SaveField.gemArray, ArrayField.gemUnk2, index, SaveField.weaponArray, ArrayField.weaponGem2Value, i));
+
+ gemIndexFromWeapon = (int) saveFile.getArrayAt(SaveField.weaponArray, i, ArrayField.weaponGem3Index);
+ if (gemIndexFromWeapon == index) viewEventOccurred(new ViewEvent(this, SaveField.gemArray, ArrayField.gemUnk2, index, SaveField.weaponArray, ArrayField.weaponGem3Value, i));
+ }
+ break;
+
+ default:
+ }
+
+ // Make index of weaponArray fully 'null' if all visible fields are 0
+ if (saveFile.isArrayIndexNullPartial(SaveField.weaponArray, index, new ArrayField[] {ArrayField.weaponGem1Value, ArrayField.weaponGem2Value, ArrayField.weaponGem3Value})) {
+ saveFile.setArrayData(SaveField.weaponArray, index, ArrayField.weaponGem1Value, 0);
+ saveFile.setArrayData(SaveField.weaponArray, index, ArrayField.weaponGem2Value, 0);
+ saveFile.setArrayData(SaveField.weaponArray, index, ArrayField.weaponGem3Value, 0);
}
}
diff --git a/Model/Array.java b/Model/Array.java
index dbe2e3e..18cbc88 100644
--- a/Model/Array.java
+++ b/Model/Array.java
@@ -94,9 +94,10 @@ private int getColNameIndex(ArrayField name) {
* Gets a Data
object for the nth index and the specified column index
* @param n the index in the Array
* @param colIndex the column index in the Array
- * @return a Data
object at the specified location
+ * @return a Data
object at the specified location; null if n is out of bounds
*/
public Data get(int n, int colIndex) {
+ if (n >= this.numEntries) return null;
int start = this.start + (entrySize*n);
// calculate number of bits from start of index to colIndex
diff --git a/Model/SaveFile.java b/Model/SaveFile.java
index 323535c..d5a641d 100644
--- a/Model/SaveFile.java
+++ b/Model/SaveFile.java
@@ -4,6 +4,8 @@
import java.io.FileOutputStream;
import java.nio.ByteBuffer;
import java.util.HashMap;
+import java.util.Set;
+
import com.google.common.collect.HashBiMap;
import Controller.ArrayField;
@@ -118,6 +120,27 @@ public class SaveFile {
// ITEM
put(SaveField.money, new Data(0x24048, 0x2404C, DataType.Int));
+ put(SaveField.weaponArray, new Array(0x1C4EC, 0x1E364, new Element[] {
+ new Element(ArrayField.weaponID1, 12, DataType.Int),
+ new StaticElement(4, 2),
+ new Element(ArrayField.weaponID2, 11, DataType.Int),
+ new StaticElement(5, 0),
+ new StaticElement(8, 0),
+ new Element(ArrayField.weaponInventorySlot, 8, DataType.Int),
+ new StaticElement(8, 1),
+ new StaticElement(8, 0),
+ new Element(ArrayField.weaponGem1Value, 64, DataType.Int),
+ new Element(ArrayField.weaponGem2Value, 64, DataType.Int),
+ new Element(ArrayField.weaponGem3Value, 64, DataType.Int),
+ new StaticElement(64, 0),
+ new Element(ArrayField.weaponGem1Index, 16, DataType.Int),
+ new Element(ArrayField.weaponGem2Index, 16, DataType.Int),
+ new Element(ArrayField.weaponGem3Index, 16, DataType.Int),
+ new StaticElement(16, 0xFFFF),
+ new Element(ArrayField.weaponNumGemSlots, 8, DataType.Int),
+ new StaticElement(8, 6),
+ new StaticElement(16, 0),
+ }));
put(SaveField.gemArray, new Array(0x206D8, 0x21998, new Element[] {
new StaticElement(16, 0xEA33), // Item ID from ITM_itemlist that doesn't affect gem attributes (just needs to be a gem type item)
new Element(ArrayField.gemID1, 11, DataType.Int),
@@ -337,6 +360,30 @@ public boolean isArrayIndexNull(Array arr, int index) {
}
return true;
}
+ public boolean isArrayIndexNull(SaveField arr, int index) {
+ return isArrayIndexNull((Array) SaveFile.DataMap.get(arr), index);
+ }
+
+ /**
+ * Checks if the given index of an Array is all 0's, ignoring specified columns
+ * Used to determine whether to clear ArrayField's not exposed to the View
+ * @param arr Array object to check
+ * @param index the index to check
+ * @param exclude array of columns (ArrayFields) to ignore/exclude
+ * @return true if all Elements, excluding the specificed columns, of arr are 0, otherwise false
+ */
+ public boolean isArrayIndexNullPartial(Array arr, int index, ArrayField[] exclude) {
+ Set excludeSet = Set.of(exclude);
+
+ for (ArrayField internalColName : arr.getColNames()) {
+ if (excludeSet.contains(internalColName)) continue;
+ if (!this.getData(arr.get(index, internalColName)).equals(0)) return false;
+ }
+ return true;
+ }
+ public boolean isArrayIndexNullPartial(SaveField arr, int index, ArrayField[] exclude) {
+ return isArrayIndexNullPartial((Array) SaveFile.DataMap.get(arr), index, exclude);
+ }
/**
* Sets a Data
object to the specified value, throwing an exception if the specified value is not the correct type
@@ -486,6 +533,17 @@ private void setBytesAt(int x, byte[] b, byte startMask, byte endMask) {
if (b.length > 1) this.setByteAt(x+b.length-1, b[b.length-1], endMask); // set last byte, if there is more than 1 byte
}
+ /**
+ * Copies bytes from origin to destination Data objects
+ * The number of bytes copied is determined by destination size
+ * @param origin Data object to copy from, may use bytes after this object if the destination Data obj is larger in size
+ * @param dest Data object to copy to, ensured that all bytes in this object are modified
+ */
+ public void copyBytes(Data origin, Data dest) {
+ byte[] bytesToCopy = getBytesAt(origin.start, origin.start + dest.size());
+ setBytesAt(dest.start, bytesToCopy);
+ }
+
/**
* Reads from the actual file, and saves into saveFile
* Fixes any checksum errors encountered upon load
diff --git a/View/.gitignore b/View/.gitignore
index 5a07826..5811d0d 100644
--- a/View/.gitignore
+++ b/View/.gitignore
@@ -39,3 +39,4 @@
/GUI$12.class
/ViewEvent$Types.class
/ViewEvent$EventType.class
+/ITEMView$1.class
diff --git a/View/GUI.java b/View/GUI.java
index 0a57aa9..33cde27 100644
--- a/View/GUI.java
+++ b/View/GUI.java
@@ -64,7 +64,7 @@ public class GUI extends JFrame {
private TIMEView TIMEPanel;
private PCPMView PCPMPanel;
private CAMDView CAMDPanel;
- private ITEMView ITEMPanel;
+ public ITEMView ITEMPanel;
private WTHRView WTHRPanel;
//private SNDSView SNDSPanel;
private MINEView MINEPanel;
@@ -388,7 +388,7 @@ public void actionPerformed(ActionEvent e) {
});
}
- else {
+ else { // adds default JComboBox action listener
cb.addActionListener(new ActionListener() {
@@ -460,6 +460,8 @@ public void setArray(SaveField arrName, ArrayField[] columnMaps, JTable jc) {
// map column names
for (int i = 0; i < columnMaps.length; i++) {
+ if (columnMaps[i] == null) continue; // If column is not mapped to an ArrayField, continue
+
HashBiMap map;
if (columnMap.containsKey(arrName)) { // add to existing HashBiMap
map = columnMap.get(arrName);
@@ -472,17 +474,17 @@ public void setArray(SaveField arrName, ArrayField[] columnMaps, JTable jc) {
}
jc.getModel().addTableModelListener(new TableModelListener() {
-
@Override
public void tableChanged(TableModelEvent e) {
int row = e.getFirstRow();
- int col = e.getColumn();
+ int col = e.getColumn();
+
+ if (columnMaps[col] == null) return; // ignore columns not mapped to ArrayField
// column number determines the dataName, row number determines the index
- if (jc.getModel().getValueAt(row, col) == null) return;
+ if (jc.getModel().getValueAt(row, col) == null) return; // TODO: why is this here?
fireViewEvent(ViewEvent.EventType.SET_ARRAY_DATA, arrName, columnMaps[col], row, jc.getModel().getValueAt(row, col).toString());
}
-
});
}
diff --git a/View/ITEMView.java b/View/ITEMView.java
index 545b276..4180a36 100644
--- a/View/ITEMView.java
+++ b/View/ITEMView.java
@@ -20,7 +20,109 @@ public class ITEMView extends JPanel {
GUI gui;
private JTextField ITEMMoney;
- private JTable gemTable;
+ private JTable gemTable, weaponTable;
+
+ private final String[] gemNames = {
+ "None",
+ "Strength Up",
+ "Chill Defence",
+ "Sleep Resist",
+ "Slow Resist",
+ "Bind Resist",
+ "Buff Time Plus",
+ "Weapon Power",
+ "Strength Down",
+ "Blaze Plus",
+ "Blaze Attack",
+ "Spike",
+ "Revival HP Up",
+ "Initial Tension",
+ "Aggro Up",
+ "EXP Up",
+ "Weaken", // Unused
+ "HP Up",
+ "Poison Defence",
+ "Spike Defence",
+ "Paralysis Resist",
+ "Debuff Resist",
+ "Recovery Up",
+ "Aura Heal",
+ "Damage Heal",
+ "Arts Heal",
+ "HP Steal",
+ "Unbeatable",
+ "AP Up",
+ "Aquatic Cloak",
+ "Auto-Heal Up",
+ "Terrain Defence",
+ "HP Weaken", // Unused
+ "Ether Up",
+ "Double Attack",
+ "Daze Resist",
+ "Pierce Resist",
+ "Daze Plus",
+ "Phys Def Down",
+ "Paralysis",
+ "Lightning Attack",
+ "Electric Plus",
+ "Back Atk Plus",
+ "First Attack Plus",
+ "Daze Up",
+ "Cast Quicken", // Unused
+ "Tension Swing",
+ "Daze Tension",
+ "Ether Weaken", // Unused
+ "Ether Def Up",
+ "Blaze Defence",
+ "Lock-On Resist",
+ "Confuse Resist",
+ "Critical Resist", // Unused
+ "Ether Protect",
+ "Slow",
+ "Bind",
+ "Ether Def Down",
+ "Chill Plus",
+ "Chill Attack",
+ "Auto-Atk Stealth",
+ "Arts Stealth",
+ "Talent Boost",
+ "Heat Sink",
+ "Ether Smash", // Unused
+ "Agility Up",
+ "Topple Resist",
+ "Good Footing",
+ "Arts Seal Resist",
+ "Accuracy Up", // Unused
+ "Haste",
+ "Topple Plus",
+ "Bleed Attack",
+ "Bleed Plus",
+ "Topple Up",
+ "Agility Down",
+ "Break",
+ "Quick Step",
+ "Fall Defence",
+ "Aerial Cloak",
+ "Agility Weaken", // Unused
+ "Muscle Up",
+ "Attack Stability",
+ "Attack Plus",
+ "Critical Up",
+ "Bleed Defence",
+ "Divine Protect",
+ "Physical Protect",
+ "Night Vision",
+ "Debuff Plus",
+ "Armour Power", // Unused
+ "Ether Down",
+ "Poison Plus",
+ "Poison Attack",
+ "Aggro Down",
+ "Earth Cloak",
+ "Muscle Waste", // Unused
+ "Unbeatable",
+ "Impurity" // Unused
+ };
public ITEMView(GUI gui) {
this.gui = gui;
@@ -37,169 +139,140 @@ public ITEMView(GUI gui) {
ITEMMoney.setColumns(10);
gui.setTextField(SaveField.money, ITEMMoney, gui.int32);
- String[] gemColumnNames = new String[] {"Gem ID (Name)", "Gem ID (Description)", "Rank", "Value", "Inventory Slot", "Unknown 1", "Unknown 2", "Unknown 3"};
+ // weapon array
+ String[] weaponColumnNames = {"Weapon ID", "Weapon ID (Name)", "Number of Gem Slots", "Gem 1 Index", "Gem 2 Index", "Gem 3 Index", "Inventory Slot"};
+ weaponTable = new JTable();
+ weaponTable.setModel(new DefaultTableModel(weaponColumnNames, 150));
+
+ // set weaponID1 to uint12
+ TableColumn weaponID1Column = weaponTable.getColumnModel().getColumn(0);
+ JTextField weaponID1TextField = new JTextField();
+ AbstractDocument doc = (AbstractDocument) weaponID1TextField.getDocument();
+ doc.setDocumentFilter(gui.uint12);
+ weaponID1Column.setCellEditor(new DefaultCellEditor(weaponID1TextField));
+
+ // set weaponID2 to uint11
+ TableColumn weaponID2Column = weaponTable.getColumnModel().getColumn(1);
+ JTextField weaponID2TextField = new JTextField();
+ doc = (AbstractDocument) weaponID2TextField.getDocument();
+ doc.setDocumentFilter(gui.uint11);
+ weaponID2Column.setCellEditor(new DefaultCellEditor(weaponID2TextField));
+
+ // set weaponNumGemSlots to uint8
+ TableColumn weaponNumGemSlotsColumn = weaponTable.getColumnModel().getColumn(2);
+ JTextField weaponNumGemSlotsTextField = new JTextField();
+ doc = (AbstractDocument) weaponNumGemSlotsTextField.getDocument();
+ doc.setDocumentFilter(gui.uint8);
+ weaponNumGemSlotsColumn.setCellEditor(new DefaultCellEditor(weaponNumGemSlotsTextField));
+
+ // set weaponGem1Index to uint16
+ TableColumn weaponGem1IndexColumn = weaponTable.getColumnModel().getColumn(3);
+ JTextField weaponGem1IndexTextField = new JTextField();
+ doc = (AbstractDocument) weaponGem1IndexTextField.getDocument();
+ doc.setDocumentFilter(gui.uint16);
+ weaponGem1IndexColumn.setCellEditor(new DefaultCellEditor(weaponGem1IndexTextField));
+
+ // set weaponGem2Index to uint16
+ TableColumn weaponGem2IndexColumn = weaponTable.getColumnModel().getColumn(4);
+ JTextField weaponGem2IndexTextField = new JTextField();
+ doc = (AbstractDocument) weaponGem2IndexTextField.getDocument();
+ doc.setDocumentFilter(gui.uint16);
+ weaponGem2IndexColumn.setCellEditor(new DefaultCellEditor(weaponGem2IndexTextField));
+
+ // set weaponGem3Index to uint16
+ TableColumn weaponGem3IndexColumn = weaponTable.getColumnModel().getColumn(5);
+ JTextField weaponGem3IndexTextField = new JTextField();
+ doc = (AbstractDocument) weaponGem3IndexTextField.getDocument();
+ doc.setDocumentFilter(gui.uint16);
+ weaponGem3IndexColumn.setCellEditor(new DefaultCellEditor(weaponGem3IndexTextField));
+
+ // set weaponInventorySlot to uint8
+ TableColumn weaponInventorySlotColumn = weaponTable.getColumnModel().getColumn(6);
+ JTextField weaponInventorySlotTextField = new JTextField();
+ doc = (AbstractDocument) weaponInventorySlotTextField.getDocument();
+ doc.setDocumentFilter(gui.uint8);
+ weaponInventorySlotColumn.setCellEditor(new DefaultCellEditor(weaponInventorySlotTextField));
+
+ gui.setArray(SaveField.weaponArray, new ArrayField[] {ArrayField.weaponID1, ArrayField.weaponID2, ArrayField.weaponNumGemSlots, ArrayField.weaponGem1Index, ArrayField.weaponGem2Index, ArrayField.weaponGem3Index, ArrayField.weaponInventorySlot}, weaponTable);
+
+ JScrollPane weaponScrollPane = new JScrollPane(weaponTable);
+ this.add(weaponScrollPane, "cell 0 1,growx,aligny top,spanx 2");
+
+
+ String[] gemColumnNames = new String[] {"Index", "Gem ID (Name)", "Gem ID (Description)", "Rank", "Value", "Inventory Slot", "Unknown 1", "Unknown 2", "Unknown 3"};
gemTable = new JTable();
- gemTable.setModel(new DefaultTableModel(gemColumnNames, 300));
-
- final String[] gemNames = {
- "None",
- "Strength Up",
- "Chill Defence",
- "Sleep Resist",
- "Slow Resist",
- "Bind Resist",
- "Buff Time Plus",
- "Weapon Power",
- "Strength Down",
- "Blaze Plus",
- "Blaze Attack",
- "Spike",
- "Revival HP Up",
- "Initial Tension",
- "Aggro Up",
- "EXP Up",
- "Weaken", // Unused
- "HP Up",
- "Poison Defence",
- "Spike Defence",
- "Paralysis Resist",
- "Debuff Resist",
- "Recovery Up",
- "Aura Heal",
- "Damage Heal",
- "Arts Heal",
- "HP Steal",
- "Unbeatable",
- "AP Up",
- "Aquatic Cloak",
- "Auto-Heal Up",
- "Terrain Defence",
- "HP Weaken", // Unused
- "Ether Up",
- "Double Attack",
- "Daze Resist",
- "Pierce Resist",
- "Daze Plus",
- "Phys Def Down",
- "Paralysis",
- "Lightning Attack",
- "Electric Plus",
- "Back Atk Plus",
- "First Attack Plus",
- "Daze Up",
- "Cast Quicken", // Unused
- "Tension Swing",
- "Daze Tension",
- "Ether Weaken", // Unused
- "Ether Def Up",
- "Blaze Defence",
- "Lock-On Resist",
- "Confuse Resist",
- "Critical Resist", // Unused
- "Ether Protect",
- "Slow",
- "Bind",
- "Ether Def Down",
- "Chill Plus",
- "Chill Attack",
- "Auto-Atk Stealth",
- "Arts Stealth",
- "Talent Boost",
- "Heat Sink",
- "Ether Smash", // Unused
- "Agility Up",
- "Topple Resist",
- "Good Footing",
- "Arts Seal Resist",
- "Accuracy Up", // Unused
- "Haste",
- "Topple Plus",
- "Bleed Attack",
- "Bleed Plus",
- "Topple Up",
- "Agility Down",
- "Break",
- "Quick Step",
- "Fall Defence",
- "Aerial Cloak",
- "Agility Weaken", // Unused
- "Muscle Up",
- "Attack Stability",
- "Attack Plus",
- "Critical Up",
- "Bleed Defence",
- "Divine Protect",
- "Physical Protect",
- "Night Vision",
- "Debuff Plus",
- "Armour Power", // Unused
- "Ether Down",
- "Poison Plus",
- "Poison Attack",
- "Aggro Down",
- "Earth Cloak",
- "Muscle Waste", // Unused
- "Unbeatable",
- "Impurity" // Unused
- };
+ gemTable.setModel(new DefaultTableModel(gemColumnNames, 300) {
+ @Override
+ public boolean isCellEditable(int row, int column) {
+ return column == 0 ? false : true; // Makes the first column (index) unmodifiable
+ }
+ });
+
+ // set Index column values
+ DefaultTableModel gemTableModel = (DefaultTableModel) gemTable.getModel();
+ for (int i = 0; i < gemTableModel.getRowCount(); i++) {
+ gemTableModel.setValueAt(i, i, 0);
+ }
// set gemID1 to JComboBox
- TableColumn gemID1Column = gemTable.getColumnModel().getColumn(0);
+ TableColumn gemID1Column = gemTable.getColumnModel().getColumn(1);
JComboBox gemID1ComboBox = new JComboBox(gemNames);
gemID1Column.setCellEditor(new DefaultCellEditor(gemID1ComboBox));
// set gemID2 to JComboBox
- TableColumn gemID2Column = gemTable.getColumnModel().getColumn(1);
+ TableColumn gemID2Column = gemTable.getColumnModel().getColumn(2);
gemID2Column.setMinWidth(100);
JComboBox gemID2ComboBox = new JComboBox(gemNames);
gemID2Column.setCellEditor(new DefaultCellEditor(gemID2ComboBox));
// set rank to uint3
- TableColumn gemRankColumn = gemTable.getColumnModel().getColumn(2);
+ TableColumn gemRankColumn = gemTable.getColumnModel().getColumn(3);
JTextField gemRankTextField = new JTextField();
- AbstractDocument doc = (AbstractDocument) gemRankTextField.getDocument();
+ doc = (AbstractDocument) gemRankTextField.getDocument();
doc.setDocumentFilter(gui.uint3);
gemRankColumn.setCellEditor(new DefaultCellEditor(gemRankTextField));
// set value to uint11
- TableColumn gemValueColumn = gemTable.getColumnModel().getColumn(3);
+ TableColumn gemValueColumn = gemTable.getColumnModel().getColumn(4);
JTextField gemValueTextField = new JTextField();
doc = (AbstractDocument) gemValueTextField.getDocument();
doc.setDocumentFilter(gui.uint11);
gemValueColumn.setCellEditor(new DefaultCellEditor(gemValueTextField));
// set gemInventorySlot to uint8
- TableColumn gemInventorySlotColumn = gemTable.getColumnModel().getColumn(4);
+ TableColumn gemInventorySlotColumn = gemTable.getColumnModel().getColumn(5);
JTextField gemInventorySlotTextField = new JTextField();
doc = (AbstractDocument) gemInventorySlotTextField.getDocument();
doc.setDocumentFilter(gui.uint8);
gemInventorySlotColumn.setCellEditor(new DefaultCellEditor(gemInventorySlotTextField));
// set gemUnk1 to uint5
- TableColumn gemUnk1Column = gemTable.getColumnModel().getColumn(5);
+ TableColumn gemUnk1Column = gemTable.getColumnModel().getColumn(6);
JTextField gemUnk1TextField = new JTextField();
doc = (AbstractDocument) gemUnk1TextField.getDocument();
doc.setDocumentFilter(gui.uint5);
gemUnk1Column.setCellEditor(new DefaultCellEditor(gemUnk1TextField));
// set gemUnk2 to uint11
- TableColumn gemUnk2Column = gemTable.getColumnModel().getColumn(6);
+ TableColumn gemUnk2Column = gemTable.getColumnModel().getColumn(7);
JTextField gemUnk2TextField = new JTextField();
doc = (AbstractDocument) gemUnk2TextField.getDocument();
doc.setDocumentFilter(gui.uint11);
gemUnk2Column.setCellEditor(new DefaultCellEditor(gemUnk2TextField));
// set gemUnk3 to uint7
- TableColumn gemUnk3Column = gemTable.getColumnModel().getColumn(7);
+ TableColumn gemUnk3Column = gemTable.getColumnModel().getColumn(8);
JTextField gemUnk3TextField = new JTextField();
doc = (AbstractDocument) gemUnk3TextField.getDocument();
doc.setDocumentFilter(gui.uint7);
gemUnk3Column.setCellEditor(new DefaultCellEditor(gemUnk3TextField));
- gui.setArray(SaveField.gemArray, new ArrayField[] {ArrayField.gemID1, ArrayField.gemID2, ArrayField.gemRank, ArrayField.gemValue, ArrayField.gemInventorySlot, ArrayField.gemUnk1, ArrayField.gemUnk2, ArrayField.gemUnk3}, gemTable);
+ gui.setArray(SaveField.gemArray, new ArrayField[] {null, ArrayField.gemID1, ArrayField.gemID2, ArrayField.gemRank, ArrayField.gemValue, ArrayField.gemInventorySlot, ArrayField.gemUnk1, ArrayField.gemUnk2, ArrayField.gemUnk3}, gemTable);
JScrollPane gemScrollPane = new JScrollPane(gemTable);
- this.add(gemScrollPane, "cell 0 1,growx,aligny top,spanx 2");
+ this.add(gemScrollPane, "cell 0 2,growx,aligny top,spanx 2");
}
+ public int getGemTableNumRows() { return this.gemTable.getModel().getRowCount(); }
+ public int getWeaponTableNumRows() { return this.weaponTable.getModel().getRowCount(); }
}
diff --git a/View/ViewEvent.java b/View/ViewEvent.java
index 96ee25a..19cd77c 100644
--- a/View/ViewEvent.java
+++ b/View/ViewEvent.java
@@ -15,8 +15,11 @@ public class ViewEvent extends EventObject {
private EventType type;
private SaveField sf;
-
private ArrayField af;
+
+ private SaveField destSf;
+ private ArrayField destAf;
+ private Integer destIndex;
private String fileLocation;
@@ -25,16 +28,17 @@ public class ViewEvent extends EventObject {
private String value;
public enum EventType {
- OPEN_FILE, // param is file location
- SAVE_FILE, // param null
- GET_DATA, // param is a SaveField
- SET_DATA, // param is "saveField:value"
- SET_ARRAY_DATA, // param is "saveField(array):index:arrayField:value"
- GET_ARRAY_DATA, // param is "saveField(array):index:arrayField"
+ OPEN_FILE,
+ SAVE_FILE,
+ GET_DATA,
+ SET_DATA,
+ SET_ARRAY_DATA,
+ GET_ARRAY_DATA,
+ SET_COPY_ARRAY_DATA, // copies array data from one array to another
}
/**
- * ViewEvent constructor with param parameter (for event OPEN_FILE, SET_DATA)
+ * ViewEvent constructor
* @param source the object that created this ViewEvent
* @param type the type of ViewEvent
described by the constants of this class
* @param fileLocation the location of the file to be opened; or null if not applicable to the type
@@ -65,6 +69,8 @@ public ViewEvent(Object source, EventType type, String fileLocation, SaveField s
case SET_DATA:
if (sf == null || value == null) throw new IllegalArgumentException();
break;
+ case SET_COPY_ARRAY_DATA:
+ throw new IllegalArgumentException();
}
this.type = type;
@@ -74,6 +80,18 @@ public ViewEvent(Object source, EventType type, String fileLocation, SaveField s
this.index = index;
this.value = value;
}
+
+ // ViewEvent constructor for SET_COPY_ARRAY_DATA
+ public ViewEvent(Object source, SaveField originSf, ArrayField originAf, Integer originIndex, SaveField destSf, ArrayField destAf, Integer destIndex) {
+ super(source);
+ this.type = EventType.SET_COPY_ARRAY_DATA;
+ this.sf = originSf;
+ this.af = originAf;
+ this.destSf = destSf;
+ this.destAf = destAf;
+ this.destIndex = destIndex;
+ this.index = originIndex;
+ }
/**
* @return the type of this ViewEvent
described by the constants of this class; or null if not applicable
@@ -90,6 +108,18 @@ public ViewEvent(Object source, EventType type, String fileLocation, SaveField s
* Used in conjunction with an index to uniquely identify an Array
element
*/
public ArrayField getArrayField() { return this.af; }
+
+ /**
+ * @return the SaveField
to copy to; null if not applicable
+ * Used only with SET_COPY_ARRAY_DATA
+ */
+ public SaveField getDestSaveField() { return this.destSf; }
+
+ /**
+ * @return the Array
column name to copy to; null if not applicable
+ * Used only with SET_COPY_ARRAY_DATA
+ */
+ public ArrayField getDestArrayField() { return this.destAf; }
/**
* @return the file location of the file to open, used only with EventType.OPEN_FILE
@@ -101,6 +131,12 @@ public ViewEvent(Object source, EventType type, String fileLocation, SaveField s
* Used in conjunction with an ArrayField to uniquely identify an Array
element
*/
public Integer getIndex() { return this.index; }
+
+ /**
+ * @return the Array
index (or row) this ViewEvent
wants to copy to; or null if not applicable
+ * Used only with SET_COPY_ARRAY_DATA
+ */
+ public Integer getDestIndex() { return this.destIndex; }
/**
* @return the value to set a save field to; or null if not applicable