package com.planet_ink.coffee_mud.MOBS; import com.planet_ink.coffee_mud.core.interfaces.*; import com.planet_ink.coffee_mud.core.*; import com.planet_ink.coffee_mud.Abilities.interfaces.*; import com.planet_ink.coffee_mud.Areas.interfaces.*; import com.planet_ink.coffee_mud.Behaviors.interfaces.*; import com.planet_ink.coffee_mud.CharClasses.interfaces.*; import com.planet_ink.coffee_mud.Commands.interfaces.*; import com.planet_ink.coffee_mud.Common.interfaces.*; import com.planet_ink.coffee_mud.Exits.interfaces.*; import com.planet_ink.coffee_mud.Items.interfaces.*; import com.planet_ink.coffee_mud.Locales.interfaces.*; import com.planet_ink.coffee_mud.MOBS.interfaces.*; import com.planet_ink.coffee_mud.Races.interfaces.*; import java.util.*; import com.planet_ink.coffee_mud.Libraries.interfaces.*; /* Copyright 2000-2006 Bo Zimmerman Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, e\ither express or implied. See the License for the specific language governing permissions and limitations under the License. */ public class StdMOB implements MOB { private static final Vector empty=new Vector(); public String ID(){return "StdMOB";} public String Username=""; protected String clanID=null; protected int clanRole=0; protected CharStats baseCharStats=(CharStats)CMClass.getCommon("DefaultCharStats"); protected CharStats charStats=(CharStats)CMClass.getCommon("DefaultCharStats"); protected EnvStats envStats=(EnvStats)CMClass.getCommon("DefaultEnvStats"); protected EnvStats baseEnvStats=(EnvStats)CMClass.getCommon("DefaultEnvStats"); protected PlayerStats playerStats=null; protected boolean amDead=false; protected Room location=null; protected Room lastLocation=null; protected Rideable riding=null; protected Session mySession=null; protected boolean pleaseDestroy=false; protected byte[] description=null; protected String displayText=""; protected String imageName=null; protected byte[] miscText=null; protected long tickStatus=Tickable.STATUS_NOT; /* containers of items and attributes*/ protected Vector inventory=new Vector(); protected DVector followers=null; protected Vector abilities=new Vector(); protected Vector affects=new Vector(); protected Vector behaviors=new Vector(); protected Vector tattoos=new Vector(); protected Vector expertises=new Vector(); protected Hashtable factions=new Hashtable(); protected DVector commandQue=new DVector(5); // gained attributes protected int Experience=0; protected int Practices=0; protected int Trains=0; protected long AgeHours=0; protected int Money=0; protected int attributesBitmap=MOB.ATT_NOTEACH; protected int tickCounter=0; private long expirationDate=0; private int manaConsumeCounter=CMLib.dice().roll(1,10,0); private double freeActions=0.0; // the core state values public CharState curState=(CharState)CMClass.getCommon("DefaultCharState"); public CharState maxState=(CharState)CMClass.getCommon("DefaultCharState"); public CharState baseState=(CharState)CMClass.getCommon("DefaultCharState"); private long lastTickedDateTime=0; private long lastCommandTime=System.currentTimeMillis(); public long lastTickedDateTime(){return lastTickedDateTime;} public void flagVariableEq(){lastTickedDateTime=-2;} protected Room startRoomPossibly=null; protected int Alignment=0; protected String WorshipCharID=""; protected String LiegeID=""; protected int WimpHitPoint=0; protected int QuestPoint=0; protected int DeityIndex=-1; protected MOB victim=null; protected MOB amFollowing=null; protected MOB soulMate=null; protected int atRange=-1; protected long peaceTime=0; protected boolean amDestroyed=false; protected boolean kickFlag=false; protected boolean imMobile=false; public long getAgeHours(){return AgeHours;} public int getPractices(){return Practices;} public int getExperience(){return Experience;} public int getExpNextLevel(){return CMLib.leveler().getLevelExperience(baseEnvStats().level());} public int getExpPrevLevel() { if(baseEnvStats().level()<=1) return 0; int neededLowest=CMLib.leveler().getLevelExperience(baseEnvStats().level()-2); return neededLowest; } public int getExpNeededDelevel() { if(baseEnvStats().level()<=1) return 0; if((CMSecurity.isDisabled("EXPERIENCE")) ||(charStats().getCurrentClass().expless()) ||(charStats().getMyRace().expless())) return 0; int ExpPrevLevel=getExpPrevLevel(); if(ExpPrevLevel>getExperience()) ExpPrevLevel=getExperience()-1000; return getExperience()-ExpPrevLevel; } public int getExpNeededLevel() { if(!isMonster()) { if((CMProps.getIntVar(CMProps.SYSTEMI_LASTPLAYERLEVEL)>0) &&(CMProps.getIntVar(CMProps.SYSTEMI_LASTPLAYERLEVEL)<=baseEnvStats().level())) return Integer.MAX_VALUE; } if((CMSecurity.isDisabled("EXPERIENCE")) ||(charStats().getCurrentClass().expless()) ||(charStats().getMyRace().expless())) return Integer.MAX_VALUE; int ExpNextLevel=getExpNextLevel(); if(ExpNextLevel<getExperience()) ExpNextLevel=getExperience()+1000; return ExpNextLevel-getExperience(); } public int getTrains(){return Trains;} public int getMoney(){return Money;} public int getBitmap(){return attributesBitmap;} public void setAgeHours(long newVal){ AgeHours=newVal;} public void setExperience(int newVal){ Experience=newVal; } public void setExpNextLevel(int newVal){} public void setPractices(int newVal){ Practices=newVal;} public void setTrains(int newVal){ Trains=newVal;} public void setMoney(int newVal){ Money=newVal;} public void setBitmap(int newVal){ attributesBitmap=newVal;} public String getFactionListing() { StringBuffer msg=new StringBuffer(); for(Enumeration e=fetchFactions();e.hasMoreElements();) { Faction F=CMLib.factions().getFaction((String)e.nextElement()); msg.append(F.name()+"("+fetchFaction(F.factionID())+");"); } return msg.toString(); } public String getLiegeID(){return LiegeID;} public String getWorshipCharID(){return WorshipCharID;} public int getWimpHitPoint(){return WimpHitPoint;} public int getQuestPoint(){return QuestPoint;} public void setLiegeID(String newVal){LiegeID=newVal;} public void setWorshipCharID(String newVal){ WorshipCharID=newVal;} public void setWimpHitPoint(int newVal){ WimpHitPoint=newVal;} public void setQuestPoint(int newVal){ QuestPoint=newVal;} public Deity getMyDeity() { if(getWorshipCharID().length()==0) return null; Deity bob=CMLib.map().getDeity(getWorshipCharID()); if(bob==null) setWorshipCharID(""); return bob; } public void initializeClass(){} public CMObject newInstance() { try { return (Environmental)this.getClass().newInstance(); } catch(Exception e) { Log.errOut(ID(),e); } return new StdMOB(); } public Room getStartRoom(){ return CMLib.map().getRoom(startRoomPossibly); } public void setStartRoom(Room room){ startRoomPossibly=room; } public long peaceTime(){return peaceTime;} public String Name() { return Username; } public void setName(String newName){Username=newName;} public String name() { if(envStats().newName()!=null) return envStats().newName(); return Username; } public String titledName() { if((playerStats==null)||(playerStats.getTitles().size()==0)) return name(); return CMStrings.replaceAll(playerStats.getActiveTitle(),"*",Name()); } public String genericName() { if(charStats().getStat(CharStats.STAT_AGE)>0) return charStats().ageName().toLowerCase()+" "+charStats().raceName().toLowerCase(); return charStats().raceName().toLowerCase(); } public String image() { if(imageName==null) imageName=CMProps.getDefaultMXPImage(this); if(!baseCharStats().getMyRace().name().equalsIgnoreCase(charStats().raceName())) return CMProps.getDefaultMXPImage(this); if(imageName==null) return ""; return imageName; } public String rawImage() { if(imageName==null) return ""; return imageName; } public void setImage(String newImage) { if((newImage==null)||(newImage.trim().length()==0)) imageName=null; else imageName=newImage; } public StdMOB() { super(); CMClass.bumpCounter(this,CMClass.OBJECT_MOB); baseCharStats().setMyRace(CMClass.getRace("Human")); baseEnvStats().setLevel(1); } public long expirationDate(){return expirationDate;} public void setExpirationDate(long time){expirationDate=time;} protected void finalize(){CMClass.unbumpCounter(this,CMClass.OBJECT_MOB);} public boolean amDestroyed(){return amDestroyed;} protected void cloneFix(MOB E) { affects=new Vector(); baseEnvStats=(EnvStats)E.baseEnvStats().copyOf(); envStats=(EnvStats)E.envStats().copyOf(); baseCharStats=(CharStats)E.baseCharStats().copyOf(); charStats=(CharStats)E.charStats().copyOf(); baseState=(CharState)E.baseState().copyOf(); curState=(CharState)E.curState().copyOf(); maxState=(CharState)E.maxState().copyOf(); pleaseDestroy=false; inventory=new Vector(); followers=null; abilities=new Vector(); affects=new Vector(); behaviors=new Vector(); Item I2=null; Item I=null; for(int i=0;i<E.inventorySize();i++) { I2=E.fetchInventory(i); if(I2!=null) { I=(Item)I2.copyOf(); I.setOwner(this); inventory.addElement(I); } } for(int i=0;i<inventorySize();i++) { I2=fetchInventory(i); if((I2!=null) &&(I2.container()!=null) &&(!isMine(I2.container()))) for(int ii=0;ii<E.inventorySize();ii++) if((E.fetchInventory(ii)==I2.container())&&(ii<inventorySize())) { I2.setContainer(fetchInventory(ii)); break;} } Ability A=null; for(int i=0;i<E.numLearnedAbilities();i++) { A=E.fetchAbility(i); if(A!=null) abilities.addElement(A.copyOf()); } for(int i=0;i<E.numEffects();i++) { A=E.fetchEffect(i); if((A!=null)&&(!A.canBeUninvoked())) addEffect((Ability)A.copyOf()); } for(int i=0;i<E.numBehaviors();i++) { Behavior B=E.fetchBehavior(i); if(B!=null) behaviors.addElement(B.copyOf()); } } public CMObject copyOf() { try { StdMOB E=(StdMOB)this.clone(); CMClass.bumpCounter(E,CMClass.OBJECT_MOB); E.cloneFix(this); return E; } catch(CloneNotSupportedException e) { return this.newInstance(); } } public boolean isGeneric(){return false;} public EnvStats envStats() { return envStats; } public EnvStats baseEnvStats() { return baseEnvStats; } public void recoverEnvStats() { baseEnvStats.copyInto(envStats); if(location()!=null) location().affectEnvStats(this,envStats); envStats().setWeight(envStats().weight()+(int)Math.round(CMath.div(getMoney(),100.0))); if(riding()!=null) riding().affectEnvStats(this,envStats); if(getMyDeity()!=null) getMyDeity().affectEnvStats(this,envStats); int num=0; if(charStats!=null) { num=charStats().numClasses(); for(int c=0;c<num;c++) charStats().getMyClass(c).affectEnvStats(this,envStats); charStats().getMyRace().affectEnvStats(this,envStats); } Item item=null; num=inventorySize(); for(int i=0;i<num;i++) { item=fetchInventory(i); if(item!=null) { item.recoverEnvStats(); item.affectEnvStats(this,envStats); } } Ability effect=null; num=numAllEffects(); for(int a=0;a<num;a++) { effect=fetchEffect(a); if(effect!=null) effect.affectEnvStats(this,envStats); } /* the follower light exception*/ if(!CMLib.flags().isLightSource(this)) { num=numFollowers(); for(int f=0;f<num;f++) if(CMLib.flags().isLightSource(fetchFollower(f))) envStats.setDisposition(envStats().disposition()|EnvStats.IS_LIGHTSOURCE); } } public void setBaseEnvStats(EnvStats newBaseEnvStats) { baseEnvStats=(EnvStats)newBaseEnvStats.copyOf(); } public int baseWeight() { if(charStats().getMyRace()==baseCharStats().getMyRace()) return baseEnvStats().weight(); return charStats().getMyRace().lightestWeight()+charStats().getMyRace().weightVariance(); } public int maxCarry() { if(CMSecurity.isAllowed(this,location(),"CARRYALL")) return Integer.MAX_VALUE/2; double str=new Integer(charStats().getStat(CharStats.STAT_STRENGTH)).doubleValue(); double bodyWeight=new Integer(baseWeight()).doubleValue(); return (int)Math.round(bodyWeight + ((str+10.0)*str*bodyWeight/150.0) + (str*5.0)); } public int maxItems() { if(CMSecurity.isAllowed(this,location(),"CARRYALL")) return Integer.MAX_VALUE/2; return (2*Item.WORN_ORDER.length) +(2*charStats().getStat(CharStats.STAT_DEXTERITY)) +(2*envStats().level()); } public int maxFollowers() { return ((int)Math.round(CMath.div(charStats().getStat(CharStats.STAT_CHARISMA),4.0))+1); } public int totalFollowers() { int total=numFollowers(); try{ for(int i=0;i<total;i++) total+=fetchFollower(i).totalFollowers(); }catch(Throwable t){} return total; } public CharStats baseCharStats(){return baseCharStats;} public CharStats charStats(){return charStats;} public void recoverCharStats() { baseCharStats.setClassLevel(baseCharStats.getCurrentClass(),baseEnvStats().level()-baseCharStats().combinedSubLevels()); baseCharStats().copyInto(charStats); if(riding()!=null) riding().affectCharStats(this,charStats); if(getMyDeity()!=null) getMyDeity().affectCharStats(this,charStats); Ability effect=null; int num=numAllEffects(); for(int a=0;a<num;a++) { effect=fetchEffect(a); if(effect!=null) effect.affectCharStats(this,charStats); } Item item=null; num=inventorySize(); for(int i=0;i<num;i++) { item=fetchInventory(i); if(item!=null) item.affectCharStats(this,charStats); } if(location()!=null) location().affectCharStats(this,charStats); num=charStats.numClasses(); for(int c=0;c<num;c++) charStats.getMyClass(c).affectCharStats(this,charStats); charStats.getMyRace().affectCharStats(this,charStats); baseCharStats.getMyRace().agingAffects(this,baseCharStats,charStats); if((playerStats!=null)&&(soulMate==null)&&(playerStats.getHygiene()>=PlayerStats.HYGIENE_DELIMIT)) { int chaAdjust=(int)(playerStats.getHygiene()/PlayerStats.HYGIENE_DELIMIT); if((charStats.getStat(CharStats.STAT_CHARISMA)/2)>chaAdjust) charStats.setStat(CharStats.STAT_CHARISMA,charStats.getStat(CharStats.STAT_CHARISMA)-chaAdjust); else charStats.setStat(CharStats.STAT_CHARISMA,charStats.getStat(CharStats.STAT_CHARISMA)/2); } } public void setBaseCharStats(CharStats newBaseCharStats) { baseCharStats=(CharStats)newBaseCharStats.copyOf(); } public void affectEnvStats(Environmental affected, EnvStats affectableStats) { if(affected instanceof Room) { if(CMLib.flags().isLightSource(this)) { if(CMLib.flags().isInDark(affected)) affectableStats.setDisposition(affectableStats.disposition()-EnvStats.IS_DARK); affectableStats.setDisposition(affectableStats.disposition()|EnvStats.IS_LIGHTSOURCE); } } } public void affectCharState(MOB affectedMob, CharState affectableMaxState) {} public boolean isMarriedToLiege() { if(getLiegeID().length()==0) return false; if(getLiegeID().equals(Name())) return false; MOB M=CMLib.map().getLoadPlayer(getLiegeID()); if(M==null){ setLiegeID(""); return false;} if(M.getLiegeID().equals(Name())) return true; return false; } public CharState curState(){return curState;} public CharState maxState(){return maxState;} public CharState baseState(){return baseState;} public PlayerStats playerStats() { if((playerStats==null)&&(soulMate!=null)) return soulMate.playerStats(); return playerStats; } public void setPlayerStats(PlayerStats newStats) { playerStats=newStats; } public void setBaseState(CharState newState) { baseState=(CharState)newState.copyOf(); maxState=(CharState)newState.copyOf(); } public void resetToMaxState() { recoverMaxState(); maxState.copyInto(curState); } public void recoverMaxState() { baseState.copyInto(maxState); if(charStats.getMyRace()!=null) charStats.getMyRace().affectCharState(this,maxState); if(riding()!=null) riding().affectCharState(this,maxState); int num=charStats.numClasses(); for(int c=0;c<num;c++) charStats.getMyClass(c).affectCharState(this,maxState); Ability effect=null; num=numAllEffects(); for(int a=0;a<num;a++) { effect=fetchEffect(a); if(effect!=null) effect.affectCharState(this,maxState); } Item item=null; num=inventorySize(); for(int i=0;i<num;i++) { item=fetchInventory(i); if(item!=null) item.affectCharState(this,maxState); } if(location()!=null) location().affectCharState(this,maxState); } public boolean amDead() { return amDead||pleaseDestroy; } public boolean amActive() { return !pleaseDestroy; } public void dispossess(boolean giveMsg) { MOB mate=soulMate(); if(mate==null) return; if(mate.soulMate()!=null) mate.dispossess(giveMsg); Session s=session(); if(s!=null) { s.setMob(mate); mate.setSession(s); setSession(null); if(giveMsg) { mate.tell("^HYour spirit has returned to your body...\n\r\n\r^N"); CMLib.commands().postLook(mate,true); } setSoulMate(null); } } public void destroy() { if((CMSecurity.isDebugging("MISSINGKIDS"))&&(fetchEffect("Age")!=null)&&CMath.isInteger(fetchEffect("Age").text())&&(CMath.s_long(fetchEffect("Age").text())>Short.MAX_VALUE)) Log.debugOut("MISSKIDS",new Exception(Name()+" went missing form "+CMLib.map().getExtendedRoomID(CMLib.map().roomLocation(this)))); if(soulMate()!=null) dispossess(false); MOB possessor=CMLib.utensils().getMobPossessingAnother(this); if(possessor!=null) possessor.dispossess(false); if(session()!=null){ session().setKillFlag(true); try{Thread.sleep(1000);}catch(Exception e){}} removeFromGame(session()!=null); while(numBehaviors()>0) delBehavior(fetchBehavior(0)); while(numEffects()>0) delEffect(fetchEffect(0)); while(numLearnedAbilities()>0) delAbility(fetchAbility(0)); while(inventorySize()>0) { Item I=fetchInventory(0); I.destroy(); delInventory(I); } if(kickFlag) CMLib.threads().deleteTick(this,-1); kickFlag=false; clanID=null; charStats=baseCharStats; envStats=baseEnvStats; playerStats=null; location=null; lastLocation=null; riding=null; mySession=null; imageName=null; inventory=new Vector(); followers=null; abilities=new Vector(); affects=new Vector(); behaviors=new Vector(); tattoos=new Vector(); expertises=new Vector(); factions=new Hashtable(); commandQue=new DVector(5); curState=maxState; WorshipCharID=""; LiegeID=""; victim=null; amFollowing=null; soulMate=null; startRoomPossibly=null; amDestroyed=true; } public void removeFromGame(boolean preserveFollowers) { pleaseDestroy=true; if((location!=null)&&(location.isInhabitant(this))) { location().delInhabitant(this); if((mySession!=null)&&(!CMProps.getBoolVar(CMProps.SYSTEMB_MUDSHUTTINGDOWN))) location().show(this,null,CMMsg.MSG_OK_ACTION,"<S-NAME> vanish(es) in a puff of smoke."); } setFollowing(null); DVector oldFollowers=new DVector(2); while(numFollowers()>0) { MOB follower=fetchFollower(0); if(follower!=null) { if((follower.isMonster())&&(!follower.isPossessing())) oldFollowers.addElement(follower,new Integer(fetchFollowerOrder(follower))); follower.setFollowing(null); delFollower(follower); } } if(preserveFollowers) { for(int f=0;f<oldFollowers.size();f++) { MOB follower=(MOB)oldFollowers.elementAt(f,1); if(follower.location()!=null) { MOB newFol=(MOB)follower.copyOf(); newFol.baseEnvStats().setRejuv(0); newFol.text(); follower.killMeDead(false); addFollower(newFol, ((Integer)oldFollowers.elementAt(f,2)).intValue()); } } if(session()!=null) session().setKillFlag(true); } setRiding(null); } public String getClanID(){return ((clanID==null)?"":clanID);} public void setClanID(String clan){clanID=clan;} public int getClanRole(){return clanRole;} public void setClanRole(int role){clanRole=role;} public void bringToLife() { amDead=false; pleaseDestroy=false; // will ensure no duplicate ticks, this obj, this id kickFlag=true; CMLib.threads().startTickDown(this,Tickable.TICKID_MOB,1); if(tickStatus==Tickable.STATUS_NOT) { try{ imMobile=true; tick(this,Tickable.TICKID_MOB); // slap on the butt }finally{ imMobile=false;} } } public void bringToLife(Room newLocation, boolean resetStats) { amDead=false; if((miscText!=null)&&(resetStats)&&(isGeneric())) { if(CMProps.getBoolVar(CMProps.SYSTEMB_MOBCOMPRESS)) CMLib.coffeeMaker().resetGenMOB(this,CMLib.coffeeMaker().getGenMOBTextUnpacked(this,CMLib.encoder().decompressString(miscText))); else CMLib.coffeeMaker().resetGenMOB(this,CMLib.coffeeMaker().getGenMOBTextUnpacked(this,CMStrings.bytesToStr(miscText))); } if(CMLib.map().getStartRoom(this)==null) setStartRoom(isMonster()?newLocation:CMLib.map().getDefaultStartRoom(this)); setLocation(newLocation); if(location()==null) { setLocation(CMLib.map().getStartRoom(this)); if(location()==null) { Log.errOut("StdMOB",Username+" cannot get a location."); return; } } if(!location().isInhabitant(this)) location().addInhabitant(this); pleaseDestroy=false; // will ensure no duplicate ticks, this obj, this id kickFlag=true; CMLib.threads().startTickDown(this,Tickable.TICKID_MOB,1); Ability A=null; for(int a=0;a<numLearnedAbilities();a++) { A=fetchAbility(a); if(A!=null) A.autoInvocation(this); } if(location()==null) { Log.errOut("StdMOB",name()+" of "+CMLib.map().getExtendedRoomID(newLocation)+" was auto-destroyed!"); destroy(); return; } Faction F=null; for(Enumeration e=CMLib.factions().factionSet().elements();e.hasMoreElements();) { F=(Faction)e.nextElement(); if((!F.hasFaction(this))&&(F.findAutoDefault(this)!=Integer.MAX_VALUE)) addFaction(F.factionID(),F.findAutoDefault(this)); } if(tickStatus==Tickable.STATUS_NOT) { try{ imMobile=true; tick(this,Tickable.TICKID_MOB); // slap on the butt }finally{ imMobile=false;} } if(location()==null) { Log.errOut("StdMOB",name()+" of "+CMLib.map().getExtendedRoomID(newLocation)+" was auto-destroyed!!"); destroy(); return; } location().recoverRoomStats(); if((!isGeneric())&&(resetStats)) resetToMaxState(); location().showOthers(this,null,CMMsg.MSG_BRINGTOLIFE,null); if(CMLib.flags().isSleeping(this)) tell("(You are asleep)"); else CMLib.commands().postLook(this,true); inventory.trimToSize(); abilities.trimToSize(); affects.trimToSize(); behaviors.trimToSize(); } public boolean isInCombat() { if(victim==null) return false; try{ Room vicR=victim.location(); if((vicR==null) ||(location()==null) ||(vicR!=location()) ||(victim.amDead())) { if((victim instanceof StdMOB) &&(((StdMOB)victim).victim==this)) victim.setVictim(null); setVictim(null); return false; } return true; }catch(NullPointerException n){} return false; } public boolean mayIFight(MOB mob) { if(mob==null) return false; if(location()==null) return false; if(mob.location()==null) return false; if(mob.amDead()) return false; if(mob.curState().getHitPoints()<=0) return false; if(amDead()) return false; if(curState().getHitPoints()<=0) return false; if(mob.isMonster()) { MOB fol=mob.amFollowing(); if(fol!=null) return mayIFight(fol); return true; } else if(isMonster()) { MOB fol=amFollowing(); if(fol!=null) return fol.mayIFight(mob); return true; } if((mob.soulMate()!=null)||(soulMate()!=null)) return true; if(mob==this) return true; if(CMProps.getVar(CMProps.SYSTEM_PKILL).startsWith("ALWAYS")) return true; if(CMProps.getVar(CMProps.SYSTEM_PKILL).startsWith("NEVER")) return false; if(CMLib.clans().isCommonClanRelations(getClanID(),mob.getClanID(),Clan.REL_WAR)) return true; if(CMath.bset(getBitmap(),MOB.ATT_PLAYERKILL)) { if(CMSecurity.isAllowed(this,location(),"PKILL") ||(CMath.bset(mob.getBitmap(),MOB.ATT_PLAYERKILL))) return true; return false; } else if(CMath.bset(mob.getBitmap(),MOB.ATT_PLAYERKILL)) { if(CMSecurity.isAllowed(mob,location(),"PKILL") ||(CMath.bset(getBitmap(),MOB.ATT_PLAYERKILL))) return true; return false; } else return false; } public boolean mayPhysicallyAttack(MOB mob) { if((!mayIFight(mob)) ||(location()!=mob.location()) ||(!CMLib.flags().isInTheGame(this,false)) ||(!CMLib.flags().isInTheGame(mob,false))) return false; return true; } public int adjustedAttackBonus(MOB mob) { double att=new Integer( envStats().attackAdjustment() +((charStats().getStat(CharStats.STAT_STRENGTH)-9)*3)).doubleValue(); if(curState().getHunger()<1) att=att*.9; if(curState().getThirst()<1) att=att*.9; if(curState().getFatigue()>CharState.FATIGUED_MILLIS) att=att*.8; if(mob==null) return (int)Math.round(att); int diff=envStats().level()-mob.envStats().level(); return (diff*CMath.abs(diff)) +(int)Math.round(att); } public int adjustedArmor() { double arm=new Integer(((charStats().getStat(CharStats.STAT_DEXTERITY)-9)*3) +50).doubleValue(); if((envStats().disposition()&EnvStats.IS_SLEEPING)>0) arm=0.0; if(arm>0.0) { if(curState().getHunger()<1) arm=arm*.85; if(curState().getThirst()<1) arm=arm*.85; if(curState().getFatigue()>CharState.FATIGUED_MILLIS) arm=arm*.85; if((envStats().disposition()&EnvStats.IS_SITTING)>0) arm=arm*.75; } return (int)Math.round(envStats().armor()-arm); } public int adjustedDamage(Weapon weapon, MOB target) { double damageAmount=0.0; if(target!=null) { if((weapon!=null)&&((weapon.weaponClassification()==Weapon.CLASS_RANGED)||(weapon.weaponClassification()==Weapon.CLASS_THROWN))) damageAmount = new Integer(CMLib.dice().roll(1, weapon.envStats().damage(),1)).doubleValue(); else damageAmount = new Integer(CMLib.dice().roll(1, envStats().damage(), (charStats().getStat(CharStats.STAT_STRENGTH) / 3)-2)).doubleValue(); if(!CMLib.flags().canBeSeenBy(target,this)) damageAmount *=.5; if(CMLib.flags().isSleeping(target)) damageAmount *=1.5; else if(CMLib.flags().isSitting(target)) damageAmount *=1.2; } else if((weapon!=null)&&((weapon.weaponClassification()==Weapon.CLASS_RANGED)||(weapon.weaponClassification()==Weapon.CLASS_THROWN))) damageAmount = new Integer(weapon.envStats().damage()+1).doubleValue(); else damageAmount = new Integer(envStats().damage()+(charStats().getStat(CharStats.STAT_STRENGTH) / 3)-2).doubleValue(); if(curState().getHunger() < 1) damageAmount *= .8; if(curState().getFatigue()>CharState.FATIGUED_MILLIS) damageAmount *=.8; if(curState().getThirst() < 1) damageAmount *= .9; if(damageAmount<1.0) damageAmount=1.0; return (int)Math.round(damageAmount); } public void setAtRange(int newRange){atRange=newRange;} public int rangeToTarget(){return atRange;} public int maxRange(){return maxRange(null);} public int minRange(){return maxRange(null);} public int maxRange(Environmental tool) { int max=0; if(tool!=null) max=tool.maxRange(); if((location()!=null)&&(location().maxRange()<max)) max=location().maxRange(); return max; } public int minRange(Environmental tool) { if(tool!=null) return tool.minRange(); return 0; } public void makePeace() { MOB myVictim=victim; setVictim(null); if(myVictim!=null) { MOB oldVictim=myVictim.getVictim(); if(oldVictim==this) myVictim.makePeace(); } } public MOB getVictim() { if(!isInCombat()) return null; return victim; } public void setVictim(MOB mob) { if(mob==null) { setAtRange(-1); if(victim!=null) synchronized(commandQue){commandQue.clear();} } if(victim==mob) return; if(mob==this) return; victim=mob; recoverEnvStats(); recoverCharStats(); recoverMaxState(); if(mob!=null) { if((mob.location()==null) ||(location()==null) ||(mob.amDead()) ||(amDead()) ||(mob.location()!=location()) ||(!location().isInhabitant(this)) ||(!location().isInhabitant(mob))) { if(victim!=null) victim.setVictim(null); victim=null; setAtRange(-1); } else { if(Log.combatChannelOn()) { Item I=fetchWieldedItem(); Item VI=mob.fetchWieldedItem(); Log.combatOut("STRT",Name()+":"+envStats().getCombatStats()+":"+curState().getCombatStats()+":"+((I==null)?"null":I.name())+":"+mob.Name()+":"+mob.envStats().getCombatStats()+":"+mob.curState().getCombatStats()+":"+((VI==null)?"null":VI.name())); } mob.recoverCharStats(); mob.recoverEnvStats(); mob.recoverMaxState(); } } } public DeadBody killMeDead(boolean createBody) { Room deathRoom=null; if(isMonster()) deathRoom=location(); else deathRoom=CMLib.map().getDefaultBodyRoom(this); if(location()!=null) location().delInhabitant(this); DeadBody Body=null; if(createBody) Body=charStats().getMyRace().getCorpseContainer(this,deathRoom); amDead=true; makePeace(); setRiding(null); synchronized(commandQue){commandQue.clear();} for(int a=numEffects()-1;a>=0;a--) { Ability A=fetchEffect(a); if(A!=null) A.unInvoke(); } setLocation(null); if(isMonster()) { while(numFollowers()>0) { MOB follower=fetchFollower(0); if(follower!=null) { follower.setFollowing(null); delFollower(follower); } } setFollowing(null); } if((!isMonster())&&(soulMate()==null)) bringToLife(CMLib.map().getDefaultDeathRoom(this),true); if(deathRoom!=null) deathRoom.recoverRoomStats(); return Body; } public Room location() { if(location==null) return lastLocation; return location; } public void setLocation(Room newRoom) { lastLocation=location; location=newRoom; } public Rideable riding(){return riding;} public void setRiding(Rideable ride) { if((ride!=null)&&(riding()!=null)&&(riding()==ride)&&(riding().amRiding(this))) return; if((riding()!=null)&&(riding().amRiding(this))) riding().delRider(this); riding=ride; if((riding()!=null)&&(!riding().amRiding(this))) riding().addRider(this); } public Session session() { return mySession; } public void setSession(Session newSession) { mySession=newSession; setBitmap(getBitmap()); } public Weapon myNaturalWeapon() { Weapon W=null; if((charStats()!=null)&&(charStats().getMyRace()!=null)) W=charStats().getMyRace().myNaturalWeapon(); else W=CMClass.getWeapon("Natural"); if(W.subjectToWearAndTear()) W.setUsesRemaining(100); return W; } public String displayName(MOB viewer) { if((CMProps.getBoolVar(CMProps.SYSTEMB_INTRODUCTIONSYSTEM)) &&(playerStats()!=null) &&(viewer!=null) &&(viewer.playerStats()!=null) &&(!viewer.playerStats().isIntroducedTo(Name()))) return CMStrings.startWithAorAn(genericName()).toLowerCase(); return name(); } public String displayText(MOB viewer) { if((displayText.length()==0) ||(!name().equals(Name())) ||(!titledName().equals(Name())) ||(CMLib.flags().isSleeping(this)) ||(CMLib.flags().isSitting(this)) ||(riding()!=null) ||((amFollowing()!=null)&&(amFollowing().fetchFollowerOrder(this)>0)) ||((this instanceof Rideable)&&(((Rideable)this).numRiders()>0)&&CMLib.flags().hasSeenContents(this)) ||(isInCombat())) { StringBuffer sendBack=null; if(!displayName(viewer).equals(Name())) sendBack=new StringBuffer(displayName(viewer)); else sendBack=new StringBuffer(titledName()); sendBack.append(" "); sendBack.append(CMLib.flags().dispositionString(this,CMFlagLibrary.flag_is)); sendBack.append(" here"); if(riding()!=null) { sendBack.append(" "+riding().stateString(this)+" "); if(riding()==viewer) sendBack.append("YOU"); else if(!CMLib.flags().canBeSeenBy(riding(),viewer)) { if(riding() instanceof Item) sendBack.append("something"); else sendBack.append("someone"); } else sendBack.append(riding().name()); } else if((this instanceof Rideable) &&(((Rideable)this).numRiders()>0) &&(((Rideable)this).stateStringSubject(((Rideable)this).fetchRider(0)).length()>0)) { Rideable me=(Rideable)this; String first=me.stateStringSubject(me.fetchRider(0)); sendBack.append(" "+first+" "); for(int r=0;r<me.numRiders();r++) { Rider rider=me.fetchRider(r); if((rider!=null)&&(me.stateStringSubject(rider).equals(first))) { if(r>0) { sendBack.append(", "); if(r==me.numRiders()-1) sendBack.append("and "); } if(rider==viewer) sendBack.append("you"); else if(!CMLib.flags().canBeSeenBy(riding(),viewer)) { if(riding() instanceof Item) sendBack.append("something"); else sendBack.append("someone"); } else sendBack.append(rider.name()); } } } if((isInCombat())&&(CMLib.flags().canMove(this))&&(!CMLib.flags().isSleeping(this))) { sendBack.append(" fighting "); if(getVictim()==viewer) sendBack.append("YOU"); else if(!CMLib.flags().canBeSeenBy(getVictim(),viewer)) sendBack.append("someone"); else sendBack.append(getVictim().name()); } if((amFollowing()!=null)&&(amFollowing().fetchFollowerOrder(this)>0)) { Vector whoseAhead=CMLib.combat().getFormationFollowed(this); if((whoseAhead!=null)&&(whoseAhead.size()>0)) { sendBack.append(", behind "); for(int v=0;v<whoseAhead.size();v++) { MOB ahead=(MOB)whoseAhead.elementAt(v); if(v>0) { sendBack.append(", "); if(v==whoseAhead.size()-1) sendBack.append("and "); } if(ahead==viewer) sendBack.append("you"); else if(!CMLib.flags().canBeSeenBy(ahead,viewer)) sendBack.append("someone"); else sendBack.append(ahead.name()); } } } sendBack.append("."); return sendBack.toString(); } return displayText; } public String displayText() { return displayText; } public void setDisplayText(String newDisplayText) { displayText=newDisplayText; } public String description() { if((description==null)||(description.length==0)) return ""; else if(CMProps.getBoolVar(CMProps.SYSTEMB_MOBDCOMPRESS)) return CMLib.encoder().decompressString(description); else return CMStrings.bytesToStr(description); } public void setDescription(String newDescription) { if(newDescription.length()==0) description=null; else if(CMProps.getBoolVar(CMProps.SYSTEMB_MOBDCOMPRESS)) description=CMLib.encoder().compressString(newDescription); else description=CMStrings.strToBytes(newDescription); } public void setMiscText(String newText) { if(newText.length()==0) miscText=null; else if(CMProps.getBoolVar(CMProps.SYSTEMB_MOBCOMPRESS)) miscText=CMLib.encoder().compressString(newText); else miscText=CMStrings.strToBytes(newText); } public String text() { if((miscText==null)||(miscText.length==0)) return ""; else if(CMProps.getBoolVar(CMProps.SYSTEMB_MOBCOMPRESS)) return CMLib.encoder().decompressString(miscText); else return CMStrings.bytesToStr(miscText); } public String miscTextFormat(){return CMParms.FORMAT_UNDEFINED;} public String healthText(MOB viewer) { String mxp="^<!ENTITY vicmaxhp \""+maxState().getHitPoints()+"\"^>^<!ENTITY vichp \""+curState().getHitPoints()+"\"^>^<Health^>^<HealthText \""+name()+"\"^>"; if((charStats()!=null)&&(charStats().getMyRace()!=null)) return mxp+charStats().getMyRace().healthText(viewer,this)+"^</HealthText^>"; return mxp+CMLib.combat().standardMobCondition(viewer,this)+"^</HealthText^>"; } public double actions(){return freeActions;} public void setActions(double remain){freeActions=remain;} public int commandQueSize(){return commandQue.size();} public boolean dequeCommand() { while((!pleaseDestroy)&&((session()==null)||(!session().killFlag()))) { Object[] doCommand=null; synchronized(commandQue) { if(commandQue.size()==0) return false; Object[] ROW=commandQue.elementsAt(0); double diff=actions()-((Double)ROW[2]).doubleValue(); if(diff>=0.0) { long nextTime=lastCommandTime +Math.round(((Double)ROW[2]).doubleValue() /envStats().speed() *TIME_TICK_DOUBLE); if((System.currentTimeMillis()<nextTime)&&(session()!=null)) return false; ROW=commandQue.removeElementsAt(0); setActions(diff); doCommand=ROW; } } if(doCommand!=null) { lastCommandTime=System.currentTimeMillis(); doCommand(doCommand[0],(Vector)doCommand[1]); synchronized(commandQue) { if(commandQue.size()>0) { Object O=commandQue.elementAt(0,1); Double D=new Double(calculateTickDelay(O,0.0)); if(commandQue.size()>0) commandQue.setElementAt(0,3,D); } else return false; return true; } } synchronized(commandQue) { if(commandQue.size()==0) return false; Object[] ROW=commandQue.elementsAt(0); if(System.currentTimeMillis()<((long[])ROW[3])[0]) return false; double diff=actions()-((Double)ROW[2]).doubleValue(); Object O=ROW[0]; Vector commands=(Vector)ROW[1]; ((long[])ROW[3])[0]=((long[])ROW[3])[0]+1000; ((int[])ROW[4])[0]+=1; int secondsElapsed=((int[])ROW[4])[0]; try { if(O instanceof Command) { if(!((Command)O).preExecute(this,commands,secondsElapsed,-diff)) { commandQue.removeElement(ROW); return true; } } else if(O instanceof Ability) { if(!CMLib.english().preEvoke(this,commands,secondsElapsed,-diff)) { commandQue.removeElement(ROW); return true; } } } catch(Exception e) { return false; } } } return false; } public void doCommand(Vector commands) { Object O=CMLib.english().findCommand(this,commands); if(O!=null) doCommand(O,commands); else CMLib.commands().handleUnknownCommand(this,commands); } protected void doCommand(Object O, Vector commands) { try { if(O instanceof Command) ((Command)O).execute(this,commands); else if(O instanceof Social) ((Social)O).invoke(this,commands,null,false); else if(O instanceof Ability) CMLib.english().evoke(this,commands); else CMLib.commands().handleUnknownCommand(this,commands); } catch(java.io.IOException io) { Log.errOut("StdMOB",CMParms.toStringList(commands)); if((io!=null)&&(io.getMessage()!=null)) Log.errOut("StdMOB",io.getMessage()); else Log.errOut("StdMOB",io); tell("Oops!"); } catch(Exception e) { Log.errOut("StdMOB",CMParms.toStringList(commands)); Log.errOut("StdMOB",e); tell("Oops!"); } } protected double calculateTickDelay(Object command, double tickDelay) { if(tickDelay<=0.0) { if(command==null){ tell("Huh?!"); return -1.0;} if(command instanceof Command) tickDelay=isInCombat()?((Command)command).combatActionsCost():((Command)command).actionsCost(); else if(command instanceof Ability) tickDelay=isInCombat()?((Ability)command).combatCastingTime():((Ability)command).castingTime(); else tickDelay=1.0; } return tickDelay; } public void prequeCommand(Vector commands, double tickDelay) { if(commands==null) return; Object O=CMLib.english().findCommand(this,commands); if(O==null){ CMLib.commands().handleUnknownCommand(this,commands); return;} tickDelay=calculateTickDelay(O,tickDelay); if(tickDelay<0.0) return; if(tickDelay==0.0) doCommand(O,commands); else synchronized(commandQue) { long[] next=new long[1]; next[0]=System.currentTimeMillis()-1; int[] seconds=new int[1]; seconds[0]=-1; commandQue.insertElementAt(0,O,commands,new Double(tickDelay),next,seconds); } dequeCommand(); } public void enqueCommand(Vector commands, double tickDelay) { if(commands==null) return; Object O=CMLib.english().findCommand(this,commands); if(O==null){ CMLib.commands().handleUnknownCommand(this,commands); return;} tickDelay=calculateTickDelay(O,tickDelay); if(tickDelay<0.0) return; if(tickDelay==0.0) doCommand(commands); else synchronized(commandQue) { long[] next=new long[1]; next[0]=System.currentTimeMillis()-1; int[] seconds=new int[1]; seconds[0]=-1; commandQue.addElement(O,commands,new Double(tickDelay),next,seconds); } dequeCommand(); } public boolean okMessage(Environmental myHost, CMMsg msg) { if((getMyDeity()!=null)&&(!getMyDeity().okMessage(this,msg))) return false; if(charStats!=null) { for(int c=0;c<charStats().numClasses();c++) if(!charStats().getMyClass(c).okMessage(this,msg)) return false; if(!charStats().getMyRace().okMessage(this, msg)) return false; } Ability A=null; int num=numAllEffects(); for(int i=0;i<num;i++) { A=fetchEffect(i); if((A!=null)&&(!A.okMessage(this,msg))) return false; } Item I=null; num=inventorySize(); for(int i=num-1;i>=0;i--) { I=fetchInventory(i); if((I!=null)&&(!I.okMessage(this,msg))) return false; } Behavior B=null; num=numBehaviors(); for(int b=0;b<num;b++) { B=fetchBehavior(b); if((B!=null)&&(!B.okMessage(this,msg))) return false; } Faction F=null; for(Enumeration e=fetchFactions();e.hasMoreElements();) { F=CMLib.factions().getFaction((String)e.nextElement()); if ((F!=null)&&(!F.okMessage(this, msg))) return false; } MOB mob=msg.source(); if((msg.sourceCode()!=CMMsg.NO_EFFECT)&&(msg.amISource(this))) { if((msg.sourceMinor()==CMMsg.TYP_DEATH) &&(CMSecurity.isAllowed(this,location(),"IMMORT"))) { curState().setHitPoints(1); if((msg.tool()!=null) &&(msg.tool()!=this) &&(msg.tool() instanceof MOB)) ((MOB)msg.tool()).tell(name()+" is immortal, and can not die."); tell("You are immortal, and can not die."); return false; } if(!CMath.bset(msg.sourceMajor(),CMMsg.MASK_ALWAYS)) { int srcCode=msg.sourceMajor(); if(amDead()) { tell("You are DEAD!"); return false; } if(CMath.bset(srcCode,CMMsg.MASK_MALICIOUS)) { if((msg.target()!=this)&&(msg.target()!=null)&&(msg.target() instanceof MOB)) { MOB target=(MOB)msg.target(); if((amFollowing()!=null)&&(target==amFollowing())) { tell("You like "+amFollowing().charStats().himher()+" too much."); return false; } if((getLiegeID().length()>0)&&(target.Name().equals(getLiegeID()))) { if(isMarriedToLiege()) tell("You are married to '"+getLiegeID()+"'!"); else tell("You are serving '"+getLiegeID()+"'!"); return false; } CMLib.combat().establishRange(this,(MOB)msg.target(),msg.tool()); } } if(CMath.bset(srcCode,CMMsg.MASK_EYES)) { if(CMLib.flags().isSleeping(this)) { tell("Not while you are sleeping."); return false; } if(!(msg.target() instanceof Room)) if(!CMLib.flags().canBeSeenBy(msg.target(),this)) { if(msg.target() instanceof Item) tell("You don't see "+msg.target().name()+" here."); else tell("You can't see that!"); return false; } } if(CMath.bset(srcCode,CMMsg.MASK_MOUTH)) { if(!CMLib.flags().aliveAwakeMobile(this,false)) return false; if(CMath.bset(srcCode,CMMsg.MASK_SOUND)) { if((msg.tool()==null) ||(!(msg.tool() instanceof Ability)) ||(!((Ability)msg.tool()).isNowAnAutoEffect())) { if(CMLib.flags().isSleeping(this)) { tell("Not while you are sleeping."); return false; } if(!CMLib.flags().canSpeak(this)) { tell("You can't make sounds!"); return false; } if(CMLib.flags().isAnimalIntelligence(this)) { tell("You aren't smart enough to speak."); return false; } } } else { if((!CMLib.flags().canBeSeenBy(msg.target(),this)) &&(!(isMine(msg.target())&&(msg.target() instanceof Item)))) { mob.tell("You don't see '"+msg.target().name()+"' here."); return false; } if(!CMLib.flags().canTaste(this)) { tell("You can't eat or drink!"); return false; } } } if(CMath.bset(srcCode,CMMsg.MASK_HANDS)) { if((!CMLib.flags().canBeSeenBy(msg.target(),this)) &&(!(isMine(msg.target())&&(msg.target() instanceof Item))) &&(!((isInCombat())&&(msg.target()==victim))) &&(CMath.bset(msg.targetCode(),CMMsg.MASK_HANDS))) { mob.tell("You don't see '"+msg.target().name()+"' here."); return false; } if(!CMLib.flags().aliveAwakeMobile(this,false)) return false; if((CMLib.flags().isSitting(this)) &&(msg.sourceMinor()!=CMMsg.TYP_SITMOVE) &&(msg.sourceMinor()!=CMMsg.TYP_BUY) &&(msg.targetCode()!=CMMsg.MSG_OK_VISUAL) &&((msg.sourceMessage()!=null)||(msg.othersMessage()!=null)) &&((!CMLib.utensils().reachableItem(this,msg.target())) ||(!CMLib.utensils().reachableItem(this,msg.tool())))) { tell("You need to stand up!"); return false; } } if(CMath.bset(srcCode,CMMsg.MASK_MOVE)) { boolean sitting=CMLib.flags().isSitting(this); if((sitting) &&((msg.sourceMinor()==CMMsg.TYP_LEAVE) ||(msg.sourceMinor()==CMMsg.TYP_ENTER))) sitting=false; if(((CMLib.flags().isSleeping(this))||(sitting)) &&(msg.sourceMinor()!=CMMsg.TYP_STAND) &&(msg.sourceMinor()!=CMMsg.TYP_SITMOVE) &&(msg.sourceMinor()!=CMMsg.TYP_SLEEP)) { tell("You need to stand up!"); if((msg.sourceMinor()!=CMMsg.TYP_WEAPONATTACK) &&(msg.sourceMinor()!=CMMsg.TYP_THROW)) return false; } if((!CMLib.flags().canMove(this))||(imMobile)) { tell("You can't move!"); return false; } } // limb check switch(msg.targetMinor()) { case CMMsg.TYP_PULL: case CMMsg.TYP_PUSH: case CMMsg.TYP_GET: case CMMsg.TYP_REMOVE: case CMMsg.TYP_OPEN: case CMMsg.TYP_CLOSE: if(charStats().getBodyPart(Race.BODY_ARM)==0) { tell("You need arms to do that."); return false; } break; case CMMsg.TYP_DELICATE_HANDS_ACT: if((charStats().getBodyPart(Race.BODY_HAND)==0) &&(msg.othersMinor()!=CMMsg.NO_EFFECT)) { tell("You need hands to do that."); return false; } break; case CMMsg.TYP_JUSTICE: if((charStats().getBodyPart(Race.BODY_HAND)==0) &&(msg.target() instanceof Item)) { tell("You need hands to do that."); return false; } break; case CMMsg.TYP_FILL: case CMMsg.TYP_GIVE: case CMMsg.TYP_HANDS: case CMMsg.TYP_LOCK: case CMMsg.TYP_PUT: case CMMsg.TYP_UNLOCK: case CMMsg.TYP_WRITE: if(charStats().getBodyPart(Race.BODY_HAND)==0) { tell("You need hands to do that."); return false; } break; case CMMsg.TYP_DRINK: if(charStats().getBodyPart(Race.BODY_HAND)==0) { if((msg.target()!=null) &&(isMine(msg.target()))) { tell("You need hands to do that."); return false; } } break; } // activity check switch(msg.sourceMinor()) { case CMMsg.TYP_JUSTICE: if((msg.target()!=null) &&(isInCombat()) &&(msg.target() instanceof Item)) { tell("Not while you are fighting!"); return false; } break; case CMMsg.TYP_THROW: if(charStats().getBodyPart(Race.BODY_ARM)==0) { tell("You need arms to do that."); return false; } break; case CMMsg.TYP_OPEN: case CMMsg.TYP_CLOSE: if(isInCombat()) { if((msg.target()!=null) &&((msg.target() instanceof Exit)||(msg.source().isMine(msg.target())))) break; tell("Not while you are fighting!"); return false; } break; case CMMsg.TYP_LEAVE: if((isInCombat())&&(location()!=null)&&(!CMath.bset(msg.sourceMajor(),CMMsg.MASK_MAGIC))) for(int i=0;i<location().numInhabitants();i++) { MOB M=location().fetchInhabitant(i); if((M!=null) &&(M!=this) &&(M.getVictim()==this) &&(CMLib.flags().aliveAwakeMobile(M,true)) &&(CMLib.flags().canSenseMoving(mob,M))) { tell("Not while you are fighting!"); return false; } } break; case CMMsg.TYP_BUY: case CMMsg.TYP_DELICATE_HANDS_ACT: case CMMsg.TYP_FILL: case CMMsg.TYP_LIST: case CMMsg.TYP_LOCK: case CMMsg.TYP_SIT: case CMMsg.TYP_SLEEP: case CMMsg.TYP_UNLOCK: case CMMsg.TYP_VALUE: case CMMsg.TYP_SELL: case CMMsg.TYP_VIEW: case CMMsg.TYP_READ: if(isInCombat()&&(!CMath.bset(msg.sourceMajor(),CMMsg.MASK_MAGIC))) { tell("Not while you are fighting!"); return false; } break; case CMMsg.TYP_REBUKE: if((msg.target()==null)||(!(msg.target() instanceof Deity))) { if(msg.target()!=null) { if((msg.target() instanceof MOB) &&(!CMLib.flags().canBeHeardBy(this,(MOB)msg.target()))) { tell(msg.target().name()+" can't hear you!"); return false; } else if((!((msg.target() instanceof MOB) &&(((MOB)msg.target()).getLiegeID().equals(Name())))) &&(!msg.target().Name().equals(getLiegeID()))) { tell(msg.target().name()+" does not serve you, and you do not serve "+msg.target().name()+"."); return false; } else if((msg.target() instanceof MOB) &&(((MOB)msg.target()).getLiegeID().equals(Name())) &&(getLiegeID().equals(msg.target().Name())) &&(((MOB)msg.target()).isMarriedToLiege())) { tell("You cannot rebuke "+msg.target().name()+". You must get an annulment or a divorce."); return false; } } else if(getLiegeID().length()==0) { tell("You aren't serving anyone!"); return false; } } else if(getWorshipCharID().length()==0) { tell("You aren't worshipping anyone!"); return false; } break; case CMMsg.TYP_SERVE: if(msg.target()==null) return false; if(msg.target()==this) { tell("You can't serve yourself!"); return false; } if(msg.target() instanceof Deity) break; if((msg.target() instanceof MOB) &&(!CMLib.flags().canBeHeardBy(this,(MOB)msg.target()))) { tell(msg.target().name()+" can't hear you!"); return false; } if(getLiegeID().length()>0) { tell("You are already serving '"+getLiegeID()+"'."); return false; } if((msg.target() instanceof MOB) &&(((MOB)msg.target()).getLiegeID().equals(Name()))) { tell("You can not serve each other!"); return false; } break; case CMMsg.TYP_CAST_SPELL: if(charStats().getStat(CharStats.STAT_INTELLIGENCE)<5) { tell("You aren't smart enough to do magic."); return false; } break; default: break; } } } if((msg.sourceCode()!=CMMsg.NO_EFFECT) &&(msg.amISource(this)) &&(msg.target()!=null) &&(msg.target()!=this) &&(!CMath.bset(msg.sourceCode(),CMMsg.MASK_ALWAYS)) &&(msg.target() instanceof MOB) &&(location()!=null) &&(location()==((MOB)msg.target()).location())) { MOB target=(MOB)msg.target(); // and now, the consequences of range if(((msg.targetMinor()==CMMsg.TYP_WEAPONATTACK)&&(rangeToTarget()>maxRange(msg.tool()))) ||((msg.sourceMinor()==CMMsg.TYP_THROW)&&(rangeToTarget()>2)&&(maxRange(msg.tool())<=0))) { String newstr="<S-NAME> advance(s) at "; msg.modify(this,target,null,CMMsg.MSG_ADVANCE,newstr+target.name(),CMMsg.MSG_ADVANCE,newstr+"you",CMMsg.MSG_ADVANCE,newstr+target.name()); boolean ok=location().okMessage(this,msg); if(ok) setAtRange(rangeToTarget()-1); if(victim!=null) { victim.setAtRange(rangeToTarget()); victim.recoverEnvStats(); } else setAtRange(-1); recoverEnvStats(); return ok; } else if(msg.targetMinor()==CMMsg.TYP_RETREAT) { if(curState().getMovement()<25) { tell("You are too tired."); return false; } if((location()!=null) &&(rangeToTarget()>=location().maxRange())) { tell("You cannot retreat any further."); return false; } curState().adjMovement(-25,maxState()); setAtRange(rangeToTarget()+1); if(victim!=null) { victim.setAtRange(rangeToTarget()); victim.recoverEnvStats(); } else setAtRange(-1); recoverEnvStats(); } else if((msg.tool()!=null) &&(msg.sourceMinor()!=CMMsg.TYP_BUY) &&(msg.sourceMinor()!=CMMsg.TYP_SELL) &&(msg.sourceMinor()!=CMMsg.TYP_VIEW)) { int useRange=-1; Environmental tool=msg.tool(); if(getVictim()!=null) { if(getVictim()==target) useRange=rangeToTarget(); else { if(target.getVictim()==this) useRange=target.rangeToTarget(); else useRange=maxRange(tool); } } if((useRange>=0)&&(maxRange(tool)<useRange)) { mob.tell("You are too far away from "+target.name()+" to use "+tool.name()+"."); return false; } else if((useRange>=0)&&(minRange(tool)>useRange)) { mob.tell("You are too close to "+target.name()+" to use "+tool.name()+"."); if((msg.targetMinor()==CMMsg.TYP_WEAPONATTACK) &&(tool instanceof Weapon) &&(!((Weapon)tool).amWearingAt(Item.IN_INVENTORY))) CMLib.commands().postRemove(this,(Weapon)msg.tool(),false); return false; } } } if((msg.targetCode()!=CMMsg.NO_EFFECT)&&(msg.amITarget(this))) { if((amDead())||(location()==null)) return false; if(CMath.bset(msg.targetCode(),CMMsg.MASK_MALICIOUS)) { if(Log.combatChannelOn()) Log.combatOut(msg.source().Name()+":"+Name()+":"+CMMsg.TYPE_DESCS[msg.targetMinor()]+":"+((msg.tool()!=null)?msg.tool().Name():"null")); if((msg.amISource(this)) &&(!CMath.bset(msg.sourceMajor(),CMMsg.MASK_ALWAYS)) &&((msg.tool()==null)||(!(msg.tool() instanceof Ability))||(!((Ability)msg.tool()).isNowAnAutoEffect()))) { mob.tell("You like yourself too much."); if(victim==this){ victim=null; setAtRange(-1);} return false; } if((!mayIFight(mob)) &&((!(msg.tool() instanceof Ability)) ||(((((Ability)msg.tool()).classificationCode()&Ability.ALL_ACODES)!=Ability.ACODE_POISON) &&((((Ability)msg.tool()).classificationCode()&Ability.ALL_ACODES)!=Ability.ACODE_DISEASE)) ||((mob==this)&&(mob.isMonster())))) { mob.tell("You are not allowed to attack "+name()+"."); mob.setVictim(null); if(victim==mob) setVictim(null); return false; } if((!isMonster())&&(!mob.isMonster()) &&(soulMate()==null) &&(mob.soulMate()==null) &&(!CMSecurity.isAllowed(this,location(),"PKILL"))&&(!CMSecurity.isAllowed(mob,mob.location(),"PKILL")) &&(mob.envStats().level()>envStats().level()+CMProps.getPKillLevelDiff()) &&((!(msg.tool() instanceof Ability)) ||(((Ability)msg.tool()).classificationCode()&Ability.ALL_ACODES)!=Ability.ACODE_DISEASE)) { mob.tell("That is not EVEN a fair fight."); mob.setVictim(null); if(victim==mob) setVictim(null); return false; } if(amFollowing()==mob) setFollowing(null); if(isInCombat()) { if((rangeToTarget()>0) &&(getVictim()!=msg.source()) &&(msg.source().getVictim()==this) &&(msg.source().rangeToTarget()==0)) { setVictim(msg.source()); setAtRange(0); } } if((msg.targetMinor()!=CMMsg.TYP_WEAPONATTACK)&&(msg.value()<=0)) { int chanceToFail=Integer.MIN_VALUE; for(int c=0;c<CharStats.STAT_MSG_MAP.length;c++) if(msg.targetMinor()==CharStats.STAT_MSG_MAP[c]) { chanceToFail=charStats().getSave(c); break;} if(chanceToFail>Integer.MIN_VALUE) { chanceToFail+=(envStats().level()-msg.source().envStats().level()); if(chanceToFail<5) chanceToFail=5; else if(chanceToFail>95) chanceToFail=95; if(CMLib.dice().rollPercentage()<chanceToFail) { CMLib.combat().resistanceMsgs(msg,msg.source(),this); msg.setValue(msg.value()+1); } } } } if((rangeToTarget()>=0)&&(!isInCombat())) setAtRange(-1); switch(msg.targetMinor()) { case CMMsg.TYP_CLOSE: case CMMsg.TYP_DRINK: case CMMsg.TYP_DROP: case CMMsg.TYP_EAT: case CMMsg.TYP_FILL: case CMMsg.TYP_GET: case CMMsg.TYP_HOLD: case CMMsg.TYP_REMOVE: case CMMsg.TYP_LOCK: case CMMsg.TYP_OPEN: case CMMsg.TYP_PUT: case CMMsg.TYP_UNLOCK: case CMMsg.TYP_WEAR: case CMMsg.TYP_WIELD: mob.tell(mob,this,null,"You can't do that to <T-NAMESELF>."); return false; case CMMsg.TYP_PULL: if((!CMLib.flags().isBoundOrHeld(this))&&(!CMLib.flags().isSleeping(this))) { mob.tell(mob,this,null,"You can't do that to <T-NAMESELF>."); return false; } if(envStats().weight()>(mob.maxCarry()/2)) { mob.tell(mob,this,null,"<T-NAME> is too big for you to pull."); return false; } break; case CMMsg.TYP_PUSH: if((!CMLib.flags().isBoundOrHeld(this))&&(!CMLib.flags().isSleeping(this))) { mob.tell(mob,this,null,"You can't do that to <T-NAMESELF>."); return false; } if(envStats().weight()>mob.maxCarry()) { mob.tell(mob,this,null,"<T-NAME> is too heavy for you to push."); return false; } break; case CMMsg.TYP_MOUNT: case CMMsg.TYP_DISMOUNT: if(!(this instanceof Rideable)) { mob.tell(mob,this,null,"You can't do that to <T-NAMESELF>."); return false; } break; case CMMsg.TYP_GIVE: if(msg.tool()==null) return false; if(!(msg.tool() instanceof Item)) return false; if(CMSecurity.isAllowed(this,location(),"ORDER") ||(CMSecurity.isAllowed(this,location(),"CMDMOBS")&&(isMonster())) ||(CMSecurity.isAllowed(this,location(),"CMDROOMS")&&(isMonster()))) return true; if(getWearPositions(Item.WORN_ARMS)==0) { msg.source().tell(name()+" is unable to accept that from you."); return false; } if((!CMLib.flags().canBeSeenBy(msg.tool(),this))&&(!CMath.bset(msg.targetCode(),CMMsg.MASK_ALWAYS))) { mob.tell(name()+" can't see what you are giving."); return false; } int GC=msg.targetCode()&CMMsg.MASK_ALWAYS; CMMsg msg2=CMClass.getMsg(msg.source(),msg.tool(),null,CMMsg.MSG_DROP,null,CMMsg.MSG_DROP,"GIVE",CMMsg.MSG_DROP,null); if(!location().okMessage(msg.source(),msg2)) return false; if((msg.target()!=null)&&(msg.target() instanceof MOB)) { msg2=CMClass.getMsg((MOB)msg.target(),msg.tool(),null,GC|CMMsg.MSG_GET,null,GC|CMMsg.MSG_GET,"GIVE",GC|CMMsg.MSG_GET,null); if(!location().okMessage(msg.target(),msg2)) { mob.tell(msg.target().name()+" cannot seem to accept "+msg.tool().name()+"."); return false; } } break; case CMMsg.TYP_FOLLOW: if(totalFollowers()+mob.totalFollowers()>=maxFollowers()) { mob.tell(name()+" can't accept any more followers."); return false; } if((CMProps.getIntVar(CMProps.SYSTEMI_FOLLOWLEVELDIFF)>0) &&(!isMonster()) &&(!mob.isMonster()) &&(!CMSecurity.isAllowed(this,location(),"ORDER")) &&(!CMSecurity.isAllowed(mob,mob.location(),"ORDER"))) { if(envStats.level() > (mob.envStats().level() + CMProps.getIntVar(CMProps.SYSTEMI_FOLLOWLEVELDIFF))) { mob.tell(name() + " is too advanced for you."); return false; } if(envStats.level() < (mob.envStats().level() - CMProps.getIntVar(CMProps.SYSTEMI_FOLLOWLEVELDIFF))) { mob.tell(name() + " is too inexperienced for you."); return false; } } break; } } if((msg.source()!=this)&&(msg.target()!=this)) { if((msg.othersMinor()==CMMsg.TYP_DEATH) &&(msg.sourceMinor()==CMMsg.TYP_DEATH)) { if((followers!=null) &&(followers.contains(msg.source())) &&(CMLib.dice().rollPercentage()==1) &&(fetchEffect("Disease_Depression")==null)) { A=CMClass.getAbility("Disease_Depression"); if(A!=null) A.invoke(this,this,true,0); } } } return true; } public void tell(MOB source, Environmental target, Environmental tool, String msg) { if((mySession!=null)&&(msg!=null)) { Session S=mySession; if(S!=null) S.stdPrintln(source,target,tool,msg); } } public void tell(String msg) { tell(this,this,null,msg); } public void executeMsg(Environmental myHost, CMMsg msg) { if(getMyDeity()!=null) getMyDeity().executeMsg(this,msg); if(charStats!=null) { for(int c=0;c<charStats().numClasses();c++) charStats().getMyClass(c).executeMsg(this,msg); charStats().getMyRace().executeMsg(this,msg); } for(int b=0;b<numBehaviors();b++) { Behavior B=fetchBehavior(b); if(B!=null) B.executeMsg(this,msg); } MOB mob=msg.source(); boolean asleep=CMLib.flags().isSleeping(this); boolean canseesrc=CMLib.flags().canBeSeenBy(msg.source(),this); boolean canhearsrc=CMLib.flags().canBeHeardBy(msg.source(),this); // first do special cases... if(msg.amITarget(this)&&(!amDead)) switch(msg.targetMinor()) { case CMMsg.TYP_HEALING: CMLib.combat().handleBeingHealed(msg); break; case CMMsg.TYP_SNIFF: CMLib.commands().handleBeingSniffed(msg); break; case CMMsg.TYP_DAMAGE: CMLib.combat().handleBeingDamaged(msg); break; default: break; } // now go on to source activities if((msg.sourceCode()!=CMMsg.NO_EFFECT)&&(msg.amISource(this))) { if((CMath.bset(msg.sourceCode(),CMMsg.MASK_MALICIOUS)) &&(msg.target() instanceof MOB) &&(getVictim()!=msg.target()) &&((!CMath.bset(msg.sourceCode(),CMMsg.MASK_ALWAYS)) ||(!(msg.tool() instanceof DiseaseAffect)))) { CMLib.combat().establishRange(this,(MOB)msg.target(),msg.tool()); if((msg.tool() instanceof Weapon) ||(!CMLib.flags().aliveAwakeMobileUnbound((MOB)msg.target(),true))) setVictim((MOB)msg.target()); } switch(msg.sourceMinor()) { case CMMsg.TYP_PANIC: CMLib.commands().postFlee(this,""); break; case CMMsg.TYP_EXPCHANGE: CMLib.leveler().handleExperienceChange(msg); break; case CMMsg.TYP_FACTIONCHANGE: if(msg.othersMessage()!=null) { if((msg.value()==Integer.MAX_VALUE)||(msg.value()==Integer.MIN_VALUE)) removeFaction(msg.othersMessage()); else adjustFaction(msg.othersMessage(),msg.value()); } break; case CMMsg.TYP_DEATH: CMLib.combat().handleDeath(msg); break; case CMMsg.TYP_REBUKE: if(((msg.target()==null)&&(getLiegeID().length()>0)) ||((msg.target()!=null) &&(msg.target().Name().equals(getLiegeID())) &&(!isMarriedToLiege()))) setLiegeID(""); tell(this,msg.target(),msg.tool(),msg.sourceMessage()); break; case CMMsg.TYP_SERVE: if((msg.target()!=null)&&(!(msg.target() instanceof Deity))) setLiegeID(msg.target().Name()); tell(this,msg.target(),msg.tool(),msg.sourceMessage()); break; case CMMsg.TYP_LOOK: case CMMsg.TYP_EXAMINE: if(msg.target()==this) CMLib.commands().handleBeingLookedAt(msg); break; case CMMsg.TYP_READ: if((CMLib.flags().canBeSeenBy(this,mob))&&(msg.amITarget(this))) tell("There is nothing written on "+name()); break; case CMMsg.TYP_SIT: CMLib.commands().handleSit(msg); break; case CMMsg.TYP_SLEEP: CMLib.commands().handleSleep(msg); break; case CMMsg.TYP_QUIT: tell(msg.source(),msg.target(),msg.tool(),msg.sourceMessage()); break; case CMMsg.TYP_STAND: CMLib.commands().handleStand(msg); break; case CMMsg.TYP_RECALL: CMLib.commands().handleRecall(msg); break; case CMMsg.TYP_FOLLOW: if((msg.target()!=null)&&(msg.target() instanceof MOB)) { setFollowing((MOB)msg.target()); tell(msg.source(),msg.target(),msg.tool(),msg.sourceMessage()); } break; case CMMsg.TYP_NOFOLLOW: setFollowing(null); tell(msg.source(),msg.target(),msg.tool(),msg.sourceMessage()); break; default: // you pretty much always know what you are doing, if you can do it. tell(msg.source(),msg.target(),msg.tool(),msg.sourceMessage()); break; } } else if((msg.targetCode()!=CMMsg.NO_EFFECT)&&(msg.amITarget(this))) { int targetMajor=msg.targetMajor(); switch(msg.targetMinor()) { case CMMsg.TYP_HEALING: case CMMsg.TYP_DAMAGE: // handled as special cases above break; case CMMsg.TYP_GIVE: if(msg.tool() instanceof Item) CMLib.commands().handleBeingGivenTo(msg); break; case CMMsg.TYP_LOOK: case CMMsg.TYP_EXAMINE: if(CMLib.flags().canBeSeenBy(this,mob)) CMLib.commands().handleBeingLookedAt(msg); break; case CMMsg.TYP_REBUKE: if((msg.source().Name().equals(getLiegeID())&&(!isMarriedToLiege()))) setLiegeID(""); break; case CMMsg.TYP_SPEAK: if((CMProps.getBoolVar(CMProps.SYSTEMB_INTRODUCTIONSYSTEM)) &&(!asleep)&&(canhearsrc)) CMLib.commands().handleIntroductions(msg.source(),this,msg.targetMessage()); break; default: if((CMath.bset(msg.targetCode(),CMMsg.MASK_MALICIOUS))&&(!amDead)) CMLib.combat().handleBeingAssaulted(msg); else if(CMath.bset(targetMajor,CMMsg.MASK_CHANNEL)) { int channelCode=((msg.targetCode()-CMMsg.MASK_CHANNEL)-CMMsg.TYP_CHANNEL); if((playerStats()!=null) &&(!CMath.bset(getBitmap(),MOB.ATT_QUIET)) &&(!CMath.isSet(playerStats().getChannelMask(),channelCode))) tell(msg.source(),msg.target(),msg.tool(),msg.targetMessage()); } break; } // now do the says if((CMath.bset(targetMajor,CMMsg.MASK_SOUND)) &&(canhearsrc)&&(!asleep)) { if((msg.targetMinor()==CMMsg.TYP_SPEAK) &&(msg.source()!=null) &&(playerStats()!=null)) playerStats().setReplyTo(msg.source()); tell(msg.source(),msg.target(),msg.tool(),msg.targetMessage()); } else if((CMath.bset(targetMajor,CMMsg.MASK_ALWAYS)) ||(msg.targetMinor()==CMMsg.TYP_DAMAGE) ||(msg.targetMinor()==CMMsg.TYP_HEALING)) tell(msg.source(),msg.target(),msg.tool(),msg.targetMessage()); else if((CMath.bset(targetMajor,CMMsg.MASK_EYES)) &&((!asleep)&&(canseesrc))) tell(msg.source(),msg.target(),msg.tool(),msg.targetMessage()); else if(CMath.bset(msg.targetCode(),CMMsg.MASK_MALICIOUS)) tell(msg.source(),msg.target(),msg.tool(),msg.targetMessage()); else if(((CMath.bset(targetMajor,CMMsg.MASK_HANDS)) ||(CMath.bset(targetMajor,CMMsg.MASK_MOVE)) ||((CMath.bset(targetMajor,CMMsg.MASK_MOUTH)) &&(!CMath.bset(targetMajor,CMMsg.MASK_SOUND)))) &&(!asleep)&&((canhearsrc)||(canseesrc))) tell(msg.source(),msg.target(),msg.tool(),msg.targetMessage()); } else if((msg.othersCode()!=CMMsg.NO_EFFECT) &&(!msg.amISource(this)) &&(!msg.amITarget(this))) { int othersMajor=msg.othersMajor(); int othersMinor=msg.othersMinor(); if(CMath.bset(msg.othersCode(),CMMsg.MASK_MALICIOUS) &&(msg.target() instanceof MOB) &&((!CMath.bset(msg.sourceCode(),CMMsg.MASK_ALWAYS)) ||(!(msg.tool() instanceof DiseaseAffect)))) CMLib.combat().makeFollowersFight(this,(MOB)msg.target(),msg.source()); if((othersMinor==CMMsg.TYP_ENTER) // exceptions to movement ||(othersMinor==CMMsg.TYP_FLEE) ||(othersMinor==CMMsg.TYP_LEAVE)) { if(((!asleep)||(msg.othersMinor()==CMMsg.TYP_ENTER)) &&(CMLib.flags().canSenseMoving(msg.source(),this))) tell(msg.source(),msg.target(),msg.tool(),msg.othersMessage()); } else if(CMath.bset(othersMajor,CMMsg.MASK_CHANNEL)) { int channelCode=((msg.othersCode()-CMMsg.MASK_CHANNEL)-CMMsg.TYP_CHANNEL); if((playerStats()!=null) &&(!CMath.bset(getBitmap(),MOB.ATT_QUIET)) &&(!CMath.isSet(playerStats().getChannelMask(),channelCode))) tell(msg.source(),msg.target(),msg.tool(),msg.othersMessage()); } else if((CMath.bset(othersMajor,CMMsg.MASK_SOUND)) &&(!asleep) &&(canhearsrc)) { if((CMProps.getBoolVar(CMProps.SYSTEMB_INTRODUCTIONSYSTEM)) &&(msg.othersMinor()==CMMsg.TYP_SPEAK)) CMLib.commands().handleIntroductions(msg.source(),this,msg.othersMessage()); tell(msg.source(),msg.target(),msg.tool(),msg.othersMessage()); } else if(((CMath.bset(othersMajor,CMMsg.MASK_EYES)) ||(CMath.bset(othersMajor,CMMsg.MASK_HANDS)) ||(CMath.bset(othersMajor,CMMsg.MASK_ALWAYS))) &&((!asleep)&&(canseesrc))) { tell(msg.source(),msg.target(),msg.tool(),msg.othersMessage()); } else if(((CMath.bset(othersMajor,CMMsg.MASK_MOVE)) ||((CMath.bset(othersMajor,CMMsg.MASK_MOUTH))&&(!CMath.bset(othersMajor,CMMsg.MASK_SOUND)))) &&(!asleep) &&((canseesrc)||(canhearsrc))) tell(msg.source(),msg.target(),msg.tool(),msg.othersMessage()); if((msg.othersMinor()==CMMsg.TYP_DEATH) &&(msg.sourceMinor()==CMMsg.TYP_DEATH) &&(location()!=null)) CMLib.combat().handleObserveDeath(this,victim,msg); } Item I=null; int num=inventorySize(); for(int i=num-1;i>=0;i--) { I=fetchInventory(i); if(I!=null) I.executeMsg(this,msg); } Ability A=null; num=numAllEffects(); for(int i=0;i<num;i++) { A=fetchEffect(i); if(A!=null) A.executeMsg(this,msg); } Faction F=null; for(Enumeration e=fetchFactions();e.hasMoreElements();) { F=CMLib.factions().getFaction((String)e.nextElement()); F.executeMsg(this,msg); } } public void affectCharStats(MOB affectedMob, CharStats affectableStats){} protected int processVariableEquipment() { int newLastTickedDateTime=0; for(int i=0;i<location().numInhabitants();i++) { MOB M=location().fetchInhabitant(i); if((M!=null)&&(!M.isMonster())&&(CMSecurity.isAllowed(M,location(),"CMDMOBS"))) { newLastTickedDateTime=-1; break;} } if(newLastTickedDateTime==0) { Vector rivals=new Vector(); for(int i=0;i<inventorySize();i++) { Item I=fetchInventory(i); if((I!=null)&&(I.baseEnvStats().rejuv()>0)&&(I.baseEnvStats().rejuv()<Integer.MAX_VALUE)) { Vector V=null; for(int r=0;r<rivals.size();r++) { Vector V2=(Vector)rivals.elementAt(r); Item I2=(Item)V2.firstElement(); if(I2.rawWornCode()==I.rawWornCode()) { V=V2; break;} } if(V==null){ V=new Vector(); rivals.addElement(V);} V.addElement(I); } } for(int i=0;i<rivals.size();i++) { Vector V=(Vector)rivals.elementAt(i); if((V.size()==1)||(((Item)V.firstElement()).rawWornCode()==0)) { for(int r=0;r<V.size();r++) { Item I=(Item)V.elementAt(r); if(CMLib.dice().rollPercentage()<I.baseEnvStats().rejuv()) delInventory(I); else { I.baseEnvStats().setRejuv(0); I.envStats().setRejuv(0); } } } else { int totalChance=0; for(int r=0;r<V.size();r++) { Item I=(Item)V.elementAt(r); totalChance+=I.baseEnvStats().rejuv(); } int chosenChance=CMLib.dice().roll(1,totalChance,0); totalChance=0; Item chosenI=null; for(int r=0;r<V.size();r++) { Item I=(Item)V.elementAt(r); if(chosenChance<=(totalChance+I.baseEnvStats().rejuv())) { chosenI=I; break; } totalChance+=I.baseEnvStats().rejuv(); } for(int r=0;r<V.size();r++) { Item I=(Item)V.elementAt(r); if(chosenI!=I) delInventory(I); else { I.baseEnvStats().setRejuv(0); I.envStats().setRejuv(0); } } } } recoverEnvStats(); recoverCharStats(); recoverMaxState(); } return newLastTickedDateTime; } public long getTickStatus(){return tickStatus;} public boolean tick(Tickable ticking, int tickID) { if(pleaseDestroy) return false; tickStatus=Tickable.STATUS_START; if(tickID==Tickable.TICKID_MOB) { if(amDead) { boolean isOk=!pleaseDestroy; tickStatus=Tickable.STATUS_DEAD; if(isMonster()) { if((envStats().rejuv()<Integer.MAX_VALUE) &&(baseEnvStats().rejuv()>0)) { envStats().setRejuv(envStats().rejuv()-1); if((envStats().rejuv()<0)||(CMProps.getBoolVar(CMProps.SYSTEMB_MUDSHUTTINGDOWN))) { tickStatus=Tickable.STATUS_REBIRTH; bringToLife(CMLib.map().getStartRoom(this),true); location().showOthers(this,null,CMMsg.MSG_OK_ACTION,"<S-NAME> appears!"); } } else { tickStatus=Tickable.STATUS_END; if(soulMate()==null) destroy(); isOk=false; } } tickStatus=Tickable.STATUS_NOT; lastTickedDateTime=System.currentTimeMillis(); return isOk; } else if(location()!=null) { // handle variable equipment! if((lastTickedDateTime<0) &&isMonster()&&location().getMobility()&&location().getArea().getMobility()) { if(lastTickedDateTime==-1) lastTickedDateTime=processVariableEquipment(); else lastTickedDateTime++; } tickStatus=Tickable.STATUS_ALIVE; curState().recoverTick(this,maxState); if(!isMonster()) curState().expendEnergy(this,maxState,false); if((!CMLib.flags().canBreathe(this))&&(!CMLib.flags().isGolem(this))) { location().show(this,this,CMMsg.MSG_OK_VISUAL,("^Z<S-NAME> can't breathe!^.^?")+CMProps.msp("choke.wav",10)); CMLib.combat().postDamage(this,this,null,(int)Math.round(CMath.mul(Math.random(),baseEnvStats().level()+2)),CMMsg.MASK_ALWAYS|CMMsg.TYP_GAS,-1,null); } if(commandQueSize()==0) setActions(actions()-Math.floor(actions())); setActions(actions()+(CMLib.flags().isSitting(this)?envStats().speed()/2.0:envStats().speed())); if(isInCombat()) { if(CMProps.getIntVar(CMProps.SYSTEMI_COMBATSYSTEM)==CombatLibrary.COMBAT_DEFAULT) setActions(actions()+1.0); // bonus action is employed in default system tickStatus=Tickable.STATUS_FIGHT; peaceTime=0; CMLib.combat().tickCombat(this); } else { peaceTime+=Tickable.TIME_TICK; if(CMath.bset(getBitmap(),MOB.ATT_AUTODRAW) &&(peaceTime>=SHEATH_TIME) &&(CMLib.flags().aliveAwakeMobileUnbound(this,true))) CMLib.commands().postSheath(this,true); } tickStatus=Tickable.STATUS_OTHER; if(!isMonster()) { if(CMLib.flags().isSleeping(this)) curState().adjFatigue(-CharState.REST_PER_TICK,maxState()); else if(!CMSecurity.isAllowed(this,location(),"IMMORT")) { curState().adjFatigue(Tickable.TIME_TICK,maxState()); if((curState().getFatigue()>CharState.FATIGUED_MILLIS) &&(!isMonster()) &&(CMLib.dice().rollPercentage()==1)) { Ability theYawns = CMClass.getAbility("Disease_Yawning"); if(theYawns!=null) theYawns.invoke(this, this, true,0); } } } else while((!amDead())&&dequeCommand()); if((riding()!=null)&&(CMLib.map().roomLocation(riding())!=location())) setRiding(null); if((!isMonster())&&(soulMate()==null)) { CMLib.coffeeTables().bump(this,CoffeeTableRow.STAT_TICKSONLINE); if(((++tickCounter)*Tickable.TIME_TICK)>60000) { tickCounter=0; if(inventory!=null) inventory.trimToSize(); if(affects!=null) affects.trimToSize(); if(abilities!=null) abilities.trimToSize(); if(followers!=null) followers.trimToSize(); CMLib.commands().tickAging(this); } } } Vector aff=cloneEffects(); if(aff!=null) { Ability A=null; for(int a=0;a<aff.size();a++) { A=(Ability)aff.elementAt(a); tickStatus=Tickable.STATUS_AFFECT+a; if(!A.tick(ticking,tickID)) A.unInvoke(); } } manaConsumeCounter=CMLib.commands().tickManaConsumption(this,manaConsumeCounter); int num=numBehaviors(); Behavior B=null; for(int b=0;b<num;b++) { B=fetchBehavior(b); tickStatus=Tickable.STATUS_BEHAVIOR+b; if(B!=null) B.tick(ticking,tickID); } num=charStats().numClasses(); tickStatus=Tickable.STATUS_CLASS; for(int c=0;c<num;c++) charStats().getMyClass(c).tick(ticking,tickID); tickStatus=Tickable.STATUS_RACE; charStats().getMyRace().tick(ticking,tickID); tickStatus=Tickable.STATUS_END; synchronized(tattoos) { try { String tattoo=null; num=numTattoos(); for(int t=0;t<num;t++) { tattoo=fetchTattoo(t); if((tattoo.length()>0) &&(Character.isDigit(tattoo.charAt(0))) &&(tattoo.indexOf(" ")>0) &&(CMath.isNumber(tattoo.substring(0,tattoo.indexOf(" "))))) { String tat=tattoo.substring(tattoo.indexOf(" ")+1).trim(); int timeDown=CMath.s_int(tattoo.substring(0,tattoo.indexOf(" "))); if(timeDown==1) { tattoos.removeElementAt(t); t--; } else tattoos.setElementAt((timeDown-1)+" "+tat,t); } } } catch(Exception e) { Log.errOut("StdMOB","Ticking tattoos."); Log.errOut("StdMOB",e); } } } if(lastTickedDateTime>=0) lastTickedDateTime=System.currentTimeMillis(); tickStatus=Tickable.STATUS_NOT; return !pleaseDestroy; } public boolean isMonster() { return (mySession==null); } public boolean isPossessing() { try { Session S=null; for(int s=0;s<CMLib.sessions().size();s++) { S=CMLib.sessions().elementAt(s); if((S.mob()!=null)&&(S.mob().soulMate()==this)) return true; } } catch(Exception e){} return false; } public int compareTo(Object o){ return CMClass.classID(this).compareToIgnoreCase(CMClass.classID(o));} public void confirmWearability() { Race R=charStats().getMyRace(); DVector reWearSet=new DVector(2); Item item=null; for(int i=0;i<inventorySize();i++) { item=fetchInventory(i); if((item!=null)&&(!item.amWearingAt(Item.IN_INVENTORY))) { Long oldCode=new Long(item.rawWornCode()); item.unWear(); if(reWearSet.size()==0) reWearSet.addElement(item,oldCode); else { short layer=(item instanceof Armor)?((Armor)item).getClothingLayer():0; int d=0; for(;d<reWearSet.size();d++) if(reWearSet.elementAt(d,1) instanceof Armor) { if(((Armor)reWearSet.elementAt(d,1)).getClothingLayer()>layer) break; } else if(0>layer) break; if(d>=reWearSet.size()) reWearSet.addElement(item,oldCode); else reWearSet.insertElementAt(d,item,oldCode); } } } for(int r=0;r<reWearSet.size();r++) { item=(Item)reWearSet.elementAt(r,1); long oldCode=((Long)reWearSet.elementAt(r,2)).longValue(); int msgCode=CMMsg.MSG_WEAR; if((oldCode&Item.WORN_WIELD)>0) msgCode=CMMsg.MSG_WIELD; else if((oldCode&Item.WORN_HELD)>0) msgCode=CMMsg.MSG_HOLD; CMMsg msg=CMClass.getMsg(this,item,null,CMMsg.NO_EFFECT,null,msgCode,null,CMMsg.NO_EFFECT,null); if((R.okMessage(this,msg)) &&(item.okMessage(item,msg)) &&((charStats().getWearableRestrictionsBitmap()&oldCode)==0) &&(item.canWear(this,oldCode))) item.wearAt(oldCode); } } public void addInventory(Item item) { item.setOwner(this); inventory.addElement(item); item.recoverEnvStats(); } public void delInventory(Item item) { inventory.removeElement(item); item.recoverEnvStats(); } public int inventorySize() { return inventory.size(); } public Item fetchInventory(int index) { try { return (Item)inventory.elementAt(index); } catch(java.lang.ArrayIndexOutOfBoundsException x){} return null; } public Item fetchFromInventory(Item goodLocation, String itemName, int wornCode, boolean allowCoins, boolean respectLocationAndWornCode) { Vector inv=inventory; if(!allowCoins) { inv=(Vector)inventory.clone(); for(int v=inv.size()-1;v>=0;v--) if(inv.elementAt(v) instanceof Coins) inv.removeElementAt(v); } Item item=null; if(respectLocationAndWornCode) { item=CMLib.english().fetchAvailableItem(inv,itemName,goodLocation,wornCode,true); if(item==null) item=CMLib.english().fetchAvailableItem(inv,itemName,goodLocation,wornCode,false); } else { item=(Item)CMLib.english().fetchEnvironmental(inv,itemName,true); if(item==null) item=(Item)CMLib.english().fetchEnvironmental(inv,itemName,false); } return item; } public Item fetchInventory(String itemName){ return fetchFromInventory(null,itemName,Item.WORNREQ_ANY,true,false);} public Item fetchInventory(Item goodLocation, String itemName){ return fetchFromInventory(goodLocation,itemName,Item.WORNREQ_ANY,true,true);} public Item fetchCarried(Item goodLocation, String itemName){ return fetchFromInventory(goodLocation,itemName,Item.WORNREQ_UNWORNONLY,true,true);} public Item fetchWornItem(String itemName){ return fetchFromInventory(null,itemName,Item.WORNREQ_WORNONLY,true,true);} public void addFollower(MOB follower, int order) { if(follower!=null) { if(followers==null) followers=new DVector(2); if(!followers.contains(follower)) followers.addElement(follower,new Integer(order)); else { int x=followers.indexOf(follower); if(x>=0) followers.setElementAt(x,2,new Integer(order)); } } } public void delFollower(MOB follower) { if((follower!=null)&&(followers!=null)&&(followers.contains(follower))) { followers.removeElement(follower); if(followers.size()==0) followers=null; } } public int numFollowers() { if(followers==null) return 0; return followers.size(); } public int fetchFollowerOrder(MOB thisOne) { try { if(followers==null) return -1; int x=followers.indexOf(thisOne); if(x>=0) return ((Integer)followers.elementAt(x,2)).intValue(); } catch(java.lang.ArrayIndexOutOfBoundsException x){} return -1; } public MOB fetchFollower(String named) { if(followers==null) return null; MOB mob=(MOB)CMLib.english().fetchEnvironmental(followers.getDimensionVector(1),named,true); if(mob==null) mob=(MOB)CMLib.english().fetchEnvironmental(followers.getDimensionVector(1),named, false); return mob; } public MOB fetchFollower(int index) { try { if(followers==null) return null; return (MOB)followers.elementAt(index,1); } catch(java.lang.ArrayIndexOutOfBoundsException x){} return null; } public boolean isFollowedBy(MOB thisOne) { if(followers==null) return false; if(followers.contains(thisOne)) return true; return false; } public boolean willFollowOrdersOf(MOB mob) { if((amFollowing()==mob) ||((isMonster()&&CMSecurity.isAllowed(mob,location(),"ORDER"))) ||(getLiegeID().equals(mob.Name())) ||(CMLib.law().doesOwnThisProperty(mob,CMLib.map().getStartRoom(this)))) return true; if((!isMonster()) &&(CMSecurity.isAllowedEverywhere(mob,"ORDER")) &&((!CMSecurity.isASysOp(this))||CMSecurity.isASysOp(mob))) return true; if((getClanID().length()>0)&&(getClanID().equals(mob.getClanID()))) { Clan C=CMLib.clans().getClan(getClanID()); if(C!=null) { if((C.allowedToDoThis(mob,Clan.FUNC_CLANCANORDERUNDERLINGS)>=0) &&(mob.getClanRole()>getClanRole())) return true; else if((isMonster()) &&(C.allowedToDoThis(mob,Clan.FUNC_CLANCANORDERCONQUERED)>=0) &&(getStartRoom()!=null)) { LegalBehavior B=CMLib.law().getLegalBehavior(getStartRoom()); if((B!=null)&&(B.rulingClan().equals(mob.getClanID()))) return true; } } } return false; } public MOB amUltimatelyFollowing() { MOB following=amFollowing; if(following==null) return null; HashSet seen=new HashSet(); while((following!=null)&&(following.amFollowing()!=null)&&(!seen.contains(following))) { seen.add(following); following=following.amFollowing(); } return following; } public MOB amFollowing() { MOB following=amFollowing; if(following!=null) { if(!following.isFollowedBy(this)) amFollowing=null; } return amFollowing; } public void setFollowing(MOB mob) { if((amFollowing!=null)&&(amFollowing!=mob)) { if(amFollowing.isFollowedBy(this)) amFollowing.delFollower(this); } if(mob!=null) { if(!mob.isFollowedBy(this)) mob.addFollower(this,-1); } amFollowing=mob; } public HashSet getRideBuddies(HashSet list) { if(list==null) return list; if(!list.contains(this)) list.add(this); if(riding()!=null) riding().getRideBuddies(list); return list; } public HashSet getGroupMembers(HashSet list) { if(list==null) return list; if(!list.contains(this)) list.add(this); if((amFollowing()!=null)&&(!list.contains(amFollowing()))) amFollowing().getGroupMembers(list); for(int f=0;f<numFollowers();f++) { MOB follower=fetchFollower(f); if((follower!=null)&&(!list.contains(follower))) follower.getGroupMembers(list); } return list; } public boolean savable() { if((!isMonster())&&(soulMate()==null)) return false; if(!CMLib.flags().isSavable(this)) return false; if(CMLib.utensils().getMobPossessingAnother(this)!=null) return false; MOB followed=amFollowing(); if(followed!=null) if(!followed.isMonster()) return false; return true; } public MOB soulMate() { return soulMate; } public void setSoulMate(MOB mob) { soulMate=mob; } public void addAbility(Ability to) { if(to==null) return; for(int a=0;a<numLearnedAbilities();a++) { Ability A=fetchAbility(a); if((A!=null)&&(A.ID().equals(to.ID()))) return; } abilities.addElement(to); } public void delAbility(Ability to) { abilities.removeElement(to); } public int numLearnedAbilities() { return abilities.size(); } public int numAbilities() { return abilities.size()+charStats().getMyRace().racialAbilities(this).size(); } public Ability fetchAbility(int index) { try { if(index<abilities.size()) return (Ability)abilities.elementAt(index); return (Ability)charStats().getMyRace().racialAbilities(this).elementAt(index-abilities.size()); } catch(java.lang.ArrayIndexOutOfBoundsException x){} return null; } public Ability fetchAbility(String ID) { Ability A=null; for(int a=0;a<numLearnedAbilities();a++) { A=fetchAbility(a); if((A!=null) &&((A.ID().equalsIgnoreCase(ID))||(A.Name().equalsIgnoreCase(ID)))) return A; } for(int a=0;a<charStats().getMyRace().racialAbilities(this).size();a++) { A=(Ability)charStats().getMyRace().racialAbilities(this).elementAt(a); if((A!=null) &&((A.ID().equalsIgnoreCase(ID))||(A.Name().equalsIgnoreCase(ID)))) return A; } return null; } public Ability findAbility(String ID) { Ability A=(Ability)CMLib.english().fetchEnvironmental(abilities,ID,true); if(A==null) A=(Ability)CMLib.english().fetchEnvironmental(abilities,ID,false); if(A==null) A=(Ability)CMLib.english().fetchEnvironmental(charStats().getMyRace().racialAbilities(this),ID,true); if(A==null) A=(Ability)CMLib.english().fetchEnvironmental(charStats().getMyRace().racialAbilities(this),ID,false); if(A==null) A=fetchAbility(ID); return A; } public void addNonUninvokableEffect(Ability to) { if(to==null) return; if(fetchEffect(to.ID())!=null) return; to.makeNonUninvokable(); to.makeLongLasting(); affects.addElement(to); to.setAffectedOne(this); } public void addEffect(Ability to) { if(to==null) return; if(fetchEffect(to.ID())!=null) return; affects.addElement(to); to.setAffectedOne(this); } public void delEffect(Ability to) { int size=affects.size(); affects.removeElement(to); if(affects.size()<size) to.setAffectedOne(null); } protected Vector cloneEffects(){return (Vector)((affects.size()==0)?null:affects.clone());} public int numAllEffects() { return affects.size();//+charStats().getMyRace().racialEffects(this).size(); } public int numEffects() { return affects.size(); } public Ability fetchEffect(int index) { try { //if(index<affects.size()) return (Ability)affects.elementAt(index); //return (Ability)charStats().getMyRace().racialEffects(this).elementAt(index-affects.size()); } catch(java.lang.ArrayIndexOutOfBoundsException x){} return null; } public Ability fetchEffect(String ID) { Ability A=null; int num=numAllEffects(); for(int a=0;a<num;a++) { A=fetchEffect(a); if((A!=null)&&(A.ID().equals(ID))) return A; } return null; } /** Manipulation of Behavior objects, which includes * movement, speech, spellcasting, etc, etc.*/ public void addBehavior(Behavior to) { if(to==null) return; if(fetchBehavior(to.ID())!=null) return; to.startBehavior(this); behaviors.addElement(to); } public void delBehavior(Behavior to) { behaviors.removeElement(to); } public int numBehaviors() { return behaviors.size(); } public Behavior fetchBehavior(int index) { try { return (Behavior)behaviors.elementAt(index); } catch(java.lang.ArrayIndexOutOfBoundsException x){} return null; } public Behavior fetchBehavior(String ID) { for(int b=0;b<numBehaviors();b++) { Behavior B=fetchBehavior(b); if((B!=null)&&(B.ID().equalsIgnoreCase(ID))) return B; } return null; } /** Manipulation of the expertise list */ public void addExpertise(String of) { if(expertises==null) expertises=new Vector(); if(fetchExpertise(of)==null) expertises.addElement(of); } public void delExpertise(String of) { of=fetchExpertise(of); if(of!=null) expertises.removeElement(of); } public int numExpertises(){return (expertises==null)?0:expertises.size();} public Enumeration uniqueExpertises() { try{ if((expertises==null)||(expertises.size()==0)) return empty.elements(); Vector exCopy=(Vector)expertises.clone(); String exper=null, experRoot=null, expTest=null; int num=-1,end=-1,num2=-1; HashSet remove=new HashSet(); for(int i1=exCopy.size()-1;i1>=0;i1--) { exper=(String)exCopy.elementAt(i1); if((exper.length()==0)||(remove.contains(exper))) continue; end=exper.length(); while(Character.isDigit(exper.charAt(end-1))) end--; if(end<exper.length()) { num=CMath.s_int(exper.substring(end)); experRoot=exper.substring(0,end); for(int i2=i1-1;i2>=0;i2--) { expTest=(String)exCopy.elementAt(i2); if((!remove.contains(expTest)) &&(expTest.startsWith(experRoot)) &&(CMath.isInteger(expTest.substring(experRoot.length())))) { num2=CMath.s_int(expTest.substring(experRoot.length())); if(num<num2) { remove.add(exper); exper=expTest; num=num2; } else remove.add(expTest); } } } else { ExpertiseLibrary.ExpertiseDefinition def=CMLib.expertises().getDefinition(exper); if(def==null) continue; int x=def.name.lastIndexOf(' '); if(x<0) continue; if(CMath.isRomanNumeral(def.name.substring(x+1).trim()) &&(exper.endsWith(def.name.substring(x+1).trim()))) { num=CMath.convertFromRoman(def.name.substring(x+1).trim()); experRoot=exper.substring(0,exper.length()-def.name.substring(x+1).trim().length()); for(int i2=i1-1;i2>=0;i2--) { expTest=(String)exCopy.elementAt(i2); if((!remove.contains(expTest)) &&(expTest.startsWith(experRoot)) &&(CMath.isRomanNumeral(expTest.substring(experRoot.length())))) { num2=CMath.convertFromRoman(expTest.substring(experRoot.length())); if(num<num2) { remove.add(exper); exper=expTest; num=num2; } else remove.add(expTest); } } } } } exCopy.removeAll(remove); return exCopy.elements(); }catch(Exception e){} return expertises.elements(); } public String fetchExpertise(int x){try{return (String)expertises.elementAt(x);}catch(Exception e){} return null;} public String fetchExpertise(String of){ try{ String X=null; for(int i=0;i<numExpertises();i++) { X=fetchExpertise(i); if((X!=null)&&(X.equalsIgnoreCase(of))) return X; } }catch(Exception e){} return null; } /** Manipulation of the tatoo list */ public void addTattoo(String of) { if(tattoos==null) tattoos=new Vector(); if(of.length()==0) return; if((fetchTattoo(of)==null)&&(of!=null)) tattoos.addElement(of.toUpperCase().trim()); } public void delTattoo(String of) { if(tattoos==null) return; synchronized(tattoos) { of=fetchTattoo(of); if(of!=null) tattoos.removeElement(of); } } public int numTattoos(){return (tattoos==null)?0:tattoos.size();} public String fetchTattoo(int x){try{return (String)tattoos.elementAt(x);}catch(Exception e){} return null;} public String fetchTattoo(String of) { try{ if((of==null)||(of.length()==0)) return null; int x=0; while(Character.isDigit(of.charAt(x))) x++; if(x<of.length()) { if(of.charAt(x)==' ') x++; else x=0; } of=of.substring(x).trim().toUpperCase(); String s=null; for(int i=0;i<numTattoos();i++) { s=fetchTattoo(i); if(s.endsWith(of)) { x=0; while(Character.isDigit(s.charAt(x))) x++; if(x<s.length()) { if(s.charAt(x)==' ') x++; else x=0; } if(s.substring(x).trim().equals(of)) return s; } } }catch(Exception e){} return null; } /** Manipulation of the factions list */ public void addFaction(String which) { if(factions==null) factions=new Hashtable(); Faction F=CMLib.factions().getFaction(which); if(F==null) return; addFaction(F.factionID().toUpperCase(),F.findDefault(this)); } public void addFaction(String which,int start) { Faction F=CMLib.factions().getFaction(which); if(F==null) return; if(start>F.maximum()) start=F.maximum(); if(start<F.minimum()) start=F.minimum(); factions.put(F.factionID().toUpperCase(),new Integer(start)); } public void adjustFaction(String which,int amount) { Faction F=CMLib.factions().getFaction(which); if(F==null) return; if(!factions.containsKey(F.factionID().toUpperCase())) addFaction(F.factionID().toUpperCase(),amount); else addFaction(F.factionID().toUpperCase(),((Integer)factions.get(F.factionID().toUpperCase())).intValue()+amount); } public Enumeration fetchFactions() { return factions.keys(); } public int fetchFaction(String which) { which=which.toUpperCase(); if(!factions.containsKey(which)) return Integer.MAX_VALUE; return ((Integer)factions.get(which)).intValue(); } public void removeFaction(String which) { factions.remove(which.toUpperCase()); } public void copyFactions(MOB source) { for(Enumeration e=source.fetchFactions();e.hasMoreElements();) { String fID=(String)e.nextElement(); addFaction(fID,source.fetchFaction(fID)); } } public boolean hasFaction(String which) { Faction F=CMLib.factions().getFaction(which); if(F==null) return false; return factions.containsKey(F.factionID().toUpperCase()); } public Vector fetchFactionRanges() { Faction F=null; Faction.FactionRange FR=null; Vector V=new Vector(); for(Enumeration e=fetchFactions();e.hasMoreElements();) { F=CMLib.factions().getFaction((String)e.nextElement()); if(F==null) continue; FR=CMLib.factions().getRange(F.factionID(),fetchFaction(F.factionID())); if(FR!=null) V.addElement(FR.rangeID()); } return V; } public int freeWearPositions(long wornCode, short belowLayer, short layerAttributes) { int x=getWearPositions(wornCode); if(x<=0) return 0; x-=fetchWornItems(wornCode,belowLayer,layerAttributes).size(); if(x<=0) return 0; return x; } public int getWearPositions(long wornCode) { if((charStats().getWearableRestrictionsBitmap()&wornCode)>0) return 0; if(wornCode==Item.WORN_FLOATING_NEARBY) return 6; int total; int add=0; boolean found=false; for(int i=0;i<Race.BODY_WEARGRID.length;i++) { if((Race.BODY_WEARGRID[i][0]>0) &&((Race.BODY_WEARGRID[i][0]&wornCode)==wornCode)) { found=true; total=charStats().getBodyPart(i); if(Race.BODY_WEARGRID[i][1]<0) { if(total>0) return 0; } else if(total<1) { return 0; } else if(i==Race.BODY_HAND) { // casting is ok here since these are all originals // that fall below the int/long fall. if(wornCode>Integer.MAX_VALUE) add+=total; else switch((int)wornCode) { case (int)Item.WORN_HANDS: if(total<2) add+=1; else add+=total/2; break; case (int)Item.WORN_WIELD: case (int)Item.WORN_RIGHT_FINGER: case (int)Item.WORN_RIGHT_WRIST: add+=1; break; case (int)Item.WORN_HELD: case (int)Item.WORN_LEFT_FINGER: case (int)Item.WORN_LEFT_WRIST: add+=total-1; break; default: add+=total; break; } } else { int num=total/((int)Race.BODY_WEARGRID[i][1]); if(num<1) add+=1; else add+=num; } } } if(!found) return 1; return add; } public Vector fetchWornItems(long wornCode, short aboveOrAroundLayer, short layerAttributes) { Vector V=new Vector(); boolean equalOk=(layerAttributes&Armor.LAYERMASK_MULTIWEAR)>0; int lay=0; for(int i=0;i<inventorySize();i++) { Item thisItem=fetchInventory(i); if((thisItem!=null)&&(thisItem.amWearingAt(wornCode))) { if(thisItem instanceof Armor) { lay=((Armor)thisItem).getClothingLayer(); if(lay>=(aboveOrAroundLayer-1)) { if(((lay>aboveOrAroundLayer-2) &&(lay<aboveOrAroundLayer+2) &&((!equalOk)||((((Armor)thisItem).getLayerAttributes()&Armor.LAYERMASK_MULTIWEAR)==0))) ||(lay>aboveOrAroundLayer)) V.addElement(thisItem); } } else V.addElement(thisItem); } } return V; } public Item fetchFirstWornItem(long wornCode) { for(int i=0;i<inventorySize();i++) { Item thisItem=fetchInventory(i); if((thisItem!=null)&&(thisItem.amWearingAt(wornCode))) return thisItem; } return null; } public Item fetchWieldedItem() { for(int i=0;i<inventorySize();i++) { Item thisItem=fetchInventory(i); if((thisItem!=null)&&(thisItem.amWearingAt(Item.WORN_WIELD))) return thisItem; } return null; } public boolean isMine(Environmental env) { if(env instanceof Item) { if(inventory.contains(env)) return true; return false; } else if(env instanceof MOB) { if((followers!=null)&&(followers.contains(env))) return true; return false; } else if(env instanceof Ability) { if(abilities.contains(env)) return true; if(affects.contains(env)) return true; return false; } return false; } public void giveItem(Item thisContainer) { // caller is responsible for recovering any env // stat changes! if(CMLib.flags().isHidden(thisContainer)) thisContainer.baseEnvStats().setDisposition(thisContainer.baseEnvStats().disposition()&((int)EnvStats.ALLMASK-EnvStats.IS_HIDDEN)); // ensure its out of its previous place Environmental owner=location(); if(thisContainer.owner()!=null) { owner=thisContainer.owner(); if(thisContainer.owner() instanceof Room) ((Room)thisContainer.owner()).delItem(thisContainer); else if(thisContainer.owner() instanceof MOB) ((MOB)thisContainer.owner()).delInventory(thisContainer); } location().delItem(thisContainer); thisContainer.unWear(); if(!isMine(thisContainer)) addInventory(thisContainer); thisContainer.recoverEnvStats(); boolean nothingDone=true; do { nothingDone=true; if(owner instanceof Room) { Room R=(Room)owner; for(int i=0;i<R.numItems();i++) { Item thisItem=R.fetchItem(i); if((thisItem!=null)&&(thisItem.container()==thisContainer)) { giveItem(thisItem); nothingDone=false; break; } } } else if(owner instanceof MOB) { MOB M=(MOB)owner; for(int i=0;i<M.inventorySize();i++) { Item thisItem=M.fetchInventory(i); if((thisItem!=null)&&(thisItem.container()==thisContainer)) { giveItem(thisItem); nothingDone=false; break; } } } }while(!nothingDone); } protected static String[] CODES={"CLASS","LEVEL","ABILITY","TEXT"}; public String getStat(String code){ switch(getCodeNum(code)) { case 0: return ID(); case 1: return ""+baseEnvStats().level(); case 2: return ""+baseEnvStats().ability(); case 3: return text(); } return ""; } public void setStat(String code, String val) { switch(getCodeNum(code)) { case 0: return; case 1: baseEnvStats().setLevel(CMath.s_int(val)); break; case 2: baseEnvStats().setAbility(CMath.s_int(val)); break; case 3: setMiscText(val); break; } } public int getSaveStatIndex(){return getStatCodes().length;} public String[] getStatCodes(){return CODES;} protected int getCodeNum(String code){ for(int i=0;i<CODES.length;i++) if(code.equalsIgnoreCase(CODES[i])) return i; return -1; } public boolean sameAs(Environmental E) { if(!(E instanceof StdMOB)) return false; for(int i=0;i<CODES.length;i++) if(!E.getStat(CODES[i]).equals(getStat(CODES[i]))) return false; return true; } }