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.Exits.interfaces.*;
import com.planet_ink.coffee_mud.Items.interfaces.*;
import com.planet_ink.coffee_mud.Libraries.interfaces.*;
import com.planet_ink.coffee_mud.Libraries.interfaces.AchievementLibrary.Event;
import com.planet_ink.coffee_mud.Locales.interfaces.*;
import com.planet_ink.coffee_mud.MOBS.interfaces.*;
import com.planet_ink.coffee_mud.Races.interfaces.*;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.io.IOException;
import java.lang.ref.WeakReference;
/*
Copyright 2004-2016 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 CommonMsgs extends StdLibrary implements CommonCommands
{
@Override
public String ID()
{
return "CommonMsgs";
}
protected final static int LOOK_LONG=0;
protected final static int LOOK_NORMAL=1;
protected final static int LOOK_BRIEFOK=2;
// this needs to be global to work right
protected final List<WeakReference<MsgMonitor>>
globalMonitors = new SLinkedList<WeakReference<MsgMonitor>>();
protected Ability awarenessA=null;
@Override
public boolean handleUnknownCommand(MOB mob, List<String> command)
{
if(mob==null)
return false;
final Room R=mob.location();
String msgStr;
if(R==null)
{
mob.tell(L("Huh?"));
return false;
}
if(command.size()>0)
{
final String word=CMLib.english().getAnEvokeWord(mob,command.get(0));
if(word!=null)
msgStr=L("You don't know how to @x1 that.",word.toLowerCase());
else
msgStr=L("Huh?");
}
else
msgStr=L("Huh?");
final CMMsg msg=CMClass.getMsg(mob,null,null,CMMsg.MSG_HUH,msgStr,CMParms.combineQuoted(command,0),null);
if(!R.okMessage(mob,msg))
return false;
R.send(mob,msg);
return true;
}
public boolean handleCommandFail(final MOB mob, final List<String> commands, final String msgStr)
{
return handleCommandFail(mob, null, null, commands, msgStr);
}
public boolean handleCommandFail(final MOB mob, Environmental target, Environmental tools, final List<String> command, final String msgStr)
{
if(mob==null)
return false;
final Room R=mob.location();
final CMMsg msg=CMClass.getMsg(mob,target,tools,CMMsg.MSG_COMMANDFAIL,msgStr,CMMsg.NO_EFFECT,CMParms.combineQuoted(command,0),CMMsg.NO_EFFECT,null);
if(!R.okMessage(mob,msg))
return false;
R.send(mob,msg);
return true;
}
@Override
public boolean doCommandFail(final MOB mob, final List<String> commands, final String msgStr)
{
return doCommandFail(mob, null, null, commands, msgStr);
}
@Override
public boolean doCommandFail(final MOB mob, Environmental target, Environmental tools, final List<String> command, final String msgStr)
{
if(mob==null)
return false;
final Room R=mob.location();
final CMMsg msg=CMClass.getMsg(mob,target,tools,CMMsg.MSG_COMMANDFAIL,msgStr,CMMsg.NO_EFFECT,CMParms.combineQuoted(command,0),CMMsg.NO_EFFECT,null);
if(!R.okMessage(mob,msg))
return false;
R.send(mob,msg);
return true;
}
@Override
public Object unforcedInternalCommand(MOB mob, String command, Object... parms)
{
try
{
final Command C=CMClass.getCommand(command);
if(C!=null)
return C.executeInternal(mob,0,parms);
}
catch(final IOException e)
{
Log.errOut("CommonMsgs",e);
}
return Boolean.FALSE;
}
@Override
public Object forceInternalCommand(MOB mob, String command, Object... parms)
{
try
{
final Command C=CMClass.getCommand(command);
if(C!=null)
return C.executeInternal(mob,MUDCmdProcessor.METAFLAG_FORCED,parms);
}
catch(final IOException e)
{
Log.errOut("CommonMsgs",e);
}
return Boolean.FALSE;
}
@Override
public boolean forceStandardCommand(MOB mob, String command, List<String> parms)
{
try
{
final Command C=CMClass.getCommand(command);
if(C!=null)
return C.execute(mob,parms,MUDCmdProcessor.METAFLAG_FORCED);
}
catch(final IOException e)
{
Log.errOut("CommonMsgs",e);
}
return false;
}
@Override
public void monitorGlobalMessage(Room room, CMMsg msg)
{
MsgMonitor M;
for (WeakReference<MsgMonitor> W : globalMonitors)
{
M=W.get();
if(M != null)
M.monitorMsg(room, msg);
else
globalMonitors.remove(M);
}
}
@Override
public void addGlobalMonitor(MsgMonitor M)
{
if(M==null)
return;
for (WeakReference<MsgMonitor> W : globalMonitors)
{
if(W.get()==M)
return;
}
globalMonitors.add(new WeakReference<MsgMonitor>(M));
}
@Override
public void delGlobalMonitor(MsgMonitor M)
{
if(M==null)
return;
for (WeakReference<MsgMonitor> W : globalMonitors)
{
if(W.get()==M)
globalMonitors.remove(W);
}
}
@Override
public StringBuilder getScore(MOB mob)
{
final Vector<String> V=new Vector<String>();
forceStandardCommand(mob,"Score",V);
if(V.size()==1)
return new StringBuilder(V.firstElement());
return new StringBuilder("");
}
@Override
public StringBuilder getEquipment(MOB viewer, MOB mob)
{
return (StringBuilder)forceInternalCommand(mob,"Equipment",viewer);
}
@Override
public StringBuilder getInventory(MOB viewer, MOB mob)
{
return new StringBuilder(forceInternalCommand(mob,"Inventory",viewer).toString());
}
@Override
public void postChannel(MOB mob, String channelName, String message, boolean systemMsg)
{
forceInternalCommand(mob,"Channel",Boolean.valueOf(systemMsg),channelName,message);
}
public MOB nonClanTalker = null;
@Override
public void postChannel(String channelName, Iterable<Pair<Clan,Integer>> clanList, String message, boolean systemMsg)
{
MOB talker;
if(clanList != null)
{
talker=CMClass.getFactoryMOB();
talker.setName("^</B^>");
talker.setLocation(CMLib.map().getRandomRoom());
talker.basePhyStats().setDisposition(PhyStats.IS_GOLEM);
talker.phyStats().setDisposition(PhyStats.IS_GOLEM);
for(final Pair<Clan,Integer> c : clanList)
talker.setClan(c.first.clanID(),c.second.intValue());
}
else
if(nonClanTalker!=null)
{
talker=nonClanTalker;
}
else
{
talker=CMClass.getFactoryMOB();
talker.setName("^</B^>");
talker.setLocation(CMLib.map().getRandomRoom());
talker.basePhyStats().setDisposition(PhyStats.IS_GOLEM);
talker.phyStats().setDisposition(PhyStats.IS_GOLEM);
nonClanTalker=talker;
}
postChannel(talker,channelName,message,systemMsg);
}
@Override
public boolean postDrop(MOB mob, Environmental dropThis, boolean quiet, boolean optimized, boolean intermediate)
{
return ((Boolean)forceInternalCommand(mob,"Drop",dropThis,Boolean.valueOf(quiet),Boolean.valueOf(optimized),Boolean.valueOf(intermediate))).booleanValue();
}
@Override
public boolean postOpen(MOB mob, Environmental openThis, boolean quiet)
{
return ((Boolean)forceInternalCommand(mob,"Open",openThis,Boolean.valueOf(quiet))).booleanValue();
}
@Override
public boolean postGet(MOB mob, Item container, Item getThis, boolean quiet)
{
if(container==null)
return ((Boolean)forceInternalCommand(mob,"Get",getThis,Boolean.valueOf(quiet))).booleanValue();
return ((Boolean)forceInternalCommand(mob,"Get",getThis,container,Boolean.valueOf(quiet))).booleanValue();
}
@Override
public boolean postRemove(MOB mob, Item item, boolean quiet)
{
return ((Boolean)forceInternalCommand(mob,"Remove",item,Boolean.valueOf(quiet))).booleanValue();
}
@Override
public void postLook(MOB mob, boolean quiet)
{
if(quiet)
forceStandardCommand(mob,"Look",new XVector<String>("LOOK","UNOBTRUSIVELY"));
else
forceStandardCommand(mob,"Look",new XVector<String>("LOOK"));
}
@Override
public void postRead(MOB mob, Physical target, String readOff, boolean quiet)
{
forceInternalCommand(mob,"Read",target,readOff,Boolean.valueOf(quiet));
}
@Override
public void postFlee(MOB mob, String whereTo)
{
forceStandardCommand(mob,"Flee",new XVector<String>("FLEE",whereTo));
}
@Override
public void postSheath(MOB mob, boolean ifPossible)
{
if(ifPossible)
forceStandardCommand(mob,"Sheath",new XVector<String>("SHEATH","IFPOSSIBLE"));
else
forceStandardCommand(mob,"Sheath",new XVector<String>("SHEATH"));
}
@Override
public void postDraw(MOB mob, boolean doHold, boolean ifNecessary)
{
if(ifNecessary)
{
if(doHold)
forceStandardCommand(mob,"Draw",new XVector<String>("DRAW","HELD","IFNECESSARY"));
else
forceStandardCommand(mob,"Draw",new XVector<String>("DRAW","IFNECESSARY"));
}
else
forceStandardCommand(mob,"Draw",new XVector<String>("DRAW"));
}
@Override
public void postStand(MOB mob, boolean ifNecessary)
{
if(ifNecessary)
forceStandardCommand(mob,"Stand",new XVector<String>("STAND","IFNECESSARY"));
else
forceStandardCommand(mob,"Stand",new XVector<String>("STAND"));
}
@Override
public void postSleep(MOB mob)
{
forceStandardCommand(mob,"Sleep",new XVector<String>("SLEEP"));
}
@Override
public void postFollow(MOB follower, MOB leader, boolean quiet)
{
if(leader!=null)
{
forceInternalCommand(follower,"Follow",leader,Boolean.valueOf(quiet));
}
else
{
if(quiet)
forceStandardCommand(follower,"Follow",new XVector<String>("FOLLOW","SELF","UNOBTRUSIVELY"));
else
forceStandardCommand(follower,"Follow",new XVector<String>("FOLLOW","SELF"));
}
}
@Override
public void postSay(MOB mob, MOB target,String text)
{
postSay(mob,target,text,false,false);
}
@Override
public void postSay(MOB mob, String text)
{
postSay(mob,null,text,false,false);
}
@Override
public void postSay(MOB mob, MOB target, String text, boolean isPrivate, boolean tellFlag)
{
Room location=mob.location();
text=CMProps.applyINIFilter(text,CMProps.Str.SAYFILTER);
if(target!=null)
location=target.location();
if(location==null)
return;
if((isPrivate)&&(target!=null))
{
if(tellFlag)
{
String targetName=target.name();
if(targetName.indexOf('@')>=0)
{
final String mudName=targetName.substring(targetName.indexOf('@')+1);
targetName=targetName.substring(0,targetName.indexOf('@'));
if((!(CMLib.intermud().i3online()))&&(!(CMLib.intermud().imc2online())))
mob.tell(L("Intermud is unavailable."));
else
CMLib.intermud().i3tell(mob,targetName,mudName,text);
}
else
{
final boolean ignore=((target.playerStats()!=null)&&(target.playerStats().getIgnored().contains(mob.Name())));
CMMsg msg=null;
if((!CMLib.flags().isSeeable(mob))||(!CMLib.flags().isSeeable(target)))
msg=CMClass.getMsg(mob,target,null,CMMsg.MSG_TELL,L("^t^<TELL \"@x1\"^>You tell <T-NAME> '@x2'^</TELL^>^?^.",CMStrings.removeColors(target.name(mob)),text),CMMsg.MSG_TELL,L("^t^<TELL \"@x1\"^><S-NAME> tell(s) you '@x2'^</TELL^>^?^.",CMStrings.removeColors(mob.name(target)),text),CMMsg.NO_EFFECT,null);
else
msg=CMClass.getMsg(mob,target,null,CMMsg.MSG_TELL,L("^t^<TELL \"@x1\"^>You tell @x2 '@x3'^</TELL^>^?^.",CMStrings.removeColors(target.name(mob)),target.name(mob),text),CMMsg.MSG_TELL,L("^t^<TELL \"@x1\"^>@x2 tell(s) you '@x3'^</TELL^>^?^.",CMStrings.removeColors(mob.name(target)),mob.Name(),text),CMMsg.NO_EFFECT,null);
if((mob.location().okMessage(mob,msg))
&&((ignore)||(target.okMessage(target,msg))))
{
if((mob.session()!=null)&&(mob.session().getClientTelnetMode(Session.TELNET_GMCP)))
{
mob.session().sendGMCPEvent("comm.channel", "{\"chan\":\"tell\",\"msg\":\""+
MiniJSON.toJSONString(CMLib.coffeeFilter().fullOutFilter(null, mob, mob, target, null, CMStrings.removeColors(msg.sourceMessage()), false))
+"\",\"player\":\""+mob.name(target)+"\"}");
}
mob.executeMsg(mob,msg);
if((mob!=target)&&(!ignore))
{
if((target.session()!=null)&&(target.session().getClientTelnetMode(Session.TELNET_GMCP)))
{
target.session().sendGMCPEvent("comm.channel", "{\"chan\":\"tell\",\"msg\":\""+
MiniJSON.toJSONString(CMLib.coffeeFilter().fullOutFilter(null, target, mob, target, null, CMStrings.removeColors(msg.targetMessage()), false))
+"\",\"player\":\""+mob.name(target)+"\"}");
}
target.executeMsg(target,msg);
if(msg.trailerMsgs()!=null)
{
for(final CMMsg msg2 : msg.trailerMsgs())
if((msg!=msg2)&&(target.okMessage(target,msg2)))
target.executeMsg(target,msg2);
msg.trailerMsgs().clear();
}
if((!mob.isMonster())&&(!target.isMonster()))
{
if(mob.playerStats()!=null)
{
mob.playerStats().setReplyTo(target,PlayerStats.REPLY_TELL);
mob.playerStats().addTellStack(CMLib.coffeeFilter().fullOutFilter(mob.session(),mob,mob,target,null,CMStrings.removeColors(msg.sourceMessage()),false));
}
if(target.playerStats()!=null)
{
target.playerStats().setReplyTo(mob,PlayerStats.REPLY_TELL);
String str=msg.targetMessage();
if((msg.tool() instanceof Ability)
&&((((Ability)msg.tool()).classificationCode() & Ability.ALL_ACODES)==Ability.ACODE_LANGUAGE)
&&(target.fetchEffect(msg.tool().ID()) != null))
str=CMStrings.substituteSayInMessage(str,CMStrings.getSayFromMessage(msg.sourceMessage()));
target.playerStats().addTellStack(CMLib.coffeeFilter().fullOutFilter(target.session(),target,mob,target,null,CMStrings.removeColors(str),false));
}
}
}
}
}
}
else
{
final CMMsg msg=CMClass.getMsg(mob,target,null,CMMsg.MSG_SPEAK,L("^T^<SAY \"@x1\"^><S-NAME> say(s) '@x2' to <T-NAMESELF>.^</SAY^>^?",CMStrings.removeColors(target.name(mob)),text),CMMsg.MSG_SPEAK,L("^T^<SAY \"@x1\"^><S-NAME> say(s) '@x2' to <T-NAMESELF>.^</SAY^>^?",CMStrings.removeColors(mob.name(target)),text),CMMsg.NO_EFFECT,null);
gmcpSaySend("say",mob, target, msg);
if(location.okMessage(mob,msg))
location.send(mob,msg);
}
}
else
if(!isPrivate)
{
final String str=L("<S-NAME> say(s) '@x1'"+((target==null)?"^</SAY^>":" to <T-NAMESELF>.^</SAY^>^?"),text);
final CMMsg msg=CMClass.getMsg(mob,target,null,CMMsg.MSG_SPEAK,"^T^<SAY \""+CMStrings.removeColors((target==null)?mob.name(target):target.name(mob))+"\"^>"+str,"^T^<SAY \""
+CMStrings.removeColors(mob.name(target))+"\"^>"+str,"^T^<SAY \""+CMStrings.removeColors(mob.name(target))+"\"^>"+str);
gmcpSaySend("say",mob, target, msg);
if(location.okMessage(mob,msg))
location.send(mob,msg);
}
}
protected void gmcpSaySend(String sayName, MOB mob, MOB target, CMMsg msg)
{
if((mob.session()!=null)&&(mob.session().getClientTelnetMode(Session.TELNET_GMCP)))
{
mob.session().sendGMCPEvent("comm.channel", "{\"chan\":\""+sayName+"\",\"msg\":\""+
MiniJSON.toJSONString(CMLib.coffeeFilter().fullOutFilter(null, mob, mob, target, null, CMStrings.removeColors(msg.sourceMessage()), false))
+"\",\"player\":\""+mob.name(target)+"\"}");
}
final Room R=mob.location();
if(R!=null)
for(int i=0;i<R.numInhabitants();i++)
{
final MOB M=R.fetchInhabitant(i);
if((M!=null)&&(M!=msg.source())&&(M.session()!=null)&&(M.session().getClientTelnetMode(Session.TELNET_GMCP)))
{
M.session().sendGMCPEvent("comm.channel", "{\"chan\":\""+sayName+"\",\"msg\":\""+
MiniJSON.toJSONString(CMLib.coffeeFilter().fullOutFilter(null, M, mob, target, null, CMStrings.removeColors(msg.othersMessage()), false))
+"\",\"player\":\""+mob.name(target)+"\"}");
}
}
}
@Override
public void handleBeingSniffed(CMMsg msg)
{
if(msg.target() instanceof Room)
handleBeingRoomSniffed(msg);
else
if(msg.target() instanceof Item)
handleBeingItemSniffed(msg);
else
if(msg.target() instanceof MOB)
handleBeingMobSniffed(msg);
}
public void handleBeingMobSniffed(CMMsg msg)
{
if(!(msg.target() instanceof MOB))
return;
final MOB sniffingmob=msg.source();
final MOB sniffedmob=(MOB)msg.target();
if((sniffedmob.playerStats()!=null)
&&(sniffedmob.soulMate()==null)
&&(sniffedmob.playerStats().getHygiene()>=PlayerStats.HYGIENE_DELIMIT))
{
final int x=(int)(sniffedmob.playerStats().getHygiene()/PlayerStats.HYGIENE_DELIMIT);
if(x<=1)
sniffingmob.tell(L("@x1 has a slight aroma about @x2.",sniffedmob.name(sniffingmob),sniffedmob.charStats().himher()));
else
if(x<=3)
sniffingmob.tell(L("@x1 smells pretty sweaty.",sniffedmob.name(sniffingmob)));
else
if(x<=7)
sniffingmob.tell(L("@x1 stinks pretty bad.",sniffedmob.name(sniffingmob)));
else
if(x<15)
sniffingmob.tell(L("@x1 smells most foul.",sniffedmob.name(sniffingmob)));
else
sniffingmob.tell(L("@x1 reeks of noxious odors.",sniffedmob.name(sniffingmob)));
}
}
@Override
public void handleObserveComesToLife(MOB observer, MOB lifer, CMMsg msg)
{
}
@Override
public void handleComeToLife(MOB mob, CMMsg msg)
{
}
@Override
public void handleSit(CMMsg msg)
{
final MOB sittingmob=msg.source();
int oldDisposition=sittingmob.basePhyStats().disposition();
oldDisposition=oldDisposition&(~(PhyStats.IS_SLEEPING|PhyStats.IS_SNEAKING|PhyStats.IS_SITTING|PhyStats.IS_CUSTOM));
sittingmob.basePhyStats().setDisposition(oldDisposition|PhyStats.IS_SITTING);
sittingmob.recoverPhyStats();
sittingmob.recoverCharStats();
sittingmob.recoverMaxState();
sittingmob.tell(sittingmob,msg.target(),msg.tool(),msg.sourceMessage());
}
@Override
public void handleSleep(CMMsg msg)
{
final MOB sleepingmob=msg.source();
int oldDisposition=sleepingmob.basePhyStats().disposition();
oldDisposition=oldDisposition&(~(PhyStats.IS_SLEEPING|PhyStats.IS_SNEAKING|PhyStats.IS_SITTING|PhyStats.IS_CUSTOM));
sleepingmob.basePhyStats().setDisposition(oldDisposition|PhyStats.IS_SLEEPING);
sleepingmob.recoverPhyStats();
sleepingmob.recoverCharStats();
sleepingmob.recoverMaxState();
sleepingmob.tell(sleepingmob,msg.target(),msg.tool(),msg.sourceMessage());
}
@Override
public void handleStand(CMMsg msg)
{
final MOB standingmob=msg.source();
int oldDisposition=standingmob.basePhyStats().disposition();
oldDisposition=oldDisposition&(~(PhyStats.IS_SLEEPING|PhyStats.IS_SNEAKING|PhyStats.IS_SITTING|PhyStats.IS_CUSTOM));
standingmob.basePhyStats().setDisposition(oldDisposition);
standingmob.recoverPhyStats();
standingmob.recoverCharStats();
standingmob.recoverMaxState();
standingmob.tell(standingmob,msg.target(),msg.tool(),msg.sourceMessage());
}
@Override
public void handleRecall(CMMsg msg)
{
final MOB recallingmob=msg.source();
if((msg.target() instanceof Room)
&&(recallingmob.location() != msg.target()))
{
recallingmob.tell(msg.source(),null,msg.tool(),msg.targetMessage());
recallingmob.location().delInhabitant(recallingmob);
((Room)msg.target()).addInhabitant(recallingmob);
((Room)msg.target()).showOthers(recallingmob,null,CMMsg.MSG_ENTER,L("<S-NAME> appears out of the Java Plane."));
recallingmob.setLocation(((Room)msg.target()));
if((recallingmob.riding()!=null)
&&(recallingmob.location()!=CMLib.map().roomLocation(recallingmob.riding())))
{
if(recallingmob.riding().mobileRideBasis())
{
if(recallingmob.riding() instanceof Item)
recallingmob.location().moveItemTo((Item)recallingmob.riding(),ItemPossessor.Expire.Never,ItemPossessor.Move.Followers);
else
if(recallingmob.riding() instanceof MOB)
recallingmob.location().bringMobHere((MOB)recallingmob.riding(),true);
}
else
recallingmob.setRiding(null);
}
recallingmob.recoverPhyStats();
recallingmob.recoverCharStats();
recallingmob.recoverMaxState();
postLook(recallingmob,true);
}
}
@Override
public int tickManaConsumption(MOB mob, int manaConsumeCounter)
{
if((CMProps.getIntVar(CMProps.Int.MANACONSUMETIME)>0)
&&(CMProps.getIntVar(CMProps.Int.MANACONSUMEAMT)>0)
&&((--manaConsumeCounter)<=0))
{
final Vector<Ability> expenseAffects=new Vector<Ability>();
manaConsumeCounter=CMProps.getIntVar(CMProps.Int.MANACONSUMETIME);
for(final Enumeration<Ability> a=mob.effects();a.hasMoreElements();)
{
final Ability A=a.nextElement();
if(A!=null)
{
if((!A.isAutoInvoked())
&&(A.canBeUninvoked())
&&(A.displayText().length()>0)
&&(((A.classificationCode()&Ability.ALL_ACODES)==Ability.ACODE_SPELL)
||((A.classificationCode()&Ability.ALL_ACODES)==Ability.ACODE_CHANT)
||((A.classificationCode()&Ability.ALL_ACODES)==Ability.ACODE_SONG)
||((A.classificationCode()&Ability.ALL_ACODES)==Ability.ACODE_PRAYER)))
{
final Ability myA=mob.fetchAbility(A.ID());
if(((myA!=null)&&(myA.usageCost(mob,false)[0]>0))||(A.usageCost(mob, false)[0]>0))
expenseAffects.addElement(A);
}
}
}
if(expenseAffects.size()>0)
{
int basePrice=1;
switch(CMProps.getIntVar(CMProps.Int.MANACONSUMEAMT))
{
case -100:
basePrice = basePrice * mob.phyStats().level();
break;
case -200:
{
int total=0;
for(int a1=0;a1<expenseAffects.size();a1++)
{
final int lql=CMLib.ableMapper().lowestQualifyingLevel(expenseAffects.elementAt(a1).ID());
if(lql>0)
total+=lql;
else
total+=1;
}
basePrice=basePrice*(total/expenseAffects.size());
}
break;
default:
basePrice=basePrice*CMProps.getIntVar(CMProps.Int.MANACONSUMEAMT);
break;
}
// 1 per tick per level per msg. +1 to the affects so that way it's about
// 3 cost = 1 regen... :)
int reallyEat=basePrice*(expenseAffects.size()+1);
while(mob.curState().getMana()<reallyEat)
{
mob.location().show(mob,null,CMMsg.MSG_OK_VISUAL,L("<S-YOUPOSS> strength of will begins to crumble."));
//pick one and kill it
final Ability A=expenseAffects.elementAt(CMLib.dice().roll(1,expenseAffects.size(),-1));
A.unInvoke();
expenseAffects.remove(A);
reallyEat=basePrice*expenseAffects.size();
}
if(reallyEat>0)
mob.curState().adjMana( -reallyEat, mob.maxState());
}
}
return manaConsumeCounter;
}
@Override
public void tickAging(final MOB mob, final long millisSinceLast)
{
if((mob==null)||(CMSecurity.isDisabled(CMSecurity.DisFlag.ALL_AGEING)))
return;
final long minutesEllapsed=(millisSinceLast / 60000);
mob.setAgeMinutes(mob.getAgeMinutes()+minutesEllapsed); // this is really minutes
if((minutesEllapsed>0)
&&((!CMLib.flags().isCloaked(mob))
||(!CMSecurity.isAllowed(mob, mob.location(), CMSecurity.SecFlag.CMDROOMS))))
CMLib.players().bumpPrideStat(mob,AccountStats.PrideStat.MINUTES_ON, (int)minutesEllapsed);
final PlayerStats stats = mob.playerStats();
if(stats==null)
return;
final int[] birthDay = stats.getBirthday();
if((mob.baseCharStats().getStat(CharStats.STAT_AGE)>0)
&&(birthDay!=null))
{
final TimeClock clock=CMLib.time().localClock(mob.getStartRoom());
final int currYear=clock.getYear();
final int month=clock.getMonth();
final int day=clock.getDayOfMonth();
final int bday=birthDay[PlayerStats.BIRTHDEX_DAY];
final int bmonth=birthDay[PlayerStats.BIRTHDEX_MONTH];
while((currYear>birthDay[PlayerStats.BIRTHDEX_LASTYEARCELEBRATED])
||((currYear==birthDay[PlayerStats.BIRTHDEX_LASTYEARCELEBRATED])&&((month>bmonth)||((month==bmonth)&&(day>=bday)))))
{
if(CMSecurity.isAllowed(mob,mob.location(),CMSecurity.SecFlag.IMMORT))
{
birthDay[PlayerStats.BIRTHDEX_YEAR]++;
}
else
{
if((month==bmonth)&&(day==bday))
mob.tell(L("Happy Birthday!"));
mob.baseCharStats().setStat(CharStats.STAT_AGE,mob.baseCharStats().getStat(CharStats.STAT_AGE)+1);
mob.recoverCharStats();
mob.recoverPhyStats();
mob.recoverMaxState();
}
if(CMSecurity.isDisabled(CMSecurity.DisFlag.SLOW_AGEING) || (birthDay[PlayerStats.BIRTHDEX_LASTYEARCELEBRATED]==currYear))
birthDay[PlayerStats.BIRTHDEX_LASTYEARCELEBRATED]++;
else
birthDay[PlayerStats.BIRTHDEX_LASTYEARCELEBRATED]=currYear;
}
if(!CMSecurity.isAllowed(mob,mob.location(),CMSecurity.SecFlag.IMMORT))
{
if((mob.baseCharStats().ageCategory()>=Race.AGE_VENERABLE)
&&(CMLib.dice().rollPercentage()==1)
&&(CMLib.dice().rollPercentage()==1)
&&(!CMSecurity.isDisabled(CMSecurity.DisFlag.AUTODISEASE)))
{
final Ability A=CMClass.getAbility("Disease_Cancer");
if((A!=null)&&(mob.fetchEffect(A.ID())==null))
A.invoke(mob,mob,true,0);
}
else
if((mob.baseCharStats().ageCategory()>=Race.AGE_ANCIENT)
&&(CMLib.dice().rollPercentage()==1)
&&(!CMSecurity.isDisabled(CMSecurity.DisFlag.AUTODISEASE)))
{
final Ability A=CMClass.getAbility("Disease_Arthritis");
if((A!=null)&&(mob.fetchEffect(A.ID())==null))
A.invoke(mob,mob,true,0);
}
else
if((mob.baseCharStats().ageCategory()>=Race.AGE_ANCIENT)
&&(CMLib.dice().rollPercentage()==1)
&&(!CMSecurity.isDisabled(CMSecurity.DisFlag.AUTODISEASE)))
{
final Ability A=CMClass.getAbility("Disease_Alzheimers");
if((A!=null)&&(mob.fetchEffect(A.ID())==null))
A.invoke(mob,mob,true,0);
}
else
if(CMLib.dice().rollPercentage()<10)
{
final int max=CMProps.getIntVar(CMProps.Int.BASEMAXSTAT);
for(final int i: CharStats.CODES.MAXCODES())
{
if((max+mob.charStats().getStat(i))<=0)
{
mob.tell(L("Your max @x1 has fallen below 1!",CharStats.CODES.DESC(CharStats.CODES.toMAXBASE(i)).toLowerCase()));
CMLib.combat().postDeath(null,mob,null);
break;
}
}
}
}
}
}
protected String relativeCharStatTest(CharStats C, MOB mob, String weakword, String strongword, int stat)
{
final double d=CMath.div(C.getStat(stat),mob.charStats().getStat(stat));
String prepend="";
if((d<=0.5)||(d>=3.0))
prepend="much ";
if(d>=1.6)
return mob.charStats().HeShe()+" appears "+prepend+weakword+" than the average "+mob.charStats().raceName()+".\n\r";
if(d<=0.67)
return mob.charStats().HeShe()+" appears "+prepend+strongword+" than the average "+mob.charStats().raceName()+".\n\r";
return "";
}
@Override
public void handleBeingLookedAt(CMMsg msg)
{
if(msg.target() instanceof Room)
handleBeingRoomLookedAt(msg);
else
if(msg.target() instanceof Item)
handleBeingItemLookedAt(msg);
else
if(msg.target() instanceof MOB)
handleBeingMobLookedAt(msg);
else
if(msg.target() instanceof Exit)
handleBeingExitLookedAt(msg);
}
public String examineItemString(MOB mob, Item item)
{
final StringBuilder response=new StringBuilder("");
String level=null;
if((mob!=null)&&(mob.charStats().getStat(CharStats.STAT_INTELLIGENCE)<10))
{
final int l=(int)Math.round(Math.floor(CMath.div(item.phyStats().level(),10.0)));
level=(l*10)+"-"+((l*10)+9);
}
else
if((mob!=null)&&(mob.charStats().getStat(CharStats.STAT_INTELLIGENCE)<18))
{
final int l=(int)Math.round(Math.floor(CMath.div(item.phyStats().level(),5.0)));
level=(l*5)+"-"+((l*5)+4);
}
else
level=""+item.phyStats().level();
double divider=100.0;
if(item.phyStats().weight()<10)
divider=4.0;
else
if(item.phyStats().weight()<50)
divider=10.0;
else
if(item.phyStats().weight()<150)
divider=20.0;
String weight=null;
if((mob!=null)&&(mob.charStats().getStat(CharStats.STAT_INTELLIGENCE)<10))
{
final double l=Math.floor(CMath.div(item.phyStats().level(),divider));
weight=(int)Math.round(CMath.mul(l,divider))+"-"+(int)Math.round(CMath.mul(l,divider)+(divider-1.0));
}
else
if((mob!=null)&&(mob.charStats().getStat(CharStats.STAT_INTELLIGENCE)<18))
{
divider=divider/2.0;
final double l=Math.floor(CMath.div(item.phyStats().level(),divider));
weight=(int)Math.round(CMath.mul(l,divider))+"-"+(int)Math.round(CMath.mul(l,divider)+(divider-1.0));
}
else
weight=""+item.phyStats().weight();
if(item instanceof CagedAnimal)
{
final MOB M=((CagedAnimal)item).unCageMe();
if(M==null)
response.append(L("\n\rLooks like some sort of lifeless thing.\n\r"));
else
{
if(M.phyStats().height()>0)
response.append(L("\n\r@x1 is @x2 inches tall and weighs @x3 pounds.\n\r",CMStrings.capitalizeFirstLetter(item.name()),""+M.phyStats().height(),weight));
if((mob==null)||(!mob.isMonster()))
response.append(CMLib.protocol().mxpImage(M," ALIGN=RIGHT H=70 W=70"));
response.append(M.healthText(mob)+"\n\r\n\r");
if(!M.description().equalsIgnoreCase(item.description()))
response.append(M.description(mob)+"\n\r\n\r");
}
}
else
{
response.append(L("\n\r@x1 is a level @x2 item, and weighs @x3 pounds. ",CMStrings.capitalizeFirstLetter(item.name(mob)),level,weight));
if((item instanceof RawMaterial)
&&(!CMLib.flags().isABonusItems(item))
&&(item.rawSecretIdentity().length()>0)
&&(item.basePhyStats().weight()>1)
&&((mob==null)||(mob.charStats().getStat(CharStats.STAT_INTELLIGENCE)>3)))
response.append(L("It appears to be a bundle of `@x1`. ",item.rawSecretIdentity()));
if((mob!=null)&&(mob.charStats().getStat(CharStats.STAT_INTELLIGENCE)<10))
response.append(L("It is mostly made of a kind of @x1. ",RawMaterial.Material.findByMask(item.material()&RawMaterial.MATERIAL_MASK).noun()));
else
response.append(L("It is mostly made of @x1. ",RawMaterial.CODES.NAME(item.material()).toLowerCase()));
if((item instanceof Recipe)&&((Recipe)item).getTotalRecipePages()>1)
response.append( L("There are @x1 blank pages/entries remaining. ",""+((Recipe)item).getTotalRecipePages()));
if(item instanceof Ammunition)
response.append(L("It is @x1 ammunition of type '@x2'. ",""+((Ammunition)item).ammunitionRemaining(),((Ammunition)item).ammunitionType()));
else
if(item instanceof Weapon)
{
if((mob==null)||mob.charStats().getStat(CharStats.STAT_INTELLIGENCE)>10)
{
response.append(L("It is a "));
if((item.rawLogicalAnd())&&CMath.bset(item.rawProperLocationBitmap(),Wearable.WORN_WIELD|Wearable.WORN_HELD))
response.append(L("two handed "));
else
response.append(L("one handed "));
response.append(L("@x1 class weapon that does @x2 damage. ",CMStrings.capitalizeAndLower(Weapon.CLASS_DESCS[((Weapon)item).weaponClassification()]),CMStrings.capitalizeAndLower(Weapon.TYPE_DESCS[((Weapon)item).weaponDamageType()])));
}
if((item instanceof AmmunitionWeapon) && ((AmmunitionWeapon)item).requiresAmmunition())
response.append(L("It requires ammunition of type '@x1'. ",((AmmunitionWeapon)item).ammunitionType()));
}
else
if((item instanceof Armor)
&&((mob==null)||mob.charStats().getStat(CharStats.STAT_INTELLIGENCE)>10))
{
if(item.phyStats().height()>0)
response.append(L(" It is a size @x1, and is ",""+item.phyStats().height()));
else
response.append(L(" It is your size, and is "));
response.append(((item.rawProperLocationBitmap()==Wearable.WORN_HELD)||(item.rawProperLocationBitmap()==(Wearable.WORN_HELD|Wearable.WORN_WIELD)))
?new StringBuilder("")
:new StringBuilder("worn on the "));
final Wearable.CODES codes = Wearable.CODES.instance();
for(final long wornCode : codes.all())
{
if((wornCode != Wearable.IN_INVENTORY)
&&(CMath.bset(item.rawProperLocationBitmap(),wornCode)))
{
final String wornString=codes.name(wornCode);
if(wornString.length()>0)
{
response.append(CMStrings.capitalizeAndLower(wornString)+" ");
if(item.rawLogicalAnd())
response.append(L("and "));
else
response.append(L("or "));
}
}
}
if(response.toString().endsWith(" and "))
response.delete(response.length()-5,response.length());
else
if(response.toString().endsWith(" or "))
response.delete(response.length()-4,response.length());
response.append(". ");
}
}
return response.toString();
}
protected String dispossessionTimeLeftString(Item item)
{
if(item.expirationDate()==0)
return "N/A";
if(item.expirationDate() > System.currentTimeMillis())
return "*IMMINENT*";
return ""+CMLib.time().date2EllapsedTime((item.expirationDate()-System.currentTimeMillis()), TimeUnit.MINUTES, false);
}
protected void handleBeingItemLookedAt(CMMsg msg)
{
final MOB mob=msg.source();
final Item item=(Item)msg.target();
if(!CMLib.flags().canBeSeenBy(item,mob))
{
mob.tell(L("You can't see that!"));
return;
}
final StringBuilder buf=new StringBuilder("");
if(mob.isAttributeSet(MOB.Attrib.SYSOPMSGS))
{
buf.append(L("@x1\n\r"
+ "Rejuv : @x2\n\r"
+ "Type : @x3\n\r"
+ "Uses : @x4\n\r"
+ "Height: @x5\n\r"
+ "Weight: @x12\n\r"
+ "Abilty: @x6\n\r"
+ "Level : @x7\n\r"
+ "Expire: @x8@x9\n\r"
+ "Misc : @x10\n\r"
+ "@x11",
item.ID(),
""+item.basePhyStats().rejuv(),
item.ID(),
""+item.usesRemaining(),
""+item.basePhyStats().height(),
""+item.basePhyStats().ability(),
""+item.basePhyStats().level(),
dispossessionTimeLeftString(item),
((item instanceof Container)?(L("\n\rCapac.: ")+((Container)item).capacity()):""),
""+item.text().length(),
item.text(),
""+item.basePhyStats().weight()));
}
if(item.description(mob).length()==0)
buf.append(L("You don't see anything special about @x1",item.name()));
else
buf.append(item.description(mob));
if((msg.targetMinor()==CMMsg.TYP_EXAMINE)&&(!item.ID().endsWith("Wallpaper")))
buf.append(examineItemString(mob,item));
if(item instanceof Container)
{
buf.append("\n\r");
final Container contitem=(Container)item;
if((contitem.isOpen())
&&((contitem.capacity()>0)
||(contitem.hasContent())
||((contitem instanceof Drink)&&(((Drink)contitem).liquidRemaining()>0))))
{
buf.append(item.name()+" contains:^<!ENTITY container \""+CMStrings.removeColors(item.name())+"\"^>"+(mob.isAttributeSet(MOB.Attrib.COMPRESS)?" ":"\n\r"));
final Vector<Item> newItems=new Vector<Item>();
if((item instanceof Drink)&&(((Drink)item).liquidRemaining()>0))
{
final RawMaterial l=(RawMaterial)CMClass.getItem("GenLiquidResource");
final int myResource=((Drink)item).liquidType();
l.setMaterial(myResource);
((Drink)l).setLiquidType(myResource);
l.setBaseValue(RawMaterial.CODES.VALUE(myResource));
l.basePhyStats().setWeight(1);
final String name=RawMaterial.CODES.NAME(myResource).toLowerCase();
l.setName(L("some @x1",name));
l.setDisplayText(L("some @x1 sits here.",name));
l.setDescription("");
CMLib.materials().addEffectsToResource(l);
l.recoverPhyStats();
newItems.addElement(l);
}
if(item.owner() instanceof MOB)
{
final MOB M=(MOB)item.owner();
for(int i=0;i<M.numItems();i++)
{
final Item item2=M.getItem(i);
if((item2!=null)&&(item2.container()==item))
newItems.addElement(item2);
}
buf.append(CMLib.lister().lister(mob,newItems,true,"CMItem","",false,mob.isAttributeSet(MOB.Attrib.COMPRESS)));
}
else
if(item.owner() instanceof Room)
{
final Room room=(Room)item.owner();
if(room!=null)
for(int i=0;i<room.numItems();i++)
{
final Item item2=room.getItem(i);
if((item2!=null)&&(item2.container()==item))
newItems.addElement(item2);
}
buf.append(CMLib.lister().lister(mob,newItems,true,"CRItem","",false,mob.isAttributeSet(MOB.Attrib.COMPRESS)));
}
}
else
if((contitem.hasADoor())&&((contitem.capacity()>0)||(contitem.hasContent())))
buf.append(item.name()+" is closed.");
}
if(!msg.source().isMonster())
buf.append(CMLib.protocol().mxpImage(item," ALIGN=RIGHT H=70 W=70"));
mob.tell(buf.toString());
}
protected void handleBeingItemSniffed(CMMsg msg)
{
String s=null;
final Item item=(Item)msg.target();
if(CMLib.flags().canSmell(msg.source()))
s=RawMaterial.CODES.SMELL(item.material()).toLowerCase();
if((s!=null)&&(s.length()>0))
msg.source().tell(msg.source(),item,null,L("<T-NAME> has a @x1 smell.",s));
}
@Override
public void handleIntroductions(MOB speaker, MOB me, String msg)
{
if((me.playerStats()!=null)
&&(speaker!=me)
&&(speaker.playerStats()!=null)
&&(msg!=null)
&&(!me.playerStats().isIntroducedTo(speaker.Name()))
&&(CMLib.english().containsString(CMStrings.getSayFromMessage(msg),speaker.Name())))
me.playerStats().introduceTo(speaker.Name());
}
protected void handleBeingRoomSniffed(CMMsg msg)
{
final Room room=(Room)msg.target();
final StringBuilder smell=new StringBuilder("");
switch(room.domainType())
{
case Room.DOMAIN_INDOORS_UNDERWATER:
case Room.DOMAIN_INDOORS_WATERSURFACE:
case Room.DOMAIN_OUTDOORS_UNDERWATER:
case Room.DOMAIN_OUTDOORS_WATERSURFACE:
smell.append(L("It smells very WET here. "));
break;
case Room.DOMAIN_OUTDOORS_SEAPORT:
smell.append(L("It smells clean, wet, and breezy here. "));
break;
case Room.DOMAIN_INDOORS_CAVE:
smell.append(L("It smells very dank and mildewy here. "));
break;
case Room.DOMAIN_OUTDOORS_HILLS:
case Room.DOMAIN_OUTDOORS_PLAINS:
switch(room.getArea().getTimeObj().getSeasonCode())
{
case FALL:
case WINTER:
smell.append(L("There is a faint grassy smell here. "));
break;
case SPRING:
case SUMMER:
smell.append(L("There is a floral grassy smell here. "));
break;
}
break;
case Room.DOMAIN_OUTDOORS_WOODS:
switch(room.getArea().getTimeObj().getSeasonCode())
{
case FALL:
case WINTER:
smell.append(L("There is a faint woodsy smell here. "));
break;
case SPRING:
case SUMMER:
smell.append(L("There is a rich woodsy smell here. "));
break;
}
break;
case Room.DOMAIN_OUTDOORS_JUNGLE:
smell.append(L("There is a rich floral and plant aroma here. "));
break;
case Room.DOMAIN_OUTDOORS_MOUNTAINS:
case Room.DOMAIN_OUTDOORS_ROCKS:
switch(room.getArea().getTimeObj().getSeasonCode())
{
case FALL:
case WINTER:
case SUMMER:
smell.append(L("It smells musty and rocky here. "));
break;
case SPRING:
smell.append(L("It smells musty, rocky, and a bit grassy here. "));
break;
}
break;
case Room.DOMAIN_OUTDOORS_SWAMP:
smell.append(L("It smells stinky and gassy here. "));
break;
}
if(smell.length()>0)
msg.source().tell(smell.toString());
}
protected void handleBeingRoomLookedAt(CMMsg msg)
{
final MOB mob=msg.source();
final Session sess = mob.session();
if(sess==null)
return; // no need for monsters to build all this data
final Room room=(Room)msg.target();
int lookCode=LOOK_LONG;
if(msg.targetMinor()!=CMMsg.TYP_EXAMINE)
lookCode=(msg.sourceMessage()==null)?LOOK_BRIEFOK:LOOK_NORMAL;
final StringBuilder finalLookStr=new StringBuilder("");
boolean sysmsgs=mob.isAttributeSet(MOB.Attrib.SYSOPMSGS);
final boolean compress=mob.isAttributeSet(MOB.Attrib.COMPRESS) || (CMath.bset(room.phyStats().sensesMask(), PhyStats.SENSE_ALWAYSCOMPRESSED));
if(sysmsgs && (!CMSecurity.isAllowed(mob,room,CMSecurity.SecFlag.SYSMSGS)))
{
mob.setAttribute(MOB.Attrib.SYSOPMSGS,false);
sysmsgs=false;
}
if(sysmsgs)
{
if(room.getArea()!=null)
finalLookStr.append("^!Area :^N "+room.getArea().Name()+"\n\r");
final String rscName=room.myResource()>=0?RawMaterial.CODES.NAME(room.myResource()):"";
final String domType;
final StringBuilder domCond=new StringBuilder("");
if((room.domainType()&Room.INDOORS)==0)
domType=Room.DOMAIN_OUTDOOR_DESCS[room.domainType()];
else
domType=Room.DOMAIN_INDOORS_DESCS[CMath.unsetb(room.domainType(),Room.INDOORS)];
final int climateType=room.getClimateType();
if(CMath.bset(climateType, Places.CLIMASK_COLD))
domCond.append(" cold");
if(CMath.bset(climateType, Places.CLIMASK_WET))
domCond.append(" wet");
if(CMath.bset(climateType, Places.CLIMASK_HOT))
domCond.append(" hot");
if(CMath.bset(climateType, Places.CLIMASK_DRY))
domCond.append(" dry");
if(CMath.bset(climateType, Places.CLIMASK_WINDY))
domCond.append(" windy");
finalLookStr.append("^!RoomID:^N "+CMLib.map().getExtendedRoomID(room)+"\n\r"
+ "^!"+room.ID()+"^N: "+domType+" "+domCond.toString()+" <"+rscName+"> "+room.basePhyStats().weight()+"mv \n\r");
}
if(CMLib.flags().canBeSeenBy(room,mob))
{
finalLookStr.append("^O^<RName^>" + room.displayText(mob)+"^</RName^>"+CMLib.flags().getDispositionBlurbs(room,mob)+"^L\n\r");
if((lookCode!=LOOK_BRIEFOK)||(!mob.isAttributeSet(MOB.Attrib.BRIEF)))
{
String roomDesc=room.description(mob);
if(lookCode==LOOK_LONG)
{
Vector<String> keyWords=null;
String word=null;
int x=0;
for(int c=0;c<room.numItems();c++)
{
final Item item=room.getItem(c);
if(item==null)
continue;
if((item.container()==null)
&&(item.displayText(mob).length()==0)
&&(CMLib.flags().canBeSeenBy(item,mob)))
{
keyWords=CMParms.parse(item.name().toUpperCase());
for(int k=0;k<keyWords.size();k++)
{
word=keyWords.elementAt(k);
x=roomDesc.toUpperCase().indexOf(word);
while(x>=0)
{
if(((x<=0)
||((!Character.isLetterOrDigit(roomDesc.charAt(x-1)))&&(roomDesc.charAt(x-1)!='>')))
&&(((x+word.length())>=(roomDesc.length()-1))
||((!Character.isLetterOrDigit(roomDesc.charAt((x+word.length()))))&&(roomDesc.charAt(x+word.length())!='^'))))
{
final int brackCheck=roomDesc.substring(x).indexOf("^>");
final int brackCheck2=roomDesc.substring(x).indexOf("^<");
if((brackCheck<0)||(brackCheck2<brackCheck))
{
int start=x;
while((start>=0)&&(!Character.isWhitespace(roomDesc.charAt(start))))
start--;
start++;
int end=(x+word.length());
while((end<roomDesc.length())&&(!Character.isWhitespace(roomDesc.charAt(end))))
end++;
final int l=roomDesc.length();
roomDesc=roomDesc.substring(0,start)+"^H^<WItem \""+CMStrings.removeColors(item.name())+"\"^>"+roomDesc.substring(start,end)+"^</WItem^>^?"+roomDesc.substring(end);
x=x+(roomDesc.length()-l);
}
}
x=roomDesc.toUpperCase().indexOf(word,x+1);
}
}
}
}
}
if((CMProps.getIntVar(CMProps.Int.EXVIEW)==1)||(CMProps.getIntVar(CMProps.Int.EXVIEW)==2))
roomDesc += getRoomExitsParagraph(mob,room);
finalLookStr.append("^L^<RDesc^>" + roomDesc+"^</RDesc^>");
if((!mob.isMonster())&&(sess.getClientTelnetMode(Session.TELNET_MXP)))
finalLookStr.append(CMLib.protocol().mxpImage(room," ALIGN=RIGHT H=70 W=70"));
if(compress)
finalLookStr.append("^N ");
else
finalLookStr.append("^N\n\r\n\r");
}
}
final Item notItem;
final Room mobLocR=mob.location();
if((mobLocR!=room)
&&(mobLocR!=null)
&&(mobLocR.getArea() instanceof BoardableShip))
notItem=((BoardableShip)mobLocR.getArea()).getShipItem();
else
notItem=null;
final List<Item> viewItems=new ArrayList<Item>(room.numItems());
final List<Item> compressedItems=((compress) || (lookCode==LOOK_LONG)) ? null : new ArrayList<Item>(1);
int itemsInTheDarkness=0;
for(int c=0;c<room.numItems();c++)
{
final Item item=room.getItem(c);
if((item==null)||(item==notItem))
continue;
if(item.container()==null)
{
if(CMLib.flags().canBarelyBeSeenBy(item,mob))
itemsInTheDarkness++;
if((compressedItems!=null)&&(CMath.bset(item.phyStats().sensesMask(), PhyStats.SENSE_ALWAYSCOMPRESSED)))
compressedItems.add(item);
else
viewItems.add(item);
}
}
if((compressedItems != null) && (compressedItems.size()>0))
{
final StringBuilder itemStr=CMLib.lister().lister(mob,compressedItems,false,"RItem"," \"*\"",false,true);
if(itemStr.length()>0)
finalLookStr.append(itemStr).append("\n\r\n\r");
}
final StringBuilder itemStr=CMLib.lister().lister(mob,viewItems,false,"RItem"," \"*\"",lookCode==LOOK_LONG,compress);
if(itemStr.length()>0)
finalLookStr.append(itemStr);
int mobsInTheDarkness=0;
for(int i=0;i<room.numInhabitants();i++)
{
final MOB mob2=room.fetchInhabitant(i);
if((mob2!=null)&&(mob2!=mob))
{
final String displayText=mob2.displayText(mob);
if((displayText.length()>0)
||(sysmsgs))
{
if(CMLib.flags().canBeSeenBy(mob2,mob))
{
if((!compress)&&(!mob.isMonster())&&(sess.getClientTelnetMode(Session.TELNET_MXP)))
finalLookStr.append(CMLib.protocol().mxpImage(mob2," H=10 W=10",""," "));
finalLookStr.append("^M^<RMob \""+CMStrings.removeColors(mob2.name())+"\"^>");
if(compress)
finalLookStr.append(CMLib.flags().getDispositionBlurbs(mob2,mob)+"^M ");
if(displayText.length()>0)
finalLookStr.append(CMStrings.endWithAPeriod(CMStrings.capitalizeFirstLetter(displayText)));
else
finalLookStr.append(CMStrings.endWithAPeriod(CMStrings.capitalizeFirstLetter(mob2.name())));
finalLookStr.append("^</RMob^>");
if(sysmsgs)
finalLookStr.append("^H("+CMClass.classID(mob2)+")^N ");
if(!compress)
finalLookStr.append(CMLib.flags().getDispositionBlurbs(mob2,mob)+"^N\n\r");
else
finalLookStr.append("^N");
}
else
if(CMLib.flags().canBarelyBeSeenBy(mob2,mob))
mobsInTheDarkness++;
}
}
}
if(finalLookStr.length()==0)
mob.tell(L("You can't see anything!"));
else
{
if(compress)
finalLookStr.append("\n\r");
mob.tell(finalLookStr.toString());
if((CMProps.getIntVar(CMProps.Int.AWARERANGE)>0)
&&(!mob.isAttributeSet(MOB.Attrib.AUTOMAP)))
{
if(awarenessA==null)
awarenessA=CMClass.getAbility("Skill_RegionalAwareness");
if(awarenessA!=null)
{
sess.colorOnlyPrintln("", true);
final Vector<String> list=new Vector<String>();
awarenessA.invoke(mob, list, mobLocR, true, CMProps.getIntVar(CMProps.Int.AWARERANGE));
for(final String o : list)
{
sess.setIdleTimers();
sess.colorOnlyPrintln(o, true); // the zero turns off stack
}
sess.colorOnlyPrintln("\n\r", true);
}
}
if(itemsInTheDarkness>0)
mob.tell(L(" ^IThere is something here, but it's too dark to make out.^?\n\r"));
if(mobsInTheDarkness>1)
mob.tell(L("^MThe darkness conceals several others.^?\n\r"));
else
if(mobsInTheDarkness>0)
mob.tell(L("^MYou are not alone, but it's too dark to tell.^?\n\r"));
}
}
private static String getRoomExitsParagraph(MOB mob, Room room)
{
if(room == null || mob == null)
return "";
final StringBuilder str = new StringBuilder("");
final Vector<Integer> exitDirs=new Vector<Integer>();
Room R;
Exit E;
final boolean useShipNames=((room instanceof BoardableShip)||(room.getArea() instanceof BoardableShip));
for(final int dir : Directions.CODES())
{
E = room.getExitInDir(dir);
R = room.getRoomInDir(dir);
if((R!=null)&&(E!=null)&&(CMLib.flags().canBeSeenBy(E,mob)))
exitDirs.add(Integer.valueOf(dir));
}
final String title = room.displayText(mob);
// do continues first
final Vector<Integer> continues = new Vector<Integer>();
for(int i=exitDirs.size()-1;i>=0;i--)
{
R = room.getRoomInDir(exitDirs.elementAt(i).intValue());
if((R!=null)&&(R.displayText(mob).equalsIgnoreCase(title)))
continues.addElement(exitDirs.remove(i));
}
if(continues.size()>0)
{
str.append(" ^L"+CMStrings.capitalizeFirstLetter(room.displayText(mob)).trim()+" continues ");
if(continues.size()==1)
{
if(useShipNames)
str.append(Directions.getShipInDirectionName(continues.firstElement().intValue())+".");
else
str.append(Directions.getInDirectionName(continues.firstElement().intValue())+".");
}
else
{
for(int i=0;i<continues.size()-1;i++)
{
if(useShipNames)
str.append(Directions.getShipDirectionName(continues.elementAt(i).intValue()).toLowerCase().trim()+", ");
else
str.append(Directions.getDirectionName(continues.elementAt(i).intValue()).toLowerCase().trim()+", ");
}
if(useShipNames)
str.append("and "+Directions.getShipInDirectionName(continues.lastElement().intValue()).trim()+".");
else
str.append("and "+Directions.getInDirectionName(continues.lastElement().intValue()).trim()+".");
}
}
final boolean style=CMLib.dice().rollPercentage()>50;
if(exitDirs.size()>0)
{
str.append(" ^L"+CMStrings.capitalizeFirstLetter(getExitFragment(mob,room,exitDirs.firstElement().intValue(),style)).trim());
if(exitDirs.size()>1)
{
str.append("^L, ");
for(int i=1;i<exitDirs.size()-1;i++)
str.append(getExitFragment(mob,room,exitDirs.elementAt(i).intValue(),style).trim()+"^L, ");
str.append("and "+getExitFragment(mob,room,exitDirs.lastElement().intValue(),style).trim());
}
str.append("^L.");
}
return str.toString();
}
private static String getExitFragment(MOB mob, Room room, int dir, boolean style)
{
if(room==null)
return "";
final Exit exit = room.getExitInDir(dir);
if(exit == null)
return "";
final boolean useShipDirs=(room instanceof BoardableShip)||(room.getArea() instanceof BoardableShip);
final String inDirName=useShipDirs?Directions.getShipInDirectionName(dir):Directions.getInDirectionName(dir);
if(style)
return inDirName + " is " +exit.viewableText(mob, room.getRoomInDir(dir));
else
return exit.viewableText(mob, room.getRoomInDir(dir)).toString().trim() +" is " + inDirName;
}
@Override
public boolean isHygienicMessage(final CMMsg msg, final int minHygiene, final long adjHygiene)
{
if(CMSecurity.isDisabled(CMSecurity.DisFlag.HYGIENE))
return false;
if((msg.sourceMajor(CMMsg.MASK_MOVE)
&&((msg.tool()==null)
||(!(msg.tool() instanceof Ability))
||((((Ability)msg.tool()).classificationCode()&Ability.ALL_ACODES)!=Ability.ACODE_COMMON_SKILL)))
||((msg.tool() instanceof Social)
&&((msg.tool().Name().toUpperCase().startsWith("BATHE"))
||(msg.tool().Name().toUpperCase().startsWith("WASH")))))
return (msg.source().playerStats()!=null)&&(msg.source().soulMate()==null);
return false;
}
@Override
public void handleHygienicMessage(final CMMsg msg, final int minHygiene, final long adjHygiene)
{
if(isHygienicMessage(msg,minHygiene,adjHygiene))
{
final MOB mob=msg.source();
if(mob.playerStats().getHygiene()>(-adjHygiene))
{
mob.playerStats().adjHygiene(adjHygiene);
if(mob.playerStats().getHygiene()>(PlayerStats.HYGIENE_DELIMIT/2))
mob.tell(L("You feel a little cleaner, but are still very dirty."));
else
if(mob.playerStats().getHygiene()<1500)
mob.tell(L("You feel a little cleaner; almost perfect."));
else
mob.tell(L("You feel a little cleaner."));
}
else
if(adjHygiene==0)
mob.tell(L("You are already perfectly clean."));
else
if((msg.sourceMinor()!=CMMsg.TYP_NOISYMOVEMENT)
||(mob.riding()!=null)
||(CMLib.flags().isWateryRoom(mob.location())))
{
final long h=mob.playerStats().getHygiene();
if((h>0)
&&(h<minHygiene)
&&(msg.sourceMinor()!=CMMsg.TYP_LEAVE)
&&((!CMLib.flags().isFlying(mob))
||(mob.location().domainType()==Room.DOMAIN_INDOORS_UNDERWATER)
||(mob.location().domainType()==Room.DOMAIN_OUTDOORS_UNDERWATER)))
{
mob.playerStats().adjHygiene(-h);
mob.tell(L("You can't get any cleaner here."));
}
}
}
}
private static boolean isAClearExitView(MOB mob, Room room, Exit exit)
{
if((room!=null)
&&(exit!=null)
&&(exit.isOpen())
&&(CMLib.flags().canBeSeenBy(room,mob))
&&(CMLib.flags().canBeSeenBy(exit,mob)))
{
final int domain=room.domainType();
switch(domain)
{
case Room.DOMAIN_INDOORS_AIR:
case Room.DOMAIN_INDOORS_UNDERWATER:
case Room.DOMAIN_OUTDOORS_AIR:
case Room.DOMAIN_OUTDOORS_UNDERWATER:
{
final int weather=room.getArea().getClimateObj().weatherType(room);
if((weather!=Climate.WEATHER_BLIZZARD)&&(weather!=Climate.WEATHER_DUSTSTORM))
return true;
break;
}
}
}
return false;
}
protected void handleBeingExitLookedAt(CMMsg msg)
{
final Exit exit=(Exit)msg.target();
final MOB mob=msg.source();
if(CMLib.flags().canBeSeenBy(exit,mob))
{
if(exit.description(mob).trim().length()>0)
mob.tell(exit.description(mob));
else
if(mob.location()!=null)
{
Room room=null;
int direction=-1;
if(msg.tool() instanceof Room)
room=(Room)msg.tool();
else
for(int d=Directions.NUM_DIRECTIONS()-1;d>=0;d--)
{
if(mob.location().getExitInDir(d)==exit)
{
room=mob.location().getRoomInDir(d);
break;
}
}
if(room!=null)
for(int d=Directions.NUM_DIRECTIONS()-1;d>=0;d--)
{
if((mob.location().getRoomInDir(d)==room)
&&((mob.location().getExitInDir(d)==exit)))
direction=d;
}
mob.tell(exit.viewableText(mob,room).toString());
if(isAClearExitView(mob,room,exit)&&(direction>=0)&&(room!=null))
{
List<Room> view=null;
final Vector<Environmental> items=new Vector<Environmental>();
if(room.getGridParent()!=null)
view=room.getGridParent().getAllRooms();
else
{
view=new Vector<Room>();
view.add(room);
for(int i=0;i<5;i++)
{
room=room.getRoomInDir(direction);
if(room==null)
break;
final Exit E=room.getExitInDir(direction);
if((isAClearExitView(mob,room,E)))
view.add(room);
}
}
for(int r=0;r<view.size();r++)
{
room=view.get(r);
for(int i=0;i<room.numItems();i++)
{
final Item E=room.getItem(i);
if(E!=null)
items.add(E);
}
for(int i=0;i<room.numInhabitants();i++)
{
final MOB E=room.fetchInhabitant(i);
if(E!=null)
items.add(E);
}
}
final StringBuilder seenThatWay=CMLib.lister().lister(msg.source(),items,true,"","",false,true);
if(seenThatWay.length()>0)
mob.tell(L("Yonder, you can also see: @x1",seenThatWay.toString()));
}
}
else
mob.tell(L("You don't see anything special."));
if(mob.isAttributeSet(MOB.Attrib.SYSOPMSGS))
{
mob.tell(L("Type : @x1",exit.ID()));
mob.tell(L("Misc : @x1",exit.text()));
}
final String image=CMLib.protocol().mxpImage(exit," ALIGN=RIGHT H=70 W=70");
if((image!=null)&&(image.length()>0))
mob.tell(image);
}
else
mob.tell(L("You can't see that way!"));
}
protected void handleBeingMobLookedAt(CMMsg msg)
{
final MOB viewermob=msg.source();
final MOB viewedmob=(MOB)msg.target();
final boolean longlook=msg.targetMinor()==CMMsg.TYP_EXAMINE;
final StringBuilder myDescription=new StringBuilder("");
if(CMLib.flags().canBeSeenBy(viewedmob,viewermob))
{
if(viewermob.isAttributeSet(MOB.Attrib.SYSOPMSGS))
{
myDescription.append("\n\rType :"+viewedmob.ID()
+"\n\rRejuv:"+viewedmob.basePhyStats().rejuv()
+((!viewedmob.isMonster())?", Hunger="+viewedmob.curState().getHunger():"")
+"\n\rAbile:"+viewedmob.basePhyStats().ability()
+((!viewedmob.isMonster())?", Thirst="+viewedmob.curState().getThirst():"")
+"\n\rLevel:"+viewedmob.basePhyStats().level()
+"\n\rDesc : "+viewedmob.description()
+"\n\rRoom :'"+((viewedmob.getStartRoom()==null)?"null":viewedmob.getStartRoom().roomID())
+"\n\rMisc : "+viewedmob.text()
+"\n\r");
}
if(!viewedmob.isMonster())
{
String levelStr=null;
if((!CMSecurity.isDisabled(CMSecurity.DisFlag.CLASSES))
&&(!viewedmob.charStats().getMyRace().classless())
&&(!viewedmob.charStats().getCurrentClass().leveless())
&&(!viewedmob.charStats().getMyRace().leveless())
&&(!CMSecurity.isDisabled(CMSecurity.DisFlag.LEVELS)))
levelStr=CMLib.english().startWithAorAn(viewedmob.charStats().displayClassLevel(viewedmob,false));
else
if((!CMSecurity.isDisabled(CMSecurity.DisFlag.LEVELS))
&&(!viewedmob.charStats().getCurrentClass().leveless())
&&(!viewedmob.charStats().getMyRace().leveless()))
levelStr="level "+viewedmob.charStats().displayClassLevelOnly(viewedmob);
else
if((!CMSecurity.isDisabled(CMSecurity.DisFlag.CLASSES))
&&(!viewedmob.charStats().getMyRace().classless()))
levelStr=CMLib.english().startWithAorAn(viewedmob.charStats().displayClassName());
if((!CMSecurity.isDisabled(CMSecurity.DisFlag.RACES))
&&(!viewedmob.charStats().getCurrentClass().raceless()))
{
myDescription.append(viewedmob.name(viewermob)+" the ");
if((viewedmob.charStats().getStat(CharStats.STAT_AGE)>0)&&(!CMSecurity.isDisabled(CMSecurity.DisFlag.ALL_AGEING)))
myDescription.append(viewedmob.charStats().ageName().toLowerCase()+" ");
myDescription.append(viewedmob.charStats().raceName());
}
else
myDescription.append(viewedmob.name(viewermob)+" ");
if(levelStr!=null)
myDescription.append(" is "+levelStr+".\n\r");
else
myDescription.append("is here.\n\r");
}
if(viewedmob.phyStats().height()>0)
myDescription.append(viewedmob.charStats().HeShe()+" is "+viewedmob.phyStats().height()+" inches tall and weighs "+viewedmob.basePhyStats().weight()+" pounds.\n\r");
if((longlook)&&(viewermob.charStats().getStat(CharStats.STAT_INTELLIGENCE)>12))
{
final CharStats C=(CharStats)CMClass.getCommon("DefaultCharStats");
final MOB testMOB=CMClass.getFactoryMOB();
viewedmob.charStats().getMyRace().affectCharStats(testMOB,C);
myDescription.append(relativeCharStatTest(C,viewedmob,"weaker","stronger",CharStats.STAT_STRENGTH));
myDescription.append(relativeCharStatTest(C,viewedmob,"clumsier","more nimble",CharStats.STAT_DEXTERITY));
myDescription.append(relativeCharStatTest(C,viewedmob,"more sickly","healthier",CharStats.STAT_CONSTITUTION));
myDescription.append(relativeCharStatTest(C,viewedmob,"more repulsive","more attractive",CharStats.STAT_CHARISMA));
myDescription.append(relativeCharStatTest(C,viewedmob,"more naive","wiser",CharStats.STAT_WISDOM));
myDescription.append(relativeCharStatTest(C,viewedmob,"dumber","smarter",CharStats.STAT_INTELLIGENCE));
testMOB.destroy();
}
if(!viewermob.isMonster())
myDescription.append(CMLib.protocol().mxpImage(viewedmob," ALIGN=RIGHT H=70 W=70"));
myDescription.append(viewedmob.healthText(viewermob)+"\n\r\n\r");
myDescription.append(viewedmob.description(viewermob)+"\n\r\n\r");
final StringBuilder eq=CMLib.commands().getEquipment(viewermob,viewedmob);
if(eq.length() > 0)
{
if((CMProps.getIntVar(CMProps.Int.EQVIEW)>1)
||((viewermob!=viewedmob)&&(CMProps.getIntVar(CMProps.Int.EQVIEW)>0)))
myDescription.append(viewedmob.charStats().HeShe()+" is wearing "+eq.toString());
else
myDescription.append(viewedmob.charStats().HeShe()+" is wearing:\n\r"+eq.toString());
}
viewermob.tell(myDescription.toString());
if(longlook)
{
final Command C=CMClass.getCommand("Consider");
try
{
if (C != null)
C.executeInternal(viewermob, 0, viewedmob);
}
catch (final java.io.IOException e)
{
}
}
}
}
@Override
public void handleBeingGivenTo(CMMsg msg)
{
if(!(msg.target() instanceof MOB))
return;
final MOB givermob=msg.source();
final MOB giveemob=(MOB)msg.target();
if(giveemob.location()!=null)
{
CMMsg msg2=CMClass.getMsg(givermob,msg.tool(),null,CMMsg.MSG_DROP|CMMsg.MASK_INTERMSG,null,CMMsg.MSG_DROP|CMMsg.MASK_INTERMSG,null,CMMsg.MSG_DROP|CMMsg.MASK_INTERMSG,null);
giveemob.location().send(givermob,msg2);
msg2=CMClass.getMsg((MOB)msg.target(),msg.tool(),null,CMMsg.MSG_GET|CMMsg.MASK_INTERMSG,null,CMMsg.MSG_GET|CMMsg.MASK_INTERMSG,null,CMMsg.MSG_GET|CMMsg.MASK_INTERMSG,null);
giveemob.location().send(giveemob,msg2);
}
}
@Override
public void handleBeingRead(CMMsg msg)
{
if((msg.targetMessage()==null)||(!msg.targetMessage().equals("CANCEL")))
{
final MOB mob=msg.source();
if(CMLib.flags().canBeSeenBy(msg.target(),mob))
{
String text=null;
if((msg.target() instanceof Exit)&&(((Exit)msg.target()).isReadable()))
text=((Exit)msg.target()).readableText();
else
if((msg.target() instanceof Item)&&(((Item)msg.target()).isReadable()))
{
final Item targetI=(Item)msg.target();
text=targetI.readableText();
if(((text==null)||(text.length()==0))
&&(targetI.description(mob).length()>0)
&&((targetI.displayText(mob).length()==0)||(!CMLib.flags().isGettable(targetI))))
text=targetI.description(mob);
}
if((text!=null)
&&(text.length()>0))
{
if(text.toUpperCase().startsWith("FILE="))
{
final StringBuffer buf=Resources.getFileResource(text.substring(5),true);
if((buf!=null)&&(buf.length()>0))
mob.tell(L("It says '@x1'.",buf.toString()));
else
if(msg.target() instanceof Electronics)
mob.tell(L("There is nothing on @x1.",((Electronics)msg.target()).name(mob)));
else
if(msg.target() instanceof Physical)
mob.tell(L("There is nothing written on @x1.",((Physical)msg.target()).name(mob)));
else
mob.tell(L("There is nothing written on @x1.",msg.target().name()));
}
else
mob.tell(L("It says '@x1'.",text));
}
else
if(msg.target() instanceof Electronics)
mob.tell(L("There is nothing on @x1.",((Electronics)msg.target()).name(mob)));
else
if(msg.target() instanceof Physical)
mob.tell(L("There is nothing written on @x1.",((Physical)msg.target()).name(mob)));
else
mob.tell(L("There is nothing written on @x1.",msg.target().name()));
}
else
mob.tell(L("You can't see that!"));
}
}
@Override
public void handleBeingGetted(CMMsg msg)
{
if(!(msg.target() instanceof Item))
return;
final Item item=(Item)msg.target();
final MOB mob=msg.source();
final boolean isMine = mob.isMine(item);
if(item instanceof Container)
{
if(msg.tool() instanceof Item)
{
final Item newitem=(Item)msg.tool();
if(newitem.container()==item)
{
newitem.setContainer(null);
newitem.unWear();
}
}
else
if(!isMine)
{
item.setContainer(null);
mob.moveItemTo(item);
if(!isMine)
CMLib.achievements().possiblyBumpAchievement(mob, Event.GOTITEM, 1, item);
if(!CMath.bset(msg.targetMajor(),CMMsg.MASK_OPTIMIZE))
mob.location().recoverRoomStats();
else
mob.phyStats().setWeight(mob.phyStats().weight()+item.recursiveWeight());
}
else
{
item.setContainer(null);
item.unWear();
if(!CMath.bset(msg.targetMajor(),CMMsg.MASK_OPTIMIZE))
mob.location().recoverRoomStats();
}
}
else
{
item.setContainer(null);
if(CMLib.flags().isHidden(item))
item.basePhyStats().setDisposition(item.basePhyStats().disposition()&((int)PhyStats.ALLMASK-PhyStats.IS_HIDDEN));
if(mob.location().isContent(item))
mob.location().delItem(item);
if(!isMine)
{
mob.addItem(item);
if(!isMine)
CMLib.achievements().possiblyBumpAchievement(mob, Event.GOTITEM, 1, item);
if(CMath.bset(msg.targetMajor(),CMMsg.MASK_OPTIMIZE))
mob.phyStats().setWeight(mob.phyStats().weight()+item.phyStats().weight());
}
item.unWear();
if(!CMath.bset(msg.targetMajor(),CMMsg.MASK_OPTIMIZE))
mob.location().recoverRoomStats();
if(item instanceof Coins)
((Coins)item).putCoinsBack();
if(item instanceof RawMaterial)
((RawMaterial)item).rebundle();
}
if(CMLib.flags().isCataloged(item))
CMLib.catalog().bumpDeathPickup(item);
}
@Override
public void handleBeingDropped(CMMsg msg)
{
if(!(msg.target() instanceof Item))
return;
final Item item=(Item)msg.target();
final MOB mob=msg.source();
if(mob.isMine(item)&&(item instanceof Container))
{
item.setContainer(null);
CMLib.utensils().recursiveDropMOB(mob,mob.location(),item,item instanceof DeadBody);
if(!CMath.bset(msg.targetMajor(),CMMsg.MASK_OPTIMIZE))
mob.location().recoverRoomStats();
}
if(mob.isMine(item))
{
mob.delItem(item);
CMLib.achievements().possiblyBumpAchievement(mob, Event.GOTITEM, -1, item);
if(!mob.location().isContent(item))
mob.location().addItem(item,ItemPossessor.Expire.Player_Drop);
if(!CMath.bset(msg.targetMajor(),CMMsg.MASK_OPTIMIZE))
mob.location().recoverRoomStats();
}
item.unWear();
item.setContainer(null);
if(!msg.targetMajor(CMMsg.MASK_INTERMSG))
{
if(item instanceof Coins)
((Coins)item).putCoinsBack();
if(item instanceof RawMaterial)
((RawMaterial)item).rebundle();
}
}
@Override
public void handleBeingRemoved(CMMsg msg)
{
if(!(msg.target() instanceof Item))
return;
final Item item=(Item)msg.target();
final MOB mob=msg.source();
if(item instanceof Container)
{
handleBeingGetted(msg);
return;
}
item.unWear();
if(!CMath.bset(msg.targetMajor(),CMMsg.MASK_OPTIMIZE))
mob.location().recoverRoomStats();
}
@Override
public void handleBeingWorn(CMMsg msg)
{
if(!(msg.target() instanceof Item))
return;
final Item item=(Item)msg.target();
final long wearLocation = (msg.value()<=0)?0:((long)(1<<msg.value())/2);
final MOB mob=msg.source();
if(item.canWear(mob,wearLocation))
{
if(wearLocation<=0)
item.wearIfPossible(mob);
else
item.wearIfPossible(mob,wearLocation);
mob.recoverCharStats();
mob.recoverPhyStats();
mob.recoverMaxState();
}
}
@Override
public void handleBeingWielded(CMMsg msg)
{
if(!(msg.target() instanceof Item))
return;
final Item item=(Item)msg.target();
final MOB mob=msg.source();
if(item.wearIfPossible(mob,Wearable.WORN_WIELD))
{
mob.recoverCharStats();
mob.recoverPhyStats();
mob.recoverMaxState();
}
}
@Override
public void handleBeingHeld(CMMsg msg)
{
if(!(msg.target() instanceof Item))
return;
final Item item=(Item)msg.target();
final MOB mob=msg.source();
if(item.wearIfPossible(mob,Wearable.WORN_HELD))
{
mob.recoverCharStats();
mob.recoverPhyStats();
mob.recoverMaxState();
}
}
@Override
public void lookAtExits(Room room, MOB mob)
{
if((mob==null)
||(room==null)
||(mob.isMonster()))
return;
if(!CMLib.flags().canSee(mob))
{
mob.tell(L("You can't see anything!"));
return;
}
final boolean useShipNames=((room instanceof BoardableShip)||(room.getArea() instanceof BoardableShip));
final StringBuilder buf=new StringBuilder("^DObvious exits:^.^N\n\r");
String Dir=null;
for(int d : Directions.DISPLAY_CODES())
{
final Exit exit=room.getExitInDir(d);
final Room room2=room.getRoomInDir(d);
StringBuilder Say=new StringBuilder("");
if(exit!=null)
Say=exit.viewableText(mob, room2);
else
if((room2!=null)&&(mob.isAttributeSet(MOB.Attrib.SYSOPMSGS)))
Say.append(room2.roomID()+" via NULL");
if(Say.length()>0)
{
Dir=CMStrings.padRightPreserve(useShipNames?Directions.getShipDirectionName(d):Directions.getDirectionName(d),5);
if((mob.playerStats()!=null)
&&(room2!=null)
&&(mob.playerStats().hasVisited(room2)))
buf.append("^D^<EX^>" + Dir+"^</EX^>:^.^N ^d"+Say+"^.^N\n\r");
else
buf.append("^U^<EX^>" + Dir+"^</EX^>:^.^N ^u"+Say+"^.^N\n\r");
}
}
boolean noBoardableShips = false;
if((mob.location() != room)
&&(mob.location() != null)
&&(mob.location().getArea()!=room.getArea())
&&(mob.location().getArea() instanceof BoardableShip))
noBoardableShips = true;
Item I=null;
for(int i=0;i<room.numItems();i++)
{
I=room.getItem(i);
if((I instanceof Exit)
&&(((Exit)I).doorName().length()>0)
&&(I.container()==null)
&&((!(I instanceof BoardableShip))||(!noBoardableShips)))
{
final StringBuilder Say=((Exit)I).viewableText(mob, room);
if(Say.length()>0)
{
Say.append(CMLib.flags().getDispositionBlurbs(I, mob));
if(Say.length()>5)
buf.append("^D^<MEX^>" + ((Exit)I).doorName()+"^</MEX^>:^.^N ^d"+Say+"^.^N\n\r");
else
buf.append("^D^<MEX^>" + CMStrings.padRight(((Exit)I).doorName(),5)+"^</MEX^>:^.^N ^d"+Say+"^.^N\n\r");
}
}
}
mob.tell(buf.toString());
}
@Override
public void lookAtExitsShort(Room room, MOB mob)
{
if((mob==null)||(room==null)||(mob.isMonster()))
return;
if(!CMLib.flags().canSee(mob))
return;
final boolean useShipNames=((room instanceof BoardableShip)||(room.getArea() instanceof BoardableShip));
final StringBuilder buf=new StringBuilder(L("^D[Exits: "));
for(int d : Directions.DISPLAY_CODES())
{
final Exit exit=room.getExitInDir(d);
if((exit!=null)&&(exit.viewableText(mob, room.getRoomInDir(d)).length()>0))
buf.append("^<EX^>"+(useShipNames?Directions.getShipDirectionName(d):Directions.getDirectionName(d))+"^</EX^> ");
}
boolean noBoardableShips = false;
if((mob.location() != room)
&&(mob.location() != null)
&&(mob.location().getArea()!=room.getArea())
&&(mob.location().getArea() instanceof BoardableShip))
noBoardableShips = true;
Item I=null;
for(int i=0;i<room.numItems();i++)
{
I=room.getItem(i);
if((I instanceof Exit)
&&(I.container()==null)
&&(((Exit)I).viewableText(mob, room).length()>0)
&&((!(I instanceof BoardableShip))||(!noBoardableShips)))
buf.append("^<MEX^>"+((Exit)I).doorName()+"^</MEX^> ");
}
mob.tell(buf.toString().trim()+"]^.^N");
}
}