/*
* Copyright (c) 2008 Tom Parker <thpr@users.sourceforge.net>
*
* This program 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 program 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.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package plugin.lsttokens.pcclass.level;
import pcgen.base.formula.AddingFormula;
import pcgen.base.formula.DividingFormula;
import pcgen.base.formula.MultiplyingFormula;
import pcgen.base.formula.SubtractingFormula;
import pcgen.cdom.base.Constants;
import pcgen.cdom.content.HitDie;
import pcgen.cdom.content.Processor;
import pcgen.cdom.enumeration.ObjectKey;
import pcgen.cdom.inst.PCClassLevel;
import pcgen.cdom.processor.HitDieFormula;
import pcgen.cdom.processor.HitDieLock;
import pcgen.cdom.processor.HitDieStep;
import pcgen.rules.context.LoadContext;
import pcgen.rules.persistence.token.AbstractToken;
import pcgen.rules.persistence.token.CDOMPrimaryToken;
import pcgen.rules.persistence.token.ComplexParseResult;
import pcgen.rules.persistence.token.ParseResult;
/**
* @author djones4
*
*/
public class HitdieLst extends AbstractToken implements
CDOMPrimaryToken<PCClassLevel>
{
@Override
public String getTokenName()
{
return "HITDIE";
}
@Override
public ParseResult parseToken(LoadContext context, PCClassLevel level, String value)
{
try
{
String lock = value;
int pipeLoc = lock.indexOf(Constants.PIPE);
if (pipeLoc != -1)
{
return new ParseResult.Fail(getTokenName() + " is invalid has a pipe: "
+ value, context);
}
Processor<HitDie> hdm;
if (lock.startsWith("%/"))
{
// HITDIE:%/num --- divides the classes hit die by num.
int denom = Integer.parseInt(lock.substring(2));
if (denom <= 0)
{
return new ParseResult.Fail(getTokenName()
+ " was expecting a Positive Integer "
+ "for dividing Lock, was : " + lock.substring(2), context);
}
hdm = new HitDieFormula(new DividingFormula(denom));
}
else if (lock.startsWith("%*"))
{
// HITDIE:%*num --- multiplies the classes hit die by num.
int mult = Integer.parseInt(lock.substring(2));
if (mult <= 0)
{
return new ParseResult.Fail(getTokenName()
+ " was expecting a Positive "
+ "Integer for multiplying Lock, was : "
+ lock.substring(2), context);
}
hdm = new HitDieFormula(new MultiplyingFormula(mult));
}
else if (lock.startsWith("%+"))
{
// possibly redundant with BONUS:HD MAX|num
// HITDIE:%+num --- adds num to the classes hit die.
int add = Integer.parseInt(lock.substring(2));
if (add <= 0)
{
return new ParseResult.Fail(getTokenName()
+ " was expecting a Positive "
+ "Integer for adding Lock, was : "
+ lock.substring(2), context);
}
hdm = new HitDieFormula(new AddingFormula(add));
}
else if (lock.startsWith("%-"))
{
// HITDIE:%-num --- subtracts num from the classes hit die.
// possibly redundant with BONUS:HD MAX|num if that will
// take negative numbers.
int sub = Integer.parseInt(lock.substring(2));
if (sub <= 0)
{
return new ParseResult.Fail(getTokenName()
+ " was expecting a Positive "
+ "Integer for subtracting Lock, was : "
+ lock.substring(2), context);
}
hdm = new HitDieFormula(new SubtractingFormula(sub));
}
else if (lock.startsWith("%up"))
{
// HITDIE:%upnum --- moves the hit die num steps up the die size
// list d4,d6,d8,d10,d12. Stops at d12.
int steps = Integer.parseInt(lock.substring(3));
if (steps <= 0)
{
return new ParseResult.Fail("Invalid Step Count: " + steps + " in "
+ getTokenName() + " up (must be positive)", context);
}
if (steps >= 5)
{
return new ParseResult.Fail("Invalid Step Count: " + steps + " in "
+ getTokenName() + " up (too large)", context);
}
hdm = new HitDieStep(steps, new HitDie(12));
}
else if (lock.startsWith("%Hup"))
{
// HITDIE:%upnum --- moves the hit die num steps up the die size
// list d4,d6,d8,d10,d12. Stops at d12.
int steps = Integer.parseInt(lock.substring(4));
if (steps <= 0)
{
return new ParseResult.Fail("Invalid Step Count: " + steps + " in "
+ getTokenName(), context);
}
hdm = new HitDieStep(steps, null);
}
else if (lock.startsWith("%down"))
{
// HITDIE:%downnum --- moves the hit die num steps down the die
// size
// list d4,d6,d8,d10,d12. Stops at d4.
int steps = Integer.parseInt(lock.substring(5));
if (steps <= 0)
{
return new ParseResult.Fail("Invalid Step Count: " + steps + " in "
+ getTokenName() + " down (must be positive)", context);
}
if (steps >= 5)
{
return new ParseResult.Fail("Invalid Step Count: " + steps + " in "
+ getTokenName() + " down (too large)", context);
}
hdm = new HitDieStep(-steps, new HitDie(4));
}
else if (lock.startsWith("%Hdown"))
{
// HITDIE:%downnum --- moves the hit die num steps down the die
// size
// list. No limit.
int steps = Integer.parseInt(lock.substring(6));
if (steps <= 0)
{
return new ParseResult.Fail("Invalid Step Count: " + steps + " in "
+ getTokenName(), context);
}
hdm = new HitDieStep(-steps, null);
}
else
{
int i = Integer.parseInt(lock);
if (i <= 0)
{
return new ParseResult.Fail("Invalid HitDie: " + i + " in "
+ getTokenName(), context);
}
// HITDIE:num --- sets the hit die to num regardless of class.
hdm = new HitDieLock(new HitDie(i));
}
context.getObjectContext().put(level, ObjectKey.HITDIE, hdm);
return ParseResult.SUCCESS;
}
catch (NumberFormatException nfe)
{
ComplexParseResult pr = new ComplexParseResult();
pr.addErrorMessage("Invalid Number in " + getTokenName() + ": "
+ nfe.getLocalizedMessage());
pr.addErrorMessage(" Must be an Integer");
return pr;
}
}
@Override
public String[] unparse(LoadContext context, PCClassLevel level)
{
Processor<HitDie> hdcf = context.getObjectContext().getObject(level,
ObjectKey.HITDIE);
if (hdcf == null)
{
return null;
}
return new String[] { hdcf.getLSTformat() };
}
@Override
public Class<PCClassLevel> getTokenClass()
{
return PCClassLevel.class;
}
}