diff --git a/src/main/java/com/projectswg/common/data/swgiff/parsers/SWGParserFactory.java b/src/main/java/com/projectswg/common/data/swgiff/parsers/SWGParserFactory.java
index caffd4f..7393da5 100644
--- a/src/main/java/com/projectswg/common/data/swgiff/parsers/SWGParserFactory.java
+++ b/src/main/java/com/projectswg/common/data/swgiff/parsers/SWGParserFactory.java
@@ -2,6 +2,8 @@ package com.projectswg.common.data.swgiff.parsers;
import com.projectswg.common.data.swgiff.parsers.appearance.*;
import com.projectswg.common.data.swgiff.parsers.appearance.extents.*;
+import com.projectswg.common.data.swgiff.parsers.creation.CombinedProfessionTemplateParser;
+import com.projectswg.common.data.swgiff.parsers.creation.ProfessionTemplateParser;
import com.projectswg.common.data.swgiff.parsers.footprint.FootprintDataParser;
import com.projectswg.common.data.swgiff.parsers.math.IndexedTriangleListParser;
import com.projectswg.common.data.swgiff.parsers.misc.CrcStringDataParser;
@@ -36,6 +38,8 @@ enum SWGParserFactory {
PARSERS.put("IDTL", IndexedTriangleListParser::new);
PARSERS.put("MESH", MeshAppearanceTemplate::new);
PARSERS.put("NULL", NullExtentParser::new);
+ PARSERS.put("PFDT", CombinedProfessionTemplateParser::new);
+ PARSERS.put("PRFI", ProfessionTemplateParser::new);
PARSERS.put("PRTL", PortalLayoutCellPortalTemplate::new);
PARSERS.put("PRTO", PortalLayoutTemplate::new);
PARSERS.put("PTAT", TerrainDataParser::new);
diff --git a/src/main/java/com/projectswg/common/data/swgiff/parsers/creation/CombinedProfessionTemplateParser.java b/src/main/java/com/projectswg/common/data/swgiff/parsers/creation/CombinedProfessionTemplateParser.java
new file mode 100644
index 0000000..bae1345
--- /dev/null
+++ b/src/main/java/com/projectswg/common/data/swgiff/parsers/creation/CombinedProfessionTemplateParser.java
@@ -0,0 +1,75 @@
+/***********************************************************************************
+ * Copyright (c) 2019 /// Project SWG /// www.projectswg.com *
+ * *
+ * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
+ * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
+ * Our goal is to create an emulator which will provide a server for players to *
+ * continue playing a game similar to the one they used to play. We are basing *
+ * it on the final publish of the game prior to end-game events. *
+ * *
+ * This file is part of Holocore. *
+ * *
+ * --------------------------------------------------------------------------------*
+ * *
+ * Holocore is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU Affero General Public License as *
+ * published by the Free Software Foundation, either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * Holocore is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU Affero General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Affero General Public License *
+ * along with Holocore. If not, see . *
+ ***********************************************************************************/
+package com.projectswg.common.data.swgiff.parsers.creation;
+
+import com.projectswg.common.data.swgiff.IffChunk;
+import com.projectswg.common.data.swgiff.IffForm;
+import com.projectswg.common.data.swgiff.parsers.SWGParser;
+
+import java.util.*;
+
+public class CombinedProfessionTemplateParser implements SWGParser {
+
+ private final List templateFiles;
+ private final Map templates;
+
+ public CombinedProfessionTemplateParser() {
+ this.templateFiles = new ArrayList<>();
+ this.templates = new HashMap<>();
+ }
+
+ @Override
+ public void read(IffForm form) {
+ assert form.getTag().equals("PFDT");
+ assert form.getVersion() == 0;
+
+ while (form.hasChunk("DATA")) {
+ try (IffChunk chunk = form.readChunk("DATA")) {
+ String file = chunk.readString();
+ templateFiles.add(file);
+ templates.put(file, SWGParser.parse("creation/profession_defaults_"+file+".iff"));
+ }
+ }
+ }
+
+ @Override
+ public IffForm write() {
+ List chunks = new ArrayList<>();
+ for (String file : templateFiles) {
+ IffChunk chunk = new IffChunk("DATA");
+ chunk.writeString(file);
+ chunks.add(chunk);
+ }
+
+ return IffForm.of("PRFI", 0, chunks);
+ }
+
+ public Map getTemplates() {
+ return Collections.unmodifiableMap(templates);
+ }
+
+}
diff --git a/src/main/java/com/projectswg/common/data/swgiff/parsers/creation/ProfessionTemplateParser.java b/src/main/java/com/projectswg/common/data/swgiff/parsers/creation/ProfessionTemplateParser.java
new file mode 100644
index 0000000..bc34178
--- /dev/null
+++ b/src/main/java/com/projectswg/common/data/swgiff/parsers/creation/ProfessionTemplateParser.java
@@ -0,0 +1,119 @@
+/***********************************************************************************
+ * Copyright (c) 2019 /// Project SWG /// www.projectswg.com *
+ * *
+ * ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
+ * July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
+ * Our goal is to create an emulator which will provide a server for players to *
+ * continue playing a game similar to the one they used to play. We are basing *
+ * it on the final publish of the game prior to end-game events. *
+ * *
+ * This file is part of Holocore. *
+ * *
+ * --------------------------------------------------------------------------------*
+ * *
+ * Holocore is free software: you can redistribute it and/or modify *
+ * it under the terms of the GNU Affero General Public License as *
+ * published by the Free Software Foundation, either version 3 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * Holocore is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU Affero General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Affero General Public License *
+ * along with Holocore. If not, see . *
+ ***********************************************************************************/
+package com.projectswg.common.data.swgiff.parsers.creation;
+
+import com.projectswg.common.data.swgiff.IffChunk;
+import com.projectswg.common.data.swgiff.IffForm;
+import com.projectswg.common.data.swgiff.parsers.SWGParser;
+
+import java.util.*;
+import java.util.Map.Entry;
+
+public class ProfessionTemplateParser implements SWGParser {
+
+ private final List skills;
+ private final Map> raceItems;
+
+ public ProfessionTemplateParser() {
+ this.skills = new ArrayList<>();
+ this.raceItems = new HashMap<>();
+ }
+
+ @Override
+ public void read(IffForm form) {
+ assert form.getTag().equals("PRFI");
+ assert form.getVersion() == 0;
+
+ try (IffForm skillForm = form.readForm("SKLS")) {
+ while (skillForm.hasChunk("SKIL")) {
+ try (IffChunk skillChunk = skillForm.readChunk("SKIL")) {
+ skills.add(skillChunk.readString());
+ }
+ }
+ }
+ while (form.hasForm("PTMP")) {
+ try (IffForm templateForm = form.readForm("PTMP")) {
+ String race;
+ List items = new ArrayList<>();
+ try (IffChunk nameChunk = templateForm.readChunk("NAME")) {
+ race = nameChunk.readString();
+ }
+ while (templateForm.hasChunk("ITEM")) {
+ try (IffChunk itemChunk = templateForm.readChunk("ITEM")) {
+ itemChunk.readInt(); // arrangementId
+ items.add(itemChunk.readString()); // shared template
+ itemChunk.readString(); // server template
+ }
+ }
+ raceItems.put(race, Collections.unmodifiableList(items));
+ }
+ }
+ }
+
+ @Override
+ public IffForm write() {
+ List forms = new ArrayList<>();
+
+ {
+ List skillChunks = new ArrayList<>();
+ for (String skill : skills) {
+ IffChunk chunk = new IffChunk("SKIL");
+ chunk.writeString(skill);
+ skillChunks.add(chunk);
+ }
+ forms.add(IffForm.of("SKLS", skillChunks));
+ }
+ {
+ for (Entry> raceItem : raceItems.entrySet()) {
+ List raceItemChunks = new ArrayList<>();
+ {
+ IffChunk nameChunk = new IffChunk("NAME");
+ nameChunk.writeString(raceItem.getKey());
+ raceItemChunks.add(nameChunk);
+ }
+ for (String sharedTemplate : raceItem.getValue()) {
+ IffChunk chunk = new IffChunk("ITEM");
+ chunk.writeInt(0);
+ chunk.writeString(sharedTemplate);
+ chunk.writeString("");
+ raceItemChunks.add(chunk);
+ }
+ forms.add(IffForm.of("PTMP", raceItemChunks));
+ }
+ }
+
+ return IffForm.of("PRFI", 0, forms);
+ }
+
+ public List getSkills() {
+ return Collections.unmodifiableList(skills);
+ }
+
+ public Map> getRaceItems() {
+ return Collections.unmodifiableMap(raceItems);
+ }
+}