<NME> StdMOB.java <BEF> package com.planet_ink.coffee_mud.MOBS; import com.planet_ink.coffee_mud.core.interfaces.*; import com.planet_ink.coffee_mud.core.interfaces.EachApplicable.ApplyAffectPhyStats; import com.planet_ink.coffee_mud.core.interfaces.ItemPossessor.Move; import com.planet_ink.coffee_mud.core.*; import com.planet_ink.coffee_mud.core.CMSecurity.DisFlag; import com.planet_ink.coffee_mud.core.collections.*; import com.planet_ink.coffee_mud.core.exceptions.CMException; import com.planet_ink.coffee_mud.core.exceptions.CharStatOutOfRangeException; import com.planet_ink.coffee_mud.Abilities.interfaces.*; import com.planet_ink.coffee_mud.Areas.interfaces.*; import com.planet_ink.coffee_mud.Areas.interfaces.Area.State; 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.FData; import com.planet_ink.coffee_mud.Common.interfaces.PlayerStats.PlayerCombatStat; import com.planet_ink.coffee_mud.Exits.interfaces.*; import com.planet_ink.coffee_mud.Items.Basic.StdItem; 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.lang.ref.WeakReference; import java.util.*; import java.util.Map.Entry; import java.util.concurrent.atomic.AtomicBoolean; import com.planet_ink.coffee_mud.Libraries.interfaces.*; import com.planet_ink.coffee_mud.Libraries.interfaces.AchievementLibrary.Event; import com.planet_ink.coffee_mud.Libraries.interfaces.ChannelsLibrary.CMChannel; /* Copyright 2000-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, e\ither express or implied. See the License for the specific language governing permissions and limitations under the License. */ //STOP-ECLIPSE-FORMATTING // @formatter: off public class StdMOB implements MOB { @Override public String ID() { return "StdMOB"; } public String _name = ""; protected CharStats baseCharStats = (CharStats) CMClass.getCommon("DefaultCharStats"); protected CharStats charStats = (CharStats) CMClass.getCommon("DefaultCharStats"); protected PhyStats phyStats = (PhyStats) CMClass.getCommon("DefaultPhyStats"); protected PhyStats basePhyStats = (PhyStats) CMClass.getCommon("DefaultPhyStats"); protected PlayerStats playerStats = null; protected Triggerer triggerer = (Triggerer) CMClass.getCommon("NonTriggerer"); protected boolean amDestroyed = false; protected boolean removeFromGame = false; protected volatile boolean amDead = false; protected volatile Room location = null; protected volatile Room lastLocation = null; protected Rideable riding = null; protected volatile Session mySession = null; protected Object description = null; protected String displayText = ""; protected String rawImageName = null; protected String cachedImageName = null; protected Object miscText = null; protected String[] xtraValues = null; // gained attributes protected int experience = 0; protected int practices = 0; protected int trains = 0; protected long ageMinutes = 0; protected int money = 0; protected double moneyVariation = 0.0; protected double speedAdj = CMProps.getSpeedAdjustment(); protected int attributesBitmap = MOB.Attrib.NOTEACH.getBitCode(); protected String databaseID = ""; protected int tickAgeCounter = 0; protected int recoverTickCter = 1; protected int validChkCounter = 60; private long expirationDate = 0; private int manaConsumeCter = CMLib.dice().roll(1, 10, 0); private volatile double freeActions = 0.0; // the core state values public CharState curState = (CharState) CMClass.getCommon("DefaultCharState"); public CharState maxState = (CharState) CMClass.getCommon("DefaultCharState"); public CharState baseState = (CharState) CMClass.getCommon("DefaultCharState"); private long lastTickedTime = 0; private long lastCommandTime = System.currentTimeMillis(); protected Room possStartRoom = null; protected String liegeID = ""; protected int wimpHitPoint = 0; protected int questPoint = 0; protected MOB victim = null; protected Followable<MOB> amFollowing = null; protected MOB soulMate = null; protected int atRange = -1; protected long peaceTime = 0; protected boolean kickFlag = false; protected MOB me = this; protected int tickStatus = Tickable.STATUS_NOT; /* containers of items and attributes */ protected SVector<Item> inventory = new SVector<Item>(1); protected CMUniqSortSVec<Ability> abilitys = new CMUniqSortSVec<Ability>(1); protected int[] abilityUseTrig = new int[Ability.USAGEINDEX_TOTAL]; protected STreeMap<String, int[][]> abilityUseCache = new STreeMap<String, int[][]>(); protected STreeMap<String, Integer> expertises = new STreeMap<String, Integer>(); protected SVector<Ability> affects = new SVector<Ability>(1); protected CMUniqSortSVec<Behavior> behaviors = new CMUniqSortSVec<Behavior>(1); protected CMUniqNameSortSVec<Tattoo> tattoos = new CMUniqNameSortSVec<Tattoo>(1); protected volatile PairList<MOB, Short> followers = null; protected LinkedList<QMCommand> commandQue = new LinkedList<QMCommand>(); protected SVector<ScriptingEngine> scripts = new SVector<ScriptingEngine>(1); protected volatile List<Ability> racialAffects = null; protected volatile List<Ability> clanAffects = null; protected SHashtable<String, FData> factions = new SHashtable<String, FData>(1); protected volatile WeakReference<Item> possWieldedItem = null; protected volatile WeakReference<Item> possHeldItem = null; protected ApplyAffectPhyStats<Ability> affectPhyStats = new ApplyAffectPhyStats<Ability>(this); protected ApplyRecAffectPhyStats<Item> recoverAffectP = new ApplyRecAffectPhyStats<Item>(this); @SuppressWarnings("rawtypes") protected ApplyAffectCharStats affectCharStats = new ApplyAffectCharStats(this); @SuppressWarnings("rawtypes") protected ApplyAffectCharState affectCharState = new ApplyAffectCharState(this); protected OrderedMap<String, Pair<Clan, Integer>> clans = new OrderedMap<String, Pair<Clan, Integer>>(); public StdMOB() { super(); // CMClass.bumpCounter(this,CMClass.CMObjectType.MOB);//removed for mem // & perf Race R = CMClass.getRace("Human"); if (R == null) R = CMClass.getRace("StdRace"); baseCharStats().setMyRace(R); basePhyStats().setLevel(1); speedAdj = CMProps.getSpeedAdjustment(); xtraValues = CMProps.getExtraStatCodesHolder(this); } private static class QMCommand { public Object commandObj = null; public double actionCost = 0.0; public long nextCheck = System.currentTimeMillis() - 1; public int seconds = -1; public int metaFlags = 0; public List<String> commandVector = null; } private static final Converter<Pair<MOB, Short>, MOB> FollowerConverter = new Pair.FirstConverter<MOB, Short>(); /** * EachApplicable class that recovers item and affect phyStats */ public static final class ApplyRecAffectPhyStats<T extends StatsAffecting> extends ApplyAffectPhyStats<T> { public ApplyRecAffectPhyStats(final Physical me) { super(me); } @Override public void apply(final T a) { ((Affectable) a).recoverPhyStats(); super.apply(a); } } /** * EachApplicable class that affect charStats */ public static class ApplyAffectCharStats<T extends StatsAffecting> implements EachApplicable<T> { protected final MOB me; public ApplyAffectCharStats(final MOB me) { this.me = me; } @Override public void apply(final T a) { a.affectCharStats(me, me.charStats()); } } /** * EachApplicable class that affect charState */ public static class ApplyAffectCharState<T extends StatsAffecting> implements EachApplicable<T> { protected final MOB me; public ApplyAffectCharState(final MOB me) { this.me = me; } @Override public void apply(final T a) { a.affectCharState(me, me.maxState()); } } @Override public long lastTickedDateTime() { return lastTickedTime; } @Override public void flagVariableEq() { lastTickedTime = -3; } @Override public long getAgeMinutes() { return ageMinutes; } @Override public int getPractices() { return practices; } @Override public int getExperience() { return experience; } @Override public int getExpNextLevel() { return CMLib.leveler().getLevelExperience(this, basePhyStats().level()); } @Override public int getExpPrevLevel() { if (basePhyStats().level() <= 1) return 0; final int neededLowest = CMLib.leveler().getLevelExperience(this, basePhyStats().level() - 2); return neededLowest; } @Override public int getExpNeededDelevel() { if (basePhyStats().level() <= 1) return 0; if ((CMSecurity.instance(session())._isDisabled(CMSecurity.DisFlag.EXPERIENCE)) || (charStats().getCurrentClass().expless()) || (charStats().getMyRace().expless())) return 0; int ExpPrevLevel = getExpPrevLevel(); if (ExpPrevLevel > getExperience()) ExpPrevLevel = getExperience() - 1000; return getExperience() - ExpPrevLevel; } @Override public int getExpNeededLevel() { final int lastPlayerLevel = CMProps.get(session()).getInt(CMProps.Int.LASTPLAYERLEVEL); if ((lastPlayerLevel > 0) && (lastPlayerLevel <= basePhyStats().level())) return Integer.MAX_VALUE; if ((CMSecurity.instance(session())._isDisabled(CMSecurity.DisFlag.EXPERIENCE)) || (charStats().getCurrentClass().expless()) || (charStats().getMyRace().expless())) return Integer.MAX_VALUE; int expNextLevel = getExpNextLevel(); if (expNextLevel < getExperience()) expNextLevel = getExperience() + 1; return expNextLevel - getExperience(); } @Override public int getTrains() { return trains; } @Override public int getMoney() { return money; } @Override public double getMoneyVariation() { return moneyVariation; } @Override public int getAttributesBitmap() { return attributesBitmap; } @Override public void setAgeMinutes(final long newVal) { ageMinutes = newVal; } @Override public void setExperience(final int newVal) { if ((newVal > experience) && (this.playerStats() != null)) { this.playerStats().bumpLevelCombatStat(PlayerCombatStat.EXPERIENCE_TOTAL, basePhyStats().level(), newVal - experience); this.playerStats().setLastXPAwardMillis(System.currentTimeMillis()); } experience = newVal; } @Override public void setPractices(final int newVal) { practices = newVal; } @Override public void setTrains(final int newVal) { trains = newVal; } @Override public void setMoney(final int newVal) { money = newVal; } @Override public void setMoneyVariation(final double newVal) { moneyVariation = newVal; } @Override public void setAttributesBitmap(final int bitmap) { this.attributesBitmap = bitmap; } @Override public void setAttribute(final Attrib attrib, final boolean set) { if (set) { attributesBitmap = attributesBitmap | attrib.getBitCode(); } else { attributesBitmap = attributesBitmap & ~attrib.getBitCode(); } } @Override public boolean isAttributeSet(final MOB.Attrib attrib) { return (attributesBitmap & attrib.getBitCode()) != 0; } @Override public String getFactionListing() { final StringBuffer msg = new StringBuffer(); for (final Iterator<String> e = new XTreeSet<String>(factions()).iterator(); e.hasNext();) { final Faction F = CMLib.factions().getFaction(e.next()); if (F != null) msg.append(F.name() + "(" + fetchFaction(F.factionID()) + ");"); } return msg.toString(); } @Override public String getLiegeID() { return liegeID; } @Override public int getWimpHitPoint() { return wimpHitPoint; } @Override public int getQuestPoint() { return questPoint; } @Override public void setLiegeID(final String newVal) { liegeID = newVal; } @Override public void setWimpHitPoint(final int newVal) { wimpHitPoint = newVal; } @Override public void setQuestPoint(final int newVal) { questPoint = newVal; } @Override public void initializeClass() { } @Override public CMObject newInstance() { try { return this.getClass().newInstance(); } catch (final Exception e) { Log.errOut(ID(), e); } return new StdMOB(); } @Override public Room getStartRoom() { return CMLib.map().getRoom(possStartRoom); } @Override public void setStartRoom(final Room room) { possStartRoom = room; } @Override public void setDatabaseID(final String id) { databaseID = id; } @Override public boolean canSaveDatabaseID() { return true; } @Override public String databaseID() { return databaseID; } @Override public String Name() { return _name; } @Override public void setName(final String newName) { _name = newName; } @Override public String name() { if (phyStats().newName() != null) return phyStats().newName(); return _name; } @Override public String titledName() { if (playerStats == null) return name(); return CMStrings.replaceAll(playerStats.getActiveTitle(), "*", Name()); } @Override public String genericName() { if ((charStats().getStat(CharStats.STAT_AGE) > 0) && (!CMSecurity.isDisabled(CMSecurity.DisFlag.ALL_AGEING))) return charStats().ageName().toLowerCase() + " " + charStats().raceName().toLowerCase(); return charStats().raceName().toLowerCase(); } @Override public String image() { if (cachedImageName == null) { if ((rawImageName != null) && (rawImageName.length() > 0)) cachedImageName = rawImageName; else cachedImageName = CMLib.protocol().getDefaultMXPImage(this); } if (!baseCharStats().getMyRace().name().equalsIgnoreCase(charStats().raceName())) return CMLib.protocol().getDefaultMXPImage(this); if (cachedImageName == null) return ""; return cachedImageName; } @Override public String rawImage() { if (rawImageName == null) return ""; return rawImageName; } @Override public void setImage(final String newImage) { if ((newImage == null) || (newImage.trim().length() == 0)) rawImageName = null; else rawImageName = newImage; if ((cachedImageName != null) && (!cachedImageName.equals(newImage))) cachedImageName = null; } @Override public long expirationDate() { return expirationDate; } @Override public void setExpirationDate(final long time) { expirationDate = time; } // protected void finalize() // CMClass.unbumpCounter(this,CMClass.CMObjectType.MOB); }//removed for mem // & perf @Override public final boolean amDestroyed() { return this.amDestroyed; } protected final void setDestroyed(final boolean truefalse) { this.amDestroyed = truefalse; } @SuppressWarnings("rawtypes") protected void cloneFix(final MOB M) { if (M == null) return; synchronized (this) { me = this; } synchronized (M) { if (!isGeneric()) { final PhyStats oldBase = basePhyStats; basePhyStats = (PhyStats) M.basePhyStats().copyOf(); phyStats = (PhyStats) M.phyStats().copyOf(); basePhyStats.setAbility(oldBase.ability()); basePhyStats.setRejuv(oldBase.rejuv()); basePhyStats.setLevel(oldBase.level()); phyStats.setAbility(oldBase.ability()); phyStats.setRejuv(oldBase.rejuv()); phyStats.setLevel(oldBase.level()); } else { basePhyStats = (PhyStats) M.basePhyStats().copyOf(); phyStats = (PhyStats) M.phyStats().copyOf(); } } affectPhyStats = new ApplyAffectPhyStats<Ability>(this); recoverAffectP = new ApplyRecAffectPhyStats<Item>(this); affectCharStats = new ApplyAffectCharStats(this); affectCharState = new ApplyAffectCharState(this); affects = new SVector<Ability>(); baseCharStats = (CharStats) M.baseCharStats().copyOf(); charStats = (CharStats) M.charStats().copyOf(); baseState = (CharState) M.baseState().copyOf(); curState = (CharState) M.curState().copyOf(); maxState = (CharState) M.maxState().copyOf(); removeFromGame = false; inventory = new SVector<Item>(); abilitys = new CMUniqSortSVec<Ability>(); abilityUseTrig = new int[Ability.USAGEINDEX_TOTAL]; abilityUseCache = new STreeMap<String, int[][]>(); behaviors = new CMUniqSortSVec<Behavior>(); tattoos = new CMUniqNameSortSVec<Tattoo>(); expertises = new STreeMap<String, Integer>(); followers = null; commandQue = new LinkedList<QMCommand>(); scripts = new SVector<ScriptingEngine>(); racialAffects = null; clanAffects = null; factions = new SHashtable<String, FData>(1); possWieldedItem = null; possHeldItem = null; clans = new OrderedMap<String, Pair<Clan, Integer>>(); for (final Pair<Clan, Integer> p : M.clans()) { setClan(p.first.clanID(), p.second.intValue()); } for (final Enumeration<String> e = M.factions(); e.hasMoreElements();) { final String fac = e.nextElement(); addFaction(fac, M.fetchFaction(fac)); } for (final Enumeration<Tattoo> e = M.tattoos(); e.hasMoreElements();) { final Tattoo t = e.nextElement(); addTattoo((Tattoo) t.copyOf()); } for (final Enumeration<String> s = M.expertises(); s.hasMoreElements();) addExpertise(s.nextElement()); Item I = null; for (int i = 0; i < M.numItems(); i++) { I = M.getItem(i); if (I != null) addItem((Item) I.copyOf()); } Item I2 = null; for (int i = 0; i < numItems(); i++) { I = getItem(i); if ((I != null) && (I.container() != null) && (!isMine(I.container()))) { for (final Enumeration<Item> e = M.items(); e.hasMoreElements();) { I2 = e.nextElement(); if ((I2 == I.container()) && (I2 instanceof Container)) { I.setContainer((Container) I2); break; } } } } Ability A = null; for (int i = 0; i < M.numAbilities(); i++) { A = M.fetchAbility(i); if (A != null) addAbility((Ability) A.copyOf()); } try { setDestroyed(true); for (final Enumeration<Ability> a = M.personalEffects(); a.hasMoreElements();) { A = a.nextElement(); if (A != null) { A = (Ability) A.copyOf(); addEffect(A); if (A.canBeUninvoked()) { A.unInvoke(); delEffect(A); } } } } finally { setDestroyed(false); } for (final Enumeration<Behavior> e = M.behaviors(); e.hasMoreElements();) { final Behavior B = e.nextElement(); if (B != null) // iteration during a clone would just be messed up. behaviors.addElement((Behavior) B.copyOf()); } ScriptingEngine SE = null; for (final Enumeration<ScriptingEngine> e = M.scripts(); e.hasMoreElements();) { SE = e.nextElement(); if (SE != null) addScript((ScriptingEngine) SE.copyOf()); } } @Override public CMObject copyOf() { try { final StdMOB E = (StdMOB) this.clone(); // CMClass.bumpCounter(E,CMClass.CMObjectType.MOB);//removed for mem // & perf E.xtraValues = (xtraValues == null) ? null : (String[]) xtraValues.clone(); E.cloneFix(this); CMLib.catalog().newInstance(this); return E; } catch (final CloneNotSupportedException e) { return this.newInstance(); } } @Override public boolean isGeneric() { return false; } @Override public PhyStats phyStats() { return phyStats; } @Override public PhyStats basePhyStats() { return basePhyStats; } @Override public void recoverPhyStats() { basePhyStats.copyInto(phyStats); if(speedAdj!=1.0) { final double baseSpeed=phyStats.speed(); if(baseSpeed>1.0) phyStats.setSpeed(1.0+((baseSpeed-1.0)*speedAdj)); } phyStats.setWeight(phyStats.weight() + charStats.getStat(CharStats.STAT_WEIGHTADJ)); if (location() != null) location().affectPhyStats(this, phyStats); if (getMoney() > 0) phyStats().setWeight(phyStats().weight() + (getMoney() / 100)); final Rideable riding = riding(); if (riding != null) riding.affectPhyStats(this, phyStats); final Deity deity = charStats().getMyDeity(); if (deity != null) deity.affectPhyStats(this, phyStats); final CharStats cStats = charStats; if (cStats != null) { for (int c = 0; c < cStats.numClasses(); c++) cStats.getMyClass(c).affectPhyStats(this, phyStats); cStats.getMyRace().affectPhyStats(this, phyStats); } eachItem(recoverAffectP); eachEffect(affectPhyStats); for (final Enumeration<FData> e = factions.elements(); e.hasMoreElements();) e.nextElement().affectPhyStats(this, phyStats); /* the follower light exception */ if (!CMLib.flags().isLightSource(this)) { for (final Enumeration<Pair<MOB, Short>> f = followers(); f.hasMoreElements();) { if (CMLib.flags().isLightSource(f.nextElement().first)) phyStats.setDisposition(phyStats().disposition() | PhyStats.IS_LIGHTSOURCE); } } } @Override public void setBasePhyStats(final PhyStats newStats) { basePhyStats = (PhyStats) newStats.copyOf(); } @Override public int baseWeight() { if (charStats().getMyRace() == baseCharStats().getMyRace()) return basePhyStats().weight() + charStats().getStat(CharStats.STAT_WEIGHTADJ); return charStats().getMyRace().lightestWeight() + charStats().getStat(CharStats.STAT_WEIGHTADJ) + charStats().getMyRace().weightVariance(); } @Override public int maxCarry() { return CMLib.login().getMaxCarry(this); } @Override public int maxItems() { return CMLib.login().getMaxItems(this); } @Override public int maxFollowers() { return CMLib.login().getMaxFollowers(this); } @Override public int totalFollowers() { int total = 0; try { final PairList<MOB, Short> followers = this.followers; if (followers != null) { for (final Iterator<Pair<MOB, Short>> f = followers.iterator(); f.hasNext();) { final MOB F = f.next().first; if (F != this) total += (1 + F.totalFollowers()); else f.remove(); } } } catch (final Exception t) { } return total; } @Override public Triggerer triggerer() { return triggerer; } @Override public void setTriggerer(final Triggerer triggerer) { if(triggerer != null) this.triggerer = triggerer; } @Override public CharStats baseCharStats() { return baseCharStats; } @Override public CharStats charStats() { return charStats; } @SuppressWarnings("unchecked") @Override public void recoverCharStats() { baseCharStats.setClassLevel(baseCharStats.getCurrentClass(), basePhyStats().level() - baseCharStats().combinedSubLevels()); baseCharStats.copyInto(charStats); final Rideable riding = riding(); if (riding != null) riding.affectCharStats(this, charStats); final Deity deity = baseCharStats.getMyDeity(); if (deity != null) deity.affectCharStats(this, charStats); final int num = charStats.numClasses(); for (int c = 0; c < num; c++) charStats.getMyClass(c).affectCharStats(this, charStats); charStats.getMyRace().affectCharStats(this, charStats); baseCharStats.getMyRace().agingAffects(this, baseCharStats, charStats); eachEffect(affectCharStats); eachItem(affectCharStats); if (location() != null) location().affectCharStats(this, charStats); for (final Enumeration<FData> e = factions.elements(); e.hasMoreElements();) e.nextElement().affectCharStats(this, charStats); if ((playerStats != null) && (soulMate == null) && (playerStats.getHygiene() >= PlayerStats.HYGIENE_DELIMIT)) { final int chaAdjust = (int) (playerStats.getHygiene() / PlayerStats.HYGIENE_DELIMIT); if ((charStats.getStat(CharStats.STAT_CHARISMA) / 2) > chaAdjust) charStats.setStat(CharStats.STAT_CHARISMA, charStats.getStat(CharStats.STAT_CHARISMA) - chaAdjust); else charStats.setStat(CharStats.STAT_CHARISMA, charStats.getStat(CharStats.STAT_CHARISMA) / 2); } } @Override public void setBaseCharStats(final CharStats newBaseCharStats) { baseCharStats = (CharStats) newBaseCharStats.copyOf(); } @Override public void affectPhyStats(final Physical affected, final PhyStats affectableStats) { if (affected instanceof Room) { if (CMLib.flags().isLightSource(this)) affectableStats.setDisposition((affectableStats.disposition() & ~PhyStats.IS_DARK) | PhyStats.IS_LIGHTSOURCE); else if (CMLib.flags().isInDark(this)) affectableStats.setDisposition((affectableStats.disposition() & ~PhyStats.IS_LIGHTSOURCE) | PhyStats.IS_DARK); } } @Override public void affectCharState(final MOB affectedMob, final CharState affectableMaxState) { } @Override public boolean isMarriedToLiege() { if (getLiegeID().length() == 0) return false; if (getLiegeID().equals(Name())) return false; if(!CMLib.players().playerExistsAllHosts(getLiegeID())) { setLiegeID(""); return false; } final String otherLiegeID=CMLib.players().getLiegeOfUserAllHosts(getLiegeID()); return ((otherLiegeID!=null)&&(otherLiegeID.equalsIgnoreCase(Name()))); } @Override public CharState curState() { return curState; } @Override public CharState maxState() { return maxState; } @Override public CharState baseState() { return baseState; } @Override public PlayerStats playerStats() { if ((playerStats == null) && (soulMate != null)) return soulMate.playerStats(); return playerStats; } @Override public void setPlayerStats(final PlayerStats newStats) { playerStats = newStats; } @Override public void setBaseState(final CharState newState) { baseState = (CharState) newState.copyOf(); maxState = (CharState) newState.copyOf(); } @Override public void resetToMaxState() { recoverMaxState(); maxState.copyInto(curState); } @SuppressWarnings("unchecked") @Override public void recoverMaxState() { baseState.copyInto(maxState); if (charStats.getMyRace() != null) charStats.getMyRace().affectCharState(this, maxState); final Rideable riding = riding(); if (riding != null) riding.affectCharState(this, maxState); final int num = charStats.numClasses(); for (int c = 0; c < num; c++) charStats.getMyClass(c).affectCharState(this, maxState); eachEffect(affectCharState); eachItem(affectCharState); for (final Enumeration<Faction.FData> e = factions.elements(); e.hasMoreElements();) e.nextElement().affectCharState(this, maxState); if (location() != null) location().affectCharState(this, maxState); } @Override public boolean amDead() { return amDead || removeFromGame; } @Override public boolean amActive() { return !removeFromGame; } @Override public void dispossess(final boolean forceLook) { final MOB mate = soulMate(); if (mate == null) return; if ((mate.soulMate() != null) && (mate != this)) mate.dispossess(forceLook); final Session s = session(); if (s != null) { s.setMob(mate); mate.setSession(s); setSession(null); if (forceLook) CMLib.commands().postLook(mate, true); setSoulMate(null); } } @Override public void destroy() { CMLib.map().registerWorldObjectDestroyed(null, getStartRoom(), this); try { CMLib.catalog().changeCatalogUsage(this, false); } catch (final Exception t) { } if ((CMSecurity.isDebugging(CMSecurity.DbgFlag.MISSINGKIDS)) && (fetchEffect("Age") != null) && CMath.isInteger(fetchEffect("Age").text()) && (CMath.s_long(fetchEffect("Age").text()) > Short.MAX_VALUE)) Log.debugOut("MISSKIDS", new Exception(Name() + " went missing form " + CMLib.map().getExtendedRoomID(CMLib.map().roomLocation(this)))); if (soulMate() != null) dispossess(false); final MOB possessor = CMLib.utensils().getMobPossessingAnother(this); if (possessor != null) possessor.dispossess(false); if (session() != null) { session().stopSession(false, false, false); CMLib.s_sleep(1000); } if (playerStats != null) CMLib.players().changePlayersLocation(this, null); removeFromGame(session() != null, true); delAllBehaviors(); delAllEffects(false); delAllAbilities(); delAllItems(true); delAllExpertises(); delAllScripts(); if (kickFlag) CMLib.threads().deleteTick(this, -1); kickFlag = false; clans.clear(); clanAffects = null; baseCharStats.reset(); charStats.reset(); basePhyStats.reset(); phyStats.reset(); playerStats = null; location = null; lastLocation = null; riding = null; mySession = null; rawImageName = null; cachedImageName = null; inventory.setSize(0); followers = null; abilitys.setSize(0); triggerer.setObsolete(); abilityUseCache.clear(); affects.setSize(0); behaviors.setSize(0); tattoos.setSize(0); expertises.clear(); factions.clear(); commandQue.clear(); scripts.setSize(0); curState = maxState; liegeID = ""; victim = null; amFollowing = null; soulMate = null; possStartRoom = null; setDestroyed(true); } @Override public void removeFromGame(final boolean preserveFollowers, final boolean killSession) { removeFromGame = true; final PlayerStats pStats = playerStats; if ((location != null) && (location.isInhabitant(this))) { location().delInhabitant(this); if ((session() != null) && (!CMProps.getBoolVar(CMProps.Bool.MUDSHUTTINGDOWN))) { final String msg = ((pStats!=null)&&(pStats.getPoofOut().length()>0))? pStats.getPoofOut():L("<S-NAME> vanish(es) in a puff of smoke."); location().showOthers(this, null, CMMsg.MSG_OK_ACTION,msg); } } if (pStats != null) CMLib.players().changePlayersLocation(this, null); setFollowing(null); final PairList<MOB, Integer> oldFollowers = new PairArrayList<MOB, Integer>(); while (numFollowers() > 0) { final MOB follower = fetchFollower(0); if (follower != null) { if ((follower.isMonster()) && (!follower.isPossessing())) oldFollowers.add(follower, Integer.valueOf(fetchFollowerOrder(follower))); follower.setFollowing(null); delFollower(follower); } } if (preserveFollowers) { for (final Pair<MOB, Integer> p : oldFollowers) { final MOB follower = p.first; if (follower.location() != null) { final MOB newFol = (MOB) follower.copyOf(); newFol.basePhyStats().setRejuv(PhyStats.NO_REJUV); newFol.phyStats().setRejuv(PhyStats.NO_REJUV); newFol.text(); follower.killMeDead(false); addFollower(newFol, p.second.intValue()); } } if (pStats != null) { pStats.setLastDateTime(System.currentTimeMillis()); CMLib.database().DBUpdateFollowers(this); if (CMSecurity.isASysOp(this) || ((!CMSecurity.isDisabled(CMSecurity.DisFlag.LOGOUTS))) && (CMLib.masking().maskCheck(CMProps.getVar(CMProps.Str.LOGOUTMASK), this, true))) { if (pStats != null) // cant do this when logouts are suspended -- folks might get killed! CMLib.threads().suspendResumeRecurse(this, false, true); } } if (killSession && (session() != null)) session().stopSession(false, false, false); } setRiding(null); } @Override public void bringToLife() { amDead = false; removeFromGame = false; speedAdj = CMProps.getSpeedAdjustment(); // will ensure no duplicate ticks, this obj, this id kickFlag = true; CMLib.threads().startTickDown(this, Tickable.TICKID_MOB, 1); if (tickStatus == Tickable.STATUS_NOT) { final boolean isImMobile = CMath.bset(phyStats.sensesMask(), PhyStats.CAN_NOT_MOVE); try { phyStats.setSensesMask(phyStats.sensesMask() | PhyStats.CAN_NOT_MOVE); tick(this, Tickable.TICKID_MOB); // slap on the butt } finally { phyStats.setSensesMask(CMath.dobit(phyStats.sensesMask(), PhyStats.CAN_NOT_MOVE, isImMobile)); } } } protected final boolean confirmLocation(final Room whereHeShouldBeR) { if (location() == null) { if (getStartRoom() != null) { Log.errOut("StdMOB", name() + " of " + CMLib.map().getDescriptiveExtendedRoomID(whereHeShouldBeR) + " was auto-killed for being nowhere!"); killMeDead(false); } else { Log.errOut("StdMOB", name() + " of " + CMLib.map().getDescriptiveExtendedRoomID(whereHeShouldBeR) + " was auto-destroyed by its tick!!"); destroy(); } return false; } return true; } @Override public void bringToLife(final Room newLocation, final boolean resetStats) { amDead = false; speedAdj = CMProps.getSpeedAdjustment(); if ((miscText != null) && (resetStats) && (isGeneric())) { if (CMProps.getBoolVar(CMProps.Bool.MOBCOMPRESS) && (miscText instanceof byte[])) { final String decompressedStr = CMLib.encoder().decompressString((byte[]) miscText); final String unpackedStr = CMLib.coffeeMaker().getGenMOBTextUnpacked(this, decompressedStr); CMLib.coffeeMaker().resetGenMOB(this,unpackedStr ); } else { final String unpackedStr = CMLib.coffeeMaker().getGenMOBTextUnpacked(this, CMStrings.bytesToStr(miscText)); CMLib.coffeeMaker().resetGenMOB(this, unpackedStr); } } if (CMLib.map().getStartRoom(this) == null) setStartRoom(isMonster() ? newLocation : CMLib.login().getDefaultStartRoom(this)); setLocation(newLocation); if (location() == null) { setLocation(CMLib.map().getStartRoom(this)); if (!confirmLocation(newLocation)) return; } if (!location().isInhabitant(this)) location().addInhabitant(this); removeFromGame = false; if (session() != null) { final Area area = CMLib.map().areaLocation(location()); if (area != null) CMLib.sessions().moveSessionToCorrectThreadGroup(session(), area.getTheme()); } // will ensure no duplicate ticks, this obj, this id kickFlag = true; CMLib.threads().startTickDown(this, Tickable.TICKID_MOB, 1); Ability A = null; for (int a = 0; a < numAbilities(); a++) { A = fetchAbility(a); if (A != null) A.autoInvocation(this, false); } if (!confirmLocation(newLocation)) return; if ((this.tattoos.size() == 0) || (findTattoo("SYSTEM_SUMMONED") == null)) CMLib.factions().updatePlayerFactions(this, location(), false); if (tickStatus == Tickable.STATUS_NOT) { final boolean isImMobile = CMath.bset(phyStats.sensesMask(), PhyStats.CAN_NOT_MOVE); try { phyStats.setSensesMask(phyStats.sensesMask() | PhyStats.CAN_NOT_MOVE); tick(this, Tickable.TICKID_MOB); // slap on the butt } catch (final Exception t) { t.printStackTrace(); } finally { phyStats.setSensesMask(CMath.dobit(phyStats.sensesMask(), PhyStats.CAN_NOT_MOVE, isImMobile)); } } if (!confirmLocation(newLocation)) return; location().recoverRoomStats(); if ((!isGeneric()) && (resetStats)) { resetToMaxState(); } if (!confirmLocation(newLocation)) return; if (isMonster()) { final Item dropItem = CMLib.catalog().getDropItem(this, true); if (dropItem != null) addItem(dropItem); } CMLib.awards().giveAutoProperties(me); CMLib.map().registerWorldObjectLoaded(null, getStartRoom(), this); location().show(this, null, CMMsg.MSG_BRINGTOLIFE, null); if (!amDestroyed) { if (CMLib.flags().isSleeping(this)) tell(L("(You are asleep)")); else CMLib.commands().postLook(this, true); } possWieldedItem = null; possHeldItem = null; inventory.trimToSize(); abilitys.trimToSize(); affects.trimToSize(); behaviors.trimToSize(); } @Override public boolean isInCombat() { if (victim == null) return false; try { final Room vicR = victim.location(); if ((vicR == null) || (location() == null) || (vicR != location()) || (victim.amDead())) { if ((victim instanceof StdMOB) && (((StdMOB) victim).victim == this)) victim.setVictim(null); setVictim(null); return false; } return true; } catch (final NullPointerException n) { } return false; } protected boolean isEitherOfUsDead(final MOB mob) { if (location() == null) return true; if (mob.location() == null) return true; if (mob.amDead()) return true; if (mob.curState().getHitPoints() <= 0) return true; if (amDead()) return true; if (curState().getHitPoints() <= 0) return true; return false; } protected boolean isPermissableToFight(final MOB mob) { if (mob == null) return false; final boolean targetIsMonster = mob.isMonster(); final boolean iAmMonster = isMonster(); if (targetIsMonster) { final MOB fol = mob.amFollowing(); if ((fol != null) && (!isEitherOfUsDead(fol))) { if (!isPermissableToFight(fol)) return false; } } if (iAmMonster) { final MOB fol = amFollowing(); if ((fol != null) && (!isEitherOfUsDead(fol))) { if (!fol.mayIFight(mob)) return false; } } if (CMLib.flags().isUnattackable(mob) && (!mob.isInCombat())) return false; if (targetIsMonster || iAmMonster) return true; if ((mob.soulMate() != null) || (soulMate() != null)) return true; if (mob == this) return true; if (CMLib.clans().isAtClanWar(this, mob)) return true; if (this.isAttributeSet(MOB.Attrib.PLAYERKILL)) { if (CMSecurity.isAllowed(this, location(), CMSecurity.SecFlag.PKILL) || (mob.isAttributeSet(MOB.Attrib.PLAYERKILL))) return true; return false; } else if (mob.isAttributeSet(MOB.Attrib.PLAYERKILL)) { if (CMSecurity.isAllowed(mob, location(), CMSecurity.SecFlag.PKILL) || (this.isAttributeSet(MOB.Attrib.PLAYERKILL))) return true; return false; } else return false; } @Override public boolean mayIFight(final PhysicalAgent victim) { if (!(victim instanceof MOB)) { if (CMLib.flags().isUnattackable(victim)) return false; if (victim instanceof Rideable) return CMLib.combat().mayIAttackThisVessel(this, victim); return false; } if (isEitherOfUsDead((MOB) victim)) return false; return isPermissableToFight((MOB) victim); } @Override public boolean mayPhysicallyAttack(final PhysicalAgent victim) { final Room myLocation = location(); if ((!mayIFight(victim)) || (myLocation == null)) return false; if (victim instanceof MOB) { if (myLocation != ((MOB) victim).location()) return false; } else { final Room R = CMLib.map().roomLocation(victim); final Area myArea = myLocation.getArea(); if ((R == null) || (myArea == null)) return false; if ((myLocation != R) && ((!(myArea instanceof Boardable)) || (!R.isContent(((Boardable) myArea).getBoardableItem())))) return false; } if ((!CMLib.flags().isInTheGame(this, false)) || (!CMLib.flags().isInTheGame(victim, false))) return false; return true; } @Override public long getPeaceTime() { return peaceTime; } @Override public void setRangeToTarget(final int newRange) { atRange = newRange; } @Override public int rangeToTarget() { return atRange; } @Override public int getDirectionToTarget() { return -1; } @Override public int maxRange() { if (location() != null) return location().maxRange(); return 10; } @Override public int minRange() { return 0; } private int maxRangeWith(final Environmental tool) { final int max = maxRange(); if (tool == null) return minRange(); if (tool.maxRange() < max) return tool.maxRange(); return max; } private int minRangeWith(final Environmental tool) { if (tool != null) return tool.minRange(); return minRange(); } @Override public void makePeace(final boolean includePlayerFollowers) { final MOB myVictim = victim; setVictim(null); for (int f = 0; f < numFollowers(); f++) { final MOB M = fetchFollower(f); if ((M != null) && (M.isInCombat()) && (includePlayerFollowers || M.isMonster())) M.makePeace(true); } if (myVictim != null) { final MOB oldVictim = myVictim.getVictim(); if (oldVictim == this) myVictim.makePeace(true); } } @Override public MOB getVictim() { if (!isInCombat()) return null; return victim; } @Override public PhysicalAgent getCombatant() { return getVictim(); } @Override public void setCombatant(final PhysicalAgent other) { if ((other == null) || (other instanceof MOB)) setVictim((MOB) other); } @Override public void setVictim(final MOB other) { if (other == null) { setRangeToTarget(-1); if (victim != null) { synchronized (commandQue) { commandQue.clear(); } } } if (victim == other) return; if (other == this) return; victim = other; recoverPhyStats(); recoverCharStats(); recoverMaxState(); if (other != null) { if ((other.location() == null) || (location() == null) || (other.amDead()) || (amDead()) || (other.location() != location()) || (!location().isInhabitant(this)) || (!location().isInhabitant(other))) { if (victim != null) victim.setVictim(null); victim = null; setRangeToTarget(-1); } else { if (Log.combatChannelOn()) { final Item I = fetchWieldedItem(); final Item VI = other.fetchWieldedItem(); Log.combatOut("STRT", Name() + ":" + phyStats().getCombatStats() + ":" + curState().getCombatStats() + ":" + ((I == null) ? "null" : I.name()) + ":" + other.Name() + ":" + other.phyStats().getCombatStats() + ":" + other.curState().getCombatStats() + ":" + ((VI == null) ? "null" : VI.name())); } other.recoverCharStats(); other.recoverPhyStats(); other.recoverMaxState(); } } } @Override public DeadBody killMeDead(final boolean createBody) { final Room deathRoom; if (isMonster()) deathRoom = location(); else deathRoom = CMLib.login().getDefaultBodyRoom(this); if (location() != null) location().delInhabitant(this); amDead = true; DeadBody bodyI = null; if (createBody) { bodyI = charStats().getMyRace().getCorpseContainer(this, deathRoom); if ((bodyI != null) && (playerStats() != null)) { bodyI.setSavable(false); // if the player is saving it, rooms are NOT. playerStats().getExtItems().addItem(bodyI); } if(deathRoom != null) deathRoom.show(this, bodyI, CMMsg.MASK_ALWAYS|CMMsg.MSG_BODYDROP, null); } makePeace(false); setRiding(null); synchronized (commandQue) { commandQue.clear(); } Ability A = null; for (int a = numEffects() - 1; a >= 0; a--) { A = fetchEffect(a); if (A != null) A.unInvoke(); } setLocation(null); if (isMonster()) { while (numFollowers() > 0) { final MOB follower = fetchFollower(0); if (follower != null) { follower.setFollowing(null); delFollower(follower); } } setFollowing(null); } if ((!isMonster()) && (soulMate() == null)) bringToLife(CMLib.login().getDefaultDeathRoom(this), true); if (deathRoom != null) deathRoom.recoverRoomStats(); return bodyI; } @Override public Room location() { if (location == null) return lastLocation; return location; } @Override public void setLocation(final Room newRoom) { lastLocation = location; location = newRoom; if ((playerStats != null) && (lastLocation != newRoom)) CMLib.players().changePlayersLocation(this, newRoom); } @Override public Rideable riding() { return riding; } @Override public void setRiding(final Rideable ride) { final Rideable amRiding = riding(); if ((ride != null) && (amRiding != null) && (amRiding == ride) && (amRiding.amRiding(this))) return; if ((amRiding != null) && (amRiding.amRiding(this))) amRiding.delRider(this); riding = ride; if ((ride != null) && (!ride.amRiding(this))) ride.addRider(this); } @Override public final Session session() { return mySession == null ? null : mySession.isFake() ? null : mySession; } @Override public void setSession(final Session newSession) { mySession = newSession; setAttributesBitmap(getAttributesBitmap()); } @Override public Weapon getNaturalWeapon() { final Weapon W; if ((charStats() != null) && (charStats().getMyRace() != null)) W = charStats().getMyRace().myNaturalWeapon(); else W = CMClass.getWeapon("Natural"); if (W.subjectToWearAndTear()) W.setUsesRemaining(100); return W; } @Override public String titledName(final MOB viewer) { if (CMProps.getBoolVar(CMProps.Bool.INTRODUCTIONSYSTEM) && (playerStats() != null) && (viewer != null) && (viewer != this) && (viewer.playerStats() != null) && (!viewer.playerStats().isIntroducedTo(Name())) && (!CMSecurity.isASysOp(viewer))) return CMLib.english().startWithAorAn(genericName()).toLowerCase(); return titledName(); } @Override public String name(final MOB viewer) { if (CMProps.getBoolVar(CMProps.Bool.INTRODUCTIONSYSTEM) && (playerStats() != null) && (viewer != null) && (viewer != this) && (viewer.playerStats() != null) && (!viewer.playerStats().isIntroducedTo(Name())) && (!CMSecurity.isASysOp(viewer))) return CMLib.english().startWithAorAn(genericName()).toLowerCase(); return name(); } @Override public String displayText(final MOB viewerMob) { if ((displayText.length() == 0) || (!name(viewerMob).equals(Name())) || (!titledName().equals(Name())) || (CMLib.flags().isSleeping(this)) || (CMLib.flags().isSitting(this)) || (riding() != null) || ((amFollowing() != null) && (amFollowing().fetchFollowerOrder(this) > 0)) || ((this instanceof Rideable) && (((Rideable) this).numRiders() > 0) && CMLib.flags().isWithSeenContents(this)) || (isInCombat())) { final StringBuilder sendBack; if (!name(viewerMob).equals(Name())) sendBack = new StringBuilder(name(viewerMob)); else sendBack = new StringBuilder(titledName(viewerMob)); sendBack.append(" "); sendBack.append(L(CMLib.flags().getPresentDispositionVerb(this, CMFlagLibrary.ComingOrGoing.IS) + " here")); if (riding() != null) { sendBack.append(" " + riding().stateString(this) + " "); if (riding() == viewerMob) sendBack.append(L("YOU")); else if (!CMLib.flags().canBeSeenBy(riding(), viewerMob)) { if (riding() instanceof Item) sendBack.append(L("something")); else sendBack.append(L("someone")); } else sendBack.append(riding().name()); } else if ((this instanceof Rideable) && (((Rideable) this).numRiders() > 0) && (((Rideable) this).stateStringSubject(((Rideable) this).fetchRider(0)).length() > 0)) { final Rideable me = (Rideable) this.me; final String first = me.stateStringSubject(me.fetchRider(0)); sendBack.append(" " + first + " "); for (int r = 0; r < me.numRiders(); r++) { final Rider rider = me.fetchRider(r); if ((rider != null) && (me.stateStringSubject(rider).equals(first))) { if (r > 0) { sendBack.append(", "); if (r == me.numRiders() - 1) sendBack.append("and "); } if (rider == viewerMob) sendBack.append("you"); else if (!CMLib.flags().canBeSeenBy(riding(), viewerMob)) { if (riding() instanceof Item) sendBack.append(L("something")); else sendBack.append(L("someone")); } else sendBack.append(rider.name()); } } } if ((isInCombat()) && (CMLib.flags().canMove(this)) && (!CMLib.flags().isSleeping(this))) { if (getVictim() == viewerMob) sendBack.append(L(" fighting YOU")); else if (!CMLib.flags().canBeSeenBy(getVictim(), viewerMob)) sendBack.append(L(" fighting someone")); else sendBack.append(L(" fighting @x1", getVictim().name())); } if ((amFollowing() != null) && (amFollowing().fetchFollowerOrder(this) > 0)) { final List<MOB> whoseAhead = CMLib.combat().getFormationFollowed(this); if ((whoseAhead != null) && (!whoseAhead.isEmpty())) { sendBack.append(L(", behind ")); for (int v = 0; v < whoseAhead.size(); v++) { final MOB ahead = whoseAhead.get(v); if (v > 0) { sendBack.append(", "); if (v == whoseAhead.size() - 1) sendBack.append(L("and ")); } if (ahead == viewerMob) sendBack.append(L("you")); else if (!CMLib.flags().canBeSeenBy(ahead, viewerMob)) sendBack.append(L("someone")); else sendBack.append(ahead.name()); } } } sendBack.append("."); return sendBack.toString(); } return displayText; } @Override public String displayText() { return displayText; } @Override public void setDisplayText(final String newDisplayText) { displayText = newDisplayText; } @Override public String description() { if (description == null) return ""; else if (description instanceof byte[]) { final byte[] descriptionBytes = (byte[]) description; if (descriptionBytes.length == 0) return ""; if (CMProps.getBoolVar(CMProps.Bool.MOBDCOMPRESS)) return CMLib.encoder().decompressString(descriptionBytes); else return CMStrings.bytesToStr(descriptionBytes); } else return (String) description; } @Override public String description(final MOB viewerMob) { return description(); } @Override public void setDescription(final String newDescription) { if (newDescription.length() == 0) description = null; else if (CMProps.getBoolVar(CMProps.Bool.MOBDCOMPRESS)) description = CMLib.encoder().compressString(newDescription); else description = newDescription; } @Override public void setMiscText(final String newText) { if (newText.length() == 0) miscText = null; else if (CMProps.getBoolVar(CMProps.Bool.MOBCOMPRESS)) miscText = CMLib.encoder().compressString(newText); else miscText = newText; } @Override public String text() { if (miscText == null) return ""; else if (miscText instanceof byte[]) { final byte[] miscTextBytes = (byte[]) miscText; if (miscTextBytes.length == 0) return ""; if (CMProps.getBoolVar(CMProps.Bool.MOBCOMPRESS)) return CMLib.encoder().decompressString(miscTextBytes); else return CMStrings.bytesToStr(miscTextBytes); } else return (String) miscText; } @Override public String miscTextFormat() { return CMParms.FORMAT_UNDEFINED; } @Override public String healthText(final MOB viewer) { final String mxp = "^<!ENTITY vicmaxhp \"" + maxState().getHitPoints() + "\"^>" + "^<!ENTITY vichp \"" + curState().getHitPoints() + "\"^>" + "^<Health^>^<HealthText \"" + CMStrings.removeColors(name(viewer)) + "\"^>"; if ((charStats() != null) && (charStats().getMyRace() != null)) return mxp + charStats().getMyRace().healthText(viewer, this) + "^</HealthText^>"; return mxp + CMLib.combat().standardMobCondition(viewer, this) + "^</HealthText^>"; } @Override public double actions() { return freeActions; } @Override public void setActions(final double remain) { freeActions = remain; } @Override public int commandQueSize() { return commandQue.size(); } @Override public void clearCommandQueue() { commandQue.clear(); } @Override public Pair<Object, List<String>> getTopCommand() { Pair<Object, List<String>> top = null; synchronized(commandQue) { if(!commandQue.isEmpty()) { final QMCommand QM=commandQue.peekFirst(); top=new Pair<Object, List<String>>(QM.commandObj, QM.commandVector); } } return top; } @Override public boolean dequeCommand() { while ((!removeFromGame) && (!amDestroyed()) && ((session() == null) || (!session().isStopped()))) { QMCommand doCommand = null; synchronized (commandQue) { if (commandQue.isEmpty()) return false; QMCommand cmd = commandQue.getFirst(); final double diff = actions() - cmd.actionCost; if (diff >= 0.0) { final long nextTime = lastCommandTime + Math.round(cmd.actionCost / phyStats().speed() * CMProps.getTickMillisD()); if ((System.currentTimeMillis() < nextTime) && (session() != null)) return false; cmd = commandQue.removeFirst(); setActions(diff); doCommand = cmd; } } if (doCommand != null) { lastCommandTime = System.currentTimeMillis(); doCommand(doCommand.commandObj, doCommand.commandVector, doCommand.metaFlags); synchronized (commandQue) { if (!commandQue.isEmpty()) { final QMCommand cmd = commandQue.getFirst(); final Object O = cmd.commandObj; cmd.actionCost = calculateActionCost(O, cmd.commandVector, 0.0); } else return false; return true; } } QMCommand cmd = null; synchronized (commandQue) { if (commandQue.isEmpty()) return false; cmd = commandQue.getFirst(); if ((cmd == null) || (System.currentTimeMillis() < cmd.nextCheck)) return false; } final double diff = actions() - cmd.actionCost; final Object O = cmd.commandObj; final List<String> commands = new XVector<String>(cmd.commandVector); cmd.nextCheck = cmd.nextCheck + 1000; cmd.seconds += 1; final int secondsElapsed = cmd.seconds; final int metaFlags = cmd.metaFlags; try { // record an action taken in personal combat stats final MOB combatant = victim; if ((cmd.actionCost > 0) && (combatant != null)) { if (playerStats != null) playerStats.bumpLevelCombatStat(PlayerCombatStat.ACTIONS_DONE, basePhyStats().level(), 1); if (combatant.playerStats() != null) combatant.playerStats().bumpLevelCombatStat(PlayerCombatStat.ACTIONS_TAKEN, combatant.basePhyStats().level(), 1); } // actually do the command queued up if (O instanceof Command) { if (!((Command) O).preExecute(this, commands, metaFlags, secondsElapsed, -diff)) { commandQue.remove(cmd); return true; } } else if (O instanceof Ability) { if (!CMLib.english().preInvokeSkill(this, commands, secondsElapsed, -diff)) { commandQue.remove(cmd); return true; } } } catch (final Exception e) { return false; } } return false; } @Override public void doCommand(final List<String> commands, final int metaFlags) { final CMObject O = CMLib.english().findCommand(this, commands); if (O != null) doCommand(O, commands, metaFlags); else CMLib.commands().handleUnknownCommand(this, commands); } protected void doCommand(final Object O, final List<String> commands, final int metaFlags) { try { if (O instanceof Command) { if (playerStats != null) { CMLib.achievements().possiblyBumpAchievement(this, AchievementLibrary.Event.CMDUSE, 1, (Command) O); CMLib.coffeeTables().bump((Command) O, CoffeeTableRow.STAT_CMDUSE); } ((Command) O).execute(this, new XVector<String>(commands), metaFlags); } else if (O instanceof Social) ((Social) O).invoke(this, new XVector<String>(commands), null, false); else if (O instanceof Ability) CMLib.english().invokeSkill(this, new XVector<String>(commands)); else CMLib.commands().handleUnknownCommand(this, commands); } catch (final java.io.IOException io) { Log.errOut("StdMOB", CMParms.toListString(commands)); if (io.getMessage() != null) Log.errOut("StdMOB", io.getMessage()); else Log.errOut("StdMOB", io); tell(L("Oops!")); } catch (final Exception e) { Log.errOut("StdMOB", Name() + " did '" + CMParms.toListString(commands) + "' in " + CMLib.map().getExtendedRoomID(location())); if ((e!=null)&&(e.getMessage() != null)) Log.errOut("StdMOB", e.getMessage()); Log.errOut("StdMOB", e); tell(L("Oops!")); } } protected double calculateActionCost(final Object command, final List<String> commands, double overrideActionCost) { if (overrideActionCost <= 0.0) { if (command == null) { tell(L("Huh?!")); return -1.0; } if (command instanceof Command) overrideActionCost = ((Command) command).checkedActionsCost(this, commands); else if (command instanceof Ability) overrideActionCost = ((Ability) command).checkedCastingCost(this, commands); else if (command instanceof Social) overrideActionCost = ((Social) command).checkedActionsCost(this, commands); else overrideActionCost = 1.0; } return overrideActionCost; } protected void checkCommandCancel() { synchronized (commandQue) { if(!commandQue.isEmpty()) { final QMCommand cmd = commandQue.peekFirst(); if((cmd.commandObj instanceof Command) &&(((Command)cmd.commandObj).canBeCancelled())) { try { ((Command)cmd.commandObj).preExecute(me, cmd.commandVector, cmd.metaFlags, -1, cmd.actionCost); } catch(final Exception e) { Log.errOut(e); } if((!commandQue.isEmpty())&&(commandQue.peekFirst() == cmd)) commandQue.removeFirst(); } } } } @Override public void prequeCommand(final List<String> commands, final int metaFlags, double actionCost) { if (commands == null) return; final CMObject O = CMLib.english().findCommand(this, commands); if (O == null) { CMLib.commands().handleUnknownCommand(this, commands); return; } actionCost = calculateActionCost(O, commands, actionCost); if (actionCost < 0.0) return; if (actionCost == 0.0) doCommand(O, commands, metaFlags); else { checkCommandCancel(); synchronized (commandQue) { final QMCommand cmd = new QMCommand(); cmd.nextCheck = System.currentTimeMillis() - 1; cmd.seconds = -1; cmd.actionCost = actionCost; cmd.metaFlags = metaFlags; cmd.commandObj = O; cmd.commandVector = commands; commandQue.addFirst(cmd); } } dequeCommand(); } @Override public void prequeCommands(final List<List<String>> commands, final int metaFlags) { if ((commands == null) || (commands.size() == 0)) return; final List<QMCommand> queueUp = new ArrayList<QMCommand>(commands.size()); for (final List<String> command : commands) { final CMObject O = CMLib.english().findCommand(this, command); if (O == null) { CMLib.commands().handleUnknownCommand(this, command); return; } final double actionCost = calculateActionCost(O, command, 0.0); if (actionCost < 0.0) return; synchronized (commandQue) { final QMCommand cmd = new QMCommand(); cmd.nextCheck = System.currentTimeMillis() - 1; cmd.seconds = -1; cmd.actionCost = actionCost; cmd.metaFlags = metaFlags; cmd.commandObj = O; cmd.commandVector = command; queueUp.add(cmd); } } if (queueUp.size() > 0) { if (this.commandQue.size() == 0) this.commandQue.addAll(queueUp); else this.commandQue.addAll(0, queueUp); } dequeCommand(); } @Override public void enqueCommand(final List<String> commands, final int metaFlags, double actionCost) { if (commands == null) return; final CMObject O = CMLib.english().findCommand(this, commands); if ((O == null) || ((O instanceof Ability) && CMath.bset(metaFlags, MUDCmdProcessor.METAFLAG_ORDER) && CMath.bset(((Ability) O).flags(), Ability.FLAG_NOORDERING))) { CMLib.commands().handleUnknownCommand(this, commands); return; } actionCost = calculateActionCost(O, commands, actionCost); if (actionCost < 0.0) return; if ((actionCost == 0.0) && (!CMath.bset(metaFlags, MUDCmdProcessor.METAFLAG_INORDER))) doCommand(commands, metaFlags); else { checkCommandCancel(); synchronized (commandQue) { final QMCommand cmd = new QMCommand(); cmd.nextCheck = System.currentTimeMillis() - 1; cmd.seconds = -1; cmd.actionCost = actionCost; cmd.metaFlags = metaFlags; cmd.commandObj = O; cmd.commandVector = commands; commandQue.addLast(cmd); } } dequeCommand(); } @Override public void enqueCommands(final List<List<String>> commands, final int metaFlags) { if ((commands == null) || (commands.size() == 0)) return; for (final List<String> cmds : commands) enqueCommand(cmds, metaFlags, 0.0); } @Override public boolean okMessage(final Environmental myHost, final CMMsg msg) { final Deity deity = charStats().getMyDeity(); if ((deity != null) && (deity != this) && (!deity.okMessage(this, msg))) return false; final CharStats cStats = charStats; if (cStats != null) { for (int c = 0; c < cStats.numClasses(); c++) { if (!cStats.getMyClass(c).okMessage(this, msg)) return false; } if (!cStats.getMyRace().okMessage(this, msg)) return false; } // the order here is significant (between eff and item -- see focus) for (final Enumeration<Ability> a = effects(); a.hasMoreElements();) { final Ability A = a.nextElement(); if (!A.okMessage(this, msg)) return false; } for (final Enumeration<Item> i = items(); i.hasMoreElements();) { final Item I = i.nextElement(); if (!I.okMessage(this, msg)) return false; } for (final Enumeration<Behavior> b = behaviors(); b.hasMoreElements();) { final Behavior B = b.nextElement(); if (!B.okMessage(this, msg)) return false; } for (final Enumeration<ScriptingEngine> s = scripts(); s.hasMoreElements();) { final ScriptingEngine S = s.nextElement(); if (!S.okMessage(this, msg)) return false; } for (final Enumeration<Faction.FData> e = factions.elements(); e.hasMoreElements();) { final Faction.FData fD = e.nextElement(); if (!fD.getFaction().okMessage(this, msg)) return false; if (!fD.okMessage(this, msg)) return false; } final MOB srcM = msg.source(); if ((msg.sourceCode() != CMMsg.NO_EFFECT) && (msg.amISource(this))) { if ((msg.sourceMinor() == CMMsg.TYP_DEATH) && (CMSecurity.isAllowed(this, location(), CMSecurity.SecFlag.IMMORT))) { curState().setHitPoints(1); if ((msg.tool() != this) && (msg.tool() instanceof MOB)) ((MOB) msg.tool()).tell(L("@x1 is immortal, and can not die.", name((MOB) msg.tool()))); tell(L("You are immortal, and can not die.")); return false; } if (!msg.sourceMajor(CMMsg.MASK_ALWAYS)) { final int srcMajor = msg.sourceMajor(); final int srcMinor = msg.sourceMinor(); final CMFlagLibrary flags = CMLib.flags(); if (amDead()) { tell(L("You are DEAD!")); return false; } if (CMath.bset(srcMajor, CMMsg.MASK_MALICIOUS)) { if (msg.target() instanceof MOB) { final MOB target = (MOB) msg.target(); if ((amFollowing() != null) && (target == amFollowing())) { tell(L("You like @x1 too much.", amFollowing().charStats().himher())); return false; } if ((getLiegeID().length() > 0) && (target.Name().equals(getLiegeID()))) { if (isMarriedToLiege()) tell(L("You are married to '@x1'!", getLiegeID())); else tell(L("You are serving '@x1'!", getLiegeID())); return false; } CMLib.combat().establishRange(this, (MOB) msg.target(), msg.tool()); } } if (CMath.bset(srcMajor, CMMsg.MASK_EYES)) { if (flags.isSleeping(this)) { tell(L("Not while you are sleeping.")); return false; } if (!(msg.target() instanceof Room)) { if (!flags.canBeSeenBy(msg.target(), this)) { if (msg.target() instanceof Item) tell(L("You don't see @x1 here.", ((Item) msg.target()).name(this))); else tell(L("You can't see that!")); return false; } } } if (CMath.bset(srcMajor, CMMsg.MASK_MOUTH)) { if (((srcMinor != CMMsg.TYP_LIST) || srcM.amDead() || flags.isSleeping(srcM)) && (!flags.isAliveAwakeMobile(this, false))) return false; if (CMath.bset(srcMajor, CMMsg.MASK_SOUND)) { if ((msg.tool() == null) || (!(msg.tool() instanceof Ability)) || (!((Ability) msg.tool()).isNowAnAutoEffect())) { if (flags.isSleeping(this)) { tell(L("Not while you are sleeping.")); return false; } if (!flags.canSpeak(this)) { tell(L("You can't make sounds!")); return false; } if ((flags.isAnimalIntelligence(this)) && (!CMath.bset(phyStats().sensesMask(), PhyStats.CAN_GRUNT_WHEN_STUPID))) { tell(L("You aren't smart enough to speak.")); return false; } } } else { if ((!flags.canBeSeenBy(msg.target(), this)) && (!isMine(msg.target())) && (msg.target() instanceof Item)) { srcM.tell(L("You don't see '@x1' here.", ((Item) msg.target()).name(this))); return false; } if (!flags.canTaste(this)) { if ((srcMinor == CMMsg.TYP_EAT) || (srcMinor == CMMsg.TYP_DRINK)) tell(L("You can't eat or drink.")); else tell(L("Your mouth is out of order.")); return false; } } } if (CMath.bset(srcMajor, CMMsg.MASK_HANDS)) { if ((!flags.canBeSeenBy(msg.target(), this)) && (!(isMine(msg.target()) && (msg.target() instanceof Item))) && ((!(msg.target() instanceof Boardable)) || (((Boardable) msg.target()).getArea() != location().getArea())) && (!((isInCombat()) && (msg.target() == victim))) && (CMath.bset(msg.targetMajor(), CMMsg.MASK_HANDS)) && (!(msg.target() instanceof Room))) { if (msg.target() instanceof Physical) { srcM.tell(L("You don't see '@x1' here.", ((Physical) msg.target()).name(this))); } else if (msg.target() != null) srcM.tell(L("You don't see '@x1' here.", msg.target().name())); else srcM.tell(L("You don't see that here.")); return false; } if (!flags.isAliveAwakeMobile(this, false)) return false; if ((flags.isSitting(this)) && (srcMinor != CMMsg.TYP_SITMOVE) && (srcMinor != CMMsg.TYP_BUY) && (srcMinor != CMMsg.TYP_BID) && (msg.targetMinor() != CMMsg.TYP_OK_VISUAL) && ((msg.sourceMessage() != null) || (msg.othersMessage() != null)) && (((!CMLib.utensils().reachableItem(this, msg.target())) || (!CMLib.utensils().reachableItem(this, msg.tool()))) && (location() != null) && (!CMath.bset(location().phyStats().sensesMask(), PhyStats.SENSE_ROOMCRUNCHEDIN)))) { tell(L("You need to stand up!")); return false; } } if (CMath.bset(srcMajor, CMMsg.MASK_MOVE)) { final boolean sleeping = flags.isSleeping(this); final boolean sitting = ((flags.isSitting(this)) && (srcMinor != CMMsg.TYP_LEAVE) && (srcMinor != CMMsg.TYP_ENTER) && ((msg.targetMinor() != CMMsg.NO_EFFECT)||(srcMinor!=CMMsg.TYP_DELICATE_HANDS_ACT)) ); if ((sleeping || sitting) && (srcMinor != CMMsg.TYP_STAND) && (srcMinor != CMMsg.TYP_SITMOVE) && (srcMinor != CMMsg.TYP_SIT) && (srcMinor != CMMsg.TYP_SLEEP)) { if (sleeping) tell(L("You need to wake up!")); else tell(L("You need to stand up!")); if ((srcMinor != CMMsg.TYP_WEAPONATTACK) && (srcMinor != CMMsg.TYP_THROW)) return false; } if (!flags.canMove(this)) { tell(L("You can't move!")); return false; } } // limb, weight check switch (msg.targetMinor()) { case CMMsg.TYP_PULL: case CMMsg.TYP_PUSH: { if (msg.target() instanceof Physical) { final int totalWeight = CMLib.utensils().getPullWeight((Physical) msg.target()); if ((maxCarry() * 10) < totalWeight) { if(msg.targetMinor() == CMMsg.TYP_PUSH) tell(L("That's way too heavy to push.")); else tell(L("That's way too heavy to pull.")); return false; } } } //$FALL-THROUGH$ case CMMsg.TYP_GET: case CMMsg.TYP_REMOVE: case CMMsg.TYP_OPEN: case CMMsg.TYP_CLOSE: if ((charStats().getBodyPart(Race.BODY_ARM) == 0) && (baseCharStats().getMyRace().bodyMask()[Race.BODY_ARM] > 0)) { tell(L("You need arms to do that.")); return false; } break; case CMMsg.TYP_DELICATE_HANDS_ACT: if ((charStats().getBodyPart(Race.BODY_HAND) == 0) && (msg.othersMinor() != CMMsg.NO_EFFECT)) { tell(L("You need hands to do that.")); return false; } break; case CMMsg.TYP_JUSTICE: if ((charStats().getBodyPart(Race.BODY_HAND) == 0) && (baseCharStats().getMyRace().bodyMask()[Race.BODY_HAND] > 0) && (msg.target() instanceof Item) && (!((msg.tool() instanceof Ability) && CMLib.ableMapper().qualifiesOnlyByRace(msg.source(), (Ability) msg.tool())))) { tell(L("You need hands to do that.")); return false; } break; case CMMsg.TYP_FILL: case CMMsg.TYP_GIVE: case CMMsg.TYP_PUT: if ((charStats().getBodyPart(Race.BODY_ARM) == 0) && (baseCharStats().getMyRace().bodyMask()[Race.BODY_ARM] > 0)) { tell(L("You need arms to do that.")); return false; } break; case CMMsg.TYP_LOCK: case CMMsg.TYP_HANDS: case CMMsg.TYP_INSTALL: case CMMsg.TYP_REPAIR: case CMMsg.TYP_ENHANCE: case CMMsg.TYP_UNLOCK: case CMMsg.TYP_WRITE: case CMMsg.TYP_REWRITE: if (charStats().getBodyPart(Race.BODY_HAND) == 0) { tell(L("You need hands to do that.")); return false; } break; case CMMsg.TYP_DRINK: if ((charStats().getBodyPart(Race.BODY_HAND) == 0) && (baseCharStats().getMyRace().bodyMask()[Race.BODY_HAND] > 0)) { if ((msg.target() != null) && (isMine(msg.target()))) { tell(L("You need hands to do that.")); return false; } } break; } // activity check switch (msg.sourceMinor()) { case CMMsg.TYP_WEAR: case CMMsg.TYP_HOLD: case CMMsg.TYP_WIELD: case CMMsg.TYP_REMOVE: possWieldedItem = null; possHeldItem = null; break; case CMMsg.TYP_RPXPCHANGE: if ((curState().getHunger() < 1) || (curState().getThirst() < 1) || (curState().getFatigue() > CharState.FATIGUED_MILLIS)) { // silent return false; } break; case CMMsg.TYP_JUSTICE: if ((isInCombat()) && (msg.target() instanceof Item)) { tell(L("Not while you are fighting!")); return false; } break; case CMMsg.TYP_THROW: if (charStats().getBodyPart(Race.BODY_ARM) == 0) { tell(L("You need arms to do that.")); return false; } break; case CMMsg.TYP_OPEN: case CMMsg.TYP_CLOSE: if (isInCombat()) { if (((msg.target() instanceof Exit) || (srcM.isMine(msg.target())))) break; tell(L("Not while you are fighting!")); return false; } break; case CMMsg.TYP_LEAVE: if ((isInCombat()) && (location() != null) && (!msg.sourceMajor(CMMsg.MASK_MAGIC)) && (!flags.isFalling(this))) { for (final Enumeration<MOB> m = location().inhabitants(); m.hasMoreElements();) { final MOB M = m.nextElement(); if ((M != this) && (M.getVictim() == this) && (flags.isAliveAwakeMobile(M, true)) && (flags.canSenseEnteringLeaving(srcM, M)) && (CMProps.getVar(CMProps.Str.PLAYERFLEE) != null) && (CMProps.getVar(CMProps.Str.PLAYERFLEE).length() > 0)) { tell(L("Not while you are fighting!")); return false; } } } break; case CMMsg.TYP_READ: if (isInCombat() && (!msg.sourceMajor(CMMsg.MASK_MAGIC)) && (!(msg.target() instanceof Scroll))) { tell(L("You are too busy fighting to read!")); return false; } break; case CMMsg.TYP_SIT: // SIT is waking! if (flags.isSleeping(this)) break; //$FALL-THROUGH$ case CMMsg.TYP_BUY: case CMMsg.TYP_BID: case CMMsg.TYP_DELICATE_HANDS_ACT: case CMMsg.TYP_FILL: case CMMsg.TYP_LIST: case CMMsg.TYP_LOCK: case CMMsg.TYP_SLEEP: case CMMsg.TYP_UNLOCK: case CMMsg.TYP_VALUE: case CMMsg.TYP_SELL: case CMMsg.TYP_VIEW: if (isInCombat() && (!msg.sourceMajor(CMMsg.MASK_MAGIC))) { tell(L("Not while you are fighting!")); return false; } break; case CMMsg.TYP_REBUKE: if ((msg.target() == null) || (!(msg.target() instanceof Deity))) { if (msg.target() != null) { if ((msg.target() instanceof MOB) && (!flags.canBeHeardSpeakingBy(this, (MOB) msg.target()))) { tell(L("@x1 can't hear you!", ((Physical) msg.target()).name(this))); return false; } else if ((msg.target() instanceof MOB) && (((MOB) msg.target()).amFollowing() == srcM) && (srcM.isFollowedBy((MOB) msg.target()))) { // should work. } else if ((!((msg.target() instanceof MOB) && (((MOB) msg.target()).getLiegeID().equals(Name())))) && (!msg.target().Name().equals(getLiegeID()))) { tell(L("@x1 does not serve you, and you do not serve @x2.", ((Physical) msg.target()).name(this), ((Physical) msg.target()).name(this))); return false; } else if ((msg.target() instanceof MOB) && (((MOB) msg.target()).getLiegeID().equals(Name())) && (getLiegeID().equals(msg.target().Name())) && (((MOB) msg.target()).isMarriedToLiege())) { tell(L("You cannot rebuke @x1. You must get an annulment or a divorce.", ((Physical) msg.target()).name(this))); return false; } } else if (getLiegeID().length() == 0) { tell(L("You aren't serving anyone!")); return false; } } else if (charStats().getWorshipCharID().length() == 0) { tell(L("You aren't worshipping anyone!")); return false; } break; case CMMsg.TYP_SERVE: if (msg.target() == null) return false; if (msg.target() == this) { tell(L("You can't serve yourself!")); return false; } if (msg.target() instanceof Deity) break; if ((msg.target() instanceof MOB) && (!flags.canBeHeardSpeakingBy(this, (MOB) msg.target()))) { tell(L("@x1 can't hear you!", ((Physical) msg.target()).name(this))); return false; } if (getLiegeID().length() > 0) { tell(L("You are already serving '@x1'.", getLiegeID())); return false; } if ((msg.target() instanceof MOB) && (((MOB) msg.target()).getLiegeID().equals(Name()))) { tell(L("You can not serve each other!")); return false; } break; case CMMsg.TYP_CAST_SPELL: if (charStats().getStat(CharStats.STAT_INTELLIGENCE) < 5) { tell(L("You aren't smart enough to do magic.")); return false; } break; default: break; } } } if ((msg.sourceCode() != CMMsg.NO_EFFECT) && (msg.amISource(this)) && (msg.target() instanceof MOB) && (msg.target() != this) && (!CMath.bset(msg.sourceMajor(), CMMsg.MASK_ALWAYS)) && (location() != null) && (location() == ((MOB) msg.target()).location())) { final MOB trgM = (MOB) msg.target(); final int srcMinor = msg.sourceMinor(); // and now, the consequences of range if (((msg.targetMinor() == CMMsg.TYP_WEAPONATTACK) && (rangeToTarget() > maxRangeWith(msg.tool()))) || ((srcMinor == CMMsg.TYP_THROW) && (rangeToTarget() > 2) && (maxRangeWith(msg.tool()) <= 0))) { msg.modify(this, trgM, null, CMMsg.MSG_ADVANCE, L("<S-NAME> advance(s) at <T-NAME>.")); final boolean ok = location().okMessage(this, msg); if (ok) setRangeToTarget(rangeToTarget() - 1); if (victim != null) { victim.setRangeToTarget(rangeToTarget()); victim.recoverPhyStats(); } else setRangeToTarget(-1); recoverPhyStats(); return ok; } else if (msg.targetMinor() == CMMsg.TYP_RETREAT) { if (curState().getMovement() < 25) { tell(L("You are too tired.")); return false; } if ((location() != null) && (rangeToTarget() >= location().maxRange())) { tell(L("You cannot retreat any further.")); return false; } curState().adjMovement(-25, maxState()); setRangeToTarget(rangeToTarget() + 1); if (victim != null) { victim.setRangeToTarget(rangeToTarget()); victim.recoverPhyStats(); } else setRangeToTarget(-1); recoverPhyStats(); } else if ((msg.tool() != null) && (srcMinor != CMMsg.TYP_BUY) && (srcMinor != CMMsg.TYP_BID) && (srcMinor != CMMsg.TYP_SELL) && (srcMinor != CMMsg.TYP_VIEW)) { // this reason this is here and not in stdability protecting // mana usage is because the target must be determined for // last second ranging, which stdability invoke won't know. int useRange = -1; final Environmental tool = msg.tool(); if (getVictim() != null) { if (getVictim() == trgM) useRange = rangeToTarget(); else { if (trgM.getVictim() == this) useRange = trgM.rangeToTarget(); else useRange = maxRangeWith(tool); } } if ((useRange >= 0) && (maxRangeWith(tool) < useRange)) { srcM.tell(L("You are too far away from @x1 to use @x2.", trgM.name(srcM), tool.name())); return false; } else if ((useRange >= 0) && (minRangeWith(tool) > useRange)) { srcM.tell(L("You are too close to @x1 to use @x2.", trgM.name(srcM), tool.name())); if ((msg.targetMinor() == CMMsg.TYP_WEAPONATTACK) && (tool instanceof Weapon) && (!((Weapon) tool).amWearingAt(Wearable.IN_INVENTORY))) CMLib.commands().postRemove(this, (Weapon) msg.tool(), false); return false; } } } if ((msg.targetMinor() != CMMsg.NO_EFFECT) && (msg.amITarget(this))) { if ((amDead()) || (location() == null)) return false; if (CMath.bset(msg.targetMajor(), CMMsg.MASK_MALICIOUS)) { if (Log.combatChannelOn()) { Log.combatOut(srcM.Name() + ":" + Name() + ":" + CMMsg.TYPE_DESCS[msg.targetMinor()] + ":" + ((msg.tool() != null) ? msg.tool().Name() : "null")); } if ((msg.amISource(this)) && (!msg.sourceMajor(CMMsg.MASK_ALWAYS)) && ((msg.tool() == null) || (!(msg.tool() instanceof Ability)) || (!((Ability) msg.tool()).isNowAnAutoEffect()))) { srcM.tell(L("You like yourself too much.")); if (victim == this) { victim = null; setRangeToTarget(-1); } return false; } if ((!mayIFight(srcM)) && ((!(msg.tool() instanceof Ability)) || (((((Ability) msg.tool()).classificationCode() & Ability.ALL_ACODES) != Ability.ACODE_POISON) && ((((Ability) msg.tool()).classificationCode() & Ability.ALL_ACODES) != Ability.ACODE_DISEASE)) || ((srcM == this) && (srcM.isMonster())))) { srcM.tell(L("You may not attack @x1.", name(srcM))); srcM.setVictim(null); if (victim == srcM) setVictim(null); return false; } if ((srcM != this) && (!isMonster()) && (!srcM.isMonster()) && (soulMate() == null) && (srcM.soulMate() == null) && (CMath.abs(srcM.phyStats().level() - phyStats().level()) > CMProps.getPKillLevelDiff()) && (!CMSecurity.isAllowed(this, location(), CMSecurity.SecFlag.PKILL)) protected String fixChannelColors(final int channelCode, final String message) { final Session session = mySession; if(session != null && session.getColorCodes()[128 + channelCode]!=null) return CMStrings.replaceAll(message, ColorLibrary.SpecialColor.CHANNEL.getEscapeCode(), mySession.getColorCodes()[128 + channelCode]); srcM.tell(L("That is not EVEN a fair fight.")); srcM.setVictim(null); if (victim == srcM) setVictim(null); return false; } if ((amFollowing() == srcM) && (!(msg.tool() instanceof DiseaseAffect))) setFollowing(null); if (isInCombat()) { if ((rangeToTarget() > 0) && (getVictim() != srcM) && (srcM.getVictim() == this) && (srcM.rangeToTarget() == 0)) { setVictim(srcM); setRangeToTarget(0); } } if (!CMLib.combat().checkSavingThrows(this, msg)) return false; } if ((rangeToTarget() >= 0) && (!isInCombat())) setRangeToTarget(-1); switch (msg.targetMinor()) { case CMMsg.TYP_CLOSE: case CMMsg.TYP_DRINK: case CMMsg.TYP_DROP: case CMMsg.TYP_EAT: case CMMsg.TYP_FILL: case CMMsg.TYP_GET: case CMMsg.TYP_HOLD: case CMMsg.TYP_REMOVE: case CMMsg.TYP_LOCK: case CMMsg.TYP_OPEN: case CMMsg.TYP_PUT: case CMMsg.TYP_UNLOCK: case CMMsg.TYP_WEAR: case CMMsg.TYP_WIELD: srcM.tell(srcM, this, null, L("You can't do that to <T-NAMESELF>.")); return false; case CMMsg.TYP_POUR: { boolean permitted = false; if (msg.tool() instanceof Potion) { for (final Ability A : ((Potion) msg.tool()).getSpells()) { if (A.castingQuality(msg.source(), this) != Ability.QUALITY_MALICIOUS) permitted = true; } } else permitted = true; if (!permitted) { srcM.tell(srcM, this, null, L("You can't do that to <T-NAMESELF>.")); return false; } break; } case CMMsg.TYP_TEACH: if (playerStats() == null) { srcM.tell(srcM, this, null, L("<T-NAME> isn't interested.")); return false; } if (playerStats().isIgnored(msg.source())) return false; if (!CMLib.expertises().canBeTaught(msg.source(), (MOB) msg.target(), msg.tool(), msg.targetMessage())) return false; break; case CMMsg.TYP_DAMAGE: if (!CMLib.combat().checkDamageSaves(this, msg)) return false; break; case CMMsg.TYP_PULL: if ((!CMLib.flags().isBoundOrHeld(this)) && (!CMLib.flags().isSleeping(this))) { srcM.tell(srcM, this, null, L("You can't do that to <T-NAMESELF>.")); return false; } if (phyStats().weight() > (srcM.maxCarry() / 2)) { srcM.tell(srcM, this, null, L("<T-NAME> is too big for you to pull.")); return false; } if ((srcM.curState().getMovement() < phyStats.movesReqToPull()) && (srcM.curState().getMovement() < srcM.maxState().getMovement())) { srcM.tell(L("You don't have enough movement.")); return false; } break; case CMMsg.TYP_PUSH: if ((!CMLib.flags().isBoundOrHeld(this)) && (!CMLib.flags().isSleeping(this))) { srcM.tell(srcM, this, null, L("You can't do that to <T-NAMESELF>.")); return false; } if (phyStats().weight() > (srcM.maxCarry() / 2)) { srcM.tell(srcM, this, null, L("<T-NAME> is too heavy for you to push.")); return false; } if ((srcM.curState().getMovement() < phyStats.movesReqToPush()) && (srcM.curState().getMovement() < srcM.maxState().getMovement())) { srcM.tell(L("You don't have enough movement.")); return false; } break; case CMMsg.TYP_MOUNT: case CMMsg.TYP_DISMOUNT: if (!(this instanceof Rideable)) { srcM.tell(srcM, this, null, L("You can't do that to <T-NAMESELF>.")); return false; } break; case CMMsg.TYP_GIVE: if (!(msg.tool() instanceof Item)) return false; if (CMSecurity.isAllowed(this, location(), CMSecurity.SecFlag.ORDER) || (CMSecurity.isAllowed(this, location(), CMSecurity.SecFlag.CMDMOBS) && (isMonster())) || (CMSecurity.isAllowed(this, location(), CMSecurity.SecFlag.CMDROOMS) && (isMonster()))) return true; if ((charStats().getBodyPart(Race.BODY_ARM) == 0) && (baseCharStats().getMyRace().bodyMask()[Race.BODY_ARM] > 0) && (!CMath.bset(msg.targetMajor(), CMMsg.MASK_ALWAYS))) { srcM.tell(L("@x1 is unable to accept that from you.", name(srcM))); return false; } if ((!CMLib.flags().canBeSeenBy(msg.tool(), this)) && (!CMath.bset(msg.targetMajor(), CMMsg.MASK_ALWAYS))) { srcM.tell(L("@x1 can't see what you are giving.", name(srcM))); return false; } final int GC = msg.targetMajor() & CMMsg.MASK_ALWAYS; CMMsg msg2 = CMClass.getMsg(srcM, msg.tool(), null, CMMsg.MSG_DROP | CMMsg.MASK_INTERMSG, null, CMMsg.MSG_DROP | CMMsg.MASK_INTERMSG, null, CMMsg.MSG_DROP | CMMsg.MASK_INTERMSG, null); if (!location().okMessage(srcM, msg2)) return false; if (msg.target() instanceof MOB) { msg2 = CMClass.getMsg((MOB) msg.target(), msg.tool(), null, GC | CMMsg.MSG_GET | CMMsg.MASK_INTERMSG, null, GC | CMMsg.MSG_GET | CMMsg.MASK_INTERMSG, null, GC | CMMsg.MSG_GET | CMMsg.MASK_INTERMSG, null); if (!location().okMessage(msg.target(), msg2)) { srcM.tell(L("@x1 cannot seem to accept @x2.", ((Physical) msg.target()).name(srcM), ((Physical) msg.tool()).name(this))); return false; } } break; case CMMsg.TYP_FOLLOW: if (totalFollowers() + srcM.totalFollowers() >= maxFollowers()) { srcM.tell(L("@x1 can't accept any more followers.", name(srcM))); return false; } if ((CMProps.getIntVar(CMProps.Int.FOLLOWLEVELDIFF) > 0) && (!isMonster()) && (!srcM.isMonster()) && (!CMSecurity.isAllowed(this, location(), CMSecurity.SecFlag.ORDER)) && (!CMSecurity.isAllowed(srcM, srcM.location(), CMSecurity.SecFlag.ORDER))) { if (phyStats.level() > (srcM.phyStats().level() + CMProps.getIntVar(CMProps.Int.FOLLOWLEVELDIFF))) { srcM.tell(L("@x1 is too advanced for you.", name(srcM))); return false; } if (phyStats.level() < (srcM.phyStats().level() - CMProps.getIntVar(CMProps.Int.FOLLOWLEVELDIFF))) { srcM.tell(L("@x1 is too inexperienced for you.", name(srcM))); return false; } } break; } } if ((srcM != this) && (msg.target()
{'commit': 'diff --git a/com/planet_ink/coffee_mud/Behaviors/Mobile.java b/com/planet_ink/coffee_mud/Behaviors/Mobile.java\nindex 59a8bdfe75..fca51949f4 100644\n--- a/com/planet_ink/coffee_mud/Behaviors/Mobile.java\n+++ b/com/planet_ink/coffee_mud/Behaviors/Mobile.java\n@@ -205,7 +205,8 @@ public class Mobile extends ActiveTicker implements MobileBehavior\n \tpublic boolean emergencyMove(MOB mob, Room room)\r\n \t{\r\n \t\tint tries=30;\r\n-\t\tif(!room.getMobility())\r\n+\t\tif((room == null)\r\n+\t\t||(!room.getMobility()))\r\n \t\t{\r\n \t\t\tfirstRun=true;\r\n \t\t\treturn false;\r\ndiff --git a/com/planet_ink/coffee_mud/MOBS/StdMOB.java b/com/planet_ink/coffee_mud/MOBS/StdMOB.java\nindex 688abc7f55..ed704aed4b 100644\n--- a/com/planet_ink/coffee_mud/MOBS/StdMOB.java\n+++ b/com/planet_ink/coffee_mud/MOBS/StdMOB.java\n@@ -3033,6 +3033,7 @@ public class StdMOB implements MOB\n \r\n \tprotected String fixChannelColors(final int channelCode, final String message)\r\n \t{\r\n+\t\t\r\n \t\tfinal Session session = mySession;\r\n \t\tif(session != null && session.getColorCodes()[128 + channelCode]!=null)\r\n \t\t\treturn CMStrings.replaceAll(message, ColorLibrary.SpecialColor.CHANNEL.getEscapeCode(), mySession.getColorCodes()[128 + channelCode]);\r\n', 'commit_subject': '', 'repo_name': 'bozimmerman/CoffeeMud', 'committer': {'name': 'bozimmerman', 'email': 'dc45fe023482b3b890b5e574e53c1d051f45b1ef@zimmers.net', 'time_sec': '1473466814', 'tz_offset': '0', 'date': {'seconds': '1473466814'}}, 'commit_tree': '88de6cd7fec7c05bc2f692ea51f4e37aa37e997e', 'commit_message': '\n\ngit-svn-id: svn://192.168.1.10/public/CoffeeMud@14619 0d6f1817-ed0e-0410-87c9-987e46238f29\n', 'language_name': 'HTML', 'license': 'apache-2.0', 'hunks': '@@ -3033,6 +3033,7 @@ public class StdMOB implements MOB\n \r\n \tprotected String fixChannelColors(final int channelCode, final String message)\r\n \t{\r\n+\t\t\r\n \t\tfinal Session session = mySession;\r\n \t\tif(session != null && session.getColorCodes()[128 + channelCode]!=null)\r\n \t\t\treturn CMStrings.replaceAll(message, ColorLibrary.SpecialColor.CHANNEL.getEscapeCode(), mySession.getColorCodes()[128 + channelCode]);\r\n', 'addition_count': 1, 'deletion_count': 0, 'src_file': 'a/com/planet_ink/coffee_mud/MOBS/StdMOB.java', 'tgt_file': 'b/com/planet_ink/coffee_mud/MOBS/StdMOB.java', 'file_extension': '.java', 'before_file': 'package com.planet_ink.coffee_mud.MOBS;\n\nimport com.planet_ink.coffee_mud.core.interfaces.*;\nimport com.planet_ink.coffee_mud.core.interfaces.EachApplicable.ApplyAffectPhyStats;\nimport com.planet_ink.coffee_mud.core.interfaces.ItemPossessor.Move;\nimport com.planet_ink.coffee_mud.core.*;\nimport com.planet_ink.coffee_mud.core.CMSecurity.DisFlag;\nimport com.planet_ink.coffee_mud.core.collections.*;\nimport com.planet_ink.coffee_mud.core.exceptions.CMException;\nimport com.planet_ink.coffee_mud.core.exceptions.CharStatOutOfRangeException;\nimport com.planet_ink.coffee_mud.Abilities.interfaces.*;\nimport com.planet_ink.coffee_mud.Areas.interfaces.*;\nimport com.planet_ink.coffee_mud.Areas.interfaces.Area.State;\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.FData;\nimport com.planet_ink.coffee_mud.Common.interfaces.PlayerStats.PlayerCombatStat;\nimport com.planet_ink.coffee_mud.Exits.interfaces.*;\nimport com.planet_ink.coffee_mud.Items.Basic.StdItem;\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.lang.ref.WeakReference;\nimport java.util.*;\nimport java.util.Map.Entry;\nimport java.util.concurrent.atomic.AtomicBoolean;\n\nimport com.planet_ink.coffee_mud.Libraries.interfaces.*;\nimport com.planet_ink.coffee_mud.Libraries.interfaces.AchievementLibrary.Event;\nimport com.planet_ink.coffee_mud.Libraries.interfaces.ChannelsLibrary.CMChannel;\n\n/*\n Copyright 2000-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 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, e\\ither express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n */\n//STOP-ECLIPSE-FORMATTING\n// @formatter: off\npublic class StdMOB implements MOB\n{\n\t@Override\n\tpublic String ID()\n\t{\n\t\treturn "StdMOB";\n\t}\n\n\tpublic String\t\t\t\t_name\t\t\t\t= "";\n\n\tprotected CharStats\t\t\tbaseCharStats\t\t= (CharStats) CMClass.getCommon("DefaultCharStats");\n\tprotected CharStats\t\t\tcharStats\t\t\t= (CharStats) CMClass.getCommon("DefaultCharStats");\n\n\tprotected PhyStats\t\t\tphyStats\t\t\t= (PhyStats) CMClass.getCommon("DefaultPhyStats");\n\tprotected PhyStats\t\t\tbasePhyStats\t\t= (PhyStats) CMClass.getCommon("DefaultPhyStats");\n\n\tprotected PlayerStats\t\tplayerStats\t\t\t= null;\n\n\tprotected Triggerer\t\t\ttriggerer\t\t\t= (Triggerer) CMClass.getCommon("NonTriggerer");\n\n\tprotected boolean\t\t\tamDestroyed\t\t\t= false;\n\tprotected boolean\t\t\tremoveFromGame\t\t= false;\n\tprotected volatile boolean\tamDead\t\t\t\t= false;\n\n\tprotected volatile Room\t\tlocation\t\t\t= null;\n\tprotected volatile Room\t\tlastLocation\t\t= null;\n\tprotected Rideable\t\t\triding\t\t\t\t= null;\n\n\tprotected volatile Session\tmySession\t\t\t= null;\n\tprotected Object\t\t\tdescription\t\t\t= null;\n\tprotected String\t\t\tdisplayText\t\t\t= "";\n\tprotected String\t\t\trawImageName\t\t= null;\n\tprotected String\t\t\tcachedImageName\t\t= null;\n\tprotected Object\t\t\tmiscText\t\t\t= null;\n\tprotected String[]\t\t\txtraValues\t\t\t= null;\n\n\t// gained attributes\n\tprotected int\t\t\t\texperience\t\t\t= 0;\n\tprotected int\t\t\t\tpractices\t\t\t= 0;\n\tprotected int\t\t\t\ttrains\t\t\t\t= 0;\n\tprotected long\t\t\t\tageMinutes\t\t\t= 0;\n\tprotected int\t\t\t\tmoney\t\t\t\t= 0;\n\tprotected double\t\t\tmoneyVariation\t\t= 0.0;\n\tprotected double\t\t\tspeedAdj\t\t\t= CMProps.getSpeedAdjustment();\n\tprotected int\t\t\t\tattributesBitmap\t= MOB.Attrib.NOTEACH.getBitCode();\n\tprotected String\t\t\tdatabaseID\t\t\t= "";\n\n\tprotected int\t\t\t\ttickAgeCounter\t\t= 0;\n\tprotected int\t\t\t\trecoverTickCter\t\t= 1;\n\tprotected int\t\t\t\tvalidChkCounter\t\t= 60;\n\tprivate long\t\t\t\texpirationDate\t\t= 0;\n\tprivate int\t\t\t\t\tmanaConsumeCter\t\t= CMLib.dice().roll(1, 10, 0);\n\tprivate volatile double\t\tfreeActions\t\t\t= 0.0;\n\n\t// the core state values\n\tpublic CharState\t\t\tcurState\t\t\t= (CharState) CMClass.getCommon("DefaultCharState");\n\tpublic CharState\t\t\tmaxState\t\t\t= (CharState) CMClass.getCommon("DefaultCharState");\n\tpublic CharState\t\t\tbaseState\t\t\t= (CharState) CMClass.getCommon("DefaultCharState");\n\tprivate long\t\t\t\tlastTickedTime\t\t= 0;\n\tprivate long\t\t\t\tlastCommandTime\t\t= System.currentTimeMillis();\n\n\tprotected Room\t\t\t\tpossStartRoom\t\t= null;\n\tprotected String\t\t\tliegeID\t\t\t\t= "";\n\tprotected int\t\t\t\twimpHitPoint\t\t= 0;\n\tprotected int\t\t\t\tquestPoint\t\t\t= 0;\n\tprotected MOB\t\t\t\tvictim\t\t\t\t= null;\n\tprotected Followable<MOB>\tamFollowing\t\t\t= null;\n\tprotected MOB\t\t\t\tsoulMate\t\t\t= null;\n\tprotected int\t\t\t\tatRange\t\t\t\t= -1;\n\tprotected long\t\t\t\tpeaceTime\t\t\t= 0;\n\tprotected boolean\t\t\tkickFlag\t\t\t= false;\n\tprotected MOB\t\t\t\tme\t\t\t\t\t= this;\n\n\tprotected int\t\t\t\ttickStatus\t\t\t= Tickable.STATUS_NOT;\n\n\t/* containers of items and attributes */\n\tprotected SVector<Item>\t\t\t\t\tinventory\t\t\t= new SVector<Item>(1);\n\tprotected CMUniqSortSVec<Ability>\t\tabilitys\t\t\t= new CMUniqSortSVec<Ability>(1);\n\tprotected int[]\t\t\t\t\t\t\tabilityUseTrig\t\t= new int[Ability.USAGEINDEX_TOTAL];\n\tprotected STreeMap<String, int[][]>\t\tabilityUseCache\t\t= new STreeMap<String, int[][]>();\n\tprotected STreeMap<String, Integer>\t\texpertises\t\t\t= new STreeMap<String, Integer>();\n\tprotected SVector<Ability>\t\t\t\taffects\t\t\t\t= new SVector<Ability>(1);\n\tprotected CMUniqSortSVec<Behavior>\t\tbehaviors\t\t\t= new CMUniqSortSVec<Behavior>(1);\n\tprotected CMUniqNameSortSVec<Tattoo>\ttattoos\t\t\t\t= new CMUniqNameSortSVec<Tattoo>(1);\n\tprotected volatile PairList<MOB, Short>\tfollowers\t\t\t= null;\n\tprotected LinkedList<QMCommand>\t\t\tcommandQue\t\t\t= new LinkedList<QMCommand>();\n\tprotected SVector<ScriptingEngine>\t\tscripts\t\t\t\t= new SVector<ScriptingEngine>(1);\n\tprotected volatile List<Ability>\t\tracialAffects\t\t= null;\n\tprotected volatile List<Ability>\t\tclanAffects\t\t\t= null;\n\tprotected SHashtable<String, FData>\t\tfactions\t\t\t= new SHashtable<String, FData>(1);\n\tprotected volatile WeakReference<Item>\tpossWieldedItem\t\t= null;\n\tprotected volatile WeakReference<Item>\tpossHeldItem\t\t= null;\n\n\tprotected ApplyAffectPhyStats<Ability>\taffectPhyStats\t\t= new ApplyAffectPhyStats<Ability>(this);\n\tprotected ApplyRecAffectPhyStats<Item>\trecoverAffectP\t\t= new ApplyRecAffectPhyStats<Item>(this);\n\t@SuppressWarnings("rawtypes")\n\tprotected ApplyAffectCharStats\t\t\taffectCharStats\t\t= new ApplyAffectCharStats(this);\n\t@SuppressWarnings("rawtypes")\n\tprotected ApplyAffectCharState\t\t\taffectCharState\t\t= new ApplyAffectCharState(this);\n\n\tprotected OrderedMap<String, Pair<Clan, Integer>>\tclans\t= new OrderedMap<String, Pair<Clan, Integer>>();\n\n\tpublic StdMOB()\n\t{\n\t\tsuper();\n\t\t// CMClass.bumpCounter(this,CMClass.CMObjectType.MOB);//removed for mem\n\t\t// & perf\n\t\tRace R = CMClass.getRace("Human");\n\t\tif (R == null)\n\t\t\tR = CMClass.getRace("StdRace");\n\t\tbaseCharStats().setMyRace(R);\n\t\tbasePhyStats().setLevel(1);\n\t\tspeedAdj = CMProps.getSpeedAdjustment();\n\t\txtraValues = CMProps.getExtraStatCodesHolder(this);\n\t}\n\n\tprivate static class QMCommand\n\t{\n\t\tpublic Object\t\tcommandObj\t\t= null;\n\t\tpublic double\t\tactionCost\t\t= 0.0;\n\t\tpublic long\t\t\tnextCheck\t\t= System.currentTimeMillis() - 1;\n\t\tpublic int\t\t\tseconds\t\t\t= -1;\n\t\tpublic int\t\t\tmetaFlags\t\t= 0;\n\t\tpublic List<String>\tcommandVector\t= null;\n\t}\n\n\tprivate static final Converter<Pair<MOB, Short>, MOB>\tFollowerConverter\t= new Pair.FirstConverter<MOB, Short>();\n\n\t/**\n\t * EachApplicable class that recovers item and affect phyStats\n\t */\n\tpublic static final class ApplyRecAffectPhyStats<T extends StatsAffecting> extends ApplyAffectPhyStats<T>\n\t{\n\t\tpublic ApplyRecAffectPhyStats(final Physical me)\n\t\t{\n\t\t\tsuper(me);\n\t\t}\n\n\t\t@Override\n\t\tpublic void apply(final T a)\n\t\t{\n\t\t\t((Affectable) a).recoverPhyStats();\n\t\t\tsuper.apply(a);\n\t\t}\n\t}\n\n\t/**\n\t * EachApplicable class that affect charStats\n\t */\n\tpublic static class ApplyAffectCharStats<T extends StatsAffecting> implements EachApplicable<T>\n\t{\n\t\tprotected final MOB\tme;\n\n\t\tpublic ApplyAffectCharStats(final MOB me)\n\t\t{\n\t\t\tthis.me = me;\n\t\t}\n\n\t\t@Override\n\t\tpublic void apply(final T a)\n\t\t{\n\t\t\ta.affectCharStats(me, me.charStats());\n\t\t}\n\t}\n\n\t/**\n\t * EachApplicable class that affect charState\n\t */\n\tpublic static class ApplyAffectCharState<T extends StatsAffecting> implements EachApplicable<T>\n\t{\n\t\tprotected final MOB\tme;\n\n\t\tpublic ApplyAffectCharState(final MOB me)\n\t\t{\n\t\t\tthis.me = me;\n\t\t}\n\n\t\t@Override\n\t\tpublic void apply(final T a)\n\t\t{\n\t\t\ta.affectCharState(me, me.maxState());\n\t\t}\n\t}\n\n\t@Override\n\tpublic long lastTickedDateTime()\n\t{\n\t\treturn lastTickedTime;\n\t}\n\n\t@Override\n\tpublic void flagVariableEq()\n\t{\n\t\tlastTickedTime = -3;\n\t}\n\n\t@Override\n\tpublic long getAgeMinutes()\n\t{\n\t\treturn ageMinutes;\n\t}\n\n\t@Override\n\tpublic int getPractices()\n\t{\n\t\treturn practices;\n\t}\n\n\t@Override\n\tpublic int getExperience()\n\t{\n\t\treturn experience;\n\t}\n\n\t@Override\n\tpublic int getExpNextLevel()\n\t{\n\t\treturn CMLib.leveler().getLevelExperience(this, basePhyStats().level());\n\t}\n\n\t@Override\n\tpublic int getExpPrevLevel()\n\t{\n\t\tif (basePhyStats().level() <= 1)\n\t\t\treturn 0;\n\t\tfinal int neededLowest = CMLib.leveler().getLevelExperience(this, basePhyStats().level() - 2);\n\t\treturn neededLowest;\n\t}\n\n\t@Override\n\tpublic int getExpNeededDelevel()\n\t{\n\t\tif (basePhyStats().level() <= 1)\n\t\t\treturn 0;\n\t\tif ((CMSecurity.instance(session())._isDisabled(CMSecurity.DisFlag.EXPERIENCE))\n\t\t|| (charStats().getCurrentClass().expless())\n\t\t|| (charStats().getMyRace().expless()))\n\t\t\treturn 0;\n\t\tint ExpPrevLevel = getExpPrevLevel();\n\t\tif (ExpPrevLevel > getExperience())\n\t\t\tExpPrevLevel = getExperience() - 1000;\n\t\treturn getExperience() - ExpPrevLevel;\n\t}\n\n\t@Override\n\tpublic int getExpNeededLevel()\n\t{\n\t\tfinal int lastPlayerLevel = CMProps.get(session()).getInt(CMProps.Int.LASTPLAYERLEVEL);\n\t\tif ((lastPlayerLevel > 0) && (lastPlayerLevel <= basePhyStats().level()))\n\t\t\treturn Integer.MAX_VALUE;\n\t\tif ((CMSecurity.instance(session())._isDisabled(CMSecurity.DisFlag.EXPERIENCE))\n\t\t|| (charStats().getCurrentClass().expless())\n\t\t|| (charStats().getMyRace().expless()))\n\t\t\treturn Integer.MAX_VALUE;\n\t\tint expNextLevel = getExpNextLevel();\n\t\tif (expNextLevel < getExperience())\n\t\t\texpNextLevel = getExperience() + 1;\n\t\treturn expNextLevel - getExperience();\n\t}\n\n\t@Override\n\tpublic int getTrains()\n\t{\n\t\treturn trains;\n\t}\n\n\t@Override\n\tpublic int getMoney()\n\t{\n\t\treturn money;\n\t}\n\n\t@Override\n\tpublic double getMoneyVariation()\n\t{\n\t\treturn moneyVariation;\n\t}\n\n\t@Override\n\tpublic int getAttributesBitmap()\n\t{\n\t\treturn attributesBitmap;\n\t}\n\n\t@Override\n\tpublic void setAgeMinutes(final long newVal)\n\t{\n\t\tageMinutes = newVal;\n\t}\n\n\t@Override\n\tpublic void setExperience(final int newVal)\n\t{\n\t\tif ((newVal > experience) && (this.playerStats() != null))\n\t\t{\n\t\t\tthis.playerStats().bumpLevelCombatStat(PlayerCombatStat.EXPERIENCE_TOTAL, basePhyStats().level(), newVal - experience);\n\t\t\tthis.playerStats().setLastXPAwardMillis(System.currentTimeMillis());\n\t\t}\n\t\texperience = newVal;\n\t}\n\n\t@Override\n\tpublic void setPractices(final int newVal)\n\t{\n\t\tpractices = newVal;\n\t}\n\n\t@Override\n\tpublic void setTrains(final int newVal)\n\t{\n\t\ttrains = newVal;\n\t}\n\n\t@Override\n\tpublic void setMoney(final int newVal)\n\t{\n\t\tmoney = newVal;\n\t}\n\n\t@Override\n\tpublic void setMoneyVariation(final double newVal)\n\t{\n\t\tmoneyVariation = newVal;\n\t}\n\n\t@Override\n\tpublic void setAttributesBitmap(final int bitmap)\n\t{\n\t\tthis.attributesBitmap = bitmap;\n\t}\n\n\t@Override\n\tpublic void setAttribute(final Attrib attrib, final boolean set)\n\t{\n\t\tif (set)\n\t\t{\n\t\t\tattributesBitmap = attributesBitmap | attrib.getBitCode();\n\t\t}\n\t\telse\n\t\t{\n\t\t\tattributesBitmap = attributesBitmap & ~attrib.getBitCode();\n\t\t}\n\t}\n\n\t@Override\n\tpublic boolean isAttributeSet(final MOB.Attrib attrib)\n\t{\n\t\treturn (attributesBitmap & attrib.getBitCode()) != 0;\n\t}\n\n\t@Override\n\tpublic String getFactionListing()\n\t{\n\t\tfinal StringBuffer msg = new StringBuffer();\n\t\tfor (final Iterator<String> e = new XTreeSet<String>(factions()).iterator(); e.hasNext();)\n\t\t{\n\t\t\tfinal Faction F = CMLib.factions().getFaction(e.next());\n\t\t\tif (F != null)\n\t\t\t\tmsg.append(F.name() + "(" + fetchFaction(F.factionID()) + ");");\n\t\t}\n\t\treturn msg.toString();\n\t}\n\n\t@Override\n\tpublic String getLiegeID()\n\t{\n\t\treturn liegeID;\n\t}\n\n\t@Override\n\tpublic int getWimpHitPoint()\n\t{\n\t\treturn wimpHitPoint;\n\t}\n\n\t@Override\n\tpublic int getQuestPoint()\n\t{\n\t\treturn questPoint;\n\t}\n\n\t@Override\n\tpublic void setLiegeID(final String newVal)\n\t{\n\t\tliegeID = newVal;\n\t}\n\n\t@Override\n\tpublic void setWimpHitPoint(final int newVal)\n\t{\n\t\twimpHitPoint = newVal;\n\t}\n\n\t@Override\n\tpublic void setQuestPoint(final int newVal)\n\t{\n\t\tquestPoint = newVal;\n\t}\n\n\t@Override\n\tpublic void initializeClass()\n\t{\n\t}\n\n\t@Override\n\tpublic CMObject newInstance()\n\t{\n\t\ttry\n\t\t{\n\t\t\treturn this.getClass().newInstance();\n\t\t}\n\t\tcatch (final Exception e)\n\t\t{\n\t\t\tLog.errOut(ID(), e);\n\t\t}\n\t\treturn new StdMOB();\n\t}\n\n\t@Override\n\tpublic Room getStartRoom()\n\t{\n\t\treturn CMLib.map().getRoom(possStartRoom);\n\t}\n\n\t@Override\n\tpublic void setStartRoom(final Room room)\n\t{\n\t\tpossStartRoom = room;\n\t}\n\n\t@Override\n\tpublic void setDatabaseID(final String id)\n\t{\n\t\tdatabaseID = id;\n\t}\n\n\t@Override\n\tpublic boolean canSaveDatabaseID()\n\t{\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic String databaseID()\n\t{\n\t\treturn databaseID;\n\t}\n\n\t@Override\n\tpublic String Name()\n\t{\n\t\treturn _name;\n\t}\n\n\t@Override\n\tpublic void setName(final String newName)\n\t{\n\t\t_name = newName;\n\t}\n\n\t@Override\n\tpublic String name()\n\t{\n\t\tif (phyStats().newName() != null)\n\t\t\treturn phyStats().newName();\n\t\treturn _name;\n\t}\n\n\t@Override\n\tpublic String titledName()\n\t{\n\t\tif (playerStats == null)\n\t\t\treturn name();\n\t\treturn CMStrings.replaceAll(playerStats.getActiveTitle(), "*", Name());\n\t}\n\n\t@Override\n\tpublic String genericName()\n\t{\n\t\tif ((charStats().getStat(CharStats.STAT_AGE) > 0) && (!CMSecurity.isDisabled(CMSecurity.DisFlag.ALL_AGEING)))\n\t\t\treturn charStats().ageName().toLowerCase() + " " + charStats().raceName().toLowerCase();\n\t\treturn charStats().raceName().toLowerCase();\n\t}\n\n\t@Override\n\tpublic String image()\n\t{\n\t\tif (cachedImageName == null)\n\t\t{\n\t\t\tif ((rawImageName != null) && (rawImageName.length() > 0))\n\t\t\t\tcachedImageName = rawImageName;\n\t\t\telse\n\t\t\t\tcachedImageName = CMLib.protocol().getDefaultMXPImage(this);\n\t\t}\n\t\tif (!baseCharStats().getMyRace().name().equalsIgnoreCase(charStats().raceName()))\n\t\t\treturn CMLib.protocol().getDefaultMXPImage(this);\n\t\tif (cachedImageName == null)\n\t\t\treturn "";\n\t\treturn cachedImageName;\n\t}\n\n\t@Override\n\tpublic String rawImage()\n\t{\n\t\tif (rawImageName == null)\n\t\t\treturn "";\n\t\treturn rawImageName;\n\t}\n\n\t@Override\n\tpublic void setImage(final String newImage)\n\t{\n\t\tif ((newImage == null) || (newImage.trim().length() == 0))\n\t\t\trawImageName = null;\n\t\telse\n\t\t\trawImageName = newImage;\n\t\tif ((cachedImageName != null) && (!cachedImageName.equals(newImage)))\n\t\t\tcachedImageName = null;\n\t}\n\n\t@Override\n\tpublic long expirationDate()\n\t{\n\t\treturn expirationDate;\n\t}\n\n\t@Override\n\tpublic void setExpirationDate(final long time)\n\t{\n\t\texpirationDate = time;\n\t}\n\n\t// protected void finalize()\n\t// CMClass.unbumpCounter(this,CMClass.CMObjectType.MOB); }//removed for mem\n\t// & perf\n\t@Override\n\tpublic final boolean amDestroyed()\n\t{\n\t\treturn this.amDestroyed;\n\t}\n\n\tprotected final void setDestroyed(final boolean truefalse)\n\t{\n\t\tthis.amDestroyed = truefalse;\n\t}\n\n\t@SuppressWarnings("rawtypes")\n\tprotected void cloneFix(final MOB M)\n\t{\n\t\tif (M == null)\n\t\t\treturn;\n\t\tsynchronized (this)\n\t\t{\n\t\t\tme = this;\n\t\t}\n\t\tsynchronized (M)\n\t\t{\n\t\t\tif (!isGeneric())\n\t\t\t{\n\t\t\t\tfinal PhyStats oldBase = basePhyStats;\n\t\t\t\tbasePhyStats = (PhyStats) M.basePhyStats().copyOf();\n\t\t\t\tphyStats = (PhyStats) M.phyStats().copyOf();\n\t\t\t\tbasePhyStats.setAbility(oldBase.ability());\n\t\t\t\tbasePhyStats.setRejuv(oldBase.rejuv());\n\t\t\t\tbasePhyStats.setLevel(oldBase.level());\n\t\t\t\tphyStats.setAbility(oldBase.ability());\n\t\t\t\tphyStats.setRejuv(oldBase.rejuv());\n\t\t\t\tphyStats.setLevel(oldBase.level());\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tbasePhyStats = (PhyStats) M.basePhyStats().copyOf();\n\t\t\t\tphyStats = (PhyStats) M.phyStats().copyOf();\n\t\t\t}\n\t\t}\n\n\t\taffectPhyStats = new ApplyAffectPhyStats<Ability>(this);\n\t\trecoverAffectP = new ApplyRecAffectPhyStats<Item>(this);\n\t\taffectCharStats = new ApplyAffectCharStats(this);\n\t\taffectCharState = new ApplyAffectCharState(this);\n\n\t\taffects = new SVector<Ability>();\n\t\tbaseCharStats = (CharStats) M.baseCharStats().copyOf();\n\t\tcharStats = (CharStats) M.charStats().copyOf();\n\t\tbaseState = (CharState) M.baseState().copyOf();\n\t\tcurState = (CharState) M.curState().copyOf();\n\t\tmaxState = (CharState) M.maxState().copyOf();\n\t\tremoveFromGame = false;\n\n\t\tinventory = new SVector<Item>();\n\t\tabilitys = new CMUniqSortSVec<Ability>();\n\t\tabilityUseTrig = new int[Ability.USAGEINDEX_TOTAL];\n\t\tabilityUseCache = new STreeMap<String, int[][]>();\n\t\tbehaviors = new CMUniqSortSVec<Behavior>();\n\t\ttattoos = new CMUniqNameSortSVec<Tattoo>();\n\t\texpertises = new STreeMap<String, Integer>();\n\t\tfollowers = null;\n\t\tcommandQue = new LinkedList<QMCommand>();\n\t\tscripts = new SVector<ScriptingEngine>();\n\t\tracialAffects = null;\n\t\tclanAffects = null;\n\t\tfactions = new SHashtable<String, FData>(1);\n\t\tpossWieldedItem = null;\n\t\tpossHeldItem = null;\n\t\tclans = new OrderedMap<String, Pair<Clan, Integer>>();\n\n\t\tfor (final Pair<Clan, Integer> p : M.clans())\n\t\t{\n\t\t\tsetClan(p.first.clanID(), p.second.intValue());\n\t\t}\n\t\tfor (final Enumeration<String> e = M.factions(); e.hasMoreElements();)\n\t\t{\n\t\t\tfinal String fac = e.nextElement();\n\t\t\taddFaction(fac, M.fetchFaction(fac));\n\t\t}\n\t\tfor (final Enumeration<Tattoo> e = M.tattoos(); e.hasMoreElements();)\n\t\t{\n\t\t\tfinal Tattoo t = e.nextElement();\n\t\t\taddTattoo((Tattoo) t.copyOf());\n\t\t}\n\t\tfor (final Enumeration<String> s = M.expertises(); s.hasMoreElements();)\n\t\t\taddExpertise(s.nextElement());\n\n\t\tItem I = null;\n\t\tfor (int i = 0; i < M.numItems(); i++)\n\t\t{\n\t\t\tI = M.getItem(i);\n\t\t\tif (I != null)\n\t\t\t\taddItem((Item) I.copyOf());\n\t\t}\n\t\tItem I2 = null;\n\t\tfor (int i = 0; i < numItems(); i++)\n\t\t{\n\t\t\tI = getItem(i);\n\t\t\tif ((I != null) && (I.container() != null) && (!isMine(I.container())))\n\t\t\t{\n\t\t\t\tfor (final Enumeration<Item> e = M.items(); e.hasMoreElements();)\n\t\t\t\t{\n\t\t\t\t\tI2 = e.nextElement();\n\t\t\t\t\tif ((I2 == I.container()) && (I2 instanceof Container))\n\t\t\t\t\t{\n\t\t\t\t\t\tI.setContainer((Container) I2);\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}\n\t\tAbility A = null;\n\t\tfor (int i = 0; i < M.numAbilities(); i++)\n\t\t{\n\t\t\tA = M.fetchAbility(i);\n\t\t\tif (A != null)\n\t\t\t\taddAbility((Ability) A.copyOf());\n\t\t}\n\t\ttry\n\t\t{\n\t\t\tsetDestroyed(true);\n\t\t\tfor (final Enumeration<Ability> a = M.personalEffects(); a.hasMoreElements();)\n\t\t\t{\n\t\t\t\tA = a.nextElement();\n\t\t\t\tif (A != null)\n\t\t\t\t{\n\t\t\t\t\tA = (Ability) A.copyOf();\n\t\t\t\t\taddEffect(A);\n\t\t\t\t\tif (A.canBeUninvoked())\n\t\t\t\t\t{\n\t\t\t\t\t\tA.unInvoke();\n\t\t\t\t\t\tdelEffect(A);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tsetDestroyed(false);\n\t\t}\n\t\tfor (final Enumeration<Behavior> e = M.behaviors(); e.hasMoreElements();)\n\t\t{\n\t\t\tfinal Behavior B = e.nextElement();\n\t\t\tif (B != null) // iteration during a clone would just be messed up.\n\t\t\t\tbehaviors.addElement((Behavior) B.copyOf());\n\t\t}\n\t\tScriptingEngine SE = null;\n\t\tfor (final Enumeration<ScriptingEngine> e = M.scripts(); e.hasMoreElements();)\n\t\t{\n\t\t\tSE = e.nextElement();\n\t\t\tif (SE != null)\n\t\t\t\taddScript((ScriptingEngine) SE.copyOf());\n\t\t}\n\t}\n\n\t@Override\n\tpublic CMObject copyOf()\n\t{\n\t\ttry\n\t\t{\n\t\t\tfinal StdMOB E = (StdMOB) this.clone();\n\t\t\t// CMClass.bumpCounter(E,CMClass.CMObjectType.MOB);//removed for mem\n\t\t\t// & perf\n\t\t\tE.xtraValues = (xtraValues == null) ? null : (String[]) xtraValues.clone();\n\t\t\tE.cloneFix(this);\n\t\t\tCMLib.catalog().newInstance(this);\n\t\t\treturn E;\n\t\t}\n\t\tcatch (final CloneNotSupportedException e)\n\t\t{\n\t\t\treturn this.newInstance();\n\t\t}\n\t}\n\n\t@Override\n\tpublic boolean isGeneric()\n\t{\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic PhyStats phyStats()\n\t{\n\t\treturn phyStats;\n\t}\n\n\t@Override\n\tpublic PhyStats basePhyStats()\n\t{\n\t\treturn basePhyStats;\n\t}\n\n\t@Override\n\tpublic void recoverPhyStats()\n\t{\n\t\tbasePhyStats.copyInto(phyStats);\n\t\tif(speedAdj!=1.0)\n\t\t{\n\t\t\tfinal double baseSpeed=phyStats.speed();\n\t\t\tif(baseSpeed>1.0)\n\t\t\t\tphyStats.setSpeed(1.0+((baseSpeed-1.0)*speedAdj));\n\t\t}\n\t\tphyStats.setWeight(phyStats.weight() + charStats.getStat(CharStats.STAT_WEIGHTADJ));\n\t\tif (location() != null)\n\t\t\tlocation().affectPhyStats(this, phyStats);\n\t\tif (getMoney() > 0)\n\t\t\tphyStats().setWeight(phyStats().weight() + (getMoney() / 100));\n\t\tfinal Rideable riding = riding();\n\t\tif (riding != null)\n\t\t\triding.affectPhyStats(this, phyStats);\n\t\tfinal Deity deity = charStats().getMyDeity();\n\t\tif (deity != null)\n\t\t\tdeity.affectPhyStats(this, phyStats);\n\t\tfinal CharStats cStats = charStats;\n\t\tif (cStats != null)\n\t\t{\n\t\t\tfor (int c = 0; c < cStats.numClasses(); c++)\n\t\t\t\tcStats.getMyClass(c).affectPhyStats(this, phyStats);\n\t\t\tcStats.getMyRace().affectPhyStats(this, phyStats);\n\t\t}\n\t\teachItem(recoverAffectP);\n\t\teachEffect(affectPhyStats);\n\t\tfor (final Enumeration<FData> e = factions.elements(); e.hasMoreElements();)\n\t\t\te.nextElement().affectPhyStats(this, phyStats);\n\t\t/* the follower light exception */\n\t\tif (!CMLib.flags().isLightSource(this))\n\t\t{\n\t\t\tfor (final Enumeration<Pair<MOB, Short>> f = followers(); f.hasMoreElements();)\n\t\t\t{\n\t\t\t\tif (CMLib.flags().isLightSource(f.nextElement().first))\n\t\t\t\t\tphyStats.setDisposition(phyStats().disposition() | PhyStats.IS_LIGHTSOURCE);\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic void setBasePhyStats(final PhyStats newStats)\n\t{\n\t\tbasePhyStats = (PhyStats) newStats.copyOf();\n\t}\n\n\t@Override\n\tpublic int baseWeight()\n\t{\n\t\tif (charStats().getMyRace() == baseCharStats().getMyRace())\n\t\t\treturn basePhyStats().weight() + charStats().getStat(CharStats.STAT_WEIGHTADJ);\n\t\treturn charStats().getMyRace().lightestWeight() + charStats().getStat(CharStats.STAT_WEIGHTADJ) + charStats().getMyRace().weightVariance();\n\t}\n\n\t@Override\n\tpublic int maxCarry()\n\t{\n\t\treturn CMLib.login().getMaxCarry(this);\n\t}\n\n\t@Override\n\tpublic int maxItems()\n\t{\n\t\treturn CMLib.login().getMaxItems(this);\n\t}\n\n\t@Override\n\tpublic int maxFollowers()\n\t{\n\t\treturn CMLib.login().getMaxFollowers(this);\n\t}\n\n\t@Override\n\tpublic int totalFollowers()\n\t{\n\t\tint total = 0;\n\t\ttry\n\t\t{\n\t\t\tfinal PairList<MOB, Short> followers = this.followers;\n\t\t\tif (followers != null)\n\t\t\t{\n\t\t\t\tfor (final Iterator<Pair<MOB, Short>> f = followers.iterator(); f.hasNext();)\n\t\t\t\t{\n\t\t\t\t\tfinal MOB F = f.next().first;\n\t\t\t\t\tif (F != this)\n\t\t\t\t\t\ttotal += (1 + F.totalFollowers());\n\t\t\t\t\telse\n\t\t\t\t\t\tf.remove();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch (final Exception t)\n\t\t{\n\t\t}\n\t\treturn total;\n\t}\n\n\t@Override\n\tpublic Triggerer triggerer()\n\t{\n\t\treturn triggerer;\n\t}\n\n\t@Override\n\tpublic void setTriggerer(final Triggerer triggerer)\n\t{\n\t\tif(triggerer != null)\n\t\t\tthis.triggerer = triggerer;\n\t}\n\n\t@Override\n\tpublic CharStats baseCharStats()\n\t{\n\t\treturn baseCharStats;\n\t}\n\n\t@Override\n\tpublic CharStats charStats()\n\t{\n\t\treturn charStats;\n\t}\n\n\t@SuppressWarnings("unchecked")\n\t@Override\n\tpublic void recoverCharStats()\n\t{\n\t\tbaseCharStats.setClassLevel(baseCharStats.getCurrentClass(), basePhyStats().level() - baseCharStats().combinedSubLevels());\n\t\tbaseCharStats.copyInto(charStats);\n\n\t\tfinal Rideable riding = riding();\n\t\tif (riding != null)\n\t\t\triding.affectCharStats(this, charStats);\n\t\tfinal Deity deity = baseCharStats.getMyDeity();\n\t\tif (deity != null)\n\t\t\tdeity.affectCharStats(this, charStats);\n\n\t\tfinal int num = charStats.numClasses();\n\t\tfor (int c = 0; c < num; c++)\n\t\t\tcharStats.getMyClass(c).affectCharStats(this, charStats);\n\t\tcharStats.getMyRace().affectCharStats(this, charStats);\n\t\tbaseCharStats.getMyRace().agingAffects(this, baseCharStats, charStats);\n\t\teachEffect(affectCharStats);\n\t\teachItem(affectCharStats);\n\t\tif (location() != null)\n\t\t\tlocation().affectCharStats(this, charStats);\n\t\tfor (final Enumeration<FData> e = factions.elements(); e.hasMoreElements();)\n\t\t\te.nextElement().affectCharStats(this, charStats);\n\t\tif ((playerStats != null) && (soulMate == null) && (playerStats.getHygiene() >= PlayerStats.HYGIENE_DELIMIT))\n\t\t{\n\t\t\tfinal int chaAdjust = (int) (playerStats.getHygiene() / PlayerStats.HYGIENE_DELIMIT);\n\t\t\tif ((charStats.getStat(CharStats.STAT_CHARISMA) / 2) > chaAdjust)\n\t\t\t\tcharStats.setStat(CharStats.STAT_CHARISMA, charStats.getStat(CharStats.STAT_CHARISMA) - chaAdjust);\n\t\t\telse\n\t\t\t\tcharStats.setStat(CharStats.STAT_CHARISMA, charStats.getStat(CharStats.STAT_CHARISMA) / 2);\n\t\t}\n\t}\n\n\t@Override\n\tpublic void setBaseCharStats(final CharStats newBaseCharStats)\n\t{\n\t\tbaseCharStats = (CharStats) newBaseCharStats.copyOf();\n\t}\n\n\t@Override\n\tpublic void affectPhyStats(final Physical affected, final PhyStats affectableStats)\n\t{\n\t\tif (affected instanceof Room)\n\t\t{\n\t\t\tif (CMLib.flags().isLightSource(this))\n\t\t\t\taffectableStats.setDisposition((affectableStats.disposition() & ~PhyStats.IS_DARK) | PhyStats.IS_LIGHTSOURCE);\n\t\t\telse\n\t\t\tif (CMLib.flags().isInDark(this))\n\t\t\t\taffectableStats.setDisposition((affectableStats.disposition() & ~PhyStats.IS_LIGHTSOURCE) | PhyStats.IS_DARK);\n\t\t}\n\t}\n\n\t@Override\n\tpublic void affectCharState(final MOB affectedMob, final CharState affectableMaxState)\n\t{\n\t}\n\n\t@Override\n\tpublic boolean isMarriedToLiege()\n\t{\n\t\tif (getLiegeID().length() == 0)\n\t\t\treturn false;\n\t\tif (getLiegeID().equals(Name()))\n\t\t\treturn false;\n\t\tif(!CMLib.players().playerExistsAllHosts(getLiegeID()))\n\t\t{\n\t\t\tsetLiegeID("");\n\t\t\treturn false;\n\t\t}\n\t\tfinal String otherLiegeID=CMLib.players().getLiegeOfUserAllHosts(getLiegeID());\n\t\treturn ((otherLiegeID!=null)&&(otherLiegeID.equalsIgnoreCase(Name())));\n\t}\n\n\t@Override\n\tpublic CharState curState()\n\t{\n\t\treturn curState;\n\t}\n\n\t@Override\n\tpublic CharState maxState()\n\t{\n\t\treturn maxState;\n\t}\n\n\t@Override\n\tpublic CharState baseState()\n\t{\n\t\treturn baseState;\n\t}\n\n\t@Override\n\tpublic PlayerStats playerStats()\n\t{\n\t\tif ((playerStats == null) && (soulMate != null))\n\t\t\treturn soulMate.playerStats();\n\t\treturn playerStats;\n\t}\n\n\t@Override\n\tpublic void setPlayerStats(final PlayerStats newStats)\n\t{\n\t\tplayerStats = newStats;\n\t}\n\n\t@Override\n\tpublic void setBaseState(final CharState newState)\n\t{\n\t\tbaseState = (CharState) newState.copyOf();\n\t\tmaxState = (CharState) newState.copyOf();\n\t}\n\n\t@Override\n\tpublic void resetToMaxState()\n\t{\n\t\trecoverMaxState();\n\t\tmaxState.copyInto(curState);\n\t}\n\n\t@SuppressWarnings("unchecked")\n\t@Override\n\tpublic void recoverMaxState()\n\t{\n\t\tbaseState.copyInto(maxState);\n\t\tif (charStats.getMyRace() != null)\n\t\t\tcharStats.getMyRace().affectCharState(this, maxState);\n\t\tfinal Rideable riding = riding();\n\t\tif (riding != null)\n\t\t\triding.affectCharState(this, maxState);\n\t\tfinal int num = charStats.numClasses();\n\t\tfor (int c = 0; c < num; c++)\n\t\t\tcharStats.getMyClass(c).affectCharState(this, maxState);\n\t\teachEffect(affectCharState);\n\t\teachItem(affectCharState);\n\t\tfor (final Enumeration<Faction.FData> e = factions.elements(); e.hasMoreElements();)\n\t\t\te.nextElement().affectCharState(this, maxState);\n\t\tif (location() != null)\n\t\t\tlocation().affectCharState(this, maxState);\n\t}\n\n\t@Override\n\tpublic boolean amDead()\n\t{\n\t\treturn amDead || removeFromGame;\n\t}\n\n\t@Override\n\tpublic boolean amActive()\n\t{\n\t\treturn !removeFromGame;\n\t}\n\n\t@Override\n\tpublic void dispossess(final boolean forceLook)\n\t{\n\t\tfinal MOB mate = soulMate();\n\t\tif (mate == null)\n\t\t\treturn;\n\t\tif ((mate.soulMate() != null) && (mate != this))\n\t\t\tmate.dispossess(forceLook);\n\t\tfinal Session s = session();\n\t\tif (s != null)\n\t\t{\n\t\t\ts.setMob(mate);\n\t\t\tmate.setSession(s);\n\t\t\tsetSession(null);\n\t\t\tif (forceLook)\n\t\t\t\tCMLib.commands().postLook(mate, true);\n\t\t\tsetSoulMate(null);\n\t\t}\n\t}\n\n\t@Override\n\tpublic void destroy()\n\t{\n\t\tCMLib.map().registerWorldObjectDestroyed(null, getStartRoom(), this);\n\t\ttry\n\t\t{\n\t\t\tCMLib.catalog().changeCatalogUsage(this, false);\n\t\t}\n\t\tcatch (final Exception t)\n\t\t{\n\t\t}\n\t\tif ((CMSecurity.isDebugging(CMSecurity.DbgFlag.MISSINGKIDS))\n\t\t&& (fetchEffect("Age") != null)\n\t\t&& CMath.isInteger(fetchEffect("Age").text())\n\t\t&& (CMath.s_long(fetchEffect("Age").text()) > Short.MAX_VALUE))\n\t\t\tLog.debugOut("MISSKIDS", new Exception(Name() + " went missing form " + CMLib.map().getExtendedRoomID(CMLib.map().roomLocation(this))));\n\t\tif (soulMate() != null)\n\t\t\tdispossess(false);\n\t\tfinal MOB possessor = CMLib.utensils().getMobPossessingAnother(this);\n\t\tif (possessor != null)\n\t\t\tpossessor.dispossess(false);\n\t\tif (session() != null)\n\t\t{\n\t\t\tsession().stopSession(false, false, false);\n\t\t\tCMLib.s_sleep(1000);\n\t\t}\n\t\tif (playerStats != null)\n\t\t\tCMLib.players().changePlayersLocation(this, null);\n\t\tremoveFromGame(session() != null, true);\n\t\tdelAllBehaviors();\n\t\tdelAllEffects(false);\n\t\tdelAllAbilities();\n\t\tdelAllItems(true);\n\t\tdelAllExpertises();\n\t\tdelAllScripts();\n\t\tif (kickFlag)\n\t\t\tCMLib.threads().deleteTick(this, -1);\n\t\tkickFlag = false;\n\t\tclans.clear();\n\t\tclanAffects = null;\n\t\tbaseCharStats.reset();\n\t\tcharStats.reset();\n\t\tbasePhyStats.reset();\n\t\tphyStats.reset();\n\t\tplayerStats = null;\n\t\tlocation = null;\n\t\tlastLocation = null;\n\t\triding = null;\n\t\tmySession = null;\n\t\trawImageName = null;\n\t\tcachedImageName = null;\n\t\tinventory.setSize(0);\n\t\tfollowers = null;\n\t\tabilitys.setSize(0);\n\t\ttriggerer.setObsolete();\n\t\tabilityUseCache.clear();\n\t\taffects.setSize(0);\n\t\tbehaviors.setSize(0);\n\t\ttattoos.setSize(0);\n\t\texpertises.clear();\n\t\tfactions.clear();\n\t\tcommandQue.clear();\n\t\tscripts.setSize(0);\n\t\tcurState = maxState;\n\t\tliegeID = "";\n\t\tvictim = null;\n\t\tamFollowing = null;\n\t\tsoulMate = null;\n\t\tpossStartRoom = null;\n\t\tsetDestroyed(true);\n\t}\n\n\t@Override\n\tpublic void removeFromGame(final boolean preserveFollowers, final boolean killSession)\n\t{\n\t\tremoveFromGame = true;\n\t\tfinal PlayerStats pStats = playerStats;\n\t\tif ((location != null) && (location.isInhabitant(this)))\n\t\t{\n\t\t\tlocation().delInhabitant(this);\n\t\t\tif ((session() != null) && (!CMProps.getBoolVar(CMProps.Bool.MUDSHUTTINGDOWN)))\n\t\t\t{\n\t\t\t\tfinal String msg = ((pStats!=null)&&(pStats.getPoofOut().length()>0))?\n\t\t\t\t\t\tpStats.getPoofOut():L("<S-NAME> vanish(es) in a puff of smoke.");\n\t\t\t\tlocation().showOthers(this, null, CMMsg.MSG_OK_ACTION,msg);\n\t\t\t}\n\t\t}\n\t\tif (pStats != null)\n\t\t\tCMLib.players().changePlayersLocation(this, null);\n\t\tsetFollowing(null);\n\t\tfinal PairList<MOB, Integer> oldFollowers = new PairArrayList<MOB, Integer>();\n\t\twhile (numFollowers() > 0)\n\t\t{\n\t\t\tfinal MOB follower = fetchFollower(0);\n\t\t\tif (follower != null)\n\t\t\t{\n\t\t\t\tif ((follower.isMonster())\n\t\t\t\t&& (!follower.isPossessing()))\n\t\t\t\t\toldFollowers.add(follower, Integer.valueOf(fetchFollowerOrder(follower)));\n\t\t\t\tfollower.setFollowing(null);\n\t\t\t\tdelFollower(follower);\n\t\t\t}\n\t\t}\n\n\t\tif (preserveFollowers)\n\t\t{\n\t\t\tfor (final Pair<MOB, Integer> p : oldFollowers)\n\t\t\t{\n\t\t\t\tfinal MOB follower = p.first;\n\t\t\t\tif (follower.location() != null)\n\t\t\t\t{\n\t\t\t\t\tfinal MOB newFol = (MOB) follower.copyOf();\n\t\t\t\t\tnewFol.basePhyStats().setRejuv(PhyStats.NO_REJUV);\n\t\t\t\t\tnewFol.phyStats().setRejuv(PhyStats.NO_REJUV);\n\t\t\t\t\tnewFol.text();\n\t\t\t\t\tfollower.killMeDead(false);\n\t\t\t\t\taddFollower(newFol, p.second.intValue());\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (pStats != null)\n\t\t\t{\n\t\t\t\tpStats.setLastDateTime(System.currentTimeMillis());\n\t\t\t\tCMLib.database().DBUpdateFollowers(this);\n\t\t\t\tif (CMSecurity.isASysOp(this)\n\t\t\t\t|| ((!CMSecurity.isDisabled(CMSecurity.DisFlag.LOGOUTS)))\n\t\t\t\t&& (CMLib.masking().maskCheck(CMProps.getVar(CMProps.Str.LOGOUTMASK), this, true)))\n\t\t\t\t{\n\t\t\t\t\tif (pStats != null) // cant do this when logouts are suspended -- folks might get killed!\n\t\t\t\t\t\tCMLib.threads().suspendResumeRecurse(this, false, true);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (killSession && (session() != null))\n\t\t\t\tsession().stopSession(false, false, false);\n\t\t}\n\t\tsetRiding(null);\n\t}\n\n\t@Override\n\tpublic void bringToLife()\n\t{\n\t\tamDead = false;\n\t\tremoveFromGame = false;\n\t\tspeedAdj = CMProps.getSpeedAdjustment();\n\n\t\t// will ensure no duplicate ticks, this obj, this id\n\t\tkickFlag = true;\n\t\tCMLib.threads().startTickDown(this, Tickable.TICKID_MOB, 1);\n\t\tif (tickStatus == Tickable.STATUS_NOT)\n\t\t{\n\t\t\tfinal boolean isImMobile = CMath.bset(phyStats.sensesMask(), PhyStats.CAN_NOT_MOVE);\n\t\t\ttry\n\t\t\t{\n\t\t\t\tphyStats.setSensesMask(phyStats.sensesMask() | PhyStats.CAN_NOT_MOVE);\n\t\t\t\ttick(this, Tickable.TICKID_MOB); // slap on the butt\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tphyStats.setSensesMask(CMath.dobit(phyStats.sensesMask(), PhyStats.CAN_NOT_MOVE, isImMobile));\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected final boolean confirmLocation(final Room whereHeShouldBeR)\n\t{\n\t\tif (location() == null)\n\t\t{\n\t\t\tif (getStartRoom() != null)\n\t\t\t{\n\t\t\t\tLog.errOut("StdMOB", name() + " of " + CMLib.map().getDescriptiveExtendedRoomID(whereHeShouldBeR) + " was auto-killed for being nowhere!");\n\t\t\t\tkillMeDead(false);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tLog.errOut("StdMOB", name() + " of " + CMLib.map().getDescriptiveExtendedRoomID(whereHeShouldBeR) + " was auto-destroyed by its tick!!");\n\t\t\t\tdestroy();\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic void bringToLife(final Room newLocation, final boolean resetStats)\n\t{\n\t\tamDead = false;\n\t\tspeedAdj = CMProps.getSpeedAdjustment();\n\t\tif ((miscText != null) && (resetStats) && (isGeneric()))\n\t\t{\n\t\t\tif (CMProps.getBoolVar(CMProps.Bool.MOBCOMPRESS) && (miscText instanceof byte[]))\n\t\t\t{\n\t\t\t\tfinal String decompressedStr = CMLib.encoder().decompressString((byte[]) miscText);\n\t\t\t\tfinal String unpackedStr = CMLib.coffeeMaker().getGenMOBTextUnpacked(this, decompressedStr);\n\t\t\t\tCMLib.coffeeMaker().resetGenMOB(this,unpackedStr );\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfinal String unpackedStr = CMLib.coffeeMaker().getGenMOBTextUnpacked(this, CMStrings.bytesToStr(miscText));\n\t\t\t\tCMLib.coffeeMaker().resetGenMOB(this, unpackedStr);\n\t\t\t}\n\t\t}\n\t\tif (CMLib.map().getStartRoom(this) == null)\n\t\t\tsetStartRoom(isMonster() ? newLocation : CMLib.login().getDefaultStartRoom(this));\n\t\tsetLocation(newLocation);\n\t\tif (location() == null)\n\t\t{\n\t\t\tsetLocation(CMLib.map().getStartRoom(this));\n\t\t\tif (!confirmLocation(newLocation))\n\t\t\t\treturn;\n\t\t}\n\t\tif (!location().isInhabitant(this))\n\t\t\tlocation().addInhabitant(this);\n\t\tremoveFromGame = false;\n\n\t\tif (session() != null)\n\t\t{\n\t\t\tfinal Area area = CMLib.map().areaLocation(location());\n\t\t\tif (area != null)\n\t\t\t\tCMLib.sessions().moveSessionToCorrectThreadGroup(session(), area.getTheme());\n\t\t}\n\n\t\t// will ensure no duplicate ticks, this obj, this id\n\t\tkickFlag = true;\n\t\tCMLib.threads().startTickDown(this, Tickable.TICKID_MOB, 1);\n\n\t\tAbility A = null;\n\t\tfor (int a = 0; a < numAbilities(); a++)\n\t\t{\n\t\t\tA = fetchAbility(a);\n\t\t\tif (A != null)\n\t\t\t\tA.autoInvocation(this, false);\n\t\t}\n\t\tif (!confirmLocation(newLocation))\n\t\t\treturn;\n\n\t\tif ((this.tattoos.size() == 0) || (findTattoo("SYSTEM_SUMMONED") == null))\n\t\t\tCMLib.factions().updatePlayerFactions(this, location(), false);\n\t\tif (tickStatus == Tickable.STATUS_NOT)\n\t\t{\n\t\t\tfinal boolean isImMobile = CMath.bset(phyStats.sensesMask(), PhyStats.CAN_NOT_MOVE);\n\t\t\ttry\n\t\t\t{\n\t\t\t\tphyStats.setSensesMask(phyStats.sensesMask() | PhyStats.CAN_NOT_MOVE);\n\t\t\t\ttick(this, Tickable.TICKID_MOB); // slap on the butt\n\t\t\t}\n\t\t\tcatch (final Exception t)\n\t\t\t{\n\t\t\t\tt.printStackTrace();\n\t\t\t}\n\t\t\tfinally\n\t\t\t{\n\t\t\t\tphyStats.setSensesMask(CMath.dobit(phyStats.sensesMask(), PhyStats.CAN_NOT_MOVE, isImMobile));\n\t\t\t}\n\t\t}\n\t\tif (!confirmLocation(newLocation))\n\t\t\treturn;\n\n\t\tlocation().recoverRoomStats();\n\t\tif ((!isGeneric()) && (resetStats))\n\t\t{\n\t\t\tresetToMaxState();\n\t\t}\n\n\t\tif (!confirmLocation(newLocation))\n\t\t\treturn;\n\n\t\tif (isMonster())\n\t\t{\n\t\t\tfinal Item dropItem = CMLib.catalog().getDropItem(this, true);\n\t\t\tif (dropItem != null)\n\t\t\t\taddItem(dropItem);\n\t\t}\n\t\tCMLib.awards().giveAutoProperties(me);\n\n\t\tCMLib.map().registerWorldObjectLoaded(null, getStartRoom(), this);\n\t\tlocation().show(this, null, CMMsg.MSG_BRINGTOLIFE, null);\n\t\tif (!amDestroyed)\n\t\t{\n\t\t\tif (CMLib.flags().isSleeping(this))\n\t\t\t\ttell(L("(You are asleep)"));\n\t\t\telse\n\t\t\t\tCMLib.commands().postLook(this, true);\n\t\t}\n\t\tpossWieldedItem = null;\n\t\tpossHeldItem = null;\n\t\tinventory.trimToSize();\n\t\tabilitys.trimToSize();\n\t\taffects.trimToSize();\n\t\tbehaviors.trimToSize();\n\t}\n\n\t@Override\n\tpublic boolean isInCombat()\n\t{\n\t\tif (victim == null)\n\t\t\treturn false;\n\t\ttry\n\t\t{\n\t\t\tfinal Room vicR = victim.location();\n\t\t\tif ((vicR == null)\n\t\t\t|| (location() == null)\n\t\t\t|| (vicR != location())\n\t\t\t|| (victim.amDead()))\n\t\t\t{\n\t\t\t\tif ((victim instanceof StdMOB) && (((StdMOB) victim).victim == this))\n\t\t\t\t\tvictim.setVictim(null);\n\t\t\t\tsetVictim(null);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\tcatch (final NullPointerException n)\n\t\t{\n\t\t}\n\t\treturn false;\n\t}\n\n\tprotected boolean isEitherOfUsDead(final MOB mob)\n\t{\n\t\tif (location() == null)\n\t\t\treturn true;\n\t\tif (mob.location() == null)\n\t\t\treturn true;\n\t\tif (mob.amDead())\n\t\t\treturn true;\n\t\tif (mob.curState().getHitPoints() <= 0)\n\t\t\treturn true;\n\t\tif (amDead())\n\t\t\treturn true;\n\t\tif (curState().getHitPoints() <= 0)\n\t\t\treturn true;\n\t\treturn false;\n\t}\n\n\tprotected boolean isPermissableToFight(final MOB mob)\n\t{\n\t\tif (mob == null)\n\t\t\treturn false;\n\t\tfinal boolean targetIsMonster = mob.isMonster();\n\t\tfinal boolean iAmMonster = isMonster();\n\t\tif (targetIsMonster)\n\t\t{\n\t\t\tfinal MOB fol = mob.amFollowing();\n\t\t\tif ((fol != null) && (!isEitherOfUsDead(fol)))\n\t\t\t{\n\t\t\t\tif (!isPermissableToFight(fol))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\tif (iAmMonster)\n\t\t{\n\t\t\tfinal MOB fol = amFollowing();\n\t\t\tif ((fol != null) && (!isEitherOfUsDead(fol)))\n\t\t\t{\n\t\t\t\tif (!fol.mayIFight(mob))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\tif (CMLib.flags().isUnattackable(mob) && (!mob.isInCombat()))\n\t\t\treturn false;\n\t\tif (targetIsMonster || iAmMonster)\n\t\t\treturn true;\n\t\tif ((mob.soulMate() != null) || (soulMate() != null))\n\t\t\treturn true;\n\t\tif (mob == this)\n\t\t\treturn true;\n\t\tif (CMLib.clans().isAtClanWar(this, mob))\n\t\t\treturn true;\n\t\tif (this.isAttributeSet(MOB.Attrib.PLAYERKILL))\n\t\t{\n\t\t\tif (CMSecurity.isAllowed(this, location(), CMSecurity.SecFlag.PKILL) || (mob.isAttributeSet(MOB.Attrib.PLAYERKILL)))\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\t\telse\n\t\tif (mob.isAttributeSet(MOB.Attrib.PLAYERKILL))\n\t\t{\n\t\t\tif (CMSecurity.isAllowed(mob, location(), CMSecurity.SecFlag.PKILL) || (this.isAttributeSet(MOB.Attrib.PLAYERKILL)))\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean mayIFight(final PhysicalAgent victim)\n\t{\n\t\tif (!(victim instanceof MOB))\n\t\t{\n\t\t\tif (CMLib.flags().isUnattackable(victim))\n\t\t\t\treturn false;\n\t\t\tif (victim instanceof Rideable)\n\t\t\t\treturn CMLib.combat().mayIAttackThisVessel(this, victim);\n\t\t\treturn false;\n\t\t}\n\t\tif (isEitherOfUsDead((MOB) victim))\n\t\t\treturn false;\n\t\treturn isPermissableToFight((MOB) victim);\n\t}\n\n\t@Override\n\tpublic boolean mayPhysicallyAttack(final PhysicalAgent victim)\n\t{\n\t\tfinal Room myLocation = location();\n\t\tif ((!mayIFight(victim)) || (myLocation == null))\n\t\t\treturn false;\n\t\tif (victim instanceof MOB)\n\t\t{\n\t\t\tif (myLocation != ((MOB) victim).location())\n\t\t\t\treturn false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfinal Room R = CMLib.map().roomLocation(victim);\n\t\t\tfinal Area myArea = myLocation.getArea();\n\t\t\tif ((R == null) || (myArea == null))\n\t\t\t\treturn false;\n\t\t\tif ((myLocation != R)\n\t\t\t&& ((!(myArea instanceof Boardable)) || (!R.isContent(((Boardable) myArea).getBoardableItem()))))\n\t\t\t\treturn false;\n\t\t}\n\t\tif ((!CMLib.flags().isInTheGame(this, false))\n\t\t|| (!CMLib.flags().isInTheGame(victim, false)))\n\t\t\treturn false;\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic long getPeaceTime()\n\t{\n\t\treturn peaceTime;\n\t}\n\n\t@Override\n\tpublic void setRangeToTarget(final int newRange)\n\t{\n\t\tatRange = newRange;\n\t}\n\n\t@Override\n\tpublic int rangeToTarget()\n\t{\n\t\treturn atRange;\n\t}\n\n\t@Override\n\tpublic int getDirectionToTarget()\n\t{\n\t\treturn -1;\n\t}\n\n\t@Override\n\tpublic int maxRange()\n\t{\n\t\tif (location() != null)\n\t\t\treturn location().maxRange();\n\t\treturn 10;\n\t}\n\n\t@Override\n\tpublic int minRange()\n\t{\n\t\treturn 0;\n\t}\n\n\tprivate int maxRangeWith(final Environmental tool)\n\t{\n\t\tfinal int max = maxRange();\n\t\tif (tool == null)\n\t\t\treturn minRange();\n\t\tif (tool.maxRange() < max)\n\t\t\treturn tool.maxRange();\n\t\treturn max;\n\t}\n\n\tprivate int minRangeWith(final Environmental tool)\n\t{\n\t\tif (tool != null)\n\t\t\treturn tool.minRange();\n\t\treturn minRange();\n\t}\n\n\t@Override\n\tpublic void makePeace(final boolean includePlayerFollowers)\n\t{\n\t\tfinal MOB myVictim = victim;\n\t\tsetVictim(null);\n\t\tfor (int f = 0; f < numFollowers(); f++)\n\t\t{\n\t\t\tfinal MOB M = fetchFollower(f);\n\t\t\tif ((M != null)\n\t\t\t&& (M.isInCombat())\n\t\t\t&& (includePlayerFollowers || M.isMonster()))\n\t\t\t\tM.makePeace(true);\n\t\t}\n\t\tif (myVictim != null)\n\t\t{\n\t\t\tfinal MOB oldVictim = myVictim.getVictim();\n\t\t\tif (oldVictim == this)\n\t\t\t\tmyVictim.makePeace(true);\n\t\t}\n\t}\n\n\t@Override\n\tpublic MOB getVictim()\n\t{\n\t\tif (!isInCombat())\n\t\t\treturn null;\n\t\treturn victim;\n\t}\n\n\t@Override\n\tpublic PhysicalAgent getCombatant()\n\t{\n\t\treturn getVictim();\n\t}\n\n\t@Override\n\tpublic void setCombatant(final PhysicalAgent other)\n\t{\n\t\tif ((other == null) || (other instanceof MOB))\n\t\t\tsetVictim((MOB) other);\n\t}\n\n\t@Override\n\tpublic void setVictim(final MOB other)\n\t{\n\t\tif (other == null)\n\t\t{\n\t\t\tsetRangeToTarget(-1);\n\t\t\tif (victim != null)\n\t\t\t{\n\t\t\t\tsynchronized (commandQue)\n\t\t\t\t{\n\t\t\t\t\tcommandQue.clear();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (victim == other)\n\t\t\treturn;\n\t\tif (other == this)\n\t\t\treturn;\n\t\tvictim = other;\n\t\trecoverPhyStats();\n\t\trecoverCharStats();\n\t\trecoverMaxState();\n\t\tif (other != null)\n\t\t{\n\t\t\tif ((other.location() == null)\n\t\t\t|| (location() == null)\n\t\t\t|| (other.amDead())\n\t\t\t|| (amDead())\n\t\t\t|| (other.location() != location())\n\t\t\t|| (!location().isInhabitant(this))\n\t\t\t|| (!location().isInhabitant(other)))\n\t\t\t{\n\t\t\t\tif (victim != null)\n\t\t\t\t\tvictim.setVictim(null);\n\t\t\t\tvictim = null;\n\t\t\t\tsetRangeToTarget(-1);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (Log.combatChannelOn())\n\t\t\t\t{\n\t\t\t\t\tfinal Item I = fetchWieldedItem();\n\t\t\t\t\tfinal Item VI = other.fetchWieldedItem();\n\t\t\t\t\tLog.combatOut("STRT", Name()\n\t\t\t\t\t\t\t\t\t\t+ ":" + phyStats().getCombatStats() + ":" + curState().getCombatStats()\n\t\t\t\t\t\t\t\t\t\t+ ":" + ((I == null) ? "null" : I.name()) + ":" + other.Name()\n\t\t\t\t\t\t\t\t\t\t+ ":" + other.phyStats().getCombatStats() + ":" + other.curState().getCombatStats()\n\t\t\t\t\t\t\t\t\t\t+ ":" + ((VI == null) ? "null" : VI.name()));\n\t\t\t\t}\n\t\t\t\tother.recoverCharStats();\n\t\t\t\tother.recoverPhyStats();\n\t\t\t\tother.recoverMaxState();\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic DeadBody killMeDead(final boolean createBody)\n\t{\n\t\tfinal Room deathRoom;\n\t\tif (isMonster())\n\t\t\tdeathRoom = location();\n\t\telse\n\t\t\tdeathRoom = CMLib.login().getDefaultBodyRoom(this);\n\t\tif (location() != null)\n\t\t\tlocation().delInhabitant(this);\n\t\tamDead = true;\n\t\tDeadBody bodyI = null;\n\t\tif (createBody)\n\t\t{\n\t\t\tbodyI = charStats().getMyRace().getCorpseContainer(this, deathRoom);\n\t\t\tif ((bodyI != null) && (playerStats() != null))\n\t\t\t{\n\t\t\t\tbodyI.setSavable(false); // if the player is saving it, rooms are NOT.\n\t\t\t\tplayerStats().getExtItems().addItem(bodyI);\n\t\t\t}\n\t\t\tif(deathRoom != null)\n\t\t\t\tdeathRoom.show(this, bodyI, CMMsg.MASK_ALWAYS|CMMsg.MSG_BODYDROP, null);\n\t\t}\n\t\tmakePeace(false);\n\t\tsetRiding(null);\n\t\tsynchronized (commandQue)\n\t\t{\n\t\t\tcommandQue.clear();\n\t\t}\n\t\tAbility A = null;\n\t\tfor (int a = numEffects() - 1; a >= 0; a--)\n\t\t{\n\t\t\tA = fetchEffect(a);\n\t\t\tif (A != null)\n\t\t\t\tA.unInvoke();\n\t\t}\n\t\tsetLocation(null);\n\t\tif (isMonster())\n\t\t{\n\t\t\twhile (numFollowers() > 0)\n\t\t\t{\n\t\t\t\tfinal MOB follower = fetchFollower(0);\n\t\t\t\tif (follower != null)\n\t\t\t\t{\n\t\t\t\t\tfollower.setFollowing(null);\n\t\t\t\t\tdelFollower(follower);\n\t\t\t\t}\n\t\t\t}\n\t\t\tsetFollowing(null);\n\t\t}\n\t\tif ((!isMonster()) && (soulMate() == null))\n\t\t\tbringToLife(CMLib.login().getDefaultDeathRoom(this), true);\n\t\tif (deathRoom != null)\n\t\t\tdeathRoom.recoverRoomStats();\n\t\treturn bodyI;\n\t}\n\n\t@Override\n\tpublic Room location()\n\t{\n\t\tif (location == null)\n\t\t\treturn lastLocation;\n\t\treturn location;\n\t}\n\n\t@Override\n\tpublic void setLocation(final Room newRoom)\n\t{\n\t\tlastLocation = location;\n\t\tlocation = newRoom;\n\t\tif ((playerStats != null) && (lastLocation != newRoom))\n\t\t\tCMLib.players().changePlayersLocation(this, newRoom);\n\t}\n\n\t@Override\n\tpublic Rideable riding()\n\t{\n\t\treturn riding;\n\t}\n\n\t@Override\n\tpublic void setRiding(final Rideable ride)\n\t{\n\t\tfinal Rideable amRiding = riding();\n\t\tif ((ride != null)\n\t\t&& (amRiding != null)\n\t\t&& (amRiding == ride)\n\t\t&& (amRiding.amRiding(this)))\n\t\t\treturn;\n\t\tif ((amRiding != null)\n\t\t&& (amRiding.amRiding(this)))\n\t\t\tamRiding.delRider(this);\n\t\triding = ride;\n\t\tif ((ride != null) && (!ride.amRiding(this)))\n\t\t\tride.addRider(this);\n\t}\n\n\t@Override\n\tpublic final Session session()\n\t{\n\t\treturn mySession == null ? null : mySession.isFake() ? null : mySession;\n\t}\n\n\t@Override\n\tpublic void setSession(final Session newSession)\n\t{\n\t\tmySession = newSession;\n\t\tsetAttributesBitmap(getAttributesBitmap());\n\t}\n\n\t@Override\n\tpublic Weapon getNaturalWeapon()\n\t{\n\t\tfinal Weapon W;\n\t\tif ((charStats() != null) && (charStats().getMyRace() != null))\n\t\t\tW = charStats().getMyRace().myNaturalWeapon();\n\t\telse\n\t\t\tW = CMClass.getWeapon("Natural");\n\t\tif (W.subjectToWearAndTear())\n\t\t\tW.setUsesRemaining(100);\n\t\treturn W;\n\t}\n\n\t@Override\n\tpublic String titledName(final MOB viewer)\n\t{\n\t\tif (CMProps.getBoolVar(CMProps.Bool.INTRODUCTIONSYSTEM)\n\t\t&& (playerStats() != null)\n\t\t&& (viewer != null)\n\t\t&& (viewer != this)\n\t\t&& (viewer.playerStats() != null)\n\t\t&& (!viewer.playerStats().isIntroducedTo(Name()))\n\t\t&& (!CMSecurity.isASysOp(viewer)))\n\t\t\treturn CMLib.english().startWithAorAn(genericName()).toLowerCase();\n\t\treturn titledName();\n\t}\n\n\t@Override\n\tpublic String name(final MOB viewer)\n\t{\n\t\tif (CMProps.getBoolVar(CMProps.Bool.INTRODUCTIONSYSTEM)\n\t\t&& (playerStats() != null)\n\t\t&& (viewer != null)\n\t\t&& (viewer != this)\n\t\t&& (viewer.playerStats() != null)\n\t\t&& (!viewer.playerStats().isIntroducedTo(Name()))\n\t\t&& (!CMSecurity.isASysOp(viewer)))\n\t\t\treturn CMLib.english().startWithAorAn(genericName()).toLowerCase();\n\t\treturn name();\n\t}\n\n\t@Override\n\tpublic String displayText(final MOB viewerMob)\n\t{\n\t\tif ((displayText.length() == 0)\n\t\t|| (!name(viewerMob).equals(Name()))\n\t\t|| (!titledName().equals(Name()))\n\t\t|| (CMLib.flags().isSleeping(this))\n\t\t|| (CMLib.flags().isSitting(this)) || (riding() != null)\n\t\t|| ((amFollowing() != null)\n\t\t\t&& (amFollowing().fetchFollowerOrder(this) > 0))\n\t\t|| ((this instanceof Rideable)\n\t\t\t&& (((Rideable) this).numRiders() > 0)\n\t\t\t&& CMLib.flags().isWithSeenContents(this))\n\t\t|| (isInCombat()))\n\t\t{\n\t\t\tfinal StringBuilder sendBack;\n\t\t\tif (!name(viewerMob).equals(Name()))\n\t\t\t\tsendBack = new StringBuilder(name(viewerMob));\n\t\t\telse\n\t\t\t\tsendBack = new StringBuilder(titledName(viewerMob));\n\t\t\tsendBack.append(" ");\n\t\t\tsendBack.append(L(CMLib.flags().getPresentDispositionVerb(this, CMFlagLibrary.ComingOrGoing.IS) + " here"));\n\t\t\tif (riding() != null)\n\t\t\t{\n\t\t\t\tsendBack.append(" " + riding().stateString(this) + " ");\n\t\t\t\tif (riding() == viewerMob)\n\t\t\t\t\tsendBack.append(L("YOU"));\n\t\t\t\telse\n\t\t\t\tif (!CMLib.flags().canBeSeenBy(riding(), viewerMob))\n\t\t\t\t{\n\t\t\t\t\tif (riding() instanceof Item)\n\t\t\t\t\t\tsendBack.append(L("something"));\n\t\t\t\t\telse\n\t\t\t\t\t\tsendBack.append(L("someone"));\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tsendBack.append(riding().name());\n\t\t\t}\n\t\t\telse\n\t\t\tif ((this instanceof Rideable)\n\t\t\t&& (((Rideable) this).numRiders() > 0)\n\t\t\t&& (((Rideable) this).stateStringSubject(((Rideable) this).fetchRider(0)).length() > 0))\n\t\t\t{\n\t\t\t\tfinal Rideable me = (Rideable) this.me;\n\t\t\t\tfinal String first = me.stateStringSubject(me.fetchRider(0));\n\t\t\t\tsendBack.append(" " + first + " ");\n\t\t\t\tfor (int r = 0; r < me.numRiders(); r++)\n\t\t\t\t{\n\t\t\t\t\tfinal Rider rider = me.fetchRider(r);\n\t\t\t\t\tif ((rider != null) && (me.stateStringSubject(rider).equals(first)))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (r > 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsendBack.append(", ");\n\t\t\t\t\t\t\tif (r == me.numRiders() - 1)\n\t\t\t\t\t\t\t\tsendBack.append("and ");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (rider == viewerMob)\n\t\t\t\t\t\t\tsendBack.append("you");\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif (!CMLib.flags().canBeSeenBy(riding(), viewerMob))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (riding() instanceof Item)\n\t\t\t\t\t\t\t\tsendBack.append(L("something"));\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tsendBack.append(L("someone"));\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tsendBack.append(rider.name());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ((isInCombat())\n\t\t\t&& (CMLib.flags().canMove(this))\n\t\t\t&& (!CMLib.flags().isSleeping(this)))\n\t\t\t{\n\t\t\t\tif (getVictim() == viewerMob)\n\t\t\t\t\tsendBack.append(L(" fighting YOU"));\n\t\t\t\telse\n\t\t\t\tif (!CMLib.flags().canBeSeenBy(getVictim(), viewerMob))\n\t\t\t\t\tsendBack.append(L(" fighting someone"));\n\t\t\t\telse\n\t\t\t\t\tsendBack.append(L(" fighting @x1", getVictim().name()));\n\t\t\t}\n\t\t\tif ((amFollowing() != null)\n\t\t\t&& (amFollowing().fetchFollowerOrder(this) > 0))\n\t\t\t{\n\t\t\t\tfinal List<MOB> whoseAhead = CMLib.combat().getFormationFollowed(this);\n\t\t\t\tif ((whoseAhead != null) && (!whoseAhead.isEmpty()))\n\t\t\t\t{\n\t\t\t\t\tsendBack.append(L(", behind "));\n\t\t\t\t\tfor (int v = 0; v < whoseAhead.size(); v++)\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal MOB ahead = whoseAhead.get(v);\n\t\t\t\t\t\tif (v > 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsendBack.append(", ");\n\t\t\t\t\t\t\tif (v == whoseAhead.size() - 1)\n\t\t\t\t\t\t\t\tsendBack.append(L("and "));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (ahead == viewerMob)\n\t\t\t\t\t\t\tsendBack.append(L("you"));\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif (!CMLib.flags().canBeSeenBy(ahead, viewerMob))\n\t\t\t\t\t\t\tsendBack.append(L("someone"));\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tsendBack.append(ahead.name());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tsendBack.append(".");\n\t\t\treturn sendBack.toString();\n\t\t}\n\t\treturn displayText;\n\t}\n\n\t@Override\n\tpublic String displayText()\n\t{\n\t\treturn displayText;\n\t}\n\n\t@Override\n\tpublic void setDisplayText(final String newDisplayText)\n\t{\n\t\tdisplayText = newDisplayText;\n\t}\n\n\t@Override\n\tpublic String description()\n\t{\n\t\tif (description == null)\n\t\t\treturn "";\n\t\telse\n\t\tif (description instanceof byte[])\n\t\t{\n\t\t\tfinal byte[] descriptionBytes = (byte[]) description;\n\t\t\tif (descriptionBytes.length == 0)\n\t\t\t\treturn "";\n\t\t\tif (CMProps.getBoolVar(CMProps.Bool.MOBDCOMPRESS))\n\t\t\t\treturn CMLib.encoder().decompressString(descriptionBytes);\n\t\t\telse\n\t\t\t\treturn CMStrings.bytesToStr(descriptionBytes);\n\t\t}\n\t\telse\n\t\t\treturn (String) description;\n\t}\n\n\t@Override\n\tpublic String description(final MOB viewerMob)\n\t{\n\t\treturn description();\n\t}\n\n\t@Override\n\tpublic void setDescription(final String newDescription)\n\t{\n\t\tif (newDescription.length() == 0)\n\t\t\tdescription = null;\n\t\telse\n\t\tif (CMProps.getBoolVar(CMProps.Bool.MOBDCOMPRESS))\n\t\t\tdescription = CMLib.encoder().compressString(newDescription);\n\t\telse\n\t\t\tdescription = newDescription;\n\t}\n\n\t@Override\n\tpublic void setMiscText(final String newText)\n\t{\n\t\tif (newText.length() == 0)\n\t\t\tmiscText = null;\n\t\telse\n\t\tif (CMProps.getBoolVar(CMProps.Bool.MOBCOMPRESS))\n\t\t\tmiscText = CMLib.encoder().compressString(newText);\n\t\telse\n\t\t\tmiscText = newText;\n\t}\n\n\t@Override\n\tpublic String text()\n\t{\n\t\tif (miscText == null)\n\t\t\treturn "";\n\t\telse\n\t\tif (miscText instanceof byte[])\n\t\t{\n\t\t\tfinal byte[] miscTextBytes = (byte[]) miscText;\n\t\t\tif (miscTextBytes.length == 0)\n\t\t\t\treturn "";\n\t\t\tif (CMProps.getBoolVar(CMProps.Bool.MOBCOMPRESS))\n\t\t\t\treturn CMLib.encoder().decompressString(miscTextBytes);\n\t\t\telse\n\t\t\t\treturn CMStrings.bytesToStr(miscTextBytes);\n\t\t}\n\t\telse\n\t\t\treturn (String) miscText;\n\t}\n\n\t@Override\n\tpublic String miscTextFormat()\n\t{\n\t\treturn CMParms.FORMAT_UNDEFINED;\n\t}\n\n\t@Override\n\tpublic String healthText(final MOB viewer)\n\t{\n\t\tfinal String mxp = "^<!ENTITY vicmaxhp \\"" + maxState().getHitPoints() + "\\"^>"\n\t\t\t\t\t\t+ "^<!ENTITY vichp \\"" + curState().getHitPoints() + "\\"^>"\n\t\t\t\t\t\t+ "^<Health^>^<HealthText \\"" + CMStrings.removeColors(name(viewer)) + "\\"^>";\n\t\tif ((charStats() != null) && (charStats().getMyRace() != null))\n\t\t\treturn mxp + charStats().getMyRace().healthText(viewer, this) + "^</HealthText^>";\n\t\treturn mxp + CMLib.combat().standardMobCondition(viewer, this) + "^</HealthText^>";\n\t}\n\n\t@Override\n\tpublic double actions()\n\t{\n\t\treturn freeActions;\n\t}\n\n\t@Override\n\tpublic void setActions(final double remain)\n\t{\n\t\tfreeActions = remain;\n\t}\n\n\t@Override\n\tpublic int commandQueSize()\n\t{\n\t\treturn commandQue.size();\n\t}\n\n\t@Override\n\tpublic void clearCommandQueue()\n\t{\n\t\tcommandQue.clear();\n\t}\n\n\t@Override\n\tpublic Pair<Object, List<String>> getTopCommand()\n\t{\n\t\tPair<Object, List<String>> top = null;\n\t\tsynchronized(commandQue)\n\t\t{\n\t\t\tif(!commandQue.isEmpty())\n\t\t\t{\n\t\t\t\tfinal QMCommand QM=commandQue.peekFirst();\n\t\t\t\ttop=new Pair<Object, List<String>>(QM.commandObj, QM.commandVector);\n\t\t\t}\n\t\t}\n\t\treturn top;\n\t}\n\n\t@Override\n\tpublic boolean dequeCommand()\n\t{\n\t\twhile ((!removeFromGame)\n\t\t&& (!amDestroyed())\n\t\t&& ((session() == null) || (!session().isStopped())))\n\t\t{\n\t\t\tQMCommand doCommand = null;\n\t\t\tsynchronized (commandQue)\n\t\t\t{\n\t\t\t\tif (commandQue.isEmpty())\n\t\t\t\t\treturn false;\n\t\t\t\tQMCommand cmd = commandQue.getFirst();\n\t\t\t\tfinal double diff = actions() - cmd.actionCost;\n\t\t\t\tif (diff >= 0.0)\n\t\t\t\t{\n\t\t\t\t\tfinal long nextTime = lastCommandTime + Math.round(cmd.actionCost / phyStats().speed() * CMProps.getTickMillisD());\n\t\t\t\t\tif ((System.currentTimeMillis() < nextTime) && (session() != null))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tcmd = commandQue.removeFirst();\n\t\t\t\t\tsetActions(diff);\n\t\t\t\t\tdoCommand = cmd;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (doCommand != null)\n\t\t\t{\n\t\t\t\tlastCommandTime = System.currentTimeMillis();\n\t\t\t\tdoCommand(doCommand.commandObj, doCommand.commandVector, doCommand.metaFlags);\n\t\t\t\tsynchronized (commandQue)\n\t\t\t\t{\n\t\t\t\t\tif (!commandQue.isEmpty())\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal QMCommand cmd = commandQue.getFirst();\n\t\t\t\t\t\tfinal Object O = cmd.commandObj;\n\t\t\t\t\t\tcmd.actionCost = calculateActionCost(O, cmd.commandVector, 0.0);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\treturn false;\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tQMCommand cmd = null;\n\t\t\tsynchronized (commandQue)\n\t\t\t{\n\t\t\t\tif (commandQue.isEmpty())\n\t\t\t\t\treturn false;\n\t\t\t\tcmd = commandQue.getFirst();\n\t\t\t\tif ((cmd == null) || (System.currentTimeMillis() < cmd.nextCheck))\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tfinal double diff = actions() - cmd.actionCost;\n\t\t\tfinal Object O = cmd.commandObj;\n\t\t\tfinal List<String> commands = new XVector<String>(cmd.commandVector);\n\t\t\tcmd.nextCheck = cmd.nextCheck + 1000;\n\t\t\tcmd.seconds += 1;\n\t\t\tfinal int secondsElapsed = cmd.seconds;\n\t\t\tfinal int metaFlags = cmd.metaFlags;\n\t\t\ttry\n\t\t\t{\n\t\t\t\t// record an action taken in personal combat stats\n\t\t\t\tfinal MOB combatant = victim;\n\t\t\t\tif ((cmd.actionCost > 0) && (combatant != null))\n\t\t\t\t{\n\t\t\t\t\tif (playerStats != null)\n\t\t\t\t\t\tplayerStats.bumpLevelCombatStat(PlayerCombatStat.ACTIONS_DONE, basePhyStats().level(), 1);\n\t\t\t\t\tif (combatant.playerStats() != null)\n\t\t\t\t\t\tcombatant.playerStats().bumpLevelCombatStat(PlayerCombatStat.ACTIONS_TAKEN, combatant.basePhyStats().level(), 1);\n\t\t\t\t}\n\n\t\t\t\t// actually do the command queued up\n\t\t\t\tif (O instanceof Command)\n\t\t\t\t{\n\t\t\t\t\tif (!((Command) O).preExecute(this, commands, metaFlags, secondsElapsed, -diff))\n\t\t\t\t\t{\n\t\t\t\t\t\tcommandQue.remove(cmd);\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\tif (O instanceof Ability)\n\t\t\t\t{\n\t\t\t\t\tif (!CMLib.english().preInvokeSkill(this, commands, secondsElapsed, -diff))\n\t\t\t\t\t{\n\t\t\t\t\t\tcommandQue.remove(cmd);\n\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\tcatch (final Exception e)\n\t\t\t{\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic void doCommand(final List<String> commands, final int metaFlags)\n\t{\n\t\tfinal CMObject O = CMLib.english().findCommand(this, commands);\n\t\tif (O != null)\n\t\t\tdoCommand(O, commands, metaFlags);\n\t\telse\n\t\t\tCMLib.commands().handleUnknownCommand(this, commands);\n\t}\n\n\tprotected void doCommand(final Object O, final List<String> commands, final int metaFlags)\n\t{\n\t\ttry\n\t\t{\n\t\t\tif (O instanceof Command)\n\t\t\t{\n\t\t\t\tif (playerStats != null)\n\t\t\t\t{\n\t\t\t\t\tCMLib.achievements().possiblyBumpAchievement(this, AchievementLibrary.Event.CMDUSE, 1, (Command) O);\n\t\t\t\t\tCMLib.coffeeTables().bump((Command) O, CoffeeTableRow.STAT_CMDUSE);\n\t\t\t\t}\n\t\t\t\t((Command) O).execute(this, new XVector<String>(commands), metaFlags);\n\t\t\t}\n\t\t\telse\n\t\t\tif (O instanceof Social)\n\t\t\t\t((Social) O).invoke(this, new XVector<String>(commands), null, false);\n\t\t\telse\n\t\t\tif (O instanceof Ability)\n\t\t\t\tCMLib.english().invokeSkill(this, new XVector<String>(commands));\n\t\t\telse\n\t\t\t\tCMLib.commands().handleUnknownCommand(this, commands);\n\t\t}\n\t\tcatch (final java.io.IOException io)\n\t\t{\n\t\t\tLog.errOut("StdMOB", CMParms.toListString(commands));\n\t\t\tif (io.getMessage() != null)\n\t\t\t\tLog.errOut("StdMOB", io.getMessage());\n\t\t\telse\n\t\t\t\tLog.errOut("StdMOB", io);\n\t\t\ttell(L("Oops!"));\n\t\t}\n\t\tcatch (final Exception e)\n\t\t{\n\t\t\tLog.errOut("StdMOB", Name() + " did \'" + CMParms.toListString(commands) + "\' in " + CMLib.map().getExtendedRoomID(location()));\n\t\t\tif ((e!=null)&&(e.getMessage() != null))\n\t\t\t\tLog.errOut("StdMOB", e.getMessage());\n\t\t\tLog.errOut("StdMOB", e);\n\t\t\ttell(L("Oops!"));\n\t\t}\n\t}\n\n\tprotected double calculateActionCost(final Object command, final List<String> commands, double overrideActionCost)\n\t{\n\t\tif (overrideActionCost <= 0.0)\n\t\t{\n\t\t\tif (command == null)\n\t\t\t{\n\t\t\t\ttell(L("Huh?!"));\n\t\t\t\treturn -1.0;\n\t\t\t}\n\t\t\tif (command instanceof Command)\n\t\t\t\toverrideActionCost = ((Command) command).checkedActionsCost(this, commands);\n\t\t\telse\n\t\t\tif (command instanceof Ability)\n\t\t\t\toverrideActionCost = ((Ability) command).checkedCastingCost(this, commands);\n\t\t\telse\n\t\t\tif (command instanceof Social)\n\t\t\t\toverrideActionCost = ((Social) command).checkedActionsCost(this, commands);\n\t\t\telse\n\t\t\t\toverrideActionCost = 1.0;\n\t\t}\n\t\treturn overrideActionCost;\n\t}\n\n\tprotected void checkCommandCancel()\n\t{\n\t\tsynchronized (commandQue)\n\t\t{\n\t\t\tif(!commandQue.isEmpty())\n\t\t\t{\n\t\t\t\tfinal QMCommand cmd = commandQue.peekFirst();\n\t\t\t\tif((cmd.commandObj instanceof Command)\n\t\t\t\t&&(((Command)cmd.commandObj).canBeCancelled()))\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\t((Command)cmd.commandObj).preExecute(me, cmd.commandVector, cmd.metaFlags, -1, cmd.actionCost);\n\t\t\t\t\t}\n\t\t\t\t\tcatch(final Exception e)\n\t\t\t\t\t{\n\t\t\t\t\t\tLog.errOut(e);\n\t\t\t\t\t}\n\t\t\t\t\tif((!commandQue.isEmpty())&&(commandQue.peekFirst() == cmd))\n\t\t\t\t\t\tcommandQue.removeFirst();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic void prequeCommand(final List<String> commands, final int metaFlags, double actionCost)\n\t{\n\t\tif (commands == null)\n\t\t\treturn;\n\t\tfinal CMObject O = CMLib.english().findCommand(this, commands);\n\t\tif (O == null)\n\t\t{\n\t\t\tCMLib.commands().handleUnknownCommand(this, commands);\n\t\t\treturn;\n\t\t}\n\t\tactionCost = calculateActionCost(O, commands, actionCost);\n\t\tif (actionCost < 0.0)\n\t\t\treturn;\n\t\tif (actionCost == 0.0)\n\t\t\tdoCommand(O, commands, metaFlags);\n\t\telse\n\t\t{\n\t\t\tcheckCommandCancel();\n\t\t\tsynchronized (commandQue)\n\t\t\t{\n\t\t\t\tfinal QMCommand cmd = new QMCommand();\n\t\t\t\tcmd.nextCheck = System.currentTimeMillis() - 1;\n\t\t\t\tcmd.seconds = -1;\n\t\t\t\tcmd.actionCost = actionCost;\n\t\t\t\tcmd.metaFlags = metaFlags;\n\t\t\t\tcmd.commandObj = O;\n\t\t\t\tcmd.commandVector = commands;\n\t\t\t\tcommandQue.addFirst(cmd);\n\t\t\t}\n\t\t}\n\t\tdequeCommand();\n\t}\n\n\t@Override\n\tpublic void prequeCommands(final List<List<String>> commands, final int metaFlags)\n\t{\n\t\tif ((commands == null) || (commands.size() == 0))\n\t\t\treturn;\n\t\tfinal List<QMCommand> queueUp = new ArrayList<QMCommand>(commands.size());\n\t\tfor (final List<String> command : commands)\n\t\t{\n\t\t\tfinal CMObject O = CMLib.english().findCommand(this, command);\n\t\t\tif (O == null)\n\t\t\t{\n\t\t\t\tCMLib.commands().handleUnknownCommand(this, command);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tfinal double actionCost = calculateActionCost(O, command, 0.0);\n\t\t\tif (actionCost < 0.0)\n\t\t\t\treturn;\n\t\t\tsynchronized (commandQue)\n\t\t\t{\n\t\t\t\tfinal QMCommand cmd = new QMCommand();\n\t\t\t\tcmd.nextCheck = System.currentTimeMillis() - 1;\n\t\t\t\tcmd.seconds = -1;\n\t\t\t\tcmd.actionCost = actionCost;\n\t\t\t\tcmd.metaFlags = metaFlags;\n\t\t\t\tcmd.commandObj = O;\n\t\t\t\tcmd.commandVector = command;\n\t\t\t\tqueueUp.add(cmd);\n\t\t\t}\n\t\t}\n\t\tif (queueUp.size() > 0)\n\t\t{\n\t\t\tif (this.commandQue.size() == 0)\n\t\t\t\tthis.commandQue.addAll(queueUp);\n\t\t\telse\n\t\t\t\tthis.commandQue.addAll(0, queueUp);\n\t\t}\n\t\tdequeCommand();\n\t}\n\n\t@Override\n\tpublic void enqueCommand(final List<String> commands, final int metaFlags, double actionCost)\n\t{\n\t\tif (commands == null)\n\t\t\treturn;\n\t\tfinal CMObject O = CMLib.english().findCommand(this, commands);\n\t\tif ((O == null)\n\t\t|| ((O instanceof Ability)\n\t\t\t&& CMath.bset(metaFlags, MUDCmdProcessor.METAFLAG_ORDER)\n\t\t\t&& CMath.bset(((Ability) O).flags(), Ability.FLAG_NOORDERING)))\n\t\t{\n\t\t\tCMLib.commands().handleUnknownCommand(this, commands);\n\t\t\treturn;\n\t\t}\n\t\tactionCost = calculateActionCost(O, commands, actionCost);\n\t\tif (actionCost < 0.0)\n\t\t\treturn;\n\t\tif ((actionCost == 0.0) && (!CMath.bset(metaFlags, MUDCmdProcessor.METAFLAG_INORDER)))\n\t\t\tdoCommand(commands, metaFlags);\n\t\telse\n\t\t{\n\t\t\tcheckCommandCancel();\n\t\t\tsynchronized (commandQue)\n\t\t\t{\n\t\t\t\tfinal QMCommand cmd = new QMCommand();\n\t\t\t\tcmd.nextCheck = System.currentTimeMillis() - 1;\n\t\t\t\tcmd.seconds = -1;\n\t\t\t\tcmd.actionCost = actionCost;\n\t\t\t\tcmd.metaFlags = metaFlags;\n\t\t\t\tcmd.commandObj = O;\n\t\t\t\tcmd.commandVector = commands;\n\t\t\t\tcommandQue.addLast(cmd);\n\t\t\t}\n\t\t}\n\t\tdequeCommand();\n\t}\n\n\t@Override\n\tpublic void enqueCommands(final List<List<String>> commands, final int metaFlags)\n\t{\n\t\tif ((commands == null) || (commands.size() == 0))\n\t\t\treturn;\n\t\tfor (final List<String> cmds : commands)\n\t\t\tenqueCommand(cmds, metaFlags, 0.0);\n\t}\n\n\t@Override\n\tpublic boolean okMessage(final Environmental myHost, final CMMsg msg)\n\t{\n\t\tfinal Deity deity = charStats().getMyDeity();\n\t\tif ((deity != null) && (deity != this) && (!deity.okMessage(this, msg)))\n\t\t\treturn false;\n\n\t\tfinal CharStats cStats = charStats;\n\t\tif (cStats != null)\n\t\t{\n\t\t\tfor (int c = 0; c < cStats.numClasses(); c++)\n\t\t\t{\n\t\t\t\tif (!cStats.getMyClass(c).okMessage(this, msg))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tif (!cStats.getMyRace().okMessage(this, msg))\n\t\t\t\treturn false;\n\t\t}\n\n\t\t// the order here is significant (between eff and item -- see focus)\n\t\tfor (final Enumeration<Ability> a = effects(); a.hasMoreElements();)\n\t\t{\n\t\t\tfinal Ability A = a.nextElement();\n\t\t\tif (!A.okMessage(this, msg))\n\t\t\t\treturn false;\n\t\t}\n\n\t\tfor (final Enumeration<Item> i = items(); i.hasMoreElements();)\n\t\t{\n\t\t\tfinal Item I = i.nextElement();\n\t\t\tif (!I.okMessage(this, msg))\n\t\t\t\treturn false;\n\t\t}\n\n\t\tfor (final Enumeration<Behavior> b = behaviors(); b.hasMoreElements();)\n\t\t{\n\t\t\tfinal Behavior B = b.nextElement();\n\t\t\tif (!B.okMessage(this, msg))\n\t\t\t\treturn false;\n\t\t}\n\n\t\tfor (final Enumeration<ScriptingEngine> s = scripts(); s.hasMoreElements();)\n\t\t{\n\t\t\tfinal ScriptingEngine S = s.nextElement();\n\t\t\tif (!S.okMessage(this, msg))\n\t\t\t\treturn false;\n\t\t}\n\n\t\tfor (final Enumeration<Faction.FData> e = factions.elements(); e.hasMoreElements();)\n\t\t{\n\t\t\tfinal Faction.FData fD = e.nextElement();\n\t\t\tif (!fD.getFaction().okMessage(this, msg))\n\t\t\t\treturn false;\n\t\t\tif (!fD.okMessage(this, msg))\n\t\t\t\treturn false;\n\t\t}\n\n\t\tfinal MOB srcM = msg.source();\n\t\tif ((msg.sourceCode() != CMMsg.NO_EFFECT) && (msg.amISource(this)))\n\t\t{\n\t\t\tif ((msg.sourceMinor() == CMMsg.TYP_DEATH)\n\t\t\t&& (CMSecurity.isAllowed(this, location(), CMSecurity.SecFlag.IMMORT)))\n\t\t\t{\n\t\t\t\tcurState().setHitPoints(1);\n\t\t\t\tif ((msg.tool() != this) && (msg.tool() instanceof MOB))\n\t\t\t\t\t((MOB) msg.tool()).tell(L("@x1 is immortal, and can not die.", name((MOB) msg.tool())));\n\t\t\t\ttell(L("You are immortal, and can not die."));\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif (!msg.sourceMajor(CMMsg.MASK_ALWAYS))\n\t\t\t{\n\t\t\t\tfinal int srcMajor = msg.sourceMajor();\n\t\t\t\tfinal int srcMinor = msg.sourceMinor();\n\t\t\t\tfinal CMFlagLibrary flags = CMLib.flags();\n\t\t\t\tif (amDead())\n\t\t\t\t{\n\t\t\t\t\ttell(L("You are DEAD!"));\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif (CMath.bset(srcMajor, CMMsg.MASK_MALICIOUS))\n\t\t\t\t{\n\t\t\t\t\tif (msg.target() instanceof MOB)\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal MOB target = (MOB) msg.target();\n\t\t\t\t\t\tif ((amFollowing() != null) && (target == amFollowing()))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttell(L("You like @x1 too much.", amFollowing().charStats().himher()));\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ((getLiegeID().length() > 0) && (target.Name().equals(getLiegeID())))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (isMarriedToLiege())\n\t\t\t\t\t\t\t\ttell(L("You are married to \'@x1\'!", getLiegeID()));\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\ttell(L("You are serving \'@x1\'!", getLiegeID()));\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tCMLib.combat().establishRange(this, (MOB) msg.target(), msg.tool());\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (CMath.bset(srcMajor, CMMsg.MASK_EYES))\n\t\t\t\t{\n\t\t\t\t\tif (flags.isSleeping(this))\n\t\t\t\t\t{\n\t\t\t\t\t\ttell(L("Not while you are sleeping."));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif (!(msg.target() instanceof Room))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!flags.canBeSeenBy(msg.target(), this))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (msg.target() instanceof Item)\n\t\t\t\t\t\t\t\ttell(L("You don\'t see @x1 here.", ((Item) msg.target()).name(this)));\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\ttell(L("You can\'t see that!"));\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (CMath.bset(srcMajor, CMMsg.MASK_MOUTH))\n\t\t\t\t{\n\t\t\t\t\tif (((srcMinor != CMMsg.TYP_LIST)\n\t\t\t\t\t\t|| srcM.amDead()\n\t\t\t\t\t\t|| flags.isSleeping(srcM))\n\t\t\t\t\t&& (!flags.isAliveAwakeMobile(this, false)))\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (CMath.bset(srcMajor, CMMsg.MASK_SOUND))\n\t\t\t\t\t{\n\t\t\t\t\t\tif ((msg.tool() == null)\n\t\t\t\t\t\t|| (!(msg.tool() instanceof Ability))\n\t\t\t\t\t\t|| (!((Ability) msg.tool()).isNowAnAutoEffect()))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (flags.isSleeping(this))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttell(L("Not while you are sleeping."));\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!flags.canSpeak(this))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttell(L("You can\'t make sounds!"));\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ((flags.isAnimalIntelligence(this)) && (!CMath.bset(phyStats().sensesMask(), PhyStats.CAN_GRUNT_WHEN_STUPID)))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttell(L("You aren\'t smart enough to speak."));\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif ((!flags.canBeSeenBy(msg.target(), this))\n\t\t\t\t\t\t&& (!isMine(msg.target()))\n\t\t\t\t\t\t&& (msg.target() instanceof Item))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsrcM.tell(L("You don\'t see \'@x1\' here.", ((Item) msg.target()).name(this)));\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!flags.canTaste(this))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif ((srcMinor == CMMsg.TYP_EAT) || (srcMinor == CMMsg.TYP_DRINK))\n\t\t\t\t\t\t\t\ttell(L("You can\'t eat or drink."));\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\ttell(L("Your mouth is out of order."));\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (CMath.bset(srcMajor, CMMsg.MASK_HANDS))\n\t\t\t\t{\n\t\t\t\t\tif ((!flags.canBeSeenBy(msg.target(), this))\n\t\t\t\t\t&& (!(isMine(msg.target()) && (msg.target() instanceof Item)))\n\t\t\t\t\t&& ((!(msg.target() instanceof Boardable))\n\t\t\t\t\t\t|| (((Boardable) msg.target()).getArea() != location().getArea()))\n\t\t\t\t\t&& (!((isInCombat()) && (msg.target() == victim)))\n\t\t\t\t\t&& (CMath.bset(msg.targetMajor(), CMMsg.MASK_HANDS))\n\t\t\t\t\t&& (!(msg.target() instanceof Room)))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (msg.target() instanceof Physical)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsrcM.tell(L("You don\'t see \'@x1\' here.", ((Physical) msg.target()).name(this)));\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif (msg.target() != null)\n\t\t\t\t\t\t\tsrcM.tell(L("You don\'t see \'@x1\' here.", msg.target().name()));\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tsrcM.tell(L("You don\'t see that here."));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif (!flags.isAliveAwakeMobile(this, false))\n\t\t\t\t\t\treturn false;\n\n\t\t\t\t\tif ((flags.isSitting(this))\n\t\t\t\t\t&& (srcMinor != CMMsg.TYP_SITMOVE)\n\t\t\t\t\t&& (srcMinor != CMMsg.TYP_BUY)\n\t\t\t\t\t&& (srcMinor != CMMsg.TYP_BID)\n\t\t\t\t\t&& (msg.targetMinor() != CMMsg.TYP_OK_VISUAL)\n\t\t\t\t\t&& ((msg.sourceMessage() != null) || (msg.othersMessage() != null))\n\t\t\t\t\t&& (((!CMLib.utensils().reachableItem(this, msg.target())) || (!CMLib.utensils().reachableItem(this, msg.tool())))\n\t\t\t\t\t\t&& (location() != null)\n\t\t\t\t\t\t&& (!CMath.bset(location().phyStats().sensesMask(), PhyStats.SENSE_ROOMCRUNCHEDIN))))\n\t\t\t\t\t{\n\t\t\t\t\t\ttell(L("You need to stand up!"));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (CMath.bset(srcMajor, CMMsg.MASK_MOVE))\n\t\t\t\t{\n\t\t\t\t\tfinal boolean sleeping = flags.isSleeping(this);\n\t\t\t\t\tfinal boolean sitting = ((flags.isSitting(this))\n\t\t\t\t\t\t\t\t\t\t\t&& (srcMinor != CMMsg.TYP_LEAVE)\n\t\t\t\t\t\t\t\t\t\t\t&& (srcMinor != CMMsg.TYP_ENTER)\n\t\t\t\t\t\t\t\t\t\t\t&& ((msg.targetMinor() != CMMsg.NO_EFFECT)||(srcMinor!=CMMsg.TYP_DELICATE_HANDS_ACT))\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\tif ((sleeping || sitting)\n\t\t\t\t\t&& (srcMinor != CMMsg.TYP_STAND)\n\t\t\t\t\t&& (srcMinor != CMMsg.TYP_SITMOVE)\n\t\t\t\t\t&& (srcMinor != CMMsg.TYP_SIT)\n\t\t\t\t\t&& (srcMinor != CMMsg.TYP_SLEEP))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (sleeping)\n\t\t\t\t\t\t\ttell(L("You need to wake up!"));\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\ttell(L("You need to stand up!"));\n\t\t\t\t\t\tif ((srcMinor != CMMsg.TYP_WEAPONATTACK) && (srcMinor != CMMsg.TYP_THROW))\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif (!flags.canMove(this))\n\t\t\t\t\t{\n\t\t\t\t\t\ttell(L("You can\'t move!"));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// limb, weight check\n\t\t\t\tswitch (msg.targetMinor())\n\t\t\t\t{\n\t\t\t\tcase CMMsg.TYP_PULL:\n\t\t\t\tcase CMMsg.TYP_PUSH:\n\t\t\t\t{\n\t\t\t\t\tif (msg.target() instanceof Physical)\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal int totalWeight = CMLib.utensils().getPullWeight((Physical) msg.target());\n\t\t\t\t\t\tif ((maxCarry() * 10) < totalWeight)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(msg.targetMinor() == CMMsg.TYP_PUSH)\n\t\t\t\t\t\t\t\ttell(L("That\'s way too heavy to push."));\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\ttell(L("That\'s way too heavy to pull."));\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t//$FALL-THROUGH$\n\t\t\t\tcase CMMsg.TYP_GET:\n\t\t\t\tcase CMMsg.TYP_REMOVE:\n\t\t\t\tcase CMMsg.TYP_OPEN:\n\t\t\t\tcase CMMsg.TYP_CLOSE:\n\t\t\t\t\tif ((charStats().getBodyPart(Race.BODY_ARM) == 0) && (baseCharStats().getMyRace().bodyMask()[Race.BODY_ARM] > 0))\n\t\t\t\t\t{\n\t\t\t\t\t\ttell(L("You need arms to do that."));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_DELICATE_HANDS_ACT:\n\t\t\t\t\tif ((charStats().getBodyPart(Race.BODY_HAND) == 0) && (msg.othersMinor() != CMMsg.NO_EFFECT))\n\t\t\t\t\t{\n\t\t\t\t\t\ttell(L("You need hands to do that."));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_JUSTICE:\n\t\t\t\t\tif ((charStats().getBodyPart(Race.BODY_HAND) == 0)\n\t\t\t\t\t&& (baseCharStats().getMyRace().bodyMask()[Race.BODY_HAND] > 0)\n\t\t\t\t\t&& (msg.target() instanceof Item)\n\t\t\t\t\t&& (!((msg.tool() instanceof Ability)\n\t\t\t\t\t&& CMLib.ableMapper().qualifiesOnlyByRace(msg.source(), (Ability) msg.tool()))))\n\t\t\t\t\t{\n\t\t\t\t\t\ttell(L("You need hands to do that."));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_FILL:\n\t\t\t\tcase CMMsg.TYP_GIVE:\n\t\t\t\tcase CMMsg.TYP_PUT:\n\t\t\t\t\tif ((charStats().getBodyPart(Race.BODY_ARM) == 0)\n\t\t\t\t\t&& (baseCharStats().getMyRace().bodyMask()[Race.BODY_ARM] > 0))\n\t\t\t\t\t{\n\t\t\t\t\t\ttell(L("You need arms to do that."));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_LOCK:\n\t\t\t\tcase CMMsg.TYP_HANDS:\n\t\t\t\tcase CMMsg.TYP_INSTALL:\n\t\t\t\tcase CMMsg.TYP_REPAIR:\n\t\t\t\tcase CMMsg.TYP_ENHANCE:\n\t\t\t\tcase CMMsg.TYP_UNLOCK:\n\t\t\t\tcase CMMsg.TYP_WRITE:\n\t\t\t\tcase CMMsg.TYP_REWRITE:\n\t\t\t\t\tif (charStats().getBodyPart(Race.BODY_HAND) == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\ttell(L("You need hands to do that."));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_DRINK:\n\t\t\t\t\tif ((charStats().getBodyPart(Race.BODY_HAND) == 0) && (baseCharStats().getMyRace().bodyMask()[Race.BODY_HAND] > 0))\n\t\t\t\t\t{\n\t\t\t\t\t\tif ((msg.target() != null) && (isMine(msg.target())))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttell(L("You need hands to do that."));\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\t// activity check\n\t\t\t\tswitch (msg.sourceMinor())\n\t\t\t\t{\n\t\t\t\tcase CMMsg.TYP_WEAR:\n\t\t\t\tcase CMMsg.TYP_HOLD:\n\t\t\t\tcase CMMsg.TYP_WIELD:\n\t\t\t\tcase CMMsg.TYP_REMOVE:\n\t\t\t\t\tpossWieldedItem = null;\n\t\t\t\t\tpossHeldItem = null;\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_RPXPCHANGE:\n\t\t\t\t\tif ((curState().getHunger() < 1)\n\t\t\t\t\t|| (curState().getThirst() < 1)\n\t\t\t\t\t|| (curState().getFatigue() > CharState.FATIGUED_MILLIS))\n\t\t\t\t\t{\n\t\t\t\t\t\t// silent\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_JUSTICE:\n\t\t\t\t\tif ((isInCombat()) && (msg.target() instanceof Item))\n\t\t\t\t\t{\n\t\t\t\t\t\ttell(L("Not while you are fighting!"));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_THROW:\n\t\t\t\t\tif (charStats().getBodyPart(Race.BODY_ARM) == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\ttell(L("You need arms to do that."));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_OPEN:\n\t\t\t\tcase CMMsg.TYP_CLOSE:\n\t\t\t\t\tif (isInCombat())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (((msg.target() instanceof Exit) || (srcM.isMine(msg.target()))))\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\ttell(L("Not while you are fighting!"));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_LEAVE:\n\t\t\t\t\tif ((isInCombat())\n\t\t\t\t\t&& (location() != null)\n\t\t\t\t\t&& (!msg.sourceMajor(CMMsg.MASK_MAGIC))\n\t\t\t\t\t&& (!flags.isFalling(this)))\n\t\t\t\t\t{\n\t\t\t\t\t\tfor (final Enumeration<MOB> m = location().inhabitants(); m.hasMoreElements();)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal MOB M = m.nextElement();\n\t\t\t\t\t\t\tif ((M != this)\n\t\t\t\t\t\t\t&& (M.getVictim() == this)\n\t\t\t\t\t\t\t&& (flags.isAliveAwakeMobile(M, true))\n\t\t\t\t\t\t\t&& (flags.canSenseEnteringLeaving(srcM, M))\n\t\t\t\t\t\t\t&& (CMProps.getVar(CMProps.Str.PLAYERFLEE) != null)\n\t\t\t\t\t\t\t&& (CMProps.getVar(CMProps.Str.PLAYERFLEE).length() > 0))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttell(L("Not while you are fighting!"));\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_READ:\n\t\t\t\t\tif (isInCombat()\n\t\t\t\t\t&& (!msg.sourceMajor(CMMsg.MASK_MAGIC))\n\t\t\t\t\t&& (!(msg.target() instanceof Scroll)))\n\t\t\t\t\t{\n\t\t\t\t\t\ttell(L("You are too busy fighting to read!"));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_SIT: // SIT is waking!\n\t\t\t\t\tif (flags.isSleeping(this))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t//$FALL-THROUGH$\n\t\t\t\tcase CMMsg.TYP_BUY:\n\t\t\t\tcase CMMsg.TYP_BID:\n\t\t\t\tcase CMMsg.TYP_DELICATE_HANDS_ACT:\n\t\t\t\tcase CMMsg.TYP_FILL:\n\t\t\t\tcase CMMsg.TYP_LIST:\n\t\t\t\tcase CMMsg.TYP_LOCK:\n\t\t\t\tcase CMMsg.TYP_SLEEP:\n\t\t\t\tcase CMMsg.TYP_UNLOCK:\n\t\t\t\tcase CMMsg.TYP_VALUE:\n\t\t\t\tcase CMMsg.TYP_SELL:\n\t\t\t\tcase CMMsg.TYP_VIEW:\n\t\t\t\t\tif (isInCombat()\n\t\t\t\t\t&& (!msg.sourceMajor(CMMsg.MASK_MAGIC)))\n\t\t\t\t\t{\n\t\t\t\t\t\ttell(L("Not while you are fighting!"));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_REBUKE:\n\t\t\t\t\tif ((msg.target() == null) || (!(msg.target() instanceof Deity)))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (msg.target() != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif ((msg.target() instanceof MOB)\n\t\t\t\t\t\t\t&& (!flags.canBeHeardSpeakingBy(this, (MOB) msg.target())))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttell(L("@x1 can\'t hear you!", ((Physical) msg.target()).name(this)));\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\tif ((msg.target() instanceof MOB)\n\t\t\t\t\t\t\t&& (((MOB) msg.target()).amFollowing() == srcM)\n\t\t\t\t\t\t\t&& (srcM.isFollowedBy((MOB) msg.target())))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t// should work.\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\tif ((!((msg.target() instanceof MOB)  && (((MOB) msg.target()).getLiegeID().equals(Name()))))\n\t\t\t\t\t\t\t&& (!msg.target().Name().equals(getLiegeID())))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttell(L("@x1 does not serve you, and you do not serve @x2.", ((Physical) msg.target()).name(this), ((Physical) msg.target()).name(this)));\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\tif ((msg.target() instanceof MOB)\n\t\t\t\t\t\t\t&& (((MOB) msg.target()).getLiegeID().equals(Name()))\n\t\t\t\t\t\t\t&& (getLiegeID().equals(msg.target().Name()))\n\t\t\t\t\t\t\t&& (((MOB) msg.target()).isMarriedToLiege()))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttell(L("You cannot rebuke @x1.  You must get an annulment or a divorce.", ((Physical) msg.target()).name(this)));\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif (getLiegeID().length() == 0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttell(L("You aren\'t serving anyone!"));\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif (charStats().getWorshipCharID().length() == 0)\n\t\t\t\t\t{\n\t\t\t\t\t\ttell(L("You aren\'t worshipping anyone!"));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_SERVE:\n\t\t\t\t\tif (msg.target() == null)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif (msg.target() == this)\n\t\t\t\t\t{\n\t\t\t\t\t\ttell(L("You can\'t serve yourself!"));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif (msg.target() instanceof Deity)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tif ((msg.target() instanceof MOB)\n\t\t\t\t\t&& (!flags.canBeHeardSpeakingBy(this, (MOB) msg.target())))\n\t\t\t\t\t{\n\t\t\t\t\t\ttell(L("@x1 can\'t hear you!", ((Physical) msg.target()).name(this)));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif (getLiegeID().length() > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\ttell(L("You are already serving \'@x1\'.", getLiegeID()));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif ((msg.target() instanceof MOB) && (((MOB) msg.target()).getLiegeID().equals(Name())))\n\t\t\t\t\t{\n\t\t\t\t\t\ttell(L("You can not serve each other!"));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_CAST_SPELL:\n\t\t\t\t\tif (charStats().getStat(CharStats.STAT_INTELLIGENCE) < 5)\n\t\t\t\t\t{\n\t\t\t\t\t\ttell(L("You aren\'t smart enough to do magic."));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ((msg.sourceCode() != CMMsg.NO_EFFECT)\n\t\t&& (msg.amISource(this))\n\t\t&& (msg.target() instanceof MOB)\n\t\t&& (msg.target() != this)\n\t\t&& (!CMath.bset(msg.sourceMajor(), CMMsg.MASK_ALWAYS))\n\t\t&& (location() != null)\n\t\t&& (location() == ((MOB) msg.target()).location()))\n\t\t{\n\t\t\tfinal MOB trgM = (MOB) msg.target();\n\t\t\tfinal int srcMinor = msg.sourceMinor();\n\t\t\t// and now, the consequences of range\n\t\t\tif (((msg.targetMinor() == CMMsg.TYP_WEAPONATTACK)\n\t\t\t\t&& (rangeToTarget() > maxRangeWith(msg.tool())))\n\t\t\t|| ((srcMinor == CMMsg.TYP_THROW)\n\t\t\t\t&& (rangeToTarget() > 2)\n\t\t\t\t&& (maxRangeWith(msg.tool()) <= 0)))\n\t\t\t{\n\t\t\t\tmsg.modify(this, trgM, null, CMMsg.MSG_ADVANCE, L("<S-NAME> advance(s) at <T-NAME>."));\n\t\t\t\tfinal boolean ok = location().okMessage(this, msg);\n\t\t\t\tif (ok)\n\t\t\t\t\tsetRangeToTarget(rangeToTarget() - 1);\n\t\t\t\tif (victim != null)\n\t\t\t\t{\n\t\t\t\t\tvictim.setRangeToTarget(rangeToTarget());\n\t\t\t\t\tvictim.recoverPhyStats();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tsetRangeToTarget(-1);\n\t\t\t\trecoverPhyStats();\n\t\t\t\treturn ok;\n\t\t\t}\n\t\t\telse\n\t\t\tif (msg.targetMinor() == CMMsg.TYP_RETREAT)\n\t\t\t{\n\t\t\t\tif (curState().getMovement() < 25)\n\t\t\t\t{\n\t\t\t\t\ttell(L("You are too tired."));\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif ((location() != null)\n\t\t\t\t&& (rangeToTarget() >= location().maxRange()))\n\t\t\t\t{\n\t\t\t\t\ttell(L("You cannot retreat any further."));\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tcurState().adjMovement(-25, maxState());\n\t\t\t\tsetRangeToTarget(rangeToTarget() + 1);\n\t\t\t\tif (victim != null)\n\t\t\t\t{\n\t\t\t\t\tvictim.setRangeToTarget(rangeToTarget());\n\t\t\t\t\tvictim.recoverPhyStats();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tsetRangeToTarget(-1);\n\t\t\t\trecoverPhyStats();\n\t\t\t}\n\t\t\telse\n\t\t\tif ((msg.tool() != null)\n\t\t\t&& (srcMinor != CMMsg.TYP_BUY)\n\t\t\t&& (srcMinor != CMMsg.TYP_BID)\n\t\t\t&& (srcMinor != CMMsg.TYP_SELL)\n\t\t\t&& (srcMinor != CMMsg.TYP_VIEW))\n\t\t\t{\n\t\t\t\t// this reason this is here and not in stdability protecting\n\t\t\t\t// mana usage is because the target must be determined for\n\t\t\t\t// last second ranging, which stdability invoke won\'t know.\n\t\t\t\tint useRange = -1;\n\t\t\t\tfinal Environmental tool = msg.tool();\n\t\t\t\tif (getVictim() != null)\n\t\t\t\t{\n\t\t\t\t\tif (getVictim() == trgM)\n\t\t\t\t\t\tuseRange = rangeToTarget();\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif (trgM.getVictim() == this)\n\t\t\t\t\t\t\tuseRange = trgM.rangeToTarget();\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tuseRange = maxRangeWith(tool);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ((useRange >= 0) && (maxRangeWith(tool) < useRange))\n\t\t\t\t{\n\t\t\t\t\tsrcM.tell(L("You are too far away from @x1 to use @x2.", trgM.name(srcM), tool.name()));\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\tif ((useRange >= 0) && (minRangeWith(tool) > useRange))\n\t\t\t\t{\n\t\t\t\t\tsrcM.tell(L("You are too close to @x1 to use @x2.", trgM.name(srcM), tool.name()));\n\t\t\t\t\tif ((msg.targetMinor() == CMMsg.TYP_WEAPONATTACK)\n\t\t\t\t\t&& (tool instanceof Weapon)\n\t\t\t\t\t&& (!((Weapon) tool).amWearingAt(Wearable.IN_INVENTORY)))\n\t\t\t\t\t\tCMLib.commands().postRemove(this, (Weapon) msg.tool(), false);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ((msg.targetMinor() != CMMsg.NO_EFFECT) && (msg.amITarget(this)))\n\t\t{\n\t\t\tif ((amDead()) || (location() == null))\n\t\t\t\treturn false;\n\t\t\tif (CMath.bset(msg.targetMajor(), CMMsg.MASK_MALICIOUS))\n\t\t\t{\n\t\t\t\tif (Log.combatChannelOn())\n\t\t\t\t{\n\t\t\t\t\tLog.combatOut(srcM.Name() + ":" + Name() + ":" + CMMsg.TYPE_DESCS[msg.targetMinor()] + ":" + ((msg.tool() != null) ? msg.tool().Name() : "null"));\n\t\t\t\t}\n\n\t\t\t\tif ((msg.amISource(this))\n\t\t\t\t&& (!msg.sourceMajor(CMMsg.MASK_ALWAYS))\n\t\t\t\t&& ((msg.tool() == null)\n\t\t\t\t\t|| (!(msg.tool() instanceof Ability))\n\t\t\t\t\t|| (!((Ability) msg.tool()).isNowAnAutoEffect())))\n\t\t\t\t{\n\t\t\t\t\tsrcM.tell(L("You like yourself too much."));\n\t\t\t\t\tif (victim == this)\n\t\t\t\t\t{\n\t\t\t\t\t\tvictim = null;\n\t\t\t\t\t\tsetRangeToTarget(-1);\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif ((!mayIFight(srcM))\n\t\t\t\t&& ((!(msg.tool() instanceof Ability))\n\t\t\t\t\t|| (((((Ability) msg.tool()).classificationCode() & Ability.ALL_ACODES) != Ability.ACODE_POISON)\n\t\t\t\t\t\t&& ((((Ability) msg.tool()).classificationCode() & Ability.ALL_ACODES) != Ability.ACODE_DISEASE))\n\t\t\t\t\t|| ((srcM == this) && (srcM.isMonster()))))\n\t\t\t\t{\n\t\t\t\t\tsrcM.tell(L("You may not attack @x1.", name(srcM)));\n\t\t\t\t\tsrcM.setVictim(null);\n\t\t\t\t\tif (victim == srcM)\n\t\t\t\t\t\tsetVictim(null);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif ((srcM != this)\n\t\t\t\t&& (!isMonster())\n\t\t\t\t&& (!srcM.isMonster())\n\t\t\t\t&& (soulMate() == null)\n\t\t\t\t&& (srcM.soulMate() == null)\n\t\t\t\t&& (CMath.abs(srcM.phyStats().level() - phyStats().level()) > CMProps.getPKillLevelDiff())\n\t\t\t\t&& (!CMSecurity.isAllowed(this, location(), CMSecurity.SecFlag.PKILL))\n\r\n\tprotected String fixChannelColors(final int channelCode, final String message)\r\n\t{\r\n\t\tfinal Session session = mySession;\r\n\t\tif(session != null && session.getColorCodes()[128 + channelCode]!=null)\r\n\t\t\treturn CMStrings.replaceAll(message, ColorLibrary.SpecialColor.CHANNEL.getEscapeCode(), mySession.getColorCodes()[128 + channelCode]);\r\n\t\t\t\t\tsrcM.tell(L("That is not EVEN a fair fight."));\n\t\t\t\t\tsrcM.setVictim(null);\n\t\t\t\t\tif (victim == srcM)\n\t\t\t\t\t\tsetVictim(null);\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tif ((amFollowing() == srcM)\n\t\t\t\t&& (!(msg.tool() instanceof DiseaseAffect)))\n\t\t\t\t\tsetFollowing(null);\n\n\t\t\t\tif (isInCombat())\n\t\t\t\t{\n\t\t\t\t\tif ((rangeToTarget() > 0)\n\t\t\t\t\t&& (getVictim() != srcM)\n\t\t\t\t\t&& (srcM.getVictim() == this)\n\t\t\t\t\t&& (srcM.rangeToTarget() == 0))\n\t\t\t\t\t{\n\t\t\t\t\t\tsetVictim(srcM);\n\t\t\t\t\t\tsetRangeToTarget(0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!CMLib.combat().checkSavingThrows(this, msg))\n\t\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif ((rangeToTarget() >= 0) && (!isInCombat()))\n\t\t\t\tsetRangeToTarget(-1);\n\n\t\t\tswitch (msg.targetMinor())\n\t\t\t{\n\t\t\tcase CMMsg.TYP_CLOSE:\n\t\t\tcase CMMsg.TYP_DRINK:\n\t\t\tcase CMMsg.TYP_DROP:\n\t\t\tcase CMMsg.TYP_EAT:\n\t\t\tcase CMMsg.TYP_FILL:\n\t\t\tcase CMMsg.TYP_GET:\n\t\t\tcase CMMsg.TYP_HOLD:\n\t\t\tcase CMMsg.TYP_REMOVE:\n\t\t\tcase CMMsg.TYP_LOCK:\n\t\t\tcase CMMsg.TYP_OPEN:\n\t\t\tcase CMMsg.TYP_PUT:\n\t\t\tcase CMMsg.TYP_UNLOCK:\n\t\t\tcase CMMsg.TYP_WEAR:\n\t\t\tcase CMMsg.TYP_WIELD:\n\t\t\t\tsrcM.tell(srcM, this, null, L("You can\'t do that to <T-NAMESELF>."));\n\t\t\t\treturn false;\n\t\t\tcase CMMsg.TYP_POUR:\n\t\t\t{\n\t\t\t\tboolean permitted = false;\n\t\t\t\tif (msg.tool() instanceof Potion)\n\t\t\t\t{\n\t\t\t\t\tfor (final Ability A : ((Potion) msg.tool()).getSpells())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (A.castingQuality(msg.source(), this) != Ability.QUALITY_MALICIOUS)\n\t\t\t\t\t\t\tpermitted = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tpermitted = true;\n\t\t\t\tif (!permitted)\n\t\t\t\t{\n\t\t\t\t\tsrcM.tell(srcM, this, null, L("You can\'t do that to <T-NAMESELF>."));\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase CMMsg.TYP_TEACH:\n\t\t\t\tif (playerStats() == null)\n\t\t\t\t{\n\t\t\t\t\tsrcM.tell(srcM, this, null, L("<T-NAME> isn\'t interested."));\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (playerStats().isIgnored(msg.source()))\n\t\t\t\t\treturn false;\n\t\t\t\tif (!CMLib.expertises().canBeTaught(msg.source(), (MOB) msg.target(), msg.tool(), msg.targetMessage()))\n\t\t\t\t\treturn false;\n\t\t\t\tbreak;\n\t\t\tcase CMMsg.TYP_DAMAGE:\n\t\t\t\tif (!CMLib.combat().checkDamageSaves(this, msg))\n\t\t\t\t\treturn false;\n\t\t\t\tbreak;\n\t\t\tcase CMMsg.TYP_PULL:\n\t\t\t\tif ((!CMLib.flags().isBoundOrHeld(this)) && (!CMLib.flags().isSleeping(this)))\n\t\t\t\t{\n\t\t\t\t\tsrcM.tell(srcM, this, null, L("You can\'t do that to <T-NAMESELF>."));\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (phyStats().weight() > (srcM.maxCarry() / 2))\n\t\t\t\t{\n\t\t\t\t\tsrcM.tell(srcM, this, null, L("<T-NAME> is too big for you to pull."));\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif ((srcM.curState().getMovement() < phyStats.movesReqToPull())\n\t\t\t\t&& (srcM.curState().getMovement() < srcM.maxState().getMovement()))\n\t\t\t\t{\n\t\t\t\t\tsrcM.tell(L("You don\'t have enough movement."));\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase CMMsg.TYP_PUSH:\n\t\t\t\tif ((!CMLib.flags().isBoundOrHeld(this)) && (!CMLib.flags().isSleeping(this)))\n\t\t\t\t{\n\t\t\t\t\tsrcM.tell(srcM, this, null, L("You can\'t do that to <T-NAMESELF>."));\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (phyStats().weight() > (srcM.maxCarry() / 2))\n\t\t\t\t{\n\t\t\t\t\tsrcM.tell(srcM, this, null, L("<T-NAME> is too heavy for you to push."));\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif ((srcM.curState().getMovement() < phyStats.movesReqToPush())\n\t\t\t\t&& (srcM.curState().getMovement() < srcM.maxState().getMovement()))\n\t\t\t\t{\n\t\t\t\t\tsrcM.tell(L("You don\'t have enough movement."));\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase CMMsg.TYP_MOUNT:\n\t\t\tcase CMMsg.TYP_DISMOUNT:\n\t\t\t\tif (!(this instanceof Rideable))\n\t\t\t\t{\n\t\t\t\t\tsrcM.tell(srcM, this, null, L("You can\'t do that to <T-NAMESELF>."));\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase CMMsg.TYP_GIVE:\n\t\t\t\tif (!(msg.tool() instanceof Item))\n\t\t\t\t\treturn false;\n\t\t\t\tif (CMSecurity.isAllowed(this, location(), CMSecurity.SecFlag.ORDER)\n\t\t\t\t|| (CMSecurity.isAllowed(this, location(), CMSecurity.SecFlag.CMDMOBS) && (isMonster()))\n\t\t\t\t|| (CMSecurity.isAllowed(this, location(), CMSecurity.SecFlag.CMDROOMS) && (isMonster())))\n\t\t\t\t\treturn true;\n\t\t\t\tif ((charStats().getBodyPart(Race.BODY_ARM) == 0)\n\t\t\t\t&& (baseCharStats().getMyRace().bodyMask()[Race.BODY_ARM] > 0)\n\t\t\t\t&& (!CMath.bset(msg.targetMajor(), CMMsg.MASK_ALWAYS)))\n\t\t\t\t{\n\t\t\t\t\tsrcM.tell(L("@x1 is unable to accept that from you.", name(srcM)));\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif ((!CMLib.flags().canBeSeenBy(msg.tool(), this))\n\t\t\t\t&& (!CMath.bset(msg.targetMajor(), CMMsg.MASK_ALWAYS)))\n\t\t\t\t{\n\t\t\t\t\tsrcM.tell(L("@x1 can\'t see what you are giving.", name(srcM)));\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tfinal int GC = msg.targetMajor() & CMMsg.MASK_ALWAYS;\n\t\t\t\tCMMsg msg2 = CMClass.getMsg(srcM, msg.tool(), null,\n\t\t\t\t\t\tCMMsg.MSG_DROP | CMMsg.MASK_INTERMSG, null,\n\t\t\t\t\t\tCMMsg.MSG_DROP | CMMsg.MASK_INTERMSG, null,\n\t\t\t\t\t\tCMMsg.MSG_DROP | CMMsg.MASK_INTERMSG, null);\n\t\t\t\tif (!location().okMessage(srcM, msg2))\n\t\t\t\t\treturn false;\n\t\t\t\tif (msg.target() instanceof MOB)\n\t\t\t\t{\n\t\t\t\t\tmsg2 = CMClass.getMsg((MOB) msg.target(), msg.tool(), null,\n\t\t\t\t\t\t\tGC | CMMsg.MSG_GET | CMMsg.MASK_INTERMSG, null,\n\t\t\t\t\t\t\tGC | CMMsg.MSG_GET | CMMsg.MASK_INTERMSG, null,\n\t\t\t\t\t\t\tGC | CMMsg.MSG_GET | CMMsg.MASK_INTERMSG, null);\n\t\t\t\t\tif (!location().okMessage(msg.target(), msg2))\n\t\t\t\t\t{\n\t\t\t\t\t\tsrcM.tell(L("@x1 cannot seem to accept @x2.", ((Physical) msg.target()).name(srcM), ((Physical) msg.tool()).name(this)));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase CMMsg.TYP_FOLLOW:\n\t\t\t\tif (totalFollowers() + srcM.totalFollowers() >= maxFollowers())\n\t\t\t\t{\n\t\t\t\t\tsrcM.tell(L("@x1 can\'t accept any more followers.", name(srcM)));\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif ((CMProps.getIntVar(CMProps.Int.FOLLOWLEVELDIFF) > 0)\n\t\t\t\t&& (!isMonster())\n\t\t\t\t&& (!srcM.isMonster())\n\t\t\t\t&& (!CMSecurity.isAllowed(this, location(), CMSecurity.SecFlag.ORDER))\n\t\t\t\t&& (!CMSecurity.isAllowed(srcM, srcM.location(), CMSecurity.SecFlag.ORDER)))\n\t\t\t\t{\n\t\t\t\t\tif (phyStats.level() > (srcM.phyStats().level() + CMProps.getIntVar(CMProps.Int.FOLLOWLEVELDIFF)))\n\t\t\t\t\t{\n\t\t\t\t\t\tsrcM.tell(L("@x1 is too advanced for you.", name(srcM)));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif (phyStats.level() < (srcM.phyStats().level() - CMProps.getIntVar(CMProps.Int.FOLLOWLEVELDIFF)))\n\t\t\t\t\t{\n\t\t\t\t\t\tsrcM.tell(L("@x1 is too inexperienced for you.", name(srcM)));\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tif ((srcM != this) && (msg.target() != this))\n\t\t{\n\t\t\tif ((msg.othersMinor() == CMMsg.TYP_DEATH) && (msg.sourceMinor() == CMMsg.TYP_DEATH))\n\t\t\t{\n\t\t\t\tif ((followers != null)\n\t\t\t\t&& (followers.containsFirst(srcM))\n\t\t\t\t&& (CMLib.dice().rollPercentage() == 1)\n\t\t\t\t&& (fetchEffect("Disease_Depression") == null)\n\t\t\t\t&& (!CMSecurity.isDisabled(CMSecurity.DisFlag.AUTODISEASE)))\n\t\t\t\t{\n\t\t\t\t\tfinal Ability A = CMClass.getAbility("Disease_Depression");\n\t\t\t\t\tif ((A != null) && (!CMSecurity.isAbilityDisabled(A.ID())))\n\t\t\t\t\t\tA.invoke(this, this, true, 0);\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic void tell(final MOB source, final Environmental target, final Environmental tool, final String msg)\n\t{\n\t\tfinal Session S = mySession;\n\t\tif ((S != null) && (msg != null))\n\t\t\tS.stdPrintln(source, target, tool, msg);\n\t}\n\n\t@Override\n\tpublic void tell(final String msg)\n\t{\n\t\ttell(this, this, null, msg);\n\t}\n\n\tprotected String fixChannelColors(final int channelCode, final String message)\n\t{\n\n\t\tfinal Session session = mySession;\n\t\tif ((session != null)\n\t\t&& ((128 + channelCode) >= 0)\n\t\t&& ((128 + channelCode) < session.getColorCodes().length)\n\t\t&& (session.getColorCodes()[128 + channelCode] != null))\n\t\t\treturn CMStrings.replaceAll(message, ColorLibrary.SpecialColor.CHANNEL.getEscapeCode(), mySession.getColorCodes()[128 + channelCode]);\n\t\telse\n\t\t{\n\t\t\tfinal CMChannel chan = CMLib.channels().getChannel(channelCode);\n\t\t\tif (chan == null)\n\t\t\t\tLog.errOut("Unknown channel number: " + channelCode);\n\t\t\telse\n\t\t\tif ((chan.colorOverrideANSICodes() != null) && (chan.colorOverrideANSICodes().length() > 0))\n\t\t\t\treturn CMStrings.replaceAll(message, ColorLibrary.SpecialColor.CHANNEL.getEscapeCode(), chan.colorOverrideANSICodes());\n\t\t}\n\t\treturn message;\n\t}\n\n\t@Override\n\tpublic void executeMsg(final Environmental myHost, final CMMsg msg)\n\t{\n\t\tfinal Deity deity = charStats().getMyDeity();\n\t\tif (deity != null)\n\t\t\tdeity.executeMsg(this, msg);\n\n\t\tfinal CharStats cStats = charStats;\n\t\tif (cStats != null)\n\t\t{\n\t\t\tfor (int c = 0; c < cStats.numClasses(); c++)\n\t\t\t\tcStats.getMyClass(c).executeMsg(this, msg);\n\t\t\tcStats.getMyRace().executeMsg(this, msg);\n\t\t}\n\n\t\tif (numBehaviors() > 0)\n\t\t{\n\t\t\teachBehavior(new EachApplicable<Behavior>()\n\t\t\t{\n\t\t\t\t@Override\n\t\t\t\tpublic final void apply(final Behavior B)\n\t\t\t\t{\n\t\t\t\t\tB.executeMsg(me, msg);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tif (numScripts() > 0)\n\t\t{\n\t\t\teachScript(new EachApplicable<ScriptingEngine>()\n\t\t\t{\n\t\t\t\t@Override\n\t\t\t\tpublic final void apply(final ScriptingEngine S)\n\t\t\t\t{\n\t\t\t\t\tS.executeMsg(me, msg);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tfinal MOB srcM = msg.source();\n\n\t\tfinal boolean asleep = CMLib.flags().isSleeping(this);\n\t\tfinal boolean canseesrc = CMLib.flags().canBeSeenBy(srcM, this);\n\t\tfinal boolean canhearsrc = (msg.targetMinor() == CMMsg.TYP_SPEAK) ?\n\t\t\t\t\t\t\t\t\tCMLib.flags().canBeHeardSpeakingBy(srcM, this) :\n\t\t\t\t\t\t\t\t\t\tCMLib.flags().canBeHeardMovingBy(srcM, this);\n\n\t\t// first do special cases...\n\t\tif (msg.amITarget(this) && (!amDead))\n\t\t{\n\t\t\tswitch (msg.targetMinor())\n\t\t\t{\n\t\t\tcase CMMsg.TYP_HEALING:\n\t\t\t\tCMLib.combat().handleBeingHealed(msg);\n\t\t\t\tbreak;\n\t\t\tcase CMMsg.TYP_SNIFF:\n\t\t\t\tCMLib.commands().handleBeingSniffed(msg);\n\t\t\t\tbreak;\n\t\t\tcase CMMsg.TYP_DAMAGE:\n\t\t\t\tCMLib.combat().handleBeingDamaged(msg);\n\t\t\t\tbreak;\n\t\t\tcase CMMsg.TYP_TEACH:\n\t\t\t\tif (msg.target() instanceof MOB)\n\t\t\t\t\tCMLib.expertises().handleBeingTaught(msg.source(), (MOB) msg.target(), msg.tool(), msg.targetMessage(), msg.value());\n\t\t\t\tbreak;\n\t\t\tcase CMMsg.TYP_GRAVITY:\n\t\t\t\tCMLib.combat().handleBeingGravitied(this, msg);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// now go on to source activities\n\t\tif ((msg.sourceCode() != CMMsg.NO_EFFECT) && (msg.amISource(this)))\n\t\t{\n\t\t\tif ((CMath.bset(msg.sourceMajor(), CMMsg.MASK_MALICIOUS))\n\t\t\t&& (msg.target() instanceof MOB)\n\t\t\t&& (getVictim() != msg.target())\n\t\t\t&& ((!CMath.bset(msg.sourceMajor(), CMMsg.MASK_ALWAYS)) || (!(msg.tool() instanceof DiseaseAffect))))\n\t\t\t{\n\t\t\t\tCMLib.combat().establishRange(this, (MOB) msg.target(), msg.tool());\n\t\t\t\tif ((msg.tool() instanceof Weapon)\n\t\t\t\t|| (msg.sourceMinor() == CMMsg.TYP_WEAPONATTACK)\n\t\t\t\t|| (!CMLib.flags().isAliveAwakeMobileUnbound((MOB) msg.target(), true)))\n\t\t\t\t\tsetVictim((MOB) msg.target());\n\t\t\t}\n\n\t\t\tif (CMath.bset(msg.sourceMajor(), CMMsg.MASK_CHANNEL))\n\t\t\t{\n\t\t\t\tint channelCode;\n\t\t\t\tif (CMath.bset(msg.othersMajor(), CMMsg.MASK_CHANNEL))\n\t\t\t\t\tchannelCode = msg.othersMinor() - CMMsg.TYP_CHANNEL;\n\t\t\t\telse\n\t\t\t\tif (CMath.bset(msg.targetMajor(), CMMsg.MASK_CHANNEL))\n\t\t\t\t\tchannelCode = msg.targetMinor() - CMMsg.TYP_CHANNEL;\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\ttell(srcM, msg.target(), msg.tool(), msg.sourceMessage());\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ttell(srcM, msg.target(), msg.tool(), fixChannelColors(channelCode, msg.sourceMessage()));\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tswitch (msg.sourceMinor())\n\t\t\t\t{\n\t\t\t\tcase CMMsg.TYP_LIFE:\n\t\t\t\t\tCMLib.commands().handleComeToLife(this, msg);\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_PANIC:\n\t\t\t\t\tCMLib.commands().postFlee(this, "");\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_EXPCHANGE:\n\t\t\t\t\tCMLib.leveler().handleExperienceChange(msg);\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_RPXPCHANGE:\n\t\t\t\t\tCMLib.leveler().handleRPExperienceChange(msg);\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_FACTIONCHANGE:\n\t\t\t\t\tif (msg.othersMessage() != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tif ((msg.value() == Integer.MAX_VALUE) || (msg.value() == Integer.MIN_VALUE))\n\t\t\t\t\t\t\tremoveFaction(msg.othersMessage());\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tadjustFaction(msg.othersMessage(), msg.value());\n\t\t\t\t\t}\n\t\t\t\t\tif (msg.sourceMessage() != null)\n\t\t\t\t\t\ttell(this, msg.target(), msg.tool(), msg.sourceMessage());\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_DEATH:\n\t\t\t\t\tCMLib.get(mySession)._combat().handleDeath(msg);\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_REBUKE:\n\t\t\t\t\tif ((getLiegeID().length() > 0) && (!isMarriedToLiege()))\n\t\t\t\t\t{\n\t\t\t\t\t\tif ((msg.target() == null)\n\t\t\t\t\t\t|| ((msg.target().Name().equals(getLiegeID())) && (!isMarriedToLiege())))\n\t\t\t\t\t\t\tsetLiegeID("");\n\t\t\t\t\t}\n\t\t\t\t\ttell(this, msg.target(), msg.tool(), msg.sourceMessage());\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_SERVE:\n\t\t\t\t\tif ((msg.target() != null)\n\t\t\t\t\t&& (!(msg.target() instanceof Deity)))\n\t\t\t\t\t\tsetLiegeID(msg.target().Name());\n\t\t\t\t\ttell(this, msg.target(), msg.tool(), msg.sourceMessage());\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_LOOK:\n\t\t\t\tcase CMMsg.TYP_EXAMINE:\n\t\t\t\t\tif (msg.target() == this)\n\t\t\t\t\t\tCMLib.commands().handleBeingLookedAt(msg);\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_READ:\n\t\t\t\t\tif ((CMLib.flags().canBeSeenBy(this, srcM)) && (msg.amITarget(this)))\n\t\t\t\t\t\tsrcM.tell(L("There is nothing written on @x1", name(srcM)));\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_SIT:\n\t\t\t\t\tCMLib.commands().handleSit(msg);\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_SLEEP:\n\t\t\t\t\tCMLib.commands().handleSleep(msg);\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_QUIT:\n\t\t\t\t\ttell(srcM, msg.target(), msg.tool(), msg.sourceMessage());\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_STAND:\n\t\t\t\t\tCMLib.commands().handleStand(msg);\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_RECALL:\n\t\t\t\t\tCMLib.commands().handleRecall(msg);\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_FOLLOW:\n\t\t\t\t\tif (msg.target() instanceof MOB)\n\t\t\t\t\t{\n\t\t\t\t\t\tsetFollowing((MOB) msg.target());\n\t\t\t\t\t\ttell(srcM, msg.target(), msg.tool(), msg.sourceMessage());\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_NOFOLLOW:\n\t\t\t\t\tsetFollowing(null);\n\t\t\t\t\ttell(srcM, msg.target(), msg.tool(), msg.sourceMessage());\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_WEAR:\n\t\t\t\tcase CMMsg.TYP_HOLD:\n\t\t\t\tcase CMMsg.TYP_WIELD:\n\t\t\t\tcase CMMsg.TYP_REMOVE:\n\t\t\t\t\tpossWieldedItem = null;\n\t\t\t\t\tpossHeldItem = null;\n\t\t\t\t\ttell(srcM, msg.target(), msg.tool(), msg.sourceMessage());\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_ATTACKMISS:\n\t\t\t\t\tif (!isAttributeSet(Attrib.NOBATTLESPAM))\n\t\t\t\t\t\ttell(srcM, msg.target(), msg.tool(), msg.sourceMessage());\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_WROTE:\n\t\t\t\t\tif ((msg.target() instanceof Item)\n\t\t\t\t\t&& (msg.targetMessage() != null)\n\t\t\t\t\t&& (msg.targetMessage().length() > 0)\n\t\t\t\t\t&& (!CMSecurity.isDisabled(DisFlag.AUTODISEASE)))\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal String msgStr = msg.targetMessage().trim();\n\t\t\t\t\t\tif (msgStr.length() > 10)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal int chc = 30 + (((msg.target() instanceof Book) && ((Book) msg.target()).isJournal()) ? 30 : 0);\n\t\t\t\t\t\t\tif ((CMLib.dice().rollPercentage() < chc)\n\t\t\t\t\t\t\t&& (CMLib.dice().rollPercentage() > CMLib.english().probabilityOfBeingEnglish(msgStr)))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal Ability A = CMClass.getAbility("Disease_WritersBlock");\n\t\t\t\t\t\t\t\tif ((A != null)\n\t\t\t\t\t\t\t\t&& (fetchEffect(A.ID()) == null) && (!CMSecurity.isAbilityDisabled(A.ID())))\n\t\t\t\t\t\t\t\t\tA.invoke(this, this, true, 0);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase CMMsg.TYP_EXPIRE:\n\t\t\t\t\tif (msg.target() instanceof Area)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!isMonster())\n\t\t\t\t\t\t\tCMLib.achievements().possiblyBumpAchievement(this, Event.INSTANCEEXPIRE, 1, new Object[] { (Area) msg.target(), Integer.valueOf(msg.value()) });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tif ((msg.targetMinor() == CMMsg.TYP_DAMAGE)\n\t\t\t\t\t&& (isAttributeSet(Attrib.NOBATTLESPAM))\n\t\t\t\t\t&& (msg.target() instanceof Physical)\n\t\t\t\t\t&& (CMLib.combat().handleDamageSpam(this, (Physical) msg.target(), msg.value())))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t// you pretty much always know what you are doing, if you can do it.\n\t\t\t\t\tif (!CMath.bset(msg.sourceMajor(), CMMsg.MASK_CNTRLMSG))\n\t\t\t\t\t\ttell(srcM, msg.target(), msg.tool(), msg.sourceMessage());\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif(triggerer.isObsolete() || (!triggerer.isDisabled()))\n\t\t\t\tCMLib.ableComponents().handleAbilityComponentTriggers(msg);\n\t\t}\n\t\telse\n\t\tif ((msg.targetMinor() != CMMsg.NO_EFFECT) && (msg.amITarget(this)))\n\t\t{\n\t\t\tfinal int targetMajor = msg.targetMajor();\n\t\t\tswitch (msg.targetMinor())\n\t\t\t{\n\t\t\tcase CMMsg.TYP_HEALING:\n\t\t\tcase CMMsg.TYP_DAMAGE:\n\t\t\t\t// handled as special cases above\n\t\t\t\tbreak;\n\t\t\tcase CMMsg.TYP_GIVE:\n\t\t\t\tif (msg.tool() instanceof Item)\n\t\t\t\t\tCMLib.commands().handleBeingGivenTo(msg);\n\t\t\t\tbreak;\n\t\t\tcase CMMsg.TYP_LOOK:\n\t\t\tcase CMMsg.TYP_EXAMINE:\n\t\t\t\tif (CMLib.flags().canBeSeenBy(this, srcM))\n\t\t\t\t\tCMLib.commands().handleBeingLookedAt(msg);\n\t\t\t\tbreak;\n\t\t\tcase CMMsg.TYP_REBUKE:\n\t\t\t\tif ((srcM.Name().equals(getLiegeID()) && (!isMarriedToLiege())))\n\t\t\t\t\tsetLiegeID("");\n\t\t\t\tbreak;\n\t\t\tcase CMMsg.TYP_SPEAK:\n\t\t\t{\n\t\t\t\tif ((CMProps.getBoolVar(CMProps.Bool.INTRODUCTIONSYSTEM)\n\t\t\t\t\t|| CMProps.get(mySession).getBool(CMProps.Bool.INTRODUCTIONSYSTEM))\n\t\t\t\t&& (!asleep) && (canhearsrc))\n\t\t\t\t\tCMLib.commands().handleIntroductions(srcM, this, msg.targetMessage());\n\t\t\t\tCMLib.commands().handleBeingSpokenTo(srcM, this, msg.targetMessage());\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tif ((CMath.bset(msg.targetMajor(), CMMsg.MASK_MALICIOUS)) && (!amDead))\n\t\t\t\t\tCMLib.combat().handleBeingAssaulted(msg);\n\t\t\t\telse\n\t\t\t\tif (CMath.bset(targetMajor, CMMsg.MASK_CHANNEL))\n\t\t\t\t{\n\t\t\t\t\tfinal int channelCode = msg.targetMinor() - CMMsg.TYP_CHANNEL;\n\t\t\t\t\tif ((playerStats() != null)\n\t\t\t\t\t&& (!this.isAttributeSet(MOB.Attrib.QUIET))\n\t\t\t\t\t&& (!CMath.isSet(playerStats().getChannelMask(), channelCode)))\n\t\t\t\t\t\ttell(srcM, msg.target(), msg.tool(), fixChannelColors(channelCode, msg.targetMessage()));\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// now do the says\n\t\t\tswitch (msg.targetMinor())\n\t\t\t{\n\t\t\tcase CMMsg.TYP_DAMAGE:\n\t\t\t{\n\t\t\t\tif ((!isAttributeSet(Attrib.NOBATTLESPAM))\n\t\t\t\t|| (!(msg.target() instanceof Physical))\n\t\t\t\t|| (!CMLib.combat().handleDamageSpam(this, (Physical) msg.target(), msg.value())))\n\t\t\t\t\ttell(srcM, msg.target(), msg.tool(), msg.targetMessage());\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase CMMsg.TYP_HEALING:\n\t\t\t{\n\t\t\t\ttell(srcM, msg.target(), msg.tool(), msg.targetMessage());\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase CMMsg.TYP_ATTACKMISS:\n\t\t\t{\n\t\t\t\tif (!isAttributeSet(Attrib.NOBATTLESPAM))\n\t\t\t\t\ttell(srcM, msg.target(), msg.tool(), msg.targetMessage());\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tif ((CMath.bset(targetMajor, CMMsg.MASK_SOUND))\n\t\t\t\t&& (canhearsrc) && (!asleep))\n\t\t\t\t{\n\t\t\t\t\tif ((msg.targetMinor() == CMMsg.TYP_SPEAK)\n\t\t\t\t\t&& (srcM != null)\n\t\t\t\t\t&& (playerStats() != null)\n\t\t\t\t\t&& (!srcM.isMonster())\n\t\t\t\t\t&& (CMLib.flags().canBeHeardSpeakingBy(srcM, this)))\n\t\t\t\t\t\tplayerStats().setReplyTo(srcM, PlayerStats.REPLY_SAY);\n\t\t\t\t\ttell(srcM, msg.target(), msg.tool(), msg.targetMessage());\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\tif (CMath.bset(targetMajor, CMMsg.MASK_ALWAYS))\n\t\t\t\t\ttell(srcM, msg.target(), msg.tool(), msg.targetMessage());\n\t\t\t\telse\n\t\t\t\tif ((CMath.bset(targetMajor, CMMsg.MASK_EYES)) && ((!asleep) && (canseesrc)))\n\t\t\t\t\ttell(srcM, msg.target(), msg.tool(), msg.targetMessage());\n\t\t\t\telse\n\t\t\t\tif (CMath.bset(msg.targetMajor(), CMMsg.MASK_MALICIOUS))\n\t\t\t\t\ttell(srcM, msg.target(), msg.tool(), msg.targetMessage());\n\t\t\t\telse\n\t\t\t\tif (((CMath.bset(targetMajor, CMMsg.MASK_HANDS))\n\t\t\t\t\t|| (CMath.bset(targetMajor, CMMsg.MASK_MOVE))\n\t\t\t\t\t|| ((CMath.bset(targetMajor, CMMsg.MASK_MOUTH) && (!CMath.bset(targetMajor, CMMsg.MASK_SOUND)))))\n\t\t\t\t&& (!asleep) && ((canhearsrc) || (canseesrc)))\n\t\t\t\t\ttell(srcM, msg.target(), msg.tool(), msg.targetMessage());\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\telse\n\t\tif ((msg.othersCode() != CMMsg.NO_EFFECT)\n\t\t&& (!msg.amISource(this))\n\t\t&& (!msg.amITarget(this)))\n\t\t{\n\t\t\tfinal int othersMajor = msg.othersMajor();\n\t\t\tfinal int othersMinor = msg.othersMinor();\n\n\t\t\tif (CMath.bset(msg.othersMajor(), CMMsg.MASK_MALICIOUS)\n\t\t\t&& (msg.target() instanceof MOB)\n\t\t\t&& ((!CMath.bset(msg.sourceMajor(), CMMsg.MASK_ALWAYS)) || (!(msg.tool() instanceof DiseaseAffect))))\n\t\t\t\tCMLib.combat().makeFollowersFight(this, (MOB) msg.target(), srcM);\n\n\t\t\t// String othersMessage = msg.othersMessage(); // see comment below\n\t\t\t// TODO: unravel this into a switch statement somehow...\n\t\t\tif (isAttributeSet(Attrib.NOBATTLESPAM)\n\t\t\t&& (((msg.targetMinor() == CMMsg.TYP_DAMAGE)\n\t\t\t\t\t&& (msg.target() instanceof Physical)\n\t\t\t\t\t&& (CMLib.combat().handleDamageSpam(this, (Physical) msg.target(), msg.value())))\n\t\t\t\t|| (msg.targetMinor() == CMMsg.TYP_ATTACKMISS)))\n\t\t\t{\n\t\t\t\t// don\'t say diddly\n\t\t\t}\n\t\t\telse\n\t\t\tif ((othersMinor == CMMsg.TYP_ENTER) // exceptions to movement\n\t\t\t|| (othersMinor == CMMsg.TYP_FLEE) || (othersMinor == CMMsg.TYP_LEAVE))\n\t\t\t{\n\t\t\t\tif (((!asleep) || (msg.othersMinor() == CMMsg.TYP_ENTER))\n\t\t\t\t&& (CMLib.flags().canSenseEnteringLeaving(srcM, this)))\n\t\t\t\t{\n\t\t\t\t\ttell(srcM, msg.target(), msg.tool(), msg.othersMessage());\n\t\t\t\t\tif ((mySession != null)\n\t\t\t\t\t&& (msg.othersMinor() == CMMsg.TYP_ENTER)\n\t\t\t\t\t&& (mySession.getClientTelnetMode(Session.TELNET_GMCP)))\n\t\t\t\t\t\tmySession.sendGMCPEvent("room.enter", "\\"" + MiniJSON.toJSONString(srcM.Name()) + "\\"");\n\t\t\t\t}\n\t\t\t\tif ((!isMonster())\n\t\t\t\t&& (riding != null)\n\t\t\t\t&& (riding.rideBasis() == Rideable.Basis.WATER_BASED)\n\t\t\t\t&& (CMLib.dice().rollPercentage() == 1)\n\t\t\t\t&& (CMLib.dice().rollPercentage() < 10)\n\t\t\t\t&& (CMLib.flags().isWateryRoom(location()))\n\t\t\t\t&& (!CMSecurity.isDisabled(CMSecurity.DisFlag.AUTODISEASE)))\n\t\t\t\t{\n\t\t\t\t\tfinal Ability A = CMClass.getAbility("Disease_SeaSickness");\n\t\t\t\t\tif ((A != null)\n\t\t\t\t\t&& (fetchEffect(A.ID()) == null)\n\t\t\t\t\t&& (!CMSecurity.isAbilityDisabled(A.ID())))\n\t\t\t\t\t\tA.invoke(this, this, true, 0);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\tif (CMath.bset(othersMajor, CMMsg.MASK_CHANNEL))\n\t\t\t{\n\t\t\t\tfinal int channelCode = (msg.othersMinor() - CMMsg.TYP_CHANNEL);\n\t\t\t\tif ((playerStats() != null)\n\t\t\t\t&& (!this.isAttributeSet(MOB.Attrib.QUIET))\n\t\t\t\t&& (!CMath.isSet(playerStats().getChannelMask(), channelCode)))\n\t\t\t\t\ttell(srcM, msg.target(), msg.tool(), fixChannelColors(channelCode, msg.othersMessage()));\n\t\t\t}\n\t\t\telse\n\t\t\tif ((CMath.bset(othersMajor, CMMsg.MASK_SOUND)) && (!asleep) && (canhearsrc))\n\t\t\t{\n\t\t\t\tif ((msg.othersMinor() == CMMsg.TYP_SPEAK)\n\t\t\t\t&& (CMProps.getBoolVar(CMProps.Bool.INTRODUCTIONSYSTEM) || CMProps.get(mySession).getBool(CMProps.Bool.INTRODUCTIONSYSTEM)))\n\t\t\t\t\tCMLib.commands().handleIntroductions(srcM, this, msg.othersMessage());\n\t\t\t\ttell(srcM, msg.target(), msg.tool(), msg.othersMessage());\n\t\t\t}\n\t\t\telse\n\t\t\tif (othersMinor == CMMsg.TYP_AROMA)\n\t\t\t{\n\t\t\t\tif (CMLib.flags().canSmell(this))\n\t\t\t\t\ttell(srcM, msg.target(), msg.tool(), msg.othersMessage());\n\t\t\t}\n\t\t\telse\n\t\t\tif (((CMath.bset(othersMajor, CMMsg.MASK_EYES))\n\t\t\t\t|| (CMath.bset(othersMajor, CMMsg.MASK_HANDS))\n\t\t\t\t|| (CMath.bset(othersMajor, CMMsg.MASK_ALWAYS)))\n\t\t\t&& (!CMath.bset(msg.othersMajor(), CMMsg.MASK_CNTRLMSG))\n\t\t\t&& ((!asleep) && (canseesrc)))\n\t\t\t{\n\t\t\t\ttell(srcM, msg.target(), msg.tool(), msg.othersMessage());\n\t\t\t}\n\t\t\telse\n\t\t\tif (((CMath.bset(othersMajor, CMMsg.MASK_MOVE))\n\t\t\t\t|| ((CMath.bset(othersMajor, CMMsg.MASK_MOUTH))\n\t\t\t\t\t&& (!CMath.bset(othersMajor, CMMsg.MASK_SOUND))))\n\t\t\t&& (!asleep) && ((canseesrc) || (canhearsrc)))\n\t\t\t\ttell(srcM, msg.target(), msg.tool(), msg.othersMessage());\n\t\t\telse\n\t\t\tif ((msg.sourceMinor() == CMMsg.TYP_TELL)\n\t\t\t&& (msg.targetCode() == CMMsg.NO_EFFECT)) // group// tell\n\t\t\t\ttell(srcM, msg.target(), msg.tool(), msg.othersMessage());\n\n\t\t\tif (((othersMinor == CMMsg.TYP_ADVANCE) || (othersMinor == CMMsg.TYP_ENTER))\n\t\t\t&& (!isMonster())\n\t\t\t&& (location() != null)\n\t\t\t&& (location().getArea() instanceof Boardable)\n\t\t\t&& (msg.source().riding() == ((Boardable) location().getArea()).getBoardableItem())\n\t\t\t&& (CMLib.dice().rollPercentage() == 1)\n\t\t\t&& (CMLib.flags().isWateryRoom(CMLib.map().roomLocation(((Boardable) location().getArea()).getBoardableItem())))\n\t\t\t&& (CMLib.dice().rollPercentage() < 10))\n\t\t\t{\n\t\t\t\tfinal Ability A = CMClass.getAbility((CMLib.dice().rollPercentage() < 20) ? "Disease_Scurvy" : "Disease_SeaSickness");\n\t\t\t\tif ((A != null) && (fetchEffect(ID()) == null) && (!CMSecurity.isAbilityDisabled(A.ID())))\n\t\t\t\t\tA.invoke(this, this, true, 0);\n\t\t\t}\n\t\t\telse\n\t\t\tif ((othersMinor == CMMsg.TYP_DEATH) && (location() != null))\n\t\t\t\tCMLib.combat().handleObserveDeath(this, victim, msg);\n\t\t\telse\n\t\t\tif (msg.sourceMinor() == CMMsg.TYP_LIFE)\n\t\t\t\tCMLib.commands().handleObserveComesToLife(this, srcM, msg);\n\t\t}\n\n\t\t// the order here is significant (between eff and item -- see focus)\n\t\tif (numItems() > 0)\n\t\t{\n\t\t\teachItem(new EachApplicable<Item>()\n\t\t\t{\n\t\t\t\t@Override\n\t\t\t\tpublic final void apply(final Item I)\n\t\t\t\t{\n\t\t\t\t\tI.executeMsg(me, msg);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tif (numAllEffects() > 0)\n\t\t{\n\t\t\teachEffect(new EachApplicable<Ability>()\n\t\t\t{\n\t\t\t\t@Override\n\t\t\t\tpublic final void apply(final Ability A)\n\t\t\t\t{\n\t\t\t\t\tA.executeMsg(me, msg);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tfor (final Enumeration<Faction.FData> e = factions.elements(); e.hasMoreElements();)\n\t\t{\n\t\t\tfinal Faction.FData fD = e.nextElement();\n\t\t\tfD.getFaction().executeMsg(this, msg);\n\t\t\tfD.executeMsg(this, msg);\n\t\t}\n\t}\n\n\t@Override\n\tpublic void affectCharStats(final MOB affectedMob, final CharStats affectableStats)\n\t{\n\t}\n\n\t@Override\n\tpublic int getTickStatus()\n\t{\n\t\treturn tickStatus;\n\t}\n\n\t@Override\n\tpublic boolean tick(final Tickable ticking, final int tickID)\n\t{\n\t\tif (removeFromGame)\n\t\t\treturn false;\n\t\ttickStatus = Tickable.STATUS_START;\n\t\tif (tickID == Tickable.TICKID_MOB)\n\t\t{\n\t\t\tfinal boolean isMonster = isMonster();\n\t\t\tif (amDead)\n\t\t\t{\n\t\t\t\tboolean isOk = !removeFromGame;\n\t\t\t\ttickStatus = Tickable.STATUS_DEAD;\n\t\t\t\tif (isMonster)\n\t\t\t\t{\n\t\t\t\t\tif ((phyStats().rejuv() != PhyStats.NO_REJUV) && (basePhyStats().rejuv() > 0))\n\t\t\t\t\t{\n\t\t\t\t\t\tphyStats().setRejuv(phyStats().rejuv() - 1);\n\t\t\t\t\t\tif ((phyStats().rejuv() < 0) || (CMProps.getBoolVar(CMProps.Bool.MUDSHUTTINGDOWN)))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal Room startRoom = CMLib.map().getStartRoom(this);\n\t\t\t\t\t\t\tif ((startRoom == null)\n\t\t\t\t\t\t\t|| (startRoom.amDestroyed())\n\t\t\t\t\t\t\t|| (startRoom.getArea() == null)\n\t\t\t\t\t\t\t|| (startRoom.getArea().amDestroyed()))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttickStatus = Tickable.STATUS_END;\n\t\t\t\t\t\t\t\tif (soulMate() == null)\n\t\t\t\t\t\t\t\t\tdestroy();\n\t\t\t\t\t\t\t\tisOk = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif ((CMLib.flags().canNotBeCamped(this) || CMLib.flags().canNotBeCamped(startRoom))\n\t\t\t\t\t\t\t\t&& (startRoom.numPCInhabitants() > 0)\n\t\t\t\t\t\t\t\t&& (!CMLib.tracking().isAnAdminHere(startRoom, false)))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tphyStats().setRejuv(0);\n\t\t\t\t\t\t\t\t\ttickStatus = Tickable.STATUS_NOT;\n\t\t\t\t\t\t\t\t\tlastTickedTime = System.currentTimeMillis();\n\t\t\t\t\t\t\t\t\treturn isOk;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\ttickStatus = Tickable.STATUS_REBIRTH;\n\t\t\t\t\t\t\t\tcloneFix(CMClass.getMOBPrototype(ID()));\n\t\t\t\t\t\t\t\tbringToLife(startRoom, true);\n\t\t\t\t\t\t\t\tfinal Room room = location();\n\t\t\t\t\t\t\t\tif (room != null)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal Area A = room.getArea();\n\t\t\t\t\t\t\t\t\tif ((lastTickedTime < 0)\n\t\t\t\t\t\t\t\t\t&& room.getMobility()\n\t\t\t\t\t\t\t\t\t&& (A.getAreaState() != Area.State.FROZEN)\n\t\t\t\t\t\t\t\t\t&& (A.getAreaState() != Area.State.STOPPED))\n\t\t\t\t\t\t\t\t\t\tlastTickedTime = CMLib.utensils().processVariableEquipment(this, true);\n\t\t\t\t\t\t\t\t\troom.showOthers(this, null, CMMsg.MSG_OK_ACTION, L("<S-NAME> appears!"));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\ttickStatus = Tickable.STATUS_END;\n\t\t\t\t\t\tif (soulMate() == null)\n\t\t\t\t\t\t\tdestroy();\n\t\t\t\t\t\tisOk = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\ttickStatus = Tickable.STATUS_NOT;\n\t\t\t\tlastTickedTime = System.currentTimeMillis();\n\t\t\t\treturn isOk;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfinal Room R = location();\n\t\t\t\tfinal Area A = (R == null) ? null : R.getArea();\n\t\t\t\tif (isMonster && (--validChkCounter <= 0))\n\t\t\t\t{\n\t\t\t\t\tvalidChkCounter = 60;\n\t\t\t\t\tfinal String mobReport = CMLib.flags().validCheck(this);\n\t\t\t\t\tif (mobReport != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (mobReport.startsWith("*"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tCMLib.s_sleep(1);\n\t\t\t\t\t\t\tfinal Room locR = location();\n\t\t\t\t\t\t\tif ((locR == null) || (amDead) || (!locR.isInhabitant(this)))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tLog.warnOut("Killing: " + mobReport);\n\t\t\t\t\t\t\t\tkillMeDead(false);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tLog.warnOut("Destroy: " + mobReport);\n\t\t\t\t\t\t\tthis.destroy();\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif((R != getStartRoom())\n\t\t\t\t\t&&(getStartRoom() != null))\n\t\t\t\t\t{\n\t\t\t\t\t\t// if npc is not mobile, perhaps it should consider going home?\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ((R != null) && (A != null))\n\t\t\t\t{\n\t\t\t\t\tfinal CMFlagLibrary flag = CMLib.flags();\n\n\t\t\t\t\t// handle variable equipment!\n\t\t\t\t\tif ((lastTickedTime < 0)\n\t\t\t\t\t&& isMonster\n\t\t\t\t\t&& R.getMobility()\n\t\t\t\t\t&& (A.getAreaState() != Area.State.FROZEN)\n\t\t\t\t\t&& (A.getAreaState() != Area.State.STOPPED))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (lastTickedTime == -1)\n\t\t\t\t\t\t\tlastTickedTime = CMLib.utensils().processVariableEquipment(this, false);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tlastTickedTime++;\n\t\t\t\t\t}\n\n\t\t\t\t\ttickStatus = Tickable.STATUS_ALIVE;\n\n\t\t\t\t\tif ( isInCombat()\n\t\t\t\t\t&&(CMProps.getIntVar(CMProps.Int.COMBATSYSTEM) == CombatLibrary.CombatSystem.TURNBASED.ordinal()))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (CMLib.combat().doTurnBasedCombat(this, R, A))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (lastTickedTime >= 0)\n\t\t\t\t\t\t\t\tlastTickedTime = System.currentTimeMillis();\n\t\t\t\t\t\t\ttickStatus = Tickable.STATUS_NOT;\n\t\t\t\t\t\t\treturn !removeFromGame;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif (commandQueSize() == 0)\n\t\t\t\t\t\t\tsetActions(actions() - Math.floor(actions()));\n\t\t\t\t\t\tsetActions(actions() + (flag.isSitting(this) ? phyStats().speed() / 2.0 : phyStats().speed()));\n\t\t\t\t\t}\n\n\t\t\t\t\tif (!flag.isGolem(this))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!flag.canBreathe(this))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal MOB killerM = CMLib.combat().getBreatheKiller(this);\n\t\t\t\t\t\t\t// R.show(this, this, CMMsg.MSG_OK_VISUAL,\n\t\t\t\t\t\t\tCMLib.combat().postDamage(killerM, this, this, (int) Math.round(CMath.mul(Math.random(), basePhyStats().level() + 2)),\n\t\t\t\t\t\t\t\t\tCMMsg.MASK_ALWAYS | CMMsg.TYP_WATER, -1,\n\t\t\t\t\t\t\t\t\tL("^Z<T-NAME> can\'t breathe!^.^?") + CMLib.protocol().msp("choke.wav", 10));\n\t\t\t\t\t\t\trecoverTickCter = CMProps.getIntVar(CMProps.Int.RECOVERRATE)\n\t\t\t\t\t\t\t\t\t* (CharState.REAL_TICK_ADJUST_FACTOR + charStats().getStat(CharStats.STAT_RECOVERRATE5_ADJ));\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif (!flag.canBreatheHere(this, R))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal int atmo = R.getAtmosphere();\n\t\t\t\t\t\t\tif ((atmo & RawMaterial.MATERIAL_MASK) == RawMaterial.MATERIAL_LIQUID)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal MOB killerM = CMLib.combat().getBreatheKiller(this);\n\t\t\t\t\t\t\t\t// R.show(this, this, CMMsg.MSG_OK_VISUAL, );\n\t\t\t\t\t\t\t\tfinal String msgStr;\n\t\t\t\t\t\t\t\tif (!flag.isSeeable(this))\n\t\t\t\t\t\t\t\t\tmsgStr = null;\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\tmsgStr = L("^Z<T-NAME> <T-IS-ARE> drowning in @x1!^.^?", RawMaterial.CODES.NAME(atmo).toLowerCase()) + CMLib.protocol().msp("choke.wav", 10);\n\t\t\t\t\t\t\t\tCMLib.combat().postDamage(killerM, this, this, (int) Math.round(CMath.mul(Math.random(), basePhyStats().level() + 2)),\n\t\t\t\t\t\t\t\t\t\tCMMsg.MASK_ALWAYS | CMMsg.TYP_WATER, -1, msgStr);\n\t\t\t\t\t\t\t\trecoverTickCter = CMProps.getIntVar(CMProps.Int.RECOVERRATE)\n\t\t\t\t\t\t\t\t\t\t* (CharState.REAL_TICK_ADJUST_FACTOR + charStats().getStat(CharStats.STAT_RECOVERRATE5_ADJ));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal String msgStr;\n\t\t\t\t\t\t\t\tif (!flag.isSeeable(this))\n\t\t\t\t\t\t\t\t\tmsgStr = null;\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tif (atmo == 0)\n\t\t\t\t\t\t\t\t\tmsgStr = L("^Z<T-NAME> can\'t breathe!^.^?") + CMLib.protocol().msp("choke.wav", 10);\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\tmsgStr = L("^Z<T-NAME> <T-IS-ARE> choking on @x1!^.^?", RawMaterial.CODES.NAME(atmo).toLowerCase());\n\t\t\t\t\t\t\t\tfinal MOB killerM = CMLib.combat().getBreatheKiller(this);\n\t\t\t\t\t\t\t\tCMLib.combat().postDamage(killerM, this, this, (int) Math.round(CMath.mul(Math.random(), basePhyStats().level() + 2)),\n\t\t\t\t\t\t\t\t\t\tCMMsg.MASK_ALWAYS | CMMsg.TYP_GAS, -1, msgStr);\n\t\t\t\t\t\t\t\trecoverTickCter = CMProps.getIntVar(CMProps.Int.RECOVERRATE)\n\t\t\t\t\t\t\t\t\t\t* (CharState.REAL_TICK_ADJUST_FACTOR + charStats().getStat(CharStats.STAT_RECOVERRATE5_ADJ));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif ((--recoverTickCter) <= 0)\n\t\t\t\t\t{\n\t\t\t\t\t\tCMLib.combat().recoverTick(this);\n\t\t\t\t\t\trecoverTickCter = CMProps.getIntVar(CMProps.Int.RECOVERRATE)\n\t\t\t\t\t\t\t\t* (CharState.REAL_TICK_ADJUST_FACTOR + charStats().getStat(CharStats.STAT_RECOVERRATE5_ADJ));\n\t\t\t\t\t}\n\t\t\t\t\tif (!isMonster)\n\t\t\t\t\t\tCMLib.combat().expendEnergy(this, false);\n\n\t\t\t\t\tif (isInCombat())\n\t\t\t\t\t{\n\t\t\t\t\t\tif (CMProps.getIntVar(CMProps.Int.COMBATSYSTEM) == CombatLibrary.CombatSystem.DEFAULT.ordinal())\n\t\t\t\t\t\t\tsetActions(actions() + 1.0); // bonus action is employed in default system\n\t\t\t\t\t\ttickStatus = Tickable.STATUS_FIGHT;\n\t\t\t\t\t\tif ((!isMonster) && isAttributeSet(MOB.Attrib.NOBATTLESPAM) && (peaceTime > 0))\n\t\t\t\t\t\t\ttell(L("^F^<FIGHT^>You are now in combat.^</FIGHT^>^N"));\n\t\t\t\t\t\tif (CMLib.flags().canAutoAttack(this))\n\t\t\t\t\t\t\tCMLib.combat().tickCombat(this);\n\n\t\t\t\t\t\tif (!isMonster)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif (playerStats() != null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif (peaceTime > 0)\n\t\t\t\t\t\t\t\t\tplayerStats().bumpLevelCombatStat(PlayerCombatStat.COMBATS_TOTAL, basePhyStats().level(), 1);\n\t\t\t\t\t\t\t\tplayerStats().bumpLevelCombatStat(PlayerCombatStat.ROUNDS_TOTAL, basePhyStats().level(), 1);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tCMLib.combat().handleDamageSpamSummary(this);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tpeaceTime = 0;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tpeaceTime += CMProps.getTickMillis();\n\t\t\t\t\t\tif (this.isAttributeSet(MOB.Attrib.AUTODRAW)\n\t\t\t\t\t\t&& (peaceTime >= START_SHEATH_TIME)\n\t\t\t\t\t\t&& (peaceTime < END_SHEATH_TIME)\n\t\t\t\t\t\t&& (CMLib.flags().isAliveAwakeMobileUnbound(this, true)))\n\t\t\t\t\t\t\tCMLib.commands().postSheath(this, true);\n\t\t\t\t\t\tif ((!isMonster)\n\t\t\t\t\t\t&& isAttributeSet(MOB.Attrib.NOBATTLESPAM)\n\t\t\t\t\t\t&& (playerStats() != null)\n\t\t\t\t\t\t&& (playerStats().getCombatSpams().size() > 0))\n\t\t\t\t\t\t\tCMLib.combat().handleDamageSpamSummary(this);\n\t\t\t\t\t}\n\n\t\t\t\t\ttickStatus = Tickable.STATUS_OTHER;\n\t\t\t\t\tif ((!isMonster)\n\t\t\t\t\t&& (maxState().getFatigue() > Long.MIN_VALUE / 2))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (CMLib.flags().isSleeping(this))\n\t\t\t\t\t\t\tcurState().adjFatigue(-CharState.REST_PER_SLEEP, maxState());\n\t\t\t\t\t\t// rest/sit isn\'t here because fatigue is sleepiness, not exhaustion per se\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif (!CMSecurity.isAllowed(this, R, CMSecurity.SecFlag.IMMORT))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tcurState().adjFatigue(Math.round(CMProps.getTickMillis()), maxState());\n\t\t\t\t\t\t\tif (curState().getFatigue() > CharState.FATIGUED_MILLIS)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal boolean smallChance = (CMLib.dice().rollPercentage() == 1);\n\t\t\t\t\t\t\t\tif((CMLib.dice().rollPercentage() < 5)\n\t\t\t\t\t\t\t\t&&(curState().getHitPoints()>=maxState().getHitPoints())\n\t\t\t\t\t\t\t\t&&(fetchEffect("Mood")==null))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal Ability moodA = CMClass.getAbility("Mood");\n\t\t\t\t\t\t\t\t\tif (moodA != null)\n\t\t\t\t\t\t\t\t\t\tmoodA.invoke(this, new XVector<String>("SILLY"), this, true, 0);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (smallChance && (!CMSecurity.isDisabled(CMSecurity.DisFlag.AUTODISEASE)))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal Ability yawnsA = CMClass.getAbility("Disease_Yawning");\n\t\t\t\t\t\t\t\t\tif ((yawnsA != null) && (!CMSecurity.isAbilityDisabled(A.ID())))\n\t\t\t\t\t\t\t\t\t\tyawnsA.invoke(this, this, true, 0);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (smallChance && curState().getFatigue() > (CharState.FATIGUED_EXHAUSTED_MILLIS))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tR.show(this, null, CMMsg.MSG_OK_ACTION, L("<S-NAME> fall(s) asleep from exhaustion!!"));\n\t\t\t\t\t\t\t\t\tbasePhyStats().setDisposition(basePhyStats().disposition() | PhyStats.IS_SLEEPING);\n\t\t\t\t\t\t\t\t\tphyStats().setDisposition(phyStats().disposition() | PhyStats.IS_SLEEPING);\n\t\t\t\t\t\t\t\t\tif ((CMLib.dice().rollPercentage() < 10) && (!CMSecurity.isDisabled(CMSecurity.DisFlag.AUTODISEASE)))\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tfinal Ability sleepA = CMClass.getAbility("Disease_Sleepwalking");\n\t\t\t\t\t\t\t\t\t\tif ((sleepA != null) && (!CMSecurity.isAbilityDisabled(A.ID())))\n\t\t\t\t\t\t\t\t\t\t\tsleepA.invoke(this, this, true, 0);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\twhile ((!amDead()) && (!amDestroyed) && dequeCommand())\n\t\t\t\t\t{\n\t\t\t\t\t}\n\n\t\t\t\t\tif ((riding() != null) && (CMLib.map().roomLocation(riding()) != R))\n\t\t\t\t\t\tCMLib.tracking().doFallenOffCheck(this);\n\n\t\t\t\t\tif ((!isMonster) && (soulMate() == null) && (ageMinutes >= 0))\n\t\t\t\t\t{\n\t\t\t\t\t\tCMLib.coffeeTables().bump(this, CoffeeTableRow.STAT_TICKSONLINE);\n\t\t\t\t\t\tif (((++tickAgeCounter) * CMProps.getTickMillis()) >= AGE_MILLIS_THRESHOLD)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal long secondsPassed = (tickAgeCounter * CMProps.getTickMillis()) / 1000;\n\t\t\t\t\t\t\tCMLib.achievements().possiblyBumpAchievement(this, AchievementLibrary.Event.TIMEPLAYED, (int) secondsPassed, this);\n\t\t\t\t\t\t\ttickAgeCounter = 0;\n\t\t\t\t\t\t\tif (inventory != null)\n\t\t\t\t\t\t\t\tinventory.trimToSize();\n\t\t\t\t\t\t\tif (affects != null)\n\t\t\t\t\t\t\t\taffects.trimToSize();\n\t\t\t\t\t\t\tif (abilitys != null)\n\t\t\t\t\t\t\t\tabilitys.trimToSize();\n\t\t\t\t\t\t\tCMLib.commands().tickAging(this, AGE_MILLIS_THRESHOLD);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\tif (isMonster && (!isPlayer()))\n\t\t\t\t{\n\t\t\t\t\tLog.errOut("Destroying " + Name() + " because he\'s not ticking anywhere at all!");\n\t\t\t\t\tthis.destroy();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttickStatus = Tickable.STATUS_AFFECT;\n\t\t\tif (numAllEffects() > 0)\n\t\t\t{\n\t\t\t\teachEffect(new EachApplicable<Ability>()\n\t\t\t\t{\n\t\t\t\t\t@Override\n\t\t\t\t\tpublic final void apply(final Ability A)\n\t\t\t\t\t{\n\t\t\t\t\t\tif (!A.tick(ticking, tickID))\n\t\t\t\t\t\t\tA.unInvoke();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tmanaConsumeCter = CMLib.commands().tickManaConsumption(this, manaConsumeCter);\n\n\t\t\tif(triggerer.isObsolete() || (!triggerer.isDisabled()))\n\t\t\t\tCMLib.ableComponents().tickAbilityComponentTriggers(this);\n\n\t\t\ttickStatus = Tickable.STATUS_BEHAVIOR;\n\t\t\tif (numBehaviors() > 0)\n\t\t\t{\n\t\t\t\teachBehavior(new EachApplicable<Behavior>()\n\t\t\t\t{\n\t\t\t\t\t@Override\n\t\t\t\t\tpublic final void apply(final Behavior B)\n\t\t\t\t\t{\n\t\t\t\t\t\tB.tick(ticking, tickID);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\ttickStatus = Tickable.STATUS_SCRIPT;\n\t\t\tif (numScripts() > 0)\n\t\t\t{\n\t\t\t\teachScript(new EachApplicable<ScriptingEngine>()\n\t\t\t\t{\n\t\t\t\t\t@Override\n\t\t\t\t\tpublic final void apply(final ScriptingEngine S)\n\t\t\t\t\t{\n\t\t\t\t\t\tS.tick(ticking, tickID);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\t// if (isMonster) why wouldn\'t this be by players Especially?!\n\t\t\t{\n\t\t\t\tfor (final Enumeration<Faction.FData> t = factions.elements(); t.hasMoreElements();)\n\t\t\t\t{\n\t\t\t\t\tfinal Faction.FData T = t.nextElement();\n\t\t\t\t\tif (T.requiresUpdating())\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal String factionID = T.getFaction().factionID();\n\t\t\t\t\t\tfinal Faction F = CMLib.factions().getFaction(factionID);\n\t\t\t\t\t\tif (F != null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal int oldValue = T.value();\n\t\t\t\t\t\t\tF.updateFactionData(this, T);\n\t\t\t\t\t\t\tT.setValue(oldValue);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tremoveFaction(factionID);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ttickStatus = Tickable.STATUS_OTHER;\n\t\t\tfor (final Enumeration<Faction.FData> t = factions.elements(); t.hasMoreElements();)\n\t\t\t{\n\t\t\t\tfinal Faction.FData T = t.nextElement();\n\t\t\t\tT.tick(ticking, tickID);\n\t\t\t}\n\n\t\t\tfinal CharStats cStats = charStats();\n\t\t\tfinal int num = cStats.numClasses();\n\t\t\ttickStatus = Tickable.STATUS_CLASS;\n\t\t\tfor (int c = 0; c < num; c++)\n\t\t\t\tcStats.getMyClass(c).tick(ticking, tickID);\n\t\t\ttickStatus = Tickable.STATUS_RACE;\n\t\t\tcStats.getMyRace().tick(ticking, tickID);\n\t\t\ttickStatus = Tickable.STATUS_END;\n\n\t\t\tif (lastTickedTime >= 0)\n\t\t\t{\n\t\t\t\tlastTickedTime = System.currentTimeMillis();\n\t\t\t\tfor (final Tattoo tattoo : tattoos)\n\t\t\t\t{\n\t\t\t\t\tif ((tattoo != null)\n\t\t\t\t\t&& (tattoo.expirationDate() > 0)\n\t\t\t\t\t&& (lastTickedTime > tattoo.expirationDate()))\n\t\t\t\t\t\tdelTattoo(tattoo);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\ttickStatus = Tickable.STATUS_NOT;\n\t\treturn !removeFromGame;\n\t}\n\n\t@Override\n\tpublic boolean isPlayer()\n\t{\n\t\treturn playerStats != null;\n\t}\n\n\t@Override\n\tpublic boolean isMonster()\n\t{\n\t\treturn (mySession == null) || (mySession.isFake());\n\t}\n\n\t@Override\n\tpublic boolean isPossessing()\n\t{\n\t\ttry\n\t\t{\n\t\t\tfor (final Session S : CMLib.sessions().allIterable())\n\t\t\t{\n\t\t\t\tif ((S.mob() != null) && (S.mob().soulMate() == this))\n\t\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\tcatch (final Exception e)\n\t\t{\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic int compareTo(final CMObject o)\n\t{\n\t\treturn CMClass.classID(this).compareToIgnoreCase(CMClass.classID(o));\n\t}\n\n\t@Override\n\tpublic void addItem(final Item item)\n\t{\n\t\tif ((item != null) && (!item.amDestroyed()))\n\t\t{\n\t\t\titem.setOwner(this);\n\t\t\tinventory.addElement(item);\n\t\t\titem.recoverPhyStats();\n\t\t}\n\t}\n\n\t@Override\n\tpublic void addItem(final Item item, final ItemPossessor.Expire expire)\n\t{\n\t\taddItem(item);\n\t}\n\n\t@Override\n\tpublic void delItem(final Item item)\n\t{\n\t\tinventory.removeElement(item);\n\t\titem.recoverPhyStats();\n\t}\n\n\t@Override\n\tpublic void delAllItems(final boolean destroy)\n\t{\n\t\tif ((destroy) && (numItems() > 0))\n\t\t{\n\t\t\tfinal LinkedList<Item> items = new LinkedList<Item>();\n\t\t\titems.addAll(inventory);\n\t\t\tinventory.clear();\n\t\t\tfor (final Iterator<Item> i = items.descendingIterator(); i.hasNext();)\n\t\t\t{\n\t\t\t\tfinal Item I = i.next();\n\t\t\t\tif (I != null)\n\t\t\t\t{\n\t\t\t\t\t// since were deleting you AND all your peers, no need for Item to do it.\n\t\t\t\t\tI.setOwner(null);\n\t\t\t\t\tI.destroy();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tinventory.clear();\n\t}\n\n\t@Override\n\tpublic int numItems()\n\t{\n\t\treturn inventory.size();\n\t}\n\n\t@Override\n\tpublic Enumeration<Item> items()\n\t{\n\t\treturn inventory.elements();\n\t}\n\n\t@Override\n\tpublic boolean isContent(final Item I)\n\t{\n\t\treturn inventory.contains(I);\n\t}\n\n\t@Override\n\tpublic List<Item> findItems(final Item goodLocation, final String itemName)\n\t{\n\t\tif (inventory.isEmpty())\n\t\t\treturn new Vector<Item>(1);\n\t\tList<Item> items = CMLib.english().fetchAvailableItems(inventory, itemName, goodLocation, Wearable.FILTER_ANY, true);\n\t\tif (items.isEmpty())\n\t\t\titems = CMLib.english().fetchAvailableItems(inventory, itemName, goodLocation, Wearable.FILTER_ANY, false);\n\t\treturn items;\n\t}\n\n\t@Override\n\tpublic Item getItem(final int index)\n\t{\n\t\ttry\n\t\t{\n\t\t\treturn inventory.elementAt(index);\n\t\t}\n\t\tcatch (final java.lang.IndexOutOfBoundsException x)\n\t\t{\n\t\t}\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic void eachItem(final EachApplicable<Item> applier)\n\t{\n\t\tfinal List<Item> contents = this.inventory;\n\t\tif (contents != null)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tfor (int a = 0; a < contents.size(); a++)\n\t\t\t\t{\n\t\t\t\t\tfinal Item I = contents.get(a);\n\t\t\t\t\tif (I != null)\n\t\t\t\t\t{\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tapplier.apply(I);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(final Exception e)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tLog.errOut(e);\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\tcatch (final java.lang.IndexOutOfBoundsException x)\n\t\t\t{\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic Item getRandomItem()\n\t{\n\t\tif (numItems() == 0)\n\t\t\treturn null;\n\t\treturn getItem(CMLib.dice().roll(1, numItems(), -1));\n\t}\n\n\tpublic Item fetchFromInventory(final Item goodLocation, final String itemName, final Filterer<Environmental> filter, final boolean respectLocationAndWornCode)\n\t{\n\t\tif (inventory.isEmpty())\n\t\t\treturn null;\n\t\tfinal SVector<Item> inv = inventory;\n\t\tItem item = null;\n\t\tif (respectLocationAndWornCode)\n\t\t{\n\t\t\titem = CMLib.english().fetchAvailableItem(inv, itemName, goodLocation, filter, true);\n\t\t\tif (item == null)\n\t\t\t\titem = CMLib.english().fetchAvailableItem(inv, itemName, goodLocation, filter, false);\n\t\t}\n\t\telse\n\t\t{\n\t\t\titem = (Item) CMLib.english().fetchEnvironmental(inv, itemName, true);\n\t\t\tif (item == null)\n\t\t\t\titem = (Item) CMLib.english().fetchEnvironmental(inv, itemName, false);\n\t\t}\n\t\treturn item;\n\t}\n\n\t@Override\n\tpublic Item findItem(final String itemName)\n\t{\n\t\treturn fetchFromInventory(null, itemName, Wearable.FILTER_ANY, false);\n\t}\n\n\t@Override\n\tpublic Item findItem(final Item goodLocation, final String itemName)\n\t{\n\t\treturn fetchFromInventory(goodLocation, itemName, Wearable.FILTER_ANY, true);\n\t}\n\n\t@Override\n\tpublic Item fetchItem(final Item goodLocation, final Filterer<Environmental> filter, final String itemName)\n\t{\n\t\treturn fetchFromInventory(goodLocation, itemName, filter, true);\n\t}\n\n\t@SuppressWarnings({ "rawtypes", "unchecked" })\n\t@Override\n\tpublic List<Item> findItems(final String itemName)\n\t{\n\t\tif (!inventory.isEmpty())\n\t\t{\n\t\t\tList V = CMLib.english().fetchEnvironmentals(inventory, itemName, true);\n\t\t\tif ((V != null) && (!V.isEmpty()))\n\t\t\t\treturn V;\n\t\t\tV = CMLib.english().fetchEnvironmentals(inventory, itemName, false);\n\t\t\tif (V != null)\n\t\t\t\treturn V;\n\t\t}\n\t\treturn new Vector<Item>(1);\n\t}\n\n\t@Override\n\tpublic void addFollower(final MOB follower, final int order)\n\t{\n\t\tif (follower != null)\n\t\t{\n\t\t\tif (followers == null)\n\t\t\t\tfollowers = new SPairList<MOB, Short>();\n\t\t\telse\n\t\t\t{\n\t\t\t\tfor (final Pair<MOB, Short> F : followers)\n\t\t\t\t{\n\t\t\t\t\tif (F.first == follower)\n\t\t\t\t\t{\n\t\t\t\t\t\tF.second = Short.valueOf((short) order);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tfollowers.add(follower, Short.valueOf((short) order));\n\t\t}\n\t}\n\n\t@Override\n\tpublic void delFollower(final MOB follower)\n\t{\n\t\tif ((follower != null) && (followers != null))\n\t\t{\n\t\t\tfor (final Pair<MOB, Short> F : followers)\n\t\t\t{\n\t\t\t\tif (F.first == follower)\n\t\t\t\t\tfollowers.remove(F);\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic int numFollowers()\n\t{\n\t\treturn (followers == null) ? 0 : followers.size();\n\t}\n\n\tprivate static final Enumeration<Pair<MOB, Short>>\temptyFollowers\t= new EmptyEnumeration<Pair<MOB, Short>>();\n\n\t@Override\n\tpublic Enumeration<Pair<MOB, Short>> followers()\n\t{\n\t\treturn (followers == null) ? emptyFollowers : new IteratorEnumeration<Pair<MOB, Short>>(followers.iterator());\n\t}\n\n\t@Override\n\tpublic int fetchFollowerOrder(final MOB thisOne)\n\t{\n\t\tfor (final Enumeration<Pair<MOB, Short>> f = followers(); f.hasMoreElements();)\n\t\t{\n\t\t\tfinal Pair<MOB, Short> F = f.nextElement();\n\t\t\tif (F.first == thisOne)\n\t\t\t\treturn F.second.intValue();\n\t\t}\n\t\treturn -1;\n\t}\n\n\t@Override\n\tpublic MOB fetchFollower(final String named)\n\t{\n\t\tif (followers == null)\n\t\t\treturn null;\n\t\tfinal List<MOB> list = new ConvertingList<Pair<MOB, Short>, MOB>(followers, FollowerConverter);\n\t\tMOB mob = (MOB) CMLib.english().fetchEnvironmental(list, named, true);\n\t\tif (mob == null)\n\t\t\tmob = (MOB) CMLib.english().fetchEnvironmental(list, named, false);\n\t\treturn mob;\n\t}\n\n\t@Override\n\tpublic MOB fetchFollower(final int index)\n\t{\n\t\ttry\n\t\t{\n\t\t\tif (followers == null)\n\t\t\t\treturn null;\n\t\t\treturn followers.get(index).first;\n\t\t}\n\t\tcatch (final java.lang.IndexOutOfBoundsException x)\n\t\t{\n\t\t}\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic boolean isFollowedBy(final MOB thisOne)\n\t{\n\t\tfor (final Enumeration<Pair<MOB, Short>> f = followers(); f.hasMoreElements();)\n\t\t{\n\t\t\tfinal Pair<MOB, Short> F = f.nextElement();\n\t\t\tif (F.first == thisOne)\n\t\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean willFollowOrdersOf(final MOB mob)\n\t{\n\t\tif (mob != null)\n\t\t{\n\t\t\tif ((amFollowing() == mob)\n\t\t\t|| ((isMonster() && CMSecurity.isAllowed(mob, location(), CMSecurity.SecFlag.ORDER)))\n\t\t\t|| (getLiegeID().equals(mob.Name()))\n\t\t\t|| (CMLib.law().doesOwnThisProperty(mob, CMLib.map().getStartRoom(this))))\n\t\t\t\treturn true;\n\t\t\tif ((!isMonster())\n\t\t\t&& (CMSecurity.isAllowedEverywhere(mob, CMSecurity.SecFlag.ORDER))\n\t\t\t&& ((!CMSecurity.isASysOp(this)) || CMSecurity.isASysOp(mob)))\n\t\t\t\treturn true;\n\t\t\tfor (final Triad<Clan, Integer, Integer> t : CMLib.clans().findCommonRivalrousClans(this, mob))\n\t\t\t{\n\t\t\t\tfinal Clan C = t.first;\n\t\t\t\tfinal int myRole = t.second.intValue();\n\t\t\t\tfinal int hisRole = t.third.intValue();\n\t\t\t\tif ((C.getAuthority(hisRole, Clan.Function.ORDER_UNDERLINGS) != Clan.Authority.CAN_NOT_DO)\n\t\t\t\t&& (C.doesOutRank(hisRole, myRole)))\n\t\t\t\t\treturn true;\n\t\t\t\telse\n\t\t\t\tif ((isMonster())\n\t\t\t\t&& (C.getAuthority(hisRole, Clan.Function.ORDER_CONQUERED) != Clan.Authority.CAN_NOT_DO)\n\t\t\t\t&& (getStartRoom() != null))\n\t\t\t\t{\n\t\t\t\t\tfinal LegalBehavior B = CMLib.law().getLegalBehavior(getStartRoom());\n\t\t\t\t\tif ((B != null) && (mob.getClanRole(B.rulingOrganization()) != null))\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 MOB amUltimatelyFollowing()\n\t{\n\t\tFollowable<MOB> following = amFollowing;\n\t\tif (following == null)\n\t\t\treturn null;\n\t\tfinal HashSet<Followable<MOB>> seen = new HashSet<Followable<MOB>>();\n\t\twhile ((following != null)\n\t\t&& (following.amFollowing() != null)\n\t\t&& (!seen.contains(following)))\n\t\t{\n\t\t\tseen.add(following);\n\t\t\tfollowing = following.amFollowing();\n\t\t}\n\t\treturn (MOB) following;\n\t}\n\n\t@Override\n\tpublic MOB amFollowing()\n\t{\n\t\tfinal Followable<MOB> following = amFollowing;\n\t\tif (following != null)\n\t\t{\n\t\t\tif (!following.isFollowedBy(this))\n\t\t\t\tamFollowing = null;\n\t\t}\n\t\treturn (MOB) amFollowing;\n\t}\n\n\t@Override\n\tpublic void setFollowing(final MOB mob)\n\t{\n\t\tif (mob == this)\n\t\t\treturn;\n\t\tif ((amFollowing != null) && (amFollowing != mob))\n\t\t{\n\t\t\tif (amFollowing.isFollowedBy(this))\n\t\t\t\tamFollowing.delFollower(this);\n\t\t}\n\t\tif (mob != null)\n\t\t{\n\t\t\tif (!mob.isFollowedBy(this))\n\t\t\t\tmob.addFollower(this, -1);\n\t\t}\n\t\tamFollowing = mob;\n\t}\n\n\t@Override\n\tpublic Set<MOB> getRideBuddies(final Set<MOB> list)\n\t{\n\t\tif (list == null)\n\t\t\treturn list;\n\t\tif (!list.contains(this))\n\t\t\tlist.add(this);\n\t\tif (riding() != null)\n\t\t\triding().getRideBuddies(list);\n\t\treturn list;\n\t}\n\n\t@Override\n\tpublic Set<MOB> getGroupMembers(final Set<MOB> list)\n\t{\n\t\tif (list == null)\n\t\t\treturn list;\n\t\tif (!list.contains(this))\n\t\t\tlist.add(this);\n\t\tfinal MOB following = amFollowing();\n\t\tif ((following != null) && (!list.contains(following)))\n\t\t\tfollowing.getGroupMembers(list);\n\t\tfor (final Enumeration<Pair<MOB, Short>> f = followers(); f.hasMoreElements();)\n\t\t{\n\t\t\tfinal Pair<MOB, Short> F = f.nextElement();\n\t\t\tif ((F.first != null) && (!list.contains(F.first)))\n\t\t\t\tF.first.getGroupMembers(list);\n\t\t}\n\t\treturn list;\n\t}\n\n\t@SuppressWarnings("unchecked")\n\t@Override\n\tpublic Set<? extends Rider> getGroupMembersAndRideables(final Set<? extends Rider> list)\n\t{\n\t\tif (list == null)\n\t\t\treturn list;\n\t\tgetGroupMembers((Set<MOB>) list);\n\t\tfinal List<Rider> riders = new ArrayList<Rider>();\n\t\triders.addAll(list);\n\t\tint startDex = 0;\n\t\twhile (startDex < riders.size())\n\t\t{\n\t\t\tint i = startDex;\n\t\t\tstartDex = riders.size();\n\t\t\tfor (; i < riders.size(); i++)\n\t\t\t{\n\t\t\t\tfinal Rider P = riders.get(i);\n\t\t\t\tfinal Rideable Pr = P.riding();\n\t\t\t\tif ((!riders.contains(Pr)) && (Pr != null))\n\t\t\t\t\triders.add(Pr);\n\t\t\t\tif (P instanceof Rideable)\n\t\t\t\t{\n\t\t\t\t\tfor (final Enumeration<Rider> r = ((Rideable) P).riders(); r.hasMoreElements();)\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal Rider R2 = r.nextElement();\n\t\t\t\t\t\tif (!riders.contains(R2))\n\t\t\t\t\t\t\triders.add(R2);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn list;\n\t}\n\n\t@Override\n\tpublic boolean isSavable()\n\t{\n\t\tif ((!isMonster()) && (soulMate() == null))\n\t\t\treturn false;\n\t\tif (!CMLib.flags().isSavable(this))\n\t\t\treturn false;\n\t\tif (CMLib.utensils().getMobPossessingAnother(this) != null)\n\t\t\treturn false;\n\t\tfinal MOB followed = amFollowing();\n\t\tif (followed != null)\n\t\t{\n\t\t\tif (!followed.isMonster())\n\t\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic void setSavable(final boolean truefalse)\n\t{\n\t\tCMLib.flags().setSavable(this, truefalse);\n\t}\n\n\t@Override\n\tpublic MOB soulMate()\n\t{\n\t\treturn soulMate;\n\t}\n\n\t@Override\n\tpublic void setSoulMate(final MOB mob)\n\t{\n\t\tsoulMate = mob;\n\t}\n\n\t@Override\n\tpublic void addAbility(final Ability to)\n\t{\n\t\tif (to == null)\n\t\t\treturn;\n\t\tif (abilitys.find(to.ID()) != null)\n\t\t\treturn;\n\t\tabilitys.addElement(to);\n\t\ttriggerer.setObsolete();\n\t}\n\n\t@Override\n\tpublic void delAbility(final Ability to)\n\t{\n\t\tabilitys.removeElement(to);\n\t\ttriggerer.setObsolete();\n\t}\n\n\t@Override\n\tpublic void delAllAbilities()\n\t{\n\t\tabilitys.clear();\n\t\tabilityUseCache.clear();\n\t\ttriggerer.setObsolete();\n\t}\n\n\t@Override\n\tpublic int numAbilities()\n\t{\n\t\treturn abilitys.size();\n\t}\n\n\t@Override\n\tpublic Enumeration<Ability> abilities()\n\t{\n\t\treturn abilitys.elements();\n\t}\n\n\t@SuppressWarnings("unchecked")\n\t@Override\n\tpublic Enumeration<Ability> allAbilities()\n\t{\n\t\tfinal MultiListEnumeration<Ability> multi = new MultiListEnumeration<Ability>(new List[] { abilitys, charStats().getMyRace().racialAbilities(this) });\n\t\tfor (final Pair<Clan, Integer> p : clans())\n\t\t\tmulti.addEnumeration(p.first.clanAbilities(this));\n\t\treturn multi;\n\t}\n\n\t@Override\n\tpublic int numAllAbilities()\n\t{\n\t\tint size = abilitys.size() + charStats().getMyRace().racialAbilities(this).size();\n\t\tfor (final Pair<Clan, Integer> p : clans())\n\t\t\tsize += p.first.clanAbilities(this).size();\n\t\treturn size;\n\t}\n\n\t@Override\n\tpublic Ability fetchRandomAbility()\n\t{\n\t\tif (numAllAbilities() == 0)\n\t\t\treturn null;\n\t\treturn fetchAbility(CMLib.dice().roll(1, numAllAbilities(), -1));\n\t}\n\n\t@Override\n\tpublic boolean isRacialAbility(final String abilityID)\n\t{\n\t\tfinal List<Ability> racialAbilities = charStats().getMyRace().racialAbilities(this);\n\t\tif (racialAbilities.size() == 0)\n\t\t\treturn false;\n\t\tfor (int i = 0; i < racialAbilities.size(); i++)\n\t\t{\n\t\t\tfinal Ability A = racialAbilities.get(i);\n\t\t\tif ((A != null) && (A.ID().equalsIgnoreCase(abilityID)))\n\t\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic Ability fetchAbility(int index)\n\t{\n\t\ttry\n\t\t{\n\t\t\tif (index < abilitys.size())\n\t\t\t\treturn abilitys.elementAt(index);\n\t\t\tfinal List<Ability> racialAbilities = charStats().getMyRace().racialAbilities(this);\n\t\t\tif (index < abilitys.size() + racialAbilities.size())\n\t\t\t\treturn racialAbilities.get(index - abilitys.size());\n\t\t\tindex -= (abilitys.size() + racialAbilities.size());\n\t\t\tfor (final Pair<Clan, Integer> p : clans())\n\t\t\t{\n\t\t\t\tfinal SearchIDList<Ability> list = p.first.clanAbilities(this);\n\t\t\t\tif (index < list.size())\n\t\t\t\t\treturn list.get(index);\n\t\t\t\tindex -= list.size();\n\t\t\t}\n\t\t}\n\t\tcatch (final java.lang.IndexOutOfBoundsException x)\n\t\t{\n\t\t}\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic Ability fetchAbility(final String ID)\n\t{\n\t\tAbility A = abilitys.find(ID);\n\t\tif (A != null)\n\t\t\treturn A;\n\t\tif (clans.size() > 0)\n\t\t{\n\t\t\tfor (final Pair<Clan, Integer> p : clans())\n\t\t\t{\n\t\t\t\tA = p.first.clanAbilities(this).find(ID);\n\t\t\t\tif (A != null)\n\t\t\t\t\treturn A;\n\t\t\t}\n\t\t}\n\t\treturn charStats().getMyRace().racialAbilities(this).find(ID);\n\t}\n\n\t@Override\n\tpublic Ability findAbility(final String ID)\n\t{\n\t\tfinal Race R = charStats().getMyRace();\n\t\tAbility A = (Ability) CMLib.english().fetchEnvironmental(abilitys, ID, true);\n\t\tif (A == null)\n\t\t\tA = (Ability) CMLib.english().fetchEnvironmental(R.racialAbilities(this), ID, true);\n\t\tif (A == null)\n\t\t{\n\t\t\tfor (final Pair<Clan, Integer> p : clans())\n\t\t\t{\n\t\t\t\tA = (Ability) CMLib.english().fetchEnvironmental(p.first.clanAbilities(this), ID, true);\n\t\t\t\tif (A != null)\n\t\t\t\t\treturn A;\n\t\t\t}\n\t\t}\n\t\tif (A == null)\n\t\t\tA = (Ability) CMLib.english().fetchEnvironmental(abilitys, ID, false);\n\t\tif (A == null)\n\t\t\tA = (Ability) CMLib.english().fetchEnvironmental(R.racialAbilities(this), ID, false);\n\t\tif (A == null)\n\t\t{\n\t\t\tfor (final Pair<Clan, Integer> p : clans())\n\t\t\t{\n\t\t\t\tA = (Ability) CMLib.english().fetchEnvironmental(p.first.clanAbilities(this), ID, false);\n\t\t\t\tif (A != null)\n\t\t\t\t\treturn A;\n\t\t\t}\n\t\t}\n\t\tif (A == null)\n\t\t\tA = fetchAbility(ID);\n\t\treturn A;\n\t}\n\n\tprotected final List<Ability> racialEffects()\n\t{\n\t\tif (racialAffects == null)\n\t\t\tracialAffects = charStats.getMyRace().racialEffects(this);\n\t\treturn racialAffects;\n\t}\n\n\tprotected final List<Ability> clanEffects()\n\t{\n\t\tList<Ability> affects = clanAffects;\n\t\tif (affects == null)\n\t\t{\n\t\t\tfinal Iterator<Pair<Clan, Integer>> c = clans().iterator();\n\t\t\tif (!c.hasNext())\n\t\t\t\taffects = CMLib.clans().getDefaultGovernment().getClanLevelEffects(this, null, null);\n\t\t\telse\n\t\t\t{\n\t\t\t\tfinal ReadOnlyMultiList<Ability> effects = new ReadOnlyMultiList<Ability>();\n\t\t\t\tfor (; c.hasNext();)\n\t\t\t\t\teffects.addList(c.next().first.clanEffects(this));\n\t\t\t\taffects = effects;\n\t\t\t}\n\t\t\tclanAffects = affects;\n\t\t}\n\t\treturn affects;\n\t}\n\n\t@Override\n\tpublic Iterable<Pair<Clan, Integer>> clans()\n\t{\n\t\treturn this.clans;\n\t}\n\n\t@Override\n\tpublic Pair<Clan, Integer> getClanRole(final String clanID)\n\t{\n\t\tif ((clanID == null) || (clanID.length() == 0))\n\t\t\treturn null;\n\t\treturn clans.get(clanID);\n\t}\n\n\t@Override\n\tpublic void setClan(final String clanID, final int role)\n\t{\n\t\tif ((clanID == null) || (clanID.length() == 0))\n\t\t{\n\t\t\tif (role == Integer.MIN_VALUE)\n\t\t\t{\n\t\t\t\tclans.clear();\n\t\t\t\tclanAffects = null;\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tif (role < 0)\n\t\t{\n\t\t\tfinal Pair<Clan, Integer> p = clans.get(clanID);\n\t\t\tif (p != null)\n\t\t\t{\n\t\t\t\tclans.remove(clanID);\n\t\t\t\tclanAffects = null;\n\t\t\t\tif ((isPlayer()) && CMSecurity.isDebugging(CMSecurity.DbgFlag.CLANMEMBERS))\n\t\t\t\t\tLog.debugOut("User \'" + Name() + "\' had membership in \'" + clanID + "\' negated");\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tPair<Clan, Integer> p = clans.get(clanID);\n\t\t\tif (p == null)\n\t\t\t{\n\t\t\t\tfinal Clan C = CMLib.clans().getClanAnyHost(clanID);\n\t\t\t\tif (C == null)\n\t\t\t\t\tLog.errOut("StdMOB", "Unknown clan: " + clanID + " on " + Name() + " in " + CMLib.map().getDescriptiveExtendedRoomID(location()));\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tp = new Pair<Clan, Integer>(C, Integer.valueOf(role));\n\t\t\t\t\tclans.put(clanID, p);\n\t\t\t\t\tclanAffects = null;\n\t\t\t\t\tif ((isPlayer()) && CMSecurity.isDebugging(CMSecurity.DbgFlag.CLANMEMBERS))\n\t\t\t\t\t\tLog.debugOut("User \'" + Name() + "\' had membership in \'" + clanID + "\' added with role " + role);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif (p.second.intValue() != role)\n\t\t\t\t{\n\t\t\t\t\tif ((isPlayer()) && CMSecurity.isDebugging(CMSecurity.DbgFlag.CLANMEMBERS))\n\t\t\t\t\t\tLog.debugOut("User \'" + Name() + "\' had membership in \'" + clanID + "\' changed from " + p.second.toString() + " to role " + role);\n\t\t\t\t\tp.second = Integer.valueOf(role);\n\t\t\t\t}\n\t\t\t\tclans.put(clanID, p);\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic void addNonUninvokableEffect(final Ability to)\n\t{\n\t\tif (to == null)\n\t\t\treturn;\n\t\tif (fetchEffect(to.ID()) != null)\n\t\t\treturn;\n\t\tto.makeNonUninvokable();\n\t\tto.makeLongLasting();\n\t\taffects.addElement(to);\n\t\tto.setAffectedOne(this);\n\t}\n\n\t@Override\n\tpublic void addPriorityEffect(final Ability to)\n\t{\n\t\tif (to == null)\n\t\t\treturn;\n\t\tif (fetchEffect(to.ID()) != null)\n\t\t\treturn;\n\t\tif (affects.isEmpty())\n\t\t\taffects.addElement(to);\n\t\telse\n\t\t\taffects.insertElementAt(to, 0);\n\t\tto.setAffectedOne(this);\n\t}\n\n\t@Override\n\tpublic void addEffect(final Ability to)\n\t{\n\t\tif (to == null)\n\t\t\treturn;\n\t\tif (fetchEffect(to.ID()) != null)\n\t\t\treturn;\n\t\taffects.addElement(to);\n\t\tto.setAffectedOne(this);\n\t}\n\n\t@Override\n\tpublic void delEffect(final Ability to)\n\t{\n\t\tif (affects.removeElement(to))\n\t\t\tto.setAffectedOne(null);\n\t}\n\n\t@Override\n\tpublic void eachEffect(final EachApplicable<Ability> applier)\n\t{\n\t\tfinal List<Ability> affects = this.affects;\n\t\tif (affects != null)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tfor (int a = 0; a < affects.size(); a++)\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tapplier.apply(affects.get(a));\n\t\t\t\t\t}\n\t\t\t\t\tcatch(final Exception e)\n\t\t\t\t\t{\n\t\t\t\t\t\tLog.errOut(e);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (final java.lang.IndexOutOfBoundsException x)\n\t\t\t{\n\t\t\t}\n\t\t}\n\t\tfinal List<Ability> racialEffects = racialEffects();\n\t\ttry\n\t\t{\n\t\t\tif (!racialEffects.isEmpty())\n\t\t\t{\n\t\t\t\tfor (final Ability A : racialEffects)\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tapplier.apply(A);\n\t\t\t\t\t}\n\t\t\t\t\tcatch(final Exception e)\n\t\t\t\t\t{\n\t\t\t\t\t\tLog.errOut(e);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch (final java.lang.IndexOutOfBoundsException x)\n\t\t{\n\t\t}\n\t\ttry\n\t\t{\n\t\t\tif (!clans.isEmpty())\n\t\t\t{\n\t\t\t\tfor (final Ability A : clanEffects())\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tapplier.apply(A);\n\t\t\t\t\t}\n\t\t\t\t\tcatch(final Exception e)\n\t\t\t\t\t{\n\t\t\t\t\t\tLog.errOut(e);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tcatch (final java.lang.IndexOutOfBoundsException x)\n\t\t{\n\t\t}\n\t}\n\n\t@Override\n\tpublic void delAllEffects(final boolean unInvoke)\n\t{\n\t\tfor (int a = numEffects() - 1; a >= 0; a--)\n\t\t{\n\t\t\tfinal Ability A = fetchEffect(a);\n\t\t\tif (A != null)\n\t\t\t{\n\t\t\t\tif (unInvoke)\n\t\t\t\t\tA.unInvoke();\n\t\t\t\tA.setAffectedOne(null);\n\t\t\t}\n\t\t}\n\t\taffects.clear();\n\t}\n\n\t@Override\n\tpublic int numAllEffects()\n\t{\n\t\tint size = affects.size() + charStats().getMyRace().numRacialEffects(this);\n\t\tfor (final Pair<Clan, Integer> p : clans())\n\t\t\tsize += p.first.numClanEffects(this);\n\t\treturn size;\n\t}\n\n\t@Override\n\tpublic int numEffects()\n\t{\n\t\treturn affects.size();\n\t}\n\n\t@Override\n\tpublic Ability fetchEffect(final int index)\n\t{\n\t\ttry\n\t\t{\n\t\t\tif (index < affects.size())\n\t\t\t\treturn affects.elementAt(index);\n\t\t\tif (index < affects.size() + charStats().getMyRace().numRacialEffects(this))\n\t\t\t\treturn racialEffects().get(index - affects.size());\n\t\t\treturn clanEffects().get(index - affects.size() - racialEffects().size());\n\t\t}\n\t\tcatch (final java.lang.IndexOutOfBoundsException x)\n\t\t{\n\t\t}\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic Ability fetchEffect(final String ID)\n\t{\n\t\tfor (final Enumeration<Ability> a = effects(); a.hasMoreElements();)\n\t\t{\n\t\t\tfinal Ability A = a.nextElement();\n\t\t\tif (A.ID().equals(ID))\n\t\t\t\treturn A;\n\t\t}\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic Enumeration<Ability> personalEffects()\n\t{\n\t\treturn affects.elements();\n\t}\n\n\t@SuppressWarnings("unchecked")\n\t@Override\n\tpublic Enumeration<Ability> effects()\n\t{\n\t\treturn new MultiListEnumeration<Ability>(new List[] { affects, racialEffects(), clanEffects() });\n\t}\n\n\t/**\n\t * Manipulation of Behavior objects, which includes movement, speech,\n\t * spellcasting, etc, etc.\n\t */\n\t@Override\n\tpublic void addBehavior(final Behavior to)\n\t{\n\t\tif (to == null)\n\t\t\treturn;\n\t\tif (fetchBehavior(to.ID()) != null)\n\t\t\treturn;\n\t\tto.startBehavior(this);\n\t\tbehaviors.addElement(to);\n\t}\n\n\t@Override\n\tpublic void delBehavior(final Behavior to)\n\t{\n\t\tif (behaviors.removeElement(to))\n\t\t\tto.endBehavior(this);\n\t}\n\n\t@Override\n\tpublic void delAllBehaviors()\n\t{\n\t\tbehaviors.clear();\n\t}\n\n\t@Override\n\tpublic int numBehaviors()\n\t{\n\t\treturn behaviors.size();\n\t}\n\n\t@Override\n\tpublic Enumeration<Behavior> behaviors()\n\t{\n\t\treturn behaviors.elements();\n\t}\n\n\t@Override\n\tpublic Behavior fetchBehavior(final int index)\n\t{\n\t\ttry\n\t\t{\n\t\t\treturn behaviors.elementAt(index);\n\t\t}\n\t\tcatch (final java.lang.IndexOutOfBoundsException x)\n\t\t{\n\t\t}\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic Behavior fetchBehavior(final String ID)\n\t{\n\t\treturn behaviors.find(ID);\n\t}\n\n\t@Override\n\tpublic void eachBehavior(final EachApplicable<Behavior> applier)\n\t{\n\t\tfinal List<Behavior> behaviors = this.behaviors;\n\t\tif (behaviors != null)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tfor (int a = 0; a < behaviors.size(); a++)\n\t\t\t\t{\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tapplier.apply(behaviors.get(a));\n\t\t\t\t\t}\n\t\t\t\t\tcatch(final Exception e)\n\t\t\t\t\t{\n\t\t\t\t\t\tLog.errOut(e);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (final java.lang.IndexOutOfBoundsException x)\n\t\t\t{\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic int[][] getAbilityUsageCache(final String abilityID)\n\t{\n\t\tint[][] ableCache;\n\t\tsynchronized (abilityUseCache)\n\t\t{\n\t\t\tableCache = abilityUseCache.get(abilityID);\n\t\t}\n\t\tif (ableCache == null)\n\t\t{\n\t\t\tableCache = new int[Ability.CACHEINDEX_TOTAL][];\n\t\t\tabilityUseCache.put(abilityID, ableCache);\n\t\t}\n\t\tfinal CharStats charStats = charStats();\n\t\tfinal CharClass charClass = charStats.getCurrentClass();\n\t\tfinal int[] ableUseTrig;\n\t\tsynchronized (abilityUseTrig)\n\t\t{\n\t\t\tableUseTrig = this.abilityUseTrig;\n\t\t}\n\t\tif ((phyStats().level() != ableUseTrig[0])\n\t\t|| (charStats.getCurrentClassLevel() != ableUseTrig[1])\n\t\t|| (charClass.hashCode() != ableUseTrig[2]))\n\t\t{\n\t\t\tclearAbilityUsageCache();\n\t\t\tableUseTrig[0] = phyStats().level();\n\t\t\tableUseTrig[1] = charStats.getCurrentClassLevel();\n\t\t\tableUseTrig[2] = charClass.hashCode();\n\t\t}\n\t\treturn ableCache;\n\t}\n\n\tprivate void clearAbilityUsageCache()\n\t{\n\t\tArrays.fill(abilityUseTrig, 0);\n\t\tabilityUseCache.clear();\n\t}\n\n\t@Override\n\tpublic void addExpertise(final String code)\n\t{\n\t\tfinal Entry<String, Integer> p = CMath.getStringFollowedByNumber(code, true);\n\t\tfinal String key = p.getKey().toUpperCase();\n\t\tfinal Integer oldNum = expertises.get(key);\n\t\tif ((oldNum == null) || ((p.getValue() != null) && (oldNum.intValue() < p.getValue().intValue())))\n\t\t{\n\t\t\texpertises.put(key, p.getValue());\n\t\t\tclearAbilityUsageCache();\n\t\t}\n\t}\n\n\t@Override\n\tpublic void delExpertise(final String baseCode)\n\t{\n\t\tif (baseCode == null)\n\t\t{\n\t\t\tclearAbilityUsageCache();\n\t\t\treturn;\n\t\t}\n\t\tif (expertises.remove(baseCode.toUpperCase()) == null)\n\t\t{\n\t\t\tfinal Entry<String, Integer> p = CMath.getStringFollowedByNumber(baseCode, true);\n\t\t\tif (expertises.remove(p.getKey().toUpperCase()) != null)\n\t\t\t\tclearAbilityUsageCache();\n\t\t}\n\t\telse\n\t\t\tclearAbilityUsageCache();\n\t}\n\n\t@Override\n\tpublic Pair<String, Integer> fetchExpertise(final String baseCode)\n\t{\n\t\tif (baseCode == null)\n\t\t\treturn null;\n\t\tfinal Entry<String, Integer> p = CMath.getStringFollowedByNumber(baseCode, false);\n\t\tfinal String key = p.getKey().toUpperCase();\n\t\tfinal Integer num = expertises.get(key);\n\t\tif ((expertises.containsKey(key))\n\t\t&& ((num == null) || (p.getValue() == null) || (p.getValue().intValue() <= num.intValue())))\n\t\t{\n\t\t\tfinal Integer i = (p.getValue() == null) ? num : p.getValue();\n\t\t\treturn new Pair<String, Integer>(key, i);\n\t\t}\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic void delAllExpertises()\n\t{\n\t\tif (!expertises.isEmpty())\n\t\t{\n\t\t\texpertises.clear();\n\t\t\tclearAbilityUsageCache();\n\t\t}\n\t}\n\n\t@Override\n\tpublic Enumeration<String> expertises()\n\t{\n\t\treturn new Enumeration<String>()\n\t\t{\n\t\t\tfinal Iterator<Entry<String, Integer>>\ti\t= expertises.entrySet().iterator();\n\n\t\t\t@Override\n\t\t\tpublic boolean hasMoreElements()\n\t\t\t{\n\t\t\t\treturn i.hasNext();\n\t\t\t}\n\n\t\t\t@Override\n\t\t\tpublic String nextElement()\n\t\t\t{\n\t\t\t\tfinal Entry<String, Integer> s = i.next();\n\t\t\t\tif (s.getValue() == null)\n\t\t\t\t\treturn s.getKey();\n\t\t\t\treturn s.getKey() + s.getValue().toString();\n\t\t\t}\n\t\t};\n\t}\n\n\t/** Manipulation of the scripts list */\n\t@Override\n\tpublic void addScript(final ScriptingEngine S)\n\t{\n\t\tif (S == null)\n\t\t\treturn;\n\t\tif (!scripts.contains(S))\n\t\t{\n\t\t\tfor (final ScriptingEngine S2 : scripts)\n\t\t\t{\n\t\t\t\tif (S2.getScript().equalsIgnoreCase(S.getScript()))\n\t\t\t\t\treturn;\n\t\t\t}\n\t\t\tscripts.addElement(S);\n\t\t}\n\t}\n\n\t@Override\n\tpublic void delScript(final ScriptingEngine S)\n\t{\n\t\tif (S == null)\n\t\t\treturn;\n\t\tscripts.removeElement(S);\n\t}\n\n\t@Override\n\tpublic void delAllScripts()\n\t{\n\t\tscripts.clear();\n\t}\n\n\t@Override\n\tpublic int numScripts()\n\t{\n\t\treturn (scripts == null) ? 0 : scripts.size();\n\t}\n\n\tprivate static final Enumeration<ScriptingEngine>\temptyScripts\t= new EmptyEnumeration<ScriptingEngine>();\n\n\t@Override\n\tpublic Enumeration<ScriptingEngine> scripts()\n\t{\n\t\treturn (scripts == null) ? emptyScripts : scripts.elements();\n\t}\n\n\t@Override\n\tpublic ScriptingEngine fetchScript(final int x)\n\t{\n\t\ttry\n\t\t{\n\t\t\treturn scripts.elementAt(x);\n\t\t}\n\t\tcatch (final Exception e)\n\t\t{\n\t\t}\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic void eachScript(final EachApplicable<ScriptingEngine> applier)\n\t{\n\t\tfinal List<ScriptingEngine> scripts = this.scripts;\n\t\tif (scripts != null)\n\t\t{\n\t\t\ttry\n\t\t\t{\n\t\t\t\tfor (int a = 0; a < scripts.size(); a++)\n\t\t\t\t{\n\t\t\t\t\tfinal ScriptingEngine S = scripts.get(a);\n\t\t\t\t\tif (S != null)\n\t\t\t\t\t\tapplier.apply(S);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (final java.lang.IndexOutOfBoundsException x)\n\t\t\t{\n\t\t\t}\n\t\t}\n\t}\n\n\t/** Manipulation of the tatoo list */\n\t@Override\n\tpublic void addTattoo(final String of)\n\t{\n\t\tfinal Tattoo T = (Tattoo) CMClass.getCommon("DefaultTattoo");\n\t\taddTattoo(T.set(of));\n\t}\n\n\t@Override\n\tpublic void addTattoo(final String of, final int tickDown)\n\t{\n\t\tfinal Tattoo T = (Tattoo) CMClass.getCommon("DefaultTattoo");\n\t\taddTattoo(T.set(of, tickDown));\n\t}\n\n\t@Override\n\tpublic void delTattoo(final String of)\n\t{\n\t\tfinal Tattoo T = findTattoo(of);\n\t\tif (T != null)\n\t\t\ttattoos.remove(T);\n\t}\n\n\t@Override\n\tpublic void addTattoo(final Tattoo of)\n\t{\n\t\tif ((of == null)\n\t\t|| (of.getTattooName() == null)\n\t\t|| (of.getTattooName().length() == 0)\n\t\t|| findTattoo(of.getTattooName()) != null)\n\t\t\treturn;\n\t\ttattoos.addElement(of);\n\t}\n\n\t@Override\n\tpublic void delTattoo(final Tattoo of)\n\t{\n\t\tif ((of == null)\n\t\t|| (of.getTattooName() == null)\n\t\t|| (of.getTattooName().length() == 0))\n\t\t\treturn;\n\t\tfinal Tattoo tat = findTattoo(of.getTattooName());\n\t\tif (tat == null)\n\t\t\treturn;\n\t\ttattoos.remove(tat);\n\t}\n\n\t@Override\n\tpublic Enumeration<Tattoo> tattoos()\n\t{\n\t\treturn tattoos.elements();\n\t}\n\n\t@Override\n\tpublic Tattoo findTattoo(final String of)\n\t{\n\t\tif ((of == null) || (of.length() == 0))\n\t\t\treturn null;\n\t\tif (of.endsWith("*"))\n\t\t\treturn tattoos.findStartsWith(of.substring(0, of.length() - 1));\n\t\treturn tattoos.find(of.trim());\n\t}\n\n\t@Override\n\tpublic Tattoo findTattooStartsWith(final String of)\n\t{\n\t\tif ((of == null) || (of.length() == 0))\n\t\t\treturn null;\n\t\treturn tattoos.findStartsWith(of.trim());\n\t}\n\n\t/** Manipulation of the factions list */\n\t@Override\n\tpublic void addFaction(String which, int start)\n\t{\n\t\twhich = which.toUpperCase();\n\t\tfinal Faction F = CMLib.factions().getFaction(which);\n\t\tif (F == null)\n\t\t\treturn;\n\t\tif (start > F.maximum())\n\t\t\tstart = F.maximum();\n\t\tif (start < F.minimum())\n\t\t\tstart = F.minimum();\n\t\twhich = F.factionID().toUpperCase();\n\t\tFaction.FData data = factions.get(which);\n\t\tif (data == null)\n\t\t{\n\t\t\tdata = F.makeFactionData(this);\n\t\t\tfactions.put(which, data);\n\t\t}\n\t\tdata.setValue(start);\n\t}\n\n\t@Override\n\tpublic void adjustFaction(String which, final int amount)\n\t{\n\t\twhich = which.toUpperCase();\n\t\tfinal Faction F = CMLib.factions().getFaction(which);\n\t\tif (F == null)\n\t\t\treturn;\n\t\twhich = F.factionID().toUpperCase();\n\t\tif (!factions.containsKey(which))\n\t\t\taddFaction(which, amount);\n\t\telse\n\t\t\taddFaction(which, fetchFaction(which) + amount);\n\t}\n\n\t@Override\n\tpublic Enumeration<String> factions()\n\t{\n\t\treturn factions.keys();\n\t}\n\n\t@Override\n\tpublic int fetchFaction(final String which)\n\t{\n\t\tfinal Faction.FData data = factions.get(which.toUpperCase());\n\t\tif (data == null)\n\t\t\treturn Integer.MAX_VALUE;\n\t\treturn data.value();\n\t}\n\n\t@Override\n\tpublic Faction.FData fetchFactionData(final String which)\n\t{\n\t\treturn factions.get(which.toUpperCase());\n\t}\n\n\t@Override\n\tpublic void removeFaction(final String which)\n\t{\n\t\tfactions.remove(which.toUpperCase());\n\t}\n\n\t@Override\n\tpublic void copyFactions(final FactionMember source)\n\t{\n\t\tfor (final Enumeration<String> e = source.factions(); e.hasMoreElements();)\n\t\t{\n\t\t\tfinal String fID = e.nextElement();\n\t\t\taddFaction(fID, source.fetchFaction(fID));\n\t\t}\n\t}\n\n\t@Override\n\tpublic boolean hasFaction(final String which)\n\t{\n\t\tfinal Faction F = CMLib.factions().getFaction(which);\n\t\tif (F == null)\n\t\t\treturn false;\n\t\treturn factions.containsKey(F.factionID().toUpperCase());\n\t}\n\n\t@Override\n\tpublic List<String> fetchFactionRanges()\n\t{\n\t\tfinal Vector<String> V = new Vector<String>(factions.size());\n\t\tfor (final Enumeration<String> e = factions(); e.hasMoreElements();)\n\t\t{\n\t\t\tfinal Faction F = CMLib.factions().getFaction(e.nextElement());\n\t\t\tif (F == null)\n\t\t\t\tcontinue;\n\t\t\tfinal Faction.FRange FR = CMLib.factions().getRange(F.factionID(), fetchFaction(F.factionID()));\n\t\t\tif (FR != null)\n\t\t\t\tV.addElement(FR.codeName());\n\t\t}\n\t\treturn V;\n\t}\n\n\t@Override\n\tpublic int freeWearPositions(final long wornCode, final short belowLayer, final short layerAttributes)\n\t{\n\t\tint x = getWearPositions(wornCode);\n\t\tif (x <= 0)\n\t\t\treturn 0;\n\t\tfinal int maxItemsEver = CMProps.getIntVar(CMProps.Int.MAXITEMSWORN);\n\t\tfinal List<Item> allItems = fetchWornItems(Long.MIN_VALUE, belowLayer, layerAttributes);\n\t\tif ((maxItemsEver > 0) && (allItems.size() >= maxItemsEver))\n\t\t\treturn 0;\n\t\tx -= counItemsWornAt(allItems, wornCode);\n\t\tif (x <= 0)\n\t\t\treturn 0;\n\t\treturn x;\n\t}\n\n\t@Override\n\tpublic int getWearPositions(final long wornCode)\n\t{\n\t\tif ((charStats().getWearableRestrictionsBitmap() & wornCode) > 0)\n\t\t\treturn 0;\n\t\tfinal int maxPerSlot = CMProps.getIntVar(CMProps.Int.MAXWEARPERLOC);\n\t\tif (wornCode == Wearable.WORN_FLOATING_NEARBY)\n\t\t\treturn (maxPerSlot == 0) ? 6 : maxPerSlot;\n\t\tint total;\n\t\tint add = 0;\n\t\tboolean found = false;\n\t\tfor (int i = 0; i < Race.BODY_WEARGRID.length; i++)\n\t\t{\n\t\t\tif ((Race.BODY_WEARGRID[i][0] > 0) && ((Race.BODY_WEARGRID[i][0] & wornCode) == wornCode))\n\t\t\t{\n\t\t\t\tfound = true;\n\t\t\t\ttotal = charStats().getBodyPart(i);\n\t\t\t\tif (Race.BODY_WEARGRID[i][1] < 0)\n\t\t\t\t{\n\t\t\t\t\tif (total > 0)\n\t\t\t\t\t\treturn 0;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\tif (total < 1)\n\t\t\t\t\treturn 0;\n\t\t\t\telse\n\t\t\t\tif (i == Race.BODY_HAND)\n\t\t\t\t{\n\t\t\t\t\t// casting is ok here since these are all originals that fall below the int/long fall.\n\t\t\t\t\tif (wornCode > Integer.MAX_VALUE)\n\t\t\t\t\t\tadd += total;\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tswitch ((int) wornCode)\n\t\t\t\t\t\t{\n\t\t\t\t\t\tcase (int) Wearable.WORN_HANDS:\n\t\t\t\t\t\t\tif (total < 2)\n\t\t\t\t\t\t\t\tadd += 1;\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tadd += total / 2;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase (int) Wearable.WORN_WIELD:\n\t\t\t\t\t\tcase (int) Wearable.WORN_RIGHT_FINGER:\n\t\t\t\t\t\tcase (int) Wearable.WORN_RIGHT_WRIST:\n\t\t\t\t\t\t\tadd += 1;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase (int) Wearable.WORN_HELD:\n\t\t\t\t\t\tcase (int) Wearable.WORN_LEFT_FINGER:\n\t\t\t\t\t\tcase (int) Wearable.WORN_LEFT_WRIST:\n\t\t\t\t\t\t\tadd += total - 1;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tadd += total;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tfinal int num = total / ((int) Race.BODY_WEARGRID[i][1]);\n\t\t\t\t\tif (num < 1)\n\t\t\t\t\t\tadd += 1;\n\t\t\t\t\telse\n\t\t\t\t\t\tadd += num;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!found)\n\t\t\treturn 1;\n\t\tif ((add > maxPerSlot) && (maxPerSlot > 0))\n\t\t\treturn maxPerSlot;\n\t\treturn add;\n\t}\n\n\tprotected int counItemsWornAt(final List<Item> items, final long wornCode)\n\t{\n\t\tint ct = 0;\n\t\tfor (final Item thisItem : items)\n\t\t{\n\t\t\tif (thisItem.amWearingAt(wornCode))\n\t\t\t\tct++;\n\t\t}\n\t\treturn ct;\n\t}\n\n\t@Override\n\tpublic List<Item> fetchWornItems(final long wornCode, final short aboveOrAroundLayer, final short layerAttributes)\n\t{\n\t\tfinal Vector<Item> V = new Vector<Item>(); // return value\n\t\tfinal boolean equalOk = (layerAttributes & Armor.LAYERMASK_MULTIWEAR) > 0;\n\t\tfinal boolean allWorn = wornCode == Long.MIN_VALUE;\n\t\tint lay = 0;\n\t\tfor (final Enumeration<Item> i = items(); i.hasMoreElements();)\n\t\t{\n\t\t\tfinal Item thisItem = i.nextElement();\n\t\t\tif ((allWorn && (!thisItem.amWearingAt(Item.IN_INVENTORY)))\n\t\t\t|| thisItem.amWearingAt(wornCode))\n\t\t\t{\n\t\t\t\tif (thisItem instanceof Armor)\n\t\t\t\t{\n\t\t\t\t\tlay = ((Armor) thisItem).getClothingLayer();\n\t\t\t\t\tif (lay >= (aboveOrAroundLayer - 1))\n\t\t\t\t\t{\n\t\t\t\t\t\tif (((lay > aboveOrAroundLayer - 2)\n\t\t\t\t\t\t\t&& (lay < aboveOrAroundLayer + 2)\n\t\t\t\t\t\t\t&& ((!equalOk) || ((((Armor) thisItem).getLayerAttributes() & Armor.LAYERMASK_MULTIWEAR) == 0)))\n\t\t\t\t\t\t|| (lay > aboveOrAroundLayer))\n\t\t\t\t\t\t\tV.addElement(thisItem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tV.addElement(thisItem);\n\t\t\t}\n\t\t}\n\t\treturn V;\n\t}\n\n\t@Override\n\tpublic boolean hasOnlyGoldInInventory()\n\t{\n\t\tfor (int i = 0; i < numItems(); i++)\n\t\t{\n\t\t\tfinal Item I = getItem(i);\n\t\t\tif (I.amWearingAt(Wearable.IN_INVENTORY)\n\t\t\t&& ((I.container() == null) || (I.ultimateContainer(null).amWearingAt(Wearable.IN_INVENTORY)))\n\t\t\t&& (!(I instanceof Coins)))\n\t\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic Item fetchFirstWornItem(final long wornCode)\n\t{\n\t\tfor (final Enumeration<Item> i = items(); i.hasMoreElements();)\n\t\t{\n\t\t\tfinal Item thisItem = i.nextElement();\n\t\t\tif (thisItem.amWearingAt(wornCode))\n\t\t\t\treturn thisItem;\n\t\t}\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic Item fetchWieldedItem()\n\t{\n\t\tfinal WeakReference<Item> wieldRef = possWieldedItem;\n\t\tif (wieldRef != null)\n\t\t{\n\t\t\tfinal Item I = wieldRef.get();\n\t\t\tif (I == null)\n\t\t\t\treturn null;\n\t\t\tif ((I.owner() == this)\n\t\t\t&& (I.amWearingAt(Wearable.WORN_WIELD))\n\t\t\t&& (!I.amDestroyed()) && (I.container() == null))\n\t\t\t\treturn I;\n\t\t\tpossWieldedItem = null;\n\t\t}\n\t\tfor (final Enumeration<Item> i = items(); i.hasMoreElements();)\n\t\t{\n\t\t\tfinal Item I = i.nextElement();\n\t\t\tif ((I != null)\n\t\t\t&& (I.owner() == this)\n\t\t\t&& (I.amWearingAt(Wearable.WORN_WIELD))\n\t\t\t&& (I.container() == null))\n\t\t\t{\n\t\t\t\tpossWieldedItem = new WeakReference<Item>(I);\n\t\t\t\treturn I;\n\t\t\t}\n\t\t}\n\t\tpossWieldedItem = new WeakReference<Item>(null);\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic Item fetchHeldItem()\n\t{\n\t\tfinal WeakReference<Item> heldRef = possHeldItem;\n\t\tif (heldRef != null)\n\t\t{\n\t\t\tfinal Item I = heldRef.get();\n\t\t\tif (I == null)\n\t\t\t\treturn null;\n\t\t\tif ((I.owner() == this)\n\t\t\t&& (I.amWearingAt(Wearable.WORN_HELD))\n\t\t\t&& (!I.amDestroyed())\n\t\t\t&& (I.container() == null))\n\t\t\t\treturn I;\n\t\t\tpossHeldItem = null;\n\t\t}\n\t\tfor (final Enumeration<Item> i = items(); i.hasMoreElements();)\n\t\t{\n\t\t\tfinal Item I = i.nextElement();\n\t\t\tif ((I != null)\n\t\t\t&& (I.owner() == this)\n\t\t\t&& (I.amWearingAt(Wearable.WORN_HELD))\n\t\t\t&& (I.container() == null))\n\t\t\t{\n\t\t\t\tpossHeldItem = new WeakReference<Item>(I);\n\t\t\t\treturn I;\n\t\t\t}\n\t\t}\n\t\tpossHeldItem = new WeakReference<Item>(null);\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic boolean isMine(final Environmental env)\n\t{\n\t\tif (env instanceof Item)\n\t\t{\n\t\t\tif (inventory.contains(env))\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\t\telse\n\t\tif (env instanceof MOB)\n\t\t{\n\t\t\tif (isFollowedBy((MOB) env))\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\t\telse\n\t\tif (env instanceof Ability)\n\t\t{\n\t\t\tif (abilitys.find(env.ID()) == env)\n\t\t\t\treturn true;\n\t\t\tif (affects.contains(env))\n\t\t\t\treturn true;\n\t\t\treturn false;\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic void moveItemTo(final Item container, final ItemPossessor.Expire expire, final Move... moveFlags)\n\t{\n\t\tmoveItemTo(container);\n\t}\n\n\t@Override\n\tpublic void moveItemTo(final Item container)\n\t{\n\t\t// caller is responsible for recovering any env\n\t\t// stat changes!\n\t\tif (CMLib.flags().isHidden(container))\n\t\t\tcontainer.basePhyStats().setDisposition(container.basePhyStats().disposition() & ((int) PhyStats.ALLMASK - PhyStats.IS_HIDDEN));\n\n\t\t// ensure its out of its previous place\n\t\tEnvironmental owner = location();\n\t\tif (container.owner() != null)\n\t\t{\n\t\t\towner = container.owner();\n\t\t\tif (owner instanceof Room)\n\t\t\t\t((Room) owner).delItem(container);\n\t\t\telse\n\t\t\tif (owner instanceof MOB)\n\t\t\t\t((MOB) owner).delItem(container);\n\t\t}\n\t\tlocation().delItem(container);\n\n\t\tcontainer.unWear();\n\n\t\tif (!isMine(container))\n\t\t\taddItem(container);\n\t\tcontainer.recoverPhyStats();\n\n\t\tboolean nothingDone = true;\n\t\tboolean doBugFix = true;\n\t\twhile (doBugFix || !nothingDone)\n\t\t{\n\t\t\tdoBugFix = false;\n\t\t\tnothingDone = true;\n\t\t\tif (owner instanceof Room)\n\t\t\t{\n\t\t\t\tfinal Room R = (Room) owner;\n\t\t\t\tfor (final Enumeration<Item> i = R.items(); i.hasMoreElements();)\n\t\t\t\t{\n\t\t\t\t\tfinal Item thisItem = i.nextElement();\n\t\t\t\t\tif (thisItem.container() == container)\n\t\t\t\t\t{\n\t\t\t\t\t\tmoveItemTo(thisItem);\n\t\t\t\t\t\tnothingDone = false;\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\telse\n\t\t\tif (owner instanceof MOB)\n\t\t\t{\n\t\t\t\tfinal MOB M = (MOB) owner;\n\t\t\t\tfor (final Enumeration<Item> i = M.items(); i.hasMoreElements();)\n\t\t\t\t{\n\t\t\t\t\tfinal Item thisItem = i.nextElement();\n\t\t\t\t\tif (thisItem.container() == container)\n\t\t\t\t\t{\n\t\t\t\t\t\tmoveItemTo(thisItem);\n\t\t\t\t\t\tnothingDone = false;\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}\n\t}\n\n\t@Override\n\tpublic String L(final String str, final String... xs)\n\t{\n\t\treturn CMLib.lang().fullSessionTranslation(str, xs);\n\t}\n\n\tprotected static String[]\tCODES\t= { "CLASS", "LEVEL", "ABILITY", "TEXT" };\n\n\t@Override\n\tpublic String getStat(final String code)\n\t{\n\t\tswitch (getCodeNum(code))\n\t\t{\n\t\tcase 0:\n\t\t\treturn ID();\n\t\tcase 1:\n\t\t\treturn "" + basePhyStats().level();\n\t\tcase 2:\n\t\t\treturn "" + basePhyStats().ability();\n\t\tcase 3:\n\t\t\treturn text();\n\t\t}\n\t\treturn "";\n\t}\n\n\t@Override\n\tpublic void setStat(final String code, final String val)\n\t{\n\t\tswitch (getCodeNum(code))\n\t\t{\n\t\tcase 0:\n\t\t\treturn;\n\t\tcase 1:\n\t\t\tbasePhyStats().setLevel(CMath.s_parseIntExpression(val));\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tbasePhyStats().setAbility(CMath.s_parseIntExpression(val));\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tsetMiscText(val);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t@Override\n\tpublic int getSaveStatIndex()\n\t{\n\t\treturn (xtraValues == null) ? getStatCodes().length : getStatCodes().length - xtraValues.length;\n\t}\n\n\t@Override\n\tpublic String[] getStatCodes()\n\t{\n\t\treturn CODES;\n\t}\n\n\t@Override\n\tpublic boolean isStat(final String code)\n\t{\n\t\treturn CMParms.indexOf(getStatCodes(), code.toUpperCase().trim()) >= 0;\n\t}\n\n\tprotected int getCodeNum(final String code)\n\t{\n\t\tfor (int i = 0; i < CODES.length; i++)\n\t\t{\n\t\t\tif (code.equalsIgnoreCase(CODES[i]))\n\t\t\t\treturn i;\n\t\t}\n\t\treturn -1;\n\t}\n\n\t@Override\n\tpublic boolean sameAs(final Environmental E)\n\t{\n\t\tif (!(E instanceof StdMOB))\n\t\t\treturn false;\n\t\tfinal String[] codes = getStatCodes();\n\t\tfor (int i = 0; i < codes.length; i++)\n\t\t{\n\t\t\tif (!E.getStat(codes[i]).equals(getStat(codes[i])))\n\t\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n}\n', 'message': '\n\ngit-svn-id: svn://192.168.1.10/public/CoffeeMud@14619 0d6f1817-ed0e-0410-87c9-987e46238f29\n', 'author_name': 'bozimmerman', 'lang': 'java'}