Search in sources :

Example 26 with Spell

use of pcgen.core.spell.Spell in project pcgen by PCGen.

the class StatTokenTest method setUp.

@Override
protected void setUp() throws Exception {
    super.setUp();
    LoadContext context = Globals.getContext();
    boots = new Equipment();
    boots.setName("Boots of Dex");
    BonusObj aBonus = Bonus.newBonus(context, "STAT|DEX|2|TYPE=Enhancement");
    if (aBonus != null) {
        boots.addToListFor(ListKey.BONUS, aBonus);
    }
    spell = new Spell();
    spell.setName("Weasel's Slipperiness");
    aBonus = Bonus.newBonus(context, "STAT|DEX|4|TYPE=Enhancement");
    if (aBonus != null) {
        spell.addToListFor(ListKey.BONUS, aBonus);
    }
    template1 = new PCTemplate();
    template1.setName("Munchkiny Goodness I");
    aBonus = Bonus.newBonus(context, "STAT|STR,CON,DEX|1|TYPE=Luck");
    if (aBonus != null) {
        template1.addToListFor(ListKey.BONUS, aBonus);
    }
    template2 = new PCTemplate();
    template2.setName("Munchkiny Goodness II");
    aBonus = Bonus.newBonus(context, "STAT|STR,CON,DEX|1|TYPE=Enhancement");
    if (aBonus != null) {
        template2.addToListFor(ListKey.BONUS, aBonus);
    }
    template3 = new PCTemplate();
    template3.setName("Lock the stat");
    template3.addToListFor(ListKey.STAT_MINVALUE, new StatLock(context.getReferenceContext().getCDOMReference(PCStat.class, "WIS"), FormulaFactory.getFormulaFor("12")));
    template4 = new PCTemplate();
    template4.setName("Unwise");
    aBonus = Bonus.newBonus(context, "STAT|WIS|-8|TYPE=Enhancement");
    if (aBonus != null) {
        template4.addToListFor(ListKey.BONUS, aBonus);
    }
}
Also used : Equipment(pcgen.core.Equipment) BonusObj(pcgen.core.bonus.BonusObj) LoadContext(pcgen.rules.context.LoadContext) PCTemplate(pcgen.core.PCTemplate) Spell(pcgen.core.spell.Spell) StatLock(pcgen.cdom.helper.StatLock)

Example 27 with Spell

use of pcgen.core.spell.Spell in project pcgen by PCGen.

the class WeaponTokenTest method testWpnFinesse.

/**
	 * Test the processing of a finesseable weapon both with and without weapon finesse
	 * and temporary bonuses.
	 */
public void testWpnFinesse() {
    PlayerCharacter character = getCharacter();
    assertEquals("Prof should be longsword", "KEY_LONGSWORD", fineSword.get(ObjectKey.WEAPON_PROF).get().getKeyName());
    LoadContext context = Globals.getContext();
    character.addEquipment(fineSword);
    EquipSet es = new EquipSet("0.1.3", "Longsword (Fine)", fineSword.getName(), fineSword);
    character.addEquipSet(es);
    character.setCalcEquipmentList();
    // Test weapon profs effects on large weapons
    WeaponToken token = new WeaponToken();
    assertEquals("Fine sword", "+18/+13/+8/+3", token.getToken("WEAPON.3.BASEHIT", character, null));
    // Now apply weapon finess and check dex is used rather than str
    Ability wpnFinesse = new Ability();
    wpnFinesse.setName("Weapon Finesse");
    wpnFinesse.setCDOMCategory(AbilityCategory.FEAT);
    wpnFinesse.put(StringKey.KEY_NAME, "Weapon Finesse");
    final BonusObj wfBonus = Bonus.newBonus(context, "COMBAT|TOHIT.Finesseable|((max(STR,DEX)-STR)+SHIELDACCHECK)|TYPE=NotRanged");
    wpnFinesse.addToListFor(ListKey.BONUS, wfBonus);
    addAbility(AbilityCategory.FEAT, wpnFinesse);
    assertEquals("Fine sword", "+19/+14/+9/+4", token.getToken("WEAPON.3.BASEHIT", character, null));
    // Add a temp penalty to dex and check that it is applied
    character.setUseTempMods(true);
    Spell spell2 = new Spell();
    spell2.setName("Concrete Boots");
    final BonusObj aBonus = Bonus.newBonus(context, "STAT|DEX|-4");
    if (aBonus != null) {
        spell2.addToListFor(ListKey.BONUS, aBonus);
    }
    BonusObj penalty = spell2.getRawBonusList(character).get(0);
    character.addTempBonus(penalty, spell2, character);
    character.calcActiveBonuses();
    assertEquals("Fine sword", "+18/+13/+8/+3", token.getToken("WEAPON.3.BASEHIT", character, null));
}
Also used : Ability(pcgen.core.Ability) PlayerCharacter(pcgen.core.PlayerCharacter) BonusObj(pcgen.core.bonus.BonusObj) EquipSet(pcgen.core.character.EquipSet) LoadContext(pcgen.rules.context.LoadContext) Spell(pcgen.core.spell.Spell)

Example 28 with Spell

use of pcgen.core.spell.Spell in project pcgen by PCGen.

the class KnownspellsTokenTest method testUnparseNegativeLevel.

@Test
public void testUnparseNegativeLevel() throws PersistenceLayerException {
    try {
        CDOMGroupRef<Spell> all = primaryContext.getReferenceContext().getCDOMAllReference(Spell.class);
        primaryProf.addToListFor(ListKey.KNOWN_SPELLS, new KnownSpellIdentifier(all, -3));
        assertBadUnparse();
    } catch (IllegalArgumentException e) {
    //Good here too :)
    }
}
Also used : KnownSpellIdentifier(pcgen.cdom.content.KnownSpellIdentifier) Spell(pcgen.core.spell.Spell) Test(org.junit.Test)

Example 29 with Spell

use of pcgen.core.spell.Spell in project pcgen by PCGen.

the class SpelllevelLst method subParse.

private <CL extends Loadable & CDOMList<Spell>> boolean subParse(LoadContext context, CDOMObject obj, Class<CL> tagType, String tokString, String spellString, List<Prerequisite> prereqs) {
    int equalLoc = tokString.indexOf(Constants.EQUALS);
    if (equalLoc == -1) {
        Logging.errorPrint("Expected an = in SPELLLEVEL " + "definition: " + tokString);
        return false;
    }
    String casterString = tokString.substring(0, equalLoc);
    String spellLevel = tokString.substring(equalLoc + 1);
    Integer splLevel;
    try {
        splLevel = Integer.decode(spellLevel);
    } catch (NumberFormatException nfe) {
        Logging.errorPrint("Expected a number for SPELLLEVEL, found: " + spellLevel);
        return false;
    }
    if (isEmpty(casterString) || hasIllegalSeparator(',', casterString)) {
        return false;
    }
    StringTokenizer clTok = new StringTokenizer(casterString, Constants.COMMA);
    List<CDOMReference<? extends CDOMList<Spell>>> slList = new ArrayList<>();
    while (clTok.hasMoreTokens()) {
        String classString = clTok.nextToken();
        CDOMReference<CL> ref;
        if (classString.startsWith("SPELLCASTER.")) {
            /*
				 * This is actually a TYPE
				 */
            ref = context.getReferenceContext().getCDOMTypeReference(tagType, classString.substring(12));
        } else {
            ref = context.getReferenceContext().getCDOMReference(tagType, classString);
        }
        slList.add(ref);
    }
    if (hasIllegalSeparator(',', spellString)) {
        return false;
    }
    StringTokenizer spTok = new StringTokenizer(spellString, ",");
    while (spTok.hasMoreTokens()) {
        String spellName = spTok.nextToken();
        CDOMReference<Spell> sp = context.getReferenceContext().getCDOMReference(Spell.class, spellName);
        for (CDOMReference<? extends CDOMList<Spell>> sl : slList) {
            AssociatedPrereqObject tpr = context.getListContext().addToList(getTokenName(), obj, sl, sp);
            tpr.setAssociation(AssociationKey.SPELL_LEVEL, splLevel);
            tpr.addAllPrerequisites(prereqs);
        }
    }
    return true;
}
Also used : ArrayList(java.util.ArrayList) Spell(pcgen.core.spell.Spell) StringTokenizer(java.util.StringTokenizer) CDOMList(pcgen.cdom.base.CDOMList) CDOMReference(pcgen.cdom.base.CDOMReference) AssociatedPrereqObject(pcgen.cdom.base.AssociatedPrereqObject)

Example 30 with Spell

use of pcgen.core.spell.Spell in project pcgen by PCGen.

the class SpellsLst method parseNonEmptyToken.

/**
	 * {@literal 
	 * SPELLS:<spellbook name>|[<optional parameters, pipe deliminated>] |<spell
	 * name>[,<formula for DC>] |<spell name2>[,<formula2 for DC>] |PRExxx
	 * |PRExxx
	 *
	 * CASTERLEVEL=<formula> Casterlevel of spells TIMES=<formula> Cast Times
	 * per day, -1=At Will
	 *}
	 * @param sourceLine
	 *            Line from the LST file without the SPELLS:
	 * @return spells list
	 */
@Override
protected ParseResult parseNonEmptyToken(LoadContext context, CDOMObject obj, String sourceLine) {
    if (obj instanceof Ungranted) {
        return new ParseResult.Fail("Cannot use " + getTokenName() + " on an Ungranted object type: " + obj.getClass().getSimpleName(), context);
    }
    if ((sourceLine == null) || sourceLine.isEmpty()) {
        return new ParseResult.Fail("Argument in " + getTokenName() + " cannot be empty", context);
    }
    if (sourceLine.equals(Constants.LST_DOT_CLEAR_ALL)) {
        context.getListContext().removeAllFromList(getTokenName(), obj, Spell.SPELLS);
        return ParseResult.SUCCESS;
    }
    ParsingSeparator sep = new ParsingSeparator(sourceLine, '|');
    sep.addGroupingPair('[', ']');
    sep.addGroupingPair('(', ')');
    String spellBook = sep.next();
    if (spellBook.isEmpty()) {
        return new ParseResult.Fail("SpellBook in " + getTokenName() + " cannot be empty", context);
    }
    // Formula casterLevel = null;
    String casterLevel = null;
    String times = null;
    String timeunit = null;
    if (!sep.hasNext()) {
        return new ParseResult.Fail(getTokenName() + ": minimally requires a Spell Name", context);
    }
    String token = sep.next();
    while (true) {
        if (token.startsWith("TIMES=")) {
            if (times != null) {
                return new ParseResult.Fail("Found two TIMES entries in " + getTokenName() + ": invalid: " + sourceLine, context);
            }
            times = token.substring(6);
            if (times.isEmpty()) {
                return new ParseResult.Fail("Error in Times in " + getTokenName() + ": argument was empty", context);
            }
            if (!sep.hasNext()) {
                return new ParseResult.Fail(getTokenName() + ": minimally requires " + "a Spell Name (after TIMES=)", context);
            }
            token = sep.next();
        } else if (token.startsWith("TIMEUNIT=")) {
            if (timeunit != null) {
                return new ParseResult.Fail("Found two TIMEUNIT entries in " + getTokenName() + ": invalid: " + sourceLine, context);
            }
            timeunit = token.substring(9);
            if (timeunit.isEmpty()) {
                return new ParseResult.Fail("Error in TimeUnit in " + getTokenName() + ": argument was empty", context);
            }
            if (!sep.hasNext()) {
                return new ParseResult.Fail(getTokenName() + ": minimally requires " + "a Spell Name (after TIMEUNIT=)", context);
            }
            token = sep.next();
        } else if (token.startsWith("CASTERLEVEL=")) {
            if (casterLevel != null) {
                return new ParseResult.Fail("Found two CASTERLEVEL entries in " + getTokenName() + ": invalid: " + sourceLine, context);
            }
            casterLevel = token.substring(12);
            if (casterLevel.isEmpty()) {
                return new ParseResult.Fail("Error in Caster Level in " + getTokenName() + ": argument was empty", context);
            }
            if (!sep.hasNext()) {
                return new ParseResult.Fail(getTokenName() + ": minimally requires a " + "Spell Name (after CASTERLEVEL=)", context);
            }
            token = sep.next();
        } else {
            break;
        }
    }
    if (times == null) {
        times = "1";
    }
    if (token.isEmpty()) {
        return new ParseResult.Fail("Spell arguments may not be empty in " + getTokenName() + ": " + sourceLine, context);
    }
    if (token.charAt(0) == ',') {
        return new ParseResult.Fail(getTokenName() + " Spell arguments may not start with , : " + token, context);
    }
    if (token.charAt(token.length() - 1) == ',') {
        return new ParseResult.Fail(getTokenName() + " Spell arguments may not end with , : " + token, context);
    }
    if (token.indexOf(",,") != -1) {
        return new ParseResult.Fail(getTokenName() + " Spell arguments uses double separator ,, : " + token, context);
    }
    /*
		 * CONSIDER This is currently order enforcing the reference fetching to
		 * match the integration tests that we perform, and their current
		 * behavior. Not sure if this is really tbe best solution?
		 *
		 * See CDOMObject.
		 */
    DoubleKeyMap<CDOMReference<Spell>, AssociationKey<?>, Object> dkm = new DoubleKeyMap<>(LinkedHashMap.class, HashMap.class);
    while (true) {
        if (token.isEmpty()) {
            return new ParseResult.Fail("Spell arguments may not end with comma or pipe in " + getTokenName() + ": " + sourceLine, context);
        }
        int commaLoc = token.indexOf(',');
        String name = commaLoc == -1 ? token : token.substring(0, commaLoc);
        CDOMReference<Spell> spell = context.getReferenceContext().getCDOMReference(Spell.class, name);
        dkm.put(spell, AssociationKey.CASTER_LEVEL, casterLevel);
        Formula timesFormula = FormulaFactory.getFormulaFor(times);
        if (!timesFormula.isValid()) {
            return new ParseResult.Fail("Times in " + getTokenName() + " was not valid: " + timesFormula.toString(), context);
        }
        dkm.put(spell, AssociationKey.TIMES_PER_UNIT, timesFormula);
        if (timeunit != null) {
            dkm.put(spell, AssociationKey.TIME_UNIT, timeunit);
        }
        dkm.put(spell, AssociationKey.SPELLBOOK, spellBook);
        if (commaLoc != -1) {
            dkm.put(spell, AssociationKey.DC_FORMULA, token.substring(commaLoc + 1));
        }
        if (!sep.hasNext()) {
            // No prereqs, so we're done
            finish(context, obj, dkm, null);
            return ParseResult.SUCCESS;
        }
        token = sep.next();
        if (looksLikeAPrerequisite(token)) {
            break;
        }
    }
    List<Prerequisite> prereqs = new ArrayList<>();
    while (true) {
        Prerequisite prereq = getPrerequisite(token);
        if (prereq == null) {
            return new ParseResult.Fail("   (Did you put spells after the " + "PRExxx tags in SPELLS:?)", context);
        }
        prereqs.add(prereq);
        if (!sep.hasNext()) {
            break;
        }
        token = sep.next();
    }
    finish(context, obj, dkm, prereqs);
    return ParseResult.SUCCESS;
}
Also used : AssociationKey(pcgen.cdom.enumeration.AssociationKey) ParseResult(pcgen.rules.persistence.token.ParseResult) ArrayList(java.util.ArrayList) Ungranted(pcgen.cdom.base.Ungranted) Spell(pcgen.core.spell.Spell) Formula(pcgen.base.formula.Formula) ParsingSeparator(pcgen.base.text.ParsingSeparator) CDOMObject(pcgen.cdom.base.CDOMObject) AssociatedPrereqObject(pcgen.cdom.base.AssociatedPrereqObject) DoubleKeyMap(pcgen.base.util.DoubleKeyMap) CDOMReference(pcgen.cdom.base.CDOMReference) Prerequisite(pcgen.core.prereq.Prerequisite)

Aggregations

Spell (pcgen.core.spell.Spell)87 CharacterSpell (pcgen.core.character.CharacterSpell)35 ArrayList (java.util.ArrayList)25 PCClass (pcgen.core.PCClass)24 AssociatedPrereqObject (pcgen.cdom.base.AssociatedPrereqObject)16 CDOMReference (pcgen.cdom.base.CDOMReference)15 Ability (pcgen.core.Ability)15 LoadContext (pcgen.rules.context.LoadContext)13 CDOMList (pcgen.cdom.base.CDOMList)12 CDOMObject (pcgen.cdom.base.CDOMObject)11 Test (org.junit.Test)10 KnownSpellIdentifier (pcgen.cdom.content.KnownSpellIdentifier)9 AvailableSpell (pcgen.cdom.helper.AvailableSpell)8 StringTokenizer (java.util.StringTokenizer)7 CNAbility (pcgen.cdom.content.CNAbility)7 ClassSpellList (pcgen.cdom.list.ClassSpellList)7 DomainSpellList (pcgen.cdom.list.DomainSpellList)7 Formula (pcgen.base.formula.Formula)6 Domain (pcgen.core.Domain)6 PObject (pcgen.core.PObject)6