PRC8/nwn/nwnprc/DocGen/trunk/prc/utils/Precache2daGen.java
Jaysyn904 5914ed2ab5 Updated Release Archive
Updated Release Archive.  Fixed Mage-killer prereqs.  Removed old LETO & ConvoCC related files.  Added organized spell scroll store.  Fixed Gloura spellbook. Various TLK fixes.  Reorganized Repo.  Removed invalid user folders. Added DocGen back in.
2023-08-22 10:00:21 -04:00

377 lines
16 KiB
Java

package prc.utils;
import prc.autodoc.*;
import java.io.File;
import java.io.FileFilter;
import java.util.HashSet;
import java.util.Set;
import static prc.Main.err_pr;
/**
* A class that parses 2das and determines which rows need to be
* cached for the spells / powers to work fast.
*
* @author Heikki 'Ornedan' Aitakangas
*/
public class Precache2daGen {
private static String path2daDir = null;
private static final Data_2da output = new Data_2da("precacherows");
static {
output.addColumn("RowNum");
output.addColumn("Type");
}
private static Data_2da spells = null/*,
feat = null*/;
private static int normalSpellMaxRow = 4200;
/**
* Ye olde maine methode.
*
* @param args The program arguments
* @throws Throwable Any problems just crash the program
*/
public static void main(String[] args) throws Throwable {
// parse args
for (int i = 0; i < args.length; i++) {//[--help] | [--normalspellsmax #] pathto2dadir
// Parameter parseage
String param = args[i];
if (param.startsWith("-")) {
if (param.equals("--help")) readMe();
else if (param.equals("--normalspellsmax")) {
try {
normalSpellMaxRow = Integer.parseInt(args[++i]);
} catch (NumberFormatException e) {
err_pr.println("Error: Invalid number given with parameter --normalspellsmax");
readMe();
}
} else {
for (char c : param.substring(1).toCharArray()) {
switch (c) {
default:
System.out.println("Unknown parameter: " + c);
readMe();
}
}
}
} else {
// It's a pathname
if (path2daDir == null)
path2daDir = param;
}
}
if (path2daDir == null)
readMe();
// Load a directory listing
File dir = new File(path2daDir);
if (!dir.isDirectory()) {
err_pr.println("Error: Not a directory: " + path2daDir);
System.exit(1);
}
// Load the main 2das
spells = Data_2da.load2da(dir.getPath() + File.separator + "spells.2da");
//feat = Data_2da.load2da(dir.getPath() + File.separator + "feat.2da");
handleNormalSpells();
//should generalise all of the AMS ones later - Flaming_Sword
handlePsionics(dir);
handleTruenaming(dir);
handleTob(dir);
handleInvocations(dir);
handleNewSpells();
output.appendRow();
output.save2da(".", false, true);
}
private static void readMe() {
// 0 1 2 3 4 5 6 7 8
// 12345678901234567890123456789012345678901234567890123456789012345678901234567890
System.out.println("Usage:\n" +
" [--help] | [--normalspellsmax #] pathto2dadir\n" +
"\n" +
" pathto2dadir path of the directory containing the 2das that will be parsed\n" +
"\n" +
" normalspellsmax The greatest index to which the normal spells seek will\n" +
" reach to. Defaults to 5000\n" +
"\n" +
"\n" +
" --help prints this text\n"
);
System.exit(0);
}
private static void handleNormalSpells() {
int temp;
for (int i = 0; i < normalSpellMaxRow; i++) {
if (// Check the row i itself
!spells.getEntry("Bard", i).equals("****") ||
!spells.getEntry("Cleric", i).equals("****") ||
!spells.getEntry("Druid", i).equals("****") ||
!spells.getEntry("Paladin", i).equals("****") ||
!spells.getEntry("Ranger", i).equals("****") ||
!spells.getEntry("Wiz_Sorc", i).equals("****") ||
// Check the master
(// Make sure a master entry exists
!spells.getEntry("Master", i).equals("****") &&
(// See if it's a normal spell
!spells.getEntry("Bard", temp = Integer.parseInt(spells.getEntry("Master", i))).equals("****") ||
!spells.getEntry("Cleric", temp).equals("****") ||
!spells.getEntry("Druid", temp).equals("****") ||
!spells.getEntry("Paladin", temp).equals("****") ||
!spells.getEntry("Ranger", temp).equals("****") ||
!spells.getEntry("Wiz_Sorc", temp).equals("****")
)
)
) {
// It's a normal spell or a subradial of one
output.appendRow();
temp = output.getEntryCount() - 1;
output.setEntry("RowNum", temp, Integer.toString(i));
output.setEntry("Type", temp, "N");
}
}
}
private static void handlePsionics(File dir) {
File[] files = dir.listFiles(new FileFilter() {
public boolean accept(File file) {
return file.getName().toLowerCase().startsWith("cls_psipw_") &&
file.getName().toLowerCase().endsWith(".2da");
}
});
Data_2da[] cls_psipw_2das = new Data_2da[files.length];
for (int i = 0; i < files.length; i++)
cls_psipw_2das[i] = Data_2da.load2da(files[i].getPath());
int temp;
Set<Integer> realEntriesHandled = new HashSet<Integer>();
// First, spells.2da referencing entries
for (Data_2da cls_psipw : cls_psipw_2das) {
for (int i = 0; i < cls_psipw.getEntryCount(); i++) {
// Add the feat-linked power's data
if (!cls_psipw.getEntry("SpellID", i).equals("****")) {
output.appendRow();
temp = output.getEntryCount() - 1;
output.setEntry("RowNum", temp, cls_psipw.getEntry("SpellID", i));
output.setEntry("Type", temp, "P");
}
// Add the real entry's data
if (!cls_psipw.getEntry("RealSpellID", i).equals("****")) {
temp = Integer.parseInt(cls_psipw.getEntry("RealSpellID", i));
if (!realEntriesHandled.contains(temp)) {
realEntriesHandled.add(temp);
output.appendRow();
temp = output.getEntryCount() - 1;
output.setEntry("RowNum", temp, cls_psipw.getEntry("RealSpellID", i));
output.setEntry("Type", temp, "PS");
}
}
}
}
// Feat.2da entries
for (Data_2da cls_psipw : cls_psipw_2das) {
for (int i = 0; i < cls_psipw.getEntryCount(); i++) {
// The feat's data
if (!cls_psipw.getEntry("FeatID", i).equals("****")) {
output.appendRow();
temp = output.getEntryCount() - 1;
output.setEntry("RowNum", temp, cls_psipw.getEntry("FeatID", i));
output.setEntry("Type", temp, "PF");
}
}
}
}
private static void handleTob(File dir) {
File[] files = dir.listFiles(new FileFilter() {
public boolean accept(File file) {
return file.getName().toLowerCase().startsWith("cls_move_") &&
file.getName().toLowerCase().endsWith(".2da");
}
});
Data_2da[] cls_psipw_2das = new Data_2da[files.length];
for (int i = 0; i < files.length; i++)
cls_psipw_2das[i] = Data_2da.load2da(files[i].getPath());
int temp;
Set<Integer> realEntriesHandled = new HashSet<Integer>();
// First, spells.2da referencing entries
for (Data_2da cls_psipw : cls_psipw_2das) {
for (int i = 0; i < cls_psipw.getEntryCount(); i++) {
// Add the feat-linked power's data
if (!cls_psipw.getEntry("SpellID", i).equals("****")) {
output.appendRow();
temp = output.getEntryCount() - 1;
output.setEntry("RowNum", temp, cls_psipw.getEntry("SpellID", i));
output.setEntry("Type", temp, "P");
}
// Add the real entry's data
if (!cls_psipw.getEntry("RealSpellID", i).equals("****")) {
temp = Integer.parseInt(cls_psipw.getEntry("RealSpellID", i));
if (!realEntriesHandled.contains(temp)) {
realEntriesHandled.add(temp);
output.appendRow();
temp = output.getEntryCount() - 1;
output.setEntry("RowNum", temp, cls_psipw.getEntry("RealSpellID", i));
output.setEntry("Type", temp, "PS");
}
}
}
}
// Feat.2da entries
for (Data_2da cls_psipw : cls_psipw_2das) {
for (int i = 0; i < cls_psipw.getEntryCount(); i++) {
// The feat's data
if (!cls_psipw.getEntry("FeatID", i).equals("****")) {
output.appendRow();
temp = output.getEntryCount() - 1;
output.setEntry("RowNum", temp, cls_psipw.getEntry("FeatID", i));
output.setEntry("Type", temp, "PF");
}
}
}
}
private static void handleInvocations(File dir) {
File[] files = dir.listFiles(new FileFilter() {
public boolean accept(File file) {
return file.getName().toLowerCase().startsWith("cls_inv_") &&
file.getName().toLowerCase().endsWith(".2da");
}
});
Data_2da[] cls_psipw_2das = new Data_2da[files.length];
for (int i = 0; i < files.length; i++)
cls_psipw_2das[i] = Data_2da.load2da(files[i].getPath());
int temp;
Set<Integer> realEntriesHandled = new HashSet<Integer>();
// First, spells.2da referencing entries
for (Data_2da cls_psipw : cls_psipw_2das) {
for (int i = 0; i < cls_psipw.getEntryCount(); i++) {
// Add the feat-linked power's data
if (!cls_psipw.getEntry("SpellID", i).equals("****")) {
output.appendRow();
temp = output.getEntryCount() - 1;
output.setEntry("RowNum", temp, cls_psipw.getEntry("SpellID", i));
output.setEntry("Type", temp, "P");
}
// Add the real entry's data
if (!cls_psipw.getEntry("RealSpellID", i).equals("****")) {
temp = Integer.parseInt(cls_psipw.getEntry("RealSpellID", i));
if (!realEntriesHandled.contains(temp)) {
realEntriesHandled.add(temp);
output.appendRow();
temp = output.getEntryCount() - 1;
output.setEntry("RowNum", temp, cls_psipw.getEntry("RealSpellID", i));
output.setEntry("Type", temp, "PS");
}
}
}
}
// Feat.2da entries
for (Data_2da cls_psipw : cls_psipw_2das) {
for (int i = 0; i < cls_psipw.getEntryCount(); i++) {
// The feat's data
if (!cls_psipw.getEntry("FeatID", i).equals("****")) {
output.appendRow();
temp = output.getEntryCount() - 1;
output.setEntry("RowNum", temp, cls_psipw.getEntry("FeatID", i));
output.setEntry("Type", temp, "PF");
}
}
}
}
// Pretty much a copy of psionics, at least for now
private static void handleTruenaming(File dir) {
File[] files = dir.listFiles(new FileFilter() {
public boolean accept(File file) {
return file.getName().toLowerCase().startsWith("cls_true_") &&
file.getName().toLowerCase().endsWith(".2da") &&
!file.getName().equalsIgnoreCase("cls_true_known.2da") && // Skip special cases
!file.getName().equalsIgnoreCase("cls_true_maxlvl.2da");
}
});
Data_2da[] cls_true_2das = new Data_2da[files.length];
for (int i = 0; i < files.length; i++)
cls_true_2das[i] = Data_2da.load2da(files[i].getPath());
int temp;
Set<Integer> realEntriesHandled = new HashSet<Integer>();
// First, spells.2da referencing entries
for (Data_2da cls_true : cls_true_2das) {
for (int i = 0; i < cls_true.getEntryCount(); i++) {
// Add the feat-linked spells.2da data
if (!cls_true.getEntry("SpellID", i).equals("****")) {
output.appendRow();
temp = output.getEntryCount() - 1;
output.setEntry("RowNum", temp, cls_true.getEntry("SpellID", i));
output.setEntry("Type", temp, "P");
}
// Add the real entry's data
if (!cls_true.getEntry("RealSpellID", i).equals("****")) {
temp = Integer.parseInt(cls_true.getEntry("RealSpellID", i));
if (!realEntriesHandled.contains(temp)) {
realEntriesHandled.add(temp);
output.appendRow();
temp = output.getEntryCount() - 1;
output.setEntry("RowNum", temp, cls_true.getEntry("RealSpellID", i));
output.setEntry("Type", temp, "PS");
}
}
}
}
// Feat.2da entries
for (Data_2da cls_true : cls_true_2das) {
for (int i = 0; i < cls_true.getEntryCount(); i++) {
// The feat's data
if (!cls_true.getEntry("FeatID", i).equals("****")) {
output.appendRow();
temp = output.getEntryCount() - 1;
output.setEntry("RowNum", temp, cls_true.getEntry("FeatID", i));
output.setEntry("Type", temp, "PF");
}
}
}
}
private static void handleNewSpells() {
int begin = -1, end = -1;
int temp, i = normalSpellMaxRow;
while (i < spells.getEntryCount()) {
if (spells.getEntry("Label", i).equals("####START_OF_NEW_SPELLBOOK_RESERVE"))
begin = i + 1;
if (spells.getEntry("Label", i).equals("####END_OF_NEW_SPELLBOOK_RESERVE"))
end = i - 1;
if (begin != -1 && end != -1)
break;
i += 1;
}
if (begin == -1 || end == -1) {
err_pr.println("Error: Missing a new spellbook reserve marker");
System.exit(1);
}
for (i = begin; i <= end; i++) {
output.appendRow();
temp = output.getEntryCount() - 1;
output.setEntry("RowNum", temp, String.valueOf(i));
output.setEntry("Type", temp, "NS");
}
}
}