From 515f38e52100eac09275f0821e93e0eaf3e2cc3c Mon Sep 17 00:00:00 2001 From: Jared Adams Date: Tue, 11 Nov 2008 14:39:23 +0000 Subject: Add a tool to convert from TMWServ format This tool will convert warps and monster spawns from TMWServ format (tmx files) into eAthena format. It will also generate the wlk files needed by eAthena. --- tools/tmwcon/MANIFEST.MF | 1 + tools/tmwcon/build.xml | 31 ++++++ tools/tmwcon/src/Converter.java | 51 +++++++++ tools/tmwcon/src/converter/Main.java | 86 +++++++++++++++ tools/tmwcon/src/converter/Process.java | 158 +++++++++++++++++++++++++++ tools/tmwcon/src/converter/WLKInterface.java | 31 ++++++ tools/tmwcon/usage | 0 7 files changed, 358 insertions(+) create mode 100644 tools/tmwcon/MANIFEST.MF create mode 100755 tools/tmwcon/build.xml create mode 100644 tools/tmwcon/src/Converter.java create mode 100644 tools/tmwcon/src/converter/Main.java create mode 100644 tools/tmwcon/src/converter/Process.java create mode 100644 tools/tmwcon/src/converter/WLKInterface.java create mode 100644 tools/tmwcon/usage diff --git a/tools/tmwcon/MANIFEST.MF b/tools/tmwcon/MANIFEST.MF new file mode 100644 index 00000000..954575d7 --- /dev/null +++ b/tools/tmwcon/MANIFEST.MF @@ -0,0 +1 @@ +Main-Class: converter.Main diff --git a/tools/tmwcon/build.xml b/tools/tmwcon/build.xml new file mode 100755 index 00000000..6edf8477 --- /dev/null +++ b/tools/tmwcon/build.xml @@ -0,0 +1,31 @@ + + + A tool to convert map data from TMWServ format to eAthena format + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/tmwcon/src/Converter.java b/tools/tmwcon/src/Converter.java new file mode 100644 index 00000000..546d5e7b --- /dev/null +++ b/tools/tmwcon/src/Converter.java @@ -0,0 +1,51 @@ +// + +import java.io.*; +import java.lang.reflect.*; +import java.net.*; +import java.util.*; + +public abstract class Converter { + static String[] tiledJars = {"tile-core.jar", "tiled.jar"}; + static String[] wlkJars = {"plugins/tmw.jar", "tmw.jar"}; + + public static void main(String[] args) throws Exception { + List urls = new ArrayList(); + + File tiled = null; + for (String s : tiledJars) { + tiled = new File(s); + if (tiled.exists()) break; + } + if (tiled == null || !tiled.exists()) { + System.err.println("Unable to find a Tiled jar file! Exiting."); + System.exit(-5); + } + urls.add(tiled.toURI().toURL()); + + File wlkWriter = null; + for (String s : wlkJars) { + wlkWriter = new File(s); + if (wlkWriter.exists()) break; + } + if (wlkWriter == null || !wlkWriter.exists()) { + System.err.println("Unable to find the tmw plugin for Tiled! No wlk files will be made!"); + } else { + urls.add(wlkWriter.toURI().toURL()); + } + + File self = new File("converter.jar"); + if (!self.exists()) { + System.err.println("Unable to find a the converter jar! Exiting."); + System.exit(-5); + } + urls.add(self.toURI().toURL()); + + URLClassLoader loader = new URLClassLoader(urls.toArray(new URL[0])); + Class c = loader.loadClass("converter.Main"); + Method m = c.getMethod("run", String[].class, Integer.TYPE); + System.out.println("Starting"); + + m.invoke(null, args, 0); + } +} diff --git a/tools/tmwcon/src/converter/Main.java b/tools/tmwcon/src/converter/Main.java new file mode 100644 index 00000000..4f3a6947 --- /dev/null +++ b/tools/tmwcon/src/converter/Main.java @@ -0,0 +1,86 @@ +// + +package converter; + +import java.io.*; +import java.util.*; + +import tiled.io.xml.*; + +public class Main extends Thread { + public static XMLMapTransformer reader = null; + + private static tiled.core.Map loadMap(File file) { + tiled.core.Map map = null; + try { + map = reader.readMap(file.getAbsolutePath()); + } catch (Exception e) { + e.printStackTrace(); + } + + return map; + } + + public static boolean isTMX(File in) { + if (in.isDirectory()) return false; + + return in.getName().matches(".*\\.tmx(\\.gz)?$"); + } + + public static Collection getTMXFiles(File directory) { + if (!directory.isDirectory()) return Collections.emptyList(); + + List ret = new Vector(); + + for (File f : directory.listFiles()) { + if (f.isDirectory()) { + ret.addAll(getTMXFiles(f)); + } else if (isTMX(f)) { + ret.add(f); + } + } + + return ret; + } + + public static PrintWriter getWriter(File f) { + try { + f.createNewFile(); + return new PrintWriter(f); + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + public static String getName(File folder, File file) { + String path = folder.getAbsolutePath(); + String name = file.getAbsolutePath(); + if (name.startsWith(path)) name = name.substring(path.length() + 1); + if (name.endsWith(".gz")) name = name.substring(0, name.length() - 3); + if (name.endsWith(".tmx")) name = name.substring(0, name.length() - 4); + return name; + } + + public static void run(String[] args, int unused) { + reader = new XMLMapTransformer(); + + File folder = new File("server-data/data/"); + Process.prepWLK(folder); + + folder = new File("tmwdata/maps/"); + + Collection tmxs = getTMXFiles(folder); + String name; + for (File f : tmxs) { + name = getName(folder, f); + System.out.printf("== %s ==\n", name); + Process.processMap(name, loadMap(f)); + } + } + + public static void main(String[] args) { + run(args, 0); + } +} diff --git a/tools/tmwcon/src/converter/Process.java b/tools/tmwcon/src/converter/Process.java new file mode 100644 index 00000000..b7fafbf5 --- /dev/null +++ b/tools/tmwcon/src/converter/Process.java @@ -0,0 +1,158 @@ +// + +package converter; + +import java.awt.*; +import java.io.*; +import java.util.Iterator; +import java.util.Properties; +import java.util.TreeSet; + +import tiled.core.*; +import tiled.plugins.tmw.*; + +public class Process { + private static WLKInterface wlk = null; + + public static void prepWLK(File folder) { + try { + wlk = new WLKInterface(folder); + } catch (NoClassDefFoundError ncdfe) {} + } + + private static String getProp(Properties props, String name, String def) { + if (name == null) return def; + for (java.util.Map.Entry entry : props.entrySet()) { + if (name.equalsIgnoreCase(entry.getKey().toString())) { + return entry.getValue().toString(); + } + } + return def; + } + + private static int getProp(Properties props, String name, int def) { + if (name == null) return def; + try { + return Integer.parseInt(getProp(props, name, "?")); + } catch (Exception e) {} + return def; + } + + private static int[] resolveBounds(Rectangle in, boolean warp) { + int x = in.x / 32; + int y = in.y / 32; + int width = in.width / 32; + int height = in.height / 32; + if (!warp) { + if (width > 1) --width; + if (height > 1) --height; + } + x += width / 2; + y += height / 2; + if (warp) { + width -= 2; + height -= 2; + } + return new int[]{x, y, width, height}; + } + + private static void handleWarp(PrintWriter out, String map, String name, Rectangle bounds, Properties props) { + if (out == null) return; + String dest = getProp(props, "dest_map", null); + if (dest == null) return; + int x = getProp(props, "dest_x", -1); + if (x < 0) return; + int y = getProp(props, "dest_y", -1); + if (y < 0) return; + int[] shape = resolveBounds(bounds, true); + System.out.printf("Usable warp found: %s\n", name); + out.printf("%s.gat,%d,%d\twarp\t%s\t%d,%d,%s.gat,%d,%d\n", map, shape[0], shape[1], name, shape[2], shape[3], dest, x / 32, y / 32); + } + + private static int handleMob(PrintWriter out, String map, String name, Rectangle bounds, Properties props) { + if (out == null) return -1; + int mob = getProp(props, "monster_id", -1); + if (mob < 0) return -1; + mob += 1002; + int max = getProp(props, "max_beings", 1); + int time1 = getProp(props, "eA_spawn", 0); + int time2 = getProp(props, "eA_death", 0); + int[] shape = resolveBounds(bounds, false); + System.out.printf("Usable mob found: %s (%d)\n", name, mob); + out.printf("%s.gat,%d,%d,%d,%d\tmonster\t%s\t%d,%d,%d,%d,Mob%s::On%d\n", map, shape[0], shape[1], shape[2], shape[3], name, mob, max, time1, time2, map, mob); + return mob; + } + + private static void processObject(MapObject mo, String map, PrintWriter warpOut, PrintWriter mobOut, TreeSet mobs) { + if (mo == null) return; + String name = mo.getName(); + String type = mo.getType(); + Rectangle bounds = new Rectangle(mo.getBounds()); + Properties props = mo.getProperties(); + + if (type.equalsIgnoreCase("warp")) { + handleWarp(warpOut, map, name, bounds, props); + } else if (type.equalsIgnoreCase("spawn")) { + mobs.add(handleMob(mobOut, map, name, bounds, props)); + } + } + + private static void processObjects(Iterator objs, String map, PrintWriter warpOut, PrintWriter mobOut, TreeSet mobs) { + MapObject mo; + while (objs.hasNext()) { + mo = objs.next(); + if (mo == null) continue; + processObject(mo, map, warpOut, mobOut, mobs); + } + } + + public static void processMap(String name, Map map) { + if (name == null) return; + if (map == null) return; + + Properties props = map.getProperties(); + String title = getProp(props, "name", ""); + String folderName = "server-data/npc/" + name; + if (title.length() > 0) { + folderName += "_" + title.replaceAll("\\s", "_"); + title = name + " " + title; + } else { + title = name; + } + + System.out.println(title); + + if (wlk != null) wlk.write(name, map); + + File folder = new File(folderName); + folder.mkdirs(); + PrintWriter warpOut = Main.getWriter(new File(folder, "passages.txt")); + PrintWriter mobOut = Main.getWriter(new File(folder, "mobs.txt")); + + warpOut.printf("// %s warps\n\n", title); + mobOut.printf("// %s mobs\n\n", title); + + TreeSet mobs = new TreeSet(); + processObjects(map.getObjects(), name, warpOut, mobOut, mobs); + for (MapLayer layer : map) { + if (layer instanceof ObjectGroup) { + processObjects(((ObjectGroup) layer).getObjects(), name, warpOut, mobOut, mobs); + } + } + + warpOut.flush(); + warpOut.close(); + + System.out.println("Starting mob points"); + mobOut.printf("\n\n%s.gat,0,0,0\tscript\tMob%1$s\t-1,{\n", name); + for (int mob : mobs) { + if (mob == -1) continue; + mobOut.printf("On%d:\n\tset @mobID, %d;\n\tcallfunc \"MobPoints\";\n\tbreak;\n\n", mob, mob); + } + mobOut.printf("\tend;\n}\n"); + System.out.println("Finished mob points"); + + mobOut.flush(); + mobOut.close(); + } +} diff --git a/tools/tmwcon/src/converter/WLKInterface.java b/tools/tmwcon/src/converter/WLKInterface.java new file mode 100644 index 00000000..da60c688 --- /dev/null +++ b/tools/tmwcon/src/converter/WLKInterface.java @@ -0,0 +1,31 @@ +// + +package converter; + +import java.io.*; + +import tiled.core.*; +import tiled.plugins.tmw.*; + +public class WLKInterface { + private File folder; + public WLKInterface(File folder) { + WLKWriter.class.getName(); + this.folder = folder; + File f = new File("server-data/data"); + f.mkdirs(); + } + + public void write(String name, Map map) { + File wlk = new File(folder, name + ".wlk"); + + try { + wlk.createNewFile(); + WLKWriter.writeMap(map, new FileOutputStream(wlk)); + System.out.println("WLK written"); + } catch (Exception e) { + System.out.println("Prolem writing WLK file:"); + e.printStackTrace(); + } + } +} diff --git a/tools/tmwcon/usage b/tools/tmwcon/usage new file mode 100644 index 00000000..e69de29b -- cgit v1.2.3-60-g2f50