/*
* BonusTest.java
* Copyright 2004 (C) James Dempsey <jdempsey@users.sourceforge.net>
*
* 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 Sep 5, 2004
*
* $Id$
*
*/
package pcgen.core.bonus;
import java.util.ArrayList;
import java.util.List;
import pcgen.AbstractCharacterTestCase;
import pcgen.cdom.base.FormulaFactory;
import pcgen.cdom.content.CNAbility;
import pcgen.cdom.enumeration.ListKey;
import pcgen.cdom.enumeration.StringKey;
import pcgen.cdom.enumeration.Type;
import pcgen.cdom.enumeration.VariableKey;
import pcgen.core.Ability;
import pcgen.core.AbilityCategory;
import pcgen.core.Equipment;
import pcgen.core.Globals;
import pcgen.core.PCClass;
import pcgen.core.PlayerCharacter;
import pcgen.core.Skill;
import pcgen.core.analysis.BonusActivation;
import pcgen.core.character.EquipSet;
import pcgen.rules.context.LoadContext;
import plugin.bonustokens.Var;
/**
* <code>BonusTest</code> test that the Bonus class is functioning
* correctly.
*
*
* @author James Dempsey <jdempsey@users.sourceforge.net>
*/
@SuppressWarnings("nls")
public class BonusTest extends AbstractCharacterTestCase
{
/**
*
*/
public BonusTest()
{
}
/**
* @param arg0
*/
public BonusTest(final String arg0)
{
super(arg0);
}
/**
* Test the skill pre reqs
* @throws Exception
*/
public void testSkillPrereq() throws Exception
{
LoadContext context = Globals.getContext();
final Skill rideSkill = new Skill();
rideSkill.setName("Ride");
rideSkill.put(StringKey.KEY_NAME, "Ride");
rideSkill.addToListFor(ListKey.TYPE, Type.getConstant("DEX"));
final Ability skillFocus = new Ability();
skillFocus.setName("Skill Focus");
skillFocus.put(StringKey.KEY_NAME, "Skill Focus");
final BonusObj saddleBonus =
Bonus.newBonus(context, "SKILL|Ride|-5|!PREITEM:1,TYPE.Saddle");
rideSkill.addToListFor(ListKey.BONUS, saddleBonus);
final Equipment saddle = new Equipment();
saddle.setName("Saddle, Test");
saddle.addToListFor(ListKey.TYPE, Type.getConstant("SADDLE"));
final PlayerCharacter pc = getCharacter();
BonusActivation.activateBonuses(rideSkill, pc);
double iBonus = saddleBonus.resolve(pc, "").doubleValue();
assertEquals("Bonus value", -5.0, iBonus, 0.05);
assertTrue("No saddle, should have a penalty", pc.isApplied(saddleBonus));
pc.addEquipment(saddle);
final EquipSet eqSet = new EquipSet("Test", "Test", "", saddle);
pc.addEquipSet(eqSet);
pc.calcActiveBonuses();
BonusActivation.activateBonuses(rideSkill, pc);
assertFalse("Saddle, should not have a penalty", pc
.isApplied(saddleBonus));
}
/**
* Test the processing of bonusing variables using both
* abilities and equipment.
*/
public void testVarBonus()
{
LoadContext context = Globals.getContext();
Ability dummyFeat = new Ability();
dummyFeat.setName("DummyFeat");
dummyFeat.setCDOMCategory(AbilityCategory.FEAT);
final PlayerCharacter pc = getCharacter();
// Create a variable
dummyFeat.put(VariableKey.getConstant("NegLevels"), FormulaFactory.ZERO);
// Create a bonus to it
Ability dummyFeat2 = new Ability();
dummyFeat2.setName("DummyFeat2");
dummyFeat2.setCDOMCategory(AbilityCategory.FEAT);
BonusObj aBonus = Bonus.newBonus(context, "VAR|NegLevels|7");
if (aBonus != null)
{
dummyFeat2.addToListFor(ListKey.BONUS, aBonus);
}
Equipment equip = new Equipment();
equip.setName("DummyEquip");
aBonus = Bonus.newBonus(context, "VAR|NegLevels|2");
if (aBonus != null)
{
equip.addToListFor(ListKey.BONUS, aBonus);
}
assertEquals("Variable value", 0.0, pc
.getVariableValue("NegLevels", "").doubleValue(), 0.05);
addAbility(AbilityCategory.FEAT, dummyFeat);
assertEquals("Variable value", 0.0, pc
.getVariableValue("NegLevels", "").doubleValue(), 0.05);
assertEquals("Variable value", -0.0, pc.getVariableValue(
"-1*NegLevels", "").doubleValue(), 0.05);
// Add a bonus to it
addAbility(AbilityCategory.FEAT, dummyFeat2);
assertEquals("Variable value", 7.0, pc
.getVariableValue("NegLevels", "").doubleValue(), 0.05);
assertEquals("Variable value", -7.0, pc.getVariableValue(
"-1*NegLevels", "").doubleValue(), 0.05);
// Add the equipment that gives a bonus to NegLevels
EquipSet def = new EquipSet("0.1", "Default");
pc.addEquipSet(def);
final EquipSet eqSet = new EquipSet("0.1.1", "Equipped", "Test", equip);
pc.addEquipSet(eqSet);
pc.setCalcEquipmentList();
pc.calcActiveBonuses();
BonusActivation.activateBonuses(dummyFeat, pc);
assertEquals("Variable value", 9.0, pc
.getVariableValue("NegLevels", "").doubleValue(), 0.05);
assertEquals("Variable value", -9.0, pc.getVariableValue(
"-1*NegLevels", "").doubleValue(), 0.05);
}
/**
* Test the buildDepends method of BonusObj.
*/
public void testBuildDepends()
{
BonusObj maxDexStr = new Var();
maxDexStr.setValue("VAR|NegLevels|max(STR,DEX)-STR");
assertTrue("Should have flagged a dependancy on DEX", maxDexStr
.getDependsOn("DEX"));
assertTrue("Should have flagged a dependancy on STR", maxDexStr
.getDependsOn("STR"));
BonusObj monkMove = new Var();
monkMove.setValue("VAR|MonkMove|floor(var(\"monkLvl\")/3)*10");
assertTrue("Should have flagged a dependancy on monkLvl", monkMove
.getDependsOn("MONKLVL"));
BonusObj condSkill = new plugin.bonustokens.Skill();
condSkill.setValue("SKILL.CONCENTRATION.MISC");
assertFalse("Should not have flagged a dependancy on stat", condSkill
.getDependsOn("STAT"));
assertTrue("Should have flagged a dependancy on concentration", condSkill
.getDependsOn("CONCENTRATION"));
assertTrue("Should have flagged a name dependancy on stat", condSkill
.getDependsOnBonusName("STAT"));
condSkill = new plugin.bonustokens.Skill();
condSkill.setValue("skillinfo(\"TOTALRANK\", \"SEARCH\")");
assertFalse("Should not have flagged a dependancy on stat", condSkill
.getDependsOn("STAT"));
assertTrue("Should have flagged a dependancy on search", condSkill
.getDependsOn("SEARCH"));
assertTrue("Should have flagged a name dependancy on stat", condSkill
.getDependsOnBonusName("STAT"));
}
/**
* Test to make sure that fix for replacing %LIST within a
* bonuses value will work.
*/
public void testBonuswithLISTValue()
{
final PlayerCharacter character = getCharacter();
LoadContext context = Globals.getContext();
setPCStat(character, intel, 18);
BonusObj bonus =
Bonus.newBonus(context, "VISION|Darkvision|%LIST+10|TYPE=Magical Boon");
List<BonusObj> bonusList = new ArrayList<>();
bonusList.add(bonus);
Ability testBonus = new Ability();
testBonus.setName("TB1Assoc");
testBonus.setCDOMCategory(AbilityCategory.FEAT);
testBonus.addToListFor(ListKey.BONUS, bonus);
Globals.getContext().unconditionallyProcess(testBonus, "CHOOSE", "PCSTAT|ALL");
Globals.getContext().unconditionallyProcess(testBonus, "MULT", "YES");
CNAbility cna = AbstractCharacterTestCase.applyAbility(character, AbilityCategory.FEAT, testBonus, "INT");
testBonus = cna.getAbility();
character.calcActiveBonuses();
bonus = testBonus.getSafeListFor(ListKey.BONUS).get(0);
List<BonusPair> bonusPairs = character.getStringListFromBonus(bonus);
assertEquals(1, bonusPairs.size());
BonusPair bp = bonusPairs.get(0);
assertEquals("VISION.DARKVISION:MAGICAL BOON", bp.fullyQualifiedBonusType);
assertEquals(14, bp.resolve(character).intValue());
}
public void testBonuswithLISTValueTwoAssoc()
{
final PlayerCharacter character = getCharacter();
LoadContext context = Globals.getContext();
setPCStat(character, intel, 18);
setPCStat(character, str, 16);
BonusObj bonus =
Bonus.newBonus(context, "VISION|Darkvision|%LIST+10|TYPE=Magical Boon");
List<BonusObj> bonusList = new ArrayList<>();
bonusList.add(bonus);
Ability testBonus = new Ability();
testBonus.setName("TB2Assoc");
testBonus.setCDOMCategory(AbilityCategory.FEAT);
testBonus.addToListFor(ListKey.BONUS, bonus);
Globals.getContext().unconditionallyProcess(testBonus, "CHOOSE", "PCSTAT|ALL");
Globals.getContext().unconditionallyProcess(testBonus, "MULT", "YES");
CNAbility cna = AbstractCharacterTestCase.applyAbility(character, AbilityCategory.FEAT, testBonus, "INT");
testBonus = cna.getAbility();
AbstractCharacterTestCase.applyAbility(character, AbilityCategory.FEAT, testBonus, "STR");
character.calcActiveBonuses();
bonus = testBonus.getSafeListFor(ListKey.BONUS).get(0);
List<BonusPair> bonusPairs = character.getStringListFromBonus(bonus);
assertEquals(2, bonusPairs.size());
int totalBonus = 0;
BonusPair bp = bonusPairs.get(0);
assertEquals("VISION.DARKVISION:MAGICAL BOON", bp.fullyQualifiedBonusType);
totalBonus += bp.resolve(character).intValue();
bp = bonusPairs.get(1);
assertEquals("VISION.DARKVISION:MAGICAL BOON", bp.fullyQualifiedBonusType);
totalBonus += bp.resolve(character).intValue();
assertEquals(27, totalBonus);
}
public void testBonuswithLISTValueTwoAssocInfoList()
{
final PlayerCharacter character = getCharacter();
LoadContext context = Globals.getContext();
setPCStat(character, intel, 18);
setPCStat(character, str, 16);
BonusObj bonus = Bonus.newBonus(context, "STAT|%LIST|%LIST+1");
List<BonusObj> bonusList = new ArrayList<>();
bonusList.add(bonus);
Ability testBonus = new Ability();
testBonus.setName("TB2AssocList");
testBonus.setCDOMCategory(AbilityCategory.FEAT);
Globals.getContext().unconditionallyProcess(testBonus, "CHOOSE", "PCSTAT|ALL");
Globals.getContext().unconditionallyProcess(testBonus, "MULT", "YES");
testBonus.addToListFor(ListKey.BONUS, bonus);
CNAbility cna = AbstractCharacterTestCase.applyAbility(character, AbilityCategory.FEAT, testBonus, "INT");
testBonus = cna.getAbility();
AbstractCharacterTestCase.applyAbility(character, AbilityCategory.FEAT, testBonus, "STR");
character.calcActiveBonuses();
bonus = testBonus.getSafeListFor(ListKey.BONUS).get(0);
List<BonusPair> bonusPairs = character.getStringListFromBonus(bonus);
assertEquals(2, bonusPairs.size());
for (BonusPair bp : bonusPairs)
{
if (bp.fullyQualifiedBonusType.equals("STAT.INT"))
{
assertEquals(5, bp.resolve(character).intValue());
}
else
{
assertEquals(4, bp.resolve(character).intValue());
}
}
}
/**
* Test to make sure that fix for replacing %LIST within a
* bonuses value will work.
*/
public void testSpellKnownBonusWithLISTValue()
{
final PlayerCharacter character = getCharacter();
LoadContext context = Globals.getContext();
context.getReferenceContext().constructNowIfNecessary(PCClass.class, "Wizard");
BonusObj bonus = Bonus.newBonus(context, "SPELLKNOWN|%LIST|1");
List<BonusObj> bonusList = new ArrayList<>();
bonusList.add(bonus);
Ability testBonus = new Ability();
testBonus.setName("TB1Assoc");
testBonus.setCDOMCategory(AbilityCategory.FEAT);
testBonus.addToListFor(ListKey.BONUS, bonus);
Globals.getContext().unconditionallyProcess(testBonus, "CHOOSE", "SPELLLEVEL|Wizard|1|5");
Globals.getContext().unconditionallyProcess(testBonus, "MULT", "YES");
CNAbility cna = AbstractCharacterTestCase.applyAbility(character, AbilityCategory.FEAT, testBonus, "CLASS.Wizard;LEVEL.1");
testBonus = cna.getAbility();
character.calcActiveBonuses();
bonus = testBonus.getSafeListFor(ListKey.BONUS).get(0);
List<BonusPair> bonusPairs = character.getStringListFromBonus(bonus);
assertEquals(1, bonusPairs.size());
BonusPair bp = bonusPairs.get(0);
assertEquals("SPELLKNOWN.CLASS.Wizard;LEVEL.1", bp.fullyQualifiedBonusType);
}
}