/** * Needs documentation. * * @param pc update skills for this PC * @param aSkill Skill to update * @param aRank Number of ranks to add * @param aCost Cost of added ranks * @param langList Languages to be selected for a language skill * @param pcClass skills apply to this class * @return <code>true</code> for success TODO What about throwing on failure? */ private boolean updatePCSkills( final PlayerCharacter pc, final Skill aSkill, final int aRank, final double aCost, List<Language> langList, final PCClass pcClass) { pc.addSkill(aSkill); boolean oldImporting = pc.isImporting(); pc.setImporting(true); final String aString = SkillRankControl.modRanks(aRank, pcClass, true, pc, aSkill); pc.setImporting(oldImporting); if (aString.length() > 0) { Logging.errorPrint("SKILL: " + aString); return false; } // Add any supplied languages ChoiceManagerList<Language> controller = ChooserUtilities.getConfiguredController(aSkill, pc, null, new ArrayList<String>()); for (Language lang : langList) { if (!controller.conditionallyApply(pc, lang)) { Logging.errorPrint("Failed to apply Language into Skill: " + lang.getLSTformat()); } } // // Fix up the skill pools to reflect what we just spent. // double ptsToSpend = aCost; if (ptsToSpend >= 0.0) { for (PCLevelInfo info : pc.getLevelInfo()) { if (info.getClassKeyName().equals(pcClass.getKeyName())) { // We are spending this class' points. int remaining = info.getSkillPointsRemaining(); if (remaining == 0) { continue; } int left = remaining - (int) Math.min(remaining, ptsToSpend); info.setSkillPointsRemaining(left); ptsToSpend -= (remaining - left); if (ptsToSpend <= 0) { break; } } } } return true; }
/* * REFACTOR This is BAD that this is referring to PCLevelInfo - that gets * VERY confusing as far as object interaction. Can we get rid of * PCLevelInfo altogether? */ public final int getSkillPool(final PlayerCharacter aPC) { int returnValue = 0; // ////////////////////////////////// // Using this method will return skills for level 0 even when there is // no information // Byngl - December 28, 2004 // for (int i = 0; i <= level; i++) // { // final PCLevelInfo pcl = aPC.getLevelInfoFor(getKeyName(), i); // // if ((pcl != null) && pcl.getClassKeyName().equals(getKeyName())) // { // returnValue += pcl.getSkillPointsRemaining(); // } // } for (PCLevelInfo pcl : aPC.getLevelInfo()) { if (pcl.getClassKeyName().equals(getKeyName())) { returnValue += pcl.getSkillPointsRemaining(); } } // ////////////////////////////////// return returnValue; }
private KitSkillAdd addRanks( PlayerCharacter pc, PCClass pcClass, Skill aSkill, double ranksLeftToAdd, boolean isFree, List<String> warnings) { if (!isFree && pcClass.getSkillPool(pc) == 0) { return null; } double curRank = 0.0; if (pc.hasSkill(aSkill)) { curRank = pc.getRank(aSkill).doubleValue(); } double ranksToAdd = ranksLeftToAdd; if (!Globals.checkRule(RuleConstants.SKILLMAX) && (ranksToAdd > 0.0)) { ranksToAdd = Math.min(pc.getMaxRank(aSkill, pcClass).doubleValue(), curRank + ranksLeftToAdd); ranksToAdd -= curRank; if (!CoreUtility.doublesEqual(ranksToAdd, ranksLeftToAdd)) { warnings.add( "SKILL: Could not add " + (ranksLeftToAdd - ranksToAdd) + " to " + aSkill.getDisplayName() + ". Exceeds MAXRANK of " + pc.getMaxRank(aSkill, pcClass) + "."); } } int ptsToSpend = 0; int[] points = new int[pc.getLevelInfoSize()]; if (!isFree) { double ranksAdded = 0.0; int skillCost = pc.getSkillCostForClass(aSkill, pcClass).getCost(); ptsToSpend = (int) (ranksToAdd * skillCost); for (int i = 0; i < pc.getLevelInfoSize(); i++) { PCLevelInfo info = pc.getLevelInfo(i); if (info.getClassKeyName().equals(pcClass.getKeyName())) { // We are spending this class' points. points[i] = info.getSkillPointsRemaining(); } else { points[i] = -1; } } for (int i = 0; i < points.length; i++) { int remaining = points[i]; if (remaining <= 0) { continue; } int left = remaining - Math.min(remaining, ptsToSpend); points[i] = left; int spent = (remaining - left); ptsToSpend -= spent; ranksAdded += ((double) spent / (double) skillCost); if (ranksAdded == ranksToAdd || ptsToSpend <= 0) { break; } } ranksToAdd = ranksAdded; ptsToSpend = (int) (ranksToAdd * skillCost); } pc.addSkill(aSkill); String ret = SkillRankControl.modRanks(ranksToAdd, pcClass, false, pc, aSkill); if (ret.length() > 0) { if (isFree && ret.indexOf("You do not have enough skill points.") != -1) { SkillRankControl.modRanks(ranksToAdd, pcClass, true, pc, aSkill); } else { warnings.add(ret); return null; } } if (!isFree) { for (int i = 0; i < pc.getLevelInfoSize(); i++) { PCLevelInfo info = pc.getLevelInfo(i); if (points[i] >= 0) { info.setSkillPointsRemaining(points[i]); } } } List<Language> langList = new ArrayList<Language>(); if (ChooseActivation.hasChooseToken(aSkill) && !selection.isEmpty()) { ChoiceManagerList<Language> controller = ChooserUtilities.getConfiguredController(aSkill, pc, null, new ArrayList<String>()); int limit = (int) ranksToAdd; for (CDOMSingleRef<Language> ref : selection) { Language lang = ref.resolvesTo(); if (controller.conditionallyApply(pc, lang)) { langList.add(lang); limit--; } if (limit <= 0) { break; } } } return new KitSkillAdd(aSkill, ranksToAdd, ptsToSpend, langList, pcClass); }