/
com/planet_ink/coffee_mud/Abilities/
com/planet_ink/coffee_mud/Abilities/Common/
com/planet_ink/coffee_mud/Abilities/Diseases/
com/planet_ink/coffee_mud/Abilities/Druid/
com/planet_ink/coffee_mud/Abilities/Fighter/
com/planet_ink/coffee_mud/Abilities/Prayers/
com/planet_ink/coffee_mud/Abilities/Properties/
com/planet_ink/coffee_mud/Abilities/Skills/
com/planet_ink/coffee_mud/Abilities/Songs/
com/planet_ink/coffee_mud/Abilities/Spells/
com/planet_ink/coffee_mud/Abilities/Thief/
com/planet_ink/coffee_mud/Abilities/Traps/
com/planet_ink/coffee_mud/Areas/interfaces/
com/planet_ink/coffee_mud/Behaviors/
com/planet_ink/coffee_mud/CharClasses/interfaces/
com/planet_ink/coffee_mud/Commands/
com/planet_ink/coffee_mud/Commands/interfaces/
com/planet_ink/coffee_mud/Exits/interfaces/
com/planet_ink/coffee_mud/Items/Armor/
com/planet_ink/coffee_mud/Items/Basic/
com/planet_ink/coffee_mud/Items/MiscMagic/
com/planet_ink/coffee_mud/Items/Software/
com/planet_ink/coffee_mud/Items/Weapons/
com/planet_ink/coffee_mud/Libraries/interfaces/
com/planet_ink/coffee_mud/Locales/
com/planet_ink/coffee_mud/Locales/interfaces/
com/planet_ink/coffee_mud/MOBS/
com/planet_ink/coffee_mud/MOBS/interfaces/
com/planet_ink/coffee_mud/Races/
com/planet_ink/coffee_mud/Races/interfaces/
com/planet_ink/coffee_mud/WebMacros/
com/planet_ink/coffee_mud/WebMacros/interfaces/
com/planet_ink/coffee_mud/application/
com/planet_ink/coffee_mud/core/smtp/
com/planet_ink/siplet/applet/
lib/
resources/examples/
resources/fakedb/
resources/quests/delivery/
resources/quests/diseased/
resources/quests/drowning/
resources/quests/gobwar/
resources/quests/holidays/
resources/quests/robbed/
resources/quests/smurfocide/
resources/quests/stolen/
resources/quests/templates/
resources/quests/treasurehunt/
resources/quests/vengeance/
web/
web/admin.templates/
web/admin/images/
web/pub.templates/
web/pub/images/mxp/
web/pub/sounds/
package com.planet_ink.coffee_mud.Abilities.Common;
import com.planet_ink.coffee_mud.core.interfaces.*;
import com.planet_ink.coffee_mud.core.*;
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.Locales.interfaces.*;
import com.planet_ink.coffee_mud.MOBS.interfaces.*;
import com.planet_ink.coffee_mud.Races.interfaces.*;


import java.util.*;

/* 
   Copyright 2000-2006 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 Construction extends CraftingSkill
{
	public String ID() { return "Construction"; }
	public String name(){ return "Construction";}
	private static final String[] triggerStrings = {"CONSTRUCT"};
	public String[] triggerStrings(){return triggerStrings;}
    public String supportedResourceString(){return "WOODEN";}

	protected static final int BUILD_WALL=0;
	protected static final int BUILD_DOOR=1;
	protected static final int BUILD_ROOF=2;
	protected static final int BUILD_GATE=3;
	protected static final int BUILD_FENCE=4;
	protected static final int BUILD_DEMOLISH=5;
	protected static final int BUILD_TITLE=6;
	protected static final int BUILD_DESC=7;
	protected static final int BUILD_SECRETDOOR=8;
	protected static final int BUILD_WINDOW=9;
	protected static final int BUILD_CRAWLWAY=10;
	protected static final int BUILD_STAIRS=11;

	private final static int DAT_NAME=0;
	private final static int DAT_WOOD=1;
	private final static int DAT_ROOF=2;
	private final static int DAT_REQDIR=3;
	private final static int DAT_REQNONULL=4;

	// name, wood, ok=0/roof=1/out=2, req direction=1, ok=0, ok=0, nonull=1, nullonly=2
	private final static String[][] data={
		{"Wall","100","1","1","0"},
		{"Door","125","1","1","0"},
		{"Roof","350","2","0","0"},
		{"Gate","50","2","1","0"},
		{"Fence","50","2","1","0"},
		{"Demolish","0","0","1","0"},
		{"Title","0","0","0","0"},
		{"Description","0","0","0","0"},
		{"Secret Door","200","1","1","0"},
		{"Window","50","1","1","1"},
		{"Crawlway","250","1","1","1"}//,{"Stairs","350","1","0","0"}
	};

	protected Room room=null;
	protected int dir=-1;
	protected int doingCode=-1;
	protected int workingOn=-1;
	protected String designTitle="";
	protected String designDescription="";
	public Construction(){super();}

	public Exit generify(Exit E)
	{
		Exit E2=CMClass.getExit("GenExit");
		E2.setName(E.name());
		E2.setDisplayText(E.displayText());
		E2.setDescription(E.description());
		E2.setDoorsNLocks(E.hasADoor(),E.isOpen(),E.defaultsClosed(),E.hasALock(),E.isLocked(),E.defaultsLocked());
		E2.setBaseEnvStats((EnvStats)E.baseEnvStats().copyOf());
		E2.setExitParams(E.doorName(),E.closeWord(),E.openWord(),E.closedText());
		E2.setKeyName(E.keyName());
		E2.setOpenDelayTicks(E.openDelayTicks());
		E2.setReadable(E.isReadable());
		E2.setReadableText(E.readableText());
		E2.setTemporaryDoorLink(E.temporaryDoorLink());
		E2.recoverEnvStats();
		return E2;
	}

	public void unInvoke()
	{
		if(canBeUninvoked())
		{
			if((affected!=null)&&(affected instanceof MOB)&&(!helping))
			{
				MOB mob=(MOB)affected;
				if(!aborted)
				{
					if((messedUp)&&(room!=null))
					switch(doingCode)
					{
					case BUILD_ROOF:
						commonTell(mob,"You've ruined the frame and roof!");
						break;
					case BUILD_WALL:
						commonTell(mob,"You've ruined the wall!");
						break;
					case BUILD_DOOR:
						commonTell(mob,"You've ruined the door!");
						break;
					case BUILD_SECRETDOOR:
						commonTell(mob,"You've ruined the secret door!");
						break;
					case BUILD_FENCE:
						commonTell(mob,"You've ruined the fence!");
						break;
					case BUILD_GATE:
						commonTell(mob,"You've ruined the gate!");
						break;
					case BUILD_TITLE:
						commonTell(mob,"You've ruined the titling!");
						break;
					case BUILD_DESC:
						commonTell(mob,"You've ruined the describing!");
						break;
					case BUILD_WINDOW:
						commonTell(mob,"You've ruined the window!");
						break;
					case BUILD_CRAWLWAY:
						commonTell(mob,"You've ruined the crawlway!");
						break;
					case BUILD_STAIRS:
						commonTell(mob,"You've ruined the stairs!");
						break;
					case BUILD_DEMOLISH:
					default:
						commonTell(mob,"You've failed to demolish!");
						break;
					}
					else
					switch(doingCode)
					{
					case BUILD_ROOF:
						{
							synchronized(("SYNC"+room.roomID()).intern())
							{
								room=CMLib.map().getRoom(room);
								Room R=CMClass.getLocale("WoodRoom");
								R.setRoomID(room.roomID());
								R.setDisplayText(room.displayText());
								R.setDescription(room.description());
                                if(R.image().equalsIgnoreCase(CMProps.getDefaultMXPImage(room))) R.setImage(null);
                                
								Area area=room.getArea();
								if(area!=null) area.delProperRoom(room);
								R.setArea(area);
								for(int a=room.numEffects()-1;a>=0;a--)
								{
									Ability A=room.fetchEffect(a);
									if(A!=null){
										room.delEffect(A);
										R.addEffect(A);
									}
								}
								for(int i=room.numItems()-1;i>=0;i--)
								{
									Item I=room.fetchItem(i);
									if(I!=null){
										room.delItem(I);
										R.addItem(I);
									}
								}
								for(int m=room.numInhabitants()-1;m>=0;m--)
								{
									MOB M=room.fetchInhabitant(m);
									if(M!=null){
										room.delInhabitant(M);
										R.addInhabitant(M);
										M.setLocation(R);
									}
								}
								CMLib.threads().deleteTick(room,-1);
								for(int d=0;d<R.rawDoors().length;d++)
								{
									if((R.rawDoors()[d]==null)
									||(R.rawDoors()[d].roomID().length()>0))
										R.rawDoors()[d]=room.rawDoors()[d];
								}
								for(int d=0;d<R.rawExits().length;d++)
								{
									if((R.rawDoors()[d]==null)
									||(R.rawDoors()[d].roomID().length()>0))
										R.rawExits()[d]=room.rawExits()[d];
								}
								R.clearSky();
								R.startItemRejuv();
								try
								{
									boolean rebuild=false;
									for(Enumeration r=CMLib.map().rooms();r.hasMoreElements();)
									{
										Room R2=(Room)r.nextElement();
										rebuild=false;
										for(int d=0;d<R2.rawDoors().length;d++)
										{
											if(R2.rawDoors()[d]==room)
											{
												rebuild=true;
												R2.rawDoors()[d]=R;
											}
										}
										if((rebuild)&&(R2 instanceof GridLocale))
											((GridLocale)R2).buildGrid();
									}
							    }catch(NoSuchElementException e){}
							    try
							    {
									for(Enumeration e=CMLib.map().players();e.hasMoreElements();)
									{
										MOB M=(MOB)e.nextElement();
										if(M.getStartRoom()==room)
											M.setStartRoom(R);
										else
										if(M.location()==room)
											M.setLocation(R);
									}
							    }catch(NoSuchElementException e){}
								R.getArea().fillInAreaRoom(R);
                                if(CMSecurity.isDebugging("PROPERTY"))
                                    Log.debugOut("Construction",R.roomID()+" updated.");
								CMLib.database().DBUpdateRoom(R);
								CMLib.database().DBUpdateExits(R);
							}
                            room.destroy();
						}
						break;
					case BUILD_STAIRS:
						break;
					case BUILD_WALL:
					case BUILD_FENCE:
						{
							synchronized(("SYNC"+room.roomID()).intern())
							{
								room=CMLib.map().getRoom(room);
								room.rawExits()[dir]=null;
								if(room.rawDoors()[dir]!=null)
								{
									room.rawDoors()[dir].rawExits()[Directions.getOpDirectionCode(dir)]=null;
									CMLib.database().DBUpdateExits(room.rawDoors()[dir]);
								}
								CMLib.database().DBUpdateExits(room);
							}
						}
						break;
					case BUILD_TITLE:
						{
							synchronized(("SYNC"+room.roomID()).intern())
							{
								room=CMLib.map().getRoom(room);
								room.setDisplayText(designTitle);
								CMLib.database().DBUpdateRoom(room);
							}
						}
						break;
					case BUILD_DESC:
						{
							synchronized(("SYNC"+room.roomID()).intern())
							{
								room=CMLib.map().getRoom(room);
								if(workingOn>=0)
								{
									Exit E=room.getExitInDir(workingOn);
									if((!E.isGeneric())&&(room.rawExits()[workingOn]==E))
									{
										E=generify(E);
										room.rawExits()[workingOn]=E;
									}
									E.setDescription(designDescription);
									CMLib.database().DBUpdateExits(room);
								}
								else
								{
									room.setDescription(designDescription);
									CMLib.database().DBUpdateRoom(room);
								}
							}
						}
						break;
					case BUILD_CRAWLWAY:
						{
							synchronized(("SYNC"+room.roomID()).intern())
							{
								room=CMLib.map().getRoom(room);
								if((workingOn>=0)&&(room.getExitInDir(workingOn)!=null))
								{
									Exit E=room.getExitInDir(workingOn);
									if((!E.isGeneric())&&(room.rawExits()[workingOn]==E))
									{
										E=generify(E);
										room.rawExits()[workingOn]=E;
									}
									Ability A=CMClass.getAbility("Prop_Crawlspace");
									if(A!=null) E.addNonUninvokableEffect(A);
									CMLib.database().DBUpdateExits(room);
								}
							}
						}
						break;
					case BUILD_WINDOW:
						{
							synchronized(("SYNC"+room.roomID()).intern())
							{
								room=CMLib.map().getRoom(room);
								if((workingOn>=0)&&(room.getExitInDir(workingOn)!=null))
								{
									Exit E=room.getExitInDir(workingOn);
									if((!E.isGeneric())&&(room.rawExits()[workingOn]==E))
									{
										E=generify(E);
										room.rawExits()[workingOn]=E;
									}
									Room R2=room.getRoomInDir(workingOn);
									if(R2!=null)
									{
										Ability A=CMClass.getAbility("Prop_RoomView");
										if(A!=null)
										{
											A.setMiscText(CMLib.map().getExtendedRoomID(R2));
											E.addNonUninvokableEffect(A);
										}
									}
									CMLib.database().DBUpdateExits(room);
								}
							}
						}
						break;
					case BUILD_GATE:
						{
							synchronized(("SYNC"+room.roomID()).intern())
							{
								room=CMLib.map().getRoom(room);
								Exit X=CMClass.getExit("GenExit");
								X.setName("a wooden gate");
								X.setDescription("");
								X.setDisplayText("");
								X.setOpenDelayTicks(9999);
								X.setExitParams("gate","close","open","a closed gate");
								X.setDoorsNLocks(true,false,true,false,false,false);
								X.text();
								room.rawExits()[dir]=X;
								if(room.rawDoors()[dir]!=null)
								{
									Exit X2=(Exit)X.copyOf();
									room.rawDoors()[dir].rawExits()[Directions.getOpDirectionCode(dir)]=X2;
									CMLib.database().DBUpdateExits(room.rawDoors()[dir]);
								}
								CMLib.database().DBUpdateExits(room);
							}
						}
						break;
					case BUILD_DOOR:
					case BUILD_SECRETDOOR:
						{
							synchronized(("SYNC"+room.roomID()).intern())
							{
								room=CMLib.map().getRoom(room);
								Exit X=CMClass.getExit("GenExit");
								if(doingCode==BUILD_SECRETDOOR)
									X.baseEnvStats().setDisposition(EnvStats.IS_HIDDEN);
								X.setName("a door");
								X.setDescription("");
								X.setDisplayText("");
								X.setOpenDelayTicks(9999);
								X.setExitParams("door","close","open","a closed door");
								X.setDoorsNLocks(true,false,true,false,false,false);
								X.recoverEnvStats();
								X.text();
								room.rawExits()[dir]=X;
								if(room.rawDoors()[dir]!=null)
								{
									Exit X2=(Exit)X.copyOf();
									if(doingCode==BUILD_SECRETDOOR)
										X2.baseEnvStats().setDisposition(EnvStats.IS_HIDDEN);
									X2.recoverEnvStats();
									X2.text();
									room.rawDoors()[dir].rawExits()[Directions.getOpDirectionCode(dir)]=X2;
									CMLib.database().DBUpdateExits(room.rawDoors()[dir]);
								}
								CMLib.database().DBUpdateExits(room);
							}
						}
						break;
					case BUILD_DEMOLISH:
					default:
						{
							synchronized(("SYNC"+room.roomID()).intern())
							{
								room=CMLib.map().getRoom(room);
								if(dir<0)
								{
									Room R=CMClass.getLocale("Plains");
									R.setRoomID(room.roomID());
									R.setDisplayText(room.displayText());
									R.setDescription(room.description());
									Area area=room.getArea();
									if(area!=null) area.delProperRoom(room);
									R.setArea(room.getArea());
									for(int a=room.numEffects()-1;a>=0;a--)
									{
										Ability A=room.fetchEffect(a);
										if(A!=null){
											room.delEffect(A);
											R.addEffect(A);
										}
									}
									for(int i=room.numItems()-1;i>=0;i--)
									{
										Item I=room.fetchItem(i);
										if(I!=null){
											room.delItem(I);
											R.addItem(I);
										}
									}
									for(int m=room.numInhabitants()-1;m>=0;m--)
									{
										MOB M=room.fetchInhabitant(m);
										if(M!=null){
											room.delInhabitant(M);
											R.addInhabitant(M);
											M.setLocation(R);
										}
									}
									CMLib.threads().deleteTick(room,-1);
									for(int d=0;d<R.rawDoors().length;d++)
										R.rawDoors()[d]=room.rawDoors()[d];
									for(int d=0;d<R.rawExits().length;d++)
										R.rawExits()[d]=room.rawExits()[d];
									R.startItemRejuv();
									try
									{
										for(Enumeration r=CMLib.map().rooms();r.hasMoreElements();)
										{
											Room R2=(Room)r.nextElement();
											for(int d=0;d<R2.rawDoors().length;d++)
												if(R2.rawDoors()[d]==room)
												{
													R2.rawDoors()[d]=R;
													if(R2 instanceof GridLocale)
														((GridLocale)R2).buildGrid();
												}
										}
								    }catch(NoSuchElementException e){}
									R.getArea().fillInAreaRoom(R);
									CMLib.database().DBUpdateRoom(R);
									CMLib.database().DBUpdateExits(R);
	                                room.destroy();
								}
								else
								{
									room.rawExits()[dir]=CMClass.getExit("Open");
									if(room.rawDoors()[dir]!=null)
									{
										room.rawDoors()[dir].rawExits()[Directions.getOpDirectionCode(dir)]=CMClass.getExit("Open");
										CMLib.database().DBUpdateExits(room.rawDoors()[dir]);
									}
									CMLib.database().DBUpdateExits(room);
								}
							}
						}
						break;
					}
				}
			}
		}
		super.unInvoke();
	}

	public boolean invoke(MOB mob, Vector commands, Environmental givenTarget, boolean auto, int asLevel)
	{
		if(commands.size()==0)
		{
			commonTell(mob,"Construct what, where? Try Construct list.");
			return false;
		}
		String str=(String)commands.elementAt(0);
		if(("LIST").startsWith(str.toUpperCase()))
		{
			StringBuffer buf=new StringBuffer(CMStrings.padRight("Item",20)+" Wood required\n\r");
			for(int r=0;r<data.length;r++)
			{
				if((r!=BUILD_SECRETDOOR)||(mob.charStats().getCurrentClass().baseClass().equals("Thief")))
                {
                    int wood=CMath.s_int(data[r][DAT_WOOD])-(int)Math.round((0.2*(double)super.getXPCOSTLevel(mob)));
					buf.append(CMStrings.padRight(data[r][DAT_NAME],20)+" "+wood+"\n\r");
                }
			}
			commonTell(mob,buf.toString());
			return true;
		}
		
		designTitle="";
		designDescription="";
		String startStr=null;
		int completion=35;
		doingCode=-1;
		workingOn=-1;
		dir=-1;

		room=null;
		messedUp=false;
		helpingAbility=null;

		if(str.equalsIgnoreCase("help"))
		{
			messedUp=!proficiencyCheck(mob,0,auto);
			completion=25;
			commands.removeElementAt(0);
			MOB targetMOB=getTarget(mob,commands,givenTarget,false,true);
			if(targetMOB==null) return false;
			if(targetMOB==mob)
			{
				commonTell(mob,"You can not do that.");
				return false;
			}
			helpingAbility=(CommonSkill)targetMOB.fetchEffect(ID());
			if(helpingAbility==null)
			{
				commonTell(mob,targetMOB.Name()+" is not constructing anything.");
				return false;
			}
			if(!super.invoke(mob,commands,givenTarget,auto,asLevel))
			{
				helpingAbility=null;
				return false;
			}
			helping=true;
			verb="helping "+targetMOB.name()+" with "+helpingAbility.name();
			startStr="<S-NAME> start(s) "+verb;
			CMMsg msg=CMClass.getMsg(mob,null,this,CMMsg.MSG_NOISYMOVEMENT,startStr+".");
			if(mob.location().okMessage(mob,msg))
			{
				mob.location().send(mob,msg);
				beneficialAffect(mob,mob,asLevel,completion);
			}
			return true;
		}
		
		String firstWord=(String)commands.firstElement();
		for(int r=0;r<data.length;r++)
		{
			if((data[r][0].toUpperCase().startsWith(firstWord.toUpperCase()))
			&&((r!=BUILD_SECRETDOOR)||(mob.charStats().getCurrentClass().baseClass().equals("Thief"))))
				doingCode=r;
		}
		if(doingCode<0)
		{
			commonTell(mob,"'"+firstWord+"' is not a valid construction project.  Try LIST.");
			return false;
		}
		String dirName=(String)commands.lastElement();
		dir=Directions.getGoodDirectionCode(dirName);
		if((doingCode==BUILD_DEMOLISH)&&(dirName.equalsIgnoreCase("roof")))
		   dir=-1;
		else
		if(((dir<0)||(dir>3))
		   &&(data[doingCode][DAT_REQDIR].equals("1")))
		{
			commonTell(mob,"A valid direction in which to build must also be specified.");
			return false;
		}
		if(data[doingCode][DAT_REQNONULL].equals("1")
		   &&(dir>=0)
		   &&(mob.location().getExitInDir(dir)==null))
		{
			commonTell(mob,"There is a wall that way that needs to be demolished first.");
			return false;
		}


		int woodRequired=CMath.s_int(data[doingCode][DAT_WOOD])-(int)Math.round((0.2*(double)super.getXPCOSTLevel(mob)));
		if(((mob.location().domainType()&Room.INDOORS)==0)
		   &&(data[doingCode][DAT_ROOF].equals("1")))
		{
			commonTell(mob,"That can only be built after a roof, which includes the frame.");
			return false;
		}
		else
		if(((mob.location().domainType()&Room.INDOORS)>0)
		   &&(data[doingCode][DAT_ROOF].equals("2")))
		{
			commonTell(mob,"That can only be built outdoors!");
			return false;
		}

        if(doingCode==BUILD_WALL)
        {
            Room nextRoom=mob.location().getRoomInDir(dir);
            if((nextRoom!=null)&&(CMLib.law().getLandTitle(nextRoom)==null))
            {
                commonTell(mob,"You can not build a wall blocking off the main entrance!");
                return false;
            }
        }
        
		if(doingCode==BUILD_TITLE)
		{
			String title=CMParms.combine(commands,1);
			if(title.length()==0)
			{
				commonTell(mob,"A title must be specified.");
				return false;
			}
    		Vector checkSet=CMLib.tracking().getRadiantRooms(mob.location(),false,false,false,false,false,20);
    		for(Enumeration r=checkSet.elements();r.hasMoreElements();)
    		{
    			Room R=CMLib.map().getRoom((Room)r.nextElement());
				if(R.displayText().equalsIgnoreCase(title))
				{
					commonTell(mob,"That title has already been taken.  Choose another.");
					return false;
				}
			}
			designTitle=title;
		}
		else
		if(doingCode==BUILD_DESC)
		{
			if(commands.size()<3)
			{
				commonTell(mob,"You must specify an exit direction or room, followed by a description for it.");
				return false;
			}
			if(Directions.getGoodDirectionCode((String)commands.elementAt(1))>=0)
			{
				dir=Directions.getGoodDirectionCode((String)commands.elementAt(1));
				if(mob.location().getExitInDir(dir)==null)
				{
					commonTell(mob,"There is no exit "+Directions.getInDirectionName(dir)+" to describe.");
					return false;
				}
				workingOn=dir;
				commands.removeElementAt(1);
			}
			else
			if(!((String)commands.elementAt(1)).equalsIgnoreCase("room"))
			{
				commonTell(mob,"'"+((String)commands.elementAt(1))+"' is neither the word room, nor an exit direction.");
				return false;
			}
			else
				commands.removeElementAt(1);

			String title=CMParms.combine(commands,1);
			if(title.length()==0)
			{
				commonTell(mob,"A description must be specified.");
				return false;
			}
			designDescription=title;
		}
		else
		if((doingCode==BUILD_WINDOW)||(doingCode==BUILD_CRAWLWAY))
			workingOn=dir;

		int[] pm={RawMaterial.MATERIAL_WOODEN};
		int[][] idata=fetchFoundResourceData(mob,
											woodRequired,"wood",pm,
											0,null,null,
											false,
											0,
											null);
		if(idata==null) return false;
		woodRequired=idata[0][FOUND_AMT];

		boolean canBuild=CMLib.law().doesOwnThisProperty(mob,mob.location());
		if(!canBuild)
		{
			if((dir>=0)
			&&((data[doingCode][DAT_REQDIR].equals("1")||(workingOn==dir))))
			{
				Room R=mob.location().getRoomInDir(dir);
				if((R!=null)&&(CMLib.law().doesOwnThisProperty(mob,R)))
					canBuild=true;
			}
		}
		if(!canBuild)
		{
			commonTell(mob,"You'll need the permission of the owner to do that.");
			return false;
		}

		if(!super.invoke(mob,commands,givenTarget,auto,asLevel))
			return false;

		room=mob.location();
		if(woodRequired>0)
			CMLib.materials().destroyResources(mob.location(),woodRequired,idata[0][FOUND_CODE],0,null);

		switch(doingCode)
		{
		case BUILD_ROOF:
			verb="building a frame and roof";
			break;
		case BUILD_WALL:
			verb="building the "+Directions.getDirectionName(dir)+" wall";
			break;
		case BUILD_FENCE:
			verb="building the "+Directions.getDirectionName(dir)+" fence";
			break;
		case BUILD_GATE:
			verb="building the "+Directions.getDirectionName(dir)+" gate";
			break;
		case BUILD_DOOR:
			verb="building the "+Directions.getDirectionName(dir)+" door";
			break;
		case BUILD_SECRETDOOR:
			verb="building a hidden "+Directions.getDirectionName(dir)+" door";
			break;
		case BUILD_WINDOW:
			verb="building a window "+Directions.getDirectionName(dir);
			break;
		case BUILD_CRAWLWAY:
			verb="building a crawlway "+Directions.getDirectionName(dir);
			break;
		case BUILD_TITLE:
			verb="giving this place a title";
			break;
		case BUILD_STAIRS:
			verb="building another floor";
			break;
		case BUILD_DESC:
			verb="giving this place a description";
			break;
		case BUILD_DEMOLISH:
		default:
			if(dir<0)
			{
				if((mob.location().domainType()==Room.DOMAIN_INDOORS_WATERSURFACE)
				   ||(mob.location().domainType()==Room.DOMAIN_OUTDOORS_WATERSURFACE))
						verb="demolishing the pool";
				else
				if((mob.location().domainType()==Room.DOMAIN_INDOORS_UNDERWATER)
				   ||(mob.location().domainType()==Room.DOMAIN_OUTDOORS_UNDERWATER))
				{
					commonTell(mob,null,null,"You must demolish a pool from above.");
					return false;
				}
				else
				if(mob.location().domainType()!=Room.DOMAIN_INDOORS_WOOD)
				{
					commonTell(mob,null,null,"There are no wooden constructs to demolish here!");
					return false;
				}
				else
					verb="demolishing the roof";
			}
			else
				verb="demolishing the "+Directions.getDirectionName(dir)+" wall";
			break;
		}
		messedUp=!proficiencyCheck(mob,0,auto);
		startStr="<S-NAME> start(s) "+verb;
        playSound="hammer.wav";
		if(completion<25) completion=25;

		CMMsg msg=CMClass.getMsg(mob,null,this,CMMsg.MSG_NOISYMOVEMENT,startStr+".");
		if(mob.location().okMessage(mob,msg))
		{
			mob.location().send(mob,msg);
			beneficialAffect(mob,mob,asLevel,completion);
		}
		return true;
	}
}