From ca31d12083abc9046b04d04e5b16adc5a4d327cc Mon Sep 17 00:00:00 2001
From: Not Zed <notzed@gmail.com>
Date: Sun, 19 Mar 2023 17:25:59 +1030
Subject: [PATCH] Various fixes to the old server to be able to get zabin's
 puzzle to run (partially).

---
 Makefile                                      |   8 +-
 .../classes/duskz/client/Dusk.java            |   8 +-
 .../classes/duskz/client/Status.java          |   2 +
 .../classes/duskz/server/DuskEngine.java      | 447 ++++++++++--------
 .../classes/duskz/server/Faction.java         |  47 +-
 .../classes/duskz/server/Script.java          |  31 +-
 .../classes/duskz/server/entity/Item.java     |  64 ++-
 .../duskz/server/entity/LivingThing.java      |  12 +-
 .../classes/duskz/server/entity/Merchant.java |   9 +-
 .../classes/duskz/server/entity/Mob.java      |  40 +-
 .../duskz/server/entity/PlayerMerchant.java   |   3 +-
 .../classes/duskz/server/entity/Prop.java     |   4 +-
 .../classes/duskz/server/entity/Sign.java     |   3 +-
 13 files changed, 396 insertions(+), 282 deletions(-)

diff --git a/Makefile b/Makefile
index 4e6e82a..5e68f2b 100644
--- a/Makefile
+++ b/Makefile
@@ -17,6 +17,7 @@ duskz.server_JDEPMOD = duskz.common
 duskz.editor_JDEPMOD = duskz.common duskz.client
 duskz.viewer_JDEPMOD = duskz.common duskz.client
 
+# auto-generate the <module>_COMMANDS variables
 define install-bin=
 $1_COMMANDS = $(notdir $(wildcard src/$1/$(TARGET)/bin/*))
 bin/$1/$(TARGET)/bin/%: src/$1/$(TARGET)/bin/%
@@ -48,10 +49,13 @@ maven_central_JARS = $(xmlbind) $(rhino)
 
 include maven.make
 
+oldgame=game-2.7.3
+oldgame=../../ext/DuskRPG/DuskFiles/Dusk2.7.3
+
 run-server-old: duskz.server
-	cd game-2.7.3 && \
+	cd $(oldgame) && \
 	$(JAVA) \
-		--module-path ../.lib:../bin/$(TARGET)/lib \
+		--module-path $(realpath .lib):$(realpath bin/$(TARGET)/lib) \
 		-m duskz.server/duskz.server.DuskServer
 
 run-server: duskz.server
diff --git a/src/duskz.client/classes/duskz/client/Dusk.java b/src/duskz.client/classes/duskz/client/Dusk.java
index 3f0c303..39ff284 100644
--- a/src/duskz.client/classes/duskz/client/Dusk.java
+++ b/src/duskz.client/classes/duskz/client/Dusk.java
@@ -222,8 +222,8 @@ public class Dusk implements Runnable, DuskProtocol {
 				DuskMessage dm = DuskMessage.receiveMessage(instream);
 
 				// debug
-				System.out.print(state + ": ");
-				dm.format(System.out);
+				//System.out.print(state + ": ");
+				//dm.format(System.out);
 
 				switch (dm.name) {
 					case MSG_AUTH: {
@@ -679,8 +679,8 @@ public class Dusk implements Runnable, DuskProtocol {
 	}
 
 	private void send(DuskMessage lm) throws IOException {
-		System.out.print("sending: ");
-		lm.format(System.out);
+		//System.out.print("sending: ");
+		//lm.format(System.out);
 		lm.sendMessage(outstream);
 	}
 
diff --git a/src/duskz.client/classes/duskz/client/Status.java b/src/duskz.client/classes/duskz/client/Status.java
index c87b162..cdb59f9 100644
--- a/src/duskz.client/classes/duskz/client/Status.java
+++ b/src/duskz.client/classes/duskz/client/Status.java
@@ -94,6 +94,8 @@ public class Status implements DuskProtocol {
 	public boolean canAttack(Entity e) {
 		// Ugh, i'm not sure what the types were, but i think it just meant 'any living thing'.
 		// Dunno why the server doesn't send this message to the client anyway
+		System.out.printf("can attack test %s type %s distance %d range %d\n",
+			e.name, e.intType, distance(e), range);
 		return e.ID != id
 //				&& ((e.intType == 0 || e.intType == 1 || e.intType == 4)
 				&& ((e.intType == 0 || e.intType == 1 || e.intType == 2)
diff --git a/src/duskz.server/classes/duskz/server/DuskEngine.java b/src/duskz.server/classes/duskz/server/DuskEngine.java
index 561690d..17eff4d 100644
--- a/src/duskz.server/classes/duskz/server/DuskEngine.java
+++ b/src/duskz.server/classes/duskz/server/DuskEngine.java
@@ -44,6 +44,8 @@ import java.io.*;
 import java.io.PrintStream;
 import java.io.FileOutputStream;
 import java.net.Socket;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.StringTokenizer;
 import java.util.Date;
@@ -52,6 +54,7 @@ import java.util.HashSet;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map.Entry;
+import java.util.Optional;
 import java.util.Properties;
 
 /**
@@ -65,51 +68,51 @@ public class DuskEngine implements Runnable, DuskProtocol {
 	public Log log;
 	//Prefs:
 	public int port = 7400,
-			trackerport = 7401,
-			maxconnections = 0,
-			petcost = 100,
-			merchantimage,
-			signimage,
-			battlesound = -1,
-			mobrespawnspeed,
-			viewrange = 5,
-			oldviewrange = 0,
-			mapsize = 11,
-			titlecap = 0,
-			noChannelMax = 600, // defalut 600=10 minutes
-			namecap = 20, //default 20
-			messagecap = 120, //default 120
-			changeRaceCpLimit = 100, //default 100cp
-			logLevel = Log.ERROR,
-			traincost = 100,
-			expgainmod = 10;
+		trackerport = 7401,
+		maxconnections = 0,
+		petcost = 100,
+		merchantimage,
+		signimage,
+		battlesound = -1,
+		mobrespawnspeed,
+		viewrange = 5,
+		oldviewrange = 0,
+		mapsize = 11,
+		titlecap = 0,
+		noChannelMax = 600, // defalut 600=10 minutes
+		namecap = 20, //default 20
+		messagecap = 120, //default 120
+		changeRaceCpLimit = 100, //default 100cp
+		logLevel = Log.ERROR,
+		traincost = 100,
+		expgainmod = 10;
 	double gplosemod = 1D / 16D, //default 1/16
-			explosemod = 1D / 16D,
-			gpfleemod = 1D / 64D, //default 1/64
-			expfleemod = 1D / 64D;
+		explosemod = 1D / 16D,
+		gpfleemod = 1D / 64D, //default 1/64
+		expfleemod = 1D / 64D;
 	public long lngMobTicks = 1000, //default 1000 milliseconds(1 second) per tick
-			lngPlayerTicks = 250, //default 250 milliseconds(1/4 second) per tick
-			floodLimit = 1000;	//default 1000 milliseconds(1 second) btw messages
+		lngPlayerTicks = 250, //default 250 milliseconds(1/4 second) per tick
+		floodLimit = 1000;	//default 1000 milliseconds(1 second) btw messages
 	public String trackername = "Just Some World.",
-			site = "none",
-			strRCAddress,
-			strRCName,
-			strLogFile = null,
-			strMusicAddress;
+		site = "none",
+		strRCAddress,
+		strRCName,
+		strLogFile = null,
+		strMusicAddress;
 	public boolean blnMusic = false,
-			blnLineOfSight = false,
-			blnAI = false,
-			blnIPF = false,
-			tracker = true,
-			blnSavingGame = false,
-			blnShuttingDown = false;
+		blnLineOfSight = false,
+		blnAI = false,
+		blnIPF = false,
+		tracker = true,
+		blnSavingGame = false,
+		blnShuttingDown = false;
 	// FIXME: Not public
 	public Script scrCanSeeLivingThing = null,
-			scrCanMoveThroughLivingThing = null,
-			scrCanAttack = null,
-			scrOnStart = null,
-			scrOnDeath = null,
-			scrOnLogOut = null;
+		scrCanMoveThroughLivingThing = null,
+		scrCanAttack = null,
+		scrOnStart = null,
+		scrOnDeath = null,
+		scrOnLogOut = null;
 	//End Prefs
 	public final static String version = "3.0 dev";
 	public final Date datStart = new Date(System.currentTimeMillis());
@@ -156,11 +159,11 @@ public class DuskEngine implements Runnable, DuskProtocol {
 	final private HashMap<String, Integer> failureAddress = new HashMap<>();
 	private long nextid = 0;
 	boolean blnVariableListChanged = false,
-			blnMapHasChanged = false,
-			blnMobListChanged = false,
-			blnSignListChanged = false,
-			blnMerchantListChanged = false,
-			blnPropListChanged = false;
+		blnMapHasChanged = false,
+		blnMobListChanged = false,
+		blnSignListChanged = false,
+		blnMerchantListChanged = false,
+		blnPropListChanged = false;
 
 	public DuskEngine() {
 		RandomAccessFile rafFile = null;
@@ -169,7 +172,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 
 		try {
 			int x = 0,
-					y = 0;
+				y = 0;
 			String line;
 
 			loadPrefs();
@@ -177,7 +180,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 			// Load Map
 			File newmap = new File("defMaps");
 			if (newmap.exists()) {
-				for (File mapfile : newmap.listFiles()) {
+				for (File mapfile: newmap.listFiles()) {
 					TileMap map;
 					log.printMessage(Log.INFO, "Loading Layered Maps...");
 					map = TileMap.loadLayered(mapfile);
@@ -249,29 +252,52 @@ 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
+			// FIXME: better version handling
+			int fmt = 0;
 			try {
 				rafFile = new RandomAccessFile("merchants", "r");
 				Merchant mrcStore;
 				log.printMessage(Log.INFO, "Loading Merchants...");
 				line = rafFile.readLine();
 				while (!(line == null || line.equals(""))) {
+					log.printMessage(Log.VERBOSE, "merchant: " + fmt + " " + line);
+					String mapname;
+					int locx, locy;
+					if (fmt == 0) {
+						mapname = line;
+						if (maps.containsKey(mapname)) {
+							locx = Integer.parseInt(rafFile.readLine());
+							fmt = 2;
+						} else {
+							locx = Integer.parseInt(mapname);
+							mapname = "main";
+							fmt = 1;
+						}
+						locy = Integer.parseInt(rafFile.readLine());
+					} else if (fmt == 1) {
+						mapname = "main";
+						locx = Integer.parseInt(line);
+						locy = Integer.parseInt(rafFile.readLine());
+					} else {
+						mapname = line;
+						locx = Integer.parseInt(rafFile.readLine());
+						locy = Integer.parseInt(rafFile.readLine());
+					}
 					mrcStore = new Merchant(this);
-					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 + ")");
+					mrcStore.map = maps.get(mapname);
+					mrcStore.x = locx;
+					mrcStore.y = locy;
+					log.printMessage(Log.VERBOSE, "Merchant(" + mapname + "@" + mrcStore.x + "," + mrcStore.y + ")");
 					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)) {
+					if (!mrcStore.map.inside(mrcStore.x, mrcStore.y)) {
 						log.printMessage(Log.VERBOSE, "Previous merchant is off of the map, ignoring");
 						blnMerchantListChanged = true;
 					} else {
@@ -299,18 +325,18 @@ public class DuskEngine implements Runnable, DuskProtocol {
 				// map
 				// x
 				// y
-				if (line.equals("mob")) {
+				if (line.equals("mob") || line.equals("mob2.3")) {
 					try {
 						String mobtype = rafFile.readLine();
-						String mapname = rafFile.readLine();
+						String mapname = line.equals("mob") ? rafFile.readLine() : "main";
 						int locx = Integer.parseInt(rafFile.readLine());
 						int locy = Integer.parseInt(rafFile.readLine());
 						TileMap map = maps.get(mapname);
 
 						thnStore = new Mob(mobtype,
-								locx,
-								locy,
-								this);
+							locx,
+							locy,
+							this);
 
 						if (!map.inside(thnStore.x, thnStore.y)) {
 							log.printMessage(Log.VERBOSE, "Previous mob is off of the map, ignoring");
@@ -330,13 +356,29 @@ public class DuskEngine implements Runnable, DuskProtocol {
 
 			// Load signs
 			Sign sgnStore;
+			fmt = 0;
 			rafFile = new RandomAccessFile("signs", "r");
 			log.printMessage(Log.INFO, "Loading Signs...");
 			line = rafFile.readLine();
 			while (!(line == null || line.equals(""))) {
-				String mapname = rafFile.readLine();
-				int locx = Integer.parseInt(rafFile.readLine());
-				int locy = Integer.parseInt(rafFile.readLine());
+				String mapname;
+				int locx, locy;
+				if (fmt == 0) {
+					mapname = rafFile.readLine();
+					if (maps.containsKey(mapname)) {
+						locx = Integer.parseInt(rafFile.readLine());
+						fmt = 2;
+					} else {
+						locx = Integer.parseInt(mapname);
+						mapname = "main";
+						fmt = 1;
+					}
+					locy = Integer.parseInt(rafFile.readLine());
+				} else {
+					mapname = fmt == 1 ? "main" : rafFile.readLine();
+					locx = Integer.parseInt(rafFile.readLine());
+					locy = Integer.parseInt(rafFile.readLine());
+				}
 				TileMap map = maps.get(mapname);
 				log.printMessage(Log.VERBOSE, line);
 				sgnStore = new Sign(this, "sign", line, locx, locy, getID());
@@ -355,10 +397,26 @@ public class DuskEngine implements Runnable, DuskProtocol {
 			rafFile = new RandomAccessFile("props", "r");
 			log.printMessage(Log.INFO, "Loading Props...");
 			line = rafFile.readLine();
+			fmt = 0;
 			while (!(line == null || line.equals(""))) {
-				String mapname = rafFile.readLine();
-				int locx = Integer.parseInt(rafFile.readLine());
-				int locy = Integer.parseInt(rafFile.readLine());
+				String mapname;
+				int locx, locy;
+				if (fmt == 0) {
+					mapname = rafFile.readLine();
+					if (maps.containsKey(mapname)) {
+						locx = Integer.parseInt(rafFile.readLine());
+						fmt = 2;
+					} else {
+						locx = Integer.parseInt(mapname);
+						mapname = "main";
+						fmt = 1;
+					}
+					locy = Integer.parseInt(rafFile.readLine());
+				} else {
+					mapname = fmt == 1 ? "main" : rafFile.readLine();
+					locx = Integer.parseInt(rafFile.readLine());
+					locy = Integer.parseInt(rafFile.readLine());
+				}
 				TileMap map = maps.get(mapname);
 
 				log.printMessage(Log.VERBOSE, line);
@@ -388,18 +446,18 @@ public class DuskEngine implements Runnable, DuskProtocol {
 			while (!(strVarName == null || strVarName.equals(""))) {
 				intType = Integer.parseInt(rafFile.readLine());
 				switch (intType) {
-					case 0: {
-						dblObject = (double) Double.parseDouble(rafFile.readLine());
-						varVariables.addVariable(strVarName, dblObject);
-						log.printMessage(Log.VERBOSE, strVarName + " = " + dblObject);
-						break;
-					}
-					case 1: {
-						strObject = rafFile.readLine();
-						varVariables.addVariable(strVarName, strObject);
-						log.printMessage(Log.VERBOSE, strVarName + " = '" + strObject + "'");
-						break;
-					}
+				case 0: {
+					dblObject = (double)Double.parseDouble(rafFile.readLine());
+					varVariables.addVariable(strVarName, dblObject);
+					log.printMessage(Log.VERBOSE, strVarName + " = " + dblObject);
+					break;
+				}
+				case 1: {
+					strObject = rafFile.readLine();
+					varVariables.addVariable(strVarName, strObject);
+					log.printMessage(Log.VERBOSE, strVarName + " = '" + strObject + "'");
+					break;
+				}
 				}
 				strVarName = rafFile.readLine();
 			}
@@ -449,9 +507,9 @@ public class DuskEngine implements Runnable, DuskProtocol {
 			return false;
 		}
 		if (strName.equals("")
-				|| strName.length() > namecap
-				|| strName.toLowerCase().equals("god")
-				|| strName.toLowerCase().equals("default")) {
+			|| strName.length() > namecap
+			|| strName.toLowerCase().equals("god")
+			|| strName.toLowerCase().equals("default")) {
 			return false;
 		}
 
@@ -548,7 +606,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 		if (viewrange != oldviewrange) {
 			oldviewrange = viewrange;
 			mapsize = 1 + (2 * viewrange);
-			for (LivingThing thnStore : playersByName.values()) {
+			for (LivingThing thnStore: playersByName.values()) {
 				thnStore.initMap();
 			}
 		}
@@ -556,7 +614,6 @@ public class DuskEngine implements Runnable, DuskProtocol {
 
 		// FIXME: all this 'synchronized' stuff is busted to shit, you can't lock on something
 		// that might be null or will be replaced by a new object.
-
 		try {
 			if (scrCanSeeLivingThing != null) {
 				synchronized (scrCanSeeLivingThing) {
@@ -638,9 +695,9 @@ public class DuskEngine implements Runnable, DuskProtocol {
 				try (FileInputStream fis = new FileInputStream(f)) {
 					props.load(fis);
 
-					for (Entry e : props.entrySet()) {
-						String key = (String) e.getKey();
-						String val = (String) e.getValue();
+					for (Entry e: props.entrySet()) {
+						String key = (String)e.getKey();
+						String val = (String)e.getValue();
 
 						HashMap<Integer, Script> target = null;
 						String path = null;
@@ -679,7 +736,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 	void loadTileScripts(HashMap<Integer, Script> scripts, String path) {
 		try {
 			int i;
-			for (Script s : scripts.values()) {
+			for (Script s: scripts.values()) {
 				s.close();
 			}
 			scripts.clear();
@@ -706,7 +763,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 	public void chatMessage(String msg, String from) {
 		from = from.toLowerCase();
 		log.printMessage(Log.ALWAYS, msg);
-		for (LivingThing lt : playersByName.values()) {
+		for (LivingThing lt: playersByName.values()) {
 			if (!lt.ignoreList.contains(from)) {
 				lt.chatMessage(msg);
 			}
@@ -729,12 +786,12 @@ public class DuskEngine implements Runnable, DuskProtocol {
 		LivingThing thnStore;
 		log.printMessage(Log.ALWAYS, inMessage);
 
-		for (TileMap.MapData md : map.range(locx, locy, viewrange)) {
-			for (DuskObject o : md.entities) {
+		for (TileMap.MapData md: map.range(locx, locy, viewrange)) {
+			for (DuskObject o: md.entities) {
 				if (o.isLivingThing()) {
-					thnStore = (LivingThing) o;
+					thnStore = (LivingThing)o;
 					if (thnStore.isPlayer()
-							&& !thnStore.ignoreList.contains(strFrom)) {
+						&& !thnStore.ignoreList.contains(strFrom)) {
 						thnStore.chatMessage(inMessage);
 					}
 				}
@@ -746,9 +803,9 @@ public class DuskEngine implements Runnable, DuskProtocol {
 	public void chatMessage(String msg, String clan, String from) {
 		from = from.toLowerCase();
 		log.printMessage(Log.ALWAYS, msg);
-		for (LivingThing lt : playersByName.values()) {
+		for (LivingThing lt: playersByName.values()) {
 			if (lt.clan.equals(clan)
-					&& !lt.ignoreList.contains(from)) {
+				&& !lt.ignoreList.contains(from)) {
 				lt.chatMessage(msg);
 			}
 		}
@@ -760,10 +817,10 @@ public class DuskEngine implements Runnable, DuskProtocol {
 	public void refreshEntities(LivingThing refresh) {
 		LinkedList<DuskObject> newEntities = new LinkedList<>();
 
-		for (TileMap.MapData md : refresh.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) {
+				&& canSeeTo(refresh, md.x, md.y)) {
+				for (DuskObject o: md.entities) {
 					newEntities.add(o);
 					//old = thnRefresh.removeEntity(objStore.ID);
 					//for (i4 = 0; i4 < thnRefresh.nearEntities.size(); i4++) {
@@ -775,13 +832,13 @@ public class DuskEngine implements Runnable, DuskProtocol {
 					//	}
 					//}
 					if (o.isPlayerMerchant()) {
-						PlayerMerchant shop = (PlayerMerchant) o;
+						PlayerMerchant shop = (PlayerMerchant)o;
 						if (refresh.x == shop.x && refresh.y == shop.y) {
 							TransactionMessage tm = new TransactionMessage(MSG_UPDATE_MERCHANT);
 
-							for (String name : shop.vctItems.keySet()) {
+							for (String name: shop.vctItems.keySet()) {
 								LinkedList<Item> vctStore = shop.vctItems.get(name);
-								Item item = (Item) vctStore.element();
+								Item item = (Item)vctStore.element();
 								int intCost = (item.intCost * 3) / 4;
 
 								if (refresh.name.equalsIgnoreCase(shop.strOwner)) {
@@ -794,10 +851,10 @@ public class DuskEngine implements Runnable, DuskProtocol {
 						}
 					}
 					if (o.isMerchant()) {
-						Merchant merchant = (Merchant) o;
+						Merchant merchant = (Merchant)o;
 						if (refresh.x == merchant.x && refresh.y == merchant.y) {
 							HashMap<String, TransactionItem> items = new HashMap<>();
-							for (String itemname : merchant.items) {
+							for (String itemname: merchant.items) {
 								TransactionItem titem = items.get(itemname);
 								if (titem == null) {
 									Item item = getItem(itemname);
@@ -849,16 +906,16 @@ public class DuskEngine implements Runnable, DuskProtocol {
 	// FIXME: move to map or livingthing?
 	@Deprecated
 	public void addEntity(TileMap map, DuskObject add) {
-		for (TileMap.MapData md : map.range(add.x, add.y, viewrange)) {
-			for (DuskObject o : md.entities) {
+		for (TileMap.MapData md: map.range(add.x, add.y, viewrange)) {
+			for (DuskObject o: md.entities) {
 				if (o.isLivingThing()) {
-					LivingThing lt = (LivingThing) o;
+					LivingThing lt = (LivingThing)o;
 					if (lt.isPlayer()) {
 						// FIXME: see if this can be merged with updateEntity() above
 
 						if (canSeeTo(lt, add.x, add.y)) {
 							if ((!add.isLivingThing()
-									|| canSeeLivingThing(lt, (LivingThing) add))) {
+								|| canSeeLivingThing(lt, (LivingThing)add))) {
 								lt.addEntity(add);
 							}
 						}
@@ -870,11 +927,11 @@ public class DuskEngine implements Runnable, DuskProtocol {
 
 	public void cleanup() {
 		log.printMessage(Log.INFO, "Starting cleanup.");
-		for (TileMap map : maps.values()) {
-			for (TileMap.MapData md : map) {
-				for (DuskObject o : md.entities) {
+		for (TileMap map: maps.values()) {
+			for (TileMap.MapData md: map) {
+				for (DuskObject o: md.entities) {
 					if (o.isLivingThing()) {
-						LivingThing lt = (LivingThing) o;
+						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.");
@@ -899,10 +956,10 @@ public class DuskEngine implements Runnable, DuskProtocol {
 	// FIXME: Move to map?
 	@Deprecated
 	void notifyRemoved(DuskObject remove) {
-		for (TileMap.MapData md : remove.map.range(remove.x, remove.y, viewrange)) {
-			for (DuskObject o : md.entities) {
+		for (TileMap.MapData md: remove.map.range(remove.x, remove.y, viewrange)) {
+			for (DuskObject o: md.entities) {
 				if (o.isLivingThing()) {
-					LivingThing lt = (LivingThing) o;
+					LivingThing lt = (LivingThing)o;
 
 					if (lt.isPlayer()) {
 						if (canSeeTo(lt, remove.x, remove.y)) {
@@ -1041,7 +1098,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 		int i;
 		Sign sgnStore;
 		for (i = 0; i < signList.size(); i++) {
-			sgnStore = (Sign) signList.get(i);
+			sgnStore = (Sign)signList.get(i);
 			if (inName.equals(sgnStore.name)) {
 				return sgnStore;
 			}
@@ -1051,7 +1108,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 
 	public LivingThing getPet(String name) {
 		// FIXME: hash map?
-		for (LivingThing pet : petList) {
+		for (LivingThing pet: petList) {
 			if (name.equalsIgnoreCase(pet.name)) {
 				return pet;
 			}
@@ -1067,11 +1124,11 @@ public class DuskEngine implements Runnable, DuskProtocol {
 
 	public Faction getFaction(String name) {
 		Faction faction;
-
-		faction = factionMap.get(name);
+		String key = name.toLowerCase();
+		faction = factionMap.get(key);
 		if (faction == null) {
 			faction = new Faction(name, this);
-			factionMap.put(name, faction);
+			factionMap.put(key, faction);
 		}
 		return faction;
 	}
@@ -1079,7 +1136,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 	public LivingThing getMobFromVct(String inName) {
 		// FIXME: hash map?
 		synchronized (mobList) {
-			for (Mob mob : mobList) {
+			for (Mob mob: mobList) {
 				if (mob.name.equals(inName)) {
 					return mob;
 				}
@@ -1092,18 +1149,24 @@ public class DuskEngine implements Runnable, DuskProtocol {
 	Prop getProp(String strName) {
 		Prop prpStore = null;
 		try {
-			RandomAccessFile rafPropDef = new RandomAccessFile("defProps/" + strName, "r");
-			prpStore = new Prop(getID(), strName);
-			String strStore = rafPropDef.readLine();
-			while (!(strStore == null || strStore.equals("."))) {
-				if (strStore.equalsIgnoreCase("description")) {
-					prpStore.description = rafPropDef.readLine();
-				} else if (strStore.equalsIgnoreCase("image")) {
-					prpStore.intImage = Integer.parseInt(rafPropDef.readLine());
-				}
-				strStore = rafPropDef.readLine();
-			}
-			rafPropDef.close();
+			String key = strName.toLowerCase();
+			Optional<Path> path = Files.find(Path.of("defProps"), 1, (t, a) -> t.getFileName().toString().toLowerCase().equals(key)).findAny();
+			if (path.isPresent()) {
+				RandomAccessFile rafPropDef = new RandomAccessFile(path.get().toFile(), "r");
+				prpStore = new Prop(getID(), strName);
+				String strStore = rafPropDef.readLine();
+				while (!(strStore == null || strStore.equals("."))) {
+					if (strStore.equalsIgnoreCase("description")) {
+						prpStore.description = rafPropDef.readLine();
+					} else if (strStore.equalsIgnoreCase("image")) {
+						prpStore.intImage = Integer.parseInt(rafPropDef.readLine());
+					}
+					strStore = rafPropDef.readLine();
+				}
+				rafPropDef.close();
+			} else {
+				throw new FileNotFoundException("defProps/" + key);
+			}
 		} catch (Exception e) {
 			log.printError("getProp():While trying to get prop \"" + strName + "\"", e);
 		}
@@ -1117,7 +1180,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 			int i = 0;
 			Prop prpStore;
 			while (true) {
-				prpStore = (Prop) propList.get(i);
+				prpStore = (Prop)propList.get(i);
 				if (prpStore.name.equals(inName)) {
 					return prpStore;
 				}
@@ -1136,7 +1199,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 			int i = 0;
 			Prop prpStore;
 			while (true) {
-				prpStore = (Prop) propList.get(i);
+				prpStore = (Prop)propList.get(i);
 				if (prpStore.name.equals(inName)) {
 					//vctProps.remove(i);
 					removeDuskObject(prpStore);
@@ -1217,7 +1280,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 			String strStore = tokName.nextToken();
 			i = Integer.parseInt(strStore);
 			strStore = inName.substring(strStore.length() + 1, inName.length());
-			itmStore = (Item) itemList.get(i);
+			itmStore = (Item)itemList.get(i);
 			if (itmStore.name.equals(strStore)) {
 				return itmStore;
 			}
@@ -1237,7 +1300,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 			String strStore = tokName.nextToken();
 			i = Integer.parseInt(strStore);
 			strStore = inName.substring(strStore.length() + 1, inName.length());
-			itmStore = (Item) itemList.get(i);
+			itmStore = (Item)itemList.get(i);
 			if (itmStore.name.equals(strStore)) {
 				//vctItems.remove(i);
 				removeDuskObject(itmStore);
@@ -1251,10 +1314,10 @@ public class DuskEngine implements Runnable, DuskProtocol {
 
 	// 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) {
+		for (TileMap.MapData md: map.range(locx, locy, viewrange)) {
+			for (DuskObject o: md.entities) {
 				if (o.isLivingThing()) {
-					LivingThing lt = (LivingThing) o;
+					LivingThing lt = (LivingThing)o;
 					if (lt.isPlayer()) {
 						lt.playSFX(sfxid);
 					}
@@ -1270,14 +1333,14 @@ public class DuskEngine implements Runnable, DuskProtocol {
 		Script scrStore;
 		boolean blnStore;
 
+		System.out.printf("can move %d,%d\n", inLocX, inLocY);
 		if (!lt.map.inside(inLocX, inLocY))
 			return false;
 
 		//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)) {
+		for (DuskObject o: lt.map.getEntities(inLocX, inLocY, null)) {
 			if (o.isLivingThing()) {
-				thnStore2 = (LivingThing) o;
+				thnStore2 = (LivingThing)o;
 				if (!canMoveThrougLivingThing(lt, thnStore2))
 					return false;
 			}
@@ -1289,10 +1352,11 @@ public class DuskEngine implements Runnable, DuskProtocol {
 			scrStore.close();
 			return blnStore;
 		} catch (Exception e) {
+			//e.printStackTrace();
 		}
 		try {
 			int tid = lt.map.getTile(inLocX, inLocY);
-			scrStore = (Script) tileCanMove.get(tid);
+			scrStore = (Script)tileCanMove.get(tid);
 			synchronized (scrStore) {
 				scrStore.varVariables.clearVariables();
 				scrStore.varVariables.addVariable("trigger", lt);
@@ -1319,7 +1383,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 		} catch (Exception e) {
 		}
 		try {
-			script = (Script) tileCanSee.get((int) lt.map.getTile(inLocX, inLocY));
+			script = (Script)tileCanSee.get((int)lt.map.getTile(inLocX, inLocY));
 			synchronized (script) {
 				script.varVariables.clearVariables();
 				script.varVariables.addVariable("trigger", lt);
@@ -1344,7 +1408,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 			return true;
 		}
 
-		for (TileMap.MapData md : lt.map.look(lt.x, lt.y, destX, destY)) {
+		for (TileMap.MapData md: lt.map.look(lt.x, lt.y, destX, destY)) {
 			if (!canSee(lt, md.x, md.y))
 				return false;
 		}
@@ -1436,10 +1500,10 @@ public class DuskEngine implements Runnable, DuskProtocol {
 	}
 
 	void updateMap(LivingThing thing, int locx, int locy) {
-		for (TileMap.MapData md : thing.map.range(locx, locy, viewrange)) {
-			for (DuskObject o : md.entities) {
+		for (TileMap.MapData md: thing.map.range(locx, locy, viewrange)) {
+			for (DuskObject o: md.entities) {
 				if (o.isLivingThing()) {
-					LivingThing lt = (LivingThing) o;
+					LivingThing lt = (LivingThing)o;
 					if (lt.isPlayer()) {
 						lt.updateMap();
 					}
@@ -1452,7 +1516,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 	synchronized void resizeMap(TileMap map, int x, int y) {
 		map.resize(x, y);
 		// FIXME: only the map that changed
-		for (LivingThing thing : playersByName.values()) {
+		for (LivingThing thing: playersByName.values()) {
 			thing.initMap();
 		}
 		blnMapHasChanged = true;
@@ -1473,7 +1537,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 			File deleteme;
 			RandomAccessFile rafFile;
 			int i,
-					i2;
+				i2;
 			if (blnMapHasChanged) {
 				System.err.println("save map not implemented");
 				log.printMessage(Log.ALWAYS, "Saving map...");
@@ -1491,7 +1555,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 					deleteme = new File("mobs");
 					deleteme.delete();
 					rafFile = new RandomAccessFile("mobs", "rw");
-					for (Mob mob : mobList) {
+					for (Mob mob: mobList) {
 						if (mob.blnOneUse == false) {
 							if (mob.level == -1) {
 								rafFile.writeBytes("mob2.3\n" + mob.name + "\n" + mob.originalX + "\n" + mob.originalY + "\n");
@@ -1511,7 +1575,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 					deleteme = new File("signs");
 					deleteme.delete();
 					rafFile = new RandomAccessFile("signs", "rw");
-					for (Sign sign : signList) {
+					for (Sign sign: signList) {
 						rafFile.writeBytes(sign.strMessage + "\n" + sign.x + "\n" + sign.y + "\n");
 					}
 					rafFile.close();
@@ -1526,10 +1590,10 @@ public class DuskEngine implements Runnable, DuskProtocol {
 					deleteme.delete();
 					try (RandomAccessFile out = new RandomAccessFile("merchants", "rw")) {
 						// FIXME: i/o on object
-						for (Merchant m : merchantList) {
+						for (Merchant m: merchantList) {
 							out.writeBytes(m.x + "\n" + m.y + "\n");
 							for (i2 = 0; i2 < m.items.size(); i2++) {
-								out.writeBytes((String) m.items.get(i2) + "\n");
+								out.writeBytes((String)m.items.get(i2) + "\n");
 							}
 							out.writeBytes("end\n");
 						}
@@ -1544,7 +1608,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 					deleteme = new File("props");
 					deleteme.delete();
 					rafFile = new RandomAccessFile("props", "rw");
-					for (Prop prop : propList) {
+					for (Prop prop: propList) {
 						rafFile.writeBytes(prop.name + "\n" + prop.x + "\n" + prop.y + "\n");
 					}
 					rafFile.close();
@@ -1558,7 +1622,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 					deleteme = new File("globals");
 					deleteme.delete();
 					rafFile = new RandomAccessFile("globals", "rw");
-					for (Variable varStore : varVariables.vctVariables.values()) {
+					for (Variable varStore: varVariables.vctVariables.values()) {
 						if (varStore.isString() || varStore.isNumber()) {
 							rafFile.writeBytes(varStore.strName + "\n");
 							rafFile.writeBytes(varStore.bytType + "\n");
@@ -1593,12 +1657,11 @@ public class DuskEngine implements Runnable, DuskProtocol {
 				int i, i2;
 
 				//	map.saveMap(new File("backup/shortmap.backup"));
-
 				deleteme = new File("backup/mobs.backup");
 				deleteme.delete();
 				rafFile = new RandomAccessFile("backup/mobs.backup", "rw");
 				synchronized (mobList) {
-					for (Mob mob : mobList) {
+					for (Mob mob: mobList) {
 						if (mob.blnOneUse == false) {
 							tknStore = new StringTokenizer(mob.name, " ");
 							rafFile.writeBytes(tknStore.nextToken() + "\n" + mob.level + "\n" + mob.originalX + "\n" + mob.originalY + "\n");
@@ -1610,7 +1673,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 				deleteme = new File("backup/signs.backup");
 				deleteme.delete();
 				rafFile = new RandomAccessFile("backup/signs.backup", "rw");
-				for (Sign sign : signList) {
+				for (Sign sign: signList) {
 					rafFile.writeBytes(sign.strMessage + "\n" + sign.x + "\n" + sign.y + "\n");
 				}
 				rafFile.close();
@@ -1618,10 +1681,10 @@ public class DuskEngine implements Runnable, DuskProtocol {
 				deleteme = new File("backup/merchants.backup");
 				deleteme.delete();
 				rafFile = new RandomAccessFile("backup/merchants.backup", "rw");
-				for (Merchant m : merchantList) {
+				for (Merchant m: merchantList) {
 					rafFile.writeBytes(m.x + "\n" + m.y + "\n");
 					for (i2 = 0; i2 < m.items.size(); i2++) {
-						rafFile.writeBytes((String) m.items.get(i2) + "\n");
+						rafFile.writeBytes((String)m.items.get(i2) + "\n");
 					}
 					rafFile.writeBytes("end\n");
 				}
@@ -1630,7 +1693,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 				deleteme = new File("backup/props.backup");
 				deleteme.delete();
 				rafFile = new RandomAccessFile("backup/props.backup", "rw");
-				for (Prop prop : propList) {
+				for (Prop prop: propList) {
 					rafFile.writeBytes(prop.name + "\n" + prop.x + "\n" + prop.y + "\n");
 				}
 				rafFile.close();
@@ -1653,29 +1716,30 @@ public class DuskEngine implements Runnable, DuskProtocol {
 	}
 
 	public void addDuskObject(TileMap map, DuskObject obj) {
+		System.out.printf("xx add '%s' %d %d\n", obj.name, obj.x, obj.y);
 		if (obj.isLivingThing()) {
-			LivingThing lt = (LivingThing) obj;
+			LivingThing lt = (LivingThing)obj;
 			if (!lt.isLoaded) {
 				return;
 			}
 			if (obj instanceof Mob) {
 				synchronized (mobList) {
-					mobList.add((Mob) obj);
+					mobList.add((Mob)obj);
 				}
 				blnMobListChanged = true;
 			} else if (lt.isPet()) {
 				petList.add(lt);
 			}
 		} else if (obj.isItem()) {
-			itemList.add((Item) obj);
+			itemList.add((Item)obj);
 		} else if (obj.isSign()) {
-			signList.add((Sign) obj);
+			signList.add((Sign)obj);
 			blnSignListChanged = true;
 		} else if (obj.isMerchant()) {
-			merchantList.add((Merchant) obj);
+			merchantList.add((Merchant)obj);
 			blnMerchantListChanged = true;
 		} else if (obj.isProp()) {
-			propList.add((Prop) obj);
+			propList.add((Prop)obj);
 			blnPropListChanged = true;
 		}
 
@@ -1686,7 +1750,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 	/**
 	 * When a mob is killed, it isn't really removed, but the player needs
 	 * to know about it.
-	 *
+	 * <p>
 	 * This 'cheats' by removing it from the game but temporarily
 	 * corrupting the mob index.
 	 *
@@ -1698,8 +1762,9 @@ public class DuskEngine implements Runnable, DuskProtocol {
 	}
 
 	public void removeDuskObject(DuskObject obj) {
+		System.out.printf("xx rem '%s' %d %d\n", obj.name, obj.x, obj.y);
 		if (obj.isLivingThing()) {
-			LivingThing lt = (LivingThing) obj;
+			LivingThing lt = (LivingThing)obj;
 			if (!lt.isLoaded) {
 				return;
 			}
@@ -1730,7 +1795,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 
 	/**
 	 * Move a living thing, updating any other living things within range.
-	 *
+	 * <p>
 	 * Only moves wihin the same map
 	 *
 	 * @param thing
@@ -1740,14 +1805,14 @@ public class DuskEngine implements Runnable, DuskProtocol {
 	 */
 	// 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 : thing.map.range(thing.x, thing.y, viewrange)) {
-			for (DuskObject o : md.entities) {
+		for (TileMap.MapData md: thing.map.range(thing.x, thing.y, viewrange)) {
+			for (DuskObject o: md.entities) {
 				if (o.isLivingThing()) {
-					LivingThing lt = (LivingThing) o;
+					LivingThing lt = (LivingThing)o;
 					if (lt.isPlayer()) {
 						boolean canSee = canSeeTo(lt, inlocx, inlocy)
-								&& (!thing.isLivingThing()
-								|| canSeeLivingThing(lt, thing));
+							&& (!thing.isLivingThing()
+							|| canSeeLivingThing(lt, thing));
 
 						if (canSee) {
 							// Add/update it if now visible
@@ -1759,7 +1824,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 						}
 					} else if (lt.isMob()) {
 						// Is this true?
-						Mob thnMob = (Mob) lt;
+						Mob thnMob = (Mob)lt;
 						thnMob.blnCanSeePlayer = true;
 					}
 				}
@@ -1775,7 +1840,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 
 	/**
 	 * Find a visible object of the given name.
-	 *
+	 * <p>
 	 * Name may also be the id.
 	 *
 	 * @param thing
@@ -1808,13 +1873,13 @@ public class DuskEngine implements Runnable, DuskProtocol {
 		}
 		//Search surrounding area
 
-		for (TileMap.MapData md : thing.map.range(thing.x, thing.y, viewrange)) {
-			for (DuskObject o : md.entities) {
+		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))) {
+					|| (byid == -1 && o.name.equalsIgnoreCase(name))) {
 					if ((!o.isLivingThing()
-							|| canSeeLivingThing(thing, (LivingThing) o))
-							&& canSeeTo(thing, o.x, o.y)) {
+						|| canSeeLivingThing(thing, (LivingThing)o))
+						&& canSeeTo(thing, o.x, o.y)) {
 						if (number == 0) {
 							return o;
 						} else {
@@ -1833,12 +1898,12 @@ public class DuskEngine implements Runnable, DuskProtocol {
 		log.printMessage(Log.ALWAYS, "Player ticks = " + lngPlayerTicks);
 		log.printMessage(Log.ALWAYS, "Starting Ticks");
 		int tick = 0,
-				i;
+			i;
 		LivingThing thnStore,
-				thnStore2;
+			thnStore2;
 		Battle batStore;
 		long lngTime = System.currentTimeMillis(),
-				lngPause = 0;
+			lngPause = 0;
 		while (true) {
 			try {
 				//250 milliseconds per tick
@@ -1848,7 +1913,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 				}
 				lngTime = System.currentTimeMillis();
 				if (tick % 73 == 0) {
-					for (LivingThing pet : petList) {
+					for (LivingThing pet: petList) {
 						if (pet.battle == null) {
 							if (pet.isSleeping) {
 								pet.hp += 3 + (pet.cons + pet.consbon);
@@ -1885,11 +1950,11 @@ public class DuskEngine implements Runnable, DuskProtocol {
 						pet.savePlayer();
 					}
 				}
-				for (LivingThing pet : petList) {
+				for (LivingThing pet: petList) {
 					pet.moveTick();
 				}
 				//Following code submitted by Randall Leeds, revised by Tom Weingarten:
-				for (LivingThing lt : playersByName.values()) {
+				for (LivingThing lt: playersByName.values()) {
 					if (!lt.isWorking) {
 						//thnStore.closeNoMsgPlayer();
 						continue;
@@ -1931,7 +1996,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 
 				if (tick % 10 == 0) {
 					for (i = 0; i < battleList.size(); i++) {
-						batStore = (Battle) battleList.get(i);
+						batStore = (Battle)battleList.get(i);
 						if (batStore.blnRunning == false) {
 							battleList.remove(i);
 							i--;
@@ -1943,7 +2008,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 				if (tick > 72) {
 					tick = 0;
 					synchronized (mobList) {
-						for (Mob mob : mobList) {
+						for (Mob mob: mobList) {
 							if (mob.battle == null) {
 								// FIXME: magic number
 								if (mob.x != -6) {
@@ -1967,7 +2032,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 							}
 						}
 					}
-					for (Faction f : factionMap.values()) {
+					for (Faction f: factionMap.values()) {
 						f.saveFactionData();;
 					}
 				}
@@ -2074,7 +2139,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 
 	/**
 	 * This registers a new player atomically.
-	 *
+	 * <p>
 	 * Any existing player with the same name is booted
 	 */
 	public void registerPlayer(LivingThing lt, String name) throws BlockedIPException {
@@ -2083,7 +2148,7 @@ public class DuskEngine implements Runnable, DuskProtocol {
 			if (blnIPF) {
 				String address = lt.getAddress();
 
-				for (LivingThing thing : playersByName.values()) {
+				for (LivingThing thing: playersByName.values()) {
 					if (thing.getAddress().equalsIgnoreCase(address)) {
 						throw new BlockedIPException("Already a player connected from your address");
 					}
diff --git a/src/duskz.server/classes/duskz/server/Faction.java b/src/duskz.server/classes/duskz/server/Faction.java
index 663b871..ab692fa 100644
--- a/src/duskz.server/classes/duskz/server/Faction.java
+++ b/src/duskz.server/classes/duskz/server/Faction.java
@@ -29,6 +29,9 @@ import duskz.server.entity.DuskObject;
 import java.io.*;
 import java.util.Vector;
 import java.lang.Math;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Optional;
 
 /**
  * a Faction represents a group of mobs.
@@ -52,15 +55,22 @@ public class Faction {
 	void parseFactionData() {
 		RandomAccessFile rafFile = null;
 		try {
-			rafFile = new RandomAccessFile("factions/" + strName, "r");
-			String strStore = rafFile.readLine();
-			while (!(strStore == null || strStore.equals("."))) {
-				if (strStore.equalsIgnoreCase("relation")) {
-					vctRelations.addElement(new Relation(rafFile.readLine().toLowerCase(), Double.valueOf(rafFile.readLine()).doubleValue()));
+			// perform case insenitive lookup to match windows filesystem
+			String key = strName.toLowerCase();
+			Optional<Path> path = Files.find(Path.of("factions"), 1, (t, a) -> t.getFileName().toString().toLowerCase().equals(key)).findAny();
+			if (path.isPresent()) {
+				rafFile = new RandomAccessFile(path.get().toFile(), "r");
+				String strStore = rafFile.readLine();
+				while (!(strStore == null || strStore.equals("."))) {
+					if (strStore.equalsIgnoreCase("relation")) {
+						vctRelations.addElement(new Relation(rafFile.readLine().toLowerCase(), Double.valueOf(rafFile.readLine()).doubleValue()));
+					}
+					strStore = rafFile.readLine();
 				}
-				strStore = rafFile.readLine();
+				rafFile.close();
+			} else {
+				throw new FileNotFoundException("factions/" + key);
 			}
-			rafFile.close();
 		} catch (Exception e) {
 			game.log.printError("parseFactionData()", e);
 		}
@@ -79,7 +89,7 @@ public class Faction {
 			rafFile = new RandomAccessFile("factions/" + strName, "rw");
 			Relation relStore;
 			for (i = 0; i < vctRelations.size(); i++) {
-				relStore = (Relation) vctRelations.elementAt(i);
+				relStore = (Relation)vctRelations.elementAt(i);
 				rafFile.writeBytes("relation\n" + relStore.strName.toLowerCase() + "\n" + relStore.dblLevel + "\n");
 			}
 			rafFile.writeBytes(".\n");
@@ -93,7 +103,7 @@ public class Faction {
 	double getRelationValue(String strName) {
 		Relation relStore;
 		for (int i = 0; i < vctRelations.size(); i++) {
-			relStore = (Relation) vctRelations.elementAt(i);
+			relStore = (Relation)vctRelations.elementAt(i);
 			if (strName.equalsIgnoreCase(relStore.strName)) {
 				if (i > 100) {
 					vctRelations.removeElementAt(i);
@@ -108,7 +118,7 @@ public class Faction {
 	Relation getRelation(String strName) {
 		Relation relStore;
 		for (int i = 0; i < vctRelations.size(); i++) {
-			relStore = (Relation) vctRelations.elementAt(i);
+			relStore = (Relation)vctRelations.elementAt(i);
 			if (strName.equalsIgnoreCase(relStore.strName)) {
 				if (i > 100) {
 					vctRelations.removeElementAt(i);
@@ -174,17 +184,16 @@ public class Faction {
 		}
 
 		// FIXME: can this be moved to DuskEngine somehow?
-
 		//Default AI
 		int intConfidence = 0;
 		LivingThing enemy = null;
 		Mob mobStore;
 		double enemyrelation = 0;
 		boolean visiblePlayer = false;
-		for (MapData md : mob.map.range(mob.x, mob.y, game.viewrange - 1)) {
-			for (DuskObject o : md.entities) {
+		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;
+					LivingThing lt = (LivingThing)o;
 					boolean visible = game.canSeeLivingThing(mob, lt);
 
 					if (visible && game.canSeeTo(mob, lt.x, lt.y)) {
@@ -212,7 +221,7 @@ public class Faction {
 						if (lt.isMob()) {
 							double relation;
 
-							mobStore = (Mob) lt;
+							mobStore = (Mob)lt;
 							if (mobStore.name.equals(mob.name)) {
 								relation = mobStore.dblGroupRelation;
 							} else {
@@ -289,15 +298,15 @@ public class Faction {
 		}
 
 		//If no enemies
-		if ((int) (Math.random() * 25) == 1) {
-			if ((int) (Math.random() * 2) == 1) {
-				if ((int) (Math.random() * 2) == 1) {
+		if ((int)(Math.random() * 25) == 1) {
+			if ((int)(Math.random() * 2) == 1) {
+				if ((int)(Math.random() * 2) == 1) {
 					mob.moveE();
 				} else {
 					mob.moveW();
 				}
 			} else {
-				if ((int) (Math.random() * 2) == 1) {
+				if ((int)(Math.random() * 2) == 1) {
 					mob.moveS();
 				} else {
 					mob.moveN();
diff --git a/src/duskz.server/classes/duskz/server/Script.java b/src/duskz.server/classes/duskz/server/Script.java
index 5281e4d..5c53d3e 100644
--- a/src/duskz.server/classes/duskz/server/Script.java
+++ b/src/duskz.server/classes/duskz/server/Script.java
@@ -252,6 +252,7 @@ public class Script {
 	}
 
 	public void runScript() {
+		engGame.log.printMessage(Log.DEBUG, "Executing script " + strName);
 		rewindScript();
 		vctUpdate = new Vector(0);
 		vctVisibleUpdate = new Vector(0);
@@ -317,7 +318,9 @@ public class Script {
 
 	public boolean rewindAndParseScript() {
 		rewindScript();
-		return parseScript();
+		boolean ok = parseScript();
+		engGame.log.printMessage(Log.DEBUG, "Executing boolean script " + strName + "=" + ok);
+		return ok;
 	}
 
 	String readScriptForCompile()
@@ -1184,25 +1187,22 @@ public class Script {
 					return false;
 				}
 				case 29: {
-					// These all need a map-name as well
-					System.err.println("create mob not implemented");
+					// Multi map: These all need a map-name as well
 					Mob mobStore = new Mob(getString(), (int) parseValue(), (int) parseValue(), engGame);
-					//engGame.addDuskObject(mobStore);
+					engGame.addDuskObject(((LivingThing)varVariables.getVariable("trigger").objData).map, 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.addDuskObject(mobStore);
+					engGame.addDuskObject(((LivingThing)varVariables.getVariable("trigger").objData).map, 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(((LivingThing)varVariables.getVariable("trigger").objData).map, itmStore);
 					return true;
 				}
 				case 59: {
@@ -1699,16 +1699,15 @@ public class Script {
 				case 46: {
 					int dbgX, dbgY;
 					short dbgValue;
+					LivingThing thing = (LivingThing)varVariables.getVariable("trigger").objData;
 					dbgX = (int) parseValue();
 					dbgY = (int) parseValue();
 					dbgValue = (short) parseValue();
 					if (dbgValue == 0) {
 						engGame.log.printMessage(Log.DEBUG, "Script " + strName + " called changeMap with 0 at " + dbgX + "," + dbgY);
 					}
-//					engGame.changeMap((int)parseValue(),(int)parseValue(),(short)parseValue());
-					// FIXME: 
-					throw new UnsupportedOperationException("script changemap not implemented");
-					//engGame.changeMap(dbgX, dbgY, dbgValue);
+					engGame.changeMap(thing, (int)parseValue(),(int)parseValue(),(short)parseValue());
+					engGame.changeMap(thing, dbgX, dbgY, dbgValue);
 				}
 				case 47: {
 					String strOne = getString();
@@ -1749,7 +1748,8 @@ public class Script {
 					//LivingThing thnStore = getLivingThing(getString());
 					//engGame.notifyRemoved(thnStore);
 					//engGame.addEntity(thnStore);
-					return true;
+					throw new UnsupportedOperationException("script token 49 not implemented");
+					//return true;
 				}
 				case 50: {
 					LivingThing thnStore = getLivingThing(getString());
@@ -1774,6 +1774,7 @@ public class Script {
 					return true;
 				}
 				case 52: {
+					throw new UnsupportedOperationException("view text not implemented");
 					// FIXME: This is the VIEW_TEXT command
 					/*
 					 LivingThing thnStore = getLivingThing(getString());
@@ -1791,7 +1792,7 @@ public class Script {
 					 thnStore.send(strStore2 + "\n");
 					 thnStore.send("--EOF--\n");
 					 * */
-					return true;
+					//return true;
 				}
 				case 53: {
 					LivingThing thnStore = getLivingThing(getString());
@@ -1885,7 +1886,7 @@ public class Script {
 					return true;
 				}
 				/*case 127:
-				 {	
+				 {
 				 return false;
 				 }*/
 			}
diff --git a/src/duskz.server/classes/duskz/server/entity/Item.java b/src/duskz.server/classes/duskz/server/entity/Item.java
index 7821b36..fc4fd53 100644
--- a/src/duskz.server/classes/duskz/server/entity/Item.java
+++ b/src/duskz.server/classes/duskz/server/entity/Item.java
@@ -25,6 +25,7 @@
  */
 package duskz.server.entity;
 
+import duskz.protocol.EntityUpdateMessage;
 import duskz.protocol.Wearing;
 import duskz.server.DuskEngine;
 import duskz.server.Script;
@@ -35,10 +36,10 @@ import java.io.RandomAccessFile;
 /*
  All code copyright Tom Weingarten (captaint@home.com) 2000
  Tom Weingarten makes no assurances as to the reliability or
- functionality of this code. Use at your own risk. 
+ functionality of this code. Use at your own risk.
 
  You are free to edit or redistribute this code or any portion
- at your wish, under the condition that you do not edit or 
+ at your wish, under the condition that you do not edit or
  remove this license, and accompany it with all redistributions.
  */
 //0-Ordinary Item
@@ -61,16 +62,16 @@ public class Item extends DuskObject {
 	public static final int DRINK = 4;
 	public static final int CONTAINER = 5;
 	private String strOnGetScript = null,
-			strOnDropScript = null;
+		strOnDropScript = null;
 	public String strOnUseScript = null,
-			strOnWearScript = null,
-			strOnUnWearScript = null;
+		strOnWearScript = null,
+		strOnUnWearScript = null;
 	public int intCost,
-			intType = -1,
-			intKind = -1,
-			intMod,
-			intUses = -1,
-			intRange = 1;
+		intType = -1,
+		intKind = -1,
+		intMod,
+		intUses = -1,
+		intRange = 1;
 	int intImage;
 	int intWeight;				// How much this object weighs
 	int intSize;				// Amount of space this object takes up
@@ -141,7 +142,18 @@ public class Item extends DuskObject {
 
 	@Override
 	public int getEntityType() {
-		return 1;
+		if (isFood())
+			return EntityUpdateMessage.TYPE_FOOD;
+		if (isDrink())
+			return EntityUpdateMessage.TYPE_DRINK;
+		if (isWeapon())
+			return EntityUpdateMessage.TYPE_WEAPON;
+		if (isArmor())
+			return EntityUpdateMessage.TYPE_ARMOUR;
+		if (isContainer())
+			return EntityUpdateMessage.TYPE_CONTAINER;
+
+		return EntityUpdateMessage.TYPE_ITEM;
 	}
 
 	/**
@@ -169,21 +181,21 @@ public class Item extends DuskObject {
 	 */
 	public String toString() {
 		return "[strName:" + name
-				+ "::strDescription:" + description
-				+ "::strOnUseScript:" + strOnUseScript
-				+ "::strOnWearScript:" + strOnWearScript
-				+ "::strOnUnWearScript:" + strOnUnWearScript
-				+ "::strOnGetScript:" + strOnGetScript
-				+ "::strOnDropScript:" + strOnDropScript
-				+ "::intCost:" + intCost
-				+ "::intType:" + intType
-				+ "::intKind:" + intKind
-				+ "::intMod:" + intMod
-				+ "::intImage:" + intImage
-				+ "::intUses:" + intUses
-				+ "::intRange:" + intRange
-				+ "::lngDurability:" + lngDurability
-				+ "]";
+			+ "::strDescription:" + description
+			+ "::strOnUseScript:" + strOnUseScript
+			+ "::strOnWearScript:" + strOnWearScript
+			+ "::strOnUnWearScript:" + strOnUnWearScript
+			+ "::strOnGetScript:" + strOnGetScript
+			+ "::strOnDropScript:" + strOnDropScript
+			+ "::intCost:" + intCost
+			+ "::intType:" + intType
+			+ "::intKind:" + intKind
+			+ "::intMod:" + intMod
+			+ "::intImage:" + intImage
+			+ "::intUses:" + intUses
+			+ "::intRange:" + intRange
+			+ "::lngDurability:" + lngDurability
+			+ "]";
 	}
 
 	public static Item getItem(long id, String inName) throws IOException {
diff --git a/src/duskz.server/classes/duskz/server/entity/LivingThing.java b/src/duskz.server/classes/duskz/server/entity/LivingThing.java
index a224964..730e689 100644
--- a/src/duskz.server/classes/duskz/server/entity/LivingThing.java
+++ b/src/duskz.server/classes/duskz/server/entity/LivingThing.java
@@ -240,10 +240,11 @@ public class LivingThing extends DuskObject implements Runnable, DuskProtocol {
 
 	@Override
 	public int getEntityType() {
-		if (isMob() || isPet()) {
-			return 4;
-		}
-		return 0;
+		if (isMob())
+			return EntityUpdateMessage.TYPE_MOBILE;
+		if (isPet())
+			return EntityUpdateMessage.TYPE_PET;
+		return EntityUpdateMessage.TYPE_PLAYER;
 	}
 
 	/**
@@ -2132,6 +2133,7 @@ public class LivingThing extends DuskObject implements Runnable, DuskProtocol {
 	}
 
 	public void addCondition(Condition cndStore) {
+		System.out.printf("add condition '%s' '%s'\n", name, cndStore.name);
 		if (conditions.isEmpty()) {
 			game.checkConditionList.add(this);
 		} else {
@@ -2941,7 +2943,7 @@ public class LivingThing extends DuskObject implements Runnable, DuskProtocol {
 					msg = messageQueue.take();
 
 					// low level protocol dump
-					msg.format(System.out);
+					//msg.format(System.out);
 
 					try {
 						msg.sendMessage(outstream);
diff --git a/src/duskz.server/classes/duskz/server/entity/Merchant.java b/src/duskz.server/classes/duskz/server/entity/Merchant.java
index 58aec25..e6c1e4f 100644
--- a/src/duskz.server/classes/duskz/server/entity/Merchant.java
+++ b/src/duskz.server/classes/duskz/server/entity/Merchant.java
@@ -24,6 +24,7 @@
  */
 package duskz.server.entity;
 
+import duskz.protocol.EntityUpdateMessage;
 import duskz.server.DuskEngine;
 import java.io.*;
 import java.util.ArrayList;
@@ -57,7 +58,7 @@ public class Merchant extends DuskObject {
 
 	@Override
 	public int getEntityType() {
-		return 2;
+		return EntityUpdateMessage.TYPE_GAME_SHOP;
 	}
 
 	public boolean contains(String item) {
@@ -83,12 +84,12 @@ public class Merchant extends DuskObject {
 			if (thnMaster.isPet()) {
 				thnMaster.chatMessage("You ARE a pet!");
 				return;
-			
+
 			}
-			
+
 			thnMaster.chatMessage("The developer hasn't implemented pets yet!, see Merchangt.java line 90");
 			if (true)return;
-		
+
 			// FIXME: requires query system.  Use callbacks?
 			/*
 			thnMaster.halt();
diff --git a/src/duskz.server/classes/duskz/server/entity/Mob.java b/src/duskz.server/classes/duskz/server/entity/Mob.java
index 2de820c..97b4ae1 100644
--- a/src/duskz.server/classes/duskz/server/entity/Mob.java
+++ b/src/duskz.server/classes/duskz/server/entity/Mob.java
@@ -34,8 +34,12 @@ import duskz.server.ItemList;
 import duskz.server.Log;
 import duskz.server.Script;
 import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Optional;
+import java.util.stream.Stream;
 
 /**
  * Mob(mobile) is the class of non-player moving entities.
@@ -71,7 +75,7 @@ public class Mob extends LivingThing {
 		wornItems = new Equipment();
 		itemList = new ItemList();
 		battle = null;
-		loadMobFile(new File("defMobs/" + strType));
+		loadMobFile(strType.toLowerCase());
 		hp = maxhp;
 		mp = maxmp;
 		isSleeping = false;
@@ -94,7 +98,7 @@ public class Mob extends LivingThing {
 		itemList = new ItemList();
 		battle = null;
 		this.level = level;
-		loadMobFile(new File("defMobs/" + strType));
+		loadMobFile(strType.toLowerCase());
 		maxhp = maxhp * level;
 		maxmp = maxmp * level;
 		stre = stre * level;
@@ -123,20 +127,30 @@ public class Mob extends LivingThing {
 		}
 	}
 
-	public void loadMobFile(File path) throws FileNotFoundException, IOException {
+	public void loadMobFile(String type) throws FileNotFoundException, IOException {
 		String line;
-		try (RandomAccessFile file = new RandomAccessFile(path, "r")) {
-			while (!((line = file.readLine()) == null || line.equals("."))) {
-				try {
-					parseMobFile(file, line);
-				} catch (NumberFormatException x) {
-					throw new IOException("Problem parsing mob " + path + " on field " + line, x);
+		// perform case insenitive lookup to match windows filesystem
+		// TODO: put in util class or fix game files
+		Optional<Path> path = Files.find(Path.of("defMobs"), 1, (t, a)-> t.getFileName().toString().toLowerCase().equals(type)).findAny();
+		if (path.isPresent()) {
+			try (RandomAccessFile file = new RandomAccessFile(path.get().toFile(), "r")) {
+				while (!((line = file.readLine()) == null || line.equals("."))) {
+					try {
+						parseMobFile(file, line);
+					} catch (NumberFormatException x) {
+						throw new IOException("Problem parsing mob " + path + " on field " + line, x);
+					}
+				}
+				if (fctFaction == null) {
+					game.log.printMessage(Log.DEBUG, "no faction found for mob \"" + name + "\"");
 				}
 			}
-			if (fctFaction == null) {
-				game.log.printMessage(Log.DEBUG, "no faction found for mob \"" + name + "\"");
-			}
+		} else {
+			throw new FileNotFoundException("defMobs/" + type);
 		}
+		System.out.println("mob loaded: " + name);
+		System.out.print("onBattle: ");
+		System.out.println(strOnBattle);
 	}
 
 	private void parseMobFile(RandomAccessFile in, String strStore) throws IOException, NumberFormatException {
@@ -257,7 +271,7 @@ public class Mob extends LivingThing {
 					game.log.printMessage(Log.DEBUG, "no faction found for \"" + strFaction + "\"");
 				}
 				break;
-			case "onBattle":
+			case "onbattle":
 				strOnBattle = in.readLine();
 				break;
 			case "nofollow":
diff --git a/src/duskz.server/classes/duskz/server/entity/PlayerMerchant.java b/src/duskz.server/classes/duskz/server/entity/PlayerMerchant.java
index 3006db6..1c98041 100644
--- a/src/duskz.server/classes/duskz/server/entity/PlayerMerchant.java
+++ b/src/duskz.server/classes/duskz/server/entity/PlayerMerchant.java
@@ -22,6 +22,7 @@
  */
 package duskz.server.entity;
 
+import duskz.protocol.EntityUpdateMessage;
 import duskz.server.DuskEngine;
 import duskz.server.ItemList;
 
@@ -58,7 +59,7 @@ public class PlayerMerchant extends DuskObject {
 
 	@Override
 	public int getEntityType() {
-		return 2;
+		return EntityUpdateMessage.TYPE_PLAYER_SHOP;
 	}
 
 	public long contains(String strStore) {
diff --git a/src/duskz.server/classes/duskz/server/entity/Prop.java b/src/duskz.server/classes/duskz/server/entity/Prop.java
index da5cdb0..736b4ab 100644
--- a/src/duskz.server/classes/duskz/server/entity/Prop.java
+++ b/src/duskz.server/classes/duskz/server/entity/Prop.java
@@ -23,6 +23,8 @@
  */
 package duskz.server.entity;
 
+import duskz.protocol.EntityUpdateMessage;
+
 /**
  * A Prop is an entity that cannot move or be used.
  *
@@ -48,6 +50,6 @@ public class Prop extends DuskObject {
 
 	@Override
 	public int getEntityType() {
-		return 3;
+		return EntityUpdateMessage.TYPE_PROP;
 	}
 }
diff --git a/src/duskz.server/classes/duskz/server/entity/Sign.java b/src/duskz.server/classes/duskz/server/entity/Sign.java
index 8753a99..fd56b88 100644
--- a/src/duskz.server/classes/duskz/server/entity/Sign.java
+++ b/src/duskz.server/classes/duskz/server/entity/Sign.java
@@ -22,6 +22,7 @@
  */
 package duskz.server.entity;
 
+import duskz.protocol.EntityUpdateMessage;
 import duskz.server.DuskEngine;
 
 /**
@@ -55,6 +56,6 @@ public class Sign extends DuskObject {
 
 	@Override
 	public int getEntityType() {
-		return 3;
+		return EntityUpdateMessage.TYPE_SIGN;
 	}
 }
-- 
2.39.5