summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Longbons <b.r.longbons@gmail.com>2012-07-11 14:16:02 -0700
committerBen Longbons <b.r.longbons@gmail.com>2012-07-19 11:04:33 -0700
commita08660ca24cc18778ad929eb5a79453ba37d232e (patch)
tree3a89c50ddb54959b661e70802eb71ca77bce7216
parentfb3b066e0b99900b0dff319ef9ca8776d9d26a64 (diff)
downloadclassic-serverdata-a08660ca24cc18778ad929eb5a79453ba37d232e.tar.gz
classic-serverdata-a08660ca24cc18778ad929eb5a79453ba37d232e.tar.bz2
classic-serverdata-a08660ca24cc18778ad929eb5a79453ba37d232e.tar.xz
classic-serverdata-a08660ca24cc18778ad929eb5a79453ba37d232e.zip
Add a tmx-to-wlk converter that handles CSV (in Python), and run it.
Some of the _mobs files changed due to bugs in the maps, which I fixed. Remove the old Java version.
-rw-r--r--GNUmakefile4
m---------client-data0
-rw-r--r--tools/tmwcon/.gitignore2
-rw-r--r--tools/tmwcon/MANIFEST.MF3
-rw-r--r--tools/tmwcon/README11
-rwxr-xr-xtools/tmwcon/build.xml30
-rw-r--r--tools/tmwcon/src/converter/Main.java103
-rw-r--r--tools/tmwcon/src/converter/Process.java246
-rw-r--r--tools/tmwcon/src/converter/WLKInterface.java31
-rw-r--r--tools/tmwcon/tiled-core.jarbin52337 -> 0 bytes
-rw-r--r--tools/tmwcon/tmw.jarbin2764 -> 0 bytes
-rwxr-xr-xtools/tmx_converter.py303
-rw-r--r--world/map/npc/003-1/_mobs.txt6
-rw-r--r--world/map/npc/006-3/_mobs.txt4
-rw-r--r--world/map/npc/013-3/_mobs.txt31
-rw-r--r--world/map/npc/017-1/_mobs.txt23
-rw-r--r--world/map/npc/025-3/_mobs.txt2
-rw-r--r--world/map/npc/025-4/_mobs.txt4
-rw-r--r--world/map/npc/028-3/_mobs.txt2
-rw-r--r--world/map/npc/046-1/_mobs.txt6
-rw-r--r--world/map/npc/047-1/_mobs.txt6
-rw-r--r--world/map/npc/048-1/_mobs.txt6
22 files changed, 350 insertions, 473 deletions
diff --git a/GNUmakefile b/GNUmakefile
index 85d5bdd7..590b111e 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -3,8 +3,8 @@
.NOTPARALLEL:
all: maps conf
maps:
- ant -f tools/tmwcon/build.xml
- java -jar tools/tmwcon/converter.jar client-data/ world/map/
+ tools/tmx_converter.py client-data/ world/map/
+
% : | %.example
cp "$|" "$@"
conf: \
diff --git a/client-data b/client-data
-Subproject 8af4270b649382081cd21890b00b4fa6eed9f82
+Subproject 59a365ebdb2754607b05d562c029ddbce384a81
diff --git a/tools/tmwcon/.gitignore b/tools/tmwcon/.gitignore
deleted file mode 100644
index 056686cf..00000000
--- a/tools/tmwcon/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/build
-/converter.jar
diff --git a/tools/tmwcon/MANIFEST.MF b/tools/tmwcon/MANIFEST.MF
deleted file mode 100644
index 2cdfdcd8..00000000
--- a/tools/tmwcon/MANIFEST.MF
+++ /dev/null
@@ -1,3 +0,0 @@
-Manifest-Version: 1.0
-Main-Class: converter.Main
-Class-Path: tiled-core.jar tmw.jar
diff --git a/tools/tmwcon/README b/tools/tmwcon/README
deleted file mode 100644
index e3a4a31a..00000000
--- a/tools/tmwcon/README
+++ /dev/null
@@ -1,11 +0,0 @@
-Dependencies:
-
- * ant (recent version)
- * J2SE 5 or higher (or equivalent)
- * Tiled core jar file (in this directory)
- * TMW Tiled plugin jar (in this directory)
-
-Compilation and Usage:
- Run
- make maps
- from the top level of the server data.
diff --git a/tools/tmwcon/build.xml b/tools/tmwcon/build.xml
deleted file mode 100755
index 26497f8e..00000000
--- a/tools/tmwcon/build.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<project name="TMWServ to eAthena Converter" default="dist">
- <description>
- A tool to convert map data from TMWServ format to eAthena format
- </description>
- <!-- set global properties for this build -->
-
- <target name="init">
- <!-- Create the time stamp -->
- <tstamp/>
- <!-- Create the build directory structure used by compile -->
- <mkdir dir="build"/>
- </target>
-
- <target name="compile" depends="init" description="Compile the source">
- <javac source="1.5" target="1.5" srcdir="src" destdir="build"
- deprecation="on" classpath="tiled-core.jar;tmw.jar"/>
- </target>
-
- <target name="dist" depends="compile" description="Generate the distribution">
- <jar
- jarfile="converter.jar"
- manifest="MANIFEST.MF"
- basedir="build"
- />
- </target>
-
- <target name="clean" description="Clean up the build directory" >
- <delete dir="build"/>
- </target>
-</project>
diff --git a/tools/tmwcon/src/converter/Main.java b/tools/tmwcon/src/converter/Main.java
deleted file mode 100644
index cb226776..00000000
--- a/tools/tmwcon/src/converter/Main.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Converter from Tiled .tmx files to tmwAthena .wlk and mob/warp scripts
- * Copyright (c) 2008 Jared Adams
- * Copyright (c) 2011 Ben Longbons
- * License: GNU GPL, v2 or later
- */
-
-package converter;
-
-import java.io.*;
-import java.util.*;
-
-import tiled.io.xml.*;
-
-public class Main {
- 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<File> getTMXFiles(File directory) {
- if (!directory.isDirectory()) return Collections.emptyList();
-
- List<File> ret = new Vector<File>();
-
- 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.getParentFile().mkdir();
- 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 main(String[] args) throws IOException {
- if (args.length != 2) {
- System.out.println("Usage: java Converter client-data-dir server-data-dir");
- System.exit(1);
- }
-
- File client_data = new File(args[0]);
- File server_data = new File(args[1]);
-
- reader = new XMLMapTransformer();
-
- PrintWriter summary = new PrintWriter("converter.txt");
-
- Process.setServerData(server_data);
-
- File folder = new File(client_data, "maps/");
-
- Collection<File> tmxs = getTMXFiles(folder);
- ArrayList<String> folders = new ArrayList<String>();
- String name;
- for (File f : tmxs) {
- name = getName(folder, f);
- System.out.printf("== %s ==\n", name);
- folders.add(Process.processMap(name, loadMap(f), f, summary));
- }
-
- summary.flush();
- summary.close();
-
- Process.writeMasterImport(folders);
- }
-}
diff --git a/tools/tmwcon/src/converter/Process.java b/tools/tmwcon/src/converter/Process.java
deleted file mode 100644
index 2e0a8646..00000000
--- a/tools/tmwcon/src/converter/Process.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Converter from Tiled .tmx files to tmwAthena .wlk and mob/warp scripts
- * Copyright (c) 2008, 2011 Jared Adams
- * Copyright (c) 2011 Ben Longbons
- * License: GNU GPL, v2 or later
- */
-
-package converter;
-
-import java.awt.*;
-import java.io.*;
-import java.util.Iterator;
-import java.util.Properties;
-import java.util.TreeSet;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Collections;
-
-import tiled.core.*;
-import tiled.plugins.tmw.*;
-
-public class Process {
- // both were formerly (hard-coded) "\t", for different reasons
- // Note: don't use println, as we want only '\n'
- private static final String SEPARATOR = "|";
- private static final String INDENTATION = " ";
-
- private static final String mobFile = "_mobs.txt";
- private static final String warpFile = "_warps.txt";
- private static final String importFile = "_import.txt";
- private static File server_data;
- private static File script_directory;
- private static File wlkFolder;
-
- private static WLKInterface wlk = null;
-
- public static void setServerData(File folder) {
- server_data = folder;
- script_directory = new File(server_data, "npc/");
- wlkFolder = new File(server_data, "data/");
- wlk = new WLKInterface();
- }
-
- private static String getProp(Properties props, String name, String def) {
- if (name == null) return def;
- for (java.util.Map.Entry<Object, Object> 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" + SEPARATOR + "warp" + SEPARATOR + "%s" + SEPARATOR + "%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" + SEPARATOR + "monster" + SEPARATOR + "%s" + SEPARATOR + "%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<Integer> 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<MapObject> objs, String map, PrintWriter warpOut, PrintWriter mobOut, TreeSet<Integer> mobs) {
- MapObject mo;
- while (objs.hasNext()) {
- mo = objs.next();
- if (mo == null) continue;
- processObject(mo, map, warpOut, mobOut, mobs);
- }
- }
-
- private static void processFiles(File folder, List<String> out) {
- for (File f : folder.listFiles()) {
- if (f.isDirectory()) {
- processFiles(folder, out);
- } else if (!f.getName().equals(importFile)) {
- out.add("npc: " + f.getPath().substring(server_data.getPath().length() + 1));
- }
- }
- }
-
- private static void makeInclude(String name, String title, File folder) {
- File _import = new File(folder, importFile);
- List<String> output_elements = new ArrayList<String>();
- processFiles(folder, output_elements);
- PrintWriter importOut = Main.getWriter(_import);
- importOut.printf("// Map %s: %s\n", name, title);
- importOut.print("// This file is generated automatically. All manually changes will be removed when running the Converter.\n");
- importOut.printf("map: %s.gat\n", name);
- Collections.sort(output_elements);
- for (String s : output_elements)
- if (!s.endsWith("~"))
- importOut.print(s + "\n");
- importOut.flush();
- importOut.close();
- }
-
- public static String processMap(String name, Map map, File mapFile, PrintWriter summary) {
- if (name == null) return null;
- if (map == null) return null;
-
- Properties props = map.getProperties();
- String title = getProp(props, "name", "unnamed map " + name);
-
- String folderName = "npc/" + name;
-
- File folder = new File(script_directory, name);
-
- System.out.println(title);
-
- File wlkFile = new File(wlkFolder, name + ".wlk");
-
- if (wlkFile.exists() && mapFile.lastModified() < wlkFile.lastModified()) {
- System.out.println("Up to date, skipping");
- makeInclude(name, title, folder);
- return folderName;
- }
-
- if (summary != null) {
- summary.printf("Name: %s: '%s'\n", name, title);
- summary.printf("Music: '%s'\n", getProp(props, "music", ""));
- summary.printf("Minimap: '%s'\n", getProp(props, "minimap", ""));
- }
-
- if (wlk != null) wlk.write(name, map, wlkFile);
-
- PrintWriter warpOut = Main.getWriter(new File(folder, warpFile));
- PrintWriter mobOut = Main.getWriter(new File(folder, mobFile));
-
- warpOut.print("// This file is generated automatically. All manually changes will be removed when running the Converter.\n");
- warpOut.printf("// %s warps\n\n", title);
- mobOut.print("// This file is generated automatically. All manually changes will be removed when running the Converter.\n");
- mobOut.printf("// %s mobs\n\n", title);
-
- TreeSet<Integer> mobs = new TreeSet<Integer>();
- 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" + SEPARATOR + "script" + SEPARATOR + "Mob%1$s" + SEPARATOR + "-1,{\n", name);
- for (int mob : mobs) {
- if (mob == -1) continue;
- mobOut.printf("On%d:\n", mob);
- mobOut.printf(INDENTATION + "set @mobID, %d;\n", mob);
- mobOut.printf(INDENTATION + "callfunc \"MobPoints\";\n");
- mobOut.printf(INDENTATION + "end;\n\n");
- }
- mobOut.printf(INDENTATION + "end;\n}\n");
- System.out.println("Finished mob points");
-
- mobOut.flush();
- mobOut.close();
-
- makeInclude(name, title, folder);
-
- return folderName;
- }
-
- public static void writeMasterImport(ArrayList<String> folders) {
- File master = new File(script_directory, importFile);
- PrintWriter out = Main.getWriter(master);
- if (out == null) return;
-
- List<String> output_elements = new ArrayList<String>();
-
- output_elements.add("// This file is generated automatically. All manually changes will be removed when running the Converter.\n");
- for (String folder : folders) {
- if (folder == null) continue;
- output_elements.add("import: " + folder + "/_import.txt");
- }
-
- Collections.sort(output_elements);
- for (String s : output_elements)
- out.print(s + "\n");
-
- out.flush();
- out.close();
- }
-}
diff --git a/tools/tmwcon/src/converter/WLKInterface.java b/tools/tmwcon/src/converter/WLKInterface.java
deleted file mode 100644
index 29436fbf..00000000
--- a/tools/tmwcon/src/converter/WLKInterface.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Converter from Tiled .tmx files to tmwAthena .wlk and mob/warp scripts
- * Copyright (c) 2008 Jared Adams
- * Copyright (c) 2011 Ben Longbons
- * License: GNU GPL, v2 or later
- */
-
-package converter;
-
-import java.io.*;
-
-import tiled.core.*;
-import tiled.plugins.tmw.*;
-
-public class WLKInterface {
- public WLKInterface() {
- // See if the writer is available
- WLKWriter.class.getName();
- }
-
- public void write(String name, Map map, File wlk) {
- try {
- wlk.createNewFile();
- WLKWriter.writeMap(map, new FileOutputStream(wlk));
- System.out.println("WLK written");
- } catch (Exception e) {
- System.out.println("Problem writing WLK file:");
- e.printStackTrace();
- }
- }
-}
diff --git a/tools/tmwcon/tiled-core.jar b/tools/tmwcon/tiled-core.jar
deleted file mode 100644
index 78d44bc0..00000000
--- a/tools/tmwcon/tiled-core.jar
+++ /dev/null
Binary files differ
diff --git a/tools/tmwcon/tmw.jar b/tools/tmwcon/tmw.jar
deleted file mode 100644
index 2ffa74dc..00000000
--- a/tools/tmwcon/tmw.jar
+++ /dev/null
Binary files differ
diff --git a/tools/tmx_converter.py b/tools/tmx_converter.py
new file mode 100755
index 00000000..763ed926
--- /dev/null
+++ b/tools/tmx_converter.py
@@ -0,0 +1,303 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+
+## tmx_converter.py - Extract walkmap, warp, and spawn information from maps.
+##
+## Copyright © 2012 Ben Longbons <b.r.longbons@gmail.com>
+##
+## This file is part of The Mana World
+##
+## This program is free software: you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation, either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program 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 General Public License for more details.
+##
+## You should have received a copy of the GNU General Public License
+## along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+from __future__ import print_function
+
+import sys
+import os
+import posixpath
+import struct
+import xml.sax
+
+dump_all = False # wall of text
+
+# lower case versions of everything except 'spawn' and 'warp'
+other_object_types = {
+ 'particle_effect',
+ 'npc', # not interpreted by client
+ 'script', # for ManaServ
+ 'fixme', # flag for things that didn't have a type before
+}
+
+# Somebody has put ManaServ fields in our data!
+other_spawn_fields = (
+ 'spawn_rate',
+)
+other_warp_fields = (
+)
+
+TILESIZE = 32
+SEPARATOR = '|'
+MESSAGE = 'This file is generated automatically. All manually changes will be removed when running the Converter.'
+CLIENT_MAPS = 'maps'
+SERVER_WLK = 'data'
+SERVER_NPCS = 'npc'
+NPC_MOBS = '_mobs.txt'
+NPC_WARPS = '_warps.txt'
+NPC_IMPORTS = '_import.txt'
+NPC_MASTER_IMPORTS = NPC_IMPORTS
+
+class State(object):
+ pass
+State.INITIAL = State()
+State.LAYER = State()
+State.DATA = State()
+State.FINAL = State()
+
+class Object(object):
+ __slots__ = (
+ 'name',
+ #'map',
+ 'x', 'y',
+ 'w', 'h',
+ )
+class Mob(Object):
+ __slots__ = (
+ 'monster_id',
+ 'max_beings',
+ 'ea_spawn',
+ 'ea_death',
+ ) + other_spawn_fields
+ def __init__(self):
+ self.max_beings = 1
+ self.ea_spawn = 0
+ self.ea_death = 0
+
+class Warp(Object):
+ __slots__ = (
+ 'dest_map',
+ 'dest_x',
+ 'dest_y',
+ ) + other_warp_fields
+
+class ContentHandler(xml.sax.ContentHandler):
+ __slots__ = (
+ 'locator', # keeps track of location in document
+ 'out', # open file handle to .wlk
+ 'state', # state of collision info
+ 'tilesets', # first gid of each tileset
+ 'buffer', # characters within a section
+ 'base', # base name of current map
+ 'npc_dir', # world/map/npc/<base>
+ 'mobs', # open file to _mobs.txt
+ 'warps', # open file to _warps.txt
+ 'imports', # open file to _import.txt
+ 'name', # name property of the current map
+ 'object', # stores properties of the latest <object> tag
+ 'mob_ids', # set of all mob types that spawn here
+ )
+ def __init__(self, out, npc_dir, mobs, warps, imports):
+ xml.sax.ContentHandler.__init__(self)
+ self.locator = None
+ self.out = open(out, 'w')
+ self.state = State.INITIAL
+ self.tilesets = {0} # consider the null tile as its own tileset
+ self.buffer = bytearray()
+ self.base = posixpath.basename(npc_dir)
+ self.npc_dir = npc_dir
+ self.mobs = mobs
+ self.warps = warps
+ self.imports = imports
+ self.object = None
+ self.mob_ids = set()
+
+ def setDocumentLocator(self, loc):
+ self.locator = loc
+
+ # this method randomly cuts in the middle of a line; thus funky logic
+ def characters(self, s):
+ if not s.strip():
+ return
+ if self.state is State.DATA:
+ self.buffer += s.encode('ascii')
+
+ def startDocument(self):
+ pass
+
+ def startElement(self, name, attr):
+ if dump_all:
+ attrs = ' '.join('%s="%s"' % (k,v) for k,v in attr.items())
+ if attrs:
+ print('<%s %s>' % (name, attrs))
+ else:
+ print('<%s>' % name)
+
+ if self.state is State.INITIAL:
+ if name == u'property' and attr[u'name'].lower() == u'name':
+ self.name = attr[u'value']
+ self.mobs.write('// %s\n' % MESSAGE)
+ self.mobs.write('// %s mobs\n\n' % self.name)
+ self.warps.write('// %s\n' % MESSAGE)
+ self.warps.write('// %s warps\n\n' % self.name)
+
+ if name == u'tileset':
+ self.tilesets.add(int(attr[u'firstgid']))
+
+ if name == u'layer' and attr[u'name'].lower().startswith(u'collision'):
+ width = int(attr[u'width'])
+ height = int(attr[u'height'])
+ self.out.write(struct.pack('<HH', width, height))
+ self.state = State.LAYER
+ elif self.state is State.LAYER:
+ if name == u'data':
+ if attr[u'encoding'] != u'csv':
+ print('Bad encoding (not csv):', attr[u'encoding'])
+ return
+ self.state = State.DATA
+ elif self.state is State.FINAL:
+ if name == u'object':
+ obj_type = attr[u'type'].lower()
+ x = int(attr[u'x']) / TILESIZE;
+ y = int(attr[u'y']) / TILESIZE;
+ w = int(attr.get(u'width', 0)) / TILESIZE;
+ h = int(attr.get(u'height', 0)) / TILESIZE;
+ # I'm not sure exactly what the w/h shrinking is for,
+ # I just copied it out of the old converter.
+ # I know that the x += w/2 is to get centers, though.
+ if obj_type == 'spawn':
+ self.object = Mob()
+ if w > 1:
+ w -= 1
+ if h > 1:
+ h -= 1
+ x += w/2
+ y += h/2
+ elif obj_type == 'warp':
+ self.object = Warp()
+ x += w/2
+ y += h/2
+ w -= 2
+ h -= 2
+ else:
+ if obj_type not in other_object_types:
+ print('Unknown object type:', obj_type, file=sys.stderr)
+ self.object = None
+ return
+ obj = self.object
+ obj.x = x
+ obj.y = y
+ obj.w = w
+ obj.h = h
+ obj.name = attr[u'name']
+ elif name == u'property':
+ obj = self.object
+ if obj is None:
+ return
+ key = attr[u'name'].lower()
+ value = attr[u'value']
+ # Not true due to defaulting
+ #assert not hasattr(obj, key)
+ try:
+ value = int(value)
+ except ValueError:
+ pass
+ setattr(obj, key, value)
+
+ def add_warp_line(self, line):
+ self.warps.write(line)
+
+ def endElement(self, name):
+ if dump_all:
+ print('</%s>' % name)
+
+ if name == u'object':
+ obj = self.object
+ if isinstance(obj, Mob):
+ mob_id = obj.monster_id
+ if mob_id < 1000:
+ mob_id += 1002
+ self.mob_ids.add(mob_id)
+ self.mobs.write(
+ SEPARATOR.join([
+ '%s.gat,%d,%d,%d,%d' % (self.base, obj.x, obj.y, obj.w, obj.h),
+ 'monster',
+ obj.name,
+ '%d,%d,%d,%d,Mob%s::On%d\n' % (mob_id, obj.max_beings, obj.ea_spawn, obj.ea_death, self.base, mob_id),
+ ])
+ )
+ elif isinstance(obj, Warp):
+ self.warps.write(
+ SEPARATOR.join([
+ '%s.gat,%d,%d' % (self.base, obj.x, obj.y),
+ 'warp',
+ obj.name,
+ '%d,%d,%s.gat,%d,%d\n' % (obj.w, obj.h, obj.dest_map, obj.dest_x / 32, obj.dest_y / 32),
+ ])
+ )
+
+ if self.state is State.DATA:
+ for x in self.buffer.split(','):
+ self.out.write(chr(int(x) not in self.tilesets))
+ self.state = State.FINAL
+
+ def endDocument(self):
+ self.mobs.write('\n\n%s.gat,0,0,0|script|Mob%s|-1,{\n' % (self.base, self.base))
+ for mob_id in sorted(self.mob_ids):
+ self.mobs.write('On%d:\n set @mobID, %d;\n callfunc "MobPoints";\n end;\n\n' % (mob_id, mob_id))
+ self.mobs.write(' end;\n}\n')
+ self.imports.write('// Map %s: %s\n' % (self.base, self.name))
+ self.imports.write('// %s\n' % MESSAGE)
+ self.imports.write('map: %s.gat\n' % self.base)
+
+ npcs = os.listdir(self.npc_dir)
+ npcs.sort()
+ for x in npcs:
+ if x == NPC_IMPORTS:
+ continue
+ if x.startswith('.'):
+ continue
+ if x.endswith('.txt'):
+ self.imports.write('npc: %s\n' % posixpath.join(SERVER_NPCS, self.base, x))
+ pass
+
+def main(argv):
+ _, client_data, server_data = argv
+ tmx_dir = posixpath.join(client_data, CLIENT_MAPS)
+ wlk_dir = posixpath.join(server_data, SERVER_WLK)
+ npc_dir = posixpath.join(server_data, SERVER_NPCS)
+
+ npc_master = []
+
+ for arg in os.listdir(tmx_dir):
+ base, ext = posixpath.splitext(arg)
+
+ if ext == '.tmx':
+ tmx = posixpath.join(tmx_dir, arg)
+ wlk = posixpath.join(wlk_dir, base + '.wlk')
+ this_map_npc_dir = posixpath.join(npc_dir, base)
+ os.path.isdir(this_map_npc_dir) or os.mkdir(this_map_npc_dir)
+ print('Converting %s to %s' % (tmx, wlk))
+ with open(posixpath.join(this_map_npc_dir, NPC_MOBS), 'w') as mobs, \
+ open(posixpath.join(this_map_npc_dir, NPC_WARPS), 'w') as warps, \
+ open(posixpath.join(this_map_npc_dir, NPC_IMPORTS), 'w') as imports:
+ xml.sax.parse(tmx, ContentHandler(wlk, this_map_npc_dir, mobs, warps, imports))
+ npc_master.append('import: %s\n' % posixpath.join(SERVER_NPCS, base, NPC_IMPORTS))
+
+ with open(posixpath.join(npc_dir, NPC_MASTER_IMPORTS), 'w') as out:
+ out.write('// %s\n\n' % MESSAGE)
+ npc_master.sort()
+ for line in npc_master:
+ out.write(line)
+
+if __name__ == '__main__':
+ main(sys.argv)
diff --git a/world/map/npc/003-1/_mobs.txt b/world/map/npc/003-1/_mobs.txt
index 62e1391e..0120bde8 100644
--- a/world/map/npc/003-1/_mobs.txt
+++ b/world/map/npc/003-1/_mobs.txt
@@ -1,6 +1,7 @@
// This file is generated automatically. All manually changes will be removed when running the Converter.
// Beach mobs
+003-1.gat,158,68,28,96|monster|Giant Maggot|1006,10,100000,30000,Mob003-1::On1006
003-1.gat,0,0,0,0|monster|Sea Slime|1033,15,100000,30000,Mob003-1::On1033
003-1.gat,120,31,22,22|monster|Sea Slime|1033,5,100000,30000,Mob003-1::On1033
003-1.gat,119,68,105,101|monster|Green Slime|1005,35,100000,30000,Mob003-1::On1005
@@ -19,6 +20,11 @@ On1005:
callfunc "MobPoints";
end;
+On1006:
+ set @mobID, 1006;
+ callfunc "MobPoints";
+ end;
+
On1026:
set @mobID, 1026;
callfunc "MobPoints";
diff --git a/world/map/npc/006-3/_mobs.txt b/world/map/npc/006-3/_mobs.txt
index 46fdfd33..30b5427e 100644
--- a/world/map/npc/006-3/_mobs.txt
+++ b/world/map/npc/006-3/_mobs.txt
@@ -7,15 +7,17 @@
006-3.gat,86,90,29,9|monster|Mountain Snake|1026,3,15000,90000,Mob006-3::On1026
006-3.gat,109,78,12,9|monster|Mountain Snake|1026,1,15000,90000,Mob006-3::On1026
006-3.gat,119,117,15,14|monster|Mountain Snake|1026,4,15000,90000,Mob006-3::On1026
+006-3.gat,106,64,14,17|monster|Mountain Snake|1026,3,15000,90000,Mob006-3::On1026
006-3.gat,65,71,31,35|monster|Mountain Snake|1026,10,15000,90000,Mob006-3::On1026
006-3.gat,57,105,27,30|monster|Mountain Snake|1026,8,15000,90000,Mob006-3::On1026
006-3.gat,73,120,16,5|monster|Mountain Snake|1026,3,15000,90000,Mob006-3::On1026
006-3.gat,117,54,11,9|monster|Mountain Snake|1026,4,15000,90000,Mob006-3::On1026
006-3.gat,123,62,10,5|monster|Mountain Snake|1026,3,15000,90000,Mob006-3::On1026
+006-3.gat,72,36,24,25|monster|Mountain Snake|1026,10,15000,90000,Mob006-3::On1026
006-3.gat,84,27,5,7|monster|Mountain Snake|1026,1,15000,90000,Mob006-3::On1026
006-3.gat,40,40,36,28|monster|Mountain Snake|1026,8,15000,90000,Mob006-3::On1026
006-3.gat,34,60,27,11|monster|Mountain Snake|1026,3,15000,90000,Mob006-3::On1026
-006-3.gat,87,74,26,9|monster|Red Slime|1008,1,15000,10000,Mob006-3::On1008
+006-3.gat,87,74,26,9|monster|Red Slime|1008,3,15000,10000,Mob006-3::On1008
006-3.gat,120,76,9,21|monster|Red Slime|1008,3,15000,10000,Mob006-3::On1008
006-3.gat,101,85,14,8|monster|Red Slimes|1008,4,15000,10000,Mob006-3::On1008
006-3.gat,44,124,29,7|monster|Mountain Snake|1026,5,15000,90000,Mob006-3::On1026
diff --git a/world/map/npc/013-3/_mobs.txt b/world/map/npc/013-3/_mobs.txt
index 8132bd96..830da7bb 100644
--- a/world/map/npc/013-3/_mobs.txt
+++ b/world/map/npc/013-3/_mobs.txt
@@ -29,12 +29,12 @@
013-3.gat,80,33,2,1|monster|Fire Skull|1023,1,120000,60000,Mob013-3::On1023
013-3.gat,75,46,2,1|monster|Poison Skull|1024,1,120000,60000,Mob013-3::On1024
013-3.gat,67,46,2,1|monster|Fire Skull|1023,1,120000,60000,Mob013-3::On1023
-013-3.gat,149,145,7,26|monster|Silkworm|2037,10,20000,5000,Mob013-3::On2037
-013-3.gat,117,157,6,14|monster|Cave Snake|2023,3,30000,10000,Mob013-3::On2023
-013-3.gat,150,129,17,4|monster|Cave Snake|2023,3,30000,10000,Mob013-3::On2023
-013-3.gat,162,138,5,5|monster|Cave Snake|2023,3,30000,10000,Mob013-3::On2023
-013-3.gat,138,174,15,8|monster|Cave Snake|2023,3,30000,10000,Mob013-3::On2023
-013-3.gat,146,151,62,54|monster|Bat|2019,20,15000,5000,Mob013-3::On2019
+013-3.gat,149,145,7,26|monster|Silkworm|1035,10,20000,5000,Mob013-3::On1035
+013-3.gat,117,157,6,14|monster|Cave Snake|1021,3,30000,10000,Mob013-3::On1021
+013-3.gat,150,129,17,4|monster|Cave Snake|1021,3,30000,10000,Mob013-3::On1021
+013-3.gat,162,138,5,5|monster|Cave Snake|1021,3,30000,10000,Mob013-3::On1021
+013-3.gat,138,174,15,8|monster|Cave Snake|1021,3,30000,10000,Mob013-3::On1021
+013-3.gat,146,151,62,54|monster|Bat|1017,20,15000,5000,Mob013-3::On1017
013-3.gat,0,0,0|script|Mob013-3|-1,{
@@ -68,6 +68,11 @@ On1012:
callfunc "MobPoints";
end;
+On1017:
+ set @mobID, 1017;
+ callfunc "MobPoints";
+ end;
+
On1021:
set @mobID, 1021;
callfunc "MobPoints";
@@ -83,18 +88,8 @@ On1024:
callfunc "MobPoints";
end;
-On2019:
- set @mobID, 2019;
- callfunc "MobPoints";
- end;
-
-On2023:
- set @mobID, 2023;
- callfunc "MobPoints";
- end;
-
-On2037:
- set @mobID, 2037;
+On1035:
+ set @mobID, 1035;
callfunc "MobPoints";
end;
diff --git a/world/map/npc/017-1/_mobs.txt b/world/map/npc/017-1/_mobs.txt
index af722b24..36eeaaf4 100644
--- a/world/map/npc/017-1/_mobs.txt
+++ b/world/map/npc/017-1/_mobs.txt
@@ -2,9 +2,11 @@
// Woodland Hills mobs
017-1.gat,0,0,0,0|monster|Clover Patch|1037,2,0,1000,Mob017-1::On1037
-017-1.gat,29,29,19,12|monster|Gamboge Herb|2033,1,0,25000,Mob017-1::On2033
-017-1.gat,91,25,76,8|monster|Log Head|2027,3,5000,60000,Mob017-1::On2027
-017-1.gat,31,48,19,12|monster|Log Head|2027,3,5000,60000,Mob017-1::On2027
+017-1.gat,99,30,2,1|monster|Clover Patch|1037,1,0,15000,Mob017-1::On1037
+017-1.gat,98,30,3,1|monster|Clover Patch|1037,1,0,15000,Mob017-1::On1037
+017-1.gat,29,29,19,12|monster|Gamboge Herb|1031,1,0,25000,Mob017-1::On1031
+017-1.gat,91,25,76,8|monster|Log Head|1025,3,5000,60000,Mob017-1::On1025
+017-1.gat,31,48,19,12|monster|Log Head|1025,3,5000,60000,Mob017-1::On1025
017-1.gat,0,0,0,0|monster|Butterfly|1055,10,30,20,Mob017-1::On1055
017-1.gat,0,0,0,0|monster|Bat|1017,5,0,0,Mob017-1::On1017
017-1.gat,0,0,0,0|monster|Fire Goblin|1011,5,0,0,Mob017-1::On1011
@@ -46,6 +48,11 @@ On1019:
callfunc "MobPoints";
end;
+On1025:
+ set @mobID, 1025;
+ callfunc "MobPoints";
+ end;
+
On1028:
set @mobID, 1028;
callfunc "MobPoints";
@@ -91,15 +98,5 @@ On1055:
callfunc "MobPoints";
end;
-On2027:
- set @mobID, 2027;
- callfunc "MobPoints";
- end;
-
-On2033:
- set @mobID, 2033;
- callfunc "MobPoints";
- end;
-
end;
}
diff --git a/world/map/npc/025-3/_mobs.txt b/world/map/npc/025-3/_mobs.txt
index 36e60dba..82ee3e08 100644
--- a/world/map/npc/025-3/_mobs.txt
+++ b/world/map/npc/025-3/_mobs.txt
@@ -3,7 +3,7 @@
025-3.gat,0,0,0,0|monster|Cave Maggot|1056,100,0,100,Mob025-3::On1056
025-3.gat,0,0,0,0|monster|Archant|1060,20,0,100,Mob025-3::On1060
-025-3.gat,0,0,0,0|monster|Angry Scorpion|1057,25,0,0,Mob025-3::On1057
+025-3.gat,0,0,0,0|monster|Angry Scorpion|1057,25,0,100,Mob025-3::On1057
025-3.gat,69,153,13,1|monster|Skeleton|1043,1,0,30000,Mob025-3::On1043
diff --git a/world/map/npc/025-4/_mobs.txt b/world/map/npc/025-4/_mobs.txt
index 7f18439c..fcf82719 100644
--- a/world/map/npc/025-4/_mobs.txt
+++ b/world/map/npc/025-4/_mobs.txt
@@ -1,8 +1,8 @@
// This file is generated automatically. All manually changes will be removed when running the Converter.
// Rossy Battle Caves mobs
-025-4.gat,29,31,20,14|monster|Cave Maggot|1056,3,0,0,Mob025-4::On1056
-025-4.gat,94,24,20,21|monster|Cave Maggot|1056,5,0,0,Mob025-4::On1056
+025-4.gat,29,31,20,14|monster|Cave Maggot|1056,3,0,100,Mob025-4::On1056
+025-4.gat,94,24,20,21|monster|Cave Maggot|1056,5,0,100,Mob025-4::On1056
025-4.gat,0,0,0|script|Mob025-4|-1,{
diff --git a/world/map/npc/028-3/_mobs.txt b/world/map/npc/028-3/_mobs.txt
index 2816948d..5556ef9d 100644
--- a/world/map/npc/028-3/_mobs.txt
+++ b/world/map/npc/028-3/_mobs.txt
@@ -1,7 +1,7 @@
// This file is generated automatically. All manually changes will be removed when running the Converter.
// Easter Island Cave mobs
-028-3.gat,51,49,22,15|monster|Silkworm|1035,10,0,3000,Mob028-3::On1035
+028-3.gat,51,49,22,15|monster|Silkworm|1035,10,30000,3000,Mob028-3::On1035
028-3.gat,43,35,1,1|monster|Evil Mushroom|1013,3,40000,5000,Mob028-3::On1013
028-3.gat,27,31,1,1|monster|Evil Mushroom|1013,3,40000,5000,Mob028-3::On1013
028-3.gat,50,49,61,60|monster|Bat|1017,10,60000,10000,Mob028-3::On1017
diff --git a/world/map/npc/046-1/_mobs.txt b/world/map/npc/046-1/_mobs.txt
index 205ac676..4cc8d70d 100644
--- a/world/map/npc/046-1/_mobs.txt
+++ b/world/map/npc/046-1/_mobs.txt
@@ -1,9 +1,9 @@
// This file is generated automatically. All manually changes will be removed when running the Converter.
// Rock Plateau mobs
-046-1.gat,0,0,0,0|monster|Reinboo|1094,40,0,0,Mob046-1::On1094
-046-1.gat,0,0,0,0|monster|Fluffy|1020,50,0,0,Mob046-1::On1020
-046-1.gat,0,0,0,0|monster|Squirrel|1038,50,0,0,Mob046-1::On1038
+046-1.gat,0,0,0,0|monster|Reinboo|1094,40,100000,30000,Mob046-1::On1094
+046-1.gat,0,0,0,0|monster|Fluffy|1020,50,100000,30000,Mob046-1::On1020
+046-1.gat,0,0,0,0|monster|Squirrel|1038,50,100000,30000,Mob046-1::On1038
046-1.gat,44,28,52,20|monster|Moggun|1061,12,100000,30000,Mob046-1::On1061
046-1.gat,0,0,0,0|monster|Yeti|1072,2,100000,30000,Mob046-1::On1072
046-1.gat,87,94,23,13|monster|Wolvern|1090,5,100000,30000,Mob046-1::On1090
diff --git a/world/map/npc/047-1/_mobs.txt b/world/map/npc/047-1/_mobs.txt
index 2b7a9c3e..d3caf06f 100644
--- a/world/map/npc/047-1/_mobs.txt
+++ b/world/map/npc/047-1/_mobs.txt
@@ -1,10 +1,10 @@
// This file is generated automatically. All manually changes will be removed when running the Converter.
// Highlands mobs
-047-1.gat,0,0,0,0|monster|Reinboo|1094,20,0,0,Mob047-1::On1094
-047-1.gat,0,0,0,0|monster|Fluffy|1020,25,0,0,Mob047-1::On1020
+047-1.gat,0,0,0,0|monster|Reinboo|1094,20,100000,30000,Mob047-1::On1094
+047-1.gat,0,0,0,0|monster|Fluffy|1020,25,100000,30000,Mob047-1::On1020
047-1.gat,0,0,0,0|monster|White Bell|1095,4,100000,30000,Mob047-1::On1095
-047-1.gat,0,0,0,0|monster|Squirrel|1038,25,0,0,Mob047-1::On1038
+047-1.gat,0,0,0,0|monster|Squirrel|1038,25,100000,30000,Mob047-1::On1038
047-1.gat,19,57,1,1|monster|Yeti|1072,1,100000,30000,Mob047-1::On1072
047-1.gat,106,26,23,13|monster|Wolvern|1090,4,100000,30000,Mob047-1::On1090
047-1.gat,30,79,22,27|monster|Wolvern|1090,4,100000,30000,Mob047-1::On1090
diff --git a/world/map/npc/048-1/_mobs.txt b/world/map/npc/048-1/_mobs.txt
index b8e5e3bd..94c84611 100644
--- a/world/map/npc/048-1/_mobs.txt
+++ b/world/map/npc/048-1/_mobs.txt
@@ -1,9 +1,9 @@
// This file is generated automatically. All manually changes will be removed when running the Converter.
// Snow Forest mobs
-048-1.gat,0,0,0,0|monster|Reinboo|1094,20,0,0,Mob048-1::On1094
-048-1.gat,0,0,0,0|monster|Fluffy|1020,25,0,0,Mob048-1::On1020
-048-1.gat,0,0,0,0|monster|Squirrel|1038,25,0,0,Mob048-1::On1038
+048-1.gat,0,0,0,0|monster|Reinboo|1094,20,100000,30000,Mob048-1::On1094
+048-1.gat,0,0,0,0|monster|Fluffy|1020,25,100000,30000,Mob048-1::On1020
+048-1.gat,0,0,0,0|monster|Squirrel|1038,25,100000,30000,Mob048-1::On1038
048-1.gat,0,0,0,0|monster|White Bell|1095,5,100000,30000,Mob048-1::On1095
048-1.gat,68,40,2,2|monster|White Slime|1093,4,100000,30000,Mob048-1::On1093
048-1.gat,72,61,4,5|monster|Blue Slime|1091,2,100000,30000,Mob048-1::On1091