diff --git a/src/com/gpl/rpg/atcontentstudio/model/Project.java b/src/com/gpl/rpg/atcontentstudio/model/Project.java index 32cf9fc..61c6227 100644 --- a/src/com/gpl/rpg/atcontentstudio/model/Project.java +++ b/src/com/gpl/rpg/atcontentstudio/model/Project.java @@ -290,7 +290,7 @@ public class Project implements ProjectTreeNode, Serializable, JsonSerializable public void linkAll() { for (ProjectTreeNode node : baseContent.gameData.v.getNonEmptyIterable()) { if (node instanceof GameDataCategory) { - for (GameDataElement e : ((GameDataCategory) node)) { + for (GameDataElement e : ((GameDataCategory) node).toList()) { e.link(); } } @@ -300,7 +300,7 @@ public class Project implements ProjectTreeNode, Serializable, JsonSerializable } for (ProjectTreeNode node : alteredContent.gameData.v.getNonEmptyIterable()) { if (node instanceof GameDataCategory) { - for (GameDataElement e : ((GameDataCategory) node)) { + for (GameDataElement e : ((GameDataCategory) node).toList()) { e.link(); } } @@ -310,7 +310,7 @@ public class Project implements ProjectTreeNode, Serializable, JsonSerializable } for (ProjectTreeNode node : createdContent.gameData.v.getNonEmptyIterable()) { if (node instanceof GameDataCategory) { - for (GameDataElement e : ((GameDataCategory) node)) { + for (GameDataElement e : ((GameDataCategory) node).toList()) { e.link(); } } @@ -937,14 +937,14 @@ public class Project implements ProjectTreeNode, Serializable, JsonSerializable public void moveToCreated(JSONElement target) { target.childrenRemoved(new ArrayList()); - ((GameDataCategory) target.getParent()).remove(target); + ((GameDataCategory) target.getParent()).removeGeneric(target); target.state = GameDataElement.State.created; createdContent.gameData.addElement(target); } public void moveToAltered(JSONElement target) { target.childrenRemoved(new ArrayList()); - ((GameDataCategory) target.getParent()).remove(target); + ((GameDataCategory) target.getParent()).removeGeneric(target); target.state = GameDataElement.State.created; ((JSONElement) target).jsonFile = new File(baseContent.gameData.getGameDataElement(((JSONElement) target).getClass(), target.id).jsonFile.getAbsolutePath()); alteredContent.gameData.addElement((JSONElement) target); @@ -1202,18 +1202,18 @@ public class Project implements ProjectTreeNode, Serializable, JsonSerializable public List writeDataDeltaForDataType(GameDataCategory created, GameDataCategory altered, GameDataCategory source, Class gdeClass, File targetFolder) { List filenamesToWrite = new LinkedList(); Map> dataToWritePerFilename = new LinkedHashMap>(); - for (JSONElement gde : altered) { + for (JSONElement gde : altered.toList()) { if (!filenamesToWrite.contains(gde.jsonFile.getName())) { filenamesToWrite.add(gde.jsonFile.getName()); } } - for (JSONElement gde : created) { + for (JSONElement gde : created.toList()) { if (!filenamesToWrite.contains(gde.jsonFile.getName())) { filenamesToWrite.add(gde.jsonFile.getName()); } } for (String fName : filenamesToWrite) { - for (JSONElement gde : source) { + for (JSONElement gde : source.toList()) { if (gde.jsonFile.getName().equals(fName)) { if (dataToWritePerFilename.get(fName) == null) { dataToWritePerFilename.put(fName, new ArrayList()); @@ -1222,7 +1222,7 @@ public class Project implements ProjectTreeNode, Serializable, JsonSerializable dataToWritePerFilename.get(fName).add(getGameDataElement(gdeClass, gde.id).toJson()); } } - for (JSONElement gde : created) { + for (JSONElement gde : created.toList()) { if (gde.jsonFile.getName().equals(fName)) { if (dataToWritePerFilename.get(fName) == null) { dataToWritePerFilename.put(fName, new ArrayList()); diff --git a/src/com/gpl/rpg/atcontentstudio/model/gamedata/GameDataCategory.java b/src/com/gpl/rpg/atcontentstudio/model/gamedata/GameDataCategory.java index 41bc63f..c50e40d 100644 --- a/src/com/gpl/rpg/atcontentstudio/model/gamedata/GameDataCategory.java +++ b/src/com/gpl/rpg/atcontentstudio/model/gamedata/GameDataCategory.java @@ -1,32 +1,115 @@ package com.gpl.rpg.atcontentstudio.model.gamedata; import com.gpl.rpg.atcontentstudio.Notification; -import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter; import com.gpl.rpg.atcontentstudio.model.*; -import com.gpl.rpg.atcontentstudio.model.GameSource.Type; import com.gpl.rpg.atcontentstudio.ui.DefaultIcons; import com.gpl.rpg.atcontentstudio.utils.FileUtils; -import org.json.simple.JSONArray; import javax.swing.tree.TreeNode; import java.awt.*; -import java.io.*; -import java.util.List; +import java.io.File; import java.util.*; +import java.util.List; -public class GameDataCategory extends ArrayList implements ProjectTreeNode, Serializable { +public class GameDataCategory implements ProjectTreeNode { + //region Data + private final ArrayList keyList = new ArrayList<>(); + private final HashMap dataMap = new HashMap<>(); + + //endregion - private static final long serialVersionUID = 5486008219704443733L; public GameDataSet parent; public String name; public GameDataCategory(GameDataSet parent, String name) { - super(); this.parent = parent; this.name = name; } + //region Helpers + public E get(String key) { + return dataMap.get(key); + } + + public E get(int index) { + String key = keyList.get(index); + return dataMap.get(key); + } + + public E getIgnoreCase(String key) { + for (String k : keyList) { + if (k.equalsIgnoreCase(key)) { + return dataMap.get(k); + } + } + return null; + } + + public E put(String key, E element) { + if (!dataMap.containsKey(key)) { + keyList.add(key); + } + return dataMap.put(key, element); + } + + public void add(E quest) { + String key = quest.id; + put(key, quest); + } + + public E remove(String key) { + if (dataMap.containsKey(key)) { + keyList.remove(key); + } + return dataMap.remove(key); + } + + public E remove(int index) { + String key = keyList.get(index); + keyList.remove(index); + return dataMap.remove(key); + } + + public boolean removeGeneric(JSONElement element){ + return remove((E) element); + } + public boolean remove(E element) { + String key = element.id; + int index = getProject().getNodeIndex(element); + boolean result = false; + if (dataMap.containsKey(key)) { + keyList.remove(key); + dataMap.remove(key); + result = true; + } + getProject().fireElementRemoved(element, index); + return result; + } + + public int size() { + return dataMap.size(); + } + public int indexOf(String key) { + return keyList.indexOf(key); + } + public int indexOf(E element) { + String key = element.id; + return keyList.indexOf(key); + } + + public ArrayList toList() { + ArrayList list = new ArrayList<>(); + for (String key : keyList) { + list.add(dataMap.get(key)); + } + return list; + } + + //endregion + + //region copied implementation of ProjectTreeNode + @Override public TreeNode getChildAt(int childIndex) { return get(childIndex); @@ -44,7 +127,7 @@ public class GameDataCategory extends ArrayList implem @Override public int getIndex(TreeNode node) { - return indexOf(node); + return indexOf((E) node); } @Override @@ -59,7 +142,7 @@ public class GameDataCategory extends ArrayList implem @Override public Enumeration children() { - return Collections.enumeration(this); + return Collections.enumeration(toList()); } @Override @@ -87,7 +170,7 @@ public class GameDataCategory extends ArrayList implem @Override public void notifyCreated() { childrenAdded(new ArrayList()); - for (E node : this) { + for (E node : dataMap.values()) { node.notifyCreated(); } } @@ -133,10 +216,15 @@ public class GameDataCategory extends ArrayList implem } @Override - public Type getDataType() { + public GameSource.Type getDataType() { return parent.getDataType(); } + @Override + public boolean isEmpty() { + return dataMap.isEmpty(); + } + @SuppressWarnings("rawtypes") public void save(File jsonFile) { if (getDataType() != GameSource.Type.created && getDataType() != GameSource.Type.altered) { @@ -144,7 +232,7 @@ public class GameDataCategory extends ArrayList implem return; } List dataToSave = new ArrayList(); - for (E element : this) { + for (E element : dataMap.values()) { if (element.jsonFile.equals(jsonFile)) { dataToSave.add(element.toJson()); } @@ -161,7 +249,7 @@ public class GameDataCategory extends ArrayList implem String toWrite = FileUtils.toJsonString(dataToSave); if(FileUtils.writeStringToFile(toWrite, jsonFile, "JSON file '"+jsonFile.getAbsolutePath()+"'")){ - for (E element : this) { + for (E element : dataMap.values()) { element.state = GameDataElement.State.saved; } } @@ -173,7 +261,8 @@ public class GameDataCategory extends ArrayList implem GameDataCategory impactedCategory = null; String impactedFileName = fileName; Map containedIds = new LinkedHashMap(); - for (JSONElement node : this) { + ArrayList list = toList(); + for (JSONElement node : list) { if (node.getDataType() == GameSource.Type.created && getProject().baseContent.gameData.getGameDataElement(node.getClass(), node.id) != null) { if (getProject().alteredContent.gameData.getGameDataElement(node.getClass(), node.id) != null) { events.add(new SaveEvent(SaveEvent.Type.moveToAltered, node, true, "Element ID matches one already present in the altered game content. Change this ID before saving.")); @@ -202,7 +291,7 @@ public class GameDataCategory extends ArrayList implem for (String key : containedIds.keySet()) { if (containedIds.get(key) > 1) { E node = null; - for (E n : this) { + for (E n : list) { if (key.equals(n.id)) { node = n; break; @@ -218,19 +307,15 @@ public class GameDataCategory extends ArrayList implem return events; } - public boolean remove(E o) { - int index = getProject().getNodeIndex(o); - boolean result = super.remove(o); - getProject().fireElementRemoved(o, index); - return result; - } - @Override public boolean needsSaving() { - for (E node : this) { + for (E node : dataMap.values()) { if (node.needsSaving()) return true; } return false; } + //endregion + } + diff --git a/src/com/gpl/rpg/atcontentstudio/model/gamedata/GameDataSet.java b/src/com/gpl/rpg/atcontentstudio/model/gamedata/GameDataSet.java index 6d1ca11..9563f8d 100644 --- a/src/com/gpl/rpg/atcontentstudio/model/gamedata/GameDataSet.java +++ b/src/com/gpl/rpg/atcontentstudio/model/gamedata/GameDataSet.java @@ -67,7 +67,7 @@ public class GameDataSet implements ProjectTreeNode, Serializable { items = new GameDataCategory(this, Item.getStaticDesc()); itemCategories = new GameDataCategory(this, ItemCategory.getStaticDesc()); npcs = new GameDataCategory(this, NPC.getStaticDesc()); - quests = new GameDataCategory(this, Quest.getStaticDesc()); + quests = new GameDataCategory<>(this, Quest.getStaticDesc()); v.add(actorConditions); v.add(dialogues); @@ -256,82 +256,42 @@ public class GameDataSet implements ProjectTreeNode, Serializable { public ActorCondition getActorCondition(String id) { if (actorConditions == null) return null; - for (ActorCondition gde : actorConditions) { - if (id.equals(gde.id)) { - return gde; - } - } - return null; + return actorConditions.get(id); } public Dialogue getDialogue(String id) { if (dialogues == null) return null; - for (Dialogue gde : dialogues) { - if (id.equals(gde.id)) { - return gde; - } - } - return null; + return dialogues.get(id); } public Droplist getDroplist(String id) { if (droplists == null) return null; - for (Droplist gde : droplists) { - if (id.equals(gde.id)) { - return gde; - } - } - return null; + return droplists.get(id); } public Item getItem(String id) { if (items == null) return null; - for (Item gde : items) { - if (id.equals(gde.id)) { - return gde; - } - } - return null; + return items.get(id); } public ItemCategory getItemCategory(String id) { if (itemCategories == null) return null; - for (ItemCategory gde : itemCategories) { - if (id.equals(gde.id)) { - return gde; - } - } - return null; + return itemCategories.get(id); } public NPC getNPC(String id) { if (npcs == null) return null; - for (NPC gde : npcs) { - if (id.equals(gde.id)) { - return gde; - } - } - return null; + return npcs.get(id); } public NPC getNPCIgnoreCase(String id) { if (npcs == null) return null; - for (NPC gde : npcs) { - if (id.equalsIgnoreCase(gde.id)) { - return gde; - } - } - return null; + return npcs.getIgnoreCase(id); } public Quest getQuest(String id) { if (quests == null) return null; - for (Quest gde : quests) { - if (id.equals(gde.id)) { - return gde; - } - } - return null; + return quests.get(id); } @Override diff --git a/src/com/gpl/rpg/atcontentstudio/model/gamedata/Quest.java b/src/com/gpl/rpg/atcontentstudio/model/gamedata/Quest.java index 77ad5b7..93d6dc7 100644 --- a/src/com/gpl/rpg/atcontentstudio/model/gamedata/Quest.java +++ b/src/com/gpl/rpg/atcontentstudio/model/gamedata/Quest.java @@ -186,5 +186,4 @@ public class Quest extends JSONElement { } return null; } - } diff --git a/src/com/gpl/rpg/atcontentstudio/model/tools/i18n/PotGenerator.java b/src/com/gpl/rpg/atcontentstudio/model/tools/i18n/PotGenerator.java index c90d8d2..ad1b954 100644 --- a/src/com/gpl/rpg/atcontentstudio/model/tools/i18n/PotGenerator.java +++ b/src/com/gpl/rpg/atcontentstudio/model/tools/i18n/PotGenerator.java @@ -19,12 +19,12 @@ public class PotGenerator { GameSource gsrc = proj.baseContent; - for (ActorCondition ac : gsrc.gameData.actorConditions) { + for (ActorCondition ac : gsrc.gameData.actorConditions.toList()) { pushString(stringsResources, resourcesStrings, ac.display_name, getPotContextComment(ac)); pushString(stringsResources, resourcesStrings, ac.description, getPotContextComment(ac) + ":description"); } - for (Dialogue d : gsrc.gameData.dialogues) { + for (Dialogue d : gsrc.gameData.dialogues.toList()) { pushString(stringsResources, resourcesStrings, d.message, getPotContextComment(d)); if (d.replies == null) continue; for (Dialogue.Reply r : d.replies) { @@ -34,20 +34,20 @@ public class PotGenerator { } } - for (ItemCategory ic : gsrc.gameData.itemCategories) { + for (ItemCategory ic : gsrc.gameData.itemCategories.toList()) { pushString(stringsResources, resourcesStrings, ic.name, getPotContextComment(ic)); } - for (Item i : gsrc.gameData.items) { + for (Item i : gsrc.gameData.items.toList()) { pushString(stringsResources, resourcesStrings, i.name, getPotContextComment(i)); pushString(stringsResources, resourcesStrings, i.description, getPotContextComment(i) + ":description"); } - for (NPC npc : gsrc.gameData.npcs) { + for (NPC npc : gsrc.gameData.npcs.toList()) { pushString(stringsResources, resourcesStrings, npc.name, getPotContextComment(npc)); } - for (Quest q : gsrc.gameData.quests) { + for (Quest q : gsrc.gameData.quests.toList()) { if (q.visible_in_log != null && q.visible_in_log != 0) { pushString(stringsResources, resourcesStrings, q.name, getPotContextComment(q)); for (QuestStage qs : q.stages) { diff --git a/src/com/gpl/rpg/atcontentstudio/model/tools/resoptimizer/ResourcesCompactor.java b/src/com/gpl/rpg/atcontentstudio/model/tools/resoptimizer/ResourcesCompactor.java index 36a6bd1..d0ab227 100644 --- a/src/com/gpl/rpg/atcontentstudio/model/tools/resoptimizer/ResourcesCompactor.java +++ b/src/com/gpl/rpg/atcontentstudio/model/tools/resoptimizer/ResourcesCompactor.java @@ -3,10 +3,7 @@ package com.gpl.rpg.atcontentstudio.model.tools.resoptimizer; import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter; import com.gpl.rpg.atcontentstudio.model.GameDataElement; import com.gpl.rpg.atcontentstudio.model.Project; -import com.gpl.rpg.atcontentstudio.model.gamedata.ActorCondition; -import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet; -import com.gpl.rpg.atcontentstudio.model.gamedata.Item; -import com.gpl.rpg.atcontentstudio.model.gamedata.NPC; +import com.gpl.rpg.atcontentstudio.model.gamedata.*; import com.gpl.rpg.atcontentstudio.model.maps.TMXMap; import com.gpl.rpg.atcontentstudio.model.maps.TMXMapSet; import com.gpl.rpg.atcontentstudio.model.sprites.SpriteSheetSet; @@ -81,12 +78,13 @@ public class ResourcesCompactor { File folder = new File(baseFolder.getAbsolutePath() + File.separator + GameDataSet.DEFAULT_REL_PATH_IN_SOURCE); if (!folder.exists()) folder.mkdirs(); - for (ActorCondition ac : proj.baseContent.gameData.actorConditions) { + ArrayList actorConditions = proj.baseContent.gameData.actorConditions.toList(); + for (ActorCondition ac : actorConditions) { if (filesCovered.contains(ac.jsonFile)) continue; File currentFile = ac.jsonFile; filesCovered.add(currentFile); List dataToSave = new ArrayList(); - for (ActorCondition acond : proj.baseContent.gameData.actorConditions) { + for (ActorCondition acond : actorConditions) { if (!acond.jsonFile.equals(currentFile)) continue; Map json = acond.toJson(); json.put("iconID", convertObjectSprite(acond.icon_id).toStringID()); @@ -96,12 +94,13 @@ public class ResourcesCompactor { writeJson(dataToSave, target); } - for (Item it : proj.baseContent.gameData.items) { + ArrayList items = proj.baseContent.gameData.items.toList(); + for (Item it : items) { if (filesCovered.contains(it.jsonFile)) continue; File currentFile = it.jsonFile; filesCovered.add(currentFile); List dataToSave = new ArrayList(); - for (Item item : proj.baseContent.gameData.items) { + for (Item item : items) { if (!item.jsonFile.equals(currentFile)) continue; Map json = item.toJson(); json.put("iconID", convertObjectSprite(item.icon_id).toStringID()); @@ -112,12 +111,13 @@ public class ResourcesCompactor { } - for (NPC np : proj.baseContent.gameData.npcs) { + ArrayList npcs = proj.baseContent.gameData.npcs.toList(); + for (NPC np : npcs) { if (filesCovered.contains(np.jsonFile)) continue; File currentFile = np.jsonFile; filesCovered.add(currentFile); List dataToSave = new ArrayList(); - for (NPC npc : proj.baseContent.gameData.npcs) { + for (NPC npc : npcs) { if (!npc.jsonFile.equals(currentFile)) continue; Map json = npc.toJson(); if (proj.getImage(npc.icon_id).getWidth(null) == TILE_WIDTH_IN_PIXELS || proj.getImage(npc.icon_id).getHeight(null) == TILE_HEIGHT_IN_PIXELS) { diff --git a/src/com/gpl/rpg/atcontentstudio/ui/SaveItemsWizard.java b/src/com/gpl/rpg/atcontentstudio/ui/SaveItemsWizard.java index 60a26f4..e8bd8c8 100644 --- a/src/com/gpl/rpg/atcontentstudio/ui/SaveItemsWizard.java +++ b/src/com/gpl/rpg/atcontentstudio/ui/SaveItemsWizard.java @@ -163,7 +163,7 @@ public class SaveItemsWizard extends JDialog { @Override public void actionPerformed(ActionEvent e) { - Map, Set> jsonToSave = new IdentityHashMap, Set>(); + Map, Set> jsonToSave = new IdentityHashMap<>(); for (SaveEvent event : movedToCreatedList) { if (event.target instanceof JSONElement) { if (!jsonToSave.containsKey(event.target.getParent())) { diff --git a/src/com/gpl/rpg/atcontentstudio/ui/WorkspaceActions.java b/src/com/gpl/rpg/atcontentstudio/ui/WorkspaceActions.java index 5679f6b..d249a5c 100644 --- a/src/com/gpl/rpg/atcontentstudio/ui/WorkspaceActions.java +++ b/src/com/gpl/rpg/atcontentstudio/ui/WorkspaceActions.java @@ -121,7 +121,7 @@ public class WorkspaceActions { if (element.getParent() instanceof GameDataCategory) { @SuppressWarnings("unchecked") GameDataCategory category = (GameDataCategory) element.getParent(); - category.remove(element); + category.remove((JSONElement) element); if (impactedCategories.get(category) == null) { impactedCategories.put(category, new HashSet()); } @@ -189,7 +189,7 @@ public class WorkspaceActions { node.childrenRemoved(new ArrayList()); if (node instanceof JSONElement) { if (node.getParent() instanceof GameDataCategory) { - ((GameDataCategory) node.getParent()).remove(node); + ((GameDataCategory) node.getParent()).removeGeneric((JSONElement) node); List events = node.attemptSave(); if (events == null || events.isEmpty()) { node.save(); diff --git a/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/JSONElementEditor.java b/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/JSONElementEditor.java index b501dba..8ad512d 100644 --- a/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/JSONElementEditor.java +++ b/src/com/gpl/rpg/atcontentstudio/ui/gamedataeditors/JSONElementEditor.java @@ -164,7 +164,7 @@ public abstract class JSONElementEditor extends Editor { ATContentStudio.frame.closeEditor(node); node.childrenRemoved(new ArrayList()); if (node.getParent() instanceof GameDataCategory) { - ((GameDataCategory) node.getParent()).remove(node); + ((GameDataCategory) node.getParent()).removeGeneric(node); node.save(); GameDataElement newOne = proj.getGameDataElement(node.getClass(), node.id); if (node instanceof Quest) {