package com.planet_ink.coffee_mud.Behaviors;
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.Locales.interfaces.*;
import com.planet_ink.coffee_mud.Libraries.interfaces.*;
import com.planet_ink.coffee_mud.Libraries.interfaces.AbilityMapper.AbilityMapping;
import com.planet_ink.coffee_mud.Libraries.interfaces.ExpertiseLibrary.ExpertiseDefinition;
import com.planet_ink.coffee_mud.MOBS.interfaces.*;
import com.planet_ink.coffee_mud.Races.interfaces.*;
import java.util.*;
import java.util.Map.Entry;
/*
Copyright 2001-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 MOBTeacher extends CombatAbilities
{
@Override
public String ID()
{
return "MOBTeacher";
}
protected MOB myMOB = null;
protected boolean teachEverything = true;
protected boolean noCommon = false;
protected boolean noExpertises = false; // doubles as a "done ticking" flag
protected boolean noHLExpertises = false;
protected int tickDownToKnowledge = 4;
protected List<ExpertiseDefinition> trainableExpertises = null;
@Override
public String accountForYourself()
{
return "skill teaching";
}
@Override
public void startBehavior(PhysicalAgent forMe)
{
if(forMe instanceof MOB)
myMOB=(MOB)forMe;
setParms(parms);
}
protected void setTheCharClass(MOB mob, CharClass C)
{
if((mob.baseCharStats().numClasses()==1)
&&(mob.baseCharStats().getMyClass(0).ID().equals("StdCharClass"))
&&(!C.ID().equals("StdCharClass")))
{
mob.baseCharStats().setMyClasses(C.ID());
mob.baseCharStats().setMyLevels(""+mob.phyStats().level());
mob.recoverCharStats();
return;
}
for(int i=0;i<mob.baseCharStats().numClasses();i++)
{
final CharClass C1=mob.baseCharStats().getMyClass(i);
if((C1!=null)
&&(mob.baseCharStats().getClassLevel(C1)>0))
mob.baseCharStats().setClassLevel(C1,1);
}
mob.baseCharStats().setCurrentClass(C);
mob.baseCharStats().setClassLevel(C,mob.phyStats().level());
mob.recoverCharStats();
}
protected void classAbles(MOB mob, Map<String,Ability> myAbles, int pct)
{
final boolean stdCharClass=mob.charStats().getCurrentClass().ID().equals("StdCharClass");
final String className=mob.charStats().getCurrentClass().ID();
Ability A=null;
for(final Enumeration<Ability> a=CMClass.abilities();a.hasMoreElements();)
{
A=a.nextElement();
if((A!=null)
&&(((stdCharClass&&(CMLib.ableMapper().lowestQualifyingLevel(A.ID())>0)))
||(CMLib.ableMapper().qualifiesByLevel(mob,A)&&(!CMLib.ableMapper().getSecretSkill(className,true,A.ID()))))
&&((!noCommon)||((A.classificationCode()&Ability.ALL_ACODES)!=Ability.ACODE_COMMON_SKILL))
&&((!stdCharClass)||(CMLib.ableMapper().availableToTheme(A.ID(),Area.THEME_FANTASY,true))))
addAbility(mob,A,pct,myAbles);
}
for(final ClanGovernment G : CMLib.clans().getStockGovernments())
{
G.getClanLevelAbilities(null,null,Integer.valueOf(Integer.MAX_VALUE));
for(final Enumeration<AbilityMapping> m= CMLib.ableMapper().getClassAbles(G.getName(), false);m.hasMoreElements();)
{
final AbilityMapping M=m.nextElement();
final Ability A2=CMClass.getAbility(M.abilityID());
addAbility(mob,A2,pct,myAbles);
}
}
}
@Override
public boolean tick(Tickable ticking, int tickID)
{
if((tickID==Tickable.TICKID_MOB)
&&(!CMSecurity.isDisabled(CMSecurity.DisFlag.MOBTEACHER))
&&((--tickDownToKnowledge)==0)
&&(ticking instanceof MOB))
{
if(!noExpertises)
{
noExpertises=true;
final MOB mob=(MOB)ticking;
if(teachEverything)
{
for(final Enumeration<ExpertiseLibrary.ExpertiseDefinition> e=CMLib.expertises().definitions();e.hasMoreElements();)
mob.addExpertise(e.nextElement().ID());
trainableExpertises=null;
}
else
{
boolean someNew=true;
final CharStats oldBase=(CharStats)mob.baseCharStats().copyOf();
for(final int i: CharStats.CODES.BASECODES())
mob.baseCharStats().setStat(i,100);
for(int i=0;i<mob.baseCharStats().numClasses();i++)
mob.baseCharStats().setClassLevel(mob.baseCharStats().getMyClass(i),100);
mob.recoverCharStats();
while(someNew)
{
someNew=false;
final List<ExpertiseDefinition> V=CMLib.expertises().myQualifiedExpertises(mob);
ExpertiseLibrary.ExpertiseDefinition def=null;
for(int v=0;v<V.size();v++)
{
def=V.get(v);
if(mob.fetchExpertise(def.ID())==null)
{
mob.addExpertise(def.ID());
someNew=true;
}
}
if(someNew)
trainableExpertises=null;
}
mob.setBaseCharStats(oldBase);
mob.recoverCharStats();
}
}
}
return super.tick(ticking,tickID);
}
public void addAbility(MOB mob, Ability A, int pct, Map<String,Ability> myAbles)
{
if(CMLib.dice().rollPercentage()<=pct)
{
final Ability A2=myAbles.get(A.ID());
if(A2==null)
{
A=(Ability)A.copyOf();
A.setSavable(false);
A.setProficiency(CMLib.ableMapper().getMaxProficiency(mob,true,A.ID()));
myAbles.put(A.ID(),A);
mob.addAbility(A);
}
else
A2.setProficiency(CMLib.ableMapper().getMaxProficiency(mob,true,A2.ID()));
}
}
protected void ensureCharClass()
{
myMOB.baseCharStats().setMyClasses("StdCharClass");
myMOB.baseCharStats().setMyLevels(""+myMOB.phyStats().level());
myMOB.recoverCharStats();
final Hashtable<String,Ability> myAbles=new Hashtable<String,Ability>();
Ability A=null;
for(final Enumeration<Ability> a=myMOB.allAbilities();a.hasMoreElements();)
{
A=a.nextElement();
if(A!=null)
myAbles.put(A.ID(),A);
}
myMOB.baseCharStats().setStat(CharStats.STAT_INTELLIGENCE,19);
myMOB.baseCharStats().setStat(CharStats.STAT_WISDOM,19);
int pct=100;
Vector<String> V=null;
A=CMClass.getAbility(getParms());
if(A!=null)
{
addAbility(myMOB,A,pct,myAbles);
teachEverything=false;
}
else
V=CMParms.parse(getParms());
if(V!=null)
{
for(int v=V.size()-1;v>=0;v--)
{
final String s=V.elementAt(v);
if(s.equalsIgnoreCase("NOCOMMON"))
{
noCommon=true;
V.removeElementAt(v);
}
if(s.equalsIgnoreCase("NOEXPS")||s.equalsIgnoreCase("NOEXP"))
{
noExpertises=true;
V.removeElementAt(v);
}
if(s.equalsIgnoreCase("NOHLEXPS")||s.equalsIgnoreCase("NOHLEXP"))
{
noHLExpertises=true;
V.removeElementAt(v);
}
}
}
if(V!=null)
{
for(int v=0;v<V.size();v++)
{
final String s=V.elementAt(v);
if(s.endsWith("%"))
{
pct=CMath.s_int(s.substring(0,s.length()-1));
continue;
}
A=CMClass.getAbility(s);
final CharClass C=CMClass.findCharClass(s);
if((C!=null)&&(C.availabilityCode()!=0))
{
teachEverything=false;
setTheCharClass(myMOB,C);
classAbles(myMOB,myAbles,pct);
myMOB.recoverCharStats();
}
else
if(A!=null)
{
addAbility(myMOB,A,pct,myAbles);
teachEverything=false;
}
else
{
final ExpertiseLibrary.ExpertiseDefinition def=CMLib.expertises().getDefinition(s);
if(def!=null)
{
myMOB.addExpertise(def.ID());
teachEverything=false;
}
}
}
}
myMOB.recoverCharStats();
if((myMOB.charStats().getCurrentClass().ID().equals("StdCharClass"))
&&(teachEverything))
classAbles(myMOB,myAbles,pct);
int lvl=myMOB.phyStats().level()/myMOB.baseCharStats().numClasses();
if(lvl<1)
lvl=1;
for(int i=0;i<myMOB.baseCharStats().numClasses();i++)
{
final CharClass C=myMOB.baseCharStats().getMyClass(i);
if((C!=null)&&(myMOB.baseCharStats().getClassLevel(C)>=0))
myMOB.baseCharStats().setClassLevel(C,lvl);
}
myMOB.recoverCharStats();
}
@Override
public void setParms(String newParms)
{
super.setParms(newParms);
if(myMOB==null)
return;
teachEverything=true;
noCommon=false;
noExpertises=false;
tickDownToKnowledge=4;
trainableExpertises=null;
ensureCharClass();
}
@Override
public boolean okMessage(Environmental host, CMMsg msg)
{
if(host instanceof MOB)
{
if(((MOB)host).isAttributeSet(MOB.Attrib.NOTEACH))
((MOB)host).setAttribute(MOB.Attrib.NOTEACH,false);
}
return super.okMessage(host,msg);
}
@Override
public void executeMsg(Environmental affecting, CMMsg msg)
{
if(myMOB==null)
return;
if(affecting.Name().equals("the guildmaster") && msg.source().name().equals("Dave"))
System.out.println("hi");
super.executeMsg(affecting,msg);
if(!canFreelyBehaveNormal(affecting))
return;
final MOB monster=myMOB;
final MOB student=msg.source();
if((!msg.amISource(monster))
&&(!student.isMonster())
&&(msg.sourceMessage()!=null)
&&((msg.target()==null)||msg.amITarget(monster))
&&(msg.targetMinor()==CMMsg.TYP_SPEAK)
&&(!CMSecurity.isDisabled(CMSecurity.DisFlag.MOBTEACHER)))
{
String sayMsg=CMStrings.getSayFromMessage(msg.sourceMessage());
if(sayMsg==null)
{
final int start=msg.sourceMessage().indexOf('\'');
if(start>0)
{
sayMsg=msg.sourceMessage().substring(start+1);
int x=sayMsg.lastIndexOf("\'");
if(x>0)
sayMsg=sayMsg.substring(0,x);
}
else
sayMsg=msg.sourceMessage();
}
int x=sayMsg.toUpperCase().indexOf("TEACH");
if(x<0)
x=sayMsg.toUpperCase().indexOf("GAIN ");
if(x>=0)
{
boolean giveABonus=false;
String s=sayMsg.substring(x+5).trim();
if(s.startsWith("\""))
s=s.substring(1).trim();
if(s.endsWith("\""))
s=s.substring(0,s.length()-1);
if(s.toUpperCase().endsWith("PLEASE"))
s=s.substring(0,s.length()-6).trim();
if(s.startsWith("\""))
s=s.substring(1).trim();
if(s.endsWith("\""))
s=s.substring(0,s.length()-1);
if(s.toUpperCase().startsWith("PLEASE "))
{
giveABonus=true;
s=s.substring(6).trim();
}
if(s.startsWith("\""))
s=s.substring(1).trim();
if(s.endsWith("\""))
s=s.substring(0,s.length()-1);
if(s.toUpperCase().startsWith("ME "))
s=s.substring(3).trim();
if(s.startsWith("\""))
s=s.substring(1).trim();
if(s.endsWith("\""))
s=s.substring(0,s.length()-1);
if(s.toUpperCase().startsWith("PLEASE "))
{
giveABonus=true;
s=s.substring(6).trim();
}
if(s.toUpperCase().startsWith("ME "))
s=s.substring(3).trim();
if(s.startsWith("\""))
s=s.substring(1).trim();
if(s.endsWith("\""))
s=s.substring(0,s.length()-1);
if(s.trim().equalsIgnoreCase("LIST"))
{
CMLib.commands().postSay(monster,student,L("Try the QUALIFY command."),true,false);
return;
}
if(s.trim().toUpperCase().equals("ALL"))
{
CMLib.commands().postSay(monster,student,L("I can't teach you everything at once. Try the QUALIFY command."),true,false);
return;
}
final Ability myAbility=CMClass.findAbility(s.trim().toUpperCase(),monster);
if(myAbility==null)
{
ExpertiseLibrary.ExpertiseDefinition theExpertise=null;
if(trainableExpertises==null)
{
trainableExpertises=new LinkedList<ExpertiseLibrary.ExpertiseDefinition>();
trainableExpertises.addAll(CMLib.expertises().myListableExpertises(monster));
for(final Enumeration<String> exi=monster.expertises();exi.hasMoreElements();)
{
final Pair<String,Integer> EXI=monster.fetchExpertise(exi.nextElement());
if(EXI.getValue()==null)
{
final ExpertiseLibrary.ExpertiseDefinition def=CMLib.expertises().getDefinition(EXI.getKey());
if((def != null) && (!trainableExpertises.contains(def)))
trainableExpertises.add(def);
}
else
{
final List<String> childrenIDs=CMLib.expertises().getStageCodes(EXI.getKey());
for(final String experID : childrenIDs)
{
final ExpertiseLibrary.ExpertiseDefinition def=CMLib.expertises().getDefinition(experID);
if((def != null) && (!trainableExpertises.contains(def)))
trainableExpertises.add(def);
}
}
}
}
for(final ExpertiseLibrary.ExpertiseDefinition def : trainableExpertises)
{
if((def.name().equalsIgnoreCase(s))
&&(theExpertise==null))
theExpertise=def;
}
if(theExpertise==null)
{
for(final ExpertiseLibrary.ExpertiseDefinition def : trainableExpertises)
{
if((CMLib.english().containsString(def.name(),s)
&&(theExpertise==null)))
theExpertise=def;
}
}
if(theExpertise!=null)
{
if(!CMLib.expertises().postTeach(monster,student,theExpertise))
return;
}
else
if((CMClass.findCharClass(s.trim())!=null))
CMLib.commands().postSay(monster,student,L("I've heard of @x1, but that's an class-- try TRAINing for it.",s),true,false);
else
{
for(final Enumeration<ExpertiseLibrary.ExpertiseDefinition> e=CMLib.expertises().definitions(); e.hasMoreElements();)
{
final ExpertiseLibrary.ExpertiseDefinition def=e.nextElement();
if(def.name().equalsIgnoreCase(s))
{
theExpertise=def;
break;
}
}
if(theExpertise==null)
CMLib.commands().postSay(monster,student,L("I'm sorry, but I've never heard of @x1",s),true,false);
else
CMLib.commands().postSay(monster,student,L("I'm sorry, but I do not know @x1.",theExpertise.name()));
}
return;
}
if(giveABonus)
{
monster.baseCharStats().setStat(CharStats.STAT_INTELLIGENCE,25);
monster.baseCharStats().setStat(CharStats.STAT_WISDOM,25);
monster.recoverCharStats();
}
final int prof75=(int)Math.round(CMath.mul(CMLib.ableMapper().getMaxProficiency(student,true,myAbility.ID()),0.75));
myAbility.setProficiency(prof75/2);
CMLib.expertises().postTeach(monster,student,myAbility);
monster.baseCharStats().setStat(CharStats.STAT_INTELLIGENCE,19);
monster.baseCharStats().setStat(CharStats.STAT_WISDOM,19);
monster.recoverCharStats();
}
}
}
}