aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/galacticgreg/schematics/SpaceSchematicHandler.java
blob: 575befaf0a5fb909b827e55fe172f448aa388373 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
package galacticgreg.schematics;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import org.apache.commons.io.FileUtils;

import galacticgreg.GalacticGreg;

/**
 * Class for XML Structure files. You only should edit/use this file/class if you want to add/fix stuff with
 * GalacticGreg itself, and never if you're a mod developer and want to add support for GGreg to your mod. However, feel
 * free to copy this code to your own mod to implement structures. If you have questions, find me on github and ask
 */
public class SpaceSchematicHandler {

    File _mConfigFolderName;
    File _mSchematicsFolderName;
    private List<SpaceSchematic> _mSpaceSchematics;

    @SuppressWarnings("ResultOfMethodCallIgnored")
    public SpaceSchematicHandler(File pConfigFolder) {
        _mConfigFolderName = new File(String.format("%s/%s", pConfigFolder.toString(), GalacticGreg.NICE_MODID));
        _mSchematicsFolderName = new File(String.format("%s/schematics", _mConfigFolderName));

        _mSpaceSchematics = new ArrayList<>();

        if (!_mSchematicsFolderName.exists()) _mSchematicsFolderName.mkdirs();
    }

    /**
     * Get a random schematic to be placed.
     *
     * @return A schematic that can be spawned in space
     */
    public SpaceSchematic getRandomSpaceSchematic() {
        int tRandomChance = GalacticGreg.GalacticRandom.nextInt(100);
        List<Integer> tRandomIDs = new ArrayList<>();
        SpaceSchematic tChoosenSchematic = null;

        if (_mSpaceSchematics == null) return null;

        if (_mSpaceSchematics.isEmpty()) return null;

        if (_mSpaceSchematics.size() == 1) {
            tChoosenSchematic = _mSpaceSchematics.get(0);
            if (tChoosenSchematic.getRarity() < tRandomChance) tChoosenSchematic = null;
        } else {
            for (int i = 0; i < _mSpaceSchematics.size(); i++) {
                if (_mSpaceSchematics.get(i)
                    .getRarity() >= tRandomChance) tRandomIDs.add(i);
            }
        }

        if (!tRandomIDs.isEmpty()) {
            int tRnd = GalacticGreg.GalacticRandom.nextInt(tRandomIDs.size());
            tChoosenSchematic = _mSpaceSchematics.get(tRandomIDs.get(tRnd));
        }

        return tChoosenSchematic;
    }

    /**
     * Try to reload the schematics. Will not change the list of currently loaded schematics if any errors are detected,
     * except if you force it to do so
     *
     * @return
     */
    public boolean reloadSchematics(boolean pForceReload) {
        try {
            Collection<File> structureFiles = FileUtils
                .listFiles(_mSchematicsFolderName, new String[] { "xml" }, false);
            List<SpaceSchematic> tNewSpaceSchematics = new ArrayList<>();
            int tErrorsFound = 0;

            if (structureFiles.isEmpty()) return true;

            for (File tSchematic : structureFiles) {
                try {
                    SpaceSchematic tSchematicObj = LoadSpaceSchematic(tSchematic);
                    if (tSchematicObj != null) tNewSpaceSchematics.add(tSchematicObj);
                    else {
                        GalacticGreg.Logger.warn("Could not load Schematic %s. Please check the syntax", tSchematic);
                        tErrorsFound++;
                    }
                } catch (Exception e) {
                    GalacticGreg.Logger.error("Error while loading Schematic %s", tSchematic);
                    e.printStackTrace();
                }

            }

            GalacticGreg.Logger.info("Successfully loaded %d Schematics", tNewSpaceSchematics.size());
            boolean tDoReplace = true;

            if (tErrorsFound > 0) {
                GalacticGreg.Logger.warn("Found %d errors while loading, not all schematics will be available");
                if (pForceReload)
                    GalacticGreg.Logger.info("Reload was forced, replacing currently active list with new one");
                else {
                    GalacticGreg.Logger.warn("Nothing was replaced. Fix any errors and reload again");
                    tDoReplace = false;
                }
            }

            if (tDoReplace) _mSpaceSchematics = tNewSpaceSchematics;

            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Saves the schematic to disk. The schematics name will be used as filename
     *
     * @param pSchematic
     * @return
     */
    public boolean SaveSpaceStructure(SpaceSchematic pSchematic) {
        try {
            if (pSchematic.getName()
                .isEmpty()) return false;

            JAXBContext tJaxbCtx = JAXBContext.newInstance(SpaceSchematic.class);
            Marshaller jaxMarsh = tJaxbCtx.createMarshaller();
            jaxMarsh.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            jaxMarsh.marshal(
                pSchematic,
                new FileOutputStream(String.format("%s/%s.xml", _mSchematicsFolderName, pSchematic.getName()), false));

            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * Load a schematic from disk by the schematic-name itself, without .xml or path
     *
     * @param pSchematicName
     * @return
     */
    public SpaceSchematic LoadSpaceSchematic(String pSchematicName) {
        return LoadSpaceSchematic(new File(String.format("%s/%s.xml", _mSchematicsFolderName, pSchematicName)));
    }

    /**
     * Load a schematic file from disk by providing the actual file-object
     *
     * @param pName
     * @return
     */
    public SpaceSchematic LoadSpaceSchematic(File pName) {
        SpaceSchematic tSchematic = null;

        try {
            JAXBContext tJaxbCtx = JAXBContext.newInstance(SpaceSchematic.class);
            if (!pName.exists()) {
                GalacticGreg.Logger.error("SchematicFile %s could not be found", pName);
                return null;
            }

            Unmarshaller jaxUnmarsh = tJaxbCtx.createUnmarshaller();
            tSchematic = (SpaceSchematic) jaxUnmarsh.unmarshal(pName);

        } catch (Exception e) {
            e.printStackTrace();
        }

        return tSchematic;
    }
}