diff --git a/java/org/artisanlogiciel/games/maze/LabyModel.java b/java/org/artisanlogiciel/games/maze/LabyModel.java index 8930dae..358fd1a 100644 --- a/java/org/artisanlogiciel/games/maze/LabyModel.java +++ b/java/org/artisanlogiciel/games/maze/LabyModel.java @@ -35,6 +35,8 @@ public class LabyModel implements WallsProvider { public final static short RIGHT = Brick.RIGHT << FLAGLENGTH | DIRECTION | HORIZONTAL | POSITIVE; public final static short UP = Brick.UP << FLAGLENGTH | DIRECTION | VERTICAL | NEGATIVE; + public final static short EMPTY = LEFT | DOWN | RIGHT | UP ; + // flag when a wall should be open to access this for entry public final static short ENTRY = Brick.ENTRY << FLAGLENGTH; // flag when a wall should be open to access this for exit @@ -100,7 +102,7 @@ public class LabyModel implements WallsProvider { /** * construct LabyModel from an InputStream, yet only "raw" is supported **/ - public LabyModel(int width, int heigh, short [][] t) { + public LabyModel(int width, int height, short [][] t) { random = null; this.width = width; this.height = height; diff --git a/java/org/artisanlogiciel/games/maze/gui/Display.java b/java/org/artisanlogiciel/games/maze/gui/Display.java index f6649bb..c4a81e4 100644 --- a/java/org/artisanlogiciel/games/maze/gui/Display.java +++ b/java/org/artisanlogiciel/games/maze/gui/Display.java @@ -368,11 +368,25 @@ implements StatusListener } }; - JButton loadOsmButton = new JButton(labels.getString("load" ) + " Osm"); - loadOsmButton.addActionListener(loadOsmAction); + loadMenu.add(newLoadButton("osm", loadOsmAction)); - loadMenu.add(loadOsmButton); + loadMenu.add(newLoadButton("we", + new AbstractAction() { + public void actionPerformed(ActionEvent evt) { + // + addStatus("load WoldEdit"); + String filename = loadName.getText(); + + if ((filename.length() > 0)) { + setMazeName(filename); + loadWorldEdit(false); + refresh(); + } + + } + } + )); return loadMenu; } @@ -459,12 +473,20 @@ implements StatusListener } - private JButton newSaveButton(String format, Action action) { - final JButton saveTextButton = new JButton(labels.getString("save") + " " + format); + private JButton newActionButton(String actionName, String format, Action action) { + final JButton saveTextButton = new JButton(labels.getString(actionName) + " " + format); saveTextButton.addActionListener(action); return saveTextButton; } + private JButton newSaveButton(String format, Action action) { + return newActionButton("save",format,action); + } + + private JButton newLoadButton(String format, Action action) { + return newActionButton("load",format,action); + } + private JPanel createResolveQuitBar() { JPanel resolveQuitBar = new JPanel(new FlowLayout()); @@ -759,6 +781,29 @@ implements StatusListener } } + private void loadWorldEdit(boolean add) { + if ( maze != null ) { + File infile = new File(params.getSaveDir(), params.getName() + ".we"); + FileInputStream inputStream = null; + try { + inputStream = new FileInputStream(infile); + model = new MazePersistWorldEdit().parseInputStream("we",inputStream); + } catch (IOException io) { + io.printStackTrace(System.err); + statusField.setText("[ERROR] Can't load " + infile.getAbsolutePath()); + } finally { + if (inputStream != null) { + // cleanup + try { + inputStream.close(); + } catch (Exception any) { + // don't care really + } + } + } + } + } + private JButton addDirection(final JPanel panel, final String direction, String key, Action goAction) { String actionName = "go" + direction; JButton button = new JButton(direction); diff --git a/java/org/artisanlogiciel/games/maze/persist/MazePersistWorldEdit.java b/java/org/artisanlogiciel/games/maze/persist/MazePersistWorldEdit.java index 2bc2c9a..99f296a 100644 --- a/java/org/artisanlogiciel/games/maze/persist/MazePersistWorldEdit.java +++ b/java/org/artisanlogiciel/games/maze/persist/MazePersistWorldEdit.java @@ -2,9 +2,8 @@ package org.artisanlogiciel.games.maze.persist; import org.artisanlogiciel.games.maze.Brick; import org.artisanlogiciel.games.maze.LabyModel; -import org.artisanlogiciel.games.minetest.Material; -import org.artisanlogiciel.games.minetest.Node; -import org.artisanlogiciel.games.minetest.WorlEditGenerator; +import org.artisanlogiciel.games.minetest.*; + import java.io.*; import static org.artisanlogiciel.games.minetest.Material.GRASS_MATERIAL; @@ -18,6 +17,10 @@ public class MazePersistWorldEdit { this.model = model; } + public MazePersistWorldEdit() { + // + } + void addNode(Node node) { if (node != null ) @@ -110,13 +113,71 @@ public class MazePersistWorldEdit { // TODO using WorldEditGenerator if ((pFormat == null) || (pFormat.equals("we"))) { // DataInputStream in = new DataInputStream(pIn); - throw new IOException("Format " + pFormat + " Not yet implemented."); - // should be at end of stream ? Not necessary can stream multiple - // labs ( or tiling ). + WorldEditReader reader = new WorldEditReader(pIn); + // skip header "5.return " hacky way ... + byte[] b = new byte[9]; + pIn.read(b); + // System.out.println(new String(b)); + World world = reader.read(); + // need to convert world into a LabyModel ... + // get level z = 0 + Slice ground = world.getSlice(0); + if ( ground != null ) + { + model = getModelFromSlice(ground); + System.out.println(model); + } + else + { + System.err.println("no ground !"); + } + return model; } else { throw new IOException("Format " + pFormat + " Not yet implemented."); } } + private LabyModel getModelFromSlice(Slice ground) { + // TODO + if ( ! ground.isEmpty() ) + { + int width = ground.getRangeSize(); + Range rawRange = ground.getRawRange(); + int height = rawRange.getRangeSize(); + int up = rawRange.getMin(); + + short [][] t = new short[width][height]; + int left = ground.getMin(); + for ( int x = ground.getMin() ; x < ground.getMax() ; x ++) + { + // work on raws ... + Raw raw = ground.getRaw(new Integer(x)); + if ( raw != null ) + { + for ( int y = raw.getMin() ; y < raw.getMax(); y ++) { + // full closed place ... ( lazzy ... ) + Node node = raw.getNode(y); + short move = LabyModel.EMPTY | 32; + if ( node != null ) { + move = 0; + } + int newx = x - left; + int newy = y - up; + System.out.println( " " + newx + " " + newy + " =" + move ); + t[newx][newy] = move; + } + } + } + model = new LabyModel(width,height, t); + return model; + } + else + { + System.out.println("empty ground"); + } + + return null; + } + } diff --git a/java/org/artisanlogiciel/games/minetest/Material.java b/java/org/artisanlogiciel/games/minetest/Material.java index 429aaf8..fc4db5e 100644 --- a/java/org/artisanlogiciel/games/minetest/Material.java +++ b/java/org/artisanlogiciel/games/minetest/Material.java @@ -19,6 +19,6 @@ public class Material { @Override public String toString() { - return "name"; + return name; } } diff --git a/java/org/artisanlogiciel/games/minetest/Node.java b/java/org/artisanlogiciel/games/minetest/Node.java index 75b5b09..8069ff9 100644 --- a/java/org/artisanlogiciel/games/minetest/Node.java +++ b/java/org/artisanlogiciel/games/minetest/Node.java @@ -1,5 +1,7 @@ package org.artisanlogiciel.games.minetest; +import java.util.HashMap; + public class Node { int x; int y; @@ -20,6 +22,16 @@ public class Node { this.material = Material.DEFAULT; } + public Node(HashMap map) + throws ClassCastException, NullPointerException + { + // FIXME WARNING HACK reverse x and z ... + x = ((Integer) map.get("x")).intValue(); + y = ((Integer) map.get("z")).intValue(); + z = ((Integer) map.get("y")).intValue(); + material = Material.getMaterialByName( (String) map.get("name")); + } + public int getX() { return x; } @@ -35,4 +47,14 @@ public class Node { public Material getMaterial() { return material; } + + @Override + public String toString() { + return "Node{" + + "x=" + x + + ", y=" + y + + ", z=" + z + + ", material=" + material + + '}'; + } } diff --git a/java/org/artisanlogiciel/games/minetest/Range.java b/java/org/artisanlogiciel/games/minetest/Range.java new file mode 100644 index 0000000..e29006a --- /dev/null +++ b/java/org/artisanlogiciel/games/minetest/Range.java @@ -0,0 +1,71 @@ +package org.artisanlogiciel.games.minetest; + +public class Range { + int min; + int max; + + public int getMin() { + return min; + } + + public int getMax() { + return max; + } + + public Range() + { + // invalid range, means empty interval + min = 0; + max = -1; + } + + public boolean isEmpty() + { + return ( min > max ); + } + + boolean union(Range other) + { + boolean update = false; + if ( ! other.isEmpty()) { + update = updateBounds(other.getMin()) | updateBounds(other.getMax()); + } + return update; + } + + boolean updateBounds(int v) + { + boolean update = false; + + // special case where previous range was unset ( min > max ). + if ( isEmpty() ) + { + min = v; + max = v; + return true; + } + if ( v < min ) + { + update = true; + min = v; + } + if ( v > max ) + { + update = true; + max = v; + } + return update; + } + + + public int getRangeSize() { + if (isEmpty()) + { + return 0; + } + else + { + return max - min; + } + } +} diff --git a/java/org/artisanlogiciel/games/minetest/Raw.java b/java/org/artisanlogiciel/games/minetest/Raw.java new file mode 100644 index 0000000..4dd5f64 --- /dev/null +++ b/java/org/artisanlogiciel/games/minetest/Raw.java @@ -0,0 +1,25 @@ +package org.artisanlogiciel.games.minetest; + +import java.util.HashMap; + +public class Raw +extends Range { + // y is index + public HashMap nodes; + + public Raw() { + super(); + nodes = new HashMap<>(); + } + + public void addNode(Integer y, Node node) + { + updateBounds(y.intValue()); + nodes.put(y,node); + } + + public Node getNode( int y) + { + return nodes.get(new Integer(y)); + } +} diff --git a/java/org/artisanlogiciel/games/minetest/Slice.java b/java/org/artisanlogiciel/games/minetest/Slice.java new file mode 100644 index 0000000..6ad3879 --- /dev/null +++ b/java/org/artisanlogiciel/games/minetest/Slice.java @@ -0,0 +1,50 @@ +package org.artisanlogiciel.games.minetest; + +import java.util.HashMap; + +public class Slice + extends Range +{ + + // x is index + HashMap raws; + + public Range getRawRange() { + return rawRange; + } + + Range rawRange; + + public Slice() { + super(); + raws = new HashMap<>(); + rawRange = new Range(); + } + + public void addNodeInRaw(Integer x, Node node) { + updateBounds(x.intValue()); + Raw r = raws.get(x); + if ( r == null ) + { + r = new Raw(); + raws.put(x,r); + } + r.addNode(new Integer(node.getY()), node); + rawRange.union(r); + } + + public Node getNode(int x, int y) + { + Raw r = raws.get(x); + if ( r == null ) + { + return null; + } + return r.getNode(y); + } + + public Raw getRaw(Integer x) + { + return raws.get(x); + } +} diff --git a/java/org/artisanlogiciel/games/minetest/WorlEditGenerator.java b/java/org/artisanlogiciel/games/minetest/WorlEditGenerator.java index 30efbc5..e1b2b65 100644 --- a/java/org/artisanlogiciel/games/minetest/WorlEditGenerator.java +++ b/java/org/artisanlogiciel/games/minetest/WorlEditGenerator.java @@ -1,5 +1,8 @@ package org.artisanlogiciel.games.minetest; +/** + * generate directly lua maps ( no intermediate LuaObject ). + */ public class WorlEditGenerator { diff --git a/java/org/artisanlogiciel/games/minetest/World.java b/java/org/artisanlogiciel/games/minetest/World.java new file mode 100644 index 0000000..30b9d68 --- /dev/null +++ b/java/org/artisanlogiciel/games/minetest/World.java @@ -0,0 +1,79 @@ +package org.artisanlogiciel.games.minetest; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class World + extends Range +{ + + List nodes; + + // z range + HashMap zSlices; + + public World() + { + super(); + nodes = new ArrayList<>(); + zSlices = new HashMap<>(); + } + + public void addNode(Node node) + { + nodes.add(node); + addNodeInSlice(new Integer(node.getZ()),node); + } + + private void addNodeInSlice(Integer z, Node node) { + updateBounds(z.intValue()); + Slice s = zSlices.get(z); + Integer x = new Integer(node.getX()); + if ( s == null ) + { + s = new Slice(); + zSlices.put(z,s); + } + s.addNodeInRaw(x,node); + + } + + public void addList(List objectList) + { + for (Object o : objectList) + { + if ( o instanceof HashMap ) + { + HashMap map = (HashMap) o; + Node node = new Node(map); + addNode(node); + } + } + } + + public Node getNode(int x, int y, int z) + { + Slice s = zSlices.get(new Integer(z)); + if ( s == null ) + { + return null; + } + else + { + return s.getNode(x,y); + } + } + + public Slice getSlice(int z) + { + return zSlices.get(new Integer(z)); + } + + @Override + public String toString() { + return "World{" + + "nodes=" + nodes + + '}'; + } +} diff --git a/java/org/artisanlogiciel/games/minetest/WorldEditReader.java b/java/org/artisanlogiciel/games/minetest/WorldEditReader.java new file mode 100644 index 0000000..0c2c7c8 --- /dev/null +++ b/java/org/artisanlogiciel/games/minetest/WorldEditReader.java @@ -0,0 +1,51 @@ +package org.artisanlogiciel.games.minetest; + +import org.artisanlogiciel.lua.CharProvider; +import org.artisanlogiciel.lua.LuaObject; +import org.artisanlogiciel.lua.Parser; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.List; + +public class WorldEditReader { + + InputStream input; + + public WorldEditReader(InputStream pIn) + { + input = pIn; + } + + public World read() + throws IOException + { + World world = new World(); + + + BufferedReader in = new BufferedReader(new InputStreamReader(input)); + byte b[] = new byte[128*1024]; + input.read(b); + String contents = new String(b); + in.close(); + + System.out.println(contents); + + CharProvider reader = new CharProvider(contents); + Parser parser = new Parser(reader); + LuaObject result = parser.parse(); + if (result != null) { + System.out.println(result.toString()); + Object we = result.wrapToJava(); + System.out.println(we); + world.addList( (List) we); + System.out.println(world); + } else { + System.err.println("result null"); + } + return world; + } + +} diff --git a/java/org/artisanlogiciel/lua/LuaTuple.java b/java/org/artisanlogiciel/lua/LuaTuple.java index 32cf9d6..c16ddf4 100644 --- a/java/org/artisanlogiciel/lua/LuaTuple.java +++ b/java/org/artisanlogiciel/lua/LuaTuple.java @@ -22,8 +22,8 @@ public class LuaTuple public String addInMap(HashMap map) { - String key = items.get(0).toString(); - Object value = items.get(1); + String key = (String) items.get(0).wrapToJava(); + Object value = items.get(1).wrapToJava(); map.put(key,value); diff --git a/java/org/artisanlogiciel/lua/Parser.java b/java/org/artisanlogiciel/lua/Parser.java index b53a924..ca38968 100644 --- a/java/org/artisanlogiciel/lua/Parser.java +++ b/java/org/artisanlogiciel/lua/Parser.java @@ -1,5 +1,7 @@ package org.artisanlogiciel.lua; +import org.artisanlogiciel.games.minetest.World; + import java.util.ArrayList; import java.util.List; @@ -128,7 +130,7 @@ public class Parser { return new LuaNumber(number); } - LuaObject parse() + public LuaObject parse() { char c = 0; while ( ((c = getNextchar()) != 0 ) && ( errors == null )) @@ -223,6 +225,9 @@ public class Parser { System.out.println(result.toString()); Object we = result.wrapToJava(); System.out.println(we); + World world = new World(); + world.addList( (List) we); + System.out.println(world); } else {