diff --git a/AndorsTrailEdit/.project b/AndorsTrailEdit/.project
new file mode 100644
index 000000000..757e6d290
--- /dev/null
+++ b/AndorsTrailEdit/.project
@@ -0,0 +1,11 @@
+
+
+ AndorsTrailEdit
+
+
+
+
+
+
+
+
diff --git a/AndorsTrailEdit/defaultimage.png b/AndorsTrailEdit/defaultimage.png
new file mode 100644
index 000000000..b5c1fba41
Binary files /dev/null and b/AndorsTrailEdit/defaultimage.png differ
diff --git a/AndorsTrailEdit/editdialog.html b/AndorsTrailEdit/editdialog.html
new file mode 100644
index 000000000..a45577a7d
--- /dev/null
+++ b/AndorsTrailEdit/editdialog.html
@@ -0,0 +1 @@
+
Dialog Editor
\ No newline at end of file
diff --git a/AndorsTrailEdit/edititems.html b/AndorsTrailEdit/edititems.html
new file mode 100644
index 000000000..498ef975e
--- /dev/null
+++ b/AndorsTrailEdit/edititems.html
@@ -0,0 +1,57 @@
+
+
+
+
+
+
+
+
+
+ Item Editor
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AndorsTrailEdit/editmonsters.html b/AndorsTrailEdit/editmonsters.html
new file mode 100644
index 000000000..80d5a98d5
--- /dev/null
+++ b/AndorsTrailEdit/editmonsters.html
@@ -0,0 +1,92 @@
+
+
+
+
+
+
+
+
+
+ Monster Editor
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/AndorsTrailEdit/editor.js b/AndorsTrailEdit/editor.js
new file mode 100644
index 000000000..a81954904
--- /dev/null
+++ b/AndorsTrailEdit/editor.js
@@ -0,0 +1,298 @@
+
+var updatingOutput = false;
+var parsingOutput = false;
+
+function updateOutput() {
+ if (parsingOutput) return;
+ updatingOutput = true;
+ var rowcontainer = $("#datarows");
+ var op = "";
+ op += "[";
+ for (var i = 0; i < fields.length; i++) {
+ if (fields[i].type == "table") continue;
+ op += fields[i].name + "|";
+ }
+ op += "];\n";
+ $('tr', rowcontainer).each(function(i){
+ var row = $(this);
+ if (row.find("#" + fields[0].name).size() == 0) return;
+ op += "{";
+ for (var i = 0; i < fields.length; i++) {
+ row.find("#" + fields[i].name).each(function() { op += $(this).val() + "|"; });
+ }
+ op += "};\n";
+ });
+ $("#result").val(op);
+ updatingOutput = false;
+}
+
+var parse_currentRow;
+var parse_fieldDef;
+
+function parseLine(_, line) {
+ var match = line.match(/(.*?)\|/gm);
+ if (match.length != parse_fieldDef.length) {
+ alert("ERROR: Cannot parse row, expected " + parse_fieldDef.length + " fields, but found " + match.length + " fields.");
+ return;
+ }
+ for (var i = 0; i < match.length; i++) {
+ fields[parse_fieldDef[i]].value = match[i].replace(/\|/, '');
+ }
+ addRow();
+}
+
+function parseFieldDef(str) {
+ var fielddef = str.match(/\[(.+?)\];/gm);
+ parse_fieldDef = [];
+ if (fielddef && fielddef.length >= 1) {
+ fielddef = fielddef[0].match(/(.*?)\|/gm);
+ for (var i = 0; i < fielddef.length; i++) {
+ var fieldname = fielddef[i].replace(/[\[\]\|]/g, '');
+ for (var j = 0; j < fields.length; j++) {
+ if (fields[j].name == fieldname) {
+ parse_fieldDef[i] = j;
+ break;
+ }
+ }
+ }
+ } else {
+ for (var i = 0; i < fields.length; i++) {
+ parse_fieldDef[i] = i;
+ }
+ }
+}
+
+function parseOutput() {
+ if (updatingOutput) return;
+ parsingOutput = true;
+ $("#datarows").html("");
+ var str = $("#result").val();
+ parseFieldDef(str);
+ str.replace(/\{(.+?)\};/gm, parseLine);
+ parsingOutput = false;
+}
+
+function createField(field) {
+ if (field.value == undefined) field.value = "";
+ return "" + eval("createField_" + field.type + "(field);") + " ";
+}
+
+function createTextField(field, size) {
+ return " ";
+}
+
+function createField_multiline(field) {
+ return "";
+}
+function createField_longtext(field) { return createTextField(field, 20); }
+function createField_text(field) { return createTextField(field, 10); }
+function createField_size(field) { return createTextField(field, 5); }
+function createField_range(field) { return createTextField(field, 5); }
+function createField_int(field) { return createTextField(field, 3); }
+function createField_table(field) {
+ var result = "";
+ for (var i = 0; i < field.fields.length; i++) {
+ result += "" + field.fields[i].name + " ";
+ }
+ result += " ";
+ for (var j = 0; j < field.length; j++) {
+ result += "";
+ for (var i = 0; i < field.fields.length; i++) {
+ var f = fields[field.startindex + (j * field.fields.length) + i];
+ result += createField(f);
+ }
+ result += " ";
+ }
+ result += "
";
+ return result;
+}
+
+function createField_image(field) {
+ return "
";
+}
+
+function createField_select(field) {
+ var result = "";
+ for (var i = 0; i < field.values.length; i++) {
+ var value = field.values[i];
+ var name = value;
+ var v = value.split(':');
+ if (v.length >= 2) {
+ name = v[0];
+ value = v[1];
+ }
+ result += "" + name + " ";
+ }
+ result += " ";
+ return result;
+}
+
+function parseimageid(str) {
+ var defaultimage = {image: "defaultimage", lid: 0, path: '' };
+ if (str == null || str == "") return defaultimage;
+ var v = str.split(":");
+ if (v.length < 1) return defaultimage;
+ return {image: v[0], lid: v[1], path: imagepath };
+}
+function genimageid(v) {
+ if (v == null) return "";
+ return v.image + ":" + v.lid;
+}
+
+var currentIcon;
+
+function selectimage(v) {
+ currentIcon = $(this);
+ $( "#selecticon_dialog" ).dialog("open");
+}
+
+function findTileImage(name) {
+ for (var i = 0; i < tileimages.length; i++) {
+ if (tileimages[i].name == name) {
+ return tileimages[i];
+ }
+ }
+ return 0;
+}
+
+function updateImageFromFormField(control) {
+ var imagestruct = parseimageid($(control).find("input").val());
+ var sourceimage = findTileImage(imagestruct.image);
+ var x = -(imagestruct.lid % sourceimage.numtilesx) * sourceimage.tilesizex;
+ var y = -Math.floor(imagestruct.lid / sourceimage.numtilesx) * sourceimage.tilesizey;
+ control.css({"background-image": "url(" +imagestruct.path + imagestruct.image + ".png)", "background-position": x+"px " + y+"px"});
+}
+
+function setSelectedImage(control, imagestruct) {
+ $(control).find("input").val(genimageid(imagestruct));
+ updateImageFromFormField(control);
+ $(control).change();
+}
+
+function addDefaultRow() {
+ for (var i = 0; i < fields.length; i++) {
+ fields[i].value = fields[i].default;
+ }
+ addRow();
+}
+function addNameRow(tagname) {
+ var result = "";
+ for (var i = 0; i < fields.length; i++) {
+ if (!fields[i].hide) {
+ result += "<" + tagname + ">" + fields[i].name + "" + tagname + ">";
+ }
+ }
+ return result;
+}
+
+function addRow() {
+ var str = "";
+ for (var i = 0; i < fields.length; i++) {
+ if (!fields[i].hide) {
+ str += createField(fields[i]);
+ }
+ }
+ $("#datarows").append("" + str + " ");
+ $("#datarows").find(".selectimage").click(selectimage);
+ $("#datarows").find(".selectimage").each(function() { updateImageFromFormField($(this)); });
+
+ if ($("#datarows > tr").size() % 10 == 0) {
+ $("#datarows").append("" + addNameRow("td") + " ");
+ }
+ $("#datarows").change();
+
+}
+
+function explodeTableFields() {
+ var moreFields = [];
+ for (var n = 0; n < fields.length; n++) {
+ var field = fields[n];
+ if (field.type == "table") {
+ field.startindex = fields.length;
+ for (var j = 0; j < field.length; j++) {
+ for (var i = 0; i < field.fields.length; i++) {
+ var f = jQuery.extend(true, {}, field.fields[i]); // Deep copy
+ f.hide = 1;
+ f.name += j;
+ fields.push(f);
+ }
+ }
+ }
+ }
+}
+
+$(document).ready(function() {
+ explodeTableFields();
+
+ $("#result").resizable();
+ $("#inputarea").resizable();
+
+ var headerrow = $("#headerrow");
+ headerrow.append(addNameRow("th"));
+
+ var hasWarning = false;
+ for (var i = 0; i < tileimages.length; i++) {
+ tileimages[i].url = imagepath + tileimages[i].name + ".png";
+ var img = new Image();
+ img.src = tileimages[i].url;
+ tileimages[i].imgwidth = img.width;
+ tileimages[i].imgheight = img.height;
+ if (!hasWarning && (tileimages[i].imgwidth <= 0 || tileimages[i].imgheight <= 0)) {
+ alert("WARNING: could not load tile image " + tileimages[i].url + " . You may need to reload the page once.");
+ hasWarning = true;
+ }
+ tileimages[i].tilesizex = Math.floor(tileimages[i].imgwidth / tileimages[i].numtilesx);
+ tileimages[i].tilesizey = Math.floor(tileimages[i].imgheight / tileimages[i].numtilesy);
+
+ $("#selecticon_dialog_tileset").append(" ");
+ }
+
+ $("#selecticon_dialog_tileset img").each(function() {
+ var img = findTileImage($(this).attr("id"));
+ $(this).click(function(e) {
+ var x = e.pageX - $(this).offset().left;
+ var y = e.pageY - $(this).offset().top;
+ setSelectedImage(currentIcon, {
+ image: img.name,
+ lid: Math.floor(x / img.tilesizex) + img.numtilesx * Math.floor(y / img.tilesizey)
+ });
+ $( "#selecticon_dialog" ).dialog("close");
+ });
+ });
+
+ $( "#selecticon_dialog" ).dialog({
+ autoOpen: false,
+ modal: true,
+ width: 600,
+ height: 800,
+ position: [50,50],
+ buttons: {
+ Cancel: function() {
+ $( this ).dialog( "close" );
+ }
+ }
+ });
+
+ $("#buttons").append(" ");
+ $("#newrow").click(addDefaultRow).click();
+
+ $("#buttons").append("Auto update output ");
+ $("#autooutput").change(function() {
+ if ($(this).attr('checked')) {
+ $("#datarows").change(updateOutput);
+ $("#result").change(parseOutput);
+ } else {
+ $("#datarows").unbind("change");
+ $("#result").unbind("change");
+ }
+ }).change();
+
+ $("#datarows").sortable();
+
+ //$("#updateoutput").click(updateOutput);
+ //$("#parseoutput").click(parseOutput);
+});
diff --git a/AndorsTrailEdit/styles.css b/AndorsTrailEdit/styles.css
new file mode 100644
index 000000000..3bda589e3
--- /dev/null
+++ b/AndorsTrailEdit/styles.css
@@ -0,0 +1,22 @@
+#inputarea {
+ height: 500px;
+ overflow: auto;
+}
+.rowdiv {
+
+}
+.selectimage {
+ width: 32px;
+ height: 32px;
+}
+#invisible {
+ display: none;
+}
+#datatable td {
+ padding: 2px 10px 2px 10px;
+ border-bottom: 1px black solid;
+ background-color: #dddddd;
+}
+.editorbutton {
+ margin-right: 20px;
+}