/*
* Copyright (c) 2010 Tom Parker <thpr@users.sourceforge.net>
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package pcgen.cdom.facet.analysis;
import java.util.HashSet;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import pcgen.cdom.base.CDOMObjectUtilities;
import pcgen.cdom.enumeration.CharID;
import pcgen.cdom.facet.SubClassFacet;
import pcgen.cdom.facet.model.ClassFacet;
import pcgen.core.PCClass;
/**
* Performs calculations related to multi-class characters (e.g. XP penalty
* multiplier)
*
* @author Thomas Parker (thpr [at] yahoo.com)
*/
public class MultiClassFacet
{
private FavoredClassFacet favoredClassFacet;
private HasAnyFavoredClassFacet hasAnyFavoredClassFacet;
private ClassFacet classFacet;
private SubClassFacet subClassFacet;
/**
* Returns the multi-class XP multiplier for the Player Character identified
* by the given CharID.
*
* @param id
* The CharID identifying the Player Character for which the
* multi-class XP multipler is to be returned
* @return The multi-class XP multiplier for the Player Character identified
* by the given CharID
*/
public double getMultiClassXPMultiplier(CharID id)
{
Set<PCClass> unfavoredClasses = new HashSet<>();
SortedSet<PCClass> favored = new TreeSet<>(
CDOMObjectUtilities.CDOM_SORTER);
favored.addAll(favoredClassFacet.getSet(id));
SortedSet<PCClass> aList = favored;
boolean hasAny = hasAnyFavoredClassFacet.contains(id, Boolean.TRUE);
PCClass maxClass = null;
PCClass secondClass = null;
int maxClassLevel = 0;
int secondClassLevel = 0;
int xpPenalty = 0;
double xpMultiplier = 1.0;
for (PCClass pcClass : classFacet.getSet(id))
{
if (!pcClass.hasXPPenalty())
{
continue;
}
String subClassKey = subClassFacet.get(id, pcClass);
PCClass evalClass = pcClass;
if (subClassKey != null && !subClassKey.equals("None"))
{
evalClass = pcClass.getSubClassKeyed(subClassKey);
}
if (!aList.contains(evalClass))
{
unfavoredClasses.add(pcClass);
int pcClassLevel = classFacet.getLevel(id, pcClass);
if (pcClassLevel > maxClassLevel)
{
if (hasAny)
{
secondClassLevel = maxClassLevel;
secondClass = maxClass;
}
maxClassLevel = pcClassLevel;
maxClass = pcClass;
}
else if ((pcClassLevel > secondClassLevel) && (hasAny))
{
secondClassLevel = pcClassLevel;
secondClass = pcClass;
}
}
}
if ((hasAny) && (secondClassLevel > 0))
{
maxClassLevel = secondClassLevel;
unfavoredClasses.remove(maxClass);
maxClass = secondClass;
}
if (maxClassLevel > 0)
{
unfavoredClasses.remove(maxClass);
for (PCClass aClass : unfavoredClasses)
{
if ((maxClassLevel - (classFacet.getLevel(id, aClass))) > 1)
{
++xpPenalty;
}
}
xpMultiplier = 1.0 - (xpPenalty * 0.2);
if (xpMultiplier < 0)
{
xpMultiplier = 0;
}
}
return xpMultiplier;
}
public void setFavoredClassFacet(FavoredClassFacet favoredClassFacet)
{
this.favoredClassFacet = favoredClassFacet;
}
public void setHasAnyFavoredClassFacet(
HasAnyFavoredClassFacet hasAnyFavoredClassFacet)
{
this.hasAnyFavoredClassFacet = hasAnyFavoredClassFacet;
}
public void setClassFacet(ClassFacet classFacet)
{
this.classFacet = classFacet;
}
public void setSubClassFacet(SubClassFacet subClassFacet)
{
this.subClassFacet = subClassFacet;
}
}