The group for gamers dedicated to Linux. No matter if game developers or game players all are welcome interested in Linux as a gaming platform.

Post news Report RSS Code Peek: A Working Faction Importer

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.

Posted by on

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)
                &amp;&amp; (absolutePath.contains(".png") == false)
                &amp;&amp; (absolutePath.contains(".jpg") == false)
                &amp;&amp; (absolutePath.toLowerCase().contains(".bmp") == false)
                &amp;&amp; (absolutePath.contains(".sxc") == false)
                &amp;&amp; (absolutePath.contains(".bfxm") == false)
                &amp;&amp; (absolutePath.contains(".pdf") == false)) {
            if ((absolutePath.contains("milky_way.xml") == false)
                    || ((absolutePath.contains("milky_way.xml") == true) &amp;&amp; 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] == '<' &amp;&amp; arr[n + 1] == 's' &amp;&amp; arr[n + 2] == 't' &amp;&amp; arr[n + 3] == 'a' &amp;&amp; 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=") &amp;&amp; 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' &amp;&amp; arr[b + 1] == 'o' &amp;&amp; arr[b + 2] == 'n' &amp;&amp; arr[b + 3] == '=' &amp;&amp; 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.

Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: