/**
* Copyright (C) 2002-2012 The FreeCol Team
*
* This file is part of FreeCol.
*
* FreeCol is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* FreeCol 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with FreeCol. If not, see <http://www.gnu.org/licenses/>.
*/
package net.sf.freecol.common.model;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;
public class Role extends BuildableType {
/**
* The Role to downgrade to after losing a battle. Defaults to
* <code>null</code>. Note that some UnitTypes and Roles may be
* disposed instead of downgraded when losing a battle.
*/
private Role downgrade;
/**
* The maximum multiple of required goods this Role may
* carry. Defaults to <code>1</code>.
*/
private int maximumCount = 1;
/**
* The expert unit for this Role, e.g. a hardy pioneer is an
* expert for the pioneer role.
*/
private UnitType expertUnit;
/**
* Sorts roles by defensive power, descendingly.
*/
public static final Comparator<Role> defensiveComparator = new Comparator<Role>() {
public int compare(Role role1, Role role2) {
float defence1 = role1.getDefence();
float defence2 = role2.getDefence();
if (defence1 > defence2) {
return -1;
} else if (defence1 < defence2) {
return 1;
} else {
return 0;
}
}
};
/**
* Sorts roles by offensive power, descendingly.
*/
public static final Comparator<Role> offensiveComparator = new Comparator<Role>() {
public int compare(Role role1, Role role2) {
float offence1 = role1.getOffence();
float offence2 = role2.getOffence();
if (offence1 > offence2) {
return -1;
} else if (offence1 < offence2) {
return 1;
} else {
return 0;
}
}
};
/**
* Creates a new <code>Role</code> instance.
*
* @param id a <code>String</code> value
* @param specification a <code>Specification</code> value
*/
public Role(String id, Specification specification) {
super(id, specification);
}
/**
* Get the <code>Downgrade</code> value.
*
* @return a <code>Role</code> value
*/
public final Role getDowngrade() {
return downgrade;
}
/**
* Set the <code>Downgrade</code> value.
*
* @param newDowngrade The new Downgrade value.
*/
public final void setDowngrade(final Role newDowngrade) {
this.downgrade = newDowngrade;
}
/**
* Get the <code>MaximumCount</code> value.
*
* @return an <code>int</code> value
*/
public final int getMaximumCount() {
return maximumCount;
}
/**
* Set the <code>MaximumCount</code> value.
*
* @param newMaximumCount The new MaximumCount value.
*/
public final void setMaximumCount(final int newMaximumCount) {
this.maximumCount = newMaximumCount;
}
/**
* Get the <code>ExpertUnit</code> value.
*
* @return an <code>UnitType</code> value
*/
public final UnitType getExpertUnit() {
return expertUnit;
}
/**
* Set the <code>ExpertUnit</code> value.
*
* @param newExpertUnit The new ExpertUnit value.
*/
public final void setExpertUnit(final UnitType newExpertUnit) {
this.expertUnit = newExpertUnit;
}
private float getOffence() {
return getFeatureContainer().applyModifier(1, "model.modifier.offence", null, null);
}
public boolean isOffensive() {
return getOffence() > 1;
}
private float getDefence() {
return getFeatureContainer().applyModifier(1, "model.modifier.defence", null, null);
}
public boolean isDefensive() {
return getDefence() > 1;
}
public boolean isCompatibleWith(Role other) {
return isCompatibleWith(this, other);
}
public static boolean isCompatibleWith(Role role1, Role role2) {
if (role1 == null) {
return role2 == null;
} else if (role2 == null) {
return false;
} else {
return role1 == role2
|| role1.getDowngrade() == role2
|| role2.getDowngrade() == role1;
}
}
public List<AbstractGoods> getDowngradeGoods() {
List<AbstractGoods> result = new ArrayList<AbstractGoods>();
if (downgrade != null) {
for (AbstractGoods goods : getGoodsRequired()) {
int amount = goods.getAmount() - downgrade.getAmountRequiredOf(goods.getType());
if (amount > 0) {
result.add(new AbstractGoods(goods.getType(), amount));
}
}
}
return result;
}
/**
* Reads the attributes of this object from an XML stream.
*
* @param in The XML input stream.
* @throws XMLStreamException if a problem was encountered
* during parsing.
*/
@Override
protected void readAttributes(XMLStreamReader in)
throws XMLStreamException {
super.readAttributes(in);
downgrade = getSpecification().getType(in, "downgrade", Role.class, null);
expertUnit = getSpecification().getType(in, "expertUnit", UnitType.class, null);
maximumCount = getAttribute(in, "maximumCount", 1);
}
/**
* Write the attributes of this object to a stream.
*
* @param out The target stream.
* @throws XMLStreamException if there are any problems writing to
* the stream.
*/
@Override
protected void writeAttributes(XMLStreamWriter out)
throws XMLStreamException {
super.writeAttributes(out);
if (downgrade != null) {
out.writeAttribute("downgrade", downgrade.getId());
}
if (expertUnit != null) {
out.writeAttribute("expertUnit", expertUnit.getId());
}
if (maximumCount > 1) {
out.writeAttribute("maximumCount", Integer.toString(maximumCount));
}
}
/**
* Returns the tag name of the root element representing this object.
*
* @return "role"
*/
public static String getXMLElementTagName() {
return "role";
}
}