Skip to content

Commit

Permalink
Merge pull request #38 from enderslash1010/weaponData
Browse files Browse the repository at this point in the history
Weapon data
  • Loading branch information
enderslash1010 authored Jan 18, 2024
2 parents 1ff8ab8 + aa8f2f7 commit 3891b06
Show file tree
Hide file tree
Showing 9 changed files with 372 additions and 133 deletions.
2 changes: 2 additions & 0 deletions Controller/ArrayField.java
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
1 change: 1 addition & 0 deletions Controller/SaveField.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public enum SaveField {

// ITEM
money,
weaponArray,
gemArray,

// WTHR
Expand Down
69 changes: 67 additions & 2 deletions Controller/SaveFileController.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand All @@ -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);
}
}

Expand Down
3 changes: 2 additions & 1 deletion Model/Array.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,10 @@ private int getColNameIndex(ArrayField name) {
* Gets a <code>Data</code> 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 <code>Data</code> object at the specified location
* @return a <code>Data</code> 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
Expand Down
58 changes: 58 additions & 0 deletions Model/SaveFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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<ArrayField> 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 <code>Data</code> object to the specified value, throwing an exception if the specified value is not the correct type
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions View/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@
/GUI$12.class
/ViewEvent$Types.class
/ViewEvent$EventType.class
/ITEMView$1.class
14 changes: 8 additions & 6 deletions View/GUI.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -388,7 +388,7 @@ public void actionPerformed(ActionEvent e) {

});
}
else {
else { // adds default JComboBox action listener

cb.addActionListener(new ActionListener() {

Expand Down Expand Up @@ -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<String, ArrayField> map;
if (columnMap.containsKey(arrName)) { // add to existing HashBiMap
map = columnMap.get(arrName);
Expand All @@ -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());
}

});
}

Expand Down
Loading

0 comments on commit 3891b06

Please sign in to comment.