First drafts of "Writer Mode".

Some bug fixes.
This commit is contained in:
Zukero
2016-09-16 15:23:00 +02:00
parent ce908f0033
commit c18ff9d2b4
14 changed files with 1851 additions and 17 deletions

View File

@@ -31,6 +31,7 @@ import com.gpl.rpg.atcontentstudio.model.maps.Worldmap;
import com.gpl.rpg.atcontentstudio.model.maps.WorldmapSegment;
import com.gpl.rpg.atcontentstudio.model.sprites.SpriteSheetSet;
import com.gpl.rpg.atcontentstudio.model.sprites.Spritesheet;
import com.gpl.rpg.atcontentstudio.model.tools.WriterModeDataSet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
public class GameSource implements ProjectTreeNode, Serializable {
@@ -44,6 +45,7 @@ public class GameSource implements ProjectTreeNode, Serializable {
public transient TMXMapSet gameMaps;
public transient SpriteSheetSet gameSprites;
public transient Worldmap worldmap;
public transient WriterModeDataSet writerModeDataSet;
private transient SavedSlotCollection v;
public static enum Type {
@@ -86,6 +88,9 @@ public class GameSource implements ProjectTreeNode, Serializable {
readResourceList();
}
}
if (type == Type.created) {
this.writerModeDataSet = new WriterModeDataSet(this);
}
this.gameData = new GameDataSet(this);
this.gameMaps = new TMXMapSet(this);
this.gameSprites = new SpriteSheetSet(this);
@@ -95,6 +100,9 @@ public class GameSource implements ProjectTreeNode, Serializable {
v.add(gameMaps);
v.add(gameSprites);
v.add(worldmap);
if (type == Type.created) {
v.add(writerModeDataSet);
}
}
public void readResourceList() {

View File

@@ -247,7 +247,7 @@ public class Dialogue extends JSONElement {
case spawnAll:
case removeSpawnArea:
case deactivateSpawnArea:
reward.map = proj.getMap(reward.map_name);
reward.map = reward.map_name != null ? proj.getMap(reward.map_name) : null;
break;
case actorCondition:
reward.reward_obj = proj.getActorCondition(reward.reward_obj_id);
@@ -315,6 +315,11 @@ public class Dialogue extends JSONElement {
if (rclone.reward_obj != null) {
rclone.reward_obj.addBacklink(clone);
}
rclone.map = r.map;
rclone.map_name = r.map_name;
if (rclone.map != null) {
rclone.map.addBacklink(clone);
}
clone.rewards.add(rclone);
}
}

View File

@@ -0,0 +1,251 @@
package com.gpl.rpg.atcontentstudio.model.tools;
import java.awt.Image;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.swing.tree.TreeNode;
import com.gpl.rpg.atcontentstudio.model.GameDataElement.State;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.SaveEvent;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.model.tools.WriterModeData.WriterDialogue;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
public class WriterModeData extends GameDataElement {
public WriterModeDataSet parent;
public Image npcIcon;
public WriterDialogue begin;
public Map<String, WriterDialogue> dialogueThreads = new LinkedHashMap<String, WriterDialogue>();
public Map<String, Integer> threadsNextIndex = new LinkedHashMap<String, Integer>();
public WriterModeData(WriterModeDataSet parent, String id_prefix){
this.parent = parent;
this.begin = new WriterDialogue();
begin.id_prefix = id_prefix;
begin.index = getNextIndex(id_prefix);
begin.text = "";
}
public WriterModeData(WriterModeDataSet parent, Map jsonObj) {
this.parent = parent;
this.begin = new WriterDialogue(jsonObj);
this.state = State.parsed;
}
public int getNextIndex(String id_prefix) {
Integer index = threadsNextIndex.get(id_prefix);
if (index == null) index = 0;
while (getProject().getDialogue(id_prefix+index) != null) {
index++;
}
threadsNextIndex.put(id_prefix, index + 1);
return index;
}
public abstract class WriterNode {
public String text;
public abstract String getTitle();
public abstract Map toJson();
}
public class WriterDialogue extends WriterNode {
public String id_prefix;
public int index;
public List<WriterReply> replies = new LinkedList<WriterReply>();
public WriterDialogue() {}
public WriterDialogue(String id_prefix) {
text = "";
this.id_prefix = id_prefix;
index = getNextIndex(id_prefix);
}
@Override
public String getTitle() {
return "Dialogue "+id_prefix+index;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public Map toJson() {
Map dialogueJson = new HashMap();
dialogueJson.put("id_prefix", id_prefix);
dialogueJson.put("index", index);
dialogueJson.put("text", text);
if (!replies.isEmpty()) {
List repliesJson = new ArrayList();
for (WriterReply reply : replies) {
repliesJson.add(reply.toJson());
}
dialogueJson.put("replies", repliesJson);
}
return dialogueJson;
}
public WriterDialogue(Map json) {
this.index = Integer.parseInt((String) json.get("index"));
this.id_prefix = (String) json.get("id_prefix");
this.text = (String) json.get("text");
List repliesJson = (List) json.get("replies");
for (Object rJson : repliesJson) {
this.replies.add(new WriterReply(this, (Map)rJson));
}
}
}
public class SpecialDialogue extends WriterDialogue {}
public class SelectorDialogue extends SpecialDialogue {}
public class ShopDialogue extends SpecialDialogue {}
public class FightDialogue extends SpecialDialogue {}
public class EndDialogue extends SpecialDialogue {}
public class WriterReply extends WriterNode {
public WriterDialogue parent;
public WriterDialogue next_dialogue;
public WriterReply() {}
public WriterReply(WriterDialogue parent) {
this.parent = parent;
this.text = "";
parent.replies.add(this);
}
public WriterReply(WriterDialogue parent, Map json) {
this.parent = parent;
this.text = (String) json.get("text");
if (json.containsKey("next_dialogue")) {
next_dialogue = new WriterDialogue((Map) json.get("next_dialogue"));
}
}
@Override
public String getTitle() {
return "Reply in "+parent.id_prefix+parent.index;
}
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public Map toJson() {
Map replyJson = new HashMap();
replyJson.put("text", text);
if (next_dialogue != null) {
replyJson.put("next_dialogue", next_dialogue.toJson());
}
return replyJson;
}
}
public class SpecialReply extends WriterReply {
public SpecialReply(WriterDialogue parent) {
super(parent);
}
}
public class EmptyReply extends SpecialReply {
public EmptyReply(WriterDialogue parent) {
super(parent);
}
}
@Override
public String getDesc() {
return (this.state == State.modified ? "*" : "")+begin.id_prefix;
}
@Override
public Project getProject() {
return parent.getProject();
}
@Override
public Image getIcon() {
return DefaultIcons.getDialogueIcon();
}
@Override
public Image getOpenIcon() {
return null;
}
@Override
public Image getClosedIcon() {
return null;
}
@Override
public Image getLeafIcon() {
return getIcon();
}
@Override
public GameDataSet getDataSet() {
return null;
}
@Override
public void parse() {
// TODO
}
@Override
public void link() {
//Useless here.
}
@Override
public GameDataElement clone() {
//TODO
return null;
}
@Override
public void elementChanged(GameDataElement oldOne, GameDataElement newOne) {
// Useless here.
}
@Override
public String getProjectFilename() {
return WriterModeDataSet.DEFAULT_REL_PATH_IN_PROJECT;
}
@Override
public void save() {
parent.save();
}
@Override
public List<SaveEvent> attemptSave() {
List<SaveEvent> events = parent.attemptSave();
if (events == null || events.isEmpty()) {
return null;
}
if (events.size() == 1 && events.get(0).type == SaveEvent.Type.alsoSave && events.get(0).target == this) {
save();
return null;
}
return events;
}
@SuppressWarnings("rawtypes")
public Map toJson() {
return begin.toJson();
}
}

View File

@@ -0,0 +1,233 @@
package com.gpl.rpg.atcontentstudio.model.tools;
import java.awt.Image;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Serializable;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.swing.tree.TreeNode;
import org.json.simple.JSONArray;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
import com.gpl.rpg.atcontentstudio.Notification;
import com.gpl.rpg.atcontentstudio.io.JsonPrettyWriter;
import com.gpl.rpg.atcontentstudio.model.GameDataElement.State;
import com.gpl.rpg.atcontentstudio.model.GameSource;
import com.gpl.rpg.atcontentstudio.model.GameSource.Type;
import com.gpl.rpg.atcontentstudio.model.GameDataElement;
import com.gpl.rpg.atcontentstudio.model.Project;
import com.gpl.rpg.atcontentstudio.model.ProjectTreeNode;
import com.gpl.rpg.atcontentstudio.model.SaveEvent;
import com.gpl.rpg.atcontentstudio.model.gamedata.GameDataSet;
import com.gpl.rpg.atcontentstudio.ui.DefaultIcons;
public class WriterModeDataSet implements ProjectTreeNode, Serializable {
private static final long serialVersionUID = 5434504851883441971L;
public static final String DEFAULT_REL_PATH_IN_PROJECT = "writer.json";
public GameSource parent;
public File writerFile;
List<WriterModeData> writerModeDataList = new LinkedList<WriterModeData>();
public WriterModeDataSet(GameSource gameSource) {
this.parent = gameSource;
writerFile = new File(parent.baseFolder, DEFAULT_REL_PATH_IN_PROJECT);
parse();
}
@Override
public TreeNode getChildAt(int childIndex) {
return null;
}
@Override
public int getChildCount() {
return writerModeDataList.size();
}
@Override
public TreeNode getParent() {
return parent;
}
@Override
public int getIndex(TreeNode node) {
return writerModeDataList.indexOf(node);
}
@Override
public boolean getAllowsChildren() {
return true;
}
@Override
public boolean isLeaf() {
return false;
}
@Override
public Enumeration children() {
return Collections.enumeration(writerModeDataList);
}
@Override
public void childrenAdded(List<ProjectTreeNode> path) {
path.add(0,this);
parent.childrenAdded(path);
}
@Override
public void childrenChanged(List<ProjectTreeNode> path) {
path.add(0,this);
parent.childrenChanged(path);
}
@Override
public void childrenRemoved(List<ProjectTreeNode> path) {
path.add(0,this);
parent.childrenRemoved(path);
}
@Override
public void notifyCreated() {
childrenAdded(new ArrayList<ProjectTreeNode>());
}
@Override
public String getDesc() {
return "Dialogue sketchs";
}
@Override
public Project getProject() {
return parent.getProject();
}
@Override
public GameDataSet getDataSet() {
return null;
}
@Override
public Image getIcon() {
return DefaultIcons.getStdClosedIcon();
}
@Override
public Image getOpenIcon() {
return DefaultIcons.getStdOpenIcon();
}
@Override
public Image getClosedIcon() {
return DefaultIcons.getStdClosedIcon();
}
@Override
public Image getLeafIcon() {
return null;
}
@Override
public Type getDataType() {
return parent.getDataType();
}
@Override
public boolean isEmpty() {
return writerModeDataList.isEmpty();
}
@SuppressWarnings("rawtypes")
public void save() {
List<Map> dataToSave = new LinkedList<Map>();
for (WriterModeData data : writerModeDataList) {
dataToSave.add(data.toJson());
}
if (dataToSave.isEmpty() && writerFile.exists()) {
if (writerFile.delete()) {
Notification.addSuccess("File "+writerFile.getAbsolutePath()+" deleted.");
} else {
Notification.addError("Error deleting file "+writerFile.getAbsolutePath());
}
return;
}
StringWriter writer = new JsonPrettyWriter();
try {
JSONArray.writeJSONString(dataToSave, writer);
} catch (IOException e) {
//Impossible with a StringWriter
}
String toWrite = writer.toString();
try {
FileWriter w = new FileWriter(writerFile);
w.write(toWrite);
w.close();
for (WriterModeData element : writerModeDataList) {
element.state = GameDataElement.State.saved;
}
Notification.addSuccess("Json file "+writerFile.getAbsolutePath()+" saved.");
} catch (IOException e) {
Notification.addError("Error while writing json file "+writerFile.getAbsolutePath()+" : "+e.getMessage());
e.printStackTrace();
}
}
public List<SaveEvent> attemptSave() {
List<SaveEvent> events = new LinkedList<SaveEvent>();
for (WriterModeData data : writerModeDataList) {
if (data.state == State.created || data.state == State.modified) {
events.add(new SaveEvent(SaveEvent.Type.alsoSave, data));
}
}
return events;
}
public void parse() {
if (!writerFile.exists()) return;
JSONParser parser = new JSONParser();
FileReader reader = null;
try {
reader = new FileReader(writerFile);
List writerDataListJson = (List) parser.parse(reader);
for (Object obj : writerDataListJson) {
Map jsonObj = (Map)obj;
writerModeDataList.add(new WriterModeData(this, jsonObj));
}
} catch (FileNotFoundException e) {
Notification.addError("Error while parsing JSON file "+writerFile.getAbsolutePath()+": "+e.getMessage());
e.printStackTrace();
} catch (IOException e) {
Notification.addError("Error while parsing JSON file "+writerFile.getAbsolutePath()+": "+e.getMessage());
e.printStackTrace();
} catch (ParseException e) {
Notification.addError("Error while parsing JSON file "+writerFile.getAbsolutePath()+": "+e.getMessage());
e.printStackTrace();
} finally {
if (reader != null)
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}