package com.planet_ink.coffee_mud.Libraries; import com.planet_ink.coffee_mud.core.interfaces.*; import com.planet_ink.coffee_mud.core.*; import com.planet_ink.coffee_mud.core.collections.*; import com.planet_ink.coffee_mud.Abilities.interfaces.*; import com.planet_ink.coffee_mud.Areas.interfaces.*; import com.planet_ink.coffee_mud.Behaviors.interfaces.*; import com.planet_ink.coffee_mud.CharClasses.interfaces.*; import com.planet_ink.coffee_mud.Commands.interfaces.*; import com.planet_ink.coffee_mud.Common.interfaces.*; import com.planet_ink.coffee_mud.Common.interfaces.Faction.Align; import com.planet_ink.coffee_mud.Exits.interfaces.*; import com.planet_ink.coffee_mud.Items.interfaces.*; import com.planet_ink.coffee_mud.Locales.interfaces.*; import com.planet_ink.coffee_mud.MOBS.interfaces.*; import com.planet_ink.coffee_mud.Races.interfaces.*; import java.util.*; import com.planet_ink.coffee_mud.Libraries.interfaces.*; /* Copyright 2001-2019 Bo Zimmerman Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ public class Sense extends StdLibrary implements CMFlagLibrary { @Override public String ID() { return "Sense"; } @Override public boolean canSee(final MOB M) { return (M != null) && (!isSleeping(M)) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_SEE) == 0); } @Override public boolean canBeLocated(final Physical P) { if(P instanceof MOB) return true; else if ((P != null) && (!isSleeping(P)) && ((P.phyStats().sensesMask() & PhyStats.SENSE_UNLOCATABLE) == 0)) { if ((P instanceof Item) && (((Item) P).container() != null)) return canBeLocated(((Item) P).container()); return true; } return false; } @Override public boolean canSeeHidden(final MOB M) { return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_HIDDEN) == PhyStats.CAN_SEE_HIDDEN); } @Override public boolean canSeeHiddenItems(final MOB M) { return (M != null) && (((M.phyStats().sensesMask() & PhyStats.CAN_SEE_HIDDEN_ITEMS) == PhyStats.CAN_SEE_HIDDEN_ITEMS) ||((M.phyStats().sensesMask() & PhyStats.CAN_SEE_HIDDEN) == PhyStats.CAN_SEE_HIDDEN)); } @Override public boolean canSeeInvisible(final MOB M) { return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_INVISIBLE) == PhyStats.CAN_SEE_INVISIBLE); } @Override public boolean canSeeEvil(final MOB M) { return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_EVIL) == PhyStats.CAN_SEE_EVIL); } @Override public boolean canSeeGood(final MOB M) { return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_GOOD) == PhyStats.CAN_SEE_GOOD); } @Override public boolean canSeeChaos(final Physical P) { return (P != null) && P.phyStats().isAmbiance("@CHAOS"); } @Override public boolean canSeeLaw(final Physical P) { return (P != null) && P.phyStats().isAmbiance("@LAW"); } @Override public boolean canSeeSneakers(final MOB M) { return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_SNEAKERS) == PhyStats.CAN_SEE_SNEAKERS); } @Override public boolean canSeeBonusItems(final MOB M) { return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_BONUS) == PhyStats.CAN_SEE_BONUS); } @Override public boolean canSeeInDark(final MOB M) { return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_DARK) == PhyStats.CAN_SEE_DARK); } @Override public boolean canSeeVictims(final MOB M) { return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_VICTIM) == PhyStats.CAN_SEE_VICTIM); } @Override public boolean canSeeInfrared(final MOB M) { return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_INFRARED) == PhyStats.CAN_SEE_INFRARED); } @Override public boolean canHear(final MOB M) { return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_HEAR) == 0); } @Override public boolean canTrack(final Physical P) { return (P != null) && ((P.phyStats().sensesMask() & PhyStats.CAN_NOT_TRACK) == 0); } @Override public boolean canAutoAttack(final MOB M) { return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_AUTO_ATTACK) == 0); } @Override public boolean canConcentrate(final MOB M) { return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_THINK) == 0); } @Override public boolean canMove(final MOB M) { return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_MOVE) == 0); } @Override public boolean allowsMovement(final Room R) { return (R != null) && ((R.phyStats().sensesMask() & PhyStats.SENSE_ROOMNOMOVEMENT) == 0); } @Override public boolean allowsMovement(final Area A) { return (A != null) && ((A.phyStats().sensesMask() & PhyStats.SENSE_ROOMNOMOVEMENT) == 0); } @Override public boolean canSmell(final MOB M) { return canBreatheHere(M, M.location()) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_SMELL) == 0); } @Override public boolean canTaste(final MOB M) { return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_TASTE) == 0); } @Override public boolean canSpeak(final MOB M) { return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_SPEAK) == 0); } @Override public boolean canBreathe(final MOB M) { return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_NOT_BREATHE) == 0); } @Override public boolean canNotBeCamped(final Physical P) { return (P != null) && ((P.phyStats().sensesMask() & PhyStats.CAN_NOT_BE_CAMPED) != 0); } @Override public boolean canBreatheThis(final MOB M, final int atmoResource) { return (canBreathe(M) &&((atmoResource<0) ||(M.charStats().getBreathables().length==0) ||(Arrays.binarySearch(M.charStats().getBreathables(), atmoResource)>=0))); } @Override public boolean canBreatheHere(final MOB M, final Room R) { return (M != null) && (canBreatheThis(M, (R == null) ? -1 : R.getAtmosphere())); } @Override public boolean canSeeMetal(final MOB M) { return (M != null) && ((M.phyStats().sensesMask() & PhyStats.CAN_SEE_METAL) == PhyStats.CAN_SEE_METAL); } @Override public boolean isReadable(final Item I) { return (I != null) && ((I.phyStats().sensesMask() & PhyStats.SENSE_ITEMREADABLE) == PhyStats.SENSE_ITEMREADABLE); } @Override public boolean isGettable(final Item I) { return (I != null) && ((I.phyStats().sensesMask() & PhyStats.SENSE_ITEMNOTGET) == 0); } @Override public boolean isDroppable(final Item I) { return (I != null) && ((I.phyStats().sensesMask() & PhyStats.SENSE_ITEMNODROP) == 0); } @Override public boolean isRemovable(final Item I) { return (I != null) && ((I.phyStats().sensesMask() & PhyStats.SENSE_ITEMNOREMOVE) == 0); } @Override public boolean isCataloged(final Environmental E) { return (E instanceof Physical) && ((((Physical) E).basePhyStats().disposition() & PhyStats.IS_CATALOGED) == PhyStats.IS_CATALOGED); } private Room roomLocation(final Environmental E) { if(E==null) return null; if((E instanceof Area)&&(!((Area)E).isProperlyEmpty())) return ((Area)E).getRandomProperRoom(); else if(E instanceof Room) return (Room)E; else if(E instanceof MOB) return ((MOB)E).location(); else if((E instanceof Item)&&(((Item)E).owner() instanceof Room)) return (Room)((Item)E).owner(); else if((E instanceof Item)&&(((Item)E).owner() instanceof MOB)) return ((MOB)((Item)E).owner()).location(); else if(E instanceof Ability) return roomLocation(((Ability)E).affecting()); else if(E instanceof Exit) return roomLocation(((Exit)E).lastRoomUsedFrom(null)); return null; } @Override public boolean isWithSeenContents(final Physical P) { return (P != null) &&((P instanceof MOB) ||((P.phyStats().sensesMask() & PhyStats.SENSE_CONTENTSUNSEEN) == 0)); } @Override public boolean isSavable(final Physical P) { if((P==null)||((P.phyStats().disposition()&PhyStats.IS_UNSAVABLE)==0)) { if((P instanceof Item) &&(((Item)P).container()!=null) &&(((Item)P).container()!=P)) return isSavable(((Item)P).container()); return true; } return false; } @Override public void setSavable(final Physical P, final boolean truefalse) { if(P==null) return; if(CMath.bset(P.basePhyStats().disposition(),PhyStats.IS_UNSAVABLE)) { if(truefalse) { P.basePhyStats().setDisposition(CMath.unsetb(P.basePhyStats().disposition(),PhyStats.IS_UNSAVABLE)); P.phyStats().setDisposition(CMath.unsetb(P.phyStats().disposition(),PhyStats.IS_UNSAVABLE)); } } else if(!truefalse) { P.basePhyStats().setDisposition(CMath.setb(P.basePhyStats().disposition(),PhyStats.IS_UNSAVABLE)); P.phyStats().setDisposition(CMath.setb(P.phyStats().disposition(),PhyStats.IS_UNSAVABLE)); } } @Override public void setReadable(final Item I, final boolean truefalse) { if(I==null) return; if(CMath.bset(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMREADABLE)) { if(!truefalse) { I.basePhyStats().setSensesMask(CMath.unsetb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMREADABLE)); I.phyStats().setSensesMask(CMath.unsetb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMREADABLE)); } } else if(truefalse) { I.basePhyStats().setSensesMask(CMath.setb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMREADABLE)); I.phyStats().setSensesMask(CMath.setb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMREADABLE)); } } @Override public boolean isEnspelled(final Physical F) { for(int a=0;a<F.numEffects();a++) // personal affects { final Ability A=F.fetchEffect(a); if((A!=null)&&(A.canBeUninvoked())&&(!A.isAutoInvoked())&&(!A.isSavable()) &&(((A.classificationCode()&Ability.ALL_ACODES)==Ability.ACODE_SPELL) ||((A.classificationCode()&Ability.ALL_ACODES)==Ability.ACODE_PRAYER) ||((A.classificationCode()&Ability.ALL_ACODES)==Ability.ACODE_CHANT) ||((A.classificationCode()&Ability.ALL_ACODES)==Ability.ACODE_SONG))) return true; } return false; } @Override public void setGettable(final Item I, final boolean truefalse) { if(I==null) return; if(!CMath.bset(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNOTGET)) { if(!truefalse) { I.basePhyStats().setSensesMask(CMath.setb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNOTGET)); I.phyStats().setSensesMask(CMath.setb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMNOTGET)); } } else if(truefalse) { I.basePhyStats().setSensesMask(CMath.unsetb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNOTGET)); I.phyStats().setSensesMask(CMath.unsetb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMNOTGET)); } } @Override public void setDroppable(final Item I, final boolean truefalse) { if(I==null) return; if(!CMath.bset(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNODROP)) { if(!truefalse) { I.basePhyStats().setSensesMask(CMath.setb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNODROP)); I.phyStats().setSensesMask(CMath.setb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMNODROP)); } } else if(truefalse) { I.basePhyStats().setSensesMask(CMath.unsetb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNODROP)); I.phyStats().setSensesMask(CMath.unsetb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMNODROP)); } } @Override public void setRemovable(final Item I, final boolean truefalse) { if(I==null) return; if(!CMath.bset(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNOREMOVE)) { if(!truefalse) { I.basePhyStats().setSensesMask(CMath.setb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNOREMOVE)); I.phyStats().setSensesMask(CMath.setb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMNOREMOVE)); } } else if(truefalse) { I.basePhyStats().setSensesMask(CMath.unsetb(I.basePhyStats().sensesMask(),PhyStats.SENSE_ITEMNOREMOVE)); I.phyStats().setSensesMask(CMath.unsetb(I.phyStats().sensesMask(),PhyStats.SENSE_ITEMNOREMOVE)); } } @Override public boolean isSeeable(final Physical P) { return (P!=null)&&(((P.phyStats().disposition()&PhyStats.IS_NOT_SEEN)==0) || isSleeping(P)); } @Override public boolean isCloaked(final Physical P) { return (P!=null)&&((P.phyStats().disposition()&PhyStats.IS_CLOAKED)==PhyStats.IS_CLOAKED); } @Override public boolean isHidden(final Physical P) { if(P==null) return false; final boolean isInHide=((P.phyStats().disposition()&PhyStats.IS_HIDDEN)==PhyStats.IS_HIDDEN); if((P instanceof MOB) &&(isInHide) &&(((MOB)P).isInCombat())) return false; return isInHide; } @Override public boolean isUndead(final MOB mob) { return (mob != null) && CMProps.getListFileVarSet(CMProps.ListFile.RACIAL_CATEGORY_IS_UNDEAD).contains(mob.charStats().getMyRace().racialCategory()); } @Override public boolean isEggLayer(final Race race) { final String[] eggLayers = new String[] { "Amphibian", "Avian", "Dragon", "Reptile", "Ophidian", "Fish" }; return (race == null) ? false : CMStrings.containsIgnoreCase(eggLayers, race.racialCategory()); } @Override public boolean isFish(final MOB mob) { return (mob != null) && CMProps.getListFileVarSet(CMProps.ListFile.RACIAL_CATEGORY_IS_FISH).contains(mob.charStats().getMyRace().racialCategory()); } @Override public boolean isMarine(final MOB mob) { return (mob != null) && CMProps.getListFileVarSet(CMProps.ListFile.RACIAL_CATEGORY_IS_MARINE).contains(mob.charStats().getMyRace().racialCategory()); } @Override public boolean isOutsider(final MOB mob) { return (mob != null) && CMProps.getListFileVarSet(CMProps.ListFile.RACIAL_CATEGORY_IS_OUTSIDER).contains(mob.charStats().getMyRace().racialCategory()); } @Override public boolean isInsect(final MOB mob) { return (mob != null) && CMProps.getListFileVarSet(CMProps.ListFile.RACIAL_CATEGORY_IS_INSECT).contains(mob.charStats().getMyRace().racialCategory()); } @Override public boolean isVermin(final MOB mob) { return (mob != null) && CMProps.getListFileVarSet(CMProps.ListFile.RACIAL_CATEGORY_IS_VERMIN).contains(mob.charStats().getMyRace().racialCategory()); } @Override public boolean isAPlant(final Item I) { return (I!=null) && ((I.material()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_VEGETATION); } @Override public boolean isAPlant(final MOB M) { if(isGolem(M) && (M!=null) && (M.charStats()!=null) && (M.charStats().getMyRace()!=null)) { final List<RawMaterial> mats = M.charStats().getMyRace().myResources(); for(final Item I : mats) { if(((I.material()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_VEGETATION) ||((I.material()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_WOODEN)) return true; } return false; } return false; } @Override public boolean isUnattackable(final Physical P) { return (P!=null)&&((P.phyStats().disposition()&PhyStats.IS_UNATTACKABLE)==PhyStats.IS_UNATTACKABLE); } @Override public boolean isInvisible(final Physical P) { return (P!=null)&&((P.phyStats().disposition()&PhyStats.IS_INVISIBLE)==PhyStats.IS_INVISIBLE); } @Override public boolean isRejuvingItem(final Item I) { if(I==null) return false; for(int i=0;i<I.numEffects();i++) { if(I.fetchEffect(i) instanceof ItemTicker) return true; } return false; } @Override public boolean isReallyEvil(final FactionMember M) { if(M != null) { Faction F=null; Faction.FRange FR=null; for(final Enumeration<String> e=M.factions();e.hasMoreElements();) { F=CMLib.factions().getFaction(e.nextElement()); if(F!=null) { FR=CMLib.factions().getRange(F.factionID(),M.fetchFaction(F.factionID())); if((FR!=null)&&(FR.alignEquiv()==Faction.Align.EVIL)) return true; } } } return false; } @Override public boolean isEvil(final Physical P) { if(P==null) return false; if ((P.phyStats().disposition()&PhyStats.IS_EVIL)==PhyStats.IS_EVIL) return true; else if(P instanceof FactionMember) return isReallyEvil((FactionMember)P); return false; } @Override public boolean isOpenAccessibleContainer(final Item I) { return (I instanceof Container) &&(CMath.bset(I.phyStats().sensesMask(), PhyStats.SENSE_INSIDEACCESSIBLE)) &&((Container)I).isOpen(); } @Override public boolean isTracking(final MOB M) { if(M!=null) return flaggedAffects(M,Ability.FLAG_TRACKING).size()>0; return false; } @Override public boolean isATrackingMonster(final MOB M) { if(M==null) return false; if(M.isMonster()) return flaggedAffects(M,Ability.FLAG_TRACKING).size()>0; return false; } @Override public boolean isReallyGood(final FactionMember M) { if(M != null) { Faction F=null; Faction.FRange FR=null; for(final Enumeration<String> e=M.factions();e.hasMoreElements();) { F=CMLib.factions().getFaction(e.nextElement()); if(F!=null) { FR=CMLib.factions().getRange(F.factionID(),M.fetchFaction(F.factionID())); if((FR!=null)&&(FR.alignEquiv()==Faction.Align.GOOD)) return true; } } } return false; } @Override public String getAge(final MOB M) { final Ability A=M.fetchEffect("Age"); if((A==null)||(A.displayText().length()==0)) { if(M.baseCharStats().getStat(CharStats.STAT_AGE)==0) return "unknown"; return L("@x1 year(s) old",""+M.baseCharStats().getStat(CharStats.STAT_AGE)); } else { String s=A.displayText(); if(s.startsWith("(")) s=s.substring(1); if(s.endsWith(")")) s=s.substring(0,s.length()-1); return s; } } @Override public boolean isGood(final Physical P) { if(P==null) return false; if ((P.phyStats().disposition()&PhyStats.IS_GOOD)==PhyStats.IS_GOOD) return true; else if(P instanceof FactionMember) return isReallyGood((FactionMember)P); return false; } @Override public boolean isLawful(final Physical P) { if((P != null) && (P.phyStats().isAmbiance("#LAW"))) return true; if(P instanceof FactionMember) { Faction F=null; Faction.FRange FR=null; final FactionMember M=(FactionMember)P; for(final Enumeration<String> e=M.factions();e.hasMoreElements();) { F=CMLib.factions().getFaction(e.nextElement()); if(F!=null) { FR=CMLib.factions().getRange(F.factionID(),M.fetchFaction(F.factionID())); if((FR!=null)&&(FR.alignEquiv()==Faction.Align.LAWFUL)) return true; } } } return false; } @Override public boolean isChaotic(final Physical P) { if((P != null) && (P.phyStats().isAmbiance("#CHAOS"))) return true; if(P instanceof FactionMember) { Faction F=null; Faction.FRange FR=null; final FactionMember M=(FactionMember)P; for(final Enumeration<String> e=M.factions();e.hasMoreElements();) { F=CMLib.factions().getFaction(e.nextElement()); if(F!=null) { FR=CMLib.factions().getRange(F.factionID(),M.fetchFaction(F.factionID())); if((FR!=null)&&(FR.alignEquiv()==Faction.Align.CHAOTIC)) return true; } } } return false; } @Override public boolean isTrapped(final Physical P) { for(final Enumeration<Ability> a=P.effects();a.hasMoreElements();) { final Ability A=a.nextElement(); if((A!=null)&&(A instanceof Trap)) return true; } return false; } @Override public boolean isDeadlyOrMaliciousEffect(final PhysicalAgent P) { if(P==null) return false; if(flaggedBehaviors(P, Behavior.FLAG_POTENTIALLYAUTODEATHING).size()>0) return true; if(isTrapped(P)) return true; for(final Enumeration<Ability> a=P.effects();a.hasMoreElements();) { final Ability A=a.nextElement(); if((A instanceof AbilityContainer) &&((A.classificationCode()&Ability.ALL_ACODES)==Ability.ACODE_PROPERTY)) { final AbilityContainer U=(AbilityContainer)A; for(final Enumeration<Ability> e=U.allAbilities();e.hasMoreElements();) { final Ability uA=e.nextElement(); if((uA!=null)&&(uA.abstractQuality()==Ability.QUALITY_MALICIOUS)) return true; } } } return false; } @Override public boolean isPossiblyAggressive(final MOB M) { if(M==null) return false; final List<Behavior> V=flaggedBehaviors(M,Behavior.FLAG_POTENTIALLYAGGRESSIVE); return ((V==null)||(V.size()==0))? false:true; } @Override public boolean isAggressiveTo(final MOB M, final MOB toM) { if((M==null)||(toM==null)) return false; final List<Behavior> V=flaggedBehaviors(M,Behavior.FLAG_POTENTIALLYAGGRESSIVE); if((V==null)||(V.size()==0)) return false; for(final Behavior B : V) { if(B.grantsAggressivenessTo(toM)) return true; } return false; } @Override public String getAlignmentName(final Environmental E) { if(E instanceof Physical) { if((((Physical)E).phyStats().disposition()&PhyStats.IS_GOOD)==PhyStats.IS_GOOD) return Faction.Align.GOOD.toString(); if((((Physical)E).phyStats().disposition()&PhyStats.IS_EVIL)==PhyStats.IS_EVIL) return Faction.Align.EVIL.toString(); } if(E instanceof MOB) { Faction F=null; Faction.FRange FR=null; for(final Enumeration<String> e=((MOB)E).factions();e.hasMoreElements();) { F=CMLib.factions().getFaction(e.nextElement()); if(F!=null) { FR=CMLib.factions().getRange(F.factionID(),((MOB)E).fetchFaction(F.factionID())); if((FR!=null)&&((FR.alignEquiv()==Align.GOOD)||(FR.alignEquiv()==Align.EVIL))) return FR.alignEquiv().toString(); } } } return Faction.Align.NEUTRAL.toString(); } @Override public boolean isReallyNeutral(final FactionMember M) { if(M != null) { Faction F=null; Faction.FRange FR=null; for(final Enumeration<String> e=M.factions();e.hasMoreElements();) { F=CMLib.factions().getFaction(e.nextElement()); if(F!=null) { FR=CMLib.factions().getRange(F.factionID(),M.fetchFaction(F.factionID())); if(FR!=null) switch(FR.alignEquiv()) { case NEUTRAL: return true; case EVIL: return false; case GOOD: return false; default: continue; } } } } return true; } @Override public boolean isNeutral(final Physical P) { if(P==null) return false; if(((P.phyStats().disposition()&PhyStats.IS_GOOD)==PhyStats.IS_GOOD) || ((P.phyStats().disposition()&PhyStats.IS_EVIL)==PhyStats.IS_EVIL)) return false; else if(P instanceof FactionMember) return isReallyNeutral((FactionMember)P); return true; } @Override public boolean isSneaking(final Physical P) { return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_SNEAKING) == PhyStats.IS_SNEAKING); } @Override public boolean isABonusItems(final Physical P) { return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_BONUS) == PhyStats.IS_BONUS); } @Override public boolean isInDark(final Physical P) { return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_DARK) == PhyStats.IS_DARK); } @Override public boolean isLightSource(final Physical P) { return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_LIGHTSOURCE) == PhyStats.IS_LIGHTSOURCE); } @Override public boolean isGlowing(final Physical P) { return (P != null) && ((isLightSource(P) || ((P.phyStats().disposition() & PhyStats.IS_GLOWING) == PhyStats.IS_GLOWING))); } @Override public boolean isGolem(final Physical P) { return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_GOLEM) == PhyStats.IS_GOLEM); } @Override public boolean isSleeping(final Physical P) { return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_SLEEPING) == PhyStats.IS_SLEEPING); } @Override public boolean isSitting(final Physical P) { return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_SITTING) == PhyStats.IS_SITTING); } @Override public boolean isFlying(final Physical P) { return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_FLYING) == PhyStats.IS_FLYING); } @Override public boolean isClimbing(final Physical P) { return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_CLIMBING) == PhyStats.IS_CLIMBING); } @Override public boolean isCrawlable(final Physical P) { if((P instanceof Room)||(P instanceof Area)||(P instanceof Exit)) return (P.phyStats().sensesMask() & PhyStats.SENSE_ROOMCRUNCHEDIN) == PhyStats.SENSE_ROOMCRUNCHEDIN; return false; } @Override public boolean isSwimming(final Physical P) { return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_SWIMMING) == PhyStats.IS_SWIMMING); } @Override public boolean isFalling(final Physical P) { return (P != null) && ((P.phyStats().disposition() & PhyStats.IS_FALLING) == PhyStats.IS_FALLING); } @Override public int getFallingDirection(final Physical P) { if(!isFalling(P)) return -1; final Ability A=P.fetchEffect("Falling"); if((A!=null) && (CMath.s_bool(A.getStat("REVERSED")))) return Directions.UP; return Directions.DOWN; } @Override public boolean isRunningLongCommand(final MOB M) { return (M != null) && (M.session() != null) && ((System.currentTimeMillis() - M.session().getInputLoopTime()) > 30000); } @Override public boolean isSwimmingInWater(final Physical P) { if(!isSwimming(P)) return false; return isWateryRoom(roomLocation(P)); } @Override public boolean isInWilderness(final Physical P) { if(P instanceof MOB) return isInWilderness(((MOB)P).location()); else if(P instanceof Item) return isInWilderness(((Item)P).owner()); else if(P instanceof Room) { return (((Room)P).domainType()!=Room.DOMAIN_OUTDOORS_CITY) &&(((Room)P).domainType()!=Room.DOMAIN_OUTDOORS_SPACEPORT) &&(((Room)P).domainType()!=Room.DOMAIN_OUTDOORS_WATERSURFACE) &&(((Room)P).domainType()!=Room.DOMAIN_OUTDOORS_UNDERWATER) &&((((Room)P).domainType()&Room.INDOORS)==0); } else return false; } @Override public boolean canBeHeardMovingBy(final Physical heard , final MOB hearer) { if(hearer==heard) return true; if(hearer==null) return false; if(heard==null) return false; if((!isSeeable(heard))&&(isCloaked(heard))) { if((!(heard instanceof MOB)) ||(heard.phyStats().level()>hearer.phyStats().level()) ||(!CMSecurity.isASysOp(hearer))) return false; } if(!canHear(hearer)) return false; if(isSneaking(heard)&&(!canSeeSneakers(hearer))) return false; return true; } @Override public boolean canBeHeardSpeakingBy(final Physical heard , final MOB hearer) { if(hearer==heard) return true; if(hearer==null) return false; if(heard==null) return false; if(!canHear(hearer)) return false; return true; } @Override public boolean canSenseMoving(final Physical sensed, final MOB sensor) { return (canBeHeardMovingBy(sensed,sensor)||canBeSeenBy(sensed,sensor)); } @Override public boolean canSenseEnteringLeaving(final Physical sensed, final MOB sensor) { return canBeHeardMovingBy(sensed,sensor); } @Override public String validCheck(final Physical P) { if(P instanceof Room) { final Room R=(Room)P; if(R.amDestroyed()) return " a destroyed place: "+CMLib.map().getExtendedRoomID(R); final Area A=R.getArea(); if((A == null)||(A.amDestroyed())) return "a destroyed area: "+CMLib.map().getExtendedRoomID(R); return null; } if(P instanceof MOB) { final MOB M=(MOB)P; final Room locR; final Room startR; synchronized(M) { startR=M.getStartRoom(); locR=M.location(); } if(M.amDestroyed()) return M.name()+" is destroyed"; if(startR!=null) { final String roomReport =validCheck(startR); if(roomReport != null) return M.name()+" is from "+roomReport; } if(!M.amDead()) { if(locR == null) return "*"+M.name()+" is nowhere!"; final MOB ultFol = M.amUltimatelyFollowing(); if(!locR.isInhabitant(M) &&(!M.isPlayer()) &&((ultFol==null)||(!ultFol.isPlayer()))) return "*"+M.name()+" is not where he is: "+CMLib.map().getExtendedRoomID(locR); final String roomReport =validCheck(locR); if(roomReport != null) return M.name()+" is from "+roomReport; } return null; } if(P instanceof Item) { final Item I=(Item)P; final ItemPossessor owner; synchronized(I) { owner=I.owner(); } if(I.amDestroyed()) return I.name()+" is destroyed"; if(owner == null) { if((I instanceof SpaceObject) &&(CMLib.map().isObjectInSpace((SpaceObject)I))) return null; return I.name()+" is unowned."; } final boolean ownerCheck; synchronized(owner) { ownerCheck=owner.isContent(I); } if(!ownerCheck) return I.name()+" is not where it is: "+owner.name()+" ("+owner.ID()+"): "+CMLib.map().getExtendedRoomID(CMLib.map().roomLocation(owner)); if(owner instanceof MOB) { final MOB M=(MOB)owner; if((!M.isPlayer()) && (!CMLib.threads().isTicking(M, -1)) && ((M.amUltimatelyFollowing()==null)||(!M.amUltimatelyFollowing().isPlayer()))) return I.name()+" on non-ticking mob: "+M.name()+", in: "+CMLib.map().getExtendedRoomID(M.location()); final String mobReport = validCheck(M); if(mobReport != null) { if(mobReport.startsWith("*")) return "*"+I.name()+" on "+mobReport.substring(1); else return I.name()+" on "+mobReport; } } if(owner instanceof Room) { final String roomReport = validCheck(owner); if(roomReport != null) return I.name()+" in "+roomReport; } return null; } return null; } @Override public boolean isAliveAwakeMobileUnbound(final MOB mob, final boolean quiet) { if(!isAliveAwakeMobile(mob,quiet)) return false; if(isBound(mob)) { if(!quiet) mob.tell(L("You are bound!")); return false; } if(isBoundOrHeld(mob)) { if(!quiet) mob.tell(L("You are paralyzed!")); return false; } return true; } @Override public boolean isAliveAwakeMobile(final MOB mob, final boolean quiet) { if(mob==null) return false; if(quiet) { if(mob.amDead() ||(mob.curState().getHitPoints()<0) ||((mob.phyStats().disposition()&PhyStats.IS_SLEEPING)!=0) ||((mob.phyStats().sensesMask()&PhyStats.CAN_NOT_MOVE)!=0)) return false; return true; } if(mob.amDead()||(mob.curState().getHitPoints()<0)) { mob.tell(L("You are DEAD!")); return false; } if(isSleeping(mob)) { mob.tell(L("You are sleeping!")); return false; } if(!canMove(mob)) { mob.tell(L("You can't move!")); return false; } return true; } @Override public boolean isStanding(final MOB mob) { return (!isSitting(mob))&&(!isSleeping(mob)); } @Override public boolean isBound(final Physical P) { if((P!=null)&&((P.phyStats().disposition()&PhyStats.IS_BOUND)==PhyStats.IS_BOUND)) return true; return false; } @Override public boolean isBoundOrHeld(final Physical P) { if(P==null) return false; if((P.phyStats().disposition()&PhyStats.IS_BOUND)==PhyStats.IS_BOUND) return true; return flaggedAnyAffects(P,Ability.FLAG_BINDING|Ability.FLAG_PARALYZING).size()>0; } @Override public boolean isOnFire(final Physical seen) { if(seen==null) return false; if(seen.fetchEffect("Burning")!=null) return true; if(seen.fetchEffect("Prayer_FlameWeapon")!=null) return true; if(!(seen instanceof Light)) return false; final Light light=(Light)seen; if(light.goesOutInTheRain() && light.isLit()) return true; return false; } @Override public boolean isFloatingFreely(final Physical P) { return ((P.fetchEffect("GravityFloat")!=null)&&(P.phyStats().isAmbiance(L("Floating")))); } @Override public int getHideScore(final Physical seen) { if(seen!=null) { int hideFactor=seen.phyStats().level(); if(seen instanceof MOB) hideFactor+=(((MOB)seen).charStats().getStat(CharStats.STAT_DEXTERITY))/2; if(CMath.bset(seen.basePhyStats().disposition(),PhyStats.IS_HIDDEN)) hideFactor+=100; else if(seen instanceof MOB) { hideFactor+=((MOB)seen).charStats().getSave(CharStats.STAT_SAVE_DETECTION); if(seen.phyStats().height()>=0) hideFactor-=(int)Math.round(Math.sqrt(seen.phyStats().height())); } else hideFactor+=100; return hideFactor; } return 0; } @Override public int getDetectScore(final MOB seer) { if(seer!=null) { int detectFactor=seer.charStats().getStat(CharStats.STAT_WISDOM)/2; if(CMath.bset(seer.basePhyStats().sensesMask(),PhyStats.CAN_SEE_HIDDEN)) detectFactor+=100; else // the 100 represents proff, and level represents time searching. detectFactor+=seer.charStats().getSave(CharStats.STAT_SAVE_OVERLOOKING); if(seer.phyStats().height()>=0) detectFactor-=(int)Math.round(Math.sqrt(seer.phyStats().height())); return detectFactor; } return 0; } @Override public boolean canBeSeenBy(final Environmental seen , final MOB seer) { if(seer==seen) return true; if(seen==null) return true; if((seer!=null) &&(seer.isAttributeSet(MOB.Attrib.SYSOPMSGS))) return true; if(!canSee(seer)) return false; if(!(seen instanceof Physical)) return true; final Physical seenP=(Physical)seen; if((!isSeeable(seenP))&&(seer!=null)) { if((!(seenP instanceof MOB)) ||(seenP.phyStats().level()>seer.phyStats().level()) ||(!CMSecurity.isASysOp(seer))) return false; } if((isInvisible(seenP))&&(!canSeeInvisible(seer))) return false; if((isHidden(seenP))&&(!(seenP instanceof Room))) { if(seer == null) return false; if(seenP instanceof Item) { if(!canSeeHiddenItems(seer)) return false; } else if(!canSeeHidden(seer)) { if((!(seen instanceof MOB)) ||(getDetectScore(seer)<getHideScore((MOB)seen))) return false; } } if((seer!=null)&&(!(seenP instanceof Room))) { final Room R=seer.location(); if((R!=null)&&(isInDark(R))) { if((isGlowing(seenP))||(isLightSource(seer))) return true; if(canSeeInDark(seer)) return true; if((!isGolem(seenP))&&(canSeeInfrared(seer))&&(seenP instanceof MOB)) return true; if((canSeeVictims(seer))&&(seer.getVictim()==seenP)) return true; final Area area=R.getArea(); if(area != null) { if((area.getClimateObj().canSeeTheMoon(R,null)) &&(area.getTimeObj().getMoonPhase(R)==TimeClock.MoonPhase.FULL)) return true; } return false; } return true; } else if(isInDark(seenP)) { if((seenP instanceof Room) &&(((Room)seenP).getArea().getClimateObj().canSeeTheMoon(((Room)seenP),null))) { switch(((Room)seenP).getArea().getTimeObj().getMoonPhase((Room)seenP)) { case FULL: case WAXGIBBOUS: case WANEGIBBOUS: return true; default: break; } } if(isLightSource(seer)) return true; if(canSeeInDark(seer)) return true; return false; } return true; } @Override public boolean canBarelyBeSeenBy(final Environmental seen , final MOB seer) { if(!canBeSeenBy(seen,seer)) { if((seer!=null)&&(!(seen instanceof Room))) { final Room R=seer.location(); if((R!=null)&&(isInDark(R))) { if(R.getArea().getClimateObj().canSeeTheMoon(R,null)) { return R.getArea().getTimeObj().getMoonPhase(R) != TimeClock.MoonPhase.NEW; } } } else if((seen instanceof Physical) && (isInDark((Physical)seen))) { if((seen instanceof Room) &&(((Room)seen).getArea().getClimateObj().canSeeTheMoon(((Room)seen),null))) { switch(((Room)seen).getArea().getTimeObj().getMoonPhase((Room)seen)) { case FULL: case WAXGIBBOUS: case WANEGIBBOUS: return false; case NEW: return false; default: return true; } } } } return false; } @Override public boolean canActAtAll(final Tickable affecting) { if(affecting instanceof MOB) { final MOB monster=(MOB)affecting; if((!isAliveAwakeMobile(monster,true)) ||(monster.location()==null) ||(!isInTheGame(monster,false))) return false; return true; } return false; } @Override public boolean canFreelyBehaveNormal(final Tickable affecting) { if(affecting instanceof MOB) { final MOB monster=(MOB)affecting; if((!canActAtAll(monster)) ||(monster.isInCombat()) ||(monster.amFollowing()!=null) ||(monster.curState().getHitPoints()<(monster.maxState().getHitPoints()/2))) return false; return true; } return false; } @Override public boolean isSeenTheSameWay(final MOB seer, final Physical seen1, final Physical seen2) { if(canBeSeenBy(seen1,seer)!=canBeSeenBy(seen2,seer)) return false; if((isEvil(seen1)!=isEvil(seen2))&&(canSeeEvil(seer))) return false; if((isGood(seen1)!=isGood(seen2))&&(canSeeGood(seer))) return false; if((isABonusItems(seen1)!=isABonusItems(seen2))&&(canSeeBonusItems(seer))) return false; if(isInvisible(seen1)!=isInvisible(seen2)) return false; if(isSneaking(seen1)!=isSneaking(seen2)) return false; if(isHidden(seen1)!=isHidden(seen2)) return false; if(isFlying(seen1)!=isFlying(seen2)) return false; if(isBound(seen1)!=isBound(seen2)) return false; if(isFalling(seen1)!=isFalling(seen2)) return false; if(isGlowing(seen1)!=isGlowing(seen2)) return false; if(isGolem(seen1)!=isGolem(seen2)) return false; if(canSeeMetal(seer)&&(seen1 instanceof Item)&&(seen2 instanceof Item) &&((((Item)seen1).material()&RawMaterial.MATERIAL_MASK)!=(((Item)seen2).material()&RawMaterial.MATERIAL_MASK))) return false; if(!CMStrings.compareStringArraysIgnoreCase(seen1.phyStats().ambiances(),seen2.phyStats().ambiances())) return false; return true; } @Override public boolean isWaterWorthy(final Physical P) { if(P==null) return false; if(isSwimming(P) &&((!(P instanceof Item))||(!((Item)P).subjectToWearAndTear())||(((Item)P).usesRemaining()>0))) return true; if((P instanceof Rider)&&(((Rider)P).riding()!=null)) return isWaterWorthy(((Rider)P).riding()); if((P instanceof Rideable) &&(((Rideable)P).rideBasis()==Rideable.RIDEABLE_WATER) &&(P instanceof MOB)) return true; if(P instanceof Item) { final List<Item> V=new Vector<Item>(); if(P instanceof Container) V.addAll(((Container)P).getDeepContents()); if(!V.contains(P)) V.add((Item)P); long totalWeight=0; long totalFloatilla=0; final RawMaterial.CODES codes = RawMaterial.CODES.instance(); for(int v=0;v<V.size();v++) { final Item I=V.get(v); totalWeight+=I.basePhyStats().weight(); totalFloatilla+=totalWeight*codes.bouancy(I.material()); } if(P instanceof Container) { final long cap=((Container)P).capacity(); if(totalWeight<cap) { totalFloatilla+=(cap-totalWeight); totalWeight+=cap-totalWeight; } } if(totalWeight<=0) return true; if(isFalling(P)) return false; return (totalFloatilla/totalWeight)<=1000; } return false; } @Override public boolean isInFlight(final Physical P) { if(P==null) return false; if(isFlying(P)) return true; if(P instanceof Rider) return isInFlight(((Rider)P).riding()); return false; } @Override public boolean isAnimalIntelligence(final MOB M) { return (M!=null)&&(M.charStats().getStat(CharStats.STAT_INTELLIGENCE)<2); } @Override public boolean isVegetable(final MOB M) { return (M != null) && CMProps.getListFileVarSet(CMProps.ListFile.RACIAL_CATEGORY_IS_VEGETATION).contains(M.charStats().getMyRace().racialCategory()); } @Override public boolean isMobile(final PhysicalAgent P) { if(P!=null) { if((P instanceof BoardableShip)&&(!((BoardableShip)P).amDestroyed())) return true; for(final Enumeration<Behavior> e=P.behaviors();e.hasMoreElements();) { final Behavior B=e.nextElement(); if((B!=null)&&(CMath.bset(B.flags(),Behavior.FLAG_MOBILITY))) return true; } } return false; } @Override public List<Behavior> flaggedBehaviors(final PhysicalAgent P, final long flag) { final Vector<Behavior> V=new Vector<Behavior>(1); if(P!=null) { for(final Enumeration<Behavior> e=P.behaviors();e.hasMoreElements();) { final Behavior B=e.nextElement(); if((B!=null)&&(CMath.bset(B.flags(),flag))) { V.addElement(B); } } } return V; } @Override public List<Ability> domainAnyAffects(final Physical P, final int domain) { final Vector<Ability> V=new Vector<Ability>(1); if(P!=null) { if(domain>Ability.ALL_ACODES) { P.eachEffect(new EachApplicable<Ability>() { @Override public void apply(final Ability A) { if((A.classificationCode()&Ability.ALL_DOMAINS)==domain) V.addElement(A); } }); } else { P.eachEffect(new EachApplicable<Ability>() { @Override public void apply(final Ability A) { if((A.classificationCode()&Ability.ALL_ACODES)==domain) V.addElement(A); } }); } } return V; } @Override public List<Ability> domainAffects(final Physical P, final int domain) { return domainAnyAffects(P,domain); } @Override public List<Ability> domainAbilities(final MOB M, final int domain) { final Vector<Ability> V=new Vector<Ability>(1); if(M!=null) { if(domain>Ability.ALL_ACODES) { for(final Enumeration<Ability> a=M.allAbilities();a.hasMoreElements();) { final Ability A=a.nextElement(); if((A!=null)&&((A.classificationCode()&Ability.ALL_DOMAINS)==domain)) { V.addElement(A); } } } else for(final Enumeration<Ability> a=M.allAbilities();a.hasMoreElements();) { final Ability A=a.nextElement(); if((A!=null)&&((A.classificationCode()&Ability.ALL_ACODES)==domain)) { V.addElement(A); } } } return V; } @Override public List<Ability> flaggedAnyAffects(final Physical P, final long flag) { final Vector<Ability> V=new Vector<Ability>(1); if(P!=null) { P.eachEffect(new EachApplicable<Ability>() { @Override public void apply(final Ability A) { if((A.flags()&flag)>0) V.addElement(A); } }); } return V; } @Override public List<Ability> matchedAffects(final MOB invoker, final Physical P, final long flag, final int abilityCode, final int domain) { final Vector<Ability> V=new Vector<Ability>(1); if(P!=null) { P.eachEffect(new EachApplicable<Ability>() { @Override public void apply(final Ability A) { if(((invoker==null)||(A.invoker()==invoker)) &&(((flag<0)||(A.flags()&flag)>0)) &&(((abilityCode<0)||((A.classificationCode()&Ability.ALL_ACODES)==abilityCode))) &&(((domain<0)||((A.classificationCode()&Ability.ALL_DOMAINS)==domain)))) V.addElement(A); } }); } return V; } @Override public List<Ability> flaggedAffects(final Physical P, final long flag) { return flaggedAnyAffects(P,flag); } @Override public List<Ability> flaggedAbilities(final MOB M, final long flag) { final Vector<Ability> V=new Vector<Ability>(); if(M!=null) { for(final Enumeration<Ability> a=M.allAbilities();a.hasMoreElements();) { final Ability A=a.nextElement(); if((A!=null)&&(CMath.bset(A.flags(),flag))) { V.addElement(A); } } } return V; } @Override public boolean canAccess(final MOB mob, final Area A) { if(A==null) return false; if((isHidden(A)) && (mob==null)) return false; if(((!isHidden(A)) &&(mob.location()!=null)&&(mob.location().getArea().getTimeObj()==A.getTimeObj())) ||(CMSecurity.isASysOp(mob)) ||(A.amISubOp(mob.Name()))) return true; return false; } @Override public boolean canAccess(final MOB mob, final Room R) { if(R==null) return false; if(isHidden(R)) { if(mob!=null) { if((CMSecurity.isASysOp(mob)) ||(R.getArea().amISubOp(mob.Name()))) return true; } return false; } else if((mob!=null) &&(mob.location()!=null) &&(mob.location().getArea().getTimeObj()!=R.getArea().getTimeObj())) { if((mob==null)||(!CMSecurity.isASysOp(mob))) return false; } return true; } @Override public boolean isMetal(final Environmental E) { if(E instanceof Item) { return((((Item)E).material()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_METAL) ||((((Item)E).material()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_MITHRIL); } if(E instanceof MOB) { final MOB M=(MOB)E; if(isGolem(M) && (M.charStats()!=null) && (M.charStats().getMyRace()!=null)) { final List<RawMaterial> mats = M.charStats().getMyRace().myResources(); for(final Item I : mats) { if(CMath.bset(I.material(), RawMaterial.MATERIAL_METAL) ||CMath.bset(I.material(), RawMaterial.MATERIAL_MITHRIL)) return true; } } } return false; } @Override public boolean isAiryRoom(final Room R) { if(R==null) return false; switch(R.domainType()) { case Room.DOMAIN_INDOORS_AIR: case Room.DOMAIN_OUTDOORS_AIR: return true; } return false; } @Override public boolean isWateryRoom(final Room R) { if(R==null) return false; switch(R.domainType()) { case Room.DOMAIN_INDOORS_UNDERWATER: case Room.DOMAIN_OUTDOORS_UNDERWATER: case Room.DOMAIN_INDOORS_WATERSURFACE: case Room.DOMAIN_OUTDOORS_WATERSURFACE: return true; } return ((R.getAtmosphere()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_LIQUID) ||isSwimming(R); } /** * Returns whether the given room, whatever is * watery, such as a water surface, etc. * @param R the room to check * @return true if it is water surfacy, false otherwise */ @Override public boolean isWaterySurfaceRoom(final Room R) { if(R==null) return false; switch(R.domainType()) { case Room.DOMAIN_INDOORS_WATERSURFACE: case Room.DOMAIN_OUTDOORS_WATERSURFACE: return true; } return ((R.getAtmosphere()&RawMaterial.MATERIAL_MASK)!=RawMaterial.MATERIAL_LIQUID) &&isSwimming(R); } /** * Returns whether the given room, whatever is * the surface of deep water, such as a water surface, etc. * with an underwater room * @param R the room to check * @return true if it is water surfacy, false otherwise */ @Override public boolean isDeepWaterySurfaceRoom(final Room R) { if((R==null)||(!isWaterySurfaceRoom(R))) return false; R.giveASky(0); return isUnderWateryRoom(R.getRoomInDir(Directions.DOWN)); } /** * Returns whether the given room, whatever is * watery, such as an underwater, etc. * @param R the room to check * @return true if it is underwatery, false otherwise */ @Override public boolean isUnderWateryRoom(final Room R) { if(R==null) return false; switch(R.domainType()) { case Room.DOMAIN_INDOORS_UNDERWATER: case Room.DOMAIN_OUTDOORS_UNDERWATER: return true; } return ((R.getAtmosphere()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_LIQUID) &&isSwimming(R); } @Override public boolean isInTheGame(final Environmental E, final boolean reqInhabitation) { if(E instanceof MOB) return isInTheGame((MOB)E,reqInhabitation); if(E instanceof Item) return isInTheGame((Item)E,reqInhabitation); if(E instanceof Room) return isInTheGame((Room)E,reqInhabitation); if(E instanceof Area) return isInTheGame((Area)E,reqInhabitation); return true; } @Override public boolean isInTheGame(final MOB E, final boolean reqInhabitation) { return (E.location()!=null) && E.amActive() &&((!reqInhabitation)||E.location().isInhabitant(E)); } @Override public boolean isInTheGame(final Item E, final boolean reqInhabitation) { if(E.owner() instanceof MOB) { return isInTheGame((MOB)E.owner(),reqInhabitation); } else if(E.owner() instanceof Room) { return ((!E.amDestroyed()) &&((!reqInhabitation)||(((Room)E.owner()).isContent(E)))); } return false; } @Override public boolean isInTheGame(final Room E, final boolean reqInhabitation) { return CMLib.map().getRoom(CMLib.map().getExtendedRoomID(E))==E; } @Override public boolean isInTheGame(final Area E, final boolean reqInhabitation) { return CMLib.map().getArea(E.Name())==E; } @Override public boolean isEnchanted(final Item I) { // poison is not an enchantment. // neither is disease, or standard properties. for(int i=0;i<I.numEffects();i++) { final Ability A=I.fetchEffect(i); if((A!=null) &&((A.classificationCode()&Ability.ALL_ACODES)!=Ability.ACODE_PROPERTY) &&((A.classificationCode()&Ability.ALL_ACODES)!=Ability.ACODE_DISEASE) &&((A.classificationCode()&Ability.ALL_ACODES)!=Ability.ACODE_POISON)) return true; } return false; } public boolean isAgingThing(final Physical P) { if(P==null) return false; final Ability A=P.fetchEffect("Age"); if((A!=null)&&(CMath.isInteger(A.text())&&(CMath.s_long(A.text())>Short.MAX_VALUE))) return true; return false; } @Override public boolean isChild(final Environmental E) { return isBaby(E)||((E instanceof MOB)&&(((MOB)E).isMonster())&&(isAgingThing((MOB)E))); } @Override public boolean isBaby(final Environmental E) { return ((E instanceof CagedAnimal)&&(isAgingThing((CagedAnimal)E))); } @Override public boolean isStillAffectedBy(final Physical obj, final List<Ability> oneOf, final boolean anyTallF) { for(int a=oneOf.size()-1;a>=0;a--) { if(obj.fetchEffect(oneOf.get(a).ID())==null) { if(!anyTallF) return false; } else { if(anyTallF) return true; } } return !anyTallF; } @Override public String getDispositionDescList(final Physical obj, final boolean useVerbs) { if(obj == null) return ""; final int disposition = obj.phyStats().disposition(); final StringBuffer buf=new StringBuffer(""); if(useVerbs) { for(int i=0;i<PhyStats.IS_VERBS.length;i++) if(CMath.isSet(disposition,i)) buf.append(PhyStats.IS_VERBS[i]+", "); } else for(int i=0;i<PhyStats.IS_CODES.length;i++) { if(CMath.isSet(disposition,i)) buf.append(PhyStats.IS_CODES[i]+", "); } String buff=buf.toString(); if(buff.endsWith(", ")) buff=buff.substring(0,buff.length()-2).trim(); return buff; } @Override public String getSensesDescList(final Physical obj, final boolean useVerbs) { if(obj == null) return ""; final int senses = obj.phyStats().sensesMask(); final StringBuffer buf=new StringBuffer(""); if(useVerbs) { for(int i=0;i<PhyStats.CAN_SEE_VERBS.length;i++) if(CMath.isSet(senses,i)) buf.append(PhyStats.CAN_SEE_VERBS[i]+", "); } else for(int i=0;i<PhyStats.CAN_SEE_CODES.length;i++) { if(CMath.isSet(senses,i)) buf.append(PhyStats.CAN_SEE_CODES[i]+", "); } String buff=buf.toString(); if(buff.endsWith(", ")) buff=buff.substring(0,buff.length()-2).trim(); return buff; } @Override public int getDispositionIndex(String name) { name=name.toUpperCase().trim(); for(int code=0;code<PhyStats.IS_CODES.length-1;code++) { if(PhyStats.IS_CODES[code].endsWith(name)) { return code; } } return -1; } @Override public int getSensesIndex(String name) { name=name.toUpperCase().trim(); for(int code=0;code<PhyStats.CAN_SEE_CODES.length-1;code++) { if(PhyStats.CAN_SEE_CODES[code].endsWith(name)) { return code; } } return -1; } @Override public String getAbilityType(final Ability A) { if(A==null) return ""; return Ability.ACODE_DESCS[A.classificationCode()&Ability.ALL_ACODES]; } @Override public String getAbilityType_(final Ability A) { if(A==null) return ""; return Ability.ACODE_DESCS_[A.classificationCode()&Ability.ALL_ACODES]; } @Override public String getAbilityDomain(final Ability A) { if(A==null) return ""; return Ability.DOMAIN_DESCS[(A.classificationCode()&Ability.ALL_DOMAINS)>>5]; } @Override public int getAbilityType(final String name) { for(int i=0;i<Ability.ACODE_DESCS.length;i++) { if(name.equalsIgnoreCase(Ability.ACODE_DESCS[i])) return i; } return -1; } @Override public int getAbilityType_(final String name) { for(int i=0;i<Ability.ACODE_DESCS_.length;i++) { if(name.equalsIgnoreCase(Ability.ACODE_DESCS_[i])) return i; } return -1; } @Override public int getAbilityDomain(final String name) { for(int i=0;i<Ability.DOMAIN_DESCS.length;i++) { if(name.equalsIgnoreCase(Ability.DOMAIN_DESCS[i])) return i<<5; } return -1; } @Override public boolean isAControlledFollower(final MOB invoker, final MOB mob, Ability A) { if((mob==null)||(mob==invoker)||(!mob.isMonster())) return false; if(A==null) return mob.getStartRoom()==null; A = mob.fetchEffect(A.ID()); if(A==null) return false; if((A.invoker() == invoker)||(A.invoker()==null)) return true; return false; } @Override public boolean hasAControlledFollower(final MOB invoker, final Ability A) { if(invoker==null) return false; final Room R = invoker.location(); if(R==null) return false; for(int r=0;r<R.numInhabitants();r++) { if(isAControlledFollower(invoker, R.fetchInhabitant(r), A)) return true; } final Set<MOB> H = invoker.getGroupMembers(new HashSet<MOB>()); for (final MOB mob : H) { if(isAControlledFollower(invoker, mob, A)) return true; } return false; } @Override public String getDispositionBlurbs(final Physical seen, final MOB seer) { if(seen == null) return ""; final PhyStats pStats=seen.phyStats(); if(pStats == null) return ""; // an exit? final String[] ambiances=pStats.ambiances(); if(!pStats.isAmbiance("-ALL")) { final StringBuilder say=new StringBuilder("^N"); if(!pStats.isAmbiance("-MOST")) { if((seer!=null) &&(seer.phyStats().sensesMask()>0)) { if((canSeeEvil(seer))&&(isEvil(seen))&&(!pStats.isAmbiance("-EVIL"))) say.append(" (glowing ^rred^?)"); if((canSeeGood(seer))&&(isGood(seen))&&(!pStats.isAmbiance("-GOOD"))) say.append(" (glowing ^bblue^?)"); if((canSeeInvisible(seer))&&(isInvisible(seen))&&(!pStats.isAmbiance("-INVISIBLE"))) say.append(" (^yinvisible^?)"); if((canSeeSneakers(seer))&&(isSneaking(seen))&&(!pStats.isAmbiance("-SNEAKING"))) say.append(" (^ysneaking^?)"); if((isHidden(seen)) &&(canSeeHidden(seer)||((seen instanceof Item)&&(canSeeHiddenItems(seer)))) &&(!pStats.isAmbiance("-HIDDEN"))) say.append(" (^yhidden^?)"); if((canSeeInfrared(seer))&&(!isGolem(seen))&&(seen instanceof MOB)&&(isInDark(seer.location()))&&(!pStats.isAmbiance("-HEAT"))) say.append(" (^rheat aura^?)"); if((canSeeBonusItems(seer))&&(isABonusItems(seen))&&(!pStats.isAmbiance("-MAGIC"))) say.append(" (^wmagical aura^?)"); if((canSeeMetal(seer))&&(seen instanceof Item)&&(!pStats.isAmbiance("-METAL"))) { if((((Item)seen).material()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_METAL) say.append(" (^wmetallic aura^?)"); else if((((Item)seen).material()&RawMaterial.MATERIAL_MASK)==RawMaterial.MATERIAL_MITHRIL) say.append(" (^wmithril aura^?)"); } } if((isGlowing(seen))&&(!(seen instanceof Room))&&(!pStats.isAmbiance("-GLOWING"))) say.append(" (^gglowing^?)"); if((seen instanceof MOB) && isRunningLongCommand((MOB)seen)&&(!pStats.isAmbiance("-BUSY"))) say.append(" (^gbusy^?)"); if((canSeeChaos(seer))&&(isChaotic(seen))&&(!pStats.isAmbiance("-CHAOS"))) say.append(" (glowing ^ppurple^?)"); if((canSeeLaw(seer))&&(isLawful(seen))&&(!pStats.isAmbiance("-LAW"))) say.append(" (glowing ^wwhite^?)"); for(int i=0;i<ambiances.length;i++) { switch(ambiances[i].charAt(0)) { case '(': if(ambiances[i].startsWith("(?)")) { final int x=ambiances[i].indexOf(':'); if(canBeHeardSpeakingBy(seen, seer)) say.append(" ("+ambiances[i].substring(3,(x>3)?x:ambiances[i].length())+")"); else if(x>3) say.append(" ("+ambiances[i].substring(x+1)+")"); } else say.append(" "+ambiances[i]); break; case '-': case '@': break; case '#': { final String ambiCode = ambiances[i].substring(1); if((pStats.isAmbiance("@"+ambiCode)) &&(!ambiCode.equals("LAW")) &&(!ambiCode.equals("CHAOS"))) { say.append(" ("+ambiCode+")"); } break; } default: say.append(" ("+ambiances[i]+")"); break; } } } if(isBound(seen)&&(!pStats.isAmbiance("-BOUND"))) say.append(" (^Wbound^?)"); if(isFlying(seen)&&(!(seen instanceof Exit))&&(!pStats.isAmbiance("-FLYING"))) say.append(" (^pflying^?)"); if((isFalling(seen))&&(!pStats.isAmbiance("-FALLING"))) { final Room R=roomLocation(seen); switch(R.domainType()) { case Room.DOMAIN_INDOORS_AIR: case Room.DOMAIN_OUTDOORS_AIR: say.append(" (^pfalling^?)"); break; case Room.DOMAIN_INDOORS_WATERSURFACE: case Room.DOMAIN_OUTDOORS_WATERSURFACE: case Room.DOMAIN_INDOORS_UNDERWATER: case Room.DOMAIN_OUTDOORS_UNDERWATER: case Room.DOMAIN_OUTDOORS_SEAPORT: say.append(" (^psinking^?)"); break; default: if(!(seen instanceof MOB)) say.append(" (^pfalling^?)"); break; } } if(say.length()>1) { say.append(" "); return say.toString(); } } return ""; } protected boolean isAlcoholEffect(final Ability A) { if(A!=null) { if(CMath.bset(A.flags(),Ability.FLAG_INTOXICATING)) return true; if(A instanceof AbilityContainer) { for(final Enumeration<Ability> a2=((AbilityContainer)A).allAbilities();a2.hasMoreElements();) { final Ability A2=a2.nextElement(); if((A2!=null)&&(CMath.bset(A2.flags(),Ability.FLAG_INTOXICATING))) return true; } } } return false; } @Override public List<String> getParents(final Physical thang) { final List<String> parents=new Vector<String>(2); final MOB babe; if(thang instanceof MOB) babe=(MOB)thang; else if(thang instanceof CagedAnimal) babe=((CagedAnimal)thang).unCageMe(); else return parents; for(final Enumeration<Tattoo> t= babe.tattoos();t.hasMoreElements();) { final Tattoo T=t.nextElement(); if(T.name().startsWith("PARENT:")) parents.add(T.name().substring(7).trim()); } if(thang instanceof CagedAnimal) babe.destroy(); return parents; } @Override public boolean isAlcoholic(final Physical thang) { if(thang==null) return false; if(thang instanceof Item) { if(((Item)thang).material()==RawMaterial.RESOURCE_LIQUOR) return true; } if(thang instanceof Drink) { if(((Drink)thang).liquidType()==RawMaterial.RESOURCE_LIQUOR) return true; if(thang instanceof Container) { for(final Item I : ((Container)thang).getContents()) { if((I!=thang) && isAlcoholic(I)) return true; } } if(thang instanceof SpellHolder) { for(final Ability A : ((SpellHolder)thang).getSpells()) { if(isAlcoholEffect(A)) return true; } } } for(int a=0;a<thang.numEffects();a++) // personal { final Ability A=thang.fetchEffect(a); if(this.isAlcoholEffect(A)) return true; } return false; } @Override public String getPresentDispositionVerb(final Physical seen, final ComingOrGoing flag_msgType) { String type=null; if(isFalling(seen)) { if((seen instanceof Item) &&(((Item)seen).owner() instanceof Room) &&(isWateryRoom((Room)((Item)seen).owner()))) type="sinks"; else if((seen instanceof MOB) &&(isWateryRoom(((MOB)seen).location()))) type="sinks"; else type="falls"; } else if(isSleeping(seen)) { if(flag_msgType!=ComingOrGoing.IS) type=(seen instanceof MOB) ? "sleepwalks" : "floats"; else type="sleeps"; } else if(isSneaking(seen)) type="sneaks"; else if(isHidden(seen)) type="prowls"; else if(isSitting(seen)) { if(flag_msgType!=ComingOrGoing.IS) type="crawls"; else if(seen instanceof MOB) type="sits"; else type="sits"; } else if(isFlying(seen)) type="flies"; else if((isClimbing(seen))&&(flag_msgType!=ComingOrGoing.IS)) type="climbs"; else if(isSwimmingInWater(seen)) type="swims"; else if(flag_msgType != null) { switch(flag_msgType) { case ARRIVES: if(seen instanceof MOB) return ((MOB)seen).charStats().getArriveStr(); else return "arrives"; case LEAVES: if(seen instanceof MOB) return ((MOB)seen).charStats().getLeaveStr(); else return "leaves"; default: return "is"; } } if(flag_msgType==ComingOrGoing.ARRIVES) return type+" in"; return type; } @Override public String getDispositionStateList(final MOB mob) { final StringBuilder str=new StringBuilder(""); if(isClimbing(mob)) str.append("climbing, "); if((mob.phyStats().disposition()&PhyStats.IS_EVIL)>0) str.append("evil, "); if(isFalling(mob)) str.append("falling, "); if(isBound(mob)) str.append("bound, "); if(isFlying(mob)) str.append("flies, "); if((mob.phyStats().disposition()&PhyStats.IS_GOOD)>0) str.append("good, "); if(isHidden(mob)) str.append("hidden, "); if(isInDark(mob)) str.append("darkness, "); if(isInvisible(mob)) str.append("invisible, "); if(isGlowing(mob)) str.append("glowing, "); if(isCloaked(mob)) str.append("cloaked, "); if(!isSeeable(mob)) str.append("unseeable, "); if(isSitting(mob)) str.append("crawls, "); if(isSleeping(mob)) str.append("sleepy, "); if(isSneaking(mob)) str.append("sneaks, "); if(isSwimming(mob)) str.append("swims, "); if(str.toString().endsWith(", ")) return str.toString().substring(0,str.length()-2); return str.toString(); } @Override public String getSensesStateList(final MOB mob) { final StringBuilder str=new StringBuilder(""); if(!canHear(mob)) str.append("deaf, "); if(!canSee(mob)) str.append("blind, "); if(!canMove(mob)) str.append("can't move, "); if(canSeeBonusItems(mob)) str.append(L("detect magic, ")); if(canSeeEvil(mob)) str.append(L("detect evil, ")); if(canSeeGood(mob)) str.append(L("detect good, ")); if(canSeeHidden(mob)) str.append("see hidden, "); else if(canSeeHiddenItems(mob)) str.append("see hidden items, "); if(canSeeInDark(mob)) str.append(L("darkvision, ")); if(canSeeInfrared(mob)) str.append(L("infravision, ")); if(canSeeInvisible(mob)) str.append(L("see invisible, ")); if(canSeeMetal(mob)) str.append(L("metalvision, ")); if(canSeeSneakers(mob)) str.append(L("see sneaking, ")); if(!canSmell(mob)) str.append("can't smell, "); if(!canSpeak(mob)) str.append("can't speak, "); if(!canTaste(mob)) str.append("can't eat, "); if(str.toString().endsWith(", ")) return str.toString().substring(0,str.length()-2); return str.toString(); } }