Skip to content

Commit 31b29ca

Browse files
authored
Letting a mod override all of the base game data, like an iWad would in Doom (#293)
* Letting a mod override all of the base game data, like an iWad would in Doom * Ensure base mod is always at the beginning * Updating JSON schema for GameData.dat
1 parent 63c14c0 commit 31b29ca

File tree

3 files changed

+64
-6
lines changed

3 files changed

+64
-6
lines changed

Dungeoneer/src/com/interrupt/dungeoneer/game/GameData.java

+4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ public GameData() { }
3232
/** Is player allowed to jump? */
3333
public boolean playerJumpEnabled = false;
3434

35+
/** Whether the mod including this should override the packaged game data.
36+
* Setting this to true makes the mod basically the Delver version of an iWad in Doom. */
37+
public boolean overrideBaseGame = false;
38+
3539
public void merge(GameData modData) {
3640
tutorialLevel = modData.tutorialLevel;
3741
endingLevel = modData.endingLevel;

Dungeoneer/src/com/interrupt/dungeoneer/game/ModManager.java

+55-6
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.badlogic.gdx.files.FileHandle;
55
import com.badlogic.gdx.utils.Array;
66
import com.badlogic.gdx.utils.ArrayMap;
7+
import com.badlogic.gdx.utils.ObjectMap;
78
import com.interrupt.api.steam.SteamApi;
89
import com.interrupt.api.steam.workshop.WorkshopModData;
910
import com.interrupt.dungeoneer.entities.Door;
@@ -82,18 +83,51 @@ public void refresh() {
8283
findMods();
8384
filterMods();
8485
loadExcludesList();
86+
87+
// Find which path should be the base
88+
String baseAssetPath = getBaseAssetPath();
89+
90+
// If the base path is just the prepackaged data, stop here
91+
if(baseAssetPath.equals("."))
92+
return;
93+
94+
// Make sure the new base path is only in once, at the beginning
95+
modsFound.removeValue(baseAssetPath, false);
96+
modsFound.set(0, baseAssetPath);
97+
}
98+
99+
private String getBaseAssetPath() {
100+
// Check if any of the game data files override the baked in assets. Use the first found.
101+
ArrayMap<String, GameData> foundGameData = findAllGameData();
102+
for(ObjectMap.Entry<String, GameData> mapPair : foundGameData) {
103+
// Ignore this entry if it is actually the packaged game
104+
if(mapPair.key.equals("."))
105+
continue;
106+
107+
if(mapPair.value.overrideBaseGame)
108+
return mapPair.key;
109+
}
110+
111+
// Default to the internally packaged data.
112+
return ".";
85113
}
86114

87115
private void findMods() {
88116
// reset
89117
allMods.clear();
90118

91-
// add the default search paths
119+
// add the baked in data path
92120
allMods.add(".");
93121

94122
FileHandle fh = Game.getInternal("mods");
95123
for(FileHandle h : fh.list()) {
96-
if(h.isDirectory()) allMods.add("mods/" + h.name());
124+
if(h.isDirectory()) {
125+
String modPath = "mods/" + h.name();
126+
127+
// Ensure mod paths only get added once
128+
if(!allMods.contains(modPath, false))
129+
allMods.add(modPath);
130+
}
97131
}
98132

99133
// add any mods subscribed in Steam Workshop
@@ -316,19 +350,34 @@ public HashMap<String, LocalizedString> loadLocalizedStrings() {
316350
return combinedLocalizedStrings;
317351
}
318352

319-
public GameData loadGameData() {
320-
GameData gameData = new GameData();
353+
public ArrayMap<String, GameData> findAllGameData() {
354+
ArrayMap<String, GameData> foundGameData = new ArrayMap<>();
321355

322356
for(String path : modsFound) {
323357
try {
324358
FileHandle modFile = Game.getInternal(path + "/data/game.dat");
325359
if(modFile.exists() && !pathIsExcluded(path + "/data/game.dat")) {
326360
GameData modData = JsonUtil.fromJson(GameData.class, modFile);
327-
gameData.merge(modData);
361+
foundGameData.put(path, modData);
328362
}
329363
}
330364
catch(Exception ex) {
331-
Gdx.app.error("Delver", "Error loading mod file " + path + "/data/game.dat");
365+
Gdx.app.error("Delver", "Error loading game data file " + path + "/data/game.dat");
366+
Logger.logExceptionToFile(ex);
367+
}
368+
}
369+
370+
return foundGameData;
371+
}
372+
373+
public GameData loadGameData() {
374+
GameData gameData = new GameData();
375+
376+
for(GameData modData : findAllGameData().values()) {
377+
try {
378+
gameData.merge(modData);
379+
} catch(Exception ex) {
380+
Gdx.app.error("Delver", ex.getMessage());
332381
Logger.logExceptionToFile(ex);
333382
}
334383
}

jsonschema/current/dungeoneer/game/GameData.schema.json

+5
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,11 @@
5757
"type": "boolean",
5858
"default": false,
5959
"description": "Is player allowed to jump."
60+
},
61+
"overrideBaseGame": {
62+
"type": "boolean",
63+
"default": false,
64+
"description": "Whether the mod including this should override the packaged game data."
6065
}
6166
},
6267
"required": [

0 commit comments

Comments
 (0)