<NME> RoomLoader.java
<BEF> package com.planet_ink.coffee_mud.core.database;
import com.planet_ink.coffee_mud.core.interfaces.*;
import com.planet_ink.coffee_mud.core.*;
import com.planet_ink.coffee_mud.core.CMProps.Bool;
import com.planet_ink.coffee_mud.core.collections.*;
import com.planet_ink.coffee_mud.core.database.DBConnector.DBPreparedBatchEntry;
import com.planet_ink.coffee_mud.Abilities.interfaces.*;
import com.planet_ink.coffee_mud.Areas.interfaces.*;
import com.planet_ink.coffee_mud.Behaviors.interfaces.*;
import com.planet_ink.coffee_mud.CharClasses.interfaces.*;
import com.planet_ink.coffee_mud.Commands.interfaces.*;
import com.planet_ink.coffee_mud.Common.interfaces.*;
import com.planet_ink.coffee_mud.Exits.interfaces.*;
import com.planet_ink.coffee_mud.Items.interfaces.*;
import com.planet_ink.coffee_mud.Libraries.interfaces.*;
import com.planet_ink.coffee_mud.Libraries.interfaces.DatabaseEngine.ReadRoomDisableFlag;
import com.planet_ink.coffee_mud.Libraries.interfaces.DatabaseEngine.RoomContent;
import com.planet_ink.coffee_mud.Locales.interfaces.*;
import com.planet_ink.coffee_mud.MOBS.interfaces.*;
import com.planet_ink.coffee_mud.Races.interfaces.*;

import java.sql.*;
import java.util.*;

/*
   Copyright 2001-2022 Bo Zimmerman

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

	   http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
public class RoomLoader
{
	protected DBConnector	DB					= null;
	private int				recordCount			= 1;
	private int				currentRecordPos	= 1;
	private int				updateBreak			= 1;

	public RoomLoader(final DBConnector newDB)
	{
		DB=newDB;
	}

	private final static String zeroes="000000000000";

	private final static Set<ReadRoomDisableFlag> noStatusReadRoomFlags=new XHashSet<ReadRoomDisableFlag>(ReadRoomDisableFlag.STATUS);
	private final static Set<ReadRoomDisableFlag> noLiveReadRoomFlags=new XHashSet<ReadRoomDisableFlag>(ReadRoomDisableFlag.LIVE);
	private final static Set<ReadRoomDisableFlag> allEnabledReadRoomFlags=new XHashSet<ReadRoomDisableFlag>();

	protected static class StuffClass
	{
		public Hashtable<String,Hashtable<String,PhysicalAgent>> itemNums=new Hashtable<String,Hashtable<String,PhysicalAgent>>();
		public Hashtable<String,Hashtable<String,String>> cataData=new Hashtable<String,Hashtable<String,String>>();
		public Hashtable<String,Hashtable<Item,String>> itemLocs=new Hashtable<String,Hashtable<Item,String>>();
		public Hashtable<String,Hashtable<MOB, String>> mobRides=new Hashtable<String,Hashtable<MOB, String>>();
	}

	protected DBPreparedBatchEntry doBulkInsert(final StringBuilder str, final List<String> clobs, final String sql, final String clob)
	{
		if(str.length()==0)
		{
			str.append(sql);
			clobs.add(clob+" ");
		}
		else
		if(str.length()<512000)
		{
			final int x=sql.indexOf(" values ");
			str.append(", ").append(sql.substring(x+7));
			clobs.add(clob+" ");
		}
		else
		{
			final DBPreparedBatchEntry entry = new DBPreparedBatchEntry(str.toString(),clobs.toArray(new String[0]));
			str.setLength(0);
			return entry;
		}
		return null;
	}

	public String DBIsAreaName(final String name)
	{
		DBConnection D=null;
		try
		{
			D=DB.DBFetch();
			final ResultSet R=D.query("SELECT CMAREA FROM CMAREA WHERE CMAREA LIKE '"+name+"'");
			if(R.next())
			{
				final String areaName=R.getString("CMAREA");
				R.close();
				return areaName;
			}
		}
		catch(final SQLException sqle)
		{
			Log.errOut("Area",sqle);
		}
		finally
		{
			DB.DBDone(D);
		}
		return null;
	}

	public void DBReadArea(final Area A)
	{
		DBConnection D=null;
		try
		{
			D=DB.DBFetch();
			final ResultSet R=D.query("SELECT * FROM CMAREA WHERE CMAREA='"+A.Name()+"'");
			while(R.next())
			{
				final String areaName=DBConnections.getRes(R,"CMAREA");
				A.setName(areaName);
				A.setClimateType((int)DBConnections.getLongRes(R,"CMCLIM"));
				A.setSubOpList(DBConnections.getRes(R,"CMSUBS"));
				A.setDescription(DBConnections.getRes(R,"CMDESC"));
				A.setMiscText(DBConnections.getRes(R,"CMROTX"));
				A.setTheme((int)DBConnections.getLongRes(R,"CMTECH"));
			}
		}
		catch(final SQLException sqle)
		{
			Log.errOut("Area",sqle);
		}
		finally
		{
			DB.DBDone(D);
		}
	}

	public boolean DBReadAreaFull(final String areaName)
	{
		if(CMLib.map().getArea(areaName)!=null)
			return false;
		final Area A=DBReadAreaObject(areaName);
		if(A==null)
			return false;
		final RoomnumberSet unloadedRooms=(RoomnumberSet)CMClass.getCommon("DefaultRoomnumberSet");
		for(final Enumeration<String> ids = CMLib.map().roomIDs();ids.hasMoreElements();)
			unloadedRooms.add(ids.nextElement());

		final RoomnumberSet set = CMLib.database().DBReadAreaRoomList(areaName, false);
		CMLib.map().addArea(A);
		CMLib.map().registerWorldObjectLoaded(A, null, A);
		final Map<String,Room> rooms=DBReadRoomData(null,set,false,null,unloadedRooms);

		DBReadRoomExits(null,rooms,false,unloadedRooms);

		DBReadContent(null,null,rooms,unloadedRooms,noStatusReadRoomFlags);

		for(final Map.Entry<String,Room> entry : rooms.entrySet())
		{
			final Room thisRoom=entry.getValue();
			thisRoom.startItemRejuv();
			thisRoom.recoverRoomStats();
		}
		return true;
	}

	public Area DBReadAreaObject(String areaName)
	{
		DBConnection D=null;
		try
		{
			D=DB.DBFetch();
			final ResultSet R=D.query("SELECT * FROM CMAREA WHERE CMAREA = '" + areaName + "'");
			recordCount=DB.getRecordCount(D,R);
			updateBreak=CMath.s_int("1"+zeroes.substring(0,(""+(recordCount/100)).length()-1));
			while(R.next())
			{
				currentRecordPos=R.getRow();
				areaName=DBConnections.getRes(R,"CMAREA");
				final String areaType=DBConnections.getRes(R,"CMTYPE");
				Area A=CMClass.getAreaType(areaType);
				if(A==null)
					A=CMClass.getAreaType("StdArea");
				if(A==null)
				{
					Log.errOut("Could not read area: "+areaName);
					continue;
				}
				A.setName(areaName);
				A.setClimateType((int)DBConnections.getLongRes(R,"CMCLIM"));
				A.setSubOpList(DBConnections.getRes(R,"CMSUBS"));
				A.setDescription(DBConnections.getRes(R,"CMDESC"));
				final String miscData=DBConnections.getRes(R,"CMROTX");
				A.setTheme((int)DBConnections.getLongRes(R,"CMTECH"));
				if((currentRecordPos%updateBreak)==0)
					CMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Loading Areas ("+currentRecordPos+" of "+recordCount+")");
				R.close();
				A.setMiscText(miscData);
				A.setAreaState(Area.State.ACTIVE);
				return A;
			}
		}
		catch(final SQLException sqle)
		{
			Log.errOut("Area",sqle);
		}
		catch(final Exception sqle)
		{
			Log.errOut("Area",sqle);
		}
		finally
		{
			DB.DBDone(D);
		}
		return null;
	}

	protected void DBReadAllAreas()
	{
		DBConnection D=null;
		while(CMLib.map().numAreas()>0)
			CMLib.map().delArea(CMLib.map().getFirstArea());
		try
		{
			D=DB.DBFetch();
			CMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Counting Areas");
			final ResultSet R=D.query("SELECT * FROM CMAREA");
			recordCount=DB.getRecordCount(D,R);
			updateBreak=CMath.s_int("1"+zeroes.substring(0,(""+(recordCount/100)).length()-1));
			final LinkedList<Pair<Area,String>> areasLoaded=new LinkedList<Pair<Area,String>>();
			while(R.next())
			{
				currentRecordPos=R.getRow();
				final String areaName=DBConnections.getRes(R,"CMAREA");
				final String areaType=DBConnections.getRes(R,"CMTYPE");
				Area A=CMClass.getAreaType(areaType);
				if(A==null)
					A=CMClass.getAreaType("StdArea");
				if(A==null)
				{
					Log.errOut("Could not read area: "+areaName);
					continue;
				}
				A.setName(areaName);
				A.setClimateType((int)DBConnections.getLongRes(R,"CMCLIM"));
				A.setSubOpList(DBConnections.getRes(R,"CMSUBS"));
				A.setDescription(DBConnections.getRes(R,"CMDESC"));
				final String miscData=DBConnections.getRes(R,"CMROTX");
				A.setTheme((int)DBConnections.getLongRes(R,"CMTECH"));
				if((currentRecordPos%updateBreak)==0)
					CMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Loading Areas ("+currentRecordPos+" of "+recordCount+")");

				CMLib.map().addArea(A);
				areasLoaded.add(new Pair<Area,String>(A,miscData));
			}
			for(final Pair<Area,String> a : areasLoaded)
			{
				a.first.setMiscText(a.second);
			}
			for(final Pair<Area,String> a : areasLoaded)
			{
				a.first.setAreaState(Area.State.ACTIVE);
				CMLib.map().registerWorldObjectLoaded(a.first, null, a.first);
			}
		}
		catch(final SQLException sqle)
		{
			Log.errOut("Area",sqle);
		}
		catch(final Exception sqle)
		{
			Log.errOut("Area",sqle);
		}
		finally
		{
			DB.DBDone(D);
		}
	}

	public RoomnumberSet DBReadAreaRoomList(final String areaName, final boolean reportStatus)
	{
		final RoomnumberSet roomSet=(RoomnumberSet)CMClass.getCommon("DefaultRoomnumberSet");
		DBConnection D=null;
		try
		{
			D=DB.DBFetch();
			if(reportStatus)
				CMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Fetching roomnums for "+areaName);
			final ResultSet R=D.query("SELECT * FROM CMROOM"+((areaName==null)?"":" WHERE CMAREA='"+areaName+"'"));
			while(R.next())
				roomSet.add(DBConnections.getRes(R,"CMROID"));
		}
		catch(final SQLException sqle)
		{
			Log.errOut("RoomSet",sqle);
			return null;
		}
		finally
		{
			DB.DBDone(D);
		}
		return roomSet;
	}

	public Room DBReadRoomData(final String singleRoomIDtoLoad, final boolean reportStatus)
	{
		final Map<String,Room> map = DBReadRoomData(singleRoomIDtoLoad,null,reportStatus,null,null);
		final Iterator<Room> i = map.values().iterator();
		if(i.hasNext())
			return i.next();
		return null;
	}

	public Room[] DBReadRoomObjects(final String areaName, final boolean reportStatus)
	{
		DBConnection D=null;
		try
		{
			D=DB.DBFetch();
			if(reportStatus)
				CMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Counting Rooms");
			final ResultSet R=D.query("SELECT * FROM CMROOM WHERE CMAREA='"+areaName+"'");
			final List<Room> rooms=buildRoomObjects(D,R,reportStatus);
			return rooms.toArray(new Room[0]);
		}
		catch(final SQLException sqle)
		{
			Log.errOut("Room",sqle);
		}
		finally
		{
			DB.DBDone(D);
		}
		return new Room[0];
	}

	private void populateRoomInnerFields(final ResultSet R, final Room newRoom) throws SQLException
	{
		newRoom.setDisplayText(DBConnections.getRes(R,"CMDESC1"));
		if(CMProps.getBoolVar(CMProps.Bool.ROOMDNOCACHE))
			newRoom.setDescription("");
		else
			newRoom.setDescription(DBConnections.getRes(R,"CMDESC2"));
		newRoom.setMiscText(DBConnections.getRes(R,"CMROTX"));
	}

	private List<Room> buildRoomObjects(final DBConnection D, final ResultSet R, final boolean reportStatus) throws SQLException
	{
		recordCount=DB.getRecordCount(D,R);
		updateBreak=CMath.s_int("1"+zeroes.substring(0,(""+(recordCount/100)).length()-1));
		String roomID=null;
		final List<Room> rooms=new Vector<Room>();
		while(R.next())
		{
			currentRecordPos=R.getRow();
			roomID=DBConnections.getRes(R,"CMROID");
			final String localeID=DBConnections.getRes(R,"CMLOID");
			//String areaName=DBConnections.getRes(R,"CMAREA");
			final Room newRoom=CMClass.getLocale(localeID);
			if(newRoom==null)
				Log.errOut("Room","Couldn't load room '"+roomID+"', localeID '"+localeID+"'.");
			else
			{
				newRoom.setRoomID(roomID);
				populateRoomInnerFields(R,newRoom);
				rooms.add(newRoom);
			}
			if(((currentRecordPos%updateBreak)==0)&&(reportStatus))
				CMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Loading Rooms ("+currentRecordPos+" of "+recordCount+")");
		}
		return rooms;
	}

	public boolean DBReReadRoomData(final Room room)
	{
		if((room==null)||(room.roomID()==null))
			return false;
		DBConnection D=null;
		try
		{
			D=DB.DBFetch();
			final ResultSet R=D.query("SELECT * FROM CMROOM WHERE CMROID='"+room.roomID()+"'");
			if(R.next())
				populateRoomInnerFields(R, room);
			else
				return false;
		}
		catch(final SQLException sqle)
		{
			Log.errOut("Room",sqle);
			return false;
		}
		finally
		{
			DB.DBDone(D);
		}
		return true;
	}

	public Room DBReadRoomObject(final String roomIDtoLoad, final boolean reportStatus)
	{
		DBConnection D=null;
		try
		{
			D=DB.DBFetch();
			if(reportStatus)
				CMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Counting Rooms");
			final ResultSet R=D.query("SELECT * FROM CMROOM WHERE CMROID='"+roomIDtoLoad+"'");
			final List<Room> rooms=buildRoomObjects(D,R,reportStatus);
			if(rooms.size()>0)
				return rooms.get(0);
		}
		catch(final SQLException sqle)
		{
			Log.errOut("Room",sqle);
		}
		finally
		{
			DB.DBDone(D);
		}
		return null;
	}

	public Map<String,Room> DBReadRoomData(final String singleRoomIDtoLoad,
										   final RoomnumberSet roomsToLoad,
										   final boolean reportStatus,
										   final List<String> unknownAreas,
										   final RoomnumberSet unloadedRooms)
	{
		final STreeMap<String, Room> roomSet = new STreeMap<String, Room>(new Comparator<String>()
		{
			@Override
			public int compare(final String o1, final String o2)
			{
				if(o1==o2)
					return 0;
				if(o1==null)
					return -1;
				if(o2==null)
					return 1;
				return o1.compareTo(o2);
			}
		});
		DBConnection D=null;
		try
		{
			D=DB.DBFetch();
			if(reportStatus)
				CMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Counting Rooms");
			final ResultSet R=D.query("SELECT * FROM CMROOM"+((singleRoomIDtoLoad==null)?"":" WHERE CMROID='"+singleRoomIDtoLoad+"'"));
			recordCount=DB.getRecordCount(D,R);
			updateBreak=CMath.s_int("1"+zeroes.substring(0,(""+(recordCount/100)).length()-1));
			String roomID=null;
			while(R.next())
			{
				currentRecordPos=R.getRow();
				roomID=DBConnections.getRes(R,"CMROID");
				if((roomsToLoad!=null)&&(!roomsToLoad.contains(roomID)))
					continue;
				final String localeID=DBConnections.getRes(R,"CMLOID");
				final String areaName=DBConnections.getRes(R,"CMAREA");
				Area myArea=CMLib.map().getArea(areaName);
				if(myArea==null)
				{
					myArea=(Area)CMClass.getAreaType("StdArea").copyOf();
					myArea.setName(areaName);
					if((unknownAreas!=null)
					&&(!unknownAreas.contains(areaName)))
						unknownAreas.add(areaName);
				}
				myArea.addProperRoomnumber(roomID);
				if(CMath.bset(myArea.flags(),Area.FLAG_THIN))
				{
					if(unloadedRooms!=null)
					{
						if(!unloadedRooms.contains(roomID))
							unloadedRooms.add(roomID);
						continue;
					}
				}
				final Room newRoom=CMClass.getLocale(localeID);
				if(newRoom==null)
					Log.errOut("Room","Couldn't load room '"+roomID+"', localeID '"+localeID+"'.");
				else
				{
					newRoom.setRoomID(roomID);
					newRoom.setArea(myArea);
					CMLib.map().registerWorldObjectLoaded(myArea, newRoom, newRoom);
					newRoom.setDisplayText(DBConnections.getRes(R,"CMDESC1"));
					if(CMProps.getBoolVar(CMProps.Bool.ROOMDNOCACHE))
						newRoom.setDescription("");
					else
						newRoom.setDescription(DBConnections.getRes(R,"CMDESC2"));
					newRoom.setMiscText(DBConnections.getRes(R,"CMROTX"));
					roomSet.put(roomID,newRoom);
				}
				if(((currentRecordPos%updateBreak)==0)&&(reportStatus))
					CMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Loading Rooms ("+currentRecordPos+" of "+recordCount+")");
			}
		}
		catch(final SQLException sqle)
		{
			Log.errOut("Room",sqle);
			return null;
		}
		finally
		{
			DB.DBDone(D);
		}
		return roomSet;
	}

	public void DBReadRoomExits(final String roomID, final Room room, final boolean reportStatus)
	{
		final Map<String,Room> map=new TreeMap<String,Room>();
		map.put(roomID, room);
		DBReadRoomExits(roomID,map,reportStatus,null);
	}

	public void DBReadRoomExits(String roomID, final Map<String, Room> allRooms, final boolean reportStatus, final RoomnumberSet unloadedRooms)
	{
		final List<String> badRoomIDs=new LinkedList<String>();
		DBConnection D=null;
		// now grab the exits
		try
		{
			D=DB.DBFetch();
			if(reportStatus)
				CMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Counting Exits");
			final ResultSet R=D.query("SELECT * FROM CMROEX"+((roomID==null)?"":" WHERE CMROID='"+roomID+"'"));
			Room thisRoom=null;
			Room newRoom=null;
			recordCount=DB.getRecordCount(D,R);
			updateBreak=CMath.s_int("1"+zeroes.substring(0,(""+(recordCount/100)).length()-1));
			while(R.next())
			{
				currentRecordPos=R.getRow();
				roomID=DBConnections.getRes(R,"CMROID");
				final int direction=(int)DBConnections.getLongRes(R,"CMDIRE");
				thisRoom=allRooms.get(roomID);
				if(thisRoom==null)
				{
					if((unloadedRooms!=null)&&(!unloadedRooms.contains(roomID)))
					{
						if((!CMProps.getBoolVar(Bool.MUDSTARTED))
						&&(!CMProps.getBoolVar(Bool.MUDSHUTTINGDOWN)))
							badRoomIDs.add(roomID);
						else
							Log.errOut("Room","Couldn't set "+direction+" exit for unknown room '"+roomID+"'");
					}
				}
				else
				{
					final String exitID=DBConnections.getRes(R,"CMEXID");
					final String exitMiscText=DBConnections.getResQuietly(R,"CMEXTX");
					final String nextRoomID=DBConnections.getRes(R,"CMNRID");
					newRoom=allRooms.get(nextRoomID);
					final Exit newExit=CMClass.getExit(exitID);
					if(nextRoomID.length()==0)
					{
						/* this is likely a room link (rebuilt by import at a later time) */
					}
					else
					if(newRoom==null)
					{
						final int x=nextRoomID.indexOf('#');
						Area otherA=null;
						if((unloadedRooms!=null)&&(unloadedRooms.contains(nextRoomID)))
							otherA=thisRoom.getArea();
						else
						if(x>0)
						{
							otherA=CMLib.map().getArea(nextRoomID.substring(0,x));
							if(otherA!=null)
							{
								if(otherA!=thisRoom.getArea())
									newRoom=otherA.getRoom(nextRoomID);
							}
						}
						else
						{
							for(final Enumeration<Area> a=CMLib.map().areas();a.hasMoreElements();)
							{
								final Area A=a.nextElement();
								if((A!=null)
								&&(A.getProperRoomnumbers().contains(nextRoomID)))
								{
									otherA=A;
									if(!CMath.bset(A.flags(), Area.FLAG_THIN))
										newRoom=otherA.getRoom(nextRoomID);
								}
							}
						}

						if(newRoom!=null)
						{
							/* its all worked out now */
						}
						else
						if(otherA==null)
							Log.errOut("RoomLoader","Unknown area for unlinked room #"+nextRoomID+" in "+roomID);
						else
						if(((unloadedRooms!=null)&&(unloadedRooms.contains(nextRoomID)))
						||(CMath.bset(otherA.flags(),Area.FLAG_THIN)))
						{
							newRoom=CMClass.getLocale("ThinRoom");
							newRoom.setRoomID(nextRoomID);
							newRoom.setArea(otherA);
						}
						else
						if(!nextRoomID.startsWith("#"))
						{
							Log.errOut("RoomLoader","Unknown unlinked room #"+nextRoomID+" in "+roomID);
							if(CMSecurity.isDisabled(CMSecurity.DisFlag.BADEXITS))
								DB.update("DELETE FROM CMROEX WHERE ROOMID='"+roomID+"' AND CMDIRE="+direction);
						}
						else
						if(newExit!=null)
							newExit.setTemporaryDoorLink(nextRoomID);
					}

					if((newExit==null)&&(newRoom==null))
						Log.errOut("Room",roomID+":no room&exit to '"+nextRoomID+"', exit type '"+exitID+"', direction: "+direction);
					else
					if((direction>255)&&(!(thisRoom instanceof GridLocale)))
						Log.errOut("Room","Not GridLocale, tried "+direction+" exit for room '"+roomID+"'");
					else
					if((direction>255)&&(newRoom!=null))
					{
						final List<String> CEs=CMParms.parseSemicolons(exitMiscText.trim(),true);
						for(int ces=0;ces<CEs.size();ces++)
						{
							final Vector<String> SCE=CMParms.parse(CEs.get(ces).trim());
							final GridLocale.CrossExit CE=new GridLocale.CrossExit();
							if(SCE.size()<3)
								continue;
							CE.x=CMath.s_int(SCE.elementAt(0));
							CE.y=CMath.s_int(SCE.elementAt(1));
							final int codeddir=CMath.s_int(SCE.elementAt(2));
							if(SCE.size()>=4)
								CE.destRoomID=newRoom.roomID()+SCE.elementAt(3);
							else
								CE.destRoomID=newRoom.roomID();
							CE.out=(codeddir&256)==256;
							CE.dir=codeddir&255;
							((GridLocale)thisRoom).addOuterExit(CE);
							if((!CE.out)&&(!(newRoom instanceof GridLocale)))
							{
								newRoom.rawDoors()[CE.dir]=thisRoom;
								newRoom.setRawExit(CE.dir,CMClass.getExit("Open"));
							}
						}
					}
					else
					{
						if(newExit!=null)
						{
							newExit.setTemporaryDoorLink("{{#"+roomID+"#}}");
							newExit.setMiscText(exitMiscText);
						}
						if(direction>=Directions.NUM_DIRECTIONS())
							Log.errOut("RoomLoader",CMLib.map().getExtendedRoomID(thisRoom)+" has an invalid direction #"+direction);
						else
						{
							thisRoom.rawDoors()[direction]=newRoom;
							thisRoom.setRawExit(direction,newExit);
							CMLib.map().registerWorldObjectLoaded(thisRoom.getArea(), newRoom, newExit);
						}
					}
				}
				if(reportStatus&&((currentRecordPos%updateBreak)==0))
					CMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Loading Exits ("+currentRecordPos+" of "+recordCount+")");
			}
		}
		catch(final SQLException sqle)
		{
			Log.errOut("Room",sqle);
		}
		finally
		{
			DB.DBDone(D);
		}
		for(final String badRoomId : badRoomIDs)
		{
			Log.errOut("RoomLoader","Deleted exits for unknown room #"+badRoomId);
			DB.update("DELETE FROM CMROEX WHERE CMROID='"+badRoomId+"';");
		}
	}

	public void DBReadAllRooms(final RoomnumberSet set)
	{
		final List<String> newAreasToCreate=new Vector<String>();
		if(set==null)
			DBReadAllAreas();
		if(CMLib.map().numAreas()==0)
			return;

		final RoomnumberSet unloadedRooms=(RoomnumberSet)CMClass.getCommon("DefaultRoomnumberSet");
		final Map<String,Room> rooms=DBReadRoomData(null,set,set==null,newAreasToCreate,unloadedRooms);

		// handle stray areas
		for(final String areaName : newAreasToCreate)
		{
		DBReadContent("CATALOG_ITEMS",null,null,null,true,false);
	}

	public void DBReadContent(String thisRoomID, Room thisRoom, Map<String, Room> rooms, RoomnumberSet unloadedRooms, boolean setStatus, boolean makeLive)
	{
		final boolean debug=Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMPOP));
			}
		}

		DBReadRoomExits(null,rooms,set==null,unloadedRooms);

		final Set<ReadRoomDisableFlag> flags=(set == null) ? RoomLoader.allEnabledReadRoomFlags : RoomLoader.noStatusReadRoomFlags;
		DBReadContent(null,null,rooms,unloadedRooms,flags);
		Hashtable<MOB, String> mobRides=null;

		final boolean catalog=((thisRoomID!=null)&&(thisRoomID.startsWith("CATALOG_")));

		DBConnection D=null;
		// now grab the items
			thisRoom.startItemRejuv();
			thisRoom.recoverRoomStats();
		}

		if(set==null)
		{
			for(final Enumeration<Area> a=CMLib.map().areas();a.hasMoreElements();)
				a.nextElement().getAreaStats();
		}
	}

	public String DBReadRoomDesc(final String roomID)
	{
					continue;
				if((!catalog)&&(roomID.startsWith("CATALOG_")))
					continue;
				itemNums=stuff.itemNums.get("NUMSFOR"+roomID.toUpperCase());
				if(itemNums==null)
				{
				final String txt=DBConnections.getRes(R,"CMDESC2");
				return txt;
			}
		}
		catch(final SQLException sqle)
		{
			Log.errOut("Room",sqle);
		}
		finally
		{
			DB.DBDone(D);
		}
		return null;
	}

	public String DBReadRoomMOBMiscText(final String roomID, final String mobID)
	{
		DBConnection D=null;
		// now grab the items
		try
		{
			D=DB.DBFetch();
			final ResultSet R=D.query("SELECT * FROM CMROCH WHERE CMROID='"+roomID+"'");
			while(R.next())
			{
				final String NUMID=DBConnections.getRes(R,"CMCHNM");
				if(NUMID.equalsIgnoreCase(mobID))
				{
					final String txt=DBConnections.getRes(R,"CMCHTX");
					return txt;
				}
			}
		}
		catch(final SQLException sqle)
		{
			Log.errOut("Room",sqle);
		}
		finally
		{
			DB.DBDone(D);
		}
		return null;
	}

	public MOB DBReadRoomMOB(final String roomID, final String mobID)
	{
		DBConnection D=null;
						}
						else
							newItem.setMiscText(DBConnections.getResQuietly(R,"CMITTX"));
						newItem.basePhyStats().setRejuv((int)DBConnections.getLongRes(R,"CMITRE"));
						newItem.setUsesRemaining((int)DBConnections.getLongRes(R,"CMITUR"));
						newItem.basePhyStats().setLevel((int)DBConnections.getLongRes(R,"CMITLV"));
				if(newMOB==null)
					return null;
				newMOB.setDatabaseID(NUMID);
				if((CMProps.getBoolVar(CMProps.Bool.MOBNOCACHE))
				&&(NUMID.indexOf(MOBID+"@")>=0))
					newMOB.setMiscText("%DBID>"+roomID+NUMID.substring(NUMID.indexOf('@')));
				else
				{
					final String text=DBConnections.getResQuietly(R,"CMCHTX");
					newMOB.setMiscText(text);
				}
				newMOB.basePhyStats().setLevel(((int)DBConnections.getLongRes(R,"CMCHLV")));
				newMOB.basePhyStats().setAbility((int)DBConnections.getLongRes(R,"CMCHAB"));
				newMOB.basePhyStats().setRejuv((int)DBConnections.getLongRes(R,"CMCHRE"));
				newMOB.recoverCharStats();
				newMOB.recoverPhyStats();
				newMOB.recoverMaxState();
				newMOB.resetToMaxState();
				CMLib.threads().deleteAllTicks(newMOB);
				return newMOB;
			}
		}
		catch(final SQLException sqle)
		{
			Log.errOut("Room",sqle);
		}
		finally
		{
			DB.DBDone(D);
		}
		return null;
	}

					continue;
				if((!catalog)&&(roomID.startsWith("CATALOG_")))
					continue;
				final String NUMID=DBConnections.getRes(R,"CMCHNM");
				final String MOBID=DBConnections.getRes(R,"CMCHID");

			if(R.next())
			{
				final String itemID=DBConnections.getRes(R,"CMITID");
				final Item newItem=CMClass.getItem(itemID);
				if(newItem==null)
					Log.errOut("Room","Couldn't find item '"+itemID+"' for room "+roomID);
				else
				{
					newItem.setDatabaseID(itemNum);
					try
					{
						newItem.setMiscText(DBConnections.getResQuietly(R,"CMITTX"));
						newItem.basePhyStats().setRejuv((int)DBConnections.getLongRes(R,"CMITRE"));
						newItem.setUsesRemaining((int)DBConnections.getLongRes(R,"CMITUR"));
						newItem.basePhyStats().setLevel((int)DBConnections.getLongRes(R,"CMITLV"));
						newItem.basePhyStats().setAbility((int)DBConnections.getLongRes(R,"CMITAB"));
						newItem.basePhyStats().setHeight((int)DBConnections.getLongRes(R,"CMHEIT"));
						newItem.recoverPhyStats();
						CMLib.threads().deleteAllTicks(newItem);
						return newItem;
					}
					catch (final Exception e)
					{
						Log.errOut("RoomLoader", e);
					}
				}
			}
		}
		catch(final SQLException sqle)
		{
			Log.errOut("Room",sqle);
		}
		finally
		{
			DB.DBDone(D);
		}
		return null;
	}

	private void fixItemKeys(final Hashtable<Item,String> itemLocs, final Hashtable<String, PhysicalAgent> itemNums)
	{
		for(final Enumeration<Item> e=itemLocs.keys();e.hasMoreElements();)
		{
			final Item keyItem=e.nextElement();
			final String location=itemLocs.get(keyItem);
			final Environmental container=itemNums.get(location);
			if((keyItem instanceof SpaceObject.SpaceGateway)
			&&(container instanceof SpaceObject))
				((SpaceObject)keyItem).setKnownTarget((SpaceObject)container);
			else
			if((container instanceof Container)&&(((Container)container).capacity()>0))
				keyItem.setContainer((Container)container);
			else
			if(container instanceof Rideable)
				keyItem.setRiding((Rideable)container);
			else
						final String ride=DBConnections.getRes(R,"CMCHRI");
						if((ride!=null)&&(ride.length()>0))
							mobRides.put(newMOB,ride);
						newMOB.recoverCharStats();
						newMOB.recoverPhyStats();
						newMOB.recoverMaxState();
			if(ride!=null)
			{
				final boolean rideFlag;
				final PhysicalAgent P;
				if(ride.startsWith("*"))
				{
					P=itemNums.get(ride.substring(1));
					rideFlag=true;
				}
				else
				{
					P=itemNums.get(ride);
					rideFlag=false;
				}
				if(P!=null)
				{
					if((M instanceof Rideable)
					&&(P instanceof Rideable)
					&&(P instanceof MOB)
					&&(!rideFlag))
						M.setFollowing((MOB)P);
					else
					if(P instanceof Rideable)
						M.setRiding((Rideable)P);
					else
					if(P instanceof MOB)
						M.setFollowing((MOB)P);
				}
			}
		}
	}

	private void fixContentContainers(final Hashtable<String,PhysicalAgent> content, final StuffClass stuff, final String roomID, final Room room, final boolean debug, final boolean makeLive)
	{
		String lastName=null;
		Hashtable<Item,String> itemLocs=null;
		Hashtable<MOB, String> mobRides=null;
		if(room != null)
		{
			for(final Enumeration<PhysicalAgent> i=content.elements();i.hasMoreElements();)
			{
				final PhysicalAgent P=i.nextElement();
				if((debug)&&((lastName==null)||(!lastName.equals(P.Name()))))
				{
					lastName=P.Name();
					Log.debugOut("RoomLoader","Loading object(s): "+P.Name());
				}
				if(P instanceof Item)
				{
					room.addItem((Item)P);
					if(makeLive)
						CMLib.map().registerWorldObjectLoaded(room.getArea(), room, P);
				}
				else
				{
					((MOB)P).setStartRoom(room);
					if(makeLive)
						((MOB)P).bringToLife(room,true);
					else
					{
						room.addInhabitant((MOB)P);
						((MOB)P).recoverPhyStats();
						((MOB)P).recoverMaxState();
						((MOB)P).recoverCharStats();
						((MOB)P).resetToMaxState();
					}
				}
			}
		}
		itemLocs=stuff.itemLocs.get("LOCSFOR"+roomID.toUpperCase());
		mobRides=stuff.mobRides.get("RIDESFOR"+roomID.toUpperCase());
		if(itemLocs!=null)
		{
			fixItemKeys(itemLocs,content);
			if(room!=null)
			{
				room.recoverRoomStats();
				room.recoverRoomStats();
			}
		}
		if(mobRides!=null)
			fixMOBRides(mobRides,content);
	}

	public void DBReadCatalogs()
	{
		DBReadContent("CATALOG_MOBS",null,null,null,noLiveReadRoomFlags);
		DBReadContent("CATALOG_ITEMS",null,null,null,noLiveReadRoomFlags);
	}

	public void DBReadSpace()
	{
		DBReadContent("SPACE",null,null,null,noLiveReadRoomFlags);
	}

	public int[] DBCountRoomMobsItems(final String roomID)
	{
		DBConnection D=null;
		final int[] count = new int[] { 0, 0};
		// now grab the items
		try
		{
			D=DB.DBFetch();
			ResultSet R=D.query("SELECT * FROM CMROIT WHERE CMROID='"+roomID+"'");
			count [1] = DB.getRecordCount(D,R);
			R.close();

			R=D.query("SELECT * FROM CMROCH WHERE CMROID='"+roomID+"'");
			count [0] = DB.getRecordCount(D,R);
			R.close();
		}
		catch(final SQLException sqle)
		{
			Log.errOut("Room",sqle);
		}
		finally
		{
			DB.DBDone(D);
		}
		return count;
	}

	public Item DBGetSavedRoomItemCopy(final String roomID, final String itemName)
	{
		DBConnection D=null;
		final Item I=null;
		// now grab the items
		try
		{
			D=DB.DBFetch();
			final ResultSet R=D.query("SELECT * FROM CMROIT WHERE CMROID='"+roomID+"'");
			while(R.next())
			{
				final String itemID=DBConnections.getRes(R,"CMITID");
				final Item newItem=CMClass.getItem(itemID);
				newItem.setMiscText(DBConnections.getResQuietly(R,"CMITTX"));
				newItem.basePhyStats().setRejuv((int)DBConnections.getLongRes(R,"CMITRE"));
				newItem.setUsesRemaining((int)DBConnections.getLongRes(R,"CMITUR"));
				newItem.basePhyStats().setLevel((int)DBConnections.getLongRes(R,"CMITLV"));
				newItem.basePhyStats().setAbility((int)DBConnections.getLongRes(R,"CMITAB"));
				newItem.basePhyStats().setHeight((int)DBConnections.getLongRes(R,"CMHEIT"));
				newItem.recoverPhyStats();
				if(newItem.Name().equalsIgnoreCase(itemName))
					return newItem;
				newItem.destroy();
			}
			R.close();
		}
		catch(final SQLException sqle)
		{
			Log.errOut("Room",sqle);
		}
		finally
		{
			DB.DBDone(D);
		}
		return I;
	}

	public boolean DBIsSavedRoomItemCopy(final String roomID, final String itemName)
	{
		final Item I=this.DBGetSavedRoomItemCopy(roomID, itemName);
		if(I!=null)
		{
			I.destroy();
			return true;
		}
		return false;
	}

	public void DBReadContent(final String thisRoomID, final Room thisRoom, Map<String, Room> rooms, final RoomnumberSet unloadedRooms, final Set<ReadRoomDisableFlag> disableFlags)
	{
		final boolean debug=Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMPOP));
		if(debug||(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS))))
			Log.debugOut("RoomLoader","Reading content of "+((thisRoomID!=null)?thisRoomID:"ALL"));

		final boolean setStatus = (disableFlags == null) || (!disableFlags.contains(ReadRoomDisableFlag.STATUS));
		final boolean makeLive = (disableFlags == null) || (!disableFlags.contains(ReadRoomDisableFlag.LIVE));
		final boolean readMobs = (disableFlags == null) || (!disableFlags.contains(ReadRoomDisableFlag.MOBS));
		final boolean readItems = (disableFlags == null) || (!disableFlags.contains(ReadRoomDisableFlag.ITEMS));

		final StuffClass stuff=new StuffClass();
		Hashtable<String,PhysicalAgent> itemNums=null;
		Hashtable<String,String> cataData=null;
		Hashtable<Item,String> itemLocs=null;
		Hashtable<MOB, String> mobRides=null;

		final boolean catalog=((thisRoomID!=null)&&(thisRoomID.startsWith("CATALOG_")));
		final boolean space=((thisRoomID!=null)&&(thisRoomID.equals("SPACE")));

		DBConnection D=null;

		if(readItems)
		{
			// now grab the items
			try
			{
				D=DB.DBFetch();
				if(setStatus)
					CMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Counting Items");
				final ResultSet R=D.query("SELECT * FROM CMROIT"+((thisRoomID==null)?"":" WHERE CMROID='"+thisRoomID+"'"));
				if(setStatus)
					recordCount=DB.getRecordCount(D,R);
				updateBreak=CMath.s_int("1"+zeroes.substring(0,(""+(recordCount/100)).length()-1));
				while(R.next())
				{
					currentRecordPos=R.getRow();
					final String roomID=DBConnections.getRes(R,"CMROID");
					if((unloadedRooms!=null)&&(unloadedRooms.contains(roomID)))
						continue;
					if((!catalog)&&(roomID.startsWith("CATALOG_")))
						continue;
					if((!space)&&(roomID.startsWith("SPACE")))
						continue;
					itemNums=stuff.itemNums.get("NUMSFOR"+roomID.toUpperCase());
					if(itemNums==null)
					{
						itemNums=new Hashtable<String,PhysicalAgent>();
						stuff.itemNums.put("NUMSFOR"+roomID.toUpperCase(),itemNums);
					}
					itemLocs=stuff.itemLocs.get("LOCSFOR"+roomID.toUpperCase());
					if(itemLocs==null)
					{
						itemLocs=new Hashtable<Item,String>();
						stuff.itemLocs.put("LOCSFOR"+roomID.toUpperCase(),itemLocs);
					}
					final String itemNum=DBConnections.getRes(R,"CMITNM");
					final String itemID=DBConnections.getRes(R,"CMITID");
					final Item newItem=CMClass.getItem(itemID);
					if(newItem==null)
						Log.errOut("Room","Couldn't find item '"+itemID+"' for room "+roomID);
					else
					{
						newItem.setDatabaseID(itemNum);
						itemNums.put(itemNum,newItem);
						final Room room=(rooms!=null)?rooms.get(roomID):thisRoom;
						newItem.setOwner(room); // temporary measure to make sure item behavior thread group is properly assigned
						final String loc=DBConnections.getResQuietly(R,"CMITLO");
						if(loc.length()>0)
						{
							final PhysicalAgent container=itemNums.get(loc);
							if((newItem instanceof SpaceObject.SpaceGateway)
							&&(container instanceof SpaceObject))
								((SpaceObject)newItem).setKnownTarget((SpaceObject)container);
							else
							if(container instanceof Container)
								newItem.setContainer((Container)container);
							else
								itemLocs.put(newItem,loc);
						}
						try
						{
							if(catalog)
							{
								String text=DBConnections.getResQuietly(R,"CMITTX");
								final int x=text.lastIndexOf("<CATALOGDATA");
								if((x>0)&&(text.indexOf("</CATALOGDATA>",x)>0))
								{
									cataData=stuff.cataData.get("CATADATAFOR"+roomID.toUpperCase());
									if(cataData==null)
									{
										cataData=new Hashtable<String,String>();
										stuff.cataData.put("CATADATAFOR"+roomID.toUpperCase(),cataData);
									}
									cataData.put(itemNum,text.substring(x));
									text=text.substring(0,x);
								}
								newItem.setMiscText(text);
							}
							else
								newItem.setMiscText(DBConnections.getResQuietly(R,"CMITTX"));
							if(newItem instanceof SpaceObject)
							{
								CMLib.space().addObjectToSpace((SpaceObject)newItem, ((SpaceObject) newItem).coordinates());
							}
							newItem.basePhyStats().setRejuv((int)DBConnections.getLongRes(R,"CMITRE"));
							newItem.setUsesRemaining((int)DBConnections.getLongRes(R,"CMITUR"));
							newItem.basePhyStats().setLevel((int)DBConnections.getLongRes(R,"CMITLV"));
							newItem.basePhyStats().setAbility((int)DBConnections.getLongRes(R,"CMITAB"));
							newItem.basePhyStats().setHeight((int)DBConnections.getLongRes(R,"CMHEIT"));
							newItem.recoverPhyStats();
						}
						catch (final Exception e)
						{
							Log.errOut("RoomLoader", e);
							itemNums.remove(itemNum);
						}
					}
					if(((currentRecordPos%updateBreak)==0)&&(setStatus))
						CMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Loading Items ("+currentRecordPos+" of "+recordCount+")");
				}
			}
			catch(final SQLException sqle)
			{
				Log.errOut("Room",sqle);
			}
			finally
			{
				DB.DBDone(D);
			}
		}

		if(readMobs)
		{
			// now grab the inhabitants
			try
			{
				D=DB.DBFetch();
				if(setStatus)
					CMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Counting MOBS");
				final ResultSet R=D.query("SELECT * FROM CMROCH"+((thisRoomID==null)?"":" WHERE CMROID='"+thisRoomID+"'"));
				if(setStatus)
					recordCount=DB.getRecordCount(D,R);
				updateBreak=CMath.s_int("1"+zeroes.substring(0,(""+(recordCount/100)).length()-1));
				while(R.next())
				{
					currentRecordPos=R.getRow();
					final String roomID=DBConnections.getRes(R,"CMROID");
					if((unloadedRooms!=null)&&(unloadedRooms.contains(roomID)))
						continue;
					if((!catalog)&&(roomID.startsWith("CATALOG_")))
						continue;
					if((!space) && roomID.equals("SPACE"))
						continue;
					final String NUMID=DBConnections.getRes(R,"CMCHNM");
					final String MOBID=DBConnections.getRes(R,"CMCHID");

					itemNums=stuff.itemNums.get("NUMSFOR"+roomID.toUpperCase());
					if(itemNums==null)
					{
						itemNums=new Hashtable<String,PhysicalAgent>();
						stuff.itemNums.put("NUMSFOR"+roomID.toUpperCase(),itemNums);
					}
					mobRides=stuff.mobRides.get("RIDESFOR"+roomID.toUpperCase());
					if(mobRides==null)
					{
						mobRides=new Hashtable<MOB, String>();
						stuff.mobRides.put("RIDESFOR"+roomID.toUpperCase(),mobRides);
					}

					final MOB newMOB=CMClass.getMOB(MOBID);
					if(newMOB==null)
						Log.errOut("Room","Couldn't find MOB '"+MOBID+"' in room " + roomID);
					else
					{
						final Room room=(rooms!=null)?rooms.get(roomID):thisRoom;
						newMOB.setLocation(room); // temporary measure to make sure thread group is properly assigned
						newMOB.setDatabaseID(NUMID);
						itemNums.put(NUMID,newMOB);
						if(thisRoom!=null)
						{
							newMOB.setStartRoom(thisRoom);
							newMOB.setLocation(thisRoom);
						}
						try
						{
							if((CMProps.getBoolVar(CMProps.Bool.MOBNOCACHE))
							&&(!catalog)
							&&(NUMID.indexOf(MOBID+"@")>=0))
								newMOB.setMiscText("%DBID>"+roomID+NUMID.substring(NUMID.indexOf('@')));
							else
							{
								String text=DBConnections.getResQuietly(R,"CMCHTX");
								if(catalog)
								{
									final int x=text.lastIndexOf("<CATALOGDATA");
									if((x>0)&&(text.indexOf("</CATALOGDATA>",x)>0))
									{
										cataData=stuff.cataData.get("CATADATAFOR"+roomID.toUpperCase());
										if(cataData==null)
										{
											cataData=new Hashtable<String,String>();
											stuff.cataData.put("CATADATAFOR"+roomID.toUpperCase(),cataData);
										}
										cataData.put(NUMID,text.substring(x));
										text=text.substring(0,x);
									}
								}
								newMOB.setMiscText(text);
							}
							newMOB.basePhyStats().setLevel(((int)DBConnections.getLongRes(R,"CMCHLV")));
							newMOB.basePhyStats().setAbility((int)DBConnections.getLongRes(R,"CMCHAB"));
							newMOB.basePhyStats().setRejuv((int)DBConnections.getLongRes(R,"CMCHRE"));
							final String ride=DBConnections.getRes(R,"CMCHRI");
							if((ride!=null)&&(ride.length()>0))
								mobRides.put(newMOB,ride);
							if(newMOB instanceof SpaceObject)
							{
								CMLib.space().addObjectToSpace((SpaceObject)newMOB, ((SpaceObject) newMOB).coordinates());
							}
							newMOB.recoverCharStats();
							newMOB.recoverPhyStats();
							newMOB.recoverMaxState();
							newMOB.resetToMaxState();
						}
						catch (final Exception e)
						{
							Log.errOut("RoomLoader", e);
							itemNums.remove(NUMID);
						}
					}
					if(((currentRecordPos%updateBreak)==0)&&(setStatus))
						CMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Loading MOBs ("+currentRecordPos+" of "+recordCount+")");
				}
			}
			catch(final SQLException sqle)
			{
				Log.errOut("Room",sqle);
			}
			finally
			{
				DB.DBDone(D);
			}
		}
		if(thisRoom!=null)
		{
			rooms=new STreeMap<String,Room>();
			rooms.put(thisRoom.roomID(),thisRoom);
		}
		if(rooms!=null)
			recordCount=rooms.size();
		updateBreak=CMath.s_int("1"+zeroes.substring(0,(""+(recordCount/100)).length()-1));
		currentRecordPos=0;

		itemNums=stuff.itemNums.get("NUMSFORCATALOG_ITEMS");
		cataData=stuff.cataData.get("CATADATAFORCATALOG_ITEMS");
		if((itemNums!=null)&&(thisRoomID!=null)&&(thisRoomID.equals("CATALOG_ITEMS")))
		{
			String itemNum;
			Item I;
			String data;
			fixContentContainers(itemNums,stuff,"CATALOG_ITEMS",null,debug,false);
			for(final Enumeration<String> e=itemNums.keys();e.hasMoreElements();)
			{
				itemNum=e.nextElement();
				I=(Item)itemNums.get(itemNum);
				data=(cataData!=null)?cataData.get(itemNum):null;
				final Item oldI=CMLib.catalog().getCatalogItem(I.Name());
				if((oldI!=null)
				&&(I.databaseID().length()>0)
				&&(!oldI.databaseID().equals(I.databaseID())))
					DBDeleteRoomItem("CATALOG_ITEMS", I);
				else
				{
					CMLib.catalog().submitToCatalog(I);
					if((data!=null)&&(data.length()>0))
					{
						final CatalogLibrary.CataData dataI=CMLib.catalog().getCatalogItemData(I.Name());
						if(dataI!=null)
							dataI.build(data);
					}
				}
			}
		}

		// load mob catalog
		itemNums=stuff.itemNums.get("NUMSFORCATALOG_MOBS");
		cataData=stuff.cataData.get("CATADATAFORCATALOG_MOBS");
		if((itemNums!=null)&&(thisRoomID!=null)&&(thisRoomID.equals("CATALOG_MOBS")))
		{
			String itemNum;
			MOB M;
			String data;
			fixContentContainers(itemNums,stuff,"CATALOG_MOBS",null,debug,false);
			for(final Enumeration<String> e=itemNums.keys();e.hasMoreElements();)
			{
				itemNum=e.nextElement();
				M=(MOB)itemNums.get(itemNum);
				data=(cataData!=null)?cataData.get(itemNum):null;
				final MOB oldM=CMLib.catalog().getCatalogMob(M.Name());
				if((oldM!=null)
				&&(M.databaseID().length()>0)
				&&(!oldM.databaseID().equals(M.databaseID())))
					DBDeleteRoomMOB("CATALOG_MOBS", M);
				else
				{
					CMLib.catalog().submitToCatalog(M);
					if((data!=null)&&(data.length()>0))
					{
						final CatalogLibrary.CataData dataM=CMLib.catalog().getCatalogMobData(M.Name());
						if(dataM!=null)
							dataM.build(data);
					}
				}
			}
		}

		// now load the rooms
		if(rooms!=null)
		{
			CMProps.setBoolAllVar(CMProps.Bool.POPULATIONSTARTED, true);
			recordCount = rooms.size();
			for(final Map.Entry<String,Room> entry : rooms.entrySet())
			{
				if((((++currentRecordPos)%updateBreak)==0)&&(setStatus))
					CMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Populating Rooms ("+(currentRecordPos)+" of "+((recordCount==1)?"?":Integer.toString(recordCount))+")");
				final Room room=entry.getValue();
				if(debug)
					Log.debugOut("RoomLoader","Populating room: "+room.roomID());
				itemNums=stuff.itemNums.get("NUMSFOR"+room.roomID().toUpperCase());
				if(itemNums!=null)
					fixContentContainers(itemNums,stuff,room.roomID(),room,debug,makeLive);
			}
		}
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Done reading content of "+((thisRoomID!=null)?thisRoomID:"ALL"));
	}

	private List<Item> DBGetContents(final Room room)
	{
		if((!room.isSavable())||(room.amDestroyed()))
			return new Vector<Item>();
		final List<Item> contents=new Vector<Item>();
		for(int i=0;i<room.numItems();i++)
		{
			final Item thisItem=room.getItem(i);
			if((thisItem!=null)
			&&(!contents.contains(thisItem))
			&&thisItem.isSavable())
				contents.add(thisItem);
		}
		return contents;
	}

	protected List<String> DBReadAreaRoomIDs(final String areaName)
	{
		final List<String> lst=new ArrayList<String>();
		DBConnection D=null;
		try
		{
			D=DB.DBFetch();
			final ResultSet R=D.query("SELECT CMROID FROM CMROOM WHERE CMAREA='"+DB.injectionClean(areaName)+"'");
			while(R.next())
			{
				final String roomID=R.getString("CMROID");
				lst.add(roomID);
			}
			R.close();
		}
		catch(final SQLException sqle)
		{
			Log.errOut("Area",sqle);
		}
		finally
		{
			DB.DBDone(D);
		}
		return lst;
	}

	public RoomContent[] DBReadAreaMobs(final String name)
	{
		final List<RoomContent> lst=new ArrayList<RoomContent>();
		final List<String> roomIDs = DBReadAreaRoomIDs(name);
		final GenericBuilder buildLib = CMLib.coffeeMaker();
		DBConnection D=null;
		try
		{
			D=DB.DBFetch();
			for(final String roomID : roomIDs)
			{
				final ResultSet R=D.query("SELECT * FROM CMROCH WHERE CMROID='"+DB.injectionClean(roomID)+"'");
				while(R.next())
				{
					int buildHash = 0;
					final String classID = DB.getRes(R, "CMCHID");
					final String text = DB.getRes(R, "CMCHTX");
					final String qName = buildLib.getQuickName(classID, text);
					buildHash = classID.hashCode() ^ text.hashCode();
					buildHash ^= (int)DB.getLongRes(R, "CMCHLV");
					buildHash ^= (int)DB.getLongRes(R, "CMCHAB");
					final int finalHash = buildHash;
					final RoomContent C=new RoomContent()
					{
						final String roomId = roomID;
						final String roomKey = DB.getRes(R, "CMCHNM");
						final String classId = classID;
						final String name = qName;
						final int hashCode = finalHash;

						@Override
						public String ID()
						{
							return classId;
						}

						@Override
						public String name()
						{
							return name;
						}

						@Override
						public String roomID()
						{
							return roomId;
						}

						@Override
						public String dbKey()
						{
							return roomKey;
						}

						@Override
						public int contentHash()
						{
							return hashCode;
						}
					};
					lst.add(C);

				}
				R.close();
			}
		}
		catch(final SQLException sqle)
		{
			Log.errOut("Area",sqle);
		}
		finally
		{
			DB.DBDone(D);
		}
		return lst.toArray(new RoomContent[lst.size()]);
	}

	public RoomContent[] DBReadAreaItems(final String name)
	{
		final List<RoomContent> lst=new ArrayList<RoomContent>();
		final List<String> roomIDs = DBReadAreaRoomIDs(name);
		final GenericBuilder buildLib = CMLib.coffeeMaker();
		DBConnection D=null;
		try
		{
			D=DB.DBFetch();
			for(final String roomID : roomIDs)
			{
				final ResultSet R=D.query("SELECT * FROM CMROIT WHERE CMROID='"+DB.injectionClean(roomID)+"'");
				while(R.next())
				{
					int buildHash = 0;
					final String classID = DB.getRes(R, "CMITID");
					final String text = DB.getRes(R, "CMITTX");
					final String qName = buildLib.getQuickName(classID, text);
					buildHash = classID.hashCode() ^ text.hashCode();
					buildHash ^= (int)DB.getLongRes(R, "CMITLV");
					buildHash ^= (int)DB.getLongRes(R, "CMITAB");
					buildHash ^= (int)DB.getLongRes(R, "CMITUR");
					buildHash ^= (int)DB.getLongRes(R, "CMHEIT");
					final int finalHash = buildHash;
					final RoomContent C=new RoomContent()
					{
						final String roomId = roomID;
						final String roomKey = DB.getRes(R, "CMITNM");
						final String classId = classID;
						final String name = qName;
						final int hashCode = finalHash;

						@Override
						public String ID()
						{
							return classId;
						}

						@Override
						public String name()
						{
							return name;
						}

						@Override
						public String roomID()
						{
							return roomId;
						}

						@Override
						public String dbKey()
						{
							return roomKey;
						}

						@Override
						public int contentHash()
						{
							return hashCode;
						}
					};
					lst.add(C);

				}
				R.close();
			}
		}
		catch(final SQLException sqle)
		{
			Log.errOut("Area",sqle);
		}
		finally
		{
			DB.DBDone(D);
		}
		return lst.toArray(new RoomContent[lst.size()]);
	}

	protected String getShortID(final Environmental E)
	{
		final String classID = ""+E;
		final int x=classID.indexOf('@');
		if(x<0)
			return E.ID()+"@"+classID.hashCode()+Math.random();
		else
			return E.ID()+classID.substring(0, x).hashCode()+classID.substring(x);
	}

	protected Pair<String,String> getDBCreateItemString(final String roomID, final Item thisItem)
	{
		final boolean catalog=((roomID!=null)&&(roomID.startsWith("CATALOG_")));
		thisItem.setExpirationDate(0); // saved items won't clear!
		Environmental container=thisItem.container();
		if((container==null)
		&&(thisItem.riding()!=null)
		&&(thisItem.riding().isSavable()))
		{
			final Room room=CMLib.map().roomLocation(thisItem);
			if(((room!=null)&&(room.isHere(thisItem.riding())))
			||(CMLib.catalog().isCatalogObj(thisItem.riding())))
				container=thisItem.riding();
		}
		final String itemID=getShortID(thisItem);
		thisItem.setDatabaseID(itemID);
		String text=thisItem.text();
		if(catalog)
		{
			final CatalogLibrary.CataData dataI=CMLib.catalog().getCatalogItemData(thisItem.Name());
			if(dataI!=null)
				text+=dataI.data(null);
		}
		return new Pair<String,String>(
		"INSERT INTO CMROIT ("
		+"CMROID, "
		+"CMITNM, "
		+"CMITID, "
		+"CMITLO, "
		+"CMITTX, "
		+"CMITRE, "
		+"CMITUR, "
		+"CMITLV, "
		+"CMITAB, "
		+"CMHEIT"
		+") values ("
		+"'"+roomID+"',"
		+"'"+itemID+"',"
		+"'"+thisItem.ID()+"',"
		+"'"+((container!=null)?(""+getShortID(container)):"")+"',"
		+"?,"
		+thisItem.basePhyStats().rejuv()+","
		+thisItem.usesRemaining()+","
		+thisItem.basePhyStats().level()+","
		+thisItem.basePhyStats().ability()+","
		+thisItem.basePhyStats().height()+")",
		text+" ");
	}

	public void DBCreateThisItem(final String roomID, final Item thisItem)
	{
		final Pair<String,String> sql=getDBCreateItemString(roomID,thisItem);
		final DBPreparedBatchEntry entry = new DBPreparedBatchEntry(sql.first,sql.second);
		DB.updateWithClobs(entry);
	}

	public void DBUpdateTheseItems(final Room room, final List<Item> items)
	{
		if((!room.isSavable())||(room.amDestroyed()))
			return;
		final boolean useBulkInserts = DB.useBulkInserts();
		final StringBuilder bulkSQL = new StringBuilder("");
		final List<String> bulkClobs = new ArrayList<String>();
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROIT)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Start item update for room "+room.roomID());
		final List<DBPreparedBatchEntry> statements=new Vector<DBPreparedBatchEntry>();
		statements.add(new DBPreparedBatchEntry("DELETE FROM CMROIT WHERE CMROID='"+room.roomID()+"'"));
		for(int i=0;i<items.size();i++)
		{
			final Item thisItem=items.get(i);
			CMLib.map().registerWorldObjectLoaded(room.getArea(), room, thisItem);
			final Pair<String,String> sqlpair=getDBCreateItemString(room.roomID(),thisItem);
			if(!useBulkInserts)
				statements.add(new DBPreparedBatchEntry(sqlpair.first,sqlpair.second));
			else
			{
				final DBPreparedBatchEntry entry = doBulkInsert(bulkSQL,bulkClobs,sqlpair.first,sqlpair.second);
				if(entry != null)
					statements.add(entry);
			}
		}
		if((bulkSQL.length()>0) && useBulkInserts)
			statements.add(new DBPreparedBatchEntry(bulkSQL.toString(),bulkClobs.toArray(new String[0])));
		DB.updateWithClobs(statements);
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROIT)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Finished items update for room "+room.roomID());
	}

	public void DBUpdateItems(final Room room)
	{
		if((!room.isSavable())||(room.amDestroyed()))
			return;
		DBUpdateTheseItems(room,DBGetContents(room));
	}

	public void DBUpdateExitsNEW(final Room room)
	{
		if((!room.isSavable())||(room.amDestroyed()))
			return;
		final String baseRoomID = room.roomID();
		if(baseRoomID.length()==0)
			return;
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROEX)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Starting exit update for room "+baseRoomID);
		DBConnection D=null;
		final Set<Integer> dirs = new HashSet<Integer>();
		try
		{
			D=DB.DBFetch();
			final ResultSet R=D.query("SELECT CMDIRE FROM CMROEX WHERE CMROID = '"+baseRoomID+"'");
			while(R.next())
				dirs.add(Integer.valueOf(R.getInt("CMDIRE")));
			R.close();
		}
		catch(final SQLException sqle)
		{
			Log.errOut("RoomLoader",sqle);
		}
		finally
		{
			DB.DBDone(D);
		}
		final List<DBPreparedBatchEntry> statements=new Vector<DBPreparedBatchEntry>();
		final boolean useBulkInserts = DB.useBulkInserts();
		final StringBuilder bulkSQL = new StringBuilder("");
		final List<String> bulkClobs = new ArrayList<String>();
		for(int d=Directions.NUM_DIRECTIONS()-1;d>=0;d--)
		{
			Exit linkE=room.getRawExit(d);
			Room linkR=room.rawDoors()[d];

			if((linkE!=null)&&(!linkE.isSavable()))
				linkE=null;
			if((linkR!=null)&&(!linkR.isSavable()))
				linkR=null;
			if((linkR!=null)||(linkE!=null))
			{
				CMLib.map().registerWorldObjectLoaded(room.getArea(), room, linkE);
				final String fullSQL;
				final String exitText = (linkE==null)?" ":linkE.text();
				if(dirs.contains(Integer.valueOf(d)))
				{
					fullSQL ="UPDATE CMROEX SET "
							+"CMEXID='"+((linkE==null)?" ":linkE.ID())+"', "
							+"CMEXTX=?, "
							+"CMNRID='"+((linkR==null)?" ":linkR.roomID())+"'"
							+" WHERE CMROID='"+baseRoomID+"' and CMDIRE="+d;
					dirs.remove(Integer.valueOf(d));
					statements.add(new DBPreparedBatchEntry(fullSQL,exitText));
				}
				else
				{
					fullSQL ="INSERT INTO CMROEX ("
							+"CMROID, "
							+"CMDIRE, "
							+"CMEXID, "
							+"CMEXTX, "
							+"CMNRID"
							+") values ("
							+"'"+baseRoomID+"',"
							+d+","
							+"'"+((linkE==null)?" ":linkE.ID())+"',"
							+"?,"
							+"'"+((linkR==null)?" ":linkR.roomID())+"')";
					if(!useBulkInserts)
						statements.add(new DBPreparedBatchEntry(fullSQL,exitText));
					else
					{
						final DBPreparedBatchEntry entry = doBulkInsert(bulkSQL,bulkClobs,fullSQL,exitText);
						if(entry != null)
							statements.add(entry);
					}
				}
			}
		}
		if(room instanceof GridLocale)
		{
			final HashSet<String> done=new HashSet<String>();
			int ordinal=0;
			for(final Iterator<GridLocale.CrossExit> i=((GridLocale)room).outerExits();i.hasNext();)
			{
				final GridLocale.CrossExit CE=i.next();
				Room R=CMLib.map().getRoom(CE.destRoomID);
				if(R==null)
					continue;
				if(R.getGridParent()!=null)
					R=R.getGridParent();
				if((R!=null)&&(R.isSavable())&&(!done.contains(R.roomID())))
				{
					done.add(R.roomID());
					final HashSet<String> oldStrs=new HashSet<String>();
					for(final Iterator<GridLocale.CrossExit> i2=((GridLocale)room).outerExits();i2.hasNext();)
					{
						final GridLocale.CrossExit CE2=i2.next();
						if((CE2.destRoomID.equals(R.roomID())
						||(CE2.destRoomID.startsWith(R.roomID()+"#("))))
						{
							final String str=CE2.x+" "+CE2.y+" "+((CE2.out?256:512)|CE2.dir)+" "+CE2.destRoomID.substring(R.roomID().length())+";";
							if(!oldStrs.contains(str))
								oldStrs.add(str);
						}
					}
					final StringBuffer exitStr=new StringBuffer("");
					for (final String string : oldStrs)
						exitStr.append(string);
					final String fullSQL;
					final int d = (256+(++ordinal));
					final String exitText = exitStr.toString();
					if(dirs.contains(Integer.valueOf(d)))
					{
						fullSQL ="UPDATE CMROEX SET "
								+"CMEXID='Open', "
								+"CMEXTX=?, "
								+"CMNRID='"+R.roomID()+"'"
								+" WHERE CMROID='"+baseRoomID+"' and CMDIRE="+d;
						dirs.remove(Integer.valueOf(d));
						statements.add(new DBPreparedBatchEntry(fullSQL,exitText));
					}
					else
					{
						fullSQL =
						"INSERT INTO CMROEX ("
						+"CMROID, "
						+"CMDIRE, "
						+"CMEXID, "
						+"CMEXTX, "
						+"CMNRID"
						+") values ("
						+"'"+baseRoomID+"',"
						+d+","
						+"'Open',"
						+"?,"
						+"'"+R.roomID()+"')";
						if(!useBulkInserts)
							statements.add(new DBPreparedBatchEntry(fullSQL,exitText));
						else
						{
							final DBPreparedBatchEntry entry = doBulkInsert(bulkSQL,bulkClobs,fullSQL,exitText);
							if(entry != null)
								statements.add(entry);
						}
					}
				}
			}
		}
		if((bulkSQL.length()>0) && useBulkInserts)
			statements.add(new DBPreparedBatchEntry(bulkSQL.toString(),bulkClobs.toArray(new String[0])));
		for(final Integer d : dirs)
		{
			final String fullSQL;
			fullSQL = "DELETE FROM CMROEX  WHERE CMROID='"+baseRoomID+"' and CMDIRE="+d;
			statements.add(new DBPreparedBatchEntry(fullSQL));
		}
		DB.updateWithClobs(statements);
		if(Log.debugChannelOn()
		&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROEX)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Finished exit update for room "+baseRoomID);
	}

	public void DBUpdateExits(final Room room)
	{
		if((!room.isSavable())||(room.amDestroyed()))
			return;

		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROEX)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Starting exit update for room "+room.roomID());
		final List<DBPreparedBatchEntry> statements=new Vector<DBPreparedBatchEntry>();
		final boolean useBulkInserts = DB.useBulkInserts();
		final StringBuilder bulkSQL = new StringBuilder("");
		final List<String> bulkClobs = new ArrayList<String>();
		statements.add(new DBPreparedBatchEntry("DELETE FROM CMROEX WHERE CMROID='"+room.roomID()+"'"));
		for(int d=Directions.NUM_DIRECTIONS()-1;d>=0;d--)
		{
			Exit linkE=room.getRawExit(d);
			Room linkR=room.rawDoors()[d];

			if((linkE!=null)&&(!linkE.isSavable()))
				linkE=null;
			if((linkR!=null)
			&&(!linkR.isSavable())
			&&(!linkR.ID().equals("ThinRoom")))
				linkR=null;
			if((linkR!=null)||(linkE!=null))
			{
				CMLib.map().registerWorldObjectLoaded(room.getArea(), room, linkE);
				final String fullSQL ="INSERT INTO CMROEX ("
						+"CMROID, "
						+"CMDIRE, "
						+"CMEXID, "
						+"CMEXTX, "
						+"CMNRID"
						+") values ("
						+"'"+room.roomID()+"',"
						+d+","
						+"'"+((linkE==null)?" ":linkE.ID())+"',"
						+"?,"
						+"'"+((linkR==null)?" ":linkR.roomID())+"')";
				final String exitText = (linkE==null)?" ":linkE.text();
				if(!useBulkInserts)
					statements.add(new DBPreparedBatchEntry(fullSQL,exitText));
				else
				{
					final DBPreparedBatchEntry entry = doBulkInsert(bulkSQL,bulkClobs,fullSQL,exitText);
					if(entry != null)
						statements.add(entry);
				}
			}
		}
		if(room instanceof GridLocale)
		{
			final HashSet<String> done=new HashSet<String>();
			int ordinal=0;
			for(final Iterator<GridLocale.CrossExit> i=((GridLocale)room).outerExits();i.hasNext();)
			{
				final GridLocale.CrossExit CE=i.next();
				Room R=CMLib.map().getRoom(CE.destRoomID);
				if(R==null)
					continue;
				if(R.getGridParent()!=null)
					R=R.getGridParent();
				if((R!=null)&&(R.isSavable())&&(!done.contains(R.roomID())))
				{
					done.add(R.roomID());
					final HashSet<String> oldStrs=new HashSet<String>();
					for(final Iterator<GridLocale.CrossExit> i2=((GridLocale)room).outerExits();i2.hasNext();)
					{
						final GridLocale.CrossExit CE2=i2.next();
						if((CE2.destRoomID.equals(R.roomID())
						||(CE2.destRoomID.startsWith(R.roomID()+"#("))))
						{
							final String str=CE2.x+" "+CE2.y+" "+((CE2.out?256:512)|CE2.dir)+" "+CE2.destRoomID.substring(R.roomID().length())+";";
							if(!oldStrs.contains(str))
								oldStrs.add(str);
						}
					}
					final StringBuffer exitStr=new StringBuffer("");
					for (final String string : oldStrs)
						exitStr.append(string);
					final String fullSQL =
					"INSERT INTO CMROEX ("
					+"CMROID, "
					+"CMDIRE, "
					+"CMEXID, "
					+"CMEXTX, "
					+"CMNRID"
					+") values ("
					+"'"+room.roomID()+"',"
					+(256+(++ordinal))+","
					+"'Open',"
					+"?,"
					+"'"+R.roomID()+"')";
					final String exitText = exitStr.toString();
					if(!useBulkInserts)
						statements.add(new DBPreparedBatchEntry(fullSQL,exitText));
					else
					{
						final DBPreparedBatchEntry entry = doBulkInsert(bulkSQL,bulkClobs,fullSQL,exitText);
						if(entry != null)
							statements.add(entry);
					}
				}
			}
		}
		if((bulkSQL.length()>0) && useBulkInserts)
			statements.add(new DBPreparedBatchEntry(bulkSQL.toString(),bulkClobs.toArray(new String[0])));
		DB.updateWithClobs(statements);
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROEX)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Finished exit update for room "+room.roomID());
	}

	public void DBCreateThisMOB(final String roomID, final MOB thisMOB)
	{
		final Pair<String,String> sql= getDBCreateMOBString(roomID,thisMOB);
		final DBPreparedBatchEntry entry = new DBPreparedBatchEntry(sql.first,sql.second);
		DB.updateWithClobs(entry);
	}

	public Pair<String,String> getDBCreateMOBString(final String roomID, final MOB thisMOB)
	{
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROCH)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Creating mob "+thisMOB.name()+" for room "+roomID);
		final boolean catalog=((roomID!=null)&&(roomID.startsWith("CATALOG_")));

		String ride=null;
		final String mobID=this.getShortID(thisMOB);
		thisMOB.setDatabaseID(mobID);
		if(thisMOB.riding()!=null)
			ride="*"+this.getShortID(thisMOB.riding());
		else
		if(thisMOB.amFollowing()!=null)
			ride=this.getShortID(thisMOB.amFollowing());
		else
			ride="";

		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROCH)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Created mob "+thisMOB.name()+" for room "+roomID);

		if((CMProps.getBoolVar(CMProps.Bool.MOBNOCACHE))&&(!catalog))
			thisMOB.setMiscText("%DBID>"+roomID+mobID.substring(mobID.indexOf('@')));

		String text=thisMOB.text();
		if(catalog)
		{
			final CatalogLibrary.CataData dataM=CMLib.catalog().getCatalogMobData(thisMOB.Name());
			if(dataM!=null)
				text+=dataM.data(null);
		}
		return new Pair<String,String>(
		"INSERT INTO CMROCH ("
		+"CMROID, "
		+"CMCHNM, "
		+"CMCHID, "
		+"CMCHTX, "
		+"CMCHLV, "
		+"CMCHAB, "
		+"CMCHRE, "
		+"CMCHRI "
		+") values ("
		+"'"+roomID+"',"
		+"'"+mobID+"',"
		+"'"+CMClass.classID(thisMOB)+"',"
		+"?,"
		+thisMOB.basePhyStats().level()+","
		+thisMOB.basePhyStats().ability()+","
		+thisMOB.basePhyStats().rejuv()+","
		+"'"+ride+"'"
		+")",
		text+" ");
	}

	public void DBUpdateTheseMOBs(final Room room, List<MOB> mobs)
	{
		if((!room.isSavable())||(room.amDestroyed()))
			return;
		final boolean useBulkInserts = DB.useBulkInserts();
		final StringBuilder bulkSQL = new StringBuilder("");
		final List<String> bulkClobs = new ArrayList<String>();
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROCH)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Updating mobs for room "+room.roomID());
		if(mobs==null)
			mobs=new ArrayList<MOB>();
		final List<DBPreparedBatchEntry> statements=new ArrayList<DBPreparedBatchEntry>();
		statements.add(new DBPreparedBatchEntry("DELETE FROM CMROCH WHERE CMROID='"+room.roomID()+"'"));
		for(int m=0;m<mobs.size();m++)
		{
			final MOB thisMOB=mobs.get(m);
			CMLib.map().registerWorldObjectLoaded(room.getArea(), room, thisMOB);
			final Pair<String,String> sqlpair= getDBCreateMOBString(room.roomID(),thisMOB);
			if(!useBulkInserts)
				statements.add(new DBPreparedBatchEntry(sqlpair.first,sqlpair.second));
			else
			{
				final DBPreparedBatchEntry entry = doBulkInsert(bulkSQL,bulkClobs,sqlpair.first,sqlpair.second);
				if(entry != null)
					statements.add(entry);
			}
		}
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROCH)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Done updating mobs for room "+room.roomID());
		if((bulkSQL.length()>0) && useBulkInserts)
			statements.add(new DBPreparedBatchEntry(bulkSQL.toString(),bulkClobs.toArray(new String[0])));
		DB.updateWithClobs(statements);
	}

	public void DBUpdateMOBs(final Room room)
	{
		if((!room.isSavable())||(room.amDestroyed()))
			return;
		final List<MOB> mobs=new ArrayList<MOB>();
		for(int m=0;m<room.numInhabitants();m++)
		{
			final MOB thisMOB=room.fetchInhabitant(m);
			if((thisMOB!=null)&&(thisMOB.isSavable()))
				mobs.add(thisMOB);
		}
		DBUpdateTheseMOBs(room,mobs);
	}

	public void DBUpdateAll(final Room room)
	{
		if((!room.isSavable())||(room.amDestroyed()))
			return;
		DBUpdateRoom(room);
		DBUpdateMOBs(room);
		DBUpdateExits(room);
		DBUpdateItems(room);
	}

	public void DBUpdateRoom(final Room room)
	{
		if((!room.isSavable())||(room.amDestroyed()))
			return;
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROOM)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Start updating room "+room.roomID());
		CMLib.map().registerWorldObjectLoaded(room.getArea(), room, room);
		DB.updateWithClobs(
		"UPDATE CMROOM SET "
		+"CMLOID='"+CMClass.classID(room)+"',"
		+"CMAREA='"+room.getArea().Name()+"',"
		+"CMDESC1='"+room.displayText().replace('\'', '`')+" ',"
		+"CMDESC2=?,"
		+"CMROTX=? "
		+"WHERE CMROID='"+room.roomID()+"'",
		new String[]{room.description()+" ",room.text()+" "});
		if(CMProps.getBoolVar(CMProps.Bool.ROOMDNOCACHE))
			room.setDescription("");
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROOM)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Done updating room "+room.roomID());
	}

	public void DBReCreate(final Room room, final String oldID)
	{
		if((!room.isSavable())||(room.amDestroyed()))
			return;
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROOM)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Recreating room "+room.roomID());

		DB.update(
		"UPDATE CMROOM SET "
		+"CMROID='"+room.roomID()+"', "
		+"CMAREA='"+room.getArea().Name()+"' "
		+"WHERE CMROID='"+oldID+"'");

		if(CMProps.getBoolVar(CMProps.Bool.MOBNOCACHE))
		{
			for(int m=0;m<room.numInhabitants();m++)
			{
				final MOB M=room.fetchInhabitant(m);
				if((M!=null)&&(M.isSavable()))
					M.setMiscText(M.text());
			}

		}
		DB.update(
		"UPDATE CMROCH SET "
		+"CMROID='"+room.roomID()+"' "
		+"WHERE CMROID='"+oldID+"'");

		DB.update(
		"UPDATE CMROEX SET "
		+"CMROID='"+room.roomID()+"' "
		+"WHERE CMROID='"+oldID+"'");

		DB.update(
		"UPDATE CMROEX SET "
		+"CMNRID='"+room.roomID()+"' "
		+"WHERE CMNRID='"+oldID+"'");

		DB.update(
		"UPDATE CMROIT SET "
		+"CMROID='"+room.roomID()+"' "
		+"WHERE CMROID='"+oldID+"'");

		CMLib.database().DBUpdatePlayerStartRooms(oldID, room.roomID());

		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROOM)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Done recreating room "+room.roomID());
	}

	public void DBCreate(final Area A)
	{
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMAREA)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Creating area "+A.name());
		if((A==null)||(A.name().length()==0))
		{
			Log.errOut("RoomLoader","Unable to create area "+((A!=null)?A.name():"null"));
			return;
		}

		CMLib.map().registerWorldObjectLoaded(A, null, A);

		DB.updateWithClobs(
		"INSERT INTO CMAREA ("
		+"CMAREA,"
		+"CMTYPE,"
		+"CMCLIM,"
		+"CMSUBS,"
		+"CMDESC,"
		+"CMROTX,"
		+"CMTECH"
		+") values ("
		+"'"+A.Name()+"',"
		+"'"+A.ID()+"',"
		+""+A.getClimateTypeCode()+","
		+"'"+A.getSubOpList()+"',"
		+"?,"
		+"?,"
		+A.getThemeCode()+")",
		new String[][]{{A.description()+" ",A.text()+" "}});
		A.setAreaState(Area.State.ACTIVE);
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMAREA)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Done creating area "+A.name());
	}

	public void DBUpdate(final String areaID, final Area A)
	{
		if((A==null)||(!A.isSavable()))
			return;
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMAREA)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Updating area "+A.name());
		final boolean ignoreType=CMSecurity.isDisabled(CMSecurity.DisFlag.FATAREAS)||CMSecurity.isDisabled(CMSecurity.DisFlag.THINAREAS);
		CMLib.map().registerWorldObjectLoaded(A, null, A);
		DB.updateWithClobs(
		"UPDATE CMAREA SET "
		+"CMAREA='"+A.Name()+"',"
		+(ignoreType?"":"CMTYPE='"+A.ID()+"',")
		+"CMCLIM="+A.getClimateTypeCode()+","
		+"CMSUBS='"+A.getSubOpList()+"',"
		+"CMDESC=?,"
		+"CMROTX=?,"
		+"CMTECH="+A.getThemeCode()+" "
		+"WHERE CMAREA='"+areaID+"'",
		new String[]{A.description()+" ",A.text()+" "});
		if(Log.debugChannelOn()
		&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMAREA)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Done updating area "+A.name());
	}

	public void DBDeleteRoomItem(final String roomID, final Item item)
	{
		String keyName=item.databaseID();
		if(keyName.length()==0)
			keyName=this.getShortID(item);
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROIT)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Done updating item "+item.name()+" in room "+roomID);
		DB.update(
		"DELETE FROM CMROIT "
		+"WHERE CMROID='"+roomID+"' "
		+"AND CMITNM='"+keyName+"'");
	}

	public void DBUpdateRoomItem(final String roomID, final Item item)
	{
		if((roomID==null)||(!item.isSavable())||(item.amDestroyed()))
			return;
		synchronized(CMClass.getSync("SYNC"+roomID.toUpperCase()))
		{
			DBDeleteRoomItem(roomID,item);
			if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROIT)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
				Log.debugOut("RoomLoader","Continue updating item "+item.name()+" in room "+roomID);
			DBCreateThisItem(roomID,item);
			if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROIT)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
				Log.debugOut("RoomLoader","Done updating item "+item.name()+" in room "+roomID);
		}
	}

	public void DBDeleteRoomMOB(final String roomID, final MOB mob)
	{
		String keyName=mob.databaseID();
		if(keyName.length()==0)
			keyName=this.getShortID(mob);
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROCH)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Done updating mob "+mob.name()+" in room "+roomID);
		DB.update(
		"DELETE FROM CMROCH "
		+"WHERE CMROID='"+roomID+"' "
		+"AND CMCHNM='"+keyName+"'");
	}

	public void DBUpdateRoomMOB(final String roomID, final MOB mob)
	{
		if((roomID==null)||(!mob.isSavable())||(mob.amDestroyed()))
			return;
		DBDeleteRoomMOB(roomID, mob);
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROCH)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Continue updating mob "+mob.name()+" in room "+roomID);
		DBCreateThisMOB(roomID,mob);
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROCH)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Done updating mob "+mob.name()+" in room "+roomID);
	}

	public void DBCreate(final Room room)
	{
		if(!room.isSavable())
			return;
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROOM)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Creating new room "+room.roomID());
		CMLib.map().registerWorldObjectLoaded(room.getArea(), room, room);
		DB.updateWithClobs(
		"INSERT INTO CMROOM ("
		+"CMROID,"
		+"CMLOID,"
		+"CMAREA,"
		+"CMDESC1,"
		+"CMDESC2,"
		+"CMROTX"
		+") values ("
		+"'"+room.roomID()+"',"
		+"'"+CMClass.classID(room)+"',"
		+"'"+room.getArea().Name()+"',"
		+"'"+room.displayText()+" ',"
		+"?,"
		+"?)",
		new String[][]{{room.description()+" ",room.text()+" "}});
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROOM)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Done creating new room "+room.roomID());
	}

	protected List<String> getRoomDeleteStrings(final String roomID)
	{
		return new XVector<String>(
			"DELETE FROM CMROEX WHERE CMROID='"+roomID+"'",
			"DELETE FROM CMROCH WHERE CMROID='"+roomID+"'",
			"DELETE FROM CMROIT WHERE CMROID='"+roomID+"'"
		);
	}

	public void DBDelete(final Room room)
	{
		if(!room.isSavable())
			return;
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROCH)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Destroying room "+room.roomID());
		DB.update(getRoomDeleteStrings(room.roomID()).toArray(new String[0]));
		DB.update("DELETE FROM CMROOM WHERE CMROID='"+room.roomID()+"'");
		room.destroy();
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROCH)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Done gestroying room "+room.roomID());
	}

	protected List<String> getAreaDeleteStrings(final String areaName)
	{
		return new XVector<String>(
			"DELETE FROM CMAREA WHERE CMAREA='"+areaName+"'",
			"DELETE FROM CMPDAT WHERE CMPLID='"+areaName+"' AND CMSECT='TIMECLOCK'"
		);
	}

	public void DBDelete(final Area A)
	{
		if(A==null)
			return;
		if(!A.isSavable())
			return;
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMAREA)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Destroying area "+A.name());
		A.setAreaState(Area.State.STOPPED);
		DB.update(getAreaDeleteStrings(A.Name()).toArray(new String[0]));
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMAREA)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Done destroying area "+A.name()+".");
	}

	public void DBDeleteAreaAndRooms(final Area A)
	{
		if(A==null)
			return;
		if(!A.isSavable())
			return;
		if(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMAREA)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))
			Log.debugOut("RoomLoader","Destroying area "+A.name());
		A.setAreaState(Area.State.STOPPED);
		final List<String> statements = new Vector<String>(4 + A.numberOfProperIDedRooms());
		statements.addAll(getAreaDeleteStrings(A.Name()));
		statements.add("DELETE FROM CMROOM WHERE CMAREA='"+A.Name()+"'");
		for(final Enumeration<String> ids=A.getProperRoomnumbers().getRoomIDs();ids.hasMoreElements();)
			statements.addAll(getRoomDeleteStrings(ids.nextElement()));
		statements.add("DELETE FROM CMROOM WHERE CMAREA='"+A.Name()+"'");
		final String[] statementsBlock = statements.toArray(new String[statements.size()]);
		statements.clear();
		for(int i=0;i<3;i++)
		{
			// not even mysql delete everything as commanded.
			DB.update(statementsBlock);
			try
			{
				Thread.sleep(A.numberOfProperIDedRooms());
			}
			catch(final Exception e)
			{
			}
		}
	}
}

<MSG> 

git-svn-id: svn://192.168.1.10/public/CoffeeMud@11456 0d6f1817-ed0e-0410-87c9-987e46238f29

<DFF> @@ -708,6 +708,11 @@ public class RoomLoader
 		DBReadContent("CATALOG_ITEMS",null,null,null,true,false);
 	}
 
+	public void DBReadSpace()
+	{
+		DBReadContent("SPACE",null,null,null,true,false);
+	}
+
 	public void DBReadContent(String thisRoomID, Room thisRoom, Map<String, Room> rooms, RoomnumberSet unloadedRooms, boolean setStatus, boolean makeLive)
 	{
 		final boolean debug=Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMPOP));
@@ -721,6 +726,7 @@ public class RoomLoader
 		Hashtable<MOB, String> mobRides=null;
 
 		final boolean catalog=((thisRoomID!=null)&&(thisRoomID.startsWith("CATALOG_")));
+		final boolean space=((thisRoomID!=null)&&(thisRoomID.equals("SPACE")));
 
 		DBConnection D=null;
 		// now grab the items
@@ -740,6 +746,8 @@ public class RoomLoader
 					continue;
 				if((!catalog)&&(roomID.startsWith("CATALOG_")))
 					continue;
+				if((!space)&&(roomID.startsWith("SPACE")))
+					continue;
 				itemNums=stuff.itemNums.get("NUMSFOR"+roomID.toUpperCase());
 				if(itemNums==null)
 				{
@@ -793,6 +801,10 @@ public class RoomLoader
 						}
 						else
 							newItem.setMiscText(DBConnections.getResQuietly(R,"CMITTX"));
+						if(newItem instanceof SpaceObject)
+						{
+							CMLib.map().addObjectToSpace((SpaceObject)newItem, ((SpaceObject) newItem).coordinates());
+						}
 						newItem.basePhyStats().setRejuv((int)DBConnections.getLongRes(R,"CMITRE"));
 						newItem.setUsesRemaining((int)DBConnections.getLongRes(R,"CMITUR"));
 						newItem.basePhyStats().setLevel((int)DBConnections.getLongRes(R,"CMITLV"));
@@ -832,6 +844,8 @@ public class RoomLoader
 					continue;
 				if((!catalog)&&(roomID.startsWith("CATALOG_")))
 					continue;
+				if((!space) && roomID.equals("SPACE"))
+					continue;
 				final String NUMID=DBConnections.getRes(R,"CMCHNM");
 				final String MOBID=DBConnections.getRes(R,"CMCHID");
 
@@ -894,6 +908,10 @@ public class RoomLoader
 						final String ride=DBConnections.getRes(R,"CMCHRI");
 						if((ride!=null)&&(ride.length()>0))
 							mobRides.put(newMOB,ride);
+						if(newMOB instanceof SpaceObject)
+						{
+							CMLib.map().addObjectToSpace((SpaceObject)newMOB, ((SpaceObject) newMOB).coordinates());
+						}
 						newMOB.recoverCharStats();
 						newMOB.recoverPhyStats();
 						newMOB.recoverMaxState();

{'commit': 'diff --git a/changelog.txt b/changelog.txt\nindex ad63557a68..5b56809141 100644\n--- a/changelog.txt\n+++ b/changelog.txt\n@@ -23,9 +23,7 @@\n   19. Ship Component Tech install skill (AstroEngineering) done-ish... like all tech, it\'s subject to change without notice.\n   20. Area editor for planets now includes space positioning editors, including relative positioning calculators.\n   21. List command now includes SPACE, SPACESHIPS, SPACESHIPAREAS, MOONS, PLANETS, and STARS \n-   *. create space objects, esp stars.  planets should be thin areas, solar systems are triggered to load when players fly near enough.  \n-   *. Modify space objects. Ability to move them relative to each other would be cool...  \n-   *. Destroy space objects.\n+  22. Create/Modify/Destroy can now be used to create and alter objects in outer space.\n    *. MoneyChanger/Banker behavior to discount currency by its distant origin (farther planet is from origin of currency, less its worth).\n    *. personal scanner/tricorder software: mineral scanner, computer interface (with ship perhaps?)!\n    *. entry systems for ships (default entry key card, voice code, identifying scanner)\ndiff --git a/com/planet_ink/coffee_mud/Areas/Moon.java b/com/planet_ink/coffee_mud/Areas/Moon.java\nnew file mode 100644\nindex 0000000000..fc87193502\n--- /dev/null\n+++ b/com/planet_ink/coffee_mud/Areas/Moon.java\n@@ -0,0 +1,48 @@\n+package com.planet_ink.coffee_mud.Areas;\r\n+import com.planet_ink.coffee_mud.core.interfaces.*;\r\n+import com.planet_ink.coffee_mud.core.*;\r\n+import com.planet_ink.coffee_mud.core.collections.*;\r\n+import com.planet_ink.coffee_mud.core.interfaces.BoundedObject;\r\n+import com.planet_ink.coffee_mud.core.interfaces.BoundedObject.BoundedCube;\r\n+import com.planet_ink.coffee_mud.Abilities.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Areas.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Behaviors.interfaces.*;\r\n+import com.planet_ink.coffee_mud.CharClasses.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Commands.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Common.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Exits.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Items.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Locales.interfaces.*;\r\n+import com.planet_ink.coffee_mud.MOBS.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Races.interfaces.*;\r\n+\r\n+import java.util.*;\r\n+\r\n+/*\r\n+Copyright 2000-2014 Bo Zimmerman\r\n+\r\n+Licensed under the Apache License, Version 2.0 (the "License");\r\n+you may not use this file except in compliance with the License.\r\n+You may obtain a copy of the License at\r\n+\r\n+\t   http://www.apache.org/licenses/LICENSE-2.0\r\n+\r\n+Unless required by applicable law or agreed to in writing, software\r\n+distributed under the License is distributed on an "AS IS" BASIS,\r\n+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+See the License for the specific language governing permissions and\r\n+limitations under the License.\r\n+*/\r\n+public class Moon extends StdThinPlanet\r\n+{\r\n+\t@Override public String ID(){ return "Moon";}\r\n+\tpublic Moon()\r\n+\t{\r\n+\t\tsuper();\r\n+\r\n+\t\tcoordinates=new long[]{Math.round(Long.MAX_VALUE*Math.random()),Math.round(Long.MAX_VALUE*Math.random()),Math.round(Long.MAX_VALUE*Math.random())};\r\n+\t\tRandom random=new Random(System.currentTimeMillis());\r\n+\t\tradius=SpaceObject.Distance.MoonRadius.dm + (random.nextLong() % Math.round(CMath.mul(SpaceObject.Distance.MoonRadius.dm,0.20)));\r\n+\t\t//TODO: need a behavior or something that "fills it out" first time it\'s hit.\r\n+\t}\r\n+}\r\ndiff --git a/com/planet_ink/coffee_mud/Areas/Planet.java b/com/planet_ink/coffee_mud/Areas/Planet.java\nnew file mode 100644\nindex 0000000000..cb1edd65ef\n--- /dev/null\n+++ b/com/planet_ink/coffee_mud/Areas/Planet.java\n@@ -0,0 +1,49 @@\n+package com.planet_ink.coffee_mud.Areas;\r\n+import com.planet_ink.coffee_mud.core.interfaces.*;\r\n+import com.planet_ink.coffee_mud.core.*;\r\n+import com.planet_ink.coffee_mud.core.collections.*;\r\n+import com.planet_ink.coffee_mud.core.interfaces.BoundedObject;\r\n+import com.planet_ink.coffee_mud.core.interfaces.BoundedObject.BoundedCube;\r\n+import com.planet_ink.coffee_mud.Abilities.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Areas.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Behaviors.interfaces.*;\r\n+import com.planet_ink.coffee_mud.CharClasses.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Commands.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Common.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Exits.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Items.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Locales.interfaces.*;\r\n+import com.planet_ink.coffee_mud.MOBS.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Races.interfaces.*;\r\n+\r\n+import java.util.*;\r\n+\r\n+/*\r\n+Copyright 2000-2014 Bo Zimmerman\r\n+\r\n+Licensed under the Apache License, Version 2.0 (the "License");\r\n+you may not use this file except in compliance with the License.\r\n+You may obtain a copy of the License at\r\n+\r\n+\t   http://www.apache.org/licenses/LICENSE-2.0\r\n+\r\n+Unless required by applicable law or agreed to in writing, software\r\n+distributed under the License is distributed on an "AS IS" BASIS,\r\n+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+See the License for the specific language governing permissions and\r\n+limitations under the License.\r\n+*/\r\n+public class Planet extends StdThinPlanet\r\n+{\r\n+\t@Override public String ID(){ return "Planet";}\r\n+\tpublic Planet()\r\n+\t{\r\n+\t\tsuper();\r\n+\r\n+\t\t\r\n+\t\tcoordinates=new long[]{Math.round(Long.MAX_VALUE*Math.random()),Math.round(Long.MAX_VALUE*Math.random()),Math.round(Long.MAX_VALUE*Math.random())};\r\n+\t\tRandom random=new Random(System.currentTimeMillis());\r\n+\t\tradius=SpaceObject.Distance.PlanetRadius.dm + (random.nextLong() % Math.round(CMath.mul(SpaceObject.Distance.PlanetRadius.dm,0.30)));\r\n+\t\t//TODO: need a behavior or something that "fills it out" first time it\'s hit.\r\n+\t}\r\n+}\r\ndiff --git a/com/planet_ink/coffee_mud/Areas/StdPlanet.java b/com/planet_ink/coffee_mud/Areas/StdPlanet.java\nindex 1d2ed85a05..86d34f6e51 100644\n--- a/com/planet_ink/coffee_mud/Areas/StdPlanet.java\n+++ b/com/planet_ink/coffee_mud/Areas/StdPlanet.java\n@@ -40,7 +40,7 @@ public class StdPlanet extends StdTimeZone implements SpaceObject\n \tprotected static double[]\temptyDirection\t= new double[2];\r\n \r\n \tprotected long[]\tcoordinates\t= new long[3];\r\n-\tprotected long\t\tradius\t\t= SpaceObject.Distance.PlanetRadius.dm;\r\n+\tprotected long\t\tradius;\r\n \r\n \tpublic StdPlanet()\r\n \t{\r\n@@ -48,6 +48,8 @@ public class StdPlanet extends StdTimeZone implements SpaceObject\n \r\n \t\tmyClock = (TimeClock)CMClass.getCommon("DefaultTimeClock");\r\n \t\tcoordinates=new long[]{Math.round(Long.MAX_VALUE*Math.random()),Math.round(Long.MAX_VALUE*Math.random()),Math.round(Long.MAX_VALUE*Math.random())};\r\n+\t\tRandom random=new Random(System.currentTimeMillis());\r\n+\t\tradius=SpaceObject.Distance.PlanetRadius.dm + (random.nextLong() % (SpaceObject.Distance.PlanetRadius.dm / 20));\r\n \t}\r\n \r\n \t@Override public long[] coordinates(){return coordinates;}\r\ndiff --git a/com/planet_ink/coffee_mud/Areas/StdSpaceShip.java b/com/planet_ink/coffee_mud/Areas/StdSpaceShip.java\nindex 2225378023..ff8e1b628f 100644\n--- a/com/planet_ink/coffee_mud/Areas/StdSpaceShip.java\n+++ b/com/planet_ink/coffee_mud/Areas/StdSpaceShip.java\n@@ -173,6 +173,7 @@ public class StdSpaceShip implements Area, SpaceShip\n \t@Override\r\n \tpublic void destroy()\r\n \t{\r\n+\t\tCMLib.map().delObjectInSpace(this);\r\n \t\tCMLib.map().registerWorldObjectDestroyed(this,null,this);\r\n \t\tphyStats=(PhyStats)CMClass.getCommon("DefaultPhyStats");\r\n \t\tspaceSource=null;\r\ndiff --git a/com/planet_ink/coffee_mud/Areas/StdThinPlanet.java b/com/planet_ink/coffee_mud/Areas/StdThinPlanet.java\nindex c082b4dd1c..c9003da8b3 100644\n--- a/com/planet_ink/coffee_mud/Areas/StdThinPlanet.java\n+++ b/com/planet_ink/coffee_mud/Areas/StdThinPlanet.java\n@@ -39,7 +39,7 @@ public class StdThinPlanet extends StdThinArea implements SpaceObject\n \r\n \tprotected long[]\tcoordinates\t= new long[3];\r\n \tprotected double[]\tdirection\t= new double[2];\r\n-\tprotected long\t\tradius\t\t= SpaceObject.Distance.PlanetRadius.dm;\r\n+\tprotected long\t\tradius;\r\n \r\n \tpublic StdThinPlanet()\r\n \t{\r\n@@ -47,6 +47,8 @@ public class StdThinPlanet extends StdThinArea implements SpaceObject\n \r\n \t\tmyClock = (TimeClock)CMClass.getCommon("DefaultTimeClock");\r\n \t\tcoordinates=new long[]{Math.round(Long.MAX_VALUE*Math.random()),Math.round(Long.MAX_VALUE*Math.random()),Math.round(Long.MAX_VALUE*Math.random())};\r\n+\t\tRandom random=new Random(System.currentTimeMillis());\r\n+\t\tradius=SpaceObject.Distance.PlanetRadius.dm + (random.nextLong() % (SpaceObject.Distance.PlanetRadius.dm / 20));\r\n \t}\r\n \r\n \t@Override\r\ndiff --git a/com/planet_ink/coffee_mud/Commands/Create.java b/com/planet_ink/coffee_mud/Commands/Create.java\nindex 98d02722a3..1065274bfc 100644\n--- a/com/planet_ink/coffee_mud/Commands/Create.java\n+++ b/com/planet_ink/coffee_mud/Commands/Create.java\n@@ -15,7 +15,6 @@ import com.planet_ink.coffee_mud.Locales.interfaces.*;\n import com.planet_ink.coffee_mud.MOBS.interfaces.*;\r\n import com.planet_ink.coffee_mud.Races.interfaces.*;\r\n \r\n-\r\n import java.util.*;\r\n import java.io.IOException;\r\n \r\n@@ -121,16 +120,82 @@ public class Create extends StdCommand\n \t\tLog.sysOut("Exits",mob.location().roomID()+" exits changed by "+mob.Name()+".");\r\n \t}\r\n \r\n-\tpublic void polls(MOB mob, Vector commands)\r\n+\tprivate long[] makeSpaceLocation(MOB mob, SpaceObject newItem, String rest)\r\n \t{\r\n+\t\tList<String> utokens=CMParms.parseSpaces(rest.toUpperCase(),true);\r\n+\t\tfinal String distErrorMsg=_("Valid distance units include: @x1.",SpaceObject.Distance.getFullList());\r\n+\t\tint x;\r\n+\t\tif(((x=utokens.indexOf("FROM"))>0)&&(x<utokens.size()-1))\r\n+\t\t{\r\n+\t\t\tdouble[] direction=new double[]{Math.toRadians(CMLib.dice().roll(1, 360, -1)),Math.toRadians(CMLib.dice().roll(1,180,-1))};\r\n+\t\t\tString distStr=CMParms.combine(utokens,0,x);\r\n+\t\t\tString objName=CMParms.combine(utokens,x+1);\r\n+\t\t\tLong dist=CMLib.english().parseSpaceDistance(distStr);\r\n+\t\t\tif(dist==null)\r\n+\t\t\t{\r\n+\t\t\t\tmob.tell(_("Unknown distance for space object @x1:",newItem.ID())+" \'"+distStr+"\'. \\n\\r"+distErrorMsg);\r\n+\t\t\t\tmob.location().showOthers(mob,null,CMMsg.MSG_OK_ACTION,_("<S-NAME> flub(s) a spell.."));\r\n+\t\t\t\treturn null;\r\n+\t\t\t}\r\n+\t\t\tSpaceObject O=null;\r\n+\t\t\tif(objName.trim().length()>0)\r\n+\t\t\t{\r\n+\t\t\t\tO=CMLib.map().findSpaceObject(objName, true);\r\n+\t\t\t\tif(O==null)\r\n+\t\t\t\t\tO=CMLib.map().findSpaceObject(objName, false);\r\n+\t\t\t}\r\n+\t\t\tif(O==null)\r\n+\t\t\t{\r\n+\t\t\t\tmob.tell(_("Unknown relative space object")+" \'"+objName+"\'.\\n\\r");\r\n+\t\t\t\tmob.location().showOthers(mob,null,CMMsg.MSG_OK_ACTION,_("<S-NAME> flub(s) a spell.."));\r\n+\t\t\t\treturn null;\r\n+\t\t\t}\r\n+\t\t\trest=CMParms.toStringList(CMLib.map().getLocation(O.coordinates(), direction, dist.longValue()));\r\n+\t\t}\r\n+\t\tList<String> valsL=CMParms.parseCommas(rest,true);\r\n+\t\tif(valsL.size()!=3)\r\n+\t\t{\r\n+\t\t\tmob.tell(_("Unknown location for space object @x1:",newItem.ID())+": \'"+rest+"\'. "+_("The format for coordinates is 3 distances from core, comma delimited, or [DISTANCE] FROM [PLACE]\\n\\r"+distErrorMsg));\r\n+\t\t\tmob.location().showOthers(mob,null,CMMsg.MSG_OK_ACTION,_("<S-NAME> flub(s) a spell.."));\r\n+\t\t\treturn null;\r\n+\t\t}\r\n+\t\telse\r\n+\t\t{\r\n+\t\t\tboolean fail=true;\r\n+\t\t\tLong[] valL=new Long[3];\r\n+\t\t\tfor(int i=0;i<3;i++)\r\n+\t\t\t{\r\n+\t\t\t\tLong newValue=CMLib.english().parseSpaceDistance(valsL.get(i));\r\n+\t\t\t\tif(newValue==null)\r\n+\t\t\t\t{\r\n+\t\t\t\t\tmob.tell(_("Unknown coord: \'@x2\'. @x3 for space object @x1:",newItem.ID(),valsL.get(i),distErrorMsg));\r\n+\t\t\t\t\tbreak;\r\n+\t\t\t\t}\r\n+\t\t\t\telse\r\n+\t\t\t\t{\r\n+\t\t\t\t\tvalL[i]=newValue;\r\n+\t\t\t\t\tif(i==2) fail=false;\r\n+\t\t\t\t}\r\n+\t\t\t}\r\n+\t\t\tif(!fail)\r\n+\t\t\t{\r\n+\t\t\t\treturn new long[]{valL[0].longValue(),valL[1].longValue(),valL[2].longValue()};\r\n+\t\t\t}\r\n+\t\t\telse\r\n+\t\t\t{\r\n+\t\t\t\tmob.location().showOthers(mob,null,CMMsg.MSG_OK_ACTION,_("<S-NAME> flub(s) a spell.."));\r\n+\t\t\t\treturn null;\r\n+\t\t\t}\r\n+\t\t}\r\n \t}\r\n-\r\n-\tpublic void items(MOB mob, Vector commands)\r\n-\t\tthrows IOException\r\n+\t\r\n+\tpublic void items(MOB mob, Vector commands) throws IOException\r\n \t{\r\n \t\tif(commands.size()<3)\r\n \t\t{\r\n-\t\t\tmob.tell(_("You have failed to specify the proper fields.\\n\\rThe format is CREATE ITEM [ITEM NAME](@ room/[MOB NAME])\\n\\r"));\r\n+\t\t\tmob.tell(_("You have failed to specify the proper fields.\\n\\r"\r\n+\t\t\t\t\t+ "The format for normal items is CREATE ITEM [ITEM NAME](@ room/[MOB NAME])\\n\\r"\r\n+\t\t\t\t\t+ "The format for space items is CREATE ITEM [ITEM NAME](@ [COORDS]/[DISTANCE] FROM [SPACE OBJ])\\n\\r"));\r\n \t\t\tmob.location().showOthers(mob,null,CMMsg.MSG_OK_ACTION,_("<S-NAME> flub(s) a spell.."));\r\n \t\t\treturn;\r\n \t\t}\r\n@@ -138,31 +203,20 @@ public class Create extends StdCommand\n \t\tString itemID=CMParms.combine(commands,2);\r\n \t\tEnvironmental dest=mob.location();\r\n \t\tContainer setContainer=null;\r\n-\t\tfinal int x=itemID.indexOf(\'@\');\r\n+\t\tString rest="";\r\n+\t\tlong [] coordinates=new long[]{\r\n+\t\t\tCMLib.dice().getRandomizer().nextLong(),\r\n+\t\t\tCMLib.dice().getRandomizer().nextLong(),\r\n+\t\t\tCMLib.dice().getRandomizer().nextLong()\r\n+\t\t};\r\n+\t\t\r\n+\t\tint x=itemID.indexOf(\'@\');\r\n \t\tif(x>0)\r\n \t\t{\r\n-\t\t\tfinal String rest=itemID.substring(x+1).trim();\r\n+\t\t\trest=itemID.substring(x+1).trim();\r\n \t\t\titemID=itemID.substring(0,x).trim();\r\n-\t\t\tif((!rest.equalsIgnoreCase("room"))\r\n-\t\t\t&&(rest.length()>0))\r\n-\t\t\t{\r\n-\t\t\t\tfinal MOB M=mob.location().fetchInhabitant(rest);\r\n-\t\t\t\tif(M==null)\r\n-\t\t\t\t{\r\n-\t\t\t\t\tfinal Item I = mob.location().findItem(null, rest);\r\n-\t\t\t\t\tif(I instanceof Container)\r\n-\t\t\t\t\t\tsetContainer=(Container)I;\r\n-\t\t\t\t\telse\r\n-\t\t\t\t\t{\r\n-\t\t\t\t\t\tmob.tell(_("MOB or Container \'@x1\' not found.",rest));\r\n-\t\t\t\t\t\tmob.location().showOthers(mob,null,CMMsg.MSG_OK_ACTION,_("<S-NAME> flub(s) a spell.."));\r\n-\t\t\t\t\t\treturn;\r\n-\t\t\t\t\t}\r\n-\t\t\t\t}\r\n-\t\t\t\telse\r\n-\t\t\t\t\tdest=M;\r\n-\t\t\t}\r\n \t\t}\r\n+\t\t\r\n \t\tItem newItem=CMClass.getItem(itemID);\r\n \t\tif((newItem==null)&&(CMLib.english().numPossibleGold(null,itemID)>0))\r\n \t\t{\r\n@@ -186,16 +240,68 @@ public class Create extends StdCommand\n \t\t\tmob.location().showOthers(mob,null,CMMsg.MSG_OK_ACTION,_("<S-NAME> flub(s) a spell.."));\r\n \t\t\treturn;\r\n \t\t}\r\n-\r\n+\t\t\r\n \t\tif((newItem instanceof ArchonOnly)\r\n \t\t&&(!CMSecurity.isASysOp(mob)))\r\n \t\t{\r\n \t\t\tmob.tell(_("NO!"));\r\n \t\t\treturn;\r\n \t\t}\r\n+\t\t\r\n+\t\tif(x>0)\r\n+\t\t{\r\n+\t\t\tif(newItem instanceof SpaceObject)\r\n+\t\t\t{\r\n+\t\t\t\tcoordinates=makeSpaceLocation(mob,(SpaceObject)newItem,rest);\r\n+\t\t\t\tif(coordinates==null)\r\n+\t\t\t\t{\r\n+\t\t\t\t\treturn;\r\n+\t\t\t\t}\r\n+\t\t\t}\r\n+\t\t\telse\r\n+\t\t\tif((!rest.equalsIgnoreCase("room"))\r\n+\t\t\t&&(rest.length()>0))\r\n+\t\t\t{\r\n+\t\t\t\tfinal MOB M=mob.location().fetchInhabitant(rest);\r\n+\t\t\t\tif(M==null)\r\n+\t\t\t\t{\r\n+\t\t\t\t\tfinal Item I = mob.location().findItem(null, rest);\r\n+\t\t\t\t\tif(I instanceof Container)\r\n+\t\t\t\t\t\tsetContainer=(Container)I;\r\n+\t\t\t\t\telse\r\n+\t\t\t\t\t{\r\n+\t\t\t\t\t\tmob.tell(_("MOB or Container \'@x1\' not found.",rest));\r\n+\t\t\t\t\t\tmob.location().showOthers(mob,null,CMMsg.MSG_OK_ACTION,_("<S-NAME> flub(s) a spell.."));\r\n+\t\t\t\t\t\treturn;\r\n+\t\t\t\t\t}\r\n+\t\t\t\t}\r\n+\t\t\t\telse\r\n+\t\t\t\t\tdest=M;\r\n+\t\t\t}\r\n+\t\t}\r\n+\t\telse\r\n+\t\tif(newItem instanceof SpaceObject)\r\n+\t\t{\r\n+\t\t\tint i=21;\r\n+\t\t\twhile((--i>0)&&(CMLib.map().getSpaceObjectsWithin(coordinates, 0, SpaceObject.Distance.SolarSystemDiameter.dm).size()>0))\r\n+\t\t\t{\r\n+\t\t\t\tcoordinates=new long[]{\r\n+\t\t\t\t\tCMLib.dice().getRandomizer().nextLong(),\r\n+\t\t\t\t\tCMLib.dice().getRandomizer().nextLong(),\r\n+\t\t\t\t\tCMLib.dice().getRandomizer().nextLong()\r\n+\t\t\t\t};\r\n+\t\t\t}\r\n+\t\t}\r\n+\t\r\n \r\n \t\tif(newItem.subjectToWearAndTear())\r\n \t\t\tnewItem.setUsesRemaining(100);\r\n+\t\tif(newItem instanceof SpaceObject)\r\n+\t\t{\r\n+\t\t\tCMLib.map().addObjectToSpace(((SpaceObject)newItem), coordinates);\r\n+\t\t\tmob.location().showHappens(CMMsg.MSG_OK_ACTION,_("Suddenly, @x1 appears in the sky.",newItem.name()));\r\n+\t\t}\r\n+\t\telse\r\n \t\tif(dest instanceof Room)\r\n \t\t{\r\n \t\t\t((Room)dest).addItem(newItem);\r\n@@ -212,6 +318,10 @@ public class Create extends StdCommand\n \r\n \t\tif((newItem.isGeneric())&&(doGenerica))\r\n \t\t\tCMLib.genEd().genMiscSet(mob,newItem);\r\n+\t\tif(newItem instanceof SpaceObject)\r\n+\t\t{\r\n+\t\t\tCMLib.database().DBCreateThisItem("SPACE", newItem);\r\n+\t\t}\r\n \t\tmob.location().recoverRoomStats();\r\n \t\tLog.sysOut("Items",mob.Name()+" created item "+newItem.ID()+".");\r\n \t}\r\n@@ -502,11 +612,27 @@ public class Create extends StdCommand\n \t{\r\n \t\tif(commands.size()<3)\r\n \t\t{\r\n-\t\t\tmob.tell(_("You have failed to specify the proper fields.\\n\\rThe format is CREATE AREA [AREA NAME]\\n\\r"));\r\n+\t\t\tmob.tell(_("You have failed to specify the proper fields.\\n\\r"\r\n+\t\t\t\t\t+ "The format for normal areas is CREATE AREA [AREA NAME]\\n\\r"\r\n+\t\t\t\t\t+ "The format for space areas is CREATE AREA [AREA NAME] (@ [COORDS] / [DISTANCE] FROM [SPACE OBJECT]\\n\\r"));\r\n \t\t\tmob.location().showOthers(mob,null,CMMsg.MSG_OK_ACTION,_("<S-NAME> flub(s) a spell.."));\r\n \t\t\treturn;\r\n \t\t}\r\n-\t\tfinal String areaName=CMParms.combine(commands,2);\r\n+\t\tString areaName=CMParms.combine(commands,2);\r\n+\t\tlong [] coordinates=new long[]{\r\n+\t\t\tCMLib.dice().getRandomizer().nextLong(),\r\n+\t\t\tCMLib.dice().getRandomizer().nextLong(),\r\n+\t\t\tCMLib.dice().getRandomizer().nextLong()\r\n+\t\t};\r\n+\t\t\t\r\n+\t\tint x=areaName.indexOf(\'@\');\r\n+\t\tString spaceCoords="";\r\n+\t\tif(x>0)\r\n+\t\t{\r\n+\t\t\tspaceCoords=areaName.substring(x+1).trim();\r\n+\t\t\tareaName=areaName.substring(0,x).trim();\r\n+\t\t}\r\n+\t\t\r\n \t\tArea A=CMLib.map().getArea(areaName);\r\n \t\tif(A!=null)\r\n \t\t{\r\n@@ -514,11 +640,13 @@ public class Create extends StdCommand\n \t\t\tmob.location().showOthers(mob,null,CMMsg.MSG_OK_ACTION,_("<S-NAME> flub(s) a spell.."));\r\n \t\t\treturn;\r\n \t\t}\r\n+\t\t\r\n \t\tString areaType="";\r\n \t\tint tries=0;\r\n+\t\tString defaultArea=(spaceCoords.length()>0)?"Planet":"StdArea";\r\n \t\twhile((areaType.length()==0)&&((++tries)<10))\r\n \t\t{\r\n-\t\t\tareaType=mob.session().prompt(_("Enter an area type to create (default=StdArea): "),_("StdArea"));\r\n+\t\t\tareaType=mob.session().prompt(_("Enter an area type to create (default=@x1): ",defaultArea),defaultArea);\r\n \t\t\tif(CMClass.getAreaType(areaType)==null)\r\n \t\t\t{\r\n \t\t\t\tmob.session().println(_("Invalid area type! Valid ones are:"));\r\n@@ -526,13 +654,26 @@ public class Create extends StdCommand\n \t\t\t\tareaType="";\r\n \t\t\t}\r\n \t\t}\r\n-\t\tif(areaType.length()==0) areaType="StdArea";\r\n+\t\tif(areaType.length()==0) \r\n+\t\t\tareaType=defaultArea;\r\n \t\tA=CMClass.getAreaType(areaType);\r\n+\t\tif(A instanceof SpaceObject)\r\n+\t\t{\r\n+\t\t\tif(spaceCoords.length()>0)\r\n+\t\t\t{\r\n+\t\t\t\tcoordinates=makeSpaceLocation(mob,(SpaceObject)A,spaceCoords);\r\n+\t\t\t\tif(coordinates==null)\r\n+\t\t\t\t{\r\n+\t\t\t\t\treturn;\r\n+\t\t\t\t}\r\n+\t\t\t}\r\n+\t\t\tCMLib.map().addObjectToSpace(((SpaceObject)A), coordinates);\r\n+\t\t}\r\n \t\tA.setName(areaName);\r\n \t\tCMLib.map().addArea(A);\r\n \t\tCMLib.database().DBCreateArea(A);\r\n \r\n-\t\tfinal Room R=CMClass.getLocale("StdRoom");\r\n+\t\tfinal Room R=CMClass.getLocale((A instanceof SpaceObject)?"SpacePort":"StdRoom");\r\n \t\tR.setRoomID(A.getNewRoomID(R,-1));\r\n \t\tR.setArea(A);\r\n \t\tR.setDisplayText(CMClass.classID(R)+"-"+R.roomID());\r\n@@ -1265,7 +1406,7 @@ public class Create extends StdCommand\n \t\t\t}\r\n \t\t\tEnvironmental E=null;\r\n \t\t\tE=CMClass.getItem(allWord);\r\n-\t\t\tif(((E!=null)&&(E instanceof Item))\r\n+\t\t\tif((E instanceof Item)\r\n \t\t\t||(CMLib.english().numPossibleGold(null,allWord)>0)\r\n \t\t\t||(CMLib.catalog().getCatalogItem(allWord)!=null))\r\n \t\t\t{\r\n@@ -1275,7 +1416,7 @@ public class Create extends StdCommand\n \t\t\telse\r\n \t\t\t{\r\n \t\t\t\tE=CMClass.getMOB(allWord);\r\n-\t\t\t\tif(((E!=null)&&(E instanceof MOB))\r\n+\t\t\t\tif((E instanceof MOB)\r\n \t\t\t\t||(CMLib.catalog().getCatalogMob(allWord)!=null))\r\n \t\t\t\t{\r\n \t\t\t\t\tcommands.insertElementAt("MOB",1);\r\n@@ -1352,6 +1493,14 @@ public class Create extends StdCommand\n \t\t\t\t}\r\n \t\t\t\telse\r\n \t\t\t\t{\r\n+\t\t\t\t\tE=CMClass.getItem(firstWord);\r\n+\t\t\t\t\tif((E instanceof Item)\r\n+\t\t\t\t\t||(CMLib.english().numPossibleGold(null,firstWord)>0)\r\n+\t\t\t\t\t||(CMLib.catalog().getCatalogItem(firstWord)!=null))\r\n+\t\t\t\t\t{\r\n+\t\t\t\t\t\tcommands.insertElementAt("ITEM",1);\r\n+\t\t\t\t\t\treturn execute(mob,commands,metaFlags);\r\n+\t\t\t\t\t}\r\n \t\t\t\t\tmob.tell(_("\\n\\rYou cannot create a \'@x1\'. However, you might try an EXIT, ITEM, QUEST, FACTION, MOB, COMPONENT, GOVERNMENT, MANUFACTURER, HOLIDAY, CLAN, RACE, ABILITY, LANGUAGE, CRAFTSKILL, ALLQUALIFY, CLASS, POLL, USER, DEBUGFLAG, NEWS, DISABLEFLAG, ROOM.",commandType));\r\n \t\t\t\t\treturn false;\r\n \t\t\t\t}\r\ndiff --git a/com/planet_ink/coffee_mud/Commands/Destroy.java b/com/planet_ink/coffee_mud/Commands/Destroy.java\nindex 7e1d851ef9..d1dded5e4a 100644\n--- a/com/planet_ink/coffee_mud/Commands/Destroy.java\n+++ b/com/planet_ink/coffee_mud/Commands/Destroy.java\n@@ -462,22 +462,39 @@ public class Destroy extends StdCommand\n \t\tItem deadItem=null;\r\n \t\tdeadItem=(srchRoom==null)?null:srchRoom.findItem(srchContainer,itemID);\r\n \t\tif((!allFlag)&&(deadItem==null)) deadItem=(srchMob==null)?null:srchMob.findItem(null,itemID);\r\n+\t\tif(deadItem==null)\r\n+\t\t{\r\n+\t\t\tEnvironmental E=CMLib.map().findSpaceObject(itemID,true);\r\n+\t\t\tif(!(E instanceof Item))\r\n+\t\t\t\tE=CMLib.map().findSpaceObject(itemID,false);\r\n+\t\t\tif(E instanceof Item)\r\n+\t\t\t\tdeadItem=(Item)E;\r\n+\t\t}\r\n \t\twhile(deadItem!=null)\r\n \t\t{\r\n \t\t\tmob.location().recoverRoomStats();\r\n \t\t\tmob.location().show(mob,null,CMMsg.MSG_OK_ACTION,_("@x1 disintegrates!",deadItem.name()));\r\n \t\t\tdoneSomething=true;\r\n \t\t\tLog.sysOut("Items",mob.Name()+" destroyed item "+deadItem.name()+".");\r\n-\t\t\tif(srchMob!=null)\r\n-\t\t\t\tdeadItem.setOwner(srchMob);\r\n+\t\t\tif(deadItem instanceof SpaceObject)\r\n+\t\t\t{\r\n+\t\t\t\tCMLib.database().DBDeleteItem("SPACE", deadItem);\r\n+\t\t\t\tdeadItem.destroy();\r\n+\t\t\t\tdeadItem=null;\r\n+\t\t\t}\r\n \t\t\telse\r\n-\t\t\tif(srchRoom!=null)\r\n-\t\t\t\tdeadItem.setOwner(srchRoom);\r\n-\t\t\tdeadItem.destroy();\r\n-\t\t\tmob.location().delItem(deadItem);\r\n-\t\t\tdeadItem=null;\r\n-\t\t\tif(!allFlag) deadItem=(srchMob==null)?null:srchMob.findItem(null,itemID);\r\n-\t\t\tif(deadItem==null) deadItem=(srchRoom==null)?null:srchRoom.findItem(null,itemID);\r\n+\t\t\t{\r\n+\t\t\t\tif(srchMob!=null)\r\n+\t\t\t\t\tdeadItem.setOwner(srchMob);\r\n+\t\t\t\telse\r\n+\t\t\t\tif(srchRoom!=null)\r\n+\t\t\t\t\tdeadItem.setOwner(srchRoom);\r\n+\t\t\t\tdeadItem.destroy();\r\n+\t\t\t\tmob.location().delItem(deadItem);\r\n+\t\t\t\tdeadItem=null;\r\n+\t\t\t\tif(!allFlag) deadItem=(srchMob==null)?null:srchMob.findItem(null,itemID);\r\n+\t\t\t\tif(deadItem==null) deadItem=(srchRoom==null)?null:srchRoom.findItem(null,itemID);\r\n+\t\t\t}\r\n \t\t\tif(!allFlag) break;\r\n \t\t}\r\n \t\tif(!doneSomething)\r\n@@ -1491,6 +1508,16 @@ public class Destroy extends StdCommand\n \t\t\t\t\t\texecute(mob,commands,metaFlags);\r\n \t\t\t\t\t}\r\n \t\t\t\t\telse\r\n+\t\t\t\t\tif((thang=CMLib.map().findSpaceObject(allWord,true))!=null)\r\n+\t\t\t\t\t{\r\n+\t\t\t\t\t\tif(thang instanceof Area)\r\n+\t\t\t\t\t\t\tcommands.insertElementAt("AREA",1);\r\n+\t\t\t\t\t\telse\r\n+\t\t\t\t\t\tif(thang instanceof Item)\r\n+\t\t\t\t\t\t\tcommands.insertElementAt("ITEM",1);\r\n+\t\t\t\t\t\texecute(mob,commands,metaFlags);\r\n+\t\t\t\t\t}\r\n+\t\t\t\t\telse\r\n \t\t\t\t\tmob.tell(\r\n \t\t\t\t\t\t_("\\n\\rYou cannot destroy a \'@x1\'. However, you might try an EXIT, ITEM, AREA, USER, MOB, QUEST, FACTION, SESSION, TICKS, THREAD, HOLIDAY, JOURNAL, SOCIAL, CLASS, ABILITY, MANUFACTURER, LANGUAGE, COMPONENT, RACE, EXPERTISE, TITLE, CLAN, BAN, GOVERNMENT, NOPURGE, BUG, TYPO, IDEA, POLL, DEBUGFLAG, DISABLEFLAG, or a ROOM.",commandType));\r\n \t\t\t\t}\r\ndiff --git a/com/planet_ink/coffee_mud/Commands/Modify.java b/com/planet_ink/coffee_mud/Commands/Modify.java\nindex 79050a3b13..c9e6c3f2af 100644\n--- a/com/planet_ink/coffee_mud/Commands/Modify.java\n+++ b/com/planet_ink/coffee_mud/Commands/Modify.java\n@@ -107,6 +107,14 @@ public class Modify extends StdCommand\n \t\t\t\tmodItem=srchRoom.findItem(itemID);\r\n \t\t}\r\n \t\tif(modItem==null)\r\n+\t\t{\r\n+\t\t\tEnvironmental E=CMLib.map().findSpaceObject(itemID,true);\r\n+\t\t\tif(!(E instanceof Item))\r\n+\t\t\t\tE=CMLib.map().findSpaceObject(itemID,false);\r\n+\t\t\tif(E instanceof Item)\r\n+\t\t\t\tmodItem=(Item)E;\r\n+\t\t}\r\n+\t\tif(modItem==null)\r\n \t\t{\r\n \t\t\tmob.tell(_("I don\'t see \'@x1 here.\\n\\r",itemID));\r\n \t\t\tmob.location().showOthers(mob,null,CMMsg.MSG_OK_ACTION,_("<S-NAME> flub(s) a spell.."));\r\n@@ -199,7 +207,13 @@ public class Modify extends StdCommand\n \t\t\tmob.location().showOthers(mob,null,CMMsg.MSG_OK_ACTION,_("<S-NAME> flub(s) a spell.."));\r\n \t\t}\r\n \t\tif(!copyItem.sameAs(modItem))\r\n+\t\t{\r\n \t\t\tLog.sysOut("Items",mob.Name()+" modified item "+modItem.ID()+".");\r\n+\t\t\tif(modItem instanceof SpaceObject)\r\n+\t\t\t{\r\n+\t\t\t\tCMLib.database().DBUpdateItem("SPACE", modItem);\r\n+\t\t\t}\r\n+\t\t}\r\n \t\tcopyItem.destroy();\r\n \t}\r\n \r\n@@ -2061,6 +2075,32 @@ public class Modify extends StdCommand\n \t\t\t\tcommands.insertElementAt("SOCIAL",1);\r\n \t\t\t\texecute(mob,commands,metaFlags);\r\n \t\t\t}\r\n+\t\t\telse\r\n+\t\t\tif((thang=CMLib.map().findSpaceObject(allWord,true))!=null)\r\n+\t\t\t{\r\n+\t\t\t\tif(thang instanceof Area)\r\n+\t\t\t\t\tcommands.insertElementAt("AREA",1);\r\n+\t\t\t\telse\r\n+\t\t\t\tif(thang instanceof Item)\r\n+\t\t\t\t\tcommands.insertElementAt("ITEM",1);\r\n+\t\t\t\texecute(mob,commands,metaFlags);\r\n+\t\t\t}\r\n+\t\t\telse\r\n+\t\t\tif((thang=CMLib.map().findArea(allWord))!=null)\r\n+\t\t\t{\r\n+\t\t\t\tcommands.insertElementAt("AREA",1);\r\n+\t\t\t\texecute(mob,commands,metaFlags);\r\n+\t\t\t}\r\n+\t\t\telse\r\n+\t\t\tif((thang=CMLib.map().findSpaceObject(allWord,false))!=null)\r\n+\t\t\t{\r\n+\t\t\t\tif(thang instanceof Area)\r\n+\t\t\t\t\tcommands.insertElementAt("AREA",1);\r\n+\t\t\t\telse\r\n+\t\t\t\tif(thang instanceof Item)\r\n+\t\t\t\t\tcommands.insertElementAt("ITEM",1);\r\n+\t\t\t\texecute(mob,commands,metaFlags);\r\n+\t\t\t}\r\n \t\t\telse\r\n \t\t\t\tmob.tell(_("\\n\\rYou cannot modify a \'@x1\'. However, you might try an ITEM, RACE, CLASS, ABILITY, LANGUAGE, CRAFTSKILL, ALLQUALIFY, AREA, EXIT, COMPONENT, RECIPE, EXPERTISE, TITLE, QUEST, MOB, USER, HOLIDAY, MANUFACTURER, GOVERNMENT, JSCRIPT, FACTION, SOCIAL, CLAN, POLL, NEWS, DAY, MONTH, YEAR, TIME, HOUR, or ROOM.",commandType));\r\n \t\t}\r\ndiff --git a/com/planet_ink/coffee_mud/Items/Basic/Asteroid.java b/com/planet_ink/coffee_mud/Items/Basic/Asteroid.java\nnew file mode 100644\nindex 0000000000..0bba4f7a35\n--- /dev/null\n+++ b/com/planet_ink/coffee_mud/Items/Basic/Asteroid.java\n@@ -0,0 +1,49 @@\n+package com.planet_ink.coffee_mud.Items.Basic;\r\n+import com.planet_ink.coffee_mud.core.interfaces.*;\r\n+import com.planet_ink.coffee_mud.core.*;\r\n+import com.planet_ink.coffee_mud.core.collections.*;\r\n+import com.planet_ink.coffee_mud.Abilities.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Areas.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Behaviors.interfaces.*;\r\n+import com.planet_ink.coffee_mud.CharClasses.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Commands.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Common.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Exits.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Items.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Locales.interfaces.*;\r\n+import com.planet_ink.coffee_mud.MOBS.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Races.interfaces.*;\r\n+\r\n+import java.util.*;\r\n+\r\n+/*\r\n+   Copyright 2000-2014 Bo Zimmerman\r\n+\r\n+   Licensed under the Apache License, Version 2.0 (the "License");\r\n+   you may not use this file except in compliance with the License.\r\n+   You may obtain a copy of the License at\r\n+\r\n+\t   http://www.apache.org/licenses/LICENSE-2.0\r\n+\r\n+   Unless required by applicable law or agreed to in writing, software\r\n+   distributed under the License is distributed on an "AS IS" BASIS,\r\n+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+   See the License for the specific language governing permissions and\r\n+   limitations under the License.\r\n+*/\r\n+public class Asteroid extends GenSpaceBody\r\n+{\r\n+\t@Override public String ID(){\treturn "Asteroid";}\r\n+\t\r\n+\tpublic Asteroid()\r\n+\t{\r\n+\t\tsuper();\r\n+\t\tsetName("an asteroid");\r\n+\t\tsetDisplayText("an asteroid is here");\r\n+\t\tsetDescription("it`s a big rock");\r\n+\t\tcoordinates=new long[]{Math.round(Long.MAX_VALUE*Math.random()),Math.round(Long.MAX_VALUE*Math.random()),Math.round(Long.MAX_VALUE*Math.random())};\r\n+\t\tRandom random=new Random(System.currentTimeMillis());\r\n+\t\tradius=(5*SpaceObject.Distance.Kilometer.dm) + (random.nextLong() % (4*SpaceObject.Distance.Kilometer.dm));\r\n+\t\trecoverPhyStats();\r\n+\t}\r\n+}\r\ndiff --git a/com/planet_ink/coffee_mud/Items/Basic/DwarfStar.java b/com/planet_ink/coffee_mud/Items/Basic/DwarfStar.java\nnew file mode 100644\nindex 0000000000..839b9db290\n--- /dev/null\n+++ b/com/planet_ink/coffee_mud/Items/Basic/DwarfStar.java\n@@ -0,0 +1,51 @@\n+package com.planet_ink.coffee_mud.Items.Basic;\r\n+import com.planet_ink.coffee_mud.core.interfaces.*;\r\n+import com.planet_ink.coffee_mud.core.*;\r\n+import com.planet_ink.coffee_mud.core.collections.*;\r\n+import com.planet_ink.coffee_mud.Abilities.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Areas.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Behaviors.interfaces.*;\r\n+import com.planet_ink.coffee_mud.CharClasses.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Commands.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Common.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Exits.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Items.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Locales.interfaces.*;\r\n+import com.planet_ink.coffee_mud.MOBS.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Races.interfaces.*;\r\n+\r\n+import java.util.*;\r\n+\r\n+/*\r\n+   Copyright 2000-2014 Bo Zimmerman\r\n+\r\n+   Licensed under the Apache License, Version 2.0 (the "License");\r\n+   you may not use this file except in compliance with the License.\r\n+   You may obtain a copy of the License at\r\n+\r\n+\t   http://www.apache.org/licenses/LICENSE-2.0\r\n+\r\n+   Unless required by applicable law or agreed to in writing, software\r\n+   distributed under the License is distributed on an "AS IS" BASIS,\r\n+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+   See the License for the specific language governing permissions and\r\n+   limitations under the License.\r\n+*/\r\n+public class DwarfStar extends GenSpaceBody\r\n+{\r\n+\t@Override public String ID(){\treturn "DwarfStar";}\r\n+\t\r\n+\tpublic DwarfStar()\r\n+\t{\r\n+\t\tsuper();\r\n+\t\tsetName("unknown dwarf star");\r\n+\t\tsetDisplayText("an unknown dwarf star is shining here");\r\n+\t\tsetDescription("it`s somewhat bright");\r\n+\t\tcoordinates=new long[]{Math.round(Long.MAX_VALUE*Math.random()),Math.round(Long.MAX_VALUE*Math.random()),Math.round(Long.MAX_VALUE*Math.random())};\r\n+\t\tRandom random=new Random(System.currentTimeMillis());\r\n+\t\tradius=SpaceObject.Distance.StarDRadius.dm + (random.nextLong() % Math.round(CMath.mul(SpaceObject.Distance.StarDRadius.dm,0.30)));\r\n+\t\tbasePhyStats().setDisposition(PhyStats.IS_LIGHTSOURCE|PhyStats.IS_GLOWING);\r\n+\t\tthis.setMaterial(RawMaterial.RESOURCE_HYDROGEN);\r\n+\t\trecoverPhyStats();\r\n+\t}\r\n+}\r\ndiff --git a/com/planet_ink/coffee_mud/Items/Basic/GasGiant.java b/com/planet_ink/coffee_mud/Items/Basic/GasGiant.java\nnew file mode 100644\nindex 0000000000..e500b45d9c\n--- /dev/null\n+++ b/com/planet_ink/coffee_mud/Items/Basic/GasGiant.java\n@@ -0,0 +1,49 @@\n+package com.planet_ink.coffee_mud.Items.Basic;\r\n+import com.planet_ink.coffee_mud.core.interfaces.*;\r\n+import com.planet_ink.coffee_mud.core.*;\r\n+import com.planet_ink.coffee_mud.core.collections.*;\r\n+import com.planet_ink.coffee_mud.Abilities.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Areas.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Behaviors.interfaces.*;\r\n+import com.planet_ink.coffee_mud.CharClasses.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Commands.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Common.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Exits.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Items.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Locales.interfaces.*;\r\n+import com.planet_ink.coffee_mud.MOBS.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Races.interfaces.*;\r\n+\r\n+import java.util.*;\r\n+\r\n+/*\r\n+   Copyright 2000-2014 Bo Zimmerman\r\n+\r\n+   Licensed under the Apache License, Version 2.0 (the "License");\r\n+   you may not use this file except in compliance with the License.\r\n+   You may obtain a copy of the License at\r\n+\r\n+\t   http://www.apache.org/licenses/LICENSE-2.0\r\n+\r\n+   Unless required by applicable law or agreed to in writing, software\r\n+   distributed under the License is distributed on an "AS IS" BASIS,\r\n+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+   See the License for the specific language governing permissions and\r\n+   limitations under the License.\r\n+*/\r\n+public class GasGiant extends GenSpaceBody\r\n+{\r\n+\t@Override public String ID(){\treturn "GasGiant";}\r\n+\t\r\n+\tpublic GasGiant()\r\n+\t{\r\n+\t\tsuper();\r\n+\t\tsetName("unknown gas giant");\r\n+\t\tsetDisplayText("an unknown gas giant is floating here");\r\n+\t\tsetDescription("it`s pretty");\r\n+\t\tcoordinates=new long[]{Math.round(Long.MAX_VALUE*Math.random()),Math.round(Long.MAX_VALUE*Math.random()),Math.round(Long.MAX_VALUE*Math.random())};\r\n+\t\tRandom random=new Random(System.currentTimeMillis());\r\n+\t\tradius=SpaceObject.Distance.SaturnRadius.dm + (random.nextLong() % (SpaceObject.Distance.SaturnRadius.dm / 2));\r\n+\t\tthis.setMaterial(RawMaterial.RESOURCE_HYDROGEN);\r\n+\t}\r\n+}\r\ndiff --git a/com/planet_ink/coffee_mud/Items/Basic/MassiveStar.java b/com/planet_ink/coffee_mud/Items/Basic/MassiveStar.java\nnew file mode 100644\nindex 0000000000..512540ea8b\n--- /dev/null\n+++ b/com/planet_ink/coffee_mud/Items/Basic/MassiveStar.java\n@@ -0,0 +1,51 @@\n+package com.planet_ink.coffee_mud.Items.Basic;\r\n+import com.planet_ink.coffee_mud.core.interfaces.*;\r\n+import com.planet_ink.coffee_mud.core.*;\r\n+import com.planet_ink.coffee_mud.core.collections.*;\r\n+import com.planet_ink.coffee_mud.Abilities.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Areas.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Behaviors.interfaces.*;\r\n+import com.planet_ink.coffee_mud.CharClasses.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Commands.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Common.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Exits.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Items.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Locales.interfaces.*;\r\n+import com.planet_ink.coffee_mud.MOBS.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Races.interfaces.*;\r\n+\r\n+import java.util.*;\r\n+\r\n+/*\r\n+   Copyright 2000-2014 Bo Zimmerman\r\n+\r\n+   Licensed under the Apache License, Version 2.0 (the "License");\r\n+   you may not use this file except in compliance with the License.\r\n+   You may obtain a copy of the License at\r\n+\r\n+\t   http://www.apache.org/licenses/LICENSE-2.0\r\n+\r\n+   Unless required by applicable law or agreed to in writing, software\r\n+   distributed under the License is distributed on an "AS IS" BASIS,\r\n+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+   See the License for the specific language governing permissions and\r\n+   limitations under the License.\r\n+*/\r\n+public class MassiveStar extends GenSpaceBody\r\n+{\r\n+\t@Override public String ID(){\treturn "MassiveStar";}\r\n+\t\r\n+\tpublic MassiveStar()\r\n+\t{\r\n+\t\tsuper();\r\n+\t\tsetName("unknown massive star");\r\n+\t\tsetDisplayText("an unknown massive star is shining here");\r\n+\t\tsetDescription("it`s very very bright");\r\n+\t\tcoordinates=new long[]{Math.round(Long.MAX_VALUE*Math.random()),Math.round(Long.MAX_VALUE*Math.random()),Math.round(Long.MAX_VALUE*Math.random())};\r\n+\t\tRandom random=new Random(System.currentTimeMillis());\r\n+\t\tradius=SpaceObject.Distance.StarBRadius.dm + (random.nextLong() % Math.round(CMath.mul(SpaceObject.Distance.StarBRadius.dm,0.30)));\r\n+\t\tbasePhyStats().setDisposition(PhyStats.IS_LIGHTSOURCE|PhyStats.IS_GLOWING);\r\n+\t\tthis.setMaterial(RawMaterial.RESOURCE_HYDROGEN);\r\n+\t\trecoverPhyStats();\r\n+\t}\r\n+}\r\ndiff --git a/com/planet_ink/coffee_mud/Items/Basic/Moonlet.java b/com/planet_ink/coffee_mud/Items/Basic/Moonlet.java\nnew file mode 100644\nindex 0000000000..601643eb48\n--- /dev/null\n+++ b/com/planet_ink/coffee_mud/Items/Basic/Moonlet.java\n@@ -0,0 +1,49 @@\n+package com.planet_ink.coffee_mud.Items.Basic;\r\n+import com.planet_ink.coffee_mud.core.interfaces.*;\r\n+import com.planet_ink.coffee_mud.core.*;\r\n+import com.planet_ink.coffee_mud.core.collections.*;\r\n+import com.planet_ink.coffee_mud.Abilities.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Areas.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Behaviors.interfaces.*;\r\n+import com.planet_ink.coffee_mud.CharClasses.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Commands.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Common.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Exits.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Items.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Locales.interfaces.*;\r\n+import com.planet_ink.coffee_mud.MOBS.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Races.interfaces.*;\r\n+\r\n+import java.util.*;\r\n+\r\n+/*\r\n+   Copyright 2000-2014 Bo Zimmerman\r\n+\r\n+   Licensed under the Apache License, Version 2.0 (the "License");\r\n+   you may not use this file except in compliance with the License.\r\n+   You may obtain a copy of the License at\r\n+\r\n+\t   http://www.apache.org/licenses/LICENSE-2.0\r\n+\r\n+   Unless required by applicable law or agreed to in writing, software\r\n+   distributed under the License is distributed on an "AS IS" BASIS,\r\n+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+   See the License for the specific language governing permissions and\r\n+   limitations under the License.\r\n+*/\r\n+public class Moonlet extends GenSpaceBody\r\n+{\r\n+\t@Override public String ID(){\treturn "Moonlet";}\r\n+\t\r\n+\tpublic Moonlet()\r\n+\t{\r\n+\t\tsuper();\r\n+\t\tsetName("a small moon");\r\n+\t\tsetDisplayText("a small moon is floating here");\r\n+\t\tsetDescription("it`s not a space station");\r\n+\t\tcoordinates=new long[]{Math.round(Long.MAX_VALUE*Math.random()),Math.round(Long.MAX_VALUE*Math.random()),Math.round(Long.MAX_VALUE*Math.random())};\r\n+\t\tRandom random=new Random(System.currentTimeMillis());\r\n+\t\tradius=(SpaceObject.Distance.MoonRadius.dm/10) + (random.nextLong() % Math.round(CMath.mul(SpaceObject.Distance.MoonRadius.dm,0.099)));\r\n+\t\trecoverPhyStats();\r\n+\t}\r\n+}\r\ndiff --git a/com/planet_ink/coffee_mud/Items/Basic/Star.java b/com/planet_ink/coffee_mud/Items/Basic/Star.java\nnew file mode 100644\nindex 0000000000..29ad965bb5\n--- /dev/null\n+++ b/com/planet_ink/coffee_mud/Items/Basic/Star.java\n@@ -0,0 +1,51 @@\n+package com.planet_ink.coffee_mud.Items.Basic;\r\n+import com.planet_ink.coffee_mud.core.interfaces.*;\r\n+import com.planet_ink.coffee_mud.core.*;\r\n+import com.planet_ink.coffee_mud.core.collections.*;\r\n+import com.planet_ink.coffee_mud.Abilities.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Areas.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Behaviors.interfaces.*;\r\n+import com.planet_ink.coffee_mud.CharClasses.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Commands.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Common.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Exits.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Items.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Locales.interfaces.*;\r\n+import com.planet_ink.coffee_mud.MOBS.interfaces.*;\r\n+import com.planet_ink.coffee_mud.Races.interfaces.*;\r\n+\r\n+import java.util.*;\r\n+\r\n+/*\r\n+   Copyright 2000-2014 Bo Zimmerman\r\n+\r\n+   Licensed under the Apache License, Version 2.0 (the "License");\r\n+   you may not use this file except in compliance with the License.\r\n+   You may obtain a copy of the License at\r\n+\r\n+\t   http://www.apache.org/licenses/LICENSE-2.0\r\n+\r\n+   Unless required by applicable law or agreed to in writing, software\r\n+   distributed under the License is distributed on an "AS IS" BASIS,\r\n+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r\n+   See the License for the specific language governing permissions and\r\n+   limitations under the License.\r\n+*/\r\n+public class Star extends GenSpaceBody\r\n+{\r\n+\t@Override public String ID(){\treturn "Star";}\r\n+\t\r\n+\tpublic Star()\r\n+\t{\r\n+\t\tsuper();\r\n+\t\tsetName("unknown star");\r\n+\t\tsetDisplayText("an unknown star is shining here");\r\n+\t\tsetDescription("it`s very bright");\r\n+\t\tcoordinates=new long[]{Math.round(Long.MAX_VALUE*Math.random()),Math.round(Long.MAX_VALUE*Math.random()),Math.round(Long.MAX_VALUE*Math.random())};\r\n+\t\tRandom random=new Random(System.currentTimeMillis());\r\n+\t\tradius=SpaceObject.Distance.StarGRadius.dm + (random.nextLong() % Math.round(CMath.mul(SpaceObject.Distance.StarGRadius.dm,0.30)));\r\n+\t\tbasePhyStats().setDisposition(PhyStats.IS_LIGHTSOURCE|PhyStats.IS_GLOWING);\r\n+\t\trecoverPhyStats();\r\n+\t\tthis.setMaterial(RawMaterial.RESOURCE_HYDROGEN);\r\n+\t}\r\n+}\r\ndiff --git a/com/planet_ink/coffee_mud/Items/Basic/StdSpaceBody.java b/com/planet_ink/coffee_mud/Items/Basic/StdSpaceBody.java\nindex c3724f6a22..a3dfeaab27 100644\n--- a/com/planet_ink/coffee_mud/Items/Basic/StdSpaceBody.java\n+++ b/com/planet_ink/coffee_mud/Items/Basic/StdSpaceBody.java\n@@ -38,7 +38,7 @@ public class StdSpaceBody extends StdItem implements SpaceObject\n \t@Override public String ID(){\treturn "StdSpaceBody";}\r\n \r\n \tprotected long[]\t\tcoordinates\t= new long[3];\r\n-\tprotected long\t\t\tradius\t\t= SpaceObject.Distance.StarBRadius.dm;\r\n+\tprotected long\t\t\tradius;\r\n \tprotected double[]\t\tdirection\t= new double[2];\r\n \tprotected long \t\t\tspeed\t\t= 0;\r\n \tprotected SpaceObject\tspaceSource = null;\r\n@@ -49,11 +49,19 @@ public class StdSpaceBody extends StdItem implements SpaceObject\n \t\tsuper();\r\n \t\tsetName("a thing in space");\r\n \t\tsetDisplayText("a thing is floating in space");\r\n+\t\tRandom random=new Random(System.currentTimeMillis());\r\n+\t\tradius=SpaceObject.Distance.Kilometer.dm + (random.nextLong() % (SpaceObject.Distance.Kilometer.dm / 2));\r\n \t\tbasePhyStats().setWeight(100);\r\n \t\tbasePhyStats().setLevel(1);\r\n \t\trecoverPhyStats();\r\n \t\tsetMaterial(RawMaterial.RESOURCE_STONE);\r\n \t}\r\n+\r\n+\tpublic void destroy()\r\n+\t{\r\n+\t\tCMLib.map().delObjectInSpace(this);\r\n+\t\tsuper.destroy();\r\n+\t}\r\n \t\r\n \t@Override\r\n \tpublic BoundedCube getBounds()\r\n@@ -64,7 +72,7 @@ public class StdSpaceBody extends StdItem implements SpaceObject\n \t@Override\r\n \tpublic long[] coordinates()\r\n \t{\r\n-\t\treturn coordinates();\r\n+\t\treturn coordinates;\r\n \t}\r\n \r\n \t@Override\r\ndiff --git a/com/planet_ink/coffee_mud/Libraries/CMGenEditor.java b/com/planet_ink/coffee_mud/Libraries/CMGenEditor.java\nindex 163874345d..3de455616a 100644\n--- a/com/planet_ink/coffee_mud/Libraries/CMGenEditor.java\n+++ b/com/planet_ink/coffee_mud/Libraries/CMGenEditor.java\n@@ -50,7 +50,6 @@ public class CMGenEditor extends StdLibrary implements GenericEditor\n \t// showNumber should always be a valid number no less than 1\r\n \t// showFlag should be a valid number for editing, or -1 for skipping\r\n \r\n-\r\n \t@Override\r\n \tpublic void promptStatInt(MOB mob, Modifiable E, int showNumber, int showFlag, String FieldDisp, String Field)\r\n \tthrows IOException\r\n@@ -4589,7 +4588,7 @@ public class CMGenEditor extends StdLibrary implements GenericEditor\n \t\t\t}\r\n \t\t\tLong newValue=CMLib.english().parseSpaceDistance(val);\r\n \t\t\tif((newValue==null)||(newValue.longValue()<0))\r\n-\t\t\t\tmob.tell(_("Unknown radius: \'@x1\', valid units include: @x2.",val,SpaceObject.Distance.getAbbrList()));\r\n+\t\t\t\tmob.tell(_("Unknown radius: \'@x1\', valid units include: @x2.",val,SpaceObject.Distance.getFullList()));\r\n \t\t\telse\r\n \t\t\t{\r\n \t\t\t\tE.setRadius(newValue.longValue());\r\n@@ -4600,7 +4599,7 @@ public class CMGenEditor extends StdLibrary implements GenericEditor\n \t\t\t\t+ _("1. 3 distances: \'[X],[Y],[Z]\', positive or negative.")+"\\n\\r"\r\n \t\t\t\t+ _("2. Relative distance: \'[X] FROM [name of another space object]\', in random direction.")+"\\n\\r"\r\n \t\t\t\t+ _("3. Relative distance: \'[X] FROM [name of another space object] TOWARD [Y],[Z]\', where Y,Z are a direction in degrees.");\r\n-\t\tfinal String coordHelp2="Valid distance units include: "+SpaceObject.Distance.getFullList()+".";\r\n+\t\tfinal String coordHelp2=_("Valid distance units include: @x1.",SpaceObject.Distance.getFullList());\r\n \t\twhile((mob!=null)&&(mob.session()!=null)&&(!mob.session().isStopped()))\r\n \t\t{\r\n \t\t\tString val=mob.session().prompt(_("@x1. Coordinates in Space (ENTER=@x2): ",""+showNumber,(CMLib.english().coordDescShort(E.coordinates()))));\r\n@@ -7429,6 +7428,11 @@ public class CMGenEditor extends StdLibrary implements GenericEditor\n \t\t\tgenValue(mob,me,++showNumber,showFlag);\r\n \t\t\tgenWeight(mob,me,++showNumber,showFlag);\r\n \t\t\tgenDisposition(mob,me.basePhyStats(),++showNumber,showFlag);\r\n+\t\t\tif(me instanceof SpaceObject)\r\n+\t\t\t{\r\n+\t\t\t\tSpaceObject spaceArea=(SpaceObject)me;\r\n+\t\t\t\tgenSpaceStuff(mob,spaceArea,++showNumber,showFlag);\r\n+\t\t\t}\r\n \t\t\tgenBehaviors(mob,me,++showNumber,showFlag);\r\n \t\t\tgenAffects(mob,me,++showNumber,showFlag);\r\n \t\t\tif(me instanceof LandTitle)\r\ndiff --git a/com/planet_ink/coffee_mud/Libraries/CMMap.java b/com/planet_ink/coffee_mud/Libraries/CMMap.java\nindex 7bd17dd33f..fdcb561954 100644\n--- a/com/planet_ink/coffee_mud/Libraries/CMMap.java\n+++ b/com/planet_ink/coffee_mud/Libraries/CMMap.java\n@@ -568,7 +568,7 @@ public class CMMap extends StdLibrary implements WorldMap\n \t@Override\r\n \tpublic List<SpaceObject> getSpaceObjectsWithin(final SpaceObject ofObj, long minDistance, long maxDistance)\r\n \t{\r\n-\t\tfinal List<SpaceObject> within=new Vector<SpaceObject>(1);\r\n+\t\tfinal List<SpaceObject> within=new ArrayList<SpaceObject>(1);\r\n \t\tif(ofObj==null)\r\n \t\t\treturn within;\r\n \t\tsynchronized(space)\r\n@@ -577,15 +577,14 @@ public class CMMap extends StdLibrary implements WorldMap\n \t\t}\r\n \t\tif(within.size()<=1)\r\n \t\t\treturn within;\r\n-\t\tfor (final SpaceObject o : within)\r\n+\t\tfor (final Iterator<SpaceObject> o=within.iterator();o.hasNext();)\r\n \t\t{\r\n-\t\t\tif(o!=ofObj)\r\n+\t\t\tSpaceObject O=o.next();\r\n+\t\t\tif(O!=ofObj)\r\n \t\t\t{\r\n-\t\t\t\tfinal long dist=getDistanceFrom(o,ofObj);\r\n-\t\t\t\tif((dist>=minDistance)&&(dist<=maxDistance))\r\n-\t\t\t\t{\r\n-\t\t\t\t\twithin.add(o);\r\n-\t\t\t\t}\r\n+\t\t\t\tfinal long dist=getDistanceFrom(O,ofObj);\r\n+\t\t\t\tif((dist>=minDistance)&&(dist>maxDistance))\r\n+\t\t\t\t\to.remove();\r\n \t\t\t}\r\n \t\t}\r\n \t\tCollections.sort(within, new Comparator<SpaceObject>()\r\n@@ -2424,6 +2423,13 @@ public class CMMap extends StdLibrary implements WorldMap\n \t\treturn false;\r\n \t}\r\n \r\n+\t@Override\r\n+\tpublic int numSpaceObjects()\r\n+\t{\r\n+\t\treturn space.count();\r\n+\t}\r\n+\r\n+\t\r\n \tprotected boolean isAScriptHost(final Area area, final PhysicalAgent host)\r\n \t{\r\n \t\tif(area == null) return false;\r\ndiff --git a/com/planet_ink/coffee_mud/Libraries/CoffeeMaker.java b/com/planet_ink/coffee_mud/Libraries/CoffeeMaker.java\nindex 8d04b5921d..eb190f7e6c 100644\n--- a/com/planet_ink/coffee_mud/Libraries/CoffeeMaker.java\n+++ b/com/planet_ink/coffee_mud/Libraries/CoffeeMaker.java\n@@ -192,20 +192,23 @@ public class CoffeeMaker extends StdLibrary implements GenericBuilder\n \t\t\tLog.errOut("CoffeeMaker","getPropertiesStr: null \'E\'");\r\n \t\t\treturn "";\r\n \t\t}\r\n-\t\treturn (E.isGeneric()?getGenPropertiesStr(E):"") + (fromTop?getOrdPropertiesStr(E):"");\r\n-\t}\r\n-\r\n-\t@Override\r\n-\tpublic String getOrdPropertiesStr(Environmental E)\r\n-\t{\r\n-\t\tfinal StringBuilder str=new StringBuilder("");\r\n \t\tif(E instanceof SpaceObject)\r\n \t\t{\r\n+\t\t\tfinal StringBuilder str=new StringBuilder("");\r\n \t\t\tstr.append(CMLib.xml().convertXMLtoTag("SSRADIUS",((SpaceObject)E).radius()));\r\n \t\t\tstr.append(CMLib.xml().convertXMLtoTag("SSCOORDS",CMParms.toStringList(((SpaceObject)E).coordinates())));\r\n \t\t\tstr.append(CMLib.xml().convertXMLtoTag("SSDIR",CMParms.toStringList(((SpaceObject)E).direction())));\r\n \t\t\tstr.append(CMLib.xml().convertXMLtoTag("SSSPEED",((SpaceObject)E).speed()));\r\n+\t\t\treturn str.append((E.isGeneric()?getGenPropertiesStr(E):"") + (fromTop?getOrdPropertiesStr(E):"")).toString();\r\n \t\t}\r\n+\t\telse\r\n+\t\t\treturn (E.isGeneric()?getGenPropertiesStr(E):"") + (fromTop?getOrdPropertiesStr(E):"");\r\n+\t}\r\n+\r\n+\t@Override\r\n+\tpublic String getOrdPropertiesStr(Environmental E)\r\n+\t{\r\n+\t\tfinal StringBuilder str=new StringBuilder("");\r\n \t\tif(E instanceof Room)\r\n \t\t{\r\n \t\t\tstr.append(CMLib.xml().convertXMLtoTag("RCLIM", ((Room)E).getClimateTypeCode()));\r\n@@ -1982,6 +1985,17 @@ public class CoffeeMaker extends StdLibrary implements GenericBuilder\n \t\t\t\tsetGenPropertiesStr(E,V);\r\n \t\t\tif(fromTop)\r\n \t\t\t\tsetOrdPropertiesStr(E,V);\r\n+\t\t\tif(E instanceof SpaceObject)\r\n+\t\t\t{\r\n+\t\t\t\t((SpaceObject)E).setRadius(CMLib.xml().getLongFromPieces(V,"SSRADIUS"));\r\n+\t\t\t\tfinal long[] coords=CMParms.toLongArray(CMParms.parseCommas(CMLib.xml().getValFromPieces(V,"SSCOORDS"), true));\r\n+\t\t\t\tif((coords!=null)&&(coords.length==3))\r\n+\t\t\t\t\t((SpaceObject)E).setCoords(coords);\r\n+\t\t\t\t((SpaceObject)E).setSpeed(CMLib.xml().getLongFromPieces(V,"SSSPEED"));\r\n+\t\t\t\tfinal double[] dir=CMParms.toDoubleArray(CMParms.parseCommas(CMLib.xml().getValFromPieces(V,"SSDIR"), true));\r\n+\t\t\t\tif((dir!=null)&&(dir.length==2))\r\n+\t\t\t\t\t((SpaceObject)E).setDirection(dir);\r\n+\t\t\t}\r\n \t\t}\r\n \t\tif(E instanceof Physical)\r\n \t\t\trecoverPhysical((Physical)E);\r\n@@ -2105,17 +2119,6 @@ public class CoffeeMaker extends StdLibrary implements GenericBuilder\n \t\t\tif(!M.isGeneric())\r\n \t\t\t\tM.setMiscText(CMLib.xml().getValFromPieces(V,"MTEXT"));\r\n \t\t}\r\n-\t\tif(E instanceof SpaceObject)\r\n-\t\t{\r\n-\t\t\t((SpaceObject)E).setRadius(CMLib.xml().getLongFromPieces(V,"SSRADIUS"));\r\n-\t\t\tfinal long[] coords=CMParms.toLongArray(CMParms.parseCommas(CMLib.xml().getValFromPieces(V,"SSCOORDS"), true));\r\n-\t\t\tif((coords!=null)&&(coords.length==3))\r\n-\t\t\t\t((SpaceObject)E).setCoords(coords);\r\n-\t\t\t((SpaceObject)E).setSpeed(CMLib.xml().getLongFromPieces(V,"SSSPEED"));\r\n-\t\t\tfinal double[] dir=CMParms.toDoubleArray(CMParms.parseCommas(CMLib.xml().getValFromPieces(V,"SSDIR"), true));\r\n-\t\t\tif((dir!=null)&&(dir.length==2))\r\n-\t\t\t\t((SpaceObject)E).setDirection(dir);\r\n-\t\t}\r\n \t}\r\n \r\n \t@Override\r\ndiff --git a/com/planet_ink/coffee_mud/Libraries/Dice.java b/com/planet_ink/coffee_mud/Libraries/Dice.java\nindex 7566df8463..f2d0799e3e 100644\n--- a/com/planet_ink/coffee_mud/Libraries/Dice.java\n+++ b/com/planet_ink/coffee_mud/Libraries/Dice.java\n@@ -95,6 +95,34 @@ public class Dice extends StdLibrary implements DiceLibrary\n \t\treturn roll(r,d,p);\r\n \t}\r\n \r\n+\tpublic long plusOrMinus(final long range)\r\n+\t{\r\n+\t\tfinal long l=randomizer.nextLong() % range;\r\n+\t\treturn randomizer.nextBoolean()?l:-l;\r\n+\t}\r\n+\t\r\n+\tpublic int plusOrMinus(final int range)\r\n+\t{\r\n+\t\tfinal int l=randomizer.nextInt() % range;\r\n+\t\treturn randomizer.nextBoolean()?l:-l;\r\n+\t}\r\n+\t\r\n+\tpublic int inRange(final int min, final int max)\r\n+\t{\r\n+\t\tif(max<=min) \r\n+\t\t\treturn min;\r\n+\t\tint l=randomizer.nextInt() % ((max-min)+1);\r\n+\t\treturn min+l;\r\n+\t}\r\n+\t\r\n+\tpublic long inRange(final long min, final long max)\r\n+\t{\r\n+\t\tif(max<=min) \r\n+\t\t\treturn min;\r\n+\t\tlong l=randomizer.nextLong() % ((max-min)+1);\r\n+\t\treturn min+l;\r\n+\t}\r\n+\t\r\n \t@Override\r\n \tpublic Object doublePick(Object[][] set)\r\n \t{\r\ndiff --git a/com/planet_ink/coffee_mud/Libraries/interfaces/DatabaseEngine.java b/com/planet_ink/coffee_mud/Libraries/interfaces/DatabaseEngine.java\nindex 96a4aec10e..3d52a79f17 100644\n--- a/com/planet_ink/coffee_mud/Libraries/interfaces/DatabaseEngine.java\n+++ b/com/planet_ink/coffee_mud/Libraries/interfaces/DatabaseEngine.java\n@@ -66,6 +66,7 @@ public interface DatabaseEngine extends CMLibrary\n \r\n \tpublic void DBUpdateFollowers(MOB mob);\r\n \tpublic void DBReadCatalogs();\r\n+\tpublic void DBReadSpace();\r\n \tpublic void DBReadContent(String roomID, Room thisRoom, boolean makeLive);\r\n \tpublic Area DBReadArea(Area A);\r\n \tpublic Map<String, Room> DBReadRoomData(String roomID, boolean reportStatus);\r\ndiff --git a/com/planet_ink/coffee_mud/Libraries/interfaces/DiceLibrary.java b/com/planet_ink/coffee_mud/Libraries/interfaces/DiceLibrary.java\nindex d85f482927..4102e44dbf 100644\n--- a/com/planet_ink/coffee_mud/Libraries/interfaces/DiceLibrary.java\n+++ b/com/planet_ink/coffee_mud/Libraries/interfaces/DiceLibrary.java\n@@ -48,4 +48,8 @@ public interface DiceLibrary extends CMLibrary\n \tpublic int rollNormalDistribution(int number, int die, int modifier);\r\n \tpublic int rollLow(int number, int die, int modifier);\r\n \tpublic Random getRandomizer();\r\n+\tpublic long plusOrMinus(final long range);\r\n+\tpublic int plusOrMinus(final int range);\r\n+\tpublic int inRange(final int min, final int max);\r\n+\tpublic long inRange(final long min, final long max);\r\n }\r\ndiff --git a/com/planet_ink/coffee_mud/Libraries/interfaces/WorldMap.java b/com/planet_ink/coffee_mud/Libraries/interfaces/WorldMap.java\nindex bfb0603ecc..02decbe128 100644\n--- a/com/planet_ink/coffee_mud/Libraries/interfaces/WorldMap.java\n+++ b/com/planet_ink/coffee_mud/Libraries/interfaces/WorldMap.java\n@@ -136,6 +136,7 @@ public interface WorldMap extends CMLibrary\n \t/**\t\t\t\t\t\t\t SPACE METHODS \t\t\t\t\t\t\t\t*/\r\n \t/************************************************************************/\r\n \tpublic long getRelativeSpeed(SpaceObject O1, SpaceObject O2);\r\n+\tpublic int numSpaceObjects();\r\n \tpublic boolean isObjectInSpace(SpaceObject O);\r\n \tpublic void delObjectInSpace(SpaceObject O);\r\n \tpublic void addObjectToSpace(SpaceObject O, long[] coords);\r\ndiff --git a/com/planet_ink/coffee_mud/application/MUD.java b/com/planet_ink/coffee_mud/application/MUD.java\nindex 8a157bd9e8..6cd8ee9ff0 100644\n--- a/com/planet_ink/coffee_mud/application/MUD.java\n+++ b/com/planet_ink/coffee_mud/application/MUD.java\n@@ -1139,6 +1139,8 @@ public class MUD extends Thread implements MudHost\n \t\t\t\tLog.sysOut(Thread.currentThread().getName(),"Loading map...");\r\n \t\t\t\tCMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: loading rooms....");\r\n \t\t\t\tCMLib.database().DBReadAllRooms(null);\r\n+\t\t\t\tCMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: loading space....");\r\n+\t\t\t\tCMLib.database().DBReadSpace();\r\n \t\t\t\tCMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: preparing map....");\r\n \t\t\t\tLog.sysOut(Thread.currentThread().getName(),"Preparing map...");\r\n \t\t\t\tCMLib.database().DBReadArtifacts();\r\n@@ -1149,6 +1151,8 @@ public class MUD extends Thread implements MudHost\n \t\t\t\t\tA.fillInAreaRooms();\r\n \t\t\t\t}\r\n \t\t\t\tLog.sysOut(Thread.currentThread().getName(),"Mapped rooms      : "+CMLib.map().numRooms()+" in "+CMLib.map().numAreas()+" areas");\r\n+\t\t\t\tif(CMLib.map().numSpaceObjects()>0)\r\n+\t\t\t\t\tLog.sysOut(Thread.currentThread().getName(),"Space objects     : "+CMLib.map().numSpaceObjects());\r\n \r\n \t\t\t\tif(!CMLib.map().roomIDs().hasMoreElements())\r\n \t\t\t\t{\r\ndiff --git a/com/planet_ink/coffee_mud/core/CMClass.java b/com/planet_ink/coffee_mud/core/CMClass.java\nindex 5715d69a6c..a222cb5ffa 100644\n--- a/com/planet_ink/coffee_mud/core/CMClass.java\n+++ b/com/planet_ink/coffee_mud/core/CMClass.java\n@@ -2220,7 +2220,7 @@ public class CMClass extends ClassLoader\n \t\t\telse\r\n \t\t\t{\r\n \t\t\t\tc.races=loadVectorListToObj(prefix+"Races/",page.getStr("RACES"),CMObjectType.RACE.ancestorName);\r\n-\t\t\t\tLog.sysOut(Thread.currentThread().getName(),"Races loaded      : "+c.races.size());\r\n+\t\t\t\t//Log.sysOut(Thread.currentThread().getName(),"Races loaded      : "+c.races.size());\r\n \t\t\t}\r\n \t\t\tif(c.races.size()==0) return false;\r\n \r\n@@ -2229,7 +2229,7 @@ public class CMClass extends ClassLoader\n \t\t\telse\r\n \t\t\t{\r\n \t\t\t\tc.charClasses=loadVectorListToObj(prefix+"CharClasses/",page.getStr("CHARCLASSES"),CMObjectType.CHARCLASS.ancestorName);\r\n-\t\t\t\tLog.sysOut(Thread.currentThread().getName(),"Classes loaded    : "+c.charClasses.size());\r\n+\t\t\t\t//Log.sysOut(Thread.currentThread().getName(),"Classes loaded    : "+c.charClasses.size());\r\n \t\t\t}\r\n \t\t\tif(c.charClasses.size()==0) return false;\r\n \r\n@@ -2494,6 +2494,7 @@ public class CMClass extends ClassLoader\n \t\t\t}\r\n \t\tif((tCode==MudHost.MAIN_HOST)||(CMProps.isPrivateToMe("RACE")))\r\n \t\t{\r\n+\t\t\tint numRaces=c.races.size();\r\n \t\t\tfor(int r=0;r<c.races.size();r++)\r\n \t\t\t{\r\n \t\t\t\tfinal Race R=c.races.elementAt(r);\r\n@@ -2503,7 +2504,6 @@ public class CMClass extends ClassLoader\n \t\t\tfinal List<DatabaseEngine.AckRecord> genRaces=CMLib.database().DBReadRaces();\r\n \t\t\tif(genRaces.size()>0)\r\n \t\t\t{\r\n-\t\t\t\tint loaded=0;\r\n \t\t\t\tfor(int r=0;r<genRaces.size();r++)\r\n \t\t\t\t{\r\n \t\t\t\t\tfinal Race GR=(Race)getRace("GenRace").copyOf();\r\n@@ -2511,15 +2511,15 @@ public class CMClass extends ClassLoader\n \t\t\t\t\tif(!GR.ID().equals("GenRace"))\r\n \t\t\t\t\t{\r\n \t\t\t\t\t\taddRace(GR);\r\n-\t\t\t\t\t\tloaded++;\r\n+\t\t\t\t\t\tnumRaces++;\r\n \t\t\t\t\t}\r\n \t\t\t\t}\r\n-\t\t\t\tif(loaded>0)\r\n-\t\t\t\t\tLog.sysOut(Thread.currentThread().getName(),"GenRaces loaded   : "+loaded);\r\n \t\t\t}\r\n+\t\t\tLog.sysOut(Thread.currentThread().getName(),"Races loaded      : "+numRaces);\r\n \t\t}\r\n \t\tif((tCode==MudHost.MAIN_HOST)||(CMProps.isPrivateToMe("CHARCLASS")))\r\n \t\t{\r\n+\t\t\tint numCharClasses=c.charClasses.size();\r\n \t\t\tCMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: reading genClasses");\r\n \t\t\tfinal List<DatabaseEngine.AckRecord> genClasses=CMLib.database().DBReadClasses();\r\n \t\t\tif(genClasses.size()>0)\r\n@@ -2532,12 +2532,11 @@ public class CMClass extends ClassLoader\n \t\t\t\t\tif(!CR.ID().equals("GenCharClass"))\r\n \t\t\t\t\t{\r\n \t\t\t\t\t\taddCharClass(CR);\r\n-\t\t\t\t\t\tloaded++;\r\n+\t\t\t\t\t\tnumCharClasses++;\r\n \t\t\t\t\t}\r\n \t\t\t\t}\r\n-\t\t\t\tif(loaded>0)\r\n-\t\t\t\t\tLog.sysOut(Thread.currentThread().getName(),"GenClasses loaded : "+loaded);\r\n \t\t\t}\r\n+\t\t\tLog.sysOut(Thread.currentThread().getName(),"Classes loaded    : "+numCharClasses);\r\n \t\t}\r\n \t\tCMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: initializing classes");\r\n \t\tc.intializeClasses();\r\ndiff --git a/com/planet_ink/coffee_mud/core/database/DBInterface.java b/com/planet_ink/coffee_mud/core/database/DBInterface.java\nindex f38e0fb9fd..d27dd61cc1 100644\n--- a/com/planet_ink/coffee_mud/core/database/DBInterface.java\n+++ b/com/planet_ink/coffee_mud/core/database/DBInterface.java\n@@ -231,6 +231,8 @@ public class DBInterface implements DatabaseEngine\n \r\n \t@Override public void DBReadCatalogs() {RoomLoader.DBReadCatalogs();}\r\n \r\n+\t@Override public void DBReadSpace() {RoomLoader.DBReadSpace();}\r\n+\t\r\n \t@Override\r\n \tpublic void DBReadContent(String roomID, Room thisRoom, boolean makeLive)\r\n \t{RoomLoader.DBReadContent(roomID,thisRoom, null,null,false,makeLive);}\r\ndiff --git a/com/planet_ink/coffee_mud/core/database/RoomLoader.java b/com/planet_ink/coffee_mud/core/database/RoomLoader.java\nindex 67b280dddb..03087bab13 100644\n--- a/com/planet_ink/coffee_mud/core/database/RoomLoader.java\n+++ b/com/planet_ink/coffee_mud/core/database/RoomLoader.java\n@@ -708,6 +708,11 @@ public class RoomLoader\n \t\tDBReadContent("CATALOG_ITEMS",null,null,null,true,false);\r\n \t}\r\n \r\n+\tpublic void DBReadSpace()\r\n+\t{\r\n+\t\tDBReadContent("SPACE",null,null,null,true,false);\r\n+\t}\r\n+\r\n \tpublic void DBReadContent(String thisRoomID, Room thisRoom, Map<String, Room> rooms, RoomnumberSet unloadedRooms, boolean setStatus, boolean makeLive)\r\n \t{\r\n \t\tfinal boolean debug=Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMPOP));\r\n@@ -721,6 +726,7 @@ public class RoomLoader\n \t\tHashtable<MOB, String> mobRides=null;\r\n \r\n \t\tfinal boolean catalog=((thisRoomID!=null)&&(thisRoomID.startsWith("CATALOG_")));\r\n+\t\tfinal boolean space=((thisRoomID!=null)&&(thisRoomID.equals("SPACE")));\r\n \r\n \t\tDBConnection D=null;\r\n \t\t// now grab the items\r\n@@ -740,6 +746,8 @@ public class RoomLoader\n \t\t\t\t\tcontinue;\r\n \t\t\t\tif((!catalog)&&(roomID.startsWith("CATALOG_")))\r\n \t\t\t\t\tcontinue;\r\n+\t\t\t\tif((!space)&&(roomID.startsWith("SPACE")))\r\n+\t\t\t\t\tcontinue;\r\n \t\t\t\titemNums=stuff.itemNums.get("NUMSFOR"+roomID.toUpperCase());\r\n \t\t\t\tif(itemNums==null)\r\n \t\t\t\t{\r\n@@ -793,6 +801,10 @@ public class RoomLoader\n \t\t\t\t\t\t}\r\n \t\t\t\t\t\telse\r\n \t\t\t\t\t\t\tnewItem.setMiscText(DBConnections.getResQuietly(R,"CMITTX"));\r\n+\t\t\t\t\t\tif(newItem instanceof SpaceObject)\r\n+\t\t\t\t\t\t{\r\n+\t\t\t\t\t\t\tCMLib.map().addObjectToSpace((SpaceObject)newItem, ((SpaceObject) newItem).coordinates());\r\n+\t\t\t\t\t\t}\r\n \t\t\t\t\t\tnewItem.basePhyStats().setRejuv((int)DBConnections.getLongRes(R,"CMITRE"));\r\n \t\t\t\t\t\tnewItem.setUsesRemaining((int)DBConnections.getLongRes(R,"CMITUR"));\r\n \t\t\t\t\t\tnewItem.basePhyStats().setLevel((int)DBConnections.getLongRes(R,"CMITLV"));\r\n@@ -832,6 +844,8 @@ public class RoomLoader\n \t\t\t\t\tcontinue;\r\n \t\t\t\tif((!catalog)&&(roomID.startsWith("CATALOG_")))\r\n \t\t\t\t\tcontinue;\r\n+\t\t\t\tif((!space) && roomID.equals("SPACE"))\r\n+\t\t\t\t\tcontinue;\r\n \t\t\t\tfinal String NUMID=DBConnections.getRes(R,"CMCHNM");\r\n \t\t\t\tfinal String MOBID=DBConnections.getRes(R,"CMCHID");\r\n \r\n@@ -894,6 +908,10 @@ public class RoomLoader\n \t\t\t\t\t\tfinal String ride=DBConnections.getRes(R,"CMCHRI");\r\n \t\t\t\t\t\tif((ride!=null)&&(ride.length()>0))\r\n \t\t\t\t\t\t\tmobRides.put(newMOB,ride);\r\n+\t\t\t\t\t\tif(newMOB instanceof SpaceObject)\r\n+\t\t\t\t\t\t{\r\n+\t\t\t\t\t\t\tCMLib.map().addObjectToSpace((SpaceObject)newMOB, ((SpaceObject) newMOB).coordinates());\r\n+\t\t\t\t\t\t}\r\n \t\t\t\t\t\tnewMOB.recoverCharStats();\r\n \t\t\t\t\t\tnewMOB.recoverPhyStats();\r\n \t\t\t\t\t\tnewMOB.recoverMaxState();\r\n', 'commit_subject': '', 'repo_name': 'bozimmerman/CoffeeMud', 'committer': {'name': 'bozimmerman', 'email': 'dc45fe023482b3b890b5e574e53c1d051f45b1ef@zimmers.net', 'time_sec': '1399529728', 'tz_offset': '0', 'date': {'seconds': '1399529728'}}, 'commit_tree': 'ef9cb8b318cac73416002d25117497d2e4730220', 'commit_message': '\n\ngit-svn-id: svn://192.168.1.10/public/CoffeeMud@11456 0d6f1817-ed0e-0410-87c9-987e46238f29\n', 'language_name': 'JavaScript', 'license': 'apache-2.0', 'hunks': '@@ -708,6 +708,11 @@ public class RoomLoader\n \t\tDBReadContent("CATALOG_ITEMS",null,null,null,true,false);\r\n \t}\r\n \r\n+\tpublic void DBReadSpace()\r\n+\t{\r\n+\t\tDBReadContent("SPACE",null,null,null,true,false);\r\n+\t}\r\n+\r\n \tpublic void DBReadContent(String thisRoomID, Room thisRoom, Map<String, Room> rooms, RoomnumberSet unloadedRooms, boolean setStatus, boolean makeLive)\r\n \t{\r\n \t\tfinal boolean debug=Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMPOP));\r\n@@ -721,6 +726,7 @@ public class RoomLoader\n \t\tHashtable<MOB, String> mobRides=null;\r\n \r\n \t\tfinal boolean catalog=((thisRoomID!=null)&&(thisRoomID.startsWith("CATALOG_")));\r\n+\t\tfinal boolean space=((thisRoomID!=null)&&(thisRoomID.equals("SPACE")));\r\n \r\n \t\tDBConnection D=null;\r\n \t\t// now grab the items\r\n@@ -740,6 +746,8 @@ public class RoomLoader\n \t\t\t\t\tcontinue;\r\n \t\t\t\tif((!catalog)&&(roomID.startsWith("CATALOG_")))\r\n \t\t\t\t\tcontinue;\r\n+\t\t\t\tif((!space)&&(roomID.startsWith("SPACE")))\r\n+\t\t\t\t\tcontinue;\r\n \t\t\t\titemNums=stuff.itemNums.get("NUMSFOR"+roomID.toUpperCase());\r\n \t\t\t\tif(itemNums==null)\r\n \t\t\t\t{\r\n@@ -793,6 +801,10 @@ public class RoomLoader\n \t\t\t\t\t\t}\r\n \t\t\t\t\t\telse\r\n \t\t\t\t\t\t\tnewItem.setMiscText(DBConnections.getResQuietly(R,"CMITTX"));\r\n+\t\t\t\t\t\tif(newItem instanceof SpaceObject)\r\n+\t\t\t\t\t\t{\r\n+\t\t\t\t\t\t\tCMLib.map().addObjectToSpace((SpaceObject)newItem, ((SpaceObject) newItem).coordinates());\r\n+\t\t\t\t\t\t}\r\n \t\t\t\t\t\tnewItem.basePhyStats().setRejuv((int)DBConnections.getLongRes(R,"CMITRE"));\r\n \t\t\t\t\t\tnewItem.setUsesRemaining((int)DBConnections.getLongRes(R,"CMITUR"));\r\n \t\t\t\t\t\tnewItem.basePhyStats().setLevel((int)DBConnections.getLongRes(R,"CMITLV"));\r\n@@ -832,6 +844,8 @@ public class RoomLoader\n \t\t\t\t\tcontinue;\r\n \t\t\t\tif((!catalog)&&(roomID.startsWith("CATALOG_")))\r\n \t\t\t\t\tcontinue;\r\n+\t\t\t\tif((!space) && roomID.equals("SPACE"))\r\n+\t\t\t\t\tcontinue;\r\n \t\t\t\tfinal String NUMID=DBConnections.getRes(R,"CMCHNM");\r\n \t\t\t\tfinal String MOBID=DBConnections.getRes(R,"CMCHID");\r\n \r\n@@ -894,6 +908,10 @@ public class RoomLoader\n \t\t\t\t\t\tfinal String ride=DBConnections.getRes(R,"CMCHRI");\r\n \t\t\t\t\t\tif((ride!=null)&&(ride.length()>0))\r\n \t\t\t\t\t\t\tmobRides.put(newMOB,ride);\r\n+\t\t\t\t\t\tif(newMOB instanceof SpaceObject)\r\n+\t\t\t\t\t\t{\r\n+\t\t\t\t\t\t\tCMLib.map().addObjectToSpace((SpaceObject)newMOB, ((SpaceObject) newMOB).coordinates());\r\n+\t\t\t\t\t\t}\r\n \t\t\t\t\t\tnewMOB.recoverCharStats();\r\n \t\t\t\t\t\tnewMOB.recoverPhyStats();\r\n \t\t\t\t\t\tnewMOB.recoverMaxState();\r\n', 'addition_count': 18, 'deletion_count': 0, 'src_file': 'a/com/planet_ink/coffee_mud/core/database/RoomLoader.java', 'tgt_file': 'b/com/planet_ink/coffee_mud/core/database/RoomLoader.java', 'file_extension': '.java', 'before_file': 'package com.planet_ink.coffee_mud.core.database;\nimport com.planet_ink.coffee_mud.core.interfaces.*;\nimport com.planet_ink.coffee_mud.core.*;\nimport com.planet_ink.coffee_mud.core.CMProps.Bool;\nimport com.planet_ink.coffee_mud.core.collections.*;\nimport com.planet_ink.coffee_mud.core.database.DBConnector.DBPreparedBatchEntry;\nimport com.planet_ink.coffee_mud.Abilities.interfaces.*;\nimport com.planet_ink.coffee_mud.Areas.interfaces.*;\nimport com.planet_ink.coffee_mud.Behaviors.interfaces.*;\nimport com.planet_ink.coffee_mud.CharClasses.interfaces.*;\nimport com.planet_ink.coffee_mud.Commands.interfaces.*;\nimport com.planet_ink.coffee_mud.Common.interfaces.*;\nimport com.planet_ink.coffee_mud.Exits.interfaces.*;\nimport com.planet_ink.coffee_mud.Items.interfaces.*;\nimport com.planet_ink.coffee_mud.Libraries.interfaces.*;\nimport com.planet_ink.coffee_mud.Libraries.interfaces.DatabaseEngine.ReadRoomDisableFlag;\nimport com.planet_ink.coffee_mud.Libraries.interfaces.DatabaseEngine.RoomContent;\nimport com.planet_ink.coffee_mud.Locales.interfaces.*;\nimport com.planet_ink.coffee_mud.MOBS.interfaces.*;\nimport com.planet_ink.coffee_mud.Races.interfaces.*;\n\nimport java.sql.*;\nimport java.util.*;\n\n/*\n   Copyright 2001-2022 Bo Zimmerman\n\n   Licensed under the Apache License, Version 2.0 (the "License");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n\t   http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an "AS IS" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\npublic class RoomLoader\n{\n\tprotected DBConnector\tDB\t\t\t\t\t= null;\n\tprivate int\t\t\t\trecordCount\t\t\t= 1;\n\tprivate int\t\t\t\tcurrentRecordPos\t= 1;\n\tprivate int\t\t\t\tupdateBreak\t\t\t= 1;\n\n\tpublic RoomLoader(final DBConnector newDB)\n\t{\n\t\tDB=newDB;\n\t}\n\n\tprivate final static String zeroes="000000000000";\n\n\tprivate final static Set<ReadRoomDisableFlag> noStatusReadRoomFlags=new XHashSet<ReadRoomDisableFlag>(ReadRoomDisableFlag.STATUS);\n\tprivate final static Set<ReadRoomDisableFlag> noLiveReadRoomFlags=new XHashSet<ReadRoomDisableFlag>(ReadRoomDisableFlag.LIVE);\n\tprivate final static Set<ReadRoomDisableFlag> allEnabledReadRoomFlags=new XHashSet<ReadRoomDisableFlag>();\n\n\tprotected static class StuffClass\n\t{\n\t\tpublic Hashtable<String,Hashtable<String,PhysicalAgent>> itemNums=new Hashtable<String,Hashtable<String,PhysicalAgent>>();\n\t\tpublic Hashtable<String,Hashtable<String,String>> cataData=new Hashtable<String,Hashtable<String,String>>();\n\t\tpublic Hashtable<String,Hashtable<Item,String>> itemLocs=new Hashtable<String,Hashtable<Item,String>>();\n\t\tpublic Hashtable<String,Hashtable<MOB, String>> mobRides=new Hashtable<String,Hashtable<MOB, String>>();\n\t}\n\n\tprotected DBPreparedBatchEntry doBulkInsert(final StringBuilder str, final List<String> clobs, final String sql, final String clob)\n\t{\n\t\tif(str.length()==0)\n\t\t{\n\t\t\tstr.append(sql);\n\t\t\tclobs.add(clob+" ");\n\t\t}\n\t\telse\n\t\tif(str.length()<512000)\n\t\t{\n\t\t\tfinal int x=sql.indexOf(" values ");\n\t\t\tstr.append(", ").append(sql.substring(x+7));\n\t\t\tclobs.add(clob+" ");\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfinal DBPreparedBatchEntry entry = new DBPreparedBatchEntry(str.toString(),clobs.toArray(new String[0]));\n\t\t\tstr.setLength(0);\n\t\t\treturn entry;\n\t\t}\n\t\treturn null;\n\t}\n\n\tpublic String DBIsAreaName(final String name)\n\t{\n\t\tDBConnection D=null;\n\t\ttry\n\t\t{\n\t\t\tD=DB.DBFetch();\n\t\t\tfinal ResultSet R=D.query("SELECT CMAREA FROM CMAREA WHERE CMAREA LIKE \'"+name+"\'");\n\t\t\tif(R.next())\n\t\t\t{\n\t\t\t\tfinal String areaName=R.getString("CMAREA");\n\t\t\t\tR.close();\n\t\t\t\treturn areaName;\n\t\t\t}\n\t\t}\n\t\tcatch(final SQLException sqle)\n\t\t{\n\t\t\tLog.errOut("Area",sqle);\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tDB.DBDone(D);\n\t\t}\n\t\treturn null;\n\t}\n\n\tpublic void DBReadArea(final Area A)\n\t{\n\t\tDBConnection D=null;\n\t\ttry\n\t\t{\n\t\t\tD=DB.DBFetch();\n\t\t\tfinal ResultSet R=D.query("SELECT * FROM CMAREA WHERE CMAREA=\'"+A.Name()+"\'");\n\t\t\twhile(R.next())\n\t\t\t{\n\t\t\t\tfinal String areaName=DBConnections.getRes(R,"CMAREA");\n\t\t\t\tA.setName(areaName);\n\t\t\t\tA.setClimateType((int)DBConnections.getLongRes(R,"CMCLIM"));\n\t\t\t\tA.setSubOpList(DBConnections.getRes(R,"CMSUBS"));\n\t\t\t\tA.setDescription(DBConnections.getRes(R,"CMDESC"));\n\t\t\t\tA.setMiscText(DBConnections.getRes(R,"CMROTX"));\n\t\t\t\tA.setTheme((int)DBConnections.getLongRes(R,"CMTECH"));\n\t\t\t}\n\t\t}\n\t\tcatch(final SQLException sqle)\n\t\t{\n\t\t\tLog.errOut("Area",sqle);\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tDB.DBDone(D);\n\t\t}\n\t}\n\n\tpublic boolean DBReadAreaFull(final String areaName)\n\t{\n\t\tif(CMLib.map().getArea(areaName)!=null)\n\t\t\treturn false;\n\t\tfinal Area A=DBReadAreaObject(areaName);\n\t\tif(A==null)\n\t\t\treturn false;\n\t\tfinal RoomnumberSet unloadedRooms=(RoomnumberSet)CMClass.getCommon("DefaultRoomnumberSet");\n\t\tfor(final Enumeration<String> ids = CMLib.map().roomIDs();ids.hasMoreElements();)\n\t\t\tunloadedRooms.add(ids.nextElement());\n\n\t\tfinal RoomnumberSet set = CMLib.database().DBReadAreaRoomList(areaName, false);\n\t\tCMLib.map().addArea(A);\n\t\tCMLib.map().registerWorldObjectLoaded(A, null, A);\n\t\tfinal Map<String,Room> rooms=DBReadRoomData(null,set,false,null,unloadedRooms);\n\n\t\tDBReadRoomExits(null,rooms,false,unloadedRooms);\n\n\t\tDBReadContent(null,null,rooms,unloadedRooms,noStatusReadRoomFlags);\n\n\t\tfor(final Map.Entry<String,Room> entry : rooms.entrySet())\n\t\t{\n\t\t\tfinal Room thisRoom=entry.getValue();\n\t\t\tthisRoom.startItemRejuv();\n\t\t\tthisRoom.recoverRoomStats();\n\t\t}\n\t\treturn true;\n\t}\n\n\tpublic Area DBReadAreaObject(String areaName)\n\t{\n\t\tDBConnection D=null;\n\t\ttry\n\t\t{\n\t\t\tD=DB.DBFetch();\n\t\t\tfinal ResultSet R=D.query("SELECT * FROM CMAREA WHERE CMAREA = \'" + areaName + "\'");\n\t\t\trecordCount=DB.getRecordCount(D,R);\n\t\t\tupdateBreak=CMath.s_int("1"+zeroes.substring(0,(""+(recordCount/100)).length()-1));\n\t\t\twhile(R.next())\n\t\t\t{\n\t\t\t\tcurrentRecordPos=R.getRow();\n\t\t\t\tareaName=DBConnections.getRes(R,"CMAREA");\n\t\t\t\tfinal String areaType=DBConnections.getRes(R,"CMTYPE");\n\t\t\t\tArea A=CMClass.getAreaType(areaType);\n\t\t\t\tif(A==null)\n\t\t\t\t\tA=CMClass.getAreaType("StdArea");\n\t\t\t\tif(A==null)\n\t\t\t\t{\n\t\t\t\t\tLog.errOut("Could not read area: "+areaName);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tA.setName(areaName);\n\t\t\t\tA.setClimateType((int)DBConnections.getLongRes(R,"CMCLIM"));\n\t\t\t\tA.setSubOpList(DBConnections.getRes(R,"CMSUBS"));\n\t\t\t\tA.setDescription(DBConnections.getRes(R,"CMDESC"));\n\t\t\t\tfinal String miscData=DBConnections.getRes(R,"CMROTX");\n\t\t\t\tA.setTheme((int)DBConnections.getLongRes(R,"CMTECH"));\n\t\t\t\tif((currentRecordPos%updateBreak)==0)\n\t\t\t\t\tCMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Loading Areas ("+currentRecordPos+" of "+recordCount+")");\n\t\t\t\tR.close();\n\t\t\t\tA.setMiscText(miscData);\n\t\t\t\tA.setAreaState(Area.State.ACTIVE);\n\t\t\t\treturn A;\n\t\t\t}\n\t\t}\n\t\tcatch(final SQLException sqle)\n\t\t{\n\t\t\tLog.errOut("Area",sqle);\n\t\t}\n\t\tcatch(final Exception sqle)\n\t\t{\n\t\t\tLog.errOut("Area",sqle);\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tDB.DBDone(D);\n\t\t}\n\t\treturn null;\n\t}\n\n\tprotected void DBReadAllAreas()\n\t{\n\t\tDBConnection D=null;\n\t\twhile(CMLib.map().numAreas()>0)\n\t\t\tCMLib.map().delArea(CMLib.map().getFirstArea());\n\t\ttry\n\t\t{\n\t\t\tD=DB.DBFetch();\n\t\t\tCMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Counting Areas");\n\t\t\tfinal ResultSet R=D.query("SELECT * FROM CMAREA");\n\t\t\trecordCount=DB.getRecordCount(D,R);\n\t\t\tupdateBreak=CMath.s_int("1"+zeroes.substring(0,(""+(recordCount/100)).length()-1));\n\t\t\tfinal LinkedList<Pair<Area,String>> areasLoaded=new LinkedList<Pair<Area,String>>();\n\t\t\twhile(R.next())\n\t\t\t{\n\t\t\t\tcurrentRecordPos=R.getRow();\n\t\t\t\tfinal String areaName=DBConnections.getRes(R,"CMAREA");\n\t\t\t\tfinal String areaType=DBConnections.getRes(R,"CMTYPE");\n\t\t\t\tArea A=CMClass.getAreaType(areaType);\n\t\t\t\tif(A==null)\n\t\t\t\t\tA=CMClass.getAreaType("StdArea");\n\t\t\t\tif(A==null)\n\t\t\t\t{\n\t\t\t\t\tLog.errOut("Could not read area: "+areaName);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tA.setName(areaName);\n\t\t\t\tA.setClimateType((int)DBConnections.getLongRes(R,"CMCLIM"));\n\t\t\t\tA.setSubOpList(DBConnections.getRes(R,"CMSUBS"));\n\t\t\t\tA.setDescription(DBConnections.getRes(R,"CMDESC"));\n\t\t\t\tfinal String miscData=DBConnections.getRes(R,"CMROTX");\n\t\t\t\tA.setTheme((int)DBConnections.getLongRes(R,"CMTECH"));\n\t\t\t\tif((currentRecordPos%updateBreak)==0)\n\t\t\t\t\tCMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Loading Areas ("+currentRecordPos+" of "+recordCount+")");\n\n\t\t\t\tCMLib.map().addArea(A);\n\t\t\t\tareasLoaded.add(new Pair<Area,String>(A,miscData));\n\t\t\t}\n\t\t\tfor(final Pair<Area,String> a : areasLoaded)\n\t\t\t{\n\t\t\t\ta.first.setMiscText(a.second);\n\t\t\t}\n\t\t\tfor(final Pair<Area,String> a : areasLoaded)\n\t\t\t{\n\t\t\t\ta.first.setAreaState(Area.State.ACTIVE);\n\t\t\t\tCMLib.map().registerWorldObjectLoaded(a.first, null, a.first);\n\t\t\t}\n\t\t}\n\t\tcatch(final SQLException sqle)\n\t\t{\n\t\t\tLog.errOut("Area",sqle);\n\t\t}\n\t\tcatch(final Exception sqle)\n\t\t{\n\t\t\tLog.errOut("Area",sqle);\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tDB.DBDone(D);\n\t\t}\n\t}\n\n\tpublic RoomnumberSet DBReadAreaRoomList(final String areaName, final boolean reportStatus)\n\t{\n\t\tfinal RoomnumberSet roomSet=(RoomnumberSet)CMClass.getCommon("DefaultRoomnumberSet");\n\t\tDBConnection D=null;\n\t\ttry\n\t\t{\n\t\t\tD=DB.DBFetch();\n\t\t\tif(reportStatus)\n\t\t\t\tCMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Fetching roomnums for "+areaName);\n\t\t\tfinal ResultSet R=D.query("SELECT * FROM CMROOM"+((areaName==null)?"":" WHERE CMAREA=\'"+areaName+"\'"));\n\t\t\twhile(R.next())\n\t\t\t\troomSet.add(DBConnections.getRes(R,"CMROID"));\n\t\t}\n\t\tcatch(final SQLException sqle)\n\t\t{\n\t\t\tLog.errOut("RoomSet",sqle);\n\t\t\treturn null;\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tDB.DBDone(D);\n\t\t}\n\t\treturn roomSet;\n\t}\n\n\tpublic Room DBReadRoomData(final String singleRoomIDtoLoad, final boolean reportStatus)\n\t{\n\t\tfinal Map<String,Room> map = DBReadRoomData(singleRoomIDtoLoad,null,reportStatus,null,null);\n\t\tfinal Iterator<Room> i = map.values().iterator();\n\t\tif(i.hasNext())\n\t\t\treturn i.next();\n\t\treturn null;\n\t}\n\n\tpublic Room[] DBReadRoomObjects(final String areaName, final boolean reportStatus)\n\t{\n\t\tDBConnection D=null;\n\t\ttry\n\t\t{\n\t\t\tD=DB.DBFetch();\n\t\t\tif(reportStatus)\n\t\t\t\tCMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Counting Rooms");\n\t\t\tfinal ResultSet R=D.query("SELECT * FROM CMROOM WHERE CMAREA=\'"+areaName+"\'");\n\t\t\tfinal List<Room> rooms=buildRoomObjects(D,R,reportStatus);\n\t\t\treturn rooms.toArray(new Room[0]);\n\t\t}\n\t\tcatch(final SQLException sqle)\n\t\t{\n\t\t\tLog.errOut("Room",sqle);\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tDB.DBDone(D);\n\t\t}\n\t\treturn new Room[0];\n\t}\n\n\tprivate void populateRoomInnerFields(final ResultSet R, final Room newRoom) throws SQLException\n\t{\n\t\tnewRoom.setDisplayText(DBConnections.getRes(R,"CMDESC1"));\n\t\tif(CMProps.getBoolVar(CMProps.Bool.ROOMDNOCACHE))\n\t\t\tnewRoom.setDescription("");\n\t\telse\n\t\t\tnewRoom.setDescription(DBConnections.getRes(R,"CMDESC2"));\n\t\tnewRoom.setMiscText(DBConnections.getRes(R,"CMROTX"));\n\t}\n\n\tprivate List<Room> buildRoomObjects(final DBConnection D, final ResultSet R, final boolean reportStatus) throws SQLException\n\t{\n\t\trecordCount=DB.getRecordCount(D,R);\n\t\tupdateBreak=CMath.s_int("1"+zeroes.substring(0,(""+(recordCount/100)).length()-1));\n\t\tString roomID=null;\n\t\tfinal List<Room> rooms=new Vector<Room>();\n\t\twhile(R.next())\n\t\t{\n\t\t\tcurrentRecordPos=R.getRow();\n\t\t\troomID=DBConnections.getRes(R,"CMROID");\n\t\t\tfinal String localeID=DBConnections.getRes(R,"CMLOID");\n\t\t\t//String areaName=DBConnections.getRes(R,"CMAREA");\n\t\t\tfinal Room newRoom=CMClass.getLocale(localeID);\n\t\t\tif(newRoom==null)\n\t\t\t\tLog.errOut("Room","Couldn\'t load room \'"+roomID+"\', localeID \'"+localeID+"\'.");\n\t\t\telse\n\t\t\t{\n\t\t\t\tnewRoom.setRoomID(roomID);\n\t\t\t\tpopulateRoomInnerFields(R,newRoom);\n\t\t\t\trooms.add(newRoom);\n\t\t\t}\n\t\t\tif(((currentRecordPos%updateBreak)==0)&&(reportStatus))\n\t\t\t\tCMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Loading Rooms ("+currentRecordPos+" of "+recordCount+")");\n\t\t}\n\t\treturn rooms;\n\t}\n\n\tpublic boolean DBReReadRoomData(final Room room)\n\t{\n\t\tif((room==null)||(room.roomID()==null))\n\t\t\treturn false;\n\t\tDBConnection D=null;\n\t\ttry\n\t\t{\n\t\t\tD=DB.DBFetch();\n\t\t\tfinal ResultSet R=D.query("SELECT * FROM CMROOM WHERE CMROID=\'"+room.roomID()+"\'");\n\t\t\tif(R.next())\n\t\t\t\tpopulateRoomInnerFields(R, room);\n\t\t\telse\n\t\t\t\treturn false;\n\t\t}\n\t\tcatch(final SQLException sqle)\n\t\t{\n\t\t\tLog.errOut("Room",sqle);\n\t\t\treturn false;\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tDB.DBDone(D);\n\t\t}\n\t\treturn true;\n\t}\n\n\tpublic Room DBReadRoomObject(final String roomIDtoLoad, final boolean reportStatus)\n\t{\n\t\tDBConnection D=null;\n\t\ttry\n\t\t{\n\t\t\tD=DB.DBFetch();\n\t\t\tif(reportStatus)\n\t\t\t\tCMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Counting Rooms");\n\t\t\tfinal ResultSet R=D.query("SELECT * FROM CMROOM WHERE CMROID=\'"+roomIDtoLoad+"\'");\n\t\t\tfinal List<Room> rooms=buildRoomObjects(D,R,reportStatus);\n\t\t\tif(rooms.size()>0)\n\t\t\t\treturn rooms.get(0);\n\t\t}\n\t\tcatch(final SQLException sqle)\n\t\t{\n\t\t\tLog.errOut("Room",sqle);\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tDB.DBDone(D);\n\t\t}\n\t\treturn null;\n\t}\n\n\tpublic Map<String,Room> DBReadRoomData(final String singleRoomIDtoLoad,\n\t\t\t\t\t\t\t\t\t\t   final RoomnumberSet roomsToLoad,\n\t\t\t\t\t\t\t\t\t\t   final boolean reportStatus,\n\t\t\t\t\t\t\t\t\t\t   final List<String> unknownAreas,\n\t\t\t\t\t\t\t\t\t\t   final RoomnumberSet unloadedRooms)\n\t{\n\t\tfinal STreeMap<String, Room> roomSet = new STreeMap<String, Room>(new Comparator<String>()\n\t\t{\n\t\t\t@Override\n\t\t\tpublic int compare(final String o1, final String o2)\n\t\t\t{\n\t\t\t\tif(o1==o2)\n\t\t\t\t\treturn 0;\n\t\t\t\tif(o1==null)\n\t\t\t\t\treturn -1;\n\t\t\t\tif(o2==null)\n\t\t\t\t\treturn 1;\n\t\t\t\treturn o1.compareTo(o2);\n\t\t\t}\n\t\t});\n\t\tDBConnection D=null;\n\t\ttry\n\t\t{\n\t\t\tD=DB.DBFetch();\n\t\t\tif(reportStatus)\n\t\t\t\tCMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Counting Rooms");\n\t\t\tfinal ResultSet R=D.query("SELECT * FROM CMROOM"+((singleRoomIDtoLoad==null)?"":" WHERE CMROID=\'"+singleRoomIDtoLoad+"\'"));\n\t\t\trecordCount=DB.getRecordCount(D,R);\n\t\t\tupdateBreak=CMath.s_int("1"+zeroes.substring(0,(""+(recordCount/100)).length()-1));\n\t\t\tString roomID=null;\n\t\t\twhile(R.next())\n\t\t\t{\n\t\t\t\tcurrentRecordPos=R.getRow();\n\t\t\t\troomID=DBConnections.getRes(R,"CMROID");\n\t\t\t\tif((roomsToLoad!=null)&&(!roomsToLoad.contains(roomID)))\n\t\t\t\t\tcontinue;\n\t\t\t\tfinal String localeID=DBConnections.getRes(R,"CMLOID");\n\t\t\t\tfinal String areaName=DBConnections.getRes(R,"CMAREA");\n\t\t\t\tArea myArea=CMLib.map().getArea(areaName);\n\t\t\t\tif(myArea==null)\n\t\t\t\t{\n\t\t\t\t\tmyArea=(Area)CMClass.getAreaType("StdArea").copyOf();\n\t\t\t\t\tmyArea.setName(areaName);\n\t\t\t\t\tif((unknownAreas!=null)\n\t\t\t\t\t&&(!unknownAreas.contains(areaName)))\n\t\t\t\t\t\tunknownAreas.add(areaName);\n\t\t\t\t}\n\t\t\t\tmyArea.addProperRoomnumber(roomID);\n\t\t\t\tif(CMath.bset(myArea.flags(),Area.FLAG_THIN))\n\t\t\t\t{\n\t\t\t\t\tif(unloadedRooms!=null)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(!unloadedRooms.contains(roomID))\n\t\t\t\t\t\t\tunloadedRooms.add(roomID);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfinal Room newRoom=CMClass.getLocale(localeID);\n\t\t\t\tif(newRoom==null)\n\t\t\t\t\tLog.errOut("Room","Couldn\'t load room \'"+roomID+"\', localeID \'"+localeID+"\'.");\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tnewRoom.setRoomID(roomID);\n\t\t\t\t\tnewRoom.setArea(myArea);\n\t\t\t\t\tCMLib.map().registerWorldObjectLoaded(myArea, newRoom, newRoom);\n\t\t\t\t\tnewRoom.setDisplayText(DBConnections.getRes(R,"CMDESC1"));\n\t\t\t\t\tif(CMProps.getBoolVar(CMProps.Bool.ROOMDNOCACHE))\n\t\t\t\t\t\tnewRoom.setDescription("");\n\t\t\t\t\telse\n\t\t\t\t\t\tnewRoom.setDescription(DBConnections.getRes(R,"CMDESC2"));\n\t\t\t\t\tnewRoom.setMiscText(DBConnections.getRes(R,"CMROTX"));\n\t\t\t\t\troomSet.put(roomID,newRoom);\n\t\t\t\t}\n\t\t\t\tif(((currentRecordPos%updateBreak)==0)&&(reportStatus))\n\t\t\t\t\tCMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Loading Rooms ("+currentRecordPos+" of "+recordCount+")");\n\t\t\t}\n\t\t}\n\t\tcatch(final SQLException sqle)\n\t\t{\n\t\t\tLog.errOut("Room",sqle);\n\t\t\treturn null;\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tDB.DBDone(D);\n\t\t}\n\t\treturn roomSet;\n\t}\n\n\tpublic void DBReadRoomExits(final String roomID, final Room room, final boolean reportStatus)\n\t{\n\t\tfinal Map<String,Room> map=new TreeMap<String,Room>();\n\t\tmap.put(roomID, room);\n\t\tDBReadRoomExits(roomID,map,reportStatus,null);\n\t}\n\n\tpublic void DBReadRoomExits(String roomID, final Map<String, Room> allRooms, final boolean reportStatus, final RoomnumberSet unloadedRooms)\n\t{\n\t\tfinal List<String> badRoomIDs=new LinkedList<String>();\n\t\tDBConnection D=null;\n\t\t// now grab the exits\n\t\ttry\n\t\t{\n\t\t\tD=DB.DBFetch();\n\t\t\tif(reportStatus)\n\t\t\t\tCMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Counting Exits");\n\t\t\tfinal ResultSet R=D.query("SELECT * FROM CMROEX"+((roomID==null)?"":" WHERE CMROID=\'"+roomID+"\'"));\n\t\t\tRoom thisRoom=null;\n\t\t\tRoom newRoom=null;\n\t\t\trecordCount=DB.getRecordCount(D,R);\n\t\t\tupdateBreak=CMath.s_int("1"+zeroes.substring(0,(""+(recordCount/100)).length()-1));\n\t\t\twhile(R.next())\n\t\t\t{\n\t\t\t\tcurrentRecordPos=R.getRow();\n\t\t\t\troomID=DBConnections.getRes(R,"CMROID");\n\t\t\t\tfinal int direction=(int)DBConnections.getLongRes(R,"CMDIRE");\n\t\t\t\tthisRoom=allRooms.get(roomID);\n\t\t\t\tif(thisRoom==null)\n\t\t\t\t{\n\t\t\t\t\tif((unloadedRooms!=null)&&(!unloadedRooms.contains(roomID)))\n\t\t\t\t\t{\n\t\t\t\t\t\tif((!CMProps.getBoolVar(Bool.MUDSTARTED))\n\t\t\t\t\t\t&&(!CMProps.getBoolVar(Bool.MUDSHUTTINGDOWN)))\n\t\t\t\t\t\t\tbadRoomIDs.add(roomID);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tLog.errOut("Room","Couldn\'t set "+direction+" exit for unknown room \'"+roomID+"\'");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfinal String exitID=DBConnections.getRes(R,"CMEXID");\n\t\t\t\t\tfinal String exitMiscText=DBConnections.getResQuietly(R,"CMEXTX");\n\t\t\t\t\tfinal String nextRoomID=DBConnections.getRes(R,"CMNRID");\n\t\t\t\t\tnewRoom=allRooms.get(nextRoomID);\n\t\t\t\t\tfinal Exit newExit=CMClass.getExit(exitID);\n\t\t\t\t\tif(nextRoomID.length()==0)\n\t\t\t\t\t{\n\t\t\t\t\t\t/* this is likely a room link (rebuilt by import at a later time) */\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(newRoom==null)\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal int x=nextRoomID.indexOf(\'#\');\n\t\t\t\t\t\tArea otherA=null;\n\t\t\t\t\t\tif((unloadedRooms!=null)&&(unloadedRooms.contains(nextRoomID)))\n\t\t\t\t\t\t\totherA=thisRoom.getArea();\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif(x>0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\totherA=CMLib.map().getArea(nextRoomID.substring(0,x));\n\t\t\t\t\t\t\tif(otherA!=null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(otherA!=thisRoom.getArea())\n\t\t\t\t\t\t\t\t\tnewRoom=otherA.getRoom(nextRoomID);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfor(final Enumeration<Area> a=CMLib.map().areas();a.hasMoreElements();)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal Area A=a.nextElement();\n\t\t\t\t\t\t\t\tif((A!=null)\n\t\t\t\t\t\t\t\t&&(A.getProperRoomnumbers().contains(nextRoomID)))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\totherA=A;\n\t\t\t\t\t\t\t\t\tif(!CMath.bset(A.flags(), Area.FLAG_THIN))\n\t\t\t\t\t\t\t\t\t\tnewRoom=otherA.getRoom(nextRoomID);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif(newRoom!=null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t/* its all worked out now */\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif(otherA==null)\n\t\t\t\t\t\t\tLog.errOut("RoomLoader","Unknown area for unlinked room #"+nextRoomID+" in "+roomID);\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif(((unloadedRooms!=null)&&(unloadedRooms.contains(nextRoomID)))\n\t\t\t\t\t\t||(CMath.bset(otherA.flags(),Area.FLAG_THIN)))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnewRoom=CMClass.getLocale("ThinRoom");\n\t\t\t\t\t\t\tnewRoom.setRoomID(nextRoomID);\n\t\t\t\t\t\t\tnewRoom.setArea(otherA);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif(!nextRoomID.startsWith("#"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tLog.errOut("RoomLoader","Unknown unlinked room #"+nextRoomID+" in "+roomID);\n\t\t\t\t\t\t\tif(CMSecurity.isDisabled(CMSecurity.DisFlag.BADEXITS))\n\t\t\t\t\t\t\t\tDB.update("DELETE FROM CMROEX WHERE ROOMID=\'"+roomID+"\' AND CMDIRE="+direction);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif(newExit!=null)\n\t\t\t\t\t\t\tnewExit.setTemporaryDoorLink(nextRoomID);\n\t\t\t\t\t}\n\n\t\t\t\t\tif((newExit==null)&&(newRoom==null))\n\t\t\t\t\t\tLog.errOut("Room",roomID+":no room&exit to \'"+nextRoomID+"\', exit type \'"+exitID+"\', direction: "+direction);\n\t\t\t\t\telse\n\t\t\t\t\tif((direction>255)&&(!(thisRoom instanceof GridLocale)))\n\t\t\t\t\t\tLog.errOut("Room","Not GridLocale, tried "+direction+" exit for room \'"+roomID+"\'");\n\t\t\t\t\telse\n\t\t\t\t\tif((direction>255)&&(newRoom!=null))\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal List<String> CEs=CMParms.parseSemicolons(exitMiscText.trim(),true);\n\t\t\t\t\t\tfor(int ces=0;ces<CEs.size();ces++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal Vector<String> SCE=CMParms.parse(CEs.get(ces).trim());\n\t\t\t\t\t\t\tfinal GridLocale.CrossExit CE=new GridLocale.CrossExit();\n\t\t\t\t\t\t\tif(SCE.size()<3)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\tCE.x=CMath.s_int(SCE.elementAt(0));\n\t\t\t\t\t\t\tCE.y=CMath.s_int(SCE.elementAt(1));\n\t\t\t\t\t\t\tfinal int codeddir=CMath.s_int(SCE.elementAt(2));\n\t\t\t\t\t\t\tif(SCE.size()>=4)\n\t\t\t\t\t\t\t\tCE.destRoomID=newRoom.roomID()+SCE.elementAt(3);\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tCE.destRoomID=newRoom.roomID();\n\t\t\t\t\t\t\tCE.out=(codeddir&256)==256;\n\t\t\t\t\t\t\tCE.dir=codeddir&255;\n\t\t\t\t\t\t\t((GridLocale)thisRoom).addOuterExit(CE);\n\t\t\t\t\t\t\tif((!CE.out)&&(!(newRoom instanceof GridLocale)))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tnewRoom.rawDoors()[CE.dir]=thisRoom;\n\t\t\t\t\t\t\t\tnewRoom.setRawExit(CE.dir,CMClass.getExit("Open"));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif(newExit!=null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnewExit.setTemporaryDoorLink("{{#"+roomID+"#}}");\n\t\t\t\t\t\t\tnewExit.setMiscText(exitMiscText);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(direction>=Directions.NUM_DIRECTIONS())\n\t\t\t\t\t\t\tLog.errOut("RoomLoader",CMLib.map().getExtendedRoomID(thisRoom)+" has an invalid direction #"+direction);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tthisRoom.rawDoors()[direction]=newRoom;\n\t\t\t\t\t\t\tthisRoom.setRawExit(direction,newExit);\n\t\t\t\t\t\t\tCMLib.map().registerWorldObjectLoaded(thisRoom.getArea(), newRoom, newExit);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(reportStatus&&((currentRecordPos%updateBreak)==0))\n\t\t\t\t\tCMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Loading Exits ("+currentRecordPos+" of "+recordCount+")");\n\t\t\t}\n\t\t}\n\t\tcatch(final SQLException sqle)\n\t\t{\n\t\t\tLog.errOut("Room",sqle);\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tDB.DBDone(D);\n\t\t}\n\t\tfor(final String badRoomId : badRoomIDs)\n\t\t{\n\t\t\tLog.errOut("RoomLoader","Deleted exits for unknown room #"+badRoomId);\n\t\t\tDB.update("DELETE FROM CMROEX WHERE CMROID=\'"+badRoomId+"\';");\n\t\t}\n\t}\n\n\tpublic void DBReadAllRooms(final RoomnumberSet set)\n\t{\n\t\tfinal List<String> newAreasToCreate=new Vector<String>();\n\t\tif(set==null)\n\t\t\tDBReadAllAreas();\n\t\tif(CMLib.map().numAreas()==0)\n\t\t\treturn;\n\n\t\tfinal RoomnumberSet unloadedRooms=(RoomnumberSet)CMClass.getCommon("DefaultRoomnumberSet");\n\t\tfinal Map<String,Room> rooms=DBReadRoomData(null,set,set==null,newAreasToCreate,unloadedRooms);\n\n\t\t// handle stray areas\n\t\tfor(final String areaName : newAreasToCreate)\n\t\t{\n\t\tDBReadContent("CATALOG_ITEMS",null,null,null,true,false);\r\n\t}\r\n\r\n\tpublic void DBReadContent(String thisRoomID, Room thisRoom, Map<String, Room> rooms, RoomnumberSet unloadedRooms, boolean setStatus, boolean makeLive)\r\n\t{\r\n\t\tfinal boolean debug=Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMPOP));\r\n\t\t\t}\n\t\t}\n\n\t\tDBReadRoomExits(null,rooms,set==null,unloadedRooms);\n\n\t\tfinal Set<ReadRoomDisableFlag> flags=(set == null) ? RoomLoader.allEnabledReadRoomFlags : RoomLoader.noStatusReadRoomFlags;\n\t\tDBReadContent(null,null,rooms,unloadedRooms,flags);\n\t\tHashtable<MOB, String> mobRides=null;\r\n\r\n\t\tfinal boolean catalog=((thisRoomID!=null)&&(thisRoomID.startsWith("CATALOG_")));\r\n\r\n\t\tDBConnection D=null;\r\n\t\t// now grab the items\r\n\t\t\tthisRoom.startItemRejuv();\n\t\t\tthisRoom.recoverRoomStats();\n\t\t}\n\n\t\tif(set==null)\n\t\t{\n\t\t\tfor(final Enumeration<Area> a=CMLib.map().areas();a.hasMoreElements();)\n\t\t\t\ta.nextElement().getAreaStats();\n\t\t}\n\t}\n\n\tpublic String DBReadRoomDesc(final String roomID)\n\t{\n\t\t\t\t\tcontinue;\r\n\t\t\t\tif((!catalog)&&(roomID.startsWith("CATALOG_")))\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\titemNums=stuff.itemNums.get("NUMSFOR"+roomID.toUpperCase());\r\n\t\t\t\tif(itemNums==null)\r\n\t\t\t\t{\r\n\t\t\t\tfinal String txt=DBConnections.getRes(R,"CMDESC2");\n\t\t\t\treturn txt;\n\t\t\t}\n\t\t}\n\t\tcatch(final SQLException sqle)\n\t\t{\n\t\t\tLog.errOut("Room",sqle);\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tDB.DBDone(D);\n\t\t}\n\t\treturn null;\n\t}\n\n\tpublic String DBReadRoomMOBMiscText(final String roomID, final String mobID)\n\t{\n\t\tDBConnection D=null;\n\t\t// now grab the items\n\t\ttry\n\t\t{\n\t\t\tD=DB.DBFetch();\n\t\t\tfinal ResultSet R=D.query("SELECT * FROM CMROCH WHERE CMROID=\'"+roomID+"\'");\n\t\t\twhile(R.next())\n\t\t\t{\n\t\t\t\tfinal String NUMID=DBConnections.getRes(R,"CMCHNM");\n\t\t\t\tif(NUMID.equalsIgnoreCase(mobID))\n\t\t\t\t{\n\t\t\t\t\tfinal String txt=DBConnections.getRes(R,"CMCHTX");\n\t\t\t\t\treturn txt;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch(final SQLException sqle)\n\t\t{\n\t\t\tLog.errOut("Room",sqle);\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tDB.DBDone(D);\n\t\t}\n\t\treturn null;\n\t}\n\n\tpublic MOB DBReadRoomMOB(final String roomID, final String mobID)\n\t{\n\t\tDBConnection D=null;\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\telse\r\n\t\t\t\t\t\t\tnewItem.setMiscText(DBConnections.getResQuietly(R,"CMITTX"));\r\n\t\t\t\t\t\tnewItem.basePhyStats().setRejuv((int)DBConnections.getLongRes(R,"CMITRE"));\r\n\t\t\t\t\t\tnewItem.setUsesRemaining((int)DBConnections.getLongRes(R,"CMITUR"));\r\n\t\t\t\t\t\tnewItem.basePhyStats().setLevel((int)DBConnections.getLongRes(R,"CMITLV"));\r\n\t\t\t\tif(newMOB==null)\n\t\t\t\t\treturn null;\n\t\t\t\tnewMOB.setDatabaseID(NUMID);\n\t\t\t\tif((CMProps.getBoolVar(CMProps.Bool.MOBNOCACHE))\n\t\t\t\t&&(NUMID.indexOf(MOBID+"@")>=0))\n\t\t\t\t\tnewMOB.setMiscText("%DBID>"+roomID+NUMID.substring(NUMID.indexOf(\'@\')));\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfinal String text=DBConnections.getResQuietly(R,"CMCHTX");\n\t\t\t\t\tnewMOB.setMiscText(text);\n\t\t\t\t}\n\t\t\t\tnewMOB.basePhyStats().setLevel(((int)DBConnections.getLongRes(R,"CMCHLV")));\n\t\t\t\tnewMOB.basePhyStats().setAbility((int)DBConnections.getLongRes(R,"CMCHAB"));\n\t\t\t\tnewMOB.basePhyStats().setRejuv((int)DBConnections.getLongRes(R,"CMCHRE"));\n\t\t\t\tnewMOB.recoverCharStats();\n\t\t\t\tnewMOB.recoverPhyStats();\n\t\t\t\tnewMOB.recoverMaxState();\n\t\t\t\tnewMOB.resetToMaxState();\n\t\t\t\tCMLib.threads().deleteAllTicks(newMOB);\n\t\t\t\treturn newMOB;\n\t\t\t}\n\t\t}\n\t\tcatch(final SQLException sqle)\n\t\t{\n\t\t\tLog.errOut("Room",sqle);\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tDB.DBDone(D);\n\t\t}\n\t\treturn null;\n\t}\n\n\t\t\t\t\tcontinue;\r\n\t\t\t\tif((!catalog)&&(roomID.startsWith("CATALOG_")))\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\tfinal String NUMID=DBConnections.getRes(R,"CMCHNM");\r\n\t\t\t\tfinal String MOBID=DBConnections.getRes(R,"CMCHID");\r\n\r\n\t\t\tif(R.next())\n\t\t\t{\n\t\t\t\tfinal String itemID=DBConnections.getRes(R,"CMITID");\n\t\t\t\tfinal Item newItem=CMClass.getItem(itemID);\n\t\t\t\tif(newItem==null)\n\t\t\t\t\tLog.errOut("Room","Couldn\'t find item \'"+itemID+"\' for room "+roomID);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tnewItem.setDatabaseID(itemNum);\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tnewItem.setMiscText(DBConnections.getResQuietly(R,"CMITTX"));\n\t\t\t\t\t\tnewItem.basePhyStats().setRejuv((int)DBConnections.getLongRes(R,"CMITRE"));\n\t\t\t\t\t\tnewItem.setUsesRemaining((int)DBConnections.getLongRes(R,"CMITUR"));\n\t\t\t\t\t\tnewItem.basePhyStats().setLevel((int)DBConnections.getLongRes(R,"CMITLV"));\n\t\t\t\t\t\tnewItem.basePhyStats().setAbility((int)DBConnections.getLongRes(R,"CMITAB"));\n\t\t\t\t\t\tnewItem.basePhyStats().setHeight((int)DBConnections.getLongRes(R,"CMHEIT"));\n\t\t\t\t\t\tnewItem.recoverPhyStats();\n\t\t\t\t\t\tCMLib.threads().deleteAllTicks(newItem);\n\t\t\t\t\t\treturn newItem;\n\t\t\t\t\t}\n\t\t\t\t\tcatch (final Exception e)\n\t\t\t\t\t{\n\t\t\t\t\t\tLog.errOut("RoomLoader", e);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch(final SQLException sqle)\n\t\t{\n\t\t\tLog.errOut("Room",sqle);\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tDB.DBDone(D);\n\t\t}\n\t\treturn null;\n\t}\n\n\tprivate void fixItemKeys(final Hashtable<Item,String> itemLocs, final Hashtable<String, PhysicalAgent> itemNums)\n\t{\n\t\tfor(final Enumeration<Item> e=itemLocs.keys();e.hasMoreElements();)\n\t\t{\n\t\t\tfinal Item keyItem=e.nextElement();\n\t\t\tfinal String location=itemLocs.get(keyItem);\n\t\t\tfinal Environmental container=itemNums.get(location);\n\t\t\tif((keyItem instanceof SpaceObject.SpaceGateway)\n\t\t\t&&(container instanceof SpaceObject))\n\t\t\t\t((SpaceObject)keyItem).setKnownTarget((SpaceObject)container);\n\t\t\telse\n\t\t\tif((container instanceof Container)&&(((Container)container).capacity()>0))\n\t\t\t\tkeyItem.setContainer((Container)container);\n\t\t\telse\n\t\t\tif(container instanceof Rideable)\n\t\t\t\tkeyItem.setRiding((Rideable)container);\n\t\t\telse\n\t\t\t\t\t\tfinal String ride=DBConnections.getRes(R,"CMCHRI");\r\n\t\t\t\t\t\tif((ride!=null)&&(ride.length()>0))\r\n\t\t\t\t\t\t\tmobRides.put(newMOB,ride);\r\n\t\t\t\t\t\tnewMOB.recoverCharStats();\r\n\t\t\t\t\t\tnewMOB.recoverPhyStats();\r\n\t\t\t\t\t\tnewMOB.recoverMaxState();\r\n\t\t\tif(ride!=null)\n\t\t\t{\n\t\t\t\tfinal boolean rideFlag;\n\t\t\t\tfinal PhysicalAgent P;\n\t\t\t\tif(ride.startsWith("*"))\n\t\t\t\t{\n\t\t\t\t\tP=itemNums.get(ride.substring(1));\n\t\t\t\t\trideFlag=true;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tP=itemNums.get(ride);\n\t\t\t\t\trideFlag=false;\n\t\t\t\t}\n\t\t\t\tif(P!=null)\n\t\t\t\t{\n\t\t\t\t\tif((M instanceof Rideable)\n\t\t\t\t\t&&(P instanceof Rideable)\n\t\t\t\t\t&&(P instanceof MOB)\n\t\t\t\t\t&&(!rideFlag))\n\t\t\t\t\t\tM.setFollowing((MOB)P);\n\t\t\t\t\telse\n\t\t\t\t\tif(P instanceof Rideable)\n\t\t\t\t\t\tM.setRiding((Rideable)P);\n\t\t\t\t\telse\n\t\t\t\t\tif(P instanceof MOB)\n\t\t\t\t\t\tM.setFollowing((MOB)P);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate void fixContentContainers(final Hashtable<String,PhysicalAgent> content, final StuffClass stuff, final String roomID, final Room room, final boolean debug, final boolean makeLive)\n\t{\n\t\tString lastName=null;\n\t\tHashtable<Item,String> itemLocs=null;\n\t\tHashtable<MOB, String> mobRides=null;\n\t\tif(room != null)\n\t\t{\n\t\t\tfor(final Enumeration<PhysicalAgent> i=content.elements();i.hasMoreElements();)\n\t\t\t{\n\t\t\t\tfinal PhysicalAgent P=i.nextElement();\n\t\t\t\tif((debug)&&((lastName==null)||(!lastName.equals(P.Name()))))\n\t\t\t\t{\n\t\t\t\t\tlastName=P.Name();\n\t\t\t\t\tLog.debugOut("RoomLoader","Loading object(s): "+P.Name());\n\t\t\t\t}\n\t\t\t\tif(P instanceof Item)\n\t\t\t\t{\n\t\t\t\t\troom.addItem((Item)P);\n\t\t\t\t\tif(makeLive)\n\t\t\t\t\t\tCMLib.map().registerWorldObjectLoaded(room.getArea(), room, P);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t((MOB)P).setStartRoom(room);\n\t\t\t\t\tif(makeLive)\n\t\t\t\t\t\t((MOB)P).bringToLife(room,true);\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\troom.addInhabitant((MOB)P);\n\t\t\t\t\t\t((MOB)P).recoverPhyStats();\n\t\t\t\t\t\t((MOB)P).recoverMaxState();\n\t\t\t\t\t\t((MOB)P).recoverCharStats();\n\t\t\t\t\t\t((MOB)P).resetToMaxState();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\titemLocs=stuff.itemLocs.get("LOCSFOR"+roomID.toUpperCase());\n\t\tmobRides=stuff.mobRides.get("RIDESFOR"+roomID.toUpperCase());\n\t\tif(itemLocs!=null)\n\t\t{\n\t\t\tfixItemKeys(itemLocs,content);\n\t\t\tif(room!=null)\n\t\t\t{\n\t\t\t\troom.recoverRoomStats();\n\t\t\t\troom.recoverRoomStats();\n\t\t\t}\n\t\t}\n\t\tif(mobRides!=null)\n\t\t\tfixMOBRides(mobRides,content);\n\t}\n\n\tpublic void DBReadCatalogs()\n\t{\n\t\tDBReadContent("CATALOG_MOBS",null,null,null,noLiveReadRoomFlags);\n\t\tDBReadContent("CATALOG_ITEMS",null,null,null,noLiveReadRoomFlags);\n\t}\n\n\tpublic void DBReadSpace()\n\t{\n\t\tDBReadContent("SPACE",null,null,null,noLiveReadRoomFlags);\n\t}\n\n\tpublic int[] DBCountRoomMobsItems(final String roomID)\n\t{\n\t\tDBConnection D=null;\n\t\tfinal int[] count = new int[] { 0, 0};\n\t\t// now grab the items\n\t\ttry\n\t\t{\n\t\t\tD=DB.DBFetch();\n\t\t\tResultSet R=D.query("SELECT * FROM CMROIT WHERE CMROID=\'"+roomID+"\'");\n\t\t\tcount [1] = DB.getRecordCount(D,R);\n\t\t\tR.close();\n\n\t\t\tR=D.query("SELECT * FROM CMROCH WHERE CMROID=\'"+roomID+"\'");\n\t\t\tcount [0] = DB.getRecordCount(D,R);\n\t\t\tR.close();\n\t\t}\n\t\tcatch(final SQLException sqle)\n\t\t{\n\t\t\tLog.errOut("Room",sqle);\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tDB.DBDone(D);\n\t\t}\n\t\treturn count;\n\t}\n\n\tpublic Item DBGetSavedRoomItemCopy(final String roomID, final String itemName)\n\t{\n\t\tDBConnection D=null;\n\t\tfinal Item I=null;\n\t\t// now grab the items\n\t\ttry\n\t\t{\n\t\t\tD=DB.DBFetch();\n\t\t\tfinal ResultSet R=D.query("SELECT * FROM CMROIT WHERE CMROID=\'"+roomID+"\'");\n\t\t\twhile(R.next())\n\t\t\t{\n\t\t\t\tfinal String itemID=DBConnections.getRes(R,"CMITID");\n\t\t\t\tfinal Item newItem=CMClass.getItem(itemID);\n\t\t\t\tnewItem.setMiscText(DBConnections.getResQuietly(R,"CMITTX"));\n\t\t\t\tnewItem.basePhyStats().setRejuv((int)DBConnections.getLongRes(R,"CMITRE"));\n\t\t\t\tnewItem.setUsesRemaining((int)DBConnections.getLongRes(R,"CMITUR"));\n\t\t\t\tnewItem.basePhyStats().setLevel((int)DBConnections.getLongRes(R,"CMITLV"));\n\t\t\t\tnewItem.basePhyStats().setAbility((int)DBConnections.getLongRes(R,"CMITAB"));\n\t\t\t\tnewItem.basePhyStats().setHeight((int)DBConnections.getLongRes(R,"CMHEIT"));\n\t\t\t\tnewItem.recoverPhyStats();\n\t\t\t\tif(newItem.Name().equalsIgnoreCase(itemName))\n\t\t\t\t\treturn newItem;\n\t\t\t\tnewItem.destroy();\n\t\t\t}\n\t\t\tR.close();\n\t\t}\n\t\tcatch(final SQLException sqle)\n\t\t{\n\t\t\tLog.errOut("Room",sqle);\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tDB.DBDone(D);\n\t\t}\n\t\treturn I;\n\t}\n\n\tpublic boolean DBIsSavedRoomItemCopy(final String roomID, final String itemName)\n\t{\n\t\tfinal Item I=this.DBGetSavedRoomItemCopy(roomID, itemName);\n\t\tif(I!=null)\n\t\t{\n\t\t\tI.destroy();\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\tpublic void DBReadContent(final String thisRoomID, final Room thisRoom, Map<String, Room> rooms, final RoomnumberSet unloadedRooms, final Set<ReadRoomDisableFlag> disableFlags)\n\t{\n\t\tfinal boolean debug=Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMPOP));\n\t\tif(debug||(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS))))\n\t\t\tLog.debugOut("RoomLoader","Reading content of "+((thisRoomID!=null)?thisRoomID:"ALL"));\n\n\t\tfinal boolean setStatus = (disableFlags == null) || (!disableFlags.contains(ReadRoomDisableFlag.STATUS));\n\t\tfinal boolean makeLive = (disableFlags == null) || (!disableFlags.contains(ReadRoomDisableFlag.LIVE));\n\t\tfinal boolean readMobs = (disableFlags == null) || (!disableFlags.contains(ReadRoomDisableFlag.MOBS));\n\t\tfinal boolean readItems = (disableFlags == null) || (!disableFlags.contains(ReadRoomDisableFlag.ITEMS));\n\n\t\tfinal StuffClass stuff=new StuffClass();\n\t\tHashtable<String,PhysicalAgent> itemNums=null;\n\t\tHashtable<String,String> cataData=null;\n\t\tHashtable<Item,String> itemLocs=null;\n\t\tHashtable<MOB, String> mobRides=null;\n\n\t\tfinal boolean catalog=((thisRoomID!=null)&&(thisRoomID.startsWith("CATALOG_")));\n\t\tfinal boolean space=((thisRoomID!=null)&&(thisRoomID.equals("SPACE")));\n\n\t\tDBConnection D=null;\n\n\t\tif(readItems)\n\t\t{\n\t\t\t// now grab the items\n\t\t\ttry\n\t\t\t{\n\t\t\t\tD=DB.DBFetch();\n\t\t\t\tif(setStatus)\n\t\t\t\t\tCMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Counting Items");\n\t\t\t\tfinal ResultSet R=D.query("SELECT * FROM CMROIT"+((thisRoomID==null)?"":" WHERE CMROID=\'"+thisRoomID+"\'"));\n\t\t\t\tif(setStatus)\n\t\t\t\t\trecordCount=DB.getRecordCount(D,R);\n\t\t\t\tupdateBreak=CMath.s_int("1"+zeroes.substring(0,(""+(recordCount/100)).length()-1));\n\t\t\t\twhile(R.next())\n\t\t\t\t{\n\t\t\t\t\tcurrentRecordPos=R.getRow();\n\t\t\t\t\tfinal String roomID=DBConnections.getRes(R,"CMROID");\n\t\t\t\t\tif((unloadedRooms!=null)&&(unloadedRooms.contains(roomID)))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tif((!catalog)&&(roomID.startsWith("CATALOG_")))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tif((!space)&&(roomID.startsWith("SPACE")))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\titemNums=stuff.itemNums.get("NUMSFOR"+roomID.toUpperCase());\n\t\t\t\t\tif(itemNums==null)\n\t\t\t\t\t{\n\t\t\t\t\t\titemNums=new Hashtable<String,PhysicalAgent>();\n\t\t\t\t\t\tstuff.itemNums.put("NUMSFOR"+roomID.toUpperCase(),itemNums);\n\t\t\t\t\t}\n\t\t\t\t\titemLocs=stuff.itemLocs.get("LOCSFOR"+roomID.toUpperCase());\n\t\t\t\t\tif(itemLocs==null)\n\t\t\t\t\t{\n\t\t\t\t\t\titemLocs=new Hashtable<Item,String>();\n\t\t\t\t\t\tstuff.itemLocs.put("LOCSFOR"+roomID.toUpperCase(),itemLocs);\n\t\t\t\t\t}\n\t\t\t\t\tfinal String itemNum=DBConnections.getRes(R,"CMITNM");\n\t\t\t\t\tfinal String itemID=DBConnections.getRes(R,"CMITID");\n\t\t\t\t\tfinal Item newItem=CMClass.getItem(itemID);\n\t\t\t\t\tif(newItem==null)\n\t\t\t\t\t\tLog.errOut("Room","Couldn\'t find item \'"+itemID+"\' for room "+roomID);\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tnewItem.setDatabaseID(itemNum);\n\t\t\t\t\t\titemNums.put(itemNum,newItem);\n\t\t\t\t\t\tfinal Room room=(rooms!=null)?rooms.get(roomID):thisRoom;\n\t\t\t\t\t\tnewItem.setOwner(room); // temporary measure to make sure item behavior thread group is properly assigned\n\t\t\t\t\t\tfinal String loc=DBConnections.getResQuietly(R,"CMITLO");\n\t\t\t\t\t\tif(loc.length()>0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal PhysicalAgent container=itemNums.get(loc);\n\t\t\t\t\t\t\tif((newItem instanceof SpaceObject.SpaceGateway)\n\t\t\t\t\t\t\t&&(container instanceof SpaceObject))\n\t\t\t\t\t\t\t\t((SpaceObject)newItem).setKnownTarget((SpaceObject)container);\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\tif(container instanceof Container)\n\t\t\t\t\t\t\t\tnewItem.setContainer((Container)container);\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\titemLocs.put(newItem,loc);\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(catalog)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tString text=DBConnections.getResQuietly(R,"CMITTX");\n\t\t\t\t\t\t\t\tfinal int x=text.lastIndexOf("<CATALOGDATA");\n\t\t\t\t\t\t\t\tif((x>0)&&(text.indexOf("</CATALOGDATA>",x)>0))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tcataData=stuff.cataData.get("CATADATAFOR"+roomID.toUpperCase());\n\t\t\t\t\t\t\t\t\tif(cataData==null)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tcataData=new Hashtable<String,String>();\n\t\t\t\t\t\t\t\t\t\tstuff.cataData.put("CATADATAFOR"+roomID.toUpperCase(),cataData);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tcataData.put(itemNum,text.substring(x));\n\t\t\t\t\t\t\t\t\ttext=text.substring(0,x);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tnewItem.setMiscText(text);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tnewItem.setMiscText(DBConnections.getResQuietly(R,"CMITTX"));\n\t\t\t\t\t\t\tif(newItem instanceof SpaceObject)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tCMLib.space().addObjectToSpace((SpaceObject)newItem, ((SpaceObject) newItem).coordinates());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnewItem.basePhyStats().setRejuv((int)DBConnections.getLongRes(R,"CMITRE"));\n\t\t\t\t\t\t\tnewItem.setUsesRemaining((int)DBConnections.getLongRes(R,"CMITUR"));\n\t\t\t\t\t\t\tnewItem.basePhyStats().setLevel((int)DBConnections.getLongRes(R,"CMITLV"));\n\t\t\t\t\t\t\tnewItem.basePhyStats().setAbility((int)DBConnections.getLongRes(R,"CMITAB"));\n\t\t\t\t\t\t\tnewItem.basePhyStats().setHeight((int)DBConnections.getLongRes(R,"CMHEIT"));\n\t\t\t\t\t\t\tnewItem.recoverPhyStats();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (final Exception e)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tLog.errOut("RoomLoader", e);\n\t\t\t\t\t\t\titemNums.remove(itemNum);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(((currentRecordPos%updateBreak)==0)&&(setStatus))\n\t\t\t\t\t\tCMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Loading Items ("+currentRecordPos+" of "+recordCount+")");\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch(final SQLException sqle)\n\t\t\t{\n\t\t\t\tLog.errOut("Room",sqle);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tDB.DBDone(D);\n\t\t\t}\n\t\t}\n\n\t\tif(readMobs)\n\t\t{\n\t\t\t// now grab the inhabitants\n\t\t\ttry\n\t\t\t{\n\t\t\t\tD=DB.DBFetch();\n\t\t\t\tif(setStatus)\n\t\t\t\t\tCMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Counting MOBS");\n\t\t\t\tfinal ResultSet R=D.query("SELECT * FROM CMROCH"+((thisRoomID==null)?"":" WHERE CMROID=\'"+thisRoomID+"\'"));\n\t\t\t\tif(setStatus)\n\t\t\t\t\trecordCount=DB.getRecordCount(D,R);\n\t\t\t\tupdateBreak=CMath.s_int("1"+zeroes.substring(0,(""+(recordCount/100)).length()-1));\n\t\t\t\twhile(R.next())\n\t\t\t\t{\n\t\t\t\t\tcurrentRecordPos=R.getRow();\n\t\t\t\t\tfinal String roomID=DBConnections.getRes(R,"CMROID");\n\t\t\t\t\tif((unloadedRooms!=null)&&(unloadedRooms.contains(roomID)))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tif((!catalog)&&(roomID.startsWith("CATALOG_")))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tif((!space) && roomID.equals("SPACE"))\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tfinal String NUMID=DBConnections.getRes(R,"CMCHNM");\n\t\t\t\t\tfinal String MOBID=DBConnections.getRes(R,"CMCHID");\n\n\t\t\t\t\titemNums=stuff.itemNums.get("NUMSFOR"+roomID.toUpperCase());\n\t\t\t\t\tif(itemNums==null)\n\t\t\t\t\t{\n\t\t\t\t\t\titemNums=new Hashtable<String,PhysicalAgent>();\n\t\t\t\t\t\tstuff.itemNums.put("NUMSFOR"+roomID.toUpperCase(),itemNums);\n\t\t\t\t\t}\n\t\t\t\t\tmobRides=stuff.mobRides.get("RIDESFOR"+roomID.toUpperCase());\n\t\t\t\t\tif(mobRides==null)\n\t\t\t\t\t{\n\t\t\t\t\t\tmobRides=new Hashtable<MOB, String>();\n\t\t\t\t\t\tstuff.mobRides.put("RIDESFOR"+roomID.toUpperCase(),mobRides);\n\t\t\t\t\t}\n\n\t\t\t\t\tfinal MOB newMOB=CMClass.getMOB(MOBID);\n\t\t\t\t\tif(newMOB==null)\n\t\t\t\t\t\tLog.errOut("Room","Couldn\'t find MOB \'"+MOBID+"\' in room " + roomID);\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal Room room=(rooms!=null)?rooms.get(roomID):thisRoom;\n\t\t\t\t\t\tnewMOB.setLocation(room); // temporary measure to make sure thread group is properly assigned\n\t\t\t\t\t\tnewMOB.setDatabaseID(NUMID);\n\t\t\t\t\t\titemNums.put(NUMID,newMOB);\n\t\t\t\t\t\tif(thisRoom!=null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnewMOB.setStartRoom(thisRoom);\n\t\t\t\t\t\t\tnewMOB.setLocation(thisRoom);\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif((CMProps.getBoolVar(CMProps.Bool.MOBNOCACHE))\n\t\t\t\t\t\t\t&&(!catalog)\n\t\t\t\t\t\t\t&&(NUMID.indexOf(MOBID+"@")>=0))\n\t\t\t\t\t\t\t\tnewMOB.setMiscText("%DBID>"+roomID+NUMID.substring(NUMID.indexOf(\'@\')));\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tString text=DBConnections.getResQuietly(R,"CMCHTX");\n\t\t\t\t\t\t\t\tif(catalog)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal int x=text.lastIndexOf("<CATALOGDATA");\n\t\t\t\t\t\t\t\t\tif((x>0)&&(text.indexOf("</CATALOGDATA>",x)>0))\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tcataData=stuff.cataData.get("CATADATAFOR"+roomID.toUpperCase());\n\t\t\t\t\t\t\t\t\t\tif(cataData==null)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tcataData=new Hashtable<String,String>();\n\t\t\t\t\t\t\t\t\t\t\tstuff.cataData.put("CATADATAFOR"+roomID.toUpperCase(),cataData);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tcataData.put(NUMID,text.substring(x));\n\t\t\t\t\t\t\t\t\t\ttext=text.substring(0,x);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tnewMOB.setMiscText(text);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnewMOB.basePhyStats().setLevel(((int)DBConnections.getLongRes(R,"CMCHLV")));\n\t\t\t\t\t\t\tnewMOB.basePhyStats().setAbility((int)DBConnections.getLongRes(R,"CMCHAB"));\n\t\t\t\t\t\t\tnewMOB.basePhyStats().setRejuv((int)DBConnections.getLongRes(R,"CMCHRE"));\n\t\t\t\t\t\t\tfinal String ride=DBConnections.getRes(R,"CMCHRI");\n\t\t\t\t\t\t\tif((ride!=null)&&(ride.length()>0))\n\t\t\t\t\t\t\t\tmobRides.put(newMOB,ride);\n\t\t\t\t\t\t\tif(newMOB instanceof SpaceObject)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tCMLib.space().addObjectToSpace((SpaceObject)newMOB, ((SpaceObject) newMOB).coordinates());\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnewMOB.recoverCharStats();\n\t\t\t\t\t\t\tnewMOB.recoverPhyStats();\n\t\t\t\t\t\t\tnewMOB.recoverMaxState();\n\t\t\t\t\t\t\tnewMOB.resetToMaxState();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch (final Exception e)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tLog.errOut("RoomLoader", e);\n\t\t\t\t\t\t\titemNums.remove(NUMID);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(((currentRecordPos%updateBreak)==0)&&(setStatus))\n\t\t\t\t\t\tCMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Loading MOBs ("+currentRecordPos+" of "+recordCount+")");\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch(final SQLException sqle)\n\t\t\t{\n\t\t\t\tLog.errOut("Room",sqle);\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tDB.DBDone(D);\n\t\t\t}\n\t\t}\n\t\tif(thisRoom!=null)\n\t\t{\n\t\t\trooms=new STreeMap<String,Room>();\n\t\t\trooms.put(thisRoom.roomID(),thisRoom);\n\t\t}\n\t\tif(rooms!=null)\n\t\t\trecordCount=rooms.size();\n\t\tupdateBreak=CMath.s_int("1"+zeroes.substring(0,(""+(recordCount/100)).length()-1));\n\t\tcurrentRecordPos=0;\n\n\t\titemNums=stuff.itemNums.get("NUMSFORCATALOG_ITEMS");\n\t\tcataData=stuff.cataData.get("CATADATAFORCATALOG_ITEMS");\n\t\tif((itemNums!=null)&&(thisRoomID!=null)&&(thisRoomID.equals("CATALOG_ITEMS")))\n\t\t{\n\t\t\tString itemNum;\n\t\t\tItem I;\n\t\t\tString data;\n\t\t\tfixContentContainers(itemNums,stuff,"CATALOG_ITEMS",null,debug,false);\n\t\t\tfor(final Enumeration<String> e=itemNums.keys();e.hasMoreElements();)\n\t\t\t{\n\t\t\t\titemNum=e.nextElement();\n\t\t\t\tI=(Item)itemNums.get(itemNum);\n\t\t\t\tdata=(cataData!=null)?cataData.get(itemNum):null;\n\t\t\t\tfinal Item oldI=CMLib.catalog().getCatalogItem(I.Name());\n\t\t\t\tif((oldI!=null)\n\t\t\t\t&&(I.databaseID().length()>0)\n\t\t\t\t&&(!oldI.databaseID().equals(I.databaseID())))\n\t\t\t\t\tDBDeleteRoomItem("CATALOG_ITEMS", I);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tCMLib.catalog().submitToCatalog(I);\n\t\t\t\t\tif((data!=null)&&(data.length()>0))\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal CatalogLibrary.CataData dataI=CMLib.catalog().getCatalogItemData(I.Name());\n\t\t\t\t\t\tif(dataI!=null)\n\t\t\t\t\t\t\tdataI.build(data);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// load mob catalog\n\t\titemNums=stuff.itemNums.get("NUMSFORCATALOG_MOBS");\n\t\tcataData=stuff.cataData.get("CATADATAFORCATALOG_MOBS");\n\t\tif((itemNums!=null)&&(thisRoomID!=null)&&(thisRoomID.equals("CATALOG_MOBS")))\n\t\t{\n\t\t\tString itemNum;\n\t\t\tMOB M;\n\t\t\tString data;\n\t\t\tfixContentContainers(itemNums,stuff,"CATALOG_MOBS",null,debug,false);\n\t\t\tfor(final Enumeration<String> e=itemNums.keys();e.hasMoreElements();)\n\t\t\t{\n\t\t\t\titemNum=e.nextElement();\n\t\t\t\tM=(MOB)itemNums.get(itemNum);\n\t\t\t\tdata=(cataData!=null)?cataData.get(itemNum):null;\n\t\t\t\tfinal MOB oldM=CMLib.catalog().getCatalogMob(M.Name());\n\t\t\t\tif((oldM!=null)\n\t\t\t\t&&(M.databaseID().length()>0)\n\t\t\t\t&&(!oldM.databaseID().equals(M.databaseID())))\n\t\t\t\t\tDBDeleteRoomMOB("CATALOG_MOBS", M);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tCMLib.catalog().submitToCatalog(M);\n\t\t\t\t\tif((data!=null)&&(data.length()>0))\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal CatalogLibrary.CataData dataM=CMLib.catalog().getCatalogMobData(M.Name());\n\t\t\t\t\t\tif(dataM!=null)\n\t\t\t\t\t\t\tdataM.build(data);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// now load the rooms\n\t\tif(rooms!=null)\n\t\t{\n\t\t\tCMProps.setBoolAllVar(CMProps.Bool.POPULATIONSTARTED, true);\n\t\t\trecordCount = rooms.size();\n\t\t\tfor(final Map.Entry<String,Room> entry : rooms.entrySet())\n\t\t\t{\n\t\t\t\tif((((++currentRecordPos)%updateBreak)==0)&&(setStatus))\n\t\t\t\t\tCMProps.setUpLowVar(CMProps.Str.MUDSTATUS,"Booting: Populating Rooms ("+(currentRecordPos)+" of "+((recordCount==1)?"?":Integer.toString(recordCount))+")");\n\t\t\t\tfinal Room room=entry.getValue();\n\t\t\t\tif(debug)\n\t\t\t\t\tLog.debugOut("RoomLoader","Populating room: "+room.roomID());\n\t\t\t\titemNums=stuff.itemNums.get("NUMSFOR"+room.roomID().toUpperCase());\n\t\t\t\tif(itemNums!=null)\n\t\t\t\t\tfixContentContainers(itemNums,stuff,room.roomID(),room,debug,makeLive);\n\t\t\t}\n\t\t}\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Done reading content of "+((thisRoomID!=null)?thisRoomID:"ALL"));\n\t}\n\n\tprivate List<Item> DBGetContents(final Room room)\n\t{\n\t\tif((!room.isSavable())||(room.amDestroyed()))\n\t\t\treturn new Vector<Item>();\n\t\tfinal List<Item> contents=new Vector<Item>();\n\t\tfor(int i=0;i<room.numItems();i++)\n\t\t{\n\t\t\tfinal Item thisItem=room.getItem(i);\n\t\t\tif((thisItem!=null)\n\t\t\t&&(!contents.contains(thisItem))\n\t\t\t&&thisItem.isSavable())\n\t\t\t\tcontents.add(thisItem);\n\t\t}\n\t\treturn contents;\n\t}\n\n\tprotected List<String> DBReadAreaRoomIDs(final String areaName)\n\t{\n\t\tfinal List<String> lst=new ArrayList<String>();\n\t\tDBConnection D=null;\n\t\ttry\n\t\t{\n\t\t\tD=DB.DBFetch();\n\t\t\tfinal ResultSet R=D.query("SELECT CMROID FROM CMROOM WHERE CMAREA=\'"+DB.injectionClean(areaName)+"\'");\n\t\t\twhile(R.next())\n\t\t\t{\n\t\t\t\tfinal String roomID=R.getString("CMROID");\n\t\t\t\tlst.add(roomID);\n\t\t\t}\n\t\t\tR.close();\n\t\t}\n\t\tcatch(final SQLException sqle)\n\t\t{\n\t\t\tLog.errOut("Area",sqle);\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tDB.DBDone(D);\n\t\t}\n\t\treturn lst;\n\t}\n\n\tpublic RoomContent[] DBReadAreaMobs(final String name)\n\t{\n\t\tfinal List<RoomContent> lst=new ArrayList<RoomContent>();\n\t\tfinal List<String> roomIDs = DBReadAreaRoomIDs(name);\n\t\tfinal GenericBuilder buildLib = CMLib.coffeeMaker();\n\t\tDBConnection D=null;\n\t\ttry\n\t\t{\n\t\t\tD=DB.DBFetch();\n\t\t\tfor(final String roomID : roomIDs)\n\t\t\t{\n\t\t\t\tfinal ResultSet R=D.query("SELECT * FROM CMROCH WHERE CMROID=\'"+DB.injectionClean(roomID)+"\'");\n\t\t\t\twhile(R.next())\n\t\t\t\t{\n\t\t\t\t\tint buildHash = 0;\n\t\t\t\t\tfinal String classID = DB.getRes(R, "CMCHID");\n\t\t\t\t\tfinal String text = DB.getRes(R, "CMCHTX");\n\t\t\t\t\tfinal String qName = buildLib.getQuickName(classID, text);\n\t\t\t\t\tbuildHash = classID.hashCode() ^ text.hashCode();\n\t\t\t\t\tbuildHash ^= (int)DB.getLongRes(R, "CMCHLV");\n\t\t\t\t\tbuildHash ^= (int)DB.getLongRes(R, "CMCHAB");\n\t\t\t\t\tfinal int finalHash = buildHash;\n\t\t\t\t\tfinal RoomContent C=new RoomContent()\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal String roomId = roomID;\n\t\t\t\t\t\tfinal String roomKey = DB.getRes(R, "CMCHNM");\n\t\t\t\t\t\tfinal String classId = classID;\n\t\t\t\t\t\tfinal String name = qName;\n\t\t\t\t\t\tfinal int hashCode = finalHash;\n\n\t\t\t\t\t\t@Override\n\t\t\t\t\t\tpublic String ID()\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn classId;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t@Override\n\t\t\t\t\t\tpublic String name()\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn name;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t@Override\n\t\t\t\t\t\tpublic String roomID()\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn roomId;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t@Override\n\t\t\t\t\t\tpublic String dbKey()\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn roomKey;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t@Override\n\t\t\t\t\t\tpublic int contentHash()\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn hashCode;\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\tlst.add(C);\n\n\t\t\t\t}\n\t\t\t\tR.close();\n\t\t\t}\n\t\t}\n\t\tcatch(final SQLException sqle)\n\t\t{\n\t\t\tLog.errOut("Area",sqle);\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tDB.DBDone(D);\n\t\t}\n\t\treturn lst.toArray(new RoomContent[lst.size()]);\n\t}\n\n\tpublic RoomContent[] DBReadAreaItems(final String name)\n\t{\n\t\tfinal List<RoomContent> lst=new ArrayList<RoomContent>();\n\t\tfinal List<String> roomIDs = DBReadAreaRoomIDs(name);\n\t\tfinal GenericBuilder buildLib = CMLib.coffeeMaker();\n\t\tDBConnection D=null;\n\t\ttry\n\t\t{\n\t\t\tD=DB.DBFetch();\n\t\t\tfor(final String roomID : roomIDs)\n\t\t\t{\n\t\t\t\tfinal ResultSet R=D.query("SELECT * FROM CMROIT WHERE CMROID=\'"+DB.injectionClean(roomID)+"\'");\n\t\t\t\twhile(R.next())\n\t\t\t\t{\n\t\t\t\t\tint buildHash = 0;\n\t\t\t\t\tfinal String classID = DB.getRes(R, "CMITID");\n\t\t\t\t\tfinal String text = DB.getRes(R, "CMITTX");\n\t\t\t\t\tfinal String qName = buildLib.getQuickName(classID, text);\n\t\t\t\t\tbuildHash = classID.hashCode() ^ text.hashCode();\n\t\t\t\t\tbuildHash ^= (int)DB.getLongRes(R, "CMITLV");\n\t\t\t\t\tbuildHash ^= (int)DB.getLongRes(R, "CMITAB");\n\t\t\t\t\tbuildHash ^= (int)DB.getLongRes(R, "CMITUR");\n\t\t\t\t\tbuildHash ^= (int)DB.getLongRes(R, "CMHEIT");\n\t\t\t\t\tfinal int finalHash = buildHash;\n\t\t\t\t\tfinal RoomContent C=new RoomContent()\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal String roomId = roomID;\n\t\t\t\t\t\tfinal String roomKey = DB.getRes(R, "CMITNM");\n\t\t\t\t\t\tfinal String classId = classID;\n\t\t\t\t\t\tfinal String name = qName;\n\t\t\t\t\t\tfinal int hashCode = finalHash;\n\n\t\t\t\t\t\t@Override\n\t\t\t\t\t\tpublic String ID()\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn classId;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t@Override\n\t\t\t\t\t\tpublic String name()\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn name;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t@Override\n\t\t\t\t\t\tpublic String roomID()\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn roomId;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t@Override\n\t\t\t\t\t\tpublic String dbKey()\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn roomKey;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t@Override\n\t\t\t\t\t\tpublic int contentHash()\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn hashCode;\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t\tlst.add(C);\n\n\t\t\t\t}\n\t\t\t\tR.close();\n\t\t\t}\n\t\t}\n\t\tcatch(final SQLException sqle)\n\t\t{\n\t\t\tLog.errOut("Area",sqle);\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tDB.DBDone(D);\n\t\t}\n\t\treturn lst.toArray(new RoomContent[lst.size()]);\n\t}\n\n\tprotected String getShortID(final Environmental E)\n\t{\n\t\tfinal String classID = ""+E;\n\t\tfinal int x=classID.indexOf(\'@\');\n\t\tif(x<0)\n\t\t\treturn E.ID()+"@"+classID.hashCode()+Math.random();\n\t\telse\n\t\t\treturn E.ID()+classID.substring(0, x).hashCode()+classID.substring(x);\n\t}\n\n\tprotected Pair<String,String> getDBCreateItemString(final String roomID, final Item thisItem)\n\t{\n\t\tfinal boolean catalog=((roomID!=null)&&(roomID.startsWith("CATALOG_")));\n\t\tthisItem.setExpirationDate(0); // saved items won\'t clear!\n\t\tEnvironmental container=thisItem.container();\n\t\tif((container==null)\n\t\t&&(thisItem.riding()!=null)\n\t\t&&(thisItem.riding().isSavable()))\n\t\t{\n\t\t\tfinal Room room=CMLib.map().roomLocation(thisItem);\n\t\t\tif(((room!=null)&&(room.isHere(thisItem.riding())))\n\t\t\t||(CMLib.catalog().isCatalogObj(thisItem.riding())))\n\t\t\t\tcontainer=thisItem.riding();\n\t\t}\n\t\tfinal String itemID=getShortID(thisItem);\n\t\tthisItem.setDatabaseID(itemID);\n\t\tString text=thisItem.text();\n\t\tif(catalog)\n\t\t{\n\t\t\tfinal CatalogLibrary.CataData dataI=CMLib.catalog().getCatalogItemData(thisItem.Name());\n\t\t\tif(dataI!=null)\n\t\t\t\ttext+=dataI.data(null);\n\t\t}\n\t\treturn new Pair<String,String>(\n\t\t"INSERT INTO CMROIT ("\n\t\t+"CMROID, "\n\t\t+"CMITNM, "\n\t\t+"CMITID, "\n\t\t+"CMITLO, "\n\t\t+"CMITTX, "\n\t\t+"CMITRE, "\n\t\t+"CMITUR, "\n\t\t+"CMITLV, "\n\t\t+"CMITAB, "\n\t\t+"CMHEIT"\n\t\t+") values ("\n\t\t+"\'"+roomID+"\',"\n\t\t+"\'"+itemID+"\',"\n\t\t+"\'"+thisItem.ID()+"\',"\n\t\t+"\'"+((container!=null)?(""+getShortID(container)):"")+"\',"\n\t\t+"?,"\n\t\t+thisItem.basePhyStats().rejuv()+","\n\t\t+thisItem.usesRemaining()+","\n\t\t+thisItem.basePhyStats().level()+","\n\t\t+thisItem.basePhyStats().ability()+","\n\t\t+thisItem.basePhyStats().height()+")",\n\t\ttext+" ");\n\t}\n\n\tpublic void DBCreateThisItem(final String roomID, final Item thisItem)\n\t{\n\t\tfinal Pair<String,String> sql=getDBCreateItemString(roomID,thisItem);\n\t\tfinal DBPreparedBatchEntry entry = new DBPreparedBatchEntry(sql.first,sql.second);\n\t\tDB.updateWithClobs(entry);\n\t}\n\n\tpublic void DBUpdateTheseItems(final Room room, final List<Item> items)\n\t{\n\t\tif((!room.isSavable())||(room.amDestroyed()))\n\t\t\treturn;\n\t\tfinal boolean useBulkInserts = DB.useBulkInserts();\n\t\tfinal StringBuilder bulkSQL = new StringBuilder("");\n\t\tfinal List<String> bulkClobs = new ArrayList<String>();\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROIT)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Start item update for room "+room.roomID());\n\t\tfinal List<DBPreparedBatchEntry> statements=new Vector<DBPreparedBatchEntry>();\n\t\tstatements.add(new DBPreparedBatchEntry("DELETE FROM CMROIT WHERE CMROID=\'"+room.roomID()+"\'"));\n\t\tfor(int i=0;i<items.size();i++)\n\t\t{\n\t\t\tfinal Item thisItem=items.get(i);\n\t\t\tCMLib.map().registerWorldObjectLoaded(room.getArea(), room, thisItem);\n\t\t\tfinal Pair<String,String> sqlpair=getDBCreateItemString(room.roomID(),thisItem);\n\t\t\tif(!useBulkInserts)\n\t\t\t\tstatements.add(new DBPreparedBatchEntry(sqlpair.first,sqlpair.second));\n\t\t\telse\n\t\t\t{\n\t\t\t\tfinal DBPreparedBatchEntry entry = doBulkInsert(bulkSQL,bulkClobs,sqlpair.first,sqlpair.second);\n\t\t\t\tif(entry != null)\n\t\t\t\t\tstatements.add(entry);\n\t\t\t}\n\t\t}\n\t\tif((bulkSQL.length()>0) && useBulkInserts)\n\t\t\tstatements.add(new DBPreparedBatchEntry(bulkSQL.toString(),bulkClobs.toArray(new String[0])));\n\t\tDB.updateWithClobs(statements);\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROIT)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Finished items update for room "+room.roomID());\n\t}\n\n\tpublic void DBUpdateItems(final Room room)\n\t{\n\t\tif((!room.isSavable())||(room.amDestroyed()))\n\t\t\treturn;\n\t\tDBUpdateTheseItems(room,DBGetContents(room));\n\t}\n\n\tpublic void DBUpdateExitsNEW(final Room room)\n\t{\n\t\tif((!room.isSavable())||(room.amDestroyed()))\n\t\t\treturn;\n\t\tfinal String baseRoomID = room.roomID();\n\t\tif(baseRoomID.length()==0)\n\t\t\treturn;\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROEX)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Starting exit update for room "+baseRoomID);\n\t\tDBConnection D=null;\n\t\tfinal Set<Integer> dirs = new HashSet<Integer>();\n\t\ttry\n\t\t{\n\t\t\tD=DB.DBFetch();\n\t\t\tfinal ResultSet R=D.query("SELECT CMDIRE FROM CMROEX WHERE CMROID = \'"+baseRoomID+"\'");\n\t\t\twhile(R.next())\n\t\t\t\tdirs.add(Integer.valueOf(R.getInt("CMDIRE")));\n\t\t\tR.close();\n\t\t}\n\t\tcatch(final SQLException sqle)\n\t\t{\n\t\t\tLog.errOut("RoomLoader",sqle);\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tDB.DBDone(D);\n\t\t}\n\t\tfinal List<DBPreparedBatchEntry> statements=new Vector<DBPreparedBatchEntry>();\n\t\tfinal boolean useBulkInserts = DB.useBulkInserts();\n\t\tfinal StringBuilder bulkSQL = new StringBuilder("");\n\t\tfinal List<String> bulkClobs = new ArrayList<String>();\n\t\tfor(int d=Directions.NUM_DIRECTIONS()-1;d>=0;d--)\n\t\t{\n\t\t\tExit linkE=room.getRawExit(d);\n\t\t\tRoom linkR=room.rawDoors()[d];\n\n\t\t\tif((linkE!=null)&&(!linkE.isSavable()))\n\t\t\t\tlinkE=null;\n\t\t\tif((linkR!=null)&&(!linkR.isSavable()))\n\t\t\t\tlinkR=null;\n\t\t\tif((linkR!=null)||(linkE!=null))\n\t\t\t{\n\t\t\t\tCMLib.map().registerWorldObjectLoaded(room.getArea(), room, linkE);\n\t\t\t\tfinal String fullSQL;\n\t\t\t\tfinal String exitText = (linkE==null)?" ":linkE.text();\n\t\t\t\tif(dirs.contains(Integer.valueOf(d)))\n\t\t\t\t{\n\t\t\t\t\tfullSQL ="UPDATE CMROEX SET "\n\t\t\t\t\t\t\t+"CMEXID=\'"+((linkE==null)?" ":linkE.ID())+"\', "\n\t\t\t\t\t\t\t+"CMEXTX=?, "\n\t\t\t\t\t\t\t+"CMNRID=\'"+((linkR==null)?" ":linkR.roomID())+"\'"\n\t\t\t\t\t\t\t+" WHERE CMROID=\'"+baseRoomID+"\' and CMDIRE="+d;\n\t\t\t\t\tdirs.remove(Integer.valueOf(d));\n\t\t\t\t\tstatements.add(new DBPreparedBatchEntry(fullSQL,exitText));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfullSQL ="INSERT INTO CMROEX ("\n\t\t\t\t\t\t\t+"CMROID, "\n\t\t\t\t\t\t\t+"CMDIRE, "\n\t\t\t\t\t\t\t+"CMEXID, "\n\t\t\t\t\t\t\t+"CMEXTX, "\n\t\t\t\t\t\t\t+"CMNRID"\n\t\t\t\t\t\t\t+") values ("\n\t\t\t\t\t\t\t+"\'"+baseRoomID+"\',"\n\t\t\t\t\t\t\t+d+","\n\t\t\t\t\t\t\t+"\'"+((linkE==null)?" ":linkE.ID())+"\',"\n\t\t\t\t\t\t\t+"?,"\n\t\t\t\t\t\t\t+"\'"+((linkR==null)?" ":linkR.roomID())+"\')";\n\t\t\t\t\tif(!useBulkInserts)\n\t\t\t\t\t\tstatements.add(new DBPreparedBatchEntry(fullSQL,exitText));\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal DBPreparedBatchEntry entry = doBulkInsert(bulkSQL,bulkClobs,fullSQL,exitText);\n\t\t\t\t\t\tif(entry != null)\n\t\t\t\t\t\t\tstatements.add(entry);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif(room instanceof GridLocale)\n\t\t{\n\t\t\tfinal HashSet<String> done=new HashSet<String>();\n\t\t\tint ordinal=0;\n\t\t\tfor(final Iterator<GridLocale.CrossExit> i=((GridLocale)room).outerExits();i.hasNext();)\n\t\t\t{\n\t\t\t\tfinal GridLocale.CrossExit CE=i.next();\n\t\t\t\tRoom R=CMLib.map().getRoom(CE.destRoomID);\n\t\t\t\tif(R==null)\n\t\t\t\t\tcontinue;\n\t\t\t\tif(R.getGridParent()!=null)\n\t\t\t\t\tR=R.getGridParent();\n\t\t\t\tif((R!=null)&&(R.isSavable())&&(!done.contains(R.roomID())))\n\t\t\t\t{\n\t\t\t\t\tdone.add(R.roomID());\n\t\t\t\t\tfinal HashSet<String> oldStrs=new HashSet<String>();\n\t\t\t\t\tfor(final Iterator<GridLocale.CrossExit> i2=((GridLocale)room).outerExits();i2.hasNext();)\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal GridLocale.CrossExit CE2=i2.next();\n\t\t\t\t\t\tif((CE2.destRoomID.equals(R.roomID())\n\t\t\t\t\t\t||(CE2.destRoomID.startsWith(R.roomID()+"#("))))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal String str=CE2.x+" "+CE2.y+" "+((CE2.out?256:512)|CE2.dir)+" "+CE2.destRoomID.substring(R.roomID().length())+";";\n\t\t\t\t\t\t\tif(!oldStrs.contains(str))\n\t\t\t\t\t\t\t\toldStrs.add(str);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfinal StringBuffer exitStr=new StringBuffer("");\n\t\t\t\t\tfor (final String string : oldStrs)\n\t\t\t\t\t\texitStr.append(string);\n\t\t\t\t\tfinal String fullSQL;\n\t\t\t\t\tfinal int d = (256+(++ordinal));\n\t\t\t\t\tfinal String exitText = exitStr.toString();\n\t\t\t\t\tif(dirs.contains(Integer.valueOf(d)))\n\t\t\t\t\t{\n\t\t\t\t\t\tfullSQL ="UPDATE CMROEX SET "\n\t\t\t\t\t\t\t\t+"CMEXID=\'Open\', "\n\t\t\t\t\t\t\t\t+"CMEXTX=?, "\n\t\t\t\t\t\t\t\t+"CMNRID=\'"+R.roomID()+"\'"\n\t\t\t\t\t\t\t\t+" WHERE CMROID=\'"+baseRoomID+"\' and CMDIRE="+d;\n\t\t\t\t\t\tdirs.remove(Integer.valueOf(d));\n\t\t\t\t\t\tstatements.add(new DBPreparedBatchEntry(fullSQL,exitText));\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tfullSQL =\n\t\t\t\t\t\t"INSERT INTO CMROEX ("\n\t\t\t\t\t\t+"CMROID, "\n\t\t\t\t\t\t+"CMDIRE, "\n\t\t\t\t\t\t+"CMEXID, "\n\t\t\t\t\t\t+"CMEXTX, "\n\t\t\t\t\t\t+"CMNRID"\n\t\t\t\t\t\t+") values ("\n\t\t\t\t\t\t+"\'"+baseRoomID+"\',"\n\t\t\t\t\t\t+d+","\n\t\t\t\t\t\t+"\'Open\',"\n\t\t\t\t\t\t+"?,"\n\t\t\t\t\t\t+"\'"+R.roomID()+"\')";\n\t\t\t\t\t\tif(!useBulkInserts)\n\t\t\t\t\t\t\tstatements.add(new DBPreparedBatchEntry(fullSQL,exitText));\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal DBPreparedBatchEntry entry = doBulkInsert(bulkSQL,bulkClobs,fullSQL,exitText);\n\t\t\t\t\t\t\tif(entry != null)\n\t\t\t\t\t\t\t\tstatements.add(entry);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif((bulkSQL.length()>0) && useBulkInserts)\n\t\t\tstatements.add(new DBPreparedBatchEntry(bulkSQL.toString(),bulkClobs.toArray(new String[0])));\n\t\tfor(final Integer d : dirs)\n\t\t{\n\t\t\tfinal String fullSQL;\n\t\t\tfullSQL = "DELETE FROM CMROEX  WHERE CMROID=\'"+baseRoomID+"\' and CMDIRE="+d;\n\t\t\tstatements.add(new DBPreparedBatchEntry(fullSQL));\n\t\t}\n\t\tDB.updateWithClobs(statements);\n\t\tif(Log.debugChannelOn()\n\t\t&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROEX)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Finished exit update for room "+baseRoomID);\n\t}\n\n\tpublic void DBUpdateExits(final Room room)\n\t{\n\t\tif((!room.isSavable())||(room.amDestroyed()))\n\t\t\treturn;\n\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROEX)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Starting exit update for room "+room.roomID());\n\t\tfinal List<DBPreparedBatchEntry> statements=new Vector<DBPreparedBatchEntry>();\n\t\tfinal boolean useBulkInserts = DB.useBulkInserts();\n\t\tfinal StringBuilder bulkSQL = new StringBuilder("");\n\t\tfinal List<String> bulkClobs = new ArrayList<String>();\n\t\tstatements.add(new DBPreparedBatchEntry("DELETE FROM CMROEX WHERE CMROID=\'"+room.roomID()+"\'"));\n\t\tfor(int d=Directions.NUM_DIRECTIONS()-1;d>=0;d--)\n\t\t{\n\t\t\tExit linkE=room.getRawExit(d);\n\t\t\tRoom linkR=room.rawDoors()[d];\n\n\t\t\tif((linkE!=null)&&(!linkE.isSavable()))\n\t\t\t\tlinkE=null;\n\t\t\tif((linkR!=null)\n\t\t\t&&(!linkR.isSavable())\n\t\t\t&&(!linkR.ID().equals("ThinRoom")))\n\t\t\t\tlinkR=null;\n\t\t\tif((linkR!=null)||(linkE!=null))\n\t\t\t{\n\t\t\t\tCMLib.map().registerWorldObjectLoaded(room.getArea(), room, linkE);\n\t\t\t\tfinal String fullSQL ="INSERT INTO CMROEX ("\n\t\t\t\t\t\t+"CMROID, "\n\t\t\t\t\t\t+"CMDIRE, "\n\t\t\t\t\t\t+"CMEXID, "\n\t\t\t\t\t\t+"CMEXTX, "\n\t\t\t\t\t\t+"CMNRID"\n\t\t\t\t\t\t+") values ("\n\t\t\t\t\t\t+"\'"+room.roomID()+"\',"\n\t\t\t\t\t\t+d+","\n\t\t\t\t\t\t+"\'"+((linkE==null)?" ":linkE.ID())+"\',"\n\t\t\t\t\t\t+"?,"\n\t\t\t\t\t\t+"\'"+((linkR==null)?" ":linkR.roomID())+"\')";\n\t\t\t\tfinal String exitText = (linkE==null)?" ":linkE.text();\n\t\t\t\tif(!useBulkInserts)\n\t\t\t\t\tstatements.add(new DBPreparedBatchEntry(fullSQL,exitText));\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfinal DBPreparedBatchEntry entry = doBulkInsert(bulkSQL,bulkClobs,fullSQL,exitText);\n\t\t\t\t\tif(entry != null)\n\t\t\t\t\t\tstatements.add(entry);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif(room instanceof GridLocale)\n\t\t{\n\t\t\tfinal HashSet<String> done=new HashSet<String>();\n\t\t\tint ordinal=0;\n\t\t\tfor(final Iterator<GridLocale.CrossExit> i=((GridLocale)room).outerExits();i.hasNext();)\n\t\t\t{\n\t\t\t\tfinal GridLocale.CrossExit CE=i.next();\n\t\t\t\tRoom R=CMLib.map().getRoom(CE.destRoomID);\n\t\t\t\tif(R==null)\n\t\t\t\t\tcontinue;\n\t\t\t\tif(R.getGridParent()!=null)\n\t\t\t\t\tR=R.getGridParent();\n\t\t\t\tif((R!=null)&&(R.isSavable())&&(!done.contains(R.roomID())))\n\t\t\t\t{\n\t\t\t\t\tdone.add(R.roomID());\n\t\t\t\t\tfinal HashSet<String> oldStrs=new HashSet<String>();\n\t\t\t\t\tfor(final Iterator<GridLocale.CrossExit> i2=((GridLocale)room).outerExits();i2.hasNext();)\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal GridLocale.CrossExit CE2=i2.next();\n\t\t\t\t\t\tif((CE2.destRoomID.equals(R.roomID())\n\t\t\t\t\t\t||(CE2.destRoomID.startsWith(R.roomID()+"#("))))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal String str=CE2.x+" "+CE2.y+" "+((CE2.out?256:512)|CE2.dir)+" "+CE2.destRoomID.substring(R.roomID().length())+";";\n\t\t\t\t\t\t\tif(!oldStrs.contains(str))\n\t\t\t\t\t\t\t\toldStrs.add(str);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfinal StringBuffer exitStr=new StringBuffer("");\n\t\t\t\t\tfor (final String string : oldStrs)\n\t\t\t\t\t\texitStr.append(string);\n\t\t\t\t\tfinal String fullSQL =\n\t\t\t\t\t"INSERT INTO CMROEX ("\n\t\t\t\t\t+"CMROID, "\n\t\t\t\t\t+"CMDIRE, "\n\t\t\t\t\t+"CMEXID, "\n\t\t\t\t\t+"CMEXTX, "\n\t\t\t\t\t+"CMNRID"\n\t\t\t\t\t+") values ("\n\t\t\t\t\t+"\'"+room.roomID()+"\',"\n\t\t\t\t\t+(256+(++ordinal))+","\n\t\t\t\t\t+"\'Open\',"\n\t\t\t\t\t+"?,"\n\t\t\t\t\t+"\'"+R.roomID()+"\')";\n\t\t\t\t\tfinal String exitText = exitStr.toString();\n\t\t\t\t\tif(!useBulkInserts)\n\t\t\t\t\t\tstatements.add(new DBPreparedBatchEntry(fullSQL,exitText));\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal DBPreparedBatchEntry entry = doBulkInsert(bulkSQL,bulkClobs,fullSQL,exitText);\n\t\t\t\t\t\tif(entry != null)\n\t\t\t\t\t\t\tstatements.add(entry);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif((bulkSQL.length()>0) && useBulkInserts)\n\t\t\tstatements.add(new DBPreparedBatchEntry(bulkSQL.toString(),bulkClobs.toArray(new String[0])));\n\t\tDB.updateWithClobs(statements);\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROEX)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Finished exit update for room "+room.roomID());\n\t}\n\n\tpublic void DBCreateThisMOB(final String roomID, final MOB thisMOB)\n\t{\n\t\tfinal Pair<String,String> sql= getDBCreateMOBString(roomID,thisMOB);\n\t\tfinal DBPreparedBatchEntry entry = new DBPreparedBatchEntry(sql.first,sql.second);\n\t\tDB.updateWithClobs(entry);\n\t}\n\n\tpublic Pair<String,String> getDBCreateMOBString(final String roomID, final MOB thisMOB)\n\t{\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROCH)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Creating mob "+thisMOB.name()+" for room "+roomID);\n\t\tfinal boolean catalog=((roomID!=null)&&(roomID.startsWith("CATALOG_")));\n\n\t\tString ride=null;\n\t\tfinal String mobID=this.getShortID(thisMOB);\n\t\tthisMOB.setDatabaseID(mobID);\n\t\tif(thisMOB.riding()!=null)\n\t\t\tride="*"+this.getShortID(thisMOB.riding());\n\t\telse\n\t\tif(thisMOB.amFollowing()!=null)\n\t\t\tride=this.getShortID(thisMOB.amFollowing());\n\t\telse\n\t\t\tride="";\n\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROCH)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Created mob "+thisMOB.name()+" for room "+roomID);\n\n\t\tif((CMProps.getBoolVar(CMProps.Bool.MOBNOCACHE))&&(!catalog))\n\t\t\tthisMOB.setMiscText("%DBID>"+roomID+mobID.substring(mobID.indexOf(\'@\')));\n\n\t\tString text=thisMOB.text();\n\t\tif(catalog)\n\t\t{\n\t\t\tfinal CatalogLibrary.CataData dataM=CMLib.catalog().getCatalogMobData(thisMOB.Name());\n\t\t\tif(dataM!=null)\n\t\t\t\ttext+=dataM.data(null);\n\t\t}\n\t\treturn new Pair<String,String>(\n\t\t"INSERT INTO CMROCH ("\n\t\t+"CMROID, "\n\t\t+"CMCHNM, "\n\t\t+"CMCHID, "\n\t\t+"CMCHTX, "\n\t\t+"CMCHLV, "\n\t\t+"CMCHAB, "\n\t\t+"CMCHRE, "\n\t\t+"CMCHRI "\n\t\t+") values ("\n\t\t+"\'"+roomID+"\',"\n\t\t+"\'"+mobID+"\',"\n\t\t+"\'"+CMClass.classID(thisMOB)+"\',"\n\t\t+"?,"\n\t\t+thisMOB.basePhyStats().level()+","\n\t\t+thisMOB.basePhyStats().ability()+","\n\t\t+thisMOB.basePhyStats().rejuv()+","\n\t\t+"\'"+ride+"\'"\n\t\t+")",\n\t\ttext+" ");\n\t}\n\n\tpublic void DBUpdateTheseMOBs(final Room room, List<MOB> mobs)\n\t{\n\t\tif((!room.isSavable())||(room.amDestroyed()))\n\t\t\treturn;\n\t\tfinal boolean useBulkInserts = DB.useBulkInserts();\n\t\tfinal StringBuilder bulkSQL = new StringBuilder("");\n\t\tfinal List<String> bulkClobs = new ArrayList<String>();\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROCH)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Updating mobs for room "+room.roomID());\n\t\tif(mobs==null)\n\t\t\tmobs=new ArrayList<MOB>();\n\t\tfinal List<DBPreparedBatchEntry> statements=new ArrayList<DBPreparedBatchEntry>();\n\t\tstatements.add(new DBPreparedBatchEntry("DELETE FROM CMROCH WHERE CMROID=\'"+room.roomID()+"\'"));\n\t\tfor(int m=0;m<mobs.size();m++)\n\t\t{\n\t\t\tfinal MOB thisMOB=mobs.get(m);\n\t\t\tCMLib.map().registerWorldObjectLoaded(room.getArea(), room, thisMOB);\n\t\t\tfinal Pair<String,String> sqlpair= getDBCreateMOBString(room.roomID(),thisMOB);\n\t\t\tif(!useBulkInserts)\n\t\t\t\tstatements.add(new DBPreparedBatchEntry(sqlpair.first,sqlpair.second));\n\t\t\telse\n\t\t\t{\n\t\t\t\tfinal DBPreparedBatchEntry entry = doBulkInsert(bulkSQL,bulkClobs,sqlpair.first,sqlpair.second);\n\t\t\t\tif(entry != null)\n\t\t\t\t\tstatements.add(entry);\n\t\t\t}\n\t\t}\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROCH)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Done updating mobs for room "+room.roomID());\n\t\tif((bulkSQL.length()>0) && useBulkInserts)\n\t\t\tstatements.add(new DBPreparedBatchEntry(bulkSQL.toString(),bulkClobs.toArray(new String[0])));\n\t\tDB.updateWithClobs(statements);\n\t}\n\n\tpublic void DBUpdateMOBs(final Room room)\n\t{\n\t\tif((!room.isSavable())||(room.amDestroyed()))\n\t\t\treturn;\n\t\tfinal List<MOB> mobs=new ArrayList<MOB>();\n\t\tfor(int m=0;m<room.numInhabitants();m++)\n\t\t{\n\t\t\tfinal MOB thisMOB=room.fetchInhabitant(m);\n\t\t\tif((thisMOB!=null)&&(thisMOB.isSavable()))\n\t\t\t\tmobs.add(thisMOB);\n\t\t}\n\t\tDBUpdateTheseMOBs(room,mobs);\n\t}\n\n\tpublic void DBUpdateAll(final Room room)\n\t{\n\t\tif((!room.isSavable())||(room.amDestroyed()))\n\t\t\treturn;\n\t\tDBUpdateRoom(room);\n\t\tDBUpdateMOBs(room);\n\t\tDBUpdateExits(room);\n\t\tDBUpdateItems(room);\n\t}\n\n\tpublic void DBUpdateRoom(final Room room)\n\t{\n\t\tif((!room.isSavable())||(room.amDestroyed()))\n\t\t\treturn;\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROOM)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Start updating room "+room.roomID());\n\t\tCMLib.map().registerWorldObjectLoaded(room.getArea(), room, room);\n\t\tDB.updateWithClobs(\n\t\t"UPDATE CMROOM SET "\n\t\t+"CMLOID=\'"+CMClass.classID(room)+"\',"\n\t\t+"CMAREA=\'"+room.getArea().Name()+"\',"\n\t\t+"CMDESC1=\'"+room.displayText().replace(\'\\\'\', \'`\')+" \',"\n\t\t+"CMDESC2=?,"\n\t\t+"CMROTX=? "\n\t\t+"WHERE CMROID=\'"+room.roomID()+"\'",\n\t\tnew String[]{room.description()+" ",room.text()+" "});\n\t\tif(CMProps.getBoolVar(CMProps.Bool.ROOMDNOCACHE))\n\t\t\troom.setDescription("");\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROOM)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Done updating room "+room.roomID());\n\t}\n\n\tpublic void DBReCreate(final Room room, final String oldID)\n\t{\n\t\tif((!room.isSavable())||(room.amDestroyed()))\n\t\t\treturn;\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROOM)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Recreating room "+room.roomID());\n\n\t\tDB.update(\n\t\t"UPDATE CMROOM SET "\n\t\t+"CMROID=\'"+room.roomID()+"\', "\n\t\t+"CMAREA=\'"+room.getArea().Name()+"\' "\n\t\t+"WHERE CMROID=\'"+oldID+"\'");\n\n\t\tif(CMProps.getBoolVar(CMProps.Bool.MOBNOCACHE))\n\t\t{\n\t\t\tfor(int m=0;m<room.numInhabitants();m++)\n\t\t\t{\n\t\t\t\tfinal MOB M=room.fetchInhabitant(m);\n\t\t\t\tif((M!=null)&&(M.isSavable()))\n\t\t\t\t\tM.setMiscText(M.text());\n\t\t\t}\n\n\t\t}\n\t\tDB.update(\n\t\t"UPDATE CMROCH SET "\n\t\t+"CMROID=\'"+room.roomID()+"\' "\n\t\t+"WHERE CMROID=\'"+oldID+"\'");\n\n\t\tDB.update(\n\t\t"UPDATE CMROEX SET "\n\t\t+"CMROID=\'"+room.roomID()+"\' "\n\t\t+"WHERE CMROID=\'"+oldID+"\'");\n\n\t\tDB.update(\n\t\t"UPDATE CMROEX SET "\n\t\t+"CMNRID=\'"+room.roomID()+"\' "\n\t\t+"WHERE CMNRID=\'"+oldID+"\'");\n\n\t\tDB.update(\n\t\t"UPDATE CMROIT SET "\n\t\t+"CMROID=\'"+room.roomID()+"\' "\n\t\t+"WHERE CMROID=\'"+oldID+"\'");\n\n\t\tCMLib.database().DBUpdatePlayerStartRooms(oldID, room.roomID());\n\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROOM)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Done recreating room "+room.roomID());\n\t}\n\n\tpublic void DBCreate(final Area A)\n\t{\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMAREA)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Creating area "+A.name());\n\t\tif((A==null)||(A.name().length()==0))\n\t\t{\n\t\t\tLog.errOut("RoomLoader","Unable to create area "+((A!=null)?A.name():"null"));\n\t\t\treturn;\n\t\t}\n\n\t\tCMLib.map().registerWorldObjectLoaded(A, null, A);\n\n\t\tDB.updateWithClobs(\n\t\t"INSERT INTO CMAREA ("\n\t\t+"CMAREA,"\n\t\t+"CMTYPE,"\n\t\t+"CMCLIM,"\n\t\t+"CMSUBS,"\n\t\t+"CMDESC,"\n\t\t+"CMROTX,"\n\t\t+"CMTECH"\n\t\t+") values ("\n\t\t+"\'"+A.Name()+"\',"\n\t\t+"\'"+A.ID()+"\',"\n\t\t+""+A.getClimateTypeCode()+","\n\t\t+"\'"+A.getSubOpList()+"\',"\n\t\t+"?,"\n\t\t+"?,"\n\t\t+A.getThemeCode()+")",\n\t\tnew String[][]{{A.description()+" ",A.text()+" "}});\n\t\tA.setAreaState(Area.State.ACTIVE);\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMAREA)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Done creating area "+A.name());\n\t}\n\n\tpublic void DBUpdate(final String areaID, final Area A)\n\t{\n\t\tif((A==null)||(!A.isSavable()))\n\t\t\treturn;\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMAREA)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Updating area "+A.name());\n\t\tfinal boolean ignoreType=CMSecurity.isDisabled(CMSecurity.DisFlag.FATAREAS)||CMSecurity.isDisabled(CMSecurity.DisFlag.THINAREAS);\n\t\tCMLib.map().registerWorldObjectLoaded(A, null, A);\n\t\tDB.updateWithClobs(\n\t\t"UPDATE CMAREA SET "\n\t\t+"CMAREA=\'"+A.Name()+"\',"\n\t\t+(ignoreType?"":"CMTYPE=\'"+A.ID()+"\',")\n\t\t+"CMCLIM="+A.getClimateTypeCode()+","\n\t\t+"CMSUBS=\'"+A.getSubOpList()+"\',"\n\t\t+"CMDESC=?,"\n\t\t+"CMROTX=?,"\n\t\t+"CMTECH="+A.getThemeCode()+" "\n\t\t+"WHERE CMAREA=\'"+areaID+"\'",\n\t\tnew String[]{A.description()+" ",A.text()+" "});\n\t\tif(Log.debugChannelOn()\n\t\t&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMAREA)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Done updating area "+A.name());\n\t}\n\n\tpublic void DBDeleteRoomItem(final String roomID, final Item item)\n\t{\n\t\tString keyName=item.databaseID();\n\t\tif(keyName.length()==0)\n\t\t\tkeyName=this.getShortID(item);\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROIT)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Done updating item "+item.name()+" in room "+roomID);\n\t\tDB.update(\n\t\t"DELETE FROM CMROIT "\n\t\t+"WHERE CMROID=\'"+roomID+"\' "\n\t\t+"AND CMITNM=\'"+keyName+"\'");\n\t}\n\n\tpublic void DBUpdateRoomItem(final String roomID, final Item item)\n\t{\n\t\tif((roomID==null)||(!item.isSavable())||(item.amDestroyed()))\n\t\t\treturn;\n\t\tsynchronized(CMClass.getSync("SYNC"+roomID.toUpperCase()))\n\t\t{\n\t\t\tDBDeleteRoomItem(roomID,item);\n\t\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROIT)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\t\tLog.debugOut("RoomLoader","Continue updating item "+item.name()+" in room "+roomID);\n\t\t\tDBCreateThisItem(roomID,item);\n\t\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROIT)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\t\tLog.debugOut("RoomLoader","Done updating item "+item.name()+" in room "+roomID);\n\t\t}\n\t}\n\n\tpublic void DBDeleteRoomMOB(final String roomID, final MOB mob)\n\t{\n\t\tString keyName=mob.databaseID();\n\t\tif(keyName.length()==0)\n\t\t\tkeyName=this.getShortID(mob);\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROCH)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Done updating mob "+mob.name()+" in room "+roomID);\n\t\tDB.update(\n\t\t"DELETE FROM CMROCH "\n\t\t+"WHERE CMROID=\'"+roomID+"\' "\n\t\t+"AND CMCHNM=\'"+keyName+"\'");\n\t}\n\n\tpublic void DBUpdateRoomMOB(final String roomID, final MOB mob)\n\t{\n\t\tif((roomID==null)||(!mob.isSavable())||(mob.amDestroyed()))\n\t\t\treturn;\n\t\tDBDeleteRoomMOB(roomID, mob);\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROCH)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Continue updating mob "+mob.name()+" in room "+roomID);\n\t\tDBCreateThisMOB(roomID,mob);\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROCH)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Done updating mob "+mob.name()+" in room "+roomID);\n\t}\n\n\tpublic void DBCreate(final Room room)\n\t{\n\t\tif(!room.isSavable())\n\t\t\treturn;\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROOM)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Creating new room "+room.roomID());\n\t\tCMLib.map().registerWorldObjectLoaded(room.getArea(), room, room);\n\t\tDB.updateWithClobs(\n\t\t"INSERT INTO CMROOM ("\n\t\t+"CMROID,"\n\t\t+"CMLOID,"\n\t\t+"CMAREA,"\n\t\t+"CMDESC1,"\n\t\t+"CMDESC2,"\n\t\t+"CMROTX"\n\t\t+") values ("\n\t\t+"\'"+room.roomID()+"\',"\n\t\t+"\'"+CMClass.classID(room)+"\',"\n\t\t+"\'"+room.getArea().Name()+"\',"\n\t\t+"\'"+room.displayText()+" \',"\n\t\t+"?,"\n\t\t+"?)",\n\t\tnew String[][]{{room.description()+" ",room.text()+" "}});\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROOM)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Done creating new room "+room.roomID());\n\t}\n\n\tprotected List<String> getRoomDeleteStrings(final String roomID)\n\t{\n\t\treturn new XVector<String>(\n\t\t\t"DELETE FROM CMROEX WHERE CMROID=\'"+roomID+"\'",\n\t\t\t"DELETE FROM CMROCH WHERE CMROID=\'"+roomID+"\'",\n\t\t\t"DELETE FROM CMROIT WHERE CMROID=\'"+roomID+"\'"\n\t\t);\n\t}\n\n\tpublic void DBDelete(final Room room)\n\t{\n\t\tif(!room.isSavable())\n\t\t\treturn;\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROCH)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Destroying room "+room.roomID());\n\t\tDB.update(getRoomDeleteStrings(room.roomID()).toArray(new String[0]));\n\t\tDB.update("DELETE FROM CMROOM WHERE CMROID=\'"+room.roomID()+"\'");\n\t\troom.destroy();\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMROCH)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Done gestroying room "+room.roomID());\n\t}\n\n\tprotected List<String> getAreaDeleteStrings(final String areaName)\n\t{\n\t\treturn new XVector<String>(\n\t\t\t"DELETE FROM CMAREA WHERE CMAREA=\'"+areaName+"\'",\n\t\t\t"DELETE FROM CMPDAT WHERE CMPLID=\'"+areaName+"\' AND CMSECT=\'TIMECLOCK\'"\n\t\t);\n\t}\n\n\tpublic void DBDelete(final Area A)\n\t{\n\t\tif(A==null)\n\t\t\treturn;\n\t\tif(!A.isSavable())\n\t\t\treturn;\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMAREA)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Destroying area "+A.name());\n\t\tA.setAreaState(Area.State.STOPPED);\n\t\tDB.update(getAreaDeleteStrings(A.Name()).toArray(new String[0]));\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMAREA)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Done destroying area "+A.name()+".");\n\t}\n\n\tpublic void DBDeleteAreaAndRooms(final Area A)\n\t{\n\t\tif(A==null)\n\t\t\treturn;\n\t\tif(!A.isSavable())\n\t\t\treturn;\n\t\tif(Log.debugChannelOn()&&(CMSecurity.isDebugging(CMSecurity.DbgFlag.CMAREA)||CMSecurity.isDebugging(CMSecurity.DbgFlag.DBROOMS)))\n\t\t\tLog.debugOut("RoomLoader","Destroying area "+A.name());\n\t\tA.setAreaState(Area.State.STOPPED);\n\t\tfinal List<String> statements = new Vector<String>(4 + A.numberOfProperIDedRooms());\n\t\tstatements.addAll(getAreaDeleteStrings(A.Name()));\n\t\tstatements.add("DELETE FROM CMROOM WHERE CMAREA=\'"+A.Name()+"\'");\n\t\tfor(final Enumeration<String> ids=A.getProperRoomnumbers().getRoomIDs();ids.hasMoreElements();)\n\t\t\tstatements.addAll(getRoomDeleteStrings(ids.nextElement()));\n\t\tstatements.add("DELETE FROM CMROOM WHERE CMAREA=\'"+A.Name()+"\'");\n\t\tfinal String[] statementsBlock = statements.toArray(new String[statements.size()]);\n\t\tstatements.clear();\n\t\tfor(int i=0;i<3;i++)\n\t\t{\n\t\t\t// not even mysql delete everything as commanded.\n\t\t\tDB.update(statementsBlock);\n\t\t\ttry\n\t\t\t{\n\t\t\t\tThread.sleep(A.numberOfProperIDedRooms());\n\t\t\t}\n\t\t\tcatch(final Exception e)\n\t\t\t{\n\t\t\t}\n\t\t}\n\t}\n}\n', 'message': '\n\ngit-svn-id: svn://192.168.1.10/public/CoffeeMud@11456 0d6f1817-ed0e-0410-87c9-987e46238f29\n', 'author_name': 'bozimmerman', 'lang': 'java'}