use of pcgen.core.WeaponProf in project pcgen by PCGen.
the class ChangeProfLstTest method testRoundRobinComplex.
@Test
public void testRoundRobinComplex() throws PersistenceLayerException {
primaryContext.getReferenceContext().constructCDOMObject(WeaponProf.class, "Hammer");
secondaryContext.getReferenceContext().constructCDOMObject(WeaponProf.class, "Hammer");
primaryContext.getReferenceContext().constructCDOMObject(WeaponProf.class, "Nail");
secondaryContext.getReferenceContext().constructCDOMObject(WeaponProf.class, "Nail");
WeaponProf a = primaryContext.getReferenceContext().constructCDOMObject(WeaponProf.class, "Longsword");
a.addToListFor(ListKey.TYPE, Type.getConstant("Martial"));
WeaponProf b = secondaryContext.getReferenceContext().constructCDOMObject(WeaponProf.class, "Longsword");
b.addToListFor(ListKey.TYPE, Type.getConstant("Martial"));
WeaponProf c = primaryContext.getReferenceContext().constructCDOMObject(WeaponProf.class, "Bolas");
c.addToListFor(ListKey.TYPE, Type.getConstant("Exotic"));
WeaponProf d = secondaryContext.getReferenceContext().constructCDOMObject(WeaponProf.class, "Bolas");
d.addToListFor(ListKey.TYPE, Type.getConstant("Exotic"));
WeaponProf e = primaryContext.getReferenceContext().constructCDOMObject(WeaponProf.class, "Sledgehammer");
e.addToListFor(ListKey.TYPE, Type.getConstant("Heavy"));
WeaponProf f = secondaryContext.getReferenceContext().constructCDOMObject(WeaponProf.class, "Sledgehammer");
f.addToListFor(ListKey.TYPE, Type.getConstant("Heavy"));
WeaponProf g = primaryContext.getReferenceContext().constructCDOMObject(WeaponProf.class, "Average Weapon");
g.addToListFor(ListKey.TYPE, Type.getConstant("Medium"));
WeaponProf h = secondaryContext.getReferenceContext().constructCDOMObject(WeaponProf.class, "Average Weapon");
h.addToListFor(ListKey.TYPE, Type.getConstant("Medium"));
WeaponProf k = primaryContext.getReferenceContext().constructCDOMObject(WeaponProf.class, "Loaded Diaper");
k.addToListFor(ListKey.TYPE, Type.getConstant("Disposable"));
k.addToListFor(ListKey.TYPE, Type.getConstant("Crazy"));
WeaponProf l = secondaryContext.getReferenceContext().constructCDOMObject(WeaponProf.class, "Loaded Diaper");
l.addToListFor(ListKey.TYPE, Type.getConstant("Crazy"));
l.addToListFor(ListKey.TYPE, Type.getConstant("Disposable"));
runRoundRobin("Hammer,TYPE.Heavy,TYPE.Medium=Martial|Nail,TYPE.Crazy,TYPE.Disposable=Exotic");
}
use of pcgen.core.WeaponProf in project pcgen by PCGen.
the class GlobalChangeProfTest method setUp.
@Override
protected void setUp() throws Exception {
super.setUp();
changeProfFacet = FacetLibrary.getFacet(ChangeProfFacet.class);
WeaponProf sword = create(WeaponProf.class, "Sword");
sword.addToListFor(ListKey.TYPE, Type.getConstant("Martial"));
WeaponProf axe = create(WeaponProf.class, "Axe");
axe.addToListFor(ListKey.TYPE, Type.getConstant("Exotic"));
}
use of pcgen.core.WeaponProf in project pcgen by PCGen.
the class TestHelper method makeWeaponProf.
/**
* Set the important info about a WeaponProf
* @param name The weaponprof name
* @param type The type info ("." separated)
* @return The weapon prof (which has also been added to global storage
*/
public static WeaponProf makeWeaponProf(final String name, final String type) {
final WeaponProf aWpnProf = new WeaponProf();
aWpnProf.setName(name);
aWpnProf.put(StringKey.KEY_NAME, ("KEY_" + name));
addType(aWpnProf, type);
Globals.getContext().getReferenceContext().importObject(aWpnProf);
return aWpnProf;
}
use of pcgen.core.WeaponProf in project pcgen by PCGen.
the class WeaponToken method getToHit.
private static String getToHit(PlayerCharacter pc, Equipment eq, int range, int content, int ammo, int hitMode, int attackNum) {
boolean isDouble = (eq.isDouble() && (eq.getLocation() == EquipmentLocation.EQUIPPED_TWO_HANDS));
boolean isDoubleSplit = (eq.isType("Head1") || eq.isType("Head2"));
// wielded as two handed, just punt now!
if (eq.isMelee() && (eq.isWeaponTwoHanded(pc))) {
if ((!isDouble && !isDoubleSplit && (hitMode != HITMODE_THHIT)) || (isDoubleSplit && (hitMode == HITMODE_BASEHIT || hitMode == HITMODE_OHHIT || hitMode == HITMODE_TWPHITH))) {
return SettingsHandler.getInvalidToHitText();
}
}
if (eq.isMelee() && eq.isWeaponOutsizedForPC(pc) && !eq.isNatural()) {
return SettingsHandler.getInvalidToHitText();
}
int weaponBaseBonus = (int) eq.bonusTo(pc, "WEAPON", "WEAPONBAB", true);
CDOMSingleRef<WeaponProf> ref = eq.get(ObjectKey.WEAPON_PROF);
WeaponProf prof;
String profKey;
if (ref == null) {
profKey = "";
prof = null;
} else {
prof = ref.get();
profKey = prof.getKeyName();
}
weaponBaseBonus += (int) pc.getTotalBonusTo("WEAPONPROF=" + profKey, "WEAPONBAB");
weaponBaseBonus += getWeaponProfTypeBonuses(pc, eq, "WEAPONBAB", WPTYPEBONUS_PC);
// The Melee, Ranged and Unarmed attack sequence
String melee = getMeleeAttackString(pc, 0, weaponBaseBonus);
String ranged = getRangedAttackString(pc, 0, weaponBaseBonus);
String unarmed = getUnarmedAttackString(pc, 0, weaponBaseBonus);
// 3.0 Monk uses special attack progression
if (eq.isMonk()) {
if (unarmed.length() > melee.length()) {
melee = unarmed;
} else if ((unarmed.length() == melee.length()) && !melee.equals(unarmed)) {
StringTokenizer mTok = new StringTokenizer(melee, "+/", false);
StringTokenizer m1Tok = new StringTokenizer(melee, "+/", false);
String msString = mTok.nextToken();
String m1sString = m1Tok.nextToken();
if (Integer.parseInt(m1sString) >= Integer.parseInt(msString)) {
melee = unarmed;
}
}
}
//
// Now do all the calculations
//
int baseBonus = 0;
int secondaryBonus = 0;
int primaryBonus = 0;
// Natural weapons are different
if (eq.isNatural()) {
if (eq.getLocation() == EquipmentLocation.EQUIPPED_PRIMARY) {
/* Primary Natural Weapons have no bonus or penalty
* associated with secondary weapons/attacks */
baseBonus = 0;
} else if (eq.getLocation() == EquipmentLocation.EQUIPPED_SECONDARY) {
/* all secondary natural weapons attack at -5 */
baseBonus = -5;
/* Unless the creature has bonuses to improve
* secondary attacks, such as MultiAttack */
baseBonus += pc.getTotalBonusTo("COMBAT", "TOHIT-SECONDARY");
}
} else {
if ((hitMode == HITMODE_TOTALHIT && eq.isRanged()) || hitMode == HITMODE_BASEHIT || hitMode == HITMODE_THHIT) {
baseBonus = 0;
} else if (hitMode == HITMODE_TWPHITH || hitMode == HITMODE_TWPHITL) {
// TWF Primary hand
baseBonus = -6;
} else if (hitMode == HITMODE_OHHIT) {
baseBonus = -4;
} else {
// TWF off-hand
baseBonus = -10;
}
// TWF with off hand light gets a bonus
if ((hitMode == HITMODE_TWPHITL) || (hitMode == HITMODE_TWFOHL)) {
baseBonus += pc.getOffHandLightBonus();
}
if ((hitMode == HITMODE_TWOHIT) && (isDouble || isDoubleSplit || eq.isWeaponLightForPC(pc))) {
baseBonus += pc.getOffHandLightBonus();
}
if ((hitMode == HITMODE_TWOHIT) || (hitMode == HITMODE_OHHIT) || (hitMode == HITMODE_TWFOHL) || (hitMode == HITMODE_TWFOHH)) {
secondaryBonus = (int) pc.getTotalBonusTo("COMBAT", "TOHIT-SECONDARY");
if (eq.isRanged()) {
secondaryBonus -= (int) pc.getBonusDueToType("COMBAT", "TOHIT-SECONDARY", "NOTRANGED");
}
if (hitMode == HITMODE_OHHIT) {
// If only using one weapon, Two-weapon Fighting Bonus does not apply
// If you have TWF, you have both TOHIT-P and TOHIT-S, so remove TOHIT-P
// TODO: Rework on this code and/or on the lst, because it "sounds" wrong
// Felipe Diniz - 12/Feb/2003
secondaryBonus -= (int) pc.getTotalBonusTo("COMBAT", "TOHIT-PRIMARY");
}
}
if (((hitMode == HITMODE_TWPHITH) || (hitMode == HITMODE_TWPHITL))) {
primaryBonus = (int) pc.getTotalBonusTo("COMBAT", "TOHIT-PRIMARY");
if (eq.isRanged()) {
primaryBonus -= (int) pc.getBonusDueToType("COMBAT", "TOHIT-PRIMARY", "NOTRANGED");
}
}
}
if (eq.getLocation() == EquipmentLocation.EQUIPPED_PRIMARY || eq.getLocation() == EquipmentLocation.EQUIPPED_SECONDARY || eq.getLocation() == EquipmentLocation.EQUIPPED_TWO_HANDS) {
// TODO Fix this
// if (eq.isWeaponOneHanded(pc, wp, false) != eq.isWeaponOneHanded(pc, wp, true))
// {
// baseBonus += (int) pc.getTotalBonusTo("WEAPONPROF=" + profName, "TOHITOVERSIZE");
// baseBonus += getWeaponProfTypeBonuses(pc, eq, "TOHITOVERSIZE", WPTYPEBONUS_PC);
// }
}
if (hitMode == HITMODE_TWPHITH || hitMode == HITMODE_TWPHITL) {
baseBonus += primaryBonus;
}
if (hitMode == HITMODE_TWOHIT || hitMode == HITMODE_OHHIT || hitMode == HITMODE_TWFOHL || hitMode == HITMODE_TWFOHH) {
baseBonus += secondaryBonus;
}
// Where abc: Ranged, Melee, Slashing, etc
for (String type : eq.typeList()) {
// is Handled elsewhere
if (type.equalsIgnoreCase("Finesseable")) {
continue;
}
//Prevents weapon from getting both melee & ranged bonuses
if ((range > -1 && type.equalsIgnoreCase("MELEE")) || (range == -1 && eq.isMelee() && (type.equalsIgnoreCase("THROWN") || type.equalsIgnoreCase("RANGED")))) {
continue;
}
baseBonus += (int) pc.getTotalBonusTo("TOHIT", "TYPE." + type);
baseBonus += (int) pc.getTotalBonusTo("COMBAT", "TOHIT." + type);
}
if (range == -1 && eq.isMelee() && eq.isFinessable(pc)) {
baseBonus += (int) pc.getTotalBonusTo("COMBAT", "TOHIT.Finesseable");
}
//
if ((ref != null) && eq.isRanged()) {
baseBonus -= (int) pc.getBonusDueToType("WEAPONPROF=" + profKey, "TOHIT", "NOTRANGED");
baseBonus -= getWeaponProfTypeBonuses(pc, eq, "TOHIT.NOTRANGED", WPTYPEBONUS_PC);
}
CharacterDisplay display = pc.getDisplay();
if (!eq.isNatural() && ((ref == null) || !display.hasWeaponProf(prof))) {
baseBonus += display.getNonProficiencyPenalty();
}
baseBonus += (int) pc.getTotalBonusTo("WEAPONPROF=" + profKey, "TOHIT");
baseBonus += getWeaponProfTypeBonuses(pc, eq, "TOHIT", WPTYPEBONUS_PC);
if (range > -1) {
int rangeSize = getRangeList(eq, true, pc).size();
int shortRange = SettingsHandler.getGame().getShortRangeDistance();
if (range < rangeSize) {
int thisRange = Integer.parseInt(getRangeList(eq, true, pc).get(range));
// at short range, add SHORTRANGE bonus
if (thisRange <= shortRange) {
baseBonus += (int) pc.getTotalBonusTo("COMBAT", "TOHIT-SHORTRANGE");
baseBonus += (int) pc.getTotalBonusTo("TOHIT", "SHORTRANGE");
baseBonus += (int) pc.getTotalBonusTo("WEAPONPROF=" + profKey, "TOHIT-SHORTRANGE");
baseBonus += getWeaponProfTypeBonuses(pc, eq, "TOHIT-SHORTRANGE", WPTYPEBONUS_PC);
baseBonus += (int) eq.bonusTo(pc, "WEAPON", "TOHIT-SHORTRANGE", true);
}
// Long Range To-Hit Modifier
int defaultRange = Integer.parseInt(EqToken.getRange(pc, eq).toString());
int rangePenalty = SettingsHandler.getGame().getRangePenalty();
rangePenalty += pc.getTotalBonusTo("COMBAT", "RANGEPENALTY");
baseBonus += rangePenalty * (int) Math.max(Math.ceil(((float) thisRange / defaultRange)) - 1, 0);
}
}
//Ammunition & Contents Modifier
Equipment containedEq = null;
if (content > -1) {
if (content < eq.getContainedEquipmentCount()) {
containedEq = eq.getContainedEquipment(content);
baseBonus += containedEq.getBonusToHit(pc, true);
}
}
Equipment ammoUser = getAmmoUser(pc, eq, ammo);
if (ammoUser != null) {
baseBonus += ammoUser.getBonusToHit(pc, true);
}
// do NOT include the size bonus/penalty since
// it is call in pc.getTotalBonusTo()
// include players TOHIT bonuses
baseBonus += (int) pc.getTotalBonusTo("TOHIT", "TOHIT");
baseBonus += (int) pc.getTotalBonusTo("COMBAT", "TOHIT");
// subtract Armor and Shield non-proficiency
baseBonus += modFromArmorOnWeaponRolls(pc);
// include bonuses from Item itself
baseBonus += eq.getBonusToHit(pc, true);
// If not using ammo stacking, correct for stacked enhancement bonus
if (!Globals.checkRule(RuleConstants.AMMOSTACKSWITHWEAPON)) {
baseBonus += calcAmmoEqCorrection("WEAPON.TOHIT.ENHANCEMENT", eq, containedEq, ammoUser);
}
// BONUS:COMBAT|ATTACKS|#
// represent extra attacks at BaB
// such as from a weapon of 'Speed'
int extra_attacks = (int) eq.bonusTo(pc, "WEAPON", "ATTACKS", true);
// or possibly the "Haste" spell cast on PC
extra_attacks += (int) pc.getTotalBonusTo("COMBAT", "ATTACKS");
String babProgression = null;
if (eq.isMelee() && range == -1) {
babProgression = melee;
} else if (eq.isRanged()) {
babProgression = ranged;
} else {
/* A weapon must either be ranged or melee. If it's not, trap
it here */
return "???";
}
StringTokenizer bTok = new StringTokenizer(babProgression, "/+");
String attack = Delta.toString(Integer.parseInt(bTok.nextToken()));
StringBuilder newAttack = new StringBuilder();
for (int i = extra_attacks; i > 0; i--) {
newAttack.append(attack).append("/");
}
boolean progress = eq.getSafe(ObjectKey.ATTACKS_PROGRESS);
int bonusProgress = (int) eq.bonusTo(pc, "WEAPON", "ATTACKSPROGRESS", true);
if (bonusProgress != 0) {
progress = bonusProgress > 0;
}
if (progress) {
/* For normal weapons, we need to append the original
* attack progression which was derived from the BAB to
* the end of the extra attacks */
newAttack.append(babProgression);
} else {
/* This is for Natural weapons and any other weapon
* which has its attack progression turned off. The
* attack progression should consist of the full number
* of attacks at the maximum tohit i.e. without
* appending the attacks from the normal attack
* progression */
newAttack.append(attack);
}
StringTokenizer aTok = new StringTokenizer(newAttack.toString(), "/+");
// When attackNum is > 0, the code is looking for a single attack
// from the sequence. This section of code down to
// if (buildNewAttackSequence) builds a new aTok which contains
// only the single attack we're looking for.
int selectAttack = attackNum;
String singleAttack = "";
boolean buildNewAttackSequence = false;
while (aTok.hasMoreTokens() && (selectAttack >= 0)) {
singleAttack = aTok.nextToken();
selectAttack--;
buildNewAttackSequence = true;
}
if (buildNewAttackSequence) {
aTok = new StringTokenizer(singleAttack, "/+");
}
int secondariesToadd = 1 + (int) pc.getTotalBonusTo("COMBAT", "ATTACKS-SECONDARY");
/*
* The data team wishes to keep the old syntax for secondary attacks.
* The docs have been updated to reflect this. The new syntax (with
* the hyphen, see above) is not used in the repository. This comment
* is here so that the old syntax will not be deprecated or removed in
* the future.
*/
secondariesToadd += (int) pc.getTotalBonusTo("COMBAT", "SECONDARYATTACKS");
if (!display.hasPrimaryWeapons() && (hitMode == HITMODE_TOTALHIT)) {
secondariesToadd = 100;
}
// Whether to construct a string for secondary attacks. This is only
// needed for double weapons because single weapons in the off hand
// are processed on their own as secondary weapons. Additionally, We
// should only construct a secondary attack string if we are not
// looking for a single attack from the sequence (attackNum < 0)
boolean doDouble = isDouble && (eq.getLocation() == EquipmentLocation.EQUIPPED_TWO_HANDS) && attackNum < 0;
// If the weapon is being considered as a secondary weapon, then we
// shouldn't add the full attack progression as a secondary weapon only
// gets one attack (plus any added by feats, etc. see extra attacks
// above) i.e. we may need to break out of the loop while aTok has more
// tokens
boolean considerEarlyExit = !isDouble && (hitMode == HITMODE_TWOHIT || display.isSecondaryWeapon(eq));
int toHit = 0;
int secondariesAdded = 0;
StringBuilder primaryAttack = new StringBuilder(20);
StringBuilder secondaryAttack = new StringBuilder(20);
StringBuilder totalAttack = new StringBuilder();
while (aTok.hasMoreTokens()) {
if (primaryAttack.length() > 0) {
primaryAttack.append('/');
}
toHit = Integer.parseInt(aTok.nextToken()) + baseBonus;
primaryAttack.append(Delta.toString(toHit));
if (doDouble && secondariesAdded < secondariesToadd) {
if (secondaryAttack.length() > 0) {
secondaryAttack.append('/');
}
secondaryAttack.append(Delta.toString(toHit));
}
// Just in case we are looping forever
if (++secondariesAdded > 100) {
break;
}
if (considerEarlyExit && secondariesAdded >= secondariesToadd) {
break;
}
}
totalAttack.append(primaryAttack.toString());
if (secondaryAttack.length() != 0 && (hitMode == HITMODE_TOTALHIT || hitMode == HITMODE_TWOHIT)) {
totalAttack.append(";" + secondaryAttack);
}
return totalAttack.toString();
}
use of pcgen.core.WeaponProf in project pcgen by PCGen.
the class WeaponhToken method getWeaponEquipment.
/**
* Create a fake Unarmed Strike equipment so we don't need it in the .lst files anymore
*
* @param display The character used to generate the size.
* @return The Unarmed Strike equipment.
*/
public static Equipment getWeaponEquipment(CharacterDisplay display) {
// Creating a fake Unarmed Strike equipment so we
// don't need it in the .lst files anymore
WeaponProf wp = Globals.getContext().getReferenceContext().silentlyGetConstructedCDOMObject(WeaponProf.class, "Unarmed Strike");
if (wp == null) {
wp = new WeaponProf();
wp.setName(LanguageBundle.getString("Equipment.UnarmedStrike"));
wp.put(StringKey.KEY_NAME, "Unarmed Strike");
wp.addToListFor(ListKey.TYPE, Type.SIMPLE);
Globals.getContext().getReferenceContext().importObject(wp);
}
Equipment eq = new Equipment();
eq.setName(LanguageBundle.getString("Equipment.UnarmedStrike"));
eq.put(StringKey.KEY_NAME, "KEY_Unarmed Strike");
eq.put(ObjectKey.WEAPON_PROF, new CDOMDirectSingleRef<>(wp));
eq.put(StringKey.OUTPUT_NAME, LanguageBundle.getString("Equipment.UnarmedStrike"));
eq.addType(Type.WEAPON);
eq.addType(Type.MELEE);
eq.addType(Type.SIMPLE);
eq.addType(Type.UNARMED);
eq.addType(Type.SUBDUAL);
eq.addType(Type.STANDARD);
eq.addType(Type.MONK);
eq.addType(Type.BLUDGEONING);
WieldCategory lightWC = Globals.getContext().getReferenceContext().silentlyGetConstructedCDOMObject(WieldCategory.class, "Light");
if (lightWC == null) {
// Error?
} else {
eq.put(ObjectKey.WIELD, lightWC);
}
eq.put(ObjectKey.COST, BigDecimal.ZERO);
eq.put(ObjectKey.CURRENT_COST, BigDecimal.ZERO);
eq.put(ObjectKey.WEIGHT, BigDecimal.ZERO);
EquipmentHead head = eq.getEquipmentHead(1);
head.put(StringKey.DAMAGE, "1d1");
head.put(IntegerKey.CRIT_MULT, 2);
head.put(IntegerKey.CRIT_RANGE, 1);
eq.put(ObjectKey.MOD_CONTROL, EqModControl.NO);
SizeAdjustment sa = display.getSizeAdjustment();
CDOMDirectSingleRef<SizeAdjustment> ref = CDOMDirectSingleRef.getRef(sa);
eq.put(ObjectKey.SIZE, ref);
eq.put(ObjectKey.BASESIZE, ref);
return eq;
}
Aggregations