package org.leumasjaffe.charsheet.model; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.stream.Collectors; import java.util.stream.Stream; import org.leumasjaffe.charsheet.model.features.DDFeat; import org.leumasjaffe.charsheet.model.features.DDProperty; import org.leumasjaffe.charsheet.model.inventory.DDInventory; import org.leumasjaffe.charsheet.model.observable.IntValue; import org.leumasjaffe.charsheet.model.observable.ObjectValue; import org.leumasjaffe.charsheet.model.skill.DDSkills; import org.leumasjaffe.observer.Observable; import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import lombok.AccessLevel; import lombok.Data; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.NonNull; import lombok.experimental.FieldDefaults; @NoArgsConstructor @Data @EqualsAndHashCode(callSuper=false) @FieldDefaults(level=AccessLevel.PRIVATE) @JsonIgnoreProperties(ignoreUnknown=true) public class DDCharacter extends Observable { @NonNull String name = ""; @NonNull String player = ""; @NonNull @Getter(AccessLevel.NONE) SortedSet classes = new TreeSet<>(); @NonNull String race = ""; @NonNull Alignment alignment; @NonNull String deity = ""; @NonNull ObjectValue size = new ObjectValue<>(SizeClass.M); int age = -1; @NonNull Gender gender = Gender.N; @NonNull String height; int weight = -1; @NonNull String eyes = ""; @NonNull String hair = ""; @NonNull String skin = ""; @NonNull IntValue experience = new IntValue(); @NonNull HitPoints health = new HitPoints(); @NonNull Ability abilities = new Ability(); @NonNull DDSkills skills = new DDSkills(Collections.emptyList()); @NonNull List feats = new ArrayList<>(); @NonNull DDInventory inventory = new DDInventory(); public String getClassAndLevelString() { final StringBuilder ss = new StringBuilder(); final Iterator it = classes.iterator(); while (it.hasNext()) { ss.append(it.next()); if (it.hasNext()) { ss.append(" / "); } } return ss.toString(); } public Set getClasses() { return Collections.unmodifiableSet(classes); } public int getBaseAttack() { return classes.stream().mapToInt(c -> c.getBab()).sum(); } public int getFortSave() { return classes.stream().mapToInt(c -> c.getFort()).sum(); } public int getRefSave() { return classes.stream().mapToInt(c -> c.getRef()).sum(); } public int getWillSave() { return classes.stream().mapToInt(c -> c.getWill()).sum(); } public boolean isClassSkill(final String skillName) { return classes.stream().anyMatch( cc -> cc.isClassSkill(skillName) ); } public int getLevel() { return classes.stream().map(DDCharacterClass::getLevel).mapToInt(IntValue::value).sum(); } public List getFeatureBonuses(Object appliesScope) { return Stream.concat(feats.stream().flatMap(f -> f.getProperties().stream()) .filter(f -> f.appliesTo(appliesScope)), classes.stream().flatMap(cl -> cl.getFeatureBonuses(appliesScope).stream())) .collect(Collectors.toList()); } }