<NME> DefaultQuest.java <BEF> package com.planet_ink.coffee_mud.Common; import com.planet_ink.coffee_mud.core.interfaces.*; import com.planet_ink.coffee_mud.core.*; import com.planet_ink.coffee_mud.core.CMClass.CMObjectType; import com.planet_ink.coffee_mud.core.CMSecurity.DbgFlag; import com.planet_ink.coffee_mud.core.collections.*; import com.planet_ink.coffee_mud.core.exceptions.*; import com.planet_ink.coffee_mud.Abilities.interfaces.*; import com.planet_ink.coffee_mud.Areas.interfaces.*; import com.planet_ink.coffee_mud.Behaviors.interfaces.*; import com.planet_ink.coffee_mud.CharClasses.interfaces.*; import com.planet_ink.coffee_mud.Commands.interfaces.*; import com.planet_ink.coffee_mud.Common.interfaces.*; import com.planet_ink.coffee_mud.Exits.interfaces.*; import com.planet_ink.coffee_mud.Items.interfaces.*; import com.planet_ink.coffee_mud.Libraries.interfaces.*; import com.planet_ink.coffee_mud.Libraries.interfaces.XMLLibrary.XMLTag; import com.planet_ink.coffee_mud.Locales.interfaces.*; import com.planet_ink.coffee_mud.MOBS.interfaces.*; import com.planet_ink.coffee_mud.Races.interfaces.*; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicInteger; import org.mozilla.javascript.Context; import org.mozilla.javascript.ScriptableObject; /* Copyright 2003-2022 Bo Zimmerman Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ public class DefaultQuest implements Quest, Tickable, CMObject { @Override public String ID() { return "DefaultQuest"; } protected String name = ""; protected String author = ""; protected String displayName = ""; protected String startDate = ""; protected String questType = ""; protected String category = ""; protected String instructions = ""; protected int duration = 450;// about // 30 // minutes protected boolean expires = false; protected String rawScriptParameter = ""; protected boolean durable = false; protected int minWait = -1; protected int minPlayers = -1; protected String playerMask = ""; protected int runLevel = -1; protected int maxWait = -1; protected int waitRemaining = -1; protected int ticksRemaining = -1; protected long lastStartDateTime = System.currentTimeMillis(); private boolean stoppingQuest = false; protected int spawn = SPAWN_NO; private QuestState questState = new QuestState(); private boolean copy = false; public DVector internalFiles = null; private int[] resetData = null; private final AtomicBoolean suspended = new AtomicBoolean(false); protected final Map<String,Long> stepEllapsedTimes = Collections.synchronizedMap(new HashMap<String,Long>()); protected final Map<String,Long> winners = new CaselessTreeMap<Long>(); protected volatile Behavable checkAcceptHost = null; protected volatile ScriptingEngine checkAcceptEng = null; protected final Object[] objs = new Object[ScriptingEngine.SPECIAL_NUM_OBJECTS]; protected volatile int parseId = 0; protected final static AtomicInteger globalParseId = new AtomicInteger(0); // the unique name of the quest @Override public String name() { return name; } @Override public void setName(final String newName) { name = newName; } // the author of the quest @Override public String author() { return author; } @Override public void setAuthor(final String newName) { author = newName; } // the display name of the quest @Override public String displayName() { return displayName; } @Override public void setDisplayName(final String newName) { displayName = newName; } @Override public String instructions() { return instructions; } @Override public void setInstructions(final String instructions) { this.instructions = instructions; } @Override public String questTypeDesc() { return this.questType; } @Override public void setQuestTypeDesc(final String newType) { this.questType = newType; } @Override public String questCategory() { return this.category; } @Override public void setQuestCategory(final String newCat) { this.category = newCat; } protected ScriptingEngine ensureEngine() { if((checkAcceptHost == null) ||(this.checkAcceptEng==null) ||((checkAcceptHost.fetchBehavior(checkAcceptEng.ID())!=checkAcceptEng) &&(!CMParms.contains(checkAcceptHost.scripts(),checkAcceptEng)))) { for(final Iterator<List<Object>> l = questState.addons.firstIterator();l.hasNext();) { final List<Object> V = l.next(); if((V.size()>1)&&(V.get(1) instanceof ScriptingEngine)) { final Behavable B=(Behavable)V.get(0); final ScriptingEngine E=(ScriptingEngine)V.get(1); if(((B.fetchBehavior(E.ID())==E) || (CMParms.contains(B.scripts(),E))) &&(E.isFunc("DO_ACCEPT")) &&(E.isFunc("CAN_ACCEPT"))) { this.checkAcceptHost=(Behavable)V.get(0); this.checkAcceptEng=E; break; } } } } return checkAcceptEng; } @Override public boolean canAcceptQuest(final MOB mob) { if(!running() || stopping()) return false; if(mob != null) { if((playerMask() != null) &&(playerMask().length()>0) &&(!CMLib.masking().maskCheck(playerMask(), mob, true))) return false; for(final Enumeration<ScriptingEngine> e= mob.scripts();e.hasMoreElements();) { final ScriptingEngine E = e.nextElement(); if((E.defaultQuestName()!=null) &&(name().equalsIgnoreCase(E.defaultQuestName()))) return false; } } final ScriptingEngine acceptEngine = this.ensureEngine(); if(acceptEngine != null) { final Behavable B = this.checkAcceptHost; if(!(B instanceof Environmental)) return false; if(mob==null) return true; final PhysicalAgent P=(B instanceof PhysicalAgent)?(PhysicalAgent)B:mob; final MOB M=(B instanceof MOB)?(MOB)B:mob; String eval = acceptEngine.callFunc("CAN_ACCEPT", mob.Name(), P, mob, (Environmental) B, M, null, null, mob.Name(), objs); if(eval == null) return false; eval=eval.toLowerCase(); return (!eval.equals("cancel")) && (eval.length()!=0); } return false; } @Override public void acceptQuest(final MOB mob) { final ScriptingEngine acceptEng = this.ensureEngine(); if(acceptEng != null) { final Behavable B = this.checkAcceptHost; if(!(B instanceof Environmental)) return; if(mob==null) return; if(!this.canAcceptQuest(mob)) return; final PhysicalAgent P=(B instanceof PhysicalAgent)?(PhysicalAgent)B:mob; final MOB M=(B instanceof MOB)?(MOB)B:mob; acceptEng.callFunc("DO_ACCEPT", mob.Name(), P, mob, (Environmental) B, M, null, null, mob.Name(), objs); } } @Override public CMObject copyOf() { try { final Object O=this.clone(); return (CMObject)O; } catch(final CloneNotSupportedException e) { return newInstance(); } } @Override public boolean suspended() { return suspended.get(); } @Override public void setSuspended(final boolean truefalse) { suspended.set(truefalse); } @Override public CMObject newInstance() { try { return getClass().newInstance(); } catch (final Exception e) { return new DefaultQuest(); } } @Override public void initializeClass() { } @Override public Object getDesignatedObject(final String named) { final QCODES q=(QCODES)CMath.s_valueOf(QCODES.class, named.toUpperCase().trim()); if(q != null) { switch(q) { case CLASS: return ID(); case NAME: return name(); case DURATION: return "" + duration(); case WAIT: return "" + minWait(); case MINPLAYERS: return "" + minPlayers(); case PLAYERMASK: return "" + playerMask(); case RUNLEVEL: return "" + runLevel(); case DATE: return "" + startDate(); case MUDDAY: return "" + startDate(); case INTERVAL: return "" + waitInterval(); case SPAWNABLE: return SPAWN_DESCS[getSpawn()]; case DISPLAY: return displayName(); case INSTRUCTIONS: return instructions(); case PERSISTANCE: return Boolean.toString(durable); case AUTHOR: return "" + author(); case EXPIRATION: return ""+(isCopy()?duration():0); case QUESTTYPE: return questType; case CATEGORY: return category; } } return questState.getStat(named); } @Override public void internalQuestDelete() { if(isCopy()) return; if((internalFiles!=null)&&(internalFiles.size()>0)) { for(int i=0;i<internalFiles.size();i++) { final String filename=((String)internalFiles.get(i,1)).toUpperCase(); final List<String> delThese=new ArrayList<String>(); boolean foundKey=false; for(final Iterator<String> k=Resources.findResourceKeys(filename);k.hasNext();) { final String key=k.next(); if(key.startsWith("PARSEDPRG: ")&&(key.toUpperCase().endsWith(filename))) { foundKey = true; delThese.add(key); } } if(foundKey) { for(int d=0;d<delThese.size();d++) Resources.removeResource(delThese.get(d)); } } internalFiles.clear(); internalFiles=null; } } // the unique name of the quest @Override public String startDate() { return startDate; } @Override public void setStartDate(final String newDate) { final int x=newDate.indexOf('-'); if((x>0) &&(CMath.isMathExpression(newDate.substring(0,x))) &&(CMath.isMathExpression(newDate.substring(x+1)))) startDate=newDate; } @Override public void setStartMudDate(final String newDate) { setStartDate(newDate); if(startDate.equals(newDate)) startDate="MUDDAY "+startDate; } // the duration, in ticks @Override public int duration() { return duration; } @Override public void setDuration(final int newTicks) { if(duration != newTicks) { if(CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS)) Log.debugOut("QuestScript#"+parseId+" Setting duration to "+newTicks); } duration = newTicks; } @Override public void setCopy(final boolean truefalse) { copy = truefalse; } @Override public boolean isCopy() { return copy; } @Override public void setSpawn(final int spawnFlag) { spawn = (spawnFlag < 0) ? 0 : spawnFlag; } @Override public int getSpawn() { return spawn; } @Override public int minPlayers() { return minPlayers; } @Override public void setMinPlayers(final int players) { minPlayers = players; } @Override public int runLevel() { return runLevel; } @Override public void setRunLevel(final int level) { runLevel = level; } @Override public String playerMask() { return playerMask; } @Override public void setPlayerMask(final String mask) { playerMask = mask; } // the rest of the script. This may be semicolon-separated instructions, // or a LOAD command followed by the quest script path. @Override public boolean setScript(final String parm, final boolean showErrors) { if(CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS)) Log.debugOut("QuestScript#"+parseId+" Setting script "+parm.length()); rawScriptParameter=parm; name=""; author=""; displayName=""; startDate=""; duration=-1; minWait=-1; maxWait=-1; minPlayers=-1; spawn=SPAWN_NO; playerMask=""; runLevel=-1; internalFiles=null; durable=false; final List<Object> questScripts=parseLoadScripts(parm,new ArrayList<Object>(),new ArrayList<Object>(),showErrors); if(questScripts.size()==0) return false; setVars(questScripts,0); if(isCopy()) spawn=SPAWN_NO; return true; } @Override public String script() { return rawScriptParameter; } @Override public void autostartup() { if(!resetWaitRemaining(0)) CMLib.threads().deleteTick(this,Tickable.TICKID_QUEST); else if(!running()) CMLib.threads().startTickDown(this,Tickable.TICKID_QUEST,1); } @Override public void setVars(final List<?> script, final int startAtLine) { List<String> parsedLine=null; String var=null; String val=null; final List<List<String>> setScripts=CMLib.quests().getNextQuestScriptCommands(script,"SET",startAtLine); for(int v=0;v<setScripts.size();v++) { parsedLine=setScripts.get(v); if(parsedLine.size()>1) { var=parsedLine.get(1).toUpperCase(); val=CMParms.combine(parsedLine,2); if(isStat(var)) setStat(var,val); } } } @Override public StringBuffer getResourceFileData(final String named, final boolean showErrors) { int index=-1; if(internalFiles!=null) { index=internalFiles.indexOf(named.toUpperCase().trim()); if(index>=0) return (StringBuffer)internalFiles.get(index,2); } final StringBuffer buf=new CMFile(Resources.makeFileResourceName(named),null,showErrors?CMFile.FLAG_LOGERRORS:0).text(); return buf; } private void questifyScriptableBehavs(final PhysicalAgent E) { if((E==null) ||((E instanceof MOB)&&(((MOB)E).isPlayer()))) return; Behavior B=null; for(final Enumeration<Behavior> e=E.behaviors();e.hasMoreElements();) { B=e.nextElement(); if(B instanceof ScriptingEngine) ((ScriptingEngine)B).registerDefaultQuest(this); } if((E instanceof Item) &&((((Item)E).numBehaviors()>0)||(((Item)E).numScripts()>0)) &&(!CMLib.threads().isTicking(E, Tickable.TICKID_ITEM_BEHAVIOR))) { CMLib.threads().startTickDown(E,Tickable.TICKID_ITEM_BEHAVIOR,1); } } private Enumeration<Room> getAppropriateRoomSet(final QuestState q) { if(q.roomGroup!=null) return new IteratorEnumeration<Room>(q.roomGroup.iterator()); else if(q.area!=null) return q.area.getMetroMap(); return CMLib.map().rooms(); } private final Enumeration<Room> getAppropriateRoomSet(final QuestState q, final Iterable<Room> useThese) { if(useThese == null) return getAppropriateRoomSet(q); return new IteratorEnumeration<Room>(useThese.iterator()); } @SuppressWarnings({ "rawtypes", "unchecked" }) private List sortSelect(final Environmental E, final String str, List choices, final List choices0, final List choices1, final List choices2, final List choices3) { final String mname=E.name().toUpperCase(); final String mdisp=E.displayText().toUpperCase(); final String mdesc=E.description().toUpperCase(); if(str.equalsIgnoreCase("any")) { choices=choices0; choices0.add(E); } else if(mname.equalsIgnoreCase(str)) { choices=choices0; choices0.add(E); } else if(CMLib.english().containsString(mname,str)) { if((choices==null)||(choices==choices2)||(choices==choices3)) choices=choices1; choices1.add(E); } else if(CMLib.english().containsString(mdisp,str)) { if((choices==null)||(choices==choices3)) choices=choices2; choices2.add(E); } else if(CMLib.english().containsString(mdesc,str)) { if(choices==null) choices=choices3; choices3.add(E); } return choices; } private TimeClock getMysteryTimeNowFromState() { TimeClock NOW=null; if(questState.mysteryData==null) return (TimeClock)CMLib.time().globalClock().copyOf(); if((questState.mysteryData.whereAt!=null)&&(questState.mysteryData.whereAt.getArea()!=null)) NOW=(TimeClock)questState.mysteryData.whereAt.getArea().getTimeObj().copyOf(); else if((questState.mysteryData.whereHappened!=null)&&(questState.mysteryData.whereHappened.getArea()!=null)) NOW=(TimeClock)questState.mysteryData.whereHappened.getArea().getTimeObj().copyOf(); else if((questState.room!=null)&&(questState.room.getArea()!=null)) NOW=(TimeClock)questState.room.getArea().getTimeObj().copyOf(); else if(questState.area!=null) NOW=(TimeClock)questState.area.getTimeObj().copyOf(); else NOW=(TimeClock)CMLib.time().globalClock().copyOf(); return NOW; } @SuppressWarnings("unchecked") public void parseQuestScriptWArgs(final List<?> script, List<Object> args) { if(args==null) args=new ArrayList<Object>(); if(args.size()==0) parseQuestScript(script, args, -1); else { final List<Object> allArgs=new ArrayList<Object>(); for(int i=0;i<args.size();i++) { final Object O=args.get(i); if(O instanceof List) { final List<Object> V=(List<Object>)O; if(allArgs.size()==0) { for(int v=0;v<V.size();v++) allArgs.add(new XVector<Object>(V.get(v))); } else { final List<Object> allArgsCopy=new XVector<Object>(allArgs); allArgs.clear(); for(int aa=0;aa<allArgsCopy.size();aa++) { final List<Object> argSet=(List<Object>)allArgsCopy.get(aa); for(int v=0;v<V.size();v++) { final List<Object> V2=new XVector<Object>(argSet); V2.add(V.get(v)); allArgs.add(V2); } } } } else if(allArgs.size()==0) allArgs.add(new XVector<Object>(O)); else for(int aa=0;aa<allArgs.size();aa++) ((List<Object>)allArgs.get(aa)).add(O); } for(int a=0;a<allArgs.size();a++) parseQuestScript(script, (List<Object>)allArgs.get(a),-1); } } protected void errorOccurred(final QuestState q, final boolean quietFlag, final String msg) { final String prefix = CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS)?("QuestScript#"+parseId+" "):""; if(!quietFlag) Log.errOut("Quest",prefix+msg); else if(CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS)) Log.debugOut("Quest",prefix+msg); q.error=true; } private void sizeDownTo(final List<?> V, final int num) { if(num<0) return; if(num==0) V.clear(); else while(V.size()>num) V.remove(CMLib.dice().roll(1,V.size(),-1)); } protected String breakOutMaskString(final String s, final List<String> p) { String mask=""; int x=s.toUpperCase().lastIndexOf("MASK="); if(x>=0) { mask=s.substring(x+5).trim(); int i=0; while((i<p.size())&&(p.get(i).toUpperCase().indexOf("MASK=")<0)) i++; if(i<=p.size()) { final String pp=p.get(i); x=pp.toUpperCase().indexOf("MASK="); if((x>0)&&(pp.substring(0,x).trim().length()>0)) { p.set(i,pp.substring(0,x).trim()); i++; } while(i<p.size()) p.remove(i); } } return mask.trim(); } protected void filterOutThoseInUse(final List<? extends Environmental> choices, final String choicesStr, final QuestState q, final boolean isQuiet, final boolean reselect) { if((choices!=null)&&(choices.size()>0)) { final Set<String> inUseByWhom=new TreeSet<String>(); for(int c=choices.size()-1;c>=0;c--) { final Environmental E=choices.get(c); if((E instanceof Physical) && (CMLib.flags().isCloaked((Physical)E))) { final Quest Q=CMLib.quests().objectInUse(E); if((!reselect) ||(Q==null) ||(!(Q instanceof DefaultQuest)) ||(!((DefaultQuest)Q).questState.reselectable.contains(E))) choices.remove(c); } else if((!reselect)&&(!q.reselectable.contains(E))) { final Quest Q=CMLib.quests().objectInUse(E); if(Q!=null) { if((!(Q instanceof DefaultQuest)) ||(!((DefaultQuest)Q).questState.reselectable.contains(E))) { choices.remove(c); inUseByWhom.add(Q.name()); } } } } if((choices.size()==0)&&(!isQuiet)) errorOccurred(q,isQuiet,"Quest '"+name()+"', all choices were taken: '"+choicesStr+"' by: "+CMParms.toListString(inUseByWhom)+"."); } } // all internal protected List<String> parseFinalQuestScript(final List<?> script) { final List<String> finalScript=new ArrayList<String>(); for(int v=0;v<script.size();v++) { if(script.get(v) instanceof String) finalScript.add((String)script.get(v)); else if(script.get(v) instanceof List) { final int vs=v; while((v<script.size())&&(script.get(v) instanceof List)) v++; final int rnum=vs+CMLib.dice().roll(1,v-vs,-1); if(rnum<script.size()) { final List<?> V=(List<?>)script.get(rnum); for(int v2=0;v2<V.size();v2++) { if(V.get(v2) instanceof String) finalScript.add((String)V.get(v2)); } } } } return finalScript; } @SuppressWarnings("unchecked") public void parseQuestScript(List<?> script, final List<Object> args, final int startLine) { final boolean debug=CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS); parseId = DefaultQuest.globalParseId.addAndGet(1); if(debug) Log.debugOut("QuestScript#"+parseId+": Parsing '"+name()+"' from script size "+script.size()+" from line "+startLine); script=parseFinalQuestScript(script); final QuestState q; synchronized(this) { q=questState; } int vStart=startLine; if(vStart<0) vStart=0; q.done=false; if(vStart>=script.size()) return; q.startLine=vStart; for(int v=vStart;v<script.size();v++) { if(startLine>=0) q.lastLine=v; final String s=modifyStringFromArgs((String)script.get(v),args); final List<String> p=CMParms.parse(s); boolean isQuiet=q.beQuiet; boolean optional=q.isOptional; if(p.size()>0) { String cmd=p.get(0).toUpperCase(); if(debug) { final String flags=(isQuiet?"Q":"")+(optional?"P":""); Log.debugOut("QuestScript#"+parseId+": Doing command '"+cmd+"' ("+flags+") from line "+v+": "+s); } if(cmd.equals("<SCRIPT>")) { final StringBuffer jscript=new StringBuffer(""); while(((++v)<script.size()) &&(!((String)script.get(v)).trim().toUpperCase().startsWith("</SCRIPT>"))) jscript.append(((String)script.get(v))+"\n"); if(v>=script.size()) { errorOccurred(q,false,"Quest '"+name()+"', <SCRIPT> command without </SCRIPT> found."); break; } if(!CMSecurity.isApprovedJScript(jscript)) { errorOccurred(q,false,"Quest '"+name()+"', <SCRIPT> not approved. Use MODIFY JSCRIPT to approve."); break; } final Context cx = Context.enter(); try { final JScriptQuest scope = new JScriptQuest(this,q); cx.initStandardObjects(scope); scope.defineFunctionProperties(JScriptQuest.functions, JScriptQuest.class, ScriptableObject.DONTENUM); cx.evaluateString(scope, jscript.toString(),"<cmd>", 1, null); } catch(final Exception e) { errorOccurred(q,false,"Quest '"+name()+"', JScript q.error: "+e.getMessage()+"."); Context.exit(); break; } Context.exit(); continue; } if(cmd.equals("OPTIONAL")) { optional=true; if(p.size()<2) { q.isOptional=true; continue; } p.remove(0); cmd=p.get(0).toUpperCase(); if(cmd.equals("ON")||cmd.equals("OFF")) { if(cmd.equals("OFF")) optional=false; if(p.size()<2) { q.isOptional=optional; continue; } p.remove(0); cmd=p.get(0).toUpperCase(); } } if(cmd.equals("QUIET")) { if(p.size()<2) { q.beQuiet=true; continue; } isQuiet=true; p.remove(0); cmd=p.get(0).toUpperCase(); if(cmd.equals("ON")||cmd.equals("OFF")) { if(cmd.equals("OFF")) isQuiet=false; if(p.size()<2) { q.beQuiet=optional; continue; } p.remove(0); cmd=p.get(0).toUpperCase(); } } if(cmd.equals("STEP")) { q.autoStepAfterDuration=false; if((p.size()>1)&&(p.get(1).equalsIgnoreCase("BREAK"))) { q.lastLine=script.size(); q.done=true; } else if((p.size()>1)&&(p.get(1).equalsIgnoreCase("BACK"))) { if(startLine>=0) q.lastLine=q.startLine; } else if((p.size()>1)&&(p.get(1).equalsIgnoreCase("AUTO"))) { if(startLine>=0) q.lastLine=v+1; q.autoStepAfterDuration=true; } else { if(startLine>=0) q.lastLine=v+1; } return; } if(cmd.equals("RESET")) { if(q.room!=null) CMLib.map().resetRoom(q.room, true); else if(q.roomGroup!=null) { for(int r=0;r<q.roomGroup.size();r++) CMLib.map().resetRoom(q.roomGroup.get(r), true); } else if(q.area!=null) CMLib.map().resetArea(q.area); else { if(optional) continue; errorOccurred(q,false,"Quest '"+name()+"', no resettable room, roomgroup, area, or areagroup set."); break; } } else if(cmd.equals("SET")) { if(p.size()<2) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', unfound variable on set."); break; } cmd=p.get(1).toUpperCase(); if(cmd.equals("AREA")) { if(p.size()<3) { q.area=null; continue; } try { q.area = (Area) getObjectIfSpecified(p, args, 2, 0); q.envObject = q.area; continue; } catch(final CMException ex) { q.area=null; } final List<String> names=new ArrayList<String>(); final List<Area> areas=new ArrayList<Area>(); if((p.size()>3)&&(p.get(2).equalsIgnoreCase("any"))) { for(int ip=3;ip<p.size();ip++) names.add(p.get(ip)); } else names.add(CMParms.combine(p,2)); for(int n=0;n<names.size();n++) { final String areaName=names.get(n); final int oldSize=areas.size(); if(areaName.equalsIgnoreCase("any")) areas.add(CMLib.map().getRandomArea()); if(oldSize==areas.size()) { for (final Enumeration<Area> e = CMLib.map().areas(); e.hasMoreElements(); ) { final Area A2 = e.nextElement(); if (A2.Name().equalsIgnoreCase(areaName)) { areas.add(A2); break; } } } if(oldSize==areas.size()) { for(final Enumeration<Boardable> e=CMLib.map().ships();e.hasMoreElements();) { final Boardable ship=e.nextElement(); final Area A2=(ship != null) ? ship.getArea() : null; if(A2 != null) { if (A2.Name().equalsIgnoreCase(areaName)) { areas.add(A2); break; } } } } if(oldSize==areas.size()) { for(final Enumeration<Area> e=CMLib.map().areas();e.hasMoreElements();) { final Area A2=e.nextElement(); if(CMLib.english().containsString(A2.Name(),areaName)) { areas.add(A2); break; } } } if(oldSize==areas.size()) { for(final Enumeration<Boardable> e=CMLib.map().ships();e.hasMoreElements();) { final Boardable ship=e.nextElement(); final Area A2=(ship != null) ? ship.getArea() : null; if(A2 != null) { if(CMLib.english().containsString(A2.Name(),areaName)) { areas.add(A2); break; } } } } } if(areas.size()>0) q.area=areas.get(CMLib.dice().roll(1,areas.size(),-1)); if(q.area==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', unknown area '"+CMParms.combine(p,2)+"'."); break; } } else if(cmd.equals("AREAGROUP")) { q.area=null; q.roomGroup=null; if(p.size()<3) continue; final List<String> names=new ArrayList<String>(); final List<Area> areas=new ArrayList<Area>(); for(int ip=2;ip<p.size();ip++) names.add(p.get(ip)); for(int n=0;n<names.size();n++) { final String areaName=names.get(n); final int oldSize=areas.size(); if(areaName.equalsIgnoreCase("any")) areas.add(CMLib.map().getRandomArea()); final boolean addAll=areaName.equalsIgnoreCase("all"); if(oldSize==areas.size()) { if(addAll) { for (final Enumeration<Area> e = CMLib.map().areas(); e.hasMoreElements(); ) { final Area A2=e.nextElement(); if(!areas.contains(A2)) areas.add(A2); } } else { Area A2=CMLib.map().findArea(areaName); if(A2 == null) { final Boardable ship=CMLib.map().findShip(areaName, true); if(ship != null) A2=ship.getArea(); } if((A2!=null)&&(!areas.contains(A2))) areas.add(A2); } } } if(areas.size()>0) { q.roomGroup=Collections.synchronizedList(new ArrayList<Room>()); Room R=null; for (final Area A : areas) { for(final Enumeration<Room> e2=A.getMetroMap();e2.hasMoreElements();) { R=e2.nextElement(); if(!q.roomGroup.contains(R)) q.roomGroup.add(R); } } q.envObject=q.roomGroup; } else { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', unknown areas '"+CMParms.combine(p,2)+"'."); break; } } else if(cmd.equals("MOBTYPE")) { boolean reselect=false; if((p.size()>2)&&(p.get(2).equalsIgnoreCase("reselect"))) { p.remove(2); reselect=true; } if(p.size()<3) { q.mob=null; continue; } try { q.mob=(MOB)getObjectIfSpecified(p,args,2,0); } catch(final CMException ex) { q.mob=null; final List<MOB> choices=new ArrayList<MOB>(); // thread safe -- not building a group final List<String> mobTypes=CMParms.parse(CMParms.combine(p,2).toUpperCase()); for(int t=0;t<mobTypes.size();t++) { final String mobType=mobTypes.get(t); if(mobType.startsWith("-")) continue; if(q.mobGroup==null) { try { for(final Enumeration<Room> e=getAppropriateRoomSet(q);e.hasMoreElements();) { final Room R2=e.nextElement(); for(int i=0;i<R2.numInhabitants();i++) { final MOB M2=R2.fetchInhabitant(i); if((M2!=null) &&(M2.isMonster()) &&((M2.amUltimatelyFollowing()==null)||(M2.amUltimatelyFollowing().isMonster()))) { if(mobType.equalsIgnoreCase("any")) choices.add(M2); else if((CMClass.classID(M2).toUpperCase().indexOf(mobType)>=0) ||(M2.charStats().getMyRace().racialCategory().toUpperCase().indexOf(mobType)>=0) ||(M2.charStats().getMyRace().name().toUpperCase().indexOf(mobType)>=0) ||(M2.charStats().getCurrentClass().name(M2.charStats().getCurrentClassLevel()).toUpperCase().indexOf(mobType)>=0)) choices.add(M2); } } } } catch (final NoSuchElementException e) { } } else { try { for(final MOB M2 : q.mobGroup) { if((M2!=null) &&(M2.isMonster()) &&((M2.amUltimatelyFollowing()==null)||(M2.amUltimatelyFollowing().isMonster()))) { if(mobType.equalsIgnoreCase("any")) choices.add(M2); else if((CMClass.classID(M2).toUpperCase().indexOf(mobType)>=0) ||(M2.charStats().getMyRace().racialCategory().toUpperCase().indexOf(mobType)>=0) ||(M2.charStats().getMyRace().name().toUpperCase().indexOf(mobType)>=0) ||(M2.charStats().getCurrentClass().name(M2.charStats().getCurrentClassLevel()).toUpperCase().indexOf(mobType)>=0)) choices.add(M2); } } } catch (final NoSuchElementException e) { } } } for(int t=0;t<mobTypes.size();t++) { String mobType=mobTypes.get(t); if(!mobType.startsWith("-")) continue; mobType=mobType.substring(1); for(int i=choices.size()-1;i>=0;i--) { final MOB M2=choices.get(i); if((M2!=null) &&(M2.isMonster()) &&((M2.amUltimatelyFollowing()==null)||(M2.amUltimatelyFollowing().isMonster()))) { if((CMClass.classID(M2).toUpperCase().indexOf(mobType)>=0) ||(M2.charStats().getMyRace().racialCategory().toUpperCase().indexOf(mobType)>=0) ||(M2.charStats().getMyRace().name().toUpperCase().indexOf(mobType)>=0) ||(M2.charStats().getCurrentClass().name(M2.charStats().getCurrentClassLevel()).toUpperCase().indexOf(mobType)>=0) ||(M2.name().toUpperCase().indexOf(mobType)>=0) ||(M2.displayText().toUpperCase().indexOf(mobType)>=0)) choices.remove(M2); } } } this.filterOutThoseInUse(choices, p.toString(), q, isQuiet, reselect); if(choices.size()>0) q.mob=choices.get(CMLib.dice().roll(1,choices.size(),-1)); } if(q.mob==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !mobtype '"+p+"'."); break; } if(reselect) q.reselectable.add(q.mob); // why is this being done -- atm, this is a simple map mob, minding his own business. questifyScriptableBehavs(q.mob); if(q.room!=null) q.room.bringMobHere(q.mob,false); else q.room=q.mob.location(); q.envObject=q.mob; runtimeRegisterObject(q.mob); if(q.room!=null) { q.area=q.room.getArea(); q.room.recoverRoomStats(); q.room.showHappens(CMMsg.MSG_OK_ACTION,null); } } else if(cmd.equals("MOBGROUP")) { q.mobGroup=null; boolean reselect=false; if((p.size()>2)&&(p.get(2).equalsIgnoreCase("reselect"))) { p.remove(2); reselect=true; } if(p.size()<3) continue; List<MOB> choices=null; String mobName=CMParms.combine(p,2).toUpperCase(); final String maskStr=breakOutMaskString(s,p); final MaskingLibrary.CompiledZMask mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr); if(mask!=null) mobName=CMParms.combine(p,2).toUpperCase(); try { choices=(List<MOB>)getObjectIfSpecified(p,args,2,1); } catch(final CMException ex) { if(mobName.length()==0) mobName="ANY"; final boolean addAll=mobName.equalsIgnoreCase("all"); final List<MOB> choices0=new ArrayList<MOB>(); final List<MOB> choices1=new ArrayList<MOB>(); final List<MOB> choices2=new ArrayList<MOB>(); final List<MOB> choices3=new ArrayList<MOB>(); try { for(final Enumeration<Room> e=getAppropriateRoomSet(q);e.hasMoreElements();) { final Room R2=e.nextElement(); for(int i=0;i<R2.numInhabitants();i++) { final MOB M2=R2.fetchInhabitant(i); if((M2!=null) &&(M2.isMonster()) &&((M2.amUltimatelyFollowing()==null)||(M2.amUltimatelyFollowing().isMonster()))) { if(CMLib.masking().maskCheck(mask,M2,true)) { if(addAll) { choices = choices0; choices.add(M2); } else choices=sortSelect(M2,mobName,choices,choices0,choices1,choices2,choices3); } } } } } catch (final NoSuchElementException e) { } this.filterOutThoseInUse(choices, p.toString(), q, isQuiet, reselect); } if((choices!=null)&&(choices.size()>0)) { q.mobGroup=Collections.synchronizedList(new ArrayList<MOB>(choices)); if(reselect) q.reselectable.addAll(choices); } else { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !mobgroup '"+mobName+":"+maskStr+"'."); break; } q.envObject=q.mobGroup; } else if(cmd.equals("PCMOBGROUP")) { q.mobGroup=null; boolean reselect=false; if((p.size()>2)&&(p.get(2).equalsIgnoreCase("reselect"))) { p.remove(2); reselect=true; } if(p.size()<3) continue; List<MOB> choices=null; String mobName=CMParms.combine(p,2).toUpperCase(); final String maskStr=breakOutMaskString(s,p); final MaskingLibrary.CompiledZMask mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr); if(mask!=null) mobName=CMParms.combine(p,2).toUpperCase(); try { choices=(List<MOB>)getObjectIfSpecified(p,args,2,1); } catch(final CMException ex) { if(mobName.length()==0) mobName="ANY"; final boolean addAll=mobName.equalsIgnoreCase("all"); final List<MOB> choices0=new ArrayList<MOB>(); final List<MOB> choices1=new ArrayList<MOB>(); final List<MOB> choices2=new ArrayList<MOB>(); final List<MOB> choices3=new ArrayList<MOB>(); try { for(final Iterator<Session> si=CMLib.sessions().sessions();si.hasNext();) { final Session S=si.next(); final MOB M2=S.mob(); if((!S.isStopped()) &&(M2!=null) &&(CMLib.flags().isInTheGame(M2, true)) &&((q.roomGroup==null)||(q.roomGroup.contains(M2.location()))) &&((q.area==null)||(q.area==M2.location().getArea())) &&(CMLib.masking().maskCheck(mask,M2,true))) { if(addAll) { choices = choices0; choices.add(M2); } else choices=sortSelect(M2,mobName,choices,choices0,choices1,choices2,choices3); } } } catch (final NoSuchElementException e) { } this.filterOutThoseInUse(choices, p.toString(), q, isQuiet, reselect); } if((choices!=null)&&(choices.size()>0)) { q.mobGroup=Collections.synchronizedList(new ArrayList<MOB>(choices)); if(reselect) q.reselectable.addAll(choices); } else { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !mobgroup '"+mobName+":"+maskStr+"'."); break; } q.envObject=q.mobGroup; } else if(cmd.equals("ITEMGROUP")) { q.itemGroup=null; boolean reselect=false; if((p.size()>2)&&(p.get(2).equalsIgnoreCase("reselect"))) { p.remove(2); reselect=true; } if(p.size()<3) continue; List<Item> choices=null; String itemName=CMParms.combine(p,2).toUpperCase(); final String maskStr=breakOutMaskString(s,p); final MaskingLibrary.CompiledZMask mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr); if(mask!=null) itemName=CMParms.combine(p,2).toUpperCase(); try { choices=(List<Item>)getObjectIfSpecified(p,args,2,1); } catch(final CMException ex) { final List<Item> choices0=new ArrayList<Item>(); final List<Item> choices1=new ArrayList<Item>(); final List<Item> choices2=new ArrayList<Item>(); final List<Item> choices3=new ArrayList<Item>(); if(itemName.length()==0) itemName="ANY"; final boolean addAll=itemName.equalsIgnoreCase("all"); try { for(final Enumeration<Room> e=getAppropriateRoomSet(q);e.hasMoreElements();) { final Room R2=e.nextElement(); for(int i=0;i<R2.numItems();i++) { final Item I2=R2.getItem(i); if(I2!=null) { if(CMLib.masking().maskCheck(mask,I2,true)) { if(addAll) { choices = choices0; choices.add(I2); } else choices=sortSelect(I2,itemName,choices,choices0,choices1,choices2,choices3); } } } } } catch (final NoSuchElementException e) { } this.filterOutThoseInUse(choices, p.toString(), q, isQuiet, reselect); } if((choices!=null)&&(choices.size()>0)) { if(reselect) q.reselectable.addAll(choices); q.itemGroup=Collections.synchronizedList(new ArrayList<Item>(choices)); } else { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !itemgroup '"+itemName+":"+maskStr+"'."); break; } q.envObject=q.itemGroup; } else if(cmd.equals("ABILITYGROUP")) { q.abilityGroup=null; if(p.size()<3) continue; List<Ability> choices=null; String abilityName=CMParms.combine(p,2).toUpperCase(); final String maskStr=breakOutMaskString(s,p); final MaskingLibrary.CompiledZMask mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr); if(mask!=null) abilityName=CMParms.combine(p,2).toUpperCase(); try { choices=(List<Ability>)getObjectIfSpecified(p,args,2,1); } catch(final CMException ex) { final List<Ability> choices0=new ArrayList<Ability>(); final List<Ability> choices1=new ArrayList<Ability>(); final List<Ability> choices2=new ArrayList<Ability>(); final List<Ability> choices3=new ArrayList<Ability>(); if(abilityName.length()==0) abilityName="ANY"; final boolean addAll=abilityName.equalsIgnoreCase("all"); try { for(final Enumeration<Room> e=getAppropriateRoomSet(q);e.hasMoreElements();) { final Room R2=e.nextElement(); for(int i=0;i<R2.numEffects();i++) { final Ability A2=R2.fetchEffect(i); if(A2!=null) { if(CMLib.masking().maskCheck(mask,A2,true)) { if(addAll) { choices = choices0; choices.add(A2); } else choices=sortSelect(A2,abilityName,choices,choices0,choices1,choices2,choices3); } } } } } catch (final NoSuchElementException e) { } this.filterOutThoseInUse(choices, p.toString(), q, isQuiet, true); } if((choices!=null)&&(choices.size()>0)) { q.abilityGroup=Collections.synchronizedList(new ArrayList<Ability>(choices)); } else { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !abilityGroup '"+abilityName+":"+maskStr+"'."); break; } q.envObject=q.itemGroup; } else if(cmd.equals("ITEMTYPE")) { boolean reselect=false; if((p.size()>2)&&(p.get(2).equalsIgnoreCase("reselect"))) { p.remove(2); reselect=true; } if(p.size()<3) { q.item=null; continue; } try { q.item=(Item)getObjectIfSpecified(p,args,2,0); } catch(final CMException ex) { q.item=null; final List<Item> choices=new ArrayList<Item>(); final List<String> itemTypes=new ArrayList<String>(); for(int i=2;i<p.size();i++) itemTypes.add(p.get(i)); for(int t=0;t<itemTypes.size();t++) { final String itemType=itemTypes.get(t).toUpperCase(); if(itemType.startsWith("-")) continue; try { if(q.itemGroup==null) { for(final Enumeration<Room> e=getAppropriateRoomSet(q);e.hasMoreElements();) { final Room R2=e.nextElement(); for(int i=0;i<R2.numItems();i++) { final Item I2=R2.getItem(i); if((I2!=null)) { if(itemType.equalsIgnoreCase("any")) choices.add(I2); else if(CMClass.classID(I2).toUpperCase().indexOf(itemType)>=0) choices.add(I2); } } } } else { for(final Item I2 : q.itemGroup) { if((I2!=null)) { if(itemType.equalsIgnoreCase("any")) choices.add(I2); else if(CMClass.classID(I2).toUpperCase().indexOf(itemType)>=0) choices.add(I2); } } } } catch(final NoSuchElementException e) { } } for(int t=0;t<itemTypes.size();t++) { String itemType=itemTypes.get(t); if(!itemType.startsWith("-")) continue; itemType=itemType.substring(1); for(int i=choices.size()-1;i>=0;i--) { final Item I2=choices.get(i); if((CMClass.classID(I2).toUpperCase().indexOf(itemType)>=0) ||(I2.name().toUpperCase().indexOf(itemType)>=0) ||(I2.displayText().toUpperCase().indexOf(itemType)>=0)) choices.remove(I2); } } this.filterOutThoseInUse(choices, p.toString(), q, isQuiet, reselect); if(choices.size()>0) q.item=choices.get(CMLib.dice().roll(1,choices.size(),-1)); } if(q.item==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !itemtype '"+p+"'."); break; } questifyScriptableBehavs(q.item); // this really makes little sense, though is harmless if(reselect) q.reselectable.add(q.item); if(q.room!=null) q.room.moveItemTo(q.item,ItemPossessor.Expire.Never,ItemPossessor.Move.Followers); else if(q.item.owner() instanceof Room) q.room=(Room)q.item.owner(); q.envObject=q.item; if(q.room!=null) { q.area=q.room.getArea(); q.room.recoverRoomStats(); q.room.showHappens(CMMsg.MSG_OK_ACTION,null); } } else if(cmd.equals("PRESERVE")) q.preserveState=CMath.parseIntExpression(p.get(2)); else if(cmd.equals("LOCALE")||cmd.equals("LOCALEGROUP")||cmd.equals("LOCALEGROUPAROUND")) { int range=0; if(cmd.equals("LOCALE")) { try { q.room=(Room)getObjectIfSpecified(p,args,2,0); if(q.room!=null) { q.area=q.room.getArea(); q.envObject=q.room; } continue; } catch(final CMException ex) { q.room=null; } } else if(cmd.equals("LOCALEGROUPAROUND")) { q.roomGroup=null; if(p.size()<3) continue; range=CMath.parseIntExpression(p.get(2)); if(range<=0) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !localegrouparound #'"+(p.get(2)+"'.")); break; } p.remove(2); if(q.room==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', localegrouparound !room."); break; } } else { try { q.roomGroup=(List<Room>)getObjectIfSpecified(p,args,2,1); q.envObject=q.roomGroup; continue; } catch(final CMException ex) { q.roomGroup=null; } } if(p.size()<3) continue; final List<String> names=new ArrayList<String>(); if((p.size()>3)&&(p.get(2).equalsIgnoreCase("any"))) { for(int ip=3;ip<p.size();ip++) names.add(p.get(ip)); } else names.add(CMParms.combine(p,2)); final List<Room> choices=new ArrayList<Room>(); List<Room> useThese=null; if(range>0) { TrackingLibrary.TrackingFlags flags; flags = CMLib.tracking().newFlags() .plus(TrackingLibrary.TrackingFlag.AREAONLY); useThese=CMLib.tracking().getRadiantRooms(q.room,flags,range); } for(int n=0;n<names.size();n++) { final String localeName=names.get(n).toUpperCase(); try { final boolean addAll=(localeName.equalsIgnoreCase("any") ||localeName.equalsIgnoreCase("all")); for(final Enumeration<Room> r=getAppropriateRoomSet(q, useThese);r.hasMoreElements();) { final Room R2=r.nextElement(); if(addAll||CMClass.classID(R2).toUpperCase().indexOf(localeName)>=0) choices.add(R2); else { final int dom=R2.domainType(); if((dom&Room.INDOORS)>0) { if(Room.DOMAIN_INDOORS_DESCS[dom-Room.INDOORS].indexOf(localeName)>=0) choices.add(R2); } else if(Room.DOMAIN_OUTDOOR_DESCS[dom].indexOf(localeName)>=0) choices.add(R2); } } } catch(final NoSuchElementException e) { } } if(cmd.equalsIgnoreCase("LOCALEGROUP")||cmd.equalsIgnoreCase("LOCALEGROUPAROUND")) { if(choices.size()>0) q.roomGroup=Collections.synchronizedList(new ArrayList<Room>(choices)); else { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !localegroup '"+CMParms.combine(p,2)+"'."); break; } q.envObject=q.roomGroup; } else { if(choices.size()>0) q.room=choices.get(CMLib.dice().roll(1,choices.size(),-1)); if(q.room==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !locale '"+CMParms.combine(p,2)+"'."); break; } q.area=q.room.getArea(); q.envObject=q.room; } } else if(cmd.equals("ROOM")||cmd.equals("ROOMGROUP")||cmd.equals("ROOMGROUPAROUND")) { int range=0; if(cmd.equals("ROOM")) { try { q.room=(Room)getObjectIfSpecified(p,args,2,0); if(q.room!=null) { q.area=q.room.getArea(); q.envObject=q.room; } continue; } catch(final CMException ex) { q.room=null; } } else if(cmd.equals("ROOMGROUPAROUND")) { q.roomGroup=null; if(p.size()<3) continue; range=CMath.s_parseIntExpression(p.get(2)); if(range<=0) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"' roomgrouparound #'"+(p.get(2)+"'.")); break; } p.remove(2); if(q.room==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', roomgrouparound !room."); break; } } else { try { q.roomGroup=(List<Room>)getObjectIfSpecified(p,args,2,1); q.envObject=q.roomGroup; continue; } catch(final CMException ex) { q.roomGroup=null; } } if(p.size()<3) continue; List<Room> choices=null; final List<Room> choices0=new ArrayList<Room>(); final List<Room> choices1=new ArrayList<Room>(); final List<Room> choices2=new ArrayList<Room>(); final List<Room> choices3=new ArrayList<Room>(); final List<String> names=new ArrayList<String>(); final String maskStr=breakOutMaskString(s,p); final MaskingLibrary.CompiledZMask mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr); if((p.size()>3)&&(p.get(2).equalsIgnoreCase("any"))) { for(int ip=3;ip<p.size();ip++) names.add(p.get(ip)); } else names.add(CMParms.combine(p,2)); List<Room> useThese=null; if(range>0) { TrackingLibrary.TrackingFlags flags; flags = CMLib.tracking().newFlags() .plus(TrackingLibrary.TrackingFlag.AREAONLY); useThese=CMLib.tracking().getRadiantRooms(q.room,flags,range); } for(int n=0;n<names.size();n++) { final String localeName=names.get(n).toUpperCase(); try { final boolean addAll=localeName.equalsIgnoreCase("any") ||localeName.equalsIgnoreCase("all"); for(final Enumeration<Room> r=getAppropriateRoomSet(q, useThese);r.hasMoreElements();) { final Room R2=r.nextElement(); if(R2==null) continue; final String display=R2.displayText().toUpperCase(); final String desc=R2.description().toUpperCase(); if((mask!=null)&&(!CMLib.masking().maskCheck(mask,R2,true))) continue; if(addAll) { choices=choices0; choices0.add(R2); } else if(CMLib.map().getExtendedRoomID(R2).equalsIgnoreCase(localeName)) { choices=choices0; choices0.add(R2); } else if(display.equals(localeName)) { if((choices==null)||(choices==choices2)||(choices==choices3)) choices=choices1; choices1.add(R2); } else if(CMLib.english().containsString(display,localeName)) { if((choices==null)||(choices==choices3)) choices=choices2; choices2.add(R2); } else if(CMLib.english().containsString(desc,localeName)) { if(choices==null) choices=choices3; choices3.add(R2); } } } catch(final NoSuchElementException e) { } } if(cmd.equalsIgnoreCase("ROOMGROUP")||cmd.equalsIgnoreCase("ROOMGROUPAROUND")) { if((choices!=null)&&(choices.size()>0)) q.roomGroup=Collections.synchronizedList(new ArrayList<Room>(choices)); else { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !roomgroup '"+CMParms.combine(p,2)+"'."); break; } q.envObject=q.roomGroup; } else { if((choices!=null)&&(choices.size()>0)) q.room=choices.get(CMLib.dice().roll(1,choices.size(),-1)); if(q.room==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !room '"+CMParms.combine(p,2)+"'."); break; } q.area=q.room.getArea(); q.envObject=q.room; } } else if(cmd.equals("MOB")) { boolean reselect=false; if((p.size()>2)&&(p.get(2).equalsIgnoreCase("reselect"))) { p.remove(2); reselect=true; } if(p.size()<3) { q.mob=null; continue; } String mobName=CMParms.combine(p,2).toUpperCase(); final String maskStr=breakOutMaskString(s,p); final MaskingLibrary.CompiledZMask mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr); if(mask!=null) mobName=CMParms.combine(p,2).toUpperCase(); try { q.mob=(MOB)getObjectIfSpecified(p,args,2,0); } catch(final CMException ex) { q.mob=null; List<MOB> choices=null; final List<MOB> choices0=new ArrayList<MOB>(); final List<MOB> choices1=new ArrayList<MOB>(); final List<MOB> choices2=new ArrayList<MOB>(); final List<MOB> choices3=new ArrayList<MOB>(); if(mobName.length()==0) mobName="ANY"; if(q.mobGroup!=null) { for(final MOB M2 : q.mobGroup) { if((M2!=null) &&(M2.isMonster()) &&((M2.amUltimatelyFollowing()==null)||(M2.amUltimatelyFollowing().isMonster()))) { if(!CMLib.masking().maskCheck(mask,M2,true)) continue; choices=sortSelect(M2,mobName,choices,choices0,choices1,choices2,choices3); } } } else { try { for(final Enumeration<Room> e=getAppropriateRoomSet(q);e.hasMoreElements();) { final Room R2=e.nextElement(); if(R2!=null) { for(int i=0;i<R2.numInhabitants();i++) { final MOB M2=R2.fetchInhabitant(i); if((M2!=null) &&(M2.isMonster()) &&((M2.amUltimatelyFollowing()==null)||(M2.amUltimatelyFollowing().isMonster()))) { if(!CMLib.masking().maskCheck(mask,M2,true)) continue; choices=sortSelect(M2,mobName,choices,choices0,choices1,choices2,choices3); } } } } } catch(final NoSuchElementException e) { } } this.filterOutThoseInUse(choices, p.toString(), q, isQuiet, reselect); if((choices!=null)&&(choices.size()>0)) q.mob=choices.get(CMLib.dice().roll(1,choices.size(),-1)); } if(q.mob==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !mob '"+mobName+"'."); break; } if(reselect) q.reselectable.add(q.mob); questifyScriptableBehavs(q.mob); // just weird if(q.room!=null) q.room.bringMobHere(q.mob,false); else q.room=q.mob.location(); if(q.room!=null) { q.area=q.room.getArea(); q.envObject=q.mob; runtimeRegisterObject(q.mob); q.room.recoverRoomStats(); q.room.showHappens(CMMsg.MSG_OK_ACTION,null); } } else if(cmd.equals("PCMOB")) { boolean reselect=false; if((p.size()>2)&&(p.get(2).equalsIgnoreCase("reselect"))) { p.remove(2); reselect=true; } if(p.size()<3) { q.mob=null; continue; } String mobName=CMParms.combine(p,2).toUpperCase(); final String maskStr=breakOutMaskString(s,p); final MaskingLibrary.CompiledZMask mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr); if(mask!=null) mobName=CMParms.combine(p,2).toUpperCase(); try { q.mob=(MOB)getObjectIfSpecified(p,args,2,0); } catch(final CMException ex) { q.mob=null; List<MOB> choices=null; final List<MOB> choices0=new ArrayList<MOB>(); final List<MOB> choices1=new ArrayList<MOB>(); final List<MOB> choices2=new ArrayList<MOB>(); final List<MOB> choices3=new ArrayList<MOB>(); if(mobName.length()==0) mobName="ANY"; if(q.mobGroup!=null) { for(final MOB M2 : q.mobGroup) { if((M2!=null)&&(M2.isPlayer())) { if(!CMLib.masking().maskCheck(mask,M2,true)) continue; choices=sortSelect(M2,mobName,choices,choices0,choices1,choices2,choices3); } } } else { try { for(final Enumeration<Room> e=getAppropriateRoomSet(q);e.hasMoreElements();) { final Room R2=e.nextElement(); if(R2!=null) { for(int i=0;i<R2.numInhabitants();i++) { final MOB M2=R2.fetchInhabitant(i); if((M2!=null)&&(M2.isPlayer())) { if(!CMLib.masking().maskCheck(mask,M2,true)) continue; choices=sortSelect(M2,mobName,choices,choices0,choices1,choices2,choices3); } } } } } catch(final NoSuchElementException e) { } } this.filterOutThoseInUse(choices, p.toString(), q, isQuiet, reselect); if((choices!=null)&&(choices.size()>0)) q.mob=choices.get(CMLib.dice().roll(1,choices.size(),-1)); } if(q.mob==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !mob '"+mobName+"'."); break; } if(reselect) q.reselectable.add(q.mob); questifyScriptableBehavs(q.mob); // just weird if(q.room!=null) q.room.bringMobHere(q.mob,false); else q.room=q.mob.location(); if(q.room!=null) { q.area=q.room.getArea(); q.envObject=q.mob; runtimeRegisterObject(q.mob); q.room.recoverRoomStats(); q.room.showHappens(CMMsg.MSG_OK_ACTION,null); } } else if(cmd.equals("ITEM")) { boolean reselect=false; if((p.size()>2)&&(p.get(2).equalsIgnoreCase("reselect"))) { p.remove(2); reselect=true; } if(p.size()<3) { q.item=null; continue; } String itemName=CMParms.combine(p,2).toUpperCase(); final String maskStr=breakOutMaskString(s,p); final MaskingLibrary.CompiledZMask mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr); if(mask!=null) itemName=CMParms.combine(p,2).toUpperCase(); try { q.item=(Item)getObjectIfSpecified(p,args,2,0); } catch(final CMException ex) { q.item=null; List<Item> choices=null; final List<Item> choices0=new ArrayList<Item>(); final List<Item> choices1=new ArrayList<Item>(); final List<Item> choices2=new ArrayList<Item>(); final List<Item> choices3=new ArrayList<Item>(); if(itemName.trim().length()==0) itemName="ANY"; try { if(q.itemGroup!=null) { for(final Item I2 : q.itemGroup) { if(I2!=null) { if(!CMLib.masking().maskCheck(mask,I2,true)) continue; choices=sortSelect(I2,itemName,choices,choices0,choices1,choices2,choices3); } } } else { for(final Enumeration<Room> e=getAppropriateRoomSet(q);e.hasMoreElements();) { final Room R2=e.nextElement(); for(int i=0;i<R2.numItems();i++) { final Item I2=R2.getItem(i); if(I2!=null) { if(!CMLib.masking().maskCheck(mask,I2,true)) continue; choices=sortSelect(I2,itemName,choices,choices0,choices1,choices2,choices3); } } } } } catch(final NoSuchElementException e) { } this.filterOutThoseInUse(choices, p.toString(), q, isQuiet, reselect); if((choices!=null)&&(choices.size()>0)) q.item=choices.get(CMLib.dice().roll(1,choices.size(),-1)); } if(q.item==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !item '"+itemName+"'."); break; } if(reselect) q.reselectable.add(q.item); questifyScriptableBehavs(q.item); // here we go again if(q.room!=null) q.room.moveItemTo(q.item,ItemPossessor.Expire.Never,ItemPossessor.Move.Followers); else if(q.item.owner() instanceof Room) q.room=(Room)q.item.owner(); q.envObject=q.item; if(q.room!=null) { q.area=q.room.getArea(); q.room.recoverRoomStats(); q.room.showHappens(CMMsg.MSG_OK_ACTION,null); } } else if(cmd.equals("ABILITY")) { if(p.size()<3) { q.ability=null; continue; } String abilityName=CMParms.combine(p,2).toUpperCase(); final String maskStr=breakOutMaskString(s,p); final MaskingLibrary.CompiledZMask mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr); if(mask!=null) abilityName=CMParms.combine(p,2).toUpperCase(); try { q.ability=(Ability)getObjectIfSpecified(p,args,2,0); } catch(final CMException ex) { q.ability=null; List<Ability> choices=null; final List<Ability> choices0=new ArrayList<Ability>(); final List<Ability> choices1=new ArrayList<Ability>(); final List<Ability> choices2=new ArrayList<Ability>(); final List<Ability> choices3=new ArrayList<Ability>(); if(abilityName.trim().length()==0) abilityName="ANY"; try { if(q.abilityGroup!=null) { for(final Ability A2 : q.abilityGroup) { if(A2!=null) { if(!CMLib.masking().maskCheck(mask,A2,true)) continue; choices=sortSelect(A2,abilityName,choices,choices0,choices1,choices2,choices3); } } } else { for(final Enumeration<Room> e=getAppropriateRoomSet(q);e.hasMoreElements();) { final Room R2=e.nextElement(); for(int i=0;i<R2.numEffects();i++) { final Ability A2=R2.fetchEffect(i); if(A2!=null) { if(!CMLib.masking().maskCheck(mask,A2,true)) continue; choices=sortSelect(A2,abilityName,choices,choices0,choices1,choices2,choices3); } } } } } catch(final NoSuchElementException e) { } this.filterOutThoseInUse(choices, p.toString(), q, isQuiet, true); if((choices!=null)&&(choices.size()>0)) q.ability=choices.get(CMLib.dice().roll(1,choices.size(),-1)); } if(q.ability==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !ability '"+abilityName+"'."); break; } q.envObject=q.item; } else if(cmd.equals("AGENT")) { if(q.mysteryData==null) q.mysteryData=new MysteryData(); try { q.mob=(MOB)getObjectIfSpecified(p,args,2,0); } catch(final CMException ex) { if(p.size()>2) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', agent syntax '"+CMParms.combine(p,2)+"'."); break; } } if(q.mob==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', agent !mob."); break; } questifyScriptableBehavs(q.mob); // should be done to loaded or q-scripted mobs only q.mysteryData.agent=q.mob; q.mob=q.mysteryData.agent; q.envObject=q.mob; } else if(cmd.equals("FACTION")) { if(q.mysteryData==null) q.mysteryData=new MysteryData(); if(p.size()<3) continue; final String numStr=CMParms.combine(p,2); Faction F=null; try { F=(Faction)getObjectIfSpecified(p,args,2,0); } catch(final CMException ex) { if(numStr.equalsIgnoreCase("ANY")) { final int numFactions=CMLib.factions().numFactions(); final int whichFaction=CMLib.dice().roll(1,numFactions,-1); int curFaction=0; for(final Enumeration<Faction> e=CMLib.factions().factions();e.hasMoreElements();curFaction++) { F=e.nextElement(); if(curFaction==whichFaction) break; } } else { F=CMLib.factions().getFaction(numStr); if(F==null) F=CMLib.factions().getFactionByName(numStr); } } if(F==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !faction #'"+numStr+"'."); break; } q.mysteryData.faction=F; } else if(cmd.equals("FACTIONGROUP")) { if(q.mysteryData==null) q.mysteryData=new MysteryData(); if(p.size()<3) { q.mysteryData.factionGroup=null; continue; } try { q.mysteryData.factionGroup=(List<Faction>)getObjectIfSpecified(p,args,2,1); } catch(final CMException ex) { q.mysteryData.factionGroup=Collections.synchronizedList(new ArrayList<Faction>()); String numStr=CMParms.combine(p,2); Faction F=null; if(q.mysteryData.faction!=null) q.mysteryData.factionGroup.add(q.mysteryData.faction); if(CMath.isMathExpression(numStr)||numStr.equalsIgnoreCase("ALL")) { final int numFactions=CMLib.factions().numFactions(); if(numStr.equalsIgnoreCase("ALL")) numStr=""+numFactions; int num=CMath.s_parseIntExpression(numStr); if(num>=numFactions) num=numFactions; int tries=500; while((q.mysteryData.factionGroup.size()<num)&&(--tries>0)) { final int whichFaction=CMLib.dice().roll(1,numFactions,-1); int curFaction=0; for(final Enumeration<Faction> e=CMLib.factions().factions();e.hasMoreElements();curFaction++) { F=e.nextElement(); if(curFaction==whichFaction) break; } if(!q.mysteryData.factionGroup.contains(F)) q.mysteryData.factionGroup.add(F); } } else { for(int pi=2;pi<p.size();pi++) { F=CMLib.factions().getFaction(p.get(pi)); if(F==null) F=CMLib.factions().getFactionByName(p.get(pi)); if(F==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !factiongroup '"+p.get(pi)+"'."); break; } if(!q.mysteryData.factionGroup.contains(F)) q.mysteryData.factionGroup.add(F); } if(q.error) break; } } if((q.mysteryData.factionGroup!=null) &&(q.mysteryData.factionGroup.size()>0) &&(q.mysteryData.faction==null)) q.mysteryData.faction=q.mysteryData.factionGroup.get(CMLib.dice().roll(1,q.mysteryData.factionGroup.size(),-1)); } else if(cmd.equals("AGENTGROUP")) { if(q.mysteryData==null) q.mysteryData=new MysteryData(); if(p.size()<3) { q.mysteryData.agentGroup=null; continue; } try { q.mysteryData.agentGroup=(List<MOB>)getObjectIfSpecified(p,args,2,1); if((q.mysteryData.agentGroup!=null) &&(q.mysteryData.agentGroup.size()>0) &&(q.mysteryData.agent==null)) q.mysteryData.agent=q.mysteryData.agentGroup.get(CMLib.dice().roll(1,q.mysteryData.agentGroup.size(),-1)); } catch(final CMException ex) { q.mysteryData.agentGroup=null; final String numStr=CMParms.combine(p,2).toUpperCase(); if(!CMath.isMathExpression(numStr)) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !agentgroup #'"+numStr+"'."); break; } if((q.mobGroup==null)||(q.mobGroup.size()==0)) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !agentgroup mobgroup."); break; } final List<MOB> V=new ArrayList<MOB>(); V.addAll(q.mobGroup); q.mysteryData.agentGroup=Collections.synchronizedList(new ArrayList<MOB>()); if(q.mysteryData.agent!=null) q.mysteryData.agentGroup.add(q.mysteryData.agent); int num=CMath.parseIntExpression(numStr); if(num>=V.size()) num=V.size(); while((q.mysteryData.agentGroup.size()<num)&&(V.size()>0)) { final int dex=CMLib.dice().roll(1,V.size(),-1); final Object O=V.get(dex); V.remove(dex); q.mysteryData.agentGroup.add((MOB)O); if(q.mysteryData.agent==null) q.mysteryData.agent=(MOB)O; } questifyScriptableBehavs(q.mob); } q.mob=q.mysteryData.agent; if(q.mysteryData.agentGroup!=null) { q.mobGroup=Collections.synchronizedList(new ArrayList<MOB>()); q.mobGroup.addAll(q.mysteryData.agentGroup); } q.envObject=q.mysteryData.agentGroup; } else if(cmd.equals("WHEREHAPPENEDGROUP")||cmd.equals("WHEREATGROUP")) { if(q.mysteryData==null) q.mysteryData=new MysteryData(); if(cmd.equals("WHEREHAPPENEDGROUP")) { try { q.mysteryData.whereHappenedGroup=(List<Room>)getObjectIfSpecified(p,args,2,1); q.roomGroup=q.mysteryData.whereHappenedGroup; q.mysteryData.whereHappened=((q.roomGroup==null)||(q.roomGroup.size()==0))?null: (Room)q.roomGroup.get(CMLib.dice().roll(1,q.roomGroup.size(),-1)); q.envObject=q.mysteryData.whereHappenedGroup; continue; } catch(final CMException ex) { q.mysteryData.whereHappenedGroup=null; } } else { try { q.mysteryData.whereAtGroup=(List<Room>)getObjectIfSpecified(p,args,2,1); q.roomGroup=q.mysteryData.whereAtGroup; q.mysteryData.whereAt=((q.roomGroup==null)||(q.roomGroup.size()==0))?null: (Room)q.roomGroup.get(CMLib.dice().roll(1,q.roomGroup.size(),-1)); q.envObject=q.mysteryData.whereAtGroup; continue; } catch(final CMException ex) { q.mysteryData.whereAtGroup=null; } } if(p.size()<3) continue; final String numStr=CMParms.combine(p,2).toUpperCase(); if(!CMath.isMathExpression(numStr)) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !"+cmd.toLowerCase()+" #'"+numStr+"'."); break; } if((q.roomGroup==null)||(q.roomGroup.size()==0)) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !"+cmd.toLowerCase()+" roomGroup."); break; } final List<Room> V=new ArrayList<Room>(); V.addAll(q.roomGroup); final List<Room> V2=new ArrayList<Room>(); Room R=null; if(cmd.equals("WHEREHAPPENEDGROUP")) { q.mysteryData.whereHappenedGroup=Collections.synchronizedList(new ArrayList<Room>(V2)); R=q.mysteryData.whereHappened; } else { q.mysteryData.whereAtGroup=null; R=q.mysteryData.whereAt; } if(R!=null) V2.add(R); int num=CMath.parseIntExpression(numStr); if(num>=V.size()) num=V.size(); while((V2.size()<num)&&(V.size()>0)) { final int dex=CMLib.dice().roll(1,V.size(),-1); final Room O=V.get(dex); V.remove(dex); if(!V2.contains(O)) V2.add(O); if(R==null) R=O; } q.roomGroup=Collections.synchronizedList(new ArrayList<Room>()); q.roomGroup.addAll(V2); q.room=R; q.envObject=q.roomGroup; if(cmd.equals("WHEREHAPPENEDGROUP")) q.mysteryData.whereHappened=R; else q.mysteryData.whereAt=R; } else if(cmd.equals("WHENHAPPENEDGROUP")||cmd.equals("WHENATGROUP")) { if(q.mysteryData==null) q.mysteryData=new MysteryData(); List<TimeClock> V2; TimeClock TC=null; if(cmd.equals("WHENHAPPENEDGROUP")) { try { q.mysteryData.whenHappenedGroup=(List<TimeClock>)getObjectIfSpecified(p,args,2,1); V2=q.mysteryData.whenHappenedGroup; if((V2!=null)&&(V2.size()>0)) q.mysteryData.whenHappened=V2.get(CMLib.dice().roll(1,V2.size(),-1)); continue; } catch(final CMException ex) { q.mysteryData.whenHappenedGroup=null; } } else { try { q.mysteryData.whenAtGroup=(List<TimeClock>)getObjectIfSpecified(p,args,2,1); V2=q.mysteryData.whenAtGroup; if((V2!=null)&&(V2.size()>0)) q.mysteryData.whenAt=V2.get(CMLib.dice().roll(1,V2.size(),-1)); continue; } catch(final CMException ex) { q.mysteryData.whenAtGroup=null; } } if(p.size()<3) continue; V2=new ArrayList<TimeClock>(); final TimeClock NOW=getMysteryTimeNowFromState(); if(cmd.equals("WHENHAPPENEDGROUP")) { q.mysteryData.whenHappenedGroup=Collections.synchronizedList(new ArrayList<TimeClock>(V2)); TC=q.mysteryData.whenHappened; } else { q.mysteryData.whenAtGroup=Collections.synchronizedList(new ArrayList<TimeClock>(V2)); TC=q.mysteryData.whenAt; } for(int pi=2;pi<p.size();pi++) { final String numStr=p.get(pi); if(!CMath.isMathExpression(numStr)) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', "+cmd.toLowerCase()+" !relative hour #: "+numStr+"."); break; } final TimeClock TC2=(TimeClock)NOW.copyOf(); TC2.tickTock(CMath.parseIntExpression(numStr)); V2.add(TC2); } if(q.error) break; if((V2.size()>0)&&(TC==null)) TC=V2.get(CMLib.dice().roll(1,V2.size(),-1)); if(cmd.equals("WHENHAPPENEDGROUP")) q.mysteryData.whenHappened=TC; else q.mysteryData.whenAt=TC; } else if(cmd.equals("WHENHAPPENED") ||cmd.equals("WHENAT")) { if(q.mysteryData==null) q.mysteryData=new MysteryData(); if(cmd.equals("WHENHAPPENED")) { try { q.mysteryData.whenHappened=(TimeClock)getObjectIfSpecified(p,args,2,0); continue; } catch(final CMException ex) { q.mysteryData.whenHappened=null; } } else { try { q.mysteryData.whenAt=(TimeClock)getObjectIfSpecified(p,args,2,0); continue; } catch(final CMException ex) { q.mysteryData.whenAt=null; } } if(p.size()<3) continue; final TimeClock NOW=getMysteryTimeNowFromState(); TimeClock TC=null; final String numStr=CMParms.combine(p,2); if(!CMath.isMathExpression(numStr)) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', "+cmd.toLowerCase()+" !relative hour #: "+numStr+"."); break; } TC=(TimeClock)NOW.copyOf(); TC.tickTock(CMath.parseIntExpression(numStr)); if(cmd.equals("WHENHAPPENED")) q.mysteryData.whenHappened=TC; else q.mysteryData.whenAt=TC; } else if(cmd.equals("MOTIVEGROUP")||cmd.equals("ACTIONGROUP")) { if(q.mysteryData==null) q.mysteryData=new MysteryData(); List<String> V2=null; int num=-1; if((p.size()>2)&&(CMath.isMathExpression(p.get(2)))) { num=CMath.s_parseIntExpression(p.get(2)); p.remove(2); } if(cmd.equals("MOTIVEGROUP")) { try { q.mysteryData.motiveGroup=(List<String>)getObjectIfSpecified(p,args,2,1); sizeDownTo(q.mysteryData.motiveGroup,num); V2=q.mysteryData.motiveGroup; if((V2!=null)&&(V2.size()>0)) q.mysteryData.motive=V2.get(CMLib.dice().roll(1,V2.size(),-1)); continue; } catch(final CMException ex) { q.mysteryData.motiveGroup=null; } } else { try { q.mysteryData.actionGroup=(List<String>)getObjectIfSpecified(p,args,2,1); sizeDownTo(q.mysteryData.actionGroup,num); V2=q.mysteryData.actionGroup; if((V2!=null)&&(V2.size()>0)) q.mysteryData.action=V2.get(CMLib.dice().roll(1,V2.size(),-1)); continue; } catch(final CMException ex) { q.mysteryData.actionGroup=null; } } if(p.size()<3) continue; V2=new ArrayList<String>(); String Mstr=null; if(cmd.equals("MOTIVEGROUP")) { q.mysteryData.motiveGroup=Collections.synchronizedList(new ArrayList<String>(V2)); Mstr=q.mysteryData.motive; } else { q.mysteryData.actionGroup=Collections.synchronizedList(new ArrayList<String>(V2)); Mstr=q.mysteryData.action; } if(Mstr!=null) V2.add(Mstr); for(int pi=2;pi<p.size();pi++) { if(!V2.contains(p.get(pi))) V2.add(p.get(pi)); } sizeDownTo(V2,num); if((V2.size()>0)&&(Mstr==null)) Mstr=V2.get(CMLib.dice().roll(1,V2.size(),-1)); if(cmd.equals("MOTIVEGROUP")) q.mysteryData.motive=Mstr; else q.mysteryData.action=Mstr; } else if(cmd.equals("MOTIVE")) { if(q.mysteryData==null) q.mysteryData=new MysteryData(); if(p.size()<3) continue; try { q.mysteryData.motive=(String)getObjectIfSpecified(p,args,2,0); continue; } catch(final CMException ex) { q.mysteryData.motive=null; } q.mysteryData.motive=CMParms.combine(p,2); } else if(cmd.equals("ACTION")) { if(q.mysteryData==null) q.mysteryData=new MysteryData(); if(p.size()<3) continue; try { q.mysteryData.action=(String)getObjectIfSpecified(p,args,2,0); continue; } catch(final CMException ex) { q.mysteryData.action=null; } q.mysteryData.action=CMParms.combine(p,2); } else if(cmd.equals("WHEREHAPPENED") ||cmd.equals("WHEREAT")) { if(q.mysteryData==null) q.mysteryData=new MysteryData(); if(cmd.equals("WHEREHAPPENED")) { try { q.mysteryData.whereHappened=(Room)getObjectIfSpecified(p,args,2,0); q.room=q.mysteryData.whereHappened; q.envObject=q.room; continue; } catch(final CMException ex) { q.mysteryData.whereHappened=null; } } else { try { q.mysteryData.whereAt=(Room)getObjectIfSpecified(p,args,2,0); q.room=q.mysteryData.whereAt; q.envObject=q.room; continue; } catch(final CMException ex) { q.mysteryData.whereAt=null; } } if(p.size()>2) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', "+cmd.toLowerCase()+" syntax '"+CMParms.combine(p,2)+"'."); break; } if(q.room==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', "+cmd.toLowerCase()+" !room."); break; } if(cmd.equals("WHEREHAPPENED")) q.mysteryData.whereHappened=q.room; else q.mysteryData.whereAt=q.room; q.envObject=q.room; } else if(cmd.equals("TARGETGROUP") ||cmd.equals("TOOLGROUP")) { if(q.mysteryData==null) q.mysteryData=new MysteryData(); List<?> V2=null; if(cmd.equals("TARGETGROUP")) { try { q.mysteryData.targetGroup=(List<Environmental>)getObjectIfSpecified(p,args,2,1); V2=q.mysteryData.targetGroup; if((V2!=null)&&(V2.size()>0)) { if(V2.get(0) instanceof MOB) { q.mobGroup=(List<MOB>)V2; q.mob=(MOB)V2.get(CMLib.dice().roll(1,V2.size(),-1)); q.envObject=q.mobGroup; q.mysteryData.target=q.mob; } if(V2.get(0) instanceof Item) { q.itemGroup=(List<Item>)V2; q.item=(Item)V2.get(CMLib.dice().roll(1,V2.size(),-1)); q.mysteryData.target=q.item; q.envObject=q.itemGroup; } } continue; } catch(final CMException ex) { q.mysteryData.targetGroup=null; } } else { try { q.mysteryData.toolGroup=(List<Environmental>)getObjectIfSpecified(p,args,2,1); V2=q.mysteryData.toolGroup; if((V2!=null)&&(V2.size()>0)) { if(V2.get(0) instanceof MOB) { q.mobGroup=(List<MOB>)V2; q.mob=(MOB)V2.get(CMLib.dice().roll(1,V2.size(),-1)); q.envObject=q.mobGroup; q.mysteryData.tool=q.mob; } if(V2.get(0) instanceof Item) { q.itemGroup=(List<Item>)V2; q.item=(Item)V2.get(CMLib.dice().roll(1,V2.size(),-1)); q.envObject=q.itemGroup; q.mysteryData.tool=q.item; } } continue; } catch(final CMException ex) { q.mysteryData.toolGroup=null; } } if(p.size()<3) continue; final String numStr=CMParms.combine(p,2).toUpperCase(); if(!CMath.isMathExpression(numStr)) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !"+cmd.toLowerCase()+" #'"+numStr+"'."); break; } if(((q.mobGroup==null)||(q.mobGroup.size()==0)) &&((q.itemGroup==null)||(q.itemGroup.size()==0))) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', !"+cmd.toLowerCase()+" mobgroup itemgroup."); break; } final List<Environmental> V=Collections.synchronizedList(new ArrayList<Environmental>()); if((q.mobGroup!=null)&&(q.mobGroup.size()>0)) V.addAll(q.mobGroup); else V.addAll(q.itemGroup); V2=new ArrayList<Environmental>(); Environmental finalE=null; if(cmd.equals("TARGETGROUP")) { q.mysteryData.targetGroup=Collections.synchronizedList(new ArrayList<Environmental>((List<Environmental>)V2)); finalE=q.mysteryData.target; } else { q.mysteryData.toolGroup=Collections.synchronizedList(new ArrayList<Environmental>((List<Environmental>)V2)); finalE=q.mysteryData.tool; } if(finalE!=null) ((List<Environmental>)V2).add(finalE); int num=CMath.parseIntExpression(numStr); if(num>=V.size()) num=V.size(); Object O; while((V2.size()<num)&&(V.size()>0)) { final int dex=CMLib.dice().roll(1,V.size(),-1); O=V.get(dex); V.remove(dex); if(!V2.contains(O)) ((List<Object>)V2).add(O); if(finalE==null) finalE=(Environmental)O; } if(finalE instanceof MOB) { q.mobGroup=Collections.synchronizedList(new ArrayList<MOB>()); q.mobGroup.addAll((List<MOB>)V2); q.mob=(MOB)finalE; questifyScriptableBehavs(q.mob); // i just dont get it } else if(finalE instanceof Item) { q.itemGroup=Collections.synchronizedList(new ArrayList<Item>()); q.itemGroup.addAll((List<Item>)V2); q.item=(Item)finalE; questifyScriptableBehavs(q.item); } q.envObject=V2; if(cmd.equals("TARGETGROUP")) q.mysteryData.target=finalE; else q.mysteryData.tool=finalE; } else if(cmd.equals("TARGET") ||cmd.equals("TOOL")) { if(q.mysteryData==null) q.mysteryData=new MysteryData(); if(cmd.equals("TARGET")) { try { q.mysteryData.target=(Environmental)getObjectIfSpecified(p,args,2,0); if(q.mysteryData.target instanceof MOB) q.mob=(MOB)q.mysteryData.target; if(q.mysteryData.target instanceof Item) q.item=(Item)q.mysteryData.target; q.envObject=q.mysteryData.target; continue; } catch(final CMException ex) { q.mysteryData.target=null; } } else { try { q.mysteryData.tool=(Environmental)getObjectIfSpecified(p,args,2,0); if(q.mysteryData.tool instanceof MOB) q.mob=(MOB)q.mysteryData.tool; if(q.mysteryData.tool instanceof Item) q.item=(Item)q.mysteryData.tool; if(q.mysteryData.tool instanceof Ability) q.ability=(Ability)q.mysteryData.tool; q.envObject=q.mysteryData.tool; continue; } catch(final CMException ex) { q.mysteryData.tool=null; } } if(p.size()>2) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', "+cmd.toLowerCase()+" syntax '"+CMParms.combine(p,2)+"'."); break; } if((q.envObject instanceof List) &&(((List<Object>)q.envObject).size()>0) &&(((List<Object>)q.envObject).get(0) instanceof Environmental)) q.envObject=((List<Object>)q.envObject).get(CMLib.dice().roll(1,((List<Object>)q.envObject).size(),-1)); if(!(q.envObject instanceof Environmental)) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', "+cmd.toLowerCase()+" !object."); break; } if(cmd.equals("TARGET")) q.mysteryData.target=(Environmental)q.envObject; else q.mysteryData.tool=(Environmental)q.envObject; if(q.envObject instanceof MOB) { q.mob=(MOB)q.envObject; questifyScriptableBehavs(q.mob); // useless, but harmless } else if(q.envObject instanceof Item) { q.item=(Item)q.envObject; questifyScriptableBehavs(q.item); } } else if(!isStat(cmd)) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', unknown variable '"+cmd+"'."); break; } } else if(cmd.equals("IMPORT")) { if(p.size()<2) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', no IMPORT type."); break; } cmd=p.get(1).toUpperCase(); if(cmd.equals("MOBS")) { if(p.size()<3) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', no IMPORT MOBS file."); break; } final StringBuffer buf=getResourceFileData(CMParms.combine(p,2), !optional); if((buf==null)||(buf.length()<20)) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"',Unknown XML file: '"+CMParms.combine(p,2)+"' for '"+name()+"'."); break; } if(buf.substring(0,20).indexOf("<MOBS>")<0) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', Invalid XML file: '"+CMParms.combine(p,2)+"' for '"+name()+"'."); break; } q.loadedMobs=Collections.synchronizedList(new ArrayList<MOB>()); final String errorStr=CMLib.coffeeMaker().addMOBsFromXML(buf.toString(),q.loadedMobs,null); if(errorStr.length()>0) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"',Error on import of: '"+CMParms.combine(p,2)+"' for '"+name()+"': "+errorStr+"."); break; } if(q.loadedMobs.size()<=0) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"',No mobs loaded: '"+CMParms.combine(p,2)+"' for '"+name()+"'."); break; } for(final MOB M : q.loadedMobs) { M.basePhyStats().setRejuv(PhyStats.NO_REJUV); M.basePhyStats().setDisposition(M.basePhyStats().disposition()|PhyStats.IS_UNSAVABLE); M.recoverPhyStats(); M.text(); CMLib.threads().deleteAllTicks(M); } } else if(cmd.equals("ITEMS")) { if(p.size()<3) { errorOccurred(q,isQuiet,"Quest '"+name()+"', no import filename!"); break; } final StringBuffer buf=getResourceFileData(CMParms.combine(p,2), !optional); if((buf==null)||(buf.length()<20)) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"',Unknown XML file: '"+CMParms.combine(p,2)+"' for '"+name()+"'."); break; } if(buf.substring(0,20).indexOf("<ITEMS>")<0) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"',Invalid XML file: '"+CMParms.combine(p,2)+"' for '"+name()+"'."); break; } q.loadedItems=Collections.synchronizedList(new ArrayList<Item>()); final String errorStr=CMLib.coffeeMaker().addItemsFromXML(buf.toString(),q.loadedItems,null); if(errorStr.length()>0) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"',Error on import of: '"+CMParms.combine(p,2)+"' for '"+name()+"': "+errorStr+"."); break; } if(q.loadedItems.size()<=0) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"',No items loaded: '"+CMParms.combine(p,2)+"' for '"+name()+"'."); break; } for(final Item I : q.loadedItems) { I.basePhyStats().setRejuv(PhyStats.NO_REJUV); I.basePhyStats().setDisposition(I.basePhyStats().disposition()|PhyStats.IS_UNSAVABLE); I.recoverPhyStats(); I.text(); CMLib.threads().deleteTick(I,Tickable.TICKID_ITEM_BEHAVIOR); } } else if(cmd.equals("ABILITIES")) { if(p.size()<3) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', no import filename!"); break; } final StringBuffer buf=getResourceFileData(CMParms.combine(p,2), !optional); if((buf==null)||(buf.length()<20)) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"',Unknown XML file: '"+CMParms.combine(p,2)+"' for '"+name()+"'."); break; } if(buf.substring(0,20).indexOf("<ABILITY")<0) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"',Invalid XML file: '"+CMParms.combine(p,2)+"' for '"+name()+"'."); break; } q.loadedAbilities=Collections.synchronizedList(new ArrayList<Ability>()); final String errorStr=CMLib.coffeeMaker().unpackAbilitiesFromXml(buf.toString(),q.loadedAbilities); if(errorStr.length()>0) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"',Error on import of: '"+CMParms.combine(p,2)+"' for '"+name()+"': "+errorStr+"."); break; } if(q.loadedAbilities.size()<=0) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"',No abilities loaded: '"+CMParms.combine(p,2)+"' for '"+name()+"'."); break; } } else { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', unknown import type '"+cmd+"'."); break; } } else if(cmd.startsWith("LOAD=")) { final boolean error=q.error; final List<Object> args2=new ArrayList<Object>(); parseQuestScriptWArgs(parseLoadScripts(s,args,args2,true),args2); if((!error)&&(q.error)&&(!optional)) break; } else if(cmd.equals("LOAD")) { if(p.size()<2) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', unfound type on load."); break; } cmd=p.get(1).toUpperCase(); if(cmd.equals("MOB")||cmd.equals("MOBGROUP")) { if(q.loadedMobs.size()==0) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot load mob, no mobs imported."); break; } int maxToLoad=Integer.MAX_VALUE; if((p.size()>2)&&(CMath.isMathExpression(p.get(2)))) { maxToLoad=CMath.parseIntExpression(p.get(2)); p.remove(2); } if(p.size()<3) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', no mob name to load!"); break; } String mobName=CMParms.combine(p,2); final String maskStr=breakOutMaskString(s,p); final MaskingLibrary.CompiledZMask mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr); if(mask!=null) mobName=CMParms.combine(p,2).toUpperCase(); if(mobName.length()==0) mobName="ANY"; final boolean addAll=mobName.equalsIgnoreCase("ALL") ||mobName.equalsIgnoreCase("ANY"); final List<MOB> choices=new ArrayList<MOB>(); // ok because is wholly temporary for(int i=0;i<q.loadedMobs.size();i++) { final MOB M2=q.loadedMobs.get(i); if((CMLib.masking().maskCheck(mask,M2,true)) &&(addAll ||(CMLib.english().containsString(M2.name(),mobName)) ||(CMLib.english().containsString(M2.displayText(),mobName)) ||(CMLib.english().containsString(M2.description(),mobName)))) choices.add((MOB)M2.copyOf()); } if(choices.size()==0) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', no mob found to load '"+mobName+"'!"); break; } final List<MOB> mobsToDo=Collections.synchronizedList(new ArrayList<MOB>()); // must remain vector for thread safety if(cmd.equalsIgnoreCase("MOB")) mobsToDo.add(choices.get(CMLib.dice().roll(1,choices.size(),-1))); else { mobsToDo.addAll(choices); q.mobGroup=mobsToDo; } while((mobsToDo.size()>maxToLoad)&&(maxToLoad>0)) mobsToDo.remove(CMLib.dice().roll(1,mobsToDo.size(),-1)); while((mobsToDo.size()<maxToLoad)&&(maxToLoad>0)&&(maxToLoad<Integer.MAX_VALUE)) mobsToDo.add((MOB)mobsToDo.get(CMLib.dice().roll(1,mobsToDo.size(),-1)).copyOf()); final Room choiceRoom=q.room; for(int m=0;m<mobsToDo.size();m++) { q.mob=mobsToDo.get(m); q.room=choiceRoom; if(q.room==null) { if(q.roomGroup!=null) q.room=q.roomGroup.get(CMLib.dice().roll(1,q.roomGroup.size(),-1)); else if(q.area!=null) q.room=q.area.getRandomMetroRoom(); else q.room=CMLib.map().getRandomRoom(); } if(q.room!=null) { q.mob.setStartRoom(null); q.mob.basePhyStats().setRejuv(PhyStats.NO_REJUV); q.mob.basePhyStats().setDisposition(q.mob.basePhyStats().disposition()|PhyStats.IS_UNSAVABLE); q.mob.recoverPhyStats(); q.mob.text(); q.mob.bringToLife(q.room,true); } questifyScriptableBehavs(q.mob); runtimeRegisterObject(q.mob); if(q.room!=null) { q.room.recoverRoomStats(); q.room.showHappens(CMMsg.MSG_OK_ACTION,null); } if(q.mob!=null) q.mob.setStartRoom(null); // necessary to tell qm to clean him UP! } q.envObject=mobsToDo; if(q.room!=null) q.area=q.room.getArea(); } else if(cmd.equals("ITEM")||cmd.equals("ITEMGROUP")) { if(q.loadedItems.size()==0) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot load item, no items imported."); break; } int maxToLoad=Integer.MAX_VALUE; if((p.size()>2)&&(CMath.isMathExpression(p.get(2)))) { maxToLoad=CMath.parseIntExpression(p.get(2)); p.remove(2); } if(p.size()<3) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', no item name to load!"); break; } final String itemName=CMParms.combine(p,2); final List<Item> choices=new ArrayList<Item>(); // only ever picked from locally for(int i=0;i<q.loadedItems.size();i++) { final Item I2=q.loadedItems.get(i); if((itemName.equalsIgnoreCase("any")) ||(CMLib.english().containsString(I2.name(),itemName)) ||(CMLib.english().containsString(I2.displayText(),itemName)) ||(CMLib.english().containsString(I2.description(),itemName))) { final Item I3=(Item)I2.copyOf(); CMLib.threads().deleteTick(I3,Tickable.TICKID_ITEM_BEHAVIOR); choices.add(I3); } } if(choices.size()==0) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', no item found to load '"+itemName+"'!"); break; } final List<Item> itemsToDo=new ArrayList<Item>(); // for thread safety, as this is global if(cmd.equalsIgnoreCase("ITEM")) itemsToDo.add(choices.get(CMLib.dice().roll(1,choices.size(),-1))); else { itemsToDo.addAll(choices); q.itemGroup=Collections.synchronizedList(new ArrayList<Item>(itemsToDo)); } while((itemsToDo.size()>maxToLoad)&&(maxToLoad>0)) itemsToDo.remove(CMLib.dice().roll(1,itemsToDo.size(),-1)); while((itemsToDo.size()<maxToLoad)&&(maxToLoad>0)&&(maxToLoad<Integer.MAX_VALUE)) { final Item I3=(Item)(itemsToDo.get(CMLib.dice().roll(1,itemsToDo.size(),-1))).copyOf(); CMLib.threads().deleteTick(I3,Tickable.TICKID_ITEM_BEHAVIOR); itemsToDo.add(I3); } final Room choiceRoom=q.room; for(int m=0;m<itemsToDo.size();m++) { q.item=itemsToDo.get(m); q.room=choiceRoom; if(q.room==null) { if(q.roomGroup!=null) q.room=q.roomGroup.get(CMLib.dice().roll(1,q.roomGroup.size(),-1)); else if(q.area!=null) q.room=q.area.getRandomMetroRoom(); else q.room=CMLib.map().getRandomRoom(); } if(q.room!=null) { q.item.basePhyStats().setRejuv(PhyStats.NO_REJUV); q.item.basePhyStats().setDisposition(q.item.basePhyStats().disposition()|PhyStats.IS_UNSAVABLE); q.item.recoverPhyStats(); q.item.text(); q.room.addItem(q.item); q.room.recoverRoomStats(); q.room.showHappens(CMMsg.MSG_OK_ACTION,null); } questifyScriptableBehavs(q.item); runtimeRegisterObject(q.item); } if(q.room!=null) q.area=q.room.getArea(); q.envObject=itemsToDo; } else if(cmd.equals("ABILITY")||cmd.equals("ABILITYGROUP")) { if(q.loadedAbilities.size()==0) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot load ability, no abilities imported."); break; } int maxToLoad=Integer.MAX_VALUE; if((p.size()>2)&&(CMath.isMathExpression(p.get(2)))) { maxToLoad=CMath.parseIntExpression(p.get(2)); p.remove(2); } if(p.size()<3) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', no ability name to load!"); break; } final String itemName=CMParms.combine(p,2); final List<Ability> choices=new ArrayList<Ability>(); // only ever picked from locally for(int i=0;i<q.loadedAbilities.size();i++) { final Ability A2=q.loadedAbilities.get(i); if((itemName.equalsIgnoreCase("any")) ||(CMLib.english().containsString(A2.name(),itemName)) ||(CMLib.english().containsString(A2.ID(),itemName))) { final Ability A3=(Ability)A2.copyOf(); choices.add(A3); } } if(choices.size()==0) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', no ability found to load '"+itemName+"'!"); break; } final List<Ability> itemsToDo=new ArrayList<Ability>(); // for thread safety, as this is global if(cmd.equalsIgnoreCase("ABILITY")) itemsToDo.add(choices.get(CMLib.dice().roll(1,choices.size(),-1))); else { itemsToDo.addAll(choices); q.abilityGroup=Collections.synchronizedList(new ArrayList<Ability>(itemsToDo)); } while((itemsToDo.size()>maxToLoad)&&(maxToLoad>0)) itemsToDo.remove(CMLib.dice().roll(1,itemsToDo.size(),-1)); while((itemsToDo.size()<maxToLoad)&&(maxToLoad>0)&&(maxToLoad<Integer.MAX_VALUE)) { final Ability A3=(Ability)(itemsToDo.get(CMLib.dice().roll(1,itemsToDo.size(),-1))).copyOf(); itemsToDo.add(A3); } if(itemsToDo.size()>0) q.ability=itemsToDo.get(0); q.envObject=itemsToDo; } else { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', unknown load type '"+cmd+"'."); break; } } else if(cmd.equals("GIVE")) { if(p.size()<2) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', unfound type on give."); break; } cmd=p.get(1).toUpperCase(); if(cmd.equals("FOLLOWER")) { if(q.mob==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give follower, no mob set."); break; } if(p.size()<3) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give follower, follower name not given."); break; } final String mobName=CMParms.combine(p,2); final List<MOB> choices=new ArrayList<MOB>(); // only ever picked from locally ReverseEnumeration<PreservedQuestObject> e; for(e=new ReverseEnumeration<PreservedQuestObject>(q.worldObjects);e.hasMoreElements();) { final PreservedQuestObject PO=e.nextElement(); if((PO.obj!=q.mob)&&(PO.obj instanceof MOB)) { final MOB M2=(MOB)PO.obj; if((mobName.equalsIgnoreCase("any")) ||(CMLib.english().containsString(M2.name(),mobName)) ||(CMLib.english().containsString(M2.displayText(),mobName)) ||(CMLib.english().containsString(M2.description(),mobName))) choices.add(M2); } } if(choices.size()==0) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give follower, no mobs called '"+mobName+"' previously set in script."); break; } final MOB M2=choices.get(CMLib.dice().roll(1,choices.size(),-1)); M2.setFollowing(q.mob); } else if(cmd.equals("ITEM")||(cmd.equalsIgnoreCase("ITEMS"))) { if((q.item==null)&&(q.itemGroup==null)&&(q.loadedItems==null)) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give item(s), no item(s) set or loaded."); break; } if((q.mob==null)&&(q.mobGroup==null)) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give item(s), no mob set."); break; } if(p.size()>2) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give item(s), parameter unnecessarily given: '"+CMParms.combine(p,2)+"'."); break; } final List<MOB> toSet=new ArrayList<MOB>(); if(q.mob!=null) toSet.add(q.mob); else if(q.mobGroup!=null) toSet.addAll(q.mobGroup); final List<Item> itemSet=new ArrayList<Item>(); if(q.item!=null) itemSet.add(q.item); else if(q.itemGroup!=null) itemSet.addAll(q.itemGroup); else if(q.loadedItems!=null) itemSet.addAll(q.loadedItems); for(int i=0;i<toSet.size();i++) { final MOB M2=toSet.get(i); runtimeRegisterObject(M2); if(cmd.equals("ITEMS")) { for(int i3=0;i3<itemSet.size();i3++) { Item I3=itemSet.get(i3); if(q.item==I3) { runtimeRegisterObject(I3); M2.moveItemTo(I3); questifyScriptableBehavs(q.item); q.item=(Item)q.item.copyOf(); questifyScriptableBehavs(q.item); CMLib.threads().deleteTick(q.item, Tickable.TICKID_ITEM_BEHAVIOR); // because it may not be used q.item.setOwner(null); // because the item copy is definitely nowhere } else { questifyScriptableBehavs(I3); CMLib.threads().deleteTick(I3, Tickable.TICKID_ITEM_BEHAVIOR); // because it may not be used?? I3=(Item)I3.copyOf(); questifyScriptableBehavs(I3); I3.setOwner(null); // because the i3 copy is nowhere runtimeRegisterObject(I3); M2.moveItemTo(I3); } } } else if(cmd.equals("ITEM")) { Item I3=itemSet.get(CMLib.dice().roll(1,itemSet.size(),-1)); questifyScriptableBehavs(I3); if(q.item==I3) { runtimeRegisterObject(I3); M2.moveItemTo(I3); q.item=(Item)q.item.copyOf(); q.item.setOwner(null);// because the copy is nowhere questifyScriptableBehavs(q.item); CMLib.threads().deleteTick(q.item, Tickable.TICKID_ITEM_BEHAVIOR); // because it may not be used } else { CMLib.threads().deleteTick(I3, Tickable.TICKID_ITEM_BEHAVIOR); // because it may not be used I3=(Item)I3.copyOf(); I3.setOwner(null);// because the copy is nowhere questifyScriptableBehavs(I3); runtimeRegisterObject(I3); M2.moveItemTo(I3); } } } } else if(cmd.equals("ABILITY")) { if((q.mob==null)&&(q.mobGroup==null)) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give ability, no mob set."); break; } if((p.size()<3)&&(q.ability==null)) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give ability, ability name not given."); break; } final Ability A3=findQuestAbility(p.get(2)); if(A3==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give ability, ability name unknown '"+(p.get(2))+"."); break; } final List<MOB> toSet=new ArrayList<MOB>(); if(q.mob!=null) toSet.add(q.mob); else if(q.mobGroup!=null) toSet.addAll(q.mobGroup); for(int i=0;i<toSet.size();i++) { final MOB M2=toSet.get(i); runtimeRegisterAbility(M2,A3.ID(),CMParms.rest(s,3),true); } } else if(cmd.equals("BEHAVIOR")) { if(q.envObject==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give behavior, no mob or item set."); break; } if(p.size()<3) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give behavior, behavior name not given."); break; } final Behavior B=CMClass.getBehavior(p.get(2)); if(B==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give behavior, behavior name unknown '"+(p.get(2))+"."); break; } List<Object> toSet=new ArrayList<Object>(); if(q.envObject instanceof List) toSet=(List<Object>)q.envObject; else if(q.envObject!=null) toSet.add(q.envObject); for(int i=0;i<toSet.size();i++) { final Environmental E2=(Environmental)toSet.get(i); if(E2 instanceof PhysicalAgent) runtimeRegisterBehavior((PhysicalAgent)E2,B.ID(),CMParms.rest(s,3),true); if((E2 instanceof Item) &&((((Item)E2).owner()==null) ||(!((Item)E2).owner().isContent((Item)E2)))) CMLib.threads().deleteTick(E2, Tickable.TICKID_ITEM_BEHAVIOR); } } else if(cmd.equals("STAT")) { if(q.envObject==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give stat, no mob or item set."); break; } if(p.size()<3) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give stat, stat name not given."); break; } final String stat=p.get(2); final String val=CMParms.rest(s,3); List<Environmental> toSet=new ArrayList<Environmental>(); if(q.envObject instanceof List) toSet=(List<Environmental>)q.envObject; else if(q.envObject!=null) toSet.add((Environmental)q.envObject); for(int i=0;i<toSet.size();i++) { final Environmental E2=toSet.get(i); if(stat.equalsIgnoreCase("KEYPLAYER") && (E2 instanceof Physical)) { final Ability A=((Physical)E2).fetchEffect("QuestBound"); if(A!=null) A.setStat("KEY",val); } else runtimeRegisterStat(E2,stat,val,true); } } else if(cmd.equals("SCRIPT")) { if(q.envObject==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give script, no object set."); break; } boolean proceed=true; boolean savable=false; boolean playerok=false; String word=null; String scope=CMStrings.replaceAll(name()," ","_").toUpperCase().trim(); while(proceed&&(p.size()>2)) { word=p.get(2); proceed=false; if(word.equalsIgnoreCase("SAVABLE")) { savable=true; proceed=true; } else if(word.equalsIgnoreCase("GLOBAL")) { scope=""; proceed=true; } else if(word.equalsIgnoreCase("INDIVIDUAL")||word.equals("*")) { scope="*"; proceed=true; } else if(word.equalsIgnoreCase("PLAYEROK")) { playerok=true; proceed=true; } if(proceed) p.remove(2); } if(p.size()<3) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give script, script not given."); break; } final String val=CMParms.rest(s,2); List<Environmental> toSet=new ArrayList<Environmental>(); if(q.envObject instanceof List) toSet=(List<Environmental>)q.envObject; else if(q.envObject!=null) toSet.add((Environmental)q.envObject); for(int i=0;i<toSet.size();i++) { final Environmental E2=toSet.get(i); if(E2 instanceof PhysicalAgent) { final ScriptingEngine S=(ScriptingEngine)CMClass.getCommon("DefaultScriptingEngine"); S.setSavable(savable); S.registerDefaultQuest(this); S.setVarScope(scope); S.setScript(val); if(debug) Log.debugOut("QuestScript#"+parseId+": Giving "+val.length()+" char script command to "+E2.Name()); if((E2 instanceof MOB) &&(((MOB)E2).isPlayer()) &&(!playerok) &&(S.isFunc("DO_ACCEPT")) &&(S.isFunc("CAN_ACCEPT"))) { final MOB M2=(MOB)E2; String eval = S.callFunc("CAN_ACCEPT", M2.Name(), M2, M2, M2, M2, null, null, M2.Name(), objs); if(eval == null) continue; // failed, so don't do it eval=eval.toLowerCase(); if(eval.equals("cancel") || (eval.length()==0)) continue; // failed, so don't do it S.callFunc("DO_ACCEPT", M2.Name(), M2, M2, M2, M2, null, null, M2.Name(), objs); } else { ((PhysicalAgent)E2).addScript(S); runtimeRegisterObject(((PhysicalAgent)E2)); if((E2 instanceof Item) &&((((Item)E2).owner()==null) ||(!((Item)E2).owner().isContent((Item)E2)))) CMLib.threads().deleteTick(E2, Tickable.TICKID_ITEM_BEHAVIOR); //OMG WHY?!?!/????!! synchronized(q) { q.addons.add(new XVector<Object>(E2,S),Integer.valueOf(q.preserveState)); } } } } } else if(cmd.equals("AFFECT")) { if(q.envObject==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give Effect, no mob, room or item set."); break; } if(p.size()<3) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give Effect, ability name not given."); break; } final Ability A3=this.findQuestAbility(p.get(2)); if(A3==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give Effect, ability name unknown '"+(p.get(2))+"."); break; } List<Object> toSet=new ArrayList<Object>(); if(q.envObject instanceof List) toSet=(List<Object>)q.envObject; else if(q.envObject!=null) toSet.add(q.envObject); for(final Object o : toSet) { if(o instanceof PhysicalAgent) runtimeRegisterEffect((PhysicalAgent)o,A3.ID(),CMParms.rest(s,3),true); } } else { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', unknown give type '"+cmd+"'."); break; } } else if(cmd.equals("TAKE")) { if(p.size()<2) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', unfound type on take."); break; } cmd=p.get(1).toUpperCase(); if(cmd.equals("ABILITY")) { if((q.mob==null)&&(q.mobGroup==null)) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot take ability, no mob set."); break; } if(p.size()<3) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot take ability, ability name not given."); break; } final Ability A3=findQuestAbility(p.get(2)); if(A3==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot take ability, ability name unknown '"+(p.get(2))+"."); break; } final List<MOB> toSet=new ArrayList<MOB>(); if(q.mob!=null) toSet.add(q.mob); else if(q.mobGroup!=null) toSet.addAll(q.mobGroup); for(int i=0;i<toSet.size();i++) { final MOB M2=toSet.get(i); runtimeRegisterAbility(M2,A3.ID(),CMParms.rest(s,3),false); } } else if(cmd.equals("BEHAVIOR")) { if(q.envObject==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot take behavior, no mob or item set."); break; } if(p.size()<3) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot take behavior, behavior name not given."); break; } final Behavior B=CMClass.getBehavior(p.get(2)); if(B==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot take behavior, behavior name unknown '"+(p.get(2))+"."); break; } List<Object> toSet=new ArrayList<Object>(); if(q.envObject instanceof List) toSet=(List<Object>)q.envObject; else if(q.envObject!=null) toSet.add(q.envObject); for(int i=0;i<toSet.size();i++) { final Environmental E2=(Environmental)toSet.get(i); if(E2 instanceof PhysicalAgent) runtimeRegisterBehavior((PhysicalAgent)E2,B.ID(),CMParms.rest(s,3),false); if((E2 instanceof Item) &&((((Item)E2).owner()==null) ||(!((Item)E2).owner().isContent((Item)E2)))) CMLib.threads().deleteTick(E2, Tickable.TICKID_ITEM_BEHAVIOR); } } else if(cmd.equals("AFFECT")) { if(q.envObject==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot take Effect, no mob, room or item set."); break; } if(p.size()<3) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot take Effect, ability name not given."); break; } final Ability A3=findQuestAbility(p.get(2)); if(A3==null) { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot take Effect, ability name unknown '"+(p.get(2))+"."); break; } List<Object> toSet=new ArrayList<Object>(); if(q.envObject instanceof List) toSet=(List<Object>)q.envObject; else if(q.envObject!=null) toSet.add(q.envObject); for(final Object o : toSet) { if(o instanceof PhysicalAgent) runtimeRegisterEffect((PhysicalAgent)o,A3.ID(),CMParms.rest(s,3),false); } } else { if(optional) continue; errorOccurred(q,isQuiet,"Quest '"+name()+"', unknown take type '"+cmd+"'."); break; } } else { errorOccurred(q,isQuiet,"Quest '"+name()+"', unknown command '"+cmd+"'."); break; } q.done=true; } } } public boolean spawnQuest(final String script, final List<?> baseVars, final boolean reTime) { final DefaultQuest Q2=(DefaultQuest)CMClass.getCommon("DefaultQuest"); Q2.setCopy(true); Q2.setVars(baseVars,0); Q2.setScript(script,true); Quest Q=CMLib.quests().fetchQuest(Q2.name()); int append=1; while((Q!=null)&&(Q!=Q2)) { Q2.setName(name()+"#"+append); append++; Q=CMLib.quests().fetchQuest(Q2.name()); } CMLib.quests().addQuest(Q2); if(reTime) { Long ellapsed=stepEllapsedTimes.get(script); if(ellapsed==null) ellapsed=Long.valueOf(0); stepEllapsedTimes.remove(script); ellapsed=Long.valueOf(ellapsed.longValue()+(System.currentTimeMillis()-lastStartDateTime)); stepEllapsedTimes.put(script,ellapsed); Q2.resetWaitRemaining(ellapsed.longValue()); if(Q2.startQuestOnTime()) { stepEllapsedTimes.remove(script); return true; } } else if(Q2.startQuestInternal()) return true; Q2.enterDormantState(); return false; } @Override public boolean startQuest() { if((!running())&&(!isCopy())) CMLib.coffeeTables().bump(this,CoffeeTableRow.STAT_QUESTSTARTATTEMPT); return startQuestInternal(); } // this will execute the quest script. If the quest is running, it // will call stopQuestInternal first to shut it down. public boolean startQuestInternal() { final String prefix = CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS)?("QuestScript#"+parseId+" "):""; if(prefix.length()>0) Log.debugOut("Quest",prefix+name()+" Start Internal called ("+running()+": resetting state and starting from scratch."); if(running()) { stopQuestInternal(); resetData=null; } final List<Object> args=new ArrayList<Object>(); questState=new QuestState(); final List<Object> baseScript=parseLoadScripts(script(),new ArrayList<Object>(),args,true); if((!isCopy())&&(getSpawn()!=SPAWN_NO)) { if(getSpawn()==SPAWN_FIRST) spawnQuest(script(),baseScript,false); else if(getSpawn()==SPAWN_ANY) { final List<String> parsed=CMLib.quests().parseQuestSteps(parseFinalQuestScript(baseScript),0,false); for(int p=0;p<parsed.size();p++) spawnQuest(parsed.get(p),baseScript,true); } lastStartDateTime=System.currentTimeMillis(); enterDormantState(); return false; // always return false, since, per se, this quest is NOT started. } try { parseQuestScript(baseScript,args,0); } catch(final Exception t) { questState.error=true; Log.errOut("DefaultQuest",t); } if(questState.error) { if(!questState.beQuiet) { int retry=0; if((durable)&&(resetData==null)) retry=10; else if(resetData!=null) retry=resetData[0]; Log.errOut("Quest",prefix+"Errors starting '" +name() +"', quest not started" +((retry>0)?", retry in "+retry+".":".")); } if((durable)&&(resetData==null)) { resetQuest(10); return false; } CMLib.coffeeTables().bump(this,CoffeeTableRow.STAT_QUESTFAILEDSTART); } else if(!questState.done) Log.errOut("Quest",prefix+"Nothing parsed in '"+name()+"', quest not started."); else if(duration()<0) { Log.errOut("Quest",prefix+"No duration, quest '"+name()+"' not started."); questState.error=true; } if((!questState.error)&&(questState.done)) { enterRunningState(); return true; } stopQuestInternal(); return false; } public void enterRunningState() { if(duration()>=0) { waitRemaining=-1; if(duration()==0) ticksRemaining=1; else if((resetData!=null)&&(resetData[1]>0)) ticksRemaining=resetData[1]; else ticksRemaining=duration(); CMLib.threads().startTickDown(this,Tickable.TICKID_QUEST,1); } resetData=null; lastStartDateTime=System.currentTimeMillis(); stepEllapsedTimes.remove(script()); } protected void cleanQuestStep(final int preserveSkip) { stoppingQuest=true; final boolean debug=CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS); if(questState.worldObjects.size()>0) { synchronized(questState) { Enumeration<PreservedQuestObject> e; PreservedQuestObject PO; for(e=new ReverseEnumeration<PreservedQuestObject>(questState.worldObjects);e.hasMoreElements();) { PO=e.nextElement(); final PhysicalAgent P=PO.obj; // always end quest between steps if(PO.preserveState!=Integer.MIN_VALUE) { if(P instanceof MOB) { final MOB M=(MOB)P; final ScriptingEngine B=(ScriptingEngine)M.fetchBehavior("Scriptable"); if(B!=null) B.endQuest(M,M,name()); for(final Enumeration<ScriptingEngine> se= M.scripts(); se.hasMoreElements();) { final ScriptingEngine SE=se.nextElement(); if(SE!=null) SE.endQuest(M, M, name()); } } else if(P instanceof Behavable) { final MOB M=CMClass.getFactoryMOB(P.name(),P.phyStats().level(),CMLib.map().roomLocation(P)); try { for(final Enumeration<ScriptingEngine> se= ((Behavable)P).scripts(); se.hasMoreElements();) { final ScriptingEngine SE=se.nextElement(); if(SE!=null) SE.endQuest(P, M, name()); } } finally { M.destroy(); } } } final int oldPreserveState=PO.preserveState; if((PO.preserveState>0)&&(preserveSkip!=0)) PO.preserveState-=preserveSkip; // might actually bump it to keep things unchanged if(PO.preserveState>0) { if(debug && (P!=null)) Log.debugOut("QuestScript#"+parseId+": Aging "+P.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(P))+" from "+oldPreserveState+" to "+(PO.preserveState-1)); PO.preserveState--; continue; } if(debug && (P!=null)) Log.debugOut("QuestScript#"+parseId+": De-registering "+P.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(P))); questState.worldObjects.remove(PO); if(PO.preserveState == Integer.MIN_VALUE) continue; PO.preserveState=Integer.MIN_VALUE; if(P != null) { final Ability A=P.fetchEffect("QuestBound"); if(A!=null) P.delEffect(A); if(P instanceof Item) { if((CMath.bset(P.basePhyStats().disposition(),PhyStats.IS_UNSAVABLE)) &&(!((Item)P).amDestroyed())) { if(debug) Log.debugOut("QuestScript#"+parseId+": Destroying "+P.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(P))); ((Item)P).destroy(); } } else if(P instanceof MOB) { final MOB M=(MOB)P; if(!M.isPlayer()) { final Room R=M.getStartRoom(); if((R==null) ||(CMath.bset(M.basePhyStats().disposition(),PhyStats.IS_UNSAVABLE))) { if(debug) Log.debugOut("QuestScript#"+parseId+": Destroying "+P.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(P))); M.setFollowing(null); CMLib.tracking().wanderAway(M,true,false); if(M.location()!=null) M.location().delInhabitant(M); M.setLocation(null); M.destroy(); } else if((!M.amDead()) &&(!M.amDestroyed()) &&((M.location()!=R)||(!R.isInhabitant(M)))) { if(debug) Log.debugOut("QuestScript#"+parseId+": Dismissing "+P.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(P))); M.setFollowing(null); CMLib.tracking().wanderAway(M,false,true); } } } } } } if((questState.addons.size()>0) &&(stoppingQuest)) { synchronized(questState) { for(int i=questState.addons.size()-1;i>=0;i--) { try { final Integer I=questState.addons.get(i).second; if(I.intValue()>0) { questState.addons.get(i).second=Integer.valueOf(I.intValue()-1); continue; } final List<Object> V=questState.addons.get(i).first; questState.addons.remove(i); if(V.size()<2) continue; final Environmental E=(Environmental)V.get(0); final Object O=V.get(1); if(O instanceof String) { final String stat=(String)O; final String parms=(String)V.get(2); if(CMStrings.contains(E.getStatCodes(),stat.toUpperCase().trim())) E.setStat(stat,parms); else if((E instanceof MOB)&&CMStrings.contains(((Physical)E).basePhyStats().getStatCodes(),stat.toUpperCase().trim())) { if(debug) Log.debugOut("QuestScript#"+parseId+": Reverting stat "+stat+" on "+E.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(E))); ((Physical)E).basePhyStats().setStat(stat.toUpperCase().trim(),parms); ((Physical)E).recoverPhyStats(); } else if((E instanceof MOB)&&(CMStrings.contains(CharStats.CODES.NAMES(),stat.toUpperCase().trim()))) { if(debug) Log.debugOut("QuestScript#"+parseId+": Reverting stat "+stat+" on "+E.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(E))); ((MOB)E).baseCharStats().setStat(CMParms.indexOf(CharStats.CODES.NAMES(),stat.toUpperCase().trim()),CMath.s_int(parms)); ((MOB)E).recoverCharStats(); } else if((E instanceof MOB)&&CMStrings.contains(((MOB)E).baseState().getStatCodes(),stat)) { if(debug) Log.debugOut("QuestScript#"+parseId+": Reverting stat "+stat+" on "+E.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(E))); ((MOB)E).baseState().setStat(stat,parms); ((MOB)E).recoverMaxState(); ((MOB)E).resetToMaxState(); } } else if(O instanceof Behavior) { if(E instanceof PhysicalAgent) { final PhysicalAgent BB=(PhysicalAgent)E; Behavior B=BB.fetchBehavior(((Behavior)O).ID()); if((E instanceof MOB)&&(B instanceof ScriptingEngine)) ((ScriptingEngine)B).endQuest((PhysicalAgent)E,(MOB)E,name()); if((V.size()>2) &&(V.get(2) instanceof String)) { if(B==null) { B=(Behavior)O; B.setParms((String)V.get(2)); BB.addBehavior(B); } else B.setParms((String)V.get(2)); if(debug) Log.debugOut("QuestScript#"+parseId+": Reverting bparms on "+B.name()+" on "+E.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(E))); } else if(B!=null) { if(debug) Log.debugOut("QuestScript#"+parseId+": Removing behavior "+B.name()+" on "+E.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(E))); BB.delBehavior(B); } } } else if(O instanceof ScriptingEngine) { final ScriptingEngine S=(ScriptingEngine)O; if(!S.isSavable()) { if(E instanceof MOB) S.endQuest((PhysicalAgent)E,(MOB)E,name()); else { final MOB M=CMClass.getFactoryMOB(E.Name(), 1, CMLib.map().roomLocation(E)); S.endQuest((PhysicalAgent)E,M,name()); M.destroy(); } if(debug) Log.debugOut("QuestScript#"+parseId+": Removing script on "+E.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(E))); ((PhysicalAgent)E).delScript(S); } } else if(O instanceof Ability) { if((V.size()>2) &&(V.get(2) instanceof Ability) &&(E instanceof MOB)) { Ability A=((MOB)E).fetchAbility(((Ability)O).ID()); if((V.size()>3)&&(V.get(3) instanceof String)) { if(A==null) { A=(Ability)O; ((MOB)E).addAbility(A); } if(debug) Log.debugOut("QuestScript#"+parseId+": Reverting aparms "+A.ID()+" on "+E.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(E))); A.setMiscText((String)V.get(3)); } else if(A!=null) { if(debug) Log.debugOut("QuestScript#"+parseId+": Removing "+A.ID()+" on "+E.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(E))); ((MOB)E).delAbility(A); } } else if(E instanceof Physical) { Ability A=((Physical)E).fetchEffect(((Ability)O).ID()); if((V.size()>2)&&(V.get(2) instanceof String)) { if(A==null) { A=(Ability)O; ((Physical)E).addEffect(A); } if(debug) Log.debugOut("QuestScript#"+parseId+": Reverting aparms "+A.ID()+" on "+E.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(E))); A.setMiscText((String)V.get(2)); } else if(A!=null) { if(debug) Log.debugOut("QuestScript#"+parseId+": Removing "+A.ID()+" on "+E.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(E))); A.unInvoke(); ((Physical)E).delEffect(A); } } } else if(O instanceof Item) ((Item)O).destroy(); } catch(final ArrayIndexOutOfBoundsException e) { // eat it } } } } } stoppingQuest=false; } // this will cause a quest to begin parsing its next "step". // this will clear out unpreserved objects from previous // step and resume quest script processing. // if this is the LAST step, stopQuestInternal() is automatically called @Override public boolean stepQuest() { if(suspended()) return false; try { setSuspended(true); final QuestState questState; synchronized(this) { questState=this.questState; } if((questState==null)||(stoppingQuest)) return false; final String prefix = CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS)?("QuestScript#"+parseId+" "):""; if(prefix.length()>0) Log.debugOut(prefix+" Quest Stepping"); cleanQuestStep(0); ticksRemaining=-1; setDuration(-1); final List<Object> args=new ArrayList<Object>(); final List<Object> script=parseLoadScripts(script(),new ArrayList<Object>(),args,true); try { questState.stepNumber++; if(prefix.length()>0) Log.debugOut(prefix+" Starting step "+questState.stepNumber+" @line "+questState.lastLine); setVars(script,questState.lastLine); parseQuestScript(script,args,questState.lastLine); } catch(final Exception t) { questState.error=true; Log.errOut("DefaultQuest",t); } if(questState.error) { if(!questState.beQuiet) Log.errOut("Quest",prefix+"One or more errors in '"+name()+"', quest not started"); } else if(!questState.done) { // valid DONE state, when stepping over the end } else if(duration()<0) { Log.errOut("Quest",prefix+"No duration, quest '"+name()+"' not started."); questState.error=true; } if((!questState.error)&&(questState.done)&&(duration()>=0)) { enterRunningState(); return true; } stopQuestInternal(); } finally { setSuspended(false); } return false; } protected int getLineNumberForStep(final int stepNum) { if(stepNum <= 1) return 0; final List<Object> args=new ArrayList<Object>(); final List<Object> oscript=parseLoadScripts(script(),new ArrayList<Object>(),args,true); final List<String> script=parseFinalQuestScript(oscript); int currentStepNumber=1; for(int v=0;v<script.size();v++) { final String s=modifyStringFromArgs(script.get(v),args); final List<String> p=CMParms.parse(s); if(p.size()>0) { final String cmd=p.get(0).toUpperCase(); if(cmd.equals("STEP")) { if((++currentStepNumber)==stepNum) return v+1; } } } return -1; } // this will cause a quest to begin parsing at the given "step". // this will clear out unpreserved objects from previous // step and resume quest script processing. // if this is the LAST step, stopQuestInternal() is automatically called @Override public boolean setQuestStep(final int stepNum) { if(stepNum <=0) return false; final QuestState questState; synchronized(this) { questState=this.questState; } if(questState==null) return false; if(suspended()) return false; final DefaultQuest qSave=this; final Runnable setQuestStepRunnable; setQuestStepRunnable= new Runnable() { private final int targetStepNum=stepNum; private final DefaultQuest Q=qSave; private final QuestState qs=questState; @Override public void run() { final String prefix = CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS)?("QuestScript#"+parseId+" "):""; if(prefix.length()>0) Log.debugOut("QuestScript#"+parseId+" setQuestStep: "+stepNum); boolean stoppingQuest; synchronized(Q) { stoppingQuest=Q.stoppingQuest; // does this really ensure cpu cache thwarting? } if(stoppingQuest) { Log.errOut("DefaultQuest",prefix+"OMG Still stopping "+name()+" when I want to set the "+targetStepNum+" step."); CMLib.threads().scheduleRunnable(this, 1000); return; } if(suspended()) { Log.errOut("DefaultQuest",prefix+"OMG Still stopping "+name()+" when in a state of suspense."); CMLib.threads().scheduleRunnable(this, 1000); return; } try { setSuspended(true); final int newLine=getLineNumberForStep(targetStepNum); if(newLine < 0) // was an illegal target step { Log.errOut("DefaultQuest",prefix+"Quest "+name()+" illegally tried to target the "+targetStepNum+" step."); return; } ticksRemaining=-1; setDuration(-1); final int curStep=qs.stepNumber; if(targetStepNum<curStep) cleanQuestStep(Integer.MAX_VALUE/4); else cleanQuestStep(targetStepNum-curStep-1); final List<Object> args=new ArrayList<Object>(); final List<Object> script=parseLoadScripts(script(),new ArrayList<Object>(),args,true); try { qs.stepNumber=stepNum; qs.lastLine=newLine; if(prefix.length()>0) Log.debugOut(prefix+" Setting step "+questState.stepNumber+" @line "+questState.lastLine); setVars(script,qs.lastLine); parseQuestScript(script,args,qs.lastLine); } catch(final Exception t) { qs.error=true; Log.errOut("DefaultQuest",t); } if(qs.error) { if(!qs.beQuiet) Log.errOut("Quest",prefix+"One or more errors in '"+name()+"', quest not started"); } else if(!qs.done) { // valid DONE state, when stepping over the end } else if(duration()<0) { Log.errOut("Quest",prefix+"No duration, quest '"+name()+"' not started."); qs.error=true; } if((!qs.error)&&(qs.done)&&(duration()>=0)) { enterRunningState(); return; } stopQuestInternal(); } finally { setSuspended(false); } } }; if(stoppingQuest) { CMLib.threads().scheduleRunnable(setQuestStepRunnable, 500); return true; } else { setQuestStepRunnable.run(); return !questState.error; } } @Override public void resetQuest(final int firstPauseTicks) { if(stoppingQuest) return; // ticksRemaining of -1 is OK, it will grab duration resetData=new int[]{firstPauseTicks,ticksRemaining}; stopQuest(); } @Override public void stopQuest() { if((!stoppingQuest)&&(running())) CMLib.coffeeTables().bump(this,CoffeeTableRow.STAT_QUESTSUCCESS); stopQuestInternal(); } // this will stop executing of the quest script. It will clean up // any objects or mobs which may have been loaded, restoring map // mobs to their previous state. public void stopQuestInternal() { if(stoppingQuest) return; // first set everything to complete! synchronized(questState) { for(final PreservedQuestObject PO : questState.worldObjects) PO.preserveState=0; for(final Pair<List<Object>,Integer> p : questState.addons) p.second=Integer.valueOf(0);
{'commit': 'diff --git a/com/planet_ink/coffee_mud/Common/DefaultQuest.java b/com/planet_ink/coffee_mud/Common/DefaultQuest.java\nindex 2b927565f2..8678efe892 100644\n--- a/com/planet_ink/coffee_mud/Common/DefaultQuest.java\n+++ b/com/planet_ink/coffee_mud/Common/DefaultQuest.java\n@@ -5792,11 +5792,24 @@ public class DefaultQuest implements Quest, Tickable, CMObject\n \t\tfinal int x=text.toLowerCase().indexOf(XMLLibrary.FILE_XML_BOUNDARY.toLowerCase());\r\n \t\tif(x>=0)\r\n \t\t{\r\n-\t\t\tfinal String xml;\r\n-\t\t\tif(skipXMLSemicolonFix)\r\n-\t\t\t\txml=text.substring(x+XMLLibrary.FILE_XML_BOUNDARY.length()).trim();\r\n-\t\t\telse\r\n-\t\t\t\txml=CMStrings.replaceAll(text.substring(x+XMLLibrary.FILE_XML_BOUNDARY.length()),"\\\\;",";").trim();\r\n+\t\t\tString xml=text.substring(x+XMLLibrary.FILE_XML_BOUNDARY.length()).trim();\r\n+\t\t\t// mildly risky change to avoid removing ALL ; escapes from JS.\r\n+\t\t\tif((!skipXMLSemicolonFix)\r\n+\t\t\t&&(xml.indexOf("\\\\;")>=0))\r\n+\t\t\t{\r\n+\t\t\t\tfinal StringBuilder newXML = new StringBuilder("");\r\n+\t\t\t\tfor(int i=0;i<xml.length();i++)\r\n+\t\t\t\t{\r\n+\t\t\t\t\tfinal char c=xml.charAt(i);\r\n+\t\t\t\t\tif((c==\'\\\\\')\r\n+\t\t\t\t\t&&(i<xml.length()-1)\r\n+\t\t\t\t\t&&(xml.charAt(i+1)==\';\'))\r\n+\t\t\t\t\t{ /* just skip the slash */}\r\n+\t\t\t\t\telse\r\n+\t\t\t\t\t\tnewXML.append(c);\r\n+\t\t\t\t}\r\n+\t\t\t\txml=newXML.toString();\r\n+\t\t\t}\r\n \t\t\ttext=text.substring(0,x);\r\n \t\t\tif((xml.length()>0)&&(internalFiles==null))\r\n \t\t\t{\r\n', 'commit_subject': 'better semicolon fix.', 'repo_name': 'bozimmerman/CoffeeMud', 'committer': {'name': 'bozimmerman', 'email': 'dc45fe023482b3b890b5e574e53c1d051f45b1ef@zimmers.net', 'time_sec': '1613515329', 'tz_offset': '0', 'date': {'seconds': '1613515329'}}, 'commit_tree': '61012b92211976619b35a5fc7c7c19164bb3bdee', 'commit_message': 'better semicolon fix.\n\ngit-svn-id: 0cdf8356e41b2d8ccbb41bb76c82068fe80b2514@20476 0d6f1817-ed0e-0410-87c9-987e46238f29\n', 'language_name': 'HTML', 'license': 'apache-2.0', 'hunks': '@@ -5792,11 +5792,24 @@ public class DefaultQuest implements Quest, Tickable, CMObject\n \t\tfinal int x=text.toLowerCase().indexOf(XMLLibrary.FILE_XML_BOUNDARY.toLowerCase());\r\n \t\tif(x>=0)\r\n \t\t{\r\n-\t\t\tfinal String xml;\r\n-\t\t\tif(skipXMLSemicolonFix)\r\n-\t\t\t\txml=text.substring(x+XMLLibrary.FILE_XML_BOUNDARY.length()).trim();\r\n-\t\t\telse\r\n-\t\t\t\txml=CMStrings.replaceAll(text.substring(x+XMLLibrary.FILE_XML_BOUNDARY.length()),"\\\\;",";").trim();\r\n+\t\t\tString xml=text.substring(x+XMLLibrary.FILE_XML_BOUNDARY.length()).trim();\r\n+\t\t\t// mildly risky change to avoid removing ALL ; escapes from JS.\r\n+\t\t\tif((!skipXMLSemicolonFix)\r\n+\t\t\t&&(xml.indexOf("\\\\;")>=0))\r\n+\t\t\t{\r\n+\t\t\t\tfinal StringBuilder newXML = new StringBuilder("");\r\n+\t\t\t\tfor(int i=0;i<xml.length();i++)\r\n+\t\t\t\t{\r\n+\t\t\t\t\tfinal char c=xml.charAt(i);\r\n+\t\t\t\t\tif((c==\'\\\\\')\r\n+\t\t\t\t\t&&(i<xml.length()-1)\r\n+\t\t\t\t\t&&(xml.charAt(i+1)==\';\'))\r\n+\t\t\t\t\t{ /* just skip the slash */}\r\n+\t\t\t\t\telse\r\n+\t\t\t\t\t\tnewXML.append(c);\r\n+\t\t\t\t}\r\n+\t\t\t\txml=newXML.toString();\r\n+\t\t\t}\r\n \t\t\ttext=text.substring(0,x);\r\n \t\t\tif((xml.length()>0)&&(internalFiles==null))\r\n \t\t\t{\r\n', 'addition_count': 18, 'deletion_count': 5, 'src_file': 'a/com/planet_ink/coffee_mud/Common/DefaultQuest.java', 'tgt_file': 'b/com/planet_ink/coffee_mud/Common/DefaultQuest.java', 'file_extension': '.java', 'before_file': 'package com.planet_ink.coffee_mud.Common;\nimport com.planet_ink.coffee_mud.core.interfaces.*;\nimport com.planet_ink.coffee_mud.core.*;\nimport com.planet_ink.coffee_mud.core.CMClass.CMObjectType;\nimport com.planet_ink.coffee_mud.core.CMSecurity.DbgFlag;\nimport com.planet_ink.coffee_mud.core.collections.*;\nimport com.planet_ink.coffee_mud.core.exceptions.*;\nimport com.planet_ink.coffee_mud.Abilities.interfaces.*;\nimport com.planet_ink.coffee_mud.Areas.interfaces.*;\nimport com.planet_ink.coffee_mud.Behaviors.interfaces.*;\nimport com.planet_ink.coffee_mud.CharClasses.interfaces.*;\nimport com.planet_ink.coffee_mud.Commands.interfaces.*;\nimport com.planet_ink.coffee_mud.Common.interfaces.*;\nimport com.planet_ink.coffee_mud.Exits.interfaces.*;\nimport com.planet_ink.coffee_mud.Items.interfaces.*;\nimport com.planet_ink.coffee_mud.Libraries.interfaces.*;\nimport com.planet_ink.coffee_mud.Libraries.interfaces.XMLLibrary.XMLTag;\nimport com.planet_ink.coffee_mud.Locales.interfaces.*;\nimport com.planet_ink.coffee_mud.MOBS.interfaces.*;\nimport com.planet_ink.coffee_mud.Races.interfaces.*;\n\nimport java.util.*;\nimport java.util.concurrent.atomic.AtomicBoolean;\nimport java.util.concurrent.atomic.AtomicInteger;\n\nimport org.mozilla.javascript.Context;\nimport org.mozilla.javascript.ScriptableObject;\n\n/*\n   Copyright 2003-2022 Bo Zimmerman\n\n   Licensed under the Apache License, Version 2.0 (the "License");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n\t   http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an "AS IS" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n*/\npublic class DefaultQuest implements Quest, Tickable, CMObject\n{\n\t@Override\n\tpublic String ID()\n\t{\n\t\treturn "DefaultQuest";\n\t}\n\n\tprotected String\tname\t\t\t\t= "";\n\tprotected String\tauthor\t\t\t\t= "";\n\tprotected String\tdisplayName\t\t\t= "";\n\tprotected String\tstartDate\t\t\t= "";\n\tprotected String\tquestType\t\t\t= "";\n\tprotected String\tcategory\t\t\t= "";\n\tprotected String\tinstructions\t\t= "";\n\tprotected int\t\tduration\t\t\t= 450;// about\t\t// 30\t// minutes\n\tprotected boolean\texpires\t\t\t\t= false;\n\tprotected String\trawScriptParameter\t= "";\n\tprotected boolean\tdurable\t\t\t\t= false;\n\tprotected int\t\tminWait\t\t\t\t= -1;\n\tprotected int\t\tminPlayers\t\t\t= -1;\n\tprotected String\tplayerMask\t\t\t= "";\n\tprotected int\t\trunLevel\t\t\t= -1;\n\tprotected int\t\tmaxWait\t\t\t\t= -1;\n\tprotected int\t\twaitRemaining\t\t= -1;\n\tprotected int\t\tticksRemaining\t\t= -1;\n\tprotected long\t\tlastStartDateTime\t= System.currentTimeMillis();\n\tprivate boolean\t\tstoppingQuest\t\t= false;\n\tprotected int\t\tspawn\t\t\t\t= SPAWN_NO;\n\tprivate QuestState\tquestState\t\t\t= new QuestState();\n\tprivate boolean\t\tcopy\t\t\t\t= false;\n\tpublic DVector\t\tinternalFiles\t\t= null;\n\tprivate int[]\t\tresetData\t\t\t= null;\n\n\tprivate final AtomicBoolean\t\t\tsuspended\t\t\t= new AtomicBoolean(false);\n\tprotected final Map<String,Long>\tstepEllapsedTimes\t= Collections.synchronizedMap(new HashMap<String,Long>());\n\tprotected final Map<String,Long>\twinners\t\t\t\t= new CaselessTreeMap<Long>();\n\tprotected volatile Behavable\t\tcheckAcceptHost\t\t= null;\n\tprotected volatile ScriptingEngine\tcheckAcceptEng\t\t= null;\n\tprotected final Object[] \t\t\tobjs\t\t\t\t= new Object[ScriptingEngine.SPECIAL_NUM_OBJECTS];\n\n\tprotected volatile int parseId = 0;\n\tprotected final static AtomicInteger globalParseId\t\t\t= new AtomicInteger(0);\n\n\t// the unique name of the quest\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\tname = newName;\n\t}\n\n\t// the author of the quest\n\t@Override\n\tpublic String author()\n\t{\n\t\treturn author;\n\t}\n\n\t@Override\n\tpublic void setAuthor(final String newName)\n\t{\n\t\tauthor = newName;\n\t}\n\n\t// the display name of the quest\n\t@Override\n\tpublic String displayName()\n\t{\n\t\treturn displayName;\n\t}\n\n\t@Override\n\tpublic void setDisplayName(final String newName)\n\t{\n\t\tdisplayName = newName;\n\t}\n\n\t@Override\n\tpublic String instructions()\n\t{\n\t\treturn instructions;\n\t}\n\n\t@Override\n\tpublic void setInstructions(final String instructions)\n\t{\n\t\tthis.instructions = instructions;\n\t}\n\n\t@Override\n\tpublic String questTypeDesc()\n\t{\n\t\treturn this.questType;\n\t}\n\n\t@Override\n\tpublic void setQuestTypeDesc(final String newType)\n\t{\n\t\tthis.questType = newType;\n\t}\n\n\t@Override\n\tpublic String questCategory()\n\t{\n\t\treturn this.category;\n\t}\n\n\t@Override\n\tpublic void setQuestCategory(final String newCat)\n\t{\n\t\tthis.category = newCat;\n\t}\n\n\tprotected ScriptingEngine ensureEngine()\n\t{\n\t\tif((checkAcceptHost == null)\n\t\t||(this.checkAcceptEng==null)\n\t\t||((checkAcceptHost.fetchBehavior(checkAcceptEng.ID())!=checkAcceptEng)\n\t\t\t&&(!CMParms.contains(checkAcceptHost.scripts(),checkAcceptEng))))\n\t\t{\n\t\t\tfor(final Iterator<List<Object>> l = questState.addons.firstIterator();l.hasNext();)\n\t\t\t{\n\t\t\t\tfinal List<Object> V = l.next();\n\t\t\t\tif((V.size()>1)&&(V.get(1) instanceof ScriptingEngine))\n\t\t\t\t{\n\t\t\t\t\tfinal Behavable B=(Behavable)V.get(0);\n\t\t\t\t\tfinal ScriptingEngine E=(ScriptingEngine)V.get(1);\n\t\t\t\t\tif(((B.fetchBehavior(E.ID())==E) || (CMParms.contains(B.scripts(),E)))\n\t\t\t\t\t&&(E.isFunc("DO_ACCEPT"))\n\t\t\t\t\t&&(E.isFunc("CAN_ACCEPT")))\n\t\t\t\t\t{\n\t\t\t\t\t\tthis.checkAcceptHost=(Behavable)V.get(0);\n\t\t\t\t\t\tthis.checkAcceptEng=E;\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\treturn checkAcceptEng;\n\t}\n\n\t@Override\n\tpublic boolean canAcceptQuest(final MOB mob)\n\t{\n\t\tif(!running() || stopping())\n\t\t\treturn false;\n\t\tif(mob != null)\n\t\t{\n\t\t\tif((playerMask() != null)\n\t\t\t&&(playerMask().length()>0)\n\t\t\t&&(!CMLib.masking().maskCheck(playerMask(), mob, true)))\n\t\t\t\treturn false;\n\t\t\tfor(final Enumeration<ScriptingEngine> e= mob.scripts();e.hasMoreElements();)\n\t\t\t{\n\t\t\t\tfinal ScriptingEngine E = e.nextElement();\n\t\t\t\tif((E.defaultQuestName()!=null)\n\t\t\t\t&&(name().equalsIgnoreCase(E.defaultQuestName())))\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\tfinal ScriptingEngine acceptEngine = this.ensureEngine();\n\t\tif(acceptEngine != null)\n\t\t{\n\t\t\tfinal Behavable B = this.checkAcceptHost;\n\t\t\tif(!(B instanceof Environmental))\n\t\t\t\treturn false;\n\t\t\tif(mob==null)\n\t\t\t\treturn true;\n\t\t\tfinal PhysicalAgent P=(B instanceof PhysicalAgent)?(PhysicalAgent)B:mob;\n\t\t\tfinal MOB M=(B instanceof MOB)?(MOB)B:mob;\n\t\t\tString eval = acceptEngine.callFunc("CAN_ACCEPT", mob.Name(), P, mob, (Environmental) B, M, null, null, mob.Name(), objs);\n\t\t\tif(eval == null)\n\t\t\t\treturn false;\n\t\t\teval=eval.toLowerCase();\n\t\t\treturn (!eval.equals("cancel")) && (eval.length()!=0);\n\t\t}\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic void acceptQuest(final MOB mob)\n\t{\n\t\tfinal ScriptingEngine acceptEng = this.ensureEngine();\n\t\tif(acceptEng != null)\n\t\t{\n\t\t\tfinal Behavable B = this.checkAcceptHost;\n\t\t\tif(!(B instanceof Environmental))\n\t\t\t\treturn;\n\t\t\tif(mob==null)\n\t\t\t\treturn;\n\t\t\tif(!this.canAcceptQuest(mob))\n\t\t\t\treturn;\n\t\t\tfinal PhysicalAgent P=(B instanceof PhysicalAgent)?(PhysicalAgent)B:mob;\n\t\t\tfinal MOB M=(B instanceof MOB)?(MOB)B:mob;\n\t\t\tacceptEng.callFunc("DO_ACCEPT", mob.Name(), P, mob, (Environmental) B, M, null, null, mob.Name(), objs);\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 Object O=this.clone();\n\t\t\treturn (CMObject)O;\n\t\t}\n\t\tcatch(final CloneNotSupportedException e)\n\t\t{\n\t\t\treturn newInstance();\n\t\t}\n\t}\n\n\t@Override\n\tpublic boolean suspended()\n\t{\n\t\treturn suspended.get();\n\t}\n\n\t@Override\n\tpublic void setSuspended(final boolean truefalse)\n\t{\n\t\tsuspended.set(truefalse);\n\t}\n\n\t@Override\n\tpublic CMObject newInstance()\n\t{\n\t\ttry\n\t\t{\n\t\t\treturn getClass().newInstance();\n\t\t}\n\t\tcatch (final Exception e)\n\t\t{\n\t\t\treturn new DefaultQuest();\n\t\t}\n\t}\n\n\t@Override\n\tpublic void initializeClass()\n\t{\n\t}\n\n\t@Override\n\tpublic Object getDesignatedObject(final String named)\n\t{\n\t\tfinal QCODES q=(QCODES)CMath.s_valueOf(QCODES.class, named.toUpperCase().trim());\n\t\tif(q != null)\n\t\t{\n\t\t\tswitch(q)\n\t\t\t{\n\t\t\tcase CLASS:\n\t\t\t\treturn ID();\n\t\t\tcase NAME:\n\t\t\t\treturn name();\n\t\t\tcase DURATION:\n\t\t\t\treturn "" + duration();\n\t\t\tcase WAIT:\n\t\t\t\treturn "" + minWait();\n\t\t\tcase MINPLAYERS:\n\t\t\t\treturn "" + minPlayers();\n\t\t\tcase PLAYERMASK:\n\t\t\t\treturn "" + playerMask();\n\t\t\tcase RUNLEVEL:\n\t\t\t\treturn "" + runLevel();\n\t\t\tcase DATE:\n\t\t\t\treturn "" + startDate();\n\t\t\tcase MUDDAY:\n\t\t\t\treturn "" + startDate();\n\t\t\tcase INTERVAL:\n\t\t\t\treturn "" + waitInterval();\n\t\t\tcase SPAWNABLE:\n\t\t\t\treturn SPAWN_DESCS[getSpawn()];\n\t\t\tcase DISPLAY:\n\t\t\t\treturn displayName();\n\t\t\tcase INSTRUCTIONS:\n\t\t\t\treturn instructions();\n\t\t\tcase PERSISTANCE:\n\t\t\t\treturn Boolean.toString(durable);\n\t\t\tcase AUTHOR:\n\t\t\t\treturn "" + author();\n\t\t\tcase EXPIRATION:\n\t\t\t\treturn ""+(isCopy()?duration():0);\n\t\t\tcase QUESTTYPE:\n\t\t\t\treturn questType;\n\t\t\tcase CATEGORY:\n\t\t\t\treturn category;\n\t\t\t}\n\t\t}\n\t\treturn questState.getStat(named);\n\t}\n\n\t@Override\n\tpublic void internalQuestDelete()\n\t{\n\t\tif(isCopy())\n\t\t\treturn;\n\t\tif((internalFiles!=null)&&(internalFiles.size()>0))\n\t\t{\n\t\t\tfor(int i=0;i<internalFiles.size();i++)\n\t\t\t{\n\t\t\t\tfinal String filename=((String)internalFiles.get(i,1)).toUpperCase();\n\t\t\t\tfinal List<String> delThese=new ArrayList<String>();\n\t\t\t\tboolean foundKey=false;\n\t\t\t\tfor(final Iterator<String> k=Resources.findResourceKeys(filename);k.hasNext();)\n\t\t\t\t{\n\t\t\t\t\tfinal String key=k.next();\n\t\t\t\t\tif(key.startsWith("PARSEDPRG: ")&&(key.toUpperCase().endsWith(filename)))\n\t\t\t\t\t{\n\t\t\t\t\t\tfoundKey = true;\n\t\t\t\t\t\tdelThese.add(key);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(foundKey)\n\t\t\t\t{\n\t\t\t\t\tfor(int d=0;d<delThese.size();d++)\n\t\t\t\t\t\tResources.removeResource(delThese.get(d));\n\t\t\t\t}\n\t\t\t}\n\t\t\tinternalFiles.clear();\n\t\t\tinternalFiles=null;\n\t\t}\n\t}\n\n\t// the unique name of the quest\n\t@Override\n\tpublic String startDate()\n\t{\n\t\treturn startDate;\n\t}\n\n\t@Override\n\tpublic void setStartDate(final String newDate)\n\t{\n\t\tfinal int x=newDate.indexOf(\'-\');\n\t\tif((x>0)\n\t\t&&(CMath.isMathExpression(newDate.substring(0,x)))\n\t\t&&(CMath.isMathExpression(newDate.substring(x+1))))\n\t\t\tstartDate=newDate;\n\t}\n\n\t@Override\n\tpublic void setStartMudDate(final String newDate)\n\t{\n\t\tsetStartDate(newDate);\n\t\tif(startDate.equals(newDate))\n\t\t\tstartDate="MUDDAY "+startDate;\n\t}\n\n\t// the duration, in ticks\n\t@Override\n\tpublic int duration()\n\t{\n\t\treturn duration;\n\t}\n\n\t@Override\n\tpublic void setDuration(final int newTicks)\n\t{\n\t\tif(duration != newTicks)\n\t\t{\n\t\t\tif(CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS))\n\t\t\t\tLog.debugOut("QuestScript#"+parseId+" Setting duration to "+newTicks);\n\t\t}\n\t\tduration = newTicks;\n\t}\n\n\t@Override\n\tpublic void setCopy(final boolean truefalse)\n\t{\n\t\tcopy = truefalse;\n\t}\n\n\t@Override\n\tpublic boolean isCopy()\n\t{\n\t\treturn copy;\n\t}\n\n\t@Override\n\tpublic void setSpawn(final int spawnFlag)\n\t{\n\t\tspawn = (spawnFlag < 0) ? 0 : spawnFlag;\n\t}\n\n\t@Override\n\tpublic int getSpawn()\n\t{\n\t\treturn spawn;\n\t}\n\n\t@Override\n\tpublic int minPlayers()\n\t{\n\t\treturn minPlayers;\n\t}\n\n\t@Override\n\tpublic void setMinPlayers(final int players)\n\t{\n\t\tminPlayers = players;\n\t}\n\n\t@Override\n\tpublic int runLevel()\n\t{\n\t\treturn runLevel;\n\t}\n\n\t@Override\n\tpublic void setRunLevel(final int level)\n\t{\n\t\trunLevel = level;\n\t}\n\n\t@Override\n\tpublic String playerMask()\n\t{\n\t\treturn playerMask;\n\t}\n\n\t@Override\n\tpublic void setPlayerMask(final String mask)\n\t{\n\t\tplayerMask = mask;\n\t}\n\n\t// the rest of the script.  This may be semicolon-separated instructions,\n\t// or a LOAD command followed by the quest script path.\n\t@Override\n\tpublic boolean setScript(final String parm, final boolean showErrors)\n\t{\n\t\tif(CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS))\n\t\t\tLog.debugOut("QuestScript#"+parseId+" Setting script "+parm.length());\n\t\trawScriptParameter=parm;\n\t\tname="";\n\t\tauthor="";\n\t\tdisplayName="";\n\t\tstartDate="";\n\t\tduration=-1;\n\t\tminWait=-1;\n\t\tmaxWait=-1;\n\t\tminPlayers=-1;\n\t\tspawn=SPAWN_NO;\n\t\tplayerMask="";\n\t\trunLevel=-1;\n\t\tinternalFiles=null;\n\t\tdurable=false;\n\t\tfinal List<Object> questScripts=parseLoadScripts(parm,new ArrayList<Object>(),new ArrayList<Object>(),showErrors);\n\t\tif(questScripts.size()==0)\n\t\t\treturn false;\n\t\tsetVars(questScripts,0);\n\t\tif(isCopy())\n\t\t\tspawn=SPAWN_NO;\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic String script()\n\t{\n\t\treturn rawScriptParameter;\n\t}\n\n\t@Override\n\tpublic void autostartup()\n\t{\n\t\tif(!resetWaitRemaining(0))\n\t\t\tCMLib.threads().deleteTick(this,Tickable.TICKID_QUEST);\n\t\telse\n\t\tif(!running())\n\t\t\tCMLib.threads().startTickDown(this,Tickable.TICKID_QUEST,1);\n\t}\n\n\t@Override\n\tpublic void setVars(final List<?> script, final int startAtLine)\n\t{\n\t\tList<String> parsedLine=null;\n\t\tString var=null;\n\t\tString val=null;\n\t\tfinal List<List<String>> setScripts=CMLib.quests().getNextQuestScriptCommands(script,"SET",startAtLine);\n\t\tfor(int v=0;v<setScripts.size();v++)\n\t\t{\n\t\t\tparsedLine=setScripts.get(v);\n\t\t\tif(parsedLine.size()>1)\n\t\t\t{\n\t\t\t\tvar=parsedLine.get(1).toUpperCase();\n\t\t\t\tval=CMParms.combine(parsedLine,2);\n\t\t\t\tif(isStat(var))\n\t\t\t\t\tsetStat(var,val);\n\t\t\t}\n\t\t}\n\t}\n\n\t@Override\n\tpublic StringBuffer getResourceFileData(final String named, final boolean showErrors)\n\t{\n\t\tint index=-1;\n\t\tif(internalFiles!=null)\n\t\t{\n\t\t\tindex=internalFiles.indexOf(named.toUpperCase().trim());\n\t\t\tif(index>=0)\n\t\t\t\treturn (StringBuffer)internalFiles.get(index,2);\n\t\t}\n\t\tfinal StringBuffer buf=new CMFile(Resources.makeFileResourceName(named),null,showErrors?CMFile.FLAG_LOGERRORS:0).text();\n\t\treturn buf;\n\t}\n\n\tprivate void questifyScriptableBehavs(final PhysicalAgent E)\n\t{\n\t\tif((E==null)\n\t\t||((E instanceof MOB)&&(((MOB)E).isPlayer())))\n\t\t\treturn;\n\t\tBehavior B=null;\n\t\tfor(final Enumeration<Behavior> e=E.behaviors();e.hasMoreElements();)\n\t\t{\n\t\t\tB=e.nextElement();\n\t\t\tif(B instanceof ScriptingEngine)\n\t\t\t\t((ScriptingEngine)B).registerDefaultQuest(this);\n\t\t}\n\t\tif((E instanceof Item)\n\t\t&&((((Item)E).numBehaviors()>0)||(((Item)E).numScripts()>0))\n\t\t&&(!CMLib.threads().isTicking(E, Tickable.TICKID_ITEM_BEHAVIOR)))\n\t\t{\n\t\t\tCMLib.threads().startTickDown(E,Tickable.TICKID_ITEM_BEHAVIOR,1);\n\t\t}\n\t}\n\n\tprivate Enumeration<Room> getAppropriateRoomSet(final QuestState q)\n\t{\n\t\tif(q.roomGroup!=null)\n\t\t\treturn new IteratorEnumeration<Room>(q.roomGroup.iterator());\n\t\telse\n\t\tif(q.area!=null)\n\t\t\treturn q.area.getMetroMap();\n\t\treturn CMLib.map().rooms();\n\t}\n\n\tprivate final Enumeration<Room> getAppropriateRoomSet(final QuestState q, final Iterable<Room> useThese)\n\t{\n\t\tif(useThese == null)\n\t\t\treturn getAppropriateRoomSet(q);\n\t\treturn new IteratorEnumeration<Room>(useThese.iterator());\n\t}\n\n\t@SuppressWarnings({ "rawtypes", "unchecked" })\n\tprivate List sortSelect(final Environmental E,\n\t\t\t\t\t\t\tfinal String str,\n\t\t\t\t\t\t\tList choices,\n\t\t\t\t\t\t\tfinal List choices0,\n\t\t\t\t\t\t\tfinal List choices1,\n\t\t\t\t\t\t\tfinal List choices2,\n\t\t\t\t\t\t\tfinal List choices3)\n\t{\n\t\tfinal String mname=E.name().toUpperCase();\n\t\tfinal String mdisp=E.displayText().toUpperCase();\n\t\tfinal String mdesc=E.description().toUpperCase();\n\t\tif(str.equalsIgnoreCase("any"))\n\t\t{\n\t\t\tchoices=choices0;\n\t\t\tchoices0.add(E);\n\t\t}\n\t\telse\n\t\tif(mname.equalsIgnoreCase(str))\n\t\t{\n\t\t\tchoices=choices0;\n\t\t\tchoices0.add(E);\n\t\t}\n\t\telse\n\t\tif(CMLib.english().containsString(mname,str))\n\t\t{\n\t\t\tif((choices==null)||(choices==choices2)||(choices==choices3))\n\t\t\t\tchoices=choices1;\n\t\t\tchoices1.add(E);\n\t\t}\n\t\telse\n\t\tif(CMLib.english().containsString(mdisp,str))\n\t\t{\n\t\t\tif((choices==null)||(choices==choices3))\n\t\t\t\tchoices=choices2;\n\t\t\tchoices2.add(E);\n\t\t}\n\t\telse\n\t\tif(CMLib.english().containsString(mdesc,str))\n\t\t{\n\t\t\tif(choices==null)\n\t\t\t\tchoices=choices3;\n\t\t\tchoices3.add(E);\n\t\t}\n\t\treturn choices;\n\t}\n\n\tprivate TimeClock getMysteryTimeNowFromState()\n\t{\n\t\tTimeClock NOW=null;\n\t\tif(questState.mysteryData==null)\n\t\t\treturn (TimeClock)CMLib.time().globalClock().copyOf();\n\t\tif((questState.mysteryData.whereAt!=null)&&(questState.mysteryData.whereAt.getArea()!=null))\n\t\t\tNOW=(TimeClock)questState.mysteryData.whereAt.getArea().getTimeObj().copyOf();\n\t\telse\n\t\tif((questState.mysteryData.whereHappened!=null)&&(questState.mysteryData.whereHappened.getArea()!=null))\n\t\t\tNOW=(TimeClock)questState.mysteryData.whereHappened.getArea().getTimeObj().copyOf();\n\t\telse\n\t\tif((questState.room!=null)&&(questState.room.getArea()!=null))\n\t\t\tNOW=(TimeClock)questState.room.getArea().getTimeObj().copyOf();\n\t\telse\n\t\tif(questState.area!=null)\n\t\t\tNOW=(TimeClock)questState.area.getTimeObj().copyOf();\n\t\telse\n\t\t\tNOW=(TimeClock)CMLib.time().globalClock().copyOf();\n\t\treturn NOW;\n\t}\n\n\t@SuppressWarnings("unchecked")\n\tpublic void parseQuestScriptWArgs(final List<?> script, List<Object> args)\n\t{\n\t\tif(args==null)\n\t\t\targs=new ArrayList<Object>();\n\t\tif(args.size()==0)\n\t\t\tparseQuestScript(script, args, -1);\n\t\telse\n\t\t{\n\t\t\tfinal List<Object> allArgs=new ArrayList<Object>();\n\t\t\tfor(int i=0;i<args.size();i++)\n\t\t\t{\n\t\t\t\tfinal Object O=args.get(i);\n\t\t\t\tif(O instanceof List)\n\t\t\t\t{\n\t\t\t\t\tfinal List<Object> V=(List<Object>)O;\n\t\t\t\t\tif(allArgs.size()==0)\n\t\t\t\t\t{\n\t\t\t\t\t\tfor(int v=0;v<V.size();v++)\n\t\t\t\t\t\t\tallArgs.add(new XVector<Object>(V.get(v)));\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal List<Object> allArgsCopy=new XVector<Object>(allArgs);\n\t\t\t\t\t\tallArgs.clear();\n\t\t\t\t\t\tfor(int aa=0;aa<allArgsCopy.size();aa++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal List<Object> argSet=(List<Object>)allArgsCopy.get(aa);\n\t\t\t\t\t\t\tfor(int v=0;v<V.size();v++)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal List<Object> V2=new XVector<Object>(argSet);\n\t\t\t\t\t\t\t\tV2.add(V.get(v));\n\t\t\t\t\t\t\t\tallArgs.add(V2);\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}\n\t\t\t\telse\n\t\t\t\tif(allArgs.size()==0)\n\t\t\t\t\tallArgs.add(new XVector<Object>(O));\n\t\t\t\telse\n\t\t\t\tfor(int aa=0;aa<allArgs.size();aa++)\n\t\t\t\t\t((List<Object>)allArgs.get(aa)).add(O);\n\t\t\t}\n\t\t\tfor(int a=0;a<allArgs.size();a++)\n\t\t\t\tparseQuestScript(script, (List<Object>)allArgs.get(a),-1);\n\t\t}\n\t}\n\n\tprotected void errorOccurred(final QuestState q, final boolean quietFlag, final String msg)\n\t{\n\t\tfinal String prefix = CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS)?("QuestScript#"+parseId+" "):"";\n\t\tif(!quietFlag)\n\t\t\tLog.errOut("Quest",prefix+msg);\n\t\telse\n\t\tif(CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS))\n\t\t\tLog.debugOut("Quest",prefix+msg);\n\t\tq.error=true;\n\t}\n\n\tprivate void sizeDownTo(final List<?> V, final int num)\n\t{\n\t\tif(num<0)\n\t\t\treturn;\n\t\tif(num==0)\n\t\t\tV.clear();\n\t\telse\n\t\twhile(V.size()>num)\n\t\t\tV.remove(CMLib.dice().roll(1,V.size(),-1));\n\t}\n\n\tprotected String breakOutMaskString(final String s, final List<String> p)\n\t{\n\t\tString mask="";\n\t\tint x=s.toUpperCase().lastIndexOf("MASK=");\n\t\tif(x>=0)\n\t\t{\n\t\t\tmask=s.substring(x+5).trim();\n\t\t\tint i=0;\n\t\t\twhile((i<p.size())&&(p.get(i).toUpperCase().indexOf("MASK=")<0))\n\t\t\t\ti++;\n\t\t\tif(i<=p.size())\n\t\t\t{\n\t\t\t\tfinal String pp=p.get(i);\n\t\t\t\tx=pp.toUpperCase().indexOf("MASK=");\n\t\t\t\tif((x>0)&&(pp.substring(0,x).trim().length()>0))\n\t\t\t\t{\n\t\t\t\t\tp.set(i,pp.substring(0,x).trim());\n\t\t\t\t\ti++;\n\t\t\t\t}\n\t\t\t\twhile(i<p.size())\n\t\t\t\t\tp.remove(i);\n\t\t\t}\n\t\t}\n\t\treturn mask.trim();\n\t}\n\n\tprotected void filterOutThoseInUse(final List<? extends Environmental> choices, final String choicesStr, final QuestState q, final boolean isQuiet, final boolean reselect)\n\t{\n\t\tif((choices!=null)&&(choices.size()>0))\n\t\t{\n\t\t\tfinal Set<String> inUseByWhom=new TreeSet<String>();\n\t\t\tfor(int c=choices.size()-1;c>=0;c--)\n\t\t\t{\n\t\t\t\tfinal Environmental E=choices.get(c);\n\t\t\t\tif((E instanceof Physical) && (CMLib.flags().isCloaked((Physical)E)))\n\t\t\t\t{\n\t\t\t\t\tfinal Quest Q=CMLib.quests().objectInUse(E);\n\t\t\t\t\tif((!reselect)\n\t\t\t\t\t||(Q==null)\n\t\t\t\t\t||(!(Q instanceof DefaultQuest))\n\t\t\t\t\t||(!((DefaultQuest)Q).questState.reselectable.contains(E)))\n\t\t\t\t\t\tchoices.remove(c);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\tif((!reselect)&&(!q.reselectable.contains(E)))\n\t\t\t\t{\n\t\t\t\t\tfinal Quest Q=CMLib.quests().objectInUse(E);\n\t\t\t\t\tif(Q!=null)\n\t\t\t\t\t{\n\t\t\t\t\t\tif((!(Q instanceof DefaultQuest))\n\t\t\t\t\t\t||(!((DefaultQuest)Q).questState.reselectable.contains(E)))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tchoices.remove(c);\n\t\t\t\t\t\t\tinUseByWhom.add(Q.name());\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\tif((choices.size()==0)&&(!isQuiet))\n\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', all choices were taken: \'"+choicesStr+"\' by: "+CMParms.toListString(inUseByWhom)+".");\n\t\t}\n\t}\n\n\t// all internal\n\tprotected List<String> parseFinalQuestScript(final List<?> script)\n\t{\n\t\tfinal List<String> finalScript=new ArrayList<String>();\n\t\tfor(int v=0;v<script.size();v++)\n\t\t{\n\t\t\tif(script.get(v) instanceof String)\n\t\t\t\tfinalScript.add((String)script.get(v));\n\t\t\telse\n\t\t\tif(script.get(v) instanceof List)\n\t\t\t{\n\t\t\t\tfinal int vs=v;\n\t\t\t\twhile((v<script.size())&&(script.get(v) instanceof List))\n\t\t\t\t\tv++;\n\t\t\t\tfinal int rnum=vs+CMLib.dice().roll(1,v-vs,-1);\n\t\t\t\tif(rnum<script.size())\n\t\t\t\t{\n\t\t\t\t\tfinal List<?> V=(List<?>)script.get(rnum);\n\t\t\t\t\tfor(int v2=0;v2<V.size();v2++)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(V.get(v2) instanceof String)\n\t\t\t\t\t\t\tfinalScript.add((String)V.get(v2));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn finalScript;\n\t}\n\n\t@SuppressWarnings("unchecked")\n\tpublic void parseQuestScript(List<?> script, final List<Object> args, final int startLine)\n\t{\n\t\tfinal boolean debug=CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS);\n\t\tparseId = DefaultQuest.globalParseId.addAndGet(1);\n\t\tif(debug)\n\t\t\tLog.debugOut("QuestScript#"+parseId+": Parsing \'"+name()+"\' from script size "+script.size()+" from line "+startLine);\n\t\tscript=parseFinalQuestScript(script);\n\t\tfinal QuestState q;\n\t\tsynchronized(this)\n\t\t{\n\t\t\tq=questState;\n\t\t}\n\t\tint vStart=startLine;\n\t\tif(vStart<0)\n\t\t\tvStart=0;\n\t\tq.done=false;\n\t\tif(vStart>=script.size())\n\t\t\treturn;\n\t\tq.startLine=vStart;\n\t\tfor(int v=vStart;v<script.size();v++)\n\t\t{\n\t\t\tif(startLine>=0)\n\t\t\t\tq.lastLine=v;\n\t\t\tfinal String s=modifyStringFromArgs((String)script.get(v),args);\n\t\t\tfinal List<String> p=CMParms.parse(s);\n\t\t\tboolean isQuiet=q.beQuiet;\n\t\t\tboolean optional=q.isOptional;\n\t\t\tif(p.size()>0)\n\t\t\t{\n\t\t\t\tString cmd=p.get(0).toUpperCase();\n\t\t\t\tif(debug)\n\t\t\t\t{\n\t\t\t\t\tfinal String flags=(isQuiet?"Q":"")+(optional?"P":"");\n\t\t\t\t\tLog.debugOut("QuestScript#"+parseId+": Doing command \'"+cmd+"\' ("+flags+") from line "+v+": "+s);\n\t\t\t\t}\n\t\t\t\tif(cmd.equals("<SCRIPT>"))\n\t\t\t\t{\n\t\t\t\t\tfinal StringBuffer jscript=new StringBuffer("");\n\t\t\t\t\twhile(((++v)<script.size())\n\t\t\t\t\t&&(!((String)script.get(v)).trim().toUpperCase().startsWith("</SCRIPT>")))\n\t\t\t\t\t\tjscript.append(((String)script.get(v))+"\\n");\n\t\t\t\t\tif(v>=script.size())\n\t\t\t\t\t{\n\t\t\t\t\t\terrorOccurred(q,false,"Quest \'"+name()+"\', <SCRIPT> command without </SCRIPT> found.");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif(!CMSecurity.isApprovedJScript(jscript))\n\t\t\t\t\t{\n\t\t\t\t\t\terrorOccurred(q,false,"Quest \'"+name()+"\', <SCRIPT> not approved.  Use MODIFY JSCRIPT to approve.");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tfinal Context cx = Context.enter();\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal JScriptQuest scope = new JScriptQuest(this,q);\n\t\t\t\t\t\tcx.initStandardObjects(scope);\n\t\t\t\t\t\tscope.defineFunctionProperties(JScriptQuest.functions,\n\t\t\t\t\t\t\t\t\t\t\t\t\t   JScriptQuest.class,\n\t\t\t\t\t\t\t\t\t\t\t\t\t   ScriptableObject.DONTENUM);\n\t\t\t\t\t\tcx.evaluateString(scope, jscript.toString(),"<cmd>", 1, null);\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\terrorOccurred(q,false,"Quest \'"+name()+"\', JScript q.error: "+e.getMessage()+".");\n\t\t\t\t\t\tContext.exit();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tContext.exit();\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif(cmd.equals("OPTIONAL"))\n\t\t\t\t{\n\t\t\t\t\toptional=true;\n\t\t\t\t\tif(p.size()<2)\n\t\t\t\t\t{\n\t\t\t\t\t\tq.isOptional=true;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tp.remove(0);\n\t\t\t\t\tcmd=p.get(0).toUpperCase();\n\t\t\t\t\tif(cmd.equals("ON")||cmd.equals("OFF"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(cmd.equals("OFF"))\n\t\t\t\t\t\t\toptional=false;\n\t\t\t\t\t\tif(p.size()<2)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.isOptional=optional;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tp.remove(0);\n\t\t\t\t\t\tcmd=p.get(0).toUpperCase();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(cmd.equals("QUIET"))\n\t\t\t\t{\n\t\t\t\t\tif(p.size()<2)\n\t\t\t\t\t{\n\t\t\t\t\t\tq.beQuiet=true;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tisQuiet=true;\n\t\t\t\t\tp.remove(0);\n\t\t\t\t\tcmd=p.get(0).toUpperCase();\n\t\t\t\t\tif(cmd.equals("ON")||cmd.equals("OFF"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(cmd.equals("OFF"))\n\t\t\t\t\t\t\tisQuiet=false;\n\t\t\t\t\t\tif(p.size()<2)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.beQuiet=optional;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tp.remove(0);\n\t\t\t\t\t\tcmd=p.get(0).toUpperCase();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(cmd.equals("STEP"))\n\t\t\t\t{\n\t\t\t\t\tq.autoStepAfterDuration=false;\n\t\t\t\t\tif((p.size()>1)&&(p.get(1).equalsIgnoreCase("BREAK")))\n\t\t\t\t\t{\n\t\t\t\t\t\tq.lastLine=script.size();\n\t\t\t\t\t\tq.done=true;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif((p.size()>1)&&(p.get(1).equalsIgnoreCase("BACK")))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(startLine>=0)\n\t\t\t\t\t\t\tq.lastLine=q.startLine;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif((p.size()>1)&&(p.get(1).equalsIgnoreCase("AUTO")))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(startLine>=0)\n\t\t\t\t\t\t\tq.lastLine=v+1;\n\t\t\t\t\t\tq.autoStepAfterDuration=true;\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(startLine>=0)\n\t\t\t\t\t\t\tq.lastLine=v+1;\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif(cmd.equals("RESET"))\n\t\t\t\t{\n\t\t\t\t\tif(q.room!=null)\n\t\t\t\t\t\tCMLib.map().resetRoom(q.room, true);\n\t\t\t\t\telse\n\t\t\t\t\tif(q.roomGroup!=null)\n\t\t\t\t\t{\n\t\t\t\t\t\tfor(int r=0;r<q.roomGroup.size();r++)\n\t\t\t\t\t\t\tCMLib.map().resetRoom(q.roomGroup.get(r), true);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(q.area!=null)\n\t\t\t\t\t\tCMLib.map().resetArea(q.area);\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\terrorOccurred(q,false,"Quest \'"+name()+"\', no resettable room, roomgroup, area, or areagroup set.");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\tif(cmd.equals("SET"))\n\t\t\t\t{\n\t\t\t\t\tif(p.size()<2)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', unfound variable on set.");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcmd=p.get(1).toUpperCase();\n\t\t\t\t\tif(cmd.equals("AREA"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.area=null;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.area = (Area) getObjectIfSpecified(p, args, 2, 0);\n\t\t\t\t\t\t\tq.envObject = q.area;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.area=null;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal List<String> names=new ArrayList<String>();\n\t\t\t\t\t\tfinal List<Area> areas=new ArrayList<Area>();\n\t\t\t\t\t\tif((p.size()>3)&&(p.get(2).equalsIgnoreCase("any")))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfor(int ip=3;ip<p.size();ip++)\n\t\t\t\t\t\t\t\tnames.add(p.get(ip));\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tnames.add(CMParms.combine(p,2));\n\t\t\t\t\t\tfor(int n=0;n<names.size();n++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal String areaName=names.get(n);\n\t\t\t\t\t\t\tfinal int oldSize=areas.size();\n\t\t\t\t\t\t\tif(areaName.equalsIgnoreCase("any"))\n\t\t\t\t\t\t\t\tareas.add(CMLib.map().getRandomArea());\n\t\t\t\t\t\t\tif(oldSize==areas.size())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfor (final Enumeration<Area> e = CMLib.map().areas(); e.hasMoreElements(); )\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal Area A2 = e.nextElement();\n\t\t\t\t\t\t\t\t\tif (A2.Name().equalsIgnoreCase(areaName))\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tareas.add(A2);\n\t\t\t\t\t\t\t\t\t\tbreak;\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\tif(oldSize==areas.size())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfor(final Enumeration<Boardable> e=CMLib.map().ships();e.hasMoreElements();)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal Boardable ship=e.nextElement();\n\t\t\t\t\t\t\t\t\tfinal Area A2=(ship != null) ? ship.getArea() : null;\n\t\t\t\t\t\t\t\t\tif(A2 != null)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif (A2.Name().equalsIgnoreCase(areaName))\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tareas.add(A2);\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\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\tif(oldSize==areas.size())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfor(final Enumeration<Area> e=CMLib.map().areas();e.hasMoreElements();)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal Area A2=e.nextElement();\n\t\t\t\t\t\t\t\t\tif(CMLib.english().containsString(A2.Name(),areaName))\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tareas.add(A2);\n\t\t\t\t\t\t\t\t\t\tbreak;\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\tif(oldSize==areas.size())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfor(final Enumeration<Boardable> e=CMLib.map().ships();e.hasMoreElements();)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal Boardable ship=e.nextElement();\n\t\t\t\t\t\t\t\t\tfinal Area A2=(ship != null) ? ship.getArea() : null;\n\t\t\t\t\t\t\t\t\tif(A2 != null)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif(CMLib.english().containsString(A2.Name(),areaName))\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tareas.add(A2);\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\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\tif(areas.size()>0)\n\t\t\t\t\t\t\tq.area=areas.get(CMLib.dice().roll(1,areas.size(),-1));\n\t\t\t\t\t\tif(q.area==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', unknown area \'"+CMParms.combine(p,2)+"\'.");\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\telse\n\t\t\t\t\tif(cmd.equals("AREAGROUP"))\n\t\t\t\t\t{\n\t\t\t\t\t\tq.area=null;\n\t\t\t\t\t\tq.roomGroup=null;\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tfinal List<String> names=new ArrayList<String>();\n\t\t\t\t\t\tfinal List<Area> areas=new ArrayList<Area>();\n\t\t\t\t\t\tfor(int ip=2;ip<p.size();ip++)\n\t\t\t\t\t\t\tnames.add(p.get(ip));\n\t\t\t\t\t\tfor(int n=0;n<names.size();n++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal String areaName=names.get(n);\n\t\t\t\t\t\t\tfinal int oldSize=areas.size();\n\t\t\t\t\t\t\tif(areaName.equalsIgnoreCase("any"))\n\t\t\t\t\t\t\t\tareas.add(CMLib.map().getRandomArea());\n\t\t\t\t\t\t\tfinal boolean addAll=areaName.equalsIgnoreCase("all");\n\t\t\t\t\t\t\tif(oldSize==areas.size())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(addAll)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfor (final Enumeration<Area> e = CMLib.map().areas(); e.hasMoreElements(); )\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tfinal Area A2=e.nextElement();\n\t\t\t\t\t\t\t\t\t\tif(!areas.contains(A2))\n\t\t\t\t\t\t\t\t\t\t\tareas.add(A2);\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\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tArea A2=CMLib.map().findArea(areaName);\n\t\t\t\t\t\t\t\t\tif(A2 == null)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tfinal Boardable ship=CMLib.map().findShip(areaName, true);\n\t\t\t\t\t\t\t\t\t\tif(ship != null)\n\t\t\t\t\t\t\t\t\t\t\tA2=ship.getArea();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif((A2!=null)&&(!areas.contains(A2)))\n\t\t\t\t\t\t\t\t\t\tareas.add(A2);\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\tif(areas.size()>0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.roomGroup=Collections.synchronizedList(new ArrayList<Room>());\n\t\t\t\t\t\t\tRoom R=null;\n\t\t\t\t\t\t\tfor (final Area A : areas)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfor(final Enumeration<Room> e2=A.getMetroMap();e2.hasMoreElements();)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tR=e2.nextElement();\n\t\t\t\t\t\t\t\t\tif(!q.roomGroup.contains(R))\n\t\t\t\t\t\t\t\t\t\tq.roomGroup.add(R);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tq.envObject=q.roomGroup;\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\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', unknown areas \'"+CMParms.combine(p,2)+"\'.");\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\telse\n\t\t\t\t\tif(cmd.equals("MOBTYPE"))\n\t\t\t\t\t{\n\t\t\t\t\t\tboolean reselect=false;\n\t\t\t\t\t\tif((p.size()>2)&&(p.get(2).equalsIgnoreCase("reselect")))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tp.remove(2);\n\t\t\t\t\t\t\treselect=true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mob=null;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mob=(MOB)getObjectIfSpecified(p,args,2,0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mob=null;\n\t\t\t\t\t\t\tfinal List<MOB> choices=new ArrayList<MOB>(); // thread safe -- not building a group\n\t\t\t\t\t\t\tfinal List<String> mobTypes=CMParms.parse(CMParms.combine(p,2).toUpperCase());\n\t\t\t\t\t\t\tfor(int t=0;t<mobTypes.size();t++)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal String mobType=mobTypes.get(t);\n\t\t\t\t\t\t\t\tif(mobType.startsWith("-"))\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\tif(q.mobGroup==null)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tfor(final Enumeration<Room> e=getAppropriateRoomSet(q);e.hasMoreElements();)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tfinal Room R2=e.nextElement();\n\t\t\t\t\t\t\t\t\t\t\tfor(int i=0;i<R2.numInhabitants();i++)\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tfinal MOB M2=R2.fetchInhabitant(i);\n\t\t\t\t\t\t\t\t\t\t\t\tif((M2!=null)\n\t\t\t\t\t\t\t\t\t\t\t\t&&(M2.isMonster())\n\t\t\t\t\t\t\t\t\t\t\t\t&&((M2.amUltimatelyFollowing()==null)||(M2.amUltimatelyFollowing().isMonster())))\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tif(mobType.equalsIgnoreCase("any"))\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tchoices.add(M2);\n\t\t\t\t\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\t\t\t\tif((CMClass.classID(M2).toUpperCase().indexOf(mobType)>=0)\n\t\t\t\t\t\t\t\t\t\t\t\t\t||(M2.charStats().getMyRace().racialCategory().toUpperCase().indexOf(mobType)>=0)\n\t\t\t\t\t\t\t\t\t\t\t\t\t||(M2.charStats().getMyRace().name().toUpperCase().indexOf(mobType)>=0)\n\t\t\t\t\t\t\t\t\t\t\t\t\t||(M2.charStats().getCurrentClass().name(M2.charStats().getCurrentClassLevel()).toUpperCase().indexOf(mobType)>=0))\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tchoices.add(M2);\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tcatch (final NoSuchElementException e)\n\t\t\t\t\t\t\t\t\t{\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\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tfor(final MOB M2 : q.mobGroup)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tif((M2!=null)\n\t\t\t\t\t\t\t\t\t\t\t&&(M2.isMonster())\n\t\t\t\t\t\t\t\t\t\t\t&&((M2.amUltimatelyFollowing()==null)||(M2.amUltimatelyFollowing().isMonster())))\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tif(mobType.equalsIgnoreCase("any"))\n\t\t\t\t\t\t\t\t\t\t\t\t\tchoices.add(M2);\n\t\t\t\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\t\t\tif((CMClass.classID(M2).toUpperCase().indexOf(mobType)>=0)\n\t\t\t\t\t\t\t\t\t\t\t\t||(M2.charStats().getMyRace().racialCategory().toUpperCase().indexOf(mobType)>=0)\n\t\t\t\t\t\t\t\t\t\t\t\t||(M2.charStats().getMyRace().name().toUpperCase().indexOf(mobType)>=0)\n\t\t\t\t\t\t\t\t\t\t\t\t||(M2.charStats().getCurrentClass().name(M2.charStats().getCurrentClassLevel()).toUpperCase().indexOf(mobType)>=0))\n\t\t\t\t\t\t\t\t\t\t\t\t\tchoices.add(M2);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tcatch (final NoSuchElementException e)\n\t\t\t\t\t\t\t\t\t{\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\n\t\t\t\t\t\t\tfor(int t=0;t<mobTypes.size();t++)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tString mobType=mobTypes.get(t);\n\t\t\t\t\t\t\t\tif(!mobType.startsWith("-"))\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\tmobType=mobType.substring(1);\n\t\t\t\t\t\t\t\tfor(int i=choices.size()-1;i>=0;i--)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal MOB M2=choices.get(i);\n\t\t\t\t\t\t\t\t\tif((M2!=null)\n\t\t\t\t\t\t\t\t\t&&(M2.isMonster())\n\t\t\t\t\t\t\t\t\t&&((M2.amUltimatelyFollowing()==null)||(M2.amUltimatelyFollowing().isMonster())))\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif((CMClass.classID(M2).toUpperCase().indexOf(mobType)>=0)\n\t\t\t\t\t\t\t\t\t\t||(M2.charStats().getMyRace().racialCategory().toUpperCase().indexOf(mobType)>=0)\n\t\t\t\t\t\t\t\t\t\t||(M2.charStats().getMyRace().name().toUpperCase().indexOf(mobType)>=0)\n\t\t\t\t\t\t\t\t\t\t||(M2.charStats().getCurrentClass().name(M2.charStats().getCurrentClassLevel()).toUpperCase().indexOf(mobType)>=0)\n\t\t\t\t\t\t\t\t\t\t||(M2.name().toUpperCase().indexOf(mobType)>=0)\n\t\t\t\t\t\t\t\t\t\t||(M2.displayText().toUpperCase().indexOf(mobType)>=0))\n\t\t\t\t\t\t\t\t\t\t\tchoices.remove(M2);\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\tthis.filterOutThoseInUse(choices, p.toString(), q, isQuiet, reselect);\n\t\t\t\t\t\t\tif(choices.size()>0)\n\t\t\t\t\t\t\t\tq.mob=choices.get(CMLib.dice().roll(1,choices.size(),-1));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(q.mob==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !mobtype \'"+p+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(reselect)\n\t\t\t\t\t\t\tq.reselectable.add(q.mob);\n\n\t\t\t\t\t\t// why is this being done -- atm, this is a simple map mob, minding his own business.\n\t\t\t\t\t\tquestifyScriptableBehavs(q.mob);\n\n\t\t\t\t\t\tif(q.room!=null)\n\t\t\t\t\t\t\tq.room.bringMobHere(q.mob,false);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tq.room=q.mob.location();\n\t\t\t\t\t\tq.envObject=q.mob;\n\t\t\t\t\t\truntimeRegisterObject(q.mob);\n\t\t\t\t\t\tif(q.room!=null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.area=q.room.getArea();\n\t\t\t\t\t\t\tq.room.recoverRoomStats();\n\t\t\t\t\t\t\tq.room.showHappens(CMMsg.MSG_OK_ACTION,null);\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(cmd.equals("MOBGROUP"))\n\t\t\t\t\t{\n\t\t\t\t\t\tq.mobGroup=null;\n\t\t\t\t\t\tboolean reselect=false;\n\t\t\t\t\t\tif((p.size()>2)&&(p.get(2).equalsIgnoreCase("reselect")))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tp.remove(2);\n\t\t\t\t\t\t\treselect=true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tList<MOB> choices=null;\n\t\t\t\t\t\tString mobName=CMParms.combine(p,2).toUpperCase();\n\t\t\t\t\t\tfinal String maskStr=breakOutMaskString(s,p);\n\t\t\t\t\t\tfinal MaskingLibrary.CompiledZMask mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr);\n\t\t\t\t\t\tif(mask!=null)\n\t\t\t\t\t\t\tmobName=CMParms.combine(p,2).toUpperCase();\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tchoices=(List<MOB>)getObjectIfSpecified(p,args,2,1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(mobName.length()==0)\n\t\t\t\t\t\t\t\tmobName="ANY";\n\t\t\t\t\t\t\tfinal boolean addAll=mobName.equalsIgnoreCase("all");\n\t\t\t\t\t\t\tfinal List<MOB> choices0=new ArrayList<MOB>();\n\t\t\t\t\t\t\tfinal List<MOB> choices1=new ArrayList<MOB>();\n\t\t\t\t\t\t\tfinal List<MOB> choices2=new ArrayList<MOB>();\n\t\t\t\t\t\t\tfinal List<MOB> choices3=new ArrayList<MOB>();\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfor(final Enumeration<Room> e=getAppropriateRoomSet(q);e.hasMoreElements();)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal Room R2=e.nextElement();\n\t\t\t\t\t\t\t\t\tfor(int i=0;i<R2.numInhabitants();i++)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tfinal MOB M2=R2.fetchInhabitant(i);\n\t\t\t\t\t\t\t\t\t\tif((M2!=null)\n\t\t\t\t\t\t\t\t\t\t&&(M2.isMonster())\n\t\t\t\t\t\t\t\t\t\t&&((M2.amUltimatelyFollowing()==null)||(M2.amUltimatelyFollowing().isMonster())))\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tif(CMLib.masking().maskCheck(mask,M2,true))\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tif(addAll)\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tchoices = choices0;\n\t\t\t\t\t\t\t\t\t\t\t\t\tchoices.add(M2);\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\t\t\t\tchoices=sortSelect(M2,mobName,choices,choices0,choices1,choices2,choices3);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\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\tcatch (final NoSuchElementException e)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis.filterOutThoseInUse(choices, p.toString(), q, isQuiet, reselect);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif((choices!=null)&&(choices.size()>0))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mobGroup=Collections.synchronizedList(new ArrayList<MOB>(choices));\n\t\t\t\t\t\t\tif(reselect)\n\t\t\t\t\t\t\t\tq.reselectable.addAll(choices);\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\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !mobgroup \'"+mobName+":"+maskStr+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tq.envObject=q.mobGroup;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(cmd.equals("PCMOBGROUP"))\n\t\t\t\t\t{\n\t\t\t\t\t\tq.mobGroup=null;\n\t\t\t\t\t\tboolean reselect=false;\n\t\t\t\t\t\tif((p.size()>2)&&(p.get(2).equalsIgnoreCase("reselect")))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tp.remove(2);\n\t\t\t\t\t\t\treselect=true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tList<MOB> choices=null;\n\t\t\t\t\t\tString mobName=CMParms.combine(p,2).toUpperCase();\n\t\t\t\t\t\tfinal String maskStr=breakOutMaskString(s,p);\n\t\t\t\t\t\tfinal MaskingLibrary.CompiledZMask mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr);\n\t\t\t\t\t\tif(mask!=null)\n\t\t\t\t\t\t\tmobName=CMParms.combine(p,2).toUpperCase();\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tchoices=(List<MOB>)getObjectIfSpecified(p,args,2,1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(mobName.length()==0)\n\t\t\t\t\t\t\t\tmobName="ANY";\n\t\t\t\t\t\t\tfinal boolean addAll=mobName.equalsIgnoreCase("all");\n\t\t\t\t\t\t\tfinal List<MOB> choices0=new ArrayList<MOB>();\n\t\t\t\t\t\t\tfinal List<MOB> choices1=new ArrayList<MOB>();\n\t\t\t\t\t\t\tfinal List<MOB> choices2=new ArrayList<MOB>();\n\t\t\t\t\t\t\tfinal List<MOB> choices3=new ArrayList<MOB>();\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfor(final Iterator<Session> si=CMLib.sessions().sessions();si.hasNext();)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal Session S=si.next();\n\t\t\t\t\t\t\t\t\tfinal MOB M2=S.mob();\n\t\t\t\t\t\t\t\t\tif((!S.isStopped())\n\t\t\t\t\t\t\t\t\t&&(M2!=null)\n\t\t\t\t\t\t\t\t\t&&(CMLib.flags().isInTheGame(M2, true))\n\t\t\t\t\t\t\t\t\t&&((q.roomGroup==null)||(q.roomGroup.contains(M2.location())))\n\t\t\t\t\t\t\t\t\t&&((q.area==null)||(q.area==M2.location().getArea()))\n\t\t\t\t\t\t\t\t\t&&(CMLib.masking().maskCheck(mask,M2,true)))\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif(addAll)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tchoices = choices0;\n\t\t\t\t\t\t\t\t\t\t\tchoices.add(M2);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\t\tchoices=sortSelect(M2,mobName,choices,choices0,choices1,choices2,choices3);\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\tcatch (final NoSuchElementException e)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tthis.filterOutThoseInUse(choices, p.toString(), q, isQuiet, reselect);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif((choices!=null)&&(choices.size()>0))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mobGroup=Collections.synchronizedList(new ArrayList<MOB>(choices));\n\t\t\t\t\t\t\tif(reselect)\n\t\t\t\t\t\t\t\tq.reselectable.addAll(choices);\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\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !mobgroup \'"+mobName+":"+maskStr+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tq.envObject=q.mobGroup;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(cmd.equals("ITEMGROUP"))\n\t\t\t\t\t{\n\t\t\t\t\t\tq.itemGroup=null;\n\t\t\t\t\t\tboolean reselect=false;\n\t\t\t\t\t\tif((p.size()>2)&&(p.get(2).equalsIgnoreCase("reselect")))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tp.remove(2);\n\t\t\t\t\t\t\treselect=true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tList<Item> choices=null;\n\t\t\t\t\t\tString itemName=CMParms.combine(p,2).toUpperCase();\n\t\t\t\t\t\tfinal String maskStr=breakOutMaskString(s,p);\n\t\t\t\t\t\tfinal MaskingLibrary.CompiledZMask mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr);\n\t\t\t\t\t\tif(mask!=null)\n\t\t\t\t\t\t\titemName=CMParms.combine(p,2).toUpperCase();\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tchoices=(List<Item>)getObjectIfSpecified(p,args,2,1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal List<Item> choices0=new ArrayList<Item>();\n\t\t\t\t\t\t\tfinal List<Item> choices1=new ArrayList<Item>();\n\t\t\t\t\t\t\tfinal List<Item> choices2=new ArrayList<Item>();\n\t\t\t\t\t\t\tfinal List<Item> choices3=new ArrayList<Item>();\n\t\t\t\t\t\t\tif(itemName.length()==0)\n\t\t\t\t\t\t\t\titemName="ANY";\n\t\t\t\t\t\t\tfinal boolean addAll=itemName.equalsIgnoreCase("all");\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfor(final Enumeration<Room> e=getAppropriateRoomSet(q);e.hasMoreElements();)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal Room R2=e.nextElement();\n\t\t\t\t\t\t\t\t\tfor(int i=0;i<R2.numItems();i++)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tfinal Item I2=R2.getItem(i);\n\t\t\t\t\t\t\t\t\t\tif(I2!=null)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tif(CMLib.masking().maskCheck(mask,I2,true))\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tif(addAll)\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tchoices = choices0;\n\t\t\t\t\t\t\t\t\t\t\t\t\tchoices.add(I2);\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\t\t\t\tchoices=sortSelect(I2,itemName,choices,choices0,choices1,choices2,choices3);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\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\tcatch (final NoSuchElementException e)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis.filterOutThoseInUse(choices, p.toString(), q, isQuiet, reselect);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif((choices!=null)&&(choices.size()>0))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(reselect)\n\t\t\t\t\t\t\t\tq.reselectable.addAll(choices);\n\t\t\t\t\t\t\tq.itemGroup=Collections.synchronizedList(new ArrayList<Item>(choices));\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\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !itemgroup \'"+itemName+":"+maskStr+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tq.envObject=q.itemGroup;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(cmd.equals("ABILITYGROUP"))\n\t\t\t\t\t{\n\t\t\t\t\t\tq.abilityGroup=null;\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tList<Ability> choices=null;\n\t\t\t\t\t\tString abilityName=CMParms.combine(p,2).toUpperCase();\n\t\t\t\t\t\tfinal String maskStr=breakOutMaskString(s,p);\n\t\t\t\t\t\tfinal MaskingLibrary.CompiledZMask mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr);\n\t\t\t\t\t\tif(mask!=null)\n\t\t\t\t\t\t\tabilityName=CMParms.combine(p,2).toUpperCase();\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tchoices=(List<Ability>)getObjectIfSpecified(p,args,2,1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal List<Ability> choices0=new ArrayList<Ability>();\n\t\t\t\t\t\t\tfinal List<Ability> choices1=new ArrayList<Ability>();\n\t\t\t\t\t\t\tfinal List<Ability> choices2=new ArrayList<Ability>();\n\t\t\t\t\t\t\tfinal List<Ability> choices3=new ArrayList<Ability>();\n\t\t\t\t\t\t\tif(abilityName.length()==0)\n\t\t\t\t\t\t\t\tabilityName="ANY";\n\t\t\t\t\t\t\tfinal boolean addAll=abilityName.equalsIgnoreCase("all");\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfor(final Enumeration<Room> e=getAppropriateRoomSet(q);e.hasMoreElements();)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal Room R2=e.nextElement();\n\t\t\t\t\t\t\t\t\tfor(int i=0;i<R2.numEffects();i++)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tfinal Ability A2=R2.fetchEffect(i);\n\t\t\t\t\t\t\t\t\t\tif(A2!=null)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tif(CMLib.masking().maskCheck(mask,A2,true))\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tif(addAll)\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tchoices = choices0;\n\t\t\t\t\t\t\t\t\t\t\t\t\tchoices.add(A2);\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\t\t\t\tchoices=sortSelect(A2,abilityName,choices,choices0,choices1,choices2,choices3);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\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\tcatch (final NoSuchElementException e)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis.filterOutThoseInUse(choices, p.toString(), q, isQuiet, true);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif((choices!=null)&&(choices.size()>0))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.abilityGroup=Collections.synchronizedList(new ArrayList<Ability>(choices));\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\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !abilityGroup \'"+abilityName+":"+maskStr+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tq.envObject=q.itemGroup;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(cmd.equals("ITEMTYPE"))\n\t\t\t\t\t{\n\t\t\t\t\t\tboolean reselect=false;\n\t\t\t\t\t\tif((p.size()>2)&&(p.get(2).equalsIgnoreCase("reselect")))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tp.remove(2);\n\t\t\t\t\t\t\treselect=true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.item=null;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.item=(Item)getObjectIfSpecified(p,args,2,0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.item=null;\n\t\t\t\t\t\t\tfinal List<Item> choices=new ArrayList<Item>();\n\t\t\t\t\t\t\tfinal List<String> itemTypes=new ArrayList<String>();\n\t\t\t\t\t\t\tfor(int i=2;i<p.size();i++)\n\t\t\t\t\t\t\t\titemTypes.add(p.get(i));\n\t\t\t\t\t\t\tfor(int t=0;t<itemTypes.size();t++)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal String itemType=itemTypes.get(t).toUpperCase();\n\t\t\t\t\t\t\t\tif(itemType.startsWith("-"))\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif(q.itemGroup==null)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tfor(final Enumeration<Room> e=getAppropriateRoomSet(q);e.hasMoreElements();)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tfinal Room R2=e.nextElement();\n\t\t\t\t\t\t\t\t\t\t\tfor(int i=0;i<R2.numItems();i++)\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tfinal Item I2=R2.getItem(i);\n\t\t\t\t\t\t\t\t\t\t\t\tif((I2!=null))\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tif(itemType.equalsIgnoreCase("any"))\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tchoices.add(I2);\n\t\t\t\t\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\t\t\t\tif(CMClass.classID(I2).toUpperCase().indexOf(itemType)>=0)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tchoices.add(I2);\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tfor(final Item I2 : q.itemGroup)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tif((I2!=null))\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tif(itemType.equalsIgnoreCase("any"))\n\t\t\t\t\t\t\t\t\t\t\t\t\tchoices.add(I2);\n\t\t\t\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\t\t\tif(CMClass.classID(I2).toUpperCase().indexOf(itemType)>=0)\n\t\t\t\t\t\t\t\t\t\t\t\t\tchoices.add(I2);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\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\tcatch(final NoSuchElementException e)\n\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\n\t\t\t\t\t\t\tfor(int t=0;t<itemTypes.size();t++)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tString itemType=itemTypes.get(t);\n\t\t\t\t\t\t\t\tif(!itemType.startsWith("-"))\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\titemType=itemType.substring(1);\n\t\t\t\t\t\t\t\tfor(int i=choices.size()-1;i>=0;i--)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal Item I2=choices.get(i);\n\t\t\t\t\t\t\t\t\tif((CMClass.classID(I2).toUpperCase().indexOf(itemType)>=0)\n\t\t\t\t\t\t\t\t\t||(I2.name().toUpperCase().indexOf(itemType)>=0)\n\t\t\t\t\t\t\t\t\t||(I2.displayText().toUpperCase().indexOf(itemType)>=0))\n\t\t\t\t\t\t\t\t\t\tchoices.remove(I2);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis.filterOutThoseInUse(choices, p.toString(), q, isQuiet, reselect);\n\t\t\t\t\t\t\tif(choices.size()>0)\n\t\t\t\t\t\t\t\tq.item=choices.get(CMLib.dice().roll(1,choices.size(),-1));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(q.item==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !itemtype \'"+p+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tquestifyScriptableBehavs(q.item); // this really makes little sense, though is harmless\n\t\t\t\t\t\tif(reselect)\n\t\t\t\t\t\t\tq.reselectable.add(q.item);\n\t\t\t\t\t\tif(q.room!=null)\n\t\t\t\t\t\t\tq.room.moveItemTo(q.item,ItemPossessor.Expire.Never,ItemPossessor.Move.Followers);\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif(q.item.owner() instanceof Room)\n\t\t\t\t\t\t\tq.room=(Room)q.item.owner();\n\t\t\t\t\t\tq.envObject=q.item;\n\t\t\t\t\t\tif(q.room!=null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.area=q.room.getArea();\n\t\t\t\t\t\t\tq.room.recoverRoomStats();\n\t\t\t\t\t\t\tq.room.showHappens(CMMsg.MSG_OK_ACTION,null);\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(cmd.equals("PRESERVE"))\n\t\t\t\t\t\tq.preserveState=CMath.parseIntExpression(p.get(2));\n\t\t\t\t\telse\n\t\t\t\t\tif(cmd.equals("LOCALE")||cmd.equals("LOCALEGROUP")||cmd.equals("LOCALEGROUPAROUND"))\n\t\t\t\t\t{\n\t\t\t\t\t\tint range=0;\n\t\t\t\t\t\tif(cmd.equals("LOCALE"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.room=(Room)getObjectIfSpecified(p,args,2,0);\n\t\t\t\t\t\t\t\tif(q.room!=null)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tq.area=q.room.getArea();\n\t\t\t\t\t\t\t\t\tq.envObject=q.room;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.room=null;\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(cmd.equals("LOCALEGROUPAROUND"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.roomGroup=null;\n\t\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\trange=CMath.parseIntExpression(p.get(2));\n\t\t\t\t\t\t\tif(range<=0)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !localegrouparound #\'"+(p.get(2)+"\'."));\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tp.remove(2);\n\t\t\t\t\t\t\tif(q.room==null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', localegrouparound !room.");\n\t\t\t\t\t\t\t\tbreak;\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\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.roomGroup=(List<Room>)getObjectIfSpecified(p,args,2,1);\n\t\t\t\t\t\t\t\tq.envObject=q.roomGroup;\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.roomGroup=null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tfinal List<String> names=new ArrayList<String>();\n\t\t\t\t\t\tif((p.size()>3)&&(p.get(2).equalsIgnoreCase("any")))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfor(int ip=3;ip<p.size();ip++)\n\t\t\t\t\t\t\t\tnames.add(p.get(ip));\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tnames.add(CMParms.combine(p,2));\n\t\t\t\t\t\tfinal List<Room> choices=new ArrayList<Room>();\n\t\t\t\t\t\tList<Room> useThese=null;\n\t\t\t\t\t\tif(range>0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tTrackingLibrary.TrackingFlags flags;\n\t\t\t\t\t\t\tflags = CMLib.tracking().newFlags()\n\t\t\t\t\t\t\t\t\t.plus(TrackingLibrary.TrackingFlag.AREAONLY);\n\t\t\t\t\t\t\tuseThese=CMLib.tracking().getRadiantRooms(q.room,flags,range);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor(int n=0;n<names.size();n++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal String localeName=names.get(n).toUpperCase();\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal boolean addAll=(localeName.equalsIgnoreCase("any")\n\t\t\t\t\t\t\t\t\t\t\t\t||localeName.equalsIgnoreCase("all"));\n\t\t\t\t\t\t\t\tfor(final Enumeration<Room> r=getAppropriateRoomSet(q, useThese);r.hasMoreElements();)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal Room R2=r.nextElement();\n\t\t\t\t\t\t\t\t\tif(addAll||CMClass.classID(R2).toUpperCase().indexOf(localeName)>=0)\n\t\t\t\t\t\t\t\t\t\tchoices.add(R2);\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tfinal int dom=R2.domainType();\n\t\t\t\t\t\t\t\t\t\tif((dom&Room.INDOORS)>0)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tif(Room.DOMAIN_INDOORS_DESCS[dom-Room.INDOORS].indexOf(localeName)>=0)\n\t\t\t\t\t\t\t\t\t\t\t\tchoices.add(R2);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\tif(Room.DOMAIN_OUTDOOR_DESCS[dom].indexOf(localeName)>=0)\n\t\t\t\t\t\t\t\t\t\t\tchoices.add(R2);\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\tcatch(final NoSuchElementException e)\n\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\tif(cmd.equalsIgnoreCase("LOCALEGROUP")||cmd.equalsIgnoreCase("LOCALEGROUPAROUND"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(choices.size()>0)\n\t\t\t\t\t\t\t\tq.roomGroup=Collections.synchronizedList(new ArrayList<Room>(choices));\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(optional)\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !localegroup \'"+CMParms.combine(p,2)+"\'.");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tq.envObject=q.roomGroup;\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\tif(choices.size()>0)\n\t\t\t\t\t\t\t\tq.room=choices.get(CMLib.dice().roll(1,choices.size(),-1));\n\t\t\t\t\t\t\tif(q.room==null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !locale \'"+CMParms.combine(p,2)+"\'.");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tq.area=q.room.getArea();\n\t\t\t\t\t\t\tq.envObject=q.room;\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(cmd.equals("ROOM")||cmd.equals("ROOMGROUP")||cmd.equals("ROOMGROUPAROUND"))\n\t\t\t\t\t{\n\t\t\t\t\t\tint range=0;\n\t\t\t\t\t\tif(cmd.equals("ROOM"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.room=(Room)getObjectIfSpecified(p,args,2,0);\n\t\t\t\t\t\t\t\tif(q.room!=null)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tq.area=q.room.getArea();\n\t\t\t\t\t\t\t\t\tq.envObject=q.room;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.room=null;\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(cmd.equals("ROOMGROUPAROUND"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.roomGroup=null;\n\t\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\trange=CMath.s_parseIntExpression(p.get(2));\n\t\t\t\t\t\t\tif(range<=0)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\' roomgrouparound #\'"+(p.get(2)+"\'."));\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tp.remove(2);\n\t\t\t\t\t\t\tif(q.room==null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', roomgrouparound !room.");\n\t\t\t\t\t\t\t\tbreak;\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\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.roomGroup=(List<Room>)getObjectIfSpecified(p,args,2,1);\n\t\t\t\t\t\t\t\tq.envObject=q.roomGroup;\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.roomGroup=null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tList<Room> choices=null;\n\t\t\t\t\t\tfinal List<Room> choices0=new ArrayList<Room>();\n\t\t\t\t\t\tfinal List<Room> choices1=new ArrayList<Room>();\n\t\t\t\t\t\tfinal List<Room> choices2=new ArrayList<Room>();\n\t\t\t\t\t\tfinal List<Room> choices3=new ArrayList<Room>();\n\t\t\t\t\t\tfinal List<String> names=new ArrayList<String>();\n\t\t\t\t\t\tfinal String maskStr=breakOutMaskString(s,p);\n\t\t\t\t\t\tfinal MaskingLibrary.CompiledZMask mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr);\n\t\t\t\t\t\tif((p.size()>3)&&(p.get(2).equalsIgnoreCase("any")))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfor(int ip=3;ip<p.size();ip++)\n\t\t\t\t\t\t\t\tnames.add(p.get(ip));\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tnames.add(CMParms.combine(p,2));\n\t\t\t\t\t\tList<Room> useThese=null;\n\t\t\t\t\t\tif(range>0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tTrackingLibrary.TrackingFlags flags;\n\t\t\t\t\t\t\tflags = CMLib.tracking().newFlags()\n\t\t\t\t\t\t\t\t\t.plus(TrackingLibrary.TrackingFlag.AREAONLY);\n\t\t\t\t\t\t\tuseThese=CMLib.tracking().getRadiantRooms(q.room,flags,range);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor(int n=0;n<names.size();n++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal String localeName=names.get(n).toUpperCase();\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal boolean addAll=localeName.equalsIgnoreCase("any")\n\t\t\t\t\t\t\t\t\t\t\t ||localeName.equalsIgnoreCase("all");\n\t\t\t\t\t\t\t\tfor(final Enumeration<Room> r=getAppropriateRoomSet(q, useThese);r.hasMoreElements();)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal Room R2=r.nextElement();\n\t\t\t\t\t\t\t\t\tif(R2==null)\n\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\tfinal String display=R2.displayText().toUpperCase();\n\t\t\t\t\t\t\t\t\tfinal String desc=R2.description().toUpperCase();\n\t\t\t\t\t\t\t\t\tif((mask!=null)&&(!CMLib.masking().maskCheck(mask,R2,true)))\n\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\tif(addAll)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tchoices=choices0;\n\t\t\t\t\t\t\t\t\t\tchoices0.add(R2);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\tif(CMLib.map().getExtendedRoomID(R2).equalsIgnoreCase(localeName))\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tchoices=choices0;\n\t\t\t\t\t\t\t\t\t\tchoices0.add(R2);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\tif(display.equals(localeName))\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif((choices==null)||(choices==choices2)||(choices==choices3))\n\t\t\t\t\t\t\t\t\t\t\tchoices=choices1;\n\t\t\t\t\t\t\t\t\t\tchoices1.add(R2);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\tif(CMLib.english().containsString(display,localeName))\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif((choices==null)||(choices==choices3))\n\t\t\t\t\t\t\t\t\t\t\tchoices=choices2;\n\t\t\t\t\t\t\t\t\t\tchoices2.add(R2);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\tif(CMLib.english().containsString(desc,localeName))\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif(choices==null)\n\t\t\t\t\t\t\t\t\t\t\tchoices=choices3;\n\t\t\t\t\t\t\t\t\t\tchoices3.add(R2);\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\tcatch(final NoSuchElementException e)\n\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\tif(cmd.equalsIgnoreCase("ROOMGROUP")||cmd.equalsIgnoreCase("ROOMGROUPAROUND"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif((choices!=null)&&(choices.size()>0))\n\t\t\t\t\t\t\t\tq.roomGroup=Collections.synchronizedList(new ArrayList<Room>(choices));\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(optional)\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !roomgroup \'"+CMParms.combine(p,2)+"\'.");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tq.envObject=q.roomGroup;\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\tif((choices!=null)&&(choices.size()>0))\n\t\t\t\t\t\t\t\tq.room=choices.get(CMLib.dice().roll(1,choices.size(),-1));\n\t\t\t\t\t\t\tif(q.room==null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !room \'"+CMParms.combine(p,2)+"\'.");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tq.area=q.room.getArea();\n\t\t\t\t\t\t\tq.envObject=q.room;\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(cmd.equals("MOB"))\n\t\t\t\t\t{\n\t\t\t\t\t\tboolean reselect=false;\n\t\t\t\t\t\tif((p.size()>2)&&(p.get(2).equalsIgnoreCase("reselect")))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tp.remove(2);\n\t\t\t\t\t\t\treselect=true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mob=null;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tString mobName=CMParms.combine(p,2).toUpperCase();\n\t\t\t\t\t\tfinal String maskStr=breakOutMaskString(s,p);\n\t\t\t\t\t\tfinal MaskingLibrary.CompiledZMask mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr);\n\t\t\t\t\t\tif(mask!=null)\n\t\t\t\t\t\t\tmobName=CMParms.combine(p,2).toUpperCase();\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mob=(MOB)getObjectIfSpecified(p,args,2,0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mob=null;\n\t\t\t\t\t\t\tList<MOB> choices=null;\n\t\t\t\t\t\t\tfinal List<MOB> choices0=new ArrayList<MOB>();\n\t\t\t\t\t\t\tfinal List<MOB> choices1=new ArrayList<MOB>();\n\t\t\t\t\t\t\tfinal List<MOB> choices2=new ArrayList<MOB>();\n\t\t\t\t\t\t\tfinal List<MOB> choices3=new ArrayList<MOB>();\n\t\t\t\t\t\t\tif(mobName.length()==0)\n\t\t\t\t\t\t\t\tmobName="ANY";\n\t\t\t\t\t\t\tif(q.mobGroup!=null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfor(final MOB M2 : q.mobGroup)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif((M2!=null)\n\t\t\t\t\t\t\t\t\t&&(M2.isMonster())\n\t\t\t\t\t\t\t\t\t&&((M2.amUltimatelyFollowing()==null)||(M2.amUltimatelyFollowing().isMonster())))\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif(!CMLib.masking().maskCheck(mask,M2,true))\n\t\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t\tchoices=sortSelect(M2,mobName,choices,choices0,choices1,choices2,choices3);\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\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfor(final Enumeration<Room> e=getAppropriateRoomSet(q);e.hasMoreElements();)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tfinal Room R2=e.nextElement();\n\t\t\t\t\t\t\t\t\t\tif(R2!=null)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tfor(int i=0;i<R2.numInhabitants();i++)\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tfinal MOB M2=R2.fetchInhabitant(i);\n\t\t\t\t\t\t\t\t\t\t\t\tif((M2!=null)\n\t\t\t\t\t\t\t\t\t\t\t\t&&(M2.isMonster())\n\t\t\t\t\t\t\t\t\t\t\t\t&&((M2.amUltimatelyFollowing()==null)||(M2.amUltimatelyFollowing().isMonster())))\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tif(!CMLib.masking().maskCheck(mask,M2,true))\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t\t\t\t\tchoices=sortSelect(M2,mobName,choices,choices0,choices1,choices2,choices3);\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\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\tcatch(final NoSuchElementException e)\n\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\tthis.filterOutThoseInUse(choices, p.toString(), q, isQuiet, reselect);\n\t\t\t\t\t\t\tif((choices!=null)&&(choices.size()>0))\n\t\t\t\t\t\t\t\tq.mob=choices.get(CMLib.dice().roll(1,choices.size(),-1));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(q.mob==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !mob \'"+mobName+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(reselect)\n\t\t\t\t\t\t\tq.reselectable.add(q.mob);\n\t\t\t\t\t\tquestifyScriptableBehavs(q.mob);  // just weird\n\t\t\t\t\t\tif(q.room!=null)\n\t\t\t\t\t\t\tq.room.bringMobHere(q.mob,false);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tq.room=q.mob.location();\n\t\t\t\t\t\tif(q.room!=null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.area=q.room.getArea();\n\t\t\t\t\t\t\tq.envObject=q.mob;\n\t\t\t\t\t\t\truntimeRegisterObject(q.mob);\n\t\t\t\t\t\t\tq.room.recoverRoomStats();\n\t\t\t\t\t\t\tq.room.showHappens(CMMsg.MSG_OK_ACTION,null);\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(cmd.equals("PCMOB"))\n\t\t\t\t\t{\n\t\t\t\t\t\tboolean reselect=false;\n\t\t\t\t\t\tif((p.size()>2)&&(p.get(2).equalsIgnoreCase("reselect")))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tp.remove(2);\n\t\t\t\t\t\t\treselect=true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mob=null;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tString mobName=CMParms.combine(p,2).toUpperCase();\n\t\t\t\t\t\tfinal String maskStr=breakOutMaskString(s,p);\n\t\t\t\t\t\tfinal MaskingLibrary.CompiledZMask mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr);\n\t\t\t\t\t\tif(mask!=null)\n\t\t\t\t\t\t\tmobName=CMParms.combine(p,2).toUpperCase();\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mob=(MOB)getObjectIfSpecified(p,args,2,0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mob=null;\n\t\t\t\t\t\t\tList<MOB> choices=null;\n\t\t\t\t\t\t\tfinal List<MOB> choices0=new ArrayList<MOB>();\n\t\t\t\t\t\t\tfinal List<MOB> choices1=new ArrayList<MOB>();\n\t\t\t\t\t\t\tfinal List<MOB> choices2=new ArrayList<MOB>();\n\t\t\t\t\t\t\tfinal List<MOB> choices3=new ArrayList<MOB>();\n\t\t\t\t\t\t\tif(mobName.length()==0)\n\t\t\t\t\t\t\t\tmobName="ANY";\n\t\t\t\t\t\t\tif(q.mobGroup!=null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfor(final MOB M2 : q.mobGroup)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif((M2!=null)&&(M2.isPlayer()))\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif(!CMLib.masking().maskCheck(mask,M2,true))\n\t\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t\tchoices=sortSelect(M2,mobName,choices,choices0,choices1,choices2,choices3);\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\telse\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfor(final Enumeration<Room> e=getAppropriateRoomSet(q);e.hasMoreElements();)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tfinal Room R2=e.nextElement();\n\t\t\t\t\t\t\t\t\t\tif(R2!=null)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tfor(int i=0;i<R2.numInhabitants();i++)\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tfinal MOB M2=R2.fetchInhabitant(i);\n\t\t\t\t\t\t\t\t\t\t\t\tif((M2!=null)&&(M2.isPlayer()))\n\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\tif(!CMLib.masking().maskCheck(mask,M2,true))\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t\t\t\t\tchoices=sortSelect(M2,mobName,choices,choices0,choices1,choices2,choices3);\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\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\tcatch(final NoSuchElementException e)\n\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\tthis.filterOutThoseInUse(choices, p.toString(), q, isQuiet, reselect);\n\t\t\t\t\t\t\tif((choices!=null)&&(choices.size()>0))\n\t\t\t\t\t\t\t\tq.mob=choices.get(CMLib.dice().roll(1,choices.size(),-1));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(q.mob==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !mob \'"+mobName+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(reselect)\n\t\t\t\t\t\t\tq.reselectable.add(q.mob);\n\t\t\t\t\t\tquestifyScriptableBehavs(q.mob);  // just weird\n\t\t\t\t\t\tif(q.room!=null)\n\t\t\t\t\t\t\tq.room.bringMobHere(q.mob,false);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tq.room=q.mob.location();\n\t\t\t\t\t\tif(q.room!=null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.area=q.room.getArea();\n\t\t\t\t\t\t\tq.envObject=q.mob;\n\t\t\t\t\t\t\truntimeRegisterObject(q.mob);\n\t\t\t\t\t\t\tq.room.recoverRoomStats();\n\t\t\t\t\t\t\tq.room.showHappens(CMMsg.MSG_OK_ACTION,null);\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(cmd.equals("ITEM"))\n\t\t\t\t\t{\n\t\t\t\t\t\tboolean reselect=false;\n\t\t\t\t\t\tif((p.size()>2)&&(p.get(2).equalsIgnoreCase("reselect")))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tp.remove(2);\n\t\t\t\t\t\t\treselect=true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.item=null;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tString itemName=CMParms.combine(p,2).toUpperCase();\n\t\t\t\t\t\tfinal String maskStr=breakOutMaskString(s,p);\n\t\t\t\t\t\tfinal MaskingLibrary.CompiledZMask mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr);\n\t\t\t\t\t\tif(mask!=null)\n\t\t\t\t\t\t\titemName=CMParms.combine(p,2).toUpperCase();\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.item=(Item)getObjectIfSpecified(p,args,2,0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.item=null;\n\t\t\t\t\t\t\tList<Item> choices=null;\n\t\t\t\t\t\t\tfinal List<Item> choices0=new ArrayList<Item>();\n\t\t\t\t\t\t\tfinal List<Item> choices1=new ArrayList<Item>();\n\t\t\t\t\t\t\tfinal List<Item> choices2=new ArrayList<Item>();\n\t\t\t\t\t\t\tfinal List<Item> choices3=new ArrayList<Item>();\n\t\t\t\t\t\t\tif(itemName.trim().length()==0)\n\t\t\t\t\t\t\t\titemName="ANY";\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(q.itemGroup!=null)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfor(final Item I2 : q.itemGroup)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif(I2!=null)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tif(!CMLib.masking().maskCheck(mask,I2,true))\n\t\t\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t\t\tchoices=sortSelect(I2,itemName,choices,choices0,choices1,choices2,choices3);\n\t\t\t\t\t\t\t\t\t\t}\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\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfor(final Enumeration<Room> e=getAppropriateRoomSet(q);e.hasMoreElements();)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tfinal Room R2=e.nextElement();\n\t\t\t\t\t\t\t\t\t\tfor(int i=0;i<R2.numItems();i++)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tfinal Item I2=R2.getItem(i);\n\t\t\t\t\t\t\t\t\t\t\tif(I2!=null)\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tif(!CMLib.masking().maskCheck(mask,I2,true))\n\t\t\t\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t\t\t\tchoices=sortSelect(I2,itemName,choices,choices0,choices1,choices2,choices3);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\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\tcatch(final NoSuchElementException e)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis.filterOutThoseInUse(choices, p.toString(), q, isQuiet, reselect);\n\t\t\t\t\t\t\tif((choices!=null)&&(choices.size()>0))\n\t\t\t\t\t\t\t\tq.item=choices.get(CMLib.dice().roll(1,choices.size(),-1));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(q.item==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !item \'"+itemName+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(reselect)\n\t\t\t\t\t\t\tq.reselectable.add(q.item);\n\t\t\t\t\t\tquestifyScriptableBehavs(q.item); // here we go again\n\t\t\t\t\t\tif(q.room!=null)\n\t\t\t\t\t\t\tq.room.moveItemTo(q.item,ItemPossessor.Expire.Never,ItemPossessor.Move.Followers);\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif(q.item.owner() instanceof Room)\n\t\t\t\t\t\t\tq.room=(Room)q.item.owner();\n\t\t\t\t\t\tq.envObject=q.item;\n\t\t\t\t\t\tif(q.room!=null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.area=q.room.getArea();\n\t\t\t\t\t\t\tq.room.recoverRoomStats();\n\t\t\t\t\t\t\tq.room.showHappens(CMMsg.MSG_OK_ACTION,null);\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(cmd.equals("ABILITY"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.ability=null;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tString abilityName=CMParms.combine(p,2).toUpperCase();\n\t\t\t\t\t\tfinal String maskStr=breakOutMaskString(s,p);\n\t\t\t\t\t\tfinal MaskingLibrary.CompiledZMask mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr);\n\t\t\t\t\t\tif(mask!=null)\n\t\t\t\t\t\t\tabilityName=CMParms.combine(p,2).toUpperCase();\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.ability=(Ability)getObjectIfSpecified(p,args,2,0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.ability=null;\n\t\t\t\t\t\t\tList<Ability> choices=null;\n\t\t\t\t\t\t\tfinal List<Ability> choices0=new ArrayList<Ability>();\n\t\t\t\t\t\t\tfinal List<Ability> choices1=new ArrayList<Ability>();\n\t\t\t\t\t\t\tfinal List<Ability> choices2=new ArrayList<Ability>();\n\t\t\t\t\t\t\tfinal List<Ability> choices3=new ArrayList<Ability>();\n\t\t\t\t\t\t\tif(abilityName.trim().length()==0)\n\t\t\t\t\t\t\t\tabilityName="ANY";\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(q.abilityGroup!=null)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfor(final Ability A2 : q.abilityGroup)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif(A2!=null)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tif(!CMLib.masking().maskCheck(mask,A2,true))\n\t\t\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t\t\tchoices=sortSelect(A2,abilityName,choices,choices0,choices1,choices2,choices3);\n\t\t\t\t\t\t\t\t\t\t}\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\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfor(final Enumeration<Room> e=getAppropriateRoomSet(q);e.hasMoreElements();)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tfinal Room R2=e.nextElement();\n\t\t\t\t\t\t\t\t\t\tfor(int i=0;i<R2.numEffects();i++)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tfinal Ability A2=R2.fetchEffect(i);\n\t\t\t\t\t\t\t\t\t\t\tif(A2!=null)\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\tif(!CMLib.masking().maskCheck(mask,A2,true))\n\t\t\t\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t\t\t\tchoices=sortSelect(A2,abilityName,choices,choices0,choices1,choices2,choices3);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\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\tcatch(final NoSuchElementException e)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis.filterOutThoseInUse(choices, p.toString(), q, isQuiet, true);\n\t\t\t\t\t\t\tif((choices!=null)&&(choices.size()>0))\n\t\t\t\t\t\t\t\tq.ability=choices.get(CMLib.dice().roll(1,choices.size(),-1));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(q.ability==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !ability \'"+abilityName+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tq.envObject=q.item;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(cmd.equals("AGENT"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.mysteryData==null)\n\t\t\t\t\t\t\tq.mysteryData=new MysteryData();\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mob=(MOB)getObjectIfSpecified(p,args,2,0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(p.size()>2)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', agent syntax \'"+CMParms.combine(p,2)+"\'.");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(q.mob==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', agent !mob.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tquestifyScriptableBehavs(q.mob);  // should be done to loaded or q-scripted mobs only\n\t\t\t\t\t\tq.mysteryData.agent=q.mob;\n\t\t\t\t\t\tq.mob=q.mysteryData.agent;\n\t\t\t\t\t\tq.envObject=q.mob;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(cmd.equals("FACTION"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.mysteryData==null)\n\t\t\t\t\t\t\tq.mysteryData=new MysteryData();\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tfinal String numStr=CMParms.combine(p,2);\n\t\t\t\t\t\tFaction F=null;\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tF=(Faction)getObjectIfSpecified(p,args,2,0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(numStr.equalsIgnoreCase("ANY"))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal int numFactions=CMLib.factions().numFactions();\n\t\t\t\t\t\t\t\tfinal int whichFaction=CMLib.dice().roll(1,numFactions,-1);\n\t\t\t\t\t\t\t\tint curFaction=0;\n\t\t\t\t\t\t\t\tfor(final Enumeration<Faction> e=CMLib.factions().factions();e.hasMoreElements();curFaction++)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tF=e.nextElement();\n\t\t\t\t\t\t\t\t\tif(curFaction==whichFaction)\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\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\tF=CMLib.factions().getFaction(numStr);\n\t\t\t\t\t\t\t\tif(F==null)\n\t\t\t\t\t\t\t\t\tF=CMLib.factions().getFactionByName(numStr);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(F==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !faction #\'"+numStr+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tq.mysteryData.faction=F;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(cmd.equals("FACTIONGROUP"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.mysteryData==null)\n\t\t\t\t\t\t\tq.mysteryData=new MysteryData();\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mysteryData.factionGroup=null;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mysteryData.factionGroup=(List<Faction>)getObjectIfSpecified(p,args,2,1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mysteryData.factionGroup=Collections.synchronizedList(new ArrayList<Faction>());\n\t\t\t\t\t\t\tString numStr=CMParms.combine(p,2);\n\t\t\t\t\t\t\tFaction F=null;\n\t\t\t\t\t\t\tif(q.mysteryData.faction!=null)\n\t\t\t\t\t\t\t\tq.mysteryData.factionGroup.add(q.mysteryData.faction);\n\t\t\t\t\t\t\tif(CMath.isMathExpression(numStr)||numStr.equalsIgnoreCase("ALL"))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal int numFactions=CMLib.factions().numFactions();\n\t\t\t\t\t\t\t\tif(numStr.equalsIgnoreCase("ALL"))\n\t\t\t\t\t\t\t\t\tnumStr=""+numFactions;\n\t\t\t\t\t\t\t\tint num=CMath.s_parseIntExpression(numStr);\n\t\t\t\t\t\t\t\tif(num>=numFactions)\n\t\t\t\t\t\t\t\t\tnum=numFactions;\n\t\t\t\t\t\t\t\tint tries=500;\n\t\t\t\t\t\t\t\twhile((q.mysteryData.factionGroup.size()<num)&&(--tries>0))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal int whichFaction=CMLib.dice().roll(1,numFactions,-1);\n\t\t\t\t\t\t\t\t\tint curFaction=0;\n\t\t\t\t\t\t\t\t\tfor(final Enumeration<Faction> e=CMLib.factions().factions();e.hasMoreElements();curFaction++)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tF=e.nextElement();\n\t\t\t\t\t\t\t\t\t\tif(curFaction==whichFaction)\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif(!q.mysteryData.factionGroup.contains(F))\n\t\t\t\t\t\t\t\t\t\tq.mysteryData.factionGroup.add(F);\n\t\t\t\t\t\t\t\t}\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\tfor(int pi=2;pi<p.size();pi++)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tF=CMLib.factions().getFaction(p.get(pi));\n\t\t\t\t\t\t\t\t\tif(F==null)\n\t\t\t\t\t\t\t\t\t\tF=CMLib.factions().getFactionByName(p.get(pi));\n\t\t\t\t\t\t\t\t\tif(F==null)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !factiongroup \'"+p.get(pi)+"\'.");\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif(!q.mysteryData.factionGroup.contains(F))\n\t\t\t\t\t\t\t\t\t\tq.mysteryData.factionGroup.add(F);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif(q.error)\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif((q.mysteryData.factionGroup!=null)\n\t\t\t\t\t\t&&(q.mysteryData.factionGroup.size()>0)\n\t\t\t\t\t\t&&(q.mysteryData.faction==null))\n\t\t\t\t\t\t\tq.mysteryData.faction=q.mysteryData.factionGroup.get(CMLib.dice().roll(1,q.mysteryData.factionGroup.size(),-1));\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(cmd.equals("AGENTGROUP"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.mysteryData==null)\n\t\t\t\t\t\t\tq.mysteryData=new MysteryData();\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mysteryData.agentGroup=null;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mysteryData.agentGroup=(List<MOB>)getObjectIfSpecified(p,args,2,1);\n\t\t\t\t\t\t\tif((q.mysteryData.agentGroup!=null)\n\t\t\t\t\t\t\t&&(q.mysteryData.agentGroup.size()>0)\n\t\t\t\t\t\t\t&&(q.mysteryData.agent==null))\n\t\t\t\t\t\t\t\tq.mysteryData.agent=q.mysteryData.agentGroup.get(CMLib.dice().roll(1,q.mysteryData.agentGroup.size(),-1));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mysteryData.agentGroup=null;\n\t\t\t\t\t\t\tfinal String numStr=CMParms.combine(p,2).toUpperCase();\n\t\t\t\t\t\t\tif(!CMath.isMathExpression(numStr))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !agentgroup #\'"+numStr+"\'.");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif((q.mobGroup==null)||(q.mobGroup.size()==0))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !agentgroup mobgroup.");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfinal List<MOB> V=new ArrayList<MOB>();\n\t\t\t\t\t\t\tV.addAll(q.mobGroup);\n\t\t\t\t\t\t\tq.mysteryData.agentGroup=Collections.synchronizedList(new ArrayList<MOB>());\n\t\t\t\t\t\t\tif(q.mysteryData.agent!=null)\n\t\t\t\t\t\t\t\tq.mysteryData.agentGroup.add(q.mysteryData.agent);\n\t\t\t\t\t\t\tint num=CMath.parseIntExpression(numStr);\n\t\t\t\t\t\t\tif(num>=V.size())\n\t\t\t\t\t\t\t\tnum=V.size();\n\t\t\t\t\t\t\twhile((q.mysteryData.agentGroup.size()<num)&&(V.size()>0))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal int dex=CMLib.dice().roll(1,V.size(),-1);\n\t\t\t\t\t\t\t\tfinal Object O=V.get(dex);\n\t\t\t\t\t\t\t\tV.remove(dex);\n\t\t\t\t\t\t\t\tq.mysteryData.agentGroup.add((MOB)O);\n\t\t\t\t\t\t\t\tif(q.mysteryData.agent==null)\n\t\t\t\t\t\t\t\t\tq.mysteryData.agent=(MOB)O;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tquestifyScriptableBehavs(q.mob);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tq.mob=q.mysteryData.agent;\n\t\t\t\t\t\tif(q.mysteryData.agentGroup!=null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mobGroup=Collections.synchronizedList(new ArrayList<MOB>());\n\t\t\t\t\t\t\tq.mobGroup.addAll(q.mysteryData.agentGroup);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tq.envObject=q.mysteryData.agentGroup;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(cmd.equals("WHEREHAPPENEDGROUP")||cmd.equals("WHEREATGROUP"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.mysteryData==null)\n\t\t\t\t\t\t\tq.mysteryData=new MysteryData();\n\t\t\t\t\t\tif(cmd.equals("WHEREHAPPENEDGROUP"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.whereHappenedGroup=(List<Room>)getObjectIfSpecified(p,args,2,1);\n\t\t\t\t\t\t\t\tq.roomGroup=q.mysteryData.whereHappenedGroup;\n\t\t\t\t\t\t\t\tq.mysteryData.whereHappened=((q.roomGroup==null)||(q.roomGroup.size()==0))?null:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(Room)q.roomGroup.get(CMLib.dice().roll(1,q.roomGroup.size(),-1));\n\t\t\t\t\t\t\t\tq.envObject=q.mysteryData.whereHappenedGroup;\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.whereHappenedGroup=null;\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\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.whereAtGroup=(List<Room>)getObjectIfSpecified(p,args,2,1);\n\t\t\t\t\t\t\t\tq.roomGroup=q.mysteryData.whereAtGroup;\n\t\t\t\t\t\t\t\tq.mysteryData.whereAt=((q.roomGroup==null)||(q.roomGroup.size()==0))?null:\n\t\t\t\t\t\t\t\t\t\t\t\t\t  (Room)q.roomGroup.get(CMLib.dice().roll(1,q.roomGroup.size(),-1));\n\t\t\t\t\t\t\t\tq.envObject=q.mysteryData.whereAtGroup;\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.whereAtGroup=null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tfinal String numStr=CMParms.combine(p,2).toUpperCase();\n\t\t\t\t\t\tif(!CMath.isMathExpression(numStr))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !"+cmd.toLowerCase()+" #\'"+numStr+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif((q.roomGroup==null)||(q.roomGroup.size()==0))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !"+cmd.toLowerCase()+" roomGroup.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal List<Room> V=new ArrayList<Room>();\n\t\t\t\t\t\tV.addAll(q.roomGroup);\n\t\t\t\t\t\tfinal List<Room> V2=new ArrayList<Room>();\n\t\t\t\t\t\tRoom R=null;\n\t\t\t\t\t\tif(cmd.equals("WHEREHAPPENEDGROUP"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mysteryData.whereHappenedGroup=Collections.synchronizedList(new ArrayList<Room>(V2));\n\t\t\t\t\t\t\tR=q.mysteryData.whereHappened;\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\tq.mysteryData.whereAtGroup=null;\n\t\t\t\t\t\t\tR=q.mysteryData.whereAt;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(R!=null)\n\t\t\t\t\t\t\tV2.add(R);\n\t\t\t\t\t\tint num=CMath.parseIntExpression(numStr);\n\t\t\t\t\t\tif(num>=V.size())\n\t\t\t\t\t\t\tnum=V.size();\n\t\t\t\t\t\twhile((V2.size()<num)&&(V.size()>0))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal int dex=CMLib.dice().roll(1,V.size(),-1);\n\t\t\t\t\t\t\tfinal Room O=V.get(dex);\n\t\t\t\t\t\t\tV.remove(dex);\n\t\t\t\t\t\t\tif(!V2.contains(O))\n\t\t\t\t\t\t\t\tV2.add(O);\n\t\t\t\t\t\t\tif(R==null)\n\t\t\t\t\t\t\t\tR=O;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tq.roomGroup=Collections.synchronizedList(new ArrayList<Room>());\n\t\t\t\t\t\tq.roomGroup.addAll(V2);\n\t\t\t\t\t\tq.room=R;\n\t\t\t\t\t\tq.envObject=q.roomGroup;\n\t\t\t\t\t\tif(cmd.equals("WHEREHAPPENEDGROUP"))\n\t\t\t\t\t\t\tq.mysteryData.whereHappened=R;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tq.mysteryData.whereAt=R;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(cmd.equals("WHENHAPPENEDGROUP")||cmd.equals("WHENATGROUP"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.mysteryData==null)\n\t\t\t\t\t\t\tq.mysteryData=new MysteryData();\n\t\t\t\t\t\tList<TimeClock> V2;\n\t\t\t\t\t\tTimeClock TC=null;\n\t\t\t\t\t\tif(cmd.equals("WHENHAPPENEDGROUP"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.whenHappenedGroup=(List<TimeClock>)getObjectIfSpecified(p,args,2,1);\n\t\t\t\t\t\t\t\tV2=q.mysteryData.whenHappenedGroup;\n\t\t\t\t\t\t\t\tif((V2!=null)&&(V2.size()>0))\n\t\t\t\t\t\t\t\t\tq.mysteryData.whenHappened=V2.get(CMLib.dice().roll(1,V2.size(),-1));\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.whenHappenedGroup=null;\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\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.whenAtGroup=(List<TimeClock>)getObjectIfSpecified(p,args,2,1);\n\t\t\t\t\t\t\t\tV2=q.mysteryData.whenAtGroup;\n\t\t\t\t\t\t\t\tif((V2!=null)&&(V2.size()>0))\n\t\t\t\t\t\t\t\t\tq.mysteryData.whenAt=V2.get(CMLib.dice().roll(1,V2.size(),-1));\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.whenAtGroup=null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tV2=new ArrayList<TimeClock>();\n\t\t\t\t\t\tfinal TimeClock NOW=getMysteryTimeNowFromState();\n\t\t\t\t\t\tif(cmd.equals("WHENHAPPENEDGROUP"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mysteryData.whenHappenedGroup=Collections.synchronizedList(new ArrayList<TimeClock>(V2));\n\t\t\t\t\t\t\tTC=q.mysteryData.whenHappened;\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\tq.mysteryData.whenAtGroup=Collections.synchronizedList(new ArrayList<TimeClock>(V2));\n\t\t\t\t\t\t\tTC=q.mysteryData.whenAt;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor(int pi=2;pi<p.size();pi++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal String numStr=p.get(pi);\n\t\t\t\t\t\t\tif(!CMath.isMathExpression(numStr))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', "+cmd.toLowerCase()+" !relative hour #: "+numStr+".");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfinal TimeClock TC2=(TimeClock)NOW.copyOf();\n\t\t\t\t\t\t\tTC2.tickTock(CMath.parseIntExpression(numStr));\n\t\t\t\t\t\t\tV2.add(TC2);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(q.error)\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tif((V2.size()>0)&&(TC==null))\n\t\t\t\t\t\t\tTC=V2.get(CMLib.dice().roll(1,V2.size(),-1));\n\t\t\t\t\t\tif(cmd.equals("WHENHAPPENEDGROUP"))\n\t\t\t\t\t\t\tq.mysteryData.whenHappened=TC;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tq.mysteryData.whenAt=TC;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(cmd.equals("WHENHAPPENED")\n\t\t\t\t\t||cmd.equals("WHENAT"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.mysteryData==null)\n\t\t\t\t\t\t\tq.mysteryData=new MysteryData();\n\t\t\t\t\t\tif(cmd.equals("WHENHAPPENED"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.whenHappened=(TimeClock)getObjectIfSpecified(p,args,2,0);\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.whenHappened=null;\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\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.whenAt=(TimeClock)getObjectIfSpecified(p,args,2,0);\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.whenAt=null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tfinal TimeClock NOW=getMysteryTimeNowFromState();\n\t\t\t\t\t\tTimeClock TC=null;\n\t\t\t\t\t\tfinal String numStr=CMParms.combine(p,2);\n\t\t\t\t\t\tif(!CMath.isMathExpression(numStr))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', "+cmd.toLowerCase()+" !relative hour #: "+numStr+".");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tTC=(TimeClock)NOW.copyOf();\n\t\t\t\t\t\tTC.tickTock(CMath.parseIntExpression(numStr));\n\t\t\t\t\t\tif(cmd.equals("WHENHAPPENED"))\n\t\t\t\t\t\t\tq.mysteryData.whenHappened=TC;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tq.mysteryData.whenAt=TC;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(cmd.equals("MOTIVEGROUP")||cmd.equals("ACTIONGROUP"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.mysteryData==null)\n\t\t\t\t\t\t\tq.mysteryData=new MysteryData();\n\t\t\t\t\t\tList<String> V2=null;\n\t\t\t\t\t\tint num=-1;\n\t\t\t\t\t\tif((p.size()>2)&&(CMath.isMathExpression(p.get(2))))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnum=CMath.s_parseIntExpression(p.get(2));\n\t\t\t\t\t\t\tp.remove(2);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(cmd.equals("MOTIVEGROUP"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.motiveGroup=(List<String>)getObjectIfSpecified(p,args,2,1);\n\t\t\t\t\t\t\t\tsizeDownTo(q.mysteryData.motiveGroup,num);\n\t\t\t\t\t\t\t\tV2=q.mysteryData.motiveGroup;\n\t\t\t\t\t\t\t\tif((V2!=null)&&(V2.size()>0))\n\t\t\t\t\t\t\t\t\tq.mysteryData.motive=V2.get(CMLib.dice().roll(1,V2.size(),-1));\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.motiveGroup=null;\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\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.actionGroup=(List<String>)getObjectIfSpecified(p,args,2,1);\n\t\t\t\t\t\t\t\tsizeDownTo(q.mysteryData.actionGroup,num);\n\t\t\t\t\t\t\t\tV2=q.mysteryData.actionGroup;\n\t\t\t\t\t\t\t\tif((V2!=null)&&(V2.size()>0))\n\t\t\t\t\t\t\t\t\tq.mysteryData.action=V2.get(CMLib.dice().roll(1,V2.size(),-1));\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.actionGroup=null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tV2=new ArrayList<String>();\n\t\t\t\t\t\tString Mstr=null;\n\t\t\t\t\t\tif(cmd.equals("MOTIVEGROUP"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mysteryData.motiveGroup=Collections.synchronizedList(new ArrayList<String>(V2));\n\t\t\t\t\t\t\tMstr=q.mysteryData.motive;\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\tq.mysteryData.actionGroup=Collections.synchronizedList(new ArrayList<String>(V2));\n\t\t\t\t\t\t\tMstr=q.mysteryData.action;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(Mstr!=null)\n\t\t\t\t\t\t\tV2.add(Mstr);\n\t\t\t\t\t\tfor(int pi=2;pi<p.size();pi++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(!V2.contains(p.get(pi)))\n\t\t\t\t\t\t\t\tV2.add(p.get(pi));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsizeDownTo(V2,num);\n\t\t\t\t\t\tif((V2.size()>0)&&(Mstr==null))\n\t\t\t\t\t\t\tMstr=V2.get(CMLib.dice().roll(1,V2.size(),-1));\n\t\t\t\t\t\tif(cmd.equals("MOTIVEGROUP"))\n\t\t\t\t\t\t\tq.mysteryData.motive=Mstr;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tq.mysteryData.action=Mstr;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(cmd.equals("MOTIVE"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.mysteryData==null)\n\t\t\t\t\t\t\tq.mysteryData=new MysteryData();\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mysteryData.motive=(String)getObjectIfSpecified(p,args,2,0);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mysteryData.motive=null;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tq.mysteryData.motive=CMParms.combine(p,2);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(cmd.equals("ACTION"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.mysteryData==null)\n\t\t\t\t\t\t\tq.mysteryData=new MysteryData();\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\ttry\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mysteryData.action=(String)getObjectIfSpecified(p,args,2,0);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mysteryData.action=null;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tq.mysteryData.action=CMParms.combine(p,2);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(cmd.equals("WHEREHAPPENED")\n\t\t\t\t\t||cmd.equals("WHEREAT"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.mysteryData==null)\n\t\t\t\t\t\t\tq.mysteryData=new MysteryData();\n\t\t\t\t\t\tif(cmd.equals("WHEREHAPPENED"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.whereHappened=(Room)getObjectIfSpecified(p,args,2,0);\n\t\t\t\t\t\t\t\tq.room=q.mysteryData.whereHappened;\n\t\t\t\t\t\t\t\tq.envObject=q.room;\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.whereHappened=null;\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\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.whereAt=(Room)getObjectIfSpecified(p,args,2,0);\n\t\t\t\t\t\t\t\tq.room=q.mysteryData.whereAt;\n\t\t\t\t\t\t\t\tq.envObject=q.room;\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.whereAt=null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()>2)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', "+cmd.toLowerCase()+" syntax \'"+CMParms.combine(p,2)+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(q.room==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', "+cmd.toLowerCase()+" !room.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(cmd.equals("WHEREHAPPENED"))\n\t\t\t\t\t\t\tq.mysteryData.whereHappened=q.room;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tq.mysteryData.whereAt=q.room;\n\t\t\t\t\t\tq.envObject=q.room;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(cmd.equals("TARGETGROUP")\n\t\t\t\t\t||cmd.equals("TOOLGROUP"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.mysteryData==null)\n\t\t\t\t\t\t\tq.mysteryData=new MysteryData();\n\t\t\t\t\t\tList<?> V2=null;\n\t\t\t\t\t\tif(cmd.equals("TARGETGROUP"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.targetGroup=(List<Environmental>)getObjectIfSpecified(p,args,2,1);\n\t\t\t\t\t\t\t\tV2=q.mysteryData.targetGroup;\n\t\t\t\t\t\t\t\tif((V2!=null)&&(V2.size()>0))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif(V2.get(0) instanceof MOB)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tq.mobGroup=(List<MOB>)V2;\n\t\t\t\t\t\t\t\t\t\tq.mob=(MOB)V2.get(CMLib.dice().roll(1,V2.size(),-1));\n\t\t\t\t\t\t\t\t\t\tq.envObject=q.mobGroup;\n\t\t\t\t\t\t\t\t\t\tq.mysteryData.target=q.mob;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif(V2.get(0) instanceof Item)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tq.itemGroup=(List<Item>)V2;\n\t\t\t\t\t\t\t\t\t\tq.item=(Item)V2.get(CMLib.dice().roll(1,V2.size(),-1));\n\t\t\t\t\t\t\t\t\t\tq.mysteryData.target=q.item;\n\t\t\t\t\t\t\t\t\t\tq.envObject=q.itemGroup;\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\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.targetGroup=null;\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\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.toolGroup=(List<Environmental>)getObjectIfSpecified(p,args,2,1);\n\t\t\t\t\t\t\t\tV2=q.mysteryData.toolGroup;\n\t\t\t\t\t\t\t\tif((V2!=null)&&(V2.size()>0))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif(V2.get(0) instanceof MOB)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tq.mobGroup=(List<MOB>)V2;\n\t\t\t\t\t\t\t\t\t\tq.mob=(MOB)V2.get(CMLib.dice().roll(1,V2.size(),-1));\n\t\t\t\t\t\t\t\t\t\tq.envObject=q.mobGroup;\n\t\t\t\t\t\t\t\t\t\tq.mysteryData.tool=q.mob;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif(V2.get(0) instanceof Item)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tq.itemGroup=(List<Item>)V2;\n\t\t\t\t\t\t\t\t\t\tq.item=(Item)V2.get(CMLib.dice().roll(1,V2.size(),-1));\n\t\t\t\t\t\t\t\t\t\tq.envObject=q.itemGroup;\n\t\t\t\t\t\t\t\t\t\tq.mysteryData.tool=q.item;\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\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.toolGroup=null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\tfinal String numStr=CMParms.combine(p,2).toUpperCase();\n\t\t\t\t\t\tif(!CMath.isMathExpression(numStr))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !"+cmd.toLowerCase()+" #\'"+numStr+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(((q.mobGroup==null)||(q.mobGroup.size()==0))\n\t\t\t\t\t\t&&((q.itemGroup==null)||(q.itemGroup.size()==0)))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', !"+cmd.toLowerCase()+" mobgroup itemgroup.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal List<Environmental> V=Collections.synchronizedList(new ArrayList<Environmental>());\n\t\t\t\t\t\tif((q.mobGroup!=null)&&(q.mobGroup.size()>0))\n\t\t\t\t\t\t\tV.addAll(q.mobGroup);\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tV.addAll(q.itemGroup);\n\t\t\t\t\t\tV2=new ArrayList<Environmental>();\n\t\t\t\t\t\tEnvironmental finalE=null;\n\t\t\t\t\t\tif(cmd.equals("TARGETGROUP"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mysteryData.targetGroup=Collections.synchronizedList(new ArrayList<Environmental>((List<Environmental>)V2));\n\t\t\t\t\t\t\tfinalE=q.mysteryData.target;\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\tq.mysteryData.toolGroup=Collections.synchronizedList(new ArrayList<Environmental>((List<Environmental>)V2));\n\t\t\t\t\t\t\tfinalE=q.mysteryData.tool;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(finalE!=null)\n\t\t\t\t\t\t\t((List<Environmental>)V2).add(finalE);\n\t\t\t\t\t\tint num=CMath.parseIntExpression(numStr);\n\t\t\t\t\t\tif(num>=V.size())\n\t\t\t\t\t\t\tnum=V.size();\n\t\t\t\t\t\tObject O;\n\t\t\t\t\t\twhile((V2.size()<num)&&(V.size()>0))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal int dex=CMLib.dice().roll(1,V.size(),-1);\n\t\t\t\t\t\t\tO=V.get(dex);\n\t\t\t\t\t\t\tV.remove(dex);\n\t\t\t\t\t\t\tif(!V2.contains(O))\n\t\t\t\t\t\t\t\t((List<Object>)V2).add(O);\n\t\t\t\t\t\t\tif(finalE==null)\n\t\t\t\t\t\t\t\tfinalE=(Environmental)O;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(finalE instanceof MOB)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mobGroup=Collections.synchronizedList(new ArrayList<MOB>());\n\t\t\t\t\t\t\tq.mobGroup.addAll((List<MOB>)V2);\n\t\t\t\t\t\t\tq.mob=(MOB)finalE;\n\t\t\t\t\t\t\tquestifyScriptableBehavs(q.mob); // i just dont get it\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif(finalE instanceof Item)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.itemGroup=Collections.synchronizedList(new ArrayList<Item>());\n\t\t\t\t\t\t\tq.itemGroup.addAll((List<Item>)V2);\n\t\t\t\t\t\t\tq.item=(Item)finalE;\n\t\t\t\t\t\t\tquestifyScriptableBehavs(q.item);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tq.envObject=V2;\n\t\t\t\t\t\tif(cmd.equals("TARGETGROUP"))\n\t\t\t\t\t\t\tq.mysteryData.target=finalE;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tq.mysteryData.tool=finalE;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(cmd.equals("TARGET")\n\t\t\t\t\t||cmd.equals("TOOL"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.mysteryData==null)\n\t\t\t\t\t\t\tq.mysteryData=new MysteryData();\n\t\t\t\t\t\tif(cmd.equals("TARGET"))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.target=(Environmental)getObjectIfSpecified(p,args,2,0);\n\t\t\t\t\t\t\t\tif(q.mysteryData.target instanceof MOB)\n\t\t\t\t\t\t\t\t\tq.mob=(MOB)q.mysteryData.target;\n\t\t\t\t\t\t\t\tif(q.mysteryData.target instanceof Item)\n\t\t\t\t\t\t\t\t\tq.item=(Item)q.mysteryData.target;\n\t\t\t\t\t\t\t\tq.envObject=q.mysteryData.target;\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.target=null;\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\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.tool=(Environmental)getObjectIfSpecified(p,args,2,0);\n\t\t\t\t\t\t\t\tif(q.mysteryData.tool instanceof MOB)\n\t\t\t\t\t\t\t\t\tq.mob=(MOB)q.mysteryData.tool;\n\t\t\t\t\t\t\t\tif(q.mysteryData.tool instanceof Item)\n\t\t\t\t\t\t\t\t\tq.item=(Item)q.mysteryData.tool;\n\t\t\t\t\t\t\t\tif(q.mysteryData.tool instanceof Ability)\n\t\t\t\t\t\t\t\t\tq.ability=(Ability)q.mysteryData.tool;\n\t\t\t\t\t\t\t\tq.envObject=q.mysteryData.tool;\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcatch(final CMException ex)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mysteryData.tool=null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()>2)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', "+cmd.toLowerCase()+" syntax \'"+CMParms.combine(p,2)+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif((q.envObject instanceof List)\n\t\t\t\t\t\t&&(((List<Object>)q.envObject).size()>0)\n\t\t\t\t\t\t&&(((List<Object>)q.envObject).get(0) instanceof Environmental))\n\t\t\t\t\t\t\tq.envObject=((List<Object>)q.envObject).get(CMLib.dice().roll(1,((List<Object>)q.envObject).size(),-1));\n\t\t\t\t\t\tif(!(q.envObject instanceof Environmental))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', "+cmd.toLowerCase()+" !object.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(cmd.equals("TARGET"))\n\t\t\t\t\t\t\tq.mysteryData.target=(Environmental)q.envObject;\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tq.mysteryData.tool=(Environmental)q.envObject;\n\t\t\t\t\t\tif(q.envObject instanceof MOB)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mob=(MOB)q.envObject;\n\t\t\t\t\t\t\tquestifyScriptableBehavs(q.mob);  // useless, but harmless\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif(q.envObject instanceof Item)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.item=(Item)q.envObject;\n\t\t\t\t\t\t\tquestifyScriptableBehavs(q.item);\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(!isStat(cmd))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', unknown variable \'"+cmd+"\'.");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\tif(cmd.equals("IMPORT"))\n\t\t\t\t{\n\t\t\t\t\tif(p.size()<2)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', no IMPORT type.");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcmd=p.get(1).toUpperCase();\n\t\t\t\t\tif(cmd.equals("MOBS"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', no IMPORT MOBS file.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal StringBuffer buf=getResourceFileData(CMParms.combine(p,2), !optional);\n\t\t\t\t\t\tif((buf==null)||(buf.length()<20))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\',Unknown XML file: \'"+CMParms.combine(p,2)+"\' for \'"+name()+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(buf.substring(0,20).indexOf("<MOBS>")<0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', Invalid XML file: \'"+CMParms.combine(p,2)+"\' for \'"+name()+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tq.loadedMobs=Collections.synchronizedList(new ArrayList<MOB>());\n\t\t\t\t\t\tfinal String errorStr=CMLib.coffeeMaker().addMOBsFromXML(buf.toString(),q.loadedMobs,null);\n\t\t\t\t\t\tif(errorStr.length()>0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\',Error on import of: \'"+CMParms.combine(p,2)+"\' for \'"+name()+"\': "+errorStr+".");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(q.loadedMobs.size()<=0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\',No mobs loaded: \'"+CMParms.combine(p,2)+"\' for \'"+name()+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor(final MOB M : q.loadedMobs)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tM.basePhyStats().setRejuv(PhyStats.NO_REJUV);\n\t\t\t\t\t\t\tM.basePhyStats().setDisposition(M.basePhyStats().disposition()|PhyStats.IS_UNSAVABLE);\n\t\t\t\t\t\t\tM.recoverPhyStats();\n\t\t\t\t\t\t\tM.text();\n\t\t\t\t\t\t\tCMLib.threads().deleteAllTicks(M);\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(cmd.equals("ITEMS"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', no import filename!");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal StringBuffer buf=getResourceFileData(CMParms.combine(p,2), !optional);\n\t\t\t\t\t\tif((buf==null)||(buf.length()<20))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\',Unknown XML file: \'"+CMParms.combine(p,2)+"\' for \'"+name()+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(buf.substring(0,20).indexOf("<ITEMS>")<0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\',Invalid XML file: \'"+CMParms.combine(p,2)+"\' for \'"+name()+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tq.loadedItems=Collections.synchronizedList(new ArrayList<Item>());\n\t\t\t\t\t\tfinal String errorStr=CMLib.coffeeMaker().addItemsFromXML(buf.toString(),q.loadedItems,null);\n\t\t\t\t\t\tif(errorStr.length()>0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\',Error on import of: \'"+CMParms.combine(p,2)+"\' for \'"+name()+"\': "+errorStr+".");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(q.loadedItems.size()<=0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\',No items loaded: \'"+CMParms.combine(p,2)+"\' for \'"+name()+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor(final Item I : q.loadedItems)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tI.basePhyStats().setRejuv(PhyStats.NO_REJUV);\n\t\t\t\t\t\t\tI.basePhyStats().setDisposition(I.basePhyStats().disposition()|PhyStats.IS_UNSAVABLE);\n\t\t\t\t\t\t\tI.recoverPhyStats();\n\t\t\t\t\t\t\tI.text();\n\t\t\t\t\t\t\tCMLib.threads().deleteTick(I,Tickable.TICKID_ITEM_BEHAVIOR);\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(cmd.equals("ABILITIES"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', no import filename!");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal StringBuffer buf=getResourceFileData(CMParms.combine(p,2), !optional);\n\t\t\t\t\t\tif((buf==null)||(buf.length()<20))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\',Unknown XML file: \'"+CMParms.combine(p,2)+"\' for \'"+name()+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(buf.substring(0,20).indexOf("<ABILITY")<0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\',Invalid XML file: \'"+CMParms.combine(p,2)+"\' for \'"+name()+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tq.loadedAbilities=Collections.synchronizedList(new ArrayList<Ability>());\n\t\t\t\t\t\tfinal String errorStr=CMLib.coffeeMaker().unpackAbilitiesFromXml(buf.toString(),q.loadedAbilities);\n\t\t\t\t\t\tif(errorStr.length()>0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\',Error on import of: \'"+CMParms.combine(p,2)+"\' for \'"+name()+"\': "+errorStr+".");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(q.loadedAbilities.size()<=0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\',No abilities loaded: \'"+CMParms.combine(p,2)+"\' for \'"+name()+"\'.");\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\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', unknown import type \'"+cmd+"\'.");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\tif(cmd.startsWith("LOAD="))\n\t\t\t\t{\n\t\t\t\t\tfinal boolean error=q.error;\n\t\t\t\t\tfinal List<Object> args2=new ArrayList<Object>();\n\t\t\t\t\tparseQuestScriptWArgs(parseLoadScripts(s,args,args2,true),args2);\n\t\t\t\t\tif((!error)&&(q.error)&&(!optional))\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\tif(cmd.equals("LOAD"))\n\t\t\t\t{\n\t\t\t\t\tif(p.size()<2)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', unfound type on load.");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcmd=p.get(1).toUpperCase();\n\t\t\t\t\tif(cmd.equals("MOB")||cmd.equals("MOBGROUP"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.loadedMobs.size()==0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot load mob, no mobs imported.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tint maxToLoad=Integer.MAX_VALUE;\n\t\t\t\t\t\tif((p.size()>2)&&(CMath.isMathExpression(p.get(2))))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmaxToLoad=CMath.parseIntExpression(p.get(2));\n\t\t\t\t\t\t\tp.remove(2);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', no mob name to load!");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tString mobName=CMParms.combine(p,2);\n\t\t\t\t\t\tfinal String maskStr=breakOutMaskString(s,p);\n\t\t\t\t\t\tfinal MaskingLibrary.CompiledZMask mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr);\n\t\t\t\t\t\tif(mask!=null)\n\t\t\t\t\t\t\tmobName=CMParms.combine(p,2).toUpperCase();\n\t\t\t\t\t\tif(mobName.length()==0)\n\t\t\t\t\t\t\tmobName="ANY";\n\t\t\t\t\t\tfinal boolean addAll=mobName.equalsIgnoreCase("ALL")\n\t\t\t\t\t\t\t\t\t\t||mobName.equalsIgnoreCase("ANY");\n\t\t\t\t\t\tfinal List<MOB> choices=new ArrayList<MOB>(); // ok because is wholly temporary\n\t\t\t\t\t\tfor(int i=0;i<q.loadedMobs.size();i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal MOB M2=q.loadedMobs.get(i);\n\t\t\t\t\t\t\tif((CMLib.masking().maskCheck(mask,M2,true))\n\t\t\t\t\t\t\t&&(addAll\n\t\t\t\t\t\t\t\t||(CMLib.english().containsString(M2.name(),mobName))\n\t\t\t\t\t\t\t\t||(CMLib.english().containsString(M2.displayText(),mobName))\n\t\t\t\t\t\t\t\t||(CMLib.english().containsString(M2.description(),mobName))))\n\t\t\t\t\t\t\t\t\tchoices.add((MOB)M2.copyOf());\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(choices.size()==0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', no mob found to load \'"+mobName+"\'!");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal List<MOB> mobsToDo=Collections.synchronizedList(new ArrayList<MOB>()); // must remain vector for thread safety\n\t\t\t\t\t\tif(cmd.equalsIgnoreCase("MOB"))\n\t\t\t\t\t\t\tmobsToDo.add(choices.get(CMLib.dice().roll(1,choices.size(),-1)));\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmobsToDo.addAll(choices);\n\t\t\t\t\t\t\tq.mobGroup=mobsToDo;\n\t\t\t\t\t\t}\n\t\t\t\t\t\twhile((mobsToDo.size()>maxToLoad)&&(maxToLoad>0))\n\t\t\t\t\t\t\tmobsToDo.remove(CMLib.dice().roll(1,mobsToDo.size(),-1));\n\t\t\t\t\t\twhile((mobsToDo.size()<maxToLoad)&&(maxToLoad>0)&&(maxToLoad<Integer.MAX_VALUE))\n\t\t\t\t\t\t\tmobsToDo.add((MOB)mobsToDo.get(CMLib.dice().roll(1,mobsToDo.size(),-1)).copyOf());\n\t\t\t\t\t\tfinal Room choiceRoom=q.room;\n\t\t\t\t\t\tfor(int m=0;m<mobsToDo.size();m++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.mob=mobsToDo.get(m);\n\t\t\t\t\t\t\tq.room=choiceRoom;\n\t\t\t\t\t\t\tif(q.room==null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(q.roomGroup!=null)\n\t\t\t\t\t\t\t\t\tq.room=q.roomGroup.get(CMLib.dice().roll(1,q.roomGroup.size(),-1));\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tif(q.area!=null)\n\t\t\t\t\t\t\t\t\tq.room=q.area.getRandomMetroRoom();\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\tq.room=CMLib.map().getRandomRoom();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(q.room!=null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.mob.setStartRoom(null);\n\t\t\t\t\t\t\t\tq.mob.basePhyStats().setRejuv(PhyStats.NO_REJUV);\n\t\t\t\t\t\t\t\tq.mob.basePhyStats().setDisposition(q.mob.basePhyStats().disposition()|PhyStats.IS_UNSAVABLE);\n\t\t\t\t\t\t\t\tq.mob.recoverPhyStats();\n\t\t\t\t\t\t\t\tq.mob.text();\n\t\t\t\t\t\t\t\tq.mob.bringToLife(q.room,true);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tquestifyScriptableBehavs(q.mob);\n\t\t\t\t\t\t\truntimeRegisterObject(q.mob);\n\t\t\t\t\t\t\tif(q.room!=null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.room.recoverRoomStats();\n\t\t\t\t\t\t\t\tq.room.showHappens(CMMsg.MSG_OK_ACTION,null);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(q.mob!=null)\n\t\t\t\t\t\t\t\tq.mob.setStartRoom(null); // necessary to tell qm to clean him UP!\n\t\t\t\t\t\t}\n\t\t\t\t\t\tq.envObject=mobsToDo;\n\t\t\t\t\t\tif(q.room!=null)\n\t\t\t\t\t\t\tq.area=q.room.getArea();\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(cmd.equals("ITEM")||cmd.equals("ITEMGROUP"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.loadedItems.size()==0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot load item, no items imported.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tint maxToLoad=Integer.MAX_VALUE;\n\t\t\t\t\t\tif((p.size()>2)&&(CMath.isMathExpression(p.get(2))))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmaxToLoad=CMath.parseIntExpression(p.get(2));\n\t\t\t\t\t\t\tp.remove(2);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', no item name to load!");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal String itemName=CMParms.combine(p,2);\n\t\t\t\t\t\tfinal List<Item> choices=new ArrayList<Item>(); // only ever picked from locally\n\t\t\t\t\t\tfor(int i=0;i<q.loadedItems.size();i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal Item I2=q.loadedItems.get(i);\n\t\t\t\t\t\t\tif((itemName.equalsIgnoreCase("any"))\n\t\t\t\t\t\t\t||(CMLib.english().containsString(I2.name(),itemName))\n\t\t\t\t\t\t\t||(CMLib.english().containsString(I2.displayText(),itemName))\n\t\t\t\t\t\t\t||(CMLib.english().containsString(I2.description(),itemName)))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal Item I3=(Item)I2.copyOf();\n\t\t\t\t\t\t\t\tCMLib.threads().deleteTick(I3,Tickable.TICKID_ITEM_BEHAVIOR);\n\t\t\t\t\t\t\t\tchoices.add(I3);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(choices.size()==0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', no item found to load \'"+itemName+"\'!");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal List<Item> itemsToDo=new ArrayList<Item>(); // for thread safety, as this is global\n\t\t\t\t\t\tif(cmd.equalsIgnoreCase("ITEM"))\n\t\t\t\t\t\t\titemsToDo.add(choices.get(CMLib.dice().roll(1,choices.size(),-1)));\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\titemsToDo.addAll(choices);\n\t\t\t\t\t\t\tq.itemGroup=Collections.synchronizedList(new ArrayList<Item>(itemsToDo));\n\t\t\t\t\t\t}\n\t\t\t\t\t\twhile((itemsToDo.size()>maxToLoad)&&(maxToLoad>0))\n\t\t\t\t\t\t\titemsToDo.remove(CMLib.dice().roll(1,itemsToDo.size(),-1));\n\t\t\t\t\t\twhile((itemsToDo.size()<maxToLoad)&&(maxToLoad>0)&&(maxToLoad<Integer.MAX_VALUE))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal Item I3=(Item)(itemsToDo.get(CMLib.dice().roll(1,itemsToDo.size(),-1))).copyOf();\n\t\t\t\t\t\t\tCMLib.threads().deleteTick(I3,Tickable.TICKID_ITEM_BEHAVIOR);\n\t\t\t\t\t\t\titemsToDo.add(I3);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal Room choiceRoom=q.room;\n\t\t\t\t\t\tfor(int m=0;m<itemsToDo.size();m++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tq.item=itemsToDo.get(m);\n\t\t\t\t\t\t\tq.room=choiceRoom;\n\t\t\t\t\t\t\tif(q.room==null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(q.roomGroup!=null)\n\t\t\t\t\t\t\t\t\tq.room=q.roomGroup.get(CMLib.dice().roll(1,q.roomGroup.size(),-1));\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tif(q.area!=null)\n\t\t\t\t\t\t\t\t\tq.room=q.area.getRandomMetroRoom();\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\tq.room=CMLib.map().getRandomRoom();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(q.room!=null)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tq.item.basePhyStats().setRejuv(PhyStats.NO_REJUV);\n\t\t\t\t\t\t\t\tq.item.basePhyStats().setDisposition(q.item.basePhyStats().disposition()|PhyStats.IS_UNSAVABLE);\n\t\t\t\t\t\t\t\tq.item.recoverPhyStats();\n\t\t\t\t\t\t\t\tq.item.text();\n\t\t\t\t\t\t\t\tq.room.addItem(q.item);\n\t\t\t\t\t\t\t\tq.room.recoverRoomStats();\n\t\t\t\t\t\t\t\tq.room.showHappens(CMMsg.MSG_OK_ACTION,null);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tquestifyScriptableBehavs(q.item);\n\t\t\t\t\t\t\truntimeRegisterObject(q.item);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(q.room!=null)\n\t\t\t\t\t\t\tq.area=q.room.getArea();\n\t\t\t\t\t\tq.envObject=itemsToDo;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(cmd.equals("ABILITY")||cmd.equals("ABILITYGROUP"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.loadedAbilities.size()==0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot load ability, no abilities imported.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tint maxToLoad=Integer.MAX_VALUE;\n\t\t\t\t\t\tif((p.size()>2)&&(CMath.isMathExpression(p.get(2))))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmaxToLoad=CMath.parseIntExpression(p.get(2));\n\t\t\t\t\t\t\tp.remove(2);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', no ability name to load!");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal String itemName=CMParms.combine(p,2);\n\t\t\t\t\t\tfinal List<Ability> choices=new ArrayList<Ability>(); // only ever picked from locally\n\t\t\t\t\t\tfor(int i=0;i<q.loadedAbilities.size();i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal Ability A2=q.loadedAbilities.get(i);\n\t\t\t\t\t\t\tif((itemName.equalsIgnoreCase("any"))\n\t\t\t\t\t\t\t||(CMLib.english().containsString(A2.name(),itemName))\n\t\t\t\t\t\t\t||(CMLib.english().containsString(A2.ID(),itemName)))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal Ability A3=(Ability)A2.copyOf();\n\t\t\t\t\t\t\t\tchoices.add(A3);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(choices.size()==0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', no ability found to load \'"+itemName+"\'!");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal List<Ability> itemsToDo=new ArrayList<Ability>(); // for thread safety, as this is global\n\t\t\t\t\t\tif(cmd.equalsIgnoreCase("ABILITY"))\n\t\t\t\t\t\t\titemsToDo.add(choices.get(CMLib.dice().roll(1,choices.size(),-1)));\n\t\t\t\t\t\telse\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\titemsToDo.addAll(choices);\n\t\t\t\t\t\t\tq.abilityGroup=Collections.synchronizedList(new ArrayList<Ability>(itemsToDo));\n\t\t\t\t\t\t}\n\t\t\t\t\t\twhile((itemsToDo.size()>maxToLoad)&&(maxToLoad>0))\n\t\t\t\t\t\t\titemsToDo.remove(CMLib.dice().roll(1,itemsToDo.size(),-1));\n\t\t\t\t\t\twhile((itemsToDo.size()<maxToLoad)&&(maxToLoad>0)&&(maxToLoad<Integer.MAX_VALUE))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal Ability A3=(Ability)(itemsToDo.get(CMLib.dice().roll(1,itemsToDo.size(),-1))).copyOf();\n\t\t\t\t\t\t\titemsToDo.add(A3);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(itemsToDo.size()>0)\n\t\t\t\t\t\t\tq.ability=itemsToDo.get(0);\n\t\t\t\t\t\tq.envObject=itemsToDo;\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(optional)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', unknown load type \'"+cmd+"\'.");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\tif(cmd.equals("GIVE"))\n\t\t\t\t{\n\t\t\t\t\tif(p.size()<2)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', unfound type on give.");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcmd=p.get(1).toUpperCase();\n\t\t\t\t\tif(cmd.equals("FOLLOWER"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.mob==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot give follower, no mob set.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot give follower, follower name not given.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal String mobName=CMParms.combine(p,2);\n\t\t\t\t\t\tfinal List<MOB> choices=new ArrayList<MOB>(); // only ever picked from locally\n\t\t\t\t\t\tReverseEnumeration<PreservedQuestObject> e;\n\t\t\t\t\t\tfor(e=new ReverseEnumeration<PreservedQuestObject>(q.worldObjects);e.hasMoreElements();)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal PreservedQuestObject PO=e.nextElement();\n\t\t\t\t\t\t\tif((PO.obj!=q.mob)&&(PO.obj instanceof MOB))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal MOB M2=(MOB)PO.obj;\n\t\t\t\t\t\t\t\tif((mobName.equalsIgnoreCase("any"))\n\t\t\t\t\t\t\t\t||(CMLib.english().containsString(M2.name(),mobName))\n\t\t\t\t\t\t\t\t||(CMLib.english().containsString(M2.displayText(),mobName))\n\t\t\t\t\t\t\t\t||(CMLib.english().containsString(M2.description(),mobName)))\n\t\t\t\t\t\t\t\t\tchoices.add(M2);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(choices.size()==0)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot give follower, no mobs called \'"+mobName+"\' previously set in script.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal MOB M2=choices.get(CMLib.dice().roll(1,choices.size(),-1));\n\t\t\t\t\t\tM2.setFollowing(q.mob);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(cmd.equals("ITEM")||(cmd.equalsIgnoreCase("ITEMS")))\n\t\t\t\t\t{\n\t\t\t\t\t\tif((q.item==null)&&(q.itemGroup==null)&&(q.loadedItems==null))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot give item(s), no item(s) set or loaded.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif((q.mob==null)&&(q.mobGroup==null))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot give item(s), no mob set.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()>2)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot give item(s), parameter unnecessarily given: \'"+CMParms.combine(p,2)+"\'.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal List<MOB> toSet=new ArrayList<MOB>();\n\t\t\t\t\t\tif(q.mob!=null)\n\t\t\t\t\t\t\ttoSet.add(q.mob);\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif(q.mobGroup!=null)\n\t\t\t\t\t\t\ttoSet.addAll(q.mobGroup);\n\t\t\t\t\t\tfinal List<Item> itemSet=new ArrayList<Item>();\n\t\t\t\t\t\tif(q.item!=null)\n\t\t\t\t\t\t\titemSet.add(q.item);\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif(q.itemGroup!=null)\n\t\t\t\t\t\t\titemSet.addAll(q.itemGroup);\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif(q.loadedItems!=null)\n\t\t\t\t\t\t\titemSet.addAll(q.loadedItems);\n\t\t\t\t\t\tfor(int i=0;i<toSet.size();i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal MOB M2=toSet.get(i);\n\t\t\t\t\t\t\truntimeRegisterObject(M2);\n\t\t\t\t\t\t\tif(cmd.equals("ITEMS"))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfor(int i3=0;i3<itemSet.size();i3++)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tItem I3=itemSet.get(i3);\n\t\t\t\t\t\t\t\t\tif(q.item==I3)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\truntimeRegisterObject(I3);\n\t\t\t\t\t\t\t\t\t\tM2.moveItemTo(I3);\n\t\t\t\t\t\t\t\t\t\tquestifyScriptableBehavs(q.item);\n\t\t\t\t\t\t\t\t\t\tq.item=(Item)q.item.copyOf();\n\t\t\t\t\t\t\t\t\t\tquestifyScriptableBehavs(q.item);\n\t\t\t\t\t\t\t\t\t\tCMLib.threads().deleteTick(q.item, Tickable.TICKID_ITEM_BEHAVIOR); // because it may not be used\n\t\t\t\t\t\t\t\t\t\tq.item.setOwner(null); // because the item copy is definitely nowhere\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tquestifyScriptableBehavs(I3);\n\t\t\t\t\t\t\t\t\t\tCMLib.threads().deleteTick(I3, Tickable.TICKID_ITEM_BEHAVIOR); // because it may not be used??\n\t\t\t\t\t\t\t\t\t\tI3=(Item)I3.copyOf();\n\t\t\t\t\t\t\t\t\t\tquestifyScriptableBehavs(I3);\n\t\t\t\t\t\t\t\t\t\tI3.setOwner(null); // because the i3 copy is nowhere\n\t\t\t\t\t\t\t\t\t\truntimeRegisterObject(I3);\n\t\t\t\t\t\t\t\t\t\tM2.moveItemTo(I3);\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\telse\n\t\t\t\t\t\t\tif(cmd.equals("ITEM"))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tItem I3=itemSet.get(CMLib.dice().roll(1,itemSet.size(),-1));\n\t\t\t\t\t\t\t\tquestifyScriptableBehavs(I3);\n\t\t\t\t\t\t\t\tif(q.item==I3)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\truntimeRegisterObject(I3);\n\t\t\t\t\t\t\t\t\tM2.moveItemTo(I3);\n\t\t\t\t\t\t\t\t\tq.item=(Item)q.item.copyOf();\n\t\t\t\t\t\t\t\t\tq.item.setOwner(null);// because the copy is nowhere\n\t\t\t\t\t\t\t\t\tquestifyScriptableBehavs(q.item);\n\t\t\t\t\t\t\t\t\tCMLib.threads().deleteTick(q.item, Tickable.TICKID_ITEM_BEHAVIOR); // because it may not be used\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tCMLib.threads().deleteTick(I3, Tickable.TICKID_ITEM_BEHAVIOR); // because it may not be used\n\t\t\t\t\t\t\t\t\tI3=(Item)I3.copyOf();\n\t\t\t\t\t\t\t\t\tI3.setOwner(null);// because the copy is nowhere\n\t\t\t\t\t\t\t\t\tquestifyScriptableBehavs(I3);\n\t\t\t\t\t\t\t\t\truntimeRegisterObject(I3);\n\t\t\t\t\t\t\t\t\tM2.moveItemTo(I3);\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\tif(cmd.equals("ABILITY"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif((q.mob==null)&&(q.mobGroup==null))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot give ability, no mob set.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif((p.size()<3)&&(q.ability==null))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot give ability, ability name not given.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal Ability A3=findQuestAbility(p.get(2));\n\t\t\t\t\t\tif(A3==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot give ability, ability name unknown \'"+(p.get(2))+".");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal List<MOB> toSet=new ArrayList<MOB>();\n\t\t\t\t\t\tif(q.mob!=null)\n\t\t\t\t\t\t\ttoSet.add(q.mob);\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif(q.mobGroup!=null)\n\t\t\t\t\t\t\ttoSet.addAll(q.mobGroup);\n\t\t\t\t\t\tfor(int i=0;i<toSet.size();i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal MOB M2=toSet.get(i);\n\t\t\t\t\t\t\truntimeRegisterAbility(M2,A3.ID(),CMParms.rest(s,3),true);\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(cmd.equals("BEHAVIOR"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.envObject==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot give behavior, no mob or item set.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot give behavior, behavior name not given.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal Behavior B=CMClass.getBehavior(p.get(2));\n\t\t\t\t\t\tif(B==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot give behavior, behavior name unknown \'"+(p.get(2))+".");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tList<Object> toSet=new ArrayList<Object>();\n\t\t\t\t\t\tif(q.envObject instanceof List)\n\t\t\t\t\t\t\ttoSet=(List<Object>)q.envObject;\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif(q.envObject!=null)\n\t\t\t\t\t\t\ttoSet.add(q.envObject);\n\t\t\t\t\t\tfor(int i=0;i<toSet.size();i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal Environmental E2=(Environmental)toSet.get(i);\n\t\t\t\t\t\t\tif(E2 instanceof PhysicalAgent)\n\t\t\t\t\t\t\t\truntimeRegisterBehavior((PhysicalAgent)E2,B.ID(),CMParms.rest(s,3),true);\n\t\t\t\t\t\t\tif((E2 instanceof Item)\n\t\t\t\t\t\t\t&&((((Item)E2).owner()==null)\n\t\t\t\t\t\t\t\t||(!((Item)E2).owner().isContent((Item)E2))))\n\t\t\t\t\t\t\t\tCMLib.threads().deleteTick(E2, Tickable.TICKID_ITEM_BEHAVIOR);\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(cmd.equals("STAT"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.envObject==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot give stat, no mob or item set.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot give stat, stat name not given.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal String stat=p.get(2);\n\t\t\t\t\t\tfinal String val=CMParms.rest(s,3);\n\t\t\t\t\t\tList<Environmental> toSet=new ArrayList<Environmental>();\n\t\t\t\t\t\tif(q.envObject instanceof List)\n\t\t\t\t\t\t\ttoSet=(List<Environmental>)q.envObject;\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif(q.envObject!=null)\n\t\t\t\t\t\t\ttoSet.add((Environmental)q.envObject);\n\t\t\t\t\t\tfor(int i=0;i<toSet.size();i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal Environmental E2=toSet.get(i);\n\t\t\t\t\t\t\tif(stat.equalsIgnoreCase("KEYPLAYER") && (E2 instanceof Physical))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal Ability A=((Physical)E2).fetchEffect("QuestBound");\n\t\t\t\t\t\t\t\tif(A!=null)\n\t\t\t\t\t\t\t\t\tA.setStat("KEY",val);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\truntimeRegisterStat(E2,stat,val,true);\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(cmd.equals("SCRIPT"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.envObject==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot give script, no object set.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tboolean proceed=true;\n\t\t\t\t\t\tboolean savable=false;\n\t\t\t\t\t\tboolean playerok=false;\n\t\t\t\t\t\tString word=null;\n\t\t\t\t\t\tString scope=CMStrings.replaceAll(name()," ","_").toUpperCase().trim();\n\t\t\t\t\t\twhile(proceed&&(p.size()>2))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tword=p.get(2);\n\t\t\t\t\t\t\tproceed=false;\n\t\t\t\t\t\t\tif(word.equalsIgnoreCase("SAVABLE"))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tsavable=true;\n\t\t\t\t\t\t\t\tproceed=true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\tif(word.equalsIgnoreCase("GLOBAL"))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tscope="";\n\t\t\t\t\t\t\t\tproceed=true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\tif(word.equalsIgnoreCase("INDIVIDUAL")||word.equals("*"))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tscope="*";\n\t\t\t\t\t\t\t\tproceed=true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\tif(word.equalsIgnoreCase("PLAYEROK"))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tplayerok=true;\n\t\t\t\t\t\t\t\tproceed=true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif(proceed)\n\t\t\t\t\t\t\t\tp.remove(2);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot give script, script not given.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal String val=CMParms.rest(s,2);\n\t\t\t\t\t\tList<Environmental> toSet=new ArrayList<Environmental>();\n\t\t\t\t\t\tif(q.envObject instanceof List)\n\t\t\t\t\t\t\ttoSet=(List<Environmental>)q.envObject;\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif(q.envObject!=null)\n\t\t\t\t\t\t\ttoSet.add((Environmental)q.envObject);\n\t\t\t\t\t\tfor(int i=0;i<toSet.size();i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal Environmental E2=toSet.get(i);\n\t\t\t\t\t\t\tif(E2 instanceof PhysicalAgent)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal ScriptingEngine S=(ScriptingEngine)CMClass.getCommon("DefaultScriptingEngine");\n\t\t\t\t\t\t\t\tS.setSavable(savable);\n\t\t\t\t\t\t\t\tS.registerDefaultQuest(this);\n\t\t\t\t\t\t\t\tS.setVarScope(scope);\n\t\t\t\t\t\t\t\tS.setScript(val);\n\t\t\t\t\t\t\t\tif(debug)\n\t\t\t\t\t\t\t\t\tLog.debugOut("QuestScript#"+parseId+": Giving "+val.length()+" char script command to "+E2.Name());\n\t\t\t\t\t\t\t\tif((E2 instanceof MOB)\n\t\t\t\t\t\t\t\t&&(((MOB)E2).isPlayer())\n\t\t\t\t\t\t\t\t&&(!playerok)\n\t\t\t\t\t\t\t\t&&(S.isFunc("DO_ACCEPT"))\n\t\t\t\t\t\t\t\t&&(S.isFunc("CAN_ACCEPT")))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal MOB M2=(MOB)E2;\n\t\t\t\t\t\t\t\t\tString eval = S.callFunc("CAN_ACCEPT", M2.Name(), M2, M2, M2, M2, null, null, M2.Name(), objs);\n\t\t\t\t\t\t\t\t\tif(eval == null)\n\t\t\t\t\t\t\t\t\t\tcontinue; // failed, so don\'t do it\n\t\t\t\t\t\t\t\t\teval=eval.toLowerCase();\n\t\t\t\t\t\t\t\t\tif(eval.equals("cancel") || (eval.length()==0))\n\t\t\t\t\t\t\t\t\t\tcontinue; // failed, so don\'t do it\n\t\t\t\t\t\t\t\t\tS.callFunc("DO_ACCEPT", M2.Name(), M2, M2, M2, M2, null, null, M2.Name(), objs);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t((PhysicalAgent)E2).addScript(S);\n\t\t\t\t\t\t\t\t\truntimeRegisterObject(((PhysicalAgent)E2));\n\t\t\t\t\t\t\t\t\tif((E2 instanceof Item)\n\t\t\t\t\t\t\t\t\t&&((((Item)E2).owner()==null)\n\t\t\t\t\t\t\t\t\t\t||(!((Item)E2).owner().isContent((Item)E2))))\n\t\t\t\t\t\t\t\t\t\tCMLib.threads().deleteTick(E2, Tickable.TICKID_ITEM_BEHAVIOR); //OMG WHY?!?!/????!!\n\t\t\t\t\t\t\t\t\tsynchronized(q)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tq.addons.add(new XVector<Object>(E2,S),Integer.valueOf(q.preserveState));\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\tif(cmd.equals("AFFECT"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.envObject==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot give Effect, no mob, room or item set.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot give Effect, ability name not given.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal Ability A3=this.findQuestAbility(p.get(2));\n\t\t\t\t\t\tif(A3==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot give Effect, ability name unknown \'"+(p.get(2))+".");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tList<Object> toSet=new ArrayList<Object>();\n\t\t\t\t\t\tif(q.envObject instanceof List)\n\t\t\t\t\t\t\ttoSet=(List<Object>)q.envObject;\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif(q.envObject!=null)\n\t\t\t\t\t\t\ttoSet.add(q.envObject);\n\t\t\t\t\t\tfor(final Object o : toSet)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(o instanceof PhysicalAgent)\n\t\t\t\t\t\t\t\truntimeRegisterEffect((PhysicalAgent)o,A3.ID(),CMParms.rest(s,3),true);\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(optional)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', unknown give type \'"+cmd+"\'.");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\tif(cmd.equals("TAKE"))\n\t\t\t\t{\n\t\t\t\t\tif(p.size()<2)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', unfound type on take.");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcmd=p.get(1).toUpperCase();\n\t\t\t\t\tif(cmd.equals("ABILITY"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif((q.mob==null)&&(q.mobGroup==null))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot take ability, no mob set.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot take ability, ability name not given.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal Ability A3=findQuestAbility(p.get(2));\n\t\t\t\t\t\tif(A3==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot take ability, ability name unknown \'"+(p.get(2))+".");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal List<MOB> toSet=new ArrayList<MOB>();\n\t\t\t\t\t\tif(q.mob!=null)\n\t\t\t\t\t\t\ttoSet.add(q.mob);\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif(q.mobGroup!=null)\n\t\t\t\t\t\t\ttoSet.addAll(q.mobGroup);\n\t\t\t\t\t\tfor(int i=0;i<toSet.size();i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal MOB M2=toSet.get(i);\n\t\t\t\t\t\t\truntimeRegisterAbility(M2,A3.ID(),CMParms.rest(s,3),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(cmd.equals("BEHAVIOR"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.envObject==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot take behavior, no mob or item set.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot take behavior, behavior name not given.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal Behavior B=CMClass.getBehavior(p.get(2));\n\t\t\t\t\t\tif(B==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot take behavior, behavior name unknown \'"+(p.get(2))+".");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tList<Object> toSet=new ArrayList<Object>();\n\t\t\t\t\t\tif(q.envObject instanceof List)\n\t\t\t\t\t\t\ttoSet=(List<Object>)q.envObject;\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif(q.envObject!=null)\n\t\t\t\t\t\t\ttoSet.add(q.envObject);\n\t\t\t\t\t\tfor(int i=0;i<toSet.size();i++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal Environmental E2=(Environmental)toSet.get(i);\n\t\t\t\t\t\t\tif(E2 instanceof PhysicalAgent)\n\t\t\t\t\t\t\t\truntimeRegisterBehavior((PhysicalAgent)E2,B.ID(),CMParms.rest(s,3),false);\n\t\t\t\t\t\t\tif((E2 instanceof Item)\n\t\t\t\t\t\t\t&&((((Item)E2).owner()==null)\n\t\t\t\t\t\t\t\t||(!((Item)E2).owner().isContent((Item)E2))))\n\t\t\t\t\t\t\t\tCMLib.threads().deleteTick(E2, Tickable.TICKID_ITEM_BEHAVIOR);\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(cmd.equals("AFFECT"))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(q.envObject==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot take Effect, no mob, room or item set.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(p.size()<3)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot take Effect, ability name not given.");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfinal Ability A3=findQuestAbility(p.get(2));\n\t\t\t\t\t\tif(A3==null)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', cannot take Effect, ability name unknown \'"+(p.get(2))+".");\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tList<Object> toSet=new ArrayList<Object>();\n\t\t\t\t\t\tif(q.envObject instanceof List)\n\t\t\t\t\t\t\ttoSet=(List<Object>)q.envObject;\n\t\t\t\t\t\telse\n\t\t\t\t\t\tif(q.envObject!=null)\n\t\t\t\t\t\t\ttoSet.add(q.envObject);\n\t\t\t\t\t\tfor(final Object o : toSet)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(o instanceof PhysicalAgent)\n\t\t\t\t\t\t\t\truntimeRegisterEffect((PhysicalAgent)o,A3.ID(),CMParms.rest(s,3),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\t{\n\t\t\t\t\t\tif(optional)\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', unknown take type \'"+cmd+"\'.");\n\t\t\t\t\t\tbreak;\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\terrorOccurred(q,isQuiet,"Quest \'"+name()+"\', unknown command \'"+cmd+"\'.");\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tq.done=true;\n\t\t\t}\n\t\t}\n\t}\n\n\tpublic boolean spawnQuest(final String script, final List<?> baseVars, final boolean reTime)\n\t{\n\t\tfinal DefaultQuest Q2=(DefaultQuest)CMClass.getCommon("DefaultQuest");\n\t\tQ2.setCopy(true);\n\t\tQ2.setVars(baseVars,0);\n\t\tQ2.setScript(script,true);\n\n\t\tQuest Q=CMLib.quests().fetchQuest(Q2.name());\n\t\tint append=1;\n\t\twhile((Q!=null)&&(Q!=Q2))\n\t\t{\n\t\t\tQ2.setName(name()+"#"+append);\n\t\t\tappend++;\n\t\t\tQ=CMLib.quests().fetchQuest(Q2.name());\n\t\t}\n\t\tCMLib.quests().addQuest(Q2);\n\t\tif(reTime)\n\t\t{\n\t\t\tLong ellapsed=stepEllapsedTimes.get(script);\n\t\t\tif(ellapsed==null)\n\t\t\t\tellapsed=Long.valueOf(0);\n\t\t\tstepEllapsedTimes.remove(script);\n\t\t\tellapsed=Long.valueOf(ellapsed.longValue()+(System.currentTimeMillis()-lastStartDateTime));\n\t\t\tstepEllapsedTimes.put(script,ellapsed);\n\t\t\tQ2.resetWaitRemaining(ellapsed.longValue());\n\t\t\tif(Q2.startQuestOnTime())\n\t\t\t{\n\t\t\t\tstepEllapsedTimes.remove(script);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\telse\n\t\tif(Q2.startQuestInternal())\n\t\t\treturn true;\n\t\tQ2.enterDormantState();\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic boolean startQuest()\n\t{\n\t\tif((!running())&&(!isCopy()))\n\t\t\tCMLib.coffeeTables().bump(this,CoffeeTableRow.STAT_QUESTSTARTATTEMPT);\n\t\treturn startQuestInternal();\n\t}\n\n\t// this will execute the quest script.  If the quest is running, it\n\t// will call stopQuestInternal first to shut it down.\n\tpublic boolean startQuestInternal()\n\t{\n\t\tfinal String prefix = CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS)?("QuestScript#"+parseId+" "):"";\n\t\tif(prefix.length()>0)\n\t\t\tLog.debugOut("Quest",prefix+name()+" Start Internal called ("+running()+": resetting state and starting from scratch.");\n\n\t\tif(running())\n\t\t{\n\t\t\tstopQuestInternal();\n\t\t\tresetData=null;\n\t\t}\n\n\t\tfinal List<Object> args=new ArrayList<Object>();\n\t\tquestState=new QuestState();\n\t\tfinal List<Object> baseScript=parseLoadScripts(script(),new ArrayList<Object>(),args,true);\n\t\tif((!isCopy())&&(getSpawn()!=SPAWN_NO))\n\t\t{\n\t\t\tif(getSpawn()==SPAWN_FIRST)\n\t\t\t\tspawnQuest(script(),baseScript,false);\n\t\t\telse\n\t\t\tif(getSpawn()==SPAWN_ANY)\n\t\t\t{\n\t\t\t\tfinal List<String> parsed=CMLib.quests().parseQuestSteps(parseFinalQuestScript(baseScript),0,false);\n\t\t\t\tfor(int p=0;p<parsed.size();p++)\n\t\t\t\t\tspawnQuest(parsed.get(p),baseScript,true);\n\t\t\t}\n\t\t\tlastStartDateTime=System.currentTimeMillis();\n\t\t\tenterDormantState();\n\t\t\treturn false; // always return false, since, per se, this quest is NOT started.\n\t\t}\n\t\ttry\n\t\t{\n\t\t\tparseQuestScript(baseScript,args,0);\n\t\t}\n\t\tcatch(final Exception t)\n\t\t{\n\t\t\tquestState.error=true;\n\t\t\tLog.errOut("DefaultQuest",t);\n\t\t}\n\t\tif(questState.error)\n\t\t{\n\t\t\tif(!questState.beQuiet)\n\t\t\t{\n\t\t\t\tint retry=0;\n\t\t\t\tif((durable)&&(resetData==null))\n\t\t\t\t\tretry=10;\n\t\t\t\telse\n\t\t\t\tif(resetData!=null)\n\t\t\t\t\tretry=resetData[0];\n\t\t\t\tLog.errOut("Quest",prefix+"Errors starting \'"\n\t\t\t\t\t\t+name()\n\t\t\t\t\t\t+"\', quest not started"\n\t\t\t\t\t\t+((retry>0)?", retry in "+retry+".":"."));\n\t\t\t}\n\t\t\tif((durable)&&(resetData==null))\n\t\t\t{\n\t\t\t\tresetQuest(10);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tCMLib.coffeeTables().bump(this,CoffeeTableRow.STAT_QUESTFAILEDSTART);\n\t\t}\n\t\telse\n\t\tif(!questState.done)\n\t\t\tLog.errOut("Quest",prefix+"Nothing parsed in \'"+name()+"\', quest not started.");\n\t\telse\n\t\tif(duration()<0)\n\t\t{\n\t\t\tLog.errOut("Quest",prefix+"No duration, quest \'"+name()+"\' not started.");\n\t\t\tquestState.error=true;\n\t\t}\n\t\tif((!questState.error)&&(questState.done))\n\t\t{\n\t\t\tenterRunningState();\n\t\t\treturn true;\n\t\t}\n\t\tstopQuestInternal();\n\t\treturn false;\n\t}\n\n\tpublic void enterRunningState()\n\t{\n\t\tif(duration()>=0)\n\t\t{\n\t\t\twaitRemaining=-1;\n\t\t\tif(duration()==0)\n\t\t\t\tticksRemaining=1;\n\t\t\telse\n\t\t\tif((resetData!=null)&&(resetData[1]>0))\n\t\t\t\tticksRemaining=resetData[1];\n\t\t\telse\n\t\t\t\tticksRemaining=duration();\n\t\t\tCMLib.threads().startTickDown(this,Tickable.TICKID_QUEST,1);\n\t\t}\n\t\tresetData=null;\n\t\tlastStartDateTime=System.currentTimeMillis();\n\t\tstepEllapsedTimes.remove(script());\n\t}\n\n\tprotected void cleanQuestStep(final int preserveSkip)\n\t{\n\t\tstoppingQuest=true;\n\t\tfinal boolean debug=CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS);\n\t\tif(questState.worldObjects.size()>0)\n\t\t{\n\t\t\tsynchronized(questState)\n\t\t\t{\n\t\t\t\tEnumeration<PreservedQuestObject> e;\n\t\t\t\tPreservedQuestObject PO;\n\t\t\t\tfor(e=new ReverseEnumeration<PreservedQuestObject>(questState.worldObjects);e.hasMoreElements();)\n\t\t\t\t{\n\t\t\t\t\tPO=e.nextElement();\n\t\t\t\t\tfinal PhysicalAgent P=PO.obj;\n\t\t\t\t\t// always end quest between steps\n\t\t\t\t\tif(PO.preserveState!=Integer.MIN_VALUE)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(P instanceof MOB)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal MOB M=(MOB)P;\n\t\t\t\t\t\t\tfinal ScriptingEngine B=(ScriptingEngine)M.fetchBehavior("Scriptable");\n\t\t\t\t\t\t\tif(B!=null)\n\t\t\t\t\t\t\t\tB.endQuest(M,M,name());\n\t\t\t\t\t\t\tfor(final Enumeration<ScriptingEngine> se= M.scripts(); se.hasMoreElements();)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal ScriptingEngine SE=se.nextElement();\n\t\t\t\t\t\t\t\tif(SE!=null)\n\t\t\t\t\t\t\t\t\tSE.endQuest(M, M, name());\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(P instanceof Behavable)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal MOB M=CMClass.getFactoryMOB(P.name(),P.phyStats().level(),CMLib.map().roomLocation(P));\n\t\t\t\t\t\t\ttry\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfor(final Enumeration<ScriptingEngine> se= ((Behavable)P).scripts(); se.hasMoreElements();)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal ScriptingEngine SE=se.nextElement();\n\t\t\t\t\t\t\t\t\tif(SE!=null)\n\t\t\t\t\t\t\t\t\t\tSE.endQuest(P, M, name());\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfinally\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tM.destroy();\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\tfinal int oldPreserveState=PO.preserveState;\n\t\t\t\t\tif((PO.preserveState>0)&&(preserveSkip!=0))\n\t\t\t\t\t\tPO.preserveState-=preserveSkip; // might actually bump it to keep things unchanged\n\t\t\t\t\tif(PO.preserveState>0)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(debug && (P!=null))\n\t\t\t\t\t\t\tLog.debugOut("QuestScript#"+parseId+": Aging "+P.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(P))+" from "+oldPreserveState+" to "+(PO.preserveState-1));\n\t\t\t\t\t\tPO.preserveState--;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\tif(debug && (P!=null))\n\t\t\t\t\t\tLog.debugOut("QuestScript#"+parseId+": De-registering "+P.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(P)));\n\t\t\t\t\tquestState.worldObjects.remove(PO);\n\t\t\t\t\tif(PO.preserveState == Integer.MIN_VALUE)\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\tPO.preserveState=Integer.MIN_VALUE;\n\t\t\t\t\tif(P != null)\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal Ability A=P.fetchEffect("QuestBound");\n\t\t\t\t\t\tif(A!=null)\n\t\t\t\t\t\t\tP.delEffect(A);\n\t\t\t\t\t\tif(P instanceof Item)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif((CMath.bset(P.basePhyStats().disposition(),PhyStats.IS_UNSAVABLE))\n\t\t\t\t\t\t\t&&(!((Item)P).amDestroyed()))\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(debug)\n\t\t\t\t\t\t\t\t\tLog.debugOut("QuestScript#"+parseId+": Destroying "+P.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(P)));\n\t\t\t\t\t\t\t\t((Item)P).destroy();\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(P instanceof MOB)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal MOB M=(MOB)P;\n\t\t\t\t\t\t\tif(!M.isPlayer())\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal Room R=M.getStartRoom();\n\t\t\t\t\t\t\t\tif((R==null)\n\t\t\t\t\t\t\t\t||(CMath.bset(M.basePhyStats().disposition(),PhyStats.IS_UNSAVABLE)))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif(debug)\n\t\t\t\t\t\t\t\t\t\tLog.debugOut("QuestScript#"+parseId+": Destroying "+P.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(P)));\n\t\t\t\t\t\t\t\t\tM.setFollowing(null);\n\t\t\t\t\t\t\t\t\tCMLib.tracking().wanderAway(M,true,false);\n\t\t\t\t\t\t\t\t\tif(M.location()!=null)\n\t\t\t\t\t\t\t\t\t\tM.location().delInhabitant(M);\n\t\t\t\t\t\t\t\t\tM.setLocation(null);\n\t\t\t\t\t\t\t\t\tM.destroy();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tif((!M.amDead())\n\t\t\t\t\t\t\t\t&&(!M.amDestroyed())\n\t\t\t\t\t\t\t\t&&((M.location()!=R)||(!R.isInhabitant(M))))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif(debug)\n\t\t\t\t\t\t\t\t\t\tLog.debugOut("QuestScript#"+parseId+": Dismissing "+P.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(P)));\n\t\t\t\t\t\t\t\t\tM.setFollowing(null);\n\t\t\t\t\t\t\t\t\tCMLib.tracking().wanderAway(M,false,true);\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}\n\t\t\t}\n\t\t\tif((questState.addons.size()>0)\n\t\t\t&&(stoppingQuest))\n\t\t\t{\n\t\t\t\tsynchronized(questState)\n\t\t\t\t{\n\t\t\t\t\tfor(int i=questState.addons.size()-1;i>=0;i--)\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\tfinal Integer I=questState.addons.get(i).second;\n\t\t\t\t\t\t\tif(I.intValue()>0)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tquestState.addons.get(i).second=Integer.valueOf(I.intValue()-1);\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfinal List<Object> V=questState.addons.get(i).first;\n\t\t\t\t\t\t\tquestState.addons.remove(i);\n\t\t\t\t\t\t\tif(V.size()<2)\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\tfinal Environmental E=(Environmental)V.get(0);\n\t\t\t\t\t\t\tfinal Object O=V.get(1);\n\t\t\t\t\t\t\tif(O instanceof String)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal String stat=(String)O;\n\t\t\t\t\t\t\t\tfinal String parms=(String)V.get(2);\n\t\t\t\t\t\t\t\tif(CMStrings.contains(E.getStatCodes(),stat.toUpperCase().trim()))\n\t\t\t\t\t\t\t\t\tE.setStat(stat,parms);\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tif((E instanceof MOB)&&CMStrings.contains(((Physical)E).basePhyStats().getStatCodes(),stat.toUpperCase().trim()))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif(debug)\n\t\t\t\t\t\t\t\t\t\tLog.debugOut("QuestScript#"+parseId+": Reverting stat "+stat+" on "+E.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(E)));\n\t\t\t\t\t\t\t\t\t((Physical)E).basePhyStats().setStat(stat.toUpperCase().trim(),parms);\n\t\t\t\t\t\t\t\t\t((Physical)E).recoverPhyStats();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tif((E instanceof MOB)&&(CMStrings.contains(CharStats.CODES.NAMES(),stat.toUpperCase().trim())))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif(debug)\n\t\t\t\t\t\t\t\t\t\tLog.debugOut("QuestScript#"+parseId+": Reverting stat "+stat+" on "+E.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(E)));\n\t\t\t\t\t\t\t\t\t((MOB)E).baseCharStats().setStat(CMParms.indexOf(CharStats.CODES.NAMES(),stat.toUpperCase().trim()),CMath.s_int(parms));\n\t\t\t\t\t\t\t\t\t((MOB)E).recoverCharStats();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tif((E instanceof MOB)&&CMStrings.contains(((MOB)E).baseState().getStatCodes(),stat))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif(debug)\n\t\t\t\t\t\t\t\t\t\tLog.debugOut("QuestScript#"+parseId+": Reverting stat "+stat+" on "+E.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(E)));\n\t\t\t\t\t\t\t\t\t((MOB)E).baseState().setStat(stat,parms);\n\t\t\t\t\t\t\t\t\t((MOB)E).recoverMaxState();\n\t\t\t\t\t\t\t\t\t((MOB)E).resetToMaxState();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\tif(O instanceof Behavior)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif(E instanceof PhysicalAgent)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tfinal PhysicalAgent BB=(PhysicalAgent)E;\n\t\t\t\t\t\t\t\t\tBehavior B=BB.fetchBehavior(((Behavior)O).ID());\n\t\t\t\t\t\t\t\t\tif((E instanceof MOB)&&(B instanceof ScriptingEngine))\n\t\t\t\t\t\t\t\t\t\t((ScriptingEngine)B).endQuest((PhysicalAgent)E,(MOB)E,name());\n\t\t\t\t\t\t\t\t\tif((V.size()>2)\n\t\t\t\t\t\t\t\t\t&&(V.get(2) instanceof String))\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif(B==null)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tB=(Behavior)O;\n\t\t\t\t\t\t\t\t\t\t\tB.setParms((String)V.get(2));\n\t\t\t\t\t\t\t\t\t\t\tBB.addBehavior(B);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\t\tB.setParms((String)V.get(2));\n\t\t\t\t\t\t\t\t\t\tif(debug)\n\t\t\t\t\t\t\t\t\t\t\tLog.debugOut("QuestScript#"+parseId+": Reverting bparms on "+B.name()+" on "+E.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(E)));\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\tif(B!=null)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif(debug)\n\t\t\t\t\t\t\t\t\t\t\tLog.debugOut("QuestScript#"+parseId+": Removing behavior "+B.name()+" on "+E.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(E)));\n\t\t\t\t\t\t\t\t\t\tBB.delBehavior(B);\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\telse\n\t\t\t\t\t\t\tif(O instanceof ScriptingEngine)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfinal ScriptingEngine S=(ScriptingEngine)O;\n\t\t\t\t\t\t\t\tif(!S.isSavable())\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tif(E instanceof MOB)\n\t\t\t\t\t\t\t\t\t\tS.endQuest((PhysicalAgent)E,(MOB)E,name());\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tfinal MOB M=CMClass.getFactoryMOB(E.Name(), 1, CMLib.map().roomLocation(E));\n\t\t\t\t\t\t\t\t\t\tS.endQuest((PhysicalAgent)E,M,name());\n\t\t\t\t\t\t\t\t\t\tM.destroy();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif(debug)\n\t\t\t\t\t\t\t\t\t\tLog.debugOut("QuestScript#"+parseId+": Removing script on "+E.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(E)));\n\t\t\t\t\t\t\t\t\t((PhysicalAgent)E).delScript(S);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\tif(O instanceof Ability)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tif((V.size()>2)\n\t\t\t\t\t\t\t\t&&(V.get(2) instanceof Ability)\n\t\t\t\t\t\t\t\t&&(E instanceof MOB))\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAbility A=((MOB)E).fetchAbility(((Ability)O).ID());\n\t\t\t\t\t\t\t\t\tif((V.size()>3)&&(V.get(3) instanceof String))\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif(A==null)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tA=(Ability)O;\n\t\t\t\t\t\t\t\t\t\t\t((MOB)E).addAbility(A);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif(debug)\n\t\t\t\t\t\t\t\t\t\t\tLog.debugOut("QuestScript#"+parseId+": Reverting aparms "+A.ID()+" on "+E.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(E)));\n\t\t\t\t\t\t\t\t\t\tA.setMiscText((String)V.get(3));\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\tif(A!=null)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif(debug)\n\t\t\t\t\t\t\t\t\t\t\tLog.debugOut("QuestScript#"+parseId+": Removing "+A.ID()+" on "+E.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(E)));\n\t\t\t\t\t\t\t\t\t\t((MOB)E).delAbility(A);\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\telse\n\t\t\t\t\t\t\t\tif(E instanceof Physical)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tAbility A=((Physical)E).fetchEffect(((Ability)O).ID());\n\t\t\t\t\t\t\t\t\tif((V.size()>2)&&(V.get(2) instanceof String))\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif(A==null)\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tA=(Ability)O;\n\t\t\t\t\t\t\t\t\t\t\t((Physical)E).addEffect(A);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif(debug)\n\t\t\t\t\t\t\t\t\t\t\tLog.debugOut("QuestScript#"+parseId+": Reverting aparms "+A.ID()+" on "+E.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(E)));\n\t\t\t\t\t\t\t\t\t\tA.setMiscText((String)V.get(2));\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\tif(A!=null)\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tif(debug)\n\t\t\t\t\t\t\t\t\t\t\tLog.debugOut("QuestScript#"+parseId+": Removing "+A.ID()+" on "+E.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(E)));\n\t\t\t\t\t\t\t\t\t\tA.unInvoke();\n\t\t\t\t\t\t\t\t\t\t((Physical)E).delEffect(A);\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\telse\n\t\t\t\t\t\t\tif(O instanceof Item)\n\t\t\t\t\t\t\t\t((Item)O).destroy();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcatch(final ArrayIndexOutOfBoundsException e)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// eat it\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tstoppingQuest=false;\n\t}\n\n\t// this will cause a quest to begin parsing its next "step".\n\t// this will clear out unpreserved objects from previous\n\t// step and resume quest script processing.\n\t// if this is the LAST step, stopQuestInternal() is automatically called\n\n\t@Override\n\tpublic boolean stepQuest()\n\t{\n\t\tif(suspended())\n\t\t\treturn false;\n\t\ttry\n\t\t{\n\t\t\tsetSuspended(true);\n\t\t\tfinal QuestState questState;\n\t\t\tsynchronized(this)\n\t\t\t{\n\t\t\t\tquestState=this.questState;\n\t\t\t}\n\t\t\tif((questState==null)||(stoppingQuest))\n\t\t\t\treturn false;\n\t\t\tfinal String prefix = CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS)?("QuestScript#"+parseId+" "):"";\n\t\t\tif(prefix.length()>0)\n\t\t\t\tLog.debugOut(prefix+" Quest Stepping");\n\t\t\tcleanQuestStep(0);\n\t\t\tticksRemaining=-1;\n\t\t\tsetDuration(-1);\n\n\t\t\tfinal List<Object> args=new ArrayList<Object>();\n\t\t\tfinal List<Object> script=parseLoadScripts(script(),new ArrayList<Object>(),args,true);\n\t\t\ttry\n\t\t\t{\n\t\t\t\tquestState.stepNumber++;\n\t\t\t\tif(prefix.length()>0)\n\t\t\t\t\tLog.debugOut(prefix+" Starting step "+questState.stepNumber+" @line "+questState.lastLine);\n\t\t\t\tsetVars(script,questState.lastLine);\n\t\t\t\tparseQuestScript(script,args,questState.lastLine);\n\t\t\t}\n\t\t\tcatch(final Exception t)\n\t\t\t{\n\t\t\t\tquestState.error=true;\n\t\t\t\tLog.errOut("DefaultQuest",t);\n\t\t\t}\n\t\t\tif(questState.error)\n\t\t\t{\n\t\t\t\tif(!questState.beQuiet)\n\t\t\t\t\tLog.errOut("Quest",prefix+"One or more errors in \'"+name()+"\', quest not started");\n\t\t\t}\n\t\t\telse\n\t\t\tif(!questState.done)\n\t\t\t{\n\t\t\t\t// valid DONE state, when stepping over the end\n\t\t\t}\n\t\t\telse\n\t\t\tif(duration()<0)\n\t\t\t{\n\t\t\t\tLog.errOut("Quest",prefix+"No duration, quest \'"+name()+"\' not started.");\n\t\t\t\tquestState.error=true;\n\t\t\t}\n\n\t\t\tif((!questState.error)&&(questState.done)&&(duration()>=0))\n\t\t\t{\n\t\t\t\tenterRunningState();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t\tstopQuestInternal();\n\t\t}\n\t\tfinally\n\t\t{\n\t\t\tsetSuspended(false);\n\t\t}\n\t\treturn false;\n\t}\n\n\tprotected int getLineNumberForStep(final int stepNum)\n\t{\n\t\tif(stepNum <= 1)\n\t\t\treturn 0;\n\t\tfinal List<Object> args=new ArrayList<Object>();\n\t\tfinal List<Object> oscript=parseLoadScripts(script(),new ArrayList<Object>(),args,true);\n\t\tfinal List<String> script=parseFinalQuestScript(oscript);\n\t\tint currentStepNumber=1;\n\t\tfor(int v=0;v<script.size();v++)\n\t\t{\n\t\t\tfinal String s=modifyStringFromArgs(script.get(v),args);\n\t\t\tfinal List<String> p=CMParms.parse(s);\n\t\t\tif(p.size()>0)\n\t\t\t{\n\t\t\t\tfinal String cmd=p.get(0).toUpperCase();\n\t\t\t\tif(cmd.equals("STEP"))\n\t\t\t\t{\n\t\t\t\t\tif((++currentStepNumber)==stepNum)\n\t\t\t\t\t\treturn v+1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t}\n\n\t// this will cause a quest to begin parsing at the given "step".\n\t// this will clear out unpreserved objects from previous\n\t// step and resume quest script processing.\n\t// if this is the LAST step, stopQuestInternal() is automatically called\n\t@Override\n\tpublic boolean setQuestStep(final int stepNum)\n\t{\n\t\tif(stepNum <=0)\n\t\t\treturn false;\n\t\tfinal QuestState questState;\n\t\tsynchronized(this)\n\t\t{\n\t\t\tquestState=this.questState;\n\t\t}\n\t\tif(questState==null)\n\t\t\treturn false;\n\t\tif(suspended())\n\t\t\treturn false;\n\t\tfinal DefaultQuest qSave=this;\n\t\tfinal Runnable setQuestStepRunnable;\n\t\tsetQuestStepRunnable= new Runnable()\n\t\t{\n\t\t\tprivate final int targetStepNum=stepNum;\n\t\t\tprivate final DefaultQuest Q=qSave;\n\t\t\tprivate final QuestState qs=questState;\n\t\t\t@Override\n\t\t\tpublic void run()\n\t\t\t{\n\t\t\t\tfinal String prefix = CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS)?("QuestScript#"+parseId+" "):"";\n\t\t\t\tif(prefix.length()>0)\n\t\t\t\t\tLog.debugOut("QuestScript#"+parseId+" setQuestStep: "+stepNum);\n\t\t\t\tboolean stoppingQuest;\n\t\t\t\tsynchronized(Q)\n\t\t\t\t{\n\t\t\t\t\tstoppingQuest=Q.stoppingQuest; // does this really ensure cpu cache thwarting?\n\t\t\t\t}\n\t\t\t\tif(stoppingQuest)\n\t\t\t\t{\n\t\t\t\t\tLog.errOut("DefaultQuest",prefix+"OMG Still stopping "+name()+" when I want to set the "+targetStepNum+" step.");\n\t\t\t\t\tCMLib.threads().scheduleRunnable(this, 1000);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif(suspended())\n\t\t\t\t{\n\t\t\t\t\tLog.errOut("DefaultQuest",prefix+"OMG Still stopping "+name()+" when in a state of suspense.");\n\t\t\t\t\tCMLib.threads().scheduleRunnable(this, 1000);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tsetSuspended(true);\n\t\t\t\t\tfinal int newLine=getLineNumberForStep(targetStepNum);\n\t\t\t\t\tif(newLine < 0) // was an illegal target step\n\t\t\t\t\t{\n\t\t\t\t\t\tLog.errOut("DefaultQuest",prefix+"Quest "+name()+" illegally tried to target the "+targetStepNum+" step.");\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tticksRemaining=-1;\n\t\t\t\t\tsetDuration(-1);\n\t\t\t\t\tfinal int curStep=qs.stepNumber;\n\t\t\t\t\tif(targetStepNum<curStep)\n\t\t\t\t\t\tcleanQuestStep(Integer.MAX_VALUE/4);\n\t\t\t\t\telse\n\t\t\t\t\t\tcleanQuestStep(targetStepNum-curStep-1);\n\t\t\t\t\tfinal List<Object> args=new ArrayList<Object>();\n\t\t\t\t\tfinal List<Object> script=parseLoadScripts(script(),new ArrayList<Object>(),args,true);\n\t\t\t\t\ttry\n\t\t\t\t\t{\n\t\t\t\t\t\tqs.stepNumber=stepNum;\n\t\t\t\t\t\tqs.lastLine=newLine;\n\t\t\t\t\t\tif(prefix.length()>0)\n\t\t\t\t\t\t\tLog.debugOut(prefix+" Setting step "+questState.stepNumber+" @line "+questState.lastLine);\n\t\t\t\t\t\tsetVars(script,qs.lastLine);\n\t\t\t\t\t\tparseQuestScript(script,args,qs.lastLine);\n\t\t\t\t\t}\n\t\t\t\t\tcatch(final Exception t)\n\t\t\t\t\t{\n\t\t\t\t\t\tqs.error=true;\n\t\t\t\t\t\tLog.errOut("DefaultQuest",t);\n\t\t\t\t\t}\n\t\t\t\t\tif(qs.error)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(!qs.beQuiet)\n\t\t\t\t\t\t\tLog.errOut("Quest",prefix+"One or more errors in \'"+name()+"\', quest not started");\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(!qs.done)\n\t\t\t\t\t{\n\t\t\t\t\t\t// valid DONE state, when stepping over the end\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(duration()<0)\n\t\t\t\t\t{\n\t\t\t\t\t\tLog.errOut("Quest",prefix+"No duration, quest \'"+name()+"\' not started.");\n\t\t\t\t\t\tqs.error=true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif((!qs.error)&&(qs.done)&&(duration()>=0))\n\t\t\t\t\t{\n\t\t\t\t\t\tenterRunningState();\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tstopQuestInternal();\n\t\t\t\t}\n\t\t\t\tfinally\n\t\t\t\t{\n\t\t\t\t\tsetSuspended(false);\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tif(stoppingQuest)\n\t\t{\n\t\t\tCMLib.threads().scheduleRunnable(setQuestStepRunnable, 500);\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsetQuestStepRunnable.run();\n\t\t\treturn !questState.error;\n\t\t}\n\t}\n\n\t@Override\n\tpublic void resetQuest(final int firstPauseTicks)\n\t{\n\t\tif(stoppingQuest)\n\t\t\treturn;\n\t\t// ticksRemaining of -1 is OK, it will grab duration\n\t\tresetData=new int[]{firstPauseTicks,ticksRemaining};\n\t\tstopQuest();\n\t}\n\n\t@Override\n\tpublic void stopQuest()\n\t{\n\t\tif((!stoppingQuest)&&(running()))\n\t\t\tCMLib.coffeeTables().bump(this,CoffeeTableRow.STAT_QUESTSUCCESS);\n\t\tstopQuestInternal();\n\t}\n\n\t// this will stop executing of the quest script.  It will clean up\n\t// any objects or mobs which may have been loaded, restoring map\n\t// mobs to their previous state.\n\tpublic void stopQuestInternal()\n\t{\n\t\tif(stoppingQuest)\n\t\t\treturn;\n\t\t// first set everything to complete!\n\t\tsynchronized(questState)\n\t\t{\n\t\t\tfor(final PreservedQuestObject PO : questState.worldObjects)\n\t\t\t\tPO.preserveState=0;\n\t\t\tfor(final Pair<List<Object>,Integer> p : questState.addons)\n\t\t\t\tp.second=Integer.valueOf(0);\n\t\t\tquestState.autoStepAfterDuration=false;\n\t\t}\n\t\tcleanQuestStep(0);\n\t\tstoppingQuest=true;\n\t\tif(!isCopy())\n\t\t\tsetScript(script(),true); // causes wait times/name to reload\n\t\tenterDormantState();\n\t\tstoppingQuest=false;\n\t}\n\n\t@Override\n\tpublic boolean enterDormantState()\n\t{\n\t\tticksRemaining=-1;\n\t\tif((isCopy())||(!resetWaitRemaining(0)))\n\t\t{\n\t\t\tResources.removeResource("VARSCOPE-"+name.toUpperCase().trim());\n\t\t\tCMLib.quests().delQuest(this);\n\t\t\tCMLib.threads().deleteTick(this,Tickable.TICKID_QUEST);\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic boolean resetWaitRemaining(final long ellapsedTime)\n\t{\n\n\t\tif(resetData!=null)\n\t\t{\n\t\t\twaitRemaining=resetData[0];\n\t\t\tresetData[0]*=2;\n\t\t\treturn true;\n\t\t}\n\n\t\tif(((minWait()<0)||(maxWait<0))\n\t\t&&(startDate().trim().length()==0))\n\t\t\treturn false;\n\t\tif(running())\n\t\t\treturn true;\n\t\tif(startDate().length()>0)\n\t\t{\n\t\t\tif(startDate().toUpperCase().startsWith("MUDDAY"))\n\t\t\t{\n\t\t\t\tfinal String sd2=startDate().substring("MUDDAY".length()).trim();\n\t\t\t\tfinal int x=sd2.indexOf(\'-\');\n\t\t\t\tif(x<0)\n\t\t\t\t\treturn false;\n\t\t\t\tfinal int mudmonth=CMath.s_parseIntExpression(sd2.substring(0,x));\n\t\t\t\tfinal int mudday=CMath.s_parseIntExpression(sd2.substring(x+1));\n\t\t\t\tfinal TimeClock C=(TimeClock)CMClass.getCommon("DefaultTimeClock");\n\t\t\t\tfinal TimeClock NOW=CMLib.time().globalClock();\n\t\t\t\tC.setMonth(mudmonth);\n\t\t\t\tC.setDayOfMonth(mudday);\n\t\t\t\tC.setHourOfDay(0);\n\t\t\t\tif((mudmonth<NOW.getMonth())\n\t\t\t\t||((mudmonth==NOW.getMonth())&&(mudday<NOW.getDayOfMonth())))\n\t\t\t\t\tC.setYear(NOW.getYear()+1);\n\t\t\t\telse\n\t\t\t\t\tC.setYear(NOW.getYear());\n\t\t\t\tfinal long distance=C.deriveMillisAfter(NOW);\n\t\t\t\twaitRemaining=(int)(distance/CMProps.getTickMillis());\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfinal int x=startDate.indexOf(\'-\');\n\t\t\t\tif(x<0)\n\t\t\t\t\treturn false;\n\t\t\t\tfinal int month=CMath.s_parseIntExpression(startDate.substring(0,x));\n\t\t\t\tfinal int day=CMath.s_parseIntExpression(startDate.substring(x+1));\n\t\t\t\tint year=Calendar.getInstance().get(Calendar.YEAR);\n\t\t\t\tlong distance=CMLib.time().string2Millis(month+"/"+day+"/"+year+" 12:00 AM");\n\t\t\t\tfinal Calendar C=Calendar.getInstance();\n\t\t\t\tfinal long today=CMLib.time().string2Millis((C.get(Calendar.MONTH)+1)+"/"+C.get(Calendar.DAY_OF_MONTH)+"/"+C.get(Calendar.YEAR)+" 12:00 AM");\n\t\t\t\twhile(distance<today)\n\t\t\t\t\tdistance=CMLib.time().string2Millis(month+"/"+day+"/"+(++year)+" 12:00 AM");\n\t\t\t\twaitRemaining=(int)((distance-today)/CMProps.getTickMillis());\n\t\t\t}\n\t\t}\n\t\telse\n\t\t\twaitRemaining=(minWait+(CMLib.dice().roll(1,maxWait,0)))-(int)(ellapsedTime/CMProps.getTickMillis());\n\t\treturn true;\n\t}\n\n\t@Override\n\tpublic int minWait()\n\t{\n\t\treturn minWait;\n\t}\n\n\t@Override\n\tpublic void setMinWait(final int wait)\n\t{\n\t\tminWait = wait;\n\t}\n\n\t@Override\n\tpublic int waitInterval()\n\t{\n\t\treturn maxWait;\n\t}\n\n\t@Override\n\tpublic void setWaitInterval(final int wait)\n\t{\n\t\tmaxWait = wait;\n\t}\n\n\t@Override\n\tpublic int waitRemaining()\n\t{\n\t\treturn waitRemaining;\n\t}\n\n\tpublic Quest getMainQuestObject()\n\t{\n\t\tQuest Q=this;\n\t\tif(isCopy())\n\t\t{\n\t\t\tQuest Q2=null;\n\t\t\tfor(int q=0;q<CMLib.quests().numQuests();q++)\n\t\t\t{\n\t\t\t\tQ2=CMLib.quests().fetchQuest(q);\n\t\t\t\tif((Q2!=null)&&(Q2.name().equals(name))&&(!isCopy()))\n\t\t\t\t{\n\t\t\t\t\tQ = Q2;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn Q;\n\t}\n\n\t// if the quest has a winner, this is him.\n\t@Override\n\tpublic void declareWinner(String name)\n\t{\n\t\tif(name==null)\n\t\t\treturn;\n\t\tname=name.trim();\n\t\tif(name.length()==0)\n\t\t\treturn;\n\t\tfinal Quest Q=getMainQuestObject();\n\t\tboolean wasWinner = false;\n\t\tboolean removeMe = false;\n\t\tif(name.startsWith("-"))\n\t\t{\n\t\t\tname=name.substring(1);\n\t\t\tremoveMe=true;\n\t\t}\n\t\tfinal Map<String,Long> V=Q.getWinners();\n\t\tif(V.remove(name) != null)\n\t\t{\n\t\t\twasWinner = true;\n\t\t}\n\t\tif(removeMe)\n\t\t{\n\t\t\tif(wasWinner)\n\t\t\t{\n\t\t\t\tCMLib.database().DBUpdateQuest(Q);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tQ.getWinners().put(name,Long.valueOf(System.currentTimeMillis()));\n\t\t\tCMLib.database().DBUpdateQuest(Q);\n\t\t}\n\t}\n\n\t@Override\n\tpublic String getWinnerStr()\n\t{\n\t\tfinal Quest Q=getMainQuestObject();\n\t\tfinal StringBuffer list=new StringBuffer("");\n\t\tfinal Map<String,Long> V=Q.getWinners();\n\t\tfor(final String name : V.keySet())\n\t\t{\n\t\t\tfinal Long time=V.get(name);\n\t\t\tlist.append(name+"@"+time.longValue()+";");\n\t\t}\n\t\treturn list.toString();\n\t}\n\n\t@Override\n\tpublic void setWinners(final String list)\n\t{\n\t\tfinal Quest Q=getMainQuestObject();\n\t\tfinal Map<String,Long> V=Q.getWinners();\n\t\tV.clear();\n\t\tfinal List<String> parts=CMParms.parseSemicolons(list, true);\n\t\tfor(final String part : parts)\n\t\t{\n\t\t\tif(part.trim().length()>0)\n\t\t\t{\n\t\t\t\tfinal int x=part.indexOf(\'@\');\n\t\t\t\tLong time=Long.valueOf(0);\n\t\t\t\tString name=part.trim();\n\t\t\t\tif(x>0)\n\t\t\t\t{\n\t\t\t\t\tname=part.substring(0,x).trim();\n\t\t\t\t\ttime=Long.valueOf(CMath.s_long(part.substring(x+1).trim()));\n\t\t\t\t}\n\t\t\t\tV.put(name,time);\n\t\t\t}\n\t\t}\n\t}\n\n\t// retrieve the list of previous winners\n\t@Override\n\tpublic Map<String, Long> getWinners()\n\t{\n\t\tfinal Quest Q=getMainQuestObject();\n\t\tif(Q==this)\n\t\t\treturn winners;\n\t\treturn Q.getWinners();\n\t}\n\n\t// was a previous winner\n\t@Override\n\tpublic boolean wasWinner(final String name)\n\t{\n\t\treturn whenLastWon(name) != null;\n\t}\n\n\t// was a previous winner\n\t@Override\n\tpublic Long whenLastWon(String name)\n\t{\n\t\tif(name==null)\n\t\t\treturn null;\n\t\tname=name.trim();\n\t\tif(name.length()==0)\n\t\t\treturn null;\n\t\tfinal Quest Q=getMainQuestObject();\n\t\tfinal Map<String,Long> V=Q.getWinners();\n\t\treturn V.get(name);\n\t}\n\n\t// informational\n\t@Override\n\tpublic boolean running()\n\t{\n\t\treturn ticksRemaining >= 0;\n\t}\n\n\t@Override\n\tpublic boolean stopping()\n\t{\n\t\treturn stoppingQuest;\n\t}\n\n\t@Override\n\tpublic boolean waiting()\n\t{\n\t\treturn waitRemaining >= 0;\n\t}\n\n\t@Override\n\tpublic int ticksRemaining()\n\t{\n\t\treturn ticksRemaining;\n\t}\n\n\t@Override\n\tpublic int minsRemaining()\n\t{\n\t\treturn (int) (ticksRemaining * CMProps.getTickMillis() / 60000);\n\t}\n\n\tprivate int\ttickStatus\t= Tickable.STATUS_NOT;\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(tickID!=Tickable.TICKID_QUEST)\n\t\t\treturn false;\n\t\tif(CMSecurity.isDisabled(CMSecurity.DisFlag.QUESTS)\n\t\t||(CMProps.getBoolVar(CMProps.Bool.MUDSHUTTINGDOWN))\n\t\t||(!CMProps.getBoolVar(CMProps.Bool.MUDSTARTED))\n\t\t||(suspended()))\n\t\t\treturn true;\n\n\t\tsynchronized(this) // mostly just to fix cpu cache issues\n\t\t{\n\t\t\ttickStatus=Tickable.STATUS_START;\n\t\t}\n\t\tif(running())\n\t\t{\n\t\t\ttickStatus=Tickable.STATUS_ALIVE;\n\t\t\tif(duration()>0)\n\t\t\t\tticksRemaining--;\n\t\t\tif(ticksRemaining<0)\n\t\t\t{\n\t\t\t\tif((questState!=null)&&(questState.autoStepAfterDuration))\n\t\t\t\t{\n\t\t\t\t\tstepQuest();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tCMLib.coffeeTables().bump(this,CoffeeTableRow.STAT_QUESTTIMESTOP);\n\t\t\t\t\tstopQuest();\n\t\t\t\t}\n\t\t\t}\n\t\t\ttickStatus=Tickable.STATUS_END;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tif(startQuestOnTime())\n\t\t\t{\n\t\t\t\tCMLib.coffeeTables().bump(this,CoffeeTableRow.STAT_QUESTTIMESTART);\n\t\t\t}\n\t\t}\n\t\ttickStatus=Tickable.STATUS_NOT;\n\t\treturn true;\n\t}\n\n\tprotected boolean startQuestOnTime()\n\t{\n\t\tif((--waitRemaining)>=0)\n\t\t\treturn false;\n\t\tboolean allowedToRun=true;\n\t\tif(runLevel()>=0)\n\t\t{\n\t\t\tfor(int q=0;q<CMLib.quests().numQuests();q++)\n\t\t\t{\n\t\t\t\tfinal Quest Q=CMLib.quests().fetchQuest(q);\n\t\t\t\tif((!Q.name().equals(name))\n\t\t\t\t&&(Q.running())\n\t\t\t\t&&(Q.duration()!=0)\n\t\t\t\t&&(Q.runLevel()<=runLevel())\n\t\t\t\t&&(Q.runLevel()>=0))\n\t\t\t\t{\n\t\t\t\t\tallowedToRun = false;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif(allowedToRun)\n\t\t{\n\t\t\tint numEligiblePlayers=0;\n\t\t\tfinal boolean isMask=(playerMask.length()>0);\n\t\t\tfor(final Session S : CMLib.sessions().localOnlineIterable())\n\t\t\t{\n\t\t\t\tif((S.mob()!=null)\n\t\t\t\t&&((!isMask) || CMLib.masking().maskCheck(playerMask,S.mob(),true)))\n\t\t\t\t\tnumEligiblePlayers++;\n\t\t\t}\n\t\t\tticksRemaining=-1;\n\t\t\tif((numEligiblePlayers>=minPlayers)||(duration()==0))\n\t\t\t\treturn startQuestInternal();\n\t\t}\n\t\tenterDormantState();\n\t\treturn false;\n\t}\n\n\tprotected Ability findQuestAbility(final String abilityID)\n\t{\n\t\tAbility A4=CMClass.getAbility(abilityID);\n\t\tif((A4==null)\n\t\t&&(questState.ability!=null)\n\t\t&&(abilityID.equalsIgnoreCase(this.questState.ability.ID())\n\t\t\t||abilityID.equalsIgnoreCase(this.questState.ability.name())))\n\t\t\tA4=questState.ability;\n\t\tif((A4==null)\n\t\t&&(questState.abilityGroup!=null)\n\t\t&&(questState.abilityGroup.size()>0))\n\t\t{\n\t\t\tfor(final Ability A : questState.abilityGroup)\n\t\t\t{\n\t\t\t\tif((abilityID.equalsIgnoreCase(A.ID())\n\t\t\t\t||abilityID.equalsIgnoreCase(A.name())))\n\t\t\t\t\tA4=A;\n\t\t\t}\n\t\t}\n\t\tif((A4==null)\n\t\t&&(questState.loadedAbilities!=null)\n\t\t&&(questState.loadedAbilities.size()>0))\n\t\t{\n\t\t\tfor(final Ability A : questState.loadedAbilities)\n\t\t\t{\n\t\t\t\tif((abilityID.equalsIgnoreCase(A.ID())\n\t\t\t\t||abilityID.equalsIgnoreCase(A.name())))\n\t\t\t\t\tA4=A;\n\t\t\t}\n\t\t}\n\t\treturn A4;\n\t}\n\n\t@Override\n\tpublic void runtimeRegisterAbility(final MOB mob, final String abilityID, final String parms, final boolean give)\n\t{\n\t\tif(mob==null)\n\t\t\treturn;\n\t\truntimeRegisterObject(mob);\n\t\tfinal List<Object> V=Collections.synchronizedList(new ArrayList<Object>());\n\t\tV.add(mob);\n\t\tAbility A4=mob.fetchAbility(abilityID);\n\t\tif(A4!=null)\n\t\t{\n\t\t\tV.add(A4);\n\t\t\tV.add(A4);\n\t\t\tV.add(A4.text());\n\t\t\tif(give)\n\t\t\t{\n\t\t\t\tA4.setMiscText(parms);\n\t\t\t\tA4.setProficiency(100);\n\t\t\t}\n\t\t\telse\n\t\t\t\tmob.delAbility(A4);\n\t\t}\n\t\telse\n\t\tif(!give)\n\t\t\treturn;\n\t\telse\n\t\t{\n\t\t\tA4=findQuestAbility(abilityID);\n\t\t\tif(A4==null)\n\t\t\t\treturn;\n\t\t\tA4.setMiscText(parms);\n\t\t\tV.add(A4);\n\t\t\tV.add(A4);\n\t\t\tA4.setProficiency(100);\n\t\t\tA4.setSavable(false); // because, WHY WOULD IT BE SAVABLE?!\n\t\t\tmob.addAbility(A4);\n\t\t}\n\t\tsynchronized(questState)\n\t\t{\n\t\t\tquestState.addons.add(V,Integer.valueOf(questState.preserveState));\n\t\t}\n\t}\n\n\t@Override\n\tpublic void runtimeRegisterObject(final PhysicalAgent P)\n\t{\n\t\tif(P==null)\n\t\t\treturn;\n\t\tsynchronized(questState)\n\t\t{\n\t\t\tfor(final PreservedQuestObject PO : questState.worldObjects)\n\t\t\t{\n\t\t\t\tif(PO.obj==P)\n\t\t\t\t{\n\t\t\t\t\tif(PO.preserveState<questState.preserveState)\n\t\t\t\t\t\tPO.preserveState=questState.preserveState;\n\t\t\t\t\t//questState.worldObjects.add(PO); // why re-adding?\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif(PO.obj.amDestroyed())\n\t\t\t\t\tquestState.worldObjects.remove(PO);\n\t\t\t}\n\t\t\tif(CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS))\n\t\t\t\tLog.debugOut("QuestScript#"+parseId+": Registering object "+P.Name()+" ("+P.ID()+") @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(P)));\n\t\t\tquestState.worldObjects.add(new PreservedQuestObject(P,questState.preserveState));\n\t\t\tAbility A=P.fetchEffect("QuestBound");\n\t\t\tif(A==null)\n\t\t\t\tA=CMClass.getAbility("QuestBound");\n\t\t\tA.setMiscText(""+this);\n\t\t\tA.setSavable(false);\n\t\t\tP.addNonUninvokableEffect(A);\n\t\t}\n\t}\n\n\t@Override\n\tpublic void runtimeRegisterEffect(final PhysicalAgent affected, final String abilityID, final String parms, final boolean give)\n\t{\n\t\tif(affected==null)\n\t\t\treturn;\n\t\truntimeRegisterObject(affected);\n\t\tfinal List<Object> V=Collections.synchronizedList(new ArrayList<Object>());\n\t\tV.add(affected);\n\t\tAbility A4=affected.fetchEffect(abilityID);\n\t\tif(A4!=null)\n\t\t{\n\t\t\tV.add(A4);\n\t\t\tV.add(A4.text());\n\t\t\tif(give)\n\t\t\t{\n\t\t\t\tA4.makeLongLasting();\n\t\t\t\tA4.setMiscText(parms);\n\t\t\t}\n\t\t\telse\n\t\t\t\taffected.delEffect(A4);\n\t\t}\n\t\telse\n\t\tif(!give)\n\t\t\treturn;\n\t\telse\n\t\t{\n\t\t\tA4=findQuestAbility(abilityID);\n\t\t\tif(A4==null)\n\t\t\t\treturn;\n\t\t\tV.add(A4);\n\t\t\tA4.setMiscText(parms);\n\t\t\tif(affected instanceof MOB)\n\t\t\t\tA4.startTickDown((MOB)affected,affected,99999);\n\t\t\telse\n\t\t\t\tA4.startTickDown(null,affected,99999);\n\t\t\tA4.setSavable(false); // because, WHY WOULD IT BE SAVABLE?!\n\t\t\tA4.makeLongLasting();\n\t\t}\n\t\tsynchronized(questState)\n\t\t{\n\t\t\tif(CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS))\n\t\t\t\tLog.debugOut("QuestScript#"+parseId+": Registering effect "+abilityID+" on "+affected.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(affected)));\n\t\t\tquestState.addons.add(V,Integer.valueOf(questState.preserveState));\n\t\t}\n\t}\n\n\t@Override\n\tpublic void runtimeRegisterBehavior(final PhysicalAgent behaving, final String behaviorID, final String parms, final boolean give)\n\t{\n\t\tif(behaving==null)\n\t\t\treturn;\n\t\truntimeRegisterObject(behaving);\n\t\tfinal List<Object> V=Collections.synchronizedList(new ArrayList<Object>());\n\t\tV.add(behaving);\n\t\tBehavior B=behaving.fetchBehavior(behaviorID);\n\t\tif(B!=null)\n\t\t{\n\t\t\tV.add(B);\n\t\t\tV.add(B.getParms());\n\t\t\tif(give)\n\t\t\t\tB.setParms(parms);\n\t\t\telse\n\t\t\t\tbehaving.delBehavior(B);\n\t\t}\n\t\telse\n\t\tif(!give)\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tB=CMClass.getBehavior(behaviorID);\n\t\t\tif(B==null)\n\t\t\t\treturn;\n\t\t\tV.add(B);\n\t\t\tB.setParms(parms);\n\t\t\tB.setSavable(false); // because, WHY WOULD IT BE SAVABLE?!\n\t\t\tbehaving.addBehavior(B);\n\t\t}\n\t\tB.registerDefaultQuest(name());\n\t\tsynchronized(questState)\n\t\t{\n\t\t\tif(CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS))\n\t\t\t\tLog.debugOut("QuestScript#"+parseId+": Registering effect "+behaviorID+" on "+behaving.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(behaving)));\n\t\t\tquestState.addons.add(V,Integer.valueOf(questState.preserveState));\n\t\t}\n\t}\n\n\tpublic void runtimeRegisterStat(final Environmental E, String stat, final String parms, final boolean give)\n\t{\n\t\tif(E==null)\n\t\t\treturn;\n\t\tif(E instanceof PhysicalAgent)\n\t\t\truntimeRegisterObject((PhysicalAgent)E);\n\t\tfinal List<Object> V=Collections.synchronizedList(new ArrayList<Object>());\n\t\tV.add(E);\n\t\tstat=stat.toUpperCase().trim();\n\t\tString oldVal="";\n\t\tif(CMStrings.contains(E.getStatCodes(),stat))\n\t\t\toldVal=E.getStat(stat);\n\t\telse\n\t\tif((E instanceof Physical)&&CMStrings.contains(((Physical)E).basePhyStats().getStatCodes(),stat))\n\t\t\toldVal=((Physical)E).basePhyStats().getStat(stat);\n\t\telse\n\t\tif((E instanceof MOB)&&(CMStrings.contains(CharStats.CODES.NAMES(),stat)))\n\t\t\toldVal=""+((MOB)E).baseCharStats().getStat(CMParms.indexOf(CharStats.CODES.NAMES(),stat));\n\t\telse\n\t\tif((E instanceof MOB)&&CMStrings.contains(((MOB)E).baseState().getStatCodes(),stat))\n\t\t\toldVal=((MOB)E).baseState().getStat(stat);\n\t\tV.add(stat);\n\t\tV.add(oldVal);\n\t\tif(!give)\n\t\t\treturn;\n\t\tV.add(stat);\n\t\tV.add(oldVal);\n\t\tif(CMStrings.contains(E.getStatCodes(),stat))\n\t\t\tE.setStat(stat,parms);\n\t\telse\n\t\tif((E instanceof Physical)&&CMStrings.contains(((Physical)E).basePhyStats().getStatCodes(),stat))\n\t\t{\n\t\t\t((Physical)E).basePhyStats().setStat(stat,parms);\n\t\t\t((Physical)E).recoverPhyStats();\n\t\t}\n\t\telse\n\t\tif((E instanceof MOB)&&(CMStrings.contains(CharStats.CODES.NAMES(),stat)))\n\t\t{\n\t\t\t((MOB)E).baseCharStats().setStat(CMParms.indexOf(CharStats.CODES.NAMES(),stat),CMath.s_int(parms));\n\t\t\t((MOB)E).recoverCharStats();\n\t\t}\n\t\telse\n\t\tif((E instanceof MOB)&&CMStrings.contains(((MOB)E).baseState().getStatCodes(),stat))\n\t\t{\n\t\t\t((MOB)E).baseState().setStat(stat,parms);\n\t\t\t((MOB)E).recoverMaxState();\n\t\t\t((MOB)E).resetToMaxState();\n\t\t}\n\t\tsynchronized(questState)\n\t\t{\n\t\t\tif(CMSecurity.isDebugging(DbgFlag.QUESTSCRIPTS))\n\t\t\t\tLog.debugOut("QuestScript#"+parseId+": Registering stat "+stat+" on "+E.Name()+" @"+CMLib.map().getApproximateExtendedRoomID(CMLib.map().roomLocation(E)));\n\t\t\tquestState.addons.add(V,Integer.valueOf(questState.preserveState));\n\t\t}\n\t}\n\n\tpublic int getQuestThingIndex(final Iterator<? extends Environmental> i, final String name, final CMClass.CMObjectType type, final int[] num)\n\t{\n\t\tif(i==null)\n\t\t\treturn -1;\n\t\tEnvironmental E;\n\t\tif(name.startsWith("*"))\n\t\t{\n\t\t\tif(name.endsWith("*"))\n\t\t\t{\n\t\t\t\tfinal String iname=(name.length()>1)?name.substring(1,name.length()-1).toLowerCase():"";\n\t\t\t\tfor(;i.hasNext();)\n\t\t\t\t{\n\t\t\t\t\tE=i.next();\n\t\t\t\t\tif(CMClass.isType(E,type))\n\t\t\t\t\t{\n\t\t\t\t\t\tswitch(type)\n\t\t\t\t\t\t{\n\t\t\t\t\t\tcase LOCALE:\n\t\t\t\t\t\t\tif(CMLib.map().getExtendedRoomID((Room)E).toLowerCase().indexOf(iname)>=0)\n\t\t\t\t\t\t\t\treturn num[0];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tif(E.Name().toLowerCase().indexOf(iname)>=0)\n\t\t\t\t\t\t\t\treturn num[0];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnum[0]++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfinal String iname=name.substring(1).toLowerCase();\n\t\t\t\tfor(;i.hasNext();)\n\t\t\t\t{\n\t\t\t\t\tE=i.next();\n\t\t\t\t\tif(CMClass.isType(E,type))\n\t\t\t\t\t{\n\t\t\t\t\t\tswitch(type)\n\t\t\t\t\t\t{\n\t\t\t\t\t\tcase LOCALE:\n\t\t\t\t\t\t\tif(CMLib.map().getExtendedRoomID((Room)E).toLowerCase().endsWith(iname))\n\t\t\t\t\t\t\t\treturn num[0];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\tif(E.Name().toLowerCase().endsWith(iname))\n\t\t\t\t\t\t\t\treturn num[0];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tnum[0]++;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\tif(name.endsWith("*"))\n\t\t{\n\t\t\tfinal String iname=name.substring(0,name.length()-1).toLowerCase();\n\t\t\tfor(;i.hasNext();)\n\t\t\t{\n\t\t\t\tE=i.next();\n\t\t\t\tif(CMClass.isType(E,type))\n\t\t\t\t{\n\t\t\t\t\tswitch(type)\n\t\t\t\t\t{\n\t\t\t\t\tcase LOCALE:\n\t\t\t\t\t\tif(CMLib.map().getExtendedRoomID((Room)E).toLowerCase().startsWith(iname))\n\t\t\t\t\t\t\treturn num[0];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif(E.Name().toLowerCase().startsWith(iname))\n\t\t\t\t\t\t\treturn num[0];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tnum[0]++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfor(;i.hasNext();)\n\t\t\t{\n\t\t\t\tE=i.next();\n\t\t\t\tif(CMClass.isType(E,type))\n\t\t\t\t{\n\t\t\t\t\tswitch(type)\n\t\t\t\t\t{\n\t\t\t\t\tcase LOCALE:\n\t\t\t\t\t\tif(CMLib.map().getExtendedRoomID((Room)E).equalsIgnoreCase(name))\n\t\t\t\t\t\t\treturn num[0];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tif(E.Name().equalsIgnoreCase(name))\n\t\t\t\t\t\t\treturn num[0];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tnum[0]++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t}\n\n\t@Override\n\tpublic int getQuestMobIndex(final String name)\n\t{\n\t\tfinal int[] num={1};\n\t\tint x=-1;\n\t\tsynchronized(questState)\n\t\t{\n\t\t\tif(questState.worldObjects!=null)\n\t\t\t\tx=getQuestThingIndex(PreservedQuestObject.getPOIter(questState.worldObjects),name,CMClass.CMObjectType.MOB,num);\n\t\t\tif((x<0)&&(questState.mobGroup!=null))\n\t\t\t\tx=getQuestThingIndex(questState.mobGroup.iterator(),name,CMClass.CMObjectType.MOB,num);\n\t\t\tif((x<0)&&(questState.mysteryData!=null)&&(questState.mysteryData.agentGroup!=null))\n\t\t\t\tx=getQuestThingIndex(questState.mysteryData.agentGroup.iterator(),name,CMClass.CMObjectType.MOB,num);\n\t\t}\n\t\treturn x;\n\t}\n\n\t@Override\n\tpublic int getQuestRoomIndex(final String roomID)\n\t{\n\t\tfinal int[] num={1};\n\t\tint x=-1;\n\t\tsynchronized(questState)\n\t\t{\n\t\t\tif(questState.worldObjects!=null)\n\t\t\t\tx=getQuestThingIndex(PreservedQuestObject.getPOIter(questState.worldObjects),roomID,CMClass.CMObjectType.LOCALE,num);\n\t\t\tif((x<0)&&(questState.roomGroup!=null))\n\t\t\t\tx=getQuestThingIndex(questState.roomGroup.iterator(),roomID,CMClass.CMObjectType.LOCALE,num);\n\t\t\tif(questState.mysteryData!=null)\n\t\t\t{\n\t\t\t\tif((x<0)&&(questState.mysteryData.whereAtGroup!=null))\n\t\t\t\t\tx=getQuestThingIndex(questState.mysteryData.whereAtGroup.iterator(),roomID,CMClass.CMObjectType.LOCALE,num);\n\t\t\t\tif((x<0)&&(questState.mysteryData.whereHappenedGroup!=null))\n\t\t\t\t\tx=getQuestThingIndex(questState.mysteryData.whereHappenedGroup.iterator(),roomID,CMClass.CMObjectType.LOCALE,num);\n\t\t\t}\n\t\t}\n\t\treturn x;\n\t}\n\n\t@Override\n\tpublic int getQuestItemIndex(final String name)\n\t{\n\t\tfinal int[] num={1};\n\t\tint x=-1;\n\t\tsynchronized(questState)\n\t\t{\n\t\t\tif(questState.worldObjects!=null)\n\t\t\t\tx=getQuestThingIndex(PreservedQuestObject.getPOIter(questState.worldObjects),name,CMClass.CMObjectType.ITEM,num);\n\t\t\tif((x<0)&&(questState.itemGroup!=null))\n\t\t\t\tx=getQuestThingIndex(questState.itemGroup.iterator(),name,CMClass.CMObjectType.ITEM,num);\n\t\t\tif(questState.mysteryData!=null)\n\t\t\t{\n\t\t\t\tif((x<0)&&(questState.mysteryData.toolGroup!=null))\n\t\t\t\t\tx=getQuestThingIndex(questState.mysteryData.toolGroup.iterator(),name,CMClass.CMObjectType.ITEM,num);\n\t\t\t}\n\t\t}\n\t\treturn x;\n\t}\n\n\t@Override\n\tpublic long getFlags()\n\t{\n\t\treturn suspended()?FLAG_SUSPENDED:0;\n\t}\n\n\t@Override\n\tpublic void setFlags(final long flags)\n\t{\n\t\tif(CMath.bset(flags,FLAG_SUSPENDED))\n\t\t{\n\t\t\tsetSuspended(true);\n\t\t}\n\t}\n\n\tpublic Environmental getQuestThing(final Iterator<? extends Environmental> e, final int dex, final CMClass.CMObjectType type, final int[] num)\n\t{\n\t\tif(e==null)\n\t\t\treturn null;\n\t\tEnvironmental E;\n\t\tfor(;e.hasNext();)\n\t\t{\n\t\t\tE=e.next();\n\t\t\tif(CMClass.isType(E,type))\n\t\t\t{\n\t\t\t\tif(dex==num[0])\n\t\t\t\t\treturn E;\n\t\t\t\tnum[0]++;\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic MOB getQuestMob(final int i)\n\t{\n\t\tfinal int[] num={1};\n\t\tEnvironmental E=null;\n\t\tsynchronized(questState)\n\t\t{\n\t\t\tif(questState.worldObjects!=null)\n\t\t\t\tE=getQuestThing(PreservedQuestObject.getPOIter(questState.worldObjects),i,CMClass.CMObjectType.MOB,num);\n\t\t\tif(E instanceof MOB)\n\t\t\t\treturn (MOB)E;\n\t\t\tif(questState.mobGroup!=null)\n\t\t\t\tE=getQuestThing(questState.mobGroup.iterator(),i,CMClass.CMObjectType.MOB,num);\n\t\t\tif(E instanceof MOB)\n\t\t\t\treturn (MOB)E;\n\t\t\tif((questState.mysteryData!=null)&&(questState.mysteryData.agentGroup!=null))\n\t\t\t\tE=getQuestThing(questState.mysteryData.agentGroup.iterator(),i,CMClass.CMObjectType.MOB,num);\n\t\t\tif(E instanceof MOB)\n\t\t\t\treturn (MOB)E;\n\t\t}\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic Item getQuestItem(final int i)\n\t{\n\t\tfinal int[] num={1};\n\t\tEnvironmental E=null;\n\t\tsynchronized(questState)\n\t\t{\n\t\t\tif(questState.worldObjects!=null)\n\t\t\t\tE=getQuestThing(PreservedQuestObject.getPOIter(questState.worldObjects),i,CMClass.CMObjectType.ITEM,num);\n\t\t\tif(E instanceof Item)\n\t\t\t\treturn (Item)E;\n\t\t\tif(questState.itemGroup!=null)\n\t\t\t\tE=getQuestThing(questState.itemGroup.iterator(),i,CMClass.CMObjectType.ITEM,num);\n\t\t\tif(E instanceof Item)\n\t\t\t\treturn (Item)E;\n\t\t\tif((questState.mysteryData!=null)&&(questState.mysteryData.toolGroup!=null))\n\t\t\t\tE=getQuestThing(questState.mysteryData.toolGroup.iterator(),i,CMClass.CMObjectType.ITEM,num);\n\t\t\tif(E instanceof Item)\n\t\t\t\treturn (Item)E;\n\t\t}\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic Room getQuestRoom(final int i)\n\t{\n\t\tfinal int[] num={1};\n\t\tEnvironmental E=null;\n\t\tsynchronized(questState)\n\t\t{\n\t\t\tif(questState.worldObjects!=null)\n\t\t\t\tE=getQuestThing(PreservedQuestObject.getPOIter(questState.worldObjects),i,CMClass.CMObjectType.LOCALE,num);\n\t\t\tif(E instanceof Room)\n\t\t\t\treturn (Room)E;\n\t\t\tif(questState.roomGroup != null)\n\t\t\t\tE=getQuestThing(questState.roomGroup.iterator(),i,CMClass.CMObjectType.LOCALE,num);\n\t\t\tif(E instanceof Room)\n\t\t\t\treturn (Room)E;\n\t\t\tif((questState.mysteryData!=null)&&(questState.mysteryData.whereAtGroup!=null))\n\t\t\t\tE=getQuestThing(questState.mysteryData.whereAtGroup.iterator(),i,CMClass.CMObjectType.LOCALE,num);\n\t\t\tif(E instanceof Room)\n\t\t\t\treturn (Room)E;\n\t\t\tif((questState.mysteryData!=null)&&(questState.mysteryData.whereHappenedGroup!=null))\n\t\t\t\tE=getQuestThing(questState.mysteryData.whereHappenedGroup.iterator(),i,CMClass.CMObjectType.LOCALE,num);\n\t\t\tif(E instanceof Room)\n\t\t\t\treturn (Room)E;\n\t\t}\n\t\treturn null;\n\t}\n\n\t@Override\n\tpublic String getQuestMobName(final int i)\n\t{\n\t\tfinal MOB M=getQuestMob(i);\n\t\tif(M!=null)\n\t\t\treturn M.name();\n\t\treturn "";\n\t}\n\n\t@Override\n\tpublic String getQuestItemName(final int i)\n\t{\n\t\tfinal Item I=getQuestItem(i);\n\t\tif(I!=null)\n\t\t\treturn I.name();\n\t\treturn "";\n\t}\n\n\t@Override\n\tpublic String getQuestRoomID(final int i)\n\t{\n\t\tfinal Room R=getQuestRoom(i);\n\t\tif(R!=null)\n\t\t\treturn CMLib.map().getExtendedRoomID(R);\n\t\treturn "";\n\t}\n\n\t@Override\n\tpublic int getObjectInUseIndex(final String name)\n\t{\n\t\tsynchronized(questState)\n\t\t{\n\t\t\tif(questState.worldObjects!=null)\n\t\t\t{\n\t\t\t\tfor(int i=0;i<questState.worldObjects.size();i++)\n\t\t\t\t{\n\t\t\t\t\tfinal PhysicalAgent O=questState.worldObjects.get(i).obj;\n\t\t\t\t\tif(O.name().equalsIgnoreCase(name))\n\t\t\t\t\t\treturn (i+1);\n\t\t\t\t}\n\t\tfinal int x=text.toLowerCase().indexOf(XMLLibrary.FILE_XML_BOUNDARY.toLowerCase());\r\n\t\tif(x>=0)\r\n\t\t{\r\n\t\t\tfinal String xml;\r\n\t\t\tif(skipXMLSemicolonFix)\r\n\t\t\t\txml=text.substring(x+XMLLibrary.FILE_XML_BOUNDARY.length()).trim();\r\n\t\t\telse\r\n\t\t\t\txml=CMStrings.replaceAll(text.substring(x+XMLLibrary.FILE_XML_BOUNDARY.length()),"\\\\;",";").trim();\r\n\t\t\ttext=text.substring(0,x);\r\n\t\t\tif((xml.length()>0)&&(internalFiles==null))\r\n\t\t\t{\r\n\t\tboolean skipXMLSemicolonFix=false;\n\t\tif(text.trim().toUpperCase().startsWith("LOAD="))\n\t\t{\n\t\t\tString filename=null;\n\t\t\tfinal List<String> V=CMParms.parse(text.trim().substring(5).trim());\n\t\t\tif(V.size()>0)\n\t\t\t{\n\t\t\t\tfilename=V.get(0);\n\t\t\t\tif(debug)\n\t\t\t\t\tLog.debugOut(prefix+"Loading "+filename);\n\t\t\t\tList<String> parms=null;\n\t\t\t\ttry\n\t\t\t\t{\n\t\t\t\t\tfor(int v=1;v<V.size();v++)\n\t\t\t\t\t{\n\t\t\t\t\t\tparms=CMParms.parse(V.get(v));\n\t\t\t\t\t\tfinal Object O=getObjectIfSpecified(parms,oldArgs,0,1);\n\t\t\t\t\t\targs.add((O==null)?"":O);\n\t\t\t\t\t}\n\t\t\t\t\tfinal StringBuffer buf=getResourceFileData(filename,showErrors);\n\t\t\t\t\tif(buf!=null)\n\t\t\t\t\t{\n\t\t\t\t\t\ttext=buf.toString();\n\t\t\t\t\t\tskipXMLSemicolonFix=true;\n\t\t\t\t\t}\n\t\t\t\t\tif(debug)\n\t\t\t\t\t\tLog.debugOut(prefix+"Loaded "+text.length()+" lines");\n\t\t\t\t}\n\t\t\t\tcatch(final CMException ex)\n\t\t\t\t{\n\t\t\t\t\tLog.errOut("DefaultQuest",prefix+"\'"+text+"\' either has a space in the filename, or unknown parms.");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif(debug)\n\t\t\tLog.debugOut(prefix+"Handed "+text.length()+" lines");\n\t\tfinal int x=text.toLowerCase().indexOf(XMLLibrary.FILE_XML_BOUNDARY.toLowerCase());\n\t\tif(x>=0)\n\t\t{\n\t\t\tString xml=text.substring(x+XMLLibrary.FILE_XML_BOUNDARY.length()).trim();\n\t\t\t// mildly risky change to avoid removing ALL ; escapes from JS.\n\t\t\tif((!skipXMLSemicolonFix)\n\t\t\t&&(xml.indexOf("\\\\;")>=0))\n\t\t\t{\n\t\t\t\tfinal StringBuilder newXML = new StringBuilder("");\n\t\t\t\tfor(int i=0;i<xml.length();i++)\n\t\t\t\t{\n\t\t\t\t\tfinal char c=xml.charAt(i);\n\t\t\t\t\tif((c==\'\\\\\')\n\t\t\t\t\t&&(i<xml.length()-1)\n\t\t\t\t\t&&(xml.charAt(i+1)==\';\'))\n\t\t\t\t\t{ /* just skip the slash */}\n\t\t\t\t\telse\n\t\t\t\t\t\tnewXML.append(c);\n\t\t\t\t}\n\t\t\t\txml=newXML.toString();\n\t\t\t}\n\t\t\ttext=text.substring(0,x);\n\t\t\tif((xml.length()>0)&&(internalFiles==null))\n\t\t\t{\n\t\t\t\tfinal List<XMLLibrary.XMLTag> topXMLV=CMLib.xml().parseAllXML(xml);\n\t\t\t\tfor(int t=0;t<topXMLV.size();t++)\n\t\t\t\t{\n\t\t\t\t\tfinal XMLTag filePiece=topXMLV.get(t);\n\t\t\t\t\tString name=null;\n\t\t\t\t\tString data=null;\n\t\t\t\t\tif(filePiece.tag().equalsIgnoreCase("FILE")&&(filePiece.contents()!=null))\n\t\t\t\t\t{\n\t\t\t\t\t\tfor(int p=0;p<filePiece.contents().size();p++)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tfinal XMLTag piece=filePiece.contents().get(p);\n\t\t\t\t\t\t\tif(piece.tag().equalsIgnoreCase("NAME"))\n\t\t\t\t\t\t\t\tname=piece.value();\n\t\t\t\t\t\t\tif(piece.tag().equalsIgnoreCase("DATA"))\n\t\t\t\t\t\t\t\tdata=piece.value();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif((name!=null)&&(data!=null)&&(name.trim().length()>0)&&(data.trim().length()>0))\n\t\t\t\t\t{\n\t\t\t\t\t\tif(debug)\n\t\t\t\t\t\t\tLog.debugOut(prefix+"Found file "+name+" of "+data.length()+" lines");\n\t\t\t\t\t\tif(internalFiles==null)\n\t\t\t\t\t\t\tinternalFiles=new DVector(2);\n\t\t\t\t\t\tinternalFiles.addElement(name.toUpperCase().trim(),new StringBuffer(data));\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tList<Object> V=script;\n\t\twhile(text.length()>0)\n\t\t{\n\t\t\tint y=-1;\n\t\t\tint yy=0;\n\t\t\twhile(yy<text.length())\n\t\t\t{\n\t\t\t\tif ((text.charAt(yy) == \';\') && ((yy <= 0) || (text.charAt(yy - 1) != \'\\\\\')))\n\t\t\t\t{\n\t\t\t\t\ty = yy;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\tif (text.charAt(yy) == \'\\n\')\n\t\t\t\t{\n\t\t\t\t\ty = yy;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\tif (text.charAt(yy) == \'\\r\')\n\t\t\t\t{\n\t\t\t\t\ty = yy;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t\tyy++;\n\t\t\t}\n\t\t\tString cmd="";\n\t\t\tif(y<0)\n\t\t\t{\n\t\t\t\tcmd=text.trim();\n\t\t\t\ttext="";\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tcmd=text.substring(0,y).trim();\n\t\t\t\ttext=text.substring(y+1).trim();\n\t\t\t}\n\t\t\tif((cmd.length()>0)&&(!cmd.startsWith("#")))\n\t\t\t{\n\t\t\t\tif(cmd.toUpperCase().startsWith("<OPTION>"))\n\t\t\t\t{\n\t\t\t\t\tV=new ArrayList<Object>();\n\t\t\t\t\tscript.add(V);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\tif(cmd.toUpperCase().startsWith("</OPTION>"))\n\t\t\t\t\tV=script;\n\t\t\t\telse\n\t\t\t\t\tV.add(CMStrings.replaceAll(cmd,"\\\\;",";").trim());\n\t\t\t}\n\t\t}\n\t\treturn script;\n\t}\n\n\tprivate static final String VALID_ASTR_CODES="_&|";\n\n\tprivate String modifyStringFromArgs(String s, final List<?> args)\n\t{\n\t\tint x=s.toUpperCase().indexOf(\'$\');\n\t\twhile((x>=0)&&(x<s.length()-1))\n\t\t{\n\t\t\tint y=x+1;\n\t\t\tif((y<s.length())&&(VALID_ASTR_CODES.indexOf(s.charAt(y))>=0))\n\t\t\t\ty++;\n\t\t\twhile((y<s.length())&&(Character.isLetterOrDigit(s.charAt(y))))\n\t\t\t\ty++;\n\t\t\ttry\n\t\t\t{\n\t\t\t\tString possObjName=(x+1>=y)?null:s.substring(x+1,y);\n\t\t\t\tif((possObjName!=null)&&(possObjName.length()>0))\n\t\t\t\t{\n\t\t\t\t\tfinal char firstCode=possObjName.charAt(0);\n\t\t\t\t\tif(VALID_ASTR_CODES.indexOf(firstCode)>=0)\n\t\t\t\t\t\tpossObjName=possObjName.substring(1);\n\t\t\t\t\tfinal Object O=getObjectIfSpecified(CMParms.cleanParameterList(possObjName),args,0,0);\n\t\t\t\t\tString replace=(O==null)?"null":O.toString();\n\t\t\t\t\tif(O instanceof Room)\n\t\t\t\t\t\treplace=((Room)O).displayText(null);\n\t\t\t\t\telse\n\t\t\t\t\tif(O instanceof Environmental)\n\t\t\t\t\t\treplace=((Environmental)O).Name();\n\t\t\t\t\telse\n\t\t\t\t\tif(O instanceof TimeClock)\n\t\t\t\t\t\treplace=((TimeClock)O).getShortTimeDescription();\n\t\t\t\t\tswitch(firstCode)\n\t\t\t\t\t{\n\t\t\t\t\tcase \'_\':\n\t\t\t\t\t\treplace=CMStrings.capitalizeAndLower(replace);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \'&\':\n\t\t\t\t\t\treplace=CMLib.english().removeArticleLead(replace);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \'|\':\n\t\t\t\t\t\treplace=CMLib.english().removeArticleLead(replace).trim().replace(\' \',\'|\');\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\ts=s.substring(0,x)+replace+s.substring(y);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (final CMException ex)\n\t\t\t{\n\t\t\t}\n\t\t\tx=s.toUpperCase().indexOf(\'$\',x+1);\n\t\t}\n\t\treturn s;\n\t}\n\n\tprivate Object getObjectIfSpecified(final List<String> parms, final List<?> args, final int startp, final int object0vector1)\n\t\tthrows CMException\n\t{\n\t\tif(parms.size()-startp==0)\n\t\t\tthrow new CMException("Not specified");\n\t\tfinal StringBuffer allParms=new StringBuffer(parms.get(startp));\n\t\tfor(int p=startp+1;p<parms.size();p++)\n\t\t\tallParms.append(parms.get(p));\n\t\tObject O=null;\n\t\tfinal List<Object> V=Collections.synchronizedList(new ArrayList<Object>());\n\t\tint lastI=0;\n\t\tString eval=null;\n\t\tchar code=\' \';\n\t\tfor(int i=0;i<=allParms.length();i++)\n\t\t{\n\t\t\teval=null;\n\t\t\tif((i==allParms.length())\n\t\t\t||((i<allParms.length())&&((allParms.charAt(i)==\'+\')||(allParms.charAt(i)==\'-\')||(allParms.charAt(i)==\'#\'))))\n\t\t\t{\n\t\t\t\teval=allParms.substring(lastI,i).trim().toUpperCase();\n\t\t\t\tlastI=i+1;\n\t\t\t}\n\t\t\tif(eval!=null)\n\t\t\t{\n\t\t\t\tif(eval.startsWith("ARG")&&CMath.isMathExpression(eval.substring(3)))\n\t\t\t\t{\n\t\t\t\t\tfinal int num=CMath.parseIntExpression(eval.substring(3));\n\t\t\t\t\tif((num<=0)||(num>args.size()))\n\t\t\t\t\t\tthrow new CMException ("Not specified: "+eval);\n\t\t\t\t\tO=args.get(num-1);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tif(!questState.isStat(eval))\n\t\t\t\t\t\tthrow new CMException ("Not specified: "+eval);\n\t\t\t\t\tO=questState.getStat(eval);\n\t\t\t\t}\n\t\t\t\tswitch(code)\n\t\t\t\t{\n\t\t\t\tcase \'#\':\n\t\t\t\t{\n\t\t\t\t\tint index=0;\n\t\t\t\t\tif(CMath.isMathExpression(eval))\n\t\t\t\t\t\tindex=CMath.parseIntExpression(eval);\n\t\t\t\t\tif((index>=0)&&(index<V.size()))\n\t\t\t\t\t{\n\t\t\t\t\t\tO=V.get(index);\n\t\t\t\t\t\tV.clear();\n\t\t\t\t\t\tV.add(O);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tcase \'-\':\n\t\t\t\t\tif(O instanceof List)\n\t\t\t\t\t\tV.removeAll((List<?>)O);\n\t\t\t\t\telse\n\t\t\t\t\tif(O!=null)\n\t\t\t\t\t\tV.remove(O);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \'+\':\n\t\t\t\tcase \' \':\n\t\t\t\t\tif(O instanceof List)\n\t\t\t\t\t\tV.addAll((List<?>)O);\n\t\t\t\t\telse\n\t\t\t\t\tif(O!=null)\n\t\t\t\t\t\tV.add(O);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif(i<allParms.length())\n\t\t\t\t\tcode=allParms.charAt(i);\n\t\t\t}\n\t\t}\n\t\tswitch(object0vector1)\n\t\t{\n\t\tcase 0:\n\t\t\tif(V.size()==0)\n\t\t\t\treturn null;\n\t\t\treturn V.get(CMLib.dice().roll(1,V.size(),-1));\n\t\tcase 1:\n\t\t\tif(V.size()==0)\n\t\t\t\treturn null;\n\t\t\treturn V;\n\t\t}\n\t\treturn null;\n\t}\n\n\tprotected static String[] CCODES = null;\n\n\t@Override\n\tpublic String[] getStatCodes()\n\t{\n\t\tif(CCODES == null)\n\t\t{\n\t\t\tfinal String[] CCODES=new String[QCODES.values().length+MYSTERY_QCODES.values().length];\n\t\t\tfor(int i=0;i<QCODES.values().length;i++)\n\t\t\t\tCCODES[i]=QCODES.values()[i].name();\n\t\t\tfor(int i=0;i<MYSTERY_QCODES.values().length;i++)\n\t\t\t\tCCODES[QCODES.values().length+i]=MYSTERY_QCODES.values()[i].name();\n\t\t\tDefaultQuest.CCODES = CCODES;\n\t\t}\n\t\treturn CCODES;\n\t}\n\n\t@Override\n\tpublic int getSaveStatIndex()\n\t{\n\t\treturn getStatCodes().length;\n\t}\n\n\tprotected int getCodeNum(final String code)\n\t{\n\t\tfinal String[] CCODES=getStatCodes();\n\t\tfor(int i=0;i<CCODES.length;i++)\n\t\t{\n\t\t\tif(code.equalsIgnoreCase(CCODES[i]))\n\t\t\t\treturn i;\n\t\t}\n\t\treturn -1;\n\t}\n\n\tpublic boolean sameAs(final DefaultQuest E)\n\t{\n\t\tfinal String[] CCODES=getStatCodes();\n\t\tfor(int i=0;i<CCODES.length;i++)\n\t\t{\n\t\t\tif(!E.getStat(CCODES[i]).equals(getStat(CCODES[i])))\n\t\t\t\treturn false;\n\t\t}\n\t\treturn true;\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\tbreak;\n\t\tcase 1:\n\t\t\tsetName(val);\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\tsetDuration(CMLib.time().parseTickExpression(val));\n\t\t\tbreak;\n\t\tcase 3:\n\t\t\tsetMinWait(CMLib.time().parseTickExpression(val));\n\t\t\tbreak;\n\t\tcase 4:\n\t\t\tsetMinPlayers(CMath.s_parseIntExpression(val));\n\t\t\tbreak;\n\t\tcase 5:\n\t\t\tsetPlayerMask(val);\n\t\t\tbreak;\n\t\tcase 6:\n\t\t\tsetRunLevel(CMath.s_parseIntExpression(val));\n\t\t\tbreak;\n\t\tcase 7:\n\t\t\tsetStartDate(val);\n\t\t\tbreak;\n\t\tcase 8:\n\t\t\tsetStartMudDate(val);\n\t\t\tbreak;\n\t\tcase 9:\n\t\t\tsetWaitInterval(CMLib.time().parseTickExpression(val));\n\t\t\tbreak;\n\t\tcase 10:\n\t\t\tsetSpawn(CMParms.indexOf(SPAWN_DESCS, val.toUpperCase().trim()));\n\t\t\tbreak;\n\t\tcase 11:\n\t\t\tsetDisplayName(val);\n\t\t\tbreak;\n\t\tcase 12: // instructions can and should fall through the default\n\t\t\tthis.instructions = val;\n\t\t\tbreak;\n\t\tcase 13:\n\t\t\tdurable = CMath.s_bool(val);\n\t\t\tbreak;\n\t\tcase 14:\n\t\t\tauthor = val;\n\t\t\tbreak;\n\t\tcase 15:\n\t\t\t{\n\t\t\t\tfinal int ticks=CMLib.time().parseTickExpression(val);\n\t\t\t\tif(ticks == 0)\n\t\t\t\t\tthis.setCopy(false);\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthis.setDuration(ticks);\n\t\t\t\t\tthis.setCopy(true);\n\t\t\t\t}\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 16: // questType\n\t\t\tthis.questType = val;\n\t\t\tbreak;\n\t\tcase 17: // category\n\t\t\tthis.category = val;\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tif((code.toUpperCase().trim().equalsIgnoreCase("REMAINING"))&&(running()))\n\t\t\t\tticksRemaining=CMLib.time().parseTickExpression(val);\n\t\t\telse\n\t\t\t\tquestState.vars.put(code.toUpperCase().trim(), val);\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t@Override\n\tpublic boolean isStat(final String code)\n\t{\n\t\tif((getCodeNum(code)>=0)\n\t\t||(questState.vars.containsKey(code)))\n\t\t\treturn true;\n\t\treturn false;\n\t}\n\n\t@Override\n\tpublic String getStat(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 "" + name();\n\t\tcase 2:\n\t\t\treturn "" + duration();\n\t\tcase 3:\n\t\t\treturn "" + minWait();\n\t\tcase 4:\n\t\t\treturn "" + minPlayers();\n\t\tcase 5:\n\t\t\treturn "" + playerMask();\n\t\tcase 6:\n\t\t\treturn "" + runLevel();\n\t\tcase 7:\n\t\t\treturn "" + startDate();\n\t\tcase 8:\n\t\t\treturn "" + startDate();\n\t\tcase 9:\n\t\t\treturn "" + waitInterval();\n\t\tcase 10:\n\t\t\treturn SPAWN_DESCS[getSpawn()];\n\t\tcase 11:\n\t\t\treturn displayName();\n\t\tcase 12:\n\t\t\treturn instructions();\n\t\tcase 13:\n\t\t\treturn Boolean.toString(durable);\n\t\tcase 14:\n\t\t\treturn author();\n\t\tcase 15: //  EXPIRATION\n\t\t\treturn "";\n\t\tcase 16:\n\t\t\treturn this.questType;\n\t\tcase 17:\n\t\t\treturn this.category;\n\t\tdefault:\n\t\t{\n\t\t\tcode=code.toUpperCase().trim();\n\t\t\tif((code.equalsIgnoreCase("REMAINING"))&&(running()))\n\t\t\t\treturn ""+ticksRemaining;\n\t\t\tif(questState.vars.containsKey(code) && (!questState.isStat(code)))\n\t\t\t\treturn questState.vars.get(code);\n\t\t\tif(questState.isStat(code))\n\t\t\t{\n\t\t\t\tfinal Object O=questState.getStat(code);\n\t\t\t\tif(O instanceof Room)\n\t\t\t\t\treturn ((Room)O).displayText(null);\n\t\t\t\tif(O instanceof TimeClock)\n\t\t\t\t\treturn ((TimeClock)O).getShortTimeDescription();\n\t\t\t\tif(O instanceof Environmental)\n\t\t\t\t\treturn ((Environmental)O).Name();\n\t\t\t\tif(O instanceof List)\n\t\t\t\t\treturn ""+((List<?>)O).size();\n\t\t\t\tif(O!=null)\n\t\t\t\t\treturn O.toString();\n\t\t\t}\n\t\t\telse\n\t\t\tif(code.endsWith("_ROOMID")&&(questState.isStat(code.substring(0,code.length()-7))))\n\t\t\t{\n\t\t\t\tcode=code.substring(0,code.length()-7);\n\t\t\t\tObject O=questState.getStat(code);\n\t\t\t\tif(O instanceof List)\n\t\t\t\t{\n\t\t\t\t\tif(((List<?>)O).size()>0)\n\t\t\t\t\t\tO=((List<?>)O).get(CMLib.dice().roll(1,((List<?>)O).size(),-1));\n\t\t\t\t}\n\t\t\t\tif(O instanceof Environmental)\n\t\t\t\t{\n\t\t\t\t\tfinal Room R=CMLib.map().roomLocation((Environmental)O);\n\t\t\t\t\tif(R!=null)\n\t\t\t\t\t\treturn CMLib.map().getExtendedRoomID(R);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\tif(code.endsWith("_CLASS")&&(questState.isStat(code.substring(0,code.length()-6))))\n\t\t\t{\n\t\t\t\tcode=code.substring(0,code.length()-6);\n\t\t\t\tObject O=questState.getStat(code);\n\t\t\t\tif(O instanceof List)\n\t\t\t\t{\n\t\t\t\t\tif(((List<?>)O).size()>0)\n\t\t\t\t\t\tO=((List<?>)O).get(CMLib.dice().roll(1,((List<?>)O).size(),-1));\n\t\t\t\t}\n\t\t\t\tif(O instanceof CMObject)\n\t\t\t\t\treturn ((CMObject)O).ID();\n\t\t\t\telse\n\t\t\t\tif(O!=null)\n\t\t\t\t\treturn O.getClass().getName();\n\t\t\t}\n\t\t\treturn "";\n\t\t}\n\t\t}\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/**\n\t * Objects selected for use by a quest can be preserved or released from\n\t * quest-state to quest-state.  This object maps a world object in use\n\t * to its quest-states remaining.\n\t * @author Bo Zimmerman\n\t */\n\tpublic static class PreservedQuestObject\n\t{\n\t\tpublic int preserveState;\n\t\tpublic PhysicalAgent obj;\n\t\tprivate static Converter<PreservedQuestObject, PhysicalAgent> converter = new Converter<PreservedQuestObject, PhysicalAgent>()\n\t\t{\n\t\t\t@Override\n\t\t\tpublic PhysicalAgent convert(final PreservedQuestObject obj)\n\t\t\t{\n\t\t\t\treturn obj.obj;\n\t\t\t}\n\t\t};\n\n\t\tpublic PreservedQuestObject(final PhysicalAgent o, final int state)\n\t\t{\n\t\t\tthis.obj = o;\n\t\t\tthis.preserveState = state;\n\t\t}\n\n\t\tpublic static Iterator<PhysicalAgent> getPOIter(final List<PreservedQuestObject> o)\n\t\t{\n\t\t\tfinal ConvertingIterator<PreservedQuestObject,PhysicalAgent> iter =\n\t\t\t\t new ConvertingIterator<PreservedQuestObject,PhysicalAgent>(o.iterator(),converter);\n\t\t\treturn iter;\n\t\t}\n\t}\n\n\t/**\n\t * A quest state class maps the parse-state of a quest, since quest parsing\n\t * is highly state dependent, but the state is not explicit in the script itself.\n\t * @author Bo Zimmerman\n\t *\n\t */\n\tpublic static class QuestState implements Cloneable\n\t{\n\t\tpublic MysteryData\tmysteryData\t\t\t\t= new MysteryData();\n\t\tpublic List<MOB>\tloadedMobs\t\t\t\t= new ArrayList<MOB>();\n\t\tpublic List<Item>\tloadedItems\t\t\t\t= new ArrayList<Item>();\n\t\tpublic List<Ability>loadedAbilities\t\t\t= new ArrayList<Ability>();\n\t\tpublic Area\t\t\tarea\t\t\t\t\t= null;\n\t\tpublic Room\t\t\troom\t\t\t\t\t= null;\n\t\tpublic MOB\t\t\tmob\t\t\t\t\t\t= null;\n\t\tpublic Ability\t\tability\t\t\t\t\t= null;\n\t\tpublic List<MOB>\tmobGroup\t\t\t\t= null;\n\t\tpublic List<Item>\titemGroup\t\t\t\t= null;\n\t\tpublic List<Room>\troomGroup\t\t\t\t= null;\n\t\tpublic List<Ability>abilityGroup\t\t\t= null;\n\t\tpublic Item\t\t\titem\t\t\t\t\t= null;\n\t\tpublic Object\t\tenvObject\t\t\t\t= null;\n\t\tpublic boolean\t\terror\t\t\t\t\t= false;\n\t\tpublic boolean\t\tdone\t\t\t\t\t= false;\n\t\tpublic boolean\t\tbeQuiet\t\t\t\t\t= false;\n\t\tpublic boolean\t\tisOptional\t\t\t\t= false;\n\t\tpublic boolean\t\tautoStepAfterDuration\t= false;\n\t\tpublic int\t\t\tpreserveState\t\t\t= 0;\n\t\tpublic int\t\t\tlastLine\t\t\t\t= 0;\n\t\tpublic int\t\t\tstepNumber\t\t\t\t= 1;\n\t\tpublic int\t\t\tstartLine;\n\t\t// contains a set of vectors, vectors are formatted as such:\n\t\t// key 1=vector, below.  key 2=preserveState\n\t\t// 0=environmental item/mob/etc\n\t\t//  1=Ability, 2=Ability (for an ability added)\n\t\t//  1=Ability, 2=Ability, 3=String (for an ability modified)\n\t\t//  1=Effect(for an Effect added)\n\t\t//  1=Effect, 2=String (for an Effect modified)\n\t\t//  1=Behavior (for an Behavior added)\n\t\t//  1=Behavior, 2=String (for an Behavior modified)\n\t\tpublic PairList<List<Object>,Integer>\taddons\t\t\t= new PairVector<List<Object>,Integer>();\n\t\tpublic Map<String, String>\t\t\t\tvars\t\t\t= new STreeMap<String, String>();\n\t\tpublic List<PhysicalAgent>\t\t\t\treselectable\t= Collections.synchronizedList(new ArrayList<PhysicalAgent>());\n\t\tpublic List<PreservedQuestObject>\t\tworldObjects\t= new SVector<PreservedQuestObject>();\n\n\t\tpublic boolean isStat(String statName)\n\t\t{\n\t\t\tfinal int x=statName.indexOf(\'#\');\n\t\t\tif(x>=0)\n\t\t\t\tstatName=statName.substring(0,x);\n\t\t\tfinal QOBJS q=(QOBJS)CMath.s_valueOf(QOBJS.class, statName.toUpperCase().trim());\n\t\t\tif(q != null)\n\t\t\t\treturn true;\n\t\t\tif(mysteryData!=null)\n\t\t\t\treturn mysteryData.isStat(statName);\n\t\t\treturn false;\n\t\t}\n\n\t\tpublic Object getStat(String statName)\n\t\t{\n\t\t\tfinal int x=statName.indexOf(\'#\');\n\t\t\tfinal String whichStr;\n\t\t\tif(x>=0)\n\t\t\t{\n\t\t\t\twhichStr=statName.substring(x+1);\n\t\t\t\tstatName=statName.substring(0,x);\n\t\t\t}\n\t\t\telse\n\t\t\t\twhichStr=null;\n\t\t\tObject O=null;\n\t\t\tfinal QOBJS q=(QOBJS)CMath.s_valueOf(QOBJS.class, statName.toUpperCase().trim());\n\t\t\tif(q==null)\n\t\t\t{\n\t\t\t\tif(mysteryData!=null)\n\t\t\t\t\tO=mysteryData.getStat(statName);\n\t\t\t}\n\t\t\telse\n\t\t\tswitch(q)\n\t\t\t{\n\t\t\tcase STEPNUM:\n\t\t\t\tO = (""+stepNumber);\n\t\t\t\tbreak;\n\t\t\tcase LOADEDMOBS:\n\t\t\t\tO = loadedMobs;\n\t\t\t\tbreak;\n\t\t\tcase LOADEDITEMS:\n\t\t\t\tO = loadedItems;\n\t\t\t\tbreak;\n\t\t\tcase LOADEDABILITIES:\n\t\t\t\tO = loadedAbilities;\n\t\t\t\tbreak;\n\t\t\tcase AREA:\n\t\t\t\tO = area;\n\t\t\t\tbreak;\n\t\t\tcase ROOM:\n\t\t\t\tO = room;\n\t\t\t\tbreak;\n\t\t\tcase MOBGROUP:\n\t\t\t\tO = mobGroup;\n\t\t\t\tbreak;\n\t\t\tcase ITEMGROUP:\n\t\t\t\tO = itemGroup;\n\t\t\t\tbreak;\n\t\t\tcase ROOMGROUP:\n\t\t\t\tO = roomGroup;\n\t\t\t\tbreak;\n\t\t\tcase ABILITYGROUP:\n\t\t\t\tO = abilityGroup;\n\t\t\t\tbreak;\n\t\t\tcase ITEM:\n\t\t\t\tO = item;\n\t\t\t\tbreak;\n\t\t\tcase ABILITY:\n\t\t\t\tO = ability;\n\t\t\t\tbreak;\n\t\t\tcase ENVOBJ:\n\t\t\t\tO = envObject;\n\t\t\t\tbreak;\n\t\t\tcase STUFF:\n\t\t\t\tO = new ConvertingList<PreservedQuestObject, PhysicalAgent>(worldObjects, PreservedQuestObject.converter);\n\t\t\t\tbreak;\n\t\t\tcase MOB:\n\t\t\t\tO = mob;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tif(mysteryData!=null)\n\t\t\t\t\tO=mysteryData.getStat(statName);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif(whichStr != null)\n\t\t\t{\n\t\t\t\tif(O instanceof List)\n\t\t\t\t{\n\t\t\t\t\tfinal List<?> V=(List<?>)O;\n\t\t\t\t\tif(CMath.isInteger(whichStr)||(whichStr.length()==0))\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal int whichNum=(whichStr.length()==0)?0:CMath.s_parseIntExpression(whichStr);\n\t\t\t\t\t\tif((whichStr!=null)&&((whichNum<=0)||(whichNum>V.size())))\n\t\t\t\t\t\t\treturn ""+V.size();\n\t\t\t\t\t\tif(whichStr!=null)\n\t\t\t\t\t\t\treturn V.get(whichNum-1);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\tif(whichStr.equals("?"))\n\t\t\t\t\t\treturn (V.size()>0)?V.get(CMLib.dice().roll(1, V.size(), -1)):O;\n\t\t\t\t\telse\n\t\t\t\t\tif(whichStr.equals("$"))\n\t\t\t\t\t{\n\t\t\t\t\t\tfinal StringBuilder str=new StringBuilder("");\n\t\t\t\t\t\tfor(final Object o : V)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(o instanceof Room)\n\t\t\t\t\t\t\t\tstr.append("\\"").append(CMLib.map().getExtendedRoomID((Room)o)).append("\\" ");\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\tif(o instanceof CMObject)\n\t\t\t\t\t\t\t\tstr.append("\\"").append(((CMObject)o).name()).append("\\" ");\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tstr.append("\\"").append(o.toString()).append("\\" ");\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn str.toString().trim();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\tif(whichStr.equals("$"))\n\t\t\t\t{\n\t\t\t\t\tfinal StringBuilder str=new StringBuilder("");\n\t\t\t\t\tif(O instanceof Room)\n\t\t\t\t\t\tstr.append("\\"").append(CMLib.map().getExtendedRoomID((Room)O)).append("\\" ");\n\t\t\t\t\telse\n\t\t\t\t\tif(O instanceof CMObject)\n\t\t\t\t\t\tstr.append("\\"").append(((CMObject)O).name()).append("\\" ");\n\t\t\t\t\telse\n\t\t\t\t\tif(O != null)\n\t\t\t\t\t\tstr.append("\\"").append(O.toString()).append("\\" ");\n\t\t\t\t\treturn str.toString().trim();\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn O;\n\t\t}\n\t}\n\n\t/**\n\t * MysteryData is a helper class for QuestState that stores quest\n\t * state variables for the parsing of quests that make use of the\n\t * "mystery" variables (mystery as in Sherlock Holmes, not as in\n\t * unknown).\n\t * @author Bo Zimmerman\n\t */\n\tpublic static class MysteryData implements Cloneable\n\t{\n\t\tpublic List<Faction>\t\tfactionGroup;\n\t\tpublic Faction\t\t\t\tfaction;\n\t\tpublic MOB\t\t\t\t\tagent;\n\t\tpublic List<MOB>\t\t\tagentGroup;\n\t\tpublic Environmental\t\ttarget;\n\t\tpublic List<Environmental>\ttargetGroup;\n\t\tpublic Environmental\t\ttool;\n\t\tpublic List<Environmental>\ttoolGroup;\n\t\tpublic Room\t\t\t\t\twhereHappened;\n\t\tpublic List<Room>\t\t\twhereHappenedGroup;\n\t\tpublic Room\t\t\t\t\twhereAt;\n\t\tpublic List<Room>\t\t\twhereAtGroup;\n\t\tpublic String\t\t\t\taction;\n\t\tpublic List<String>\t\t\tactionGroup;\n\t\tpublic String\t\t\t\tmotive;\n\t\tpublic List<String>\t\t\tmotiveGroup;\n\t\tpublic TimeClock\t\t\twhenHappened;\n\t\tpublic List<TimeClock>\t\twhenHappenedGroup;\n\t\tpublic TimeClock\t\t\twhenAt;\n\t\tpublic List<TimeClock>\t\twhenAtGroup;\n\n\t\tpublic boolean isStat(final String statName)\n\t\t{\n\t\t\treturn CMath.s_valueOf(Quest.MYSTERY_QCODES.class, statName.toUpperCase().trim()) != null;\n\t\t}\n\n\t\tpublic Object getStat(final String statName)\n\t\t{\n\t\t\tfinal MYSTERY_QCODES q=(MYSTERY_QCODES)CMath.s_valueOf(Quest.MYSTERY_QCODES.class, statName.toUpperCase().trim());\n\t\t\tfinal int code=(q==null)?-1:q.ordinal();\n\t\t\tswitch(code)\n\t\t\t{\n\t\t\tcase 0:\n\t\t\t\treturn faction;\n\t\t\tcase 1:\n\t\t\t\treturn factionGroup;\n\t\t\tcase 2:\n\t\t\t\treturn agent;\n\t\t\tcase 3:\n\t\t\t\treturn agentGroup;\n\t\t\tcase 4:\n\t\t\t\treturn action;\n\t\t\tcase 5:\n\t\t\t\treturn actionGroup;\n\t\t\tcase 6:\n\t\t\t\treturn target;\n\t\t\tcase 7:\n\t\t\t\treturn targetGroup;\n\t\t\tcase 8:\n\t\t\t\treturn motive;\n\t\t\tcase 9:\n\t\t\t\treturn motiveGroup;\n\t\t\tcase 10:\n\t\t\t\treturn whereHappened;\n\t\t\tcase 11:\n\t\t\t\treturn whereHappenedGroup;\n\t\t\tcase 12:\n\t\t\t\treturn whereAt;\n\t\t\tcase 13:\n\t\t\t\treturn whereAtGroup;\n\t\t\tcase 14:\n\t\t\t\treturn whenHappened;\n\t\t\tcase 15:\n\t\t\t\treturn whenHappenedGroup;\n\t\t\tcase 16:\n\t\t\t\treturn whenAt;\n\t\t\tcase 17:\n\t\t\t\treturn whenAtGroup;\n\t\t\tcase 18:\n\t\t\t\treturn tool;\n\t\t\tcase 19:\n\t\t\t\treturn toolGroup;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t}\n\n\tprotected static class JScriptQuest extends ScriptableObject\n\t{\n\t\t@Override\n\t\tpublic String getClassName()\n\t\t{\n\t\t\treturn "JScriptQuest";\n\t\t}\n\n\t\tstatic final long\tserialVersionUID\t= 44;\n\t\tQuest\t\t\t\tquest\t\t\t\t= null;\n\t\tQuestState\t\t\tstate\t\t\t\t= null;\n\n\t\tpublic Quest quest()\n\t\t{\n\t\t\treturn quest;\n\t\t}\n\n\t\tpublic QuestState setupState()\n\t\t{\n\t\t\treturn state;\n\t\t}\n\n\t\tpublic JScriptQuest(final Quest Q, final QuestState S)\n\t\t{\n\t\t\tquest = Q;\n\t\t\tstate = S;\n\t\t}\n\n\t\tpublic static String[]\tfunctions\t= { "quest", "setupState", "toJavaString", "getCMType" };\n\n\t\tpublic String toJavaString(final Object O)\n\t\t{\n\t\t\treturn Context.toString(O);\n\t\t}\n\n\t\tpublic String getCMType(final Object O)\n\t\t{\n\t\t\tif(O == null)\n\t\t\t\treturn "null";\n\t\t\tfinal CMObjectType typ = CMClass.getObjectType(O);\n\t\t\tif(typ == null)\n\t\t\t\treturn "unknown";\n\t\t\treturn typ.name().toLowerCase();\n\t\t}\n\t}\n}\n', 'message': 'better semicolon fix.\n\ngit-svn-id: 0cdf8356e41b2d8ccbb41bb76c82068fe80b2514@20476 0d6f1817-ed0e-0410-87c9-987e46238f29\n', 'author_name': 'bozimmerman', 'lang': 'java'}