use of pcgen.core.pclevelinfo.PCLevelInfo in project pcgen by PCGen.
the class CharacterLevelsFacadeImpl method refreshClassList.
/**
* Update the list of class levels from scratch to match the current
* state of the character.
*/
private void refreshClassList() {
List<PCClass> newClasses = charDisplay.getClassList();
Collection<PCLevelInfo> levelInfo = charDisplay.getLevelInfo();
Map<String, Integer> levelCount = new HashMap<>();
Map<String, PCClass> classMap = new HashMap<>();
for (PCClass pcClass : newClasses) {
levelCount.put(pcClass.getKeyName(), 1);
classMap.put(pcClass.getKeyName(), pcClass);
}
classLevels.clear();
clearContents();
for (PCLevelInfo lvlInfo : levelInfo) {
final String classKeyName = lvlInfo.getClassKeyName();
PCClass currClass = classMap.get(classKeyName);
if (currClass == null) {
Logging.errorPrint("No PCClass found for '" + classKeyName + "' in character's class list: " + newClasses);
return;
}
int clsLvlNum = levelCount.get(classKeyName);
levelCount.put(classKeyName, clsLvlNum + 1);
classLevels.add(currClass);
CharacterLevelFacadeImpl levelFI = new CharacterLevelFacadeImpl(currClass, classLevels.size());
addElement(levelFI);
//PCClassLevel classLevel = currClass.getClassLevel(clsLvlNum);
}
updateSkillsTodo();
}
use of pcgen.core.pclevelinfo.PCLevelInfo in project pcgen by PCGen.
the class ClassSkillChoiceActor method applyChoice.
/**
* Applies the given Skill choice to the given PlayerCharacter. The given
* Skill is added as a class skill for the PCClass provided during
* construction of this ClassSkillChoiceActor. If the number of ranks
* provided during construction of this ClassSkillChoiceActor was not null
* or zero, then ranks are also applied to the given skill.
*
* @param owner
* The owning object for this choice.
* @param choice
* The Skill which should be added as a Class Skill for the
* PCClass provided during construction of this
* ClassSkillChoiceActor
* @param pc
* The PlayerCharacter to which the changes driven by this
* ClassSkillChoiceActor should be applied.
*/
@Override
public void applyChoice(CDOMObject owner, Skill choice, PlayerCharacter pc) {
PCClass pcc = getSourceClass(pc);
if (pcc == null) {
Logging.errorPrint("Unable to find the pc's class " + source + " to apply skill choices to.");
return;
}
pc.addLocalCost(pcc, choice, SkillCost.CLASS, owner);
if (applyRank != null) {
if (owner instanceof PCClassLevel) {
// Ensure that the skill points for this level are already calculated.
PCClassLevel classLevel = (PCClassLevel) owner;
PCClass pcClass = (PCClass) classLevel.getSafe(ObjectKey.PARENT);
int levelIndex = 1;
for (PCLevelInfo lvlInfo : pc.getLevelInfo()) {
if (lvlInfo.getClassKeyName() == pcClass.getKeyName() && lvlInfo.getClassLevel() == classLevel.getSafe(IntegerKey.LEVEL)) {
pc.checkSkillModChangeForLevel(pcClass, lvlInfo, classLevel, levelIndex++);
break;
}
}
}
String result = SkillRankControl.modRanks(applyRank, pcc, false, pc, choice);
if (StringUtils.isNotEmpty(result)) {
Logging.errorPrint("Unable to apply {0} ranks of {1}. Error: {2}", applyRank, choice, result);
}
}
}
use of pcgen.core.pclevelinfo.PCLevelInfo in project pcgen by PCGen.
the class MonsterClassFacet method dataAdded.
/**
* Adds monster classes to the Player Character when a CDOMObject which
* grants monster classes is added to the Player Character.
*
* Triggered when one of the Facets to which MonsterClassFacet listens fires
* a DataFacetChangeEvent to indicate a CDOMObject was added to a Player
* Character.
*
* @param dfce
* The DataFacetChangeEvent containing the information about the
* change
*
* @see pcgen.cdom.facet.event.DataFacetChangeListener#dataAdded(pcgen.cdom.facet.event.DataFacetChangeEvent)
*/
@Override
public void dataAdded(DataFacetChangeEvent<CharID, CDOMObject> dfce) {
CharID id = dfce.getCharID();
CDOMObject cdo = dfce.getCDOMObject();
// Get existing classes
ClassInfo ci = classFacet.removeAllClasses(id);
//
for (int i = levelInfoFacet.getCount(id) - 1; i >= 0; --i) {
PCLevelInfo pli = levelInfoFacet.get(id, i);
final String classKeyName = pli.getClassKeyName();
final PCClass aClass = Globals.getContext().getReferenceContext().silentlyGetConstructedCDOMObject(PCClass.class, classKeyName);
if (aClass.isMonster()) {
levelInfoFacet.remove(id, pli);
}
}
PlayerCharacter pc = trackingFacet.getPC(id);
final List<PCLevelInfo> existingLevelInfo = new ArrayList<>(levelInfoFacet.getSet(id));
levelInfoFacet.removeAll(id);
// Make sure monster classes are added first
if (!pc.isImporting()) {
LevelCommandFactory lcf = cdo.get(ObjectKey.MONSTER_CLASS);
if (lcf != null) {
int levelCount = formulaResolvingFacet.resolve(id, lcf.getLevelCount(), "").intValue();
pc.incrementClassLevel(levelCount, lcf.getPCClass(), true);
}
}
levelInfoFacet.addAll(id, existingLevelInfo);
//
if (!pc.isImporting() && ci != null && !ci.isEmpty()) {
int totalLevels = levelFacet.getTotalLevels(id);
for (PCClass pcClass : ci.getClassSet()) {
//
if (!pcClass.isMonster()) {
classFacet.addClass(id, pcClass);
int cLevels = ci.getLevel(pcClass);
classFacet.setLevel(id, pcClass, cLevels);
pc.setSkillPool(pcClass, 0);
int cMod = 0;
for (int j = 0; j < cLevels; ++j) {
cMod += pc.recalcSkillPointMod(pcClass, ++totalLevels);
}
pc.setSkillPool(pcClass, cMod);
}
}
}
}
use of pcgen.core.pclevelinfo.PCLevelInfo in project pcgen by PCGen.
the class PCGVer2Parser method parseClassLine.
/*
* ###############################################################
* Character Class(es) methods
* ###############################################################
*/
private void parseClassLine(final String line) throws PCGParseException {
final PCGTokenizer tokens;
try {
tokens = new PCGTokenizer(line);
} catch (PCGParseException pcgpex) {
/*
* Classes are critical for characters,
* need to stop the load process
*
* Thomas Behr 14-08-02
*/
throw new PCGParseException("parseClassLine", line, //$NON-NLS-1$
pcgpex.getMessage());
}
PCClass aPCClass = null;
String tag;
PCGElement element;
final Iterator<PCGElement> it = tokens.getElements().iterator();
// the first element defines the class key name!!!
if (it.hasNext()) {
element = it.next();
String classKey = EntityEncoder.decode(element.getText());
// First check for an existing class, say from a racial casting ability
aPCClass = thePC.getClassKeyed(classKey);
if (aPCClass == null) {
aPCClass = Globals.getContext().getReferenceContext().silentlyGetConstructedCDOMObject(PCClass.class, classKey);
if (aPCClass != null) {
// Icky: Need to redesign the way classes work!
// Icky: Having to clone the class here is UGLY!
aPCClass = aPCClass.clone();
} else {
final String msg = LanguageBundle.getFormattedString(//$NON-NLS-1$
"Warnings.PCGenParser.CouldntAddClass", element.getText());
warnings.add(msg);
return;
}
}
}
int level = -1;
int skillPool = -1;
String subClassKey = Constants.NONE;
while (it.hasNext()) {
element = it.next();
tag = element.getName();
if (IOConstants.TAG_SUBCLASS.equals(tag)) {
subClassKey = EntityEncoder.decode(element.getText());
if ((!subClassKey.isEmpty()) && !subClassKey.equals(Constants.NONE)) {
SubClass sc = aPCClass.getSubClassKeyed(subClassKey);
if (sc == null) {
if (subClassKey.equals(aPCClass.getKeyName())) {
subClassKey = Constants.NONE;
} else {
final String msg = LanguageBundle.getFormattedString(//$NON-NLS-1$
"Warnings.PCGenParser.InvalidSubclass", element.getText());
warnings.add(msg);
}
}
}
}
if (IOConstants.TAG_LEVEL.equals(tag)) {
try {
level = Integer.parseInt(element.getText());
} catch (NumberFormatException nfe) {
final String msg = LanguageBundle.getFormattedString(//$NON-NLS-1$
"Warnings.PCGenParser.InvalidLevel", element.getText());
warnings.add(msg);
}
} else if (IOConstants.TAG_SKILLPOOL.equals(tag)) {
try {
skillPool = Integer.parseInt(element.getText());
} catch (NumberFormatException nfe) {
final String msg = LanguageBundle.getFormattedString(//$NON-NLS-1$
"Warnings.PCGenParser.InvalidSkillPool", element.getText());
warnings.add(msg);
}
} else if (IOConstants.TAG_CANCASTPERDAY.equals(tag)) {
// TODO
} else if (IOConstants.TAG_SPELLBASE.equals(tag)) {
final String spellBase = EntityEncoder.decode(element.getText());
if (!Constants.NONE.equals(spellBase)) {
Globals.getContext().unconditionallyProcess(aPCClass, "SPELLSTAT", spellBase);
}
} else if (IOConstants.TAG_PROHIBITED.equals(tag)) {
String prohib = EntityEncoder.decode(element.getText());
StringTokenizer st = new StringTokenizer(prohib, Constants.COMMA);
while (st.hasMoreTokens()) {
String choice = st.nextToken();
if (!"None".equalsIgnoreCase(choice)) {
SpellProhibitor prohibSchool = new SpellProhibitor();
prohibSchool.setType(ProhibitedSpellType.SCHOOL);
prohibSchool.addValue(choice);
SpellProhibitor prohibSubSchool = new SpellProhibitor();
prohibSubSchool.setType(ProhibitedSpellType.SUBSCHOOL);
prohibSubSchool.addValue(choice);
thePC.addProhibitedSchool(prohibSchool, aPCClass);
thePC.addProhibitedSchool(prohibSubSchool, aPCClass);
}
}
}
}
if (level > -1) {
thePC.addClass(aPCClass);
if (StringUtils.isNotBlank(subClassKey) && !subClassKey.equals(Constants.NONE)) {
SubClassApplication.setSubClassKey(thePC, aPCClass, subClassKey);
}
for (int i = 0; i < level; ++i) {
PCLevelInfo levelInfo = thePC.addLevelInfo(aPCClass.getKeyName());
aPCClass.addLevel(false, false, thePC, true);
}
}
//Must process ADD after CLASS is added to the PC
for (PCGElement e : new PCGTokenizer(line).getElements()) {
tag = e.getName();
if (tag.equals(IOConstants.TAG_ADDTOKEN)) {
parseAddTokenInfo(e, aPCClass);
}
}
if (skillPool > -1) {
thePC.setSkillPool(aPCClass, skillPool);
}
}
use of pcgen.core.pclevelinfo.PCLevelInfo in project pcgen by PCGen.
the class PCGVer2Creator method appendClassLines.
/*
* ###############################################################
* Character Class(es) methods
* ###############################################################
*/
private void appendClassLines(StringBuilder buffer) {
Cache specials = new Cache();
for (PCClass pcClass : charDisplay.getClassSet()) {
int classLevel = charDisplay.getLevel(pcClass);
buffer.append(IOConstants.TAG_CLASS).append(':');
buffer.append(EntityEncoder.encode(pcClass.getKeyName()));
final String subClassKey = charDisplay.getSubClassName(pcClass);
if (subClassKey != null && !Constants.EMPTY_STRING.equals(subClassKey)) {
buffer.append('|');
buffer.append(IOConstants.TAG_SUBCLASS).append(':');
buffer.append(EntityEncoder.encode(subClassKey));
}
buffer.append('|');
buffer.append(IOConstants.TAG_LEVEL).append(':');
buffer.append(classLevel);
buffer.append('|');
buffer.append(IOConstants.TAG_SKILLPOOL).append(':');
Integer currentPool = thePC.getSkillPool(pcClass);
buffer.append(currentPool == null ? 0 : currentPool);
// determine if this class can cast spells
boolean isCaster = false;
if (!thePC.getSpellSupport(pcClass).canCastSpells(thePC)) {
isCaster = true;
}
boolean isPsionic = thePC.getSpellSupport(pcClass).hasKnownList() && !isCaster;
if (isCaster || isPsionic) {
buffer.append('|');
buffer.append(IOConstants.TAG_SPELLBASE).append(':');
buffer.append(EntityEncoder.encode(pcClass.getSpellBaseStat()));
buffer.append('|');
buffer.append(IOConstants.TAG_CANCASTPERDAY).append(':');
buffer.append(StringUtil.join(thePC.getSpellSupport(pcClass).getCastListForLevel(classLevel), ","));
}
Collection<? extends SpellProhibitor> prohib = charDisplay.getProhibitedSchools(pcClass);
if (prohib != null) {
Set<String> set = new TreeSet<>();
for (SpellProhibitor sp : prohib) {
set.addAll(sp.getValueList());
}
if (!set.isEmpty()) {
buffer.append('|');
buffer.append(IOConstants.TAG_PROHIBITED).append(':');
buffer.append(EntityEncoder.encode(StringUtil.join(set, ",")));
}
}
appendAddTokenInfo(buffer, pcClass);
buffer.append(IOConstants.LINE_SEP);
String spec = thePC.getAssoc(pcClass, AssociationKey.SPECIALTY);
if (spec != null) {
specials.put(pcClass.getKeyName() + IOConstants.TAG_SPECIALTY + '0', spec);
}
String key;
key = pcClass.getKeyName() + IOConstants.TAG_SAVE + '0';
List<? extends SpecialAbility> salist = charDisplay.getUserSpecialAbilityList(pcClass);
if (salist != null && !salist.isEmpty()) {
SpecialAbility sa = salist.get(0);
specials.put(pcClass.getKeyName() + IOConstants.TAG_SA + 0, sa.getKeyName());
}
for (BonusObj save : thePC.getSaveableBonusList(pcClass)) {
specials.put(key, "BONUS|" + save);
}
for (int i = 1; i <= charDisplay.getLevel(pcClass); i++) {
key = pcClass.getKeyName() + IOConstants.TAG_SAVE + (i - 1);
PCClassLevel pcl = charDisplay.getActiveClassLevel(pcClass, i);
for (BonusObj save : thePC.getSaveableBonusList(pcl)) {
specials.put(key, "BONUS|" + save);
}
}
}
//
for (PCLevelInfo pcl : charDisplay.getLevelInfo()) {
final String classKeyName = pcl.getClassKeyName();
int lvl = pcl.getClassLevel() - 1;
PCClass pcClass = thePC.getClassKeyed(classKeyName);
buffer.append(IOConstants.TAG_CLASSABILITIESLEVEL).append(':');
if (pcClass == null) {
pcClass = Globals.getContext().getReferenceContext().silentlyGetConstructedCDOMObject(PCClass.class, classKeyName);
if (pcClass != null) {
pcClass = thePC.getClassKeyed(pcClass.get(ObjectKey.EX_CLASS).get().getKeyName());
}
}
if (pcClass != null) {
buffer.append(EntityEncoder.encode(pcClass.getKeyName()));
} else {
//$NON-NLS-1$
buffer.append(EntityEncoder.encode("???"));
}
buffer.append('=').append(lvl + 1);
if (pcClass != null) {
String aKey = charDisplay.getSubstitutionClassName(charDisplay.getActiveClassLevel(pcClass, lvl + 1));
if (aKey != null) {
buffer.append('|');
buffer.append(IOConstants.TAG_SUBSTITUTIONLEVEL).append(':');
buffer.append(aKey);
}
buffer.append('|');
buffer.append(IOConstants.TAG_HITPOINTS).append(':');
PCClassLevel classLevel = charDisplay.getActiveClassLevel(pcClass, lvl);
Integer hp = charDisplay.getHP(classLevel);
buffer.append(hp == null ? 0 : hp);
appendSpecials(buffer, specials.get(pcClass.getKeyName() + IOConstants.TAG_SAVE + lvl), IOConstants.TAG_SAVES, IOConstants.TAG_SAVE, lvl);
appendSpecials(buffer, specials.get(pcClass.getKeyName() + IOConstants.TAG_SPECIALTY + lvl), IOConstants.TAG_SPECIALTIES, IOConstants.TAG_SPECIALTY, lvl);
appendSpecials(buffer, specials.get(pcClass.getKeyName() + IOConstants.TAG_SA + lvl), IOConstants.TAG_SPECIALABILITIES, IOConstants.TAG_SA, lvl);
if (lvl == 0) {
appendSpecials(buffer, specials.get(pcClass.getKeyName() + IOConstants.TAG_SA + (lvl - 1)), IOConstants.TAG_SPECIALABILITIES, IOConstants.TAG_SA, -1);
}
//
// Remember what choices were made for each of the ADD: tags
//
appendAddTokenInfo(buffer, charDisplay.getActiveClassLevel(pcClass, lvl + 1));
}
List<PCLevelInfoStat> statList = pcl.getModifiedStats(true);
if (statList != null) {
for (PCLevelInfoStat stat : statList) {
buffer.append('|').append(IOConstants.TAG_PRESTAT).append(':').append(stat.toString());
}
}
statList = pcl.getModifiedStats(false);
if (statList != null) {
for (PCLevelInfoStat stat : statList) {
buffer.append('|').append(IOConstants.TAG_PRESTAT).append(':').append(stat.toString());
}
}
int sp = pcl.getSkillPointsGained(thePC);
//if (sp != 0)
{
buffer.append('|').append(IOConstants.TAG_SKILLPOINTSGAINED).append(':').append(sp);
}
sp = pcl.getSkillPointsRemaining();
//if (sp != 0)
{
buffer.append('|').append(IOConstants.TAG_SKILLPOINTSREMAINING).append(':').append(sp);
}
buffer.append(IOConstants.LINE_SEP);
}
}
Aggregations