<NME> Sense.java
<BEF> package com.planet_ink.coffee_mud.Libraries;
import com.planet_ink.coffee_mud.core.interfaces.*;
import com.planet_ink.coffee_mud.core.*;
import com.planet_ink.coffee_mud.core.Directions.DirType;
import com.planet_ink.coffee_mud.core.collections.*;
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.Common.interfaces.Faction.Align;
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.*;

import com.planet_ink.coffee_mud.Libraries.interfaces.*;

/*
   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 Sense extends StdLibrary implements CMFlagLibrary
{
	@Override
	public String ID()
	{
		return "Sense";
	}

	@Override
	public boolean canSee(final MOB M)
	{
		return (M != null) && (!isSleeping(M)) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_SEE) == 0);
	}

	@Override
	public boolean canBeLocated(final Physical P)
	{
		if(P instanceof MOB)
			return true;
		else
		if ((P != null)
		&& (!isSleeping(P))
		&& ((P.phyStats().sensesMask() & PhyStats.SENSE_UNLOCATABLE) == 0))
		{
			if ((P instanceof Item) && (((Item) P).container() != null))
				return canBeLocated(((Item) P).container());
			return true;
		}
		return false;
	}

	@Override
	public boolean canSeeHidden(final MOB M)
	{
		return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_HIDDEN) == PhyStats.CAN_SEE_HIDDEN);
	}

	@Override
	public boolean canSeeHiddenItems(final MOB M)
	{
		return (M != null)
			&& (((M.phyStats().sensesMask() & PhyStats.CAN_SEE_HIDDEN_ITEMS) == PhyStats.CAN_SEE_HIDDEN_ITEMS)
				||((M.phyStats().sensesMask() & PhyStats.CAN_SEE_HIDDEN) == PhyStats.CAN_SEE_HIDDEN));
	}

	@Override
	public boolean canSeeInvisible(final MOB M)
	{
		return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_INVISIBLE) == PhyStats.CAN_SEE_INVISIBLE);
	}

	@Override
	public boolean canSeeEvil(final MOB M)
	{
		return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_EVIL) == PhyStats.CAN_SEE_EVIL);
	}

	@Override
	public boolean canSeeGood(final MOB M)
	{
		return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_GOOD) == PhyStats.CAN_SEE_GOOD);
	}

	@Override
	public boolean canSeeChaos(final Physical P)
	{
		return (P != null) && P.phyStats().isAmbiance("@CHAOS");
	}

	@Override
	public boolean canSeeLaw(final Physical P)
	{
		return (P != null) && P.phyStats().isAmbiance("@LAW");
	}

	@Override
	public boolean canSeeSneakers(final MOB M)
	{
		return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_SNEAKERS) == PhyStats.CAN_SEE_SNEAKERS);
	}

	@Override
	public boolean canSeeBonusItems(final MOB M)
	{
		return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_BONUS) == PhyStats.CAN_SEE_BONUS);
	}

	@Override
	public boolean canSeeInDark(final MOB M)
	{
		return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_DARK) == PhyStats.CAN_SEE_DARK);
	}

	@Override
	public boolean canSeeVictims(final MOB M)
	{
		return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_VICTIM) == PhyStats.CAN_SEE_VICTIM);
	}

	@Override
	public boolean canSeeInfrared(final MOB M)
	{
		return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_INFRARED) == PhyStats.CAN_SEE_INFRARED);
	}

	@Override
	public boolean canHear(final MOB M)
	{
		return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_HEAR) == 0);
	}

	@Override
	public boolean canTrack(final Physical P)
	{
		return (P != null) && ((P.phyStats().sensesMask() & PhyStats.CAN_NOT_TRACK) == 0);
	}

	@Override
	public boolean canAutoAttack(final MOB M)
	{
		return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_AUTO_ATTACK) == 0);
	}

	@Override
	public boolean canConcentrate(final MOB M)
	{
		return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_THINK) == 0);
	}

	@Override
	public boolean canMove(final MOB M)
	{
		return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_MOVE) == 0);
	}

	@Override
	public boolean allowsMovement(final Room R)
	{
		return (R != null) && ((R.phyStats().sensesMask() & PhyStats.SENSE_ROOMNOMOVEMENT) == 0);
	}

	@Override
	public boolean allowsMovement(final Area A)
	{
		return (A != null) && ((A.phyStats().sensesMask() & PhyStats.SENSE_ROOMNOMOVEMENT) == 0);
	}

	@Override
	public boolean canSmell(final MOB M)
	{
		return canBreatheHere(M, M.location()) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_SMELL) == 0);
	}

	@Override
	public boolean canTaste(final MOB M)
	{
		return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_TASTE) == 0);
	}

	@Override
	public boolean canSpeak(final MOB M)
	{
		return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_SPEAK) == 0);
	}

	@Override
	public boolean canBreathe(final MOB M)
	{
		return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_BREATHE) == 0);
	}

	@Override
	public boolean canNotBeCamped(final Physical P)
	{
		return (P != null) && ((P.phyStats().sensesMask() & PhyStats.CAN_NOT_BE_CAMPED) != 0);
	}

	@Override
	public boolean canBreatheThis(final MOB M, final int atmoResource)
	{
		return (canBreathe(M)
				&&((atmoResource<0)
					||(M.charStats().getBreathables().length==0)
					||(Arrays.binarySearch(M.charStats().getBreathables(), atmoResource)>=0)));
	}

	@Override
	public boolean canBreatheHere(final MOB M, final Room R)
	{
		return (M != null) && (canBreatheThis(M, (R == null) ? -1 : R.getAtmosphere()));
	}

	@Override
	public boolean canSeeMetal(final MOB M)
	{
		return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_METAL) == PhyStats.CAN_SEE_METAL);
	}

	@Override
	public boolean isReadable(final Item I)
	{
		return (I != null) && ((I.phyStats().sensesMask() & PhyStats.SENSE_ITEMREADABLE) == PhyStats.SENSE_ITEMREADABLE);
	}

	@Override
	public boolean isGettable(final Item I)
	{
		return (I != null) && ((I.phyStats().sensesMask() & PhyStats.SENSE_ITEMNOTGET) == 0);
	}

	@Override
	public boolean isDroppable(final Item I)
	{
		return (I != null) && ((I.phyStats().sensesMask() & PhyStats.SENSE_ITEMNODROP) == 0);
	}

	@Override
	public boolean isRemovable(final Item I)
	{
		return (I != null) && ((I.phyStats().sensesMask() & PhyStats.SENSE_ITEMNOREMOVE) == 0);
	}

	@Override
	public boolean isCataloged(final Environmental E)
	{
		return (E instanceof Physical)
				&& ((((Physical) E).basePhyStats().disposition() & PhyStats.IS_CATALOGED) == PhyStats.IS_CATALOGED);
	}

	@Override
	public Rideable.Basis getNavRideBasis(final Environmental E)
	{
		if(E instanceof NavigableItem)
			return ((NavigableItem)E).navBasis();
		if((E instanceof Boardable)&&(((Boardable)E).getBoardableItem()!=E))
			return getNavRideBasis(((Boardable)E).getBoardableItem());
		if(E instanceof Room)
			return getNavRideBasis(((Room)E).getArea());
		return null;
	}

	private Room roomLocation(final Environmental E)
	{
		if(E==null)
			return null;
		if((E instanceof Area)&&(!((Area)E).isProperlyEmpty()))
			return ((Area)E).getRandomProperRoom();
		else
		if(E instanceof Room)
			return (Room)E;
		else
		if(E instanceof MOB)
			return ((MOB)E).location();
		else
		if((E instanceof Item)&&(((Item)E).owner() instanceof Room))
			return (Room)((Item)E).owner();
		else
		if((E instanceof Item)&&(((Item)E).owner() instanceof MOB))
			return ((MOB)((Item)E).owner()).location();
		else
		if(E instanceof Ability)
			return roomLocation(((Ability)E).affecting());
		else
		if(E instanceof Exit)
			return roomLocation(((Exit)E).lastRoomUsedFrom(null));
		return null;
	}

	@Override
	public boolean isWithSeenContents(final Physical P)
	{
		return (P != null)
			&&((P instanceof MOB)
				||((P.phyStats().sensesMask() & PhyStats.SENSE_CONTENTSUNSEEN) == 0));
	}

	@Override
	public boolean isSavable(final Physical P)
	{
		if((P==null)||((P.phyStats().disposition()&PhyStats.IS_UNSAVABLE)==0))
		{
			if((P instanceof Item)
			&&(((Item)P).container()!=null)
			&&(((Item)P).container()!=P))
				return isSavable(((Item)P).container());
			return true;
		}
		return false;
	}

	@Override
	public void setSavable(final Physical P, final boolean truefalse)
	{
		if(P==null)
			return;
		if(CMath.bset(P.basePhyStats().disposition(),PhyStats.IS_UNSAVABLE))
		{
			if(truefalse)
			{
				P.basePhyStats().setDisposition(CMath.unsetb(P.basePhyStats().disposition(),PhyStats.IS_UNSAVABLE));
				P.phyStats().setDisposition(CMath.unsetb(P.phyStats().disposition(),PhyStats.IS_UNSAVABLE));
			}
		}
		else
		if(!truefalse)
		{
			P.basePhyStats().setDisposition(CMath.setb(P.basePhyStats().disposition(),PhyStats.IS_UNSAVABLE));
			P.phyStats().setDisposition(CMath.setb(P.phyStats().disposition(),PhyStats.IS_UNSAVABLE));
		}
	}

	@Override
	public void setReadable(final Item I, final boolean truefalse)
	{
		if(I==null)
			return;
		if(CMath.bset(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMREADABLE))
		{
			if(!truefalse)
			{
				I.basePhyStats().setSensesMask(CMath.unsetb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMREADABLE));
				I.phyStats().setSensesMask(CMath.unsetb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMREADABLE));
			}
		}
		else
		if(truefalse)
		{
			I.basePhyStats().setSensesMask(CMath.setb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMREADABLE));
			I.phyStats().setSensesMask(CMath.setb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMREADABLE));
		}
	}

	@Override
	public boolean isEnspelled(final Physical F)
	{
		for(int a=0;a<F.numEffects();a++) // personal affects
		{
			final Ability A=F.fetchEffect(a);
			if((A!=null)&&(A.canBeUninvoked())&&(!A.isAutoInvoked())&&(!A.isSavable())
			&&(((A.classificationCode()&Ability.ALL_ACODES)==Ability.ACODE_SPELL)
			   ||((A.classificationCode()&Ability.ALL_ACODES)==Ability.ACODE_PRAYER)
			   ||((A.classificationCode()&Ability.ALL_ACODES)==Ability.ACODE_CHANT)
			   ||((A.classificationCode()&Ability.ALL_ACODES)==Ability.ACODE_SONG)))
				return true;
		}
		return false;
	}

	@Override
	public void setGettable(final Item I, final boolean truefalse)
	{
		if(I==null)
			return;
		if(!CMath.bset(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNOTGET))
		{
			if(!truefalse)
			{
				I.basePhyStats().setSensesMask(CMath.setb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNOTGET));
				I.phyStats().setSensesMask(CMath.setb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMNOTGET));
			}
		}
		else
		if(truefalse)
		{
			I.basePhyStats().setSensesMask(CMath.unsetb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNOTGET));
			I.phyStats().setSensesMask(CMath.unsetb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMNOTGET));
		}
	}

	@Override
	public void setDroppable(final Item I, final boolean truefalse)
	{
		if(I==null)
			return;
		if(!CMath.bset(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNODROP))
		{
			if(!truefalse)
			{
				I.basePhyStats().setSensesMask(CMath.setb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNODROP));
				I.phyStats().setSensesMask(CMath.setb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMNODROP));
			}
		}
		else
		if(truefalse)
		{
			I.basePhyStats().setSensesMask(CMath.unsetb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNODROP));
			I.phyStats().setSensesMask(CMath.unsetb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMNODROP));
		}
	}

	@Override
	public void setRemovable(final Item I, final boolean truefalse)
	{
		if(I==null)
			return;
		if(!CMath.bset(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNOREMOVE))
		{
			if(!truefalse)
			{
				I.basePhyStats().setSensesMask(CMath.setb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNOREMOVE));
				I.phyStats().setSensesMask(CMath.setb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMNOREMOVE));
			}
		}
		else
		if(truefalse)
		{
			I.basePhyStats().setSensesMask(CMath.unsetb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNOREMOVE));
			I.phyStats().setSensesMask(CMath.unsetb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMNOREMOVE));
		}
	}

	@Override
	public boolean isSeeable(final Physical P)
	{
		return (P!=null)&&(((P.phyStats().disposition()&PhyStats.IS_NOT_SEEN)==0) || isSleeping(P));
	}

	@Override
	public boolean isCloaked(final Physical P)
	{
		return (P!=null)&&((P.phyStats().disposition()&PhyStats.IS_CLOAKED)==PhyStats.IS_CLOAKED);
	}

	@Override
	public boolean isHidden(final Physical P)
	{
		if(P==null)
			return false;
		final boolean isInHide=((P.phyStats().disposition()&PhyStats.IS_HIDDEN)==PhyStats.IS_HIDDEN);
		if((P instanceof MOB)
		&&(isInHide)
		&&(((MOB)P).isInCombat()))
			return false;
		return isInHide;
	}

	@Override
	public boolean isUndead(final MOB mob)
	{
		return (mob != null)
				&& CMProps.getListFileVarSet(CMProps.ListFile.RACIAL_CATEGORY_IS_UNDEAD).contains(mob.charStats().getMyRace().racialCategory());
	}

	@Override
	public boolean isEggLayer(final Race race)
	{
		final String[] eggLayers = new String[]
		{
			"Amphibian",
			"Avian",
			"Dragon",
			"Reptile",
			"Ophidian",
			"Fish"
		};
		return (race == null) ? false : CMStrings.containsIgnoreCase(eggLayers, race.racialCategory());
	}

	@Override
	public boolean isFish(final MOB mob)
	{
		return (mob != null)
				&& CMProps.getListFileVarSet(CMProps.ListFile.RACIAL_CATEGORY_IS_FISH).contains(mob.charStats().getMyRace().racialCategory());
	}

	@Override
	public boolean isMarine(final MOB mob)
	{
		return (mob != null)
				&& CMProps.getListFileVarSet(CMProps.ListFile.RACIAL_CATEGORY_IS_MARINE).contains(mob.charStats().getMyRace().racialCategory());
	}

	@Override
	public boolean isOutsider(final MOB mob)
	{
		return (mob != null)
				&& CMProps.getListFileVarSet(CMProps.ListFile.RACIAL_CATEGORY_IS_OUTSIDER).contains(mob.charStats().getMyRace().racialCategory());
	}

	@Override
	public boolean isInsect(final MOB mob)
	{
		return (mob != null)
				&& CMProps.getListFileVarSet(CMProps.ListFile.RACIAL_CATEGORY_IS_INSECT).contains(mob.charStats().getMyRace().racialCategory());
	}

	@Override
	public boolean isVermin(final MOB mob)
	{
		return (mob != null)
				&& CMProps.getListFileVarSet(CMProps.ListFile.RACIAL_CATEGORY_IS_VERMIN).contains(mob.charStats().getMyRace().racialCategory());
	}

	@Override
	public boolean isAPlant(final Item I)
	{
		return (I!=null) && ((I.material()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_VEGETATION);
	}

	@Override
	public boolean isAPlant(final MOB M)
	{
		if(isGolem(M) && (M!=null) && (M.charStats()!=null) && (M.charStats().getMyRace()!=null))
		{
			final List<RawMaterial> mats = M.charStats().getMyRace().myResources();
			for(final Item I : mats)
			{
				if(((I.material()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_VEGETATION)
				||((I.material()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_WOODEN))
					return true;
			}
			return false;
		}
		return false;
	}

	@Override
	public boolean isUnattackable(final Physical P)
	{
		return (P!=null)&&((P.phyStats().disposition()&PhyStats.IS_UNATTACKABLE)==PhyStats.IS_UNATTACKABLE);
	}

	@Override
	public boolean isInvisible(final Physical P)
	{
		return (P!=null)&&((P.phyStats().disposition()&PhyStats.IS_INVISIBLE)==PhyStats.IS_INVISIBLE);
	}

	@Override
	public boolean isRejuvingItem(final Item I)
	{
		if(I==null)
			return false;
		for(int i=0;i<I.numEffects();i++)
		{
			if(I.fetchEffect(i) instanceof ItemTicker)
				return true;
		}
		return false;
	}

	@Override
	public boolean isReallyEvil(final FactionMember M)
	{
		if(M != null)
		{
			Faction F=null;
			Faction.FRange FR=null;
			for(final Enumeration<String> e=M.factions();e.hasMoreElements();)
			{
				F=CMLib.factions().getFaction(e.nextElement());
				if(F!=null)
				{
					FR=CMLib.factions().getRange(F.factionID(),M.fetchFaction(F.factionID()));
					if((FR!=null)&&(FR.alignEquiv()==Faction.Align.EVIL))
						return true;
				}
			}
		}
		return false;
	}

	@Override
	public boolean isEvil(final Physical P)
	{
		if(P==null)
			return false;
		if ((P.phyStats().disposition()&PhyStats.IS_EVIL)==PhyStats.IS_EVIL)
			return ((P.phyStats().disposition()&PhyStats.IS_GOOD)==0);
		else
		if(P instanceof FactionMember)
			return isReallyEvil((FactionMember)P);
		return false;
	}

	@Override
	public boolean isOpenAccessibleContainer(final Item I)
	{
		return (I instanceof Container)
			 &&(CMath.bset(I.phyStats().sensesMask(), PhyStats.SENSE_INSIDEACCESSIBLE))
			 &&((Container)I).isOpen();
	}

	@Override
	public boolean isTracking(final MOB M)
	{
		if(M!=null)
			return flaggedAffects(M,Ability.FLAG_TRACKING).size()>0;
		return false;
	}

	@Override
	public boolean isATrackingMonster(final MOB M)
	{
		if(M==null)
			return false;
		if(M.isMonster())
			return flaggedAffects(M,Ability.FLAG_TRACKING).size()>0;
		return false;
	}

	@Override
	public boolean isReallyGood(final FactionMember M)
	{
		if(M != null)
		{
			Faction F=null;
			Faction.FRange FR=null;
			for(final Enumeration<String> e=M.factions();e.hasMoreElements();)
			{
				F=CMLib.factions().getFaction(e.nextElement());
				if(F!=null)
				{
					FR=CMLib.factions().getRange(F.factionID(),M.fetchFaction(F.factionID()));
					if((FR!=null)&&(FR.alignEquiv()==Faction.Align.GOOD))
						return true;
				}
			}
		}
		return false;
	}

	@Override
	public String getPlaneOfExistence(final Physical P)
	{
		final Area A=CMLib.map().areaLocation(P);
		if((A!=null)
		&&(A.numEffects()>0))
		{
			for(final Enumeration<Ability> a=A.effects();a.hasMoreElements();)
			{
				final Ability eA=a.nextElement();
				if((eA instanceof PlanarAbility)
				&&(eA.text().length()>0))
					return eA.text();
			}
		}
		return null;
	}

	@Override
	public String getAge(final MOB M)
	{
		final Ability A=M.fetchEffect("Age");
		if((A==null)||(A.displayText().length()==0))
		{
			if(M.baseCharStats().getStat(CharStats.STAT_AGE)==0)
				return "unknown";
			return L("@x1 year(s) old",""+M.baseCharStats().getStat(CharStats.STAT_AGE));
		}
		else
		{
			String s=A.displayText();
			if(s.startsWith("("))
				s=s.substring(1);
			if(s.endsWith(")"))
				s=s.substring(0,s.length()-1);
			return s;
		}
	}

	@Override
	public boolean isGood(final Physical P)
	{
		if(P==null)
			return false;
		if ((P.phyStats().disposition()&PhyStats.IS_GOOD)==PhyStats.IS_GOOD)
			return ((P.phyStats().disposition()&PhyStats.IS_EVIL)==0);
		else
		if(P instanceof FactionMember)
			return isReallyGood((FactionMember)P);
		return false;
	}

	@Override
	public boolean isLawful(final Physical P)
	{
		if((P != null) && (P.phyStats().isAmbiance("#LAW")))
			return true;
		if(P instanceof FactionMember)
		{
			Faction F=null;
			Faction.FRange FR=null;
			final FactionMember M=(FactionMember)P;
			for(final Enumeration<String> e=M.factions();e.hasMoreElements();)
			{
				F=CMLib.factions().getFaction(e.nextElement());
				if(F!=null)
				{
					FR=CMLib.factions().getRange(F.factionID(),M.fetchFaction(F.factionID()));
					if((FR!=null)&&(FR.alignEquiv()==Faction.Align.LAWFUL))
						return true;
				}
			}
		}
		return false;
	}

	@Override
	public boolean isChaotic(final Physical P)
	{
		if((P != null) && (P.phyStats().isAmbiance("#CHAOS")))
			return true;
		if(P instanceof FactionMember)
		{
			Faction F=null;
			Faction.FRange FR=null;
			final FactionMember M=(FactionMember)P;
			for(final Enumeration<String> e=M.factions();e.hasMoreElements();)
			{
				F=CMLib.factions().getFaction(e.nextElement());
				if(F!=null)
				{
					FR=CMLib.factions().getRange(F.factionID(),M.fetchFaction(F.factionID()));
					if((FR!=null)&&(FR.alignEquiv()==Faction.Align.CHAOTIC))
						return true;
				}
			}
		}
		return false;
	}

	@Override
	public boolean isModerate(final Physical P)
	{
		if((P != null) && (P.phyStats().isAmbiance("#MODERATE")))
			return true;
		if(P instanceof FactionMember)
		{
			Faction F=null;
			Faction.FRange FR=null;
			final FactionMember M=(FactionMember)P;
			for(final Enumeration<String> e=M.factions();e.hasMoreElements();)
			{
				F=CMLib.factions().getFaction(e.nextElement());
				if(F!=null)
				{
					FR=CMLib.factions().getRange(F.factionID(),M.fetchFaction(F.factionID()));
					if((FR!=null)&&(FR.alignEquiv()==Faction.Align.MODERATE))
						return true;
				}
			}
		}
		return false;
	}

	@Override
	public boolean isTrapped(final Physical P)
	{
		for(final Enumeration<Ability> a=P.effects();a.hasMoreElements();)
		{
			final Ability A=a.nextElement();
			if((A instanceof Trap))
				return true;
		}
		return false;
	}

	@Override
	public boolean isDeadlyOrMaliciousEffect(final PhysicalAgent P)
	{
		if(P==null)
			return false;
		if(flaggedBehaviors(P, Behavior.FLAG_POTENTIALLYAUTODEATHING).size()>0)
			return true;
		if(isTrapped(P))
			return true;
		for(final Enumeration<Ability> a=P.effects();a.hasMoreElements();)
		{
			final Ability A=a.nextElement();
			if((A instanceof AbilityContainer)
			&&((A.classificationCode()&Ability.ALL_ACODES)==Ability.ACODE_PROPERTY))
			{
				final AbilityContainer U=(AbilityContainer)A;
				for(final Enumeration<Ability> e=U.allAbilities();e.hasMoreElements();)
				{
					final Ability uA=e.nextElement();
					if((uA!=null)&&(uA.abstractQuality()==Ability.QUALITY_MALICIOUS))
						return true;
				}
			}
		}
		return false;
	}

	@Override
	public boolean isPossiblyAggressive(final MOB M)
	{
		if(M==null)
			return false;
		final List<Behavior> V=flaggedBehaviors(M,Behavior.FLAG_POTENTIALLYAGGRESSIVE);
		return ((V==null)||(V.size()==0))? false:true;
	}

	@Override
	public boolean isAggressiveTo(final MOB M, final MOB toM)
	{
		if((M==null)||(toM==null))
			return false;
		final List<Behavior> V=flaggedBehaviors(M,Behavior.FLAG_POTENTIALLYAGGRESSIVE);
		if((V==null)||(V.size()==0))
			return false;
		for(final Behavior B : V)
		{
			if(B.grantsAggressivenessTo(toM))
				return true;
		}
		return false;
	}

	@Override
	public String getAlignmentName(final Environmental E)
	{
		if(E instanceof Physical)
		{
			if((((Physical)E).phyStats().disposition()&PhyStats.IS_GOOD)==PhyStats.IS_GOOD)
				return Faction.Align.GOOD.toString();
			if((((Physical)E).phyStats().disposition()&PhyStats.IS_EVIL)==PhyStats.IS_EVIL)
				return Faction.Align.EVIL.toString();
			if(((Physical)E).phyStats().isAmbiance("#GOOD"))
				return Faction.Align.GOOD.toString();
			if(((Physical)E).phyStats().isAmbiance("#EVIL"))
				return Faction.Align.EVIL.toString();
		}
		if(E instanceof MOB)
		{
			Faction F=null;
			Faction.FRange FR=null;
			for(final Enumeration<String> e=((MOB)E).factions();e.hasMoreElements();)
			{
				F=CMLib.factions().getFaction(e.nextElement());
				if(F!=null)
				{
					FR=CMLib.factions().getRange(F.factionID(),((MOB)E).fetchFaction(F.factionID()));
					if((FR!=null)&&((FR.alignEquiv()==Align.GOOD)||(FR.alignEquiv()==Align.EVIL)))
						return FR.alignEquiv().toString();
				}
			}
		}
		return Faction.Align.NEUTRAL.toString();
	}

	@Override
	public boolean isReallyNeutral(final FactionMember M)
	{
		if(M != null)
		{
			Faction F=null;
			Faction.FRange FR=null;
			for(final Enumeration<String> e=M.factions();e.hasMoreElements();)
			{
				F=CMLib.factions().getFaction(e.nextElement());
				if(F!=null)
				{
					FR=CMLib.factions().getRange(F.factionID(),M.fetchFaction(F.factionID()));
					if(FR!=null)
					switch(FR.alignEquiv())
					{
						case NEUTRAL:
							return true;
						case EVIL:
							return false;
						case GOOD:
							return false;
						default:
							continue;
					}
				}
			}
		}
		return true;
	}

	@Override
	public boolean isNeutral(final Physical P)
	{
		if(P==null)
			return false;
		if((P.phyStats().disposition()&PhyStats.IS_GOOD)==PhyStats.IS_GOOD)
		{
			if((P.phyStats().disposition()&PhyStats.IS_EVIL)==PhyStats.IS_EVIL)
				return true;
			return false;
		}
		else
		if((P.phyStats().disposition()&PhyStats.IS_EVIL)==PhyStats.IS_EVIL)
			return false;
		else
		if(P instanceof FactionMember)
			return isReallyNeutral((FactionMember)P);
		return true;
	}

	@Override
	public boolean isSneaking(final Physical P)
	{
		return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_SNEAKING) == PhyStats.IS_SNEAKING);
	}

	@Override
	public boolean isABonusItems(final Physical P)
	{
		return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_BONUS) == PhyStats.IS_BONUS);
	}

	@Override
	public boolean isInDark(final Physical P)
	{
		return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_DARK) == PhyStats.IS_DARK);
	}

	@Override
	public boolean isLightSource(final Physical P)
	{
		return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_LIGHTSOURCE) == PhyStats.IS_LIGHTSOURCE);
	}

	@Override
	public boolean isGlowing(final Physical P)
	{
		return (P != null) && ((isLightSource(P) || ((P.phyStats().disposition() & PhyStats.IS_GLOWING) == PhyStats.IS_GLOWING)));
	}

	@Override
	public boolean isGolem(final Physical P)
	{
		return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_GOLEM) == PhyStats.IS_GOLEM);
	}

	@Override
	public boolean isSleeping(final Physical P)
	{
		return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_SLEEPING) == PhyStats.IS_SLEEPING);
	}

	@Override
	public boolean isSitting(final Physical P)
	{
		return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_SITTING) == PhyStats.IS_SITTING);
	}

	@Override
	public boolean isFlying(final Physical P)
	{
		return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_FLYING) == PhyStats.IS_FLYING);
	}

	@Override
	public boolean isClimbing(final Physical P)
	{
		return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_CLIMBING) == PhyStats.IS_CLIMBING);
	}

	@Override
	public boolean isCrawlable(final Physical P)
	{
		if((P instanceof Room)||(P instanceof Area)||(P instanceof Exit))
			return (P.phyStats().sensesMask() & PhyStats.SENSE_ROOMCRUNCHEDIN) == PhyStats.SENSE_ROOMCRUNCHEDIN;
		return false;
	}

	@Override
	public boolean isSwimming(final Physical P)
	{
		return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_SWIMMING) == PhyStats.IS_SWIMMING);
	}

	@Override
	public boolean isFalling(final Physical P)
	{
		return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_FALLING) == PhyStats.IS_FALLING);
	}

	@Override
	public int getFallingDirection(final Physical P)
	{
		if(!isFalling(P))
			return -1;
		final Ability A=P.fetchEffect("Falling");
		if((A!=null) && (CMath.s_bool(A.getStat("REVERSED"))))
			return Directions.UP;
		return Directions.DOWN;
	}

	@Override
	public boolean isRunningLongCommand(final MOB M)
	{
		return (M != null)
			&& (M.session() != null)
			&& ((System.currentTimeMillis() - M.session().getInputLoopTime()) > 30000);
	}

	@Override
	public boolean isSwimmingInWater(final Physical P)
	{
		if(!isSwimming(P))
			return false;
		return isWateryRoom(roomLocation(P));
	}

	@Override
	public boolean isInWilderness(final Physical P)
	{
		if(P instanceof MOB)
			return isInWilderness(((MOB)P).location());
		else
		if(P instanceof Item)
			return isInWilderness(((Item)P).owner());
		else
		if(P instanceof Room)
		{
				ownerCheck=owner.isContent(I);
			}
			if(!ownerCheck)
				return I.name()+" is not where it is: "+owner.name();
			if(owner instanceof MOB)
			{
				final MOB M=(MOB)owner;
			return false;
	}

	@Override
	public boolean isACityRoom(final Physical P)
	{
		if(P instanceof MOB)
			return isACityRoom(((MOB)P).location());
		else
		if(P instanceof Item)
			return isACityRoom(((Item)P).owner());
		else
		if(P instanceof Room)
		{
			switch(((Room)P).domainType())
			{
			case Room.DOMAIN_OUTDOORS_CITY:
				return true;
			case Room.DOMAIN_OUTDOORS_SPACEPORT:
				return true;
			case Room.DOMAIN_OUTDOORS_UNDERWATER:
				if((P.phyStats().weight()>2)&&(P.maxRange()>4))
					return true;
				return false;
			case Room.DOMAIN_INDOORS_STONE:
				if((P.phyStats().weight()>2)&&(P.maxRange()>4))
					return true;
				return false;
			default:
				return false;
			}
		}
		else
			return false;
	}

	@Override
	public boolean canBeHeardMovingBy(final Physical heard , final MOB hearer)
	{
		if(hearer==heard)
			return true;
		if(hearer==null)
			return false;
		if(heard==null)
			return false;
		if((!isSeeable(heard))&&(isCloaked(heard)))
		{
			if((!(heard instanceof MOB))
			||(heard.phyStats().level()>hearer.phyStats().level())
			||(!CMSecurity.isASysOp(hearer)))
				return false;
		}
		if(!canHear(hearer))
			return false;
		if(isSneaking(heard)&&(!canSeeSneakers(hearer)))
			return false;
		return true;
	}

	@Override
	public boolean canBeHeardSpeakingBy(final Physical heard , final MOB hearer)
	{
		if(hearer==heard)
			return true;
		if(hearer==null)
			return false;
		if(heard==null)
			return false;
		if(!canHear(hearer))
			return false;
		return true;
	}

	@Override
	public boolean canSenseMoving(final Physical sensed, final MOB sensor)
	{
		return (canBeHeardMovingBy(sensed,sensor)||canBeSeenBy(sensed,sensor));
	}

	@Override
	public boolean canSenseEnteringLeaving(final Physical sensed, final MOB sensor)
	{
		return canBeHeardMovingBy(sensed,sensor);
	}

	@Override
	public String validCheck(final Physical P)
	{
		if(P instanceof Room)
		{
			final Room R=(Room)P;
			if(R.amDestroyed())
				return " a destroyed place: "+CMLib.map().getExtendedRoomID(R);
			final Area A=R.getArea();
			if((A == null)||(A.amDestroyed()))
				return "a destroyed area: "+CMLib.map().getExtendedRoomID(R);
			return null;
		}
		if(P instanceof MOB)
		{
			final MOB M=(MOB)P;
			final Room locR;
			final Room startR;
			synchronized(M)
			{
				startR=M.getStartRoom();
				locR=M.location();
			}
			if(M.amDestroyed())
				return M.name()+" is destroyed";
			if(startR!=null)
			{
				final String roomReport =validCheck(startR);
				if(roomReport != null)
					return M.name()+" is from "+roomReport;
			}
			if(!M.amDead())
			{
				if(locR == null)
					return "*"+M.name()+" is nowhere!";
				final MOB ultFol = M.amUltimatelyFollowing();
				if(!locR.isInhabitant(M)
				&&(!M.isPlayer())
				&&((ultFol==null)||(!ultFol.isPlayer())))
					return "*"+M.name()+" is not where he is: "+CMLib.map().getExtendedRoomID(locR);
				final String roomReport =validCheck(locR);
				if(roomReport != null)
					return M.name()+" is from "+roomReport;
			}
			return null;
		}
		if(P instanceof Item)
		{
			final Item I=(Item)P;
			final ItemPossessor owner;
			synchronized(I)
			{
				owner=I.owner();
			}
			if(I.amDestroyed())
				return I.name()+" is destroyed";
			if(owner == null)
			{
				if((I instanceof SpaceObject)
				&&(CMLib.space().isObjectInSpace((SpaceObject)I)))
					return null;
				return I.name()+" is unowned.";
			}
			final boolean ownerCheck;
			synchronized(owner)
			{
				ownerCheck=owner.isContent(I);
			}
			if(!ownerCheck)
				return I.name()+" is not where it is: "+owner.name()+" ("+owner.ID()+"): "+CMLib.map().getExtendedRoomID(CMLib.map().roomLocation(owner));
			if(owner instanceof MOB)
			{
				final MOB M=(MOB)owner;
				if((!M.isPlayer())
				&& (!CMLib.threads().isTicking(M, -1))
				&& ((M.amUltimatelyFollowing()==null)||(!M.amUltimatelyFollowing().isPlayer())))
					return I.name()+" on non-ticking mob: "+M.name()+", in: "+CMLib.map().getExtendedRoomID(M.location());
				final String mobReport = validCheck(M);
				if(mobReport != null)
				{
					if(mobReport.startsWith("*"))
						return "*"+I.name()+" on "+mobReport.substring(1);
					else
						return I.name()+" on "+mobReport;
				}
			}
			if(owner instanceof Room)
			{
				final String roomReport = validCheck(owner);
				if(roomReport != null)
					return I.name()+" in "+roomReport;
			}
			return null;
		}
		return null;
	}

	@Override
	public boolean isAliveAwakeMobileUnbound(final MOB mob, final boolean quiet)
	{
		if(!isAliveAwakeMobile(mob,quiet))
			return false;
		if(isBound(mob))
		{
			if(!quiet)
				mob.tell(L("You are bound!"));
			return false;
		}
		if(isBoundOrHeld(mob))
		{
			if(!quiet)
				mob.tell(L("You can't move!"));
			return false;
		}
		return true;
	}

	@Override
	public boolean isAliveAwakeMobile(final MOB mob, final boolean quiet)
	{
		if(mob==null)
			return false;
		if(quiet)
		{
			if(mob.amDead()
			||(mob.curState().getHitPoints()<0)
			||((mob.phyStats().disposition()&PhyStats.IS_SLEEPING)!=0)
			||((mob.phyStats().sensesMask()&PhyStats.CAN_NOT_MOVE)!=0))
				return false;
			return true;
		}
		if(mob.amDead()||(mob.curState().getHitPoints()<0))
		{
			mob.tell(L("You are DEAD!"));
			return false;
		}
		if(isSleeping(mob))
		{
			mob.tell(L("You are sleeping!"));
			return false;
		}
		if(!canMove(mob))
		{
			mob.tell(L("You can't move!"));
			return false;
		}
		return true;
	}

	@Override
	public boolean isStanding(final MOB mob)
	{
		return (!isSitting(mob))&&(!isSleeping(mob));
	}

	@Override
	public boolean isBound(final Physical P)
	{
		if((P!=null)&&((P.phyStats().disposition()&PhyStats.IS_BOUND)==PhyStats.IS_BOUND))
			return true;
		return false;
	}

	@Override
	public boolean isBoundOrHeld(final Physical P)
	{
		if(P==null)
			return false;
		if((P.phyStats().disposition()&PhyStats.IS_BOUND)==PhyStats.IS_BOUND)
			return true;
		return flaggedAnyAffects(P,Ability.FLAG_BINDING|Ability.FLAG_PARALYZING).size()>0;
	}

	@Override
	public boolean isOnFire(final Physical seen)
	{
		if(seen==null)
			return false;
		if(seen.fetchEffect("Burning")!=null)
			return true;
		if(seen.fetchEffect("Prayer_FlameWeapon")!=null)
			return true;
		if(!(seen instanceof Light))
			return false;
		final Light light=(Light)seen;
		if(light.goesOutInTheRain() && light.isLit())
			return true;
		return false;
	}

	@Override
	public boolean isFloatingFreely(final Physical P)
	{
		return ((P.fetchEffect("GravityFloat")!=null)&&(P.phyStats().isAmbiance(L("Floating"))));
	}

	@Override
	public int getHideScore(final Physical seen)
	{
		if(seen!=null)
		{
			int hideFactor=seen.phyStats().level();
			if(seen instanceof MOB)
				hideFactor+=(((MOB)seen).charStats().getStat(CharStats.STAT_DEXTERITY))/2;
			if(CMath.bset(seen.basePhyStats().disposition(),PhyStats.IS_HIDDEN))
				hideFactor+=100;
			else
			if(seen instanceof MOB)
			{
				hideFactor+=((MOB)seen).charStats().getSave(CharStats.STAT_SAVE_DETECTION);
				if(seen.phyStats().height()>=0)
					hideFactor-=(int)Math.round(Math.sqrt(seen.phyStats().height()));
			}
			else
				hideFactor+=100;
			return hideFactor;
		}
		return 0;
	}

	@Override
	public int getDetectScore(final MOB seer)
	{
		if(seer!=null)
		{
			int detectFactor=seer.charStats().getStat(CharStats.STAT_WISDOM)/2;
			if(CMath.bset(seer.basePhyStats().sensesMask(),PhyStats.CAN_SEE_HIDDEN))
				detectFactor+=100;
			else // the 100 represents proff, and level represents time searching.
				detectFactor+=seer.charStats().getSave(CharStats.STAT_SAVE_OVERLOOKING);
			if(seer.phyStats().height()>=0)
				detectFactor-=(int)Math.round(Math.sqrt(seer.phyStats().height()));
			return detectFactor;
		}
		return 0;
	}

	@Override
	public boolean canBeSeenBy(final Environmental seen , final MOB seer)
	{
		if(seer==seen)
			return true;
		if(seen==null)
			return true;

		if((seer!=null)
		&&(seer.isAttributeSet(MOB.Attrib.SYSOPMSGS)))
			return true;

		if(!canSee(seer))
			return false;

		if(!(seen instanceof Physical))
			return true;

		final Physical seenP=(Physical)seen;

		if((!isSeeable(seenP))&&(seer!=null))
		{
			if((!(seenP instanceof MOB))
			||(seenP.phyStats().level()>seer.phyStats().level())
			||(!CMSecurity.isASysOp(seer)))
				return false;
		}

		if((isInvisible(seenP))&&(!canSeeInvisible(seer)))
			return false;

		if((isHidden(seenP))&&(!(seenP instanceof Room)))
		{
			if(seer == null)
				return false;
			if(seenP instanceof Item)
			{
				if(!canSeeHiddenItems(seer))
					return false;
			}
			else
			if(!canSeeHidden(seer))
			{
				if((!(seen instanceof MOB))
				||(getDetectScore(seer)<getHideScore((MOB)seen)))
					return false;
			}
		}

		if((seer!=null)&&(!(seenP instanceof Room)))
		{
			final Room R=seer.location();
			if((R!=null)&&(isInDark(R)))
			{
				if((isGlowing(seenP))||(isLightSource(seer)))
					return true;
				if(canSeeInDark(seer))
					return true;
				if((!isGolem(seenP))&&(canSeeInfrared(seer))&&(seenP instanceof MOB))
					return true;
				if((canSeeVictims(seer))&&(seer.getVictim()==seenP))
					return true;
				final Area area=R.getArea();
				if(area != null)
				{
					if((area.getClimateObj().canSeeTheMoon(R,null))
					&&(area.getTimeObj().getMoonPhase(R)==TimeClock.MoonPhase.FULL))
						return true;
				}
				return false;
			}
			return true;
		}
		else
		if(isInDark(seenP))
		{
			if((seenP instanceof Room)
			&&(((Room)seenP).getArea().getClimateObj().canSeeTheMoon(((Room)seenP),null)))
			{
				switch(((Room)seenP).getArea().getTimeObj().getMoonPhase((Room)seenP))
				{
				case FULL:
				case WAXGIBBOUS:
				case WANEGIBBOUS:
					return true;
				default:
					break;
				}
			}

			if(isLightSource(seer))
				return true;
			if(canSeeInDark(seer))
				return true;
			return false;
		}
		return true;
	}

	@Override
	public boolean canBarelyBeSeenBy(final Environmental seen , final MOB seer)
	{
		if(!canBeSeenBy(seen,seer))
		{
			if((seer!=null)&&(!(seen instanceof Room)))
			{
				final Room R=seer.location();
				if((R!=null)&&(isInDark(R)))
				{
					if(R.getArea().getClimateObj().canSeeTheMoon(R,null))
					{
						return R.getArea().getTimeObj().getMoonPhase(R) != TimeClock.MoonPhase.NEW;
					}
				}
			}
			else
			if((seen instanceof Physical) && (isInDark((Physical)seen)))
			{
				if((seen instanceof Room)
				&&(((Room)seen).getArea().getClimateObj().canSeeTheMoon(((Room)seen),null)))
				{
					switch(((Room)seen).getArea().getTimeObj().getMoonPhase((Room)seen))
					{
						case FULL:
						case WAXGIBBOUS:
						case WANEGIBBOUS:
							return false;
						case NEW:
							return false;
						default:
							return true;
					}
				}
			}
		}
		return false;
	}

	@Override
	public boolean canActAtAll(final Tickable affecting)
	{
		if(affecting instanceof MOB)
		{
			final MOB monster=(MOB)affecting;
			if((!isAliveAwakeMobile(monster,true))
			||(monster.location()==null)
			||(!isInTheGame(monster,false)))
				return false;
			return true;
		}
		return false;
	}

	@Override
	public boolean canFreelyBehaveNormal(final Tickable affecting)
	{
		if(affecting instanceof MOB)
		{
			final MOB monster=(MOB)affecting;
			if((!canActAtAll(monster))
			||(monster.isInCombat())
			||((monster.amFollowing()!=null)&&(!monster.isPlayer()))
			||(monster.curState().getHitPoints()<(monster.maxState().getHitPoints()/2)))
				return false;
			return true;
		}
		return false;
	}


	@Override
	public Directions.DirType getDirType(final Physical P)
	{
		// never check the location of P generically, as
		// it would create ambiguity with getInDirtype when
		// a mob is passed in.
		if(P instanceof Boardable)
		{
			final Item I=((Boardable)P).getBoardableItem();
			if(I instanceof SpaceShip)
				return DirType.SHIP;
			if(I instanceof NavigableItem)
			{
				switch(((NavigableItem)I).navBasis())
				{
				case AIR_FLYING:
					return DirType.SHIP;
				case LAND_BASED:
					return DirType.CARAVAN;
				case WAGON:
					return DirType.CARAVAN;
				case WATER_BASED:
					return DirType.SHIP;
				default:
					return DirType.COMPASS;
				}
			}
			return DirType.SHIP;
		}
		if(P instanceof Rider)
		{
			final Rider rider=(Rider)P;
			final Rideable ride=rider.riding();
			if((ride instanceof Boardable)
			&&(((Boardable)ride).Name().equals(rider.Name())))
				return getDirType(ride);
		}
		if(P instanceof Room)
			return getDirType(((Room)P).getArea());
		return DirType.COMPASS;
	}

	@Override
	public Directions.DirType getInDirType(final MOB M)
	{
		return (M==null)?DirType.COMPASS:getDirType(M.location());
	}

	@Override
	public boolean isSeenTheSameWay(final MOB seer, final Physical seen1, final Physical seen2)
	{
		if(canBeSeenBy(seen1,seer)!=canBeSeenBy(seen2,seer))
			return false;
		if((isEvil(seen1)!=isEvil(seen2))&&(canSeeEvil(seer)))
			return false;
		if((isGood(seen1)!=isGood(seen2))&&(canSeeGood(seer)))
			return false;
		if((isABonusItems(seen1)!=isABonusItems(seen2))&&(canSeeBonusItems(seer)))
			return false;
		if(isInvisible(seen1)!=isInvisible(seen2))
			return false;
		if(isSneaking(seen1)!=isSneaking(seen2))
			return false;
		if(isHidden(seen1)!=isHidden(seen2))
			return false;
		if(isFlying(seen1)!=isFlying(seen2))
			return false;
		if(isBound(seen1)!=isBound(seen2))
			return false;
		if(isFalling(seen1)!=isFalling(seen2))
			return false;
		if(isGlowing(seen1)!=isGlowing(seen2))
			return false;
		if(isGolem(seen1)!=isGolem(seen2))
			return false;
		if(canSeeMetal(seer)&&(seen1 instanceof Item)&&(seen2 instanceof Item)
			&&((((Item)seen1).material()&RawMaterial.MATERIAL_MASK)!=(((Item)seen2).material()&RawMaterial.MATERIAL_MASK)))
		   return false;
		if(!CMStrings.compareStringArraysIgnoreCase(seen1.phyStats().ambiances(),seen2.phyStats().ambiances()))
			return false;
		return true;
	}

	@Override
	public boolean isWaterWorthy(final Physical P)
	{
		if(P==null)
			return false;
		if(isSwimming(P)
		&&((!(P instanceof Item))||(!((Item)P).subjectToWearAndTear())||(((Item)P).usesRemaining()>0)))
			return true;
		if((P instanceof Rider)&&(((Rider)P).riding()!=null))
			return isWaterWorthy(((Rider)P).riding());
		if((P instanceof Rideable)
		&&(((Rideable)P).rideBasis()==Rideable.Basis.WATER_BASED)
		&&(P instanceof MOB))
			return true;
		if(P instanceof Item)
		{
			final List<Item> V=new Vector<Item>();
			if(P instanceof Container)
				V.addAll(((Container)P).getDeepContents());
			if(!V.contains(P))
				V.add((Item)P);
			long totalWeight=0;
			long totalFloatilla=0;
			final RawMaterial.CODES codes = RawMaterial.CODES.instance();
			for(int v=0;v<V.size();v++)
			{
				final Item I=V.get(v);
				totalWeight+=I.basePhyStats().weight();
				totalFloatilla+=totalWeight*codes.bouancy(I.material());
			}
			if(P instanceof Container)
			{
				final long cap=((Container)P).capacity();
				if(totalWeight<cap)
				{
					totalFloatilla+=(cap-totalWeight);
					totalWeight+=cap-totalWeight;
				}
			}
			if(totalWeight<=0)
				return true;

			if(isFalling(P))
				return false;
			return (totalFloatilla/totalWeight)<=1000;
		}
		return false;
	}

	@Override
	public boolean isInFlight(final Physical P)
	{
		if(P==null)
			return false;
		if(isFlying(P))
			return true;
		if(P instanceof Rider)
			return isInFlight(((Rider)P).riding());
		return false;
	}

	@Override
	public boolean isAnimalIntelligence(final MOB M)
	{
		return (M!=null)&&(M.charStats().getStat(CharStats.STAT_INTELLIGENCE)<2);
	}

	@Override
	public boolean isVegetable(final MOB M)
	{
		return (M != null)
				&& CMProps.getListFileVarSet(CMProps.ListFile.RACIAL_CATEGORY_IS_VEGETATION).contains(M.charStats().getMyRace().racialCategory());
	}

	@Override
	public boolean isMobile(final PhysicalAgent P)
	{
		if(P!=null)
		{
			if((P instanceof Boardable)&&(!((Boardable)P).amDestroyed()))
				return true;
			for(final Enumeration<Behavior> e=P.behaviors();e.hasMoreElements();)
			{
				final Behavior B=e.nextElement();
				if((B!=null)&&(CMath.bset(B.flags(),Behavior.FLAG_MOBILITY)))
					return true;
			}
		}
		return false;
	}

	@Override
	public List<Behavior> flaggedBehaviors(final PhysicalAgent P, final long flag)
	{
		final Vector<Behavior> V=new Vector<Behavior>(1);
		if(P!=null)
		{
			for(final Enumeration<Behavior> e=P.behaviors();e.hasMoreElements();)
			{
				final Behavior B=e.nextElement();
				if((B!=null)&&(CMath.bset(B.flags(),flag)))
				{
					V.addElement(B);
				}
			}
		}
		return V;
	}

	@Override
	public List<Ability> domainAnyAffects(final Physical P, final int domain)
	{
		final Vector<Ability> V=new Vector<Ability>(1);
		if(P!=null)
		{
			if(domain>Ability.ALL_ACODES)
			{
				P.eachEffect(new EachApplicable<Ability>()
				{
					@Override
					public void apply(final Ability A)
					{
						if((A.classificationCode()&Ability.ALL_DOMAINS)==domain)
							V.addElement(A);
					}
				});
			}
			else
			{
				P.eachEffect(new EachApplicable<Ability>()
				{
					@Override
					public void apply(final Ability A)
					{
						if((A.classificationCode()&Ability.ALL_ACODES)==domain)
							V.addElement(A);
					}
				});
			}
		}
		return V;
	}

	@Override
	public List<Ability> domainAffects(final Physical P, final int domain)
	{
		return domainAnyAffects(P,domain);
	}

	@Override
	public List<Ability> domainAbilities(final MOB M, final int domain)
	{
		final Vector<Ability> V=new Vector<Ability>(1);
		if(M!=null)
		{
			if(domain>Ability.ALL_ACODES)
			{
				for(final Enumeration<Ability> a=M.allAbilities();a.hasMoreElements();)
				{
					final Ability A=a.nextElement();
					if((A!=null)&&((A.classificationCode()&Ability.ALL_DOMAINS)==domain))
					{
						V.addElement(A);
					}
				}
			}
			else
			for(final Enumeration<Ability> a=M.allAbilities();a.hasMoreElements();)
			{
				final Ability A=a.nextElement();
				if((A!=null)&&((A.classificationCode()&Ability.ALL_ACODES)==domain))
				{
					V.addElement(A);
				}
			}
		}
		return V;
	}

	@Override
	public List<Ability> flaggedAnyAffects(final Physical P, final long flag)
	{
		final Vector<Ability> V=new Vector<Ability>(1);
		if(P!=null)
		{
			P.eachEffect(new EachApplicable<Ability>()
			{
				@Override
				public void apply(final Ability A)
				{
					if((A.flags()&flag)>0)
						V.addElement(A);
				}
			});
		}
		return V;
	}

	@Override
	public List<Ability> matchedAffects(final MOB invoker, final Physical P, final long flag, final int abilityCode, final int domain)
	{
		final Vector<Ability> V=new Vector<Ability>(1);
		if(P!=null)
		{
			P.eachEffect(new EachApplicable<Ability>()
			{
				@Override
				public void apply(final Ability A)
				{
					if(((invoker==null)||(A.invoker()==invoker))
					&&(((flag<0)||(A.flags()&flag)>0))
					&&(((abilityCode<0)||((A.classificationCode()&Ability.ALL_ACODES)==abilityCode)))
					&&(((domain<0)||((A.classificationCode()&Ability.ALL_DOMAINS)==domain))))
						V.addElement(A);
				}
			});
		}
		return V;
	}

	@Override
	public List<Ability> flaggedAffects(final Physical P, final long flag)
	{
		return flaggedAnyAffects(P,flag);
	}

	@Override
	public List<Ability> flaggedAbilities(final MOB M, final long flag)
	{
		final Vector<Ability> V=new Vector<Ability>();
		if(M!=null)
		{
			for(final Enumeration<Ability> a=M.allAbilities();a.hasMoreElements();)
			{
				final Ability A=a.nextElement();
				if((A!=null)&&(CMath.bset(A.flags(),flag)))
				{
					V.addElement(A);
				}
			}
		}
		return V;
	}

	@Override
	public boolean canAccess(final MOB mob, final Area A)
	{
		if(A==null)
			return false;
		if((isHidden(A)) && (mob==null))
			return false;
		if(((!isHidden(A))
			&&(mob.location()!=null)&&(mob.location().getArea().getTimeObj()==A.getTimeObj()))
		||(CMSecurity.isASysOp(mob))
		||(A.amISubOp(mob.Name())))
			return true;
		return false;
	}

	@Override
	public boolean canAccess(final MOB mob, final Room R)
	{
		if(R==null)
			return false;
		if(isHidden(R))
		{
			if(mob!=null)
			{
				if((CMSecurity.isASysOp(mob))
				||(R.getArea().amISubOp(mob.Name())))
					return true;
			}
			return false;
		}
		else
		if((mob!=null)
		&&(mob.location()!=null)
		&&(mob.location().getArea().getTimeObj()!=R.getArea().getTimeObj()))
		{
			if((mob==null)||(!CMSecurity.isASysOp(mob)))
				return false;
		}
		return true;
	}

	@Override
	public boolean isMetal(final Environmental E)
	{
		if(E instanceof Item)
		{
			return((((Item)E).material()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_METAL)
				||((((Item)E).material()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_MITHRIL);
		}
		if(E instanceof MOB)
		{
			final MOB M=(MOB)E;
			if(isGolem(M) && (M.charStats()!=null) && (M.charStats().getMyRace()!=null))
			{
				final List<RawMaterial> mats = M.charStats().getMyRace().myResources();
				for(final Item I : mats)
				{
					if(CMath.bset(I.material(), RawMaterial.MATERIAL_METAL)
					||CMath.bset(I.material(), RawMaterial.MATERIAL_MITHRIL))
						return true;
				}
			}
		}
		return false;
	}

	@Override
	public boolean isAiryRoom(final Room R)
	{
		if(R==null)
			return false;
		switch(R.domainType())
		{
		case Room.DOMAIN_INDOORS_AIR:
		case Room.DOMAIN_OUTDOORS_AIR:
			return true;
		}
		return false;
	}

	@Override
	public boolean isWateryRoom(final Room R)
	{
		if(R==null)
			return false;
		switch(R.domainType())
		{
		case Room.DOMAIN_INDOORS_UNDERWATER:
		case Room.DOMAIN_OUTDOORS_UNDERWATER:
		case Room.DOMAIN_INDOORS_WATERSURFACE:
		case Room.DOMAIN_OUTDOORS_WATERSURFACE:
			return true;
		}
		return ((R.getAtmosphere()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_LIQUID)
				||isSwimming(R);
	}

	/**
	 * Returns whether the given room, whatever is
	 * watery, such as a water surface, etc.
	 * @param R the room to check
	 * @return true if it is water surfacy, false otherwise
	 */
	@Override
	public boolean isWaterySurfaceRoom(final Room R)
	{
		if(R==null)
			return false;
		switch(R.domainType())
		{
		case Room.DOMAIN_INDOORS_WATERSURFACE:
		case Room.DOMAIN_OUTDOORS_WATERSURFACE:
			return true;
		}
		return ((R.getAtmosphere()&RawMaterial.MATERIAL_MASK)!=RawMaterial.MATERIAL_LIQUID)
				&&isSwimming(R);
	}

	/**
	 * Returns whether the given room, whatever is
	 * the surface of deep water, such as a water surface, etc.
	 * with an underwater room
	 * @param R the room to check
	 * @return true if it is water surfacy, false otherwise
	 */
	@Override
	public boolean isDeepWaterySurfaceRoom(final Room R)
	{

		if((R==null)||(!isWaterySurfaceRoom(R)))
			return false;
		R.giveASky(0);
		return isUnderWateryRoom(R.getRoomInDir(Directions.DOWN));
	}

	/**
	 * Returns whether the given room, whatever is
	 * watery, such as an underwater, etc.
	 * @param R the room to check
	 * @return true if it is underwatery, false otherwise
	 */
	@Override
	public boolean isUnderWateryRoom(final Room R)
	{
		if(R==null)
			return false;
		switch(R.domainType())
		{
		case Room.DOMAIN_INDOORS_UNDERWATER:
		case Room.DOMAIN_OUTDOORS_UNDERWATER:
			return true;
		}
		return ((R.getAtmosphere()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_LIQUID)
				&&isSwimming(R);
	}

	@Override
	public boolean isInTheGame(final Environmental E, final boolean reqInhabitation)
	{
		if(E instanceof MOB)
			return isInTheGame((MOB)E,reqInhabitation);
		if(E instanceof Item)
			return isInTheGame((Item)E,reqInhabitation);
		if(E instanceof Room)
			return isInTheGame((Room)E,reqInhabitation);
		if(E instanceof Area)
			return isInTheGame((Area)E,reqInhabitation);
		return true;
	}

	@Override
	public boolean isInTheGame(final MOB E, final boolean reqInhabitation)
	{
		return (E.location()!=null)
				&& E.amActive()
				&&((!reqInhabitation)||E.location().isInhabitant(E));
	}

	@Override
	public boolean isInTheGame(final Item E, final boolean reqInhabitation)
	{
		if(E.owner() instanceof MOB)
		{
			return isInTheGame((MOB)E.owner(),reqInhabitation);
		}
		else
		if(E.owner() instanceof Room)
		{
			return ((!E.amDestroyed())
					&&((!reqInhabitation)||(((Room)E.owner()).isContent(E))));
		}
		return false;
	}

	@Override
	public boolean isInTheGame(final Room E, final boolean reqInhabitation)
	{
		return CMLib.map().getRoom(CMLib.map().getExtendedRoomID(E))==E;
	}

	@Override
	public boolean isInTheGame(final Area E, final boolean reqInhabitation)
	{
		return CMLib.map().getArea(E.Name())==E;
	}

	@Override
	public boolean isEnchanted(final Item I)
	{
		// poison is not an enchantment.
		// neither is disease, or standard properties.
		for(int i=0;i<I.numEffects();i++)
		{
			final Ability A=I.fetchEffect(i);
			if(A!=null)
			{
				if(((A.classificationCode()&Ability.ALL_ACODES)!=Ability.ACODE_PROPERTY)
				&&((A.classificationCode()&Ability.ALL_ACODES)!=Ability.ACODE_DISEASE)
				&&((A.classificationCode()&Ability.ALL_ACODES)!=Ability.ACODE_POISON)
				&&(!(A instanceof Deity.DeityWorshipper))
				&&(!CMath.bset(A.flags(), Ability.FLAG_NONENCHANTMENT)))
					return true;
				if(A instanceof AbilityContainer)
				{
					for(final Enumeration<Ability> a=((AbilityContainer)A).abilities();a.hasMoreElements();)
					{
						final Ability A1=a.nextElement();
						if((A1!=null)
						&&((A1.classificationCode()&Ability.ALL_ACODES)!=Ability.ACODE_PROPERTY)
						&&((A1.classificationCode()&Ability.ALL_ACODES)!=Ability.ACODE_DISEASE)
						&&((A1.classificationCode()&Ability.ALL_ACODES)!=Ability.ACODE_POISON)
						&&(!CMath.bset(A1.flags(), Ability.FLAG_NONENCHANTMENT)))
						{
							if(!(I instanceof RawMaterial))
								return true;
							final Ability[] natEff = RawMaterial.CODES.EFFECTA(I.material());
							if(natEff == null)
								return true;
							boolean found=false;
							for(final Ability A2 : natEff)
							{
								if((A2 != null)
								&&(A2.ID().equals(A.ID()))
								&&(((AbilityContainer)A2).fetchAbility(A1.ID())!=null))
									found=true;
							}
							if(!found)
								return true;
						}
					}
				}
			}
		}
		if((I instanceof Weapon)||(I instanceof Armor))
			return this.isABonusItems(I);
		return false;
	}

	public boolean isAgingThing(final Physical P)
	{
		if(P==null)
			return false;
		final Ability A=P.fetchEffect("Age");
		if((A!=null)&&(CMath.isInteger(A.text())&&(CMath.s_long(A.text())>Short.MAX_VALUE)))
			return true;
		return false;
	}

	@Override
	public boolean isChild(final Environmental E)
	{
		return isBaby(E)||((E instanceof MOB)&&(((MOB)E).isMonster())&&(isAgingThing((MOB)E)));
	}

	@Override
	public boolean isBaby(final Environmental E)
	{
		return ((E instanceof CagedAnimal)&&(isAgingThing((CagedAnimal)E)));
	}

	@Override
	public boolean isStillAffectedBy(final Physical obj, final List<Ability> oneOf, final boolean anyTallF)
	{
		for(int a=oneOf.size()-1;a>=0;a--)
		{
			if(obj.fetchEffect(oneOf.get(a).ID())==null)
			{
				if(!anyTallF)
					return false;
			}
			else
			{
				if(anyTallF)
					return true;
			}
		}
		return !anyTallF;
	}

	@Override
	public String getDispositionDescList(final Physical obj, final boolean useVerbs)
	{
		if(obj == null)
			return "";
		final int disposition = obj.phyStats().disposition();
		final StringBuffer buf=new StringBuffer("");
		if(useVerbs)
		{
			for(int i=0;i<PhyStats.IS_VERBS.length;i++)
				if(CMath.isSet(disposition,i))
					buf.append(PhyStats.IS_VERBS[i]+", ");
		}
		else
		for(int i=0;i<PhyStats.IS_CODES.length;i++)
		{
			if(CMath.isSet(disposition,i))
				buf.append(PhyStats.IS_CODES[i]+", ");
		}
		String buff=buf.toString();
		if(buff.endsWith(", "))
			buff=buff.substring(0,buff.length()-2).trim();
		return buff;
	}

	@Override
	public String getSensesDescList(final Physical obj, final boolean useVerbs)
	{
		if(obj == null)
			return "";
		final int senses = obj.phyStats().sensesMask();
		final StringBuffer buf=new StringBuffer("");
		if(useVerbs)
		{
			for(int i=0;i<PhyStats.CAN_SEE_VERBS.length;i++)
				if(CMath.isSet(senses,i))
					buf.append(PhyStats.CAN_SEE_VERBS[i]+", ");
		}
		else
		for(int i=0;i<PhyStats.CAN_SEE_CODES.length;i++)
		{
			if(CMath.isSet(senses,i))
				buf.append(PhyStats.CAN_SEE_CODES[i]+", ");
		}
		String buff=buf.toString();
		if(buff.endsWith(", "))
			buff=buff.substring(0,buff.length()-2).trim();
		return buff;
	}

	@Override
	public int getDispositionIndex(String name)
	{
		name=name.toUpperCase().trim();
		for(int code=0;code<PhyStats.IS_CODES.length-1;code++)
		{
			if(PhyStats.IS_CODES[code].endsWith(name))
			{
				return code;
			}
		}
		return -1;
	}

	@Override
	public int getSensesIndex(String name)
	{
		name=name.toUpperCase().trim();
		for(int code=0;code<PhyStats.CAN_SEE_CODES.length-1;code++)
		{
			if(PhyStats.CAN_SEE_CODES[code].endsWith(name))
			{
				return code;
			}
		}
		return -1;
	}

	@Override
	public String getAbilityType(final Ability A)
	{
		if(A==null)
			return "";
		return Ability.ACODE_DESCS[A.classificationCode()&Ability.ALL_ACODES];
	}

	@Override
	public String getAbilityType_(final Ability A)
	{
		if(A==null)
			return "";
		return Ability.ACODE_DESCS_[A.classificationCode()&Ability.ALL_ACODES];
	}

	@Override
	public String getAbilityDomain(final Ability A)
	{
		if(A==null)
			return "";
		return Ability.DOMAIN_DESCS[(A.classificationCode()&Ability.ALL_DOMAINS)>>5];
	}

	@Override
	public int getAbilityType(final String name)
	{
		for(int i=0;i<Ability.ACODE_DESCS.length;i++)
		{
			if(name.equalsIgnoreCase(Ability.ACODE_DESCS[i]))
				return i;
		}
		return -1;
	}

	@Override
	public int getAbilityType_(final String name)
	{
		for(int i=0;i<Ability.ACODE_DESCS_.length;i++)
		{
			if(name.equalsIgnoreCase(Ability.ACODE_DESCS_[i]))
				return i;
		}
		return -1;
	}

	@Override
	public int getAbilityDomain(final String name)
	{
		for(int i=0;i<Ability.DOMAIN_DESCS.length;i++)
		{
			if(name.equalsIgnoreCase(Ability.DOMAIN_DESCS[i]))
				return i<<5;
		}
		return -1;
	}

	@Override
	public boolean isAControlledFollower(final MOB invoker, final MOB mob, Ability A)
	{
		if((mob==null)||(mob==invoker)||(!mob.isMonster()))
			return false;
		if(A==null)
			return mob.getStartRoom()==null;
		A = mob.fetchEffect(A.ID());
		if(A==null)
			return false;
		if((A.invoker() == invoker)||(A.invoker()==null))
			return true;
		return false;
	}

	@Override
	public boolean hasAControlledFollower(final MOB invoker, final Ability A)
	{
		if(invoker==null)
			return false;
		final Room R = invoker.location();
		if(R==null)
			return false;
		for(int r=0;r<R.numInhabitants();r++)
		{
			if(isAControlledFollower(invoker, R.fetchInhabitant(r), A))
				return true;
		}
		final Set<MOB> H = invoker.getGroupMembers(new HashSet<MOB>());
		for (final MOB mob : H)
		{
			if(isAControlledFollower(invoker, mob, A))
				return true;
		}
		return false;
	}

	@Override
	public String getDispositionBlurbs(final Physical seen, final MOB seer)
	{
		if(seen == null)
			return "";
		final PhyStats pStats=seen.phyStats();
		if(pStats == null)
			return ""; // an exit?
		final String[] ambiances=pStats.ambiances();
		if(!pStats.isAmbiance("-ALL"))
		{
			final StringBuilder say=new StringBuilder("^N");
			if(!pStats.isAmbiance("-MOST"))
			{
				if((seer!=null)
				&&(seer.phyStats().sensesMask()>0))
				{
					if((canSeeEvil(seer))&&(isEvil(seen))&&(!pStats.isAmbiance("-EVIL")))
						say.append(" (glowing ^rred^?)");
					if((canSeeGood(seer))&&(isGood(seen))&&(!pStats.isAmbiance("-GOOD")))
						say.append(" (glowing ^bblue^?)");
					if((canSeeInvisible(seer))&&(isInvisible(seen))&&(!pStats.isAmbiance("-INVISIBLE")))
						say.append(" (^yinvisible^?)");
					if((canSeeSneakers(seer))&&(isSneaking(seen))&&(!pStats.isAmbiance("-SNEAKING")))
						say.append(" (^ysneaking^?)");
					if((isHidden(seen))
					&&(canSeeHidden(seer)||((seen instanceof Item)&&(canSeeHiddenItems(seer))))
					&&(!pStats.isAmbiance("-HIDDEN")))
						say.append(" (^yhidden^?)");
					if((canSeeInfrared(seer))&&(!isGolem(seen))&&(seen instanceof MOB)&&(isInDark(seer.location()))&&(!pStats.isAmbiance("-HEAT")))
						say.append(" (^rheat aura^?)");
					if((canSeeBonusItems(seer))&&(isABonusItems(seen))&&(!pStats.isAmbiance("-MAGIC")))
						say.append(" (^wmagical aura^?)");
					if((canSeeMetal(seer))&&(seen instanceof Item)&&(!pStats.isAmbiance("-METAL")))
					{
						if((((Item)seen).material()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_METAL)
							say.append(" (^wmetallic aura^?)");
						else
						if((((Item)seen).material()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_MITHRIL)
							say.append(" (^wmithril aura^?)");
					}
				}

				if((isGlowing(seen))&&(!(seen instanceof Room))&&(!pStats.isAmbiance("-GLOWING")))
					say.append(" (^gglowing^?)");
				if((seen instanceof MOB) && isRunningLongCommand((MOB)seen)&&(!pStats.isAmbiance("-BUSY")))
					say.append(" (^gbusy^?)");
				if((canSeeChaos(seer))&&(isChaotic(seen))&&(!pStats.isAmbiance("-CHAOS")))
					say.append(" (glowing ^ppurple^?)");
				if((canSeeLaw(seer))&&(isLawful(seen))&&(!pStats.isAmbiance("-LAW")))
					say.append(" (glowing ^wwhite^?)");
				for(int i=0;i<ambiances.length;i++)
				{
					switch(ambiances[i].charAt(0))
					{
					case '(':
						if(ambiances[i].startsWith("(?)"))
						{
							final int x=ambiances[i].indexOf(':');
							if(canBeHeardSpeakingBy(seen, seer))
								say.append(" ("+ambiances[i].substring(3,(x>3)?x:ambiances[i].length())+")");
							else
							if(x>3)
								say.append(" ("+ambiances[i].substring(x+1)+")");
						}
						else
							say.append(" "+ambiances[i]);
						break;
					case '-':
						break;
					case '@':
						break;
					case '#':
					{
						final String ambiCode = ambiances[i].substring(1);
						if((pStats.isAmbiance("@"+ambiCode))
						&&(!ambiCode.equals("LAW"))
						&&(!ambiCode.equals("CHAOS")))
							say.append(" ("+ambiCode+")");
						break;
					}
					default:
						say.append(" ("+ambiances[i]+")");
						break;
					}
				}
			}
			if(isBound(seen)&&(!pStats.isAmbiance("-BOUND")))
				say.append(" (^Wbound^?)");
			if(isFlying(seen)&&(!(seen instanceof Exit))&&(!pStats.isAmbiance("-FLYING")))
				say.append(" (^pflying^?)");
			if((isFalling(seen))&&(!pStats.isAmbiance("-FALLING")))
			{
				final Room R=roomLocation(seen);
				switch(R.domainType())
				{
				case Room.DOMAIN_INDOORS_AIR:
				case Room.DOMAIN_OUTDOORS_AIR:
					say.append(" (^pfalling^?)");
					break;
				case Room.DOMAIN_INDOORS_WATERSURFACE:
				case Room.DOMAIN_OUTDOORS_WATERSURFACE:
				case Room.DOMAIN_INDOORS_UNDERWATER:
				case Room.DOMAIN_OUTDOORS_UNDERWATER:
				case Room.DOMAIN_OUTDOORS_SEAPORT:
				case Room.DOMAIN_INDOORS_SEAPORT:
				case Room.DOMAIN_INDOORS_CAVE_SEAPORT:
					if(R.rawDoors()[Directions.DOWN]==null)
						say.append(" (^psunk^?)");
					else
						say.append(" (^psinking^?)");
					break;
				default:
					if(!(seen instanceof MOB))
						say.append(" (^pfalling^?)");
					break;
				}
			}
			if(say.length()>1)
			{
				say.append(" ");
				return say.toString();
			}
		}
		return "";
	}

	protected boolean isAlcoholEffect(final Ability A)
	{
		if(A!=null)
		{
			if(CMath.bset(A.flags(),Ability.FLAG_INTOXICATING))
				return true;
			if(A instanceof AbilityContainer)
			{
				for(final Enumeration<Ability> a2=((AbilityContainer)A).allAbilities();a2.hasMoreElements();)
				{
					final Ability A2=a2.nextElement();
					if((A2!=null)&&(CMath.bset(A2.flags(),Ability.FLAG_INTOXICATING)))
						return true;
				}
			}
		}
		return false;
	}

	@Override
	public List<String> getParents(final Physical thang)
	{
		final List<String> parents=new Vector<String>(2);
		final MOB babe;
		if(thang instanceof MOB)
			babe=(MOB)thang;
		else
		if(thang instanceof CagedAnimal)
			babe=((CagedAnimal)thang).unCageMe();
		else
			return parents;
		for(final Enumeration<Tattoo> t= babe.tattoos();t.hasMoreElements();)
		{
			final Tattoo T=t.nextElement();
			if(T.name().startsWith("PARENT:"))
				parents.add(T.name().substring(7).trim());
		}
		if(thang instanceof CagedAnimal)
			babe.destroy();
		return parents;
	}

	@Override
	public boolean isAlcoholic(final Physical thang)
	{
		if(thang==null)
			return false;
		if(thang instanceof Item)
		{
			if(((Item)thang).material()==RawMaterial.RESOURCE_LIQUOR)
				return true;
		}
		if(thang instanceof LiquidHolder)
		{
			if(((LiquidHolder)thang).liquidType()==RawMaterial.RESOURCE_LIQUOR)
				return true;
			if(thang instanceof Container)
			{
				for(final Item I : ((Container)thang).getContents())
				{
					if((I!=thang) && isAlcoholic(I))
						return true;
				}
			}
			if(thang instanceof SpellHolder)
			{
				for(final Ability A : ((SpellHolder)thang).getSpells())
				{
					if(isAlcoholEffect(A))
						return true;
				}
			}
		}
		for(int a=0;a<thang.numEffects();a++) // personal
		{
			final Ability A=thang.fetchEffect(a);
			if(this.isAlcoholEffect(A))
				return true;
		}
		return false;
	}

	@Override
	public String getPresentDispositionVerb(final Physical seen, final ComingOrGoing flag_msgType)
	{
		String type=null;
		if(isFalling(seen))
		{
			if((seen instanceof Item)
			&&(((Item)seen).owner() instanceof Room)
			&&(isWateryRoom((Room)((Item)seen).owner())))
				type="sinks";
			else
			if((seen instanceof MOB)
			&&(isWateryRoom(((MOB)seen).location())))
				type="sinks";
			else
				type="falls";
		}
		else
		if(isSleeping(seen))
		{
			if(flag_msgType!=ComingOrGoing.IS)
				type=(seen instanceof MOB) ? "sleepwalks" : "floats";
			else
				type="sleeps";
		}
		else
		if(isSneaking(seen))
			type="sneaks";
		else
		if(isHidden(seen))
			type="prowls";
		else
		if(isSitting(seen))
		{
			if(flag_msgType!=ComingOrGoing.IS)
				type="crawls";
			else
			if(seen instanceof MOB)
				type="sits";
			else
				type="sits";
		}
		else
		if(isFlying(seen))
			type="flies";
		else
		if((isClimbing(seen))&&(flag_msgType!=ComingOrGoing.IS))
			type="climbs";
		else
		if(isSwimmingInWater(seen))
			type="swims";
		else
		if(flag_msgType != null)
		{
			switch(flag_msgType)
			{
			case ARRIVES:
				if(seen instanceof MOB)
					return ((MOB)seen).charStats().getArriveStr();
				else
					return "arrives";
			case LEAVES:
				if(seen instanceof MOB)
					return ((MOB)seen).charStats().getLeaveStr();
				else
					return "leaves";
			default:
				return "is";
			}
		}

		if(flag_msgType==ComingOrGoing.ARRIVES)
			return type+" in";
		return type;

	}

	@Override
	public String getDispositionStateList(final MOB mob)
	{
		final StringBuilder str=new StringBuilder("");
		if(isClimbing(mob))
			str.append("climbing, ");
		if((mob.phyStats().disposition()&PhyStats.IS_EVIL)>0)
		{
			if((mob.phyStats().disposition()&PhyStats.IS_GOOD)>0)
				str.append("sacred, ");
			else
				str.append("evil, ");
		}
		if(isFalling(mob))
			str.append("falling, ");
		if(isBound(mob))
			str.append("bound, ");
		if(isFlying(mob))
			str.append("flies, ");
		if((mob.phyStats().disposition()&PhyStats.IS_GOOD)>0)
		{
			if((mob.phyStats().disposition()&PhyStats.IS_EVIL)==0)
				str.append("good, ");
		}
		if(isHidden(mob))
			str.append("hidden, ");
		if(isInDark(mob))
			str.append("darkness, ");
		if(isInvisible(mob))
			str.append("invisible, ");
		if(isGlowing(mob))
			str.append("glowing, ");
		if(isCloaked(mob))
			str.append("cloaked, ");
		if(!isSeeable(mob))
			str.append("unseeable, ");
		if(isSitting(mob))
			str.append("crawls, ");
		if(isSleeping(mob))
			str.append("sleepy, ");
		if(isSneaking(mob))
			str.append("sneaks, ");
		if(isSwimming(mob))
			str.append("swims, ");
		if(str.toString().endsWith(", "))
			return str.toString().substring(0,str.length()-2);
		return str.toString();
	}

	@Override
	public String getSensesStateList(final MOB mob)
	{
		final StringBuilder str=new StringBuilder("");
		if(!canHear(mob))
			str.append("deaf, ");
		if(!canSee(mob))
			str.append("blind, ");
		if(!canMove(mob))
			str.append("can't move, ");
		if(canSeeBonusItems(mob))
			str.append(L("detect magic, "));
		if(canSeeEvil(mob))
			str.append(L("detect evil, "));
		if(canSeeGood(mob))
			str.append(L("detect good, "));
		if(canSeeHidden(mob))
			str.append("see hidden, ");
		else
		if(canSeeHiddenItems(mob))
			str.append("see hidden items, ");
		if(canSeeInDark(mob))
			str.append(L("darkvision, "));
		if(canSeeInfrared(mob))
			str.append(L("infravision, "));
		if(canSeeInvisible(mob))
			str.append(L("see invisible, "));
		if(canSeeMetal(mob))
			str.append(L("metalvision, "));
		if(canSeeSneakers(mob))
			str.append(L("see sneaking, "));
		if(!canSmell(mob))
			str.append("can't smell, ");
		if(!canSpeak(mob))
			str.append("can't speak, ");
		if(!canTaste(mob))
			str.append("can't eat, ");
		if(str.toString().endsWith(", "))
			return str.toString().substring(0,str.length()-2);
		return str.toString();
	}
}

<MSG> bit more info about bad double-links.

git-svn-id: 0cdf8356e41b2d8ccbb41bb76c82068fe80b2514@17788 0d6f1817-ed0e-0410-87c9-987e46238f29

<DFF> @@ -1049,7 +1049,7 @@ public class Sense extends StdLibrary implements CMFlagLibrary
 				ownerCheck=owner.isContent(I);
 			}
 			if(!ownerCheck)
-				return I.name()+" is not where it is: "+owner.name();
+				return I.name()+" is not where it is: "+owner.name()+" ("+owner.ID()+"): "+CMLib.map().getExtendedRoomID(CMLib.map().roomLocation(owner));
 			if(owner instanceof MOB)
 			{
 				final MOB M=(MOB)owner;

{'commit': 'diff --git a/com/planet_ink/coffee_mud/Libraries/Sense.java b/com/planet_ink/coffee_mud/Libraries/Sense.java\nindex 814ca62594..d8fab5a77f 100644\n--- a/com/planet_ink/coffee_mud/Libraries/Sense.java\n+++ b/com/planet_ink/coffee_mud/Libraries/Sense.java\n@@ -1049,7 +1049,7 @@ public class Sense extends StdLibrary implements CMFlagLibrary\n \t\t\t\townerCheck=owner.isContent(I);\r\n \t\t\t}\r\n \t\t\tif(!ownerCheck)\r\n-\t\t\t\treturn I.name()+" is not where it is: "+owner.name();\r\n+\t\t\t\treturn I.name()+" is not where it is: "+owner.name()+" ("+owner.ID()+"): "+CMLib.map().getExtendedRoomID(CMLib.map().roomLocation(owner));\r\n \t\t\tif(owner instanceof MOB)\r\n \t\t\t{\r\n \t\t\t\tfinal MOB M=(MOB)owner;\r\n', 'commit_subject': 'bit more info about bad double-links.', 'repo_name': 'bozimmerman/CoffeeMud', 'committer': {'name': 'bozimmerman', 'email': 'dc45fe023482b3b890b5e574e53c1d051f45b1ef@zimmers.net', 'time_sec': '1550689912', 'tz_offset': '0', 'date': {'seconds': '1550689912'}}, 'commit_tree': 'f7807e9b74f434ba0236351d3d7d6125b6751dda', 'commit_message': 'bit more info about bad double-links.\n\ngit-svn-id: 0cdf8356e41b2d8ccbb41bb76c82068fe80b2514@17788 0d6f1817-ed0e-0410-87c9-987e46238f29\n', 'language_name': 'Java', 'license': 'apache-2.0', 'hunks': '@@ -1049,7 +1049,7 @@ public class Sense extends StdLibrary implements CMFlagLibrary\n \t\t\t\townerCheck=owner.isContent(I);\r\n \t\t\t}\r\n \t\t\tif(!ownerCheck)\r\n-\t\t\t\treturn I.name()+" is not where it is: "+owner.name();\r\n+\t\t\t\treturn I.name()+" is not where it is: "+owner.name()+" ("+owner.ID()+"): "+CMLib.map().getExtendedRoomID(CMLib.map().roomLocation(owner));\r\n \t\t\tif(owner instanceof MOB)\r\n \t\t\t{\r\n \t\t\t\tfinal MOB M=(MOB)owner;\r\n', 'addition_count': 1, 'deletion_count': 1, 'src_file': 'a/com/planet_ink/coffee_mud/Libraries/Sense.java', 'tgt_file': 'b/com/planet_ink/coffee_mud/Libraries/Sense.java', 'file_extension': '.java', 'before_file': 'package com.planet_ink.coffee_mud.Libraries;\nimport com.planet_ink.coffee_mud.core.interfaces.*;\nimport com.planet_ink.coffee_mud.core.*;\nimport com.planet_ink.coffee_mud.core.Directions.DirType;\nimport com.planet_ink.coffee_mud.core.collections.*;\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.Common.interfaces.Faction.Align;\nimport com.planet_ink.coffee_mud.Exits.interfaces.*;\nimport com.planet_ink.coffee_mud.Items.interfaces.*;\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.util.*;\n\nimport com.planet_ink.coffee_mud.Libraries.interfaces.*;\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 Sense extends StdLibrary implements CMFlagLibrary\n{\n\t@Override\n\tpublic String ID()\n\t{\n\t\treturn "Sense";\n\t}\n\n\t@Override\n\tpublic boolean canSee(final MOB M)\n\t{\n\t\treturn (M != null) && (!isSleeping(M)) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_SEE) == 0);\n\t}\n\n\t@Override\n\tpublic boolean canBeLocated(final Physical P)\n\t{\n\t\tif(P instanceof MOB)\n\t\t\treturn true;\n\t\telse\n\t\tif ((P != null)\n\t\t&& (!isSleeping(P))\n\t\t&& ((P.phyStats().sensesMask() & PhyStats.SENSE_UNLOCATABLE) == 0))\n\t\t{\n\t\t\tif ((P instanceof Item) && (((Item) P).container() != null))\n\t\t\t\treturn canBeLocated(((Item) P).container());\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean canSeeHidden(final MOB M)\n\t{\n\t\treturn (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_HIDDEN) == PhyStats.CAN_SEE_HIDDEN);\n\t}\n\n\t@Override\n\tpublic boolean canSeeHiddenItems(final MOB M)\n\t{\n\t\treturn (M != null)\n\t\t\t&& (((M.phyStats().sensesMask() & PhyStats.CAN_SEE_HIDDEN_ITEMS) == PhyStats.CAN_SEE_HIDDEN_ITEMS)\n\t\t\t\t||((M.phyStats().sensesMask() & PhyStats.CAN_SEE_HIDDEN) == PhyStats.CAN_SEE_HIDDEN));\n\t}\n\n\t@Override\n\tpublic boolean canSeeInvisible(final MOB M)\n\t{\n\t\treturn (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_INVISIBLE) == PhyStats.CAN_SEE_INVISIBLE);\n\t}\n\n\t@Override\n\tpublic boolean canSeeEvil(final MOB M)\n\t{\n\t\treturn (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_EVIL) == PhyStats.CAN_SEE_EVIL);\n\t}\n\n\t@Override\n\tpublic boolean canSeeGood(final MOB M)\n\t{\n\t\treturn (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_GOOD) == PhyStats.CAN_SEE_GOOD);\n\t}\n\n\t@Override\n\tpublic boolean canSeeChaos(final Physical P)\n\t{\n\t\treturn (P != null) && P.phyStats().isAmbiance("@CHAOS");\n\t}\n\n\t@Override\n\tpublic boolean canSeeLaw(final Physical P)\n\t{\n\t\treturn (P != null) && P.phyStats().isAmbiance("@LAW");\n\t}\n\n\t@Override\n\tpublic boolean canSeeSneakers(final MOB M)\n\t{\n\t\treturn (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_SNEAKERS) == PhyStats.CAN_SEE_SNEAKERS);\n\t}\n\n\t@Override\n\tpublic boolean canSeeBonusItems(final MOB M)\n\t{\n\t\treturn (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_BONUS) == PhyStats.CAN_SEE_BONUS);\n\t}\n\n\t@Override\n\tpublic boolean canSeeInDark(final MOB M)\n\t{\n\t\treturn (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_DARK) == PhyStats.CAN_SEE_DARK);\n\t}\n\n\t@Override\n\tpublic boolean canSeeVictims(final MOB M)\n\t{\n\t\treturn (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_VICTIM) == PhyStats.CAN_SEE_VICTIM);\n\t}\n\n\t@Override\n\tpublic boolean canSeeInfrared(final MOB M)\n\t{\n\t\treturn (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_INFRARED) == PhyStats.CAN_SEE_INFRARED);\n\t}\n\n\t@Override\n\tpublic boolean canHear(final MOB M)\n\t{\n\t\treturn (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_HEAR) == 0);\n\t}\n\n\t@Override\n\tpublic boolean canTrack(final Physical P)\n\t{\n\t\treturn (P != null) && ((P.phyStats().sensesMask() & PhyStats.CAN_NOT_TRACK) == 0);\n\t}\n\n\t@Override\n\tpublic boolean canAutoAttack(final MOB M)\n\t{\n\t\treturn (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_AUTO_ATTACK) == 0);\n\t}\n\n\t@Override\n\tpublic boolean canConcentrate(final MOB M)\n\t{\n\t\treturn (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_THINK) == 0);\n\t}\n\n\t@Override\n\tpublic boolean canMove(final MOB M)\n\t{\n\t\treturn (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_MOVE) == 0);\n\t}\n\n\t@Override\n\tpublic boolean allowsMovement(final Room R)\n\t{\n\t\treturn (R != null) && ((R.phyStats().sensesMask() & PhyStats.SENSE_ROOMNOMOVEMENT) == 0);\n\t}\n\n\t@Override\n\tpublic boolean allowsMovement(final Area A)\n\t{\n\t\treturn (A != null) && ((A.phyStats().sensesMask() & PhyStats.SENSE_ROOMNOMOVEMENT) == 0);\n\t}\n\n\t@Override\n\tpublic boolean canSmell(final MOB M)\n\t{\n\t\treturn canBreatheHere(M, M.location()) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_SMELL) == 0);\n\t}\n\n\t@Override\n\tpublic boolean canTaste(final MOB M)\n\t{\n\t\treturn (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_TASTE) == 0);\n\t}\n\n\t@Override\n\tpublic boolean canSpeak(final MOB M)\n\t{\n\t\treturn (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_SPEAK) == 0);\n\t}\n\n\t@Override\n\tpublic boolean canBreathe(final MOB M)\n\t{\n\t\treturn (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_BREATHE) == 0);\n\t}\n\n\t@Override\n\tpublic boolean canNotBeCamped(final Physical P)\n\t{\n\t\treturn (P != null) && ((P.phyStats().sensesMask() & PhyStats.CAN_NOT_BE_CAMPED) != 0);\n\t}\n\n\t@Override\n\tpublic boolean canBreatheThis(final MOB M, final int atmoResource)\n\t{\n\t\treturn (canBreathe(M)\n\t\t\t\t&&((atmoResource<0)\n\t\t\t\t\t||(M.charStats().getBreathables().length==0)\n\t\t\t\t\t||(Arrays.binarySearch(M.charStats().getBreathables(), atmoResource)>=0)));\n\t}\n\n\t@Override\n\tpublic boolean canBreatheHere(final MOB M, final Room R)\n\t{\n\t\treturn (M != null) && (canBreatheThis(M, (R == null) ? -1 : R.getAtmosphere()));\n\t}\n\n\t@Override\n\tpublic boolean canSeeMetal(final MOB M)\n\t{\n\t\treturn (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_METAL) == PhyStats.CAN_SEE_METAL);\n\t}\n\n\t@Override\n\tpublic boolean isReadable(final Item I)\n\t{\n\t\treturn (I != null) && ((I.phyStats().sensesMask() & PhyStats.SENSE_ITEMREADABLE) == PhyStats.SENSE_ITEMREADABLE);\n\t}\n\n\t@Override\n\tpublic boolean isGettable(final Item I)\n\t{\n\t\treturn (I != null) && ((I.phyStats().sensesMask() & PhyStats.SENSE_ITEMNOTGET) == 0);\n\t}\n\n\t@Override\n\tpublic boolean isDroppable(final Item I)\n\t{\n\t\treturn (I != null) && ((I.phyStats().sensesMask() & PhyStats.SENSE_ITEMNODROP) == 0);\n\t}\n\n\t@Override\n\tpublic boolean isRemovable(final Item I)\n\t{\n\t\treturn (I != null) && ((I.phyStats().sensesMask() & PhyStats.SENSE_ITEMNOREMOVE) == 0);\n\t}\n\n\t@Override\n\tpublic boolean isCataloged(final Environmental E)\n\t{\n\t\treturn (E instanceof Physical)\n\t\t\t\t&& ((((Physical) E).basePhyStats().disposition() & PhyStats.IS_CATALOGED) == PhyStats.IS_CATALOGED);\n\t}\n\n\t@Override\n\tpublic Rideable.Basis getNavRideBasis(final Environmental E)\n\t{\n\t\tif(E instanceof NavigableItem)\n\t\t\treturn ((NavigableItem)E).navBasis();\n\t\tif((E instanceof Boardable)&&(((Boardable)E).getBoardableItem()!=E))\n\t\t\treturn getNavRideBasis(((Boardable)E).getBoardableItem());\n\t\tif(E instanceof Room)\n\t\t\treturn getNavRideBasis(((Room)E).getArea());\n\t\treturn null;\n\t}\n\n\tprivate Room roomLocation(final Environmental E)\n\t{\n\t\tif(E==null)\n\t\t\treturn null;\n\t\tif((E instanceof Area)&&(!((Area)E).isProperlyEmpty()))\n\t\t\treturn ((Area)E).getRandomProperRoom();\n\t\telse\n\t\tif(E instanceof Room)\n\t\t\treturn (Room)E;\n\t\telse\n\t\tif(E instanceof MOB)\n\t\t\treturn ((MOB)E).location();\n\t\telse\n\t\tif((E instanceof Item)&&(((Item)E).owner() instanceof Room))\n\t\t\treturn (Room)((Item)E).owner();\n\t\telse\n\t\tif((E instanceof Item)&&(((Item)E).owner() instanceof MOB))\n\t\t\treturn ((MOB)((Item)E).owner()).location();\n\t\telse\n\t\tif(E instanceof Ability)\n\t\t\treturn roomLocation(((Ability)E).affecting());\n\t\telse\n\t\tif(E instanceof Exit)\n\t\t\treturn roomLocation(((Exit)E).lastRoomUsedFrom(null));\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic boolean isWithSeenContents(final Physical P)\n\t{\n\t\treturn (P != null)\n\t\t\t&&((P instanceof MOB)\n\t\t\t\t||((P.phyStats().sensesMask() & PhyStats.SENSE_CONTENTSUNSEEN) == 0));\n\t}\n\n\t@Override\n\tpublic boolean isSavable(final Physical P)\n\t{\n\t\tif((P==null)||((P.phyStats().disposition()&PhyStats.IS_UNSAVABLE)==0))\n\t\t{\n\t\t\tif((P instanceof Item)\n\t\t\t&&(((Item)P).container()!=null)\n\t\t\t&&(((Item)P).container()!=P))\n\t\t\t\treturn isSavable(((Item)P).container());\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic void setSavable(final Physical P, final boolean truefalse)\n\t{\n\t\tif(P==null)\n\t\t\treturn;\n\t\tif(CMath.bset(P.basePhyStats().disposition(),PhyStats.IS_UNSAVABLE))\n\t\t{\n\t\t\tif(truefalse)\n\t\t\t{\n\t\t\t\tP.basePhyStats().setDisposition(CMath.unsetb(P.basePhyStats().disposition(),PhyStats.IS_UNSAVABLE));\n\t\t\t\tP.phyStats().setDisposition(CMath.unsetb(P.phyStats().disposition(),PhyStats.IS_UNSAVABLE));\n\t\t\t}\n\t\t}\n\t\telse\n\t\tif(!truefalse)\n\t\t{\n\t\t\tP.basePhyStats().setDisposition(CMath.setb(P.basePhyStats().disposition(),PhyStats.IS_UNSAVABLE));\n\t\t\tP.phyStats().setDisposition(CMath.setb(P.phyStats().disposition(),PhyStats.IS_UNSAVABLE));\n\t\t}\n\t}\n\n\t@Override\n\tpublic void setReadable(final Item I, final boolean truefalse)\n\t{\n\t\tif(I==null)\n\t\t\treturn;\n\t\tif(CMath.bset(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMREADABLE))\n\t\t{\n\t\t\tif(!truefalse)\n\t\t\t{\n\t\t\t\tI.basePhyStats().setSensesMask(CMath.unsetb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMREADABLE));\n\t\t\t\tI.phyStats().setSensesMask(CMath.unsetb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMREADABLE));\n\t\t\t}\n\t\t}\n\t\telse\n\t\tif(truefalse)\n\t\t{\n\t\t\tI.basePhyStats().setSensesMask(CMath.setb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMREADABLE));\n\t\t\tI.phyStats().setSensesMask(CMath.setb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMREADABLE));\n\t\t}\n\t}\n\n\t@Override\n\tpublic boolean isEnspelled(final Physical F)\n\t{\n\t\tfor(int a=0;a<F.numEffects();a++) // personal affects\n\t\t{\n\t\t\tfinal Ability A=F.fetchEffect(a);\n\t\t\tif((A!=null)&&(A.canBeUninvoked())&&(!A.isAutoInvoked())&&(!A.isSavable())\n\t\t\t&&(((A.classificationCode()&Ability.ALL_ACODES)==Ability.ACODE_SPELL)\n\t\t\t   ||((A.classificationCode()&Ability.ALL_ACODES)==Ability.ACODE_PRAYER)\n\t\t\t   ||((A.classificationCode()&Ability.ALL_ACODES)==Ability.ACODE_CHANT)\n\t\t\t   ||((A.classificationCode()&Ability.ALL_ACODES)==Ability.ACODE_SONG)))\n\t\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic void setGettable(final Item I, final boolean truefalse)\n\t{\n\t\tif(I==null)\n\t\t\treturn;\n\t\tif(!CMath.bset(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNOTGET))\n\t\t{\n\t\t\tif(!truefalse)\n\t\t\t{\n\t\t\t\tI.basePhyStats().setSensesMask(CMath.setb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNOTGET));\n\t\t\t\tI.phyStats().setSensesMask(CMath.setb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMNOTGET));\n\t\t\t}\n\t\t}\n\t\telse\n\t\tif(truefalse)\n\t\t{\n\t\t\tI.basePhyStats().setSensesMask(CMath.unsetb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNOTGET));\n\t\t\tI.phyStats().setSensesMask(CMath.unsetb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMNOTGET));\n\t\t}\n\t}\n\n\t@Override\n\tpublic void setDroppable(final Item I, final boolean truefalse)\n\t{\n\t\tif(I==null)\n\t\t\treturn;\n\t\tif(!CMath.bset(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNODROP))\n\t\t{\n\t\t\tif(!truefalse)\n\t\t\t{\n\t\t\t\tI.basePhyStats().setSensesMask(CMath.setb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNODROP));\n\t\t\t\tI.phyStats().setSensesMask(CMath.setb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMNODROP));\n\t\t\t}\n\t\t}\n\t\telse\n\t\tif(truefalse)\n\t\t{\n\t\t\tI.basePhyStats().setSensesMask(CMath.unsetb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNODROP));\n\t\t\tI.phyStats().setSensesMask(CMath.unsetb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMNODROP));\n\t\t}\n\t}\n\n\t@Override\n\tpublic void setRemovable(final Item I, final boolean truefalse)\n\t{\n\t\tif(I==null)\n\t\t\treturn;\n\t\tif(!CMath.bset(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNOREMOVE))\n\t\t{\n\t\t\tif(!truefalse)\n\t\t\t{\n\t\t\t\tI.basePhyStats().setSensesMask(CMath.setb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNOREMOVE));\n\t\t\t\tI.phyStats().setSensesMask(CMath.setb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMNOREMOVE));\n\t\t\t}\n\t\t}\n\t\telse\n\t\tif(truefalse)\n\t\t{\n\t\t\tI.basePhyStats().setSensesMask(CMath.unsetb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNOREMOVE));\n\t\t\tI.phyStats().setSensesMask(CMath.unsetb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMNOREMOVE));\n\t\t}\n\t}\n\n\t@Override\n\tpublic boolean isSeeable(final Physical P)\n\t{\n\t\treturn (P!=null)&&(((P.phyStats().disposition()&PhyStats.IS_NOT_SEEN)==0) || isSleeping(P));\n\t}\n\n\t@Override\n\tpublic boolean isCloaked(final Physical P)\n\t{\n\t\treturn (P!=null)&&((P.phyStats().disposition()&PhyStats.IS_CLOAKED)==PhyStats.IS_CLOAKED);\n\t}\n\n\t@Override\n\tpublic boolean isHidden(final Physical P)\n\t{\n\t\tif(P==null)\n\t\t\treturn false;\n\t\tfinal boolean isInHide=((P.phyStats().disposition()&PhyStats.IS_HIDDEN)==PhyStats.IS_HIDDEN);\n\t\tif((P instanceof MOB)\n\t\t&&(isInHide)\n\t\t&&(((MOB)P).isInCombat()))\n\t\t\treturn false;\n\t\treturn isInHide;\n\t}\n\n\t@Override\n\tpublic boolean isUndead(final MOB mob)\n\t{\n\t\treturn (mob != null)\n\t\t\t\t&& CMProps.getListFileVarSet(CMProps.ListFile.RACIAL_CATEGORY_IS_UNDEAD).contains(mob.charStats().getMyRace().racialCategory());\n\t}\n\n\t@Override\n\tpublic boolean isEggLayer(final Race race)\n\t{\n\t\tfinal String[] eggLayers = new String[]\n\t\t{\n\t\t\t"Amphibian",\n\t\t\t"Avian",\n\t\t\t"Dragon",\n\t\t\t"Reptile",\n\t\t\t"Ophidian",\n\t\t\t"Fish"\n\t\t};\n\t\treturn (race == null) ? false : CMStrings.containsIgnoreCase(eggLayers, race.racialCategory());\n\t}\n\n\t@Override\n\tpublic boolean isFish(final MOB mob)\n\t{\n\t\treturn (mob != null)\n\t\t\t\t&& CMProps.getListFileVarSet(CMProps.ListFile.RACIAL_CATEGORY_IS_FISH).contains(mob.charStats().getMyRace().racialCategory());\n\t}\n\n\t@Override\n\tpublic boolean isMarine(final MOB mob)\n\t{\n\t\treturn (mob != null)\n\t\t\t\t&& CMProps.getListFileVarSet(CMProps.ListFile.RACIAL_CATEGORY_IS_MARINE).contains(mob.charStats().getMyRace().racialCategory());\n\t}\n\n\t@Override\n\tpublic boolean isOutsider(final MOB mob)\n\t{\n\t\treturn (mob != null)\n\t\t\t\t&& CMProps.getListFileVarSet(CMProps.ListFile.RACIAL_CATEGORY_IS_OUTSIDER).contains(mob.charStats().getMyRace().racialCategory());\n\t}\n\n\t@Override\n\tpublic boolean isInsect(final MOB mob)\n\t{\n\t\treturn (mob != null)\n\t\t\t\t&& CMProps.getListFileVarSet(CMProps.ListFile.RACIAL_CATEGORY_IS_INSECT).contains(mob.charStats().getMyRace().racialCategory());\n\t}\n\n\t@Override\n\tpublic boolean isVermin(final MOB mob)\n\t{\n\t\treturn (mob != null)\n\t\t\t\t&& CMProps.getListFileVarSet(CMProps.ListFile.RACIAL_CATEGORY_IS_VERMIN).contains(mob.charStats().getMyRace().racialCategory());\n\t}\n\n\t@Override\n\tpublic boolean isAPlant(final Item I)\n\t{\n\t\treturn (I!=null) && ((I.material()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_VEGETATION);\n\t}\n\n\t@Override\n\tpublic boolean isAPlant(final MOB M)\n\t{\n\t\tif(isGolem(M) && (M!=null) && (M.charStats()!=null) && (M.charStats().getMyRace()!=null))\n\t\t{\n\t\t\tfinal List<RawMaterial> mats = M.charStats().getMyRace().myResources();\n\t\t\tfor(final Item I : mats)\n\t\t\t{\n\t\t\t\tif(((I.material()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_VEGETATION)\n\t\t\t\t||((I.material()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_WOODEN))\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isUnattackable(final Physical P)\n\t{\n\t\treturn (P!=null)&&((P.phyStats().disposition()&PhyStats.IS_UNATTACKABLE)==PhyStats.IS_UNATTACKABLE);\n\t}\n\n\t@Override\n\tpublic boolean isInvisible(final Physical P)\n\t{\n\t\treturn (P!=null)&&((P.phyStats().disposition()&PhyStats.IS_INVISIBLE)==PhyStats.IS_INVISIBLE);\n\t}\n\n\t@Override\n\tpublic boolean isRejuvingItem(final Item I)\n\t{\n\t\tif(I==null)\n\t\t\treturn false;\n\t\tfor(int i=0;i<I.numEffects();i++)\n\t\t{\n\t\t\tif(I.fetchEffect(i) instanceof ItemTicker)\n\t\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isReallyEvil(final FactionMember M)\n\t{\n\t\tif(M != null)\n\t\t{\n\t\t\tFaction F=null;\n\t\t\tFaction.FRange FR=null;\n\t\t\tfor(final Enumeration<String> e=M.factions();e.hasMoreElements();)\n\t\t\t{\n\t\t\t\tF=CMLib.factions().getFaction(e.nextElement());\n\t\t\t\tif(F!=null)\n\t\t\t\t{\n\t\t\t\t\tFR=CMLib.factions().getRange(F.factionID(),M.fetchFaction(F.factionID()));\n\t\t\t\t\tif((FR!=null)&&(FR.alignEquiv()==Faction.Align.EVIL))\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isEvil(final Physical P)\n\t{\n\t\tif(P==null)\n\t\t\treturn false;\n\t\tif ((P.phyStats().disposition()&PhyStats.IS_EVIL)==PhyStats.IS_EVIL)\n\t\t\treturn ((P.phyStats().disposition()&PhyStats.IS_GOOD)==0);\n\t\telse\n\t\tif(P instanceof FactionMember)\n\t\t\treturn isReallyEvil((FactionMember)P);\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isOpenAccessibleContainer(final Item I)\n\t{\n\t\treturn (I instanceof Container)\n\t\t\t &&(CMath.bset(I.phyStats().sensesMask(), PhyStats.SENSE_INSIDEACCESSIBLE))\n\t\t\t &&((Container)I).isOpen();\n\t}\n\n\t@Override\n\tpublic boolean isTracking(final MOB M)\n\t{\n\t\tif(M!=null)\n\t\t\treturn flaggedAffects(M,Ability.FLAG_TRACKING).size()>0;\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isATrackingMonster(final MOB M)\n\t{\n\t\tif(M==null)\n\t\t\treturn false;\n\t\tif(M.isMonster())\n\t\t\treturn flaggedAffects(M,Ability.FLAG_TRACKING).size()>0;\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isReallyGood(final FactionMember M)\n\t{\n\t\tif(M != null)\n\t\t{\n\t\t\tFaction F=null;\n\t\t\tFaction.FRange FR=null;\n\t\t\tfor(final Enumeration<String> e=M.factions();e.hasMoreElements();)\n\t\t\t{\n\t\t\t\tF=CMLib.factions().getFaction(e.nextElement());\n\t\t\t\tif(F!=null)\n\t\t\t\t{\n\t\t\t\t\tFR=CMLib.factions().getRange(F.factionID(),M.fetchFaction(F.factionID()));\n\t\t\t\t\tif((FR!=null)&&(FR.alignEquiv()==Faction.Align.GOOD))\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic String getPlaneOfExistence(final Physical P)\n\t{\n\t\tfinal Area A=CMLib.map().areaLocation(P);\n\t\tif((A!=null)\n\t\t&&(A.numEffects()>0))\n\t\t{\n\t\t\tfor(final Enumeration<Ability> a=A.effects();a.hasMoreElements();)\n\t\t\t{\n\t\t\t\tfinal Ability eA=a.nextElement();\n\t\t\t\tif((eA instanceof PlanarAbility)\n\t\t\t\t&&(eA.text().length()>0))\n\t\t\t\t\treturn eA.text();\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic String getAge(final MOB M)\n\t{\n\t\tfinal Ability A=M.fetchEffect("Age");\n\t\tif((A==null)||(A.displayText().length()==0))\n\t\t{\n\t\t\tif(M.baseCharStats().getStat(CharStats.STAT_AGE)==0)\n\t\t\t\treturn "unknown";\n\t\t\treturn L("@x1 year(s) old",""+M.baseCharStats().getStat(CharStats.STAT_AGE));\n\t\t}\n\t\telse\n\t\t{\n\t\t\tString s=A.displayText();\n\t\t\tif(s.startsWith("("))\n\t\t\t\ts=s.substring(1);\n\t\t\tif(s.endsWith(")"))\n\t\t\t\ts=s.substring(0,s.length()-1);\n\t\t\treturn s;\n\t\t}\n\t}\n\n\t@Override\n\tpublic boolean isGood(final Physical P)\n\t{\n\t\tif(P==null)\n\t\t\treturn false;\n\t\tif ((P.phyStats().disposition()&PhyStats.IS_GOOD)==PhyStats.IS_GOOD)\n\t\t\treturn ((P.phyStats().disposition()&PhyStats.IS_EVIL)==0);\n\t\telse\n\t\tif(P instanceof FactionMember)\n\t\t\treturn isReallyGood((FactionMember)P);\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isLawful(final Physical P)\n\t{\n\t\tif((P != null) && (P.phyStats().isAmbiance("#LAW")))\n\t\t\treturn true;\n\t\tif(P instanceof FactionMember)\n\t\t{\n\t\t\tFaction F=null;\n\t\t\tFaction.FRange FR=null;\n\t\t\tfinal FactionMember M=(FactionMember)P;\n\t\t\tfor(final Enumeration<String> e=M.factions();e.hasMoreElements();)\n\t\t\t{\n\t\t\t\tF=CMLib.factions().getFaction(e.nextElement());\n\t\t\t\tif(F!=null)\n\t\t\t\t{\n\t\t\t\t\tFR=CMLib.factions().getRange(F.factionID(),M.fetchFaction(F.factionID()));\n\t\t\t\t\tif((FR!=null)&&(FR.alignEquiv()==Faction.Align.LAWFUL))\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isChaotic(final Physical P)\n\t{\n\t\tif((P != null) && (P.phyStats().isAmbiance("#CHAOS")))\n\t\t\treturn true;\n\t\tif(P instanceof FactionMember)\n\t\t{\n\t\t\tFaction F=null;\n\t\t\tFaction.FRange FR=null;\n\t\t\tfinal FactionMember M=(FactionMember)P;\n\t\t\tfor(final Enumeration<String> e=M.factions();e.hasMoreElements();)\n\t\t\t{\n\t\t\t\tF=CMLib.factions().getFaction(e.nextElement());\n\t\t\t\tif(F!=null)\n\t\t\t\t{\n\t\t\t\t\tFR=CMLib.factions().getRange(F.factionID(),M.fetchFaction(F.factionID()));\n\t\t\t\t\tif((FR!=null)&&(FR.alignEquiv()==Faction.Align.CHAOTIC))\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isModerate(final Physical P)\n\t{\n\t\tif((P != null) && (P.phyStats().isAmbiance("#MODERATE")))\n\t\t\treturn true;\n\t\tif(P instanceof FactionMember)\n\t\t{\n\t\t\tFaction F=null;\n\t\t\tFaction.FRange FR=null;\n\t\t\tfinal FactionMember M=(FactionMember)P;\n\t\t\tfor(final Enumeration<String> e=M.factions();e.hasMoreElements();)\n\t\t\t{\n\t\t\t\tF=CMLib.factions().getFaction(e.nextElement());\n\t\t\t\tif(F!=null)\n\t\t\t\t{\n\t\t\t\t\tFR=CMLib.factions().getRange(F.factionID(),M.fetchFaction(F.factionID()));\n\t\t\t\t\tif((FR!=null)&&(FR.alignEquiv()==Faction.Align.MODERATE))\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isTrapped(final Physical P)\n\t{\n\t\tfor(final Enumeration<Ability> a=P.effects();a.hasMoreElements();)\n\t\t{\n\t\t\tfinal Ability A=a.nextElement();\n\t\t\tif((A instanceof Trap))\n\t\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isDeadlyOrMaliciousEffect(final PhysicalAgent P)\n\t{\n\t\tif(P==null)\n\t\t\treturn false;\n\t\tif(flaggedBehaviors(P, Behavior.FLAG_POTENTIALLYAUTODEATHING).size()>0)\n\t\t\treturn true;\n\t\tif(isTrapped(P))\n\t\t\treturn true;\n\t\tfor(final Enumeration<Ability> a=P.effects();a.hasMoreElements();)\n\t\t{\n\t\t\tfinal Ability A=a.nextElement();\n\t\t\tif((A instanceof AbilityContainer)\n\t\t\t&&((A.classificationCode()&Ability.ALL_ACODES)==Ability.ACODE_PROPERTY))\n\t\t\t{\n\t\t\t\tfinal AbilityContainer U=(AbilityContainer)A;\n\t\t\t\tfor(final Enumeration<Ability> e=U.allAbilities();e.hasMoreElements();)\n\t\t\t\t{\n\t\t\t\t\tfinal Ability uA=e.nextElement();\n\t\t\t\t\tif((uA!=null)&&(uA.abstractQuality()==Ability.QUALITY_MALICIOUS))\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isPossiblyAggressive(final MOB M)\n\t{\n\t\tif(M==null)\n\t\t\treturn false;\n\t\tfinal List<Behavior> V=flaggedBehaviors(M,Behavior.FLAG_POTENTIALLYAGGRESSIVE);\n\t\treturn ((V==null)||(V.size()==0))? false:true;\n\t}\n\n\t@Override\n\tpublic boolean isAggressiveTo(final MOB M, final MOB toM)\n\t{\n\t\tif((M==null)||(toM==null))\n\t\t\treturn false;\n\t\tfinal List<Behavior> V=flaggedBehaviors(M,Behavior.FLAG_POTENTIALLYAGGRESSIVE);\n\t\tif((V==null)||(V.size()==0))\n\t\t\treturn false;\n\t\tfor(final Behavior B : V)\n\t\t{\n\t\t\tif(B.grantsAggressivenessTo(toM))\n\t\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic String getAlignmentName(final Environmental E)\n\t{\n\t\tif(E instanceof Physical)\n\t\t{\n\t\t\tif((((Physical)E).phyStats().disposition()&PhyStats.IS_GOOD)==PhyStats.IS_GOOD)\n\t\t\t\treturn Faction.Align.GOOD.toString();\n\t\t\tif((((Physical)E).phyStats().disposition()&PhyStats.IS_EVIL)==PhyStats.IS_EVIL)\n\t\t\t\treturn Faction.Align.EVIL.toString();\n\t\t\tif(((Physical)E).phyStats().isAmbiance("#GOOD"))\n\t\t\t\treturn Faction.Align.GOOD.toString();\n\t\t\tif(((Physical)E).phyStats().isAmbiance("#EVIL"))\n\t\t\t\treturn Faction.Align.EVIL.toString();\n\t\t}\n\t\tif(E instanceof MOB)\n\t\t{\n\t\t\tFaction F=null;\n\t\t\tFaction.FRange FR=null;\n\t\t\tfor(final Enumeration<String> e=((MOB)E).factions();e.hasMoreElements();)\n\t\t\t{\n\t\t\t\tF=CMLib.factions().getFaction(e.nextElement());\n\t\t\t\tif(F!=null)\n\t\t\t\t{\n\t\t\t\t\tFR=CMLib.factions().getRange(F.factionID(),((MOB)E).fetchFaction(F.factionID()));\n\t\t\t\t\tif((FR!=null)&&((FR.alignEquiv()==Align.GOOD)||(FR.alignEquiv()==Align.EVIL)))\n\t\t\t\t\t\treturn FR.alignEquiv().toString();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn Faction.Align.NEUTRAL.toString();\n\t}\n\n\t@Override\n\tpublic boolean isReallyNeutral(final FactionMember M)\n\t{\n\t\tif(M != null)\n\t\t{\n\t\t\tFaction F=null;\n\t\t\tFaction.FRange FR=null;\n\t\t\tfor(final Enumeration<String> e=M.factions();e.hasMoreElements();)\n\t\t\t{\n\t\t\t\tF=CMLib.factions().getFaction(e.nextElement());\n\t\t\t\tif(F!=null)\n\t\t\t\t{\n\t\t\t\t\tFR=CMLib.factions().getRange(F.factionID(),M.fetchFaction(F.factionID()));\n\t\t\t\t\tif(FR!=null)\n\t\t\t\t\tswitch(FR.alignEquiv())\n\t\t\t\t\t{\n\t\t\t\t\t\tcase NEUTRAL:\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\tcase EVIL:\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tcase GOOD:\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic boolean isNeutral(final Physical P)\n\t{\n\t\tif(P==null)\n\t\t\treturn false;\n\t\tif((P.phyStats().disposition()&PhyStats.IS_GOOD)==PhyStats.IS_GOOD)\n\t\t{\n\t\t\tif((P.phyStats().disposition()&PhyStats.IS_EVIL)==PhyStats.IS_EVIL)\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\t\telse\n\t\tif((P.phyStats().disposition()&PhyStats.IS_EVIL)==PhyStats.IS_EVIL)\n\t\t\treturn false;\n\t\telse\n\t\tif(P instanceof FactionMember)\n\t\t\treturn isReallyNeutral((FactionMember)P);\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic boolean isSneaking(final Physical P)\n\t{\n\t\treturn (P != null) && ((P.phyStats().disposition() & PhyStats.IS_SNEAKING) == PhyStats.IS_SNEAKING);\n\t}\n\n\t@Override\n\tpublic boolean isABonusItems(final Physical P)\n\t{\n\t\treturn (P != null) && ((P.phyStats().disposition() & PhyStats.IS_BONUS) == PhyStats.IS_BONUS);\n\t}\n\n\t@Override\n\tpublic boolean isInDark(final Physical P)\n\t{\n\t\treturn (P != null) && ((P.phyStats().disposition() & PhyStats.IS_DARK) == PhyStats.IS_DARK);\n\t}\n\n\t@Override\n\tpublic boolean isLightSource(final Physical P)\n\t{\n\t\treturn (P != null) && ((P.phyStats().disposition() & PhyStats.IS_LIGHTSOURCE) == PhyStats.IS_LIGHTSOURCE);\n\t}\n\n\t@Override\n\tpublic boolean isGlowing(final Physical P)\n\t{\n\t\treturn (P != null) && ((isLightSource(P) || ((P.phyStats().disposition() & PhyStats.IS_GLOWING) == PhyStats.IS_GLOWING)));\n\t}\n\n\t@Override\n\tpublic boolean isGolem(final Physical P)\n\t{\n\t\treturn (P != null) && ((P.phyStats().disposition() & PhyStats.IS_GOLEM) == PhyStats.IS_GOLEM);\n\t}\n\n\t@Override\n\tpublic boolean isSleeping(final Physical P)\n\t{\n\t\treturn (P != null) && ((P.phyStats().disposition() & PhyStats.IS_SLEEPING) == PhyStats.IS_SLEEPING);\n\t}\n\n\t@Override\n\tpublic boolean isSitting(final Physical P)\n\t{\n\t\treturn (P != null) && ((P.phyStats().disposition() & PhyStats.IS_SITTING) == PhyStats.IS_SITTING);\n\t}\n\n\t@Override\n\tpublic boolean isFlying(final Physical P)\n\t{\n\t\treturn (P != null) && ((P.phyStats().disposition() & PhyStats.IS_FLYING) == PhyStats.IS_FLYING);\n\t}\n\n\t@Override\n\tpublic boolean isClimbing(final Physical P)\n\t{\n\t\treturn (P != null) && ((P.phyStats().disposition() & PhyStats.IS_CLIMBING) == PhyStats.IS_CLIMBING);\n\t}\n\n\t@Override\n\tpublic boolean isCrawlable(final Physical P)\n\t{\n\t\tif((P instanceof Room)||(P instanceof Area)||(P instanceof Exit))\n\t\t\treturn (P.phyStats().sensesMask() & PhyStats.SENSE_ROOMCRUNCHEDIN) == PhyStats.SENSE_ROOMCRUNCHEDIN;\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isSwimming(final Physical P)\n\t{\n\t\treturn (P != null) && ((P.phyStats().disposition() & PhyStats.IS_SWIMMING) == PhyStats.IS_SWIMMING);\n\t}\n\n\t@Override\n\tpublic boolean isFalling(final Physical P)\n\t{\n\t\treturn (P != null) && ((P.phyStats().disposition() & PhyStats.IS_FALLING) == PhyStats.IS_FALLING);\n\t}\n\n\t@Override\n\tpublic int getFallingDirection(final Physical P)\n\t{\n\t\tif(!isFalling(P))\n\t\t\treturn -1;\n\t\tfinal Ability A=P.fetchEffect("Falling");\n\t\tif((A!=null) && (CMath.s_bool(A.getStat("REVERSED"))))\n\t\t\treturn Directions.UP;\n\t\treturn Directions.DOWN;\n\t}\n\n\t@Override\n\tpublic boolean isRunningLongCommand(final MOB M)\n\t{\n\t\treturn (M != null)\n\t\t\t&& (M.session() != null)\n\t\t\t&& ((System.currentTimeMillis() - M.session().getInputLoopTime()) > 30000);\n\t}\n\n\t@Override\n\tpublic boolean isSwimmingInWater(final Physical P)\n\t{\n\t\tif(!isSwimming(P))\n\t\t\treturn false;\n\t\treturn isWateryRoom(roomLocation(P));\n\t}\n\n\t@Override\n\tpublic boolean isInWilderness(final Physical P)\n\t{\n\t\tif(P instanceof MOB)\n\t\t\treturn isInWilderness(((MOB)P).location());\n\t\telse\n\t\tif(P instanceof Item)\n\t\t\treturn isInWilderness(((Item)P).owner());\n\t\telse\n\t\tif(P instanceof Room)\n\t\t{\n\t\t\t\townerCheck=owner.isContent(I);\r\n\t\t\t}\r\n\t\t\tif(!ownerCheck)\r\n\t\t\t\treturn I.name()+" is not where it is: "+owner.name();\r\n\t\t\tif(owner instanceof MOB)\r\n\t\t\t{\r\n\t\t\t\tfinal MOB M=(MOB)owner;\r\n\t\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isACityRoom(final Physical P)\n\t{\n\t\tif(P instanceof MOB)\n\t\t\treturn isACityRoom(((MOB)P).location());\n\t\telse\n\t\tif(P instanceof Item)\n\t\t\treturn isACityRoom(((Item)P).owner());\n\t\telse\n\t\tif(P instanceof Room)\n\t\t{\n\t\t\tswitch(((Room)P).domainType())\n\t\t\t{\n\t\t\tcase Room.DOMAIN_OUTDOORS_CITY:\n\t\t\t\treturn true;\n\t\t\tcase Room.DOMAIN_OUTDOORS_SPACEPORT:\n\t\t\t\treturn true;\n\t\t\tcase Room.DOMAIN_OUTDOORS_UNDERWATER:\n\t\t\t\tif((P.phyStats().weight()>2)&&(P.maxRange()>4))\n\t\t\t\t\treturn true;\n\t\t\t\treturn false;\n\t\t\tcase Room.DOMAIN_INDOORS_STONE:\n\t\t\t\tif((P.phyStats().weight()>2)&&(P.maxRange()>4))\n\t\t\t\t\treturn true;\n\t\t\t\treturn false;\n\t\t\tdefault:\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean canBeHeardMovingBy(final Physical heard , final MOB hearer)\n\t{\n\t\tif(hearer==heard)\n\t\t\treturn true;\n\t\tif(hearer==null)\n\t\t\treturn false;\n\t\tif(heard==null)\n\t\t\treturn false;\n\t\tif((!isSeeable(heard))&&(isCloaked(heard)))\n\t\t{\n\t\t\tif((!(heard instanceof MOB))\n\t\t\t||(heard.phyStats().level()>hearer.phyStats().level())\n\t\t\t||(!CMSecurity.isASysOp(hearer)))\n\t\t\t\treturn false;\n\t\t}\n\t\tif(!canHear(hearer))\n\t\t\treturn false;\n\t\tif(isSneaking(heard)&&(!canSeeSneakers(hearer)))\n\t\t\treturn false;\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic boolean canBeHeardSpeakingBy(final Physical heard , final MOB hearer)\n\t{\n\t\tif(hearer==heard)\n\t\t\treturn true;\n\t\tif(hearer==null)\n\t\t\treturn false;\n\t\tif(heard==null)\n\t\t\treturn false;\n\t\tif(!canHear(hearer))\n\t\t\treturn false;\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic boolean canSenseMoving(final Physical sensed, final MOB sensor)\n\t{\n\t\treturn (canBeHeardMovingBy(sensed,sensor)||canBeSeenBy(sensed,sensor));\n\t}\n\n\t@Override\n\tpublic boolean canSenseEnteringLeaving(final Physical sensed, final MOB sensor)\n\t{\n\t\treturn canBeHeardMovingBy(sensed,sensor);\n\t}\n\n\t@Override\n\tpublic String validCheck(final Physical P)\n\t{\n\t\tif(P instanceof Room)\n\t\t{\n\t\t\tfinal Room R=(Room)P;\n\t\t\tif(R.amDestroyed())\n\t\t\t\treturn " a destroyed place: "+CMLib.map().getExtendedRoomID(R);\n\t\t\tfinal Area A=R.getArea();\n\t\t\tif((A == null)||(A.amDestroyed()))\n\t\t\t\treturn "a destroyed area: "+CMLib.map().getExtendedRoomID(R);\n\t\t\treturn null;\n\t\t}\n\t\tif(P instanceof MOB)\n\t\t{\n\t\t\tfinal MOB M=(MOB)P;\n\t\t\tfinal Room locR;\n\t\t\tfinal Room startR;\n\t\t\tsynchronized(M)\n\t\t\t{\n\t\t\t\tstartR=M.getStartRoom();\n\t\t\t\tlocR=M.location();\n\t\t\t}\n\t\t\tif(M.amDestroyed())\n\t\t\t\treturn M.name()+" is destroyed";\n\t\t\tif(startR!=null)\n\t\t\t{\n\t\t\t\tfinal String roomReport =validCheck(startR);\n\t\t\t\tif(roomReport != null)\n\t\t\t\t\treturn M.name()+" is from "+roomReport;\n\t\t\t}\n\t\t\tif(!M.amDead())\n\t\t\t{\n\t\t\t\tif(locR == null)\n\t\t\t\t\treturn "*"+M.name()+" is nowhere!";\n\t\t\t\tfinal MOB ultFol = M.amUltimatelyFollowing();\n\t\t\t\tif(!locR.isInhabitant(M)\n\t\t\t\t&&(!M.isPlayer())\n\t\t\t\t&&((ultFol==null)||(!ultFol.isPlayer())))\n\t\t\t\t\treturn "*"+M.name()+" is not where he is: "+CMLib.map().getExtendedRoomID(locR);\n\t\t\t\tfinal String roomReport =validCheck(locR);\n\t\t\t\tif(roomReport != null)\n\t\t\t\t\treturn M.name()+" is from "+roomReport;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\tif(P instanceof Item)\n\t\t{\n\t\t\tfinal Item I=(Item)P;\n\t\t\tfinal ItemPossessor owner;\n\t\t\tsynchronized(I)\n\t\t\t{\n\t\t\t\towner=I.owner();\n\t\t\t}\n\t\t\tif(I.amDestroyed())\n\t\t\t\treturn I.name()+" is destroyed";\n\t\t\tif(owner == null)\n\t\t\t{\n\t\t\t\tif((I instanceof SpaceObject)\n\t\t\t\t&&(CMLib.space().isObjectInSpace((SpaceObject)I)))\n\t\t\t\t\treturn null;\n\t\t\t\treturn I.name()+" is unowned.";\n\t\t\t}\n\t\t\tfinal boolean ownerCheck;\n\t\t\tsynchronized(owner)\n\t\t\t{\n\t\t\t\townerCheck=owner.isContent(I);\n\t\t\t}\n\t\t\tif(!ownerCheck)\n\t\t\t\treturn I.name()+" is not where it is: "+owner.name()+" ("+owner.ID()+"): "+CMLib.map().getExtendedRoomID(CMLib.map().roomLocation(owner));\n\t\t\tif(owner instanceof MOB)\n\t\t\t{\n\t\t\t\tfinal MOB M=(MOB)owner;\n\t\t\t\tif((!M.isPlayer())\n\t\t\t\t&& (!CMLib.threads().isTicking(M, -1))\n\t\t\t\t&& ((M.amUltimatelyFollowing()==null)||(!M.amUltimatelyFollowing().isPlayer())))\n\t\t\t\t\treturn I.name()+" on non-ticking mob: "+M.name()+", in: "+CMLib.map().getExtendedRoomID(M.location());\n\t\t\t\tfinal String mobReport = validCheck(M);\n\t\t\t\tif(mobReport != null)\n\t\t\t\t{\n\t\t\t\t\tif(mobReport.startsWith("*"))\n\t\t\t\t\t\treturn "*"+I.name()+" on "+mobReport.substring(1);\n\t\t\t\t\telse\n\t\t\t\t\t\treturn I.name()+" on "+mobReport;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(owner instanceof Room)\n\t\t\t{\n\t\t\t\tfinal String roomReport = validCheck(owner);\n\t\t\t\tif(roomReport != null)\n\t\t\t\t\treturn I.name()+" in "+roomReport;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic boolean isAliveAwakeMobileUnbound(final MOB mob, final boolean quiet)\n\t{\n\t\tif(!isAliveAwakeMobile(mob,quiet))\n\t\t\treturn false;\n\t\tif(isBound(mob))\n\t\t{\n\t\t\tif(!quiet)\n\t\t\t\tmob.tell(L("You are bound!"));\n\t\t\treturn false;\n\t\t}\n\t\tif(isBoundOrHeld(mob))\n\t\t{\n\t\t\tif(!quiet)\n\t\t\t\tmob.tell(L("You can\'t move!"));\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic boolean isAliveAwakeMobile(final MOB mob, final boolean quiet)\n\t{\n\t\tif(mob==null)\n\t\t\treturn false;\n\t\tif(quiet)\n\t\t{\n\t\t\tif(mob.amDead()\n\t\t\t||(mob.curState().getHitPoints()<0)\n\t\t\t||((mob.phyStats().disposition()&PhyStats.IS_SLEEPING)!=0)\n\t\t\t||((mob.phyStats().sensesMask()&PhyStats.CAN_NOT_MOVE)!=0))\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\t\tif(mob.amDead()||(mob.curState().getHitPoints()<0))\n\t\t{\n\t\t\tmob.tell(L("You are DEAD!"));\n\t\t\treturn false;\n\t\t}\n\t\tif(isSleeping(mob))\n\t\t{\n\t\t\tmob.tell(L("You are sleeping!"));\n\t\t\treturn false;\n\t\t}\n\t\tif(!canMove(mob))\n\t\t{\n\t\t\tmob.tell(L("You can\'t move!"));\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic boolean isStanding(final MOB mob)\n\t{\n\t\treturn (!isSitting(mob))&&(!isSleeping(mob));\n\t}\n\n\t@Override\n\tpublic boolean isBound(final Physical P)\n\t{\n\t\tif((P!=null)&&((P.phyStats().disposition()&PhyStats.IS_BOUND)==PhyStats.IS_BOUND))\n\t\t\treturn true;\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isBoundOrHeld(final Physical P)\n\t{\n\t\tif(P==null)\n\t\t\treturn false;\n\t\tif((P.phyStats().disposition()&PhyStats.IS_BOUND)==PhyStats.IS_BOUND)\n\t\t\treturn true;\n\t\treturn flaggedAnyAffects(P,Ability.FLAG_BINDING|Ability.FLAG_PARALYZING).size()>0;\n\t}\n\n\t@Override\n\tpublic boolean isOnFire(final Physical seen)\n\t{\n\t\tif(seen==null)\n\t\t\treturn false;\n\t\tif(seen.fetchEffect("Burning")!=null)\n\t\t\treturn true;\n\t\tif(seen.fetchEffect("Prayer_FlameWeapon")!=null)\n\t\t\treturn true;\n\t\tif(!(seen instanceof Light))\n\t\t\treturn false;\n\t\tfinal Light light=(Light)seen;\n\t\tif(light.goesOutInTheRain() && light.isLit())\n\t\t\treturn true;\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isFloatingFreely(final Physical P)\n\t{\n\t\treturn ((P.fetchEffect("GravityFloat")!=null)&&(P.phyStats().isAmbiance(L("Floating"))));\n\t}\n\n\t@Override\n\tpublic int getHideScore(final Physical seen)\n\t{\n\t\tif(seen!=null)\n\t\t{\n\t\t\tint hideFactor=seen.phyStats().level();\n\t\t\tif(seen instanceof MOB)\n\t\t\t\thideFactor+=(((MOB)seen).charStats().getStat(CharStats.STAT_DEXTERITY))/2;\n\t\t\tif(CMath.bset(seen.basePhyStats().disposition(),PhyStats.IS_HIDDEN))\n\t\t\t\thideFactor+=100;\n\t\t\telse\n\t\t\tif(seen instanceof MOB)\n\t\t\t{\n\t\t\t\thideFactor+=((MOB)seen).charStats().getSave(CharStats.STAT_SAVE_DETECTION);\n\t\t\t\tif(seen.phyStats().height()>=0)\n\t\t\t\t\thideFactor-=(int)Math.round(Math.sqrt(seen.phyStats().height()));\n\t\t\t}\n\t\t\telse\n\t\t\t\thideFactor+=100;\n\t\t\treturn hideFactor;\n\t\t}\n\t\treturn 0;\n\t}\n\n\t@Override\n\tpublic int getDetectScore(final MOB seer)\n\t{\n\t\tif(seer!=null)\n\t\t{\n\t\t\tint detectFactor=seer.charStats().getStat(CharStats.STAT_WISDOM)/2;\n\t\t\tif(CMath.bset(seer.basePhyStats().sensesMask(),PhyStats.CAN_SEE_HIDDEN))\n\t\t\t\tdetectFactor+=100;\n\t\t\telse // the 100 represents proff, and level represents time searching.\n\t\t\t\tdetectFactor+=seer.charStats().getSave(CharStats.STAT_SAVE_OVERLOOKING);\n\t\t\tif(seer.phyStats().height()>=0)\n\t\t\t\tdetectFactor-=(int)Math.round(Math.sqrt(seer.phyStats().height()));\n\t\t\treturn detectFactor;\n\t\t}\n\t\treturn 0;\n\t}\n\n\t@Override\n\tpublic boolean canBeSeenBy(final Environmental seen , final MOB seer)\n\t{\n\t\tif(seer==seen)\n\t\t\treturn true;\n\t\tif(seen==null)\n\t\t\treturn true;\n\n\t\tif((seer!=null)\n\t\t&&(seer.isAttributeSet(MOB.Attrib.SYSOPMSGS)))\n\t\t\treturn true;\n\n\t\tif(!canSee(seer))\n\t\t\treturn false;\n\n\t\tif(!(seen instanceof Physical))\n\t\t\treturn true;\n\n\t\tfinal Physical seenP=(Physical)seen;\n\n\t\tif((!isSeeable(seenP))&&(seer!=null))\n\t\t{\n\t\t\tif((!(seenP instanceof MOB))\n\t\t\t||(seenP.phyStats().level()>seer.phyStats().level())\n\t\t\t||(!CMSecurity.isASysOp(seer)))\n\t\t\t\treturn false;\n\t\t}\n\n\t\tif((isInvisible(seenP))&&(!canSeeInvisible(seer)))\n\t\t\treturn false;\n\n\t\tif((isHidden(seenP))&&(!(seenP instanceof Room)))\n\t\t{\n\t\t\tif(seer == null)\n\t\t\t\treturn false;\n\t\t\tif(seenP instanceof Item)\n\t\t\t{\n\t\t\t\tif(!canSeeHiddenItems(seer))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\tif(!canSeeHidden(seer))\n\t\t\t{\n\t\t\t\tif((!(seen instanceof MOB))\n\t\t\t\t||(getDetectScore(seer)<getHideScore((MOB)seen)))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tif((seer!=null)&&(!(seenP instanceof Room)))\n\t\t{\n\t\t\tfinal Room R=seer.location();\n\t\t\tif((R!=null)&&(isInDark(R)))\n\t\t\t{\n\t\t\t\tif((isGlowing(seenP))||(isLightSource(seer)))\n\t\t\t\t\treturn true;\n\t\t\t\tif(canSeeInDark(seer))\n\t\t\t\t\treturn true;\n\t\t\t\tif((!isGolem(seenP))&&(canSeeInfrared(seer))&&(seenP instanceof MOB))\n\t\t\t\t\treturn true;\n\t\t\t\tif((canSeeVictims(seer))&&(seer.getVictim()==seenP))\n\t\t\t\t\treturn true;\n\t\t\t\tfinal Area area=R.getArea();\n\t\t\t\tif(area != null)\n\t\t\t\t{\n\t\t\t\t\tif((area.getClimateObj().canSeeTheMoon(R,null))\n\t\t\t\t\t&&(area.getTimeObj().getMoonPhase(R)==TimeClock.MoonPhase.FULL))\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\tif(isInDark(seenP))\n\t\t{\n\t\t\tif((seenP instanceof Room)\n\t\t\t&&(((Room)seenP).getArea().getClimateObj().canSeeTheMoon(((Room)seenP),null)))\n\t\t\t{\n\t\t\t\tswitch(((Room)seenP).getArea().getTimeObj().getMoonPhase((Room)seenP))\n\t\t\t\t{\n\t\t\t\tcase FULL:\n\t\t\t\tcase WAXGIBBOUS:\n\t\t\t\tcase WANEGIBBOUS:\n\t\t\t\t\treturn true;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(isLightSource(seer))\n\t\t\t\treturn true;\n\t\t\tif(canSeeInDark(seer))\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic boolean canBarelyBeSeenBy(final Environmental seen , final MOB seer)\n\t{\n\t\tif(!canBeSeenBy(seen,seer))\n\t\t{\n\t\t\tif((seer!=null)&&(!(seen instanceof Room)))\n\t\t\t{\n\t\t\t\tfinal Room R=seer.location();\n\t\t\t\tif((R!=null)&&(isInDark(R)))\n\t\t\t\t{\n\t\t\t\t\tif(R.getArea().getClimateObj().canSeeTheMoon(R,null))\n\t\t\t\t\t{\n\t\t\t\t\t\treturn R.getArea().getTimeObj().getMoonPhase(R) != TimeClock.MoonPhase.NEW;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\tif((seen instanceof Physical) && (isInDark((Physical)seen)))\n\t\t\t{\n\t\t\t\tif((seen instanceof Room)\n\t\t\t\t&&(((Room)seen).getArea().getClimateObj().canSeeTheMoon(((Room)seen),null)))\n\t\t\t\t{\n\t\t\t\t\tswitch(((Room)seen).getArea().getTimeObj().getMoonPhase((Room)seen))\n\t\t\t\t\t{\n\t\t\t\t\t\tcase FULL:\n\t\t\t\t\t\tcase WAXGIBBOUS:\n\t\t\t\t\t\tcase WANEGIBBOUS:\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tcase NEW:\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean canActAtAll(final Tickable affecting)\n\t{\n\t\tif(affecting instanceof MOB)\n\t\t{\n\t\t\tfinal MOB monster=(MOB)affecting;\n\t\t\tif((!isAliveAwakeMobile(monster,true))\n\t\t\t||(monster.location()==null)\n\t\t\t||(!isInTheGame(monster,false)))\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean canFreelyBehaveNormal(final Tickable affecting)\n\t{\n\t\tif(affecting instanceof MOB)\n\t\t{\n\t\t\tfinal MOB monster=(MOB)affecting;\n\t\t\tif((!canActAtAll(monster))\n\t\t\t||(monster.isInCombat())\n\t\t\t||((monster.amFollowing()!=null)&&(!monster.isPlayer()))\n\t\t\t||(monster.curState().getHitPoints()<(monster.maxState().getHitPoints()/2)))\n\t\t\t\treturn false;\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\n\t@Override\n\tpublic Directions.DirType getDirType(final Physical P)\n\t{\n\t\t// never check the location of P generically, as\n\t\t// it would create ambiguity with getInDirtype when\n\t\t// a mob is passed in.\n\t\tif(P instanceof Boardable)\n\t\t{\n\t\t\tfinal Item I=((Boardable)P).getBoardableItem();\n\t\t\tif(I instanceof SpaceShip)\n\t\t\t\treturn DirType.SHIP;\n\t\t\tif(I instanceof NavigableItem)\n\t\t\t{\n\t\t\t\tswitch(((NavigableItem)I).navBasis())\n\t\t\t\t{\n\t\t\t\tcase AIR_FLYING:\n\t\t\t\t\treturn DirType.SHIP;\n\t\t\t\tcase LAND_BASED:\n\t\t\t\t\treturn DirType.CARAVAN;\n\t\t\t\tcase WAGON:\n\t\t\t\t\treturn DirType.CARAVAN;\n\t\t\t\tcase WATER_BASED:\n\t\t\t\t\treturn DirType.SHIP;\n\t\t\t\tdefault:\n\t\t\t\t\treturn DirType.COMPASS;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn DirType.SHIP;\n\t\t}\n\t\tif(P instanceof Rider)\n\t\t{\n\t\t\tfinal Rider rider=(Rider)P;\n\t\t\tfinal Rideable ride=rider.riding();\n\t\t\tif((ride instanceof Boardable)\n\t\t\t&&(((Boardable)ride).Name().equals(rider.Name())))\n\t\t\t\treturn getDirType(ride);\n\t\t}\n\t\tif(P instanceof Room)\n\t\t\treturn getDirType(((Room)P).getArea());\n\t\treturn DirType.COMPASS;\n\t}\n\n\t@Override\n\tpublic Directions.DirType getInDirType(final MOB M)\n\t{\n\t\treturn (M==null)?DirType.COMPASS:getDirType(M.location());\n\t}\n\n\t@Override\n\tpublic boolean isSeenTheSameWay(final MOB seer, final Physical seen1, final Physical seen2)\n\t{\n\t\tif(canBeSeenBy(seen1,seer)!=canBeSeenBy(seen2,seer))\n\t\t\treturn false;\n\t\tif((isEvil(seen1)!=isEvil(seen2))&&(canSeeEvil(seer)))\n\t\t\treturn false;\n\t\tif((isGood(seen1)!=isGood(seen2))&&(canSeeGood(seer)))\n\t\t\treturn false;\n\t\tif((isABonusItems(seen1)!=isABonusItems(seen2))&&(canSeeBonusItems(seer)))\n\t\t\treturn false;\n\t\tif(isInvisible(seen1)!=isInvisible(seen2))\n\t\t\treturn false;\n\t\tif(isSneaking(seen1)!=isSneaking(seen2))\n\t\t\treturn false;\n\t\tif(isHidden(seen1)!=isHidden(seen2))\n\t\t\treturn false;\n\t\tif(isFlying(seen1)!=isFlying(seen2))\n\t\t\treturn false;\n\t\tif(isBound(seen1)!=isBound(seen2))\n\t\t\treturn false;\n\t\tif(isFalling(seen1)!=isFalling(seen2))\n\t\t\treturn false;\n\t\tif(isGlowing(seen1)!=isGlowing(seen2))\n\t\t\treturn false;\n\t\tif(isGolem(seen1)!=isGolem(seen2))\n\t\t\treturn false;\n\t\tif(canSeeMetal(seer)&&(seen1 instanceof Item)&&(seen2 instanceof Item)\n\t\t\t&&((((Item)seen1).material()&RawMaterial.MATERIAL_MASK)!=(((Item)seen2).material()&RawMaterial.MATERIAL_MASK)))\n\t\t   return false;\n\t\tif(!CMStrings.compareStringArraysIgnoreCase(seen1.phyStats().ambiances(),seen2.phyStats().ambiances()))\n\t\t\treturn false;\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic boolean isWaterWorthy(final Physical P)\n\t{\n\t\tif(P==null)\n\t\t\treturn false;\n\t\tif(isSwimming(P)\n\t\t&&((!(P instanceof Item))||(!((Item)P).subjectToWearAndTear())||(((Item)P).usesRemaining()>0)))\n\t\t\treturn true;\n\t\tif((P instanceof Rider)&&(((Rider)P).riding()!=null))\n\t\t\treturn isWaterWorthy(((Rider)P).riding());\n\t\tif((P instanceof Rideable)\n\t\t&&(((Rideable)P).rideBasis()==Rideable.Basis.WATER_BASED)\n\t\t&&(P instanceof MOB))\n\t\t\treturn true;\n\t\tif(P instanceof Item)\n\t\t{\n\t\t\tfinal List<Item> V=new Vector<Item>();\n\t\t\tif(P instanceof Container)\n\t\t\t\tV.addAll(((Container)P).getDeepContents());\n\t\t\tif(!V.contains(P))\n\t\t\t\tV.add((Item)P);\n\t\t\tlong totalWeight=0;\n\t\t\tlong totalFloatilla=0;\n\t\t\tfinal RawMaterial.CODES codes = RawMaterial.CODES.instance();\n\t\t\tfor(int v=0;v<V.size();v++)\n\t\t\t{\n\t\t\t\tfinal Item I=V.get(v);\n\t\t\t\ttotalWeight+=I.basePhyStats().weight();\n\t\t\t\ttotalFloatilla+=totalWeight*codes.bouancy(I.material());\n\t\t\t}\n\t\t\tif(P instanceof Container)\n\t\t\t{\n\t\t\t\tfinal long cap=((Container)P).capacity();\n\t\t\t\tif(totalWeight<cap)\n\t\t\t\t{\n\t\t\t\t\ttotalFloatilla+=(cap-totalWeight);\n\t\t\t\t\ttotalWeight+=cap-totalWeight;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(totalWeight<=0)\n\t\t\t\treturn true;\n\n\t\t\tif(isFalling(P))\n\t\t\t\treturn false;\n\t\t\treturn (totalFloatilla/totalWeight)<=1000;\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isInFlight(final Physical P)\n\t{\n\t\tif(P==null)\n\t\t\treturn false;\n\t\tif(isFlying(P))\n\t\t\treturn true;\n\t\tif(P instanceof Rider)\n\t\t\treturn isInFlight(((Rider)P).riding());\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isAnimalIntelligence(final MOB M)\n\t{\n\t\treturn (M!=null)&&(M.charStats().getStat(CharStats.STAT_INTELLIGENCE)<2);\n\t}\n\n\t@Override\n\tpublic boolean isVegetable(final MOB M)\n\t{\n\t\treturn (M != null)\n\t\t\t\t&& CMProps.getListFileVarSet(CMProps.ListFile.RACIAL_CATEGORY_IS_VEGETATION).contains(M.charStats().getMyRace().racialCategory());\n\t}\n\n\t@Override\n\tpublic boolean isMobile(final PhysicalAgent P)\n\t{\n\t\tif(P!=null)\n\t\t{\n\t\t\tif((P instanceof Boardable)&&(!((Boardable)P).amDestroyed()))\n\t\t\t\treturn true;\n\t\t\tfor(final Enumeration<Behavior> e=P.behaviors();e.hasMoreElements();)\n\t\t\t{\n\t\t\t\tfinal Behavior B=e.nextElement();\n\t\t\t\tif((B!=null)&&(CMath.bset(B.flags(),Behavior.FLAG_MOBILITY)))\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic List<Behavior> flaggedBehaviors(final PhysicalAgent P, final long flag)\n\t{\n\t\tfinal Vector<Behavior> V=new Vector<Behavior>(1);\n\t\tif(P!=null)\n\t\t{\n\t\t\tfor(final Enumeration<Behavior> e=P.behaviors();e.hasMoreElements();)\n\t\t\t{\n\t\t\t\tfinal Behavior B=e.nextElement();\n\t\t\t\tif((B!=null)&&(CMath.bset(B.flags(),flag)))\n\t\t\t\t{\n\t\t\t\t\tV.addElement(B);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn V;\n\t}\n\n\t@Override\n\tpublic List<Ability> domainAnyAffects(final Physical P, final int domain)\n\t{\n\t\tfinal Vector<Ability> V=new Vector<Ability>(1);\n\t\tif(P!=null)\n\t\t{\n\t\t\tif(domain>Ability.ALL_ACODES)\n\t\t\t{\n\t\t\t\tP.eachEffect(new EachApplicable<Ability>()\n\t\t\t\t{\n\t\t\t\t\t@Override\n\t\t\t\t\tpublic void apply(final Ability A)\n\t\t\t\t\t{\n\t\t\t\t\t\tif((A.classificationCode()&Ability.ALL_DOMAINS)==domain)\n\t\t\t\t\t\t\tV.addElement(A);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tP.eachEffect(new EachApplicable<Ability>()\n\t\t\t\t{\n\t\t\t\t\t@Override\n\t\t\t\t\tpublic void apply(final Ability A)\n\t\t\t\t\t{\n\t\t\t\t\t\tif((A.classificationCode()&Ability.ALL_ACODES)==domain)\n\t\t\t\t\t\t\tV.addElement(A);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn V;\n\t}\n\n\t@Override\n\tpublic List<Ability> domainAffects(final Physical P, final int domain)\n\t{\n\t\treturn domainAnyAffects(P,domain);\n\t}\n\n\t@Override\n\tpublic List<Ability> domainAbilities(final MOB M, final int domain)\n\t{\n\t\tfinal Vector<Ability> V=new Vector<Ability>(1);\n\t\tif(M!=null)\n\t\t{\n\t\t\tif(domain>Ability.ALL_ACODES)\n\t\t\t{\n\t\t\t\tfor(final Enumeration<Ability> a=M.allAbilities();a.hasMoreElements();)\n\t\t\t\t{\n\t\t\t\t\tfinal Ability A=a.nextElement();\n\t\t\t\t\tif((A!=null)&&((A.classificationCode()&Ability.ALL_DOMAINS)==domain))\n\t\t\t\t\t{\n\t\t\t\t\t\tV.addElement(A);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\tfor(final Enumeration<Ability> a=M.allAbilities();a.hasMoreElements();)\n\t\t\t{\n\t\t\t\tfinal Ability A=a.nextElement();\n\t\t\t\tif((A!=null)&&((A.classificationCode()&Ability.ALL_ACODES)==domain))\n\t\t\t\t{\n\t\t\t\t\tV.addElement(A);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn V;\n\t}\n\n\t@Override\n\tpublic List<Ability> flaggedAnyAffects(final Physical P, final long flag)\n\t{\n\t\tfinal Vector<Ability> V=new Vector<Ability>(1);\n\t\tif(P!=null)\n\t\t{\n\t\t\tP.eachEffect(new EachApplicable<Ability>()\n\t\t\t{\n\t\t\t\t@Override\n\t\t\t\tpublic void apply(final Ability A)\n\t\t\t\t{\n\t\t\t\t\tif((A.flags()&flag)>0)\n\t\t\t\t\t\tV.addElement(A);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\treturn V;\n\t}\n\n\t@Override\n\tpublic List<Ability> matchedAffects(final MOB invoker, final Physical P, final long flag, final int abilityCode, final int domain)\n\t{\n\t\tfinal Vector<Ability> V=new Vector<Ability>(1);\n\t\tif(P!=null)\n\t\t{\n\t\t\tP.eachEffect(new EachApplicable<Ability>()\n\t\t\t{\n\t\t\t\t@Override\n\t\t\t\tpublic void apply(final Ability A)\n\t\t\t\t{\n\t\t\t\t\tif(((invoker==null)||(A.invoker()==invoker))\n\t\t\t\t\t&&(((flag<0)||(A.flags()&flag)>0))\n\t\t\t\t\t&&(((abilityCode<0)||((A.classificationCode()&Ability.ALL_ACODES)==abilityCode)))\n\t\t\t\t\t&&(((domain<0)||((A.classificationCode()&Ability.ALL_DOMAINS)==domain))))\n\t\t\t\t\t\tV.addElement(A);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\treturn V;\n\t}\n\n\t@Override\n\tpublic List<Ability> flaggedAffects(final Physical P, final long flag)\n\t{\n\t\treturn flaggedAnyAffects(P,flag);\n\t}\n\n\t@Override\n\tpublic List<Ability> flaggedAbilities(final MOB M, final long flag)\n\t{\n\t\tfinal Vector<Ability> V=new Vector<Ability>();\n\t\tif(M!=null)\n\t\t{\n\t\t\tfor(final Enumeration<Ability> a=M.allAbilities();a.hasMoreElements();)\n\t\t\t{\n\t\t\t\tfinal Ability A=a.nextElement();\n\t\t\t\tif((A!=null)&&(CMath.bset(A.flags(),flag)))\n\t\t\t\t{\n\t\t\t\t\tV.addElement(A);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn V;\n\t}\n\n\t@Override\n\tpublic boolean canAccess(final MOB mob, final Area A)\n\t{\n\t\tif(A==null)\n\t\t\treturn false;\n\t\tif((isHidden(A)) && (mob==null))\n\t\t\treturn false;\n\t\tif(((!isHidden(A))\n\t\t\t&&(mob.location()!=null)&&(mob.location().getArea().getTimeObj()==A.getTimeObj()))\n\t\t||(CMSecurity.isASysOp(mob))\n\t\t||(A.amISubOp(mob.Name())))\n\t\t\treturn true;\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean canAccess(final MOB mob, final Room R)\n\t{\n\t\tif(R==null)\n\t\t\treturn false;\n\t\tif(isHidden(R))\n\t\t{\n\t\t\tif(mob!=null)\n\t\t\t{\n\t\t\t\tif((CMSecurity.isASysOp(mob))\n\t\t\t\t||(R.getArea().amISubOp(mob.Name())))\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\telse\n\t\tif((mob!=null)\n\t\t&&(mob.location()!=null)\n\t\t&&(mob.location().getArea().getTimeObj()!=R.getArea().getTimeObj()))\n\t\t{\n\t\t\tif((mob==null)||(!CMSecurity.isASysOp(mob)))\n\t\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic boolean isMetal(final Environmental E)\n\t{\n\t\tif(E instanceof Item)\n\t\t{\n\t\t\treturn((((Item)E).material()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_METAL)\n\t\t\t\t||((((Item)E).material()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_MITHRIL);\n\t\t}\n\t\tif(E instanceof MOB)\n\t\t{\n\t\t\tfinal MOB M=(MOB)E;\n\t\t\tif(isGolem(M) && (M.charStats()!=null) && (M.charStats().getMyRace()!=null))\n\t\t\t{\n\t\t\t\tfinal List<RawMaterial> mats = M.charStats().getMyRace().myResources();\n\t\t\t\tfor(final Item I : mats)\n\t\t\t\t{\n\t\t\t\t\tif(CMath.bset(I.material(), RawMaterial.MATERIAL_METAL)\n\t\t\t\t\t||CMath.bset(I.material(), RawMaterial.MATERIAL_MITHRIL))\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isAiryRoom(final Room R)\n\t{\n\t\tif(R==null)\n\t\t\treturn false;\n\t\tswitch(R.domainType())\n\t\t{\n\t\tcase Room.DOMAIN_INDOORS_AIR:\n\t\tcase Room.DOMAIN_OUTDOORS_AIR:\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isWateryRoom(final Room R)\n\t{\n\t\tif(R==null)\n\t\t\treturn false;\n\t\tswitch(R.domainType())\n\t\t{\n\t\tcase Room.DOMAIN_INDOORS_UNDERWATER:\n\t\tcase Room.DOMAIN_OUTDOORS_UNDERWATER:\n\t\tcase Room.DOMAIN_INDOORS_WATERSURFACE:\n\t\tcase Room.DOMAIN_OUTDOORS_WATERSURFACE:\n\t\t\treturn true;\n\t\t}\n\t\treturn ((R.getAtmosphere()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_LIQUID)\n\t\t\t\t||isSwimming(R);\n\t}\n\n\t/**\n\t * Returns whether the given room, whatever is\n\t * watery, such as a water surface, etc.\n\t * @param R the room to check\n\t * @return true if it is water surfacy, false otherwise\n\t */\n\t@Override\n\tpublic boolean isWaterySurfaceRoom(final Room R)\n\t{\n\t\tif(R==null)\n\t\t\treturn false;\n\t\tswitch(R.domainType())\n\t\t{\n\t\tcase Room.DOMAIN_INDOORS_WATERSURFACE:\n\t\tcase Room.DOMAIN_OUTDOORS_WATERSURFACE:\n\t\t\treturn true;\n\t\t}\n\t\treturn ((R.getAtmosphere()&RawMaterial.MATERIAL_MASK)!=RawMaterial.MATERIAL_LIQUID)\n\t\t\t\t&&isSwimming(R);\n\t}\n\n\t/**\n\t * Returns whether the given room, whatever is\n\t * the surface of deep water, such as a water surface, etc.\n\t * with an underwater room\n\t * @param R the room to check\n\t * @return true if it is water surfacy, false otherwise\n\t */\n\t@Override\n\tpublic boolean isDeepWaterySurfaceRoom(final Room R)\n\t{\n\n\t\tif((R==null)||(!isWaterySurfaceRoom(R)))\n\t\t\treturn false;\n\t\tR.giveASky(0);\n\t\treturn isUnderWateryRoom(R.getRoomInDir(Directions.DOWN));\n\t}\n\n\t/**\n\t * Returns whether the given room, whatever is\n\t * watery, such as an underwater, etc.\n\t * @param R the room to check\n\t * @return true if it is underwatery, false otherwise\n\t */\n\t@Override\n\tpublic boolean isUnderWateryRoom(final Room R)\n\t{\n\t\tif(R==null)\n\t\t\treturn false;\n\t\tswitch(R.domainType())\n\t\t{\n\t\tcase Room.DOMAIN_INDOORS_UNDERWATER:\n\t\tcase Room.DOMAIN_OUTDOORS_UNDERWATER:\n\t\t\treturn true;\n\t\t}\n\t\treturn ((R.getAtmosphere()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_LIQUID)\n\t\t\t\t&&isSwimming(R);\n\t}\n\n\t@Override\n\tpublic boolean isInTheGame(final Environmental E, final boolean reqInhabitation)\n\t{\n\t\tif(E instanceof MOB)\n\t\t\treturn isInTheGame((MOB)E,reqInhabitation);\n\t\tif(E instanceof Item)\n\t\t\treturn isInTheGame((Item)E,reqInhabitation);\n\t\tif(E instanceof Room)\n\t\t\treturn isInTheGame((Room)E,reqInhabitation);\n\t\tif(E instanceof Area)\n\t\t\treturn isInTheGame((Area)E,reqInhabitation);\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic boolean isInTheGame(final MOB E, final boolean reqInhabitation)\n\t{\n\t\treturn (E.location()!=null)\n\t\t\t\t&& E.amActive()\n\t\t\t\t&&((!reqInhabitation)||E.location().isInhabitant(E));\n\t}\n\n\t@Override\n\tpublic boolean isInTheGame(final Item E, final boolean reqInhabitation)\n\t{\n\t\tif(E.owner() instanceof MOB)\n\t\t{\n\t\t\treturn isInTheGame((MOB)E.owner(),reqInhabitation);\n\t\t}\n\t\telse\n\t\tif(E.owner() instanceof Room)\n\t\t{\n\t\t\treturn ((!E.amDestroyed())\n\t\t\t\t\t&&((!reqInhabitation)||(((Room)E.owner()).isContent(E))));\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isInTheGame(final Room E, final boolean reqInhabitation)\n\t{\n\t\treturn CMLib.map().getRoom(CMLib.map().getExtendedRoomID(E))==E;\n\t}\n\n\t@Override\n\tpublic boolean isInTheGame(final Area E, final boolean reqInhabitation)\n\t{\n\t\treturn CMLib.map().getArea(E.Name())==E;\n\t}\n\n\t@Override\n\tpublic boolean isEnchanted(final Item I)\n\t{\n\t\t// poison is not an enchantment.\n\t\t// neither is disease, or standard properties.\n\t\tfor(int i=0;i<I.numEffects();i++)\n\t\t{\n\t\t\tfinal Ability A=I.fetchEffect(i);\n\t\t\tif(A!=null)\n\t\t\t{\n\t\t\t\tif(((A.classificationCode()&Ability.ALL_ACODES)!=Ability.ACODE_PROPERTY)\n\t\t\t\t&&((A.classificationCode()&Ability.ALL_ACODES)!=Ability.ACODE_DISEASE)\n\t\t\t\t&&((A.classificationCode()&Ability.ALL_ACODES)!=Ability.ACODE_POISON)\n\t\t\t\t&&(!(A instanceof Deity.DeityWorshipper))\n\t\t\t\t&&(!CMath.bset(A.flags(), Ability.FLAG_NONENCHANTMENT)))\n\t\t\t\t\treturn true;\n\t\t\t\tif(A instanceof AbilityContainer)\n\t\t\t\t{\n\t\t\t\t\tfor(final Enumeration<Ability> a=((AbilityContainer)A).abilities();a.hasMoreElements();)\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal Ability A1=a.nextElement();\n\t\t\t\t\t\tif((A1!=null)\n\t\t\t\t\t\t&&((A1.classificationCode()&Ability.ALL_ACODES)!=Ability.ACODE_PROPERTY)\n\t\t\t\t\t\t&&((A1.classificationCode()&Ability.ALL_ACODES)!=Ability.ACODE_DISEASE)\n\t\t\t\t\t\t&&((A1.classificationCode()&Ability.ALL_ACODES)!=Ability.ACODE_POISON)\n\t\t\t\t\t\t&&(!CMath.bset(A1.flags(), Ability.FLAG_NONENCHANTMENT)))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(!(I instanceof RawMaterial))\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tfinal Ability[] natEff = RawMaterial.CODES.EFFECTA(I.material());\n\t\t\t\t\t\t\tif(natEff == null)\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\tboolean found=false;\n\t\t\t\t\t\t\tfor(final Ability A2 : natEff)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif((A2 != null)\n\t\t\t\t\t\t\t\t&&(A2.ID().equals(A.ID()))\n\t\t\t\t\t\t\t\t&&(((AbilityContainer)A2).fetchAbility(A1.ID())!=null))\n\t\t\t\t\t\t\t\t\tfound=true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(!found)\n\t\t\t\t\t\t\t\treturn true;\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((I instanceof Weapon)||(I instanceof Armor))\n\t\t\treturn this.isABonusItems(I);\n\t\treturn false;\n\t}\n\n\tpublic boolean isAgingThing(final Physical P)\n\t{\n\t\tif(P==null)\n\t\t\treturn false;\n\t\tfinal Ability A=P.fetchEffect("Age");\n\t\tif((A!=null)&&(CMath.isInteger(A.text())&&(CMath.s_long(A.text())>Short.MAX_VALUE)))\n\t\t\treturn true;\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean isChild(final Environmental E)\n\t{\n\t\treturn isBaby(E)||((E instanceof MOB)&&(((MOB)E).isMonster())&&(isAgingThing((MOB)E)));\n\t}\n\n\t@Override\n\tpublic boolean isBaby(final Environmental E)\n\t{\n\t\treturn ((E instanceof CagedAnimal)&&(isAgingThing((CagedAnimal)E)));\n\t}\n\n\t@Override\n\tpublic boolean isStillAffectedBy(final Physical obj, final List<Ability> oneOf, final boolean anyTallF)\n\t{\n\t\tfor(int a=oneOf.size()-1;a>=0;a--)\n\t\t{\n\t\t\tif(obj.fetchEffect(oneOf.get(a).ID())==null)\n\t\t\t{\n\t\t\t\tif(!anyTallF)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif(anyTallF)\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn !anyTallF;\n\t}\n\n\t@Override\n\tpublic String getDispositionDescList(final Physical obj, final boolean useVerbs)\n\t{\n\t\tif(obj == null)\n\t\t\treturn "";\n\t\tfinal int disposition = obj.phyStats().disposition();\n\t\tfinal StringBuffer buf=new StringBuffer("");\n\t\tif(useVerbs)\n\t\t{\n\t\t\tfor(int i=0;i<PhyStats.IS_VERBS.length;i++)\n\t\t\t\tif(CMath.isSet(disposition,i))\n\t\t\t\t\tbuf.append(PhyStats.IS_VERBS[i]+", ");\n\t\t}\n\t\telse\n\t\tfor(int i=0;i<PhyStats.IS_CODES.length;i++)\n\t\t{\n\t\t\tif(CMath.isSet(disposition,i))\n\t\t\t\tbuf.append(PhyStats.IS_CODES[i]+", ");\n\t\t}\n\t\tString buff=buf.toString();\n\t\tif(buff.endsWith(", "))\n\t\t\tbuff=buff.substring(0,buff.length()-2).trim();\n\t\treturn buff;\n\t}\n\n\t@Override\n\tpublic String getSensesDescList(final Physical obj, final boolean useVerbs)\n\t{\n\t\tif(obj == null)\n\t\t\treturn "";\n\t\tfinal int senses = obj.phyStats().sensesMask();\n\t\tfinal StringBuffer buf=new StringBuffer("");\n\t\tif(useVerbs)\n\t\t{\n\t\t\tfor(int i=0;i<PhyStats.CAN_SEE_VERBS.length;i++)\n\t\t\t\tif(CMath.isSet(senses,i))\n\t\t\t\t\tbuf.append(PhyStats.CAN_SEE_VERBS[i]+", ");\n\t\t}\n\t\telse\n\t\tfor(int i=0;i<PhyStats.CAN_SEE_CODES.length;i++)\n\t\t{\n\t\t\tif(CMath.isSet(senses,i))\n\t\t\t\tbuf.append(PhyStats.CAN_SEE_CODES[i]+", ");\n\t\t}\n\t\tString buff=buf.toString();\n\t\tif(buff.endsWith(", "))\n\t\t\tbuff=buff.substring(0,buff.length()-2).trim();\n\t\treturn buff;\n\t}\n\n\t@Override\n\tpublic int getDispositionIndex(String name)\n\t{\n\t\tname=name.toUpperCase().trim();\n\t\tfor(int code=0;code<PhyStats.IS_CODES.length-1;code++)\n\t\t{\n\t\t\tif(PhyStats.IS_CODES[code].endsWith(name))\n\t\t\t{\n\t\t\t\treturn code;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t}\n\n\t@Override\n\tpublic int getSensesIndex(String name)\n\t{\n\t\tname=name.toUpperCase().trim();\n\t\tfor(int code=0;code<PhyStats.CAN_SEE_CODES.length-1;code++)\n\t\t{\n\t\t\tif(PhyStats.CAN_SEE_CODES[code].endsWith(name))\n\t\t\t{\n\t\t\t\treturn code;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t}\n\n\t@Override\n\tpublic String getAbilityType(final Ability A)\n\t{\n\t\tif(A==null)\n\t\t\treturn "";\n\t\treturn Ability.ACODE_DESCS[A.classificationCode()&Ability.ALL_ACODES];\n\t}\n\n\t@Override\n\tpublic String getAbilityType_(final Ability A)\n\t{\n\t\tif(A==null)\n\t\t\treturn "";\n\t\treturn Ability.ACODE_DESCS_[A.classificationCode()&Ability.ALL_ACODES];\n\t}\n\n\t@Override\n\tpublic String getAbilityDomain(final Ability A)\n\t{\n\t\tif(A==null)\n\t\t\treturn "";\n\t\treturn Ability.DOMAIN_DESCS[(A.classificationCode()&Ability.ALL_DOMAINS)>>5];\n\t}\n\n\t@Override\n\tpublic int getAbilityType(final String name)\n\t{\n\t\tfor(int i=0;i<Ability.ACODE_DESCS.length;i++)\n\t\t{\n\t\t\tif(name.equalsIgnoreCase(Ability.ACODE_DESCS[i]))\n\t\t\t\treturn i;\n\t\t}\n\t\treturn -1;\n\t}\n\n\t@Override\n\tpublic int getAbilityType_(final String name)\n\t{\n\t\tfor(int i=0;i<Ability.ACODE_DESCS_.length;i++)\n\t\t{\n\t\t\tif(name.equalsIgnoreCase(Ability.ACODE_DESCS_[i]))\n\t\t\t\treturn i;\n\t\t}\n\t\treturn -1;\n\t}\n\n\t@Override\n\tpublic int getAbilityDomain(final String name)\n\t{\n\t\tfor(int i=0;i<Ability.DOMAIN_DESCS.length;i++)\n\t\t{\n\t\t\tif(name.equalsIgnoreCase(Ability.DOMAIN_DESCS[i]))\n\t\t\t\treturn i<<5;\n\t\t}\n\t\treturn -1;\n\t}\n\n\t@Override\n\tpublic boolean isAControlledFollower(final MOB invoker, final MOB mob, Ability A)\n\t{\n\t\tif((mob==null)||(mob==invoker)||(!mob.isMonster()))\n\t\t\treturn false;\n\t\tif(A==null)\n\t\t\treturn mob.getStartRoom()==null;\n\t\tA = mob.fetchEffect(A.ID());\n\t\tif(A==null)\n\t\t\treturn false;\n\t\tif((A.invoker() == invoker)||(A.invoker()==null))\n\t\t\treturn true;\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean hasAControlledFollower(final MOB invoker, final Ability A)\n\t{\n\t\tif(invoker==null)\n\t\t\treturn false;\n\t\tfinal Room R = invoker.location();\n\t\tif(R==null)\n\t\t\treturn false;\n\t\tfor(int r=0;r<R.numInhabitants();r++)\n\t\t{\n\t\t\tif(isAControlledFollower(invoker, R.fetchInhabitant(r), A))\n\t\t\t\treturn true;\n\t\t}\n\t\tfinal Set<MOB> H = invoker.getGroupMembers(new HashSet<MOB>());\n\t\tfor (final MOB mob : H)\n\t\t{\n\t\t\tif(isAControlledFollower(invoker, mob, A))\n\t\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic String getDispositionBlurbs(final Physical seen, final MOB seer)\n\t{\n\t\tif(seen == null)\n\t\t\treturn "";\n\t\tfinal PhyStats pStats=seen.phyStats();\n\t\tif(pStats == null)\n\t\t\treturn ""; // an exit?\n\t\tfinal String[] ambiances=pStats.ambiances();\n\t\tif(!pStats.isAmbiance("-ALL"))\n\t\t{\n\t\t\tfinal StringBuilder say=new StringBuilder("^N");\n\t\t\tif(!pStats.isAmbiance("-MOST"))\n\t\t\t{\n\t\t\t\tif((seer!=null)\n\t\t\t\t&&(seer.phyStats().sensesMask()>0))\n\t\t\t\t{\n\t\t\t\t\tif((canSeeEvil(seer))&&(isEvil(seen))&&(!pStats.isAmbiance("-EVIL")))\n\t\t\t\t\t\tsay.append(" (glowing ^rred^?)");\n\t\t\t\t\tif((canSeeGood(seer))&&(isGood(seen))&&(!pStats.isAmbiance("-GOOD")))\n\t\t\t\t\t\tsay.append(" (glowing ^bblue^?)");\n\t\t\t\t\tif((canSeeInvisible(seer))&&(isInvisible(seen))&&(!pStats.isAmbiance("-INVISIBLE")))\n\t\t\t\t\t\tsay.append(" (^yinvisible^?)");\n\t\t\t\t\tif((canSeeSneakers(seer))&&(isSneaking(seen))&&(!pStats.isAmbiance("-SNEAKING")))\n\t\t\t\t\t\tsay.append(" (^ysneaking^?)");\n\t\t\t\t\tif((isHidden(seen))\n\t\t\t\t\t&&(canSeeHidden(seer)||((seen instanceof Item)&&(canSeeHiddenItems(seer))))\n\t\t\t\t\t&&(!pStats.isAmbiance("-HIDDEN")))\n\t\t\t\t\t\tsay.append(" (^yhidden^?)");\n\t\t\t\t\tif((canSeeInfrared(seer))&&(!isGolem(seen))&&(seen instanceof MOB)&&(isInDark(seer.location()))&&(!pStats.isAmbiance("-HEAT")))\n\t\t\t\t\t\tsay.append(" (^rheat aura^?)");\n\t\t\t\t\tif((canSeeBonusItems(seer))&&(isABonusItems(seen))&&(!pStats.isAmbiance("-MAGIC")))\n\t\t\t\t\t\tsay.append(" (^wmagical aura^?)");\n\t\t\t\t\tif((canSeeMetal(seer))&&(seen instanceof Item)&&(!pStats.isAmbiance("-METAL")))\n\t\t\t\t\t{\n\t\t\t\t\t\tif((((Item)seen).material()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_METAL)\n\t\t\t\t\t\t\tsay.append(" (^wmetallic aura^?)");\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif((((Item)seen).material()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_MITHRIL)\n\t\t\t\t\t\t\tsay.append(" (^wmithril aura^?)");\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif((isGlowing(seen))&&(!(seen instanceof Room))&&(!pStats.isAmbiance("-GLOWING")))\n\t\t\t\t\tsay.append(" (^gglowing^?)");\n\t\t\t\tif((seen instanceof MOB) && isRunningLongCommand((MOB)seen)&&(!pStats.isAmbiance("-BUSY")))\n\t\t\t\t\tsay.append(" (^gbusy^?)");\n\t\t\t\tif((canSeeChaos(seer))&&(isChaotic(seen))&&(!pStats.isAmbiance("-CHAOS")))\n\t\t\t\t\tsay.append(" (glowing ^ppurple^?)");\n\t\t\t\tif((canSeeLaw(seer))&&(isLawful(seen))&&(!pStats.isAmbiance("-LAW")))\n\t\t\t\t\tsay.append(" (glowing ^wwhite^?)");\n\t\t\t\tfor(int i=0;i<ambiances.length;i++)\n\t\t\t\t{\n\t\t\t\t\tswitch(ambiances[i].charAt(0))\n\t\t\t\t\t{\n\t\t\t\t\tcase \'(\':\n\t\t\t\t\t\tif(ambiances[i].startsWith("(?)"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal int x=ambiances[i].indexOf(\':\');\n\t\t\t\t\t\t\tif(canBeHeardSpeakingBy(seen, seer))\n\t\t\t\t\t\t\t\tsay.append(" ("+ambiances[i].substring(3,(x>3)?x:ambiances[i].length())+")");\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\tif(x>3)\n\t\t\t\t\t\t\t\tsay.append(" ("+ambiances[i].substring(x+1)+")");\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tsay.append(" "+ambiances[i]);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \'-\':\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \'@\':\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \'#\':\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal String ambiCode = ambiances[i].substring(1);\n\t\t\t\t\t\tif((pStats.isAmbiance("@"+ambiCode))\n\t\t\t\t\t\t&&(!ambiCode.equals("LAW"))\n\t\t\t\t\t\t&&(!ambiCode.equals("CHAOS")))\n\t\t\t\t\t\t\tsay.append(" ("+ambiCode+")");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tsay.append(" ("+ambiances[i]+")");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(isBound(seen)&&(!pStats.isAmbiance("-BOUND")))\n\t\t\t\tsay.append(" (^Wbound^?)");\n\t\t\tif(isFlying(seen)&&(!(seen instanceof Exit))&&(!pStats.isAmbiance("-FLYING")))\n\t\t\t\tsay.append(" (^pflying^?)");\n\t\t\tif((isFalling(seen))&&(!pStats.isAmbiance("-FALLING")))\n\t\t\t{\n\t\t\t\tfinal Room R=roomLocation(seen);\n\t\t\t\tswitch(R.domainType())\n\t\t\t\t{\n\t\t\t\tcase Room.DOMAIN_INDOORS_AIR:\n\t\t\t\tcase Room.DOMAIN_OUTDOORS_AIR:\n\t\t\t\t\tsay.append(" (^pfalling^?)");\n\t\t\t\t\tbreak;\n\t\t\t\tcase Room.DOMAIN_INDOORS_WATERSURFACE:\n\t\t\t\tcase Room.DOMAIN_OUTDOORS_WATERSURFACE:\n\t\t\t\tcase Room.DOMAIN_INDOORS_UNDERWATER:\n\t\t\t\tcase Room.DOMAIN_OUTDOORS_UNDERWATER:\n\t\t\t\tcase Room.DOMAIN_OUTDOORS_SEAPORT:\n\t\t\t\tcase Room.DOMAIN_INDOORS_SEAPORT:\n\t\t\t\tcase Room.DOMAIN_INDOORS_CAVE_SEAPORT:\n\t\t\t\t\tif(R.rawDoors()[Directions.DOWN]==null)\n\t\t\t\t\t\tsay.append(" (^psunk^?)");\n\t\t\t\t\telse\n\t\t\t\t\t\tsay.append(" (^psinking^?)");\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tif(!(seen instanceof MOB))\n\t\t\t\t\t\tsay.append(" (^pfalling^?)");\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(say.length()>1)\n\t\t\t{\n\t\t\t\tsay.append(" ");\n\t\t\t\treturn say.toString();\n\t\t\t}\n\t\t}\n\t\treturn "";\n\t}\n\n\tprotected boolean isAlcoholEffect(final Ability A)\n\t{\n\t\tif(A!=null)\n\t\t{\n\t\t\tif(CMath.bset(A.flags(),Ability.FLAG_INTOXICATING))\n\t\t\t\treturn true;\n\t\t\tif(A instanceof AbilityContainer)\n\t\t\t{\n\t\t\t\tfor(final Enumeration<Ability> a2=((AbilityContainer)A).allAbilities();a2.hasMoreElements();)\n\t\t\t\t{\n\t\t\t\t\tfinal Ability A2=a2.nextElement();\n\t\t\t\t\tif((A2!=null)&&(CMath.bset(A2.flags(),Ability.FLAG_INTOXICATING)))\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic List<String> getParents(final Physical thang)\n\t{\n\t\tfinal List<String> parents=new Vector<String>(2);\n\t\tfinal MOB babe;\n\t\tif(thang instanceof MOB)\n\t\t\tbabe=(MOB)thang;\n\t\telse\n\t\tif(thang instanceof CagedAnimal)\n\t\t\tbabe=((CagedAnimal)thang).unCageMe();\n\t\telse\n\t\t\treturn parents;\n\t\tfor(final Enumeration<Tattoo> t= babe.tattoos();t.hasMoreElements();)\n\t\t{\n\t\t\tfinal Tattoo T=t.nextElement();\n\t\t\tif(T.name().startsWith("PARENT:"))\n\t\t\t\tparents.add(T.name().substring(7).trim());\n\t\t}\n\t\tif(thang instanceof CagedAnimal)\n\t\t\tbabe.destroy();\n\t\treturn parents;\n\t}\n\n\t@Override\n\tpublic boolean isAlcoholic(final Physical thang)\n\t{\n\t\tif(thang==null)\n\t\t\treturn false;\n\t\tif(thang instanceof Item)\n\t\t{\n\t\t\tif(((Item)thang).material()==RawMaterial.RESOURCE_LIQUOR)\n\t\t\t\treturn true;\n\t\t}\n\t\tif(thang instanceof LiquidHolder)\n\t\t{\n\t\t\tif(((LiquidHolder)thang).liquidType()==RawMaterial.RESOURCE_LIQUOR)\n\t\t\t\treturn true;\n\t\t\tif(thang instanceof Container)\n\t\t\t{\n\t\t\t\tfor(final Item I : ((Container)thang).getContents())\n\t\t\t\t{\n\t\t\t\t\tif((I!=thang) && isAlcoholic(I))\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(thang instanceof SpellHolder)\n\t\t\t{\n\t\t\t\tfor(final Ability A : ((SpellHolder)thang).getSpells())\n\t\t\t\t{\n\t\t\t\t\tif(isAlcoholEffect(A))\n\t\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfor(int a=0;a<thang.numEffects();a++) // personal\n\t\t{\n\t\t\tfinal Ability A=thang.fetchEffect(a);\n\t\t\tif(this.isAlcoholEffect(A))\n\t\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic String getPresentDispositionVerb(final Physical seen, final ComingOrGoing flag_msgType)\n\t{\n\t\tString type=null;\n\t\tif(isFalling(seen))\n\t\t{\n\t\t\tif((seen instanceof Item)\n\t\t\t&&(((Item)seen).owner() instanceof Room)\n\t\t\t&&(isWateryRoom((Room)((Item)seen).owner())))\n\t\t\t\ttype="sinks";\n\t\t\telse\n\t\t\tif((seen instanceof MOB)\n\t\t\t&&(isWateryRoom(((MOB)seen).location())))\n\t\t\t\ttype="sinks";\n\t\t\telse\n\t\t\t\ttype="falls";\n\t\t}\n\t\telse\n\t\tif(isSleeping(seen))\n\t\t{\n\t\t\tif(flag_msgType!=ComingOrGoing.IS)\n\t\t\t\ttype=(seen instanceof MOB) ? "sleepwalks" : "floats";\n\t\t\telse\n\t\t\t\ttype="sleeps";\n\t\t}\n\t\telse\n\t\tif(isSneaking(seen))\n\t\t\ttype="sneaks";\n\t\telse\n\t\tif(isHidden(seen))\n\t\t\ttype="prowls";\n\t\telse\n\t\tif(isSitting(seen))\n\t\t{\n\t\t\tif(flag_msgType!=ComingOrGoing.IS)\n\t\t\t\ttype="crawls";\n\t\t\telse\n\t\t\tif(seen instanceof MOB)\n\t\t\t\ttype="sits";\n\t\t\telse\n\t\t\t\ttype="sits";\n\t\t}\n\t\telse\n\t\tif(isFlying(seen))\n\t\t\ttype="flies";\n\t\telse\n\t\tif((isClimbing(seen))&&(flag_msgType!=ComingOrGoing.IS))\n\t\t\ttype="climbs";\n\t\telse\n\t\tif(isSwimmingInWater(seen))\n\t\t\ttype="swims";\n\t\telse\n\t\tif(flag_msgType != null)\n\t\t{\n\t\t\tswitch(flag_msgType)\n\t\t\t{\n\t\t\tcase ARRIVES:\n\t\t\t\tif(seen instanceof MOB)\n\t\t\t\t\treturn ((MOB)seen).charStats().getArriveStr();\n\t\t\t\telse\n\t\t\t\t\treturn "arrives";\n\t\t\tcase LEAVES:\n\t\t\t\tif(seen instanceof MOB)\n\t\t\t\t\treturn ((MOB)seen).charStats().getLeaveStr();\n\t\t\t\telse\n\t\t\t\t\treturn "leaves";\n\t\t\tdefault:\n\t\t\t\treturn "is";\n\t\t\t}\n\t\t}\n\n\t\tif(flag_msgType==ComingOrGoing.ARRIVES)\n\t\t\treturn type+" in";\n\t\treturn type;\n\n\t}\n\n\t@Override\n\tpublic String getDispositionStateList(final MOB mob)\n\t{\n\t\tfinal StringBuilder str=new StringBuilder("");\n\t\tif(isClimbing(mob))\n\t\t\tstr.append("climbing, ");\n\t\tif((mob.phyStats().disposition()&PhyStats.IS_EVIL)>0)\n\t\t{\n\t\t\tif((mob.phyStats().disposition()&PhyStats.IS_GOOD)>0)\n\t\t\t\tstr.append("sacred, ");\n\t\t\telse\n\t\t\t\tstr.append("evil, ");\n\t\t}\n\t\tif(isFalling(mob))\n\t\t\tstr.append("falling, ");\n\t\tif(isBound(mob))\n\t\t\tstr.append("bound, ");\n\t\tif(isFlying(mob))\n\t\t\tstr.append("flies, ");\n\t\tif((mob.phyStats().disposition()&PhyStats.IS_GOOD)>0)\n\t\t{\n\t\t\tif((mob.phyStats().disposition()&PhyStats.IS_EVIL)==0)\n\t\t\t\tstr.append("good, ");\n\t\t}\n\t\tif(isHidden(mob))\n\t\t\tstr.append("hidden, ");\n\t\tif(isInDark(mob))\n\t\t\tstr.append("darkness, ");\n\t\tif(isInvisible(mob))\n\t\t\tstr.append("invisible, ");\n\t\tif(isGlowing(mob))\n\t\t\tstr.append("glowing, ");\n\t\tif(isCloaked(mob))\n\t\t\tstr.append("cloaked, ");\n\t\tif(!isSeeable(mob))\n\t\t\tstr.append("unseeable, ");\n\t\tif(isSitting(mob))\n\t\t\tstr.append("crawls, ");\n\t\tif(isSleeping(mob))\n\t\t\tstr.append("sleepy, ");\n\t\tif(isSneaking(mob))\n\t\t\tstr.append("sneaks, ");\n\t\tif(isSwimming(mob))\n\t\t\tstr.append("swims, ");\n\t\tif(str.toString().endsWith(", "))\n\t\t\treturn str.toString().substring(0,str.length()-2);\n\t\treturn str.toString();\n\t}\n\n\t@Override\n\tpublic String getSensesStateList(final MOB mob)\n\t{\n\t\tfinal StringBuilder str=new StringBuilder("");\n\t\tif(!canHear(mob))\n\t\t\tstr.append("deaf, ");\n\t\tif(!canSee(mob))\n\t\t\tstr.append("blind, ");\n\t\tif(!canMove(mob))\n\t\t\tstr.append("can\'t move, ");\n\t\tif(canSeeBonusItems(mob))\n\t\t\tstr.append(L("detect magic, "));\n\t\tif(canSeeEvil(mob))\n\t\t\tstr.append(L("detect evil, "));\n\t\tif(canSeeGood(mob))\n\t\t\tstr.append(L("detect good, "));\n\t\tif(canSeeHidden(mob))\n\t\t\tstr.append("see hidden, ");\n\t\telse\n\t\tif(canSeeHiddenItems(mob))\n\t\t\tstr.append("see hidden items, ");\n\t\tif(canSeeInDark(mob))\n\t\t\tstr.append(L("darkvision, "));\n\t\tif(canSeeInfrared(mob))\n\t\t\tstr.append(L("infravision, "));\n\t\tif(canSeeInvisible(mob))\n\t\t\tstr.append(L("see invisible, "));\n\t\tif(canSeeMetal(mob))\n\t\t\tstr.append(L("metalvision, "));\n\t\tif(canSeeSneakers(mob))\n\t\t\tstr.append(L("see sneaking, "));\n\t\tif(!canSmell(mob))\n\t\t\tstr.append("can\'t smell, ");\n\t\tif(!canSpeak(mob))\n\t\t\tstr.append("can\'t speak, ");\n\t\tif(!canTaste(mob))\n\t\t\tstr.append("can\'t eat, ");\n\t\tif(str.toString().endsWith(", "))\n\t\t\treturn str.toString().substring(0,str.length()-2);\n\t\treturn str.toString();\n\t}\n}\n', 'message': 'bit more info about bad double-links.\n\ngit-svn-id: 0cdf8356e41b2d8ccbb41bb76c82068fe80b2514@17788 0d6f1817-ed0e-0410-87c9-987e46238f29\n', 'author_name': 'bozimmerman', 'lang': 'java'}