Fixes and improvements.
authorNot Zed <notzed@gmail.com>
Thu, 2 Mar 2023 02:32:47 +0000 (13:02 +1030)
committerNot Zed <notzed@gmail.com>
Thu, 2 Mar 2023 02:32:47 +0000 (13:02 +1030)
Move to rhino for javascript, unable to get nashorn to work with modules.
Change tile textures to be the size of the tile rather than sub-textures,
 previous caused significant performance issues.
Change the tileset format and include sprites and player sprites.
Merge in anim code from db branch, seems incomplete still.
Add some scripts to run the install image.
Load some prefs in the new server.
Create some conversion utilities for client data.
Improved duskz.editor, multi-map support, bugs, layout.

30 files changed:
Makefile
README
java.make
nbproject/configs/client.properties [new file with mode: 0644]
nbproject/configs/editor.properties [new file with mode: 0644]
nbproject/configs/server-old.properties [new file with mode: 0644]
src/duskz.client/classes/duskz/client/DataManager.java
src/duskz.client/classes/duskz/client/Dusk.java
src/duskz.client/classes/duskz/client/GUI.java
src/duskz.client/classes/duskz/client/fx/DataManagerFX.java
src/duskz.client/classes/duskz/client/fx/DuskFX.java
src/duskz.client/classes/duskz/client/fx/MainFrameFX.java
src/duskz.client/classes/jfxtras/internal/scene/control/ListSpinner.css [new file with mode: 0644]
src/duskz.client/windows-amd64/bin/run-client.bat [new file with mode: 0644]
src/duskz.common/classes/duskz/map/TileMap.java
src/duskz.server/classes/duskz/server/DuskEngine.java
src/duskz.server/classes/duskz/server/entity/LivingThing.java
src/duskz.server/classes/duskz/server/entityz/Game.java
src/duskz.server/classes/duskz/server/entityz/GameServer.java
src/duskz.server/classes/duskz/server/entityz/ScriptManager.java
src/duskz.server/classes/module-info.java
src/duskz.server/linux-amd64/bin/run-server [new file with mode: 0755]
src/duskz.server/windows-amd64/bin/run-server.bat [new file with mode: 0644]
src/duskz.tools/classes/duskz/editor/DuskInfoView.java
src/duskz.tools/classes/duskz/editor/LocationEditor.java
src/duskz.tools/classes/duskz/editor/TileZ.java
src/duskz.tools/classes/duskz/editor/style.css [new file with mode: 0644]
src/duskz.tools/classes/duskz/tool/Convert.java
src/duskz.tools/classes/duskz/tool/fx/MapView.java
src/duskz.tools/classes/duskz/viewer/MapViewer.java

index da8e461..4e6e82a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -17,26 +17,34 @@ duskz.server_JDEPMOD = duskz.common
 duskz.editor_JDEPMOD = duskz.common duskz.client
 duskz.viewer_JDEPMOD = duskz.common duskz.client
 
+define install-bin=
+$1_COMMANDS = $(notdir $(wildcard src/$1/$(TARGET)/bin/*))
+bin/$1/$(TARGET)/bin/%: src/$1/$(TARGET)/bin/%
+       install -D -t $$(@D) $$<
+endef
+$(foreach mod,$(java_MODULES),$(eval $(call install-bin,$(mod))))
+
 include java.make
 
-maven_central_JARS = \
-       jakarta.xml.bind:jakarta.xml.bind-api:4.0.0 \
-       jakarta.activation:jakarta.activation-api:2.1.1 \
-       com.sun.xml.bind:jaxb-impl:4.0.1 \
+xmlbind = jakarta.xml.bind:jakarta.xml.bind-api:4.0.0  \
+       jakarta.activation:jakarta.activation-api:2.1.1 \
+       com.sun.xml.bind:jaxb-impl:4.0.1                \
        com.sun.xml.bind:jaxb-core:4.0.2
 
 # two possible javascript engines
-maven_central_JARS +=                          \
-       org.openjdk.nashorn:nashorn-core:15.4   \
-       org.ow2.asm:asm:7.3.1                   \
-       org.ow2.asm:asm-commons:7.3.1           \
-       org.ow2.asm:asm-tree:7.3.1              \
-       org.ow2.asm:asm-analysis:7.3.1          \
-       org.ow2.asm:asm-util:7.3.1
-
-#maven_central_JARS +=                         \
-#      org.mozilla:rhino:1.7.14                \
-#      org.mozilla:rhino-engine:1.7.14
+# nashorn can't find methods on any objects for some reason
+#nashorn +=                            \
+#      org.openjdk.nashorn:nashorn-core:15.4   \
+#      org.ow2.asm:asm:7.3.1                   \
+#      org.ow2.asm:asm-commons:7.3.1           \
+#      org.ow2.asm:asm-tree:7.3.1              \
+#      org.ow2.asm:asm-analysis:7.3.1          \
+#      org.ow2.asm:asm-util:7.3.1
+
+rhino =        org.mozilla:rhino:1.7.14                \
+       org.mozilla:rhino-engine:1.7.14
+
+maven_central_JARS = $(xmlbind) $(rhino)
 
 include maven.make
 
@@ -66,17 +74,57 @@ run-editor: duskz.tools
                $(if $(JAVAMODPATH),--module-path $(subst $(S),:,$(JAVAMODPATH))) \
                -m duskz.tools/duskz.viewer.MapViewer
 
+convert-client: duskz.tools
+       $(JAVA) \
+               $(if $(JAVAMODPATH),--module-path $(subst $(S),:,$(JAVAMODPATH))) \
+               -m duskz.tools/duskz.tool.Convert client rc somedusk
+
+
 ifeq ($(TARGET),linux-amd64)
 jlink_MODPATH = $(JAVA_HOME)/jmods:/usr/local/javafx-jmods
 else
 jlink_MODPATH = /usr/local/$(TARGET)/jdk/jmods:/usr/local/$(TARGET)/javafx-jmods
 endif
 
-link: duskz.client duskz.server duskz.common
-       rm -rf bin/$(TARGET)/image
+# need to make rhino modular for jlink to work
+bin/org.mozilla.rhino-1.7.14.jar: .lib/rhino-1.7.14.jar .lib/rhino-engine-1.7.14.jar
+       mkdir -p bin/tmp/org.mozilla.rhino
+       cd bin/tmp/org.mozilla.rhino && $(JAVA_HOME)/bin/jar xf $(realpath .lib/rhino-engine-1.7.14.jar)
+       cd bin/tmp/org.mozilla.rhino && $(JAVA_HOME)/bin/jar xf $(realpath .lib/rhino-1.7.14.jar)
+       jar cfm bin/org.mozilla.rhino.jar bin/tmp/org.mozilla.rhino/META-INF/MANIFEST.MF \
+               -C bin/tmp/org.mozilla.rhino META-INF \
+               -C bin/tmp/org.mozilla.rhino org
+       $(JAVA_HOME)/bin/jdeps --generate-module-info bin/gen bin/org.mozilla.rhino.jar
+       javac -cp rhino.jar -d bin/tmp/org.mozilla.rhino bin/gen/org.mozilla.rhino/module-info.java
+       jar cfm bin/org.mozilla.rhino-1.7.14.jar~ bin/tmp/org.mozilla.rhino/META-INF/MANIFEST.MF \
+               -C bin/tmp/org.mozilla.rhino META-INF \
+               -C bin/tmp/org.mozilla.rhino org  \
+               -C bin/tmp/org.mozilla.rhino module-info.class
+       mv $@~ $@
+
+bin/status/org.mozilla.rhino.engine.classes: .lib/rhino-engine-1.7.14.jar
+       $(JAVA_HOME)/bin/jdeps --generate-module-info bin/gen/ --module-path .lib $<
+       mkdir -p bin/modules/org.mozilla.rhino.engine
+       cd bin/modules/org.mozilla.rhino.engine && $(JAVA_HOME)/bin/jar xf $(realpath $<)
+       $(JAVAC) -d bin/modules/org.mozilla.rhino.engine \
+               --module-path .lib:bin/modules \
+               bin/gen/org.mozilla.rhino.engine/module-info.java
+
+#jarname=$(word 2,$(subst :, ,$1))-$(word 3,$(subst :, ,$1)).jar
+define jarname
+$(word 2,$(subst :, ,$1))-$(word 3,$(subst :, ,$1)).jar
+endef
+
+#              --strip-debug
+link: duskz.client duskz.server duskz.common bin/org.mozilla.rhino-1.7.14.jar
+       rm -rf bin/$(TARGET)/image bin/$(TARGET)/tmp
+       mkdir -p bin/$(TARGET)/tmp
+       $(foreach artifact,$(xmlbind),( cd bin/$(TARGET)/tmp && ln -s ../../../.lib/$(call jarname,$(artifact)) ); )
+       cd bin/$(TARGET)/tmp ; ln -s ../../org.mozilla.rhino-1.7.14.jar
        $(JAVA_HOME)/bin/jlink \
-               --module-path .lib:bin/$(TARGET)/jmods:$(jlink_MODPATH) \
-               --add-modules duskz.client,duskz.server \
+               --module-path bin/$(TARGET)/jmods:bin/$(TARGET)/tmp:$(jlink_MODPATH) \
+               --add-modules duskz.client,duskz.server,org.mozilla.rhino \
+               --bind-services \
                --no-man-pages \
                --compress 2 \
                --output bin/$(TARGET)/image
diff --git a/README b/README
index 9de326d..92228d9 100644 (file)
--- a/README
+++ b/README
@@ -57,7 +57,9 @@ This is currently in an alpha state.
 BUIDING
 -------
 
-First get the 3rd party libraries from maven:
+Copy config.make.in to config.make and configure for your local setup.
+
+Then get the 3rd party libraries from maven:
 
 $ make maven-init
 
index 266b0ac..0ecc128 100644 (file)
--- a/java.make
+++ b/java.make
@@ -227,7 +227,7 @@ define module_vars=
 $1_sdk  := $(addprefix $(java_bindir)/,$($1_COMMANDS)) $(addprefix $(java_libdir)/,$($1_LIBRARIES)) $($1_NATIVE_LIBRARIES:%=$(java_libdir)/lib%.so)
 $1_jmod := $(addprefix $($1_bindir)/,$($1_COMMANDS)) $(addprefix $($1_libdir)/,$($1_LIBRARIES)) $($1_NATIVE_LIBRARIES:%=$($1_libdir)/lib%.so)
 $1_java :=$($1_JAVA:%=src/$1/classes/%) $($1_JAVA_GENERATED:%=$($1_genjavadir)/%)
-$1_resources:= $($1_RESOURCES:%=src/$1/classes/%) $($1_RESOURCES_GENERATED:%=$($1_genjavadir)/%)
+$1_resources:= $($1_RESOURCES:%=bin/modules/$1/%) $($1_RESOURCES_GENERATED:%=bin/modules/$1/%)
 $1_depjava := $($1_API:%=bin/status/$1-%.export) $(patsubst %,bin/status/%.classes, $(filter $($1_JDEPMOD),$(java_MODULES)))
 
 ifneq ("$$(strip $$($1_java) $$($1_depjava))", "")
@@ -294,9 +294,7 @@ $(java_jardir)/$1.jar: bin/status/$1.depjar
        @install -d $$(@D)
        $(JAR) cf $$@ \
          $(JARFLAGS) $$($(1)_JARFLAGS) \
-         -C bin/modules/$(1) . \
-         $(if $($1_RESOURCES),$($1_RESOURCES:%=-C src/$1/classes %)) \
-         $(if $($1_RESOURCES_GENERATED),$($1_RESOURCES_GENERATED:%=-C bin/gen/$1/classes %))
+         -C bin/modules/$(1) .
 
 # Create a jmod
 $(java_jmoddir)/$1.jmod: bin/status/$1.depmod
@@ -322,6 +320,8 @@ $(java_jardir)/$1-sources.zip: bin/status/$1.depjar
 # resources
 bin/modules/$1/%: src/$1/classes/%
        install -vD $$< $$@
+bin/modules/$1/%: $($1_gejavadir)/%
+       install -vD $$< $$@
 
 # Compile module.
 bin/status/$1.classes: bin/status/$1.depjava
diff --git a/nbproject/configs/client.properties b/nbproject/configs/client.properties
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/nbproject/configs/editor.properties b/nbproject/configs/editor.properties
new file mode 100644 (file)
index 0000000..8bbf2f2
--- /dev/null
@@ -0,0 +1,2 @@
+main.class=duskz.editor.TileZ
+run.jvmargs=-Djavafx.verbose=true -Dprism.verbose=true
diff --git a/nbproject/configs/server-old.properties b/nbproject/configs/server-old.properties
new file mode 100644 (file)
index 0000000..0833fea
--- /dev/null
@@ -0,0 +1 @@
+main.class=duskz.server.DuskServer
index 3c7343f..65881a1 100644 (file)
 package duskz.client;
 
 import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.function.Consumer;
 import java.util.jar.Attributes;
 import java.util.jar.JarEntry;
 import java.util.jar.JarInputStream;
 import java.util.jar.Manifest;
-import javafx.geometry.Rectangle2D;
-import javafx.scene.image.ImageView;
 
 /**
- * Utility for loading game objects from jar file
- * and managing them
- *
- * TODO: i couldn't work out how to do generics with the inner class thing
- *
- * @author notzed
+ * Utility for loading/managing client game images.
+ * <p>
  */
 public class DataManager {
 
        String source;
-       protected ImageSet[] tilesets;
+       protected Map<String, ImageSet[]> sets = new HashMap<>();
 
        public DataManager(String source) {
                this.source = source;
        }
 
-       public void open() throws IOException {
-               tilesets = getImageSet("tilesets");
-               // TODO: sprites, etc.
+       public String getSource() {
+               return source;
+       }
 
-               for (ImageSet is : tilesets)
-                       is.load();
+       public ImageSet[] getImageSet(String type) {
+               return sets.getOrDefault(type, new ImageSet[0]);
+       }
+
+       public void load() throws IOException {
+               try (JarInputStream jis = new JarInputStream(new FileInputStream(source + ".jar"))) {
+                       Map<String, Consumer<JarInputStream>> handle = new HashMap<>();
+                       JarEntry je;
+
+                       scanManifest(jis.getManifest(), handle);
+
+                       while ((je = jis.getNextJarEntry()) != null) {
+                               Consumer<JarInputStream> proc = handle.get(je.getName());
+                               if (proc != null)
+                                       proc.accept(jis);
+                       }
+               }
        }
 
        private int getInt(Attributes a, int index, String name) {
                try {
-                       return Integer.valueOf(a.getValue(index + "_" + name));
+                       return Integer.parseInt(a.getValue(name + index));
                } catch (NumberFormatException x) {
                        return -1;
                }
@@ -71,55 +80,40 @@ public class DataManager {
                return new ImageSet();
        }
 
-       JarInputStream openJar() throws IOException {
-               return new JarInputStream(new FileInputStream(source));
-       }
+       /**
+        * Scan manifest for information of interest.
+        *
+        * @param man
+        * @return a predicate that might process a jar entry, it returns true if it was processed.
+        */
+       protected void scanManifest(Manifest man, Map<String, Consumer<JarInputStream>> handle) {
+               String[] names = new String[]{"tiles", "sprites", "players"};
+
+               for (String name: names) {
+                       Attributes a = man.getAttributes(name);
+                       int count = Integer.parseInt(a.getValue("count"));
+                       ImageSet[] list = new ImageSet[count];
 
-       public ImageSet[] getImageSet(String setName) throws IOException {
-               List<ImageSet> list;
-               try (JarInputStream jis = openJar()) {
-                       list = new ArrayList<>();
-                       Manifest man = jis.getManifest();
-                       Attributes a = man.getAttributes(setName);
-                       int count = Integer.valueOf(a.getValue("count"));
                        for (int i = 0; i < count; i++) {
                                ImageSet set = createImageSet();
 
-                               set.name = a.getValue(i + "_name");
-                               set.source = a.getValue(i + "_source");
-                               set.gid = getInt(a, i, "gid");
-                               set.count = getInt(a, i, "count");
-                               set.width = getInt(a, i, "width");
-                               set.height = getInt(a, i, "height");
-
-                               // Load it straight away?
-
-                               list.add(set);
-                       }
-               }
-
-               return list.toArray(new ImageSet[list.size()]);
-       }
-
-       public InputStream getInputStream(String path) throws IOException {
-               JarInputStream jis = null;
-               try {
-                       jis = openJar();
-                       JarEntry je;
-
-                       System.out.println("Looking for: " + path);
-
-                       while ((je = jis.getNextJarEntry()) != null) {
-                               System.out.println("je = " + je.getName());
-                               if (je.getName().equals(path))
-                                       return jis;
+                               set.name = a.getValue("name_" + i);
+                               set.source = a.getValue("source_" + i);
+                               set.gid = getInt(a, i, "gid_");
+                               set.count = getInt(a, i, "count_");
+                               set.width = getInt(a, i, "width_");
+                               set.height = getInt(a, i, "height_");
+
+                               list[i] = set;
+                               handle.put(set.source, jis -> {
+                                       try {
+                                               set.load(jis);
+                                       } catch (IOException ex) {
+                                               ex.printStackTrace();
+                                       }
+                               });
                        }
-                       jis.close();
-                       throw new FileNotFoundException(path);
-               } catch (IOException ex) {
-                       if (jis != null)
-                               jis.close();
-                       throw ex;
+                       sets.put(name, list);
                }
        }
 
@@ -135,29 +129,7 @@ public class DataManager {
                public ImageSet() {
                }
 
-               public void load() throws IOException {
+               public void load(InputStream is) throws IOException {
                }
-               /*
-                public InputStream getInputStream() throws IOException {
-                JarInputStream jis = null;
-                try {
-                jis = openJar();
-                JarEntry je;
-
-                System.out.println("Looking for: " + source);
-
-                while ((je = jis.getNextJarEntry()) != null) {
-                System.out.println("je = " + je.getName());
-                if (je.getName().equals(source))
-                return jis;
-                }
-                jis.close();
-                throw new FileNotFoundException(source);
-                } catch (IOException ex) {
-                if (jis != null)
-                jis.close();
-                throw ex;
-                }
-                }*/
        }
 }
index c63efd7..3f0c303 100644 (file)
@@ -63,14 +63,14 @@ public class Dusk implements Runnable, DuskProtocol {
        // FIXME: applet will have a different frontend or something
        //AudioClip audSFX[],   audMusic[][];
        //AudioClip audMusicPlaying;
-       String rcLocation;
+       //String rcLocation;
        List<TransactionItem> buyList = new ArrayList<>();
        List<TransactionItem> sellList = new ArrayList<>();
        Equipment worn = new Equipment();
        private Socket socket;
        private DataOutputStream outstream;
        private DataInputStream instream;
-       int mapSize = 11;
+       //int mapSize = 11;
        ClientMap map;
        boolean intStep,
                        blnMusic = true;
@@ -308,18 +308,12 @@ public class Dusk implements Runnable, DuskProtocol {
 
                                        case MSG_INIT_MAP: {
                                                ListMessage lm = (ListMessage) dm;
+                                               String rc = lm.getString(FIELD_MAP_ASSETLOCATION);
+                                               int mapWidth =  lm.getInteger(FIELD_MAP_WIDTH);
+                                               int mapHeight =  lm.getInteger(FIELD_MAP_HEIGHT);
 
-                                               // FIXME: use jar stuff
-                                               rcLocation = lm.getString(FIELD_MAP_ASSETLOCATION);
-                                               // FIXME: hack
-                                               rcLocation = "rc/" + rcLocation;
-
-                                               frame.setImages(new File(rcLocation + "/images/map.gif").toURI().toString(), 32,
-                                                               new File(rcLocation + "/images/players.gif").toURI().toString(), 64,
-                                                               new File(rcLocation + "/images/sprites.gif").toURI().toString(), 64);
-
-                                               mapSize = lm.getInteger(FIELD_MAP_WIDTH);
-                                               map = new ClientMap(mapSize, mapSize);
+                                               frame.setImages(rc);
+                                               map = new ClientMap(mapWidth, mapHeight);
                                                break;
                                        }
                                        case MSG_UPDATE_MAP: {
index 9bd3490..b4b8ceb 100644 (file)
@@ -124,7 +124,7 @@ public interface GUI {
        public void setLookList(List<Entity> list);
 
        // setup/map
-       public void setImages(String tiles, int tileSize, String players, int playerSize, String sprites, int spriteSize);
+       public void setImages(String rc);
 
        /**
         * Update the map.
index 8281c91..e282c02 100644 (file)
@@ -23,22 +23,25 @@ package duskz.client.fx;
 
 import duskz.client.DataManager;
 import java.io.BufferedReader;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
+import java.util.function.Consumer;
+import java.util.jar.JarInputStream;
+import java.util.jar.Manifest;
 import javafx.geometry.Rectangle2D;
 import javafx.scene.image.Image;
 import javafx.scene.image.ImageView;
+import javafx.scene.image.PixelReader;
+import javafx.scene.image.WritableImage;
 
 /**
  * Data manager for JavaFX - loads images into Image nodes and helpers
  * to create positioned tiles.
- *
- * @author notzed
  */
 public class DataManagerFX extends DataManager {
 
@@ -57,50 +60,47 @@ public class DataManagerFX extends DataManager {
        }
 
        @Override
-       public void open() throws IOException {
-               super.open();
+       protected void scanManifest(Manifest man, Map<String, Consumer<JarInputStream>> handle) {
+               super.scanManifest(man, handle);
 
-               try (BufferedReader is = new BufferedReader(new InputStreamReader(getInputStream("tiles/anim")))) {
-                       String line;
-                       PropParser prop = new PropParser();
+               handle.put("titles/anim", jis -> {
+                       try (BufferedReader is = new BufferedReader(new InputStreamReader(jis))) {
+                               String line;
+                               PropParser prop = new PropParser();
 
-                       while ((line = is.readLine()) != null) {
-                               if (!prop.setInput(line))
-                                       continue;
+                               while ((line = is.readLine()) != null) {
+                                       if (!prop.setInput(line))
+                                               continue;
 
-                               if (!prop.getProperty().startsWith("anim."))
-                                       continue;
+                                       if (!prop.getProperty().startsWith("anim."))
+                                               continue;
 
-                               AnimSetFX anim = new AnimSetFX(prop.getProperty().substring(5));
-                               List<Rectangle2D> rects = new ArrayList<>();
-                               while (!prop.eof()) {
-                                       int tileid = prop.nextInt();
-                                       int time = 250;
+                                       AnimSetFX anim = new AnimSetFX(prop.getProperty().substring(5));
+                                       List<Rectangle2D> rects = new ArrayList<>();
+                                       while (!prop.eof()) {
+                                               int tileid = prop.nextInt();
+                                               int time = 250;
 
-                                       if (prop.nextChar(':')) {
-                                               time = prop.nextInt();
-                                       }
+                                               if (prop.nextChar(':')) {
+                                                       time = prop.nextInt();
+                                               }
 
-                                       if (anim.root == -1)
-                                               anim.root = tileid;
-                                       rects.add(createTile(tileid, 0, 0, 64, 64).getViewport());
+                                               if (anim.root == -1)
+                                                       anim.root = tileid;
+                                               rects.add(createTile(tileid, 0, 0, 64, 64).getViewport());
 
-                                       if (!prop.nextChar(','))
-                                               break;
-                               }
-                               if (anim.root != -1) {
-                                       anim.tiles = rects.toArray(new Rectangle2D[rects.size()]);
-                                       animset.put(anim.root, anim);
+                                               if (!prop.nextChar(','))
+                                                       break;
+                                       }
+                                       if (anim.root != -1) {
+                                               anim.tiles = rects.toArray(new Rectangle2D[rects.size()]);
+                                               animset.put(anim.root, anim);
+                                       }
                                }
+                       } catch (IOException ex) {
+                               ex.printStackTrace();
                        }
-               } catch (FileNotFoundException ex) {
-               }
-               /*              final Rectangle2D[] anims = new Rectangle2D[2];
-                anims[0] = data.createTile(305, 0, 0, tileSize, tileSize).getViewport();
-                anims[1] = data.createTile(304, 0, 0, tileSize, tileSize).getViewport();
-                final List<ImageView> animated = new ArrayList<>();
-                */
-
+               });
        }
 
        static class PropParser {
@@ -161,13 +161,11 @@ public class DataManagerFX extends DataManager {
        }
 
        public void updateTile(ImageView iv, int tileid, int tilewidth, int tileheight) {
-               for (int i = 0; i < tilesets.length; i++) {
-                       ImageSetFX is = (ImageSetFX) tilesets[i];
+               ImageSet[] tiles = sets.get("tiles");
+               for (int i = 0; i < tiles.length; i++) {
+                       ImageSetFX is = (ImageSetFX)tiles[i];
                        if (tileid >= is.gid && tileid < is.gid + is.count) {
-                               tileid -= is.gid;
-                               iv.setImage(is.image);
-                               //iv.setViewport(new Rectangle2D(tileid * is.width, 0, is.width, is.height));
-                               iv.setViewport(is.getViewport(tileid));
+                               iv.setImage(is.tiles[tileid - is.gid]);
                                iv.setTranslateY(-(is.height - tileheight));
                                //iv.relocate(tilex * tilewidth, tiley * tileheight - (is.height - tileheight));
                                return;
@@ -177,7 +175,7 @@ public class DataManagerFX extends DataManager {
 
        /**
         * Create a tile image and align it to the baseline of the map tile.
-        *
+        * <p>
         * This assumes the tiles are the same width but height may vary
         *
         * @param tileid
@@ -189,16 +187,39 @@ public class DataManagerFX extends DataManager {
         */
        public ImageView createTile(int tileid, int tilex, int tiley, int tilewidth, int tileheight) {
                try {
-                       for (int i = 0; i < tilesets.length; i++) {
-                               ImageSetFX is = (ImageSetFX) tilesets[i];
+                       ImageSet[] tiles = sets.get("tiles");
+                       for (int i = 0; i < tiles.length; i++) {
+                               ImageSetFX is = (ImageSetFX)tiles[i];
                                if (tileid >= is.gid && tileid < is.gid + is.count) {
-                                       ImageView iv = new ImageView(is.image);
-
-                                       tileid -= is.gid;
-                                       //iv.setViewport(new Rectangle2D(tileid * is.width, 0, is.width, is.height));
-                                       iv.setViewport(is.getViewport(tileid));
+                                       ImageView iv = new ImageView(is.tiles[tileid - is.gid]);
                                        iv.relocate(tilex * tilewidth, tiley * tileheight - (is.height - tileheight));
+                                       return iv;
+                               }
+                       }
+               } catch (Exception x) {
+                       x.printStackTrace();
+               }
+               System.out.println("No such tile: " + tileid);
+               // Broken image?
+               return new ImageView();
+       }
+
+       public ImageView createSprite(String set, int tileid, int tilex, int tiley, int tilewidth, int tileheight) {
+               try {
+                       ImageSet[] tiles = sets.get(set);
+                       for (int i = 0; i < tiles.length; i++) {
+                               ImageSetFX is = (ImageSetFX)tiles[i];
+                               if (tileid >= is.gid && tileid < is.gid + is.count) {
+                                       ImageView iv = new ImageView(is.tiles[tileid - is.gid]);
 
+                                       if (is.height != tileheight) {
+                                               double scale = (double)tileheight / is.height;
+
+                                               //iv.relocate(tilex * tilewidth - tilewidth  * scale, tiley * tileheight - tileheight * scale);
+                                               iv.setScaleX(scale);
+                                               iv.setScaleY(scale);
+                                       }
+                                       iv.relocate(tilex * tilewidth - tilewidth * 0.5, tiley * tileheight - tileheight * 0.5);
                                        return iv;
                                }
                        }
@@ -225,29 +246,21 @@ public class DataManagerFX extends DataManager {
        public class ImageSetFX extends ImageSet {
 
                Image image;
-               Rectangle2D tiles[];
+               public Image[] tiles;
 
                public ImageSetFX() {
                }
 
-               public void load() throws IOException {
+               @Override
+               public void load(InputStream is) throws IOException {
                        System.out.println("Load tileset " + name + " gid " + gid + " count " + count);
-                       try (InputStream s = getInputStream(this.source)) {
-                               image = new Image(s);
-                       }
+                       image = new Image(is);
 
-                       tiles = new Rectangle2D[count];
+                       tiles = new Image[count];
+                       PixelReader reader = image.getPixelReader();
                        for (int i = 0; i < count; i++) {
-                               tiles[i] = new Rectangle2D(i * width, 0, width, height);
+                               tiles[i] = new WritableImage(reader, i * width, 0, width, height);
                        }
                }
-
-               public Image getImage() {
-                       return image;
-               }
-
-               public Rectangle2D getViewport(int tileid) {
-                       return tiles[tileid];
-               }
        }
 }
index f0450b6..35f71ee 100644 (file)
@@ -55,7 +55,7 @@ public class DuskFX extends Application {
                        }
                });
 
-               stage.getScene().getStylesheets().add(DuskFX.class.getResource("style.css").toExternalForm());
+               stage.getScene().getStylesheets().add(DuskFX.class.getResource("style.css").toString());
                stage.setTitle("DuskZ JavaFX");
                stage.show();
 
index d991a78..04e7d64 100644 (file)
@@ -34,7 +34,9 @@ import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import java.util.Random;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -850,31 +852,22 @@ public class MainFrameFX extends StackPane implements GUI {
                });
        }
        DataManagerFX data;
-       //Image tileImage;
-       int tileSize;
+       int tileSize = 32;
        Image playerImage;
        int playerSize;
        Image spriteImage;
        int spriteSize;
 
        @Override
-       public void setImages(String tiles, int tileSize, String players, int playerSize, String sprites, int spriteSize) {
+       public void setImages(String rc) {
                try {
-                       System.out.println("set tile image");
-                       // FIXME: put sprites into data manager
-                       data = new DataManagerFX("tileset.jar");
-                       data.open();
-                       //tileImage = new Image(tiles, false);
-                       this.tileSize = tileSize;
-                       playerImage = new Image(players, false);
-                       this.playerSize = playerSize;
-                       spriteImage = new Image(sprites, false);
-                       this.spriteSize = spriteSize;
+                       data = new DataManagerFX(rc);
+                       data.load();
                } catch (IOException ex) {
                        Logger.getLogger(MainFrameFX.class.getName()).log(Level.SEVERE, null, ex);
                }
        }
-       TileAnimator animator;
+       HashMap<Integer, TileAnimator> animators = new HashMap<>();
 
        @Override
        public void updateMap(ClientMap map) {
@@ -895,11 +888,8 @@ public class MainFrameFX extends StackPane implements GUI {
                final ArrayList<Node> upper = new ArrayList<>();
                int levelCount = map.getLevelCount();
 
-               // Animated tiles hack test
-               final Rectangle2D[] anims = new Rectangle2D[2];
-               anims[0] = data.createTile(305, 0, 0, tileSize, tileSize).getViewport();
-               anims[1] = data.createTile(304, 0, 0, tileSize, tileSize).getViewport();
-               final List<ImageView> animated = new ArrayList<>();
+               // Animated tiles stuff
+               final HashMap<Integer, List<ImageView>> animated = new HashMap<>();
 
                // Build map
                for (int l = 0; l < levelCount; l++) {
@@ -911,8 +901,14 @@ public class MainFrameFX extends StackPane implements GUI {
                                                ImageView iv = data.createTile(tileid, x, y, tileSize, tileSize);
                                                children.add(iv);
 
-                                               if (tileid == 305)
-                                                       animated.add(iv);
+                                               if (data.isAnimRoot(tileid)) {
+                                                       List<ImageView> list = animated.get(tileid);
+                                                       if (list == null) {
+                                                               list = new ArrayList<>();
+                                                               animated.put(tileid, list);
+                                                       }
+                                                       list.add(iv);
+                                               }
                                        }
                                }
 
@@ -940,13 +936,20 @@ public class MainFrameFX extends StackPane implements GUI {
                                graphics.getChildren().setAll(children);
                                graphics.getChildren().addAll(upper);
 
-                               System.out.println("animated node count = " + animated.size());
-                               if (animator == null) {
-                                       animator = new TileAnimator(animated, Duration.seconds(0.25), anims);
-                                       animator.setCycleCount(Animation.INDEFINITE);
-                                       animator.play();
-                               } else
-                                       animator.setNodes(animated);
+                               for (Map.Entry<Integer, List<ImageView>> e: animated.entrySet()) {
+                                       int root = e.getKey();
+                                       TileAnimator animator = animators.get(root);
+                                       DataManagerFX.AnimSetFX set = data.getAnimSet(root);
+                                       if (animator == null) {
+                                               animator = new TileAnimator(e.getValue(), Duration.seconds(0.25), set.tiles);
+                                               animators.put(root, animator);
+                                               animator.setCycleCount(Animation.INDEFINITE);
+                                               animator.play();
+                                       } else {
+                                               animator.setNodes(e.getValue());
+                                       }
+                                       System.out.printf("Set anim root %d\n", root);
+                               }
                        }
                });
        }
@@ -959,22 +962,11 @@ public class MainFrameFX extends StackPane implements GUI {
 
                // TODO: just make it an entity node
                if (e.intStep == -1) {
-                       // Hack: sprites are 64x64
-                       ImageView iv = new ImageView(spriteImage);
-                       iv.setViewport(new Rectangle2D(e.intImage * spriteSize, 0,
-                               spriteSize, spriteSize));
-                       iv.relocate((x * tileSize) - tileSize / 2, (y * tileSize) - tileSize / 2);
-                       iv.setScaleX(0.5);
-                       iv.setScaleY(0.5);
+                       ImageView iv = data.createSprite("sprites", e.intImage, e.locx - offx, e.locy - offy, tileSize, tileSize);
                        children.add(iv);
 
                } else {
-                       ImageView iv = new ImageView(playerImage);
-                       iv.setViewport(new Rectangle2D((e.intImage * 8 + e.intStep) * spriteSize, 0,
-                               spriteSize, spriteSize));
-                       iv.relocate((x * tileSize) + tileSize / 2 - spriteSize / 2, (y * tileSize) - spriteSize / 2);
-                       iv.setScaleX(1);
-                       iv.setScaleY(1);
+                       ImageView iv = data.createSprite("players", e.intImage * 8 + e.intStep,  e.locx - offx, e.locy - offy, tileSize, tileSize);
                        children.add(iv);
                }
                // FIXME: intnum not used anymore
diff --git a/src/duskz.client/classes/jfxtras/internal/scene/control/ListSpinner.css b/src/duskz.client/classes/jfxtras/internal/scene/control/ListSpinner.css
new file mode 100644 (file)
index 0000000..52fa048
--- /dev/null
@@ -0,0 +1,50 @@
+/* basic settings */\r
+.ListSpinner { \r
+       -fx-background-color: -fx-shadow-highlight-color, -fx-outer-border, -fx-inner-border, -fx-body-color;\r
+       -fx-background-insets: 0 0 -1 0, 0, 1, 2;\r
+       -fx-background-radius: 5, 5, 4, 3;\r
+       -fx-padding: 0.266667em 0.233333em 0.25em 0.233333em;\r
+       -fx-text-fill: -fx-text-base-color;\r
+}\r
+\r
+.ListSpinner:hover {\r
+    -fx-color: -fx-hover-base;\r
+}\r
+\r
+.ListSpinner:focused { \r
+       -fx-color: -fx-base;\r
+       -fx-background-color: -fx-focus-color, -fx-outer-border, -fx-inner-border, -fx-body-color;\r
+       -fx-background-insets: -1.4, 0, 1, 2;\r
+       -fx-background-radius: 6.4, 5, 4, 3;    \r
+}\r
+\r
+.ListSpinner .valuePane { \r
+       -fx-padding: 0.0em 0.2em 0.0em 0.2em;\r
+}\r
+\r
+.ListSpinner .left-arrow { \r
+    -fx-shape: "M4,-4 L0,0 L4,4 Z";\r
+    -fx-scale-shape: false;\r
+    -fx-padding: 8;\r
+}\r
+.ListSpinner .right-arrow { \r
+    -fx-shape: "M0,-4 L4,0 L0,4 Z";\r
+    -fx-scale-shape: false;\r
+    -fx-padding: 8;\r
+}\r
+.ListSpinner .down-arrow { \r
+    -fx-shape: "M-4,-2 L0,2 L4,-2 Z";\r
+    -fx-scale-shape: false;\r
+    -fx-padding: 8;\r
+}\r
+.ListSpinner .up-arrow { \r
+    -fx-shape: "M4,2 L-4,2 L0,-2 Z";\r
+    -fx-scale-shape: false;\r
+    -fx-padding: 8;\r
+}\r
+.ListSpinner .idle {\r
+    -fx-background-color: -fx-mark-color;\r
+}\r
+.ListSpinner .clicked { \r
+    -fx-background-color: -fx-focus-color;\r
+}\r
diff --git a/src/duskz.client/windows-amd64/bin/run-client.bat b/src/duskz.client/windows-amd64/bin/run-client.bat
new file mode 100644 (file)
index 0000000..ccc4cca
--- /dev/null
@@ -0,0 +1,6 @@
+REM run-client
+@echo off
+set JAVA_HOME=%~dp0\..
+rem stops cmd window staying visible
+rem start /min "dusk client" "%JAVA_HOME%\bin\java" -m duskz.client/duskz.client.fx.DuskFX
+"%JAVA_HOME%\bin\java" -m duskz.client/duskz.client.fx.DuskFX
index de35e0b..e851b3c 100644 (file)
@@ -45,7 +45,7 @@ import java.util.zip.GZIPInputStream;
 
 /**
  * Low level map management and helpers.
- *
+ * <p>
  * Some of the helpers provide higher level functionality like path finding.
  *
  * @author notzed
@@ -88,7 +88,7 @@ public class TileMap<Thing extends Locatable> implements Iterable<TileMap.MapDat
         * Layers
         */
        private int groundLayer;
-       private TileLayer layers[];
+       private TileLayer layers[] = new TileLayer[0];
        /**
         * privileges for each cell. This appears to be unimplemented in Dusk so
         * isn't here either.
@@ -136,6 +136,7 @@ public class TileMap<Thing extends Locatable> implements Iterable<TileMap.MapDat
                return groundLayer;
        }
 
+       /** FIXME: only saves old 'shortmap' format */
        public void saveMap(File path) throws IOException {
                path.delete();
                try (RandomAccessFile rafFile = new RandomAccessFile(path, "rw")) {
@@ -175,14 +176,14 @@ public class TileMap<Thing extends Locatable> implements Iterable<TileMap.MapDat
                        tx -= this.x;
                        ty -= this.y;
                        return tx >= 0 && tx < width
-                                       && ty >= 0 && ty < height;
+                               && ty >= 0 && ty < height;
                }
 
                public short getTile(int tx, int ty) {
                        tx -= this.x;
                        ty -= this.y;
                        if (tx >= 0 && tx < width
-                                       && ty >= 0 && ty < height) {
+                               && ty >= 0 && ty < height) {
                                return tiles[tx + ty * width];
                        } else
                                return 0;
@@ -196,7 +197,7 @@ public class TileMap<Thing extends Locatable> implements Iterable<TileMap.MapDat
 
        /**
         * Load just the map part of a map.
-        *
+        * <p>
         * TODO: sort something out with the alias stuff and loadLayered()
         *
         * @param is
@@ -217,7 +218,7 @@ public class TileMap<Thing extends Locatable> implements Iterable<TileMap.MapDat
                        int layerCount = mapFile.readInt();
 
                        if (magic != MAGIC_LAYERED
-                                       || version != 0) {
+                               || version != 0) {
                                throw new IOException("Invalid format/magic/unknown version");
                        }
 
@@ -287,7 +288,7 @@ public class TileMap<Thing extends Locatable> implements Iterable<TileMap.MapDat
                        int layerCount = mapFile.readInt();
 
                        if (magic != MAGIC_LAYERED
-                                       || version != 0) {
+                               || version != 0) {
                                throw new IOException("Invalid format/magic/unknown version");
                        }
 
@@ -324,34 +325,34 @@ public class TileMap<Thing extends Locatable> implements Iterable<TileMap.MapDat
                // Format is alias.x.y=name
                File aliasPath = new File(path.getParentFile(), path.getName() + ".alias");
                try (PropertyLoader pl = new PropertyLoader(aliasPath)) {
-                       for (PropertyEntry pe : pl) {
+                       for (PropertyEntry pe: pl) {
                                String[] line = pe.name.split("\\.");
                                int x = Integer.valueOf(line[0]);
                                int y = Integer.valueOf(line[1]);
                                Location l = new Location(x, y);
 
                                switch (line[2]) {
-                                       case "alias":
-                                               map.aliases.put(l, pe.value);
-                                               map.aliasesByName.put(pe.value, l);
-                                               break;
-                                       //case "script":
-                                       //      map.seeScript.put(l, pe.value);
-                                       //      map.moveScript.put(l, pe.value);
-                                       //      map.locationActionScript.put(l, pe.value);
-                                       //      break;
-                                       case "visible":
-                                               map.visibleScript.put(l, pe.value);
-                                               break;
-                                       case "able":
-                                               map.ableScript.put(l, pe.value);
-                                               break;
-                                       case "action":
-                                               map.actionScript.put(l, pe.value);
-                                               break;
-                                       case "goto":
-                                               map.jumpTable.put(l, pe.value);
-                                               break;
+                               case "alias":
+                                       map.aliases.put(l, pe.value);
+                                       map.aliasesByName.put(pe.value, l);
+                                       break;
+                               //case "script":
+                               //      map.seeScript.put(l, pe.value);
+                               //      map.moveScript.put(l, pe.value);
+                               //      map.locationActionScript.put(l, pe.value);
+                               //      break;
+                               case "visible":
+                                       map.visibleScript.put(l, pe.value);
+                                       break;
+                               case "able":
+                                       map.ableScript.put(l, pe.value);
+                                       break;
+                               case "action":
+                                       map.actionScript.put(l, pe.value);
+                                       break;
+                               case "goto":
+                                       map.jumpTable.put(l, pe.value);
+                                       break;
                                }
                        }
                } catch (NullPointerException | IndexOutOfBoundsException x) {
@@ -403,7 +404,7 @@ public class TileMap<Thing extends Locatable> implements Iterable<TileMap.MapDat
                                        if (format == FORMAT_BYTE)
                                                map.setTile(x, y, mapFile.readByte());
                                        else
-                                               map.setTile(x, y, mapFile.readShort());
+                                               map.setTile(x, y, mapFile.readShort() + 1);
                                }
                        }
                        map.layers = new TileLayer[1];
@@ -444,12 +445,12 @@ public class TileMap<Thing extends Locatable> implements Iterable<TileMap.MapDat
 
        public boolean inside(int x, int y) {
                return x >= 0 && x < cols
-                               && y >= 0 && y < rows;
+                       && y >= 0 && y < rows;
        }
 
        public boolean inside(int layer, int x, int y) {
                return x >= 0 && x < cols
-                               && y >= 0 && y < rows;
+                       && y >= 0 && y < rows;
        }
 
        /**
@@ -508,7 +509,7 @@ public class TileMap<Thing extends Locatable> implements Iterable<TileMap.MapDat
        }
 
        public void setTile(int x, int y, int t) {
-               tiles[x + y * cols] = (short) t;
+               tiles[x + y * cols] = (short)t;
        }
 
        public short getTile(int x, int y) {
@@ -682,7 +683,7 @@ public class TileMap<Thing extends Locatable> implements Iterable<TileMap.MapDat
        @Override
        public boolean equals(Object obj) {
                if (obj instanceof TileMap) {
-                       return name.equals(((TileMap) obj).name);
+                       return name.equals(((TileMap)obj).name);
                } else
                        return false;
        }
@@ -811,7 +812,7 @@ public class TileMap<Thing extends Locatable> implements Iterable<TileMap.MapDat
                @Override
                public boolean hasNext() {
                        return (x + 1) < x1
-                                       || (y + 1) < y1;
+                               || (y + 1) < y1;
                }
 
                @Override
@@ -840,7 +841,7 @@ public class TileMap<Thing extends Locatable> implements Iterable<TileMap.MapDat
 
        /**
         * Implements an iterator which follows a 'looking' path
-        *
+        * <p>
         * TODO: it should probably use Bresenhams line algorithm
         */
        private class LookIterator implements Iterator<MapData> {
@@ -897,7 +898,6 @@ public class TileMap<Thing extends Locatable> implements Iterable<TileMap.MapDat
                        //if ((flags & SKIP_START) != 0 && sx == x && sy == y) {
                        //      lineStep();
                        //}
-
                        data.setData(x, y);
 
                        if (!there) {
@@ -961,7 +961,7 @@ public class TileMap<Thing extends Locatable> implements Iterable<TileMap.MapDat
 
                @Override
                public boolean equals(Object obj) {
-                       MoveInfo o = (MoveInfo) obj;
+                       MoveInfo o = (MoveInfo)obj;
 
                        return x == o.x && y == o.y;
                }
@@ -983,9 +983,9 @@ public class TileMap<Thing extends Locatable> implements Iterable<TileMap.MapDat
        /**
         * An iterator which steps through the individual moves to get to a
         * destination.
-        *
+        * <p>
         * Implemented using A* algorithm, so can handle obstructions.
-        *
+        * <p>
         * TODO: Limit the search space.
         */
        private class MoveIterator implements Iterator<MoveData> {
@@ -1011,13 +1011,12 @@ public class TileMap<Thing extends Locatable> implements Iterable<TileMap.MapDat
                        this.l = l;
 
                        // A* requires the whole path to be calculated ahead of time.
-
                        List<MoveInfo> path = findPath();
 
                        System.out.printf("Finding path from %d,%d to %d,%d: ", sx, sy, ex, ey);
 
                        if (path != null) {
-                               for (MoveInfo mi : path) {
+                               for (MoveInfo mi: path) {
                                        System.out.print(" ");
                                        System.out.print(mi.direction);
                                }
@@ -1034,7 +1033,7 @@ public class TileMap<Thing extends Locatable> implements Iterable<TileMap.MapDat
                }
 
                float estimateCost(int sx, int sy, int ex, int ey) {
-                       return (float) Math.sqrt((ex - sx) * (ex - sx) + (ey - sy) * (ey - sy));
+                       return (float)Math.sqrt((ex - sx) * (ex - sx) + (ey - sy) * (ey - sy));
                }
 
                List<MoveInfo> constructPath(List<MoveInfo> list, MoveInfo n) {
@@ -1098,7 +1097,7 @@ public class TileMap<Thing extends Locatable> implements Iterable<TileMap.MapDat
                                        // traversed or if a shorter path to this
                                        // neighbor node is found.
                                        if ((!isOpen && !isClosed)
-                                                       || costFromStart < nnode.cost) {
+                                               || costFromStart < nnode.cost) {
                                                nnode.parent = node;
                                                nnode.cost = costFromStart;
                                                nnode.estimate = estimateCost(nnode.x, nnode.y, ex, ey);
index 2272517..561690d 100644 (file)
@@ -186,7 +186,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
                                }
                        } else if ((newmap = new File("shortmapx")).exists()) {
                                TileMap map;
-                               log.printMessage(Log.INFO, "Loading Map...");
+                               log.printMessage(Log.INFO, "Loading Map shortmapx ...");
                                map = TileMap.loadMapX(newmap);
                                maps.put("main", map);
                                log.printMessage(Log.VERBOSE, map.getCols() + "/" + map.getRows());
@@ -194,7 +194,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
                                TileMap map;
                                newmap = new File("shortmap");
                                if (newmap.exists()) {
-                                       log.printMessage(Log.INFO, "Loading Map...");
+                                       log.printMessage(Log.INFO, "Loading Map shortmap...");
                                        map = TileMap.loadMap(newmap, TileMap.FORMAT_SHORT);
                                        log.printMessage(Log.VERBOSE, map.getCols() + "/" + map.getRows());
                                } else {
@@ -1349,7 +1349,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
                                return false;
                }
                return true;
-               /*              
+               /*
                 int tempX = thing.x;
                 int tempY = thing.y;
 
index 9c8cdf6..a224964 100644 (file)
@@ -1596,7 +1596,7 @@ public class LivingThing extends DuskObject implements Runnable, DuskProtocol {
                y = newLocY;
                try {
                        // Really move + map should be atomic to client.
-                       
+
                        //update entity:
                        if (isWorking) {
                                game.addDuskObject(map, this);
@@ -2475,6 +2475,10 @@ public class LivingThing extends DuskObject implements Runnable, DuskProtocol {
                 */
                if (!create)
                        loadUserFile(file, true);
+               if (map == null) {
+                       game.log.printMessage(Log.INFO, "No map set in user, using default");
+                       map = game.maps.values().stream().findFirst().orElseThrow();
+               }
 
                /*
                 ** Try to load a pet, if they don't already have one
@@ -2540,7 +2544,7 @@ public class LivingThing extends DuskObject implements Runnable, DuskProtocol {
                 strStore2;
                 int count=0;
                 RandomAccessFile rafMusic;
-                       
+
                 rafMusic = new RandomAccessFile("music0","r");
                 strStore = "";
                 try
@@ -2796,7 +2800,7 @@ public class LivingThing extends DuskObject implements Runnable, DuskProtocol {
         qMessage.push(sd);
         }
         }
-       
+
         public void send(long data)
         {
         if (isPlayer() && blnWorking && !blnIsClosing)
index cef2ab3..492af84 100644 (file)
@@ -22,11 +22,13 @@ package duskz.server.entityz;
 
 import duskz.map.Location;
 import duskz.map.TileMap;
-import duskz.util.PropertyLoader;
 import duskz.server.BlockedIPException;
+import duskz.util.PropertyLoader;
+import java.io.BufferedInputStream;
 import java.io.BufferedReader;
 import java.io.BufferedWriter;
 import java.io.File;
+import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.FileReader;
 import java.io.IOException;
@@ -36,6 +38,7 @@ import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Properties;
 import java.util.concurrent.Future;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -43,7 +46,7 @@ import java.util.regex.Pattern;
 
 /**
  * Main game engine
- *
+ * <p>
  * Handles game setup, prefs, loading/restoring state, and the main
  * game clock.
  *
@@ -149,7 +152,14 @@ public class Game {
                props = new ThingTable<>(new File(root, "props"));
 
                // Load preferences
-               // TODO: load preferences
+               // TODO: load more preferences
+               Properties prefs = new Properties();
+               try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File(confDir, "prefs")))) {
+                       prefs.load(bis);
+               } catch (FileNotFoundException ex) {
+                       log.printf(ex, "Preferences not found: %s", new File(confDir, "prefs"));
+               }
+               rcName = prefs.getProperty("rcname", "somedusk");
 
                // Load all races (move to 'racelist' class?)
                {
@@ -157,7 +167,7 @@ public class Game {
                        if (!path.isDirectory())
                                throw new FileNotFoundException("Unable to find races");
 
-                       for (File file : path.listFiles()) {
+                       for (File file: path.listFiles()) {
                                try {
                                        Race race = Race.loadRace(file);
                                        races.put(race.name, race);
@@ -172,7 +182,7 @@ public class Game {
                        File path = new File(root, "defMaps");
                        if (!path.isDirectory())
                                throw new FileNotFoundException("Unable to find maps");
-                       for (File file : path.listFiles()) {
+                       for (File file: path.listFiles()) {
                                if (file.getName().endsWith(".alias"))
                                        continue;
                                try {
@@ -190,20 +200,20 @@ public class Game {
                {
                        File path = new File(root, "tileScriptMap");
                        try (PropertyLoader pl = new PropertyLoader(path)) {
-                               for (PropertyLoader.PropertyEntry pe : pl) {
+                               for (PropertyLoader.PropertyEntry pe: pl) {
                                        String[] line = pe.name.split("\\.");
                                        Integer id = Integer.valueOf(line[0]);
 
                                        switch (line[1]) {
-                                               case "visible":
-                                                       tileVisible.put(id, pe.value);
-                                                       break;
-                                               case "able":
-                                                       tileAble.put(id, pe.value);
-                                                       break;
-                                               case "action":
-                                                       tileAction.put(id, pe.value);
-                                                       break;
+                                       case "visible":
+                                               tileVisible.put(id, pe.value);
+                                               break;
+                                       case "able":
+                                               tileAble.put(id, pe.value);
+                                               break;
+                                       case "action":
+                                               tileAction.put(id, pe.value);
+                                               break;
                                        }
                                }
                        }
@@ -224,7 +234,7 @@ public class Game {
                        File path = new File(root, "factions");
                        if (!path.isDirectory())
                                throw new FileNotFoundException("Unable to find factions");
-                       for (File file : path.listFiles()) {
+                       for (File file: path.listFiles()) {
                                try {
                                        Faction f = new Faction(file.getName(), this);
                                        f.load();
@@ -242,7 +252,7 @@ public class Game {
                        File path = new File(root, "defMobs");
                        if (!path.isDirectory())
                                throw new FileNotFoundException("Unable to find mobs");
-                       for (File file : path.listFiles()) {
+                       for (File file: path.listFiles()) {
                                try {
                                        Mobile mob = new Mobile(this);
                                        mob.load(file);
@@ -254,7 +264,6 @@ public class Game {
                        }
                }
 
-
                // Load all active objects
                // FIXME: has to copy to various indices
                mobs.restoreState(this, new File(root, "defMobs"));
@@ -263,15 +272,15 @@ public class Game {
                props.restoreState(this);
 
                // HACK: just copy to indices now
-               for (Mobile m : mobs.values()) {
+               for (Mobile m: mobs.values()) {
                        System.out.println("add mob " + m.name + " on " + m.map.name);
                        addThing(m);
                }
-               for (Sign s : signs.values()) {
+               for (Sign s: signs.values()) {
                        System.out.println("add sign: " + s.name + " at " + s.x + ", " + s.y + " on map " + s.map.name);
                        addThing(s);
                }
-               for (Shop s : gameShops.values()) {
+               for (Shop s: gameShops.values()) {
                        System.out.println("add shop: " + s.name + " at " + s.x + ", " + s.y + " on map " + s.map.name);
                        addThing(s);
                }
@@ -318,7 +327,7 @@ public class Game {
                Thing.ThingResolver resolver = new Thing.EmptyResolver();
 
                try (BufferedReader in = new BufferedReader(new FileReader(new File(root, "defItems/" + name.toLowerCase())))) {
-                       return (Holdable) Thing.restoreState(this, in, resolver);
+                       return (Holdable)Thing.restoreState(this, in, resolver);
                } catch (IOException ex) {
                        log.printf(ex, "Loading item: %s", name);
                }
@@ -333,8 +342,8 @@ public class Game {
         */
        public boolean isPreference(String name) {
                switch (name) {
-                       case PREF_AI:
-                               return true;
+               case PREF_AI:
+                       return true;
                }
                // FIXME: implement properly
                return true;
@@ -350,7 +359,7 @@ public class Game {
         */
        public void globalChat(Player from, String clan, String msg) {
                //log.printMessage(Log.ALWAYS, msg);
-               for (Player player : players.values()) {
+               for (Player player: players.values()) {
                        player.chatMessage(from, clan, msg);
                }
        }
@@ -377,17 +386,17 @@ public class Game {
                assert (things.containsKey(thing.ID));
 
                switch (thing.getType()) {
-                       case Thing.TYPE_PLAYER:
-                               players.remove(((Player) thing).name);
-                               actives.remove(thing.ID);
-                               break;
-                       case Thing.TYPE_MOBILE:
-                               mobs.remove((Mobile) thing);
-                               actives.remove(thing.ID);
-                               break;
-                       case Thing.TYPE_PET:
-                               actives.remove(thing.ID);
-                               break;
+               case Thing.TYPE_PLAYER:
+                       players.remove(((Player)thing).name);
+                       actives.remove(thing.ID);
+                       break;
+               case Thing.TYPE_MOBILE:
+                       mobs.remove((Mobile)thing);
+                       actives.remove(thing.ID);
+                       break;
+               case Thing.TYPE_PET:
+                       actives.remove(thing.ID);
+                       break;
                }
 
                thing.map.removeEntity(thing);
@@ -399,20 +408,20 @@ public class Game {
                things.put(t.ID, t);
 
                switch (t.getType()) {
-                       case Thing.TYPE_PLAYER: {
-                               Player player = (Player) t;
-                               players.put(player.name, player);
-                               actives.put(player.ID, player);
-                               break;
-                       }
-                       case Thing.TYPE_MOBILE:
-                               mobs.add((Mobile) t);
-                               actives.put(t.ID, (Active) t);
-                               // Mobs are not addded to the map directly, respawn does it
-                               return;
-                       case Thing.TYPE_PET:
-                               actives.put(t.ID, (Active) t);
-                               break;
+               case Thing.TYPE_PLAYER: {
+                       Player player = (Player)t;
+                       players.put(player.name, player);
+                       actives.put(player.ID, player);
+                       break;
+               }
+               case Thing.TYPE_MOBILE:
+                       mobs.add((Mobile)t);
+                       actives.put(t.ID, (Active)t);
+                       // Mobs are not addded to the map directly, respawn does it
+                       return;
+               case Thing.TYPE_PET:
+                       actives.put(t.ID, (Active)t);
+                       break;
                }
                t.map.addEntity(t);
        }
@@ -510,8 +519,8 @@ public class Game {
 
                if (name != null) {
                        runScript(tileActionDir, name,
-                                       "game", this,
-                                       "trigger", trigger);
+                               "game", this,
+                               "trigger", trigger);
                }
        }
 
@@ -520,8 +529,8 @@ public class Game {
 
                if (name != null) {
                        return runScriptBoolean(false, tileVisibleDir, name,
-                                       "game", this,
-                                       "trigger", trigger);
+                               "game", this,
+                               "trigger", trigger);
                }
                return false;
        }
@@ -530,11 +539,10 @@ public class Game {
                String name = tileAble.get(tileid);
 
                //System.out.printf("onTileTable tid=%d script=%s\n", tileid, name);
-
                if (name != null) {
                        return runScriptBoolean(false, tileAbleDir, name,
-                                       "game", this,
-                                       "trigger", trigger);
+                               "game", this,
+                               "trigger", trigger);
                }
                return false;
        }
@@ -545,7 +553,7 @@ public class Game {
                        TileMap map = trigger.map;
                        Location l = map.locationForAlias(alias);
                        if (l == null) {
-                               for (TileMap scan : maps.values()) {
+                               for (TileMap scan: maps.values()) {
                                        l = scan.locationForAlias(alias);
                                        if (l != null) {
                                                map = scan;
@@ -555,7 +563,7 @@ public class Game {
                        }
                        if (l != null) {
                                System.out.printf("direct jump to '%s'  map %s %d,%d\n",
-                                               alias, map.name, l.x, l.y);
+                                       alias, map.name, l.x, l.y);
                                trigger.jumpTo(map, l.x, l.y);
                                return;
                        } else {
@@ -564,8 +572,8 @@ public class Game {
                }
 
                runScript(locationActionDir, trigger.map.locationActionScript(x, y),
-                               "game", this,
-                               "trigger", trigger);
+                       "game", this,
+                       "trigger", trigger);
        }
 
        private boolean haveMoveAble(Active trigger, int x, int y) {
@@ -574,8 +582,8 @@ public class Game {
 
        private boolean onMoveAble(Active trigger, int x, int y) {
                return runScriptBoolean(false, locationAbleDir, trigger.map.locationAbleScript(x, y),
-                               "game", this,
-                               "trigger", trigger);
+                       "game", this,
+                       "trigger", trigger);
        }
 
        private boolean haveMoveVisible(Active trigger, int x, int y) {
@@ -585,8 +593,8 @@ public class Game {
 
        private boolean onMoveVisible(Active trigger, int x, int y) {
                return runScriptBoolean(false, locationVisibleDir, trigger.map.locationVisibleScript(x, y),
-                               "game", this,
-                               "trigger", trigger);
+                       "game", this,
+                       "trigger", trigger);
        }
 
        /**
@@ -656,9 +664,9 @@ public class Game {
         */
        public void onItem(Active owner, Holdable item, String what) {
                runScript(onScriptDir, item.name + "." + what,
-                               "game", this,
-                               "owner", owner,
-                               "item", item);
+                       "game", this,
+                       "owner", owner,
+                       "item", item);
        }
 
        public boolean haveOnCondition(Holdable trigger, String what) {
@@ -674,9 +682,9 @@ public class Game {
         */
        public void onCondition(Active owner, Condition cond, String what) {
                runScript(onConditionDir, cond.name + "." + what,
-                               "game", this,
-                               "owner", owner,
-                               "condition", cond);
+                       "game", this,
+                       "owner", owner,
+                       "condition", cond);
        }
        private int tick;
 
@@ -686,7 +694,7 @@ public class Game {
 
        /**
         * Main game loop.
-        *
+        * <p>
         * 1. all actives are moved active.moveTick()
         * 2. run per-tick activities
         * 3. run player updates
@@ -696,16 +704,16 @@ public class Game {
        void gameTick(int tick) {
                this.tick = tick;
                // TODO: the order of this might need tweaking
-               for (Active a : actives.values()) {
+               for (Active a: actives.values()) {
                        a.moveTick();
                }
-               for (Active a : actives.values()) {
+               for (Active a: actives.values()) {
                        a.tick(tick);
                }
                //if (tick % 10 == 0) {
                if (tick % battleRate == 0) {
                        ArrayList<Battle> done = new ArrayList<>();
-                       for (Battle b : battles) {
+                       for (Battle b: battles) {
                                if (b.isFighting()) {
                                        b.run();
                                } else {
@@ -715,7 +723,7 @@ public class Game {
                        battles.removeAll(done);
                }
 
-               for (Active a : actives.values()) {
+               for (Active a: actives.values()) {
                        a.visibilityTick(tick);
                }
        }
@@ -736,7 +744,6 @@ public class Game {
        boolean checkPassword(String name, String pass, String address) throws TooManyTriesException, BlockedIPException {
 
                // TODO: handle ip blocked checking here
-
                Player p = new Player(this, null);
                try {
                        p.load(new File(root, "players/" + name.toLowerCase()));
@@ -792,7 +799,7 @@ public class Game {
                Pattern valid = Pattern.compile("^[A-Za-z]+$");
 
                if (reserved.matcher(lcplayer).matches()
-                               || !valid.matcher(player).matches()) {
+                       || !valid.matcher(player).matches()) {
                        return false;
                }
 
@@ -855,7 +862,7 @@ public class Game {
        public List<String> getRaceNames() {
                ArrayList<String> l = new ArrayList<>(races.size());
 
-               for (Race r : races.values()) {
+               for (Race r: races.values()) {
                        l.add(r.name);
                }
                return l;
index 5368059..4ac6385 100644 (file)
@@ -45,7 +45,7 @@ import java.util.logging.Logger;
 public class GameServer {
 
        // ms per tick: TODO: move into game prefs
-       int tickRate = 250;
+       int tickRate = 100;
        boolean cancelled = false;
        ServerSocket serverSocket;
        Socket socket;
@@ -61,7 +61,7 @@ public class GameServer {
                System.err.println();
                System.err.println(why);
        }
-       
+
        /**
         * Creates a new DuskServer object;
         */
index ab9c5a9..88bed64 100644 (file)
@@ -45,6 +45,7 @@ import java.util.concurrent.ThreadFactory;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import javax.script.Bindings;
+import javax.script.Invocable;
 import javax.script.ScriptContext;
 import javax.script.ScriptEngine;
 import javax.script.ScriptEngineManager;
@@ -52,14 +53,14 @@ import javax.script.SimpleScriptContext;
 
 /**
  * Manages the (javascript) engine
- *
+ * <p>
  * Doing this securely is complicated, so is likely to be buggy and not really
  * secure ...
- *
+ * <p>
  * I found I had to create the script engine itself from the same doPrivileged()
  * invocation or it simply broke the sanboxing. Hence all script execution is
  * performed from a pool of threads created from the same sandbox.
- *
+ * <p>
  * Another thread monitors the pool checking for out of control scripts (i.e.
  * they take too long to run).
  *
@@ -78,15 +79,14 @@ public class ScriptManager {
 
        public ScriptManager() {
                Permissions perms = new Permissions();
-               
+
                // FIXME: fix security manager for the actual paths used
-               
                //perms.add(new AllPermission());
                perms.add(new FilePermission("scripts/*", "read,write"));
                //      perms.add(new NetPermission("*"));
                //perms.add(new RuntimePermission("accessDeclaredMembers"));
                // Cast to Certificate[] required because of ambiguity:
-               ProtectionDomain domain = new ProtectionDomain(new CodeSource(null, (Certificate[]) null), perms);
+               ProtectionDomain domain = new ProtectionDomain(new CodeSource(null, (Certificate[])null), perms);
                ac = new AccessControlContext(new ProtectionDomain[]{domain});
        }
 
@@ -109,7 +109,6 @@ public class ScriptManager {
                                });
 
                                // TOOD: anything else I want to do here?  A management/monitoring thread?
-
                                return null;
                        }
                }, ac);
@@ -138,9 +137,8 @@ public class ScriptManager {
                // Well it mozilla code after-all ...
 
                // So i'm forced to use stop with all its apparent dangers.
-
                long now = System.currentTimeMillis();
-               for (Entry<Thread, Long> e : active.entrySet()) {
+               for (Entry<Thread, Long> e: active.entrySet()) {
                        if ((now - e.getValue()) > 1000) {
                                System.out.println("Job taking too long, interrupting it!");
                                //e.getKey().interrupt();
@@ -177,14 +175,14 @@ public class ScriptManager {
 
                public ScriptData(String script, Object... args) {
                        for (int i = 0; i < args.length; i += 2) {
-                               this.args.put((String) args[i], args[i + 1]);
+                               this.args.put((String)args[i], args[i + 1]);
                        }
                        this.script = script;
                }
 
                public ScriptData(File scriptFile, Object... args) throws FileNotFoundException, ClassCastException {
                        for (int i = 0; i < args.length; i += 2) {
-                               this.args.put((String) args[i], args[i + 1]);
+                               this.args.put((String)args[i], args[i + 1]);
                        }
                        this.scriptReader = new FileReader(scriptFile);
                }
@@ -203,11 +201,17 @@ public class ScriptManager {
                                b.clear();
                                b.putAll(args);
 
+                               System.out.println("invoke [");
+                               for (String s: b.keySet()) {
+                                       System.out.printf("arg %s: %s\n", s, b.get(s));
+                               }
+                               System.out.println("]\n");
+
                                startJob(Thread.currentThread());
                                if (scriptReader != null)
-                                       res = (T) engine.eval(scriptReader, b);
+                                       res = (T)engine.eval(scriptReader, b);
                                else
-                                       res = (T) engine.eval(script, b);
+                                       res = (T)engine.eval(script, b);
                                //                      lastStart = -1;
                                b.clear();
                        } finally {
@@ -219,7 +223,38 @@ public class ScriptManager {
                }
        };
 
+       public static class Bob {
+               public String bob() {
+                       System.out.println("bob called\n");
+                       return "3";
+               }
+       }
        public static void main(String[] args) {
+
+               if (true) {
+                       try {
+                               ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
+                               System.out.println(engine);
+                               engine.eval("""
+                function foo(trigger) {
+                print(trigger.hashCode());
+                                print(typeof trigger);
+                print(typeof trigger.bob);
+                print(typeof trigger['bob']);
+                               print(trigger.bob());
+                }
+                """);
+                               Invocable invocable = (Invocable)engine;
+
+                               Bob b = new Bob();
+                               Object x = invocable.invokeFunction("foo", b);
+                               System.out.println(x);
+                       } catch (Exception ex) {
+                               ex.printStackTrace(System.out);
+                       }
+                       return;
+               }
+
                // Lets see if it the security shit works
                ScriptManager sm = new ScriptManager();
 
@@ -242,9 +277,9 @@ public class ScriptManager {
 
                try {
                        String s = "var out = new java.io.FileOutputStream('hack-thread.txt');"
-                                       + " out.write(65);"
-                                       + "out.close();"
-                                       + " println('wrote hack.txt ok');";
+                               + " out.write(65);"
+                               + "out.close();"
+                               + " println('wrote hack.txt ok');";
 
                        f = sm.runScript(s);
                        System.out.println("result = " + f.get());
@@ -259,8 +294,8 @@ public class ScriptManager {
                }
                try {
                        String s = "var out = new java.io.FileInputStream('hack.script');"
-                                       + "out.close();"
-                                       + " println('read hack.script ok');";
+                               + "out.close();"
+                               + " println('read hack.script ok');";
 
                        f = sm.runScript(s);
                        System.out.println("result = " + f.get());
@@ -283,9 +318,9 @@ public class ScriptManager {
                }
                try {
                        String s = "var out = new java.io.FileOutputStream('scripts/newscript');"
-                                       + " out.write(65);"
-                                       + "out.close();"
-                                       + " println('wrote scripts/newscript ok');";
+                               + " out.write(65);"
+                               + "out.close();"
+                               + " println('wrote scripts/newscript ok');";
 
                        f = sm.runScript(s);
                        System.out.println("result = " + f.get());
index 979f666..7b8065c 100644 (file)
@@ -23,4 +23,5 @@ module duskz.server {
        requires java.desktop;
        requires java.logging;
 
+       exports duskz.server.entityz to org.mozilla.rhino, org.openjdk.nashorn;
 }
diff --git a/src/duskz.server/linux-amd64/bin/run-server b/src/duskz.server/linux-amd64/bin/run-server
new file mode 100755 (executable)
index 0000000..3ee3dfd
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+export JAVA_HOME=$(dirname $(readlink -f $0))/..
+exec ${JAVA_HOME}/bin/java -m duskz.server/duskz.server.entityz.GameServer $@
diff --git a/src/duskz.server/windows-amd64/bin/run-server.bat b/src/duskz.server/windows-amd64/bin/run-server.bat
new file mode 100644 (file)
index 0000000..5e1bb7c
--- /dev/null
@@ -0,0 +1,5 @@
+REM run-server game-dir
+@echo off
+set JAVA_HOME=%~dp0\..
+rem stops cmd window staying visible
+start /min "server" "%JAVA_HOME%\bin\java" -m duskz.server/duskz.server.entityz.GameServer %*
index b99ac98..286b372 100644 (file)
@@ -35,7 +35,7 @@ import javafx.scene.layout.VBox;
  */
 public class DuskInfoView extends BorderPane {
 
-       String oldmap = "/home/notzed/src/DuskRPG/DuskFiles/Dusk2.7.3";
+       String oldmap = "game-2.7.3";
        TextArea action;
        TextArea able;
 
@@ -44,13 +44,18 @@ public class DuskInfoView extends BorderPane {
 
                action = new TextArea();
                able = new TextArea();
-                               
+
                action.setEditable(false);
                able.setEditable(false);
 
-               vbox.getChildren().addAll(
-                               new TitledPane("defMoveActions", action),
-                               new TitledPane("defCanMoveScripts", able));
+               action.setPrefColumnCount(60);
+               able.setPrefColumnCount(60);
+
+               TitledPane move = new TitledPane("defMoveActions", action);
+               TitledPane canMove = new TitledPane("defCanMoveScripts", able);
+               vbox.getChildren().addAll(move, canMove);
+               move.setAnimated(false);
+               canMove.setAnimated(false);
 
                setCenter(vbox);
        }
@@ -60,7 +65,7 @@ public class DuskInfoView extends BorderPane {
                        try {
                                byte[] data = Files.readAllBytes(path.toPath());
                                String string = new String(data, Charset.defaultCharset()).trim();
-                               
+
                                if (!string.equals(""))
                                        text.setText(string);
                                else
index 36b9e1b..7315f66 100644 (file)
@@ -45,7 +45,7 @@ import javafx.scene.layout.GridPane;
  */
 public class LocationEditor extends BorderPane implements ChangeListener<Number> {
 
-       String game = "/home/notzed/dusk/game";
+       String game = "game";
        int tx, ty;
        TileMap map;
        TextField alias;
@@ -72,10 +72,15 @@ public class LocationEditor extends BorderPane implements ChangeListener<Number>
                actionScript = new TextArea();
                visibleScript = new TextArea();
 
+               ableScript.setPrefColumnCount(60);
+               actionScript.setPrefColumnCount(60);
+               visibleScript.setPrefColumnCount(60);
+
                Button aliasb, gotob, ableb, visibleb, actionb;
                int r = 0;
 
                TextField location;
+               TitledPane tp;
                main.add(new Button("Location"), 0, r);
                main.add(location = new TextField(), 1, r++);
                main.add(aliasb = new Button("Alias"), 0, r);
@@ -84,13 +89,16 @@ public class LocationEditor extends BorderPane implements ChangeListener<Number>
                main.add(jumpto, 1, r++);
                main.add(actionb = new Button("Action"), 0, r);
                main.add(action, 1, r++);
-               main.add(new TitledPane("Action Script", actionScript), 0, r++, 2, 1);
+               main.add(tp = new TitledPane("Action Script", actionScript), 0, r++, 2, 1);
+               tp.setAnimated(false);
                main.add(ableb = new Button("Able"), 0, r);
                main.add(able, 1, r++);
-               main.add(new TitledPane("Able Script", ableScript), 0, r++, 2, 1);
+               main.add(tp = new TitledPane("Able Script", ableScript), 0, r++, 2, 1);
+               tp.setAnimated(false);
                main.add(visibleb = new Button("Visible"), 0, r);
                main.add(visible, 1, r++);
-               main.add(new TitledPane("Visible Script", visibleScript), 0, r++, 2, 1);
+               main.add(tp = new TitledPane("Visible Script", visibleScript), 0, r++, 2, 1);
+               tp.setAnimated(false);
 
                location.textProperty().bind(tileX.asString().concat(", ").concat(tileY.asString()));
 
@@ -155,7 +163,7 @@ public class LocationEditor extends BorderPane implements ChangeListener<Number>
 
                try {
                        TextEditor te = new TextEditor();
-                       te.setPath(Paths.get("/home/notzed/dusk/game", type, name));
+                       te.setPath(Paths.get(game, type, name));
                        te.show();
                } catch (IOException ex) {
                        Logger.getLogger(LocationEditor.class.getName()).log(Level.SEVERE, null, ex);
index 5373236..573802e 100644 (file)
 package duskz.editor;
 
 import duskz.client.fx.DataManagerFX;
+import duskz.map.TileMap;
 import duskz.tool.fx.MapSelectionModel;
 import duskz.tool.fx.MapView;
+import java.io.DataInputStream;
+import java.io.FileInputStream;
 import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import java.util.zip.GZIPInputStream;
 import javafx.application.Application;
 import javafx.beans.value.ChangeListener;
 import javafx.beans.value.ObservableValue;
+import javafx.collections.FXCollections;
+import javafx.collections.ObservableList;
 import javafx.scene.Scene;
+import javafx.scene.control.ChoiceBox;
+import javafx.scene.control.ToolBar;
 import javafx.scene.layout.BorderPane;
 import javafx.scene.layout.VBox;
 import javafx.stage.Stage;
@@ -42,49 +52,57 @@ public class TileZ extends Application {
        LocationEditor locationEditor;
        DuskInfoView oldInfo;
        DataManagerFX data;
+       Path game = Path.of("game");
+       String rcName = "nowhere";
 
        @Override
-       public void start(Stage stage) {
+       public void start(Stage stage) throws IOException {
                BorderPane root = new BorderPane();
 
                VBox left = new VBox();
+               ToolBar toolbar = new ToolBar();
 
                left.getChildren().addAll(
-                               locationEditor = new LocationEditor(),
-                               oldInfo = new DuskInfoView());
+                       locationEditor = new LocationEditor(),
+                       oldInfo = new DuskInfoView());
 
+               ChoiceBox<Path> maps = new ChoiceBox<>(findMaps(game));
+
+               toolbar.getItems().add(maps);
+
+               root.setTop(toolbar);
                root.setCenter(mapView = new MapView());
                root.setLeft(left);
 
-               Scene scene = new Scene(root, 768, 512);
+               Scene scene = new Scene(root, 1280, 768);
 
+               scene.getStylesheets().add(TileZ.class.getResource("style.css").toString());
                stage.setTitle("TileZ");
                stage.setScene(scene);
                stage.show();
 
-               String datapath = "/home/notzed/house.jar";
-               String mappath = "/home/notzed/dusk/game/defMaps/dusk";
+               maps.getSelectionModel().selectedItemProperty().addListener((ObservableValue<? extends Path> o, Path ov, Path nv) -> {
+                       loadMap(nv);
+               });
 
-               try {
-                       data = new DataManagerFX(datapath);
-                       data.open();
-                       mapView.loadMap(data, mappath);
-
-                       locationEditor.setMap(mapView.getMap());
-
-                       mapView.getSelectionModel().boundsProperty().addListener(new ChangeListener<MapSelectionModel.Bounds>() {
-                               @Override
-                               public void changed(ObservableValue<? extends MapSelectionModel.Bounds> ov, MapSelectionModel.Bounds t, MapSelectionModel.Bounds t1) {
-                                       if (t1 != null) {
-                                               locationEditor.setTileX(t1.left);
-                                               locationEditor.setTileY(t1.top);
-                                               oldInfo.setLocation(t1.left, t1.top);
-                                       } else {
-                                               locationEditor.setTileX(-1);
-                                               locationEditor.setTileY(-1);
-                                       }
+               mapView.getSelectionModel().boundsProperty().addListener(new ChangeListener<MapSelectionModel.Bounds>() {
+                       @Override
+                       public void changed(ObservableValue<? extends MapSelectionModel.Bounds> ov, MapSelectionModel.Bounds t, MapSelectionModel.Bounds t1) {
+                               if (t1 != null) {
+                                       locationEditor.setTileX(t1.left);
+                                       locationEditor.setTileY(t1.top);
+                                       oldInfo.setLocation(t1.left, t1.top);
+                               } else {
+                                       locationEditor.setTileX(-1);
+                                       locationEditor.setTileY(-1);
                                }
-                       });
+                       }
+               });
+
+               try {
+                       data = new DataManagerFX(rcName);
+                       data.load();
+                       maps.getSelectionModel().select(0);
                } catch (IOException ex) {
                        Logger.getLogger(TileZ.class.getName()).log(Level.SEVERE, null, ex);
                }
@@ -96,6 +114,39 @@ public class TileZ extends Application {
                TZ.shutdown();
        }
 
+       void loadMap(Path map) {
+               try {
+                       if (map != null) {
+                               mapView.loadExternalMap(data, map.toString());
+                               locationEditor.setMap(mapView.getMap());
+                       } else {
+                               TileMap tm = new TileMap("empty", 0, 0);
+                               mapView.setMap(tm);
+                               locationEditor.setMap(tm);
+                       }
+               } catch (IOException ex) {
+                       ex.printStackTrace();
+               }
+       }
+
+       ObservableList<Path> findMaps(Path game) throws IOException {
+               return FXCollections.observableArrayList(
+                       Files.list(game.resolve("defMaps"))
+                               .filter(p -> {
+                                       // TODO: check if gzip, etc.
+                                       try (DataInputStream dis = new DataInputStream(new GZIPInputStream(new FileInputStream(p.toFile())))) {
+                                               int magic = dis.readInt();
+                                               int version = dis.readInt();
+                                               System.out.printf("magic: %08x\n", magic);
+
+                                               return magic == TileMap.MAGIC_LAYERED;
+                                       } catch (IOException x) {
+                                               return false;
+                                       }
+                               })
+                               .toList());
+       }
+
        /**
         * The main() method is ignored in correctly deployed JavaFX
         * application. main() serves only as fallback in case the
diff --git a/src/duskz.tools/classes/duskz/editor/style.css b/src/duskz.tools/classes/duskz/editor/style.css
new file mode 100644 (file)
index 0000000..d50803f
--- /dev/null
@@ -0,0 +1,4 @@
+
+.text-area {
+       -fx-font: 10pt monospace;
+}
\ No newline at end of file
index d584803..51c3e4c 100644 (file)
  */
 package duskz.tool;
 
+import java.awt.image.BufferedImage;
 import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.FileReader;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.io.PrintStream;
+import java.util.jar.Attributes;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import javax.imageio.ImageIO;
 
 /**
  * Convert a few basic files
- *
- * @author Michael Zucchi <notzed@gmail.com>
  */
 public class Convert {
 
+       static void usage() {
+               System.err.println("""
+                      Usage: Convert cmd [args]
+                                               client <rc> <game>
+                            convert old client image files in <rc>/<game>/* to jar format <game>.jar
+                        map-client <map.jar> playersprites sprites <client.jar>
+                            extract client info from combined map jar
+                      """);
+               System.exit(1);
+       }
+
+       static void addImage(Manifest man, String name, int gid0, BufferedImage image) {
+               Attributes a = new Attributes();
+               int size = image.getHeight();
+               int count = image.getWidth() / size;
+
+               a.putValue("name_0", name);
+               a.putValue("gid_0", String.valueOf(gid0));
+               a.putValue("count_0", String.valueOf(count));
+               a.putValue("source_0", String.format("%s/%04d.png", name, gid0));
+               a.putValue("width_0", String.valueOf(size));
+               a.putValue("height_0", String.valueOf(size));
+
+               System.out.printf("%s: %d images @ %dx%d\n", name, count, size, size);
+
+               a.putValue("count", "1");
+               man.getEntries().put(name, a);
+       }
+
+       static void copyStream(InputStream is, OutputStream os) throws IOException {
+               byte[] buf = new byte[4096];
+               int len;
+
+               while ((len = is.read(buf)) > 0) {
+                       os.write(buf, 0, len);
+               }
+       }
+
        public static void main(String[] args) throws IOException {
+               //args = new String[]{"client", "rc", "somedusk"};
+               //args = new String[] { "map-client", "tileset.jar", "rc/somedusk/images/players.gif", "rc/somedusk/images/sprites.gif", "nowhere.jar" };
+               if (args.length < 1) {
+                       usage();
+               }
+
+               String cmd = args[0];
+               switch (cmd) {
+               case "client": {
+                       String rc = args[1];
+                       String game = args[2];
+                       File dir = new File(rc, game);
+                       String[] srcs = {"images/map.gif", "images/players.gif", "images/sprites.gif"};
+                       BufferedImage[] images = new BufferedImage[srcs.length];
+                       String[] names = {"tiles", "players", "sprites"};
+                       int[] gid0 = {0, 0, 0};
+                       Manifest man = new Manifest();
+
+                       for (int i = 0; i < srcs.length; i++) {
+                               images[i] = ImageIO.read(new File(dir, srcs[i]));
+                               addImage(man, names[i], gid0[i], images[i]);
+                       }
+
+                       try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(game + ".jar"), man)) {
+                               for (int i = 0; i < names.length; i++) {
+                                       JarEntry je = new JarEntry(names[i] + "/");
+                                       jos.putNextEntry(je);
+                                       jos.closeEntry();
+                               }
+                               for (int i = 0; i < names.length; i++) {
+                                       JarEntry ze = new JarEntry(String.format("%s/%04d.png", names[i], gid0[i]));
+                                       jos.putNextEntry(ze);
+                                       ImageIO.write(images[i], "png", jos);
+                                       jos.closeEntry();
+                               }
+                       }
+
+                       break;
+               }
+               case "map-client": {
+                       String map = args[1];
+                       String[] srcs = new String[]{args[2], args[3]};
+
+                       String client = args[4];
+                       final String[] names = {"players", "sprites"};
+                       final String[] fields = {"name", "gid", "count", "width", "height"};
+                       int[] gid0 = {0, 0};
+                       BufferedImage[] images = new BufferedImage[srcs.length];
+
+                       try (JarInputStream jis = new JarInputStream(new FileInputStream(map))) {
+                               Manifest src = jis.getManifest();
+                               Manifest dst = new Manifest();
+
+                               // copy tiles, but rename soiurce
+                               {
+                                       Attributes a = src.getAttributes("tilesets");
+                                       Attributes b = new Attributes();
+                                       int count = Integer.parseInt(a.getValue("count"));
+
+                                       for (int i = 0; i < count; i++) {
+                                               for (String field: fields) {
+                                                       b.putValue(field + "_" + i, a.getValue(i + "_" + field));
+                                               }
+                                               b.putValue("source_" + i, String.format("tiles/%04d.png", Integer.valueOf(a.getValue(i + "_gid"))));
+                                       }
+
+                                       b.putValue("count", a.getValue("count"));
+                                       dst.getEntries().put("tiles", b);
+                               }
+
+                               for (int i = 0; i < srcs.length; i++) {
+                                       images[i] = ImageIO.read(new File(srcs[i]));
+                                       addImage(dst, names[i], gid0[i], images[i]);
+                               }
+
+                               try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(client), dst)) {
+                                       JarEntry se;
+
+                                       // copy everything?
+                                       while ((se = jis.getNextJarEntry()) != null) {
+                                               String n = se.getName();
+                                               if (n.matches("tiles/tiles_\\d+\\.png")) {
+                                                       JarEntry de = new JarEntry(String.format("tiles/%04d.png", Integer.valueOf(n.substring(12, n.length() - 4))));
+                                                       jos.putNextEntry(de);
+                                               } else {
+                                                       jos.putNextEntry(se);
+                                               }
+                                               copyStream(jis, jos);
+                                               jos.closeEntry();
+                                       }
+
+                                       // write sprites/etc
+                                       for (String name: names) {
+                                               JarEntry je = new JarEntry(name + "/");
+                                               jos.putNextEntry(je);
+                                               jos.closeEntry();
+                                       }
+                                       for (int i = 0; i < names.length; i++) {
+                                               JarEntry ze = new JarEntry(String.format("%s/%04d.png", names[i], gid0[i]));
+                                               jos.putNextEntry(ze);
+                                               ImageIO.write(images[i], "png", jos);
+                                               jos.closeEntry();
+                                       }
+                               }
+                       }
+                       break;
+               }
+               default:
+                       usage();
+                       break;
+
+               }
+
+       }
+
+       public static void junk(String[] args) throws IOException {
                File src = new File("/home/notzed/src/DuskRPG/DuskFiles/Dusk2.7.3");
                File dst = new File("/home/notzed/dusk/game");
-               
+
                PrintStream o = new PrintStream(new File(dst, "mobs.new"));
-               
+
                try (BufferedReader is = new BufferedReader(new FileReader(new File(src, "mobs")))) {
                        while (true) {
                                String m = is.readLine();
-                               
+
                                if (m == null || !m.trim().equals("mob2.3"))
                                        break;
-                               
-                               String name= is.readLine();
+
+                               String name = is.readLine();
                                int x = Integer.valueOf(is.readLine());
                                int y = Integer.valueOf(is.readLine());
-                               
+
                                o.println("type.Mobile=" + name);
                                o.println("map=dusk");
                                o.println("x=" + x);
index 26a1bee..ca008d5 100644 (file)
@@ -20,12 +20,16 @@ package duskz.tool.fx;
 import duskz.client.fx.DataManagerFX;
 import duskz.map.TileMap;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map.Entry;
+import java.util.jar.JarEntry;
+import java.util.jar.JarInputStream;
 import javafx.animation.Animation;
 import javafx.application.Platform;
 import javafx.beans.value.ChangeListener;
@@ -53,7 +57,7 @@ import javafx.util.Duration;
  */
 public class MapView extends Region implements ChangeListener<Number> {
 
-       String oldmap = "/home/notzed/src/DuskRPG/DuskFiles/Dusk2.7.3";
+       String oldmap = "game-2.7.3";
        TileMap map;
        DataManagerFX data;
        // TODO: tilesize on DataManagerFX
@@ -110,7 +114,7 @@ public class MapView extends Region implements ChangeListener<Number> {
                        public void handle(MouseEvent t) {
 
                                if (t.getEventType() == MouseEvent.MOUSE_PRESSED) {
-                                       if (t.getButton() == MouseButton.SECONDARY) {
+                                       if (t.getButton() == MouseButton.MIDDLE) {
                                                startx = t.getX();
                                                starty = t.getY();
                                                hstart = hbar.getValue();
@@ -130,7 +134,9 @@ public class MapView extends Region implements ChangeListener<Number> {
                                                double fixv = (vbar.getMax() + vbar.getVisibleAmount()) / vbar.getMax();
                                                hbar.setValue(hstart - dx * fixh);
                                                vbar.setValue(vstart - dy * fixv);
+                                               System.out.println("drag " + dx + "," + dy);
                                                t.consume();
+                                               updateMapVisible();
                                        }
                                        //}
                                } else if (t.getEventType() == MouseEvent.MOUSE_RELEASED) {
@@ -139,14 +145,15 @@ public class MapView extends Region implements ChangeListener<Number> {
                                                t.consume();
                                        }
                                } else if (t.getEventType() == MouseEvent.MOUSE_CLICKED) {
-                                       int tx = (int) ((getOriginX() + t.getX()) / tileSize / scale);
-                                       int ty = (int) ((getOriginY() + t.getY()) / tileSize / scale);
-
-                                       //System.out.printf("selecting %d,%d mouse %f,%f  origin %f,%f\n", tx, ty, t.getX(), t.getY(), getOriginX(), getOriginY());
-
-                                       selectionModel.setSelected(tx, ty);
-                                       // hack
-                                       requestLayout();
+                                       if (t.getButton() == MouseButton.PRIMARY) {
+                                               int tx = (int)((getOriginX() + t.getX()) / tileSize / scale);
+                                               int ty = (int)((getOriginY() + t.getY()) / tileSize / scale);
+
+                                               System.out.printf("selecting %d,%d mouse %f,%f  origin %f,%f\n", tx, ty, t.getX(), t.getY(), getOriginX(), getOriginY());
+                                               selectionModel.setSelected(tx, ty);
+                                               // hack
+                                               updateMapVisible();
+                                       }
                                }
                        }
                });
@@ -161,7 +168,6 @@ public class MapView extends Region implements ChangeListener<Number> {
                super.layoutChildren();
 
                //System.out.printf("layout children dimensions = %fx%f\n", getWidth(), getHeight());
-
                overlay.resize(getWidth(), getHeight());
 
                if (map != null) {
@@ -177,12 +183,12 @@ public class MapView extends Region implements ChangeListener<Number> {
                        vbar.setVisibleAmount(getHeight());
                        hbar.setVisibleAmount(getWidth());
 
-                       //System.out.printf("visible %f total %f\n", vbar.getVisibleAmount(), vbar.getMax());
+                       vcols = (int)(getWidth() / (tileSize * scale)) + 1;
+                       vrows = (int)(getHeight() / (tileSize * scale)) + 1;
 
+                       //System.out.printf("visible %f total %f\n", vbar.getVisibleAmount(), vbar.getMax());
                        // create imageview objects to cover screen
-                       if (oldw != getWidth() || oldh != getHeight()) {
-                               vcols = (int) (getWidth() / (tileSize * scale)) + 1;
-                               vrows = (int) (getHeight() / (tileSize * scale)) + 1;
+                       if (oldw != getWidth() || oldh != getHeight() || graphics.getChildren().size() != vcols * vrows * map.getLayerCount()) {
                                oldw = getWidth();
                                oldh = getHeight();
                                ObservableList<Node> c = graphics.getChildren();
@@ -211,14 +217,39 @@ public class MapView extends Region implements ChangeListener<Number> {
                System.out.println("trnaslate changed");
        }
 
+       public InputStream getInputStream(String jar, String path) throws IOException {
+               JarInputStream jis = null;
+               try {
+                       jis = new JarInputStream(new FileInputStream(jar));
+                       JarEntry je;
+
+                       while ((je = jis.getNextJarEntry()) != null) {
+                               System.out.println("je = " + je.getName());
+                               if (je.getName().equals(path))
+                                       return jis;
+                       }
+                       jis.close();
+                       throw new FileNotFoundException(path);
+               } catch (IOException ex) {
+                       if (jis != null)
+                               jis.close();
+                       throw ex;
+               }
+       }
+
        public void loadMap(DataManagerFX data, String name) throws IOException {
                this.data = data;
 
-               try (InputStream is = data.getInputStream("maps/" + name)) {
-                       map = TileMap.loadLayeredMap(is, name);
+               try (InputStream is = getInputStream(data.getSource() + ".jar", "maps/" + name)) {
+                       setMap(TileMap.loadLayeredMap(is, name));
                }
-               updateMap();
-               requestLayout();
+       }
+
+       public void loadExternalMap(DataManagerFX data, String path) throws IOException {
+               this.data = data;
+
+               //      map = TileMap.loadMap(new File(path), TileMap.FORMAT_SHORT);
+               setMap(TileMap.loadLayered(new File(path)));
        }
 
        public MapSelectionModel getSelectionModel() {
@@ -229,6 +260,14 @@ public class MapView extends Region implements ChangeListener<Number> {
                return map;
        }
 
+       public void setMap(TileMap map) {
+               this.map = map;
+               //updateMap();
+               vbar.setValue(0);
+               hbar.setValue(0);
+               requestLayout();
+       }
+
        @Override
        protected double computePrefHeight(double d) {
                //if (map == null)
@@ -261,11 +300,11 @@ public class MapView extends Region implements ChangeListener<Number> {
        }
 
        public int getTileX() {
-               return (int) (getOriginX() / tileSize / scale);
+               return (int)(getOriginX() / tileSize / scale);
        }
 
        public int getTileY() {
-               return (int) (getOriginY() / tileSize / scale);
+               return (int)(getOriginY() / tileSize / scale);
        }
 
        void updateMapVisible() {
@@ -273,26 +312,23 @@ public class MapView extends Region implements ChangeListener<Number> {
                final ArrayList<Node> upper = new ArrayList<>();
                int levelCount = map.getLayerCount();
 
+               System.out.println("update visible map");
+
                // Animated tiles hack test
                //      final Rectangle2D[] anims = new Rectangle2D[2];
                //      anims[0] = data.createTile(305, 0, 0, tileSize, tileSize).getViewport();
                //      anims[1] = data.createTile(304, 0, 0, tileSize, tileSize).getViewport();
                //      final List<ImageView> animated = new ArrayList<>();
-
                int x0 = getTileX();
                int y0 = getTileY();
 
                //      y0 = Math.min(y0, map.getRows());
                //      y1 = Math.min(y1, map.getRows());
-
                //graphics.setTranslateX(-((long) getOriginX() & (tileSize - 1)) * scale);
                //graphics.setTranslateY(-((long) getOriginY() & (tileSize - 1)) * scale);
-
                // TODO: set position pixel or some shit
-
                //if (oldx0 == x0 && oldy0 == y0 && oldvcols == vcols && oldvrows == vrows)
                //      return;
-
                oldx0 = x0;
                oldy0 = y0;
                oldvcols = vcols;
@@ -305,7 +341,7 @@ public class MapView extends Region implements ChangeListener<Number> {
                                int ty = y + y0;
                                for (int x = 0; x < vcols; x++) {
                                        int tx = x + x0;
-                                       ImageView iv = (ImageView) graphics.getChildren().get(x + y * vcols + l * vcols * vrows);
+                                       ImageView iv = (ImageView)graphics.getChildren().get(x + y * vcols + l * vcols * vrows);
 
                                        int tileid = map.getTile(l, tx, ty);
                                        if (tileid != 0) {
@@ -329,7 +365,6 @@ public class MapView extends Region implements ChangeListener<Number> {
                        }
                }
 
-
                // Check for meta data on map region
                List<Node> nodes = new ArrayList<Node>();
 
@@ -368,10 +403,10 @@ public class MapView extends Region implements ChangeListener<Number> {
                                String visible = map.locationVisibleScript(tx, ty);
 
                                if (a != null
-                                               || j != null
-                                               || able != null
-                                               || action != null
-                                               || visible != null) {
+                                       || j != null
+                                       || able != null
+                                       || action != null
+                                       || visible != null) {
                                        Rectangle r = new Rectangle(tileSize - 4, tileSize - 4);
                                        r.setFill(null);
                                        r.setStroke(Color.RED);
@@ -405,7 +440,7 @@ public class MapView extends Region implements ChangeListener<Number> {
                alias.getChildren().setAll(nodes);
 
                // Load animation stuff
-               for (Entry<Integer, List<ImageView>> e : animated.entrySet()) {
+               for (Entry<Integer, List<ImageView>> e: animated.entrySet()) {
                        int root = e.getKey();
                        TileAnimator animator = animators.get(root);
                        DataManagerFX.AnimSetFX set = data.getAnimSet(root);
@@ -421,6 +456,7 @@ public class MapView extends Region implements ChangeListener<Number> {
                        }
                }
        }
+
        /*
         Future f;
 
@@ -436,7 +472,6 @@ public class MapView extends Region implements ChangeListener<Number> {
 
         f = TZ.single.submit(new Update(x0, y0, 1, vcols, vrows));
         }*/
-
        class Update implements Runnable {
 
                int x0, y0, xstep;
@@ -488,7 +523,6 @@ public class MapView extends Region implements ChangeListener<Number> {
                //      anims[0] = data.createTile(305, 0, 0, tileSize, tileSize).getViewport();
                //      anims[1] = data.createTile(304, 0, 0, tileSize, tileSize).getViewport();
                //      final List<ImageView> animated = new ArrayList<>();
-
                // Build whole map
                for (int l = 0; l < levelCount; l++) {
                        for (int y = 0; y < map.getRows(); y++) {
@@ -526,7 +560,6 @@ public class MapView extends Region implements ChangeListener<Number> {
                //for (Entity e : map.getEntities()) {
                //      drawEntity(map.offx, map.offy, children, e);
                //}
-
                Platform.runLater(new Runnable() {
                        @Override
                        public void run() {
index 6de2844..56d7500 100644 (file)
@@ -1,6 +1,19 @@
-/*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
+/**
+ * TileZ is a tile editor.
+ * Copyright (C) 2013 Michael Zucchi
+ *
+ * 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 3 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/>.
  */
 package duskz.viewer;
 
@@ -36,14 +49,14 @@ public class MapViewer extends Application {
                stage.setScene(scene);
                stage.show();
 
-               String datapath = "/home/notzed/house.jar";
-               String mappath = "main";
+               String datapath = "somedusk";
+               String mappath = "game-2.7.3/shortmap";
 
                try {
                        data = new DataManagerFX(datapath);
-                       data.open();
-                       mapView.loadMap(data, mappath);
-
+                       data.load();
+                       //mapView.loadMap(data, mappath);
+                       mapView.loadExternalMap(data, mappath);
                //      locationEditor.setMap(mapView.map);
 
                        /*