Skip to content

Commit

Permalink
Improve custom SPLPROT value selection for STATE.IDS and AREATYPE.IDS
Browse files Browse the repository at this point in the history
types in effect opcodes and projectiles

Creates Flags datatype to enable bitwise selection.
  • Loading branch information
Argent77 committed Jul 21, 2023
1 parent cb24e1a commit d8c3f2c
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 53 deletions.
60 changes: 58 additions & 2 deletions src/org/infinity/datatype/SpellProtType.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import org.infinity.resource.Profile;
import org.infinity.resource.ResourceFactory;
import org.infinity.resource.StructEntry;
import org.infinity.resource.are.AreResource;
import org.infinity.resource.cre.CreResource;
import org.infinity.util.IdsMap;
import org.infinity.util.IdsMapCache;
import org.infinity.util.IdsMapEntry;
Expand Down Expand Up @@ -136,8 +138,17 @@ public StructEntry createCreatureValueFromType(ByteBuffer buffer, int offset) {

public StructEntry createCreatureValueFromType(ByteBuffer buffer, int offset, int size, String name) {
if (useCustomValue()) {
String idsFile = getIdsFile();
if (!idsFile.isEmpty()) {
final int stat = getSpellProtStat();
final String idsFile = getIdsFile();
if (stat == 0x106 && useCustomValue()) {
// AREATYPE.IDS as flags
return new Flag(buffer, offset, size, DEFAULT_NAME_VALUE,
IdsMapCache.getUpdatedIdsFlags(AreResource.FLAGS_ARRAY, idsFile, 2, false, false));
} else if (stat == 0x111 && useCustomValue()) {
// STATE.IDS as flags
return CreResource.uniqueIdsFlag(new IdsFlag(buffer, offset, size, DEFAULT_NAME_VALUE, idsFile),
idsFile, '_');
} else if (!idsFile.isEmpty()) {
return new IdsBitmap(buffer, offset, size, createFieldName(name, index, DEFAULT_NAME_VALUE), idsFile);
} else {
return new DecNumber(buffer, offset, size, createFieldName(name, index, DEFAULT_NAME_VALUE));
Expand Down Expand Up @@ -199,6 +210,51 @@ public String getIdsFile() {
return "";
}

/**
* Returns the STAT value associated with the current SPLPROT.2DA entry.
*
* @return STAT value of the current SPLPROT.2DA entry. Returns -1 for hardcoded entries.
*/
public int getSpellProtStat() {
if (isExternalized()) {
Table2da table = Table2daCache.get(TABLE_NAME);
if (table != null) {
return toNumber(table.get(getValue(), 1), -1);
}
}
return -1;
}

/**
* Returns the VALUE value associated with the current SPLPROT.2DA entry.
*
* @return VALUE value of the current SPLPROT.2DA entry. Returns -1 for hardcoded entries.
*/
public int getSpellProtValue() {
if (isExternalized()) {
Table2da table = Table2daCache.get(TABLE_NAME);
if (table != null) {
return toNumber(table.get(getValue(), 2), -1);
}
}
return -1;
}

/**
* Returns the RELATION value associated with the current SPLPROT.2DA entry.
*
* @return RELATION value of the current SPLPROT.2DA entry. Returns -1 for hardcoded entries.
*/
public int getSpellProtRelation() {
if (isExternalized()) {
Table2da table = Table2daCache.get(TABLE_NAME);
if (table != null) {
return toNumber(table.get(getValue(), 3), -1);
}
}
return -1;
}

/** Returns whether creature table has been externalized into a 2DA file. */
public static boolean isTableExternalized() {
if (Profile.isEnhancedEdition()) {
Expand Down
109 changes: 58 additions & 51 deletions src/org/infinity/resource/cre/CreResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,64 @@ public static String getScriptName(ByteBuffer buffer) throws IOException {
return retVal;
}

/**
* Removes characters from flag descriptions which are shared by all relevant ids entries.
*
* @param field The {@link IdsFlag} instance to adjust.
* @param idsFile Associated IDS file.
* @param separatorChar Character to separate individual words (usually {@code '_'}).
* @return Updated {@link IdsFlag} instance.
*/
public static IdsFlag uniqueIdsFlag(IdsFlag field, String idsFile, char separatorChar) {
if (field == null) {
return field;
}
IdsMap map = IdsMapCache.get(idsFile);
if (map == null) {
return field;
}

String[] table = new String[field.getSize() * 8];
// determine longest common prefix
IdsMapEntry entry = map.get(0L);
String prefix = (entry != null) ? entry.getSymbol() : null;
for (int i = 0; i < table.length; i++) {
entry = map.get(1L << i);
if (entry != null) {
if (prefix == null) {
prefix = entry.getSymbol();
} else {
String name = entry.getSymbol();
for (int j = 0, jmax = Math.min(prefix.length(), name.length()); j < jmax; j++) {
if (Character.toUpperCase(prefix.charAt(j)) != Character.toUpperCase(name.charAt(j))) {
prefix = prefix.substring(0, j);
break;
}
}
}
}
}
if (prefix == null) {
prefix = "";
}

// cut off prefix after last matching separator character
if (separatorChar != 0) {
prefix = prefix.substring(0, prefix.lastIndexOf(separatorChar) + 1);
}

// update flag descriptions
entry = map.get(0L);
field.setEmptyDesc((entry != null) ? entry.getSymbol().substring(prefix.length()) : null);
for (int i = 0; i < table.length; i++) {
entry = map.get(1L << i);
table[i] = (entry != null) ? entry.getSymbol().substring(prefix.length()) : null;
}
field.setFlagDescriptions(field.getSize(), table, 0);

return field;
}

public CreResource(String name) throws Exception {
super(null, name,
StructureFactory.getInstance().createStructure(StructureFactory.ResType.RES_CRE, null, null).getBuffer(), 0);
Expand Down Expand Up @@ -2036,57 +2094,6 @@ private int setColorFieldsPSTEE(int animId, ByteBuffer buffer, int startOffset,
return startOffset;
}

// Removes characters from flag descriptions which are shared by all relevant ids entries.
private IdsFlag uniqueIdsFlag(IdsFlag field, String idsFile, char separatorChar) {
if (field == null) {
return field;
}
IdsMap map = IdsMapCache.get(idsFile);
if (map == null) {
return field;
}

String[] table = new String[field.getSize() * 8];
// determine longest common prefix
IdsMapEntry entry = map.get(0L);
String prefix = (entry != null) ? entry.getSymbol() : null;
for (int i = 0; i < table.length; i++) {
entry = map.get(1L << i);
if (entry != null) {
if (prefix == null) {
prefix = entry.getSymbol();
} else {
String name = entry.getSymbol();
for (int j = 0, jmax = Math.min(prefix.length(), name.length()); j < jmax; j++) {
if (Character.toUpperCase(prefix.charAt(j)) != Character.toUpperCase(name.charAt(j))) {
prefix = prefix.substring(0, j);
break;
}
}
}
}
}
if (prefix == null) {
prefix = "";
}

// cut off prefix after last matching separator character
if (separatorChar != 0) {
prefix = prefix.substring(0, prefix.lastIndexOf(separatorChar) + 1);
}

// update flag descriptions
entry = map.get(0L);
field.setEmptyDesc((entry != null) ? entry.getSymbol().substring(prefix.length()) : null);
for (int i = 0; i < table.length; i++) {
entry = map.get(1L << i);
table[i] = (entry != null) ? entry.getSymbol().substring(prefix.length()) : null;
}
field.setFlagDescriptions(field.getSize(), table, 0);

return field;
}

/**
* Converts effect structures to the specified EFF version.
*
Expand Down

0 comments on commit d8c3f2c

Please sign in to comment.