Very rough and untested multiple map support.
authornotzed@gmail.com <notzed@gmail.com@b8b59bfb-1aa4-4687-8f88-a62eeb14c21e>
Tue, 5 Mar 2013 16:57:29 +0000 (16:57 +0000)
committernotzed@gmail.com <notzed@gmail.com@b8b59bfb-1aa4-4687-8f88-a62eeb14c21e>
Tue, 5 Mar 2013 16:57:29 +0000 (16:57 +0000)
git-svn-id: file:///home/notzed/svn/duskz/trunk@12 b8b59bfb-1aa4-4687-8f88-a62eeb14c21e

12 files changed:
DuskServer/docs/duskz-multimap [new file with mode: 0644]
DuskServer/src/duskz/io/Tiled.java
DuskServer/src/duskz/server/Battle.java
DuskServer/src/duskz/server/Commands.java
DuskServer/src/duskz/server/DuskEngine.java
DuskServer/src/duskz/server/Faction.java
DuskServer/src/duskz/server/Script.java
DuskServer/src/duskz/server/TickThread.java
DuskServer/src/duskz/server/entity/DuskObject.java
DuskServer/src/duskz/server/entity/LivingThing.java
DuskServer/src/duskz/server/entity/Mob.java
DuskServer/src/duskz/server/entity/TileMap.java

diff --git a/DuskServer/docs/duskz-multimap b/DuskServer/docs/duskz-multimap
new file mode 100644 (file)
index 0000000..77cf083
--- /dev/null
@@ -0,0 +1,69 @@
+
+This lists some changes to files to support multiple maps.
+
+Map files
+---------
+
+Maps are encoded in a binary format and stored in multiple files under
+defMaps/
+
+The filename of the map is the name as referenced elsewhere.
+
+LivingThing
+-----------
+
+New parameter 'map' supplies the name of the map the thing is on.
+
+mobs
+----
+
+Added the map name to the mob entries.  Changed the header name from
+'mob2.3' to 'mob'.
+
+mob
+Ent
+mainmap
+100
+100
+
+merchants
+---------
+
+Each entry in the merchants file now starts with
+
+mapname
+xlocation
+ylocation
+
+rather than xlocation.
+
+TODO: it needs more structure/consistency
+
+mainmap
+100
+100
+Wooden boots
+end
+
+
+signs
+-----
+
+Added map to location
+
+TODO: it needs more structure/consistency
+
+some sign text
+mapname
+100
+100
+
+props
+-----
+
+Added map to location
+
+prop type
+mapname
+100
+100
index bb6e37c..f11b7e6 100644 (file)
@@ -402,7 +402,7 @@ public class Tiled {
                                }
                        }
 
-                       TileMap map = new TileMap(tmap.getWidth(), tmap.getHeight());
+                       TileMap map = new TileMap("main", tmap.getWidth(), tmap.getHeight());
 
                        int lid = 0;
 
@@ -560,7 +560,7 @@ public class Tiled {
                        // TODO: write out tileset info somewhere
 
 
-                       TileMap map = new TileMap(tmap.getWidth(), tmap.getHeight());
+                       TileMap map = new TileMap(dst.getName(), tmap.getWidth(), tmap.getHeight());
 
                        int lid = 0;
 
@@ -582,6 +582,9 @@ public class Tiled {
                                }
                        }
 
+                       if (twidth == 0 || theight == 0)
+                               throw new IOException("Couldn't find a layer called 'ground'");
+                       
                        System.out.printf("Found %d layers\n", nlayers);
                        System.out.printf("Ground on layer %d\n", groundid);
                        // Create map 
@@ -665,8 +668,10 @@ public class Tiled {
        public static void main(String[] args) throws IOException {
                //testimport(new File("/home/notzed/house.tmx"),
                //              new File("/home/notzed/house.jar"));
-               tiledToDusk(new File("/home/notzed/test-map.tmx"),
-                               new File("/home/notzed/test-map.bin"));
+               //tiledToDusk(new File("/home/notzed/test-map.tmx"),
+               //              new File("/home/notzed/test-map.bin"));
+               tiledToDusk(new File("/home/notzed/dusk/maps/do-drop-inn.tmx"),
+                               new File("/home/notzed/src/DuskRPG/DuskFiles/DuskX/defMaps/do-drop-inn"));
                //testexport();
        }
 }
index 38cd620..4fa3081 100644 (file)
@@ -82,7 +82,7 @@ public class Battle implements DuskProtocol {
                                thnFront1 = thnFront1.getMaster();
                        }
                        thnFront1 = inpla1;
-                       engGame.chatMessage("-" + inpla1.name + " has attacked " + inpla2.name, inpla1.x, inpla1.y, "default");
+                       engGame.chatMessage(inpla1.map, "-" + inpla1.name + " has attacked " + inpla2.name, inpla1.x, inpla1.y, "default");
                        inpla1.startBattle(inpla2);
                        inpla2.startBattle(inpla1);
                } catch (Exception e) {
@@ -172,7 +172,7 @@ public class Battle implements DuskProtocol {
                        hitMessage(attackee.getID(), 0, attackee.hp, attackee.maxhp, attackor.getID(), "Dodged!");
                } else {
                        if (engGame.battlesound != -1) {
-                               engGame.playSound(engGame.battlesound, attackee.x, attackee.y);
+                               engGame.playSound(attackor.map, engGame.battlesound, attackee.x, attackee.y);
                        }
                        int i = damRoll(attackor, attackee, range);
                        if (i < 0) {
@@ -626,7 +626,7 @@ public class Battle implements DuskProtocol {
                                        updateFlags(vctSide2, thnFront2.getFollowing().ID, 0);
                                        thnFront2.getFollowing().leaveBattle();
                                        thnFront2.getFollowing().damageDone = 0;
-                                       thnFront2.getFollowing().changeLocBypass(thnFront2.x, thnFront2.y);
+                                       thnFront2.getFollowing().changeLocBypass(thnFront2.map, thnFront2.x, thnFront2.y);
                                }
                        } else if (thnFront2.isMob()) {
                                Mob mob = (Mob) thnFront2;
index c28b57f..d9061c1 100644 (file)
@@ -35,6 +35,7 @@ import duskz.server.entity.DuskObject;
 import duskz.server.entity.Equipment;
 import duskz.server.entity.PlayerMerchant;
 import duskz.server.entity.LivingThing;
+import duskz.server.entity.TileMap;
 import java.io.*;
 import java.util.LinkedList;
 import java.util.StringTokenizer;
@@ -104,7 +105,7 @@ public class Commands implements DuskProtocol {
 
                                String strMapLog = "shortmap_redraw";
                                try (PrintStream psMap = new PrintStream(new FileOutputStream(strMapLog, true), true)) {
-                                       game.changeMap(lt.x, lt.y, Short.parseShort(cmdline));
+                                       game.changeMap(lt, lt.x, lt.y, Short.parseShort(cmdline));
                                        psMap.println("changetile " + lt.x + " " + lt.y + " " + Short.parseShort(cmdline));
                                        return null;
                                } catch (Exception e) {
@@ -122,10 +123,10 @@ public class Commands implements DuskProtocol {
                                        game.saveMap();
                                        return "Game settings saved";
                                } else if (cmdline.equalsIgnoreCase("merchant")) {
-                                       if (game.overMerchant(lt.x, lt.y) != null) {
+                                       if (lt.overMerchant() != null) {
                                                return "There's already a merchant there.";
                                        }
-                                       if (game.overPlayerMerchant(lt.x, lt.y) != null) {
+                                       if (lt.overPlayerMerchant() != null) {
                                                return "There's already a merchant there.";
                                        }
                                        Merchant mrcStore = new Merchant(game);
@@ -133,7 +134,7 @@ public class Commands implements DuskProtocol {
                                        mrcStore.y = lt.y;
                                        //game.vctMerchants.add(mrcStore);
                                        //game.blnMerchantListChanged = true;
-                                       game.addDuskObject(mrcStore);
+                                       game.addDuskObject(lt.map, mrcStore);
                                        return null;
                                } else if (cmdline.toLowerCase().startsWith("prop ")) {
                                        if (cmdline.length() == 5) {
@@ -146,7 +147,7 @@ public class Commands implements DuskProtocol {
                                                prpStore.y = lt.y;
                                                //game.vctProps.addElement(prpStore);
                                                //game.blnPropListChanged = true;
-                                               game.addDuskObject(prpStore);
+                                               game.addDuskObject(lt.map, prpStore);
                                        }
                                        return null;
                                } else if (cmdline.startsWith("sign ")) {
@@ -156,7 +157,7 @@ public class Commands implements DuskProtocol {
                                        Sign sgnStore = new Sign(game, "sign", cmdline.substring(5), lt.x, lt.y, game.getID());
                                        //game.vctSigns.add(sgnStore);
                                        //game.blnSignListChanged = true;
-                                       game.addDuskObject(sgnStore);
+                                       game.addDuskObject(lt.map, sgnStore);
                                        return null;
                                }
                                Item itmStore = game.getItem(cmdline);
@@ -164,7 +165,7 @@ public class Commands implements DuskProtocol {
                                        itmStore.x = lt.x;
                                        itmStore.y = lt.y;
                                        //game.vctItems.add(itmStore);
-                                       game.addDuskObject(itmStore);
+                                       game.addDuskObject(lt.map, itmStore);
                                        return null;
                                }
                                try {
@@ -172,9 +173,9 @@ public class Commands implements DuskProtocol {
                                        // TODO: this previously didn't call addDuskObject - bug or intentional?
                                        //game.vctMobs.addElement(mob);
                                        //game.blnMobListChanged = true;
-                                       game.addDuskObject(mob);
+                                       game.addDuskObject(lt.map, mob);
 
-                                       mob.changeLocBypass(lt.x, lt.y);
+                                       mob.changeLocBypass(lt.map, lt.x, lt.y);
                                } catch (Exception e) {
                                        game.log.printError("parseCommand():While creating mob \"" + cmdline + "\"", e);
                                }
@@ -317,7 +318,7 @@ public class Commands implements DuskProtocol {
                                thnStore.chatMessage("You have been kicked out of " + lt.clan + ".");
                                thnStore.clan = "none";
                                game.removeDuskObject(thnStore);
-                               game.addDuskObject(thnStore);
+                               game.addDuskObject(thnStore.map, thnStore);
                                return thnStore.name + " has been kicked out of your clan.";
                        }
 //             if (lt.privs > 2) {
@@ -358,7 +359,7 @@ public class Commands implements DuskProtocol {
                                if (lt.privs <= 4)
                                        return "Huh?";
                                game.log.printMessage(Log.INFO, "godcommand:" + lt.name + ":" + cmdline + ":" + lt.x + "," + lt.y);
-                               game.resizeMap(lt.x + 1, lt.y + 1);
+                               game.resizeMap(lt.map, lt.x + 1, lt.y + 1);
                                return "Map resized";
                        case "shutdown":
                                if (lt.privs <= 4)
@@ -961,7 +962,7 @@ public class Commands implements DuskProtocol {
                                        thnStore.chatMessage("You are now a member of the " + args + " clan.");
                                }
                                game.removeDuskObject(thnStore);
-                               game.addDuskObject(thnStore);
+                               game.addDuskObject(thnStore.map, thnStore);
                                return thnStore.name + " is now a leader of the " + args + " clan.";
                        }
                        case "boot": {
@@ -1069,13 +1070,23 @@ public class Commands implements DuskProtocol {
                                        charSep = '_';
                                }
                                try {
-                                       int destX = Integer.parseInt(args.substring(0, args.lastIndexOf(charSep)));
-                                       int destY = Integer.parseInt(args.substring(args.lastIndexOf(charSep) + 1));
-                                       if (lt.privs < 5 && destX >= game.map.getCols()) {
-                                               destX = game.map.getCols() - 1;
+                                       String[] params = args.split(" ");
+                                       TileMap map;
+                                       int destX, destY;
+                                       if (params.length == 3) {
+                                               map = game.maps.get(params[0]);
+                                               destX = Integer.parseInt(params[1]);
+                                               destY = Integer.parseInt(params[2]);
+                                       } else {
+                                               map = lt.map;
+                                               destX = Integer.parseInt(params[0]);
+                                               destY = Integer.parseInt(params[1]);
+                                       }
+                                       if (lt.privs < 5 && destX >= map.getCols()) {
+                                               destX = map.getCols() - 1;
                                        }
-                                       if (lt.privs < 5 && destY >= game.map.getRows()) {
-                                               destY = game.map.getRows() - 1;
+                                       if (lt.privs < 5 && destY >= map.getRows()) {
+                                               destY = map.getRows() - 1;
                                        }
                                        if (destX < 0) {
                                                destX = 0;
@@ -1083,12 +1094,14 @@ public class Commands implements DuskProtocol {
                                        if (destY < 0) {
                                                destY = 0;
                                        }
-                                       lt.changeLocBypass(destX, destY);
+                                       lt.changeLocBypass(map, destX, destY);
                                } catch (Exception e) {
                                        LivingThing thnStore = game.getPlayer(args);
                                        if (thnStore == null) {
                                                return "Teleport to where?";
                                        } else {
+                                               // Hmm, i'm not sure what this does, teleport to another player?
+                                               // Whats with the weird range checking?
                                                int destX = thnStore.x;
                                                int destY = thnStore.y;
                                                if (lt.privs < 5 && destX > 349) {
@@ -1103,7 +1116,7 @@ public class Commands implements DuskProtocol {
                                                if (destY < 0) {
                                                        destY = 0;
                                                }
-                                               lt.changeLocBypass(destX, destY);
+                                               lt.changeLocBypass(thnStore.map, destX, destY);
                                        }
                                }
                                return null;
@@ -1181,13 +1194,13 @@ public class Commands implements DuskProtocol {
                                if (args == null) {
                                        return "Madd what?";
                                }
-                               Merchant mrcStore = game.overMerchant(lt.x, lt.y);
+                               Merchant mrcStore = lt.overMerchant();
                                if (mrcStore != null) {
                                        game.log.printMessage(Log.INFO, "godcommand:" + lt.name + ":" + cmdline + ":" + lt.x + "," + lt.y);
                                        mrcStore.items.add(args);
                                        game.refreshEntities(lt);
                                } else {
-                                       if (game.overPlayerMerchant(lt.x, lt.y) != null) {
+                                       if (lt.overPlayerMerchant() != null) {
                                                return "You cannot add items to a player's merchant this way.";
                                        }
                                        return "You are not on a merchant.";
@@ -1200,13 +1213,13 @@ public class Commands implements DuskProtocol {
                                if (args == null) {
                                        return "Mremove what?";
                                }
-                               Merchant mrcStore = game.overMerchant(lt.x, lt.y);
+                               Merchant mrcStore = lt.overMerchant();
                                if (mrcStore != null) {
                                        game.log.printMessage(Log.INFO, "godcommand:" + lt.name + ":" + cmdline + ":" + lt.x + "," + lt.y);
                                        mrcStore.items.remove(args);
                                        game.refreshEntities(lt);
                                } else {
-                                       if (game.overPlayerMerchant(lt.x, lt.y) != null) {
+                                       if (lt.overPlayerMerchant() != null) {
                                                return "You cannot remove items from a player's merchant this way.";
                                        }
                                        return "You are not on a merchant.";
@@ -1302,7 +1315,7 @@ public class Commands implements DuskProtocol {
                                lt.isSleeping = true;
                                lt.updateActions();
                                game.removeDuskObject(lt);
-                               game.addDuskObject(lt);
+                               game.addDuskObject(lt.map, lt);
                                return "You go to sleep";
                        }
                        case "wake": {
@@ -1310,7 +1323,7 @@ public class Commands implements DuskProtocol {
                                        lt.isSleeping = false;
                                        lt.updateActions();
                                        game.removeDuskObject(lt);
-                                       game.addDuskObject(lt);
+                                       game.addDuskObject(lt.map, lt);
                                        return "You wake up";
                                } else {
                                        return "You are already awake";
@@ -1370,7 +1383,7 @@ public class Commands implements DuskProtocol {
                                         }
                                         */
                                        game.removeDuskObject(lt);
-                                       game.addDuskObject(lt);
+                                       game.addDuskObject(lt.map, lt);
                                        lt.updateStats();
                                        return "Your race has been changed.";
                                }
@@ -1442,9 +1455,9 @@ public class Commands implements DuskProtocol {
                                }
                                if (!args.equals("")) {
                                        if (lt.isPet()) {
-                                               game.chatMessage("Pet " + lt.name + " says: " + args, lt.x, lt.y, lt.name);
+                                               game.chatMessage(lt.map, "Pet " + lt.name + " says: " + args, lt.x, lt.y, lt.name);
                                        } else if (lt.isMob()) {
-                                               game.chatMessage("Mob " + lt.name + " says: " + args, lt.x, lt.y, "default");
+                                               game.chatMessage(lt.map, "Mob " + lt.name + " says: " + args, lt.x, lt.y, "default");
                                        } else {
                                                long lTemp = lt.lastMessageStamp;
                                                lt.lastMessageStamp = System.currentTimeMillis();
@@ -1457,7 +1470,7 @@ public class Commands implements DuskProtocol {
                                                                && lt.hasCondition("invis2")) {
                                                        strPerson = "A god";
                                                }
-                                               game.chatMessage(strPerson + " says: " + args, lt.x, lt.y, lt.name);
+                                               game.chatMessage(lt.map, strPerson + " says: " + args, lt.x, lt.y, lt.name);
                                        }
                                }
                                return null;
@@ -1484,7 +1497,7 @@ public class Commands implements DuskProtocol {
                                                        && lt.hasCondition("invis2")) {
                                                strPerson = "A god";
                                        }
-                                       game.chatMessage(strPerson + " " + args, lt.x, lt.y, lt.name);
+                                       game.chatMessage(lt.map, strPerson + " " + args, lt.x, lt.y, lt.name);
                                }
                                return null;
                        }
@@ -1903,7 +1916,7 @@ public class Commands implements DuskProtocol {
                                                itmStore.y = lt.y;
                                                if (itmStore.intCost != 0) {
                                                        //game.vctItems.add(itmStore);
-                                                       game.addDuskObject(itmStore);
+                                                       game.addDuskObject(lt.map, itmStore);
                                                        lt.updateItems();
                                                }
                                                itmStore.onDropItem(game, lt);
@@ -2049,7 +2062,7 @@ public class Commands implements DuskProtocol {
                                } else if (quantity < 1) {
                                        return "You can't buy less than one of something.";
                                }
-                               PlayerMerchant pmrStore = game.overPlayerMerchant(lt.x, lt.y);
+                               PlayerMerchant pmrStore = lt.overPlayerMerchant();
                                if (pmrStore != null) {
                                        long numItem = pmrStore.contains(args);
                                        if (numItem > 0) {
@@ -2080,7 +2093,7 @@ public class Commands implements DuskProtocol {
                                        }
                                }
 
-                               Merchant mrcStore = game.overMerchant(lt.x, lt.y);
+                               Merchant mrcStore = lt.overMerchant();
                                if (mrcStore == null) {
                                        return "Buy from whom?";
                                }
@@ -2132,7 +2145,7 @@ public class Commands implements DuskProtocol {
                                        return "Sell what?";
                                }
 
-                               PlayerMerchant pmrStore = game.overPlayerMerchant(lt.x, lt.y);
+                               PlayerMerchant pmrStore = lt.overPlayerMerchant();
                                if (pmrStore != null) {
                                        if (lt.name.equalsIgnoreCase(pmrStore.strOwner)) {
                                                int quantity = 1;
@@ -2161,7 +2174,7 @@ public class Commands implements DuskProtocol {
                                        return "You cannot sell items to this merchant.";
                                }
 
-                               Merchant mrcStore = game.overMerchant(lt.x, lt.y);
+                               Merchant mrcStore = lt.overMerchant();
                                if (mrcStore == null) {
                                        return "Sell that to whom?";
                                }
@@ -2343,18 +2356,18 @@ public class Commands implements DuskProtocol {
                                        return "unclan not implemented yet";
                                try {
                                        /*
-                                       lt.halt();
-                                       lt.chatMessage("Are you sure you want to drop out of your clan? If so type yes.");
-                                       if (lt.instream.readLine().equalsIgnoreCase("yes")) {
-                                               lt.clan = "none";
-                                               if (lt.privs == 1) {
-                                                       lt.privs = 0;
-                                               }
-                                               lt.proceed();
-                                               game.removeDuskObject(lt);
-                                               game.addDuskObject(lt);
-                                               return "You have been removed from your clan.";
-                                       }*/
+                                        lt.halt();
+                                        lt.chatMessage("Are you sure you want to drop out of your clan? If so type yes.");
+                                        if (lt.instream.readLine().equalsIgnoreCase("yes")) {
+                                        lt.clan = "none";
+                                        if (lt.privs == 1) {
+                                        lt.privs = 0;
+                                        }
+                                        lt.proceed();
+                                        game.removeDuskObject(lt);
+                                        game.addDuskObject(lt);
+                                        return "You have been removed from your clan.";
+                                        }*/
                                } catch (Exception e) {
                                        game.log.printError("parseCommand():While " + lt.name + " was trying to dropout of their clan", e);
                                }
@@ -2392,34 +2405,34 @@ public class Commands implements DuskProtocol {
                                }
                                return "password changing not re-implemented yet";
                                /*
-                               try {
-                                       lt.halt();
-                                       lt.chatMessage("Enter your current password.");
-                                       String strOldPass = lt.instream.readLine();
-                                       if (!strOldPass.equals(lt.password)) {
-                                               lt.proceed();
-                                               return "Sorry, that is not your password.";
-                                       }
-                                       lt.chatMessage("Enter a new password.");
-                                       String strNewPass = lt.instream.readLine();
-                                       lt.chatMessage("Repeat that password.");
-                                       String strNewPassRepeat = lt.instream.readLine();
-                                       if (strNewPass == null) {
-                                               lt.proceed();
-                                               return "Not a valid password.";
-                                       }
-                                       if (!strNewPass.equals(strNewPassRepeat)) {
-                                               lt.proceed();
-                                               return "Sorry, those passwords do not match.";
-                                       }
-                                       lt.password = strNewPass;
-                                       lt.proceed();
-                                       return "Your password has now been changed.";
-                               } catch (Exception e) {
-                                       game.log.printError("parseCommand():While " + lt.name + " was changing their password", e);
-                               }
-                               lt.proceed();
-                               */
+                                try {
+                                lt.halt();
+                                lt.chatMessage("Enter your current password.");
+                                String strOldPass = lt.instream.readLine();
+                                if (!strOldPass.equals(lt.password)) {
+                                lt.proceed();
+                                return "Sorry, that is not your password.";
+                                }
+                                lt.chatMessage("Enter a new password.");
+                                String strNewPass = lt.instream.readLine();
+                                lt.chatMessage("Repeat that password.");
+                                String strNewPassRepeat = lt.instream.readLine();
+                                if (strNewPass == null) {
+                                lt.proceed();
+                                return "Not a valid password.";
+                                }
+                                if (!strNewPass.equals(strNewPassRepeat)) {
+                                lt.proceed();
+                                return "Sorry, those passwords do not match.";
+                                }
+                                lt.password = strNewPass;
+                                lt.proceed();
+                                return "Your password has now been changed.";
+                                } catch (Exception e) {
+                                game.log.printError("parseCommand():While " + lt.name + " was changing their password", e);
+                                }
+                                lt.proceed();
+                                */
                        }
 
                        case "wear": {
index f1f7a4a..86de141 100644 (file)
@@ -119,7 +119,8 @@ public class DuskEngine implements Runnable, DuskProtocol {
        //protected short shrMapOwnerPrivs[][];
        //protected int intMapOwnerID[][];
        //protected Config IDtoName;
-       public TileMap map;
+       //public TileMap map;
+       public final HashMap<String, TileMap> maps = new HashMap<>();
        final public List<Battle> battleList = new ArrayList<>();
        // Indices of various Entities
        final public HashSet<Merchant> merchantList = new HashSet<>();
@@ -169,22 +170,28 @@ public class DuskEngine implements Runnable, DuskProtocol {
                try {
                        int x = 0,
                                        y = 0;
-                       String strStore;
+                       String line;
 
                        loadPrefs();
 
                        // Load Map
-                       File newmap = new File("defMaps/main");
+                       File newmap = new File("defMaps");
                        if (newmap.exists()) {
-                               // FIXME: load multiple maps here
-                               log.printMessage(Log.INFO, "Loading Layered Map...");
-                               map = TileMap.loadLayered(newmap);
-                               log.printMessage(Log.VERBOSE, map.getCols() + "x" + map.getRows() + "x" + map.getLayerCount());
+                               for (File mapfile : newmap.listFiles()) {
+                                       TileMap map;
+                                       log.printMessage(Log.INFO, "Loading Layered Maps...");
+                                       map = TileMap.loadLayered(mapfile);
+                                       maps.put(map.name, map);
+                                       log.printMessage(Log.VERBOSE, map.name + ": " + map.getCols() + "x" + map.getRows() + "x" + map.getLayerCount());
+                               }
                        } else if ((newmap = new File("shortmapx")).exists()) {
+                               TileMap map;
                                log.printMessage(Log.INFO, "Loading Map...");
                                map = TileMap.loadMapX(newmap);
+                               maps.put("main", map);
                                log.printMessage(Log.VERBOSE, map.getCols() + "/" + map.getRows());
                        } else {
+                               TileMap map;
                                newmap = new File("shortmap");
                                if (newmap.exists()) {
                                        log.printMessage(Log.INFO, "Loading Map...");
@@ -195,6 +202,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
                                        map = TileMap.loadMap(newmap, TileMap.FORMAT_BYTE);
                                        log.printMessage(Log.VERBOSE, map.getCols() + "/" + map.getRows());
                                }
+                               maps.put("main", map);
                        }
 
                        log.printMessage(Log.INFO, "Map Loaded...");
@@ -242,31 +250,34 @@ public class DuskEngine implements Runnable, DuskProtocol {
                         rafFile.close();
                         }*/
 
+                       // FIXME: use some sort of common file format or at least conventions
+                       // between all these state files.
+
                        // Load Merchants
                        try {
                                rafFile = new RandomAccessFile("merchants", "r");
                                Merchant mrcStore;
                                log.printMessage(Log.INFO, "Loading Merchants...");
-                               strStore = rafFile.readLine();
-                               while (!(strStore == null || strStore.equals(""))) {
+                               line = rafFile.readLine();
+                               while (!(line == null || line.equals(""))) {
                                        mrcStore = new Merchant(this);
-                                       mrcStore.x = Integer.parseInt(strStore);
+                                       TileMap map = maps.get(line);
+                                       mrcStore.x = Integer.parseInt(rafFile.readLine());
                                        mrcStore.y = Integer.parseInt(rafFile.readLine());
                                        log.printMessage(Log.VERBOSE, "Merchant(" + mrcStore.x + "," + mrcStore.y + ")");
-                                       strStore = rafFile.readLine();
-                                       while (strStore != null && !strStore.equals("") && !strStore.equalsIgnoreCase("end")) {
-                                               log.printMessage(Log.DEBUG, "\t" + strStore);
-                                               mrcStore.items.add(strStore);
-                                               strStore = rafFile.readLine();
+                                       line = rafFile.readLine();
+                                       while (line != null && !line.equals("") && !line.equalsIgnoreCase("end")) {
+                                               log.printMessage(Log.DEBUG, "\t" + line);
+                                               mrcStore.items.add(line);
+                                               line = rafFile.readLine();
                                        }
                                        if (!map.inside(mrcStore.x, mrcStore.y)) {
                                                log.printMessage(Log.VERBOSE, "Previous merchant is off of the map, ignoring");
                                                blnMerchantListChanged = true;
                                        } else {
-                                               //vctMerchants.add(mrcStore);
-                                               addDuskObject(mrcStore);
+                                               addDuskObject(mrcStore.map, mrcStore);
                                        }
-                                       strStore = rafFile.readLine();
+                                       line = rafFile.readLine();
                                }
                        } catch (Exception e) {
                                log.printError("DuskEngine():While loading merchants", e);
@@ -277,49 +288,43 @@ public class DuskEngine implements Runnable, DuskProtocol {
                        LivingThing thnStore;
                        rafFile = new RandomAccessFile("mobs", "r");
                        log.printMessage(Log.INFO, "Loading Mobs...");
-                       strStore = rafFile.readLine();
-                       while (strStore != null) {
-                               if (strStore.equals("")) {
+                       line = rafFile.readLine();
+                       while (line != null) {
+                               if (line.equals("")) {
                                        break;
                                }
-                               if (strStore.equals("mob2.3")) {
-                                       strStore = rafFile.readLine();
-                                       log.printMessage(Log.VERBOSE, strStore);
-                                       try {
-                                               thnStore = new Mob(strStore,
-                                                               Integer.parseInt(rafFile.readLine()),
-                                                               Integer.parseInt(rafFile.readLine()),
-                                                               this);
-                                               if (!map.inside(thnStore.x, thnStore.y)) {
-                                                       log.printMessage(Log.VERBOSE, "Previous mob is off of the map, ignoring");
-                                                       blnMobListChanged = true;
-                                               } else {
-                                                       //vctMobs.addElement(thnStore);
-                                                       addDuskObject(thnStore);
-                                               }
-                                       } catch (Exception e) {
-                                               log.printError("DuskEngine():While loading mobs", e);
-                                       }
-                               } else {
-                                       log.printMessage(Log.VERBOSE, strStore);
+                               // Only bother to support new file format:
+                               // mob
+                               // type
+                               // map
+                               // x
+                               // y
+                               if (line.equals("mob")) {
                                        try {
-                                               thnStore = new Mob(strStore,
-                                                               Integer.parseInt(rafFile.readLine()),
-                                                               Integer.parseInt(rafFile.readLine()),
-                                                               Integer.parseInt(rafFile.readLine()),
+                                               String mobtype = rafFile.readLine();
+                                               String mapname = rafFile.readLine();
+                                               int locx = Integer.parseInt(rafFile.readLine());
+                                               int locy = Integer.parseInt(rafFile.readLine());
+                                               TileMap map = maps.get(mapname);
+
+                                               thnStore = new Mob(mobtype,
+                                                               locx,
+                                                               locy,
                                                                this);
+
                                                if (!map.inside(thnStore.x, thnStore.y)) {
                                                        log.printMessage(Log.VERBOSE, "Previous mob is off of the map, ignoring");
                                                        blnMobListChanged = true;
                                                } else {
                                                        //vctMobs.addElement(thnStore);
-                                                       addDuskObject(thnStore);
+                                                       addDuskObject(map, thnStore);
                                                }
+
                                        } catch (Exception e) {
-                                               log.printError("DuskEngine():While loading mobs", e);
+                                               log.printError("Error loading mobs", e);
                                        }
                                }
-                               strStore = rafFile.readLine();
+                               line = rafFile.readLine();
                        }
                        rafFile.close();
 
@@ -327,18 +332,21 @@ public class DuskEngine implements Runnable, DuskProtocol {
                        Sign sgnStore;
                        rafFile = new RandomAccessFile("signs", "r");
                        log.printMessage(Log.INFO, "Loading Signs...");
-                       strStore = rafFile.readLine();
-                       while (!(strStore == null || strStore.equals(""))) {
-                               log.printMessage(Log.VERBOSE, strStore);
-                               sgnStore = new Sign(this, "sign", strStore, Integer.parseInt(rafFile.readLine()), Integer.parseInt(rafFile.readLine()), getID());
+                       line = rafFile.readLine();
+                       while (!(line == null || line.equals(""))) {
+                               String mapname = rafFile.readLine();
+                               int locx = Integer.parseInt(rafFile.readLine());
+                               int locy = Integer.parseInt(rafFile.readLine());
+                               TileMap map = maps.get(mapname);
+                               log.printMessage(Log.VERBOSE, line);
+                               sgnStore = new Sign(this, "sign", line, locx, locy, getID());
                                if (!map.inside(sgnStore.x, sgnStore.y)) {
                                        log.printMessage(Log.VERBOSE, "Previous sign is off of the map, ignoring");
                                        blnSignListChanged = true;
                                } else {
-                                       //vctSigns.add(sgnStore);
-                                       addDuskObject(sgnStore);
+                                       addDuskObject(map, sgnStore);
                                }
-                               strStore = rafFile.readLine();
+                               line = rafFile.readLine();
                        }
                        rafFile.close();
 
@@ -346,22 +354,26 @@ public class DuskEngine implements Runnable, DuskProtocol {
                        Prop prpStore;
                        rafFile = new RandomAccessFile("props", "r");
                        log.printMessage(Log.INFO, "Loading Props...");
-                       strStore = rafFile.readLine();
-                       while (!(strStore == null || strStore.equals(""))) {
-                               log.printMessage(Log.VERBOSE, strStore);
-                               prpStore = getProp(strStore);
+                       line = rafFile.readLine();
+                       while (!(line == null || line.equals(""))) {
+                               String mapname = rafFile.readLine();
+                               int locx = Integer.parseInt(rafFile.readLine());
+                               int locy = Integer.parseInt(rafFile.readLine());
+                               TileMap map = maps.get(mapname);
+
+                               log.printMessage(Log.VERBOSE, line);
+                               prpStore = getProp(line);
                                if (prpStore != null) {
-                                       prpStore.x = Integer.parseInt(rafFile.readLine());
-                                       prpStore.y = Integer.parseInt(rafFile.readLine());
+                                       prpStore.x = locx;
+                                       prpStore.y = locy;
                                        if (!map.inside(prpStore.x, prpStore.y)) {
                                                log.printMessage(Log.VERBOSE, "Previous prop is off of the map, ignoring");
                                                blnPropListChanged = true;
                                        } else {
-                                               //vctProps.addElement(prpStore);
-                                               addDuskObject(prpStore);
+                                               addDuskObject(map, prpStore);
                                        }
                                }
-                               strStore = rafFile.readLine();
+                               line = rafFile.readLine();
                        }
                        rafFile.close();
 
@@ -676,6 +688,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
                                try {
                                        scripts.put(i, new Script(path + i, this, true));
                                } catch (Exception e) {
+                                       System.out.println("Loaded tile scripts " + path + " until: " + i);
                                        break;
                                }
                        }
@@ -698,7 +711,17 @@ public class DuskEngine implements Runnable, DuskProtocol {
                }
        }
 
-       public void chatMessage(String inMessage, int locx, int locy, String strFrom) {
+       /**
+        * Sends a chat message to other players within visible range.
+        *
+        * @param map
+        * @param inMessage
+        * @param locx
+        * @param locy
+        * @param strFrom
+        */
+       // FIXME: move somewhere better
+       public void chatMessage(TileMap map, String inMessage, int locx, int locy, String strFrom) {
                strFrom = strFrom.toLowerCase();
                LivingThing thnStore;
                log.printMessage(Log.ALWAYS, inMessage);
@@ -727,10 +750,11 @@ public class DuskEngine implements Runnable, DuskProtocol {
                }
        }
 
+       // FIXME: move to livinghting?
        public void refreshEntities(LivingThing refresh) {
                LinkedList<DuskObject> newEntities = new LinkedList<>();
 
-               for (TileMap.MapData md : map.range(refresh.x, refresh.y, viewrange)) {
+               for (TileMap.MapData md : refresh.map.range(refresh.x, refresh.y, viewrange)) {
                        if (!md.entities.isEmpty()
                                        && canSeeTo(refresh, md.x, md.y)) {
                                for (DuskObject o : md.entities) {
@@ -816,7 +840,8 @@ public class DuskEngine implements Runnable, DuskProtocol {
                refresh.setEntities(newEntities);
        }
 
-       public void addEntity(DuskObject add) {
+       // FIXME: move to map or livingthing?
+       public void addEntity(TileMap map, DuskObject add) {
                for (TileMap.MapData md : map.range(add.x, add.y, viewrange)) {
                        for (DuskObject o : md.entities) {
                                if (o.isLivingThing()) {
@@ -838,22 +863,24 @@ public class DuskEngine implements Runnable, DuskProtocol {
 
        public void cleanup() {
                log.printMessage(Log.INFO, "Starting cleanup.");
-               for (TileMap.MapData md : map) {
-                       for (DuskObject o : md.entities) {
-                               if (o.isLivingThing()) {
-                                       LivingThing lt = (LivingThing) o;
-                                       if (lt.isPlayer()) {
-                                               if (!playersByName.containsKey(lt.name)) {
-                                                       log.printMessage(Log.INFO, "**found defunct player at " + md.x + "," + md.y + " during cleanup.");
-                                                       removeDuskObject(lt);
-                                                       lt.battle = null;
-                                                       lt.isStopped = true;
+               for (TileMap map : maps.values()) {
+                       for (TileMap.MapData md : map) {
+                               for (DuskObject o : md.entities) {
+                                       if (o.isLivingThing()) {
+                                               LivingThing lt = (LivingThing) o;
+                                               if (lt.isPlayer()) {
+                                                       if (!playersByName.containsKey(lt.name)) {
+                                                               log.printMessage(Log.INFO, "**found defunct player at " + md.x + "," + md.y + " during cleanup.");
+                                                               removeDuskObject(lt);
+                                                               lt.battle = null;
+                                                               lt.isStopped = true;
+                                                       }
                                                }
-                                       }
-                                       if (lt.isPet()) {
-                                               if (!petList.contains(lt)) {
-                                                       log.printMessage(Log.INFO, "**found defunct pet at " + md.x + "," + md.y + " during cleanup.");
-                                                       removeDuskObject(lt);
+                                               if (lt.isPet()) {
+                                                       if (!petList.contains(lt)) {
+                                                               log.printMessage(Log.INFO, "**found defunct pet at " + md.x + "," + md.y + " during cleanup.");
+                                                               removeDuskObject(lt);
+                                                       }
                                                }
                                        }
                                }
@@ -862,8 +889,9 @@ public class DuskEngine implements Runnable, DuskProtocol {
                log.printMessage(Log.INFO, "Finished cleanup.");
        }
 
+       // FIXME: Move to map?
        void notifyRemoved(DuskObject remove) {
-               for (TileMap.MapData md : map.range(remove.x, remove.y, viewrange)) {
+               for (TileMap.MapData md : remove.map.range(remove.x, remove.y, viewrange)) {
                        for (DuskObject o : md.entities) {
                                if (o.isLivingThing()) {
                                        LivingThing lt = (LivingThing) o;
@@ -951,11 +979,11 @@ public class DuskEngine implements Runnable, DuskProtocol {
                                pla1.chatMessage("Players who are not in clans cannot fight other players.");
                                return;
                        }
-                       if (pla2.isPlayer() && overMerchant(pla2.x, pla2.y) != null) {
+                       if (pla2.isPlayer() && pla2.overMerchant() != null) {
                                pla1.chatMessage("You cannot attack players who are shopping.");
                                return;
                        }
-                       if (pla2.isPlayer() && overPlayerMerchant(pla2.x, pla2.y) != null) {
+                       if (pla2.isPlayer() && pla2.overPlayerMerchant() != null) {
                                pla1.chatMessage("You cannot attack players who are shopping.");
                                return;
                        }
@@ -1213,7 +1241,8 @@ public class DuskEngine implements Runnable, DuskProtocol {
                return null;
        }
 
-       void playSound(int sfxid, int locx, int locy) {
+       // FIXME: move to map or livinghting?
+       void playSound(TileMap map, int sfxid, int locx, int locy) {
                for (TileMap.MapData md : map.range(locx, locy, viewrange)) {
                        for (DuskObject o : md.entities) {
                                if (o.isLivingThing()) {
@@ -1226,35 +1255,39 @@ public class DuskEngine implements Runnable, DuskProtocol {
                }
        }
 
-       public boolean canMoveTo(int inLocX, int inLocY, LivingThing thnStore) {
+       // FIXME: move to map or livingthing
+       public boolean canMoveTo(int inLocX, int inLocY, LivingThing lt) {
                int i;
                LivingThing thnStore2;
                Script scrStore;
                boolean blnStore;
 
-               if (!map.inside(inLocX, inLocY))
+               if (!lt.map.inside(inLocX, inLocY))
                        return false;
 
-               for (DuskObject o : map.getEntities(inLocX, inLocY, null)) {
+               System.out.printf("can move to: %d,%d tid=%3d on map %s\n", inLocX, inLocY, lt.map.getTile(inLocX, inLocY), lt.map.name);
+
+               for (DuskObject o : lt.map.getEntities(inLocX, inLocY, null)) {
                        if (o.isLivingThing()) {
                                thnStore2 = (LivingThing) o;
-                               if (!canMoveThrougLivingThing(thnStore, thnStore2))
+                               if (!canMoveThrougLivingThing(lt, thnStore2))
                                        return false;
                        }
                }
                try {
                        scrStore = new Script("defCanMoveScripts/" + inLocX + "_" + inLocY, this, false);
-                       scrStore.varVariables.addVariable("trigger", thnStore);
+                       scrStore.varVariables.addVariable("trigger", lt);
                        blnStore = scrStore.rewindAndParseScript();
                        scrStore.close();
                        return blnStore;
                } catch (Exception e) {
                }
                try {
-                       scrStore = (Script) tileCanMove.get((int) map.getTile(inLocX, inLocY));
+                       int tid = lt.map.getTile(inLocX, inLocY);
+                       scrStore = (Script) tileCanMove.get(tid);
                        synchronized (scrStore) {
                                scrStore.varVariables.clearVariables();
-                               scrStore.varVariables.addVariable("trigger", thnStore);
+                               scrStore.varVariables.addVariable("trigger", lt);
                                blnStore = scrStore.rewindAndParseScript();
                        }
                        return blnStore;
@@ -1264,26 +1297,25 @@ public class DuskEngine implements Runnable, DuskProtocol {
                return false;
        }
 
-       boolean canSee(int inLocX, int inLocY, LivingThing thnStore) {
+       // FIXME: move to lt
+       boolean canSee(LivingThing lt, int inLocX, int inLocY) {
                int i;
-               LivingThing thnStore2;
-               DuskObject objStore = null;
-               Script scrStore;
+               Script script;
                boolean blnStore;
                try {
-                       scrStore = new Script("defCanSeeScripts/" + inLocX + "_" + inLocY, this, false);
-                       scrStore.varVariables.addVariable("trigger", thnStore);
-                       blnStore = scrStore.rewindAndParseScript();
-                       scrStore.close();
+                       script = new Script("defCanSeeScripts/" + inLocX + "_" + inLocY, this, false);
+                       script.varVariables.addVariable("trigger", lt);
+                       blnStore = script.rewindAndParseScript();
+                       script.close();
                        return blnStore;
                } catch (Exception e) {
                }
                try {
-                       scrStore = (Script) tileCanSee.get((int) map.getTile(inLocX, inLocY));
-                       synchronized (scrStore) {
-                               scrStore.varVariables.clearVariables();
-                               scrStore.varVariables.addVariable("trigger", thnStore);
-                               blnStore = scrStore.rewindAndParseScript();
+                       script = (Script) tileCanSee.get((int) lt.map.getTile(inLocX, inLocY));
+                       synchronized (script) {
+                               script.varVariables.clearVariables();
+                               script.varVariables.addVariable("trigger", lt);
+                               blnStore = script.rewindAndParseScript();
                        }
                        return blnStore;
                } catch (Exception e) {
@@ -1292,10 +1324,11 @@ public class DuskEngine implements Runnable, DuskProtocol {
        }
 
        // TODO: Move this to map, then everything that uses it can be elsewhere
+       // Or to living thing
        // Following by Randall Leeds and Tom Weingarten
        // map/iterator version by notzed
-       public boolean canSeeTo(LivingThing thing, int destX, int destY) {
-               if (Math.abs(thing.x - destX) > viewrange || Math.abs(thing.y - destY) > viewrange) {
+       public boolean canSeeTo(LivingThing lt, int destX, int destY) {
+               if (Math.abs(lt.x - destX) > viewrange || Math.abs(lt.y - destY) > viewrange) {
                        return false;
                }
 
@@ -1303,8 +1336,8 @@ public class DuskEngine implements Runnable, DuskProtocol {
                        return true;
                }
 
-               for (TileMap.MapData md : map.look(thing.x, thing.y, destX, destY)) {
-                       if (!canSee(md.x, md.y, thing))
+               for (TileMap.MapData md : lt.map.look(lt.x, lt.y, destX, destY)) {
+                       if (!canSee(lt, md.x, md.y))
                                return false;
                }
                return true;
@@ -1379,42 +1412,40 @@ public class DuskEngine implements Runnable, DuskProtocol {
        }
        //End contributed portion
 
-       public Merchant overMerchant(int x, int y) {
-               for (DuskObject o : map.getEntities(x, y, null)) {
-                       if (o.isMerchant()) {
-                               return (Merchant) o;
-                       }
-               }
-               return null;
-       }
-
-       public PlayerMerchant overPlayerMerchant(int x, int y) {
-               for (DuskObject o : map.getEntities(x, y, null)) {
-                       if (o.isPlayerMerchant()) {
-                               return (PlayerMerchant) o;
-                       }
-               }
-               return null;
-       }
-
-       synchronized void changeMap(int locx, int locy, short value) {
+       // FIXME: Move to livingthing? Enforce privs?
+       synchronized void changeMap(LivingThing god, int locx, int locy, short value) {
                if (value < 0 || value > tileCanMove.size()) {
                        log.printMessage(Log.INFO, "Invalid value passed to changeMap(" + locx + "," + locy + "," + value + ")");
                        return;
                }
-               if (!map.inside(locx, locy)) {
+               if (!god.map.inside(locx, locy)) {
                        log.printMessage(Log.INFO, "Invalid location to changeMap(" + locx + "," + locy + "," + value + ")");
                        return;
                }
-               map.setTile(locx, locy, value);
+               god.map.setTile(locx, locy, value);
                blnMapHasChanged = true;
-               updateMap(locx, locy);
+               updateMap(god, locx, locy);
+       }
+
+       void updateMap(LivingThing thing, int locx, int locy) {
+               for (TileMap.MapData md : thing.map.range(locx, locy, viewrange)) {
+                       for (DuskObject o : md.entities) {
+                               if (o.isLivingThing()) {
+                                       LivingThing lt = (LivingThing) o;
+                                       if (lt.isPlayer()) {
+                                               lt.updateMap();
+                                       }
+                               }
+                       }
+               }
        }
 
-       synchronized void resizeMap(int x, int y) {
+       // FIXME: move to livingthing enforce privs?
+       synchronized void resizeMap(TileMap map, int x, int y) {
                map.resize(x, y);
-               for (LivingThing lt : playersByName.values()) {
-                       lt.initMap();
+               // FIXME: only the map that changed
+               for (LivingThing thing : playersByName.values()) {
+                       thing.initMap();
                }
                blnMapHasChanged = true;
        }
@@ -1436,8 +1467,9 @@ public class DuskEngine implements Runnable, DuskProtocol {
                        int i,
                                        i2;
                        if (blnMapHasChanged) {
+                               System.err.println("save map not implemented");
                                log.printMessage(Log.ALWAYS, "Saving map...");
-                               map.saveMap(new File("shortmap"));
+                               //map.saveMap(new File("shortmap"));
                                String strMapLog = "shortmap_redraw";
                                PrintStream psMap = new PrintStream(new FileOutputStream(strMapLog, true), true);
                                psMap.println("# Map Saved");
@@ -1537,6 +1569,8 @@ public class DuskEngine implements Runnable, DuskProtocol {
        }
 
        void backupMap() {
+               if (true)
+                       throw new UnsupportedOperationException("backupmap not implemented");
                try {
                        StringTokenizer tknStore;
                        Mob mobStore;
@@ -1544,12 +1578,13 @@ public class DuskEngine implements Runnable, DuskProtocol {
                        Sign sgnStore;
                        Merchant mrcStore;
                        Prop prpStore;
-                       synchronized (map) {
+//                     synchronized (map) {
+                       {
                                File deleteme;
                                RandomAccessFile rafFile;
                                int i, i2;
 
-                               map.saveMap(new File("backup/shortmap.backup"));
+                               //      map.saveMap(new File("backup/shortmap.backup"));
 
                                deleteme = new File("backup/mobs.backup");
                                deleteme.delete();
@@ -1599,30 +1634,17 @@ public class DuskEngine implements Runnable, DuskProtocol {
        }
 
        @Deprecated
-       DuskObject getDuskObject(int x, int y, String name) {
-               //synchronized (entities) {
-               //      return DuskObject.find(entities[x][y], name);
-               //}
-               for (DuskObject o : map.getEntities(x, y, null)) {
-                       if (o.name.equalsIgnoreCase(name))
-                               return o;
-
-               }
-               return null;
-       }
-
-       // must have objEntities locked
-       @Deprecated
-       private void pushDuskObject(DuskObject o) {
+       private void pushDuskObject(TileMap map, DuskObject o) {
+               o.map = map;
                map.addEntity(o);
        }
 
        @Deprecated
-       private void popDuskObject(DuskObject o) {
+       private void popDuskObject(TileMap map, DuskObject o) {
                map.removeEntity(o);
        }
 
-       public void addDuskObject(DuskObject obj) {
+       public void addDuskObject(TileMap map, DuskObject obj) {
                if (obj.isLivingThing()) {
                        LivingThing lt = (LivingThing) obj;
                        if (!lt.isLoaded) {
@@ -1649,9 +1671,8 @@ public class DuskEngine implements Runnable, DuskProtocol {
                        blnPropListChanged = true;
                }
 
-
-               pushDuskObject(obj);
-               addEntity(obj);
+               pushDuskObject(map, obj);
+               addEntity(map, obj);
        }
 
        /**
@@ -1665,7 +1686,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
         */
        public void mobKilled(Mob obj) {
                notifyRemoved(obj);
-               popDuskObject(obj);
+               popDuskObject(obj.map, obj);
        }
 
        public void removeDuskObject(DuskObject obj) {
@@ -1696,24 +1717,22 @@ public class DuskEngine implements Runnable, DuskProtocol {
                }
 
                notifyRemoved(obj);
-               popDuskObject(obj);
-       }
-
-       public Iterable<TileMap.MapData> visibleMap(int x, int y) {
-               return map.range(x, y, viewrange);
+               popDuskObject(obj.map, obj);
        }
 
        /**
-        * Move a living thing, updating any other living things within range
+        * Move a living thing, updating any other living things within range.
+        *
+        * Only moves wihin the same map
         *
         * @param thing
         * @param inlocx
         * @param inlocy
         * @param dir
         */
-       // FIXME: now i think this probably needs to be moved back to livingthing ...
+       // FIXME: after moving here now i think this probably needs to be moved back to livingthing ...
        public void moveDuskObject(LivingThing thing, int inlocx, int inlocy, byte dir) {
-               for (TileMap.MapData md : map.range(thing.x, thing.y, viewrange)) {
+               for (TileMap.MapData md : thing.map.range(thing.x, thing.y, viewrange)) {
                        for (DuskObject o : md.entities) {
                                if (o.isLivingThing()) {
                                        LivingThing lt = (LivingThing) o;
@@ -1739,10 +1758,10 @@ public class DuskEngine implements Runnable, DuskProtocol {
                        }
                }
                // Move it from cell to cell
-               popDuskObject(thing);
+               popDuskObject(thing.map, thing);
                thing.x = inlocx;
                thing.y = inlocy;
-               pushDuskObject(thing);
+               pushDuskObject(thing.map, thing);
                //addDuskObject(objIn);
        }
 
@@ -1755,6 +1774,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
         * @param name
         * @return
         */
+       // FIXME: move to livingthing?
        public DuskObject findVisibleObject(LivingThing thing, String name) {
                int number = 0;
                int byid = -1;
@@ -1780,7 +1800,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
                }
                //Search surrounding area
 
-               for (TileMap.MapData md : map.range(thing.x, thing.y, viewrange)) {
+               for (TileMap.MapData md : thing.map.range(thing.x, thing.y, viewrange)) {
                        for (DuskObject o : md.entities) {
                                if (byid == o.ID
                                                || (byid == -1 && o.name.equalsIgnoreCase(name))) {
@@ -1800,19 +1820,6 @@ public class DuskEngine implements Runnable, DuskProtocol {
                return null;
        }
 
-       void updateMap(int locx, int locy) {
-               for (TileMap.MapData md : map.range(locx, locy, viewrange)) {
-                       for (DuskObject o : md.entities) {
-                               if (o.isLivingThing()) {
-                                       LivingThing lt = (LivingThing) o;
-                                       if (lt.isPlayer()) {
-                                               lt.updateMap();
-                                       }
-                               }
-                       }
-               }
-       }
-
        public void run() {
                log.printMessage(Log.ALWAYS, "Mob ticks = " + lngMobTicks);
                log.printMessage(Log.ALWAYS, "Player ticks = " + lngPlayerTicks);
@@ -1945,7 +1952,8 @@ public class DuskEngine implements Runnable, DuskProtocol {
                                                                        if (mob.hp > 0) {
                                                                                mob.hp = mob.maxhp;
                                                                                mob.mp = mob.maxmp;
-                                                                               mob.changeLocBypass(mob.originalX, mob.originalY);
+                                                                               // mobx always stay on same map?
+                                                                               mob.changeLocBypass(mob.map, mob.originalX, mob.originalY);
                                                                        }
                                                                }
                                                        }
index b48e814..f8646d9 100644 (file)
@@ -181,7 +181,7 @@ public class Faction {
                Mob mobStore;
                double enemyrelation = 0;
                boolean visiblePlayer = false;
-               for (MapData md : game.map.range(mob.x, mob.y, game.viewrange - 1)) {
+               for (MapData md : mob.map.range(mob.x, mob.y, game.viewrange - 1)) {
                        for (DuskObject o : md.entities) {
                                if (o.isLivingThing()) {
                                        LivingThing lt = (LivingThing) o;
index fe0e5fb..5281e4d 100644 (file)
@@ -265,7 +265,7 @@ public class Script {
                for (int i = 0; i < vctVisibleUpdate.size(); i++) {
                        thnStore = (LivingThing) vctVisibleUpdate.elementAt(i);
                        engGame.removeDuskObject(thnStore);
-                       engGame.addDuskObject(thnStore);
+                       engGame.addDuskObject(thnStore.map, thnStore);
                }
        }
 
@@ -937,6 +937,11 @@ public class Script {
                                rafCompile.writeByte(24);
                                rafCompile.writeBytes(getStringForCompile());
                        }
+                       if (strStore.equalsIgnoreCase("mapxy")) {
+                               rafCompile.writeByte(25);
+                               rafCompile.writeBytes(getStringForCompile());
+                               rafCompile.writeBytes(parseValueForCompile());
+                       }
                        rafCompile.writeBytes(parseValueForCompile());
                        return true;
                } else if (strStore.equalsIgnoreCase("changeTile")) {
@@ -1053,7 +1058,8 @@ public class Script {
                                        return false;
                                }
                                case 5: {
-                                       engGame.playSound((int) parseValue(), (int) parseValue(), (int) parseValue());
+                                       // FIXME: playsound script, who played it?
+                                       //engGame.playSound((int) parseValue(), (int) parseValue(), (int) parseValue());
                                        return true;
                                }
                                case 6: {
@@ -1178,23 +1184,25 @@ public class Script {
                                        return false;
                                }
                                case 29: {
+                                       // These all need a map-name as well
+                                       System.err.println("create mob not implemented");
                                        Mob mobStore = new Mob(getString(), (int) parseValue(), (int) parseValue(), engGame);
-                                       //engGame.vctMobs.add(mobStore);
-                                       engGame.addDuskObject(mobStore);
+                                       //engGame.addDuskObject(mobStore);
                                        return true;
                                }
                                case 30: {
+                                       System.err.println("create mob one use not implemented");
                                        Mob mobStore = new Mob(getString(), (int) parseValue(), (int) parseValue(), engGame);
                                        mobStore.blnOneUse = true;
-                                       //engGame.vctMobs.add(mobStore);
-                                       engGame.addDuskObject(mobStore);
+                                       //engGame.addDuskObject(mobStore);
                                        return true;
                                }
                                case 31: {
+                                       System.err.println("create item not implemented");
                                        Item itmStore = engGame.getItem(getString());
                                        itmStore.x = (int) parseValue();
                                        itmStore.y = (int) parseValue();
-                                       engGame.addDuskObject(itmStore);
+                                       //engGame.addDuskObject(itmStore);
                                        return true;
                                }
                                case 59: {
@@ -1467,15 +1475,15 @@ public class Script {
                                                        return true;
                                                }
                                                case 19: {
-                                                       thnStore.changeLocBypass((int) parseValue() + thnStore.x, thnStore.y);
+                                                       thnStore.changeLocBypass(thnStore.map, (int) parseValue() + thnStore.x, thnStore.y);
                                                        return true;
                                                }
                                                case 20: {
-                                                       thnStore.changeLocBypass(thnStore.x, (int) parseValue() + thnStore.y);
+                                                       thnStore.changeLocBypass(thnStore.map, thnStore.x, (int) parseValue() + thnStore.y);
                                                        return true;
                                                }
                                                case 21: {
-                                                       thnStore.changeLocBypass((int) parseValue() + thnStore.x, (int) parseValue() + thnStore.y);
+                                                       thnStore.changeLocBypass(thnStore.map, (int) parseValue() + thnStore.x, (int) parseValue() + thnStore.y);
                                                        return true;
                                                }
                                                case 22: {
@@ -1648,15 +1656,15 @@ public class Script {
                                                        return true;
                                                }
                                                case 19: {
-                                                       thnStore.changeLocBypass((int) parseValue(), thnStore.y);
+                                                       thnStore.changeLocBypass(thnStore.map, (int) parseValue(), thnStore.y);
                                                        return true;
                                                }
                                                case 20: {
-                                                       thnStore.changeLocBypass(thnStore.x, (int) parseValue());
+                                                       thnStore.changeLocBypass(thnStore.map, thnStore.x, (int) parseValue());
                                                        return true;
                                                }
                                                case 21: {
-                                                       thnStore.changeLocBypass((int) parseValue(), (int) parseValue());
+                                                       thnStore.changeLocBypass(thnStore.map, (int) parseValue(), (int) parseValue());
                                                        return true;
                                                }
                                                case 22: {
@@ -1682,6 +1690,10 @@ public class Script {
                                                        }
                                                        return true;
                                                }
+                                               case 25: {
+                                                       thnStore.changeLocBypass(engGame.maps.get(getString()), (int) parseValue(), (int) parseValue());
+                                                       return true;
+                                               }
                                        }
                                }
                                case 46: {
@@ -1694,8 +1706,9 @@ public class Script {
                                                engGame.log.printMessage(Log.DEBUG, "Script " + strName + " called changeMap with 0 at " + dbgX + "," + dbgY);
                                        }
 //                                     engGame.changeMap((int)parseValue(),(int)parseValue(),(short)parseValue());
-                                       engGame.changeMap(dbgX, dbgY, dbgValue);
-                                       return true;
+                                       // FIXME: 
+                                       throw new UnsupportedOperationException("script changemap not implemented");
+                                       //engGame.changeMap(dbgX, dbgY, dbgValue);
                                }
                                case 47: {
                                        String strOne = getString();
@@ -1732,9 +1745,10 @@ public class Script {
                                        return true;
                                }
                                case 49: {
-                                       LivingThing thnStore = getLivingThing(getString());
-                                       engGame.notifyRemoved(thnStore);
-                                       engGame.addEntity(thnStore);
+                                       // FIXME: do i need ensurevisible?
+                                       //LivingThing thnStore = getLivingThing(getString());
+                                       //engGame.notifyRemoved(thnStore);
+                                       //engGame.addEntity(thnStore);
                                        return true;
                                }
                                case 50: {
index 4c018e6..7a4fa0c 100644 (file)
@@ -57,7 +57,7 @@ public class TickThread implements Runnable {
                                                if (mob.x == -6) {
                                                        mob.hp++;
                                                        if (mob.hp > -1) {
-                                                               mob.changeLocBypass(mob.originalX, mob.originalY);
+                                                               mob.changeLocBypass(mob.map, mob.originalX, mob.originalY);
                                                                mob.hp = mob.maxhp;
                                                        }
                                                } else {
index 92e413f..b4e7736 100644 (file)
@@ -54,6 +54,9 @@ public abstract class DuskObject {
        public String name;             // Name of this object
        public String description = null;       // Description of this object
        boolean isHideName;             // if true: Do not display object's name on the client map.
+       // Current map for object
+       public TileMap map;
+       // current location on map
        public int x, y;
        DuskObject next = null; //Linked List
 
index bb41604..40d4009 100644 (file)
@@ -689,6 +689,9 @@ public class LivingThing extends DuskObject implements Runnable, DuskProtocol {
                        case "description":
                                description = in.readLine();
                                break;
+                       case "map":
+                               map = game.maps.get(in.readLine());
+                               break;
                        case "x":
                                x = Integer.parseInt(in.readLine());
                                break;
@@ -901,6 +904,7 @@ public class LivingThing extends DuskObject implements Runnable, DuskProtocol {
                                } else {
                                        rafPlayerFile.writeBytes("clan\nnone\n");
                                }
+                               rafPlayerFile.writeBytes("map\n" + map.name + "\n");
                                rafPlayerFile.writeBytes("x\n" + String.valueOf(x) + "\n");
                                rafPlayerFile.writeBytes("y\n" + String.valueOf(y) + "\n");
                                if (popup == false) {
@@ -1413,17 +1417,17 @@ public class LivingThing extends DuskObject implements Runnable, DuskProtocol {
                        };
                        int mflags = goon ? 0 : TileMap.SKIP_END;
 
-                       for (MoveData md : game.map.move(x, y, destX, destY, mflags, ml)) {
+                       for (MoveData md : map.move(x, y, destX, destY, mflags, ml)) {
                                moveQueue.add(md.direction);
                        }
                }
                return null;
        }
 
-       // FIXME: should probably be in DuskEngine
+       // This implemented path seeking, and moving within the same map
        protected synchronized void moveTo(int newLocX, int newLocY, byte dir, int intNewStep) {
-               if (privs < 5 && (newLocX >= (game.map.getCols() - 1)
-                               || newLocY >= (game.map.getRows() - 1)
+               if (privs < 5 && (newLocX >= (map.getCols())
+                               || newLocY >= (map.getRows())
                                || newLocX < 0
                                || newLocY < 0)) {
                        return;
@@ -1444,24 +1448,23 @@ public class LivingThing extends DuskObject implements Runnable, DuskProtocol {
                } else {
                        return;
                }
+               boolean wasMerchant = overMerchant() != null || overPlayerMerchant() != null;
                int oldLocX = x;
                int oldLocY = y;
+               TileMap oldMap = map;
                // Move it from cell to cell
                game.moveDuskObject(this, newLocX, newLocY, dir);
                try {
                        imagestep = intNewStep;
                        if (isPlayer()) {
-                               if (game.overMerchant(oldLocX, oldLocY) != null) {
-                                       offMerchant();
-                               }
-                               if (game.overPlayerMerchant(oldLocX, oldLocY) != null) {
+                               if (wasMerchant) {
                                        offMerchant();
                                }
                                updateMap();
                        }
                        Script scrStore;
                        try {
-                               scrStore = (Script) game.tileAction.get((int) game.map.getTile(x, y));
+                               scrStore = (Script) game.tileAction.get((int) map.getTile(x, y));
                                synchronized (scrStore) {
                                        scrStore.varVariables.clearVariables();
                                        scrStore.varVariables.addVariable("trigger", this);
@@ -1485,7 +1488,8 @@ public class LivingThing extends DuskObject implements Runnable, DuskProtocol {
                                                        following.following.master = null;
                                                        following.following = null;
                                                }
-                                               following.changeLocBypass(oldLocX, oldLocY);
+                                               // FIXME: verify this is correct: moveTo can't change the map anyway
+                                               following.changeLocBypass(oldMap, oldLocX, oldLocY);
                                        } else {
                                                chatMessage(following.name + " is no longer following you.");
                                                following.chatMessage("You are no longer following " + name + ".");
@@ -1591,7 +1595,7 @@ public class LivingThing extends DuskObject implements Runnable, DuskProtocol {
                        } else {
                                // This is a new one
                                //nearEntities.put(o.ID, o);
-                               game.addEntity(o);
+                               game.addEntity(map, o);
                        }
                }
                // anything left over must be removed
@@ -1600,40 +1604,43 @@ public class LivingThing extends DuskObject implements Runnable, DuskProtocol {
                }
        }
 
-       public void changeLoc(int newLocX, int newLocY) {
-               if (privs > 1 || (battle == null && !isSleeping && game.canMoveTo(newLocX, newLocY, this))) {
-                       if (isMob()) {
-                               if (!(Math.abs(originalX - newLocX) < game.viewrange && Math.abs(originalY - newLocY) < game.viewrange)) {
-                                       return;
-                               }
-                       }
-                       changeLocBypass(newLocX, newLocY);
-               }
-       }
-
-       synchronized public void changeLocBypass(int newLocX, int newLocY) {
+       /*
+        * unused
+        public void changeLoc(int newLocX, int newLocY) {
+        if (privs > 1 || (battle == null && !isSleeping && game.canMoveTo(newLocX, newLocY, this))) {
+        if (isMob()) {
+        if (!(Math.abs(originalX - newLocX) < game.viewrange && Math.abs(originalY - newLocY) < game.viewrange)) {
+        return;
+        }
+        }
+        changeLocBypass(newLocX, newLocY);
+        }
+        }*/
+       // FIXME: supply map too
+       synchronized public void changeLocBypass(TileMap map, int newLocX, int newLocY) {
                int oldLocX = x;
                int oldLocY = y;
+               boolean wasMerchant = overMerchant() != null || overPlayerMerchant() != null;
                game.removeDuskObject(this);
                x = newLocX;
                y = newLocY;
                try {
+                       // Really move + map should be atomic to client.
+                       
+                       //update entity:
+                       if (isWorking) {
+                               game.addDuskObject(map, this);
+                       }
+                       // Moved after addDuskObject so the map is set on 'this'
                        if (isPlayer()) {
                                updateMap();
-                               if (game.overMerchant(oldLocX, oldLocY) != null) {
-                                       offMerchant();
-                               }
-                               if (game.overPlayerMerchant(oldLocX, oldLocY) != null) {
+                               if (wasMerchant) {
                                        offMerchant();
                                }
                        }
-                       //update entity:
-                       if (isWorking) {
-                               game.addDuskObject(this);
-                       }
                        Script scrStore;
                        try {
-                               scrStore = (Script) game.tileAction.get((int) game.map.getTile(newLocX, newLocY));
+                               scrStore = (Script) game.tileAction.get((int) map.getTile(newLocX, newLocY));
                                synchronized (scrStore) {
                                        scrStore.varVariables.clearVariables();
                                        scrStore.varVariables.addVariable("trigger", this);
@@ -1643,7 +1650,7 @@ public class LivingThing extends DuskObject implements Runnable, DuskProtocol {
                        }
                        Script.exec("defMoveActions/" + newLocX + "_" + newLocY, game, this);
                        if (following != null) {
-                               following.changeLocBypass(oldLocX, oldLocY);
+                               following.changeLocBypass(map, oldLocX, oldLocY);
                        }
                        if (isPlayer()) {
                                game.refreshEntities(this);
@@ -1676,30 +1683,32 @@ public class LivingThing extends DuskObject implements Runnable, DuskProtocol {
 
                int r = game.viewrange;
 
+               System.out.printf("update map %d,%d map %s\n", x, y, map.name);
+
                int width = r * 2 + 1;
                int height = r * 2 + 1;
                short[] tiles = null;
                int i = 0;
-               int nlayers = game.map.getLayerCount();
+               int nlayers = map.getLayerCount();
                int nused = 0;
                short[][] layers = new short[nlayers][];
                int groundLayer = 0;
-               for (int l=0;l<nlayers;l++) {
+               for (int l = 0; l < nlayers; l++) {
                        if (tiles == null)
-                               tiles = new short[width*height];
-                       
-                       short[] visible = game.map.getRegion(l, x-r, y-r, width, height, tiles);
-                       
+                               tiles = new short[width * height];
+
+                       short[] visible = map.getRegion(l, x - r, y - r, width, height, tiles);
+
                        if (visible != null) {
                                tiles = null;
-                               
-                               if (l == game.map.getGroundLayer())
+
+                               if (l == map.getGroundLayer())
                                        groundLayer = nused;
-                               
+
                                layers[nused++] = visible;
                        }
                }
-               
+
                send(new MapMessage(MSG_UPDATE_MAP, width, height, x, y, groundLayer, nused, layers));
        }
 
@@ -2062,6 +2071,25 @@ public class LivingThing extends DuskObject implements Runnable, DuskProtocol {
                }
        }
 
+       public Merchant overMerchant() {
+               // or move to map?
+               for (DuskObject o : map.getEntities(x, y, null)) {
+                       if (o.isMerchant()) {
+                               return (Merchant) o;
+                       }
+               }
+               return null;
+       }
+
+       public PlayerMerchant overPlayerMerchant() {
+               for (DuskObject o : map.getEntities(x, y, null)) {
+                       if (o.isPlayerMerchant()) {
+                               return (PlayerMerchant) o;
+                       }
+               }
+               return null;
+       }
+
        public boolean isWearing(String name) {
                return wornItems.isWearing(name);
        }
@@ -2349,7 +2377,7 @@ public class LivingThing extends DuskObject implements Runnable, DuskProtocol {
                connectionThread.setName("LivingThing(" + name + ")");
                sendThread.setName("LivingThing(" + name + ").send");
                initMap();
-               changeLocBypass(x, y);
+               changeLocBypass(map, x, y);
                updateInfo();
                updateStats();
                updateItems();
@@ -2497,7 +2525,7 @@ public class LivingThing extends DuskObject implements Runnable, DuskProtocol {
                isLoaded = true;
                if (following != null) {
                        following.isLoaded = true;
-                       following.changeLocBypass(x, y);
+                       following.changeLocBypass(map, x, y);
                }
 
                if (create) {
index b053714..52297a4 100644 (file)
@@ -179,12 +179,17 @@ public class Mob extends LivingThing {
                        case "description":
                                description = in.readLine();
                                break;
+                               // Mobs are assigned locations separately
+                               /*
+                       case "map":
+                               map = game.maps.get(in.readLine());
+                               break;
                        case "x":
                                x = Integer.parseInt(in.readLine());
                                break;
                        case "y":
                                y = Integer.parseInt(in.readLine());
-                               break;
+                               break;*/
                        case "maxhp":
                                maxhp = Integer.parseInt(in.readLine());
                                break;
index d53db82..3bf654a 100644 (file)
@@ -41,6 +41,13 @@ import java.util.PriorityQueue;
  */
 public class TileMap implements Iterable<TileMap.MapData> {
 
+       /**
+        * Name of map for referencing
+        */
+       public final String name;
+       /**
+        * Size
+        */
        private int rows, cols;
        /**
         * Tile map
@@ -77,7 +84,8 @@ public class TileMap implements Iterable<TileMap.MapData> {
         * @param cols
         * @param rows
         */
-       public TileMap(int cols, int rows) {
+       public TileMap(String name, int cols, int rows) {
+               this.name = name;
                this.rows = rows;
                this.cols = cols;
 
@@ -197,7 +205,12 @@ public class TileMap implements Iterable<TileMap.MapData> {
                                throw new IOException("Invalid format/magic/unknown version");
                        }
 
-                       map = new TileMap(cols, rows);
+                       System.out.println("Load map: " + path);
+                       System.out.printf(" size: %dx%d\n", cols, rows);
+                       System.out.printf(" groundLayer: %d\n", groundLayer);
+                       System.out.printf(" layerCount: %d\n", layerCount);
+                       
+                       map = new TileMap(path.getName(), cols, rows);
 
                        map.groundLayer = groundLayer;
                        map.layers = new TileLayer[layerCount];
@@ -208,6 +221,7 @@ public class TileMap implements Iterable<TileMap.MapData> {
                                int theight = mapFile.readInt();
                                TileLayer tl;
 
+                               System.out.printf("  layer %2d: at %3d,%3d size %3dx%3d\n", l, tx, ty, twidth, theight);
                                if (l == groundLayer)
                                        tl = new TileLayer(tx, ty, twidth, theight, map.tiles);
                                else
@@ -230,7 +244,7 @@ public class TileMap implements Iterable<TileMap.MapData> {
                try (DataInputStream mapFile = new DataInputStream(new FileInputStream(path))) {
                        int cols = mapFile.readInt();
                        int rows = mapFile.readInt();
-                       map = new TileMap(cols, rows);
+                       map = new TileMap(path.getName(), cols, rows);
                        for (int y = 0; y < rows; y++) {
                                for (int x = 0; x < cols; x++) {
                                        map.setTile(x, y, mapFile.readShort());
@@ -249,7 +263,7 @@ public class TileMap implements Iterable<TileMap.MapData> {
                try (RandomAccessFile mapFile = new RandomAccessFile(path, "r")) {
                        int cols = mapFile.readInt();
                        int rows = mapFile.readInt();
-                       map = new TileMap(cols, rows);
+                       map = new TileMap(path.getName(), cols, rows);
                        for (int x = 0; x < cols; x++) {
                                for (int y = 0; y < rows; y++) {
                                        if (format == FORMAT_BYTE)
@@ -892,7 +906,7 @@ public class TileMap implements Iterable<TileMap.MapData> {
        }
 
        public static void main(String[] args) {
-               TileMap map = new TileMap(16, 16);
+               TileMap map = new TileMap("test", 16, 16);
 
                /*
                 for (MapData md : map.look(5, 5, 10, 3)) {