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.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.Locales.interfaces.*; import com.planet_ink.coffee_mud.MOBS.interfaces.*; import com.planet_ink.coffee_mud.Races.interfaces.*; import java.util.*; import org.mozilla.javascript.Context; import org.mozilla.javascript.ScriptableObject; /* Copyright 2000-2010 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. */ @SuppressWarnings("unchecked") public class DefaultQuest implements Quest, Tickable, CMObject { public String ID(){return "DefaultQuest";} protected String name=""; protected String author=""; protected String displayName=""; protected String startDate=""; protected int duration=450; // about 30 minutes protected String rawScriptParameter=""; protected Vector winners=new Vector(); 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; private boolean suspended=false; private Hashtable stepEllapsedTimes=new Hashtable(); public DVector internalFiles=null; private int[] resetData=null; // the unique name of the quest public String name(){return name;} public void setName(String newName){name=newName;} // the author of the quest public String author(){return author;} public void setAuthor(String newName){author=newName;} // the display name of the quest public String displayName(){ return displayName;} public void setDisplayName(String newName){ displayName=newName;} public CMObject copyOf() { try { Object O=this.clone(); return (CMObject)O; } catch(CloneNotSupportedException e) { return newInstance(); } } public boolean suspended(){ return suspended;} public void setSuspended(boolean truefalse){suspended=truefalse;} public CMObject newInstance(){try{return (CMObject)getClass().newInstance();}catch(Exception e){return new DefaultQuest();}} public void initializeClass(){} public Object getDesignatedObject(String named) { int code=-1; for(int i=0;i<QCODES.length;i++) if(named.equalsIgnoreCase(QCODES[i])) { code=i; break;} switch(code) { case 0: return ID(); case 1: return name(); case 2: return ""+duration(); case 3: return ""+minWait(); case 4: return ""+minPlayers(); case 5: return ""+playerMask(); case 6: return ""+runLevel(); case 7: return ""+startDate(); case 8: return ""+startDate(); case 9: return ""+waitInterval(); case 10: return SPAWN_DESCS[getSpawn()]; case 11: return displayName(); case 13: return Boolean.toString(durable); case 12: break; // instructions should fall through } return questState.getStat(named); } public void internalQuestDelete() { if(isCopy()) return; if((internalFiles!=null)&&(internalFiles.size()>0)) { for(int i=0;i<internalFiles.size();i++) { String filename=((String)internalFiles.elementAt(i,1)).toUpperCase(); Vector delThese=new Vector(); boolean foundKey=false; Vector V=Resources.findResourceKeys(filename); for(Enumeration e=V.elements();e.hasMoreElements();) { String key=(String)e.nextElement(); if(key.startsWith("PARSEDPRG: ")&&(key.toUpperCase().endsWith(filename))) { foundKey=true; delThese.addElement(key);} } if(foundKey) for(int d=0;d<delThese.size();d++) Resources.removeResource((String)delThese.elementAt(d)); } internalFiles.clear(); internalFiles=null; } } // the unique name of the quest public String startDate(){return startDate;} public void setStartDate(String newDate){ int x=newDate.indexOf("-"); if((x>0) &&(CMath.isMathExpression(newDate.substring(0,x))) &&(CMath.isMathExpression(newDate.substring(x+1)))) startDate=newDate; } public void setStartMudDate(String newDate){ setStartDate(newDate); if(startDate.equals(newDate)) startDate="MUDDAY "+startDate; } // the duration, in ticks public int duration(){return duration;} public void setDuration(int newTicks){duration=newTicks;} public void setCopy(boolean truefalse){copy=truefalse;} public boolean isCopy(){return copy;} public void setSpawn(int spawnFlag){spawn=(spawnFlag<0)?0:spawnFlag;} public int getSpawn(){return spawn;} public int minPlayers(){return minPlayers;} public void setMinPlayers(int players){minPlayers=players;} public int runLevel(){return runLevel;} public void setRunLevel(int level){runLevel=level;} public String playerMask(){return playerMask;} public void setPlayerMask(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. public void setScript(String parm){ rawScriptParameter=parm; name=""; author=""; displayName=""; startDate=""; duration=-1; minWait=-1; maxWait=-1; minPlayers=-1; spawn=SPAWN_NO; playerMask=""; runLevel=-1; internalFiles=null; durable=false; setVars(parseLoadScripts(parm,new Vector(),new Vector()),0); if(isCopy()) spawn=SPAWN_NO; } public String script(){return rawScriptParameter;} public void autostartup() { if(!resetWaitRemaining(0)) CMLib.threads().deleteTick(this,Tickable.TICKID_QUEST); else if(!running()) CMLib.threads().startTickDown(this,Tickable.TICKID_QUEST,1); } public void setVars(Vector script, int startAtLine) { Vector parsedLine=null; String var=null; String val=null; Vector setScripts=CMLib.quests().parseQuestCommandLines(script,"SET",startAtLine); for(int v=0;v<setScripts.size();v++) { parsedLine=(Vector)setScripts.elementAt(v); if(parsedLine.size()>1) { var=((String)parsedLine.elementAt(1)).toUpperCase(); val=CMParms.combine(parsedLine,2); if(isStat(var)) setStat(var,val); } } } public StringBuffer getResourceFileData(String named) { int index=-1; if(internalFiles!=null){ index=internalFiles.indexOf(named.toUpperCase().trim()); if(index>=0) return (StringBuffer)internalFiles.elementAt(index,2); } StringBuffer buf=new CMFile(Resources.makeFileResourceName(named),null,true).text(); return buf; } private void questifyScriptableBehavs(Environmental E) { if(E==null) return; Behavior B=null; for(int b=0;b<E.numBehaviors();b++) { B=E.fetchBehavior(b); if(B instanceof ScriptingEngine) ((ScriptingEngine)B).registerDefaultQuest(this.name()); } } private Vector sortSelect(Environmental E, String str, Vector choices, Vector choices0, Vector choices1, Vector choices2, Vector choices3) { String mname=E.name().toUpperCase(); String mdisp=E.displayText().toUpperCase(); String mdesc=E.description().toUpperCase(); if(str.equalsIgnoreCase("any")) { choices=choices0; choices0.addElement(E); } else if(mname.equalsIgnoreCase(str)) { choices=choices0; choices0.addElement(E); } else if(CMLib.english().containsString(mname,str)) { if((choices==null)||(choices==choices2)||(choices==choices3)) choices=choices1; choices1.addElement(E); } else if(CMLib.english().containsString(mdisp,str)) { if((choices==null)||(choices==choices3)) choices=choices2; choices2.addElement(E); } else if(CMLib.english().containsString(mdesc,str)) { if(choices==null) choices=choices3; choices3.addElement(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; } public void parseQuestScriptWArgs(Vector script, Vector args) { if(args==null) args=new Vector(); if(args.size()==0) parseQuestScript(script, args, -1); else { Vector allArgs=new Vector(); for(int i=0;i<args.size();i++) { Object O=args.elementAt(i); if(O instanceof Vector) { Vector V=(Vector)O; if(allArgs.size()==0) for(int v=0;v<V.size();v++) allArgs.addElement(CMParms.makeVector(V.elementAt(v))); else { Vector allArgsCopy=(Vector)allArgs.clone(); allArgs.clear(); for(int aa=0;aa<allArgsCopy.size();aa++) { Vector argSet=(Vector)allArgsCopy.elementAt(aa); for(int v=0;v<V.size();v++) { Vector V2=(Vector)argSet.clone(); V2.addElement(V.elementAt(v)); allArgs.addElement(V2); } } } } else if(allArgs.size()==0) allArgs.addElement(CMParms.makeVector(O)); else for(int aa=0;aa<allArgs.size();aa++) ((Vector)allArgs.elementAt(aa)).addElement(O); } for(int a=0;a<allArgs.size();a++) parseQuestScript(script, (Vector)allArgs.elementAt(a),-1); } } protected void errorOccurred(QuestState q, boolean quietFlag, String msg) { if(!quietFlag) Log.errOut("Quest",msg); q.error=true; } private Enumeration getAppropriateRoomSet(QuestState q) { if(q.roomGroup!=null) return q.roomGroup.elements(); else if(q.area!=null) return q.area.getMetroMap(); return CMLib.map().rooms(); } private void sizeDownTo(Vector V, int num) { if(num<0) return; if(num==0) V.clear(); else while(V.size()>num) V.removeElementAt(CMLib.dice().roll(1,V.size(),-1)); } public void parseQuestScript(Vector script, Vector args, int startLine) { Vector finalScript=new Vector(); for(int v=0;v<script.size();v++) { if(script.elementAt(v) instanceof String) finalScript.addElement(script.elementAt(v)); else if(script.elementAt(v) instanceof Vector) { int vs=v; while((v<script.size())&&(script.elementAt(v) instanceof Vector)) v++; int rnum=vs+CMLib.dice().roll(1,v-vs,-1); if(rnum<script.size()) { Vector V=(Vector)script.elementAt(rnum); for(int v2=0;v2<V.size();v2++) if(V.elementAt(v2) instanceof String) finalScript.addElement(V.elementAt(v2)); } } } script=finalScript; QuestState 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; String s=modifyStringFromArgs((String)script.elementAt(v),args); Vector p=CMParms.parse(s); boolean isQuiet=q.beQuiet; if(p.size()>0) { String cmd=((String)p.elementAt(0)).toUpperCase(); if(cmd.equals("<SCRIPT>")) { StringBuffer jscript=new StringBuffer(""); while(((++v)<script.size()) &&(!((String)script.elementAt(v)).trim().toUpperCase().startsWith("</SCRIPT>"))) jscript.append(((String)script.elementAt(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; } Context cx = Context.enter(); try { 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(Exception e) { errorOccurred(q,false,"Quest '"+name()+"', JScript q.error: "+e.getMessage()+"."); Context.exit(); break; } Context.exit(); continue; } if(cmd.equals("QUIET")) { if(p.size()<2) { q.beQuiet=true; continue; } isQuiet=true; p.removeElementAt(0); cmd=((String)p.elementAt(0)).toUpperCase(); } if(cmd.equals("STEP")) { if((p.size()>1)&&(((String)p.elementAt(1)).equalsIgnoreCase("BREAK"))) { q.lastLine=script.size(); q.done=true; } else if((p.size()>1)&&(((String)p.elementAt(1)).equalsIgnoreCase("BACK"))) { if(startLine>=0) q.lastLine=q.startLine; } 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((Room)q.roomGroup.elementAt(r), true); } else if(q.area!=null) CMLib.map().resetArea(q.area); else { errorOccurred(q,false,"Quest '"+name()+"', no resettable room, roomgroup, area, or areagroup set."); break; } } else if(cmd.equals("SET")) { if(p.size()<2) { errorOccurred(q,isQuiet,"Quest '"+name()+"', unfound variable on set."); break; } cmd=((String)p.elementAt(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(CMException ex){ q.area=null; } Vector names=new Vector(); Vector areas=new Vector(); if((p.size()>3)&&(((String)p.elementAt(2)).equalsIgnoreCase("any"))) for(int ip=3;ip<p.size();ip++) names.addElement(p.elementAt(ip)); else names.addElement(CMParms.combine(p,2)); for(int n=0;n<names.size();n++) { String areaName=(String)names.elementAt(n); int oldSize=areas.size(); if(areaName.equalsIgnoreCase("any")) areas.addElement(CMLib.map().getRandomArea()); if(oldSize==areas.size()) for (Enumeration e = CMLib.map().areas(); e.hasMoreElements(); ) { Area A2 = (Area) e.nextElement(); if (A2.Name().equalsIgnoreCase(areaName)) { areas.addElement(A2); break; } } if(oldSize==areas.size()) for(Enumeration e=CMLib.map().areas();e.hasMoreElements();) { Area A2=(Area)e.nextElement(); if(CMLib.english().containsString(A2.Name(),areaName)) { areas.addElement(A2); break; } } } if(areas.size()>0) q.area=(Area)areas.elementAt(CMLib.dice().roll(1,areas.size(),-1)); if(q.area==null) { 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; Vector names=new Vector(); Vector areas=new Vector(); for(int ip=2;ip<p.size();ip++) names.addElement(p.elementAt(ip)); for(int n=0;n<names.size();n++) { String areaName=(String)names.elementAt(n); int oldSize=areas.size(); if(areaName.equalsIgnoreCase("any")) areas.addElement(CMLib.map().getRandomArea()); boolean addAll=areaName.equalsIgnoreCase("all"); if(oldSize==areas.size()) { if(addAll) { for (Enumeration e = CMLib.map().areas(); e.hasMoreElements(); ) { Area A2=(Area)e.nextElement(); if(!areas.contains(A2)) areas.addElement(e.nextElement()); } } else { Area A2=CMLib.map().findArea(areaName); if((A2!=null)&&(!areas.contains(A2))) areas.addElement(A2); } } } if(areas.size()>0) { q.roomGroup=new Vector(); Area A=null; Room R=null; for(Enumeration e=areas.elements();e.hasMoreElements();) { A=(Area)e.nextElement(); for(Enumeration e2=A.getMetroMap();e2.hasMoreElements();) { R=(Room)e2.nextElement(); if(!q.roomGroup.contains(R)) q.roomGroup.add(R); } } q.envObject=q.roomGroup; } else { errorOccurred(q,isQuiet,"Quest '"+name()+"', unknown areas '"+CMParms.combine(p,2)+"'."); break; } } else if(cmd.equals("MOBTYPE")) { boolean reselect=false; if((p.size()>2)&&(((String)p.elementAt(2)).equalsIgnoreCase("reselect"))) { p.removeElementAt(2); reselect=true; } if(p.size()<3){ q.mob=null; continue; } try{ q.mob=(MOB)getObjectIfSpecified(p,args,2,0); }catch(CMException ex){ q.mob=null; Vector choices=new Vector(); Vector mobTypes=CMParms.parse(CMParms.combine(p,2).toUpperCase()); for(int t=0;t<mobTypes.size();t++) { String mobType=(String)mobTypes.elementAt(t); if(mobType.startsWith("-")) continue; if(q.mobGroup==null) { try { for(Enumeration e=getAppropriateRoomSet(q);e.hasMoreElements();) { Room R2=(Room)e.nextElement(); for(int i=0;i<R2.numInhabitants();i++) { MOB M2=R2.fetchInhabitant(i); if((M2!=null) &&(M2.isMonster()) &&((M2.amUltimatelyFollowing()==null)||(M2.amUltimatelyFollowing().isMonster()))) { if(mobType.equalsIgnoreCase("any")) choices.addElement(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.addElement(M2); } } } }catch(NoSuchElementException e){} } else { try { for(Enumeration e=q.mobGroup.elements();e.hasMoreElements();) { MOB M2=(MOB)e.nextElement(); if((M2!=null) &&(M2.isMonster()) &&((M2.amUltimatelyFollowing()==null)||(M2.amUltimatelyFollowing().isMonster()))) { if(mobType.equalsIgnoreCase("any")) choices.addElement(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.addElement(M2); } } }catch(NoSuchElementException e){} } } for(int t=0;t<mobTypes.size();t++) { String mobType=(String)mobTypes.elementAt(t); if(!mobType.startsWith("-")) continue; mobType=mobType.substring(1); for(int i=choices.size()-1;i>=0;i--) { MOB M2=(MOB)choices.elementAt(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.removeElement(M2); } } } if(choices.size()>0) { for(int c=choices.size()-1;c>=0;c--) if(((!reselect)||(!q.reselectable.contains(choices.elementAt(c)))) &&(CMLib.quests().objectInUse((Environmental)choices.elementAt(c))!=null)) choices.removeElementAt(c); if((choices.size()==0)&&(!isQuiet)) errorOccurred(q,isQuiet,"Quest '"+name()+"', all choices were taken: '"+p+"'."); } if(choices.size()>0) q.mob=(MOB)choices.elementAt(CMLib.dice().roll(1,choices.size(),-1)); } if(q.mob==null) { 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)&&(((String)p.elementAt(2)).equalsIgnoreCase("reselect"))) { p.removeElementAt(2); reselect=true; } if(p.size()<3) continue; Vector choices=null; String mobName=CMParms.combine(p,2).toUpperCase(); String maskStr=CMLib.quests().breakOutMaskString(s,p); Vector mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr); if(mask!=null) mobName=CMParms.combine(p,2).toUpperCase(); try{ choices=(Vector)getObjectIfSpecified(p,args,2,1); }catch(CMException ex){ if(mobName.length()==0) mobName="ANY"; boolean addAll=mobName.equalsIgnoreCase("all"); Vector choices0=new Vector(); Vector choices1=new Vector(); Vector choices2=new Vector(); Vector choices3=new Vector(); try { for(Enumeration e=getAppropriateRoomSet(q);e.hasMoreElements();) { Room R2=(Room)e.nextElement(); for(int i=0;i<R2.numInhabitants();i++) { 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.addElement(M2); } else choices=sortSelect(M2,mobName,choices,choices0,choices1,choices2,choices3); } } } } }catch(NoSuchElementException e){} if((choices!=null)&&(choices.size()>0)) { for(int c=choices.size()-1;c>=0;c--) if(((!reselect)||(!q.reselectable.contains(choices.elementAt(c)))) &&(CMLib.quests().objectInUse((Environmental)choices.elementAt(c))!=null)) choices.removeElementAt(c); if((choices.size()==0)&&(!isQuiet)) errorOccurred(q,isQuiet,"Quest '"+name()+"', all choices were taken: '"+p+"'."); } } if((choices!=null)&&(choices.size()>0)) { q.mobGroup=choices; if(reselect) q.reselectable.addAll(choices); } else { errorOccurred(q,isQuiet,"Quest '"+name()+"', !mobgroup '"+mobName+":"+mask+"'."); break; } q.envObject=q.mobGroup; } else if(cmd.equals("ITEMGROUP")) { q.itemGroup=null; boolean reselect=false; if((p.size()>2)&&(((String)p.elementAt(2)).equalsIgnoreCase("reselect"))) { p.removeElementAt(2); reselect=true; } if(p.size()<3) continue; Vector choices=null; String itemName=CMParms.combine(p,2).toUpperCase(); String maskStr=CMLib.quests().breakOutMaskString(s,p); Vector mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr); if(mask!=null) itemName=CMParms.combine(p,2).toUpperCase(); try{ choices=(Vector)getObjectIfSpecified(p,args,2,1); }catch(CMException ex){ Vector choices0=new Vector(); Vector choices1=new Vector(); Vector choices2=new Vector(); Vector choices3=new Vector(); if(itemName.length()==0) itemName="ANY"; boolean addAll=itemName.equalsIgnoreCase("all"); try { for(Enumeration e=getAppropriateRoomSet(q);e.hasMoreElements();) { Room R2=(Room)e.nextElement(); for(int i=0;i<R2.numItems();i++) { Item I2=R2.fetchItem(i); if(I2!=null) { if(CMLib.masking().maskCheck(mask,I2,true)) { if(addAll) { choices = choices0; choices.addElement(I2); } else choices=sortSelect(I2,itemName,choices,choices0,choices1,choices2,choices3); } } } } }catch(NoSuchElementException e){} if((choices!=null)&&(choices.size()>0)) { for(int c=choices.size()-1;c>=0;c--) if(((!reselect)||(!q.reselectable.contains(choices.elementAt(c)))) &&(CMLib.quests().objectInUse((Environmental)choices.elementAt(c))!=null)) choices.removeElementAt(c); if((choices.size()==0)&&(!isQuiet)) errorOccurred(q,isQuiet,"Quest '"+name()+"', all choices were taken: '"+p+"'."); } } if((choices!=null)&&(choices.size()>0)) { if(reselect) q.reselectable.addAll(choices); q.itemGroup=choices; } else { errorOccurred(q,isQuiet,"Quest '"+name()+"', !itemgroup '"+itemName+":"+mask+"'."); break; } q.envObject=q.itemGroup; } else if(cmd.equals("ITEMTYPE")) { boolean reselect=false; if((p.size()>2)&&(((String)p.elementAt(2)).equalsIgnoreCase("reselect"))) { p.removeElementAt(2); reselect=true; } if(p.size()<3){ q.item=null; continue; } try{ q.item=(Item)getObjectIfSpecified(p,args,2,0); }catch(CMException ex){ q.item=null; Vector choices=new Vector(); Vector itemTypes=new Vector(); for(int i=2;i<p.size();i++) itemTypes.addElement(p.elementAt(i)); for(int t=0;t<itemTypes.size();t++) { String itemType=((String)itemTypes.elementAt(t)).toUpperCase(); if(itemType.startsWith("-")) continue; try { if(q.itemGroup==null) { for(Enumeration e=getAppropriateRoomSet(q);e.hasMoreElements();) { Room R2=(Room)e.nextElement(); for(int i=0;i<R2.numItems();i++) { Item I2=R2.fetchItem(i); if((I2!=null)) { if(itemType.equalsIgnoreCase("any")) choices.addElement(I2); else if(CMClass.classID(I2).toUpperCase().indexOf(itemType)>=0) choices.addElement(I2); } } } } else { for(Enumeration e=q.itemGroup.elements();e.hasMoreElements();) { Item I2=(Item)e.nextElement(); if((I2!=null)) { if(itemType.equalsIgnoreCase("any")) choices.addElement(I2); else if(CMClass.classID(I2).toUpperCase().indexOf(itemType)>=0) choices.addElement(I2); } } } }catch(NoSuchElementException e){} } for(int t=0;t<itemTypes.size();t++) { String itemType=(String)itemTypes.elementAt(t); if(!itemType.startsWith("-")) continue; itemType=itemType.substring(1); for(int i=choices.size()-1;i>=0;i--) { Item I2=(Item)choices.elementAt(i); if((CMClass.classID(I2).toUpperCase().indexOf(itemType)>=0) ||(I2.name().toUpperCase().indexOf(itemType)>=0) ||(I2.displayText().toUpperCase().indexOf(itemType)>=0)) choices.removeElement(I2); } } if(choices.size()>0) { for(int c=choices.size()-1;c>=0;c--) if(((!reselect)||(!q.reselectable.contains(choices.elementAt(c)))) &&(CMLib.quests().objectInUse((Environmental)choices.elementAt(c))!=null)) choices.removeElementAt(c); if((choices.size()==0)&&(!isQuiet)) errorOccurred(q,isQuiet,"Quest '"+name()+"', all choices were taken: '"+p+"'."); } if(choices.size()>0) q.item=(Item)choices.elementAt(CMLib.dice().roll(1,choices.size(),-1)); } if(q.item==null) { 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.bringItemHere(q.item,-1,true); 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((String)p.elementAt(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(CMException ex){ q.room=null; } } else if(cmd.equals("LOCALEGROUPAROUND")) { q.roomGroup=null; if(p.size()<3) continue; range=CMath.parseIntExpression((String)p.elementAt(2)); if(range<=0) { errorOccurred(q,isQuiet,"Quest '"+name()+"', !localegrouparound #'"+((String)p.elementAt(2)+"'.")); break; } p.removeElementAt(2); if(q.room==null) { errorOccurred(q,isQuiet,"Quest '"+name()+"', localegrouparound !room."); break; } } else { try{ q.roomGroup=(Vector)getObjectIfSpecified(p,args,2,1); q.envObject=q.roomGroup; continue; }catch(CMException ex){ q.roomGroup=null; } } if(p.size()<3) continue; Vector names=new Vector(); if((p.size()>3)&&(((String)p.elementAt(2)).equalsIgnoreCase("any"))) for(int ip=3;ip<p.size();ip++) names.addElement(p.elementAt(ip)); else names.addElement(CMParms.combine(p,2)); Vector choices=new Vector(); Vector useThese=null; if(range>0) { TrackingLibrary.TrackingFlags flags; flags = new TrackingLibrary.TrackingFlags() .add(TrackingLibrary.TrackingFlag.AREAONLY); useThese=CMLib.tracking().getRadiantRooms(q.room,flags,range); } for(int n=0;n<names.size();n++) { String localeName=((String)names.elementAt(n)).toUpperCase(); try { Enumeration e=null; if(useThese!=null) e=useThese.elements(); else if(q.area!=null) e=q.area.getMetroMap(); else e=CMLib.map().rooms(); boolean addAll=(localeName.equalsIgnoreCase("any") ||localeName.equalsIgnoreCase("all")); for(;e.hasMoreElements();) { Room R2=(Room)e.nextElement(); if(addAll||CMClass.classID(R2).toUpperCase().indexOf(localeName)>=0) choices.addElement(R2); else { int dom=R2.domainType(); if((dom&Room.INDOORS)>0) { if(Room.indoorDomainDescs[dom-Room.INDOORS].indexOf(localeName)>=0) choices.addElement(R2); } else if(Room.outdoorDomainDescs[dom].indexOf(localeName)>=0) choices.addElement(R2); } } }catch(NoSuchElementException e){} } if(cmd.equalsIgnoreCase("LOCALEGROUP")||cmd.equalsIgnoreCase("LOCALEGROUPAROUND")) { if(choices.size()>0) q.roomGroup=(Vector)choices.clone(); else { errorOccurred(q,isQuiet,"Quest '"+name()+"', !localegroup '"+CMParms.combine(p,2)+"'."); break; } q.envObject=q.roomGroup; } else { if(choices.size()>0) q.room=(Room)choices.elementAt(CMLib.dice().roll(1,choices.size(),-1)); if(q.room==null) { 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(CMException ex){ q.room=null; } } else if(cmd.equals("ROOMGROUPAROUND")) { q.roomGroup=null; if(p.size()<3) continue; range=CMath.s_parseIntExpression((String)p.elementAt(2)); if(range<=0) { errorOccurred(q,isQuiet,"Quest '"+name()+"' roomgrouparound #'"+((String)p.elementAt(2)+"'.")); break; } p.removeElementAt(2); if(q.room==null) { errorOccurred(q,isQuiet,"Quest '"+name()+"', roomgrouparound !room."); break; } } else { try{ q.roomGroup=(Vector)getObjectIfSpecified(p,args,2,1); q.envObject=q.roomGroup; continue; }catch(CMException ex){ q.roomGroup=null; } } if(p.size()<3) continue; Vector choices=null; Vector choices0=new Vector(); Vector choices1=new Vector(); Vector choices2=new Vector(); Vector choices3=new Vector(); Vector names=new Vector(); String maskStr=CMLib.quests().breakOutMaskString(s,p); Vector mask=(maskStr.trim().length()==0)?null:CMLib.masking().maskCompile(maskStr); if((p.size()>3)&&(((String)p.elementAt(2)).equalsIgnoreCase("any"))) for(int ip=3;ip<p.size();ip++) names.addElement(p.elementAt(ip)); else names.addElement(CMParms.combine(p,2)); Vector useThese=null; if(range>0) { TrackingLibrary.TrackingFlags flags; flags = new TrackingLibrary.TrackingFlags() .add(TrackingLibrary.TrackingFlag.AREAONLY); useThese=CMLib.tracking().getRadiantRooms(q.room,flags,range); } for(int n=0;n<names.size();n++) { String localeName=((String)names.elementAt(n)).toUpperCase(); try { Enumeration e=null; if(useThese!=null) e=useThese.elements(); else if(q.area!=null) e=q.area.getMetroMap(); else e=CMLib.map().rooms(); boolean addAll=localeName.equalsIgnoreCase("any") ||localeName.equalsIgnoreCase("all"); for(;e.hasMoreElements();) { Room R2=(Room)e.nextElement(); String display=R2.displayText().toUpperCase(); String desc=R2.description().toUpperCase(); if((mask!=null)&&(!CMLib.masking().maskCheck(mask,R2,true))) continue; if(addAll) { choices=choices0; choices0.addElement(R2); } else if(CMLib.map().getExtendedRoomID(R2).equalsIgnoreCase(localeName)) { choices=choices0; choices0.addElement(R2); } else if(display.equalsIgnoreCase(localeName)) { if((choices==null)||(choices==choices2)||(choices==choices3)) choices=choices1; choices1.addElement(R2); } else if(CMLib.english().containsString(display,localeName)) { if((choices==null)||(choices==choices3)) choices=choices2; choices2.addElement(R2); } else if(CMLib.english().containsString(desc,localeName)) { if(choices==null) choices=choices3; choices3.addElement(R2); } } }catch(NoSuchElementException e){} } if(cmd.equalsIgnoreCase("ROOMGROUP")||cmd.equalsIgnoreCase("ROOMGROUPAROUND")) { if((choices!=null)&&(choices.size()>0)) q.roomGroup=(Vector)choices.clone(); else { errorOccurred(q,isQuiet,"Quest '"+name()+"', !roomgroup '"+CMParms.combine(p,2)+"'."); break; } q.envObject=q.roomGroup; } else { if((choices!=null)&&(choices.size()>0)) q.room=(Room)choices.elementAt(CMLib.dice().roll(1,choices.size(),-1)); if(q.room==null) { 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)&&(((String)p.elementAt(2)).equalsIgnoreCase("reselect"))) { p.removeElementAt(2); reselect=true; } if(p.size()<3){ q.mob=null; continue; } String mobName=CMParms.combine(p,2).toUpperCase(); String maskStr=CMLib.quests().breakOutMaskString(s,p); Vector 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(CMException ex){ q.mob=null; Vector choices=null; Vector choices0=new Vector(); Vector choices1=new Vector(); Vector choices2=new Vector(); Vector choices3=new Vector(); if(mobName.length()==0) mobName="ANY"; if(q.mobGroup!=null) { for(Enumeration e=q.mobGroup.elements();e.hasMoreElements();) { MOB M2=(MOB)e.nextElement(); 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(Enumeration e=getAppropriateRoomSet(q);e.hasMoreElements();) { Room R2=(Room)e.nextElement(); for(int i=0;i<R2.numInhabitants();i++) { 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(NoSuchElementException e){} } if((choices!=null) &&(choices.size()>0)) { for(int c=choices.size()-1;c>=0;c--) if(((!reselect)||(!q.reselectable.contains(choices.elementAt(c)))) &&(CMLib.quests().objectInUse((Environmental)choices.elementAt(c))!=null)) choices.removeElementAt(c); if((choices.size()==0)&&(!isQuiet)) errorOccurred(q,isQuiet,"Quest '"+name()+"', all choices were taken: '"+p+"'."); } if((choices!=null)&&(choices.size()>0)) q.mob=(MOB)choices.elementAt(CMLib.dice().roll(1,choices.size(),-1)); } if(q.mob==null) { errorOccurred(q,isQuiet,"Quest '"+name()+"', !mob '"+mobName+"'."); break; } if(reselect) q.reselectable.addElement(q.mob); questifyScriptableBehavs(q.mob); // just wierd 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)&&(((String)p.elementAt(2)).equalsIgnoreCase("reselect"))) { p.removeElementAt(2); reselect=true; } if(p.size()<3){ q.item=null; continue; } String itemName=CMParms.combine(p,2).toUpperCase(); String maskStr=CMLib.quests().breakOutMaskString(s,p); Vector 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(CMException ex){ q.item=null; Vector choices=null; Vector choices0=new Vector(); Vector choices1=new Vector(); Vector choices2=new Vector(); Vector choices3=new Vector(); if(itemName.trim().length()==0) itemName="ANY"; try { if(q.itemGroup!=null) { for(Enumeration e=q.itemGroup.elements();e.hasMoreElements();) { Item I2=(Item)e.nextElement(); if(I2!=null) { if(!CMLib.masking().maskCheck(mask,I2,true)) continue; choices=sortSelect(I2,itemName,choices,choices0,choices1,choices2,choices3); } } } else { for(Enumeration e=getAppropriateRoomSet(q);e.hasMoreElements();) { Room R2=(Room)e.nextElement(); for(int i=0;i<R2.numItems();i++) { Item I2=R2.fetchItem(i); if(I2!=null) { if(!CMLib.masking().maskCheck(mask,I2,true)) continue; choices=sortSelect(I2,itemName,choices,choices0,choices1,choices2,choices3); } } } } }catch(NoSuchElementException e){} if((choices!=null)&&(choices.size()>0)) { for(int c=choices.size()-1;c>=0;c--) if(((!reselect)||(!q.reselectable.contains(choices.elementAt(c)))) &&(CMLib.quests().objectInUse((Environmental)choices.elementAt(c))!=null)) choices.removeElementAt(c); if((choices.size()==0)&&(!isQuiet)) errorOccurred(q,isQuiet,"Quest '"+name()+"', all choices were taken: '"+p+"'."); } if((choices!=null)&&(choices.size()>0)) q.item=(Item)choices.elementAt(CMLib.dice().roll(1,choices.size(),-1)); } if(q.item==null) { 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.bringItemHere(q.item,-1,true); 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("AGENT")) { if(q.mysteryData==null) q.mysteryData=new MysteryData(); try{ q.mob=(MOB)getObjectIfSpecified(p,args,2,0); }catch(CMException ex){ if(p.size()>2) { errorOccurred(q,isQuiet,"Quest '"+name()+"', agent syntax '"+CMParms.combine(p,2)+"'."); break; } } if(q.mob==null) { 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; String numStr=CMParms.combine(p,2); Faction F=null; try{ F=(Faction)getObjectIfSpecified(p,args,2,0); }catch(CMException ex){ if(numStr.equalsIgnoreCase("ANY")) { int numFactions=CMLib.factions().factionSet().size(); int whichFaction=CMLib.dice().roll(1,numFactions,-1); int curFaction=0; Hashtable factions=(Hashtable)CMLib.factions().factionSet().clone(); for(Enumeration e=factions.elements();e.hasMoreElements();) { F=(Faction)e.nextElement(); if(curFaction==whichFaction) break; curFaction++; } } else { F=CMLib.factions().getFaction(numStr); if(F==null) F=CMLib.factions().getFactionByName(numStr); } } if(F==null) { 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=(Vector)getObjectIfSpecified(p,args,2,1); }catch(CMException ex){ q.mysteryData.factionGroup=null; String numStr=CMParms.combine(p,2); Faction F=null; if(q.mysteryData.faction!=null) q.mysteryData.factionGroup.addElement(q.mysteryData.faction); if(CMath.isMathExpression(numStr)||numStr.equalsIgnoreCase("ALL")) { int numFactions=CMLib.factions().factionSet().size(); 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)) { int whichFaction=CMLib.dice().roll(1,numFactions,-1); int curFaction=0; Hashtable factions=(Hashtable)CMLib.factions().factionSet().clone(); for(Enumeration e=factions.elements();e.hasMoreElements();) { F=(Faction)e.nextElement(); if(curFaction==whichFaction) break; curFaction++; } if(!q.mysteryData.factionGroup.contains(F)) q.mysteryData.factionGroup.addElement(F); } } else { for(int pi=2;pi<p.size();pi++) { F=CMLib.factions().getFaction((String)p.elementAt(pi)); if(F==null) F=CMLib.factions().getFactionByName((String)p.elementAt(pi)); if(F==null) { errorOccurred(q,isQuiet,"Quest '"+name()+"', !factiongroup '"+(String)p.elementAt(pi)+"'."); break; } if(!q.mysteryData.factionGroup.contains(F)) q.mysteryData.factionGroup.addElement(F); } if(q.error) break; } } if((q.mysteryData.factionGroup!=null) &&(q.mysteryData.factionGroup.size()>0) &&(q.mysteryData.faction==null)) q.mysteryData.faction=(Faction)q.mysteryData.factionGroup.elementAt(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=(Vector)getObjectIfSpecified(p,args,2,1); if((q.mysteryData.agentGroup!=null) &&(q.mysteryData.agentGroup.size()>0) &&(q.mysteryData.agent==null)) q.mysteryData.agent=(MOB)q.mysteryData.agentGroup.elementAt(CMLib.dice().roll(1,q.mysteryData.agentGroup.size(),-1)); }catch(CMException ex){ q.mysteryData.agentGroup=null; String numStr=CMParms.combine(p,2).toUpperCase(); if(!CMath.isMathExpression(numStr)) { errorOccurred(q,isQuiet,"Quest '"+name()+"', !agentgroup #'"+numStr+"'."); break; } if((q.mobGroup==null)||(q.mobGroup.size()==0)) { errorOccurred(q,isQuiet,"Quest '"+name()+"', !agentgroup mobgroup."); break; } Vector V=(Vector)q.mobGroup.clone(); q.mysteryData.agentGroup=new Vector(); if(q.mysteryData.agent!=null) q.mysteryData.agentGroup.addElement(q.mysteryData.agent); int num=CMath.parseIntExpression(numStr); if(num>=V.size()) num=V.size(); while((q.mysteryData.agentGroup.size()<num)&&(V.size()>0)) { int dex=CMLib.dice().roll(1,V.size(),-1); Object O=V.elementAt(dex); V.removeElementAt(dex); q.mysteryData.agentGroup.addElement(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=(Vector)q.mysteryData.agentGroup.clone(); 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=(Vector)getObjectIfSpecified(p,args,2,1); q.roomGroup=q.mysteryData.whereHappenedGroup; q.mysteryData.whereHappened=((q.roomGroup==null)||(q.roomGroup.size()==0))?null: (Room)q.roomGroup.elementAt(CMLib.dice().roll(1,q.roomGroup.size(),-1)); q.envObject=q.mysteryData.whereHappenedGroup; continue; }catch(CMException ex){ q.mysteryData.whereHappenedGroup=null; } } else { try{ q.mysteryData.whereAtGroup=(Vector)getObjectIfSpecified(p,args,2,1); q.roomGroup=q.mysteryData.whereAtGroup; q.mysteryData.whereAt=((q.roomGroup==null)||(q.roomGroup.size()==0))?null: (Room)q.roomGroup.elementAt(CMLib.dice().roll(1,q.roomGroup.size(),-1)); q.envObject=q.mysteryData.whereAtGroup; continue; }catch(CMException ex){ q.mysteryData.whereAtGroup=null; } } if(p.size()<3) continue; String numStr=CMParms.combine(p,2).toUpperCase(); if(!CMath.isMathExpression(numStr)) { errorOccurred(q,isQuiet,"Quest '"+name()+"', !"+cmd.toLowerCase()+" #'"+numStr+"'."); break; } if((q.roomGroup==null)||(q.roomGroup.size()==0)) { errorOccurred(q,isQuiet,"Quest '"+name()+"', !"+cmd.toLowerCase()+" roomGroup."); break; } Vector V=(Vector)q.roomGroup.clone(); Vector V2=new Vector(); Room R=null; if(cmd.equals("WHEREHAPPENEDGROUP")) { q.mysteryData.whereHappenedGroup=V2; R=q.mysteryData.whereHappened; } else { q.mysteryData.whereAtGroup=null; R=q.mysteryData.whereAt; } if(R!=null) V2.addElement(R); int num=CMath.parseIntExpression(numStr); if(num>=V.size()) num=V.size(); while((V2.size()<num)&&(V.size()>0)) { int dex=CMLib.dice().roll(1,V.size(),-1); Object O=V.elementAt(dex); V.removeElementAt(dex); if(!V2.contains(O)) V2.addElement(O); if(R==null) R=(Room)O; } q.roomGroup=(Vector)V2.clone(); 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(); Vector V2; TimeClock TC=null; if(cmd.equals("WHENHAPPENEDGROUP")) { try{ q.mysteryData.whenHappenedGroup=(Vector)getObjectIfSpecified(p,args,2,1); V2=q.mysteryData.whenHappenedGroup; if((V2!=null)&&(V2.size()>0)) q.mysteryData.whenHappened=(TimeClock)V2.elementAt(CMLib.dice().roll(1,V2.size(),-1)); continue; }catch(CMException ex){ q.mysteryData.whenHappenedGroup=null; } } else { try{ q.mysteryData.whenAtGroup=(Vector)getObjectIfSpecified(p,args,2,1); V2=q.mysteryData.whenAtGroup; if((V2!=null)&&(V2.size()>0)) q.mysteryData.whenAt=(TimeClock)V2.elementAt(CMLib.dice().roll(1,V2.size(),-1)); continue; }catch(CMException ex){ q.mysteryData.whenAtGroup=null; } } if(p.size()<3) continue; V2=new Vector(); TimeClock NOW=getMysteryTimeNowFromState(); if(TC!=null) V2.addElement(TC); if(cmd.equals("WHENHAPPENEDGROUP")) { q.mysteryData.whenHappenedGroup=V2; TC=q.mysteryData.whenHappened; } else { q.mysteryData.whenAtGroup=V2; TC=q.mysteryData.whenAt; } for(int pi=2;pi<p.size();pi++) { String numStr=(String)p.elementAt(pi); if(!CMath.isMathExpression(numStr)) { errorOccurred(q,isQuiet,"Quest '"+name()+"', "+cmd.toLowerCase()+" !relative hour #: "+numStr+"."); break; } TimeClock TC2=(TimeClock)NOW.copyOf(); TC2.tickTock(CMath.parseIntExpression(numStr)); V2.addElement(TC2); } if(q.error) break; if((V2.size()>0)&&(TC==null)) TC=(TimeClock)V2.elementAt(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(CMException ex){ q.mysteryData.whenHappened=null; } } else { try{ q.mysteryData.whenAt=(TimeClock)getObjectIfSpecified(p,args,2,0); continue; }catch(CMException ex){ q.mysteryData.whenAt=null; } } if(p.size()<3) continue; TimeClock NOW=getMysteryTimeNowFromState(); TimeClock TC=null; String numStr=CMParms.combine(p,2); if(!CMath.isMathExpression(numStr)) { 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(); Vector V2=null; int num=-1; if((p.size()>2)&&(CMath.isMathExpression((String)p.elementAt(2)))) { num=CMath.s_parseIntExpression((String)p.elementAt(2)); p.removeElementAt(2); } if(cmd.equals("MOTIVEGROUP")) { try{ q.mysteryData.motiveGroup=(Vector)getObjectIfSpecified(p,args,2,1); sizeDownTo(q.mysteryData.motiveGroup,num); V2=q.mysteryData.motiveGroup; if((V2!=null)&&(V2.size()>0)) q.mysteryData.motive=(String)V2.elementAt(CMLib.dice().roll(1,V2.size(),-1)); continue; }catch(CMException ex){ q.mysteryData.motiveGroup=null; } } else { try{ q.mysteryData.actionGroup=(Vector)getObjectIfSpecified(p,args,2,1); sizeDownTo(q.mysteryData.actionGroup,num); V2=q.mysteryData.actionGroup; if((V2!=null)&&(V2.size()>0)) q.mysteryData.action=(String)V2.elementAt(CMLib.dice().roll(1,V2.size(),-1)); continue; }catch(CMException ex){ q.mysteryData.actionGroup=null; } } if(p.size()<3) continue; V2=new Vector(); String Mstr=null; if(cmd.equals("MOTIVEGROUP")) { q.mysteryData.motiveGroup=V2; Mstr=q.mysteryData.motive; } else { q.mysteryData.actionGroup=V2; Mstr=q.mysteryData.action; } if(Mstr!=null) V2.addElement(Mstr); for(int pi=2;pi<p.size();pi++) if(!V2.contains(p.elementAt(pi))) V2.addElement(p.elementAt(pi)); sizeDownTo(V2,num); if((V2.size()>0)&&(Mstr==null)) Mstr=(String)V2.elementAt(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(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(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(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(CMException ex){ q.mysteryData.whereAt=null; } } if(p.size()>2) { errorOccurred(q,isQuiet,"Quest '"+name()+"', "+cmd.toLowerCase()+" syntax '"+CMParms.combine(p,2)+"'."); break; } if(q.room==null) { 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(); Vector V2=null; if(cmd.equals("TARGETGROUP")) { try{ q.mysteryData.targetGroup=(Vector)getObjectIfSpecified(p,args,2,1); V2=q.mysteryData.targetGroup; if((V2!=null)&&(V2.size()>0)) { if(V2.firstElement() instanceof MOB) { q.mobGroup=V2; q.mob=(MOB)V2.elementAt(CMLib.dice().roll(1,V2.size(),-1)); q.envObject=q.mobGroup; q.mysteryData.target=q.mob; } if(V2.firstElement() instanceof Item) { q.itemGroup=V2; q.item=(Item)V2.elementAt(CMLib.dice().roll(1,V2.size(),-1)); q.mysteryData.target=q.item; q.envObject=q.itemGroup; } } continue; }catch(CMException ex){ q.mysteryData.targetGroup=null; } } else { try{ q.mysteryData.toolGroup=(Vector)getObjectIfSpecified(p,args,2,1); V2=q.mysteryData.toolGroup; if((V2!=null)&&(V2.size()>0)) { if(V2.firstElement() instanceof MOB) { q.mobGroup=V2; q.mob=(MOB)V2.elementAt(CMLib.dice().roll(1,V2.size(),-1)); q.envObject=q.mobGroup; q.mysteryData.tool=q.mob; } if(V2.firstElement() instanceof Item) { q.itemGroup=V2; q.item=(Item)V2.elementAt(CMLib.dice().roll(1,V2.size(),-1)); q.envObject=q.itemGroup; q.mysteryData.tool=q.item; } } continue; }catch(CMException ex){ q.mysteryData.toolGroup=null; } } if(p.size()<3) continue; String numStr=CMParms.combine(p,2).toUpperCase(); if(!CMath.isMathExpression(numStr)) { errorOccurred(q,isQuiet,"Quest '"+name()+"', !"+cmd.toLowerCase()+" #'"+numStr+"'."); break; } if(((q.mobGroup==null)||(q.mobGroup.size()==0)) &&((q.itemGroup==null)||(q.itemGroup.size()==0))) { errorOccurred(q,isQuiet,"Quest '"+name()+"', !"+cmd.toLowerCase()+" mobgroup itemgroup."); break; } Vector V; if((q.mobGroup!=null)&&(q.mobGroup.size()>0)) V=(Vector)q.mobGroup.clone(); else V=(Vector)q.itemGroup.clone(); V2=new Vector(); Environmental finalE=null; if(cmd.equals("TARGETGROUP")) { q.mysteryData.targetGroup=V2; finalE=q.mysteryData.target; } else { q.mysteryData.toolGroup=V2; finalE=q.mysteryData.tool; } if(finalE!=null)V2.addElement(finalE); int num=CMath.parseIntExpression(numStr); if(num>=V.size()) num=V.size(); Object O; while((V2.size()<num)&&(V.size()>0)) { int dex=CMLib.dice().roll(1,V.size(),-1); O=V.elementAt(dex); V.removeElementAt(dex); if(!V2.contains(O)) V2.addElement(O); if(finalE==null) finalE=(Environmental)O; } if(finalE instanceof MOB) { q.mobGroup=(Vector)V2.clone(); q.mob=(MOB)finalE; questifyScriptableBehavs(q.mob); // i just dont get it } else if(finalE instanceof Item) { q.itemGroup=(Vector)V2.clone(); 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(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; q.envObject=q.mysteryData.tool; continue; }catch(CMException ex){ q.mysteryData.tool=null; } } if(p.size()>2) { errorOccurred(q,isQuiet,"Quest '"+name()+"', "+cmd.toLowerCase()+" syntax '"+CMParms.combine(p,2)+"'."); break; } if((q.envObject instanceof Vector) &&(((Vector)q.envObject).size()>0) &&(((Vector)q.envObject).firstElement() instanceof Environmental)) q.envObject=(Environmental)((Vector)q.envObject).elementAt(CMLib.dice().roll(1,((Vector)q.envObject).size(),-1)); if(!(q.envObject instanceof Environmental)) { 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)) { errorOccurred(q,isQuiet,"Quest '"+name()+"', unknown variable '"+cmd+"'."); break; } } else if(cmd.equals("IMPORT")) { if(p.size()<2) { errorOccurred(q,isQuiet,"Quest '"+name()+"', no IMPORT type."); break; } cmd=((String)p.elementAt(1)).toUpperCase(); if(cmd.equals("MOBS")) { if(p.size()<3) { errorOccurred(q,isQuiet,"Quest '"+name()+"', no IMPORT MOBS file."); break; } StringBuffer buf=getResourceFileData(CMParms.combine(p,2)); if((buf==null)||(buf.length()<20)) { errorOccurred(q,isQuiet,"Quest '"+name()+"',Unknown XML file: '"+CMParms.combine(p,2)+"' for '"+name()+"'."); break; } if(buf.substring(0,20).indexOf("<MOBS>")<0) { errorOccurred(q,isQuiet,"Quest '"+name()+"', Invalid XML file: '"+CMParms.combine(p,2)+"' for '"+name()+"'."); break; } q.loadedMobs=new Vector(); String errorStr=CMLib.coffeeMaker().addMOBsFromXML(buf.toString(),q.loadedMobs,null); if(errorStr.length()>0) { errorOccurred(q,isQuiet,"Quest '"+name()+"',Error on import of: '"+CMParms.combine(p,2)+"' for '"+name()+"': "+errorStr+"."); break; } if(q.loadedMobs.size()<=0) { errorOccurred(q,isQuiet,"Quest '"+name()+"',No mobs loaded: '"+CMParms.combine(p,2)+"' for '"+name()+"'."); break; } } else if(cmd.equals("ITEMS")) { if(p.size()<3) { errorOccurred(q,isQuiet,"Quest '"+name()+"', no import filename!"); break; } StringBuffer buf=getResourceFileData(CMParms.combine(p,2)); if((buf==null)||(buf.length()<20)) { errorOccurred(q,isQuiet,"Quest '"+name()+"',Unknown XML file: '"+CMParms.combine(p,2)+"' for '"+name()+"'."); break; } if(buf.substring(0,20).indexOf("<ITEMS>")<0) { errorOccurred(q,isQuiet,"Quest '"+name()+"',Invalid XML file: '"+CMParms.combine(p,2)+"' for '"+name()+"'."); break; } q.loadedItems=new Vector(); String errorStr=CMLib.coffeeMaker().addItemsFromXML(buf.toString(),q.loadedItems,null); if(errorStr.length()>0) { errorOccurred(q,isQuiet,"Quest '"+name()+"',Error on import of: '"+CMParms.combine(p,2)+"' for '"+name()+"': "+errorStr+"."); break; } if(q.loadedItems.size()<=0) { errorOccurred(q,isQuiet,"Quest '"+name()+"',No items loaded: '"+CMParms.combine(p,2)+"' for '"+name()+"'."); break; } } else { errorOccurred(q,isQuiet,"Quest '"+name()+"', unknown import type '"+cmd+"'."); break; } } else if(cmd.startsWith("LOAD=")) { boolean error=q.error; Vector args2=new Vector(); parseQuestScriptWArgs(parseLoadScripts(s,args,args2),args2); if((!error)&&(q.error)) break; } else if(cmd.equals("LOAD")) { if(p.size()<2) { errorOccurred(q,isQuiet,"Quest '"+name()+"', unfound type on load."); break; } cmd=((String)p.elementAt(1)).toUpperCase(); if(cmd.equals("MOB")||cmd.equals("MOBGROUP")) { if(q.loadedMobs.size()==0) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot load mob, no mobs imported."); break; } int maxToLoad=Integer.MAX_VALUE; if((p.size()>2)&&(CMath.isMathExpression((String)p.elementAt(2)))) { maxToLoad=CMath.parseIntExpression((String)p.elementAt(2)); p.removeElementAt(2); } if(p.size()<3) { errorOccurred(q,isQuiet,"Quest '"+name()+"', no mob name to load!"); break; } String mobName=CMParms.combine(p,2); String maskStr=CMLib.quests().breakOutMaskString(s,p); Vector 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"; boolean addAll=mobName.equalsIgnoreCase("ALL") ||mobName.equalsIgnoreCase("ANY"); Vector choices=new Vector(); for(int i=0;i<q.loadedMobs.size();i++) { MOB M2=(MOB)q.loadedMobs.elementAt(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.addElement(M2.copyOf()); } if(choices.size()==0) { errorOccurred(q,isQuiet,"Quest '"+name()+"', no mob found to load '"+mobName+"'!"); break; } Vector mobsToDo=null; if(cmd.equalsIgnoreCase("MOB")) { mobsToDo=new Vector(); mobsToDo.addElement(choices.elementAt(CMLib.dice().roll(1,choices.size(),-1))); } else { mobsToDo=(Vector)choices.clone(); q.mobGroup=mobsToDo; } while((mobsToDo.size()>maxToLoad)&&(maxToLoad>0)) mobsToDo.removeElementAt(CMLib.dice().roll(1,mobsToDo.size(),-1)); while((mobsToDo.size()<maxToLoad)&&(maxToLoad>0)&&(maxToLoad<Integer.MAX_VALUE)) mobsToDo.addElement(((CMObject)mobsToDo.elementAt(CMLib.dice().roll(1,mobsToDo.size(),-1))).copyOf()); Room choiceRoom=q.room; for(int m=0;m<mobsToDo.size();m++) { q.mob=(MOB)mobsToDo.elementAt(m); q.room=choiceRoom; if(q.room==null) { if(q.roomGroup!=null) q.room=(Room)q.roomGroup.elementAt(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.baseEnvStats().setRejuv(0); q.mob.baseEnvStats().setDisposition(q.mob.baseEnvStats().disposition()|EnvStats.IS_UNSAVABLE); q.mob.recoverEnvStats(); q.mob.text(); q.mob.bringToLife(q.room,true); } questifyScriptableBehavs(q.mob); runtimeRegisterObject(q.mob); 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.clone(); if(q.room!=null) q.area=q.room.getArea(); } else if(cmd.equals("ITEM")||cmd.equals("ITEMGROUP")) { if(q.loadedItems.size()==0) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot load item, no items imported."); break; } int maxToLoad=Integer.MAX_VALUE; if((p.size()>2)&&(CMath.isMathExpression((String)p.elementAt(2)))) { maxToLoad=CMath.parseIntExpression((String)p.elementAt(2)); p.removeElementAt(2); } if(p.size()<3) { errorOccurred(q,isQuiet,"Quest '"+name()+"', no item name to load!"); break; } String itemName=CMParms.combine(p,2); Vector choices=new Vector(); for(int i=0;i<q.loadedItems.size();i++) { Item I2=(Item)q.loadedItems.elementAt(i); if((itemName.equalsIgnoreCase("any")) ||(CMLib.english().containsString(I2.name(),itemName)) ||(CMLib.english().containsString(I2.displayText(),itemName)) ||(CMLib.english().containsString(I2.description(),itemName))) choices.addElement(I2.copyOf()); } if(choices.size()==0) { errorOccurred(q,isQuiet,"Quest '"+name()+"', no item found to load '"+itemName+"'!"); break; } Vector itemsToDo=null; if(cmd.equalsIgnoreCase("ITEM")) { itemsToDo=new Vector(); itemsToDo.addElement(choices.elementAt(CMLib.dice().roll(1,choices.size(),-1))); } else { itemsToDo=(Vector)choices.clone(); q.itemGroup=itemsToDo; } while((itemsToDo.size()>maxToLoad)&&(maxToLoad>0)) itemsToDo.removeElementAt(CMLib.dice().roll(1,itemsToDo.size(),-1)); while((itemsToDo.size()<maxToLoad)&&(maxToLoad>0)&&(maxToLoad<Integer.MAX_VALUE)) itemsToDo.addElement(((CMObject)itemsToDo.elementAt(CMLib.dice().roll(1,itemsToDo.size(),-1))).copyOf()); Room choiceRoom=q.room; for(int m=0;m<itemsToDo.size();m++) { q.item=(Item)itemsToDo.elementAt(m); q.room=choiceRoom; if(q.room==null) { if(q.roomGroup!=null) q.room=(Room)q.roomGroup.elementAt(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.baseEnvStats().setRejuv(0); q.item.baseEnvStats().setDisposition(q.item.baseEnvStats().disposition()|EnvStats.IS_UNSAVABLE); q.item.recoverEnvStats(); 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.clone(); } else { errorOccurred(q,isQuiet,"Quest '"+name()+"', unknown load type '"+cmd+"'."); break; } } else if(cmd.equals("GIVE")) { if(p.size()<2) { errorOccurred(q,isQuiet,"Quest '"+name()+"', unfound type on give."); break; } cmd=((String)p.elementAt(1)).toUpperCase(); if(cmd.equals("FOLLOWER")) { if(q.mob==null) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give follower, no mob set."); break; } if(p.size()<3) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give follower, follower name not given."); break; } String mobName=CMParms.combine(p,2); Vector choices=new Vector(); for(int i=q.stuff.size()-1;i>=0;i--) { Environmental E2=(Environmental)q.stuff.elementAt(i,1); if((E2!=q.mob)&&(E2 instanceof MOB)) { MOB M2=(MOB)E2; if((mobName.equalsIgnoreCase("any")) ||(CMLib.english().containsString(M2.name(),mobName)) ||(CMLib.english().containsString(M2.displayText(),mobName)) ||(CMLib.english().containsString(M2.description(),mobName))) choices.addElement(M2); } } if(choices.size()==0) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give follower, no mobs called '"+mobName+"' previously set in script."); break; } MOB M2=(MOB)choices.elementAt(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)) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give item(s), no item(s) set or loaded."); break; } if((q.mob==null)&&(q.mobGroup==null)) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give item(s), no mob set."); break; } if(p.size()>2) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give item(s), parameter unnecessarily given: '"+CMParms.combine(p,2)+"'."); break; } Vector toSet=new Vector(); if(q.mob!=null) toSet.addElement(q.mob); else if(q.mobGroup!=null) toSet=q.mobGroup; Vector itemSet=new Vector(); if(q.item!=null) itemSet.addElement(q.item); else if(q.itemGroup!=null) itemSet=q.itemGroup; else if(q.loadedItems!=null) itemSet=q.loadedItems; for(int i=0;i<toSet.size();i++) { MOB M2=(MOB)toSet.elementAt(i); runtimeRegisterObject(M2); if(cmd.equals("ITEMS")) { for(int i3=0;i3<itemSet.size();i3++) { Item I3=(Item)itemSet.elementAt(i3); if(q.item==I3) { M2.giveItem(I3); q.item=(Item)q.item.copyOf(); questifyScriptableBehavs(q.item); } else { I3=(Item)I3.copyOf(); questifyScriptableBehavs(I3); M2.giveItem(I3); } } } else if(cmd.equals("ITEM")) { Item I3=(Item)itemSet.elementAt(CMLib.dice().roll(1,itemSet.size(),-1)); questifyScriptableBehavs(I3); if(q.item==I3) { M2.giveItem(I3); q.item=(Item)q.item.copyOf(); questifyScriptableBehavs(q.item); } else { I3=(Item)I3.copyOf(); questifyScriptableBehavs(I3); M2.giveItem(I3); } } } } else if(cmd.equals("ABILITY")) { if((q.mob==null)&&(q.mobGroup==null)) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give ability, no mob set."); break; } if(p.size()<3) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give ability, ability name not given."); break; } Ability A3=CMClass.findAbility((String)p.elementAt(2)); if(A3==null) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give ability, ability name unknown '"+((String)p.elementAt(2))+"."); break; } Vector toSet=new Vector(); if(q.mob!=null) toSet.addElement(q.mob); else if(q.mobGroup!=null) toSet=q.mobGroup; for(int i=0;i<toSet.size();i++) { MOB M2=(MOB)toSet.elementAt(i); runtimeRegisterAbility(M2,A3.ID(),CMParms.combineWithQuotes(p,3),true); } } else if(cmd.equals("BEHAVIOR")) { if(q.envObject==null) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give behavior, no mob or item set."); break; } if(p.size()<3) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give behavior, behavior name not given."); break; } Behavior B=CMClass.getBehavior((String)p.elementAt(2)); if(B==null) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give behavior, behavior name unknown '"+((String)p.elementAt(2))+"."); break; } Vector toSet=new Vector(); if(q.envObject instanceof Vector) toSet=(Vector)q.envObject; else if(q.envObject!=null) toSet.addElement(q.envObject); for(int i=0;i<toSet.size();i++) { Environmental E2=(Environmental)toSet.elementAt(i); runtimeRegisterBehavior(E2,B.ID(),CMParms.combineWithQuotes(p,3),true); } } else if(cmd.equals("STAT")) { if(q.envObject==null) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give stat, no mob or item set."); break; } if(p.size()<3) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give stat, stat name not given."); break; } String stat=(String)p.elementAt(2); String val=CMParms.combineWithQuotes(p,3); Vector toSet=new Vector(); if(q.envObject instanceof Vector) toSet=(Vector)q.envObject; else if(q.envObject!=null) toSet.addElement(q.envObject); for(int i=0;i<toSet.size();i++) { Environmental E2=(Environmental)toSet.elementAt(i); if(stat.equalsIgnoreCase("KEYPLAYER")) { Ability A=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) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give script, no object set."); break; } boolean proceed=true; boolean savable=false; String word=null; String scope=CMStrings.replaceAll(name()," ","_").toUpperCase().trim(); while(proceed&&(p.size()>2)) { word=(String)p.elementAt(2); proceed=false; if(word.equalsIgnoreCase("SAVABLE")) { savable=true; proceed=true; } else if(word.equalsIgnoreCase("GLOBAL")) { scope=""; proceed=true; } else if(word.equalsIgnoreCase("INDIVIDUAL")) { scope="*"; proceed=true; } if(proceed) p.removeElementAt(2); } if(p.size()<3) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give script, script not given."); break; } String val=CMParms.combineWithQuotes(p,2); Vector toSet=new Vector(); if(q.envObject instanceof Vector) toSet=(Vector)q.envObject; else if(q.envObject!=null) toSet.addElement(q.envObject); for(int i=0;i<toSet.size();i++) { Environmental E2=(Environmental)toSet.elementAt(i); ScriptingEngine S=(ScriptingEngine)CMClass.getCommon("DefaultScriptingEngine"); S.setSavable(savable); S.registerDefaultQuest(name()); S.setVarScope(scope); S.setScript(val); E2.addScript(S); runtimeRegisterObject(E2); questState.addons.addElement(CMParms.makeVector(E2,S),Integer.valueOf(questState.preserveState)); } } else if(cmd.equals("AFFECT")) { if(q.envObject==null) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give Effect, no mob, room or item set."); break; } if(p.size()<3) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give Effect, ability name not given."); break; } Ability A3=CMClass.findAbility((String)p.elementAt(2)); if(A3==null) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot give Effect, ability name unknown '"+((String)p.elementAt(2))+"."); break; } Vector toSet=new Vector(); if(q.envObject instanceof Vector) toSet=(Vector)q.envObject; else if(q.envObject!=null) toSet.addElement(q.envObject); for(int i=0;i<toSet.size();i++) { Environmental E2=(Environmental)toSet.elementAt(i); runtimeRegisterEffect(E2,A3.ID(),CMParms.combineWithQuotes(p,3),true); } } else { errorOccurred(q,isQuiet,"Quest '"+name()+"', unknown give type '"+cmd+"'."); break; } } else if(cmd.equals("TAKE")) { if(p.size()<2) { errorOccurred(q,isQuiet,"Quest '"+name()+"', unfound type on take."); break; } cmd=((String)p.elementAt(1)).toUpperCase(); if(cmd.equals("ABILITY")) { if((q.mob==null)&&(q.mobGroup==null)) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot take ability, no mob set."); break; } if(p.size()<3) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot take ability, ability name not given."); break; } Ability A3=CMClass.findAbility((String)p.elementAt(2)); if(A3==null) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot take ability, ability name unknown '"+((String)p.elementAt(2))+"."); break; } Vector toSet=new Vector(); if(q.mob!=null) toSet.addElement(q.mob); else if(q.mobGroup!=null) toSet=q.mobGroup; for(int i=0;i<toSet.size();i++) { MOB M2=(MOB)toSet.elementAt(i); runtimeRegisterAbility(M2,A3.ID(),CMParms.combineWithQuotes(p,3),false); } } else if(cmd.equals("BEHAVIOR")) { if(q.envObject==null) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot take behavior, no mob or item set."); break; } if(p.size()<3) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot take behavior, behavior name not given."); break; } Behavior B=CMClass.getBehavior((String)p.elementAt(2)); if(B==null) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot take behavior, behavior name unknown '"+((String)p.elementAt(2))+"."); break; } Vector toSet=new Vector(); if(q.envObject instanceof Vector) toSet=(Vector)q.envObject; else if(q.envObject!=null) toSet.addElement(q.envObject); for(int i=0;i<toSet.size();i++) { Environmental E2=(Environmental)toSet.elementAt(i); runtimeRegisterBehavior(E2,B.ID(),CMParms.combineWithQuotes(p,3),false); } } else if(cmd.equals("AFFECT")) { if(q.envObject==null) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot take Effect, no mob, room or item set."); break; } if(p.size()<3) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot take Effect, ability name not given."); break; } Ability A3=CMClass.findAbility((String)p.elementAt(2)); if(A3==null) { errorOccurred(q,isQuiet,"Quest '"+name()+"', cannot take Effect, ability name unknown '"+((String)p.elementAt(2))+"."); break; } Vector toSet=new Vector(); if(q.envObject instanceof Vector) toSet=(Vector)q.envObject; else if(q.envObject!=null) toSet.addElement(q.envObject); for(int i=0;i<toSet.size();i++) { Environmental E2=(Environmental)toSet.elementAt(i); runtimeRegisterEffect(E2,A3.ID(),CMParms.combineWithQuotes(p,3),false); } } else { 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(String script, Vector baseVars, boolean reTime) { DefaultQuest Q2=(DefaultQuest)CMClass.getCommon("DefaultQuest"); Q2.setCopy(true); Q2.setVars(baseVars,0); Q2.setScript(script); CMLib.quests().addQuest(Q2); if(reTime) { Long ellapsed=(Long)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; } 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() { if(running()) { stopQuestInternal(); resetData=null; } Vector args=new Vector(); questState=new QuestState(); Vector baseScript=parseLoadScripts(script(),new Vector(),args); if((!isCopy())&&(getSpawn()!=SPAWN_NO)) { if(getSpawn()==SPAWN_FIRST) spawnQuest(script(),baseScript,false); else if(getSpawn()==SPAWN_ANY) { Vector parsed=CMLib.quests().parseQuestSteps(baseScript,0,false); for(int p=0;p<parsed.size();p++) spawnQuest((String)parsed.elementAt(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(Throwable 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","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","Nothing parsed in '"+name()+"', quest not started."); else if(duration()<0) { Log.errOut("Quest","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()); } public void cleanQuestStep() { stoppingQuest=true; if(questState.stuff.size()>0) { synchronized(questState) { for(int i=0;i<questState.stuff.size();i++) { Integer I=(Integer)questState.stuff.elementAt(i,2); if(I.intValue()>0) { questState.stuff.setElementAt(i,2,Integer.valueOf(I.intValue()-1)); continue; } Environmental E=(Environmental)questState.stuff.elementAt(i,1); Ability A=E.fetchEffect("QuestBound"); if(A!=null)E.delEffect(A); questState.stuff.removeElementAt(i); if(E instanceof Item) { if((CMath.bset(E.baseEnvStats().disposition(),EnvStats.IS_UNSAVABLE)) &&(!((Item)E).amDestroyed())) ((Item)E).destroy(); } else if(E instanceof MOB) { MOB M=(MOB)E; ScriptingEngine B=(ScriptingEngine)((MOB)E).fetchBehavior("Scriptable"); if(B!=null) B.endQuest(E,M,name()); Room R=M.getStartRoom(); if((R==null)||(CMath.bset(E.baseEnvStats().disposition(),EnvStats.IS_UNSAVABLE))) { 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)))) { M.setFollowing(null); CMLib.tracking().wanderAway(M,false,true); } } i--; } } if(questState.addons.size()>0) { synchronized(questState) { if(stoppingQuest) for(int i=questState.addons.size()-1;i>=0;i--) { Integer I=(Integer)questState.addons.elementAt(i,2); if(I.intValue()>0) { questState.addons.setElementAt(i,2,Integer.valueOf(I.intValue()-1)); continue; } Vector V=(Vector)questState.addons.elementAt(i,1); questState.addons.removeElementAt(i); if(V.size()<2) continue; Environmental E=(Environmental)V.elementAt(0); Object O=V.elementAt(1); if(O instanceof String) { String stat=(String)O; String parms=(String)V.elementAt(2); if(CMStrings.contains(E.getStatCodes(),stat.toUpperCase().trim())) E.setStat(stat,parms); else if(CMStrings.contains(E.baseEnvStats().getStatCodes(),stat.toUpperCase().trim())) { E.baseEnvStats().setStat(stat.toUpperCase().trim(),parms); E.recoverEnvStats(); } else if((E instanceof MOB)&&(CMStrings.contains(CharStats.STAT_NAMES,stat.toUpperCase().trim()))) { ((MOB)E).baseCharStats().setStat(CMParms.indexOf(CharStats.STAT_NAMES,stat.toUpperCase().trim()),CMath.s_int(parms)); ((MOB)E).recoverCharStats(); } else if((E instanceof MOB)&&CMStrings.contains(((MOB)E).baseState().getStatCodes(),stat)) { ((MOB)E).baseState().setStat(stat,parms); ((MOB)E).recoverMaxState(); ((MOB)E).resetToMaxState(); } } else if(O instanceof Behavior) { Behavior B=E.fetchBehavior(((Behavior)O).ID()); if((E instanceof MOB)&&(B instanceof ScriptingEngine)) ((ScriptingEngine)B).endQuest(E,(MOB)E,name()); if((V.size()>2)&&(V.elementAt(2) instanceof String)) { if(B==null){ B=(Behavior)O; E.addBehavior(B);} B.setParms((String)V.elementAt(2)); } else if(B!=null) E.delBehavior(B); } else if(O instanceof ScriptingEngine) { ScriptingEngine S=(ScriptingEngine)O; if((E instanceof MOB)&&(!S.isSavable())) { S.endQuest(E,(MOB)E,name()); ((MOB)E).delScript(S); } } else if(O instanceof Ability) { if((V.size()>2) &&(V.elementAt(2) instanceof Ability) &&(E instanceof MOB)) { Ability A=((MOB)E).fetchAbility(((Ability)O).ID()); if((V.size()>3)&&(V.elementAt(3) instanceof String)) { if(A==null){A=(Ability)O; ((MOB)E).addAbility(A);} A.setMiscText((String)V.elementAt(3)); } else if(A!=null) ((MOB)E).delAbility(A); } else { Ability A=E.fetchEffect(((Ability)O).ID()); if((V.size()>2)&&(V.elementAt(2) instanceof String)) { if(A==null){A=(Ability)O; E.addEffect(A);} A.setMiscText((String)V.elementAt(2)); } else if(A!=null) { A.unInvoke(); E.delEffect(A); } } } else if(O instanceof Item) ((Item)O).destroy(); } } } } 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 public boolean stepQuest() { if((questState==null)||(stoppingQuest)) return false; cleanQuestStep(); ticksRemaining=-1; setDuration(-1); Vector args=new Vector(); Vector script=parseLoadScripts(script(),new Vector(),args); try{ setVars(script,questState.lastLine); parseQuestScript(script,args,questState.lastLine); }catch(Throwable t){ questState.error=true; Log.errOut("DefaultQuest",t); } if(questState.error) { if(!questState.beQuiet) Log.errOut("Quest","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","No duration, quest '"+name()+"' not started."); questState.error=true; } if((!questState.error)&&(questState.done)&&(duration()>=0)) { enterRunningState(); return true; } stopQuestInternal(); return false; } public void resetQuest(int firstPauseTicks) { if(stoppingQuest) return; // ticksRemaining of -1 is OK, it will grab duration resetData=new int[]{firstPauseTicks,ticksRemaining}; stopQuest(); } 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(int q=0;q<questState.stuff.size();q++) questState.stuff.setElementAt(q,2,Integer.valueOf(0)); for(int q=0;q<questState.addons.size();q++) questState.addons.setElementAt(q,2,Integer.valueOf(0)); } cleanQuestStep(); stoppingQuest=true; if(!isCopy()) setScript(script()); // causes wait times/name to reload enterDormantState(); stoppingQuest=false; } public boolean enterDormantState() { ticksRemaining=-1; if((isCopy())||(!resetWaitRemaining(0))) { CMLib.quests().delQuest(this); CMLib.threads().deleteTick(this,Tickable.TICKID_QUEST); return false; } return true; } public boolean resetWaitRemaining(long ellapsedTime) { if(resetData!=null) { waitRemaining=resetData[0]; resetData[0]*=2; return true; } if(((minWait()<0)||(maxWait<0)) &&(startDate().trim().length()==0)) return false; if(running()) return true; if(startDate().length()>0) { if(startDate().toUpperCase().startsWith("MUDDAY")) { String sd2=startDate().substring("MUDDAY".length()).trim(); int x=sd2.indexOf("-"); if(x<0) return false; int mudmonth=CMath.s_parseIntExpression(sd2.substring(0,x)); int mudday=CMath.s_parseIntExpression(sd2.substring(x+1)); TimeClock C=(TimeClock)CMClass.getCommon("DefaultTimeClock"); TimeClock NOW=CMLib.time().globalClock(); C.setMonth(mudmonth); C.setDayOfMonth(mudday); C.setTimeOfDay(0); if((mudmonth<NOW.getMonth()) ||((mudmonth==NOW.getMonth())&&(mudday<NOW.getDayOfMonth()))) C.setYear(NOW.getYear()+1); else C.setYear(NOW.getYear()); long distance=C.deriveMillisAfter(NOW); waitRemaining=(int)(distance/Tickable.TIME_TICK); } else { int x=startDate.indexOf("-"); if(x<0) return false; int month=CMath.s_parseIntExpression(startDate.substring(0,x)); int day=CMath.s_parseIntExpression(startDate.substring(x+1)); int year=Calendar.getInstance().get(Calendar.YEAR); long distance=CMLib.time().string2Millis(month+"/"+day+"/"+year+" 12:00 AM"); while(distance<System.currentTimeMillis()) distance=CMLib.time().string2Millis(month+"/"+day+"/"+(++year)+" 12:00 AM"); waitRemaining=(int)((distance-System.currentTimeMillis())/Tickable.TIME_TICK); } } else waitRemaining=(minWait+(CMLib.dice().roll(1,maxWait,0)))-(int)(ellapsedTime/Tickable.TIME_TICK); return true; } public int minWait(){return minWait;} public void setMinWait(int wait){minWait=wait;} public int waitInterval(){return maxWait;} public void setWaitInterval(int wait){maxWait=wait;} public int waitRemaining(){return waitRemaining;} public Quest getMainQuestObject() { Quest Q=this; if(isCopy()) { Quest Q2=null; for(int q=0;q<CMLib.quests().numQuests();q++) { Q2=CMLib.quests().fetchQuest(q); if((Q2!=null)&&(Q2.name().equals(name))&&(!isCopy())) { Q=Q2; break;} } } return Q; } // if the quest has a winner, this is him. public void declareWinner(String name) { if(name==null) return; name=name.trim(); if(name.length()==0) return; Quest Q=getMainQuestObject(); if(!Q.wasWinner(name)) { Q.getWinners().addElement(name); CMLib.database().DBUpdateQuest(Q); } } public String getWinnerStr() { Quest Q=getMainQuestObject(); StringBuffer list=new StringBuffer(""); Vector V=Q.getWinners(); for(int i=0;i<V.size();i++) list.append(((String)V.elementAt(i))+";"); return list.toString(); } public void setWinners(String list) { Quest Q=getMainQuestObject(); Vector V=Q.getWinners(); V.clear(); list=list.trim(); int x=list.indexOf(";"); while(x>0) { String s=list.substring(0,x).trim(); list=list.substring(x+1).trim(); if(s.length()>0) V.addElement(s); x=list.indexOf(";"); } if(list.trim().length()>0) V.addElement(list.trim()); } // retreive the list of previous winners public Vector getWinners() { Quest Q=getMainQuestObject(); if(Q==this) return winners; return Q.getWinners(); } // was a previous winner public boolean wasWinner(String name) { if(name==null) return false; name=name.trim(); if(name.length()==0) return false; Quest Q=getMainQuestObject(); Vector V=Q.getWinners(); for(int i=0;i<V.size();i++) { if(((String)V.elementAt(i)).equalsIgnoreCase(name)) return true; } return false; } // informational public boolean running(){return ticksRemaining>=0;} public boolean stopping(){return stoppingQuest;} public boolean waiting(){return waitRemaining>=0;} public int ticksRemaining(){return ticksRemaining;} public int minsRemaining(){return (int)(ticksRemaining*Tickable.TIME_TICK/60000);} private long tickStatus=Tickable.STATUS_NOT; public long getTickStatus(){return tickStatus;} public boolean tick(Tickable ticking, int tickID) { if(tickID!=Tickable.TICKID_QUEST) return false; if(CMSecurity.isDisabled("QUESTS") ||(CMProps.getBoolVar(CMProps.SYSTEMB_MUDSHUTTINGDOWN)) ||(!CMProps.getBoolVar(CMProps.SYSTEMB_MUDSTARTED)) ||(suspended)) return true; tickStatus=Tickable.STATUS_START; if(running()) { tickStatus=Tickable.STATUS_ALIVE; if(duration()>0) ticksRemaining--; if(ticksRemaining<0) { CMLib.coffeeTables().bump(this,CoffeeTableRow.STAT_QUESTTIMESTOP); stopQuest(); } tickStatus=Tickable.STATUS_END; } else { if(startQuestOnTime()) { CMLib.coffeeTables().bump(this,CoffeeTableRow.STAT_QUESTTIMESTART); } } tickStatus=Tickable.STATUS_NOT; return true; } protected boolean startQuestOnTime() { if((--waitRemaining)>=0) return false; boolean allowedToRun=true; if(runLevel()>=0) for(int q=0;q<CMLib.quests().numQuests();q++) { Quest Q=CMLib.quests().fetchQuest(q); if((!Q.name().equals(name)) &&(Q.running()) &&(Q.duration()!=0) &&(Q.runLevel()<=runLevel())) { allowedToRun=false; break;} } if(allowedToRun) { int numElligiblePlayers=CMLib.sessions().size(); if(playerMask.length()>0) { numElligiblePlayers=0; for(int s=CMLib.sessions().size()-1;s>=0;s--) { Session S=CMLib.sessions().elementAt(s); if((S.mob()!=null)&&(CMLib.masking().maskCheck(playerMask,S.mob(),true))) numElligiblePlayers++; } } ticksRemaining=-1; if((numElligiblePlayers>=minPlayers)||(duration()==0)) return startQuestInternal(); } enterDormantState(); return false; } public void runtimeRegisterAbility(MOB mob, String abilityID, String parms, boolean give) { if(mob==null) return; runtimeRegisterObject(mob); Vector V=new Vector(); V.addElement(mob); Ability A4=mob.fetchAbility(abilityID); if(A4!=null) { V.addElement(A4); V.addElement(A4); V.addElement(A4.text()); if(give) { A4.setMiscText(parms); A4.setProficiency(100); } else mob.delAbility(A4); } else if(!give) return; else { A4=CMClass.getAbility(abilityID); if(A4==null) return; A4.setMiscText(parms); V.addElement(A4); V.addElement(A4); A4.setProficiency(100); mob.addAbility(A4); } synchronized(questState) { questState.addons.addElement(V,Integer.valueOf(questState.preserveState)); } } public void runtimeRegisterObject(Environmental object) { synchronized(questState) { int x=questState.stuff.indexOf(object); if(x<0) { questState.stuff.addElement(object, Integer.valueOf(questState.preserveState)); Ability A=CMClass.getAbility("QuestBound"); A.setMiscText(""+this); object.addNonUninvokableEffect(A); } else { Integer I=(Integer)questState.stuff.elementAt(x,2); if(I.intValue()<questState.preserveState) questState.stuff.setElementAt(x,2, Integer.valueOf(questState.preserveState)); } } } public void runtimeRegisterEffect(Environmental affected, String abilityID, String parms, boolean give) { if(affected==null) return; runtimeRegisterObject(affected); Vector V=new Vector(); V.addElement(affected); Ability A4=affected.fetchEffect(abilityID); if(A4!=null) { V.addElement(A4); V.addElement(A4.text()); if(give) { A4.makeLongLasting(); A4.setMiscText(parms); } else affected.delEffect(A4); } else if(!give) return; else { A4=CMClass.getAbility(abilityID); if(A4==null) return; V.addElement(A4); A4.setMiscText(parms); if(affected instanceof MOB) A4.startTickDown((MOB)affected,affected,99999); else A4.startTickDown(null,affected,99999); A4.makeLongLasting(); } synchronized(questState) { questState.addons.addElement(V,Integer.valueOf(questState.preserveState)); } } public void runtimeRegisterBehavior(Environmental behaving, String behaviorID, String parms, boolean give) { if(behaving==null) return; runtimeRegisterObject(behaving); Vector V=new Vector(); V.addElement(behaving); Behavior B=behaving.fetchBehavior(behaviorID); if(B!=null) { V.addElement(B); V.addElement(B.getParms()); if(give) B.setParms(parms); else behaving.delBehavior(B); } else if(!give){ return; } else { B=CMClass.getBehavior(behaviorID); if(B==null) return; V.addElement(B); B.setParms(parms); behaving.addBehavior(B); } B.registerDefaultQuest(name()); synchronized(questState) { questState.addons.addElement(V,Integer.valueOf(questState.preserveState)); } } public void runtimeRegisterStat(Environmental E, String stat, String parms, boolean give) { if(E==null) return; runtimeRegisterObject(E); Vector V=new Vector(); V.addElement(E); stat=stat.toUpperCase().trim(); String oldVal=""; if(CMStrings.contains(E.getStatCodes(),stat)) oldVal=E.getStat(stat); else if(CMStrings.contains(E.baseEnvStats().getStatCodes(),stat)) oldVal=E.baseEnvStats().getStat(stat); else if((E instanceof MOB)&&(CMStrings.contains(CharStats.STAT_NAMES,stat))) oldVal=""+((MOB)E).baseCharStats().getStat(CMParms.indexOf(CharStats.STAT_NAMES,stat)); else if((E instanceof MOB)&&CMStrings.contains(((MOB)E).baseState().getStatCodes(),stat)) oldVal=((MOB)E).baseState().getStat(stat); V.addElement(stat); V.addElement(oldVal); if(!give) return; V.addElement(stat); V.addElement(oldVal); if(CMStrings.contains(E.getStatCodes(),stat)) E.setStat(stat,parms); else if(CMStrings.contains(E.baseEnvStats().getStatCodes(),stat)) { E.baseEnvStats().setStat(stat,parms); E.recoverEnvStats(); } else if((E instanceof MOB)&&(CMStrings.contains(CharStats.STAT_NAMES,stat))) { ((MOB)E).baseCharStats().setStat(CMParms.indexOf(CharStats.STAT_NAMES,stat),CMath.s_int(parms)); ((MOB)E).recoverCharStats(); } else if((E instanceof MOB)&&CMStrings.contains(((MOB)E).baseState().getStatCodes(),stat)) { ((MOB)E).baseState().setStat(stat,parms); ((MOB)E).recoverMaxState(); ((MOB)E).resetToMaxState(); } synchronized(questState) { questState.addons.addElement(V,Integer.valueOf(questState.preserveState)); } } public int getQuestThingIndex(Vector V, String name, int type, int[] num) { if(V==null) return -1; for(int i=0;i<V.size();i++) { Environmental E=(Environmental)V.elementAt(i); if(CMClass.isType(E,type)) { switch(type) { case CMClass.OBJECT_LOCALE: if(CMLib.map().getExtendedRoomID((Room)E).equalsIgnoreCase(name)) return num[0]; break; default: if(E.Name().equalsIgnoreCase(name)) return num[0]; break; } num[0]++; } } return -1; } public int getQuestMobIndex(String name) { int[] num={1}; int x=-1; synchronized(questState) { if(questState.stuff!=null) x=getQuestThingIndex(questState.stuff.getDimensionVector(1),name,CMClass.OBJECT_MOB,num); if(x<0) x=getQuestThingIndex(questState.mobGroup,name,CMClass.OBJECT_MOB,num); if((x<0)&&(questState.mysteryData!=null)) x=getQuestThingIndex(questState.mysteryData.agentGroup,name,CMClass.OBJECT_MOB,num); } return x; } public int getQuestRoomIndex(String roomID) { int[] num={1}; int x=-1; synchronized(questState) { if(questState.stuff!=null) x=getQuestThingIndex(questState.stuff.getDimensionVector(1),roomID,CMClass.OBJECT_LOCALE,num); if(x<0) x=getQuestThingIndex(questState.roomGroup,roomID,CMClass.OBJECT_LOCALE,num); if(questState.mysteryData!=null) { if(x<0) x=getQuestThingIndex(questState.mysteryData.whereAtGroup,roomID,CMClass.OBJECT_LOCALE,num); if(x<0) x=getQuestThingIndex(questState.mysteryData.whereHappenedGroup,roomID,CMClass.OBJECT_LOCALE,num); } } return x; } public int getQuestItemIndex(String name) { int[] num={1}; int x=-1; synchronized(questState) { if(questState.stuff!=null) x=getQuestThingIndex(questState.stuff.getDimensionVector(1),name,CMClass.OBJECT_ITEM,num); if(x<0) x=getQuestThingIndex(questState.itemGroup,name,CMClass.OBJECT_ITEM,num); if(questState.mysteryData!=null) { if(x<0) x=getQuestThingIndex(questState.mysteryData.toolGroup,name,CMClass.OBJECT_ITEM,num); } } return x; } public Environmental getQuestThing(Vector V, int dex, int type, int[] num) { if(V==null) return null; for(int i=0;i<V.size();i++) { Environmental E=(Environmental)V.elementAt(i); if(CMClass.isType(E,type)) { if(dex==num[0]) return E; num[0]++; } } return null; } public MOB getQuestMob(int i) { int[] num={1}; Environmental E=null; synchronized(questState) { if(questState.stuff!=null) E=getQuestThing(questState.stuff.getDimensionVector(1),i,CMClass.OBJECT_MOB,num); if(E instanceof MOB) return (MOB)E; E=getQuestThing(questState.mobGroup,i,CMClass.OBJECT_MOB,num); if(E instanceof MOB) return (MOB)E; if(questState.mysteryData!=null) E=getQuestThing(questState.mysteryData.agentGroup,i,CMClass.OBJECT_MOB,num); if(E instanceof MOB) return (MOB)E; } return null; } public Item getQuestItem(int i) { int[] num={1}; Environmental E=null; synchronized(questState) { if(questState.stuff!=null) E=getQuestThing(questState.stuff.getDimensionVector(1),i,CMClass.OBJECT_ITEM,num); if(E instanceof Item) return (Item)E; E=getQuestThing(questState.itemGroup,i,CMClass.OBJECT_ITEM,num); if(E instanceof Item) return (Item)E; if(questState.mysteryData!=null) E=getQuestThing(questState.mysteryData.toolGroup,i,CMClass.OBJECT_ITEM,num); if(E instanceof Item) return (Item)E; } return null; } public Room getQuestRoom(int i) { int[] num={1}; Environmental E=null; synchronized(questState) { if(questState.stuff!=null) E=getQuestThing(questState.stuff.getDimensionVector(1),i,CMClass.OBJECT_LOCALE,num); if(E instanceof Room) return (Room)E; E=getQuestThing(questState.roomGroup,i,CMClass.OBJECT_LOCALE,num); if(E instanceof Room) return (Room)E; if(questState.mysteryData!=null) E=getQuestThing(questState.mysteryData.whereAtGroup,i,CMClass.OBJECT_LOCALE,num); if(E instanceof Room) return (Room)E; if(questState.mysteryData!=null) E=getQuestThing(questState.mysteryData.whereHappenedGroup,i,CMClass.OBJECT_LOCALE,num); if(E instanceof Room) return (Room)E; } return null; } public String getQuestMobName(int i) { MOB M=getQuestMob(i); if(M!=null) return M.name(); return ""; } public String getQuestItemName(int i) { Item I=getQuestItem(i); if(I!=null) return I.name(); return ""; } public String getQuestRoomID(int i) { Room R=getQuestRoom(i); if(R!=null) return CMLib.map().getExtendedRoomID(R); return ""; } public int getObjectInUseIndex(String name) { synchronized(questState) { for(int i=0;i<questState.stuff.size();i++) { Environmental E=(Environmental)questState.stuff.elementAt(i,1); if(E.name().equalsIgnoreCase(name)) return (i+1); } } return -1; } public boolean isObjectInUse(Environmental E) { return ((questState.stuff!=null)&&(questState.stuff.contains(E))); } public Vector parseLoadScripts(String text, Vector oldArgs, Vector args) { if(text.trim().toUpperCase().startsWith("LOAD=")) { String filename=null; Vector V=CMParms.parse(text.trim().substring(5).trim()); if(V.size()>0) { filename=(String)V.firstElement(); Vector parms=null; try{ for(int v=1;v<V.size();v++) { parms=CMParms.parse((String)V.elementAt(v)); Object O=getObjectIfSpecified(parms,oldArgs,0,1); args.addElement((O==null)?"":O); } StringBuffer buf=getResourceFileData(filename); if(buf!=null) text=buf.toString(); }catch(CMException ex){ Log.errOut("DefaultQuest","'"+text+"' either has a space in the filename, or unknown parms."); } } } int x=text.toLowerCase().indexOf(XMLLibrary.FILE_XML_BOUNDARY.toLowerCase()); if(x>=0) { String xml=text.substring(x+XMLLibrary.FILE_XML_BOUNDARY.length()).trim(); text=text.substring(0,x); if((xml.length()>0)&&(internalFiles==null)) { Vector topXMLV=CMLib.xml().parseAllXML(xml); for(int t=0;t<topXMLV.size();t++) { XMLLibrary.XMLpiece filePiece=(XMLLibrary.XMLpiece)topXMLV.elementAt(t); String name=null; String data=null; if(filePiece.tag.equalsIgnoreCase("FILE")&&(filePiece.contents!=null)) for(int p=0;p<filePiece.contents.size();p++) { XMLLibrary.XMLpiece piece=(XMLLibrary.XMLpiece)filePiece.contents.elementAt(p); if(piece.tag.equalsIgnoreCase("NAME")) name=piece.value; if(piece.tag.equalsIgnoreCase("DATA")) data=piece.value; } if((name!=null)&&(data!=null)&&(name.trim().length()>0)&&(data.trim().length()>0)) { if(internalFiles==null) internalFiles=new DVector(2); internalFiles.addElement(name.toUpperCase().trim(),new StringBuffer(data)); } } } } Vector script=new Vector(); Vector V=script; while(text.length()>0) { int y=-1; int yy=0; while(yy<text.length()) if((text.charAt(yy)==';')&&((yy<=0)||(text.charAt(yy-1)!='\\'))) {y=yy;break;} else if(text.charAt(yy)=='\n'){y=yy;break;} else if(text.charAt(yy)=='\r'){y=yy;break;} else yy++; String cmd=""; if(y<0) { cmd=text.trim(); text=""; } else { cmd=text.substring(0,y).trim(); text=text.substring(y+1).trim(); } if((cmd.length()>0)&&(!cmd.startsWith("#"))) { if(cmd.toUpperCase().startsWith("<OPTION>")) { V=new Vector(); script.addElement(V); } else if(cmd.toUpperCase().startsWith("</OPTION>")) V=script; else V.addElement(CMStrings.replaceAll(cmd,"\\;",";").trim()); } } return script; } private static final String VALID_ASTR_CODES="_&|"; private String modifyStringFromArgs(String s, Vector args) { int x=s.toUpperCase().indexOf("$"); while((x>=0)&&(x<s.length()-1)) { int y=x+1; if((y<s.length())&&(VALID_ASTR_CODES.indexOf(s.charAt(y))>=0)) y++; while((y<s.length())&&(Character.isLetterOrDigit(s.charAt(y)))) y++; try{ String possObjName=(x+1>=y)?null:s.substring(x+1,y); if((possObjName!=null)&&(possObjName.length()>0)) { char firstCode=possObjName.charAt(0); if(VALID_ASTR_CODES.indexOf(firstCode)>=0) possObjName=possObjName.substring(1); Object O=getObjectIfSpecified(CMParms.paramParse(possObjName),args,0,0); String replace=(O==null)?"null":O.toString(); if(O instanceof Room) replace=((Room)O).roomTitle(null); else if(O instanceof Environmental) replace=((Environmental)O).Name(); else if(O instanceof TimeClock) replace=((TimeClock)O).getShortTimeDescription(); switch(firstCode){ case '_': replace=CMStrings.capitalizeAndLower(replace); break; case '&': replace=CMLib.english().cleanArticles(replace); break; case '|': replace=CMLib.english().cleanArticles(replace).trim().replace(' ','|'); break; } s=s.substring(0,x)+replace+s.substring(y); } }catch(CMException ex){} x=s.toUpperCase().indexOf("$",x+1); } return s; } private Object getObjectIfSpecified(Vector parms, Vector args, int startp, int object0vector1) throws CMException { if(parms.size()-startp==0) throw new CMException("Not specified"); StringBuffer allParms=new StringBuffer((String)parms.elementAt(startp)); for(int p=startp+1;p<parms.size();p++) allParms.append((String)parms.elementAt(p)); Object O=null; Vector V=new Vector(); int lastI=0; String eval=null; char code=' '; for(int i=0;i<=allParms.length();i++) { eval=null; if((i==allParms.length()) ||((i<allParms.length())&&((allParms.charAt(i)=='+')||(allParms.charAt(i)=='-')||(allParms.charAt(i)=='#')))) { eval=allParms.substring(lastI,i).trim().toUpperCase(); lastI=i+1; } if(eval!=null) { if(eval.startsWith("ARG")&&CMath.isMathExpression(eval.substring(3))) { int num=CMath.parseIntExpression(eval.substring(3)); if((num<=0)||(num>args.size())) throw new CMException ("Not specified: "+eval); O=args.elementAt(num-1); } else { if(!questState.isStat(eval)) throw new CMException ("Not specified: "+eval); O=questState.getStat(eval); } switch(code) { case '#': { int index=0; if(CMath.isMathExpression(eval)) index=CMath.parseIntExpression(eval); if((index>=0)&&(index<V.size())) { O=V.elementAt(index); V.clear(); V.addElement(O); } break; } case '-': if(O instanceof Vector) CMParms.delFromVector((Vector)O,V); else if(O!=null) V.removeElement(O); break; case '+': case ' ': if(O instanceof Vector) CMParms.addToVector((Vector)O,V); else if(O!=null) V.addElement(O); break; } if(i<allParms.length()) code=allParms.charAt(i); } } switch(object0vector1) { case 0: if(V.size()==0) return null; return V.elementAt(CMLib.dice().roll(1,V.size(),-1)); case 1: if(V.size()==0) return null; return V; } return null; } public static class QuestState implements Cloneable { public MysteryData mysteryData=new MysteryData(); public Vector loadedMobs=new Vector(); public Vector loadedItems=new Vector(); public Area area=null; public Room room=null; public MOB mob=null; public Vector mobGroup=null; public Vector reselectable=new Vector(); public Vector itemGroup=null; public Vector roomGroup=null; public Item item=null; public Object envObject=null; public boolean error=false; public boolean done=false; public boolean beQuiet=false; protected int preserveState=0; protected int lastLine=0; protected int startLine; // key 1=vector, below. key 2=preserveState public DVector stuff=new DVector(2); // contains a set of vectors, vectors are formatted as such: // key 1=vector, below. key 2=preserveState // 0=environmental item/mob/etc // 1=Ability, 2=Ability (for an ability added) // 1=Ability, 2=Ability, 3=String (for an ability modified) // 1=Effect(for an Effect added) // 1=Effect, 2=String (for an Effect modified) // 1=Behavior (for an Behavior added) // 1=Behavior, 2=String (for an Behavior modified) protected DVector addons=new DVector(2); public DVector vars=new DVector(2); public boolean isStat(String statName) { int x=statName.indexOf("#"); if(x>=0) statName=statName.substring(0,x); for(int i=0;i<QOBJS.length;i++) if(statName.equalsIgnoreCase(QOBJS[i])) return true; if(mysteryData!=null) return mysteryData.isStat(statName); return false; } public Object getStat(String statName) { int x=statName.indexOf("#"); String whichStr=null; int whichNum=-1; if(x>=0){ whichStr=statName.substring(x+1); if(whichStr.length()>0) whichNum=CMath.s_parseIntExpression(whichStr); statName=statName.substring(0,x); } Object O=null; int code=-1; for(int i=0;i<QOBJS.length;i++) if(statName.equalsIgnoreCase(QOBJS[i])) { code=i; break;} switch(code) { case 0: O=loadedMobs; break; case 1: O=loadedItems; break; case 2: O=area; break; case 3: O=room; break; case 4: O=mobGroup; break; case 5: O=itemGroup; break; case 6: O=roomGroup; break; case 7: O=item; break; case 8: O=envObject; break; case 9: O=stuff; break; case 10: O=mob; break; default: if(mysteryData!=null) O=mysteryData.getStat(statName); break; } if(O instanceof Vector) { Vector V=(Vector)O; if((whichStr!=null)&&((whichNum<=0)||(whichNum>V.size()))) return ""+V.size(); if(whichStr!=null) return V.elementAt(whichNum-1); } return O; } } public static class MysteryData implements Cloneable { public Vector factionGroup; public Faction faction; public MOB agent; public Vector agentGroup; public Environmental target; public Vector targetGroup; public Environmental tool; public Vector toolGroup; public Room whereHappened; public Vector whereHappenedGroup; public Room whereAt; public Vector whereAtGroup; public String action; public Vector actionGroup; public String motive; public Vector motiveGroup; public TimeClock whenHappened; public Vector whenHappenedGroup; public TimeClock whenAt; public Vector whenAtGroup; public boolean isStat(String statName) { for(int i=0;i<MYSTERY_QCODES.length;i++) if(statName.equalsIgnoreCase(MYSTERY_QCODES[i])) return true; return false; } public Object getStat(String statName) { int code=-1; for(int i=0;i<MYSTERY_QCODES.length;i++) if(statName.equalsIgnoreCase(MYSTERY_QCODES[i])) { code=i; break;} switch(code){ case 0: return faction; case 1: return factionGroup; case 2: return agent; case 3: return agentGroup; case 4: return action; case 5: return actionGroup; case 6: return target; case 7: return targetGroup; case 8: return motive; case 9: return motiveGroup; case 10: return whereHappened; case 11: return whereHappenedGroup; case 12: return whereAt; case 13: return whereAtGroup; case 14: return whenHappened; case 15: return whenHappenedGroup; case 16: return whenAt; case 17: return whenAtGroup; case 18: return tool; case 19: return toolGroup; } return null; } } public String[] getStatCodes() { String[] CCODES=new String[QCODES.length+MYSTERY_QCODES.length]; for(int i=0;i<QCODES.length;i++) CCODES[i]=QCODES[i]; for(int i=0;i<MYSTERY_QCODES.length;i++) CCODES[QCODES.length+i]=MYSTERY_QCODES[i]; return QCODES; } public int getSaveStatIndex(){return getStatCodes().length;} protected int getCodeNum(String code) { String[] CCODES=getStatCodes(); for(int i=0;i<CCODES.length;i++) if(code.equalsIgnoreCase(CCODES[i])) return i; return -1; } public boolean sameAs(DefaultQuest E) { String[] CCODES=getStatCodes(); for(int i=0;i<CCODES.length;i++) if(!E.getStat(CCODES[i]).equals(getStat(CCODES[i]))) return false; return true; } public void setStat(String code, String val) { switch(getCodeNum(code)){ case 0: break; case 1: setName(val); break; case 2: setDuration(CMLib.time().parseTickExpression(val)); break; case 3: setMinWait(CMLib.time().parseTickExpression(val)); break; case 4: setMinPlayers(CMath.s_parseIntExpression(val)); break; case 5: setPlayerMask(val); break; case 6: setRunLevel(CMath.s_parseIntExpression(val)); break; case 7: setStartDate(val); break; case 8: setStartMudDate(val); break; case 9: setWaitInterval(CMLib.time().parseTickExpression(val)); break; case 10: setSpawn(CMParms.indexOf(SPAWN_DESCS,val.toUpperCase().trim())); break; case 11: setDisplayName(val); break; case 13: durable=CMath.s_bool(val); break; case 14: author=val; break; case 12: // instructions can and should fall through the default default: if((code.toUpperCase().trim().equalsIgnoreCase("REMAINING"))&&(running())) ticksRemaining=CMLib.time().parseTickExpression(val); else { int x=questState.vars.indexOf(code.toUpperCase().trim()); if(x>=0) questState.vars.setElementAt(x,2,val); else questState.vars.addElement(code.toUpperCase().trim(),val); } break; } } public boolean isStat(String code) { if((getCodeNum(code)>=0) ||(questState.vars.contains(code))) return true; return false; } public String getStat(String code) { switch(getCodeNum(code)){ case 0: return ""+ID(); case 1: return ""+name(); case 2: return ""+duration(); case 3: return ""+minWait(); case 4: return ""+minPlayers(); case 5: return ""+playerMask(); case 6: return ""+runLevel(); case 7: return ""+startDate(); case 8: return ""+startDate(); case 9: return ""+waitInterval(); case 10: return SPAWN_DESCS[getSpawn()]; case 11: return displayName(); case 13: return Boolean.toString(durable); case 14: return author(); case 12: // instructions can and should fall through the default default: { code=code.toUpperCase().trim(); if((code.equalsIgnoreCase("REMAINING"))&&(running())) return ""+ticksRemaining; int x=questState.vars.indexOf(code); if(x>=0) return (String)questState.vars.elementAt(x,2); if(questState.isStat(code)) { Object O=questState.getStat(code); if(O instanceof Room) return ((Room)O).roomTitle(null); if(O instanceof TimeClock) return ((TimeClock)O).getShortTimeDescription(); if(O instanceof Environmental) return ((Environmental)O).Name(); if(O instanceof Vector) return ""+((Vector)O).size(); if(O!=null) return O.toString(); } else if(code.endsWith("_ROOMID")&&(questState.isStat(code.substring(0,code.length()-7)))) { code=code.substring(0,code.length()-7); Object O=questState.getStat(code); if(O instanceof Vector){ if(((Vector)O).size()>0) O=((Vector)O).elementAt(CMLib.dice().roll(1,((Vector)O).size(),-1)); } if(O instanceof Environmental) { Room R=CMLib.map().roomLocation((Environmental)O); if(R!=null) return CMLib.map().getExtendedRoomID(R); } } else if(code.endsWith("_CLASS")&&(questState.isStat(code.substring(0,code.length()-6)))) { code=code.substring(0,code.length()-6); Object O=questState.getStat(code); if(O instanceof Vector){ if(((Vector)O).size()>0) O=((Vector)O).elementAt(CMLib.dice().roll(1,((Vector)O).size(),-1)); } if(O instanceof CMObject) return ((CMObject)O).ID(); else if(O!=null) return O.getClass().getName(); } return ""; } } } public int compareTo(CMObject o) { return CMClass.classID(this).compareToIgnoreCase(CMClass.classID(o)); } protected static class JScriptQuest extends ScriptableObject { public String getClassName(){ return "JScriptQuest";} static final long serialVersionUID=44; Quest quest=null; QuestState state=null; public Quest quest(){return quest;} public QuestState setupState(){return state;} public JScriptQuest(Quest Q, QuestState S){quest=Q; state=S;} public static String[] functions = { "quest", "setupState", "toJavaString"}; public String toJavaString(Object O){return Context.toString(O);} } }