Introduction
After not writing any code for a week (busy week), I got back to doing so today. I have been working on the faction importing code, so that factions can be edited and saved back to factions.xml . Currently, I have two new features to report.
A Working Faction Renamer
Importing faction names from the factions.xml file is easy, but for some reason importing the standings of that faction compared to another faction are a bit harder. The main challenge is that I am not using an XML importer to handle the XML files, for one simple reason: Many of Vega Strike data files are not in XML format Editing factions involves also dealing with a lot of Python files.
However, I have written code that renames factions without damaging the game's universe. All it is is a glorified find and replace that edits the same files you'd normally have to open a find and replace on. The actual rename faction class is very simple:
public void renameFaction(String oldName, String newName, boolean milkyWay, boolean deepSearch) {
//Just parse down the folder list and rename everything in the generic file list
for (int x = 0; x
< subFolderListBasic.length; x++) {
try {
replaceInFile(this.vegaStrikeDataFolder + subFolderListBasic[x], oldName, newName, milkyWay);
} catch (IOException ex) {
Logger.getLogger(VegaStrikeFactionParser.class.getName()).log(Level.SEVERE, null, ex);
}
} //If deep search was selected we have another set of tasks
if (deepSearch) {
String[] sectors = getFileList(vegaStrikeDataFolder + "/sectors/");
//scan into each one for its stuff
for (int a = 0; a
< sectors.length; a++) {
String[] subFiles = getFileList(sectors[a] + "/");
for (int b = 0; b
< subFiles.length; b++) {
try {
replaceInFile(subFiles[b], oldName, newName, false);
} catch (IOException ex) {
Logger.getLogger(VegaStrikeFactionParser.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
}
But it relies on a support class called replaceInFile():
public void replaceInFile(String absolutePath, String oldDat, String newDat, boolean milkyWay) throws IOException {
if ((absolutePath.contains(".vsus") == false)
&& (absolutePath.contains(".png") == false)
&& (absolutePath.contains(".jpg") == false)
&& (absolutePath.toLowerCase().contains(".bmp") == false)
&& (absolutePath.contains(".sxc") == false)
&& (absolutePath.contains(".bfxm") == false)
&& (absolutePath.contains(".pdf") == false)) {
if ((absolutePath.contains("milky_way.xml") == false)
|| ((absolutePath.contains("milky_way.xml") == true) && milkyWay == true)) {
String tmp = openFile(absolutePath);
//do a simple find and replace on it
tmp = tmp.replace(oldDat, newDat);
//Delete original file
File file = new File(absolutePath);
file.delete();
file.createNewFile();
//Save it out to the file
writeFile(
tmp, absolutePath);
}
}
}
This class ignores a wide variety of file formats that have been causing issues, and it simply does a find and replace and passes the new string to a file writer. This means that I can decide to rename confed to Alliance, if I wanted. This makes this program a powerful time saver (it does 2 minutes of work automatically instead of me doing it manually, in 35 seconds).
Standings Editing
The first step to a working standings editor is a standings importer.
public String[] getFactionList() {
String[] list = null;
try {
//Opens the factions.xml file to determine what factions exist in-game
//Works on the logical basis that all factions have a relationship to every other faction
String tmpFile = this.openFile(vegaStrikeDataFolder + "/factions.xml");
//as usual break down the file
String[] brokenFile = tmpFile.split("~");
String rawFactionNames = "";
boolean grabbing = false;
for (int a = 0; a < brokenFile.length; a++) {
if (brokenFile[a].contains("stats name=")) {
//grab it
grabbing = true;
}
if (brokenFile[a].contains("</Faction>")) {
grabbing = false;
a = brokenFile.length + 900;
break;
}
//CAPTURE!
if (grabbing) {
rawFactionNames = rawFactionNames + brokenFile[a] + "~";
}
}
//Now we break down the faction names
grabbing = false;
String[] relevantLines = rawFactionNames.split("~");
rawFactionNames = "";
//And look at the <stats name="WHAT WE WANT"
for (int a = 0; a < relevantLines.length; a++) {
char[] arr = relevantLines[a].toCharArray();
//look inside the char array for our markers
for (int n = 0; n < arr.length; n++) {
if (arr[n] == '<' && arr[n + 1] == 's' && arr[n + 2] == 't' && arr[n + 3] == 'a' && arr[n + 4] == 't') {
//this is most likely what we want
grabbing = true;
n = n + ("<stats name=" + quote).length();
}
if (arr[n] == this.quote) {
grabbing = false;
n = n + 90000000;
break;
}
if (grabbing) {
rawFactionNames = rawFactionNames + arr[n];
}
}
rawFactionNames = rawFactionNames + "~";
}
//Break it down AGAIN lol
String[] factionNames = rawFactionNames.split("~");
list = factionNames;
//we are looking for the start of the first faction and parsing until its end
} catch (IOException ex) {
Logger.getLogger(VegaStrikeFactionParser.class.getName()).log(Level.SEVERE, null, ex);
}
return list;
}
This creates an array that is used to fill a list box, where the user can select a faction to edit. Importing faction standings is handled here:
public String[] getFactionStandings(String faction) {
String[] standings = null;
//This works on the logical concept that faction standings are in the same order in every entry
//First import the list, it will be used later
String[] list = getFactionList();
standings = list;
try {
boolean grabbing = false;
String tmpDat = ""; //used for temp storage
//Next, we have to identify our faction by looking for <Faction name="our crap"
String tmpFile = this.openFile(vegaStrikeDataFolder + "/factions.xml");
String[] brokenFile = tmpFile.split("~");
String[] imported = null;
System.out.println(faction);
for (int a = 0; a < brokenFile.length; a++) {
//look for Faction name= and FACTION
if (brokenFile[a].contains("Faction name=") && brokenFile[a].contains(faction)) {
System.out.println("Located Faction Data at Line " + a);
grabbing = true; //start grabbing
}
if (brokenFile[a].contains("</Faction>")) {
System.out.println("Located End of Faction Data at Line " + a);
grabbing = false; //stop
}
if (grabbing) {
//record each line
tmpDat = tmpDat + brokenFile[a] + "~";
System.out.println("Grabbing: " + brokenFile[a]);
}
}
//part two
grabbing = false;
String[] toParse = tmpDat.split("~");
//clear the tmp
tmpDat = "";
//and for part two!
for (int a = 1; a < toParse.length; a++) { //<stats name="privateer" relation="0.05"/>
//we are going to make the logical assumption that in every entry, the factions are in the same order.
//why is this logical? Because why would you jumble up everything?
//if this turns out to not work, I will simply write the bullet proof version of the code.
if (brokenFile[a].contains("stats name=")) {
System.out.println("Found Standings information at Line " + a);
grabbing = true; //start grabbing
}
if (brokenFile[a].contains("</Faction>")) {
System.out.println("Located End of Standings information at Line " + a);
grabbing = false; //stop
}
if (grabbing) {
//locate the actual standings at the line
char[] arr = brokenFile[a].toCharArray();
//our tmp local
String localTmp = "";
boolean localGrabbing = false;
for (int b = 0; b < arr.length; b++) {
if (arr[b]== 'i' && arr[b + 1] == 'o' && arr[b + 2] == 'n' && arr[b + 3] == '=' && arr[b + 4] == quote) {
//we found it!
b = b + 5;
localGrabbing = true;
}
if (arr[b]== quote) {
localGrabbing = false;
}
if (localGrabbing) {
localTmp = localTmp + arr[b];
}
}
//update the master
System.out.println(localTmp);
tmpDat = tmpDat + localTmp + "~";
//finally, clear it for the next session
localTmp = "";
localGrabbing = false;
}
}
//now we pu the two together into the main thing
imported = tmpDat.split("~");
for (int a = 0; a < imported.length; a++) {
//simple enough
standings[a] = standings[a] + ":" + imported[a];
}
} catch (IOException ex) {
Logger.getLogger(VegaStrikeFactionParser.class.getName()).log(Level.SEVERE, null, ex);
}
return standings;
}
The Next Step
Now that faction standings can be imported and factions can be renamed, I will be focusing on implementing...
- Save Modified Faction Standings.
- Add New Factions.
- Delete Factions.
- Provide an interface to building conversations.
In that order. The project is coming along nicely, and the faction editor is shaping into a useful tool that removes the need to edit many files.