/* * FollowersLst.java * Copyright 2006 (C) Aaron Divinsky <boomer70@yahoo.com> * Copyright 2008 (C) Thomas Parker <thpr@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 * * Current Ver: $Revision$ */ package plugin.lsttokens; import java.util.TreeSet; import pcgen.base.formula.Formula; import pcgen.base.text.ParsingSeparator; import pcgen.cdom.base.CDOMObject; import pcgen.cdom.base.Constants; import pcgen.cdom.base.FormulaFactory; import pcgen.cdom.base.Ungranted; import pcgen.cdom.enumeration.ListKey; import pcgen.cdom.helper.FollowerLimit; import pcgen.cdom.list.CompanionList; import pcgen.cdom.reference.CDOMSingleRef; import pcgen.rules.context.Changes; import pcgen.rules.context.LoadContext; import pcgen.rules.persistence.token.CDOMPrimaryToken; import pcgen.rules.persistence.token.ParseResult; /** * This class implements support for the FOLLOWERS LST token. * <p> * <b>Tag Name</b>: {@code FOLLOWERS}:x|y<br> * <b>Variables Used (x)</b>: Text (The type of companion the limit will apply * to).<br> * <b>Variables Used (y)</b>: Number, variable or formula (Number of this type * of companion the master can have) * <p> * <b>What it does:</b><br> * <ul> * <li>Limits the number of the specified type of companion the master can * have.</li> * <li>Optional, if this tag is not present no limits are placed on the number * of companions the character can have.</li> * <li>If more than one tag is encountered the highest value is used.</li> * <li>The value can be adjusted with the {@code BONUS:FOLLOWERS} tag</li> * </ul> * <b>Where it is used:</b><br> * Global tag, would most often be used in class and feat (ability) files, * should also be enabled for templates and Domains. * <p> * <b>Examples:</b><br> * {@code FOLLOWERS:Familiar|1}<br> * A character is allowed only 1 companion of type Familiar * * @author divaa01 * */ public class FollowersLst implements CDOMPrimaryToken<CDOMObject> { /** * * @return token name */ @Override public String getTokenName() { return "FOLLOWERS"; //$NON-NLS-1$ } @Override public ParseResult parseToken(LoadContext context, CDOMObject obj, String value) { if (obj instanceof Ungranted) { return new ParseResult.Fail("Cannot use " + getTokenName() + " on an Ungranted object type: " + obj.getClass().getSimpleName(), context); } if ((value == null) || value.isEmpty()) { return new ParseResult.Fail("Argument in " + getTokenName() + " cannot be empty", context); } ParsingSeparator sep = new ParsingSeparator(value, '|'); sep.addGroupingPair('[', ']'); sep.addGroupingPair('(', ')'); String followerType = sep.next(); if (followerType.isEmpty()) { return new ParseResult.Fail("Follower Type in " + getTokenName() + " cannot be empty", context); } if (!sep.hasNext()) { return new ParseResult.Fail(getTokenName() + " has no PIPE character: " + "Must be of the form <follower type>|<formula>", context); } String followerNumber = sep.next(); if (sep.hasNext()) { return new ParseResult.Fail(getTokenName() + " has too many PIPE characters: " + "Must be of the form <follower type>|<formula", context); } if (followerNumber.isEmpty()) { return new ParseResult.Fail("Follower Count in " + getTokenName() + " cannot be empty", context); } CDOMSingleRef<CompanionList> cl = context.getReferenceContext().getCDOMReference( CompanionList.class, followerType); Formula num = FormulaFactory.getFormulaFor(followerNumber); if (!num.isValid()) { return new ParseResult.Fail("Number of Followers in " + getTokenName() + " was not valid: " + num.toString(), context); } context.getObjectContext().addToList(obj, ListKey.FOLLOWERS, new FollowerLimit(cl, num)); return ParseResult.SUCCESS; } @Override public String[] unparse(LoadContext context, CDOMObject obj) { Changes<FollowerLimit> changes = context.getObjectContext() .getListChanges(obj, ListKey.FOLLOWERS); if (changes == null || changes.isEmpty()) { return null; } TreeSet<String> returnSet = new TreeSet<>(); for (FollowerLimit fl : changes.getAdded()) { String followerType = fl.getCompanionList().getLSTformat(false); Formula followerNumber = fl.getValue(); returnSet.add(followerType + Constants.PIPE + followerNumber.toString()); } return returnSet.toArray(new String[returnSet.size()]); } @Override public Class<CDOMObject> getTokenClass() { return CDOMObject.class; } }