/*
* KitProf.java
* Copyright 2001 (C) Greg Bingleman <byngl@hotmail.com>
*
* This library 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 library 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* Created on September 28, 2002, 11:50 PM
*
* $Id$
*/
package pcgen.core.kit;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import pcgen.base.lang.StringUtil;
import pcgen.cdom.base.CDOMObject;
import pcgen.cdom.base.PersistentTransitionChoice;
import pcgen.cdom.enumeration.ListKey;
import pcgen.cdom.reference.CDOMSingleRef;
import pcgen.core.Globals;
import pcgen.core.Kit;
import pcgen.core.PCClass;
import pcgen.core.PlayerCharacter;
import pcgen.core.Race;
import pcgen.core.WeaponProf;
/**
* {@code KitFeat}.
*
* @author Greg Bingleman <byngl@hotmail.com>
*/
public final class KitProf extends BaseKit
{
private Integer choiceCount;
private final List<CDOMSingleRef<WeaponProf>> profList =
new ArrayList<>();
private Boolean racialProf;
// These members store the state of an instance of this class. They are
// not cloned.
private transient CDOMObject thePObject = null;
private transient List<WeaponProf> weaponProfs = null;
/**
* True if it is a racial proficiency
* @return True if it is a racial proficiency
*/
public boolean isRacial()
{
return racialProf != null && racialProf;
}
/**
* Set racial proficiency flag
* @param argRacial
*/
public void setRacialProf(Boolean argRacial)
{
racialProf = argRacial;
}
@Override
public String toString()
{
final int maxSize = profList.size();
final StringBuilder info = new StringBuilder(maxSize * 10);
if ((getSafeCount() != 1) || (maxSize != 1))
{
info.append(getSafeCount()).append(" of ");
}
info.append(StringUtil.join(profList, ", "));
return info.toString();
}
@Override
public boolean testApply(Kit aKit, PlayerCharacter aPC,
List<String> warnings)
{
thePObject = null;
weaponProfs = null;
PersistentTransitionChoice<WeaponProf> wpPTC = null;
if (isRacial())
{
final Race pcRace = aPC.getRace();
if (pcRace == null)
{
warnings.add("PROF: PC has no race");
return false;
}
if (!aPC.hasBonusWeaponProfs(pcRace))
{
warnings
.add("PROF: Race has already selected bonus weapon proficiency");
return false;
}
thePObject = pcRace;
wpPTC = getPTC(pcRace);
if (wpPTC == null)
{
warnings.add("PROF: PC race has no WEAPONBONUS");
return false;
}
}
else
{
Collection<PCClass> pcClasses = aPC.getClassSet();
if (pcClasses == null || pcClasses.isEmpty())
{
warnings.add("PROF: No owning class found.");
return false;
}
// Search for a class that has bonusWeaponProfs.
PCClass pcClass = null;
for (Iterator<PCClass> i = pcClasses.iterator(); i.hasNext();)
{
pcClass = i.next();
wpPTC = getPTC(pcClass);
if (wpPTC != null)
{
break;
}
}
if (wpPTC == null)
{
warnings.add("PROF: PC classes have no WEAPONBONUS");
return false;
}
thePObject = pcClass;
if (!aPC.hasBonusWeaponProfs(pcClass))
{
warnings
.add("PROF: Class has already selected bonus weapon proficiency");
return false;
}
}
final List<WeaponProf> aProfList = new ArrayList<>();
Collection<?> choices = wpPTC.getChoices().getSet(aPC);
for (CDOMSingleRef<WeaponProf> profKey : profList)
{
WeaponProf wp = profKey.get();
if (choices.contains(wp))
{
wpPTC.act(Collections.singleton(wp), thePObject, aPC);
}
else
{
warnings.add("PROF: Weapon proficiency \"" + wp.getKeyName()
+ "\" is not in list of choices");
}
}
int numberOfChoices = getSafeCount();
//
// Can't choose more entries than there are...
//
if (numberOfChoices > aProfList.size())
{
numberOfChoices = aProfList.size();
}
if (numberOfChoices == 0)
{
return false;
}
List<WeaponProf> xs;
if (numberOfChoices == aProfList.size())
{
xs = aProfList;
}
else
{
//
// Force user to make enough selections
//
while (true)
{
xs =
Globals
.getChoiceFromList("Choose Proficiencies",
aProfList, new ArrayList<>(),
numberOfChoices, aPC);
if (!xs.isEmpty())
{
break;
}
}
}
//
// Add to list of things to add to the character
//
for (WeaponProf prof : xs)
{
if (weaponProfs == null)
{
weaponProfs = new ArrayList<>();
}
weaponProfs.add(prof);
}
return false;
}
private PersistentTransitionChoice<WeaponProf> getPTC(CDOMObject cdo)
{
List<PersistentTransitionChoice<?>> adds =
cdo.getListFor(ListKey.ADD);
for (PersistentTransitionChoice<?> ptc: adds)
{
if (ptc.getChoiceClass().equals(WeaponProf.class))
{
return (PersistentTransitionChoice<WeaponProf>) ptc;
}
}
return null;
}
@Override
public void apply(PlayerCharacter aPC)
{
PersistentTransitionChoice<WeaponProf> wpPTC = getPTC(thePObject);
Collection<?> choices = wpPTC.getChoices().getSet(aPC);
for (CDOMSingleRef<WeaponProf> profKey : profList)
{
WeaponProf wp = profKey.get();
if (choices.contains(wp))
{
wpPTC.act(Collections.singleton(wp), thePObject, aPC);
}
}
}
@Override
public String getObjectName()
{
return "Proficiencies";
}
public void setCount(Integer quan)
{
choiceCount = quan;
}
public Integer getCount()
{
return choiceCount;
}
public int getSafeCount()
{
return choiceCount == null ? 1 : choiceCount;
}
public void addProficiency(CDOMSingleRef<WeaponProf> ref)
{
profList.add(ref);
}
public Collection<CDOMSingleRef<WeaponProf>> getProficiencies()
{
return profList;
}
public Boolean getRacialProf()
{
return racialProf;
}
}