Selaa lähdekoodia

Refactor ability scores, instead of having two parallel 'arrays', have one array of paired values.
This allows modifications to be more visible. In the future, temp scores might be represented as an offset, instead of as an alternative value.

Sam Jaffe 8 vuotta sitten
vanhempi
commit
3240c1928c
23 muutettua tiedostoa jossa 126 lisäystä ja 105 poistoa
  1. 30 28
      src/main/lombok/org/leumasjaffe/charsheet/model/Ability.java
  2. 7 0
      src/main/lombok/org/leumasjaffe/charsheet/observer/ObserverHelper.java
  3. 3 4
      src/main/lombok/org/leumasjaffe/charsheet/observer/helper/AbilModStringify.java
  4. 20 0
      src/main/lombok/org/leumasjaffe/charsheet/util/AbilityHelper.java
  5. 2 3
      src/main/lombok/org/leumasjaffe/charsheet/view/magic/ChooseSpellsPerDayHeader.java
  6. 3 3
      src/main/lombok/org/leumasjaffe/charsheet/view/magic/PrepareSpellsDialog.java
  7. 3 3
      src/main/lombok/org/leumasjaffe/charsheet/view/magic/SelectPreparedSpellsPanel.java
  8. 2 2
      src/main/lombok/org/leumasjaffe/charsheet/view/magic/SpellLevelPanel.java
  9. 2 2
      src/main/lombok/org/leumasjaffe/charsheet/view/magic/SpellLevelPerDayPanel.java
  10. 4 4
      src/main/lombok/org/leumasjaffe/charsheet/view/magic/SpellPanel.java
  11. 2 3
      src/main/lombok/org/leumasjaffe/charsheet/view/magic/SpellsKnownHeader.java
  12. 2 3
      src/main/lombok/org/leumasjaffe/charsheet/view/magic/SpellsPerDayHeader.java
  13. 2 1
      src/main/lombok/org/leumasjaffe/charsheet/view/skills/SkillLevelUpDialog.java
  14. 7 6
      src/main/lombok/org/leumasjaffe/charsheet/view/skills/SkillLevelUpLine.java
  15. 6 6
      src/main/lombok/org/leumasjaffe/charsheet/view/skills/SkillLine.java
  16. 3 3
      src/main/lombok/org/leumasjaffe/charsheet/view/summary/AbilityBox.java
  17. 5 5
      src/main/lombok/org/leumasjaffe/charsheet/view/summary/AbilityLine.java
  18. 4 5
      src/main/lombok/org/leumasjaffe/charsheet/view/summary/AbilityPanel.java
  19. 3 4
      src/main/lombok/org/leumasjaffe/charsheet/view/summary/ArmorLine.java
  20. 3 4
      src/main/lombok/org/leumasjaffe/charsheet/view/summary/AttackLine.java
  21. 5 7
      src/main/lombok/org/leumasjaffe/charsheet/view/summary/InitiativeLine.java
  22. 5 6
      src/main/lombok/org/leumasjaffe/charsheet/view/summary/ResistanceLine.java
  23. 3 3
      src/main/lombok/org/leumasjaffe/charsheet/view/summary/ResistancePanel.java

+ 30 - 28
src/main/lombok/org/leumasjaffe/charsheet/model/Ability.java

@@ -6,6 +6,7 @@ import java.util.Map;
 import java.util.function.Function;
 
 import org.leumasjaffe.charsheet.model.observable.IntValue;
+import org.leumasjaffe.observer.Observable;
 
 import com.fasterxml.jackson.annotation.JsonCreator;
 import com.fasterxml.jackson.annotation.JsonProperty;
@@ -13,58 +14,59 @@ import com.fasterxml.jackson.annotation.JsonProperty;
 import lombok.AccessLevel;
 import lombok.AllArgsConstructor;
 import lombok.Data;
-import lombok.NonNull;
+import lombok.EqualsAndHashCode;
 import lombok.experimental.FieldDefaults;
 
 @Data
 @AllArgsConstructor
 @FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
 public class Ability {
-	public static final Map<String, Function<Scores, IntValue>> fields;
+	public static final Map<String, Function<Ability, Scores>> fields;
 	
 	static {
-		Map<String, Function<Scores, IntValue>> tmp = new HashMap<>();
-		tmp.put("STR", Scores::getStr);
-		tmp.put("DEX", Scores::getDex);
-		tmp.put("CON", Scores::getCon);
-		tmp.put("INT", Scores::getInt);
-		tmp.put("WIS", Scores::getWis);
-		tmp.put("CHA", Scores::getCha);
+		Map<String, Function<Ability, Scores>> tmp = new HashMap<>();
+		tmp.put("STR", Ability::getStr);
+		tmp.put("DEX", Ability::getDex);
+		tmp.put("CON", Ability::getCon);
+		tmp.put("INT", Ability::getInt);
+		tmp.put("WIS", Ability::getWis);
+		tmp.put("CHA", Ability::getCha);
 		
 		fields = Collections.unmodifiableMap(tmp);
 	}
 	
 	@Data
 	@AllArgsConstructor
+	@EqualsAndHashCode(callSuper=false)
 	@FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
-	public static class Scores {
-		IntValue str; 
-		IntValue dex; 
-		IntValue con; 
-		@JsonProperty(value="int") IntValue Int; 
-		IntValue wis; 
-		IntValue cha;
+	public static class Scores extends Observable {
+		IntValue base, temp;
 		
 		@JsonCreator
-		Scores() {
-			this.str = new IntValue();
-			this.dex = new IntValue();
-			this.con = new IntValue();
-			this.Int = new IntValue();
-			this.wis = new IntValue();
-			this.cha = new IntValue();
+		public Scores() {
+			this.base = new IntValue(-1);
+			this.temp = new IntValue(-1);
 		}
+		
+		public int baseScore() { return base.value(); }
+		public int score() { return temp.value() == -1 ? base.value() : temp.value(); }
+		public int baseModifier() { return Ability.modifier(baseScore()); }
+		public int modifier() { return Ability.modifier(score()); }
 	}
 	
-	@NonNull Scores base;
-	@NonNull Scores temp;
+	Scores str, dex, con, wis, cha; 
+	@JsonProperty(value="int") Scores Int;
 	
 	public Ability() {
-		this.base = new Scores();
-		this.temp = new Scores();
+		this.str = new Scores();
+		this.dex = new Scores();
+		this.con = new Scores();
+		this.Int = new Scores();
+		this.wis = new Scores();
+		this.cha = new Scores();
 	}
 	
 	public static int modifier(int val) {
-		return val / 2 - 5;
+		return val == -1 ? 0 : val / 2 - 5;
 	}
 }

+ 7 - 0
src/main/lombok/org/leumasjaffe/charsheet/observer/ObserverHelper.java

@@ -1,5 +1,6 @@
 package org.leumasjaffe.charsheet.observer;
 
+import org.leumasjaffe.charsheet.model.Ability;
 import org.leumasjaffe.charsheet.model.DDCharacterClass;
 import org.leumasjaffe.observer.ObserverDispatch;
 
@@ -11,4 +12,10 @@ public class ObserverHelper {
 		ObserverDispatch.notifySubscribers(dclass, src);
 		dclass.getSpellBook().ifPresent(sb -> ObserverDispatch.notifySubscribers(sb, src));
 	}
+	
+	public void notifyObservableHierarchy(final Ability.Scores abil, final Object src) {
+		ObserverDispatch.notifySubscribers(abil, src);
+		ObserverDispatch.notifySubscribers(abil.getBase(), src);
+		ObserverDispatch.notifySubscribers(abil.getTemp(), src);
+	}
 }

+ 3 - 4
src/main/lombok/org/leumasjaffe/charsheet/observer/helper/AbilModStringify.java

@@ -5,14 +5,13 @@ import java.util.function.BiConsumer;
 import javax.swing.text.JTextComponent;
 
 import org.leumasjaffe.charsheet.model.Ability;
-import org.leumasjaffe.charsheet.model.observable.IntValue;
 import org.leumasjaffe.charsheet.util.StringHelper;
 
-public class AbilModStringify implements BiConsumer<JTextComponent, IntValue> {
+public class AbilModStringify implements BiConsumer<JTextComponent, Ability.Scores> {
 
 	@Override
-	public void accept(JTextComponent c, IntValue v) {
-		c.setText(StringHelper.toString(Ability.modifier(v.value())));
+	public void accept(JTextComponent c, Ability.Scores v) {
+		c.setText(StringHelper.toString(v.modifier()));
 	}
 
 }

+ 20 - 0
src/main/lombok/org/leumasjaffe/charsheet/util/AbilityHelper.java

@@ -0,0 +1,20 @@
+package org.leumasjaffe.charsheet.util;
+
+import org.leumasjaffe.charsheet.model.Ability;
+import org.leumasjaffe.charsheet.model.Ability.Scores;
+import org.leumasjaffe.charsheet.model.DDCharacter;
+import org.leumasjaffe.charsheet.model.DDCharacterClass;
+import org.leumasjaffe.charsheet.model.skill.DDSkill;
+
+import lombok.experimental.UtilityClass;
+
+@UtilityClass
+public class AbilityHelper {
+	public Ability.Scores get(final DDCharacter chara, final DDCharacterClass caster) {
+		return Ability.fields.get(caster.getProto().getSpells().get().getAbility()).apply(chara.getAbilities());
+	}
+	
+	public Scores get(DDCharacter chara, DDSkill skill) {
+		return Ability.fields.get(skill.getAbility()).apply(chara.getAbilities());
+	}
+}

+ 2 - 3
src/main/lombok/org/leumasjaffe/charsheet/view/magic/ChooseSpellsPerDayHeader.java

@@ -10,7 +10,6 @@ import javax.swing.JTextField;
 
 import org.leumasjaffe.charsheet.model.Ability;
 import org.leumasjaffe.charsheet.model.magic.DDSpellbook;
-import org.leumasjaffe.charsheet.model.observable.IntValue;
 import org.leumasjaffe.charsheet.util.StringHelper;
 
 import java.awt.Dimension;
@@ -22,7 +21,7 @@ class ChooseSpellsPerDayHeader extends JPanel {
 	private static final long serialVersionUID = 1L;
 	private JTextField textFieldKnown;
 
-	public ChooseSpellsPerDayHeader(int level, DDSpellbook model, IntValue ability) {
+	public ChooseSpellsPerDayHeader(int level, DDSpellbook model, Ability.Scores ability) {
 		setPreferredSize(new Dimension(450, 20));
 		GridBagLayout gridBagLayout = new GridBagLayout();
 		gridBagLayout.columnWidths = new int[]{0, 30, 0, 30, 0, 30, 0, 0, 0, 0};
@@ -57,7 +56,7 @@ class ChooseSpellsPerDayHeader extends JPanel {
 		gbc_lblSaveDc.gridy = 0;
 		add(lblSaveDc, gbc_lblSaveDc);
 		
-		JTextField textFieldSpellSave = new JTextField(Integer.toString(10 + level + Ability.modifier(ability.value())));
+		JTextField textFieldSpellSave = new JTextField(Integer.toString(10 + level + ability.modifier()));
 		textFieldSpellSave.setEditable(false);
 		textFieldSpellSave.setColumns(10);
 		GridBagConstraints gbc_textFieldSpellSave = new GridBagConstraints();

+ 3 - 3
src/main/lombok/org/leumasjaffe/charsheet/view/magic/PrepareSpellsDialog.java

@@ -7,7 +7,7 @@ import org.leumasjaffe.charsheet.model.Ability;
 import org.leumasjaffe.charsheet.model.DDCharacter;
 import org.leumasjaffe.charsheet.model.DDCharacterClass;
 import org.leumasjaffe.charsheet.model.magic.impl.Prepared;
-import org.leumasjaffe.charsheet.model.observable.IntValue;
+import org.leumasjaffe.charsheet.util.AbilityHelper;
 
 import lombok.AccessLevel;
 import lombok.experimental.FieldDefaults;
@@ -78,12 +78,12 @@ public class PrepareSpellsDialog extends JPanel {
 		JPanel panel = new JPanel(new VerticalLayout(5));
 		scrollPane.setViewportView(panel);
 		
-		final IntValue value = Ability.fields.get(dclass.getProto().getSpells().get().getAbility()).apply(chara.getAbilities().getBase());
+		final Ability.Scores score = AbilityHelper.get(chara, dclass);
 
 		final Prepared spellBook = (Prepared) dclass.getSpellBook().get();
 		List<SelectPreparedSpellsPanel> panels = new ArrayList<>();
 		for (int i = 0; i < highestSpellLevel; ++i) {
-			SelectPreparedSpellsPanel lvl = new SelectPreparedSpellsPanel(i, dclass, value);
+			SelectPreparedSpellsPanel lvl = new SelectPreparedSpellsPanel(i, dclass, score);
 			panels.add(lvl);
 			lvl.addPropertyChangeListener(SelectPreparedSpellsPanel.READY, e -> {
 				if ((Boolean) e.getNewValue()) ++ready[0];

+ 3 - 3
src/main/lombok/org/leumasjaffe/charsheet/view/magic/SelectPreparedSpellsPanel.java

@@ -9,10 +9,10 @@ import javax.swing.JPopupMenu;
 import javax.swing.JTable;
 import javax.swing.ListSelectionModel;
 
+import org.leumasjaffe.charsheet.model.Ability;
 import org.leumasjaffe.charsheet.model.DDCharacterClass;
 import org.leumasjaffe.charsheet.model.magic.DDSpell;
 import org.leumasjaffe.charsheet.model.magic.impl.Prepared;
-import org.leumasjaffe.charsheet.model.observable.IntValue;
 import org.leumasjaffe.charsheet.util.StringHelper;
 import org.leumasjaffe.graphics.SelectTableRowPopupMenuListener;
 
@@ -80,7 +80,7 @@ class SelectPreparedSpellsPanel extends JPanel {
 	
 	SelectSpellModel modelPrepared, modelKnown;
 
-	public SelectPreparedSpellsPanel(int level, DDCharacterClass dclass, IntValue ability) {
+	public SelectPreparedSpellsPanel(int level, DDCharacterClass dclass, Ability.Scores score) {
 		putClientProperty(READY, true);
 		final Prepared spellBook = (Prepared) dclass.getSpellBook().get();
 		this.prepared = new ArrayList<>(spellBook.getSpellsPreparedPreviouslyForLevel(level));
@@ -95,7 +95,7 @@ class SelectPreparedSpellsPanel extends JPanel {
 		gridBagLayout.rowWeights = new double[]{0.0, 1.0, Double.MIN_VALUE};
 		setLayout(gridBagLayout);
 		
-		JPanel panel = new ChooseSpellsPerDayHeader(level, spellBook, ability);
+		JPanel panel = new ChooseSpellsPerDayHeader(level, spellBook, score);
 		GridBagConstraints gbc_panel = new GridBagConstraints();
 		gbc_panel.gridwidth = 3;
 		gbc_panel.insets = new Insets(0, 0, 5, 5);

+ 2 - 2
src/main/lombok/org/leumasjaffe/charsheet/view/magic/SpellLevelPanel.java

@@ -9,9 +9,9 @@ import java.awt.Insets;
 import java.util.List;
 
 import org.jdesktop.swingx.VerticalLayout;
+import org.leumasjaffe.charsheet.model.Ability;
 import org.leumasjaffe.charsheet.model.DDCharacterClass;
 import org.leumasjaffe.charsheet.model.magic.DDSpell;
-import org.leumasjaffe.charsheet.model.observable.IntValue;
 import org.leumasjaffe.observer.IndirectObservableListener;
 
 import lombok.AccessLevel;
@@ -67,7 +67,7 @@ class SpellLevelPanel extends JPanel {
 		listener.setObserved(dclass, dclass.getSpellBook().get());
 	}
 	
-	public SpellLevelPanel(DDCharacterClass dclass, int level, IntValue ability) {
+	public SpellLevelPanel(DDCharacterClass dclass, int level, Ability.Scores ability) {
 		this(new SpellsKnownHeader(level, dclass.getSpellBook().get(), ability), dclass, level);
 	}
 	

+ 2 - 2
src/main/lombok/org/leumasjaffe/charsheet/view/magic/SpellLevelPerDayPanel.java

@@ -1,7 +1,7 @@
 package org.leumasjaffe.charsheet.view.magic;
 
+import org.leumasjaffe.charsheet.model.Ability;
 import org.leumasjaffe.charsheet.model.DDCharacterClass;
-import org.leumasjaffe.charsheet.model.observable.IntValue;
 
 import lombok.AccessLevel;
 import lombok.experimental.FieldDefaults;
@@ -14,7 +14,7 @@ class SpellLevelPerDayPanel extends SpellLevelPanel {
 	 */
 	private static final long serialVersionUID = 1L;
 	
-	public SpellLevelPerDayPanel(DDCharacterClass dclass, int level, IntValue ability) {
+	public SpellLevelPerDayPanel(DDCharacterClass dclass, int level, Ability.Scores ability) {
 		super(new SpellsPerDayHeader(level, dclass.getSpellBook().get(), ability), dclass, level);
 	}
 	

+ 4 - 4
src/main/lombok/org/leumasjaffe/charsheet/view/magic/SpellPanel.java

@@ -12,7 +12,7 @@ import org.jdesktop.swingx.VerticalLayout;
 import org.leumasjaffe.charsheet.model.Ability;
 import org.leumasjaffe.charsheet.model.DDCharacter;
 import org.leumasjaffe.charsheet.model.DDCharacterClass;
-import org.leumasjaffe.charsheet.model.observable.IntValue;
+import org.leumasjaffe.charsheet.util.AbilityHelper;
 import org.leumasjaffe.function.TriFunction;
 import org.leumasjaffe.observer.IndirectObservableListener;
 
@@ -52,7 +52,7 @@ public class SpellPanel extends JPanel {
 		JScrollPane knownPane = new JScrollPane();
 		spellsPane.addTab("Known", null, knownPane, "Spells the player knows for this class");
 		
-		final IntValue ability = Ability.fields.get(dclass.getProto().getSpells().get().getAbility()).apply(chara.getAbilities().getBase());
+		final Ability.Scores ability = AbilityHelper.get(chara, dclass);
 		final JPanel prepared = new JPanel(new VerticalLayout());
 		preparedPane.setViewportView(prepared);
 		final JPanel known = new JPanel(new VerticalLayout());
@@ -70,8 +70,8 @@ public class SpellPanel extends JPanel {
 	@FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true)
 	private static final class AppendSpellLevelOperation implements BiConsumer<JPanel, DDCharacterClass> {
 		@NonFinal int previousHighestSpellLevel = 0;
-		IntValue ability;
-		TriFunction<DDCharacterClass, Integer, IntValue, JPanel> function;
+		Ability.Scores ability;
+		TriFunction<DDCharacterClass, Integer, Ability.Scores, JPanel> function;
 
 		@Override
 		public void accept(final JPanel root, final DDCharacterClass dclass) {		

+ 2 - 3
src/main/lombok/org/leumasjaffe/charsheet/view/magic/SpellsKnownHeader.java

@@ -10,7 +10,6 @@ import javax.swing.JTextField;
 
 import org.leumasjaffe.charsheet.model.Ability;
 import org.leumasjaffe.charsheet.model.magic.DDSpellbook;
-import org.leumasjaffe.charsheet.model.observable.IntValue;
 import org.leumasjaffe.charsheet.util.StringHelper;
 import java.awt.Dimension;
 
@@ -20,7 +19,7 @@ class SpellsKnownHeader extends JPanel {
 	 */
 	private static final long serialVersionUID = 1L;
 
-	public SpellsKnownHeader(int level, DDSpellbook model, IntValue ability) {
+	public SpellsKnownHeader(int level, DDSpellbook model, Ability.Scores ability) {
 		setPreferredSize(new Dimension(350, 20));
 		GridBagLayout gridBagLayout = new GridBagLayout();
 		gridBagLayout.columnWidths = new int[]{0, 30, 0, 30, 0, 30, 0, 0};
@@ -57,7 +56,7 @@ class SpellsKnownHeader extends JPanel {
 		gbc_lblSaveDc.gridy = 0;
 		add(lblSaveDc, gbc_lblSaveDc);
 		
-		JTextField textFieldSpellSave = new JTextField(Integer.toString(10 + level + Ability.modifier(ability.value())));
+		JTextField textFieldSpellSave = new JTextField(Integer.toString(10 + level + ability.modifier()));
 		textFieldSpellSave.setPreferredSize(new Dimension(30, 20));
 		textFieldSpellSave.setMaximumSize(new Dimension(30, 20));
 		textFieldSpellSave.setEditable(false);

+ 2 - 3
src/main/lombok/org/leumasjaffe/charsheet/view/magic/SpellsPerDayHeader.java

@@ -10,7 +10,6 @@ import javax.swing.JTextField;
 
 import org.leumasjaffe.charsheet.model.Ability;
 import org.leumasjaffe.charsheet.model.magic.DDSpellbook;
-import org.leumasjaffe.charsheet.model.observable.IntValue;
 import org.leumasjaffe.observer.ObservableListener;
 
 import java.awt.Dimension;
@@ -23,7 +22,7 @@ class SpellsPerDayHeader extends JPanel {
 
 	ObservableListener<JTextField, DDSpellbook> listener;
 
-	public SpellsPerDayHeader(int level, DDSpellbook model, IntValue ability) {
+	public SpellsPerDayHeader(int level, DDSpellbook model, Ability.Scores ability) {
 		setPreferredSize(new Dimension(350, 20));
 		GridBagLayout gridBagLayout = new GridBagLayout();
 		gridBagLayout.columnWidths = new int[]{0, 30, 0, 30, 0, 30, 0, 30, 0, 0};
@@ -58,7 +57,7 @@ class SpellsPerDayHeader extends JPanel {
 		gbc_lblSaveDc.gridy = 0;
 		add(lblSaveDc, gbc_lblSaveDc);
 		
-		JTextField textFieldSpellSave = new JTextField(Integer.toString(10 + level + Ability.modifier(ability.value())));
+		JTextField textFieldSpellSave = new JTextField(Integer.toString(10 + level + ability.modifier()));
 		textFieldSpellSave.setEditable(false);
 		textFieldSpellSave.setColumns(10);
 		GridBagConstraints gbc_textFieldSpellSave = new GridBagConstraints();

+ 2 - 1
src/main/lombok/org/leumasjaffe/charsheet/view/skills/SkillLevelUpDialog.java

@@ -35,7 +35,8 @@ public class SkillLevelUpDialog extends JPanel {
 	private static final long serialVersionUID = 1L;
 	
 	public SkillLevelUpDialog(final DDCharacter chara, final DDCharacterClass cclass) {
-		final IntValue pointsAvaliable = new IntValue(Math.max(1, cclass.getSkillPoints() + Ability.modifier(chara.getAbilities().getBase().getInt().value())));
+		final IntValue pointsAvaliable = new IntValue(Math.max(1, cclass.getSkillPoints() + 
+				Ability.modifier(chara.getAbilities().getInt().baseModifier())));
 		
 		GridBagLayout gridBagLayout = new GridBagLayout();
 		gridBagLayout.columnWidths = new int[]{0, 0};

+ 7 - 6
src/main/lombok/org/leumasjaffe/charsheet/view/skills/SkillLevelUpLine.java

@@ -7,6 +7,7 @@ import org.leumasjaffe.charsheet.model.DDCharacter;
 import org.leumasjaffe.charsheet.model.DDCharacterClass;
 import org.leumasjaffe.charsheet.model.observable.IntValue;
 import org.leumasjaffe.charsheet.model.skill.DDSkill;
+import org.leumasjaffe.charsheet.util.AbilityHelper;
 import org.leumasjaffe.charsheet.util.StringHelper;
 import org.leumasjaffe.observer.IndirectObservableListener;
 import org.leumasjaffe.observer.ObserverDispatch;
@@ -45,7 +46,7 @@ class SkillLevelUpLine extends JPanel {
 	
 	@Value
 	private static final class TotalPacket {
-		Optional<IntValue> ability;
+		Optional<Ability.Scores> ability;
 		DDSkill skill;
 		IntValue points;
 	}
@@ -217,17 +218,17 @@ class SkillLevelUpLine extends JPanel {
 		totalListener = new IndirectObservableListener<>(total,
 				(c, p) -> {
 					final int skillRanks = p.skill.getRanks().value();
-					final int mod = Ability.modifier(p.ability.map(v -> v.value()).orElse(10));
+					final int mod = p.ability.map(v -> v.baseModifier()).orElse(0);
 					c.setText(StringHelper.toString(skillRanks + mod + p.points.value()));
 				});
-		final Optional<IntValue> ability = getAbility(chara, skill);
-		ability.ifPresent(v -> modifier.setText(StringHelper.toString(Ability.modifier(v.value()))));
+		final Optional<Ability.Scores> ability = getAbility(chara, skill);
+		ability.ifPresent(v -> modifier.setText(StringHelper.toString(v.baseModifier())));
 		totalListener.setObserved(new TotalPacket(ability, skill, current), current);
 	}
 
-	private Optional<IntValue> getAbility(final DDCharacter chara, final DDSkill skill) {
+	private Optional<Ability.Scores> getAbility(final DDCharacter chara, final DDSkill skill) {
 		if (skill.getAbility().isEmpty()) { return Optional.empty(); }
-		else { return Optional.of(Ability.fields.get(skill.getAbility()).apply(chara.getAbilities().getBase())); }
+		else { return Optional.of(AbilityHelper.get(chara, skill)); }
 	}
 
 	void applyChange() {

+ 6 - 6
src/main/lombok/org/leumasjaffe/charsheet/view/skills/SkillLine.java

@@ -6,6 +6,7 @@ import org.leumasjaffe.charsheet.model.Ability;
 import org.leumasjaffe.charsheet.model.DDCharacter;
 import org.leumasjaffe.charsheet.model.observable.IntValue;
 import org.leumasjaffe.charsheet.model.skill.DDSkill;
+import org.leumasjaffe.charsheet.util.AbilityHelper;
 import org.leumasjaffe.charsheet.util.StringHelper;
 import org.leumasjaffe.observer.IndirectObservableListener;
 import org.leumasjaffe.observer.ObservableListener;
@@ -30,7 +31,8 @@ public class SkillLine extends JPanel {
 	 * 
 	 */
 	private static final long serialVersionUID = 1L;
-	ObservableListener<JTextField, IntValue> modifierListener, skillListener;
+	ObservableListener<JTextField, Ability.Scores> modifierListener;
+	ObservableListener<JTextField, IntValue> skillListener;
 	IndirectObservableListener<JTextField, DDCharacter> totalListener;
 
 	public SkillLine(final DDCharacter chara, final DDSkill skill) {
@@ -170,15 +172,13 @@ public class SkillLine extends JPanel {
 			totalListener = new IndirectObservableListener<>(total,
 					(c, v) -> {
 						final float skillRanks = skill.getRanks().value();
-						final int mod = Ability.modifier(Ability.fields.get(skill.getAbility())
-								.apply(chara.getAbilities().getBase()).value());
+						final int mod = AbilityHelper.get(chara, skill).modifier();
 						c.setText(StringHelper.toString(skillRanks + mod));
 					});
 			modifierListener = new ObservableListener<>(modifier, 
-					( c, v ) -> c.setText(StringHelper.toString(Ability.modifier(v.value()))));
+					( c, v ) -> c.setText(StringHelper.toString(v.modifier())));
 			
-			final IntValue abilScore = 	Ability.fields.get(skill.getAbility())
-					.apply(chara.getAbilities().getBase());
+			final Ability.Scores abilScore = AbilityHelper.get(chara, skill);
 			totalListener.setObserved(chara, skill.getRanks(), abilScore);
 			modifierListener.setObserved(abilScore);
 		}

+ 3 - 3
src/main/lombok/org/leumasjaffe/charsheet/view/summary/AbilityBox.java

@@ -91,9 +91,9 @@ public class AbilityBox extends JPanel {
 					StringHelper.toString(modifier(v.value()))));
 	}
 
-	public void setModel(IntValue scores) {
-		valueListener.setObserved(scores);
-		modListener.setObserved(scores);
+	public void setModel(IntValue value) {
+		valueListener.setObserved(value);
+		modListener.setObserved(value);
 	}
 
 }

+ 5 - 5
src/main/lombok/org/leumasjaffe/charsheet/view/summary/AbilityLine.java

@@ -7,7 +7,6 @@ import java.awt.Font;
 import javax.swing.border.LineBorder;
 
 import org.leumasjaffe.charsheet.model.Ability;
-import org.leumasjaffe.charsheet.model.observable.IntValue;
 
 import lombok.AccessLevel;
 import lombok.experimental.FieldDefaults;
@@ -24,11 +23,11 @@ public class AbilityLine extends JPanel {
 	 * 
 	 */
 	private static final long serialVersionUID = 1L;
-	Function<Ability.Scores, IntValue> access;
+	Function<Ability, Ability.Scores> access;
 	AbilityBox ability;
 	AbilityBox temporary;
 	
-	public AbilityLine(final String name, Function<Ability.Scores, IntValue> func) {
+	public AbilityLine(final String name, Function<Ability, Ability.Scores> func) {
 		this.access = func;
 		
 		setMaximumSize(new Dimension(220, 26));
@@ -75,8 +74,9 @@ public class AbilityLine extends JPanel {
 	}
 
 	public void setModel(Ability model) {
-		this.ability.setModel(access.apply(model.getBase()));
-		this.temporary.setModel(access.apply(model.getTemp()));
+		final Ability.Scores score = access.apply(model);
+		this.ability.setModel(score.getBase());
+		this.temporary.setModel(score.getTemp());
 	}
 
 }

+ 4 - 5
src/main/lombok/org/leumasjaffe/charsheet/view/summary/AbilityPanel.java

@@ -11,7 +11,6 @@ import java.awt.Dimension;
 import java.awt.Color;
 
 import org.leumasjaffe.charsheet.model.Ability;
-import org.leumasjaffe.charsheet.model.observable.IntValue;
 
 import lombok.AccessLevel;
 import lombok.experimental.FieldDefaults;
@@ -23,9 +22,9 @@ public class AbilityPanel extends JPanel {
 	 */
 	private static final long serialVersionUID = 1L;
 	private static final String[] abils = new String[] { "STR", "DEX", "CON", "INT", "WIS", "CHA" };
-	private static final List<Function<Ability.Scores, IntValue>> funcs = Arrays.asList( 
-		Ability.Scores::getStr, Ability.Scores::getDex, Ability.Scores::getCon,
-		Ability.Scores::getInt, Ability.Scores::getWis, Ability.Scores::getCha
+	private static final List<Function<Ability, Ability.Scores>> funcs = Arrays.asList( 
+		Ability::getStr, Ability::getDex, Ability::getCon,
+		Ability::getInt, Ability::getWis, Ability::getCha
 		);
 	AbilityLine[] lines = new AbilityLine[6];
 	
@@ -46,7 +45,7 @@ public class AbilityPanel extends JPanel {
 		}
 	}
 
-	private AbilityLine addAbility(int y, String name, Function<Ability.Scores, IntValue> func) {
+	private AbilityLine addAbility(int y, String name, Function<Ability, Ability.Scores> func) {
 		AbilityLine abilityLine = new AbilityLine(name, func);
 		abilityLine.setOpaque(false);
 		GridBagConstraints gbc_abilityLine = new GridBagConstraints();

+ 3 - 4
src/main/lombok/org/leumasjaffe/charsheet/view/summary/ArmorLine.java

@@ -12,7 +12,6 @@ import org.leumasjaffe.charsheet.model.DDCharacter;
 import org.leumasjaffe.charsheet.model.inventory.DDInventory;
 import org.leumasjaffe.charsheet.model.inventory.DDItem;
 import org.leumasjaffe.charsheet.model.inventory.EquipmentSlot;
-import org.leumasjaffe.charsheet.model.observable.IntValue;
 import org.leumasjaffe.charsheet.util.StringHelper;
 import org.leumasjaffe.observer.IndirectObservableListener;
 import org.leumasjaffe.observer.ObservableListener;
@@ -360,7 +359,7 @@ public class ArmorLine extends JPanel {
 			final DDInventory inv = v.getInventory();
 			int iarmor = 0;
 			int ishield = 0;
-			int dex = Ability.modifier(v.getAbilities().getBase().getDex().value());
+			int dex = v.getAbilities().getDex().modifier();
 			int isize = v.getSize().value().modifier;
 			int inatural = 0;
 			int ideflect = 0;
@@ -402,7 +401,7 @@ public class ArmorLine extends JPanel {
 		
 		armorDexObserver = new IndirectObservableListener<>(dexterity, (c, v) -> {
 			final DDInventory inv = v.getInventory();
-			int dex = Ability.modifier(v.getAbilities().getBase().getDex().value());
+			int dex = v.getAbilities().getDex().modifier();
 			{
 				final DDItem body = inv.getEquipment().get(EquipmentSlot.BODY);
 				if ( body != null && body.isArmor() ) {
@@ -415,7 +414,7 @@ public class ArmorLine extends JPanel {
 	
 	public void setModel(final DDCharacter model) {
 		final DDInventory inv = model.getInventory();
-		final IntValue dex = model.getAbilities().getBase().getDex();
+		final Ability.Scores dex = model.getAbilities().getDex();
 		armorTotalObserver.setObserved(model, inv, dex);
 		armorArmorObserver.setObserved(inv);
 		armorShieldObserver.setObserved(inv);

+ 3 - 4
src/main/lombok/org/leumasjaffe/charsheet/view/summary/AttackLine.java

@@ -9,7 +9,6 @@ import javax.swing.border.LineBorder;
 
 import org.leumasjaffe.charsheet.model.Ability;
 import org.leumasjaffe.charsheet.model.DDCharacter;
-import org.leumasjaffe.charsheet.model.observable.IntValue;
 import org.leumasjaffe.charsheet.observer.helper.AbilModStringify;
 import org.leumasjaffe.charsheet.util.StringHelper;
 import org.leumasjaffe.observer.IndirectObservableListener;
@@ -39,7 +38,7 @@ public class AttackLine extends JPanel {
 	JTextField baseAttack;
 	
 	IndirectObservableListener<JTextField, DDCharacter> gTtlObserver;
-	ObservableListener<JTextField, IntValue> gStrObserver;
+	ObservableListener<JTextField, Ability.Scores> gStrObserver;
 
 	public AttackLine() {
 		setPreferredSize(new Dimension(600, 25));
@@ -226,7 +225,7 @@ public class AttackLine extends JPanel {
 		gTtlObserver = new IndirectObservableListener<>(grappleTtl,
 				(c, v) -> {
 					final int bab = v.getBaseAttack();
-					final int str = Ability.modifier(this.model.getAbilities().getBase().getStr().value());
+					final int str = this.model.getAbilities().getStr().modifier();
 					final int size = v.getSize().value().modifier;
 					final int misc = 0;
 					c.setText(StringHelper.toString(bab + str + size + misc));
@@ -241,7 +240,7 @@ public class AttackLine extends JPanel {
 		final int size = this.model.getSize().value().modifier;
 		final int misc = 0;
 		this.baseAttack.setText(StringHelper.toString(bab));
-		final IntValue str = model.getAbilities().getBase().getStr();
+		final Ability.Scores str = model.getAbilities().getStr();
 		gTtlObserver.setObserved(model, str);
 		gStrObserver.setObserved(str);
 		this.grappleSize.setText(StringHelper.toString(size));

+ 5 - 7
src/main/lombok/org/leumasjaffe/charsheet/view/summary/InitiativeLine.java

@@ -5,13 +5,11 @@ import java.awt.GridBagLayout;
 import javax.swing.JLabel;
 import java.awt.GridBagConstraints;
 
-import static org.leumasjaffe.charsheet.model.Ability.modifier;
-
 import java.awt.Color;
 import javax.swing.border.LineBorder;
 
+import org.leumasjaffe.charsheet.model.Ability;
 import org.leumasjaffe.charsheet.model.DDCharacter;
-import org.leumasjaffe.charsheet.model.observable.IntValue;
 import org.leumasjaffe.charsheet.observer.helper.AbilModStringify;
 import org.leumasjaffe.charsheet.util.StringHelper;
 import org.leumasjaffe.observer.IndirectObservableListener;
@@ -33,7 +31,7 @@ public class InitiativeLine extends JPanel {
 	 */
 	private static final long serialVersionUID = 1L;
 	IndirectObservableListener<JTextField, DDCharacter> ttlObserver;
-	ObservableListener<JTextField, IntValue> dexObserver;
+	ObservableListener<JTextField, Ability.Scores> dexObserver;
 
 	public InitiativeLine() {
 		setOpaque(false);
@@ -127,15 +125,15 @@ public class InitiativeLine extends JPanel {
 		
 		ttlObserver = new IndirectObservableListener<>(total, 
 				(c, v) -> {
-					final int adex = v.getAbilities().getBase().getDex().value();
-					c.setText(StringHelper.toString( modifier(adex) ));
+					final int adex = v.getAbilities().getDex().modifier();
+					c.setText(StringHelper.toString( adex ));
 				});
 		dexObserver = new ObservableListener<>(dex, 
 				new AbilModStringify());
 	}
 
 	public void setModel(DDCharacter model) {
-		final IntValue dex = model.getAbilities().getBase().getDex();
+		final Ability.Scores dex = model.getAbilities().getDex();
 		ttlObserver.setObserved(model, dex);
 		dexObserver.setObserved(dex);
 	}

+ 5 - 6
src/main/lombok/org/leumasjaffe/charsheet/view/summary/ResistanceLine.java

@@ -9,7 +9,6 @@ import javax.swing.border.LineBorder;
 
 import org.leumasjaffe.charsheet.model.Ability;
 import org.leumasjaffe.charsheet.model.DDCharacter;
-import org.leumasjaffe.charsheet.model.observable.IntValue;
 import org.leumasjaffe.charsheet.observer.helper.AbilModStringify;
 import org.leumasjaffe.charsheet.util.StringHelper;
 import org.leumasjaffe.graphics.NumberTextField;
@@ -34,14 +33,14 @@ public class ResistanceLine extends JPanel {
 	 * 
 	 */
 	private static final long serialVersionUID = 1L;
-	Function<Ability.Scores, IntValue> access;
+	Function<Ability, Ability.Scores> access;
 	
 	IndirectObservableListener<JTextField, DDCharacter> totalObserver;
 	IndirectObservableListener<JTextField, DDCharacter> baseObserver;
-	ObservableListener<JTextField, IntValue> abilObserver;
+	ObservableListener<JTextField, Ability.Scores> abilObserver;
 	
 	public ResistanceLine(final String name, Function<DDCharacter, Integer> save, 
-			Function<Ability.Scores, IntValue> func) {
+			Function<Ability, Ability.Scores> func) {
 		this.access = func;
 		
 		setMinimumSize(new Dimension(400, 25));
@@ -222,7 +221,7 @@ public class ResistanceLine extends JPanel {
 		totalObserver = new IndirectObservableListener<>(totalField,
 				(c, v) -> {
 					final int base = save.apply(v);
-					final int abil = Ability.modifier(access.apply(v.getAbilities().getBase()).value());
+					final int abil = access.apply(v.getAbilities()).modifier();
 					final int magic = 0;
 					final int misc = 0;
 					final int temp = 0;
@@ -235,7 +234,7 @@ public class ResistanceLine extends JPanel {
 	}
 	
 	public void setModel(DDCharacter model) {
-		final IntValue abil = access.apply(model.getAbilities().getBase());
+		final Ability.Scores abil = access.apply(model.getAbilities());
 		totalObserver.setObserved(model, abil);
 		baseObserver.setObserved(model, abil);
 		abilObserver.setObserved(abil);

+ 3 - 3
src/main/lombok/org/leumasjaffe/charsheet/view/summary/ResistancePanel.java

@@ -31,21 +31,21 @@ public class ResistancePanel extends JPanel {
 		gridBagLayout.rowWeights = new double[]{0.0, 0.0, 0.0, Double.MIN_VALUE};
 		setLayout(gridBagLayout);
 		
-		fortitude = new ResistanceLine("FORTITUDE", DDCharacter::getFortSave, Ability.Scores::getCon);
+		fortitude = new ResistanceLine("FORTITUDE", DDCharacter::getFortSave, Ability::getCon);
 		GridBagConstraints gbc_fortitude = new GridBagConstraints();
 		gbc_fortitude.fill = GridBagConstraints.BOTH;
 		gbc_fortitude.gridx = 0;
 		gbc_fortitude.gridy = 0;
 		add(fortitude, gbc_fortitude);
 		
-		reflex = new ResistanceLine("REFLEX", DDCharacter::getRefSave, Ability.Scores::getDex);
+		reflex = new ResistanceLine("REFLEX", DDCharacter::getRefSave, Ability::getDex);
 		GridBagConstraints gbc_reflex = new GridBagConstraints();
 		gbc_reflex.fill = GridBagConstraints.BOTH;
 		gbc_reflex.gridx = 0;
 		gbc_reflex.gridy = 1;
 		add(reflex, gbc_reflex);
 		
-		will = new ResistanceLine("WILL", DDCharacter::getWillSave, Ability.Scores::getWis);
+		will = new ResistanceLine("WILL", DDCharacter::getWillSave, Ability::getWis);
 		GridBagConstraints gbc_will = new GridBagConstraints();
 		gbc_will.fill = GridBagConstraints.BOTH;
 		gbc_will.gridx = 0;